Skip to content

Commit

Permalink
added support main reddit frontend (#732)
Browse files Browse the repository at this point in the history
  • Loading branch information
ilyhalight committed Nov 12, 2024
1 parent b30a3dd commit 0ca97ef
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 124 deletions.
Binary file modified bun.lockb
Binary file not shown.
8 changes: 4 additions & 4 deletions dist/vot-min.user.js

Large diffs are not rendered by default.

172 changes: 104 additions & 68 deletions dist/vot.user.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
// @match *://*.youku.com/*
// @match *://*.archive.org/*
// @match *://*.patreon.com/*
// @match *://old.reddit.com/*
// @match *://*.reddit.com/*
// @match *://*.kodik.info/*
// @match *://*.kodik.biz/*
// @match *://*.kodik.cc/*
Expand Down Expand Up @@ -2470,13 +2470,23 @@ const sitesCoursehunterLike = ["coursehunter.net", "coursetrain.net"];
needExtraData: true,
},
{
additionalData: "old",
host: VideoService.reddit,
url: "stub",
match: /^(www.|new.|old.)?reddit.com$/,
match: /^old.reddit.com$/,
selector: ".reddit-video-player-root",
needExtraData: true,
needBypassCSP: true,
},
{
host: VideoService.reddit,
url: "stub",
match: /^(www.|new.)?reddit.com$/,
selector: "div[slot=post-media-container]",
shadowRoot: true,
needExtraData: true,
needBypassCSP: true,
},
{
host: VideoService.kick,
url: "https://kick.com/",
Expand Down Expand Up @@ -3425,11 +3435,13 @@ class RedditHelper extends BaseHelper {
API_ORIGIN = "https://www.reddit.com";
async getVideoData(videoId) {
try {
const contentUrl = document
.querySelector("[data-hls-url]")
?.dataset
.hlsUrl
.replaceAll("&", "&");
const contentUrl = this.service.additionalData === "old" ?
document
.querySelector("[data-hls-url]")
?.dataset
.hlsUrl
.replaceAll("&", "&") :
document.querySelector("shreddit-player-2")?.src;
if (!contentUrl) {
throw new VideoHelperError("Failed to find content url");
}
Expand Down Expand Up @@ -7503,11 +7515,6 @@ const filterVideoNodes = (nodes) => {
for (let j = 0; j < videos.length; j++) {
result.push(videos[j]);
}
} else if (node.shadowRoot) {
const shadowVideos = node.shadowRoot.querySelectorAll("video");
for (let k = 0; k < shadowVideos.length; k++) {
result.push(shadowVideos[k]);
}
}
}
return result;
Expand Down Expand Up @@ -7562,10 +7569,23 @@ class VideoObserver {
this.onVideoRemoved = new EventImpl();

this.observer = new MutationObserver(this.handleMutations);
this.intersectionObserver = new IntersectionObserver(
this.handleIntersections,
{ threshold: 0.1 },
);
this.patchAttachShadow();
}

patchAttachShadow() {
const originalAttachShadow = Element.prototype.attachShadow;
const self = this;
Element.prototype.attachShadow = function (...args) {
const shadowRoot = originalAttachShadow.apply(this, args);
self.searchInRoot(shadowRoot);
self.observeShadowRoot(shadowRoot);
return shadowRoot;
};
}

observeShadowRoot(shadowRoot) {
const shadowObserver = new MutationObserver(this.handleMutations);
shadowObserver.observe(shadowRoot, { childList: true, subtree: true });
}

handleMutations = (mutationsList) => {
Expand All @@ -7590,65 +7610,57 @@ class VideoObserver {
);
};

handleIntersections = (entries) => {
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
if (entry.isIntersecting) {
this.handleIntersectingVideo(entry.target);
}
searchInRoot(root) {
const findVideosInRoot = (currentRoot) => {
const videos = new Set();

const searchNode = (node) => {
if (node instanceof HTMLVideoElement) {
videos.add(node);
}

if (node instanceof Element) {
const directVideos = node.querySelectorAll("video");
for (let i = 0; i < directVideos.length; i++) {
videos.add(directVideos[i]);
}

const children = node.children;
if (children) {
for (let i = 0; i < children.length; i++) {
searchNode(children[i]);
}
}
}
};

searchNode(currentRoot);
return Array.from(videos);
};

const foundVideos = findVideosInRoot(root);
for (let i = 0; i < foundVideos.length; i++) {
this.checkAndHandleVideo(foundVideos[i]);
}
};
}

enable() {
this.observer.observe(document, { childList: true, subtree: true });
const videos = this.getAllVideoEls();
for (let i = 0; i < videos.length; i++) {
this.checkAndHandleVideo(videos[i]);

const regularVideos = document.querySelectorAll("video");
for (let i = 0; i < regularVideos.length; i++) {
this.checkAndHandleVideo(regularVideos[i]);
}
}

disable() {
this.observer.disconnect();
this.intersectionObserver.disconnect();
}

getAllVideoEls() {
const videos = document.querySelectorAll("video");
if (videos.length) return Array.from(videos);

// Use it only if we don't find videos
// It takes a long time to complete
const videoElements = new Set();
const traverseShadowRoot = (root) => {
if (!root) return;
const shadowVideos = root.querySelectorAll("video");
for (let i = 0; i < shadowVideos.length; i++) {
videoElements.add(shadowVideos[i]);
}
const shadowElements = root.querySelectorAll("*");
for (let i = 0; i < shadowElements.length; i++) {
if (shadowElements[i].shadowRoot)
traverseShadowRoot(shadowElements[i].shadowRoot);
}
};

const allElements = document.querySelectorAll("*");
for (let i = 0; i < allElements.length; i++) {
if (allElements[i].shadowRoot)
traverseShadowRoot(allElements[i].shadowRoot);
}

return Array.from(videoElements);
}

checkAndHandleVideo = (video) => {
if (this.videoCache.has(video)) return;
this.videoCache.add(video);
this.intersectionObserver.observe(video);
};

handleIntersectingVideo = (video) => {
this.intersectionObserver.unobserve(video);
if (isAdVideo(video) || isMutedVideo(video)) {
debug.log("The promotional/muted video was ignored", video);
return;
Expand Down Expand Up @@ -11515,6 +11527,31 @@ class VideoHandler {
const videoObserver = new VideoObserver();
const videosWrappers = new WeakMap();

/**
* Finds the parent element of a given element that matches a specified selector.
*
* @param {HTMLElement} el - The element to start searching from.
* @param {string} selector - The CSS selector to match.
* @returns {HTMLElement|null} The parent element that matches the selector, or null if no match is found.
*/
function climb(el, selector) {
if (!el || !selector) {
return null;
}

if (el instanceof Document) {
return el.querySelector(selector);
}

const foundEl = el.closest(selector);
if (foundEl) {
return foundEl;
}

const root = el.getRootNode();
return climb(root instanceof Document ? root : root.host, selector);
}

/**
* Finds the container element for a given video element and site object.
*
Expand All @@ -11523,17 +11560,16 @@ const videosWrappers = new WeakMap();
* @return {Object|null} The container element or null if not found.
*/
function findContainer(site, video) {
debug.log("findContainer", site, video);
if (site.shadowRoot) {
let container = site.selector
? Array.from(document.querySelectorAll(site.selector)).find((e) =>
e.shadowRoot.contains(video),
)
: video.parentElement;
return container && container.shadowRoot
? container.parentElement
: container;
let container = climb(video, site.selector);

debug.log("findContainer with site.shadowRoot", container);
return container ?? video.parentElement;
}

debug.log("findContainer without shadowRoot");

const browserVersion = browserInfo.browser.version?.split(".")?.[0];
if (
site.selector?.includes(":not") &&
Expand Down
Loading

0 comments on commit 0ca97ef

Please sign in to comment.