Add 27.0 js src

This commit is contained in:
√(noham)²
2026-09-17 13:47:07 +02:00
parent c768a1667c
commit 897293bc5f
39 changed files with 24598 additions and 1 deletions

View File

@@ -0,0 +1,202 @@
//# sourceURL=__InjectedScript_YouTubeCaptionQuirk.js
(function () {
"use strict";
class CaptionMirror {
static _instances = new WeakMap();
constructor(video) {
let oldMirror = CaptionMirror._instances.get(video);
if (oldMirror) {
oldMirror.invalidate();
CaptionMirror._instances.delete(video);
}
CaptionMirror._instances.set(video, this);
this._video = video;
this._player = video.parentElement.parentElement;
this._captionWindowSelector = ".ytp-caption-window-container";
this._mirrorTrack = video.addTextTrack("forced", "YouTube Captions");
this._mirrorTrack.mode = "hidden";
this._captionObserver = null;
this._waitObserver = null;
this._onCaptionsTrackListChanged = () => this._syncTrackList();
this._onCaptionsChanged = () => this._syncTrackList();
this._player.addEventListener(
"onCaptionsTrackListChanged",
this._onCaptionsTrackListChanged,
);
this._player.addEventListener("captionschanged", this._onCaptionsChanged);
navigator.mediaSession.setActionHandler("togglecaptions", (details) =>
this._handleMediaSessionAction(details),
);
navigator.mediaSession.setActionHandler("selectcaptiontrack", (details) =>
this._handleMediaSessionAction(details),
);
this._onPresentationModeChanged = () =>
this._handlePresentationModeChanged();
this._video.addEventListener(
"webkitpresentationmodechanged",
this._onPresentationModeChanged,
);
this._attachCaptionWindowObserver();
this._syncTrackList();
}
invalidate() {
if (this._captionObserver) {
this._captionObserver.disconnect();
this._captionObserver = null;
}
if (this._waitObserver) {
this._waitObserver.disconnect();
this._waitObserver = null;
}
this._mirrorTrack.mode = "disabled";
this._player.removeEventListener(
"onCaptionsTrackListChanged",
this._onCaptionsTrackListChanged,
);
this._player.removeEventListener(
"captionschanged",
this._onCaptionsChanged,
);
this._video.removeEventListener(
"webkitpresentationmodechanged",
this._onPresentationModeChanged,
);
}
_syncTrackList() {
var trackList = this._getTrackList();
var activeTrack = this._getActiveTrack();
navigator.mediaSession.captionTracks =
trackList?.map((track) => {
return {
label: track.displayName,
language: track.languageCode,
enabled: this._areTracksEqual(track, activeTrack),
};
}) ?? [];
navigator.mediaSession.captionsEnabled = this._player.isSubtitlesOn();
}
_syncCues(captionWindowContainer) {
while (this._mirrorTrack.cues?.length)
this._mirrorTrack.removeCue(this._mirrorTrack.cues[0]);
for (var captionWindow of captionWindowContainer.querySelectorAll(
".caption-window",
)) {
var text = Array.from(
captionWindow.querySelectorAll(".captions-text > span"),
)
.map((span) => span.textContent)
.join("\n");
if (!text) continue;
var cue = new VTTCue(0, 10e7, text);
switch (captionWindow.style.textAlign) {
case "left":
case "start":
cue.align = "start";
cue.positionAlign = "line-left";
break;
case "end":
case "right":
cue.align = "end";
cue.positionAlign = "line-right";
break;
default:
cue.align = "center";
cue.positionAlign = "center";
}
var topPercent = parseFloat(captionWindow.style.top);
var bottomPercent = parseFloat(captionWindow.style.bottom);
var leftPercent = parseFloat(captionWindow.style.left);
var rightPercent = parseFloat(captionWindow.style.right);
if (!isNaN(topPercent)) {
cue.snapToLines = false;
cue.line = topPercent;
} else if (!isNaN(bottomPercent)) {
cue.snapToLines = false;
cue.line = 100 - bottomPercent;
}
if (!isNaN(leftPercent)) cue.position = leftPercent;
else if (!isNaN(rightPercent)) cue.position = 100 - rightPercent;
this._mirrorTrack.addCue(cue);
}
}
_attachCaptionWindowObserver() {
var container = this._player.querySelector(this._captionWindowSelector);
if (container) this._attachCaptionObserver(container);
else {
this._waitObserver = new MutationObserver(() => {
var container = this._player.querySelector(
this._captionWindowSelector,
);
if (container) {
this._attachCaptionObserver(container);
this._waitObserver.disconnect();
this._waitObserver = null;
}
});
this._waitObserver.observe(this._player, {
childList: true,
subtree: true,
});
}
}
_attachCaptionObserver(container) {
if (this._captionObserver) this._captionObserver.disconnect();
this._captionObserver = new MutationObserver(() => {
var container = this._player.querySelector(this._captionWindowSelector);
if (container) this._syncCues(container);
});
this._captionObserver.observe(container, {
childList: true,
subtree: true,
characterData: true,
});
}
_getIsInline() {
if (typeof this._video.webkitPresentationMode === "undefined")
return !this._video.webkitDisplayingFullscreen;
return this._video.webkitPresentationMode == "inline";
}
_handlePresentationModeChanged() {
var captionContainer = this._player.querySelector(
this._captionWindowSelector,
);
if (this._getIsInline()) {
this._mirrorTrack.mode = "hidden";
if (captionContainer)
captionContainer.style.removeProperty("visibility");
return;
}
this._player.loadModule("captions");
this._mirrorTrack.mode = "showing";
if (captionContainer)
captionContainer.style.setProperty("visibility", "hidden", "important");
}
_handleMediaSessionAction(details) {
switch (details.action) {
case "togglecaptions":
this._player.toggleSubtitles();
break;
case "selectcaptiontrack": {
var list = this._getTrackList();
var index = details.trackIndex;
if (index >= 0 && index < list.length)
this._player.setOption("captions", "track", list[index]);
else this._player.setOption("captions", "track", {});
break;
}
}
}
_getTrackList() {
return this._player.getOption("captions", "tracklist") || [];
}
_getActiveTrack() {
return this._player.getOption("captions", "track");
}
_areTracksEqual(a, b) {
return a && b && a.vss_id === b.vss_id;
}
}
window.setupCaptionMirroring = function (video) {
new CaptionMirror(video);
};
})();