mmmturkeybacon Color Coded Search with Checkpoints

Changes the title row of a HIT's description to match the average of it's Turkopticon ratings. Changes the color of the reward amount to match the color of the Turkopticon rating for pay. Adds colored checkboxes to show/hide HITs by color rating. Adds a gray checkbox to show only HITs for which you are not qualified. Changes the background color of the HIT title and link to white for Master's HITs. Changes the color of HITs for which you are not qualified to a darker gray. And more!

当前为 2015-03-28 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name mmmturkeybacon Color Coded Search with Checkpoints
  3. // @author mmmturkeybacon
  4. // @description Changes the title row of a HIT's description to match the average of it's Turkopticon ratings. Changes the color of the reward amount to match the color of the Turkopticon rating for pay. Adds colored checkboxes to show/hide HITs by color rating. Adds a gray checkbox to show only HITs for which you are not qualified. Changes the background color of the HIT title and link to white for Master's HITs. Changes the color of HITs for which you are not qualified to a darker gray. And more!
  5. // Changes the color of visited links to black. Automatically clicks "Show all details". Adds checkboxes next to HIT links so that you can set a checkpoint. A checkpoint will notify you that you've already seen a HIT by changing the HIT link to display the date the checkpoint was set. A well-placed checkpoint is useful when browsing HITs by creation date (newest first) because it will alert you that you've already seen the checkpoint HIT and probably all the HITs that come after it. It's best to place a checkpoint on a HIT that won't be recreated because recreated HITs jump to the first page. This script is not a substitute for actually reading Turkopticon reviews.
  6. // @namespace http://userscripts.org/users/523367
  7. // @match https://*.mturk.com/mturk/viewhits*
  8. // @match https://*.mturk.com/mturk/findhits*
  9. // @match https://*.mturk.com/mturk/sorthits*
  10. // @match https://*.mturk.com/mturk/searchbar*
  11. // @match https://*.mturk.com/mturk/viewsearchbar*
  12. // @match https://*.mturk.com/mturk/sortsearchbar*
  13. // @match https://*.mturk.com/mturk/preview?*
  14. // @match https://*.mturk.com/mturk/return*
  15. // @require https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js
  16. // @version 3.15
  17. // @grant GM_xmlhttpRequest
  18. // @grant GM_getValue
  19. // @grant GM_setValue
  20. // @grant GM_deleteValue
  21. // ==/UserScript==
  22.  
  23. /**********************************************************************/
  24. /* NB: turkopticon.ucsd.edu (TO website) uses yellow for a rating between 2 and 3,
  25. * but TO extension uses orange
  26. *
  27. * Turkopticon scale
  28. * green : 3 < average <= 5
  29. * orange: 2 < average <= 3
  30. * red : 1 < average <= 2
  31. *
  32. * Color Coded Search scale (so that green represents the very best HITs)
  33. * green : 4 < average <= 5
  34. * yellow: 3 < average <= 4 yellow are OK HITs, that's why the yellow has a touch of green
  35. * orange: 2 < average <= 3
  36. * red : 1 < average <= 2
  37. */
  38. var GREEN = '#66CC66'; // (4,5]
  39. //var YELLOW = '#FFFF00'; // (3,4] yellow
  40. //var YELLOW = '#CDFF2F'; // (3,4] yellow with hint of green
  41. var YELLOW = '#ADFF2F'; // (3,4] green yellow
  42. //var YELLOW = '#9CE62A'; // (3,4] darker green yello
  43. var ORANGE = '#FF9900'; // (2,3]
  44. //var RED = '#FF0000'; // (1,2]
  45. var RED = '#FF3030'; // (1,2]
  46. var BLUE = '#7FAAEB'; // no rating
  47.  
  48. var VISITED_LINK = '#000000'; // black
  49. var MASTERS = '#FFFFFF'; // white
  50. //var MASTERS = '#B56CFF'; // purple
  51.  
  52. var NEW_NOTQUAL_BODY = '#A9AAA4'; // dark grey
  53.  
  54. var COMM_WEIGHT = 1;
  55. var PAY_WEIGHT = 3;
  56. var FAIR_WEIGHT = 3;
  57. var FAST_WEIGHT = 1;
  58.  
  59. var CHECKPOINT_COLOR = '#000000'; // black
  60. //var CHECKPOINT_COLOR = '#00AAAA'; // dark green-blue
  61. var CHECKPOINT_MESSAGE = 'CHECKPOINT REACHED!';
  62. //var CHECKPOINT_MESSAGE = 'YOU SHALL NOT PASS!';
  63.  
  64. var SHOW_ALL_DETAILS = true;
  65.  
  66. /**********************************************************************/
  67.  
  68. // URLs for testing, learning parameters
  69. //http://mturk-api.istrack.in/multi-attrs.php?ids=ABSF8UXFZYEK6
  70. //http://data.istrack.in/turkopticon.php?data=2.57,2.31,2.89,2.71
  71.  
  72. var TIMEOUT = 10000; // [ms] milliseconds, 0 means wait forever
  73.  
  74. var API_BASE = 'https://turkopticon.ucsd.edu/api/';
  75. var API_MULTI_ATTRS_URL = API_BASE + 'multi-attrs.php?ids=';
  76.  
  77. var API_PROXY_BASE = 'https://mturk-api.istrack.in/';
  78. var API_PROXY_MULTI_ATTRS_URL = API_PROXY_BASE + 'multi-attrs.php?ids=';
  79.  
  80. var REVIEWS_BASE = 'http://turkopticon.ucsd.edu/';
  81. var HIT_GROUPS_BASE_LINK = '/mturk/searchbar?selectedSearchType=hitgroups&requesterId=';
  82.  
  83. var NOTQUAL_BODY = '#F1F3EB';
  84.  
  85. var qual_checkbox;
  86. var notqual_checkbox;
  87. var green_checkbox;
  88. var yellow_checkbox;
  89. var orange_checkbox;
  90. var red_checkbox;
  91. var blue_checkbox;
  92. var $parent_tables;
  93.  
  94. function process_TO_data(requester_data)
  95. {
  96. var average = 0;
  97. var comm_rnd = 0;
  98. var pay_rnd = 0;
  99. var fair_rnd = 0;
  100. var fast_rnd = 0;
  101. var reviews = 0;
  102. var tos = 0;
  103.  
  104. // after the API update, this if isn't necessary. leaving it in until
  105. // sure API is stable
  106. if (requester_data)
  107. {
  108. var comm = requester_data.attrs.comm;
  109. var pay = requester_data.attrs.pay;
  110. var fair = requester_data.attrs.fair;
  111. var fast = requester_data.attrs.fast;
  112. var sum = 0;
  113. var divisor = 0;
  114.  
  115. if (comm > 0)
  116. {
  117. sum += COMM_WEIGHT*comm;
  118. divisor += COMM_WEIGHT;
  119. }
  120. if (pay > 0)
  121. {
  122. sum += PAY_WEIGHT*pay;
  123. divisor += PAY_WEIGHT;
  124. }
  125. if (fair > 0)
  126. {
  127. sum += FAIR_WEIGHT*fair;
  128. divisor += FAIR_WEIGHT;
  129. }
  130. if (fast > 0)
  131. {
  132. sum += FAST_WEIGHT*fast;
  133. divisor += FAST_WEIGHT;
  134. }
  135. if (divisor > 0)
  136. {
  137. average = sum/divisor;
  138. }
  139.  
  140. comm_rnd = Math.round(comm*4)/4;
  141. pay_rnd = Math.round(pay*4)/4;
  142. fair_rnd = Math.round(fair*4)/4;
  143. fast_rnd = Math.round(fast*4)/4;
  144. if (requester_data.reviews)
  145. {
  146. reviews = requester_data.reviews;
  147. }
  148. if (requester_data.tos_flags)
  149. {
  150. tos = requester_data.tos_flags;
  151. }
  152. }
  153.  
  154. comm_rnd = comm_rnd.toFixed(2);
  155. pay_rnd = pay_rnd.toFixed(2);
  156. fair_rnd = fair_rnd.toFixed(2);
  157. fast_rnd = fast_rnd.toFixed(2);
  158.  
  159. return {comm_rnd:comm_rnd, pay_rnd:pay_rnd, fair_rnd:fair_rnd, fast_rnd:fast_rnd, reviews:reviews, tos:tos, average:average};
  160. }
  161.  
  162. function determine_color(rating)
  163. {
  164. // The lowest rating that can be given is a 1.
  165. // green is (4,5]
  166. // yellow is (3,4]
  167. // orange is (2,3]
  168. // red is (1,2]
  169. // blue is 0 (no rating)
  170. // (0,1) is no man's land but I set the lower bound for red to 0 to agree with data.istrack.in
  171.  
  172. var color = BLUE;
  173.  
  174. if (rating > 4)
  175. {
  176. color = GREEN;
  177. }
  178. else if (rating > 3)
  179. {
  180. color = YELLOW;
  181. }
  182. else if (rating > 2 )
  183. {
  184. color = ORANGE;
  185. }
  186. else if (rating > 0)
  187. {
  188. color = RED;
  189. }
  190.  
  191. return color;
  192. }
  193.  
  194. function show_hide_color(color)
  195. {
  196. if (notqual_checkbox.checked == true)
  197. {
  198. var $color_subset_tables = $parent_tables.filter('[title_color='+color+'][qualified_for="false"][hideable!=false]');
  199. }
  200. else
  201. {
  202. var $color_subset_tables = $parent_tables.filter('[title_color='+color+'][hideable!=false]');
  203. }
  204. switch(color)
  205. {
  206. case GREEN:
  207. {
  208. GM_setValue('green_checkbox_checked', green_checkbox.checked);
  209. if (green_checkbox.checked == false)
  210. {
  211. $color_subset_tables.each(function()
  212. {
  213. $(this).hide();
  214. });
  215. }
  216. else
  217. {
  218. $color_subset_tables.each(function()
  219. {
  220. $(this).show();
  221. });
  222. }
  223. break;
  224. }
  225. case YELLOW:
  226. {
  227. GM_setValue('yellow_checkbox_checked', yellow_checkbox.checked);
  228. if (yellow_checkbox.checked == false)
  229. {
  230. $color_subset_tables.each(function()
  231. {
  232. $(this).hide();
  233. });
  234. }
  235. else
  236. {
  237. $color_subset_tables.each(function()
  238. {
  239. $(this).show();
  240. });
  241. }
  242. break;
  243. }
  244. case ORANGE:
  245. {
  246. GM_setValue('orange_checkbox_checked', orange_checkbox.checked);
  247. if (orange_checkbox.checked == false)
  248. {
  249. $color_subset_tables.each(function()
  250. {
  251. $(this).hide();
  252. });
  253. }
  254. else
  255. {
  256. $color_subset_tables.each(function()
  257. {
  258. $(this).show();
  259. });
  260. }
  261. break;
  262. }
  263. case RED:
  264. {
  265. GM_setValue('red_checkbox_checked', red_checkbox.checked);
  266. if (red_checkbox.checked == false)
  267. {
  268. $color_subset_tables.each(function()
  269. {
  270. $(this).hide();
  271. });
  272. }
  273. else
  274. {
  275. $color_subset_tables.each(function()
  276. {
  277. $(this).show();
  278. });
  279. }
  280. break;
  281. }
  282. case BLUE:
  283. {
  284. GM_setValue('blue_checkbox_checked', blue_checkbox.checked);
  285. if (blue_checkbox.checked == false)
  286. {
  287. $color_subset_tables.each(function()
  288. {
  289. $(this).hide();
  290. });
  291. }
  292. else
  293. {
  294. $color_subset_tables.each(function()
  295. {
  296. $(this).show();
  297. });
  298. }
  299. break;
  300. }
  301. }
  302. }
  303.  
  304. function show_hide_all_colors()
  305. {
  306. show_hide_color(GREEN);
  307. show_hide_color(YELLOW);
  308. show_hide_color(ORANGE);
  309. show_hide_color(RED);
  310. show_hide_color(BLUE);
  311. }
  312.  
  313. function show_hide_qual()
  314. {
  315. GM_setValue('notqual_checkbox_checked', notqual_checkbox.checked);
  316. if (notqual_checkbox.checked == true)
  317. {
  318. $parent_tables.filter('[qualified_for="true"][hideable!=false]').each(function()
  319. {
  320. $(this).hide();
  321. });
  322. }
  323. else
  324. {
  325. show_hide_all_colors();
  326. }
  327. }
  328.  
  329. function set_checkpoint(e)
  330. {
  331. var caller = e.target || e.srcElement;
  332.  
  333. if (caller.checked)
  334. {
  335. var d = new Date();
  336. GM_setValue(caller.name+'_checked', caller.checked);
  337. GM_setValue(caller.name+'_date', '['+d.toLocaleDateString()+'] ');
  338. }
  339. else
  340. {
  341. GM_deleteValue(caller.name+'_checked');
  342. GM_deleteValue(caller.name+'_date');
  343. }
  344. }
  345.  
  346. function create_colored_checkboxes()
  347. {
  348. var checkbox_div = document.createElement('DIV');
  349. var notqual_div = document.createElement('DIV');
  350. var green_div = document.createElement('DIV');
  351. var yellow_div = document.createElement('DIV');
  352. var orange_div = document.createElement('DIV');
  353. var red_div = document.createElement('DIV');
  354. var blue_div = document.createElement('DIV');
  355. notqual_div.style.cssText = 'display:inline-block; background-color: '+NEW_NOTQUAL_BODY+';'
  356. green_div.style.cssText = 'display:inline-block; background-color: '+GREEN+';'
  357. yellow_div.style.cssText = 'display:inline-block; background-color: '+YELLOW+';'
  358. orange_div.style.cssText = 'display:inline-block; background-color: '+ORANGE+';'
  359. red_div.style.cssText = 'display:inline-block; background-color: '+RED+';'
  360. blue_div.style.cssText = 'display:inline-block; background-color: '+BLUE+';'
  361.  
  362. notqual_checkbox = document.createElement('INPUT');
  363. green_checkbox = document.createElement('INPUT');
  364. yellow_checkbox = document.createElement('INPUT');
  365. orange_checkbox = document.createElement('INPUT');
  366. red_checkbox = document.createElement('INPUT');
  367. blue_checkbox = document.createElement('INPUT');
  368. notqual_checkbox.type = 'checkbox';
  369. green_checkbox.type = 'checkbox';
  370. yellow_checkbox.type = 'checkbox';
  371. orange_checkbox.type = 'checkbox';
  372. red_checkbox.type = 'checkbox';
  373. blue_checkbox.type = 'checkbox';
  374. notqual_checkbox.checked = GM_getValue('notqual_checkbox_checked', false);
  375. green_checkbox.checked = GM_getValue('green_checkbox_checked', true);
  376. yellow_checkbox.checked = GM_getValue('yellow_checkbox_checked', true);
  377. orange_checkbox.checked = GM_getValue('orange_checkbox_checked', true);
  378. red_checkbox.checked = GM_getValue('red_checkbox_checked', true);
  379. blue_checkbox.checked = GM_getValue('blue_checkbox_checked', true);
  380. notqual_checkbox.name = 'notqual_checkbox';
  381. green_checkbox.name = 'green_checkbox';
  382. yellow_checkbox.name = 'yellow_checkbox';
  383. orange_checkbox.name = 'orange_checkbox';
  384. red_checkbox.name = 'red_checkbox';
  385. blue_checkbox.name = 'blue_checkbox';
  386. notqual_checkbox.title = 'Only show HITs for which you are not qualified';
  387. green_checkbox.title = 'Show/Hide green';
  388. yellow_checkbox.title = 'Show/Hide yellow';
  389. orange_checkbox.title = 'Show/Hide orange';
  390. red_checkbox.title = 'Show/Hide red';
  391. blue_checkbox.title = 'Show/Hide no TO';
  392. notqual_checkbox.addEventListener('click', show_hide_qual);
  393. green_checkbox.addEventListener('click', function(){show_hide_color(GREEN);});
  394. yellow_checkbox.addEventListener('click', function(){show_hide_color(YELLOW);});
  395. orange_checkbox.addEventListener('click', function(){show_hide_color(ORANGE);});
  396. red_checkbox.addEventListener('click', function(){show_hide_color(RED);});
  397. blue_checkbox.addEventListener('click', function(){show_hide_color(BLUE);});
  398.  
  399. notqual_div.appendChild(notqual_checkbox);
  400. green_div.appendChild(green_checkbox);
  401. yellow_div.appendChild(yellow_checkbox);
  402. orange_div.appendChild(orange_checkbox);
  403. red_div.appendChild(red_checkbox);
  404. blue_div.appendChild(blue_checkbox);
  405. checkbox_div.align = 'center';
  406. checkbox_div.appendChild(notqual_div);
  407. checkbox_div.appendChild(green_div);
  408. checkbox_div.appendChild(yellow_div);
  409. checkbox_div.appendChild(orange_div);
  410. checkbox_div.appendChild(red_div);
  411. checkbox_div.appendChild(blue_div);
  412. return checkbox_div;
  413. }
  414.  
  415.  
  416. function color_code($parent_tables, api_base, requester_IDs_csv)
  417. {
  418. GM_xmlhttpRequest(
  419. {
  420. method: 'GET',
  421. url: api_base+requester_IDs_csv,
  422. timeout: TIMEOUT,
  423. onload: function (results)
  424. {
  425. var rdata = $.parseJSON(results.responseText);
  426.  
  427. var checkbox_div = create_colored_checkboxes();
  428. $('table[cellspacing="0"][cellpadding="0"][border="0"][style="margin:5px; clear:both;"]').eq(1).after(checkbox_div);
  429.  
  430. $parent_tables.each(function()
  431. {
  432. var $requester_ID_link = $(this).find('a[href^="'+HIT_GROUPS_BASE_LINK+'"]').attr('href');
  433. var requester_ID = $requester_ID_link.replace(HIT_GROUPS_BASE_LINK,'');
  434. var title_row = $(this).find('tr').eq(1);
  435. var link_bgcolor = $(this).find('td[width="100%"][valign="middle"][height="20"][align="left"]').attr('bgcolor');
  436.  
  437. var pdata = process_TO_data(rdata[requester_ID]);
  438. var title_color = determine_color(pdata.average);
  439. var qualified_for = !($(this).find('a[href^="/mturk/notqualified?"]').length > 0);
  440.  
  441. $(this).attr('title_color', title_color);
  442. $(this).attr('qualified_for', qualified_for);
  443.  
  444. //var $title_line = $(this).find('td[width="100%"][valign="middle"][height="20"][align="left"]');
  445. //$title_line.css('background-color', title_color);
  446. $(this).find('td[valign="middle"][nowrap=""][align="left"]').css('background-color', title_color);
  447. $(this).find('td[valign="middle"][align="left"]').css('background-color', title_color);
  448. $(this).find('td[width="100%"][valign="middle"][nowrap=""][align="right"]').css('background-color', title_color);
  449. //$(this).find('a[href^="/mturk/preview?groupId="]').css('background-color', link_bgcolor);
  450.  
  451. var link_href = REVIEWS_BASE + requester_ID;
  452. var link_text = pdata.reviews + ((pdata.reviews != 1) ? ' reviews ' : ' review ');
  453. //link_text = '['+link_text + '|comm: '+pdata.comm_rnd+'|pay: '+pdata.pay_rnd+'|fair: '+pdata.fair_rnd+'|fast: '+pdata.fast_rnd+'|tos: '+pdata.tos+']';
  454. link_text = '['+link_text + '|pay: '+pdata.pay_rnd+'|fair: '+pdata.fair_rnd+'|comm: '+pdata.comm_rnd+'|fast: '+pdata.fast_rnd+'|tos: '+pdata.tos+']';
  455. var link = '<a href="'+link_href+'" target="_blank">'+link_text+'</a>&nbsp;';
  456. title_row.after('<tr><td width="1" valign="middle" bgcolor="#336699" align="center"></td><td width="18" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="100%" valign="top" bgcolor="'+title_color+'" align="right">'+link+'</td><td width="8" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="1" valign="middle" bgcolor="#336699" align="center"></td></tr>');
  457.  
  458. // after the API update, this if isn't necessary. leaving it in until
  459. // sure API is stable
  460. var pay = 0;
  461. if (rdata[requester_ID])
  462. {
  463. pay = rdata[requester_ID].attrs.pay;
  464. }
  465. var pay_color = determine_color(pay);
  466. //var pay_color = determine_color(rdata[requester_ID].attrs.pay);
  467. $(this).find('span[class="reward"]').css('background-color', pay_color);
  468.  
  469. // highlight Masters HITs title and link
  470. var is_masters = $(this).find('td[style="padding-right: 2em; white-space: nowrap;"]:contains("Masters")').length > 0;
  471. if (is_masters)
  472. {
  473. $(this).find('td[valign="middle"][nowrap=""][align="left"]').css('background-color', MASTERS);
  474. $(this).find('a[href^="/mturk/preview?groupId="]').css('background-color', MASTERS);
  475. }
  476.  
  477. // create checkpoints
  478. var $preview_link = $(this).find('a:contains("View a HIT in this group")');
  479. var groupId = $preview_link.attr('href')
  480. groupId = (groupId) ? groupId.split('=')[1] : $(this).find('a[href^="/mturk/notqualified?hitGroupId="]').attr('href').split(/=|&/)[1];
  481. var checkbox = document.createElement('INPUT');
  482. checkbox.type = 'checkbox';
  483. checkbox.name = groupId;
  484. checkbox.title = 'Set a checkpoint to help remember a HIT you\'ve seen before.\nUseful when browsing by HIT Creation Date.';
  485. checkbox.checked = GM_getValue(checkbox.name+'_checked', false);
  486. checkbox.addEventListener('click', set_checkpoint);
  487. checkbox.style.cssText ='vertical-align:middle;';
  488. $preview_link.after(checkbox);
  489. // mark checkpoints
  490. if (checkbox.checked == true)
  491. {
  492. var checkpoint_date = GM_getValue(checkbox.name+'_date');
  493. $preview_link.text(checkpoint_date+CHECKPOINT_MESSAGE);
  494. $(this).attr('hideable', false);
  495. $(this).css('border', '50px solid '+CHECKPOINT_COLOR);
  496. }
  497. });
  498. show_hide_all_colors();
  499. show_hide_qual();
  500. },
  501. ontimeout: function()
  502. {
  503. if (api_base == API_MULTI_ATTRS_URL)
  504. { // tried main api server and failed, now try mirror
  505. color_code($parent_tables, API_PROXY_MULTI_ATTRS_URL, requester_IDs_csv);
  506. }
  507. else
  508. { // tried mirror and failed, add basic link to reviews and checkpoints
  509. $parent_tables.each(function()
  510. {
  511. var $requester_ID_link = $(this).find('a[href^="'+HIT_GROUPS_BASE_LINK+'"]').attr('href');
  512. var requester_ID = $requester_ID_link.replace(HIT_GROUPS_BASE_LINK,'');
  513. var title_row = $(this).find('tr').eq(1);
  514. var link_bgcolor = $(this).find('td[width="100%"][valign="middle"][height="20"][align="left"]').attr('bgcolor');
  515.  
  516. var link_href = REVIEWS_BASE + requester_ID;
  517. var link_text = 'Turkopticon reviews';
  518. var link = '<a href="'+link_href+'" target="_blank">'+link_text+'</a>&nbsp;';
  519. title_row.after('<tr><td width="1" valign="middle" bgcolor="#336699" align="center"></td><td width="18" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="100%" valign="top" bgcolor="'+link_bgcolor+'" align="right">'+link+'</td><td width="8" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="1" valign="middle" bgcolor="#336699" align="center"></td></tr>');
  520.  
  521. // create checkpoints
  522. var $preview_link = $(this).find('a:contains("View a HIT in this group")');
  523. var groupId = $preview_link.attr('href')
  524. groupId = (groupId) ? groupId.split('=')[1] : $(this).find('a[href^="/mturk/notqualified?hitGroupId="]').attr('href').split(/=|&/)[1];
  525. var checkbox = document.createElement('INPUT');
  526. checkbox.type = 'checkbox';
  527. checkbox.name = groupId;
  528. checkbox.title = 'Set a checkpoint to help remember a HIT you\'ve seen before.\nUseful when browsing by HIT Creation Date.';
  529. checkbox.checked = GM_getValue(checkbox.name+'_checked', false);
  530. checkbox.addEventListener('click', set_checkpoint);
  531. checkbox.style.cssText ='vertical-align:middle;';
  532. $preview_link.after(checkbox);
  533. // mark checkpoints
  534. if (checkbox.checked == true)
  535. {
  536. var checkpoint_date = GM_getValue(checkbox.name+'_date');
  537. $preview_link.text(checkpoint_date+CHECKPOINT_MESSAGE);
  538. $(this).attr('hideable', false);
  539. $(this).css('border', '50px solid '+CHECKPOINT_COLOR);
  540. }
  541. });
  542. }
  543. },
  544. onerror: function()
  545. {
  546. if (api_base == API_MULTI_ATTRS_URL)
  547. { // tried main api server and failed, now try mirror
  548. color_code($parent_tables, API_PROXY_MULTI_ATTRS_URL, requester_IDs_csv);
  549. }
  550. else
  551. { // tried mirror and failed, add basic link to reviews and checkpoints
  552. $parent_tables.each(function()
  553. {
  554. var $requester_ID_link = $(this).find('a[href^="'+HIT_GROUPS_BASE_LINK+'"]').attr('href');
  555. var requester_ID = $requester_ID_link.replace(HIT_GROUPS_BASE_LINK,'');
  556. var title_row = $(this).find('tr').eq(1);
  557. var link_bgcolor = $(this).find('td[width="100%"][valign="middle"][height="20"][align="left"]').attr('bgcolor');
  558.  
  559. var link_href = REVIEWS_BASE + requester_ID;
  560. var link_text = 'Turkopticon reviews';
  561. var link = '<a href="'+link_href+'" target="_blank">'+link_text+'</a>&nbsp;';
  562. title_row.after('<tr><td width="1" valign="middle" bgcolor="#336699" align="center"></td><td width="18" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="100%" valign="top" bgcolor="'+link_bgcolor+'" align="right">'+link+'</td><td width="8" valign="middle" bgcolor="'+link_bgcolor+'" align="center"></td><td width="1" valign="middle" bgcolor="#336699" align="center"></td></tr>');
  563.  
  564. // create checkpoints
  565. var $preview_link = $(this).find('a:contains("View a HIT in this group")');
  566. var groupId = $preview_link.attr('href')
  567. groupId = (groupId) ? groupId.split('=')[1] : $(this).find('a[href^="/mturk/notqualified?hitGroupId="]').attr('href').split(/=|&/)[1];
  568. var checkbox = document.createElement('INPUT');
  569. checkbox.type = 'checkbox';
  570. checkbox.name = groupId;
  571. checkbox.title = 'Set a checkpoint to help remember a HIT you\'ve seen before.\nUseful when browsing by HIT Creation Date.';
  572. checkbox.checked = GM_getValue(checkbox.name+'_checked', false);
  573. checkbox.addEventListener('click', set_checkpoint);
  574. checkbox.style.cssText ='vertical-align:middle;';
  575. $preview_link.after(checkbox);
  576. // mark checkpoints
  577. if (checkbox.checked == true)
  578. {
  579. var checkpoint_date = GM_getValue(checkbox.name+'_date');
  580. $preview_link.text(checkpoint_date+CHECKPOINT_MESSAGE);
  581. $(this).attr('hideable', false);
  582. $(this).css('border', '50px solid '+CHECKPOINT_COLOR);
  583. }
  584. });
  585. }
  586. }
  587. });
  588. }
  589.  
  590. //$(document).ready(function()
  591. //{
  592. var is_HIT = $('input[type="hidden"][name="isAccepted"]').length > 0;
  593. if (is_HIT)
  594. {
  595. throw new Error('Not on a search page. Exit.');
  596. }
  597.  
  598. // change visited link color to make it easier to differentiate from unvisited link
  599. // code snippet from http://stackoverflow.com/questions/7030289/how-to-set-link-visited-color-in-jquery
  600. var visited_link_styling = '<style> a:visited {color:'+VISITED_LINK+';} </style>';
  601. $('head').append(visited_link_styling);
  602. // end snippet
  603.  
  604. if (SHOW_ALL_DETAILS)
  605. {
  606. // click 'Show all details'
  607. $(window).load(function(){$('a[id="expandall"][class="footer_links"][href="#"]:contains("Show all details")').get(0).click();});
  608. }
  609.  
  610. // change color of HITs not qualified for to make it easier to differentiate
  611. $('[bgcolor="'+NOTQUAL_BODY+'"]').each(function(){
  612. $(this).attr('bgcolor',$(this).attr('bgcolor').replace(NOTQUAL_BODY, NEW_NOTQUAL_BODY));
  613. });
  614.  
  615. var requester_IDs = new Array();
  616. $parent_tables = $('table[width="100%"][cellspacing="0"][cellpadding="0"][border="0"][height="100%"]');
  617. $parent_tables.each(function()
  618. {
  619. var $requester_ID_link = $(this).find('a[href^="'+HIT_GROUPS_BASE_LINK+'"]').attr('href');
  620. requester_IDs.push($requester_ID_link.replace(HIT_GROUPS_BASE_LINK,''));
  621. });
  622.  
  623. // code snippet from http://stackoverflow.com/questions/5381621/jquery-function-to-get-all-unique-elements-from-an-array
  624. requester_IDs = requester_IDs.filter(function(itm,i,a)
  625. {
  626. return i==a.indexOf(itm);
  627. });
  628. // end snippet
  629.  
  630. var requester_IDs_csv = '';
  631. for (var i = 0; i < requester_IDs.length-1; i++)
  632. {
  633. requester_IDs_csv += requester_IDs[i] + ','
  634. }
  635. requester_IDs_csv += requester_IDs[i];
  636.  
  637. color_code($parent_tables, API_MULTI_ATTRS_URL, requester_IDs_csv);
  638. //});