mirror of
https://github.com/ajayyy/SponsorBlock.git
synced 2025-12-14 23:47:04 +03:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8840dba90f | ||
|
|
856dded58f | ||
|
|
1d1bd2a003 | ||
|
|
dc91ee76ca | ||
|
|
90bb9a4d02 | ||
|
|
d12d847f2f | ||
|
|
31a9de252d | ||
|
|
299cb485c3 | ||
|
|
882d462849 | ||
|
|
fc3710b37b | ||
|
|
3ac170ad01 | ||
|
|
4069545603 | ||
|
|
db9fc11f13 | ||
|
|
76667f68ec | ||
|
|
e27a287a68 | ||
|
|
ce3731774d | ||
|
|
8cbf2bb50b | ||
|
|
6f8c44b2eb |
@@ -4,5 +4,8 @@
|
||||
],
|
||||
"background": {
|
||||
"persistent": false
|
||||
}
|
||||
},
|
||||
"permissions": [
|
||||
"https://*.youtube.com/*"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "__MSG_fullName__",
|
||||
"short_name": "SponsorBlock",
|
||||
"version": "5.4.11",
|
||||
"version": "5.4.13",
|
||||
"default_locale": "en",
|
||||
"description": "__MSG_Description__",
|
||||
"homepage_url": "https://sponsor.ajay.app",
|
||||
|
||||
Submodule maze-utils updated: b7f55f39cc...b3572eaeff
10
package-lock.json
generated
10
package-lock.json
generated
@@ -13332,8 +13332,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -23348,8 +23349,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
|
||||
Submodule public/_locales updated: fc6e767fd0...9e1f32d7c6
@@ -867,3 +867,7 @@ input::-webkit-inner-spin-button {
|
||||
.sponsorThumbnailLabel:hover span {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.sponsorblock-chapter-visible {
|
||||
display: inherit !important;
|
||||
}
|
||||
@@ -13,6 +13,9 @@ window.SB = Config;
|
||||
|
||||
import Utils from "./utils";
|
||||
import { getExtensionIdsToImportFrom } from "./utils/crossExtension";
|
||||
import { isFirefoxOrSafari } from "./maze-utils";
|
||||
import { injectUpdatedScripts } from "./maze-utils/cleanup";
|
||||
import { logWarn } from "./utils/logger";
|
||||
const utils = new Utils({
|
||||
registerFirefoxContentScript,
|
||||
unregisterFirefoxContentScript
|
||||
@@ -132,6 +135,11 @@ chrome.runtime.onInstalled.addListener(function () {
|
||||
}
|
||||
}
|
||||
}, 1500);
|
||||
|
||||
// Only do this once the old version understands how to clean itself up
|
||||
if (!isFirefoxOrSafari() && chrome.runtime.getManifest().version !== "5.4.13") {
|
||||
injectUpdatedScripts().catch(logWarn);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import * as React from "react";
|
||||
import Config from "../config";
|
||||
import SbSvg from "../svg-icons/sb_svg";
|
||||
|
||||
enum CountdownMode {
|
||||
Timer,
|
||||
@@ -28,6 +29,7 @@ export interface NoticeProps {
|
||||
extraClass?: string;
|
||||
hideLogo?: boolean;
|
||||
hideRightInfo?: boolean;
|
||||
logoFill?: string;
|
||||
|
||||
// Callback for when this is closed
|
||||
closeListener: () => void;
|
||||
@@ -122,10 +124,10 @@ class NoticeComponent extends React.Component<NoticeProps, NoticeState> {
|
||||
<td className="noticeLeftIcon">
|
||||
{/* Logo */}
|
||||
{!this.props.hideLogo &&
|
||||
<img id={"sponsorSkipLogo" + this.idSuffix}
|
||||
className="sponsorSkipLogo sponsorSkipObject"
|
||||
src={chrome.extension.getURL("icons/IconSponsorBlocker256px.png")}>
|
||||
</img>
|
||||
<SbSvg
|
||||
id={"sponsorSkipLogo" + this.idSuffix}
|
||||
fill={this.props.logoFill}
|
||||
className="sponsorSkipLogo sponsorSkipObject"/>
|
||||
}
|
||||
|
||||
<span id={"sponsorSkipMessage" + this.idSuffix}
|
||||
|
||||
@@ -177,7 +177,8 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||
) : null;
|
||||
|
||||
return (
|
||||
<NoticeComponent noticeTitle={this.state.noticeTitle}
|
||||
<NoticeComponent
|
||||
noticeTitle={this.state.noticeTitle}
|
||||
amountOfPreviousNotices={this.amountOfPreviousNotices}
|
||||
showInSecondSlot={this.showInSecondSlot}
|
||||
idSuffix={this.idSuffix}
|
||||
@@ -191,6 +192,7 @@ class SkipNoticeComponent extends React.Component<SkipNoticeProps, SkipNoticeSta
|
||||
ref={this.noticeRef}
|
||||
closeListener={() => this.closeListener()}
|
||||
smaller={this.state.smaller}
|
||||
logoFill={Config.config.barTypes[this.segments[0].category].color}
|
||||
limitWidth={true}
|
||||
firstColumn={firstColumn}
|
||||
bottomRow={[...this.getMessageBoxes(), ...this.getBottomRow() ]}
|
||||
|
||||
@@ -75,7 +75,7 @@ interface SBConfig {
|
||||
allowScrollingToEdit: boolean;
|
||||
deArrowInstalled: boolean;
|
||||
showDeArrowPromotion: boolean;
|
||||
showZoomToFillError: boolean;
|
||||
showZoomToFillError2: boolean;
|
||||
|
||||
// Used to cache calculated text color info
|
||||
categoryPillColors: {
|
||||
@@ -148,6 +148,10 @@ class ConfigClass extends ProtoConfig<SBConfig, SBStorage> {
|
||||
}
|
||||
|
||||
function migrateOldSyncFormats(config: SBConfig) {
|
||||
if (config["showZoomToFillError"]) {
|
||||
chrome.storage.sync.remove("showZoomToFillError");
|
||||
}
|
||||
|
||||
if (!config["chapterCategoryAdded"]) {
|
||||
config["chapterCategoryAdded"] = true;
|
||||
|
||||
@@ -312,7 +316,7 @@ const syncDefaults = {
|
||||
allowScrollingToEdit: true,
|
||||
deArrowInstalled: false,
|
||||
showDeArrowPromotion: true,
|
||||
showZoomToFillError: true,
|
||||
showZoomToFillError2: true,
|
||||
|
||||
categoryPillColors: {},
|
||||
|
||||
|
||||
136
src/content.ts
136
src/content.ts
@@ -24,7 +24,7 @@ import SubmissionNotice from "./render/SubmissionNotice";
|
||||
import { Message, MessageResponse, VoteResponse } from "./messageTypes";
|
||||
import { SkipButtonControlBar } from "./js-components/skipButtonControlBar";
|
||||
import { getStartTimeFromUrl } from "./utils/urlParser";
|
||||
import { getControls, getExistingChapters, getHashParams, isVisible } from "./utils/pageUtils";
|
||||
import { getControls, getExistingChapters, getHashParams, isPlayingPlaylist, isVisible } from "./utils/pageUtils";
|
||||
import { CategoryPill } from "./render/CategoryPill";
|
||||
import { AnimationUtils } from "./utils/animationUtils";
|
||||
import { GenericUtils } from "./utils/genericUtils";
|
||||
@@ -45,6 +45,10 @@ import * as documentScript from "../dist/js/document.js";
|
||||
import { Tooltip } from "./render/Tooltip";
|
||||
import { isDeArrowInstalled } from "./utils/crossExtension";
|
||||
import { runCompatibilityChecks } from "./utils/compatibility";
|
||||
import { cleanPage } from "./utils/pageCleaner";
|
||||
import { addCleanupListener } from "./maze-utils/cleanup";
|
||||
|
||||
cleanPage();
|
||||
|
||||
const utils = new Utils();
|
||||
|
||||
@@ -473,6 +477,8 @@ function videoIDChange(): void {
|
||||
}
|
||||
|
||||
function handleMobileControlsMutations(): void {
|
||||
if (!chrome.runtime?.id) return;
|
||||
|
||||
updateVisibilityOfPlayerControlsButton();
|
||||
|
||||
skipButtonControlBar?.updateMobileControls();
|
||||
@@ -703,7 +709,7 @@ async function startSponsorSchedule(includeIntersectingSegments = false, current
|
||||
|
||||
// Don't pretend to be earlier than we are, could result in loops
|
||||
if (forcedSkipTime !== null && forceVideoTime > forcedSkipTime) {
|
||||
forcedSkipTime = null;
|
||||
forcedSkipTime = forceVideoTime;
|
||||
}
|
||||
|
||||
startSponsorSchedule(forcedIncludeIntersectingSegments, forcedSkipTime, forcedIncludeNonIntersectingSegments);
|
||||
@@ -812,18 +818,26 @@ function incorrectVideoCheck(videoID?: string, sponsorTime?: SponsorTime): boole
|
||||
}
|
||||
}
|
||||
|
||||
let setupVideoListenersFirstTime = true;
|
||||
function setupVideoListeners() {
|
||||
//wait until it is loaded
|
||||
getVideo().addEventListener('loadstart', videoOnReadyListener)
|
||||
getVideo().addEventListener('durationchange', durationChangeListener);
|
||||
|
||||
if (setupVideoListenersFirstTime) {
|
||||
addCleanupListener(() => {
|
||||
getVideo().removeEventListener('loadstart', videoOnReadyListener);
|
||||
getVideo().removeEventListener('durationchange', durationChangeListener);
|
||||
});
|
||||
}
|
||||
|
||||
if (!Config.config.disableSkipping) {
|
||||
switchingVideos = false;
|
||||
|
||||
let startedWaiting = false;
|
||||
let lastPausedAtZero = true;
|
||||
|
||||
getVideo().addEventListener('play', () => {
|
||||
const playListener = () => {
|
||||
// If it is not the first event, then the only way to get to 0 is if there is a seek event
|
||||
// This check makes sure that changing the video resolution doesn't cause the extension to think it
|
||||
// gone back to the begining
|
||||
@@ -854,8 +868,10 @@ function setupVideoListeners() {
|
||||
startSponsorSchedule();
|
||||
}
|
||||
|
||||
});
|
||||
getVideo().addEventListener('playing', () => {
|
||||
};
|
||||
getVideo().addEventListener('play', playListener);
|
||||
|
||||
const playingListener = () => {
|
||||
updateVirtualTime();
|
||||
lastPausedAtZero = false;
|
||||
|
||||
@@ -881,8 +897,10 @@ function setupVideoListeners() {
|
||||
|
||||
startSponsorSchedule();
|
||||
}
|
||||
});
|
||||
getVideo().addEventListener('seeking', () => {
|
||||
};
|
||||
getVideo().addEventListener('playing', playingListener);
|
||||
|
||||
const seekingListener = () => {
|
||||
lastKnownVideoTime.fromPause = false;
|
||||
|
||||
if (!getVideo().paused){
|
||||
@@ -906,20 +924,19 @@ function setupVideoListeners() {
|
||||
lastPausedAtZero = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
getVideo().addEventListener('ratechange', () => {
|
||||
};
|
||||
getVideo().addEventListener('seeking', seekingListener);
|
||||
|
||||
const rateChangeListener = () => {
|
||||
updateVirtualTime();
|
||||
clearWaitingTime();
|
||||
|
||||
startSponsorSchedule();
|
||||
});
|
||||
};
|
||||
getVideo().addEventListener('ratechange', () => rateChangeListener);
|
||||
// Used by videospeed extension (https://github.com/igrigorik/videospeed/pull/740)
|
||||
getVideo().addEventListener('videoSpeed_ratechange', () => {
|
||||
updateVirtualTime();
|
||||
clearWaitingTime();
|
||||
getVideo().addEventListener('videoSpeed_ratechange', rateChangeListener);
|
||||
|
||||
startSponsorSchedule();
|
||||
});
|
||||
const stoppedPlayback = () => {
|
||||
// Reset lastCheckVideoTime
|
||||
lastCheckVideoTime = -1;
|
||||
@@ -931,20 +948,36 @@ function setupVideoListeners() {
|
||||
|
||||
cancelSponsorSchedule();
|
||||
};
|
||||
getVideo().addEventListener('pause', () => {
|
||||
const pauseListener = () => {
|
||||
lastKnownVideoTime.fromPause = true;
|
||||
|
||||
stoppedPlayback();
|
||||
});
|
||||
getVideo().addEventListener('waiting', () => {
|
||||
};
|
||||
getVideo().addEventListener('pause', pauseListener);
|
||||
const waitingListener = () => {
|
||||
logDebug("[SB] Not skipping due to buffering");
|
||||
startedWaiting = true;
|
||||
|
||||
stoppedPlayback();
|
||||
});
|
||||
};
|
||||
getVideo().addEventListener('waiting', waitingListener);
|
||||
|
||||
startSponsorSchedule();
|
||||
|
||||
if (setupVideoListenersFirstTime) {
|
||||
addCleanupListener(() => {
|
||||
getVideo().removeEventListener('play', playListener);
|
||||
getVideo().removeEventListener('playing', playingListener);
|
||||
getVideo().removeEventListener('seeking', seekingListener);
|
||||
getVideo().removeEventListener('ratechange', rateChangeListener);
|
||||
getVideo().removeEventListener('videoSpeed_ratechange', rateChangeListener);
|
||||
getVideo().removeEventListener('pause', pauseListener);
|
||||
getVideo().removeEventListener('waiting', waitingListener);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
setupVideoListenersFirstTime = false;
|
||||
}
|
||||
|
||||
function updateVirtualTime() {
|
||||
@@ -1356,18 +1389,20 @@ async function channelIDChange(channelIDInfo: ChannelIDInfo) {
|
||||
}
|
||||
|
||||
function videoElementChange(newVideo: boolean): void {
|
||||
if (newVideo) {
|
||||
setupVideoListeners();
|
||||
setupSkipButtonControlBar();
|
||||
setupCategoryPill();
|
||||
}
|
||||
|
||||
checkPreviewbarState();
|
||||
|
||||
// Incase the page is still transitioning, check again in a few seconds
|
||||
setTimeout(checkPreviewbarState, 100);
|
||||
setTimeout(checkPreviewbarState, 1000);
|
||||
setTimeout(checkPreviewbarState, 5000);
|
||||
waitFor(() => Config.isReady()).then(() => {
|
||||
if (newVideo) {
|
||||
setupVideoListeners();
|
||||
setupSkipButtonControlBar();
|
||||
setupCategoryPill();
|
||||
}
|
||||
|
||||
checkPreviewbarState();
|
||||
|
||||
// Incase the page is still transitioning, check again in a few seconds
|
||||
setTimeout(checkPreviewbarState, 100);
|
||||
setTimeout(checkPreviewbarState, 1000);
|
||||
setTimeout(checkPreviewbarState, 5000);
|
||||
})
|
||||
}
|
||||
|
||||
function checkPreviewbarState(): void {
|
||||
@@ -1587,8 +1622,10 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||
// for some reason you also can't skip to 1 second before the end
|
||||
if (v.loop && v.duration > 1 && skipTime[1] >= v.duration - 1) {
|
||||
v.currentTime = 0;
|
||||
} else if (navigator.vendor === "Apple Computer, Inc." && v.duration > 1 && skipTime[1] >= v.duration) {
|
||||
} else if (v.duration > 1 && skipTime[1] >= v.duration
|
||||
&& (navigator.vendor === "Apple Computer, Inc." || isPlayingPlaylist())) {
|
||||
// MacOS will loop otherwise #1027
|
||||
// Sometimes playlists loop too #1804
|
||||
v.currentTime = v.duration - 0.001;
|
||||
} else {
|
||||
if (inMuteSegment(skipTime[1], true)) {
|
||||
@@ -1619,9 +1656,10 @@ function skipToTime({v, skipTime, skippingSegments, openNotice, forceAutoSkip, u
|
||||
beep.play();
|
||||
beep.addEventListener("ended", () => {
|
||||
navigator.mediaSession.metadata = null;
|
||||
setTimeout(() =>
|
||||
navigator.mediaSession.metadata = oldMetadata
|
||||
);
|
||||
setTimeout(() => {
|
||||
navigator.mediaSession.metadata = oldMetadata;
|
||||
beep.remove();
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2331,11 +2369,21 @@ function previousChapter(): void {
|
||||
function addHotkeyListener(): void {
|
||||
document.addEventListener("keydown", hotkeyListener);
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
const onLoad = () => {
|
||||
// Allow us to stop propagation to YouTube by being deeper
|
||||
document.removeEventListener("keydown", hotkeyListener);
|
||||
document.body.addEventListener("keydown", hotkeyListener);
|
||||
});
|
||||
|
||||
addCleanupListener(() => {
|
||||
document.body.removeEventListener("keydown", hotkeyListener);
|
||||
});
|
||||
};
|
||||
|
||||
if (document.readyState === "complete") {
|
||||
onLoad();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", onLoad);
|
||||
}
|
||||
}
|
||||
|
||||
function hotkeyListener(e: KeyboardEvent): void {
|
||||
@@ -2392,7 +2440,7 @@ function hotkeyListener(e: KeyboardEvent): void {
|
||||
*/
|
||||
function addCSS() {
|
||||
if (!isFirefoxOrSafari() && Config.config.invidiousInstances.includes(new URL(document.URL).hostname)) {
|
||||
window.addEventListener("DOMContentLoaded", () => {
|
||||
const onLoad = () => {
|
||||
const head = document.getElementsByTagName("head")[0];
|
||||
|
||||
for (const file of utils.css) {
|
||||
@@ -2404,7 +2452,13 @@ function addCSS() {
|
||||
|
||||
head.appendChild(fileref);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (document.readyState === "complete") {
|
||||
onLoad();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", onLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2489,7 +2543,9 @@ function setCategoryColorCSSVariables() {
|
||||
if (!styleContainer) {
|
||||
styleContainer = document.createElement("style");
|
||||
styleContainer.id = "sbCategoryColorStyle";
|
||||
document.head.appendChild(styleContainer)
|
||||
|
||||
const head = (document.head || document.documentElement);
|
||||
head.appendChild(styleContainer)
|
||||
}
|
||||
|
||||
let css = ":root {"
|
||||
|
||||
@@ -4,7 +4,11 @@ import { showDonationLink } from "./utils/configUtils";
|
||||
|
||||
import { waitFor } from "./maze-utils";
|
||||
|
||||
window.addEventListener('DOMContentLoaded', init);
|
||||
if (document.readyState === "complete") {
|
||||
init();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
localizeHtmlPage();
|
||||
|
||||
@@ -13,6 +13,7 @@ import { DEFAULT_CATEGORY, shortCategoryName } from "../utils/categoryUtils";
|
||||
import { normalizeChapterName } from "../utils/exporter";
|
||||
import { getFormattedTimeToSeconds } from "../maze-utils/formating";
|
||||
import { findValidElement } from "../maze-utils/dom";
|
||||
import { addCleanupListener } from "../maze-utils/cleanup";
|
||||
|
||||
const TOOLTIP_VISIBLE_CLASS = 'sponsorCategoryTooltipVisible';
|
||||
const MIN_CHAPTER_SIZE = 0.003;
|
||||
@@ -201,6 +202,10 @@ class PreviewBar {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
addCleanupListener(() => {
|
||||
observer.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
private setTooltipTitle(segment: PreviewBarSegment, tooltip: HTMLElement): void {
|
||||
@@ -626,6 +631,11 @@ class PreviewBar {
|
||||
childListObserver.observe(this.originalChapterBar, {
|
||||
childList: true
|
||||
});
|
||||
|
||||
addCleanupListener(() => {
|
||||
attributeObserver.disconnect();
|
||||
childListObserver.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
private updateChapterAllMutation(originalChapterBar: HTMLElement, progressBar: HTMLElement, firstUpdate = false): void {
|
||||
@@ -774,10 +784,11 @@ class PreviewBar {
|
||||
if (!Config.config.showSegmentNameInChapterBar
|
||||
|| ((!segments || segments.length <= 0) && submittingSegments?.length <= 0)) {
|
||||
const chaptersContainer = this.getChaptersContainer();
|
||||
const chapterButton = this.getChapterButton(chaptersContainer);
|
||||
if (chapterButton && chapterButton.classList.contains("ytp-chapter-container-disabled")) {
|
||||
chaptersContainer.style.display = "none";
|
||||
}
|
||||
chaptersContainer.querySelector(".sponsorChapterText")?.remove();
|
||||
const chapterTitle = chaptersContainer.querySelector(".ytp-chapter-title-content") as HTMLDivElement;
|
||||
|
||||
chapterTitle.style.removeProperty("display");
|
||||
chaptersContainer.classList.remove("sponsorblock-chapter-visible");
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -802,7 +813,7 @@ class PreviewBar {
|
||||
|
||||
if (chaptersContainer) {
|
||||
if (segments.length > 0) {
|
||||
chaptersContainer.style.removeProperty("display");
|
||||
chaptersContainer.classList.add("sponsorblock-chapter-visible");
|
||||
|
||||
const chosenSegment = segments.sort((a, b) => {
|
||||
if (a.actionType === ActionType.Chapter && b.actionType !== ActionType.Chapter) {
|
||||
@@ -819,11 +830,11 @@ class PreviewBar {
|
||||
chapterButton.disabled = false;
|
||||
|
||||
const chapterTitle = chaptersContainer.querySelector(".ytp-chapter-title-content") as HTMLDivElement;
|
||||
chapterTitle.innerText = "";
|
||||
chapterTitle.style.display = "none";
|
||||
|
||||
const chapterCustomText = (chapterTitle.querySelector(".sponsorChapterText") || (() => {
|
||||
const chapterCustomText = (chapterTitle.parentElement.querySelector(".sponsorChapterText") || (() => {
|
||||
const elem = document.createElement("div");
|
||||
chapterTitle.appendChild(elem);
|
||||
chapterTitle.parentElement.insertBefore(elem, chapterTitle);
|
||||
elem.classList.add("sponsorChapterText");
|
||||
return elem;
|
||||
})()) as HTMLDivElement;
|
||||
@@ -854,11 +865,10 @@ class PreviewBar {
|
||||
} else {
|
||||
chaptersContainer.querySelector(".sponsorChapterText")?.remove();
|
||||
const chapterTitle = chaptersContainer.querySelector(".ytp-chapter-title-content") as HTMLDivElement;
|
||||
if (chapterTitle.innerText === "") {
|
||||
chaptersContainer.style.display = "none";
|
||||
} else {
|
||||
chaptersContainer.style.removeProperty("display");
|
||||
}
|
||||
|
||||
chapterTitle.style.removeProperty("display");
|
||||
chaptersContainer.classList.remove("sponsorblock-chapter-visible");
|
||||
|
||||
this.chapterVote.setVisibility(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,11 @@ let embed = false;
|
||||
const categoryChoosers: CategoryChooser[] = [];
|
||||
const unsubmittedVideos: UnsubmittedVideos[] = [];
|
||||
|
||||
window.addEventListener('DOMContentLoaded', init);
|
||||
if (document.readyState === "complete") {
|
||||
init();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
localizeHtmlPage();
|
||||
|
||||
@@ -7,7 +7,11 @@ const utils = new Utils();
|
||||
// Probably due to cyclic dependencies
|
||||
Config.config;
|
||||
|
||||
window.addEventListener('DOMContentLoaded', init);
|
||||
if (document.readyState === "complete") {
|
||||
init();
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", init);
|
||||
}
|
||||
|
||||
async function init() {
|
||||
localizeHtmlPage();
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Category, SegmentUUID, SponsorTime } from "../types";
|
||||
import { Tooltip } from "./Tooltip";
|
||||
import { waitFor } from "../maze-utils";
|
||||
import { getYouTubeTitleNode } from "../maze-utils/elements";
|
||||
import { addCleanupListener } from "../maze-utils/cleanup";
|
||||
|
||||
const id = "categoryPill";
|
||||
|
||||
@@ -24,6 +25,12 @@ export class CategoryPill {
|
||||
|
||||
constructor() {
|
||||
this.ref = React.createRef();
|
||||
|
||||
addCleanupListener(() => {
|
||||
if (this.mutationObserver) {
|
||||
this.mutationObserver.disconnect();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async attachToPage(onMobileYouTube: boolean, onInvidious: boolean,
|
||||
|
||||
@@ -47,6 +47,7 @@ export default class GenericNotice {
|
||||
const referenceNode = options.referenceNode ?? utils.findReferenceNode();
|
||||
|
||||
this.noticeElement = document.createElement("div");
|
||||
this.noticeElement.className = "sponsorSkipNoticeContainer";
|
||||
this.noticeElement.id = "sponsorSkipNoticeContainer" + idSuffix;
|
||||
|
||||
referenceNode.prepend(this.noticeElement);
|
||||
|
||||
@@ -38,6 +38,7 @@ class SkipNotice {
|
||||
idSuffix += amountOfPreviousNotices;
|
||||
|
||||
this.noticeElement = document.createElement("div");
|
||||
this.noticeElement.className = "sponsorSkipNoticeContainer";
|
||||
this.noticeElement.id = "sponsorSkipNoticeContainer" + idSuffix;
|
||||
|
||||
referenceNode.prepend(this.noticeElement);
|
||||
|
||||
55
src/svg-icons/sb_svg.tsx
Normal file
55
src/svg-icons/sb_svg.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import * as React from "react";
|
||||
|
||||
export interface SbIconProps {
|
||||
id?: string;
|
||||
fill?: string;
|
||||
className?: string;
|
||||
width?: string;
|
||||
height?: string;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export default function SbSvg({
|
||||
id = "",
|
||||
fill = "#ff0000",
|
||||
className = "",
|
||||
onClick
|
||||
}: SbIconProps): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 565.15 568"
|
||||
id={id}
|
||||
className={className}
|
||||
onClick={() => onClick?.() } >
|
||||
<g
|
||||
id="Layer_2"
|
||||
data-name="Layer 2">
|
||||
<g
|
||||
id="Layer_1-2"
|
||||
data-name="Layer 1"
|
||||
style={{
|
||||
fill
|
||||
}}>
|
||||
<path
|
||||
d="M282.58,568a65,65,0,0,1-34.14-9.66C95.41,463.94,2.54,300.46,0,121A64.91,64.91,0,0,1,34,62.91a522.56,522.56,0,0,1,497.16,0,64.91,64.91,0,0,1,34,58.12c-2.53,179.43-95.4,342.91-248.42,437.3A65,65,0,0,1,282.58,568Zm0-548.31A502.24,502.24,0,0,0,43.4,80.22a45.27,45.27,0,0,0-23.7,40.53c2.44,172.67,91.81,330,239.07,420.83a46.19,46.19,0,0,0,47.61,0C453.64,450.73,543,293.42,545.45,120.75a45.26,45.26,0,0,0-23.7-40.54A502.26,502.26,0,0,0,282.58,19.69Z"
|
||||
id="path8"
|
||||
style={{
|
||||
fill
|
||||
}} />
|
||||
<path
|
||||
style={{
|
||||
fill
|
||||
}}
|
||||
d="M 284.70508 42.693359 A 479.9 479.9 0 0 0 54.369141 100.41992 A 22.53 22.53 0 0 0 42.669922 120.41992 C 45.069922 290.25992 135.67008 438.63977 270.83008 522.00977 A 22.48 22.48 0 0 0 294.32031 522.00977 C 429.48031 438.63977 520.08047 290.25992 522.48047 120.41992 A 22.53 22.53 0 0 0 510.7793 100.41992 A 479.9 479.9 0 0 0 284.70508 42.693359 z M 220.41016 145.74023 L 411.2793 255.93945 L 220.41016 366.14062 L 220.41016 145.74023 z "
|
||||
id="path10" />
|
||||
</g>
|
||||
</g>
|
||||
<polygon style={{
|
||||
fill: "#fff"
|
||||
}}
|
||||
points="411.28 255.94 220.41 145.74 220.41 366.14 411.28 255.94"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import Config from "../config";
|
||||
|
||||
export function runCompatibilityChecks() {
|
||||
if (Config.config.showZoomToFillError) {
|
||||
if (Config.config.showZoomToFillError2 && document.URL.includes("watch?v=")) {
|
||||
setTimeout(() => {
|
||||
const zoomToFill = document.querySelector(".zoomtofillBtn");
|
||||
|
||||
@@ -9,7 +9,7 @@ export function runCompatibilityChecks() {
|
||||
alert(chrome.i18n.getMessage("zoomToFillUnsupported"));
|
||||
}
|
||||
|
||||
Config.config.showZoomToFillError = false;
|
||||
Config.config.showZoomToFillError2 = false;
|
||||
}, 10000);
|
||||
}
|
||||
}
|
||||
8
src/utils/pageCleaner.ts
Normal file
8
src/utils/pageCleaner.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export function cleanPage() {
|
||||
// For live-updates
|
||||
if (document.readyState === "complete") {
|
||||
for (const element of document.querySelectorAll("#categoryPillParent, .playerButton, .sponsorThumbnailLabel, #submissionNoticeContainer, .sponsorSkipNoticeContainer, #sponsorBlockPopupContainer, .skipButtonControlBarContainer, #previewbar, .sponsorBlockChapterBar")) {
|
||||
element.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,4 +93,8 @@ export function getExistingChapters(currentVideoID: VideoID, duration: number):
|
||||
}
|
||||
|
||||
return chapters;
|
||||
}
|
||||
|
||||
export function isPlayingPlaylist() {
|
||||
return !!document.URL.includes("&list=");
|
||||
}
|
||||
Reference in New Issue
Block a user