Skip to content

Instantly share code, notes, and snippets.

@eneim
Forked from tuanchauict/README.md
Created July 9, 2022 13:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eneim/3ca3365efd7478b82678f7f5222227b5 to your computer and use it in GitHub Desktop.
Save eneim/3ca3365efd7478b82678f7f5222227b5 to your computer and use it in GitHub Desktop.
Attach a stopwatch to Leetcode

This script attaches a stopwatch into the toolbar of Leetcode's problem page.

The feature is simple:

  • Start/Stop the stopwatch
  • Auto start after 2 mins remaining on the problem
  • Restore unstopped stopwatch for the next visit on the problem

Use this script with any browser extension allowing attaching JS to the page. (I use User JavaScript and CSS)

Happy Leetcoding!

function attachStopWatch() {
if (document.getElementById("stopwatch")) {
// Already attached
return;
}
const container = document.getElementsByClassName("css-1lexzqe-TabHeaderContainer e5i1odf2");
if (container.length > 0) {
container[0].appendChild(createStopWatchElement());
}
}
function createStopWatchElement() {
const root = document.createElement("div");
root.className = "css-1lelwtv-TabHeader e5i1odf4 stopwatch--root";
root.id = "stopwatch";
root.innerHTML = '<div class="css-1uwsqgo-TabHeaderRow e5i1odf3"><div class="tab-header__20aW"><span class="stopwatch--label"></span>&nbsp;&nbsp;<span class="stopwatch--clock"></span></div></div>';
const stateNode = root.getElementsByClassName("stopwatch--label")[0];
const clockNode = root.getElementsByClassName("stopwatch--clock")[0];
const startCounting = function (startTimeMillis) {
if (root.intervalId) {
return;
}
localStorage.setItem(getStorageKey(), startTimeMillis);
root.intervalId = setInterval(clockTick, 500, clockNode, startTimeMillis);
stateNode.innerText = "Stop";
clockNode.innerText = toTimeString(getCurrentTimeInMillis() - startTimeMillis);
}
const stopCounting = function () {
clearInterval(root.intervalId);
root.intervalId = null;
localStorage.removeItem(getStorageKey());
stateNode.innerText = "Start";
}
const previousRunTime = localStorage.getItem(getStorageKey());
if (previousRunTime) {
startCounting(parseInt(previousRunTime));
} else {
stateNode.innerText = "Start";
clockNode.innerText = "00:00:00";
}
root.onclick = function () {
if (root.intervalId) {
stopCounting();
} else {
startCounting(getCurrentTimeInMillis());
}
}
const ONE_MIN = 60*1000;
setTimeout(function() {startCounting(getCurrentTimeInMillis() - ONE_MIN)}, 2*ONE_MIN);
return root;
}
function getStorageKey() {
const path = location.pathname;
const arr = path.split('/');
return "stopwatch_" + arr[2];
}
function clockTick(clockNode, startTime) {
const diff = getCurrentTimeInMillis() - startTime;
clockNode.innerText = toTimeString(diff);
}
function getCurrentTimeInMillis() {
return new Date().getTime();
}
function toTimeString(time) {
const hours = Math.floor(time / (1000 * 60 * 60));
const minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((time % (1000 * 60)) / 1000);
return pad(hours, 2) + ":" + pad(minutes, 2) + ":" + pad(seconds, 2);
}
function pad(num, size) {
var s = "000000000" + num;
return s.substr(s.length - size);
}
setInterval(attachStopWatch, 1000);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment