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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
uBlock Origin - a browser extension to block requests. 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 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 it under the terms of the GNU General Public License as published by
@ -24,9 +24,9 @@
/******************************************************************************/ /******************************************************************************/
µBlock.scriptletFilteringEngine = (function() { µBlock.scriptletFilteringEngine = (function() {
var api = {}; let api = {};
var µb = µBlock, let µb = µBlock,
scriptletDB = new µb.staticExtFilteringEngine.HostnameBasedDB(), scriptletDB = new µb.staticExtFilteringEngine.HostnameBasedDB(),
duplicates = new Set(), duplicates = new Set(),
acceptedCount = 0, acceptedCount = 0,
@ -36,15 +36,29 @@
scriptletsRegister = new Map(), scriptletsRegister = new Map(),
reEscapeScriptArg = /[\\'"]/g; reEscapeScriptArg = /[\\'"]/g;
var scriptletRemover = [ let contentscriptCodeParts = [
'(function() {', '(',
' var c = document.currentScript, p = c && c.parentNode;', function() {
' if ( p ) { p.removeChild(c); }', let d = document;
'})();' let script = d.createElement('script');
].join('\n'); 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');
let lookupScriptlet = function(raw, reng, toInject) {
var lookupScriptlet = function(raw, reng, toInject) {
if ( toInject.has(raw) ) { return; } if ( toInject.has(raw) ) { return; }
if ( scriptletCache.resetTime < reng.modifyTime ) { if ( scriptletCache.resetTime < reng.modifyTime ) {
scriptletCache.reset(); scriptletCache.reset();
@ -77,7 +91,7 @@
// Fill template placeholders. Return falsy if: // Fill template placeholders. Return falsy if:
// - At least one argument contains anything else than /\w/ and `.` // - At least one argument contains anything else than /\w/ and `.`
var patchScriptlet = function(content, args) { let patchScriptlet = function(content, args) {
var i = 1, var i = 1,
pos, arg; pos, arg;
while ( args !== '' ) { while ( args !== '' ) {
@ -91,7 +105,7 @@
return content; return content;
}; };
var logOne = function(isException, token, details) { let logOne = function(isException, token, details) {
µb.logger.writeOne( µb.logger.writeOne(
details.tabId, details.tabId,
'cosmetic', 'cosmetic',
@ -256,16 +270,38 @@
if ( out.length === 0 ) { return; } if ( out.length === 0 ) { return; }
out.push(scriptletRemover);
return out.join('\n'); return out.join('\n');
}; };
api.apply = function(doc, details) { api.injectNow = function(details) {
var script = doc.createElement('script'); if ( typeof details.frameId !== 'number' ) { return; }
script.textContent = details.scriptlets; if ( µb.URI.isNetworkURI(details.url) === false ) { return; }
doc.head.insertBefore(script, doc.head.firstChild); let request = {
return true; 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() { api.toSelfie = function() {

View File

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