Skip to content

Instantly share code, notes, and snippets.

@rodneyrehm
Created July 21, 2016 16: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 rodneyrehm/bae83c13e2b4c579b62ce45a253ca011 to your computer and use it in GitHub Desktop.
Save rodneyrehm/bae83c13e2b4c579b62ce45a253ca011 to your computer and use it in GitHub Desktop.
TamperMonkey: force noopener for window-spawning links (Google Chrome)
// ==UserScript==
// @name force noopener for window-spawning links
// @namespace *
// @version 0.1
// @description adds rel="noopener" to <a href="…" target="_blank">
// @author Rodney Rehm
// @match http://*/*
// @grant none
// ==/UserScript==
// see https://jakearchibald.com/2016/performance-benefits-of-rel-noopener/
(function() {
'use strict';
const safeTargets = new Set(['_self', '_parent', '_top']);
function patchLink(element) {
const rel = element.getAttribute('rel') || '';
if (rel.indexOf('noopener') === -1) {
element.setAttribute('rel', rel + ' noopener');
console.log("patching", element);
}
}
function patchLinks(context) {
// find all links that open in a new window by way of the target attribute
const links = context.querySelectorAll('a[target]');
const windowSpawningLinks = Array.from(links).filter(element => !safeTargets.has(element.target.trim()));
// add rel="noopener" to the links opening new windows/tabs
windowSpawningLinks.forEach(patchLink);
}
// patch current DOM
patchLinks(document);
// make sure future mutations are considered as well
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.info('MUTATION MUTATION');
if (mutation.type === 'attributes') {
patchLink(mutation.target);
} else if (mutation.type === 'childList') {
patchLinks(mutation.target);
}
});
});
observer.observe(document.body, {
subtree: true,
attributes: true,
attributeFilter: ['target'],
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment