2 changed files with 53 additions and 1 deletions
@ -0,0 +1,44 @@
@@ -0,0 +1,44 @@
|
||||
/* |
||||
Due to Owncast's goal of being private by default, we don't want any external |
||||
links to leak the instance of Owncast as a referrer. |
||||
This observer attempts to catch any anchor tags and automatically add the |
||||
noopener and noreferrer attributes to them so the instance of Owncast isn't |
||||
passed along in the headers. |
||||
|
||||
This should should be fired somewhere relatively high level in the DOM and live |
||||
for the entirety of the page. |
||||
*/ |
||||
|
||||
/* eslint-disable no-restricted-syntax */ |
||||
export default function setupNoLinkReferrer(observationRoot: HTMLElement): void { |
||||
// Options for the observer (which mutations to observe)
|
||||
const config = { attributes: false, childList: true, subtree: true }; |
||||
|
||||
const addNoReferrer = (node: Element): void => { |
||||
node.setAttribute('rel', 'noopener noreferrer '); |
||||
}; |
||||
|
||||
// Callback function to execute when mutations are observed
|
||||
// eslint-disable-next-line func-names
|
||||
const callback = function (mutationList) { |
||||
for (const mutation of mutationList) { |
||||
for (const node of mutation.addedNodes) { |
||||
// we track only elements, skip other nodes (e.g. text nodes)
|
||||
// eslint-disable-next-line no-continue
|
||||
if (!(node instanceof HTMLElement)) continue; |
||||
|
||||
if (node.tagName.toLowerCase() === 'a') { |
||||
addNoReferrer(node); |
||||
} |
||||
} |
||||
} |
||||
}; |
||||
|
||||
observationRoot.querySelectorAll('a').forEach(anchor => addNoReferrer(anchor)); |
||||
|
||||
// Create an observer instance linked to the callback function
|
||||
const observer = new MutationObserver(callback); |
||||
|
||||
// Start observing the target node for configured mutations
|
||||
observer.observe(observationRoot, config); |
||||
} |
||||
Loading…
Reference in new issue