From 71d915eff1c27cffa4ffd4ad2cc67b5baf81720d Mon Sep 17 00:00:00 2001 From: simon Date: Wed, 23 Nov 2022 17:43:40 +0700 Subject: [PATCH] rewrite basics for observer --- extension/script.js | 293 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 274 insertions(+), 19 deletions(-) diff --git a/extension/script.js b/extension/script.js index 97dbfc5..7dedffe 100644 --- a/extension/script.js +++ b/extension/script.js @@ -21,26 +21,279 @@ function getBrowser() { }; } +const downloadIcon = ` + + + + + + + + + + + + + + + + + + + + + + +`; -function detectUrlType(url) { +const checkmarkIcon = ` + + + + + + + + + + + + + + - const videoRe = new RegExp(/^https:\/\/(www\.)?(youtube.com\/watch\?v=|youtu\.be\/)[\w-]{11}/); - if (videoRe.test(url)) { - return "video" - } - const channelRe = new RegExp(/^https:?\/\/www\.?youtube.com\/c|channel|user\/[\w-]+(\/|featured|videos)?$/); - if (channelRe.test(url)) { - return "channel" - } - const playlistRe = new RegExp(/^https:\/\/(www\.)?youtube.com\/playlist\?list=/); - if (playlistRe.test(url)) { - return "playlist" - } + + + + + + + + +` - return false + +function buildButtonDiv() { + var buttonDiv = document.createElement("div"); + buttonDiv.setAttribute("id", "ta-channel-button"); + + Object.assign(buttonDiv.style, { + display: "flex", + alignItems: "center", + backgroundColor: "#00202f", + color: "#fff", + fontSize: "1.7rem", + padding: "5px", + margin: "0 5px", + borderRadius: "8px", + }); + return buttonDiv +} + +function buildSubLink(channelContainer) { + var subLink = document.createElement("span"); + var currentLocation = window.location; + subLink.innerText = "Subscribe"; + subLink.addEventListener('click', e => { + e.preventDefault(); + console.log("subscribe to: " + currentLocation) + }); + subLink.addEventListener("mouseover", e => { + let subText + if (window.location.pathname == "/watch") { + subText = window.location.href; + } else { + subText = channelContainer.querySelector("#text").textContent; + }; + + e.target.title = "TA Subscribe: " + subText; + }); + Object.assign(subLink.style, { + padding: "5px 10px", + cursor: "pointer", + }); + + return subLink +} + +function buildSpacer() { + var spacer = document.createElement("span"); + spacer.innerText = "|"; + + return spacer +} + +function buildDlLink(channelContainer) { + var dlLink = document.createElement("span"); + var currentLocation = window.location; + dlLink.innerHTML = downloadIcon; + + dlLink.addEventListener('click', e => { + e.preventDefault(); + console.log("download: " + currentLocation) + }); + dlLink.addEventListener("mouseover", e => { + let channelName = channelContainer.querySelector("#text").textContent; + e.target.title = "TA Download: " + channelName; + }); + Object.assign(dlLink.style, { + filter: "invert()", + width: "20px", + padding: "0 10px", + cursor: "pointer", + }); + + return dlLink +} + + +function buildChannelButton(channelContainer) { + + var buttonDiv = buildButtonDiv() + + var subLink = buildSubLink(channelContainer); + buttonDiv.appendChild(subLink) + + var spacer = buildSpacer() + buttonDiv.appendChild(spacer); + + var dlLink = buildDlLink(channelContainer) + buttonDiv.appendChild(dlLink); + + return buttonDiv } +function getChannelContainers() { + var nodes = document.querySelectorAll("#inner-header-container, #owner"); + return nodes +} + +function getVideoContainers() { + var nodes = document.querySelectorAll('#title-wrapper, #title'); + return nodes +} + + +function buildVideoButton(videoContainer) { + var titleLink = videoContainer.querySelector('#video-title')?.href; + if (titleLink == null) return; + + var dlButton = document.createElement("a"); + dlButton.href = '#' + + Object.assign(dlButton.style, { + display: "flex", + alignItems: "center", + backgroundColor: "#00202f", + color: "#fff", + fontSize: "1.4rem", + textDecoration: "none", + borderRadius: "8px", + cursor: "pointer", + }); + + var dlIcon = document.createElement("span"); + dlIcon.innerHTML = downloadIcon; + Object.assign(dlIcon.style, { + filter: "invert()", + width: "20px", + padding: "10px 13px", + }); + dlButton.appendChild(dlIcon); + + dlIcon.addEventListener('click', e => { + e.preventDefault(); + let videoLink = videoContainer.querySelector('#video-title')?.href; + console.log("download: " + videoLink); + }); + dlIcon.addEventListener('mouseover', e => { + let videoTitle = videoContainer.querySelector('#video-title')?.text.trim(); + e.target.title = "TA download: " + videoTitle; + }) + + return dlButton +} + + +function ensureTALinks() { + + var channelContainerNodes = getChannelContainers() + + for (var channelContainer of channelContainerNodes) { + if (channelContainer.hasTA) continue; + var channelButton = buildChannelButton(channelContainer); + channelContainer.appendChild(channelButton); + channelContainer.hasTA = true; + } + + var videoContainerNodes = getVideoContainers() + + for (var videoContainer of videoContainerNodes) { + if (videoContainer.hasTA) continue; + var videoButton = buildVideoButton(videoContainer); + if (videoButton == null) continue; + videoContainer.appendChild(videoButton); + videoContainer.hasTA = true; + } + + // var videoContainerNodes = getVideoContainers(); + // for (var videoContainer of videoContainerNodes) { + // console.log(videoContainerNodes); + // } + +} + + +// function detectUrlType(url) { + +// const videoRe = new RegExp(/^https:\/\/(www\.)?(youtube.com\/watch\?v=|youtu\.be\/)[\w-]{11}/); +// if (videoRe.test(url)) { +// return "video" +// } +// const channelRe = new RegExp(/^https:?\/\/www\.?youtube.com\/c|channel|user\/[\w-]+(\/|featured|videos)?$/); +// if (channelRe.test(url)) { +// return "channel" +// } +// const playlistRe = new RegExp(/^https:\/\/(www\.)?youtube.com\/playlist\?list=/); +// if (playlistRe.test(url)) { +// return "playlist" +// } + +// return false + +// } + function sendUrl() { @@ -67,9 +320,11 @@ function sendUrl() { }; -document.addEventListener("yt-navigate-finish", function (event) { - setTimeout(function(){ - sendUrl(); - return false; - }, 2000); +let observer = new MutationObserver(list => { + if (list.some(i => i.type === 'childList' && i.addedNodes.length > 0)) { + console.log("observer hit") + ensureTALinks(); + } }); + +observer.observe(document.body, { attributes: false, childList: true, subtree: true });