diff --git a/extension/manifest.json b/extension/manifest.json index bf1df3c..d5d8cfe 100644 --- a/extension/manifest.json +++ b/extension/manifest.json @@ -20,7 +20,7 @@ "scripts": ["dist/background.js", "dist/vendors.js"] }, "content_scripts": [{ - "matches": ["*://*.youtube.com/*"], + "matches": ["*://*.youtube.com/*", "*://*.invidio.us/*"], "js": ["dist/youtube.js", "dist/vendors.js"] }, { "matches": ["https://*/videos/watch/*"], diff --git a/src/background.ts b/src/background.ts index fd414b2..06ee3cc 100644 --- a/src/background.ts +++ b/src/background.ts @@ -18,7 +18,6 @@ import * as _ from 'lodash/fp'; import * as browser from 'webextension-polyfill'; import { MessageKind, RedirectType } from './types'; -import constants from './constants'; import Preferences from './preferences'; import * as InvidiousAPI from './invidious-api'; import * as PeertubeAPI from './peertube-api'; @@ -33,25 +32,27 @@ const getTitle = async (id: string) => { } /** - * Redirect Youtube without loading it if the video is found and preferences lAHhDKzReKBQKj3R + * Redirect Youtube without loading it if the video is found and preferences * set on automatic redirection. */ const redirectYoutube = async (r) => { const prefs = await Preferences.getPreferences(); if (prefs.redirectYoutube == RedirectType.Auto) { - const query = new URLSearchParams(r.url.substring(r.url.indexOf('?') + 1)); + const isEmbed = _.contains('embed', r.url); - const title = await getTitle(query.get('v')); + const query = isEmbed + ? r.url.substr(r.url.lastIndexOf('/') + 1, 11) + : r.url.substr(r.url.indexOf('?v=') + 3, 11); + + const title = await getTitle(query); const video = await searchByName(title); - const url = getPeertubeVideoURL(video, prefs); + const url = getPeertubeVideoURL(video, prefs, { isEmbed }); return { redirectUrl: url }; } - - throw new Error('No results.'); }; /** @@ -70,18 +71,18 @@ const redirectPeertube = async (r) => { const id = _.last(_.split('/', r.url)); const video: any = await PeertubeAPI.getVideo(id); + const isEmbed = _.contains('embed', r.url); + if (prefs.openInOriginalInstance && video.account.host === hostname) { return {}; // Don't redirect if original instance } - const url = getPeertubeVideoURL(video, prefs); + const url = getPeertubeVideoURL(video, prefs, { isEmbed }); return { redirectUrl: url }; } - - throw new Error('No results.'); }; const searchByName = query => new Promise(async (resolve, reject) => { @@ -97,7 +98,7 @@ const searchByName = query => new Promise(async (resolve, reject) => { }); }); -browser.runtime.onMessage.addListener(function(message, sender) { +browser.runtime.onMessage.addListener(function(message) { switch (message.kind) { case MessageKind.SearchByName: return searchByName(message.query); @@ -108,12 +109,12 @@ browser.runtime.onMessage.addListener(function(message, sender) { browser.webRequest.onBeforeRequest.addListener( redirectYoutube, - { urls: ['*://*.youtube.com/watch?v=*'] }, + { urls: ['*://*.youtube.com/watch?v=*', '*://*.youtube.com/embed/*', '*://*.invidio.us/watch?v=*', '*://*.invidio.us/embed/*'] }, ['blocking'] ); browser.webRequest.onBeforeRequest.addListener( redirectPeertube, - { urls: ['*://*/videos/watch/*'] }, + { urls: ['*://*/videos/watch/*', '*://*/videos/embed/*'] }, ['blocking'] ); diff --git a/src/util.ts b/src/util.ts index 502d097..3027bc4 100644 --- a/src/util.ts +++ b/src/util.ts @@ -4,8 +4,10 @@ export function htmlToElement(html: string): Element { return template.content.firstElementChild; } -export function getPeertubeVideoURL(video, prefs) { - return `https://${getPeertubeHost(video.account.host, prefs)}/videos/watch/${video.uuid}` +export function getPeertubeVideoURL(video, prefs, { isEmbed = false } = {}) { + const endpoint = isEmbed ? 'embed' : 'watch'; + + return `https://${getPeertubeHost(video.account.host, prefs)}/videos/${endpoint}/${video.uuid}`; } export function getPeertubeHost(host, prefs) { diff --git a/src/youtube.ts b/src/youtube.ts index 7fe2f57..b99148d 100644 --- a/src/youtube.ts +++ b/src/youtube.ts @@ -22,7 +22,7 @@ import { MessageKind, RedirectType } from './types'; import Preferences from './preferences' const thumbnailURL = (host, path) => `https://${host}${path}`; - +const isYouTube = _.contains('youtube.com', document.location.hostname); const LINK_ID = 'peertube-link'; function searchVideo(query) { @@ -43,7 +43,9 @@ async function peertubeify(query: String) { const link = videoLink(url, video); removeVideoLink(); - document.querySelector('ytd-app').appendChild(link); + + const querySelector = isYouTube ? 'ytd-app' : 'body'; + document.querySelector(querySelector).appendChild(link); }).catch(removeVideoLink); break; } @@ -53,23 +55,32 @@ async function peertubeify(query: String) { } } -const throttledPeertubeify = _.throttle(1000, peertubeify); -const observer = new MutationObserver(function(mutationsList) { - for (const mutation of mutationsList) { - if ((mutation.target as Element).classList.contains('ytp-title-link')) { - for (const node of mutation.addedNodes) { - if (node.nodeType == Node.TEXT_NODE) { - throttledPeertubeify(node.textContent); +if (isYouTube) { + const throttledPeertubeify = _.throttle(1000, peertubeify); + const observer = new MutationObserver(function(mutationsList) { + for (const mutation of mutationsList) { + if ((mutation.target as Element).classList.contains('ytp-title-link')) { + for (const node of mutation.addedNodes) { + if (node.nodeType == Node.TEXT_NODE) { + throttledPeertubeify(node.textContent); + } } } } - } -}); + }); -observer.observe(document.body, { - childList: true, - subtree: true, -}) + observer.observe(document.body, { + childList: true, + subtree: true, + }) +} else { + peertubeify(document.title.substring(0, document.title.indexOf(' - Invidious'))); +} + +const backgroundColor = isYouTube ? 'var(--yt-swatch-primary)' : '#fff'; +const buttonColor = isYouTube ? 'var(--yt-swatch-text)' : '#000'; +const textColor = isYouTube ? 'var(--yt-primary-text-color)' : '#000'; +const hostSize = isYouTube ? '1.4rem' : '0.9rem'; const videoLink = (url, video) => htmlToElement(`