mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-16 23:42:39 +01:00
Keep moving related scriptlets into separate files
This commit is contained in:
parent
ce4908b341
commit
e5a088738d
@ -22,6 +22,7 @@
|
|||||||
web page context.
|
web page context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { registerScriptlet } from './base.js';
|
||||||
import { runAt } from './run-at.js';
|
import { runAt } from './run-at.js';
|
||||||
import { safeSelf } from './safe-self.js';
|
import { safeSelf } from './safe-self.js';
|
||||||
|
|
||||||
@ -95,13 +96,13 @@ export function setAttrFn(
|
|||||||
};
|
};
|
||||||
runAt(( ) => { start(); }, 'idle');
|
runAt(( ) => { start(); }, 'idle');
|
||||||
}
|
}
|
||||||
setAttrFn.details = {
|
registerScriptlet(setAttrFn, {
|
||||||
name: 'set-attr.fn',
|
name: 'set-attr.fn',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
runAt,
|
runAt,
|
||||||
safeSelf,
|
safeSelf,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @scriptlet set-attr
|
* @scriptlet set-attr
|
||||||
@ -149,14 +150,14 @@ export function setAttr(
|
|||||||
|
|
||||||
setAttrFn(logPrefix, selector, attr, value);
|
setAttrFn(logPrefix, selector, attr, value);
|
||||||
}
|
}
|
||||||
setAttr.details = {
|
registerScriptlet(setAttr, {
|
||||||
name: 'set-attr.js',
|
name: 'set-attr.js',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
safeSelf,
|
safeSelf,
|
||||||
setAttrFn,
|
setAttrFn,
|
||||||
],
|
],
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @trustedScriptlet trusted-set-attr
|
* @trustedScriptlet trusted-set-attr
|
||||||
@ -188,7 +189,7 @@ export function trustedSetAttr(
|
|||||||
const logPrefix = safe.makeLogPrefix('trusted-set-attr', selector, attr, value);
|
const logPrefix = safe.makeLogPrefix('trusted-set-attr', selector, attr, value);
|
||||||
setAttrFn(logPrefix, selector, attr, value);
|
setAttrFn(logPrefix, selector, attr, value);
|
||||||
}
|
}
|
||||||
trustedSetAttr.details = {
|
registerScriptlet(trustedSetAttr, {
|
||||||
name: 'trusted-set-attr.js',
|
name: 'trusted-set-attr.js',
|
||||||
requiresTrust: true,
|
requiresTrust: true,
|
||||||
dependencies: [
|
dependencies: [
|
||||||
@ -196,7 +197,7 @@ trustedSetAttr.details = {
|
|||||||
setAttrFn,
|
setAttrFn,
|
||||||
],
|
],
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @scriptlet remove-attr
|
* @scriptlet remove-attr
|
||||||
@ -291,7 +292,7 @@ export function removeAttr(
|
|||||||
};
|
};
|
||||||
runAt(( ) => { start(); }, behavior.split(/\s+/));
|
runAt(( ) => { start(); }, behavior.split(/\s+/));
|
||||||
}
|
}
|
||||||
removeAttr.details = {
|
registerScriptlet(removeAttr, {
|
||||||
name: 'remove-attr.js',
|
name: 'remove-attr.js',
|
||||||
aliases: [
|
aliases: [
|
||||||
'ra.js',
|
'ra.js',
|
||||||
@ -300,6 +301,6 @@ removeAttr.details = {
|
|||||||
runAt,
|
runAt,
|
||||||
safeSelf,
|
safeSelf,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
40
assets/resources/base.js
Normal file
40
assets/resources/base.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a comprehensive, efficient content blocker
|
||||||
|
Copyright (C) 2019-present Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
|
||||||
|
The scriptlets below are meant to be injected only into a
|
||||||
|
web page context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const registeredScriptlets = [];
|
||||||
|
|
||||||
|
export const registerScriptlet = (fn, details) => {
|
||||||
|
if ( typeof details !== 'object' ) {
|
||||||
|
throw new ReferenceError('Missing scriptlet details');
|
||||||
|
}
|
||||||
|
details.fn = fn;
|
||||||
|
fn.details = details;
|
||||||
|
if ( Array.isArray(details.dependencies) ) {
|
||||||
|
details.dependencies.forEach((fn, i, array) => {
|
||||||
|
if ( typeof fn !== 'function' ) { return; }
|
||||||
|
array[i] = fn.details.name;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
registeredScriptlets.push(details);
|
||||||
|
};
|
@ -22,6 +22,7 @@
|
|||||||
web page context.
|
web page context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { registerScriptlet } from './base.js';
|
||||||
import { safeSelf } from './safe-self.js';
|
import { safeSelf } from './safe-self.js';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
@ -47,9 +48,9 @@ export function getSafeCookieValuesFn() {
|
|||||||
'yes', 'y', 'no', 'n',
|
'yes', 'y', 'no', 'n',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
getSafeCookieValuesFn.details = {
|
registerScriptlet(getSafeCookieValuesFn, {
|
||||||
name: 'get-safe-cookie-values.fn',
|
name: 'get-safe-cookie-values.fn',
|
||||||
};
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -63,9 +64,9 @@ export function getAllCookiesFn() {
|
|||||||
return { key, value };
|
return { key, value };
|
||||||
}).filter(s => s !== undefined);
|
}).filter(s => s !== undefined);
|
||||||
}
|
}
|
||||||
getAllCookiesFn.details = {
|
registerScriptlet(getAllCookiesFn, {
|
||||||
name: 'get-all-cookies.fn',
|
name: 'get-all-cookies.fn',
|
||||||
};
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -79,9 +80,9 @@ export function getCookieFn(
|
|||||||
return s.slice(pos+1).trim();
|
return s.slice(pos+1).trim();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getCookieFn.details = {
|
registerScriptlet(getCookieFn, {
|
||||||
name: 'get-cookie.fn',
|
name: 'get-cookie.fn',
|
||||||
};
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
@ -142,12 +143,12 @@ export function setCookieFn(
|
|||||||
|
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
setCookieFn.details = {
|
registerScriptlet(setCookieFn, {
|
||||||
name: 'set-cookie.fn',
|
name: 'set-cookie.fn',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'get-cookie.fn',
|
getCookieFn,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @scriptlet set-cookie
|
* @scriptlet set-cookie
|
||||||
@ -200,27 +201,27 @@ export function setCookie(
|
|||||||
safe.uboLog(logPrefix, 'Done');
|
safe.uboLog(logPrefix, 'Done');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCookie.details = {
|
registerScriptlet(setCookie, {
|
||||||
name: 'set-cookie.js',
|
name: 'set-cookie.js',
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'get-safe-cookie-values.fn',
|
getSafeCookieValuesFn,
|
||||||
'safe-self.fn',
|
safeSelf,
|
||||||
'set-cookie.fn',
|
setCookieFn,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
// For compatibility with AdGuard
|
// For compatibility with AdGuard
|
||||||
export function setCookieReload(name, value, path, ...args) {
|
export function setCookieReload(name, value, path, ...args) {
|
||||||
setCookie(name, value, path, 'reload', '1', ...args);
|
setCookie(name, value, path, 'reload', '1', ...args);
|
||||||
}
|
}
|
||||||
setCookieReload.details = {
|
registerScriptlet(setCookieReload, {
|
||||||
name: 'set-cookie-reload.js',
|
name: 'set-cookie-reload.js',
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'set-cookie.js',
|
setCookie,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @trustedScriptlet trusted-set-cookie
|
* @trustedScriptlet trusted-set-cookie
|
||||||
@ -294,28 +295,28 @@ export function trustedSetCookie(
|
|||||||
safe.uboLog(logPrefix, 'Done');
|
safe.uboLog(logPrefix, 'Done');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trustedSetCookie.details = {
|
registerScriptlet(trustedSetCookie, {
|
||||||
name: 'trusted-set-cookie.js',
|
name: 'trusted-set-cookie.js',
|
||||||
requiresTrust: true,
|
requiresTrust: true,
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'safe-self.fn',
|
safeSelf,
|
||||||
'set-cookie.fn',
|
setCookieFn,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
// For compatibility with AdGuard
|
// For compatibility with AdGuard
|
||||||
export function trustedSetCookieReload(name, value, offsetExpiresSec, path, ...args) {
|
export function trustedSetCookieReload(name, value, offsetExpiresSec, path, ...args) {
|
||||||
trustedSetCookie(name, value, offsetExpiresSec, path, 'reload', '1', ...args);
|
trustedSetCookie(name, value, offsetExpiresSec, path, 'reload', '1', ...args);
|
||||||
}
|
}
|
||||||
trustedSetCookieReload.details = {
|
registerScriptlet(trustedSetCookieReload, {
|
||||||
name: 'trusted-set-cookie-reload.js',
|
name: 'trusted-set-cookie-reload.js',
|
||||||
requiresTrust: true,
|
requiresTrust: true,
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'trusted-set-cookie.js',
|
trustedSetCookie,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @scriptlet remove-cookie
|
* @scriptlet remove-cookie
|
||||||
@ -396,15 +397,15 @@ export function removeCookie(
|
|||||||
}, { passive: true });
|
}, { passive: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
removeCookie.details = {
|
registerScriptlet(removeCookie, {
|
||||||
name: 'remove-cookie.js',
|
name: 'remove-cookie.js',
|
||||||
aliases: [
|
aliases: [
|
||||||
'cookie-remover.js',
|
'cookie-remover.js',
|
||||||
],
|
],
|
||||||
world: 'ISOLATED',
|
world: 'ISOLATED',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
'safe-self.fn',
|
safeSelf,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
237
assets/resources/localstorage.js
Normal file
237
assets/resources/localstorage.js
Normal file
@ -0,0 +1,237 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
|
||||||
|
uBlock Origin - a comprehensive, efficient content blocker
|
||||||
|
Copyright (C) 2019-present Raymond Hill
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
|
||||||
|
Home: https://github.com/gorhill/uBlock
|
||||||
|
|
||||||
|
The scriptlets below are meant to be injected only into a
|
||||||
|
web page context.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { getSafeCookieValuesFn } from './cookie.js';
|
||||||
|
import { registerScriptlet } from './base.js';
|
||||||
|
import { safeSelf } from './safe-self.js';
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
export function getAllLocalStorageFn(which = 'localStorage') {
|
||||||
|
const storage = self[which];
|
||||||
|
const out = [];
|
||||||
|
for ( let i = 0; i < storage.length; i++ ) {
|
||||||
|
const key = storage.key(i);
|
||||||
|
const value = storage.getItem(key);
|
||||||
|
return { key, value };
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
registerScriptlet(getAllLocalStorageFn, {
|
||||||
|
name: 'get-all-local-storage.fn',
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
export function setLocalStorageItemFn(
|
||||||
|
which = 'local',
|
||||||
|
trusted = false,
|
||||||
|
key = '',
|
||||||
|
value = '',
|
||||||
|
) {
|
||||||
|
if ( key === '' ) { return; }
|
||||||
|
|
||||||
|
// For increased compatibility with AdGuard
|
||||||
|
if ( value === 'emptyArr' ) {
|
||||||
|
value = '[]';
|
||||||
|
} else if ( value === 'emptyObj' ) {
|
||||||
|
value = '{}';
|
||||||
|
}
|
||||||
|
|
||||||
|
const trustedValues = [
|
||||||
|
'',
|
||||||
|
'undefined', 'null',
|
||||||
|
'{}', '[]', '""',
|
||||||
|
'$remove$',
|
||||||
|
...getSafeCookieValuesFn(),
|
||||||
|
];
|
||||||
|
|
||||||
|
if ( trusted ) {
|
||||||
|
if ( value.includes('$now$') ) {
|
||||||
|
value = value.replaceAll('$now$', Date.now());
|
||||||
|
}
|
||||||
|
if ( value.includes('$currentDate$') ) {
|
||||||
|
value = value.replaceAll('$currentDate$', `${Date()}`);
|
||||||
|
}
|
||||||
|
if ( value.includes('$currentISODate$') ) {
|
||||||
|
value = value.replaceAll('$currentISODate$', (new Date()).toISOString());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const normalized = value.toLowerCase();
|
||||||
|
const match = /^("?)(.+)\1$/.exec(normalized);
|
||||||
|
const unquoted = match && match[2] || normalized;
|
||||||
|
if ( trustedValues.includes(unquoted) === false ) {
|
||||||
|
if ( /^-?\d+$/.test(unquoted) === false ) { return; }
|
||||||
|
const n = parseInt(unquoted, 10) || 0;
|
||||||
|
if ( n < -32767 || n > 32767 ) { return; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const storage = self[`${which}Storage`];
|
||||||
|
if ( value === '$remove$' ) {
|
||||||
|
const safe = safeSelf();
|
||||||
|
const pattern = safe.patternToRegex(key, undefined, true );
|
||||||
|
const toRemove = [];
|
||||||
|
for ( let i = 0, n = storage.length; i < n; i++ ) {
|
||||||
|
const key = storage.key(i);
|
||||||
|
if ( pattern.test(key) ) { toRemove.push(key); }
|
||||||
|
}
|
||||||
|
for ( const key of toRemove ) {
|
||||||
|
storage.removeItem(key);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
storage.setItem(key, `${value}`);
|
||||||
|
}
|
||||||
|
} catch(ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
registerScriptlet(setLocalStorageItemFn, {
|
||||||
|
name: 'set-local-storage-item.fn',
|
||||||
|
dependencies: [
|
||||||
|
getSafeCookieValuesFn,
|
||||||
|
safeSelf,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
export function removeCacheStorageItem(
|
||||||
|
cacheNamePattern = '',
|
||||||
|
requestPattern = ''
|
||||||
|
) {
|
||||||
|
if ( cacheNamePattern === '' ) { return; }
|
||||||
|
const safe = safeSelf();
|
||||||
|
const logPrefix = safe.makeLogPrefix('remove-cache-storage-item', cacheNamePattern, requestPattern);
|
||||||
|
const cacheStorage = self.caches;
|
||||||
|
if ( cacheStorage instanceof Object === false ) { return; }
|
||||||
|
const reCache = safe.patternToRegex(cacheNamePattern, undefined, true);
|
||||||
|
const reRequest = safe.patternToRegex(requestPattern, undefined, true);
|
||||||
|
cacheStorage.keys().then(cacheNames => {
|
||||||
|
for ( const cacheName of cacheNames ) {
|
||||||
|
if ( reCache.test(cacheName) === false ) { continue; }
|
||||||
|
if ( requestPattern === '' ) {
|
||||||
|
cacheStorage.delete(cacheName).then(result => {
|
||||||
|
if ( safe.logLevel > 1 ) {
|
||||||
|
safe.uboLog(logPrefix, `Deleting ${cacheName}`);
|
||||||
|
}
|
||||||
|
if ( result !== true ) { return; }
|
||||||
|
safe.uboLog(logPrefix, `Deleted ${cacheName}: ${result}`);
|
||||||
|
});
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
cacheStorage.open(cacheName).then(cache => {
|
||||||
|
cache.keys().then(requests => {
|
||||||
|
for ( const request of requests ) {
|
||||||
|
if ( reRequest.test(request.url) === false ) { continue; }
|
||||||
|
if ( safe.logLevel > 1 ) {
|
||||||
|
safe.uboLog(logPrefix, `Deleting ${cacheName}/${request.url}`);
|
||||||
|
}
|
||||||
|
cache.delete(request).then(result => {
|
||||||
|
if ( result !== true ) { return; }
|
||||||
|
safe.uboLog(logPrefix, `Deleted ${cacheName}/${request.url}: ${result}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
registerScriptlet(removeCacheStorageItem, {
|
||||||
|
name: 'remove-cache-storage-item.fn',
|
||||||
|
world: 'ISOLATED',
|
||||||
|
dependencies: [
|
||||||
|
safeSelf,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* set-local-storage-item.js
|
||||||
|
* set-session-storage-item.js
|
||||||
|
*
|
||||||
|
* Set a local/session storage entry to a specific, allowed value.
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/set-local-storage-item.js
|
||||||
|
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/set-session-storage-item.js
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
export function setLocalStorageItem(key = '', value = '') {
|
||||||
|
setLocalStorageItemFn('local', false, key, value);
|
||||||
|
}
|
||||||
|
registerScriptlet(setLocalStorageItem, {
|
||||||
|
name: 'set-local-storage-item.js',
|
||||||
|
world: 'ISOLATED',
|
||||||
|
dependencies: [
|
||||||
|
setLocalStorageItemFn,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export function setSessionStorageItem(key = '', value = '') {
|
||||||
|
setLocalStorageItemFn('session', false, key, value);
|
||||||
|
}
|
||||||
|
registerScriptlet(setSessionStorageItem, {
|
||||||
|
name: 'set-session-storage-item.js',
|
||||||
|
world: 'ISOLATED',
|
||||||
|
dependencies: [
|
||||||
|
setLocalStorageItemFn,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
*
|
||||||
|
* trusted-set-local-storage-item.js
|
||||||
|
*
|
||||||
|
* Set a local storage entry to an arbitrary value.
|
||||||
|
*
|
||||||
|
* Reference:
|
||||||
|
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/trusted-set-local-storage-item.js
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
|
||||||
|
export function trustedSetLocalStorageItem(key = '', value = '') {
|
||||||
|
setLocalStorageItemFn('local', true, key, value);
|
||||||
|
}
|
||||||
|
registerScriptlet(trustedSetLocalStorageItem, {
|
||||||
|
name: 'trusted-set-local-storage-item.js',
|
||||||
|
requiresTrust: true,
|
||||||
|
world: 'ISOLATED',
|
||||||
|
dependencies: [
|
||||||
|
setLocalStorageItemFn,
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export function trustedSetSessionStorageItem(key = '', value = '') {
|
||||||
|
setLocalStorageItemFn('session', true, key, value);
|
||||||
|
}
|
||||||
|
registerScriptlet(trustedSetSessionStorageItem, {
|
||||||
|
name: 'trusted-set-session-storage-item.js',
|
||||||
|
requiresTrust: true,
|
||||||
|
world: 'ISOLATED',
|
||||||
|
dependencies: [
|
||||||
|
setLocalStorageItemFn,
|
||||||
|
],
|
||||||
|
});
|
@ -22,6 +22,7 @@
|
|||||||
web page context.
|
web page context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { registerScriptlet } from './base.js';
|
||||||
import { safeSelf } from './safe-self.js';
|
import { safeSelf } from './safe-self.js';
|
||||||
|
|
||||||
/* eslint no-prototype-builtins: 0 */
|
/* eslint no-prototype-builtins: 0 */
|
||||||
@ -72,9 +73,26 @@ export function runAt(fn, when) {
|
|||||||
const args = [ 'readystatechange', onStateChange, { capture: true } ];
|
const args = [ 'readystatechange', onStateChange, { capture: true } ];
|
||||||
safe.addEventListener.apply(document, args);
|
safe.addEventListener.apply(document, args);
|
||||||
}
|
}
|
||||||
runAt.details = {
|
registerScriptlet(runAt, {
|
||||||
name: 'run-at.fn',
|
name: 'run-at.fn',
|
||||||
dependencies: [
|
dependencies: [
|
||||||
safeSelf,
|
safeSelf,
|
||||||
],
|
],
|
||||||
};
|
});
|
||||||
|
|
||||||
|
/******************************************************************************/
|
||||||
|
|
||||||
|
function runAtHtmlElementFn(fn) {
|
||||||
|
if ( document.documentElement ) {
|
||||||
|
fn();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const observer = new MutationObserver(( ) => {
|
||||||
|
observer.disconnect();
|
||||||
|
fn();
|
||||||
|
});
|
||||||
|
observer.observe(document, { childList: true });
|
||||||
|
}
|
||||||
|
registerScriptlet(runAtHtmlElementFn, {
|
||||||
|
name: 'run-at-html-element.fn',
|
||||||
|
});
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
web page context.
|
web page context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { registerScriptlet } from './base.js';
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
// Externally added to the private namespace in which scriptlets execute.
|
// Externally added to the private namespace in which scriptlets execute.
|
||||||
@ -213,6 +215,6 @@ export function safeSelf() {
|
|||||||
}
|
}
|
||||||
return safe;
|
return safe;
|
||||||
}
|
}
|
||||||
safeSelf.details = {
|
registerScriptlet(safeSelf, {
|
||||||
name: 'safe-self.fn',
|
name: 'safe-self.fn',
|
||||||
};
|
});
|
||||||
|
@ -22,70 +22,24 @@
|
|||||||
web page context.
|
web page context.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import './attribute.js';
|
||||||
getAllCookiesFn,
|
import './cookie.js';
|
||||||
getCookieFn,
|
import './localstorage.js';
|
||||||
getSafeCookieValuesFn,
|
import './run-at.js';
|
||||||
removeCookie,
|
import './safe-self.js';
|
||||||
setCookie,
|
|
||||||
setCookieFn,
|
|
||||||
setCookieReload,
|
|
||||||
trustedSetCookie,
|
|
||||||
trustedSetCookieReload,
|
|
||||||
} from './cookie.js';
|
|
||||||
|
|
||||||
import {
|
|
||||||
removeAttr,
|
|
||||||
setAttr,
|
|
||||||
setAttrFn,
|
|
||||||
trustedSetAttr,
|
|
||||||
} from './attribute.js';
|
|
||||||
|
|
||||||
|
import { getAllCookiesFn } from './cookie.js';
|
||||||
|
import { getAllLocalStorageFn } from './localstorage.js';
|
||||||
|
import { registeredScriptlets } from './base.js';
|
||||||
import { runAt } from './run-at.js';
|
import { runAt } from './run-at.js';
|
||||||
import { safeSelf } from './safe-self.js';
|
import { safeSelf } from './safe-self.js';
|
||||||
|
|
||||||
/* eslint no-prototype-builtins: 0 */
|
|
||||||
|
|
||||||
// Externally added to the private namespace in which scriptlets execute.
|
// Externally added to the private namespace in which scriptlets execute.
|
||||||
/* global scriptletGlobals */
|
/* global scriptletGlobals */
|
||||||
|
|
||||||
export const builtinScriptlets = [];
|
/* eslint no-prototype-builtins: 0 */
|
||||||
|
|
||||||
/******************************************************************************/
|
export const builtinScriptlets = registeredScriptlets;
|
||||||
|
|
||||||
// Register scriptlets declared in other files.
|
|
||||||
|
|
||||||
const registerScriptlet = fn => {
|
|
||||||
const details = fn.details;
|
|
||||||
if ( typeof details !== 'object' ) {
|
|
||||||
throw new ReferenceError('Unknown scriptlet function');
|
|
||||||
}
|
|
||||||
details.fn = fn;
|
|
||||||
if ( Array.isArray(details.dependencies) ) {
|
|
||||||
details.dependencies.forEach((fn, i, array) => {
|
|
||||||
if ( typeof fn !== 'function' ) { return; }
|
|
||||||
array[i] = fn.details.name;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
builtinScriptlets.push(details);
|
|
||||||
};
|
|
||||||
|
|
||||||
registerScriptlet(safeSelf);
|
|
||||||
|
|
||||||
registerScriptlet(removeAttr);
|
|
||||||
registerScriptlet(setAttrFn);
|
|
||||||
registerScriptlet(setAttr);
|
|
||||||
registerScriptlet(trustedSetAttr);
|
|
||||||
|
|
||||||
registerScriptlet(getAllCookiesFn);
|
|
||||||
registerScriptlet(getCookieFn);
|
|
||||||
registerScriptlet(getSafeCookieValuesFn);
|
|
||||||
registerScriptlet(removeCookie);
|
|
||||||
registerScriptlet(setCookie);
|
|
||||||
registerScriptlet(setCookieFn);
|
|
||||||
registerScriptlet(setCookieReload);
|
|
||||||
registerScriptlet(trustedSetCookie);
|
|
||||||
registerScriptlet(trustedSetCookieReload);
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
|
||||||
@ -141,34 +95,6 @@ function shouldDebug(details) {
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'run-at.fn',
|
|
||||||
fn: runAt,
|
|
||||||
dependencies: [
|
|
||||||
'safe-self.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'run-at-html-element.fn',
|
|
||||||
fn: runAtHtmlElementFn,
|
|
||||||
});
|
|
||||||
function runAtHtmlElementFn(fn) {
|
|
||||||
if ( document.documentElement ) {
|
|
||||||
fn();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const observer = new MutationObserver(( ) => {
|
|
||||||
observer.disconnect();
|
|
||||||
fn();
|
|
||||||
});
|
|
||||||
observer.observe(document, { childList: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
// Reference:
|
// Reference:
|
||||||
// https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-xhr
|
// https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-xhr
|
||||||
//
|
//
|
||||||
@ -823,97 +749,6 @@ function objectFindOwnerFn(
|
|||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'get-all-local-storage.fn',
|
|
||||||
fn: getAllLocalStorageFn,
|
|
||||||
});
|
|
||||||
function getAllLocalStorageFn(which = 'localStorage') {
|
|
||||||
const storage = self[which];
|
|
||||||
const out = [];
|
|
||||||
for ( let i = 0; i < storage.length; i++ ) {
|
|
||||||
const key = storage.key(i);
|
|
||||||
const value = storage.getItem(key);
|
|
||||||
return { key, value };
|
|
||||||
}
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'set-local-storage-item.fn',
|
|
||||||
fn: setLocalStorageItemFn,
|
|
||||||
dependencies: [
|
|
||||||
'get-safe-cookie-values.fn',
|
|
||||||
'safe-self.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function setLocalStorageItemFn(
|
|
||||||
which = 'local',
|
|
||||||
trusted = false,
|
|
||||||
key = '',
|
|
||||||
value = '',
|
|
||||||
) {
|
|
||||||
if ( key === '' ) { return; }
|
|
||||||
|
|
||||||
// For increased compatibility with AdGuard
|
|
||||||
if ( value === 'emptyArr' ) {
|
|
||||||
value = '[]';
|
|
||||||
} else if ( value === 'emptyObj' ) {
|
|
||||||
value = '{}';
|
|
||||||
}
|
|
||||||
|
|
||||||
const trustedValues = [
|
|
||||||
'',
|
|
||||||
'undefined', 'null',
|
|
||||||
'{}', '[]', '""',
|
|
||||||
'$remove$',
|
|
||||||
...getSafeCookieValuesFn(),
|
|
||||||
];
|
|
||||||
|
|
||||||
if ( trusted ) {
|
|
||||||
if ( value.includes('$now$') ) {
|
|
||||||
value = value.replaceAll('$now$', Date.now());
|
|
||||||
}
|
|
||||||
if ( value.includes('$currentDate$') ) {
|
|
||||||
value = value.replaceAll('$currentDate$', `${Date()}`);
|
|
||||||
}
|
|
||||||
if ( value.includes('$currentISODate$') ) {
|
|
||||||
value = value.replaceAll('$currentISODate$', (new Date()).toISOString());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const normalized = value.toLowerCase();
|
|
||||||
const match = /^("?)(.+)\1$/.exec(normalized);
|
|
||||||
const unquoted = match && match[2] || normalized;
|
|
||||||
if ( trustedValues.includes(unquoted) === false ) {
|
|
||||||
if ( /^\d+$/.test(unquoted) === false ) { return; }
|
|
||||||
const n = parseInt(unquoted, 10);
|
|
||||||
if ( n > 32767 ) { return; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const storage = self[`${which}Storage`];
|
|
||||||
if ( value === '$remove$' ) {
|
|
||||||
const safe = safeSelf();
|
|
||||||
const pattern = safe.patternToRegex(key, undefined, true );
|
|
||||||
const toRemove = [];
|
|
||||||
for ( let i = 0, n = storage.length; i < n; i++ ) {
|
|
||||||
const key = storage.key(i);
|
|
||||||
if ( pattern.test(key) ) { toRemove.push(key); }
|
|
||||||
}
|
|
||||||
for ( const key of toRemove ) {
|
|
||||||
storage.removeItem(key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
storage.setItem(key, `${value}`);
|
|
||||||
}
|
|
||||||
} catch(ex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
builtinScriptlets.push({
|
||||||
name: 'matches-stack-trace.fn',
|
name: 'matches-stack-trace.fn',
|
||||||
fn: matchesStackTrace,
|
fn: matchesStackTrace,
|
||||||
@ -3569,43 +3404,6 @@ function removeNodeText(
|
|||||||
replaceNodeTextFn(nodeName, '', '', 'includes', includes || '', ...extraArgs);
|
replaceNodeTextFn(nodeName, '', '', 'includes', includes || '', ...extraArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* set-local-storage-item.js
|
|
||||||
* set-session-storage-item.js
|
|
||||||
*
|
|
||||||
* Set a local/session storage entry to a specific, allowed value.
|
|
||||||
*
|
|
||||||
* Reference:
|
|
||||||
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/set-local-storage-item.js
|
|
||||||
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/set-session-storage-item.js
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'set-local-storage-item.js',
|
|
||||||
fn: setLocalStorageItem,
|
|
||||||
world: 'ISOLATED',
|
|
||||||
dependencies: [
|
|
||||||
'set-local-storage-item.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function setLocalStorageItem(key = '', value = '') {
|
|
||||||
setLocalStorageItemFn('local', false, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'set-session-storage-item.js',
|
|
||||||
fn: setSessionStorageItem,
|
|
||||||
world: 'ISOLATED',
|
|
||||||
dependencies: [
|
|
||||||
'set-local-storage-item.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function setSessionStorageItem(key = '', value = '') {
|
|
||||||
setLocalStorageItemFn('session', false, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* @scriptlet prevent-canvas
|
* @scriptlet prevent-canvas
|
||||||
@ -3693,57 +3491,6 @@ function multiup() {
|
|||||||
document.addEventListener('click', handler, { capture: true });
|
document.addEventListener('click', handler, { capture: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'remove-cache-storage-item.js',
|
|
||||||
fn: removeCacheStorageItem,
|
|
||||||
world: 'ISOLATED',
|
|
||||||
dependencies: [
|
|
||||||
'safe-self.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function removeCacheStorageItem(
|
|
||||||
cacheNamePattern = '',
|
|
||||||
requestPattern = ''
|
|
||||||
) {
|
|
||||||
if ( cacheNamePattern === '' ) { return; }
|
|
||||||
const safe = safeSelf();
|
|
||||||
const logPrefix = safe.makeLogPrefix('remove-cache-storage-item', cacheNamePattern, requestPattern);
|
|
||||||
const cacheStorage = self.caches;
|
|
||||||
if ( cacheStorage instanceof Object === false ) { return; }
|
|
||||||
const reCache = safe.patternToRegex(cacheNamePattern, undefined, true);
|
|
||||||
const reRequest = safe.patternToRegex(requestPattern, undefined, true);
|
|
||||||
cacheStorage.keys().then(cacheNames => {
|
|
||||||
for ( const cacheName of cacheNames ) {
|
|
||||||
if ( reCache.test(cacheName) === false ) { continue; }
|
|
||||||
if ( requestPattern === '' ) {
|
|
||||||
cacheStorage.delete(cacheName).then(result => {
|
|
||||||
if ( safe.logLevel > 1 ) {
|
|
||||||
safe.uboLog(logPrefix, `Deleting ${cacheName}`);
|
|
||||||
}
|
|
||||||
if ( result !== true ) { return; }
|
|
||||||
safe.uboLog(logPrefix, `Deleted ${cacheName}: ${result}`);
|
|
||||||
});
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
cacheStorage.open(cacheName).then(cache => {
|
|
||||||
cache.keys().then(requests => {
|
|
||||||
for ( const request of requests ) {
|
|
||||||
if ( reRequest.test(request.url) === false ) { continue; }
|
|
||||||
if ( safe.logLevel > 1 ) {
|
|
||||||
safe.uboLog(logPrefix, `Deleting ${cacheName}/${request.url}`);
|
|
||||||
}
|
|
||||||
cache.delete(request).then(result => {
|
|
||||||
if ( result !== true ) { return; }
|
|
||||||
safe.uboLog(logPrefix, `Deleted ${cacheName}/${request.url}: ${result}`);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@ -3831,43 +3578,6 @@ function trustedSetConstant(
|
|||||||
setConstantFn(true, ...args);
|
setConstantFn(true, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
*
|
|
||||||
* trusted-set-local-storage-item.js
|
|
||||||
*
|
|
||||||
* Set a local storage entry to an arbitrary value.
|
|
||||||
*
|
|
||||||
* Reference:
|
|
||||||
* https://github.com/AdguardTeam/Scriptlets/blob/master/src/scriptlets/trusted-set-local-storage-item.js
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'trusted-set-local-storage-item.js',
|
|
||||||
requiresTrust: true,
|
|
||||||
fn: trustedSetLocalStorageItem,
|
|
||||||
world: 'ISOLATED',
|
|
||||||
dependencies: [
|
|
||||||
'set-local-storage-item.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function trustedSetLocalStorageItem(key = '', value = '') {
|
|
||||||
setLocalStorageItemFn('local', true, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
builtinScriptlets.push({
|
|
||||||
name: 'trusted-set-session-storage-item.js',
|
|
||||||
requiresTrust: true,
|
|
||||||
fn: trustedSetSessionStorageItem,
|
|
||||||
world: 'ISOLATED',
|
|
||||||
dependencies: [
|
|
||||||
'set-local-storage-item.fn',
|
|
||||||
],
|
|
||||||
});
|
|
||||||
function trustedSetSessionStorageItem(key = '', value = '') {
|
|
||||||
setLocalStorageItemFn('session', true, key, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* trusted-replace-fetch-response.js
|
* trusted-replace-fetch-response.js
|
||||||
|
@ -333,6 +333,8 @@ class RedirectEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.modifyTime = Date.now();
|
this.modifyTime = Date.now();
|
||||||
|
}).catch(reason => {
|
||||||
|
console.error(reason);
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user