summaryrefslogtreecommitdiffstats
path: root/src/js/firstparties/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/js/firstparties/lib')
-rw-r--r--src/js/firstparties/lib/utils.js62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/js/firstparties/lib/utils.js b/src/js/firstparties/lib/utils.js
new file mode 100644
index 0000000..3edb0c8
--- /dev/null
+++ b/src/js/firstparties/lib/utils.js
@@ -0,0 +1,62 @@
+window.isURL = function(url) {
+ // ensure the URL starts with HTTP or HTTPS; otherwise we might be vulnerable
+ // to XSS attacks
+ return (url && (url.startsWith("https://") || url.startsWith("http://")));
+};
+
+/**
+ * Search a window and all IFrames within it for a query selector, then return a
+ * list of all the elements in any frame that match.
+ */
+window.findInAllFrames = function(query) {
+ let out = [];
+ document.querySelectorAll(query).forEach((node) => {
+ out.push(node);
+ });
+ Array.from(document.getElementsByTagName('iframe')).forEach((iframe) => {
+ try {
+ iframe.contentDocument.querySelectorAll(query).forEach((node) => {
+ out.push(node);
+ });
+ } catch (e) {
+ // pass on cross origin iframe errors
+ }
+ });
+ return out;
+};
+
+/**
+ * Listen for mutations on a page. If any nodes that match `selector` are added
+ * to the page, execute the function `callback` on them.
+ * Used by first-party scripts to listen for new links being added to the page
+ * and strip them of tracking code immediately.
+ */
+window.observeMutations = function(selector, callback) {
+ // Check all new nodes added by a mutation for tracking links and unwrap them
+ function onMutation(mutation) {
+ if (!mutation.addedNodes.length) {
+ return;
+ }
+ for (let node of mutation.addedNodes) {
+ // Only act on element nodes, otherwise querySelectorAll won't work
+ if (node.nodeType != Node.ELEMENT_NODE) {
+ continue;
+ }
+
+ // check all child nodes against the selector first
+ node.querySelectorAll(selector).forEach((element) => {
+ callback(element);
+ });
+
+ // then check the node itself
+ if (node.matches(selector)) {
+ callback(node);
+ }
+ }
+ }
+
+ // Set up a mutation observer with the constructed callback
+ new MutationObserver(function(mutations) {
+ mutations.forEach(onMutation);
+ }).observe(document, {childList: true, subtree: true, attributes: false, characterData: false});
+};