Skip to content

Instantly share code, notes, and snippets.

@atnbueno
Last active January 22, 2022 21:22
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 atnbueno/f8bc6376bcdb1d8dace2c490f9ac0770 to your computer and use it in GitHub Desktop.
Save atnbueno/f8bc6376bcdb1d8dace2c490f9ac0770 to your computer and use it in GitHub Desktop.
Greasemonkey: import/export Wordle's game state to migrate playing it from one device to another
// ==UserScript==
// @name Wordle import/export
// @version 1.3
// @author Antonio Bueno
// @namespace userscripts.atnbueno.com
// @match https://www.powerlanguage.co.uk/wordle/
// @match https://wordle.danielfrg.com/
// @require https://cdn.jsdelivr.net/npm/jquery@3/dist/jquery.min.js
// @require https://cdn.jsdelivr.net/npm/toastify-js
// @resource toastifyCSS https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css
// @grant GM.getResourceUrl
// @grant GM.setClipboard
// ==/UserScript==
(function () {
"use strict";
// DOM manipulations courtesy of jQuery
const strings = JSON.parse(`{
"en": {
"label": "Import/export",
"prompt": "Paste to import, leave empty to export",
"importOK": "Updated data",
"importKO": "Data could not be updated",
"exportOK": "Game state copied to the clipboard",
"exportKO": "Game state could not be copied"
},
"es": {
"label": "Importar/exportar",
"prompt": "Pega para importar, deja en blanco para exportar",
"importOK": "Datos actualizados",
"importKO": "Los datos no se han podido actualizar",
"exportOK": "Estado del juego copiado al portapapeles",
"exportKO": "El estado del juego no se ha podido copiar"
}}`);
const lang = location.href.includes("danielfrg") ? "es" : "en";
// Modificacions are applied once the DOM has been build (images may be still loading)
$(document).ready(function () {
$("body").append('<button id="import-export">' + strings[lang].label);
$("#import-export").on("click", function () {
let pasted = prompt(strings[lang].prompt);
if (pasted != "") {
try {
let data = JSON.parse(atob(pasted));
Object.keys(data).forEach(key => { window.localStorage.setItem(key, data[key]) });
notification(strings[lang].importOK + ":\n" + Object.keys(data).join(", "));
} catch (error) {
notification(strings[lang].importKO + ":\n" + error.message, "error");
}
} else {
let data = {};
try {
Object.keys(window.localStorage).forEach(key => { data[key] = localStorage.getItem(key); });
GM.setClipboard(btoa(JSON.stringify(data)));
notification(strings[lang].exportOK + ":\n" + Object.keys(data).join(", "));
} catch (error) {
notification(strings[lang].exportKO + ":\n" + error.message, "error");
}
}
});
});
// External CSS files
(async function () {
// Toastify CSS
var externalFileURL = await GM.getResourceUrl("toastifyCSS");
stylesheet = document.createElement("link");
stylesheet.setAttribute("rel", "stylesheet");
stylesheet.setAttribute("href", externalFileURL);
document.documentElement.appendChild(stylesheet);
})();
// Inline CSS
var stylesheet = document.createElement("style");
stylesheet.textContent = `
div.toastify { margin: inherit; padding-bottom: 20px; }
div.toastify, #import-export { font-family: -apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif; }
#import-export { background-color: #E8E8F0; border-radius: 4px; border: 1px solid #888890; color: black; padding: 2px 6px; font-size: 13px; z-index: 50; position: fixed; bottom: 8px; right: 8px; }
#import-export:hover { background-color: #C8C8D0; border: 1px solid #686870; }
`;
document.documentElement.appendChild(stylesheet);
// Notifications courtesy of Toastify JS (see https://apvarun.github.io/toastify-js/)
function notification(message, type = "info", timeout = 5) {
// The "type" parameter accepts four values: "info", "warning", "error" and "hello"
// The "timeout" parameter is expressed in seconds although Toastify uses milliseconds
var color, icon;
switch (type) {
case "warning":
color = "rgba(201, 201, 0, 0.8)";
icon = "⚠";
break;
case "error":
color = "rgba(201, 51, 51, 0.8)";
icon = "🛑";
break;
case "hello":
color = "rgba(51, 153, 51, 0.8)";
icon = "👋🏼";
break;
default:
color = "rgba(51, 51, 153, 0.8)";
icon = "ℹ";
}
Toastify({
text: icon + " " + message,
duration: timeout * 1000,
gravity: "bottom",
style: {
background: color,
}
}).showToast();
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment