Skip to content

Instantly share code, notes, and snippets.

@cole-wilson
Last active May 10, 2023 06:43
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cole-wilson/3a414155ee6acaf22728b482075df167 to your computer and use it in GitHub Desktop.
Save cole-wilson/3a414155ee6acaf22728b482075df167 to your computer and use it in GitHub Desktop.
Bookmarklet

Edit Bookmarklet

Edit websites in contenteditable and designMode mode, then save your changes in localStorage and restore later. Also change URL slug.

Warning Disinformation is a serious issue, and while a script like this could be used for pranks or just pure utility, it is important to not use it to spread lies or harmful information.

Use by adding the contents of bookmarklet.txt to a new bookmark in your bookmarks bar as the URL.

Escaped bookmarklet code generated by mrcoles.com/bookmarklet (unaffiliated with me).

javascript:_bm_name="Edit Bookmarklet";(function()%7B_bm_id %3D location.href%3B_bm_window %3D window.open(""%2C _bm_name%2C "fullscreen%3Dno%2Cheight%3D150%2Cleft%3D50%2Clocation%3Dno%2Cmenubar%3Dno%2Cresizable%3Dno%2Cscrollbars%3Dno%2Cstatus%3Dno%2Ctitlebar%3Dno%2Ctoolbar%3Dno%2Ctop%3D50%2Cwidth%3D100")%3B_bm_edit %3D function() %7Bwindow.focus()%3Bdocument.body.contentEditable %3D true%3Bdocument.designMode %3D true%3Balert("Editing...")%3B_bm_window.focus()%3B%7D%3B_bm_save %3D function() %7Bif (!_bm_window.confirm("Are you sure you want to save%3F This will overwrite other saves for this page.")) return%3Bdocument.body.contentEditable %3D false%3Bdocument.designMode %3D false%3Blet pathparts %3D location.pathname.split("%2F")%3Blet data %3D %7Bbody%3A document.body.innerHTML%2Curl%3A pathparts%5Bpathparts.length-1%5D%2Ctitle%3A document.title%7D%3BlocalStorage.setItem(_bm_name %2B " " %2B _bm_id%2C JSON.stringify(data))%3B_bm_window.alert("Changes Saved")%3B_bm_window.focus()%3B%7D%3B_bm_load %3D function() %7Blet data %3D JSON.parse(localStorage.getItem(_bm_name %2B " " %2B _bm_id))%3Bdocument.body.innerHTML %3D data.body%3Bdocument.title %3D data.title%3Bhistory.pushState(%7Byoda%3Atrue%7D%2C ""%2C data.url)%3B_bm_window.alert("Changes Loaded")%3B_bm_window.focus()%3B%7D%3B_bm_find_replace %3D function() %7Blet a %3D _bm_window.prompt("Replace all instances of%3A")%3Blet b %3D _bm_window.prompt("with%3A")%3Bdocument.body.innerHTML %3D document.body.innerHTML.replaceAll(a%2Cb)%3B_bm_window.alert("Done!")%3B_bm_window.focus()%3B%7D%3B_bm_title %3D function() %7Bdocument.title %3D _bm_window.prompt("Title%3A")%3B%7D%3B_bm_path %3D function() %7Bwindow.focus()%3Bhistory.pushState(%7Byoda%3Afalse%7D%2C ""%2C _bm_window.prompt("New URL path%3F"))%3B%7D%3Bfunction _bm_start() %7Bif (typeof _bm_open !%3D%3D 'undefined') return%3B_bm_window.document.write(%60<body style%3D'font-family%3Amonospace%3Btext-align%3Acenter'><b>%24%7B_bm_name%7D<%2Fb><br><br><a href%3D'%23' onclick%3D'opener._bm_edit()'>edit<%2Fa>%26nbsp%3B<a href%3D'%23' onclick%3D'opener._bm_save()'>save<%2Fa>%26nbsp%3B<a href%3D'%23' onclick%3D'opener._bm_load()'>load<%2Fa>%26nbsp%3B<br><br><a href%3D'%23' onclick%3D'opener._bm_find_replace()'>find %26 replace<%2Fa><br><a href%3D'%23' onclick%3D'opener._bm_title()'>set title<%2Fa><br><a href%3D'%23' onclick%3D'opener._bm_path()'>set URL<%2Fa><%2Fbody>%60)%3B_bm_window.onunload %3D function() %7Bdelete _bm_open%7D%3Bwindow.onunload %3D function() %7B_bm_window.close()%3Bhistory.pushState(%7Byoda%3A"maybe"%7D%2C _bm_id)%3B%7D%3B_bm_open %3D true%3B%7D_bm_start()%7D)()
_bm_name = "Edit Bookmarklet";
_bm_id = location.href;
_bm_window = window.open("", _bm_name, "fullscreen=no,height=150,left=50,location=no,menubar=no,resizable=no,scrollbars=no,status=no,titlebar=no,toolbar=no,top=50,width=100");
_bm_edit = function() {
window.focus();
document.body.contentEditable = true;
document.designMode = true;
alert("Editing...");
_bm_window.focus();
};
_bm_save = function() {
if (!_bm_window.confirm("Are you sure you want to save? This will overwrite other saves for this page.")) return;
document.body.contentEditable = false;
document.designMode = false;
let pathparts = location.pathname.split("/");
let data = {
body: document.body.innerHTML,
url: pathparts[pathparts.length-1],
title: document.title
};
localStorage.setItem(_bm_name + " " + _bm_id, JSON.stringify(data));
_bm_window.alert("Changes Saved");
_bm_window.focus();
};
_bm_load = function() {
let data = JSON.parse(localStorage.getItem(_bm_name + " " + _bm_id));
document.body.innerHTML = data.body;
document.title = data.title;
history.pushState({yoda:true}, "", data.url);
_bm_window.alert("Changes Loaded");
_bm_window.focus();
};
_bm_find_replace = function() {
let a = _bm_window.prompt("Replace all instances of:");
let b = _bm_window.prompt("with:");
document.body.innerHTML = document.body.innerHTML.replaceAll(a,b);
_bm_window.alert("Done!");
_bm_window.focus();
};
_bm_title = function() {
document.title = _bm_window.prompt("Title:");
};
_bm_path = function() {
window.focus();
history.pushState({yoda:false}, "", prompt("New URL path?"));
};
function _bm_start() {
if (typeof _bm_open !== 'undefined') return;
_bm_window.document.write(`
<body style='font-family:monospace;text-align:center'>
<b>${_bm_name}</b><br><br>
<a href='#' onclick='opener._bm_edit()'>edit</a>&nbsp;
<a href='#' onclick='opener._bm_save()'>save</a>&nbsp;
<a href='#' onclick='opener._bm_load()'>load</a>&nbsp;
<br><br>
<a href='#' onclick='opener._bm_find_replace()'>find & replace</a><br>
<a href='#' onclick='opener._bm_title()'>set title</a><br>
<a href='#' onclick='opener._bm_path()'>set URL</a>
</body>`);
_bm_window.onunload = function() {delete _bm_open};
window.onunload = function() {
_bm_window.close();
history.pushState({yoda:"maybe"}, _bm_id);
};
_bm_open = true;
}
_bm_start();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment