update polyfill for Chrome>=55
This commit is contained in:
parent
7c205880d2
commit
a01bd3cd61
|
@ -12,7 +12,6 @@ createAPI({
|
||||||
compileUsercss,
|
compileUsercss,
|
||||||
parseUsercssMeta(text, indexOffset = 0) {
|
parseUsercssMeta(text, indexOffset = 0) {
|
||||||
loadScript(
|
loadScript(
|
||||||
'/js/polyfill.js',
|
|
||||||
'/vendor/usercss-meta/usercss-meta.min.js',
|
'/vendor/usercss-meta/usercss-meta.min.js',
|
||||||
'/vendor-overwrites/colorpicker/colorconverter.js',
|
'/vendor-overwrites/colorpicker/colorconverter.js',
|
||||||
'/js/meta-parser.js'
|
'/js/meta-parser.js'
|
||||||
|
@ -21,7 +20,6 @@ createAPI({
|
||||||
},
|
},
|
||||||
nullifyInvalidVars(vars) {
|
nullifyInvalidVars(vars) {
|
||||||
loadScript(
|
loadScript(
|
||||||
'/js/polyfill.js',
|
|
||||||
'/vendor/usercss-meta/usercss-meta.min.js',
|
'/vendor/usercss-meta/usercss-meta.min.js',
|
||||||
'/vendor-overwrites/colorpicker/colorconverter.js',
|
'/vendor-overwrites/colorpicker/colorconverter.js',
|
||||||
'/js/meta-parser.js'
|
'/js/meta-parser.js'
|
||||||
|
|
|
@ -16,7 +16,6 @@ createAPI({
|
||||||
},
|
},
|
||||||
metalint: code => {
|
metalint: code => {
|
||||||
loadScript(
|
loadScript(
|
||||||
'/js/polyfill.js',
|
|
||||||
'/vendor/usercss-meta/usercss-meta.min.js',
|
'/vendor/usercss-meta/usercss-meta.min.js',
|
||||||
'/vendor-overwrites/colorpicker/colorconverter.js',
|
'/vendor-overwrites/colorpicker/colorconverter.js',
|
||||||
'/js/meta-parser.js'
|
'/js/meta-parser.js'
|
||||||
|
|
122
js/polyfill.js
122
js/polyfill.js
|
@ -3,27 +3,33 @@
|
||||||
// eslint-disable-next-line no-unused-expressions
|
// eslint-disable-next-line no-unused-expressions
|
||||||
self.INJECTED !== 1 && (() => {
|
self.INJECTED !== 1 && (() => {
|
||||||
|
|
||||||
// this part runs in workers, content scripts, our extension pages
|
//#region for content scripts and our extension pages
|
||||||
|
|
||||||
if (!Object.entries) {
|
if (!window.browser || !browser.runtime) {
|
||||||
Object.entries = obj => Object.keys(obj).map(k => [k, obj[k]]);
|
const createTrap = (base, parent) => {
|
||||||
|
const target = typeof base === 'function' ? () => {} : {};
|
||||||
|
target.isTrap = true;
|
||||||
|
return new Proxy(target, {
|
||||||
|
get: (target, prop) => {
|
||||||
|
if (target[prop]) return target[prop];
|
||||||
|
if (base[prop] && (typeof base[prop] === 'object' || typeof base[prop] === 'function')) {
|
||||||
|
target[prop] = createTrap(base[prop], base);
|
||||||
|
return target[prop];
|
||||||
|
}
|
||||||
|
return base[prop];
|
||||||
|
},
|
||||||
|
apply: (target, thisArg, args) => base.apply(parent, args)
|
||||||
|
});
|
||||||
|
};
|
||||||
|
window.browser = createTrap(chrome, null);
|
||||||
}
|
}
|
||||||
if (!Object.values) {
|
|
||||||
Object.values = obj => Object.keys(obj).map(k => obj[k]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't use self.chrome. It is undefined in Firefox
|
|
||||||
if (typeof chrome !== 'object') return;
|
|
||||||
// the rest is for content scripts and our extension pages
|
|
||||||
|
|
||||||
self.browser = polyfillBrowser();
|
|
||||||
|
|
||||||
/* Promisifies the specified `chrome` methods into `browser`.
|
/* Promisifies the specified `chrome` methods into `browser`.
|
||||||
The definitions is an object like this: {
|
The definitions is an object like this: {
|
||||||
'storage.sync': ['get', 'set'], // if deeper than one level, combine the path via `.`
|
'storage.sync': ['get', 'set'], // if deeper than one level, combine the path via `.`
|
||||||
windows: ['create', 'update'], // items and sub-objects will only be created if present in `chrome`
|
windows: ['create', 'update'], // items and sub-objects will only be created if present in `chrome`
|
||||||
} */
|
} */
|
||||||
self.promisifyChrome = definitions => {
|
window.promisifyChrome = definitions => {
|
||||||
for (const [scopeName, methods] of Object.entries(definitions)) {
|
for (const [scopeName, methods] of Object.entries(definitions)) {
|
||||||
const path = scopeName.split('.');
|
const path = scopeName.split('.');
|
||||||
const src = path.reduce((obj, p) => obj && obj[p], chrome);
|
const src = path.reduce((obj, p) => obj && obj[p], chrome);
|
||||||
|
@ -43,90 +49,18 @@ self.INJECTED !== 1 && (() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!chrome.tabs) return;
|
if (!chrome.tabs) return;
|
||||||
// the rest is for our extension pages
|
|
||||||
|
|
||||||
if (typeof document === 'object') {
|
//#endregion
|
||||||
const ELEMENT_METH = {
|
//#region for our extension pages
|
||||||
append: {
|
|
||||||
base: [Element, Document, DocumentFragment],
|
|
||||||
fn: (node, frag) => {
|
|
||||||
node.appendChild(frag);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
prepend: {
|
|
||||||
base: [Element, Document, DocumentFragment],
|
|
||||||
fn: (node, frag) => {
|
|
||||||
node.insertBefore(frag, node.firstChild);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
before: {
|
|
||||||
base: [Element, CharacterData, DocumentType],
|
|
||||||
fn: (node, frag) => {
|
|
||||||
node.parentNode.insertBefore(frag, node);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
after: {
|
|
||||||
base: [Element, CharacterData, DocumentType],
|
|
||||||
fn: (node, frag) => {
|
|
||||||
node.parentNode.insertBefore(frag, node.nextSibling);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const [key, {base, fn}] of Object.entries(ELEMENT_METH)) {
|
for (const storage of ['localStorage', 'sessionStorage']) {
|
||||||
for (const cls of base) {
|
try {
|
||||||
if (cls.prototype[key]) {
|
window[storage]._access_check = 1;
|
||||||
continue;
|
delete window[storage]._access_check;
|
||||||
}
|
} catch (err) {
|
||||||
cls.prototype[key] = function (...nodes) {
|
Object.defineProperty(window, storage, {value: {}});
|
||||||
const frag = document.createDocumentFragment();
|
|
||||||
for (const node of nodes) {
|
|
||||||
frag.appendChild(typeof node === 'string' ? document.createTextNode(node) : node);
|
|
||||||
}
|
|
||||||
fn(this, frag);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (!localStorage) {
|
|
||||||
throw new Error('localStorage is null');
|
|
||||||
}
|
|
||||||
localStorage._access_check = 1;
|
|
||||||
delete localStorage._access_check;
|
|
||||||
} catch (err) {
|
|
||||||
Object.defineProperty(self, 'localStorage', {value: {}});
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (!sessionStorage) {
|
|
||||||
throw new Error('sessionStorage is null');
|
|
||||||
}
|
|
||||||
sessionStorage._access_check = 1;
|
|
||||||
delete sessionStorage._access_check;
|
|
||||||
} catch (err) {
|
|
||||||
Object.defineProperty(self, 'sessionStorage', {value: {}});
|
|
||||||
}
|
|
||||||
|
|
||||||
function polyfillBrowser() {
|
//#endregion
|
||||||
if (typeof browser === 'object' && browser.runtime) {
|
|
||||||
return browser;
|
|
||||||
}
|
|
||||||
return createTrap(chrome, null);
|
|
||||||
|
|
||||||
function createTrap(base, parent) {
|
|
||||||
const target = typeof base === 'function' ? () => {} : {};
|
|
||||||
target.isTrap = true;
|
|
||||||
return new Proxy(target, {
|
|
||||||
get: (target, prop) => {
|
|
||||||
if (target[prop]) return target[prop];
|
|
||||||
if (base[prop] && (typeof base[prop] === 'object' || typeof base[prop] === 'function')) {
|
|
||||||
target[prop] = createTrap(base[prop], base);
|
|
||||||
return target[prop];
|
|
||||||
}
|
|
||||||
return base[prop];
|
|
||||||
},
|
|
||||||
apply: (target, thisArg, args) => base.apply(parent, args)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user