mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-10 09:07:54 +01:00
parent
2feadb4a0d
commit
e9157bafb7
12 changed files with 360 additions and 219 deletions
|
@ -42,6 +42,10 @@ vAPI.firefox = true;
|
|||
vAPI.fennec = Services.appinfo.ID === '{aa3c5121-dab2-40e2-81ca-7ea25febc110}';
|
||||
vAPI.thunderbird = Services.appinfo.ID === '{3550f703-e582-4d05-9a08-453d09bdfdc6}';
|
||||
|
||||
if ( vAPI.fennec ) {
|
||||
vAPI.battery = true;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
var deferUntil = function(testFn, mainFn, details) {
|
||||
|
|
|
@ -19,9 +19,12 @@
|
|||
<li><input type="checkbox" id="autoUpdate"><label data-i18n="3pAutoUpdatePrompt1" for="autoUpdate"></label> 
|
||||
<button class="custom important disabled" id="buttonUpdate" data-i18n="3pUpdateNow"></button>
|
||||
<button id="buttonPurgeAll" class="custom disabled" data-i18n="3pPurgeAll"></button>
|
||||
<li><input type="checkbox" id="parseCosmeticFilters"><label data-i18n="3pParseAllABPHideFiltersPrompt1" for="parseCosmeticFilters"></label>
|
||||
<button class="whatisthis"></button>
|
||||
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
|
||||
<li><input type="checkbox" id="parseCosmeticFilters"><label data-i18n="3pParseAllABPHideFiltersPrompt1" for="parseCosmeticFilters"></label><button class="whatisthis"></button>
|
||||
<div class="whatisthis-expandable para" data-i18n="3pParseAllABPHideFiltersInfo"></div>
|
||||
<ul style="padding-left: 2em;">
|
||||
<li><input type="checkbox" id="ignoreGenericCosmeticFilters"><label data-i18n="3pIgnoreGenericCosmeticFilters" for="ignoreGenericCosmeticFilters"></label><button class="whatisthis"></button>
|
||||
<div class="whatisthis-expandable para" data-i18n="3pIgnoreGenericCosmeticFiltersInfo"></div>
|
||||
</ul>
|
||||
<li><p id="listsOfBlockedHostsPrompt"></p>
|
||||
</ul>
|
||||
<ul id="lists"></ul>
|
||||
|
|
|
@ -31,7 +31,8 @@
|
|||
|
||||
var userListName = vAPI.i18n('1pPageName');
|
||||
var listDetails = {};
|
||||
var cosmeticSwitch = true;
|
||||
var parseCosmeticFilters = true;
|
||||
var ignoreGenericCosmeticFilters = false;
|
||||
var externalLists = '';
|
||||
var cacheWasPurged = false;
|
||||
var needUpdate = false;
|
||||
|
@ -216,7 +217,8 @@ var renderFilterLists = function() {
|
|||
var onListsReceived = function(details) {
|
||||
// Before all, set context vars
|
||||
listDetails = details;
|
||||
cosmeticSwitch = details.cosmetic;
|
||||
parseCosmeticFilters = details.parseCosmeticFilters;
|
||||
ignoreGenericCosmeticFilters = details.ignoreGenericCosmeticFilters;
|
||||
needUpdate = false;
|
||||
hasCachedContent = false;
|
||||
|
||||
|
@ -257,7 +259,8 @@ var renderFilterLists = function() {
|
|||
.replace('{{cosmeticFilterCount}}', renderNumber(details.cosmeticFilterCount))
|
||||
);
|
||||
uDom('#autoUpdate').prop('checked', listDetails.autoUpdate === true);
|
||||
uDom('#parseCosmeticFilters').prop('checked', listDetails.cosmetic === true);
|
||||
uDom('#parseCosmeticFilters').prop('checked', listDetails.parseCosmeticFilters === true);
|
||||
uDom('#ignoreGenericCosmeticFilters').prop('checked', listDetails.ignoreGenericCosmeticFilters === true);
|
||||
|
||||
renderWidgets();
|
||||
renderBusyOverlay(details.manualUpdate, details.manualUpdateProgress);
|
||||
|
@ -302,7 +305,10 @@ var renderWidgets = function() {
|
|||
// Return whether selection of lists changed.
|
||||
|
||||
var listsSelectionChanged = function() {
|
||||
if ( listDetails.cosmetic !== cosmeticSwitch ) {
|
||||
if (
|
||||
listDetails.parseCosmeticFilters !== parseCosmeticFilters ||
|
||||
listDetails.parseCosmeticFilters && listDetails.ignoreGenericCosmeticFilters !== ignoreGenericCosmeticFilters
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -401,14 +407,16 @@ var onPurgeClicked = function() {
|
|||
|
||||
var selectFilterLists = function(callback) {
|
||||
// Cosmetic filtering switch
|
||||
messaging.send(
|
||||
'dashboard',
|
||||
{
|
||||
what: 'userSettings',
|
||||
name: 'parseAllABPHideFilters',
|
||||
value: listDetails.cosmetic
|
||||
}
|
||||
);
|
||||
messaging.send('dashboard', {
|
||||
what: 'userSettings',
|
||||
name: 'parseAllABPHideFilters',
|
||||
value: listDetails.parseCosmeticFilters
|
||||
});
|
||||
messaging.send('dashboard', {
|
||||
what: 'userSettings',
|
||||
name: 'ignoreGenericCosmeticFilters',
|
||||
value: listDetails.ignoreGenericCosmeticFilters
|
||||
});
|
||||
|
||||
// Filter lists
|
||||
var switches = [];
|
||||
|
@ -497,7 +505,8 @@ var autoUpdateCheckboxChanged = function() {
|
|||
/******************************************************************************/
|
||||
|
||||
var cosmeticSwitchChanged = function() {
|
||||
listDetails.cosmetic = this.checked;
|
||||
listDetails.parseCosmeticFilters = uDom.nodeFromId('parseCosmeticFilters').checked;
|
||||
listDetails.ignoreGenericCosmeticFilters = uDom.nodeFromId('ignoreGenericCosmeticFilters').checked;
|
||||
renderWidgets();
|
||||
};
|
||||
|
||||
|
@ -556,6 +565,7 @@ var groupEntryClickHandler = function() {
|
|||
var getCloudData = function() {
|
||||
var bin = {
|
||||
parseCosmeticFilters: uDom.nodeFromId('parseCosmeticFilters').checked,
|
||||
ignoreGenericCosmeticFilters: uDom.nodeFromId('ignoreGenericCosmeticFilters').checked,
|
||||
selectedLists: [],
|
||||
externalLists: externalLists
|
||||
};
|
||||
|
@ -580,9 +590,12 @@ var setCloudData = function(data, append) {
|
|||
var elem, checked;
|
||||
|
||||
elem = uDom.nodeFromId('parseCosmeticFilters');
|
||||
checked = data.parseCosmeticFilters === true ||
|
||||
append && elem.checked;
|
||||
elem.checked = listDetails.cosmetic = checked;
|
||||
checked = data.parseCosmeticFilters === true || append && elem.checked;
|
||||
elem.checked = listDetails.parseCosmeticFilters = checked;
|
||||
|
||||
elem = uDom.nodeFromId('ignoreGenericCosmeticFilters');
|
||||
checked = data.ignoreGenericCosmeticFilters === true || append && elem.checked;
|
||||
elem.checked = listDetails.ignoreGenericCosmeticFilters = checked;
|
||||
|
||||
var lis = uDom('#lists .listEntry'), li, listKey;
|
||||
var i = lis.length;
|
||||
|
@ -613,6 +626,7 @@ self.cloud.onPull = setCloudData;
|
|||
|
||||
uDom('#autoUpdate').on('change', autoUpdateCheckboxChanged);
|
||||
uDom('#parseCosmeticFilters').on('change', cosmeticSwitchChanged);
|
||||
uDom('#ignoreGenericCosmeticFilters').on('change', cosmeticSwitchChanged);
|
||||
uDom('#buttonApply').on('click', buttonApplyHandler);
|
||||
uDom('#buttonUpdate').on('click', buttonUpdateHandler);
|
||||
uDom('#buttonPurgeAll').on('click', buttonPurgeAllHandler);
|
||||
|
|
|
@ -59,6 +59,7 @@ return {
|
|||
externalLists: defaultExternalLists,
|
||||
firewallPaneMinimized: true,
|
||||
hyperlinkAuditingDisabled: true,
|
||||
ignoreGenericCosmeticFilters: false,
|
||||
largeMediaSize: 50,
|
||||
parseAllABPHideFilters: true,
|
||||
prefetchingDisabled: true,
|
||||
|
@ -92,7 +93,7 @@ return {
|
|||
// read-only
|
||||
systemSettings: {
|
||||
compiledMagic: 'splsmclwnvoj',
|
||||
selfieMagic: 'splsmclwnvoj'
|
||||
selfieMagic: 'rkzqonintytj'
|
||||
},
|
||||
|
||||
restoreBackupSettings: {
|
||||
|
|
|
@ -280,7 +280,8 @@ var runXpathJob = function(job, fn) {
|
|||
/******************************************************************************/
|
||||
|
||||
var domFilterer = {
|
||||
commitMissCount: 0,
|
||||
addedNodesHandlerMissCount: 0,
|
||||
removedNodesHandlerMissCount: 0,
|
||||
disabledId: vAPI.randomToken(),
|
||||
enabled: true,
|
||||
hiddenId: vAPI.randomToken(),
|
||||
|
@ -387,7 +388,7 @@ var domFilterer = {
|
|||
mustCommit = true;
|
||||
}
|
||||
if ( mustCommit && commitIfNeeded ) {
|
||||
this.commit();
|
||||
this.commit('all');
|
||||
}
|
||||
return mustCommit;
|
||||
},
|
||||
|
@ -397,6 +398,8 @@ var domFilterer = {
|
|||
return;
|
||||
}
|
||||
|
||||
vAPI.executionCost.start();
|
||||
|
||||
var beforeHiddenNodeCount = this.hiddenNodeCount,
|
||||
styleText = '', i, n;
|
||||
|
||||
|
@ -452,9 +455,9 @@ var domFilterer = {
|
|||
|
||||
var commitHit = this.hiddenNodeCount !== beforeHiddenNodeCount;
|
||||
if ( commitHit ) {
|
||||
this.commitMissCount = 0;
|
||||
this.addedNodesHandlerMissCount = 0;
|
||||
} else {
|
||||
this.commitMissCount += 1;
|
||||
this.addedNodesHandlerMissCount += 1;
|
||||
}
|
||||
|
||||
// Un-hide nodes previously hidden.
|
||||
|
@ -478,11 +481,13 @@ var domFilterer = {
|
|||
503
|
||||
);
|
||||
}
|
||||
|
||||
vAPI.executionCost.stop('domFilterer.commit_');
|
||||
},
|
||||
|
||||
commit: function(nodes, commitNow) {
|
||||
var firstCommit = stagedNodes.length === 0;
|
||||
if ( nodes === undefined ) {
|
||||
if ( nodes === 'all' ) {
|
||||
stagedNodes = [ document.documentElement ];
|
||||
} else if ( stagedNodes[0] !== document.documentElement ) {
|
||||
stagedNodes = stagedNodes.concat(nodes);
|
||||
|
@ -601,6 +606,29 @@ var domFilterer = {
|
|||
if ( shadow && shadow[shadowId] && shadow.firstElementChild !== null ) {
|
||||
shadow.removeChild(shadow.firstElementChild);
|
||||
}
|
||||
},
|
||||
|
||||
domChangedHandler: function(addedNodes, removedNodes) {
|
||||
if ( addedNodes.length !== 0 ) {
|
||||
this.commit(addedNodes);
|
||||
}
|
||||
// https://github.com/gorhill/uBlock/issues/873
|
||||
// This will ensure our style elements will stay in the DOM.
|
||||
if ( removedNodes && this.removedNodesHandlerMissCount < 16 ) {
|
||||
if ( domFilterer.checkStyleTags(true) ) {
|
||||
this.removedNodesHandlerMissCount = 0;
|
||||
} else {
|
||||
this.removedNodesHandlerMissCount += 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
start: function() {
|
||||
var domChangedHandler = this.domChangedHandler.bind(this);
|
||||
vAPI.domWatcher.addListener(domChangedHandler);
|
||||
vAPI.shutdown.add(function() {
|
||||
vAPI.domWatcher.removeListener(domChangedHandler);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -660,7 +688,7 @@ return domFilterer;
|
|||
if ( cfeDetails.cosmeticHide.length !== 0 || cfeDetails.cosmeticDonthide.length !== 0 ) {
|
||||
domFilterer.addExceptions(cfeDetails.cosmeticDonthide);
|
||||
domFilterer.addSelectors(cfeDetails.cosmeticHide);
|
||||
domFilterer.commit(undefined, true);
|
||||
domFilterer.commit('all', true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,7 +787,7 @@ vAPI.domWatcher = (function() {
|
|||
}
|
||||
}
|
||||
addedNodeLists.length = 0;
|
||||
if ( addedNodes.length !== 0 ) {
|
||||
if ( addedNodes.length !== 0 || removedNodes ) {
|
||||
listeners[0](addedNodes, removedNodes);
|
||||
if ( listeners[1] ) {
|
||||
listeners[1](addedNodes, removedNodes);
|
||||
|
@ -825,26 +853,16 @@ vAPI.domWatcher = (function() {
|
|||
domLayoutObserver = null;
|
||||
};
|
||||
|
||||
var stop = function() {
|
||||
if ( domLayoutObserver !== null ) {
|
||||
domLayoutObserver.disconnect();
|
||||
domLayoutObserver = null;
|
||||
}
|
||||
if ( safeObserverHandlerTimer !== null ) {
|
||||
window.cancelAnimationFrame(safeObserverHandlerTimer);
|
||||
}
|
||||
};
|
||||
|
||||
var start = function() {
|
||||
// Observe changes in the DOM only if...
|
||||
// - there is a document.body
|
||||
// - there is at least one `script` tag
|
||||
if ( document.body === null || document.querySelector('script') === null ) {
|
||||
vAPI.domWatcher = null;
|
||||
return;
|
||||
}
|
||||
// https://github.com/gorhill/uMatrix/issues/144
|
||||
vAPI.shutdown.add(stop);
|
||||
vAPI.shutdown.add(function() {
|
||||
if ( domLayoutObserver !== null ) {
|
||||
domLayoutObserver.disconnect();
|
||||
domLayoutObserver = null;
|
||||
}
|
||||
if ( safeObserverHandlerTimer !== null ) {
|
||||
window.cancelAnimationFrame(safeObserverHandlerTimer);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -887,16 +905,11 @@ vAPI.domCollapser = (function() {
|
|||
if ( !response ) {
|
||||
return;
|
||||
}
|
||||
// https://github.com/gorhill/uMatrix/issues/144
|
||||
if ( response.shutdown ) {
|
||||
vAPI.shutdown.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
var requests = response.result;
|
||||
if ( requests === null || Array.isArray(requests) === false ) {
|
||||
return;
|
||||
}
|
||||
vAPI.executionCost.start();
|
||||
var selectors = [],
|
||||
netSelectorCacheCountMax = response.netSelectorCacheCountMax,
|
||||
aa = [ null ],
|
||||
|
@ -947,9 +960,11 @@ vAPI.domCollapser = (function() {
|
|||
}
|
||||
);
|
||||
}
|
||||
vAPI.executionCost.stop('domCollapser/onProcessed');
|
||||
};
|
||||
|
||||
var send = function() {
|
||||
vAPI.executionCost.start();
|
||||
timer = null;
|
||||
messaging.send(
|
||||
'contentscript',
|
||||
|
@ -961,6 +976,7 @@ vAPI.domCollapser = (function() {
|
|||
}, onProcessed
|
||||
);
|
||||
roundtripRequests = [];
|
||||
vAPI.executionCost.stop('domCollapser/send');
|
||||
};
|
||||
|
||||
var process = function(delay) {
|
||||
|
@ -1084,6 +1100,13 @@ vAPI.domCollapser = (function() {
|
|||
}
|
||||
};
|
||||
|
||||
var onResourceFailed = function(ev) {
|
||||
vAPI.executionCost.start();
|
||||
vAPI.domCollapser.add(ev.target);
|
||||
vAPI.domCollapser.process();
|
||||
vAPI.executionCost.stop('domCollapser/onResourceFailed');
|
||||
};
|
||||
|
||||
var domChangedHandler = function(nodes) {
|
||||
var node;
|
||||
for ( var i = 0, ni = nodes.length; i < ni; i++ ) {
|
||||
|
@ -1101,13 +1124,6 @@ vAPI.domCollapser = (function() {
|
|||
process();
|
||||
};
|
||||
|
||||
var onResourceFailed = function(ev) {
|
||||
vAPI.executionCost.start();
|
||||
vAPI.domCollapser.add(ev.target);
|
||||
vAPI.domCollapser.process();
|
||||
vAPI.executionCost.stop('domIsLoaded/onResourceFailed');
|
||||
};
|
||||
|
||||
var start = function() {
|
||||
// Listener to collapse blocked resources.
|
||||
// - Future requests not blocked yet
|
||||
|
@ -1131,15 +1147,13 @@ vAPI.domCollapser = (function() {
|
|||
process(0);
|
||||
|
||||
document.addEventListener('error', onResourceFailed, true);
|
||||
if ( vAPI.domWatcher ) {
|
||||
vAPI.domWatcher.addListener(domChangedHandler);
|
||||
}
|
||||
vAPI.domWatcher.addListener(domChangedHandler);
|
||||
|
||||
// https://github.com/gorhill/uMatrix/issues/144
|
||||
vAPI.shutdown.add(function() {
|
||||
document.removeEventListener('error', onResourceFailed, true);
|
||||
if ( vAPI.domWatcher ) {
|
||||
vAPI.domWatcher.removeListener(domChangedHandler);
|
||||
vAPI.domWatcher.removeListener(domChangedHandler);
|
||||
if ( timer !== null ) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -1159,29 +1173,17 @@ vAPI.domCollapser = (function() {
|
|||
/******************************************************************************/
|
||||
|
||||
vAPI.domSurveyor = (function() {
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/789
|
||||
// https://github.com/gorhill/uBlock/issues/873
|
||||
// Be sure that our style tags used for cosmetic filtering are still
|
||||
// applied.
|
||||
|
||||
var domFilterer = null,
|
||||
messaging = vAPI.messaging,
|
||||
surveyPhase3Nodes = [],
|
||||
cosmeticSurveyingMissCount = 0,
|
||||
highGenerics = null,
|
||||
lowGenericSelectors = [],
|
||||
queriedSelectors = Object.create(null),
|
||||
removedNodesHandlerMissCount = 0;
|
||||
queriedSelectors = Object.create(null);
|
||||
|
||||
// Handle main process' response.
|
||||
|
||||
var surveyPhase3 = function(response) {
|
||||
// https://github.com/gorhill/uMatrix/issues/144
|
||||
if ( response && response.shutdown ) {
|
||||
vAPI.shutdown.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
vAPI.executionCost.start();
|
||||
|
||||
var result = response && response.result,
|
||||
|
@ -1232,7 +1234,7 @@ vAPI.domSurveyor = (function() {
|
|||
domFilterer.commit(surveyPhase3Nodes);
|
||||
surveyPhase3Nodes = [];
|
||||
|
||||
vAPI.executionCost.stop('domIsLoaded/surveyPhase2');
|
||||
vAPI.executionCost.stop('domSurveyor/surveyPhase3');
|
||||
};
|
||||
|
||||
// Query main process.
|
||||
|
@ -1465,31 +1467,27 @@ vAPI.domSurveyor = (function() {
|
|||
};
|
||||
|
||||
var domChangedHandler = function(addedNodes, removedNodes) {
|
||||
if ( cosmeticSurveyingMissCount < 256 ) {
|
||||
surveyPhase1(addedNodes);
|
||||
} else {
|
||||
domFilterer.commit(addedNodes);
|
||||
if ( cosmeticSurveyingMissCount > 255 ) {
|
||||
vAPI.domWatcher.removeListener(domChangedHandler);
|
||||
vAPI.domSurveyor = null;
|
||||
domFilterer.domChangedHandler(addedNodes, removedNodes);
|
||||
domFilterer.start();
|
||||
return;
|
||||
}
|
||||
// https://github.com/gorhill/uBlock/issues/873
|
||||
// This will ensure our style elements will stay in the DOM.
|
||||
if ( removedNodes && removedNodesHandlerMissCount < 16 ) {
|
||||
if ( domFilterer.checkStyleTags(true) === false ) {
|
||||
removedNodesHandlerMissCount += 1;
|
||||
}
|
||||
|
||||
surveyPhase1(addedNodes);
|
||||
if ( removedNodes ) {
|
||||
domFilterer.domChangedHandler([], true);
|
||||
}
|
||||
};
|
||||
|
||||
var start = function() {
|
||||
domFilterer = vAPI.domFilterer;
|
||||
if ( domFilterer === null ) {
|
||||
return;
|
||||
}
|
||||
domFilterer.checkStyleTags(false);
|
||||
domFilterer.commit();
|
||||
domChangedHandler([ document.documentElement ]);
|
||||
if ( vAPI.domWatcher ) {
|
||||
vAPI.domWatcher.addListener(domChangedHandler);
|
||||
}
|
||||
vAPI.domWatcher.addListener(domChangedHandler);
|
||||
vAPI.shutdown.add(function() {
|
||||
vAPI.domWatcher.removeListener(domChangedHandler);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -1514,16 +1512,20 @@ vAPI.domIsLoaded = function(ev) {
|
|||
|
||||
vAPI.executionCost.start();
|
||||
|
||||
if ( vAPI.domWatcher ) {
|
||||
vAPI.domWatcher.start();
|
||||
}
|
||||
vAPI.domWatcher.start();
|
||||
vAPI.domCollapser.start();
|
||||
|
||||
if ( vAPI.domCollapser ) {
|
||||
vAPI.domCollapser.start();
|
||||
}
|
||||
|
||||
if ( vAPI.domFilterer && vAPI.domSurveyor ) {
|
||||
vAPI.domSurveyor.start();
|
||||
if ( vAPI.domFilterer ) {
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/789
|
||||
// https://github.com/gorhill/uBlock/issues/873
|
||||
// Be sure our style tags used for cosmetic filtering are still applied.
|
||||
vAPI.domFilterer.checkStyleTags(false);
|
||||
vAPI.domFilterer.commit('all');
|
||||
if ( vAPI.domSurveyor ) {
|
||||
vAPI.domSurveyor.start();
|
||||
} else {
|
||||
vAPI.domFilterer.start();
|
||||
}
|
||||
}
|
||||
|
||||
// To send mouse coordinates to main process, as the chrome API fails
|
||||
|
@ -1533,30 +1535,26 @@ vAPI.domIsLoaded = function(ev) {
|
|||
// as nuisance popups.
|
||||
// Ref.: https://developer.mozilla.org/en-US/docs/Web/Events/contextmenu
|
||||
|
||||
var onMouseClick = function(ev) {
|
||||
var elem = ev.target;
|
||||
while ( elem !== null && elem.localName !== 'a' ) {
|
||||
elem = elem.parentElement;
|
||||
}
|
||||
vAPI.messaging.send(
|
||||
'contentscript',
|
||||
{
|
||||
what: 'mouseClick',
|
||||
x: ev.clientX,
|
||||
y: ev.clientY,
|
||||
url: elem !== null ? elem.href : ''
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
(function() {
|
||||
if ( window !== window.top || !vAPI.domFilterer ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var messaging = vAPI.messaging;
|
||||
|
||||
var onMouseClick = function(ev) {
|
||||
vAPI.executionCost.start();
|
||||
var elem = ev.target;
|
||||
while ( elem !== null && elem.localName !== 'a' ) {
|
||||
elem = elem.parentElement;
|
||||
}
|
||||
messaging.send(
|
||||
'contentscript',
|
||||
{
|
||||
what: 'mouseClick',
|
||||
x: ev.clientX,
|
||||
y: ev.clientY,
|
||||
url: elem !== null ? elem.href : ''
|
||||
});
|
||||
vAPI.executionCost.stop('domIsLoaded/onMouseClick');
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', onMouseClick, true);
|
||||
|
||||
// https://github.com/gorhill/uMatrix/issues/144
|
||||
|
|
|
@ -690,9 +690,12 @@ FilterContainer.prototype.reset = function() {
|
|||
this.selectorCacheTimer = null;
|
||||
}
|
||||
|
||||
// permanent
|
||||
// generic filters
|
||||
this.hasGenericHide = false;
|
||||
|
||||
// [class], [id]
|
||||
this.lowGenericHide = {};
|
||||
this.lowGenericHideCount = 0;
|
||||
|
||||
// [alt="..."], [title="..."]
|
||||
this.highLowGenericHide = {};
|
||||
|
@ -726,6 +729,33 @@ FilterContainer.prototype.reset = function() {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.freeze = function() {
|
||||
this.duplicateBuster = {};
|
||||
|
||||
if ( this.highHighSimpleGenericHide !== '' ) {
|
||||
this.highHighSimpleGenericHideArray.unshift(this.highHighSimpleGenericHide);
|
||||
}
|
||||
this.highHighSimpleGenericHide = this.highHighSimpleGenericHideArray.join(',\n');
|
||||
this.highHighSimpleGenericHideArray = [];
|
||||
|
||||
if ( this.highHighComplexGenericHide !== '' ) {
|
||||
this.highHighComplexGenericHideArray.unshift(this.highHighComplexGenericHide);
|
||||
}
|
||||
this.highHighComplexGenericHide = this.highHighComplexGenericHideArray.join(',\n');
|
||||
this.highHighComplexGenericHideArray = [];
|
||||
|
||||
this.hasGenericHide = this.lowGenericHideCount !== 0 ||
|
||||
this.highLowGenericHideCount !== 0 ||
|
||||
this.highMediumGenericHideCount !== 0 ||
|
||||
this.highHighSimpleGenericHideCount !== 0 ||
|
||||
this.highHighComplexGenericHideCount !== 0;
|
||||
|
||||
this.parser.reset();
|
||||
this.frozen = true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/1004
|
||||
// Detect and report invalid CSS selectors.
|
||||
|
||||
|
@ -1006,26 +1036,23 @@ FilterContainer.prototype.compileEntitySelector = function(hostname, parsed, out
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
||||
if ( skip ) {
|
||||
return this.skipCompiledContent(text, lineBeg);
|
||||
FilterContainer.prototype.fromCompiledContent = function(lineIter, skipGenericCosmetic, skipCosmetic) {
|
||||
if ( skipCosmetic ) {
|
||||
this.skipCompiledContent(lineIter);
|
||||
return;
|
||||
}
|
||||
if ( skipGenericCosmetic ) {
|
||||
this.skipGenericCompiledContent(lineIter);
|
||||
return;
|
||||
}
|
||||
|
||||
var lineEnd;
|
||||
var textEnd = text.length;
|
||||
var line, fields, filter, key, bucket;
|
||||
|
||||
while ( lineBeg < textEnd ) {
|
||||
if ( text.charCodeAt(lineBeg) !== 0x63 /* 'c' */ ) {
|
||||
return lineBeg;
|
||||
while ( lineIter.eot() === false ) {
|
||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
||||
return;
|
||||
}
|
||||
lineEnd = text.indexOf('\n', lineBeg);
|
||||
if ( lineEnd === -1 ) {
|
||||
lineEnd = textEnd;
|
||||
}
|
||||
line = text.slice(lineBeg + 2, lineEnd);
|
||||
lineBeg = lineEnd + 1;
|
||||
|
||||
line = lineIter.next().slice(2);
|
||||
|
||||
this.acceptedCount += 1;
|
||||
if ( this.duplicateBuster.hasOwnProperty(line) ) {
|
||||
|
@ -1069,6 +1096,7 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||
} else {
|
||||
this.lowGenericHide[fields[1]] = new FilterBucket(bucket, filter);
|
||||
}
|
||||
this.lowGenericHideCount += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1124,30 +1152,114 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg, skip) {
|
|||
// Generic exception filters: expected to be a rare occurrence.
|
||||
if ( fields[0] === 'g1' ) {
|
||||
this.genericDonthide.push(fields[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.discardedCount += 1;
|
||||
}
|
||||
return textEnd;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.skipCompiledContent = function(text, lineBeg) {
|
||||
var lineEnd;
|
||||
var textEnd = text.length;
|
||||
FilterContainer.prototype.skipGenericCompiledContent = function(lineIter) {
|
||||
var line, fields, filter, bucket;
|
||||
|
||||
while ( lineBeg < textEnd ) {
|
||||
if ( text.charCodeAt(lineBeg) !== 0x63 /* 'c' */ ) {
|
||||
return lineBeg;
|
||||
}
|
||||
lineEnd = text.indexOf('\n', lineBeg);
|
||||
if ( lineEnd === -1 ) {
|
||||
lineEnd = textEnd;
|
||||
while ( lineIter.eot() === false ) {
|
||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
||||
return;
|
||||
}
|
||||
line = lineIter.next().slice(2);
|
||||
|
||||
this.acceptedCount += 1;
|
||||
if ( this.duplicateBuster.hasOwnProperty(line) ) {
|
||||
this.discardedCount += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
fields = line.split('\v');
|
||||
|
||||
// h [\t] ir [\t] twitter.com [\t] .promoted-tweet
|
||||
if ( fields[0] === 'h' ) {
|
||||
this.duplicateBuster[line] = true;
|
||||
// Special filter: script tags. Not a real CSS selector.
|
||||
if ( fields[3].startsWith('script') ) {
|
||||
this.createScriptFilter(fields[2], fields[3].slice(6));
|
||||
continue;
|
||||
}
|
||||
filter = new FilterHostname(fields[3], fields[2]);
|
||||
bucket = this.hostnameFilters[fields[1]];
|
||||
if ( bucket === undefined ) {
|
||||
this.hostnameFilters[fields[1]] = filter;
|
||||
} else if ( bucket instanceof FilterBucket ) {
|
||||
bucket.add(filter);
|
||||
} else {
|
||||
this.hostnameFilters[fields[1]] = new FilterBucket(bucket, filter);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// entity [\t] selector
|
||||
if ( fields[0] === 'e' ) {
|
||||
this.duplicateBuster[line] = true;
|
||||
// Special filter: script tags. Not a real CSS selector.
|
||||
if ( fields[2].startsWith('script') ) {
|
||||
this.createScriptFilter(fields[1], fields[2].slice(6));
|
||||
continue;
|
||||
}
|
||||
bucket = this.entityFilters[fields[1]];
|
||||
if ( bucket === undefined ) {
|
||||
this.entityFilters[fields[1]] = [fields[2]];
|
||||
} else {
|
||||
bucket.push(fields[2]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// https://github.com/chrisaljoudi/uBlock/issues/497
|
||||
// Generic exception filters: expected to be a rare occurrence.
|
||||
if ( fields[0] === 'g1' ) {
|
||||
this.duplicateBuster[line] = true;
|
||||
this.genericDonthide.push(fields[1]);
|
||||
continue;
|
||||
}
|
||||
|
||||
this.discardedCount += 1;
|
||||
}
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.skipCompiledContent = function(lineIter) {
|
||||
var line, fields;
|
||||
|
||||
while ( lineIter.eot() === false ) {
|
||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x63 /* 'c' */ ) {
|
||||
return;
|
||||
}
|
||||
line = lineIter.next().slice(2);
|
||||
|
||||
this.acceptedCount += 1;
|
||||
if ( this.duplicateBuster.hasOwnProperty(line) ) {
|
||||
this.discardedCount += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
fields = line.split('\v');
|
||||
|
||||
if ( fields[0] === 'h' && fields[3].startsWith('script') ) {
|
||||
this.duplicateBuster[line] = true;
|
||||
this.createScriptFilter(fields[2], fields[3].slice(6));
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( fields[0] === 'e' && fields[2].startsWith('script') ) {
|
||||
this.duplicateBuster[line] = true;
|
||||
this.createScriptFilter(fields[1], fields[2].slice(6));
|
||||
continue;
|
||||
}
|
||||
|
||||
this.discardedCount += 1;
|
||||
lineBeg = lineEnd + 1;
|
||||
}
|
||||
return textEnd;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -1260,27 +1372,6 @@ FilterContainer.prototype.retrieveScriptTags = function(domain, hostname) {
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.freeze = function() {
|
||||
this.duplicateBuster = {};
|
||||
|
||||
if ( this.highHighSimpleGenericHide !== '' ) {
|
||||
this.highHighSimpleGenericHideArray.unshift(this.highHighSimpleGenericHide);
|
||||
}
|
||||
this.highHighSimpleGenericHide = this.highHighSimpleGenericHideArray.join(',\n');
|
||||
this.highHighSimpleGenericHideArray = [];
|
||||
|
||||
if ( this.highHighComplexGenericHide !== '' ) {
|
||||
this.highHighComplexGenericHideArray.unshift(this.highHighComplexGenericHide);
|
||||
}
|
||||
this.highHighComplexGenericHide = this.highHighComplexGenericHideArray.join(',\n');
|
||||
this.highHighComplexGenericHideArray = [];
|
||||
|
||||
this.parser.reset();
|
||||
this.frozen = true;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.toSelfie = function() {
|
||||
var selfieFromDict = function(dict) {
|
||||
var selfie = [];
|
||||
|
@ -1312,7 +1403,9 @@ FilterContainer.prototype.toSelfie = function() {
|
|||
discardedCount: this.discardedCount,
|
||||
hostnameSpecificFilters: selfieFromDict(this.hostnameFilters),
|
||||
entitySpecificFilters: this.entityFilters,
|
||||
hasGenericHide: this.hasGenericHide,
|
||||
lowGenericHide: selfieFromDict(this.lowGenericHide),
|
||||
lowGenericHideCount: this.lowGenericHideCount,
|
||||
highLowGenericHide: this.highLowGenericHide,
|
||||
highLowGenericHideCount: this.highLowGenericHideCount,
|
||||
highMediumGenericHide: this.highMediumGenericHide,
|
||||
|
@ -1378,7 +1471,9 @@ FilterContainer.prototype.fromSelfie = function(selfie) {
|
|||
this.discardedCount = selfie.discardedCount;
|
||||
this.hostnameFilters = dictFromSelfie(selfie.hostnameSpecificFilters);
|
||||
this.entityFilters = selfie.entitySpecificFilters;
|
||||
this.hasGenericHide = selfie.hasGenericHide;
|
||||
this.lowGenericHide = dictFromSelfie(selfie.lowGenericHide);
|
||||
this.lowGenericHideCount = selfie.lowGenericHideCount;
|
||||
this.highLowGenericHide = selfie.highLowGenericHide;
|
||||
this.highLowGenericHideCount = selfie.highLowGenericHideCount;
|
||||
this.highMediumGenericHide = selfie.highMediumGenericHide;
|
||||
|
@ -1573,7 +1668,7 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request, noCosmetic
|
|||
ready: this.frozen,
|
||||
domain: domain,
|
||||
entity: pos === -1 ? domain : domain.slice(0, pos - domain.length),
|
||||
noDOMSurveying: false,
|
||||
noDOMSurveying: this.hasGenericHide === false,
|
||||
cosmeticHide: [],
|
||||
cosmeticDonthide: [],
|
||||
netHide: [],
|
||||
|
@ -1600,7 +1695,9 @@ FilterContainer.prototype.retrieveDomainSelectors = function(request, noCosmetic
|
|||
// cached cosmetic filters.
|
||||
if ( cacheEntry ) {
|
||||
cacheEntry.retrieve('cosmetic', r.cosmeticHide);
|
||||
r.noDOMSurveying = cacheEntry.cosmeticSurveyingMissCount > cosmeticSurveyingMissCountMax;
|
||||
if ( r.noDOMSurveying === false ) {
|
||||
r.noDOMSurveying = cacheEntry.cosmeticSurveyingMissCount > cosmeticSurveyingMissCountMax;
|
||||
}
|
||||
}
|
||||
|
||||
// Exception cosmetic filters.
|
||||
|
|
|
@ -110,5 +110,6 @@ uDom('.whatisthis').on('click', function() {
|
|||
uDom(this)
|
||||
.parent()
|
||||
.descendants('.whatisthis-expandable')
|
||||
.first()
|
||||
.toggleClass('whatisthis-expanded');
|
||||
});
|
||||
|
|
|
@ -534,23 +534,19 @@ var onMessage = function(request, sender, callback) {
|
|||
break;
|
||||
|
||||
case 'retrieveGenericCosmeticSelectors':
|
||||
response = {
|
||||
shutdown: !pageStore || !pageStore.getNetFilteringSwitch(),
|
||||
result: null
|
||||
};
|
||||
if ( !response.shutdown && pageStore.getGenericCosmeticFilteringSwitch() ) {
|
||||
response.result = µb.cosmeticFilteringEngine.retrieveGenericSelectors(request);
|
||||
if ( pageStore && pageStore.getGenericCosmeticFilteringSwitch() ) {
|
||||
response = {
|
||||
result: µb.cosmeticFilteringEngine.retrieveGenericSelectors(request)
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
case 'filterRequests':
|
||||
response = {
|
||||
shutdown: !pageStore || !pageStore.getNetFilteringSwitch(),
|
||||
result: null,
|
||||
netSelectorCacheCountMax: µb.cosmeticFilteringEngine.netSelectorCacheCountMax
|
||||
};
|
||||
if ( !response.shutdown ) {
|
||||
response.result = filterRequests(pageStore, request);
|
||||
if ( pageStore && pageStore.getNetFilteringSwitch() ) {
|
||||
response = {
|
||||
result: filterRequests(pageStore, request),
|
||||
netSelectorCacheCountMax: µb.cosmeticFilteringEngine.netSelectorCacheCountMax
|
||||
};
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -855,9 +851,10 @@ var getLists = function(callback) {
|
|||
autoUpdate: µb.userSettings.autoUpdate,
|
||||
available: null,
|
||||
cache: null,
|
||||
cosmetic: µb.userSettings.parseAllABPHideFilters,
|
||||
parseCosmeticFilters: µb.userSettings.parseAllABPHideFilters,
|
||||
cosmeticFilterCount: µb.cosmeticFilteringEngine.getFilterCount(),
|
||||
current: µb.remoteBlacklists,
|
||||
ignoreGenericCosmeticFilters: µb.userSettings.ignoreGenericCosmeticFilters,
|
||||
manualUpdate: false,
|
||||
netFilterCount: µb.staticNetFilteringEngine.getFilterCount(),
|
||||
userFiltersPath: µb.userFiltersPath
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock - a browser extension to block requests.
|
||||
Copyright (C) 2014-2015 Raymond Hill
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2014-2016 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
|
||||
|
@ -19,7 +19,9 @@
|
|||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
/* global publicSuffixList, vAPI, µBlock */
|
||||
/* global publicSuffixList */
|
||||
|
||||
'use strict';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
|
@ -27,8 +29,6 @@
|
|||
|
||||
µBlock.restart = (function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
//quickProfiler.start('start.js');
|
||||
|
||||
/******************************************************************************/
|
||||
|
@ -178,6 +178,13 @@ var onUserSettingsReady = function(fetched) {
|
|||
µb.sessionURLFiltering.assign(µb.permanentURLFiltering);
|
||||
µb.hnSwitches.fromString(fetched.hostnameSwitchesString);
|
||||
|
||||
// https://github.com/gorhill/uBlock/issues/1892
|
||||
// For first installation on a battery-powered device, disable generic
|
||||
// cosmetic filtering.
|
||||
if ( µb.firstInstall && vAPI.battery ) {
|
||||
userSettings.ignoreGenericCosmeticFilters = true;
|
||||
}
|
||||
|
||||
// Remove obsolete setting
|
||||
delete userSettings.logRequests;
|
||||
vAPI.storage.remove('logRequests');
|
||||
|
|
|
@ -2055,22 +2055,15 @@ FilterContainer.prototype.compileToAtomicFilter = function(filterClass, parsed,
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
FilterContainer.prototype.fromCompiledContent = function(text, lineBeg) {
|
||||
var lineEnd;
|
||||
var textEnd = text.length;
|
||||
FilterContainer.prototype.fromCompiledContent = function(lineIter) {
|
||||
var line, fields, bucket, entry, factory, filter;
|
||||
|
||||
while ( lineBeg < textEnd ) {
|
||||
if ( text.charCodeAt(lineBeg) !== 0x6E /* 'n' */ ) {
|
||||
return lineBeg;
|
||||
while ( lineIter.eot() === false ) {
|
||||
if ( lineIter.text.charCodeAt(lineIter.offset) !== 0x6E /* 'n' */ ) {
|
||||
return;
|
||||
}
|
||||
lineEnd = text.indexOf('\n', lineBeg);
|
||||
if ( lineEnd === -1 ) {
|
||||
lineEnd = textEnd;
|
||||
}
|
||||
line = text.slice(lineBeg + 2, lineEnd);
|
||||
line = lineIter.next().slice(2);
|
||||
fields = line.split('\v');
|
||||
lineBeg = lineEnd + 1;
|
||||
|
||||
// Special cases: delegate to more specialized engines.
|
||||
// Redirect engine.
|
||||
|
@ -2124,7 +2117,6 @@ FilterContainer.prototype.fromCompiledContent = function(text, lineBeg) {
|
|||
}
|
||||
bucket[fields[1]] = new FilterBucket(entry, filter);
|
||||
}
|
||||
return textEnd;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
|
@ -632,14 +632,14 @@
|
|||
// applying 1st-party filters.
|
||||
|
||||
µBlock.applyCompiledFilters = function(rawText, firstparty) {
|
||||
var skipCosmetic = !firstparty && !this.userSettings.parseAllABPHideFilters;
|
||||
var staticNetFilteringEngine = this.staticNetFilteringEngine;
|
||||
var cosmeticFilteringEngine = this.cosmeticFilteringEngine;
|
||||
var lineBeg = 0;
|
||||
var rawEnd = rawText.length;
|
||||
while ( lineBeg < rawEnd ) {
|
||||
lineBeg = cosmeticFilteringEngine.fromCompiledContent(rawText, lineBeg, skipCosmetic);
|
||||
lineBeg = staticNetFilteringEngine.fromCompiledContent(rawText, lineBeg);
|
||||
var skipCosmetic = !firstparty && !this.userSettings.parseAllABPHideFilters,
|
||||
skipGenericCosmetic = this.userSettings.ignoreGenericCosmeticFilters,
|
||||
staticNetFilteringEngine = this.staticNetFilteringEngine,
|
||||
cosmeticFilteringEngine = this.cosmeticFilteringEngine,
|
||||
lineIter = new this.LineIterator(rawText);
|
||||
while ( lineIter.eot() === false ) {
|
||||
cosmeticFilteringEngine.fromCompiledContent(lineIter, skipGenericCosmetic, skipCosmetic);
|
||||
staticNetFilteringEngine.fromCompiledContent(lineIter);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a browser extension to block requests.
|
||||
Copyright (C) 2014-2015 Raymond Hill
|
||||
Copyright (C) 2014-2016 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
|
||||
|
@ -123,3 +123,30 @@
|
|||
// https://www.youtube.com/watch?v=DyvzfyqYm_s
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
µBlock.LineIterator = function(text, offset) {
|
||||
this.text = text;
|
||||
this.offset = offset || 0;
|
||||
};
|
||||
|
||||
µBlock.LineIterator.prototype.next = function() {
|
||||
if ( this.offset >= this.text.length ) {
|
||||
return undefined;
|
||||
}
|
||||
var lineEnd = this.text.indexOf('\n', this.offset);
|
||||
if ( lineEnd === -1 ) {
|
||||
lineEnd = this.text.indexOf('\r', this.offset);
|
||||
if ( lineEnd === -1 ) {
|
||||
lineEnd = this.text.length;
|
||||
}
|
||||
}
|
||||
var line = this.text.slice(this.offset, lineEnd);
|
||||
this.offset = lineEnd + 1;
|
||||
return line;
|
||||
};
|
||||
|
||||
µBlock.LineIterator.prototype.eot = function() {
|
||||
return this.offset >= this.text.length;
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
Loading…
Reference in a new issue