Created
March 24, 2018 02:58
-
-
Save cuylerstuwe/e82a1df02df2e16305c87480b6eeee77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name mTurk Title Bar Timer / Wage | |
// @author Cuyler Stuwe (salembeats) | |
// @namespace salembeats | |
// @version 45yoga | |
// @description Title bar timer/counter. Latest update: Fix for mTurk swapping a div to a span. | |
// @include https://www.mturk.com/mturk/preview?* | |
// @include https://www.mturk.com/mturk/accept?* | |
// @include https://www.mturk.com/mturk/continue?* | |
// @include https://www.mturk.com/mturk/return?* | |
// @include https://www.mturk.com/mturk/previewandaccept* | |
// @include https://worker.mturk.com/projects/* | |
// @icon https://i.imgur.com/Y68Qxdd.png | |
// @grant GM_setValue | |
// @grant GM_getValue | |
// ==/UserScript== | |
// Changing this to true will base wages on the total time passed since the tab has opened. | |
// False means wages are based on the total time that the tab has been in focus. | |
const ALWAYS_TICK_WAGE_TIMER = true; | |
// Whether to show the "Big Emoji", and configurable parameters related to its display (i.e., size and transparency). | |
const SHOW_BIG_EMOJI = true; | |
const BIG_EMOJI_SIZE = "250px"; | |
const BIG_EMOJI_OPACITY_ZERO_TO_ONE = "0.03"; | |
// No need to change this. One second is alwyas 1000ms. Just here to add meaning to some code. | |
const ONE_SECOND_IN_MS = 1000; | |
// The wage amounts. Change these to your liking. | |
const LOVE_WAGE_LOWER_LIMIT = 12.00; | |
const HAPPY_WAGE_LOWER_LIMIT = 8.00; | |
const OK_WAGE_LOWER_LIMIT = 6.00; | |
const SAD_WAGE_LOWER_LIMIT = 4.00; | |
const DISGUSTED_WAGE_LOWER_LIMIT = 0.00; | |
// The emojis. Change these to whatever you want to display for each wage range. | |
const LOVE_WAGE_EMOJI = "😍"; | |
const HAPPY_WAGE_EMOJI = "😀"; | |
const OK_WAGE_EMOJI = "😐"; | |
const SAD_WAGE_EMOJI = "😭"; | |
const DISGUSTED_WAGE_EMOJI = "💩"; | |
// Changing this to a bigger number will save you CPU cycles. | |
// Changing it to a smaller number will give you more timely data. | |
// Chrome automatically slows down the interval timers that this is based on in background tabs, though, so this is influenced strongly by that. | |
// TODO: Fix this so we can change to a different update rate without breaking "seconds visible / invisible" (I know how to do it, but haven't bothered writing it yet since it doesn't earn me money to do so.) | |
// The eventual fix will be to keep two separate stores of "seconds visible/invisible", managed by taking snapshots of the last time visibility status was changed. | |
const UPDATE_RATE_IN_MILLISECONDS = (ALWAYS_TICK_WAGE_TIMER ? (ONE_SECOND_IN_MS / 3) : ONE_SECOND_IN_MS); | |
var Utility = (function createUtility() { | |
const _scriptStartTime = new Date().getTime(); | |
const _fallbackHITStartTime = (unsafeWindow.pageTimes === undefined ? _scriptStartTime : unsafeWindow.pageTimes.beginPageLoad); | |
const _HITStartTime = (performance.timing === undefined ? _fallbackHitStartTime : performance.timing.navigationStart); | |
const _HITLoadTime =_scriptStartTime - _HITStartTime; | |
let _HITLoadTimeAccuracy; | |
if(performance.timing === undefined) { | |
if(unsafeWindow.pageTimes === undefined) { | |
_HITLoadTimeAccuracy = "low"; | |
} | |
else { | |
_HITLoadTimeAccuracy = "medium"; | |
} | |
} | |
else { | |
_HITLoadTimeAccuracy = "high"; | |
} | |
let _allContentLoadedTime; | |
let _allContentLoadedCallback = () => {}; | |
document.addEventListener('readystatechange', function(event) { | |
if(document.readyState === "complete") { | |
_allContentLoadedTime = performance.now(); | |
_allContentLoadedCallback(); | |
} | |
}); | |
var _secondsVisible = 0; | |
var _pauseOnInvisible = true; | |
function getHITStartTime() { | |
return _HITStartTime; | |
} | |
function getHITLoadTime() { | |
return _HITLoadTime; | |
} | |
function getAllContentLoadedTime() { | |
return _allContentLoadedTime; | |
} | |
function setAllContentLoadedCallback(newFn) { | |
_allContentLoadedCallback = newFn; | |
} | |
function getHITLoadTimeAccuracy() { | |
return _HITLoadTimeAccuracy; | |
} | |
function getSecondsSinceStartTime() { | |
return ( new Date().getTime() - _HITStartTime) / 1000; | |
} | |
function isWindowTopFrame() { | |
return (window === window.top); | |
} | |
function updateSecondsVisible() { | |
if(!document.hidden && document.hasFocus()) {incrementSecondsVisible();} | |
} | |
function incrementSecondsVisible() { | |
_secondsVisible += (UPDATE_RATE_IN_MILLISECONDS / ONE_SECOND_IN_MS); | |
} | |
function getSecondsVisible() { | |
return _secondsVisible; | |
} | |
function hourlyWageDollars(secondsPassed, rewardCents) { | |
return (rewardCents / secondsPassed) * 36; | |
} | |
function hmsToSeconds(hours, minutes, seconds) { | |
return hoursToSeconds(hours) + minutesToSeconds(minutes) + seconds; | |
} | |
function minutesToSeconds(minutes) { | |
return (minutes * 60); | |
} | |
function toMMSSString(secondsRemaining) { | |
let minutesRemaining = Math.floor(secondsRemaining/60); | |
let remainderSeconds = secondsRemaining - (minutesRemaining * 60); | |
const localeOptions = {useGrouping: false, minimumIntegerDigits: 2, maximumFractionDigits: 0}; | |
return minutesRemaining.toLocaleString(undefined,localeOptions) + ":" + remainderSeconds.toLocaleString(undefined,localeOptions); | |
} | |
function daysToSeconds(days) { | |
return (days * 86400); | |
} | |
function hoursToSeconds(hours) { | |
return (hours * 3600); | |
} | |
function secondsRemainingInHHMMSSCountdown(hhmmssString) { | |
let values = hhmmssString.split(":"); | |
return hmsToSeconds(Number(values[0]), Number(values[1]), Number(values[2])); | |
} | |
function secondsRemainingInMMSSCountdown(mmssString) { | |
let values = mmssString.split(":"); | |
let minutes = Number(values[0]); | |
let seconds = Number(values[1]); | |
return minutesToSeconds(minutes) + seconds; | |
} | |
function secondsRemainingInMMSSCountup(mmssString, totalSeconds) { | |
let countupValues = mmssString.split(":"); | |
let countupMinutes = Number(countupValues[0]); | |
let countupSeconds = Number(countupValues[1]); | |
let totalSecondsCounted = (countupMinutes * 60) + countupSeconds; | |
return totalSeconds - totalSecondsCounted; | |
} | |
function secondsRemainingInHHMMSSCountup(hhmmssString, totalSeconds) { | |
let values = hhmmssString.split(":"); | |
return totalSeconds - hmsToSeconds(Number(values[0]), Number(values[1]), Number(values[2])); | |
} | |
function secondsGoalForTargetWage(desiredCentsPerHour, jobCents) { | |
let desiredCentsPerSecond = desiredCentsPerHour / 3600; | |
return jobCents / desiredCentsPerSecond; | |
} | |
function secondsPassed(totalSeconds, secondsRemaining) { | |
return totalSeconds - secondsRemaining; | |
} | |
function dollarsToCents(dollars) { | |
return dollars * 100; | |
} | |
function askWorkerFrameWhetherSurvey() { | |
document.querySelector("iframe").contentWindow.postMessage({msg: "Are you a survey HIT?"}, "*"); | |
} | |
function disablePauseOnInvisible() { | |
_pauseOnInvisible = false; | |
} | |
function isPausingOnInvisible() { | |
return _pauseOnInvisible; | |
} | |
function highlightWageRange(cssSelectorString) { | |
document.querySelector(cssSelectorString).style = "font-weight: bold; text-decoration: underline;"; | |
} | |
function unhighlightWageRange(cssSelectorString) { | |
document.querySelector(cssSelectorString).style = "font-weight: normal; text-decoration: none;"; | |
} | |
return { | |
getSecondsSinceStartTime, | |
getHITStartTime, | |
isWindowTopFrame, | |
updateSecondsVisible, | |
getSecondsVisible, | |
hourlyWageDollars, | |
minutesToSeconds, | |
toMMSSString, | |
secondsRemainingInMMSSCountdown, | |
secondsRemainingInMMSSCountup, | |
secondsPassed, | |
dollarsToCents, | |
askWorkerFrameWhetherSurvey, | |
disablePauseOnInvisible, | |
isPausingOnInvisible, | |
hmsToSeconds, | |
secondsRemainingInHHMMSSCountdown, | |
secondsRemainingInHHMMSSCountup, | |
daysToSeconds, | |
secondsGoalForTargetWage, | |
highlightWageRange, | |
unhighlightWageRange, | |
getHITLoadTime, | |
getHITLoadTimeAccuracy, | |
getAllContentLoadedTime, | |
setAllContentLoadedCallback | |
}; | |
})(); | |
function updateActiveHITTabTimer(requesterName, secondsRemaining, rewardInCents) { | |
if( secondsRemaining <= 0 ){ | |
document.title = `EXPIRED - ${requesterName}`; return; | |
} | |
Utility.updateSecondsVisible(); | |
let newTitle = `${Utility.toMMSSString(secondsRemaining)} `; | |
let secondsPassed; | |
if(Utility.isPausingOnInvisible() && (!ALWAYS_TICK_WAGE_TIMER)) { | |
secondsPassed = Utility.getSecondsVisible(); | |
} | |
else { | |
secondsPassed = Utility.getSecondsSinceStartTime(); | |
} | |
document.querySelector("#timeWorkedSpan").innerText = Utility.toMMSSString(secondsPassed); | |
let hourlyWageDollars = Utility.hourlyWageDollars(secondsPassed, rewardInCents + (document.querySelector("#bonusWageCents").value !== "" ? Utility.dollarsToCents(document.querySelector("#bonusWageCents").value) : 0)); | |
if(hourlyWageDollars > LOVE_WAGE_LOWER_LIMIT) { | |
newTitle += LOVE_WAGE_EMOJI; | |
if(SHOW_BIG_EMOJI) { document.querySelector("#pageEmoji").innerText = LOVE_WAGE_EMOJI; } | |
Utility.highlightWageRange("#loveWageSpan"); | |
Utility.unhighlightWageRange("#happyWageSpan"); | |
Utility.unhighlightWageRange("#okWageSpan"); | |
Utility.unhighlightWageRange("#sadWageSpan"); | |
Utility.unhighlightWageRange("#disgustedWageSpan"); | |
} | |
else if(hourlyWageDollars > HAPPY_WAGE_LOWER_LIMIT) { | |
newTitle += HAPPY_WAGE_EMOJI; | |
if(SHOW_BIG_EMOJI) { document.querySelector("#pageEmoji").innerText = HAPPY_WAGE_EMOJI; } | |
Utility.unhighlightWageRange("#loveWageSpan"); | |
Utility.highlightWageRange("#happyWageSpan"); | |
Utility.unhighlightWageRange("#okWageSpan"); | |
Utility.unhighlightWageRange("#sadWageSpan"); | |
Utility.unhighlightWageRange("#disgustedWageSpan"); | |
} | |
else if(hourlyWageDollars > OK_WAGE_LOWER_LIMIT) { | |
newTitle += OK_WAGE_EMOJI; | |
if(SHOW_BIG_EMOJI) { document.querySelector("#pageEmoji").innerText = OK_WAGE_EMOJI; } | |
Utility.unhighlightWageRange("#loveWageSpan"); | |
Utility.unhighlightWageRange("#happyWageSpan"); | |
Utility.highlightWageRange("#okWageSpan"); | |
Utility.unhighlightWageRange("#sadWageSpan"); | |
Utility.unhighlightWageRange("#disgustedWageSpan"); | |
} | |
else if(hourlyWageDollars > SAD_WAGE_LOWER_LIMIT) { | |
newTitle += SAD_WAGE_EMOJI; | |
if(SHOW_BIG_EMOJI) { document.querySelector("#pageEmoji").innerText = SAD_WAGE_EMOJI; } | |
Utility.unhighlightWageRange("#loveWageSpan"); | |
Utility.unhighlightWageRange("#happyWageSpan"); | |
Utility.unhighlightWageRange("#okWageSpan"); | |
Utility.highlightWageRange("#sadWageSpan"); | |
Utility.unhighlightWageRange("#disgustedWageSpan"); | |
} | |
else if(hourlyWageDollars > DISGUSTED_WAGE_LOWER_LIMIT) { | |
newTitle += DISGUSTED_WAGE_EMOJI; | |
if(SHOW_BIG_EMOJI) { document.querySelector("#pageEmoji").innerText = DISGUSTED_WAGE_EMOJI; } | |
Utility.unhighlightWageRange("#loveWageSpan"); | |
Utility.unhighlightWageRange("#happyWageSpan"); | |
Utility.unhighlightWageRange("#okWageSpan"); | |
Utility.unhighlightWageRange("#sadWageSpan"); | |
Utility.highlightWageRange("#disgustedWageSpan"); | |
} | |
let pageLoadSpan = document.querySelector("#timeLostToPageLoad"); | |
if(pageLoadSpan.innerText.trim() === "") { | |
pageLoadSpan.innerText = Utility.getHITLoadTime().toFixed(0); | |
} | |
let fullPageLoadSpan = document.querySelector("#timeLostToFullPageLoad"); | |
if(fullPageLoadSpan.innerText.trim() === "") { | |
if(Utility.getAllContentLoadedTime()) { | |
fullPageLoadSpan.innerText = Utility.getAllContentLoadedTime().toFixed(0); | |
} | |
} | |
newTitle = newTitle + ` \$${hourlyWageDollars.toFixed(2)}/hr.`; | |
newTitle += ` ${requesterName}`; | |
if( !ALWAYS_TICK_WAGE_TIMER && ( !(document.visible && document.hasFocus()) ) ) { | |
newTitle += `(\$ timer paused)`; | |
} | |
document.title = newTitle; | |
} | |
function swapToExpanderBar() { | |
document.querySelector("#titleBarTimerBar").style.left = "-100%"; | |
document.querySelector("#expanderBar").style.left = "50%"; | |
GM_setValue("timerBarVisible", false); | |
} | |
function swapToTimerBar() { | |
document.querySelector("#titleBarTimerBar").style.left = "50%"; | |
document.querySelector("#expanderBar").style.left = "-100%"; | |
GM_setValue("timerBarVisible", true); | |
} | |
function restoreTimerBarCollapseState() { | |
let isTimerBarVisible = GM_getValue("timerBarVisible"); | |
if(isTimerBarVisible !== undefined) { | |
if(!isTimerBarVisible) { | |
swapToExpanderBar(); | |
} | |
} | |
else { | |
} | |
} | |
function workerSiteMain() { | |
if(Utility.isWindowTopFrame()) { | |
const divID = document.querySelector(`[data-react-class*="reactComponents/common/ShowModal"]`); | |
console.log(divID); | |
const reactProps = divID.getAttribute("data-react-props"); | |
const json = JSON.parse(reactProps); | |
const requesterName = json.modalOptions.requesterName; | |
const notAcceptedSpan = document.querySelector(`span[data-react-props*='"text":"accept"']`); | |
if(notAcceptedSpan) { | |
document.title = `NOT ACCEPTED - ${requesterName}`; | |
} | |
else { | |
const countdownTimer = document.querySelector("span[data-react-class*='reactComponents/common/CompletionTimer'] span:last-of-type"); | |
const rewardInDollars = json.modalOptions.monetaryReward.amountInDollars; | |
const rewardInCents = Utility.dollarsToCents(rewardInDollars); | |
const timeGivenMinutesSplit = (countdownTimer.innerText.trim().match(/(\d+) Min/)||[0,0])[1]; | |
const timeGivenSecondsSplit = 0; // TODO: Change this when I figure out what a HIT with <1 min reads out as. | |
const maximumTimeGivenInSeconds = Utility.hmsToSeconds(0, timeGivenMinutesSplit, timeGivenSecondsSplit); | |
const secondsForLoveWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(LOVE_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForHappyWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(HAPPY_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForOKWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(OK_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForSadWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(SAD_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForDisgustedWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(DISGUSTED_WAGE_LOWER_LIMIT), rewardInCents); | |
document.body.insertAdjacentHTML('afterend', | |
`<div id='titleBarTimerBar' style="position: fixed !important; pointer-events: none !important; background: white !important; opacity: 0.95 !important; width: 100% !important; left: 50% !important; margin-left: -50% !important; top: 0px !important; z-index: ${Number.MAX_SAFE_INTEGER} !important; text-align: center !important;">` + | |
`<span id="loveWageSpan">${LOVE_WAGE_EMOJI}: (<= ${Utility.toMMSSString(secondsForLoveWage)})</span> ` + | |
`<span id="happyWageSpan">${HAPPY_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForLoveWage)} - ${Utility.toMMSSString(secondsForHappyWage)})</span> ` + | |
`<span id="okWageSpan">${OK_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForHappyWage)} - ${Utility.toMMSSString(secondsForOKWage)})</span> ` + | |
`<span id="sadWageSpan">${SAD_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForOKWage)} - ${Utility.toMMSSString(secondsForSadWage)})</span> ` + | |
`<span id="disgustedWageSpan">${DISGUSTED_WAGE_EMOJI}: (>= ${Utility.toMMSSString(secondsForSadWage)})</span>` + | |
`<div style="text-align: center !important; margin-left: auto !important; margin-right: auto !important; font-style: italic !important;">Time Worked: <span id="timeWorkedSpan">00:00</span> <input type="text" id="bonusWageCents" style="pointer-events: auto !important;" placeholder="Bonus $" size="5"> <div>Pageload: <span id="timeLostToPageLoad"></span>ms Complete: <span id="timeLostToFullPageLoad"></span>ms</div></div>` + | |
`<button id='hideBarButton' style="pointer-events: auto !important;">Hide</button>` + | |
'</div>' | |
); | |
document.body.insertAdjacentHTML('afterend', | |
`<div id='expanderBar' style="position: fixed; pointer-events: none; background: white; opacity: 0.95; width: 100%; left: -100%; margin-left: -50%; top: 0px; z-index: ${Number.MAX_SAFE_INTEGER}; text-align: center;">` + | |
`<button id='showBarButton' style="pointer-events: auto;">Show $/hr. Details</button>` + | |
'</div>' | |
); | |
document.querySelector('#hideBarButton').addEventListener('click', function hideBar() { | |
swapToExpanderBar(); | |
}); | |
document.querySelector('#showBarButton').addEventListener('click', function hideBar() { | |
swapToTimerBar(); | |
}); | |
restoreTimerBarCollapseState(); | |
if(SHOW_BIG_EMOJI) { | |
document.body.insertAdjacentHTML('afterend', | |
`<div id="pageEmoji" draggable="false" style="position: fixed; opacity: ${BIG_EMOJI_OPACITY_ZERO_TO_ONE}; font-size: ${BIG_EMOJI_SIZE}; pointer-events: none; user-drag: none; user-select: none; width: 100%; left: 0px; height: 50%; top: 50%; z-index: ${Number.MAX_SAFE_INTEGER}; text-align: center;">` + | |
`` + | |
`</div>`); | |
} | |
setInterval(function workerSiteUpdate() { | |
let countdownTimerText = countdownTimer.innerText.match(/\d+:\d+\b/)[0]; | |
// let secondsRemaining = Utility.secondsRemainingInHHMMSSCountdown(countdownTimerText); | |
let secondsRemaining = Utility.secondsRemainingInMMSSCountup(countdownTimerText, maximumTimeGivenInSeconds); | |
updateActiveHITTabTimer(requesterName, secondsRemaining, rewardInCents); | |
}, UPDATE_RATE_IN_MILLISECONDS); | |
} // End of HIT accepted check. | |
} // End of isWindowTopFrame(). | |
} | |
function originalSiteMain() { | |
if(Utility.isWindowTopFrame()) { | |
const countdownTimer = document.querySelector("#theTime"); | |
const acceptHITInput = document.querySelector("input[name='/accept']"); | |
const capsuleTexts = document.querySelectorAll(".capsule_field_text"); | |
const requesterName = capsuleTexts[0].innerText.trim(); | |
const rewardInDollars = capsuleTexts[1].innerText.trim().match(/\$([0-9.]+)/)[1]; | |
const rewardInCents = Utility.dollarsToCents(rewardInDollars); | |
const timeGivenDaysSplit = (capsuleTexts[3].innerText.trim().match(/(\d+) days/)||[0,0])[1]; | |
const timeGivenHoursSplit = (capsuleTexts[3].innerText.trim().match(/(\d+) hours/)||[0,0])[1]; | |
const timeGivenMinutesSplit = (capsuleTexts[3].innerText.trim().match(/(\d+) minutes/)||[0,0])[1]; | |
const timeGivenSecondsSplit = (capsuleTexts[3].innerText.trim().match(/(\d+) seconds/)||[0,0])[1]; | |
const maximumTimeGivenInSeconds = Utility.daysToSeconds(timeGivenDaysSplit) + Utility.hmsToSeconds(timeGivenHoursSplit, timeGivenMinutesSplit, timeGivenSecondsSplit); | |
const secondsForLoveWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(LOVE_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForHappyWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(HAPPY_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForOKWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(OK_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForSadWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(SAD_WAGE_LOWER_LIMIT), rewardInCents); | |
const secondsForDisgustedWage = Utility.secondsGoalForTargetWage(Utility.dollarsToCents(DISGUSTED_WAGE_LOWER_LIMIT), rewardInCents); | |
console.log("You lost", Utility.getHITLoadTime() / 1000, "seconds to HIT loading, with accuracy:", Utility.getHITLoadTimeAccuracy()); | |
console.log("For a theoretical 1-second submission, this means that loading time cut your wage from", `\$${Utility.hourlyWageDollars(1,rewardInCents).toFixed(2)}/hr.`, "to", `\$${Utility.hourlyWageDollars(1 + (Utility.getHITLoadTime() / 1000),rewardInCents).toFixed(2)}/hr.`); | |
console.log("For a theoretical 5-second submission, this means that loading time cut your wage from", `\$${Utility.hourlyWageDollars(5,rewardInCents).toFixed(2)}/hr.`, "to", `\$${Utility.hourlyWageDollars(5 + (Utility.getHITLoadTime() / 1000),rewardInCents).toFixed(2)}/hr.`); | |
Utility.setAllContentLoadedCallback( () => { | |
console.log("You lost", Utility.getAllContentLoadedTime() / 1000, "seconds to HIT the full page load, with accuracy:", Utility.getHITLoadTimeAccuracy()); | |
console.log("If you waited for the whole page to load, this means that the most you could earn with an instant submission would be", `\$${Utility.hourlyWageDollars(Utility.getAllContentLoadedTime() / 1000,rewardInCents).toFixed(2)}/hr.`); | |
}); | |
document.body.insertAdjacentHTML('afterend', | |
`<div id="titleBarTimerBar" style="position: fixed; pointer-events: none; background: white; opacity: 0.95; width: 100%; left: 50%; margin-left: -50%; top: 0px; z-index: ${Number.MAX_SAFE_INTEGER}; text-align: center;">` + | |
`<span id="loveWageSpan">${LOVE_WAGE_EMOJI}: (<= ${Utility.toMMSSString(secondsForLoveWage)})</span> ` + | |
`<span id="happyWageSpan">${HAPPY_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForLoveWage)} - ${Utility.toMMSSString(secondsForHappyWage)})</span> ` + | |
`<span id="okWageSpan">${OK_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForHappyWage)} - ${Utility.toMMSSString(secondsForOKWage)})</span> ` + | |
`<span id="sadWageSpan">${SAD_WAGE_EMOJI}: (${Utility.toMMSSString(secondsForOKWage)} - ${Utility.toMMSSString(secondsForSadWage)})</span> ` + | |
`<span id="disgustedWageSpan">${DISGUSTED_WAGE_EMOJI}: (>= ${Utility.toMMSSString(secondsForSadWage)})</span>` + | |
`<div style="text-align: center; margin-left: auto; margin-right: auto; font-style: italic;">Time Worked: <span id="timeWorkedSpan">00:00</span> <input type="text" style="pointer-events: auto;" id="bonusWageCents" placeholder="Bonus $" size="5"><div>Pageload: <span id="timeLostToPageLoad"></span>ms Complete: <span id="timeLostToFullPageLoad"></span>ms</div></div>` + | |
`<button id='hideBarButton' style="pointer-events: auto;">Hide</button>` + | |
'</div>' | |
); | |
document.body.insertAdjacentHTML('afterend', | |
`<div id='expanderBar' style="position: fixed; pointer-events: none; background: white; opacity: 0.95; width: 100%; left: -100%; margin-left: -50%; top: 0px; z-index: ${Number.MAX_SAFE_INTEGER}; text-align: center;">` + | |
`<button id='showBarButton' style="pointer-events: auto;">Show $/hr. Details</button>` + | |
'</div>' | |
); | |
document.querySelector('#hideBarButton').addEventListener('click', function hideBar() { | |
swapToExpanderBar(); | |
}); | |
document.querySelector('#showBarButton').addEventListener('click', function hideBar() { | |
swapToTimerBar(); | |
}); | |
restoreTimerBarCollapseState(); | |
if(SHOW_BIG_EMOJI) { | |
document.body.insertAdjacentHTML('afterend', | |
`<div id="pageEmoji" draggable="false" style="position: fixed !important; opacity: ${BIG_EMOJI_OPACITY_ZERO_TO_ONE} !important; font-size: ${BIG_EMOJI_SIZE} !important; pointer-events: none !important; user-drag: none !important; user-select: none !important; width: 100% !important; left: 0px !important; height: 50% !important; top: 50% !important; z-index: ${Number.MAX_SAFE_INTEGER} !important; text-align: center !important;">` + | |
`😍` + | |
`</div>`); | |
} | |
if(acceptHITInput) { | |
document.title = `NOT ACCEPTED - ${requesterName}`; | |
} | |
else { | |
setInterval(function mainSiteUpdate() { | |
let countupTimerText = countdownTimer.innerText.trim(); | |
let secondsRemaining = Utility.secondsRemainingInHHMMSSCountup(countupTimerText, maximumTimeGivenInSeconds); | |
updateActiveHITTabTimer(requesterName, secondsRemaining, rewardInCents); | |
}, UPDATE_RATE_IN_MILLISECONDS); | |
} // End of HIT accepted check. | |
} // End of isWindowTopFrame(). | |
} | |
function isWorkerSite() { | |
return window.location.href.toLowerCase().includes("worker.mturk.com"); | |
} | |
(function main() { | |
window.addEventListener("message", function handleMessage(event) { | |
if(event.data.msg === "I'm ready for you to ask me questions.") { | |
console.log("PARENT FRAME: Kid said it's ready for questions."); | |
Utility.askWorkerFrameWhetherSurvey(); | |
console.log("PARENT FRAME: I asked whether the kid was a survey."); | |
} | |
else if(event.data.msg === "I am a survey HIT.") { | |
console.log("PARENT FRAME: Kid said he was a survey."); | |
Utility.disablePauseOnInvisible(); | |
console.log("PARENT FRAME: I disabled pausing on invisible, since the kid said he was a survey."); | |
} | |
if(event.data.msg === "Submit relay.") { | |
console.log("PARENT FRAME: I detected a form submit."); | |
alert("Detected a form submit."); | |
} | |
}); | |
if(isWorkerSite()) { | |
workerSiteMain(); | |
} | |
else { | |
originalSiteMain(); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment