diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eed2341 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +web-ext-artifacts/ +.web-extension-id diff --git a/background.js b/background.js new file mode 100644 index 0000000..d5bc742 --- /dev/null +++ b/background.js @@ -0,0 +1,49 @@ +// Storage init +browser.runtime.onInstalled.addListener(function() { + browser.storage.sync.set({ + url: "https://invidious.snopyta.org" + }); +}); + + +// Url format +function getVideoToken(url) { + // https://regexr.com/531i0 + var rx = /(?:\/|%3D|v=|vi=)([0-9A-z-_]{11})(?:[%#?&]|$)/g; + var arr = rx.exec(url); + return arr[1]; +} + +function cleanToken(token) { + let t = token; + // https://regexr.com/531i0 + t = t.replace(/^(vi=|v=)/,""); + t = t.replace(/^(\/)/,""); + t = t.replace(/^(%3D)/,""); + t = t.replace(/(&|%)$/,""); + return t; +} + + +// Links click event handling +browser.runtime.onMessage.addListener(function(message) { + let url = message.youtubeUrl; + const name = message.targetName; + browser.storage.sync.get("url").then(function(item) { + const subst = item.url + `/watch?v=`; + let token = getVideoToken(url) + const cleanedToken = cleanToken(token) + url = url.replace(/.*\/watch\?v=/gm, subst); + + if (name != "_self") { + browser.tabs.create( + {active: true, url: url} + ); + } else { + browser.tabs.update( + {url: url, loadReplace: true} + ) + } + console.log('Youtube to invidious is redirecting you to invidious') + }) +}); \ No newline at end of file diff --git a/icons/48.png b/icons/48.png new file mode 100644 index 0000000..0548069 Binary files /dev/null and b/icons/48.png differ diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..12ae35a --- /dev/null +++ b/manifest.json @@ -0,0 +1,35 @@ +{ + + "manifest_version": 2, + "name": "Youtube to invidious", + "version": "0.1", + + "description": "Change every youtube link to an invidious one", + + "icons": { + "48": "icons/48.png" + }, + "web_accessible_resources": ["icons/48.png"], + "content_scripts": [ + { + "matches": [""], + "js": ["to-invidious.js"] + } + ], + "background": { + "scripts": ["background.js"] + }, + "options_ui": { + "page": "options.html" + }, + + "permissions": ["storage", "tabs"], + + "browser_specific_settings": { + "gecko": { + "id": "1f63659fb336c2593b0f48375566cf66c5d8e12d@amine-louveau.fr" + } + } + +} + diff --git a/options.html b/options.html new file mode 100644 index 0000000..fa58e01 --- /dev/null +++ b/options.html @@ -0,0 +1,20 @@ + + + + + + + + + +
+ + +
+ + + + + + + diff --git a/options.js b/options.js new file mode 100644 index 0000000..c46dfdb --- /dev/null +++ b/options.js @@ -0,0 +1,23 @@ +function saveOptions(e) { + e.preventDefault(); + browser.storage.sync.set({ + url: document.querySelector("#url").value + }); +} + +function restoreOptions() { + + function setCurrentChoice(result) { + document.querySelector("#url").value = result.url; + } + + function onError(error) { + console.log(`Error: ${error}`); + } + + let getting = browser.storage.sync.get("url"); + getting.then(setCurrentChoice, onError); +} + +document.addEventListener("DOMContentLoaded", restoreOptions); +document.querySelector("form").addEventListener("submit", saveOptions); diff --git a/to-invidious.js b/to-invidious.js new file mode 100644 index 0000000..a6f01ce --- /dev/null +++ b/to-invidious.js @@ -0,0 +1,11 @@ +window.addEventListener("click", (e) => { + var target = e.target; + while ((target.tagName != "A" || !target.href) && target.parentNode) { + target = target.parentNode; + } + if (target.tagName != "A" || target.href.indexOf('youtube') == -1) + return; + + e.preventDefault(); + browser.runtime.sendMessage({"youtubeUrl": target.href, "targetName": (target.attributes.target != null ? target.attributes.target.nodeValue : '_self')}); +}); \ No newline at end of file