JR mturk timer warning

Script will warn you at specific times left for your hit. The times can be set in the options menu.

当前为 2018-01-24 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name JR mturk timer warning
  3. // @version 0.7.9
  4. // @namespace https://greasyfork.org/users/6406
  5. // @description Script will warn you at specific times left for your hit. The times can be set in the options menu.
  6. // @author John Ramirez (JohnnyRS)
  7. // @include http*://*.mturk.com/mturk/continue*
  8. // @include http*://*.mturk.com/mturk/accept*
  9. // @include http*://*.mturk.com/mturk/preview*
  10. // @include http*://*.mturk.com/mturk/myhits*
  11. // @include http*://*.mturk.com/mturk/submit*
  12. // @include http*://worker.mturk.com/projects/*
  13. // @exclude *mturk.com/*HITMONITOR*
  14. // @require http://code.jquery.com/jquery-2.1.4.min.js
  15. // @grant GM_getValue
  16. // @grant GM_setValue
  17. // ==/UserScript==
  18.  
  19. // Warns you with a voice, alarm or colors on the amount of time left for the current hit. You can set your own options
  20. // in the menu at top. There is a male and female voice for the warning. You can turn off the warnings and color.
  21. // the options are saved so you don't have to set it again. You can stop it saving options for the current hit if
  22. // you just want changes for the hit you are on.
  23.  
  24. var gSeconds = 0, gElapsedSeconds = 0, gWorking = false, gDoNotSpeak = false, gVolume = 1, intervalVar=null, gNewSite=false, gSpeech=new SpeechSynthesisUtterance();
  25. var gOptionsDefault = {"status":["On",0],"voice":["female",0],"alarm":["Off",0],"color":["On",0],"firstSpeak":["On",0]};
  26. var gOptionTimesDefault = {"60":["Off",0],"30":["On",0],"20":["Off",0],"10":["Off",0],"5":["On",0],"1":["On",0],"30s":["On",0],"every1":["off",0],
  27. "every5":["off",0],"every10":["off",0]};
  28. var gWarningTimes = {"60":false,"30":false,"20":false,"10":false,"5":false,"1":false,"30s":false,"every1":false,"every5":false,
  29. "every10":false};
  30. var gHtmlColors = ["FF0000","FF3322","FF6633","FFAA39","FFCCCC","FFEFEC","FFEFCC","EEEFCC","CCCCBB","CCCCBF","CCCCCC","CCCCDD","CCCCDF","CCCCEE","CCCCEF","CCDDFF","DDDDFF","EEEEFF","EEEEF9","EEEEF6","FFFFF2","FFFFF5","FFFFF8","FFFFFF"];
  31.  
  32. var f60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20hour%20left%20-%20Laura.mp3");
  33. var m60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20hour%20left%20-%20Paul.mp3");
  34. var a60MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2060%20minutes%20left.mp3");
  35. var f30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20minutes%20left%20-%20laura.mp3");
  36. var m30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20minutes%20left%20-%20Paul.mp3");
  37. var a30MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2030%20minutes%20left.mp3");
  38. var f20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2020%20minutes%20left%20-%20laura.mp3");
  39. var m20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2020%20minutes%20left%20-%20Paul.mp3");
  40. var a20MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2020%20minutes%20left.mp3");
  41. var f10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2010%20minutes%20left%20-%20Laura.mp3");
  42. var m10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2010%20minutes%20left%20-%20Paul.mp3");
  43. var a10MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2010%20minutes%20left.mp3");
  44. var f5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%205%20minutes%20left%20-%20Laura.mp3");
  45. var m5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%205%20minutes%20left%20-%20Paul.mp3");
  46. var a5MinutesLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%205%20minutes%20left.mp3");
  47. var f1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20minute%20left%20-%20Laura.mp3");
  48. var m1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%201%20minute%20left%20-%20Paul.mp3");
  49. var a1MinuteLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%201%20minute%20left.mp3");
  50. var f30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20seconds%20left%20-%20Laura.mp3");
  51. var m30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/You%20have%20less%20than%2030%20seconds%20left%20-%20Paul.mp3");
  52. var a30SecondsLeft = new Audio("http://www.allbyjohn.com/sounds/Alarm%2030%20seconds%20left.mp3");
  53. var fTesting = new Audio("http://www.allbyjohn.com/sounds/This%20is%20just%20a%20test%20of%20this%20warning%20system%20-%20Laura.mp3");
  54. var mTesting = new Audio("http://www.allbyjohn.com/sounds/This%20is%20just%20a%20test%20of%20this%20warning%20system%20-%20Paul.mp3");
  55. var g60MinutesLeft = null, g30MinutesLeft = null, g20MinutesLeft = null, g10MinutesLeft = null, g5MinutesLeft = null, g1MinutesLeft = null,
  56. g30SecondsLeft = null, gTesting = null, gOptions = null, gOptionTimes = null, gVoices = null;
  57.  
  58. function defaultFillIn(data,defaultData) {
  59. if (!data) return null; var returnData = data;
  60. for (var key in defaultData) { if (!(key in returnData)) returnData[key] = defaultData[key]; }
  61. return returnData;
  62. }
  63. function loadSettings() {
  64. var loadedOptions = JSON.parse(GM_getValue("JR_WN_options",JSON.stringify(gOptionsDefault)));
  65. var loadedOptionTimes = JSON.parse(GM_getValue("JR_WN_optionTimes",JSON.stringify(gOptionTimesDefault)));
  66. gOptions = defaultFillIn(loadedOptions,gOptionsDefault);
  67. gOptionTimes = defaultFillIn(loadedOptionTimes,gOptionTimesDefault);
  68. }
  69. function saveSettings() {
  70. GM_setValue("JR_WN_options",JSON.stringify(gOptions));
  71. GM_setValue("JR_WN_optionTimes",JSON.stringify(gOptionTimes));
  72. }
  73. function speakThisNow(thisText,gender) {
  74. if('speechSynthesis' in window){
  75. var thisVoice = (gender) ? ((gender.toLowerCase()=="male") ? gVoices[0] : gVoices[1]) : gVoices[0];
  76. gSpeech.lang = 'en-US';
  77. gSpeech.volume = gVolume;
  78. gSpeech.voice = thisVoice;
  79. gSpeech.text = thisText;
  80. window.speechSynthesis.speak(gSpeech);
  81. }
  82. }
  83. function convertTimeToSeconds(hours,minutes,seconds,days,weeks) {
  84. var totalSeconds = seconds + ((minutes) ? (minutes*60) : 0) + ((hours) ? (hours*3600) : 0) +
  85. ((days) ? (days*86400) : 0) + ((weeks) ? (weeks*604800) : 0);
  86. return totalSeconds;
  87. }
  88. function pad(number, length) {
  89. var str = '' + number;
  90. while (str.length < length) {
  91. str = '&nbsp;' + str;
  92. }
  93. return str;
  94. }
  95. (function($){ $.fn.disableSelection = function() { return this.attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false); }; })(jQuery);
  96. function createDiv(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<div>').html(inner); }
  97. function createSpan(theHtml) { var inner = (theHtml) ? theHtml : ""; return $('<span>').html(inner); }
  98. function createMyElement(elementName,theClass,theId,theStyle,theText) {
  99. var theElement = document.createElement(elementName);
  100. if (theClass) theElement.className = theClass;
  101. if (theId) theElement.id = theId;
  102. if (theStyle) theElement.setAttribute("style",theStyle);
  103. if (theText) theElement.innerHTML = theText;
  104. return theElement;
  105. }
  106. function createButton(theClass,theId,theValue,theName,theStyle) {
  107. var theButton = createMyElement("input",theClass,theId,theStyle);
  108. theButton.type = "button";
  109. if (theValue) theButton.value = theValue;
  110. if (theName) theButton.name = theName;
  111. return theButton;
  112. }
  113. function createCheckbox(theClass,theId,theValue,theName,theStyle) {
  114. var theCheckbox = createMyElement("input",theClass,theId,theStyle);
  115. theCheckbox.value = theValue;
  116. theCheckbox.type = "checkbox";
  117. if (theName) theCheckbox.name = theName;
  118. return theCheckbox;
  119. }
  120. function createTextInput(theClass,theId,theValue,theName,theStyle) {
  121. var theInput = createMyElement("input",theClass,theId,theStyle);
  122. theInput.type = "text";
  123. if (theValue) theInput.value = theValue;
  124. if (theName) theInput.name = theName;
  125. return theInput;
  126. }
  127. function setUpVoices(gender) {
  128. if (gender == "Female") {
  129. g60MinutesLeft = f60MinutesLeft; g30MinutesLeft = f30MinutesLeft; g20MinutesLeft = f20MinutesLeft; g10MinutesLeft = f10MinutesLeft;
  130. g5MinutesLeft = f5MinutesLeft; g1MinuteLeft = f1MinuteLeft; g30SecondsLeft = f30SecondsLeft; gTesting = fTesting;
  131. } else if (gender == "Male") {
  132. g60MinutesLeft = m60MinutesLeft; g30MinutesLeft = m30MinutesLeft; g20MinutesLeft = m20MinutesLeft; g10MinutesLeft = m10MinutesLeft;
  133. g5MinutesLeft = m5MinutesLeft; g1MinuteLeft = m1MinuteLeft; g30SecondsLeft = m30SecondsLeft; gTesting = mTesting;
  134. } else {
  135. g60MinutesLeft = a60MinutesLeft; g30MinutesLeft = a30MinutesLeft; g20MinutesLeft = a20MinutesLeft; g10MinutesLeft = a10MinutesLeft;
  136. g5MinutesLeft = a5MinutesLeft; g1MinuteLeft = a1MinuteLeft; g30SecondsLeft = a30SecondsLeft; gTesting = a30SecondsLeft;
  137. }
  138. }
  139. function setColor(theTimeLeft) {
  140. var theColor = "FFFFFF";
  141. if (theTimeLeft<30) theColor = gHtmlColors[0]; // less than 30 seconds
  142. else if (theTimeLeft<60) theColor = gHtmlColors[1]; // less than 1 minute
  143. else if (theTimeLeft<600) {
  144. theColor = gHtmlColors[Math.ceil(theTimeLeft/60)]; // less than 10 minutes
  145. }
  146. else if (theTimeLeft<1200) {
  147. theColor = gHtmlColors[Math.ceil((theTimeLeft-600)/120)+10]; // less than 20 minutes
  148. }
  149. else if (theTimeLeft<1800) {
  150. theColor = gHtmlColors[Math.ceil((theTimeLeft-1200)/240)+15]; // less than 30 minutes
  151. }
  152. else if (theTimeLeft<2100) theColor = gHtmlColors[20];
  153. else if (theTimeLeft<2400) theColor = gHtmlColors[21];
  154. else if (theTimeLeft<3000) theColor = gHtmlColors[22];
  155. else if (theTimeLeft<2600) theColor = gHtmlColors[23];
  156. if (gNewSite) $("#MainContent").css("background-color","#"+theColor);
  157. else document.getElementsByTagName("form")[1].style.backgroundColor = "#"+theColor;
  158. }
  159. function timeLeft() {
  160. theTime = document.getElementById("theTime");
  161. if (theTime) {
  162. var theSplit = theTime.innerHTML.split(":");
  163. hours = parseInt(theSplit[0]);
  164. minutes = parseInt(theSplit[1]);
  165. seconds = parseInt(theSplit[2]);
  166. minutes += hours * 60;
  167. gElapsedSeconds = seconds + (minutes * 60);
  168. var timeLeftMinutes = Math.floor(gSeconds/60) - minutes - 1;
  169. document.getElementById("timeLeftDiv").innerHTML = "Time Left: " + timeLeftMinutes + " Minutes : " + (60-seconds) + " Seconds";
  170. return gSeconds - gElapsedSeconds;
  171. } else return null;
  172. }
  173. function warning(theSound,theTime) {
  174. theSound.volume = gVolume;
  175. theSound.play();
  176. gWarningTimes[theTime] = true;
  177. }
  178. function checkTimes(announceNow) {
  179. var timeLeftSeconds = timeLeft();
  180. var timeLeftMinutes = Math.floor(timeLeftSeconds/60);
  181.  
  182.  
  183. if (timeLeftSeconds) {
  184. if (timeLeftSeconds<=30) {
  185. if (gOptionTimes["30s"][0] == "On" && !gWarningTimes["30s"]) warning(g30SecondsLeft,"30s");
  186. } else if (timeLeftSeconds<=60) {
  187. if (gOptionTimes["1"][0] == "On" && !gWarningTimes["1"]) warning(g1MinuteLeft,"1");
  188. } else if (timeLeftMinutes<5 && (timeLeftMinutes>3 || announceNow)) {
  189. if (gOptionTimes["5"][0] == "On" && (!gWarningTimes["5"] || announceNow))
  190. if (gElapsedSeconds>185 || announceNow) warning(g5MinutesLeft,"5");
  191. } else if (timeLeftMinutes<10 && (timeLeftMinutes>7 || announceNow)) {
  192. if (gOptionTimes["10"][0] == "On" && (!gWarningTimes["10"] || announceNow))
  193. if (gElapsedSeconds>185 || announceNow) warning(g10MinutesLeft,"10");
  194.  
  195. } else if (timeLeftMinutes<20 && (timeLeftMinutes>15 || announceNow)) {
  196. if (gOptionTimes["20"][0] == "On" && (!gWarningTimes["20"] || announceNow))
  197. if (gElapsedSeconds>305 || announceNow) warning(g20MinutesLeft,"20");
  198. } else if (timeLeftMinutes<30 && (timeLeftMinutes>24 || announceNow)) {
  199. if (gOptionTimes["30"][0] == "On" && (!gWarningTimes["30"] || announceNow))
  200. if (gElapsedSeconds>365 || announceNow) warning(g30MinutesLeft,"30");
  201. } else if (timeLeftMinutes<60 && (timeLeftMinutes>53 || announceNow)) {
  202. if (gOptionTimes["60"][0] == "On" && (!gWarningTimes["60"] || announceNow))
  203. if (gElapsedSeconds>425 || announceNow) warning(g60MinutesLeft,"60");
  204. }
  205. if (gOptions.color[0] == "On") setColor(timeLeftSeconds);
  206. else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
  207. }
  208. }
  209. function setOptions() {
  210. gOptions.status[0] = document.getElementById("warningOption").getAttribute("currentValue");
  211. gOptions.status[1] = document.getElementById("warningOption").getAttribute("valueIndex");
  212. gOptions.voice[0] = document.getElementById("warningVoiceOptions").getAttribute("currentValue");
  213. gOptions.voice[1] = document.getElementById("warningVoiceOptions").getAttribute("valueIndex");
  214. gOptions.alarm[0] = document.getElementById("warningAlarmOptions").getAttribute("currentValue");
  215. gOptions.alarm[1] = document.getElementById("warningAlarmOptions").getAttribute("valueIndex");
  216. gOptions.color[0] = document.getElementById("warningColorOptions").getAttribute("currentValue");
  217. gOptions.color[1] = document.getElementById("warningColorOptions").getAttribute("valueIndex");
  218. gOptions.firstSpeak[0] = document.getElementById("speakStartOption").getAttribute("currentValue");
  219. gOptions.firstSpeak[1] = document.getElementById("speakStartOption").getAttribute("valueIndex");
  220. gOptionTimes["60"][0] = document.getElementById("1HourOptions").getAttribute("currentValue");
  221. gOptionTimes["60"][1] = document.getElementById("1HourOptions").getAttribute("valueIndex");
  222. gOptionTimes["30"][0] = document.getElementById("30MinutesOptions").getAttribute("currentValue");
  223. gOptionTimes["30"][1] = document.getElementById("30MinutesOptions").getAttribute("valueIndex");
  224. gOptionTimes["20"][0] = document.getElementById("20MinutesOptions").getAttribute("currentValue");
  225. gOptionTimes["20"][1] = document.getElementById("20MinutesOptions").getAttribute("valueIndex");
  226. gOptionTimes["10"][0] = document.getElementById("10MinutesOptions").getAttribute("currentValue");
  227. gOptionTimes["10"][1] = document.getElementById("10MinutesOptions").getAttribute("valueIndex");
  228. gOptionTimes["5"][0] = document.getElementById("5MinutesOptions").getAttribute("currentValue");
  229. gOptionTimes["5"][1] = document.getElementById("5MinutesOptions").getAttribute("valueIndex");
  230. gOptionTimes["1"][0] = document.getElementById("1MinuteOptions").getAttribute("currentValue");
  231. gOptionTimes["1"][1] = document.getElementById("1MinuteOptions").getAttribute("valueIndex");
  232. gOptionTimes["30s"][0] = document.getElementById("30SecondsOptions").getAttribute("currentValue");
  233. gOptionTimes["30s"][1] = document.getElementById("30SecondsOptions").getAttribute("valueIndex");
  234. gOptionTimes.every1[0] = document.getElementById("every1").getAttribute("currentValue");
  235. gOptionTimes.every1[1] = document.getElementById("every1").getAttribute("valueIndex");
  236. gOptionTimes.every5[0] = document.getElementById("every5").getAttribute("currentValue");
  237. gOptionTimes.every5[1] = document.getElementById("every5").getAttribute("valueIndex");
  238. gOptionTimes.every10[0] = document.getElementById("every10").getAttribute("currentValue");
  239. gOptionTimes.every10[1] = document.getElementById("every10").getAttribute("valueIndex");
  240. if (gOptions.voice[0] != "Off") setUpVoices(gOptions.voice[0]);
  241. else if (gOptions.alarm[0] != "Off") setUpVoices();
  242. if (gWorking) {
  243. if (gOptions.color[0] == "On" && gOptions.status[0] == "On") setColor(timeLeft());
  244. else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
  245. if (!gDoNotSpeak && gOptions.status[0] == "On" && (gOptions.voice[0] != "Off" || gOptions.alarm[0] != "Off")) checkTimes(true);
  246. } else if (gOptions.status[0] == "On" && gOptions.voice[0] != "Off" && !gDoNotSpeak) {
  247. if (gNewSite) speakThisNow("This is a test of this warning system.",gOptions.voice[0]); else gTesting.play();
  248. }
  249. if (document.getElementById("warningOptionsSave").checked) saveSettings();
  250. }
  251. function createSpanOptions(theNode,theOptions) {
  252. var theId = "", theText = "", theValues = [], theStatus = "", replaceWith="";
  253. for (var i=0,len=theOptions.length; i<len; i++) {
  254. theId = theOptions[i][0];
  255. theText = theOptions[i][1];
  256. theValues = theOptions[i][2];
  257. theStatus = theValues[theOptions[i][3]].substr(0,1);
  258. replaceWith = theValues[theOptions[i][3]].replace(theStatus,"");
  259. theOption = createMyElement("span","myOwnSpan",theId,
  260. "cursor:pointer; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;",
  261. theText.replace("$",replaceWith));
  262. if (theStatus=="-") theOption.style.color = "#FF0000";
  263. else theOption.style.color = "#006600";
  264. theOption.setAttribute("theValues",JSON.stringify(theValues));
  265. theOption.setAttribute("valueIndex",theOptions[i][3]);
  266. theOption.setAttribute("theText",theText);
  267. theOption.setAttribute("currentValue",replaceWith);
  268. theNode.appendChild(document.createTextNode(" "));
  269. theNode.appendChild(theOption);
  270. theOption.onmousemove = function(e) {
  271. e.preventDefault();
  272. e.stopPropagation();
  273. return false;
  274. };
  275. theOption.onclick = function() {
  276. gDoNotSpeak = true;
  277. var theValues = JSON.parse(this.getAttribute("theValues"));
  278. var theIndex = parseInt(this.getAttribute("valueIndex"));
  279. var theText = this.getAttribute("theText");
  280. theIndex = (theIndex < theValues.length-1) ? theIndex+1 : 0;
  281. this.setAttribute("valueIndex",theIndex);
  282. var theStatus = theValues[theIndex].substr(0,1);
  283. var replaceWith = theValues[theIndex].replace(theStatus,"");
  284. this.innerHTML = theText.replace("$",replaceWith);
  285. this.setAttribute("currentValue",replaceWith);
  286. if (theStatus=="-") this.style.color = "#FF0000";
  287. else this.style.color = "#006600";
  288. if (this.id == "warningAlarmOptions" && replaceWith == "On") {
  289. document.getElementById("warningVoiceOptions").setAttribute("currentValue","Off");
  290. document.getElementById("warningVoiceOptions").setAttribute("valueIndex","1");
  291. document.getElementById("warningVoiceOptions").innerHTML = "[ Voice: Off ]";
  292. document.getElementById("warningVoiceOptions").style.color = "#FF0000";
  293. } else if (this.id == "warningVoiceOptions" && replaceWith != "Off") {
  294. document.getElementById("warningAlarmOptions").setAttribute("currentValue","Off");
  295. document.getElementById("warningAlarmOptions").setAttribute("valueIndex","0");
  296. document.getElementById("warningAlarmOptions").innerHTML = "[ Alarm: Off ]";
  297. document.getElementById("warningAlarmOptions").style.color = "#FF0000";
  298. gDoNotSpeak = false;
  299. } else if (this.id == "warningOption" && replaceWith != "Off") {
  300. gDoNotSpeak = false;
  301. } else if (this.id == "speakStartOption") { gDoNotSpeak = true; sayTimeLeft(); }
  302. setOptions();
  303. };
  304. }
  305. }
  306. function toggleOptionsMenu() {
  307. var rect = $("#JRTimerOptions").offset();
  308. toggleOptionsMenu.display = toggleOptionsMenu.display || false;
  309. toggleOptionsMenu.display = !toggleOptionsMenu.display;
  310. if (toggleOptionsMenu.display) $("#JR_TimerWOptionsMenu").css("top",rect.top - $(window).scrollTop() + 18).show();
  311. else $("#JR_TimerWOptionsMenu").hide();
  312. }
  313. function showOptionsNew(menuNode) {
  314. var theOptionsContainer = createMyElement("div","myOwnDiv","warningOptionsContainer", "padding: 11px 1px 0 7px;");
  315. var theOptionsControl = createMyElement("div","myOwnDiv","warningOptionsController","");
  316. var spanWarningOptions = [ ["warningOption","[ Status: $ ]",["+On","-Off"],gOptions.status[1]], ["warningVoiceOptions","[ Voice: $ ]",["+Female","-Off","+Male"],
  317. gOptions.voice[1]], ["warningAlarmOptions","[ Alarm: $ ]",["-Off","+On"],gOptions.alarm[1]], ["warningColorOptions","[ Color: $ ]",["+On","-Off"],gOptions.color[1]]];
  318. theOptionsControl.appendChild( createMyElement("span","myOwnSpan","","color:blue; font-weight:bold;","Time Left Warning: ") );
  319. createSpanOptions(theOptionsControl,spanWarningOptions);
  320. theOptionsControl.appendChild(createMyElement("br"));
  321. theOptionsControl.appendChild( createMyElement("span","myOwnSpan","","color:blue; font-weight:bold;","Warn at: ") );
  322. var spanTimeOptions = [ ["30SecondsOptions","[30 seconds]",["+On","-Off"],gOptionTimes["30s"][1]], ["1MinuteOptions","[1 minute]",["+On","-Off"],gOptionTimes["1"][1]],
  323. ["5MinutesOptions","[5 minutes]",["+On","-Off"],gOptionTimes["5"][1]], ["10MinutesOptions","[10 minutes]",["-Off","+On"],gOptionTimes["10"][1]],
  324. ["20MinutesOptions","[20 minutes]",["-Off","+On"],gOptionTimes["20"][1]], ["30MinutesOptions","[30 minutes]",["+On","-Off"],gOptionTimes["30"][1]],
  325. ["1HourOptions","[1 hour]",["-Off","+On"],gOptionTimes["60"][1]] ];
  326. createSpanOptions(theOptionsControl,spanTimeOptions);
  327. theOptionsControl.appendChild(createMyElement("br"));
  328. theOptionsControl.appendChild( createMyElement("span","myOwnSpan","","color:blue; font-weight:bold;","Warn for: ") );
  329. var spanEveryOptions = [ ["every1","[Every&nbsp;Minute]",["-Off","+On"],gOptionTimes.every1[1]],
  330. ["every5","[Every&nbsp;Five&nbsp;Minutes]",["-Off","+On"],gOptionTimes.every5[1]],["every10","[Every&nbsp;10&nbsp;Minutes]",["-Off","+On"],gOptionTimes.every10[1]]];
  331. createSpanOptions(theOptionsControl,spanEveryOptions);
  332. theOptionsControl.appendChild(createMyElement("br"));
  333. var spanStartOptions = [ ["speakStartOption","[ Speak Time Left: $ ]",["+On","-Off"],gOptions.firstSpeak[1]] ];
  334. theOptionsControl.appendChild( createMyElement("span","myOwnSpan","","color:blue; font-weight:bold;","At Beginning Options: ") );
  335. createSpanOptions(theOptionsControl,spanStartOptions);
  336. theOptionsControl.appendChild(createMyElement("br"));
  337. theOptionsControl.appendChild(document.createTextNode("Click on text above to change options."));
  338. theOptionsControl.appendChild(createMyElement("br"));
  339. var theOptionsSave = createCheckbox("myOwnCheckBox","warningOptionsSave","save Me","","margin-left:20px; height:10px;");
  340. theOptionsSave.checked = true;
  341. theOptionsSave.onclick = function() { if (theOptionsSave.checked) saveSettings(); };
  342. theOptionsControl.appendChild(theOptionsSave);
  343. theOptionsControl.appendChild(document.createTextNode(" Permanently Save Options"));
  344. var volumeLower = createMyElement("span","myOwnSpan","lowerVolumeControl",
  345. "cursor: pointer; margin-left:20px; margin-right:10px; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;","<-");
  346. theOptionsControl.appendChild(volumeLower);
  347. var volumeLevelText = createMyElement("span","myOwnSpan","theVolumeText",
  348. "cursor:pointer; display: inline-block; width:125px; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;",
  349. " Volume Level: 100 ");
  350. theOptionsControl.appendChild(volumeLevelText);
  351. var volumeHigher = createMyElement("span","myOwnSpan","lowerVolumeControl",
  352. "cursor: pointer; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;","->");
  353. theOptionsControl.appendChild(volumeHigher);
  354. volumeLower.onclick = function() {
  355. gVolume = (gVolume<0.1) ? 0 : (gVolume-0.1);
  356. document.getElementById("theVolumeText").innerHTML = " Volume Level: " + pad(Math.round(gVolume*100),3);
  357. speakThisNow("Hi",gOptions.voice[0]);
  358. };
  359. volumeHigher.onclick = function() {
  360. gVolume = (gVolume>0.9) ? 1 : (gVolume+0.1);
  361. document.getElementById("theVolumeText").innerHTML = " Volume Level: " + pad(Math.round(gVolume*100),3);
  362. speakThisNow("Hi",gOptions.voice[0]);
  363. };
  364. theOptionsControl.appendChild(createMyElement("br"));
  365. theOptionsControl.appendChild( createMyElement("div","myOwnDiv","myCloseMenu","box-sizing:content-box; font-size:12px; background-color:#eeeeee; " +
  366. "border:3px groove darkgrey; padding:0px 2px; margin-left:45px; margin-top:5px; width:150px;","Close Menu" ));
  367. theOptionsControl.appendChild(createMyElement("br"));
  368. theOptionsContainer.appendChild(theOptionsControl);
  369. $(menuNode).append($(theOptionsContainer)[0]);
  370. $("#myCloseMenu").disableSelection().click(function() { toggleOptionsMenu(); });
  371. }
  372. function showOptions(targetNode,targetAction) {
  373. var floater = (targetAction=="append") ? " margin: 0 auto;" : " margin: 0 auto;";
  374. var theOptionsContainer = createMyElement("div","myOwnSpan","warningOptionsContainer",
  375. "background-color:#D8FCFB; text-align:center; padding: 0; width:60%; border: 2px solid black;" + floater);
  376. var theOptionsToggle = createMyElement("span","myOwnSpan","warningOptionsToggle","margin:0; padding:0 0 2px 0; background-color:#696969;" +
  377. "color: Aqua; font-size:10px; cursor:default;", "Click here for Time Left Warning options.");
  378. var theOptionsControl = createMyElement("div","myOwnDiv","warningOptionsController","display:none;");
  379. var theOptionsSave = createCheckbox("myOwnCheckBox","warningOptionsSave","save Me","","margin-left:20px; height:10px;");
  380. theOptionsSave.checked = true;
  381. theOptionsSave.onclick = function() { if (theOptionsSave.checked) saveSettings(); };
  382. var spanWarningOptions = [ ["warningOption","[ Status: $ ]",["+On","-Off"],gOptions.status[1]], ["warningVoiceOptions","[ Voice: $ ]",["+Female","-Off","+Male"],gOptions.voice[1]],
  383. ["warningAlarmOptions","[ Alarm: $ ]",["-Off","+On"],gOptions.alarm[1]], ["warningColorOptions","[ Color: $ ]",["+On","-Off"],gOptions.color[1]]];
  384. theOptionsControl.appendChild(document.createTextNode("Time Left Warning:"));
  385. createSpanOptions(theOptionsControl,spanWarningOptions);
  386. theOptionsControl.appendChild(theOptionsSave);
  387. theOptionsControl.appendChild(document.createTextNode(" Permanently Save Options"));
  388. theOptionsControl.appendChild(createMyElement("br"));
  389. theOptionsControl.appendChild(document.createTextNode("Warn at: "));
  390. var spanTimeOptions = [ ["30SecondsOptions","[30 seconds]",["+On","-Off"],gOptionTimes["30s"][1]], ["1MinuteOptions","[1 minute]",["+On","-Off"],gOptionTimes["1"][1]],
  391. ["5MinutesOptions","[5 minutes]",["+On","-Off"],gOptionTimes["5"][1]], ["10MinutesOptions","[10 minutes]",["-Off","+On"],gOptionTimes["10"][1]],
  392. ["20MinutesOptions","[20&nbsp;minutes]",["-Off","+On"],gOptionTimes["20"][1]], ["30MinutesOptions","[30&nbsp;minutes]",["+On","-Off"],gOptionTimes["30"][1]],
  393. ["1HourOptions","[1&nbsp;hour]",["-Off","+On"],gOptionTimes["60"][1]]];
  394. createSpanOptions(theOptionsControl,spanTimeOptions);
  395. theOptionsControl.appendChild(createMyElement("br"));
  396. theOptionsControl.appendChild(document.createTextNode("Click on text above to change options."));
  397. var volumeLower = createMyElement("span","myOwnSpan","lowerVolumeControl",
  398. "cursor: pointer; margin-left:20px; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;","<-");
  399. theOptionsControl.appendChild(volumeLower);
  400. var volumeLevelText = createMyElement("span","myOwnSpan","theVolumeText",
  401. "cursor:pointer; display: inline-block; width:110px; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;",
  402. " Volume Level: 100 ");
  403. theOptionsControl.appendChild(volumeLevelText);
  404. var volumeHigher = createMyElement("span","myOwnSpan","lowerVolumeControl",
  405. "cursor: pointer; -moz-user-select: -moz-none; -khtml-user-select: none; -webkit-user-select: none;","->");
  406. theOptionsControl.appendChild(volumeHigher);
  407. volumeLower.onclick = function() {
  408. gVolume = (gVolume<0.1) ? 0 : (gVolume-0.1);
  409. document.getElementById("theVolumeText").innerHTML = " Volume Level: " + pad(Math.round(gVolume*100),3);
  410. };
  411. volumeHigher.onclick = function() {
  412. gVolume = (gVolume>0.9) ? 1 : (gVolume+0.1);
  413. document.getElementById("theVolumeText").innerHTML = " Volume Level: " + pad(Math.round(gVolume*100),3);
  414. };
  415. theOptionsToggle.onclick = function() {
  416. var theDisplay = theOptionsControl.style.display;
  417. theOptionsControl.style.display = (theDisplay == "none") ? "block" : "none";
  418. if (theOptionsControl.style.display == "none") this.innerHTML = "Click here for Time Left Warning options menu.";
  419. else this.innerHTML = "Click here to hide the options menu";
  420. };
  421. theOptionsContainer.appendChild(theOptionsToggle);
  422. theOptionsContainer.appendChild(theOptionsControl);
  423. if (targetAction=="append") targetNode.append(theOptionsContainer);
  424. else targetNode.before(theOptionsContainer);
  425. }
  426. function getTimeLeft(theTime) {
  427. if (theTime) {
  428. var tempArray = (theTime.indexOf("second") != -1) ? theTime.split("second")[0].trim().split(" ") : null;
  429. var seconds = (tempArray) ? tempArray[tempArray.length-1] : "0";
  430. tempArray = (theTime.indexOf("minute") != -1) ? theTime.split("minute")[0].trim().split(" ") : null;
  431. var minutes = (tempArray) ? tempArray[tempArray.length-1] : "0";
  432. tempArray = (theTime.indexOf("hour") != -1) ? theTime.split("hour")[0].trim().split(" ") : null;
  433. var hours = (tempArray) ? tempArray[tempArray.length-1] : "0";
  434. tempArray = (theTime.indexOf("day") != -1) ? theTime.split("day")[0].trim().split(" ") : null;
  435. var days = (tempArray) ? tempArray[tempArray.length-1] : "0";
  436. tempArray = (theTime.indexOf("week") != -1) ? theTime.split("week")[0].trim().split(" ") : null;
  437. var weeks = (tempArray) ? tempArray[tempArray.length-1] : "0";
  438. return( {"weeks":weeks,"days":days,"hours":hours,"minutes":minutes,"seconds":seconds} );
  439. } else return null;
  440. }
  441. function timerLeftAlarms(theHours,theMinutes,theSeconds,voice) {
  442. var returnValue = "";
  443. if (timerLeftAlarms.last) {
  444. if (theHours===0 && theMinutes===0 && theSeconds>0) {
  445. if (theSeconds==30 && gOptionTimes["30s"][0] == "On")
  446. returnValue= (voice) ? "seconds" : "30seconds"; // 30second alarm should sound
  447. else returnValue="";
  448. }
  449. if (returnValue === "") {
  450. if (timerLeftAlarms.last.minutes != theMinutes) {
  451. if (gOptionTimes.every1[0] == "On") returnValue= (voice) ? "minutes" : "every"; // every 1 minute alarm should sound
  452. else if (gOptionTimes.every5[0] == "On" && theMinutes % 5 === 0)
  453. returnValue= (voice) ? "minutes" : "every"; // every 5 minute alarm should sound
  454. else if (gOptionTimes.every10[0] == "On" && theMinutes % 10 === 0)
  455. returnValue= (voice) ? "minutes" : "every"; // every 10 minute alarm should sound
  456. else if (theHours===0 && theMinutes===1 && theSeconds===0 && gOptionTimes["1"][0] == "On")
  457. returnValue= (voice) ? "minutes" : "oneminute"; // 1 minute alarm should sound
  458. else if (theHours===0 && theMinutes===5 && theSeconds===0 && gOptionTimes["5"][0] == "On")
  459. returnValue= (voice) ? "minutes" : "fiveminute"; // 5 minute alarm should sound
  460. else if (theHours===0 && theMinutes===10 && theSeconds===0 && gOptionTimes["10"][0] == "On")
  461. returnValue= (voice) ? "minutes" : "tenminute"; // 10 minute alarm should sound
  462. else if (theHours===0 && theMinutes===20 && theSeconds===0 && gOptionTimes["20"][0] == "On")
  463. returnValue= (voice) ? "minutes" : "twentyminute"; // 20 minute alarm should sound
  464. else if (theHours===0 && theMinutes===30 && theSeconds===0 && gOptionTimes["30"][0] == "On")
  465. returnValue= (voice) ? "minutes" : "thirtyminute"; // 30 minute alarm should sound
  466. else if (theHours===1 && theMinutes===0 && theSeconds===0 && gOptionTimes["60"][0] == "On")
  467. returnValue= (voice) ? "hours" : "sixtyminute"; // 60 minute alarm should sound
  468. }
  469. }
  470. } else returnValue = (gOptions.firstSpeak[0]=="On") ? "full" : "";
  471. timerLeftAlarms.last = {"hours":theHours,"minutes":theMinutes,"seconds":theSeconds};
  472. return returnValue;
  473. }
  474. function sayTimeLeft(format) {
  475. var thisTimerText = $(".completion-timer:first").text().trim(), thisFormat="";
  476. var theHours = Number(thisTimerText.split(":")[0]);
  477. var theMinutes = Number(thisTimerText.split(":")[1]);
  478. var theSeconds = Number(thisTimerText.split(":")[2]);
  479. if ( (thisFormat=timerLeftAlarms(theHours,theMinutes,theSeconds, (gOptions.alarm[0]=="On") ? false : true)) !== "") {
  480. if (thisFormat=="full") speakThisNow( "You have " + ((theHours>0) ? (theHours + ((theHours>1) ? (" Hours ") : " Hour ")) : "") +
  481. theMinutes + " Minutes" + theSeconds + " Seconds left",gOptions.voice[0]);
  482. else if (thisFormat=="minutes") speakThisNow( "You have " + ((theHours>0) ? (theHours + ((theHours>1) ? (" Hours ") : " Hour ")) : "") +
  483. theMinutes + ((theMinutes>1) ? " Minutes" : " Minute") + " Left",gOptions.voice[0]);
  484. else if (thisFormat=="seconds") speakThisNow( "You have " + theSeconds + " Seconds Left",gOptions.voice[0]);
  485. else {
  486. if (thisFormat=="30seconds") warning(g30SecondsLeft,"30s"); else if (thisFormat=="oneminute") warning(g1MinuteLeft,"1");
  487. else if (thisFormat=="fiveminute") warning(g5MinutesLeft,"5"); else if (thisFormat=="tenminute") warning(g10MinutesLeft,"10");
  488. else if (thisFormat=="twentyminute") warning(g20MinutesLeft,"20"); else if (thisFormat=="thirtyminute") warning(g30MinutesLeft,"30");
  489. else if (thisFormat=="sixtyminute") warning(g60MinutesLeft,"60"); else if (thisFormat=="every") warning(g10MinutesLeft,"10");
  490. }
  491. }
  492. if (gOptions.color[0] == "On") setColor(convertTimeToSeconds(theHours,theMinutes,theSeconds));
  493. else $("#MainContent").css("background-color","#FFFFFF");
  494. }
  495.  
  496. $(function() {
  497. if (window.location.href.indexOf("worker.mturk.com") != -1) {
  498. if('speechSynthesis' in window){
  499. gVoices = window.speechSynthesis.getVoices();
  500. window.speechSynthesis.onvoiceschanged = function() {
  501. gVoices = window.speechSynthesis.getVoices();
  502. };
  503. }
  504. gNewSite = true;
  505. loadSettings();
  506. setUpVoices();
  507. var newTimerNode = $(".completion-timer:first");
  508. if (newTimerNode.length && $(newTimerNode).closest("div").text().indexOf("Time Remaining") != -1) {
  509. if ($(".checkbox.m-y-0").length) {
  510. createSpan("Timer Options").css({"box-sizing":"content-box","font-size":"10px","background-color":"#eeeeee", "border":"2px groove darkgrey", "padding":"0px 4px","margin-left":"5px" }).attr('id', "JRTimerOptions").disableSelection()
  511. .click(function() { toggleOptionsMenu(); }).appendTo($(".checkbox.m-y-0:first"));
  512. } else {
  513. buttonPosition = $(".col-md-6.col-xs-12:first").find(".col-sm-8.col-xs-7");
  514. createDiv("Timer Options").css({"box-sizing":"content-box","float":"left","font-size":"10px","background-color":"#eeeeee", "border":"2px groove darkgrey", "padding":"0px 2px" }).attr('id', "JRTimerOptions")
  515. .disableSelection().click(function() { toggleOptionsMenu(); }).appendTo(buttonPosition);
  516. }
  517. createDiv("").css({"position":"fixed","width":"700px","height":"200px","top":"78px","right":"280px","float":"right",
  518. "background-color":"#eceadf","border":"3px solid #000"}).attr({"id":"JR_TimerWOptionsMenu"}).hide().appendTo("body");
  519. setTimeout( function() {
  520. intervalVar = setInterval( function(){
  521. sayTimeLeft();
  522. }, 1000);
  523. }, 1300);
  524. showOptionsNew($("#JR_TimerWOptionsMenu"));
  525. }
  526. } else {
  527. loadSettings();
  528. setUpVoices(gOptions.voice[0]);
  529. var timerTextNode = $(".title_orange_text:first");
  530. if (timerTextNode.length && timerTextNode.text().indexOf("Timer:") != -1) {
  531. gWorking = true;
  532. var weeks = 0, days = 0, hours = 0, minutes = 0;
  533. var theTime = $("#theTime");
  534. var timeLeftNode = createMyElement("div","myOwnDiv","timeLeftContainer","padding-left:20px; margin:0 auto;");
  535. $(theTime).closest("form").before($(timeLeftNode));
  536. var ofTime = timerTextNode[0].innerHTML.split("</span>")[1];
  537. ofTime = ofTime.split("<noscript>")[0].replace(/\s\s+/g," ").trim();
  538. var realOfTime = ofTime.replace("of ","").trim();
  539. var theTimeLeft = getTimeLeft(realOfTime);
  540. if (theTimeLeft) { console.log("realOfTime=" + realOfTime + " : theTimeLeft=" + JSON.stringify(theTimeLeft));
  541. days = parseInt(theTimeLeft.weeks*7);
  542. hours = parseInt(theTimeLeft.days*24) + parseInt(days*24);
  543. minutes = parseInt(theTimeLeft.hours*60) + parseInt(hours*60);
  544. gSeconds = parseInt(theTimeLeft.minutes*60) + parseInt(minutes*60);
  545. intervalVar = setInterval( function(){
  546. if (gOptions.status[0] == "On" && (gOptions.voice[0] != "Off" || gOptions.alarm[0] != "Off")) checkTimes();
  547. else if (gOptions.status[0] == "On") timeLeft();
  548. }, 4000);
  549. var theHitForm = ($(theTime).closest("form"))[0];
  550. var theTable = theHitForm.getElementsByTagName("table")[0];
  551. var theDiv = theHitForm.getElementsByTagName("div")[2];
  552. var theIframe = theHitForm.getElementsByTagName("iframe")[0];
  553. theTable.style.backgroundColor = "#FFFFFF";
  554. if (theDiv) theDiv.style.backgroundColor = "#FFFFFF";
  555. if (theIframe) theIframe.style.backgroundColor = "#FFFFFF";
  556. showOptions(timeLeftNode,"append");
  557. if (gOptions.color[0] == "On" && gOptions.status[0] == "On") setColor(timeLeft());
  558. else document.getElementsByTagName("form")[1].style.backgroundColor = "#FFFFFF";
  559. }
  560.  
  561. } else {
  562. var theAlertBox = document.getElementById("alertBox");
  563. var theErrorTitle = document.getElementsByClassName("error_title")[0];
  564. var beforeNode = (theErrorTitle) ? theErrorTitle.parentNode.parentNode.parentNode : (theAlertBox) ? theAlertBox : timerTextNode.parentNode.parentNode.parentNode;
  565. showOptions(beforeNode,"before");
  566. }
  567. }
  568. });