update USO bug workarounds, remove obsolete ones
This commit is contained in:
parent
f63fb8cc15
commit
85a9f6fb6a
|
@ -1,7 +1,11 @@
|
||||||
/* global cloneInto msg API */
|
/* global cloneInto msg API */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
(() => {
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
/^\/styles\/(\d+)(\/([^/]*))?([?#].*)?$/.test(location.pathname) && (() => {
|
||||||
|
const styleId = RegExp.$1;
|
||||||
|
const pageEventId = `${performance.now()}${Math.random()}`;
|
||||||
|
|
||||||
window.dispatchEvent(new CustomEvent(chrome.runtime.id + '-install'));
|
window.dispatchEvent(new CustomEvent(chrome.runtime.id + '-install'));
|
||||||
window.addEventListener(chrome.runtime.id + '-install', orphanCheck, true);
|
window.addEventListener(chrome.runtime.id + '-install', orphanCheck, true);
|
||||||
|
|
||||||
|
@ -17,35 +21,18 @@
|
||||||
}, '*');
|
}, '*');
|
||||||
});
|
});
|
||||||
|
|
||||||
let gotBody = false;
|
|
||||||
let currentMd5;
|
let currentMd5;
|
||||||
new MutationObserver(observeDOM).observe(document.documentElement, {
|
const md5Url = getMeta('stylish-md5-url') || `https://update.userstyles.org/${styleId}.md5`;
|
||||||
childList: true,
|
Promise.all([
|
||||||
subtree: true,
|
API.findStyle({md5Url}),
|
||||||
});
|
getResource(md5Url),
|
||||||
observeDOM();
|
onDOMready(),
|
||||||
|
]).then(checkUpdatability);
|
||||||
|
|
||||||
function observeDOM() {
|
document.documentElement.appendChild(
|
||||||
if (!gotBody) {
|
Object.assign(document.createElement('script'), {
|
||||||
if (!document.body) return;
|
textContent: `(${inPageContext})('${pageEventId}')`,
|
||||||
gotBody = true;
|
}));
|
||||||
// TODO: remove the following statement when USO pagination title is fixed
|
|
||||||
document.title = document.title.replace(/^(\d+)&\w+=/, '#$1: ');
|
|
||||||
const md5Url = getMeta('stylish-md5-url') || location.href;
|
|
||||||
Promise.all([
|
|
||||||
API.findStyle({md5Url}),
|
|
||||||
getResource(md5Url)
|
|
||||||
])
|
|
||||||
.then(checkUpdatability);
|
|
||||||
}
|
|
||||||
if (document.getElementById('install_button')) {
|
|
||||||
onDOMready().then(() => {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
sendEvent(sendEvent.lastEvent);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onMessage(msg) {
|
function onMessage(msg) {
|
||||||
switch (msg.method) {
|
switch (msg.method) {
|
||||||
|
@ -72,7 +59,7 @@
|
||||||
|
|
||||||
function checkUpdatability([installedStyle, md5]) {
|
function checkUpdatability([installedStyle, md5]) {
|
||||||
// TODO: remove the following statement when USO is fixed
|
// TODO: remove the following statement when USO is fixed
|
||||||
document.dispatchEvent(new CustomEvent('stylusFixBuggyUSOsettings', {
|
document.dispatchEvent(new CustomEvent(pageEventId, {
|
||||||
detail: installedStyle && installedStyle.updateUrl,
|
detail: installedStyle && installedStyle.updateUrl,
|
||||||
}));
|
}));
|
||||||
currentMd5 = md5;
|
currentMd5 = md5;
|
||||||
|
@ -141,7 +128,6 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onClick(event) {
|
function onClick(event) {
|
||||||
if (onClick.processing || !orphanCheck()) {
|
if (onClick.processing || !orphanCheck()) {
|
||||||
return;
|
return;
|
||||||
|
@ -227,13 +213,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getMeta(name) {
|
function getMeta(name) {
|
||||||
const e = document.querySelector(`link[rel="${name}"]`);
|
const e = document.querySelector(`link[rel="${name}"]`);
|
||||||
return e ? e.getAttribute('href') : null;
|
return e ? e.getAttribute('href') : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getResource(url, options) {
|
function getResource(url, options) {
|
||||||
if (url.startsWith('#')) {
|
if (url.startsWith('#')) {
|
||||||
return Promise.resolve(document.getElementById(url.slice(1)).textContent);
|
return Promise.resolve(document.getElementById(url.slice(1)).textContent);
|
||||||
|
@ -280,7 +264,6 @@
|
||||||
.catch(() => null);
|
.catch(() => null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function styleSectionsEqual({sections: a}, {sections: b}) {
|
function styleSectionsEqual({sections: a}, {sections: b}) {
|
||||||
if (!a || !b) {
|
if (!a || !b) {
|
||||||
return undefined;
|
return undefined;
|
||||||
|
@ -318,14 +301,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function onDOMready() {
|
function onDOMready() {
|
||||||
return document.readyState !== 'loading'
|
return document.readyState !== 'loading'
|
||||||
? Promise.resolve()
|
? Promise.resolve()
|
||||||
: new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve, {once: true}));
|
: new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve, {once: true}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function openSettings(countdown = 10e3) {
|
function openSettings(countdown = 10e3) {
|
||||||
const button = document.querySelector('.customize_button');
|
const button = document.querySelector('.customize_button');
|
||||||
if (button) {
|
if (button) {
|
||||||
|
@ -343,12 +324,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function orphanCheck() {
|
function orphanCheck() {
|
||||||
// TODO: switch to install-hook-usercss.js impl, and remove explicit orphanCheck() calls
|
try {
|
||||||
if (chrome.i18n && chrome.i18n.getUILanguage()) {
|
if (chrome.i18n.getUILanguage()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
} catch (e) {}
|
||||||
// In Chrome content script is orphaned on an extension update/reload
|
// In Chrome content script is orphaned on an extension update/reload
|
||||||
// so we need to detach event listeners
|
// so we need to detach event listeners
|
||||||
window.removeEventListener(chrome.runtime.id + '-install', orphanCheck, true);
|
window.removeEventListener(chrome.runtime.id + '-install', orphanCheck, true);
|
||||||
|
@ -360,129 +341,56 @@
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// run in page context
|
function inPageContext(eventId) {
|
||||||
document.documentElement.appendChild(document.createElement('script')).text = '(' + (
|
document.currentScript.remove();
|
||||||
() => {
|
const origMethods = {
|
||||||
document.currentScript.remove();
|
json: Response.prototype.json,
|
||||||
|
byId: document.getElementById,
|
||||||
// spoof Stylish extension presence in Chrome
|
};
|
||||||
if (window.chrome && chrome.app) {
|
let vars;
|
||||||
const realImage = window.Image;
|
// USO bug workaround: prevent errors in console after install and busy cursor
|
||||||
window.Image = function Image(...args) {
|
document.getElementById = id =>
|
||||||
return new Proxy(new realImage(...args), {
|
origMethods.byId.call(document, id) ||
|
||||||
get(obj, key) {
|
(/^(stylish-code|stylish-installed-style-installed-\w+|post-install-ad|style-install-unknown)$/.test(id)
|
||||||
return obj[key];
|
? Object.assign(document.createElement('p'), {className: 'afterdownload-ad'})
|
||||||
},
|
: null);
|
||||||
set(obj, key, value) {
|
// USO bug workaround: use the actual image data in customized settings
|
||||||
if (key === 'src' && /^chrome-extension:/i.test(value)) {
|
document.addEventListener(eventId, ({detail}) => {
|
||||||
setTimeout(() => typeof obj.onload === 'function' && obj.onload());
|
vars = /\?/.test(detail) && new URL(detail).searchParams;
|
||||||
} else {
|
if (!vars) Response.prototype.json = origMethods.json;
|
||||||
obj[key] = value;
|
}, {once: true});
|
||||||
}
|
Response.prototype.json = async function () {
|
||||||
return true;
|
const json = await origMethods.json.apply(this, arguments);
|
||||||
},
|
if (vars && json && Array.isArray(json.style_settings)) {
|
||||||
});
|
Response.prototype.json = origMethods.json;
|
||||||
};
|
const images = new Map();
|
||||||
}
|
for (const ss of json.style_settings) {
|
||||||
|
const value = vars.get('ik-' + ss.install_key);
|
||||||
// USO bug workaround: use the actual style settings in API response
|
if (value && ss.setting_type === 'image' && ss.style_setting_options) {
|
||||||
let settings;
|
let isListed;
|
||||||
const originalResponseJson = Response.prototype.json;
|
for (const opt of ss.style_setting_options) {
|
||||||
document.addEventListener('stylusFixBuggyUSOsettings', ({detail}) => {
|
isListed |= opt.default = (opt.value === value);
|
||||||
settings = /\?/.test(detail) && new URL(detail).searchParams;
|
}
|
||||||
if (!settings) {
|
images.set(ss.install_key, {url: value, isListed});
|
||||||
Response.prototype.json = originalResponseJson;
|
}
|
||||||
}
|
}
|
||||||
}, {once: true});
|
if (images.size) {
|
||||||
Response.prototype.json = function (...args) {
|
new MutationObserver((_, observer) => {
|
||||||
return originalResponseJson.call(this, ...args).then(json => {
|
if (document.getElementById('style-settings')) {
|
||||||
if (!settings || typeof ((json || {}).style_settings || {}).every !== 'function') {
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
Response.prototype.json = originalResponseJson;
|
|
||||||
const images = new Map();
|
|
||||||
for (const jsonSetting of json.style_settings) {
|
|
||||||
let value = settings.get('ik-' + jsonSetting.install_key);
|
|
||||||
if (!value
|
|
||||||
|| !jsonSetting.style_setting_options
|
|
||||||
|| !jsonSetting.style_setting_options[0]) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (value.startsWith('ik-')) {
|
|
||||||
value = value.replace(/^ik-/, '');
|
|
||||||
const defaultItem = jsonSetting.style_setting_options.find(item => item.default);
|
|
||||||
if (!defaultItem || defaultItem.install_key !== value) {
|
|
||||||
if (defaultItem) {
|
|
||||||
defaultItem.default = false;
|
|
||||||
}
|
|
||||||
jsonSetting.style_setting_options.some(item => {
|
|
||||||
if (item.install_key === value) {
|
|
||||||
item.default = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (jsonSetting.setting_type === 'image') {
|
|
||||||
jsonSetting.style_setting_options.some(item => {
|
|
||||||
if (item.default) {
|
|
||||||
item.default = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
images.set(jsonSetting.install_key, value);
|
|
||||||
} else {
|
|
||||||
const item = jsonSetting.style_setting_options[0];
|
|
||||||
if (item.value !== value && item.install_key === 'placeholder') {
|
|
||||||
item.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (images.size) {
|
|
||||||
new MutationObserver((_, observer) => {
|
|
||||||
if (!document.getElementById('style-settings')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
observer.disconnect();
|
observer.disconnect();
|
||||||
for (const [name, url] of images.entries()) {
|
for (const [name, {url, isListed}] of images) {
|
||||||
const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`);
|
const elRadio = document.querySelector(`input[name="ik-${name}"][value="user-url"]`);
|
||||||
const elUrl = elRadio && document.getElementById(elRadio.id.replace('url-choice', 'user-url'));
|
const elUrl = elRadio &&
|
||||||
|
document.getElementById(elRadio.id.replace('url-choice', 'user-url'));
|
||||||
if (elUrl) {
|
if (elUrl) {
|
||||||
|
elRadio.checked = !isListed;
|
||||||
elUrl.value = url;
|
elUrl.value = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).observe(document, {childList: true, subtree: true});
|
}
|
||||||
}
|
}).observe(document, {childList: true, subtree: true});
|
||||||
return json;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
) + `)('${chrome.runtime.getURL('').slice(0, -1)}')`;
|
|
||||||
|
|
||||||
// TODO: remove the following statement when USO pagination is fixed
|
|
||||||
if (location.search.includes('category=')) {
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
|
||||||
new MutationObserver((_, observer) => {
|
|
||||||
if (!document.getElementById('pagination')) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
observer.disconnect();
|
|
||||||
const category = '&' + location.search.match(/category=[^&]+/)[0];
|
|
||||||
const links = document.querySelectorAll('#pagination a[href*="page="]:not([href*="category="])');
|
|
||||||
for (let i = 0; i < links.length; i++) {
|
|
||||||
links[i].href += category;
|
|
||||||
}
|
|
||||||
}).observe(document, {childList: true, subtree: true});
|
|
||||||
}, {once: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (/^https?:\/\/userstyles\.org\/styles\/\d{3,}/.test(location.href)) {
|
|
||||||
new MutationObserver((_, observer) => {
|
|
||||||
const cssButton = document.getElementsByClassName('css_button');
|
|
||||||
if (cssButton.length) {
|
|
||||||
// Click on the "Show CSS Code" button to workaround the JS error
|
|
||||||
cssButton[0].click();
|
|
||||||
cssButton[0].click();
|
|
||||||
observer.disconnect();
|
|
||||||
}
|
}
|
||||||
}).observe(document, {childList: true, subtree: true});
|
return json;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user