Skip to content

Instantly share code, notes, and snippets.

@benbernard
Last active September 24, 2020 16:57
Show Gist options
  • Save benbernard/659b2bf555e56a5dfc689341e5d4c721 to your computer and use it in GitHub Desktop.
Save benbernard/659b2bf555e56a5dfc689341e5d4c721 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Cracking the Cryptic
// @namespace http://tampermonkey.net/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://cracking-the-cryptic.web.app/sudoku/*
// @grant GM_addStyle
// @grant GM_getResourceText
// @require https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/keymap/sublime.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/keymap/vim.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/mode/markdown/markdown.min.js
// @resource CodeMirrorCSS https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/codemirror.min.css
// @resource Monokai https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.58.1/theme/monokai.min.css
// @run-at document-start
// ==/UserScript==
const SCRATCH_KEYMAP = "sublime";
const originalAddEventListener = EventTarget.prototype.addEventListener;
let isDeselecting = false;
GM_addStyle(GM_getResourceText("CodeMirrorCSS"));
GM_addStyle(GM_getResourceText("Monokai"));
GM_addStyle(`
:root {
--board-width: min(1024px, 60vw);
}
.sudoku-play { width: var(--board-width); }
.scratchpad-container {
position: absolute;
left: var(--board-width);
top: 50px; /* leave room for the top bar */
width: calc(100% - var(--board-width));
height: calc(100% - 50px);
}
.CodeMirror {
height: 100%;
padding: 5px;
box-sizing: border-box;
font-size: 20px;
}
`);
window.addEventListener("DOMContentLoaded", () => {
console.log("DOM fully loaded and parsed");
const scratchContainer = document.createElement("div");
scratchContainer.classList.add("scratchpad-container");
document.body.appendChild(scratchContainer);
CodeMirror(scratchContainer, {
value: "# This is a scratch space for your notes",
mode: "markdown",
keyMap: SCRATCH_KEYMAP,
theme: "monokai",
lineWrapping: true,
});
});
function selectCells(cells) {
const startEndCell = cells.pop();
triggerMouseEvent(startEndCell, "mousedown");
cells.forEach((cell) => triggerMouseEvent(cell, "mouseover"));
cells.forEach((cell) => triggerMouseEvent(cell, "mouseup"));
}
function triggerMouseEvent(node, eventType) {
var clickEvent = document.createEvent("MouseEvents");
clickEvent.initEvent(eventType, true, true);
node.dispatchEvent(clickEvent);
}
document.addEventListener("keydown", (e) => {
// Command-a selects all
if (e.metaKey && e.key === "a" && !document.querySelector("textarea:focus")) {
selectCells([...document.querySelectorAll(".sudoku-cell")]);
e.preventDefault();
e.stopPropagation();
}
});
// Use alt to switch to the color panel
let previousSelectedButton = null;
document.addEventListener("keydown", (e) => {
if (e.key !== "Alt") return;
previousSelectedButton = document.querySelector(
".sudoku-play__action-button--primary"
);
document
.querySelector(".sudoku-play__mode-controls .action-button:last-child")
.click();
});
document.addEventListener("keyup", (e) => {
if (e.key !== "Alt") return;
previousSelectedButton?.click();
previousSelectedButton = null;
});
// Override black and yellow colors to make them not suck
const colorFixer = () => {
const map = (fromName, value) => {
const mappingNames = [
"originalHighlight",
"newHighlight",
"originalSwatch",
"newSwatch",
];
const table = [
// Yellow to better yellow
[
"rgba(247, 208, 56, 0.5)",
"rgba(255, 255, 0, 0.8)",
"rgb(247, 208, 56)",
"rgb(255, 255, 0)",
],
// Black to red
[
"rgb(0, 0, 0)",
"rgba(255, 0, 0, 0.7)",
"rgb(0, 0, 0)",
"rgb(255, 0, 0)",
],
// "red" to pink
[
"rgba(230, 38, 31, 0.5)",
"rgba(255, 100, 150, 0.5)",
"rgb(230, 38, 31)",
"rgba(255, 100, 150)",
],
// white to blue
[
"rgb(255, 255, 255)",
"rgba(0, 50, 255, 0.5)",
"rgb(255, 255, 255)",
"rgb(0, 50, 255)",
],
// Magenta to purple (no swatch change)
["rgba(210, 59, 231, 0.5)", "rgba(180, 0, 255, 0.5)"],
// Make orange oranger
["rgba(235, 117, 50, 0.5)", "rgba(255, 150, 0, 0.75)"],
// Light blue to proper cyan
[
"rgba(52, 187, 230, 0.5)",
"rgba(0, 255, 255, 0.5)",
"rgb(52, 187, 230)",
"rgb(0, 255, 255)",
],
// Make green really green
[
"rgba(163, 224, 72, 0.5)",
"rgb(160, 255, 0)",
"rgb(163, 224, 72)",
"rgb(0, 255, 0)",
],
];
const fromIndex = mappingNames.indexOf(fromName);
return table.find((row) => row[fromIndex] === value)?.[fromIndex + 1];
};
// Find all highlight elements
for (const highlight of document.querySelectorAll(
".sudoku-cell__highlight"
)) {
const mapping = map("originalHighlight", highlight.style.backgroundColor);
if (mapping) {
highlight.style.backgroundColor = mapping;
} else if (highlight.style.backgroundColor === "rgba(255, 215, 0, 0.5)") {
// selection
highlight.style.background = `url(${selectionImageData})`;
highlight.style.backgroundSize = "15px";
highlight.style.opacity = 0.12;
highlight.classList.add("selection-highlight");
}
}
// Find all swatches
for (const swatch of document.querySelectorAll(
".sudoku-play__color-square"
)) {
const mapping = map("originalSwatch", swatch.style.backgroundColor);
if (mapping) {
swatch.style.backgroundColor = mapping;
}
}
requestAnimationFrame(colorFixer);
};
colorFixer();
const selectionImageData =
"data:image/gif;base64,R0lGODlhDAAMAIAAAAAAAP7/ACH/C05FVFNDQVBFMi4wAwEAAAAh/wtYTVAgRGF0YVhNUDw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDYuMC1jMDAyIDc5LjE2NDQ2MCwgMjAyMC8wNS8xMi0xNjowNDoxNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIDIxLjIgKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NkY3RTJERjNDODg0MTFFQTlFNTVEMkYxQzk4NTU0MDIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NkY3RTJERjRDODg0MTFFQTlFNTVEMkYxQzk4NTU0MDIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo2RjdFMkRGMUM4ODQxMUVBOUU1NUQyRjFDOTg1NTQwMiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo2RjdFMkRGMkM4ODQxMUVBOUU1NUQyRjFDOTg1NTQwMiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAQDAAAALAAAAAAMAAwAAAIaTIB2uaDo2mNrxmrgtFxmpn1R6GElRaIqUAAAIfkEBAMAAAAsAAAAAAwADAAAAhmMgRYIl97Wk5Ep6+7cXEcKeeGIgdkoiU4BACH5BAQDAAAALAAAAAAMAAwAAAIZRA55odjcknFTLgtnvhpD3oUiBZKmh45IAQAh+QQEAwAAACwAAAAADAAMAAACGgSCdrmh6Npja8Zq4LRcZqZ9UehhJUWialAAACH5BAQDAAAALAAAAAAMAAwAAAIZhIMGGJfe1pORKevu3FxHCnnhiIHZKIlOAQAh+QQEAwAAACwAAAAADAAMAAACGQweeaDY3JJxUy4LZ74aQ96FIgWSpoeOSAEAIfkEBAMAAAAsAAAAAAwADAAAAhpMgHa5oOjaY2vGauC0XGamfVHoYSVFoipQAAAh+QQEAwAAACwAAAAADAAMAAACGYyBFgiX3taTkSnr7txcRwp54YiB2SiJTgEAIfkEBAMAAAAsAAAAAAwADAAAAhlEDnmh2NyScVMuC2e+GkPehSIFkqaHjkgBACH5BAQDAAAALAAAAAAMAAwAAAIaBIJ2uaHo2mNrxmrgtFxmpn1R6GElRaJqUAAAIfkEBAMAAAAsAAAAAAwADAAAAhmEgwYYl97Wk5Ep6+7cXEcKeeGIgdkoiU4BADs=";
// Custom CSS
const css = `
.sudoku-cell__candidates--user, .sudoku-cell__pm--user, .sudoku-cell__value--user {
z-index: 101;
--strokewidth: 2px;
text-shadow: white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth),
white 0 0 var(--strokewidth);
}
.sudoku-cell__highlight {
mix-blend-mode: multiply;
z-index: 100;
}
`;
const styleEl = document.createElement("style");
styleEl.textContent = css;
document.body.append(styleEl);
// Protect against navigation
window.addEventListener("beforeunload", (e) => {
e.preventDefault();
e.returnValue = "";
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment