inject scriptlets earlier (experimental) (ex. https://github.com/uBlockOrigin/uAssets/issues/2300)

This commit is contained in:
Raymond Hill 2018-05-17 07:33:21 -04:00
parent 02810664df
commit c5d8588118
No known key found for this signature in database
GPG key ID: 25E1490B761470C2
5 changed files with 64 additions and 38 deletions

View file

@ -350,16 +350,7 @@ vAPI.tabs.registerListeners = function() {
}
};
var onBeforeNavigate = function(details) {
if ( details.frameId !== 0 ) {
return;
}
};
var onCommitted = function(details) {
if ( details.frameId !== 0 ) {
return;
}
details.url = sanitizeURL(details.url);
onNavigationClient(details);
};
@ -382,7 +373,6 @@ vAPI.tabs.registerListeners = function() {
onUpdatedClient(tabId, changeInfo, tab);
};
chrome.webNavigation.onBeforeNavigate.addListener(onBeforeNavigate);
chrome.webNavigation.onCommitted.addListener(onCommitted);
// Not supported on Firefox WebExtensions yet.
if ( chrome.webNavigation.onCreatedNavigationTarget instanceof Object ) {

View file

@ -42,6 +42,7 @@ var µBlock = (function() { // jshint ignore:line
assetFetchTimeout: 30,
autoUpdateAssetFetchPeriod: 120,
autoUpdatePeriod: 7,
debugScriptlets: false,
ignoreRedirectFilters: false,
ignoreScriptInjectFilters: false,
manualUpdateAssetFetchPeriod: 500,

View file

@ -517,7 +517,6 @@ var onMessage = function(request, sender, callback) {
request.entity = µb.URI.entityFromDomain(request.domain);
response.specificCosmeticFilters =
µb.cosmeticFilteringEngine.retrieveDomainSelectors(request, response);
response.scriptlets = µb.scriptletFilteringEngine.retrieve(request);
if ( request.isRootFrame && µb.logger.isEnabled() ) {
µb.logCosmeticFilters(tabId);
}

View file

@ -1,7 +1,7 @@
/*******************************************************************************
uBlock Origin - a browser extension to block requests.
Copyright (C) 2017 Raymond Hill
Copyright (C) 2017-2018 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
@ -24,9 +24,9 @@
/******************************************************************************/
µBlock.scriptletFilteringEngine = (function() {
var api = {};
let api = {};
var µb = µBlock,
let µb = µBlock,
scriptletDB = new µb.staticExtFilteringEngine.HostnameBasedDB(),
duplicates = new Set(),
acceptedCount = 0,
@ -36,15 +36,29 @@
scriptletsRegister = new Map(),
reEscapeScriptArg = /[\\'"]/g;
var scriptletRemover = [
'(function() {',
' var c = document.currentScript, p = c && c.parentNode;',
' if ( p ) { p.removeChild(c); }',
'})();'
].join('\n');
let contentscriptCodeParts = [
'(',
function() {
let d = document;
let script = d.createElement('script');
try {
script.appendChild(d.createTextNode(
decodeURIComponent(arguments[0]))
);
(d.head || d.documentElement).appendChild(script);
} catch (ex) {
}
if ( script.parentNode ) {
script.parentNode.removeChild(script);
}
}.toString(),
')("', 'scriptlets-slot', '");\n',
'void 0;',
];
let contentscriptCodeScriptletsSlot =
contentscriptCodeParts.indexOf('scriptlets-slot');
var lookupScriptlet = function(raw, reng, toInject) {
let lookupScriptlet = function(raw, reng, toInject) {
if ( toInject.has(raw) ) { return; }
if ( scriptletCache.resetTime < reng.modifyTime ) {
scriptletCache.reset();
@ -77,7 +91,7 @@
// Fill template placeholders. Return falsy if:
// - At least one argument contains anything else than /\w/ and `.`
var patchScriptlet = function(content, args) {
let patchScriptlet = function(content, args) {
var i = 1,
pos, arg;
while ( args !== '' ) {
@ -91,7 +105,7 @@
return content;
};
var logOne = function(isException, token, details) {
let logOne = function(isException, token, details) {
µb.logger.writeOne(
details.tabId,
'cosmetic',
@ -256,16 +270,38 @@
if ( out.length === 0 ) { return; }
out.push(scriptletRemover);
return out.join('\n');
};
api.apply = function(doc, details) {
var script = doc.createElement('script');
script.textContent = details.scriptlets;
doc.head.insertBefore(script, doc.head.firstChild);
return true;
api.injectNow = function(details) {
if ( typeof details.frameId !== 'number' ) { return; }
if ( µb.URI.isNetworkURI(details.url) === false ) { return; }
let request = {
tabId: details.tabId,
frameId: details.frameId,
url: details.url,
hostname: µb.URI.hostnameFromURI(details.url),
domain: undefined,
entity: undefined
};
request.domain = µb.URI.domainFromHostname(request.hostname);
request.entity = µb.URI.entityFromDomain(request.domain);
let scriptlets = µb.scriptletFilteringEngine.retrieve(request);
if ( scriptlets === undefined ) { return; }
if ( µb.hiddenSettings.debugScriptlets ) {
scriptlets = 'debugger;\n' + scriptlets;
}
contentscriptCodeParts[contentscriptCodeScriptletsSlot] =
encodeURIComponent(scriptlets);
chrome.tabs.executeScript(
details.tabId,
{
code: contentscriptCodeParts.join(''),
frameId: details.frameId,
matchAboutBlank: true,
runAt: 'document_start'
}
);
};
api.toSelfie = function() {

View file

@ -486,14 +486,14 @@ housekeep itself.
// content has changed.
vAPI.tabs.onNavigation = function(details) {
if ( details.frameId !== 0 ) {
return;
}
µb.tabContextManager.commit(details.tabId, details.url);
var pageStore = µb.bindTabToPageStats(details.tabId, 'tabCommitted');
if ( pageStore ) {
pageStore.journalAddRootFrame('committed', details.url);
if ( details.frameId === 0 ) {
µb.tabContextManager.commit(details.tabId, details.url);
let pageStore = µb.bindTabToPageStats(details.tabId, 'tabCommitted');
if ( pageStore ) {
pageStore.journalAddRootFrame('committed', details.url);
}
}
µb.scriptletFilteringEngine.injectNow(details);
};
/******************************************************************************/