Bail out when counting hidden elements is too expensive

Related issue:
- https://github.com/uBlockOrigin/uBlock-issues/issues/756

When trying the number of hidden elements as a result of
cosmetic filtering for popup panel badge purpose, the
code will bail out if this takes too long, and in such
case the badge will be set to `?`, meaning the number
of hidden elements is undetermined.
This commit is contained in:
Raymond Hill 2019-11-02 09:16:23 -04:00
parent d30c0192b3
commit 6d935c8925
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
3 changed files with 19 additions and 9 deletions

View File

@ -374,10 +374,11 @@ const getElementCount = async function(tabId, what) {
});
let total = 0;
results.forEach(count => {
if ( typeof count !== 'number' ) { return; }
for ( const count of results ) {
if ( typeof count !== 'number' ) { continue; }
if ( count === -1 ) { return -1; }
total += count;
});
}
return total;
};

View File

@ -688,9 +688,15 @@ const renderPopupLazy = (( ) => {
what: 'getHiddenElementCount',
tabId: popupData.tabId,
}).then(count => {
badge.textContent = (count || 0) !== 0
? Math.min(count, 99).toLocaleString()
: '';
let text;
if ( (count || 0) === 0 ) {
text = '';
} else if ( count === -1 ) {
text = '?';
} else {
text = Math.min(count, 99).toLocaleString();
}
badge.textContent = text;
sw.classList.remove('hnSwitchBusy');
});
};

View File

@ -30,11 +30,12 @@
if ( typeof vAPI !== 'object' ) { return; }
const t0 = Date.now();
const tMax = t0 + 100;
if ( vAPI.domSurveyElements instanceof Object === false ) {
vAPI.domSurveyElements = {
busy: false,
hiddenElementCount: -1,
hiddenElementCount: Number.NaN,
surveyTime: t0,
};
}
@ -44,11 +45,11 @@
surveyResults.busy = true;
if ( surveyResults.surveyTime < vAPI.domMutationTime ) {
surveyResults.hiddenElementCount = -1;
surveyResults.hiddenElementCount = Number.NaN;
}
surveyResults.surveyTime = t0;
if ( surveyResults.hiddenElementCount === -1 ) {
if ( isNaN(surveyResults.hiddenElementCount) ) {
surveyResults.hiddenElementCount = (( ) => {
if ( vAPI.domFilterer instanceof Object === false ) { return 0; }
const details = vAPI.domFilterer.getAllSelectors_(true);
@ -90,6 +91,7 @@
candidates.delete(node);
matched.add(node);
if ( matched.size === 99 ) { break; }
if ( Date.now() > tMax ) { return -1; }
}
}
if ( matched.size < 99 && complexStr !== '') {
@ -97,6 +99,7 @@
if ( node.closest(complexStr) !== node ) { continue; }
matched.add(node);
if ( matched.size === 99 ) { break; }
if ( Date.now() > tMax ) { return -1; }
}
}
return matched.size;