mirror of
https://github.com/th-ch/youtube-music.git
synced 2026-01-11 18:41:47 +00:00
* feat(music-together): test `peerjs` * feat(music-together): replace `prompt` to `custom-electron-prompt` * fix(music-together): fix * test fix * wow * test * feat(music-together): improve `onStart` * fix: adblocker * fix(adblock): fix crash with `peerjs` * feat(music-together): add host UI * feat(music-together): implement addSong, removeSong, syncQueue * feat(music-together): inject panel * feat(music-together): redesign music together panel * feat(music-together): sync queue, profile * feat(music-together): sync progress, song, state * fix(music-together): fix some bug * fix(music-together): fix sync queue * feat(music-together): support i18n * feat(music-together): improve sync queue * feat(music-together): add profile in music item * refactor(music-together): refactor structure * feat(music-together): add permission * fix(music-together): fix queue sync bug * fix(music-together): fix some bugs * fix(music-together): fix permission not working on guest mode * fix(music-together): fix queue sync relate bugs * fix(music-together): fix automix items not append using music together * fix(music-together): fix * feat(music-together): improve video injection * fix(music-together): fix injection code * fix(music-together): fix broadcast guest * feat(music-together): add more permission * fix(music-together): fix injector * fix(music-together): fix guest add song logic * feat(music-together): add popup close listener * fix(music-together): fix connection issue * fix(music-together): fix connection issue 2 * feat(music-together): reserve playlist * fix(music-together): exclude automix songs * fix(music-together): fix playlist index sync bug * fix(music-together): fix connection failed error and sync index * fix(music-together): fix host set index bug * fix: apply fix from eslint * feat(util): add `ImageElementFromSrc` * chore(util): update jsdoc * feat(music-together): add owner name * chore(music-together): add translation * feat(music-together): add progress sync * chore(music-together): remove `console.log` --------- Co-authored-by: JellyBrick <shlee1503@naver.com>
444 lines
8.8 KiB
JavaScript
444 lines
8.8 KiB
JavaScript
/* eslint-disable */
|
|
|
|
// Source: https://addons.mozilla.org/en-US/firefox/addon/adblock-for-youtube/
|
|
// https://robwu.nl/crxviewer/?crx=https%3A%2F%2Faddons.mozilla.org%2Fen-US%2Ffirefox%2Faddon%2Fadblock-for-youtube%2F
|
|
|
|
/*
|
|
Parts of this code is derived from set-constant.js:
|
|
https://github.com/gorhill/uBlock/blob/5de0ce975753b7565759ac40983d31978d1f84ca/assets/resources/scriptlets.js#L704
|
|
*/
|
|
|
|
let injected = false;
|
|
|
|
export const isInjected = () => injected;
|
|
|
|
/**
|
|
* @param {Electron.ContextBridge} contextBridge
|
|
* @returns {*}
|
|
*/
|
|
export const inject = (contextBridge) => {
|
|
injected = true;
|
|
{
|
|
const pruner = function (o) {
|
|
delete o.playerAds;
|
|
delete o.adPlacements;
|
|
//
|
|
if (o.playerResponse) {
|
|
delete o.playerResponse.playerAds;
|
|
delete o.playerResponse.adPlacements;
|
|
}
|
|
|
|
//
|
|
return o;
|
|
};
|
|
|
|
contextBridge.exposeInMainWorld('_proxyJsonParse', new Proxy(JSON.parse, {
|
|
apply() {
|
|
return pruner(Reflect.apply(...arguments));
|
|
},
|
|
}));
|
|
|
|
contextBridge.exposeInMainWorld('_proxyResponseJson', new Proxy(Response.prototype.json, {
|
|
apply() {
|
|
return Reflect.apply(...arguments).then((o) => pruner(o));
|
|
},
|
|
}));
|
|
}
|
|
|
|
(function () {
|
|
let cValue = 'undefined';
|
|
const chain = 'playerResponse.adPlacements';
|
|
const thisScript = document.currentScript;
|
|
//
|
|
switch (cValue) {
|
|
case 'null': {
|
|
cValue = null;
|
|
break;
|
|
}
|
|
|
|
case "''": {
|
|
cValue = '';
|
|
break;
|
|
}
|
|
|
|
case 'true': {
|
|
cValue = true;
|
|
break;
|
|
}
|
|
|
|
case 'false': {
|
|
cValue = false;
|
|
break;
|
|
}
|
|
|
|
case 'undefined': {
|
|
cValue = undefined;
|
|
break;
|
|
}
|
|
|
|
case 'noopFunc': {
|
|
cValue = function () {};
|
|
|
|
break;
|
|
}
|
|
|
|
case 'trueFunc': {
|
|
cValue = function () {
|
|
return true;
|
|
};
|
|
|
|
break;
|
|
}
|
|
|
|
case 'falseFunc': {
|
|
cValue = function () {
|
|
return false;
|
|
};
|
|
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
if (/^\d+$/.test(cValue)) {
|
|
cValue = Number.parseFloat(cValue);
|
|
//
|
|
if (isNaN(cValue)) {
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(cValue) > 0x7f_ff) {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
let aborted = false;
|
|
const mustAbort = function (v) {
|
|
if (aborted) {
|
|
return true;
|
|
}
|
|
|
|
aborted =
|
|
v !== undefined &&
|
|
v !== null &&
|
|
cValue !== undefined &&
|
|
cValue !== null &&
|
|
typeof v !== typeof cValue;
|
|
return aborted;
|
|
};
|
|
|
|
/*
|
|
Support multiple trappers for the same property:
|
|
https://github.com/uBlockOrigin/uBlock-issues/issues/156
|
|
*/
|
|
|
|
const trapProp = function (owner, prop, configurable, handler) {
|
|
if (handler.init(owner[prop]) === false) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
|
|
let previousGetter;
|
|
let previousSetter;
|
|
if (odesc instanceof Object) {
|
|
if (odesc.configurable === false) {
|
|
return;
|
|
}
|
|
|
|
if (odesc.get instanceof Function) {
|
|
previousGetter = odesc.get;
|
|
}
|
|
|
|
if (odesc.set instanceof Function) {
|
|
previousSetter = odesc.set;
|
|
}
|
|
}
|
|
|
|
//
|
|
Object.defineProperty(owner, prop, {
|
|
configurable,
|
|
get() {
|
|
if (previousGetter !== undefined) {
|
|
previousGetter();
|
|
}
|
|
|
|
//
|
|
return handler.getter();
|
|
},
|
|
set(a) {
|
|
if (previousSetter !== undefined) {
|
|
previousSetter(a);
|
|
}
|
|
|
|
//
|
|
handler.setter(a);
|
|
},
|
|
});
|
|
};
|
|
|
|
const trapChain = function (owner, chain) {
|
|
const pos = chain.indexOf('.');
|
|
if (pos === -1) {
|
|
trapProp(owner, chain, false, {
|
|
v: undefined,
|
|
getter() {
|
|
return document.currentScript === thisScript ? this.v : cValue;
|
|
},
|
|
setter(a) {
|
|
if (mustAbort(a) === false) {
|
|
return;
|
|
}
|
|
|
|
cValue = a;
|
|
},
|
|
init(v) {
|
|
if (mustAbort(v)) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
this.v = v;
|
|
return true;
|
|
},
|
|
});
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
const prop = chain.slice(0, pos);
|
|
const v = owner[prop];
|
|
//
|
|
chain = chain.slice(pos + 1);
|
|
if (v instanceof Object || (typeof v === 'object' && v !== null)) {
|
|
trapChain(v, chain);
|
|
return;
|
|
}
|
|
|
|
//
|
|
trapProp(owner, prop, true, {
|
|
v: undefined,
|
|
getter() {
|
|
return this.v;
|
|
},
|
|
setter(a) {
|
|
this.v = a;
|
|
if (a instanceof Object) {
|
|
trapChain(a, chain);
|
|
}
|
|
},
|
|
init(v) {
|
|
this.v = v;
|
|
return true;
|
|
},
|
|
});
|
|
};
|
|
|
|
//
|
|
trapChain(window, chain);
|
|
})();
|
|
|
|
(function () {
|
|
let cValue = 'undefined';
|
|
const thisScript = document.currentScript;
|
|
const chain = 'ytInitialPlayerResponse.adPlacements';
|
|
//
|
|
switch (cValue) {
|
|
case 'null': {
|
|
cValue = null;
|
|
break;
|
|
}
|
|
|
|
case "''": {
|
|
cValue = '';
|
|
break;
|
|
}
|
|
|
|
case 'true': {
|
|
cValue = true;
|
|
break;
|
|
}
|
|
|
|
case 'false': {
|
|
cValue = false;
|
|
break;
|
|
}
|
|
|
|
case 'undefined': {
|
|
cValue = undefined;
|
|
break;
|
|
}
|
|
|
|
case 'noopFunc': {
|
|
cValue = function () {};
|
|
|
|
break;
|
|
}
|
|
|
|
case 'trueFunc': {
|
|
cValue = function () {
|
|
return true;
|
|
};
|
|
|
|
break;
|
|
}
|
|
|
|
case 'falseFunc': {
|
|
cValue = function () {
|
|
return false;
|
|
};
|
|
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
if (/^\d+$/.test(cValue)) {
|
|
cValue = Number.parseFloat(cValue);
|
|
//
|
|
if (isNaN(cValue)) {
|
|
return;
|
|
}
|
|
|
|
if (Math.abs(cValue) > 0x7f_ff) {
|
|
return;
|
|
}
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
let aborted = false;
|
|
const mustAbort = function (v) {
|
|
if (aborted) {
|
|
return true;
|
|
}
|
|
|
|
aborted =
|
|
v !== undefined &&
|
|
v !== null &&
|
|
cValue !== undefined &&
|
|
cValue !== null &&
|
|
typeof v !== typeof cValue;
|
|
return aborted;
|
|
};
|
|
|
|
/*
|
|
Support multiple trappers for the same property:
|
|
https://github.com/uBlockOrigin/uBlock-issues/issues/156
|
|
*/
|
|
|
|
const trapProp = function (owner, prop, configurable, handler) {
|
|
if (handler.init(owner[prop]) === false) {
|
|
return;
|
|
}
|
|
|
|
//
|
|
const odesc = Object.getOwnPropertyDescriptor(owner, prop);
|
|
let previousGetter;
|
|
let previousSetter;
|
|
if (odesc instanceof Object) {
|
|
if (odesc.configurable === false) {
|
|
return;
|
|
}
|
|
|
|
if (odesc.get instanceof Function) {
|
|
previousGetter = odesc.get;
|
|
}
|
|
|
|
if (odesc.set instanceof Function) {
|
|
previousSetter = odesc.set;
|
|
}
|
|
}
|
|
|
|
//
|
|
Object.defineProperty(owner, prop, {
|
|
configurable,
|
|
get() {
|
|
if (previousGetter !== undefined) {
|
|
previousGetter();
|
|
}
|
|
|
|
//
|
|
return handler.getter();
|
|
},
|
|
set(a) {
|
|
if (previousSetter !== undefined) {
|
|
previousSetter(a);
|
|
}
|
|
|
|
//
|
|
handler.setter(a);
|
|
},
|
|
});
|
|
};
|
|
|
|
const trapChain = function (owner, chain) {
|
|
const pos = chain.indexOf('.');
|
|
if (pos === -1) {
|
|
trapProp(owner, chain, false, {
|
|
v: undefined,
|
|
getter() {
|
|
return document.currentScript === thisScript ? this.v : cValue;
|
|
},
|
|
setter(a) {
|
|
if (mustAbort(a) === false) {
|
|
return;
|
|
}
|
|
|
|
cValue = a;
|
|
},
|
|
init(v) {
|
|
if (mustAbort(v)) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
this.v = v;
|
|
return true;
|
|
},
|
|
});
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
const prop = chain.slice(0, pos);
|
|
const v = owner[prop];
|
|
//
|
|
chain = chain.slice(pos + 1);
|
|
if (v instanceof Object || (typeof v === 'object' && v !== null)) {
|
|
trapChain(v, chain);
|
|
return;
|
|
}
|
|
|
|
//
|
|
trapProp(owner, prop, true, {
|
|
v: undefined,
|
|
getter() {
|
|
return this.v;
|
|
},
|
|
setter(a) {
|
|
this.v = a;
|
|
if (a instanceof Object) {
|
|
trapChain(a, chain);
|
|
}
|
|
},
|
|
init(v) {
|
|
this.v = v;
|
|
return true;
|
|
},
|
|
});
|
|
};
|
|
|
|
//
|
|
trapChain(window, chain);
|
|
})();
|
|
};
|