Bookmarklets

This is my tiny collection of bookmarklets, both as compressed links and readable source code. If you're already familiar with what bookmarklets are and how to use them, then you can skip down to the headings below. Each one is a bookmarklet I wrote to help when I'm surfing and developing for the web. If not, read on for a brief overview of what they are and how to use them.

Bookmarklets are URIs that sit in the javascript scheme. This scheme is honored by most user agents to indicate that the data following the scheme represents executable JavaScript that can be run in the context of the current page. This is of course powerful, and as such formidable. As a result some user agents have taken steps to gate access to this functionality. You may have to enable them in your user agent and/or be sure that your bookmarks really do start with the javascript: prefix when you try to save them. It should be possible though on any dominant user agent.

It is worth understanding that any bookmarklet you run has the ability to completely impersonate you on the page. The user agents are guarding this functionality because people have been phished into running bookmarklets that steal their credentials to popular websites. As a good rule of thumb, be suspicious of any bookmarklet that loads scripts from elsewhere as they're harder to audit and can be changed to include malicious functionality at any point in the future. As always, if you don't trust it, don't run it.

The best way to use bookmarklets is by running around with your bookmark toolbar enabled at all times. Many user agents have begun to hide this by default or only show it on blank tabs. It should be possible to configure it to always show this. Finally, with all that out of the way, you should only have to drag a bookmarklet link (like the headings on this page) into your bookmark toolbar and then click to use it on any page. Neat, right? They're kind of like an add-on/extension without all the hassle of installing it or letting it run in the background on every page you visit. It only runs when you click it.

Not much else to say. Each bookmarklet below has a short description of what it does and the source code without any compression applied. I've also gone ahead and disabled my CSP forbidding inline scripts on this page so you can try them out without even having to add them to your bookmarks. Hope you find something useful!

Archive Version

See if the page was archived at some point by the Internet Archive. If you find yourself often using this, consider donating to them for the insane amount of charity they do for the web ecosystem. If you don't have the cash to spare, perhaps consider signing up for an account to browse their huge catalogue of online books.

window.location.href = `https://web.archive.org/web/*/${document.URL}`;

Border Debug

Show the box model of the page by putting a bright red box around everything. See that the nesting looks good and nothing's chunky or broken. This is super valuable for spotting inline elements inside block elements, or links with a click target that is bigger than the visible parts of the element. It also helps debug a wide variety of other CSS and box model issues. This is by far the bookmarklet I use most.

document.querySelectorAll("*").forEach(
	(elm, _) => {elm.style.boxShadow="0 0 0 1px red inset"}
);

List Globals

This lists all the global variables on the page. Super handy to start to understand a site's code and APIs. It just compares the globals of the tab to that of a blank tab. It then uses said blank tab to list the unique global properties of the current tab, one per line. It's also a great gauge of how clean the devs are being about state. You wouldn't believe all the junk you often find.

const newWindow = open();
const agentGlobals = new Set(Object.keys(newWindow.window));
newWindow.document.documentElement.innerText = (
	Object.keys(window)
	.filter((key) => (!agentGlobals.has(key)))
	.sort()
	.join("\n")
);

URL++

Wardialing the URL continues to work to this day. Not perfect, not efficient, but a handy hammer when you spot a nail.

window.location = window.location.href.replace(
	/(.*)(\d+)(.*)/,
	(_, start, num, end) => (
		`${start}${parseInt(num) + 1}${end}`
	),
);

Zap Images

This sets every <img> tag's src attribute to an empty string which should break most images on the page. This won't break CSS based images. This just helps catch issues around alt text and graceful degradation of the site.

document.querySelectorAll("img").forEach((elm, _) => {elm.src = ""});

Zap CSS

This disables all the CSS on the page. Both a graceful degradation test and super crude accessibility first pass. This helps catch a lot of insane sized images/SVGs, menu hells, and JS that assumes styles are working. It's not perfect. It doesn't catch CSS issues from assumed agent defaults or that older user agents aren't left with a mess of half working styles. On the other hand, every bit helps.

[...document.styleSheets].forEach((sheet, _) => {sheet.disabled = true});

Session Transplant

This copies all the cookies and local storage data from a page into the clipboard. It formats it so you can paste it into the console of some other profile, page, or user agent. Effectively a way to "transplant" the state. It can't copy HttpOnly cookies (obviously), so it won't work on well secured sites. It's kind of an odd ball I created for a situation you may find yourself in.

const node = document.createElement('textarea');
const selection = document.getSelection();

node.textContent = `
	document.cookie = ${JSON.stringify(document.cookie)};
	Object.assign(window.localStorage, ${JSON.stringify(window.localStorage)});
	location.reload();
`;

document.body.appendChild(node);

selection.removeAllRanges();
node.select();
document.execCommand('copy');

selection.removeAllRanges();
document.body.removeChild(node);
alert("Session Copied!");