Simplify fetching title of tabs

The title of tabs in uBO is solely to have a better
presentation in the logger -- no other purpose.

This commit simplify keeping track of the titles, from
an active approach by directly querying it from tabs
whenever a change occurs, to a passive approach by
storing it when the title string become available in
some tab event handlers.
This commit is contained in:
Raymond Hill 2021-07-16 08:59:30 -04:00
parent 01cdf50f33
commit ec7db30b2f
No known key found for this signature in database
GPG Key ID: 25E1490B761470C2
3 changed files with 27 additions and 69 deletions

View File

@ -328,7 +328,7 @@ const HostnameDetailsMap = class extends Map {
/******************************************************************************/
const PageStore = class {
constructor(tabId, context) {
constructor(tabId, details) {
this.extraData = new Map();
this.journal = [];
this.journalTimer = undefined;
@ -337,15 +337,15 @@ const PageStore = class {
this.netFilteringCache = NetFilteringResultCache.factory();
this.hostnameDetailsMap = new HostnameDetailsMap();
this.counts = new CountDetails();
this.init(tabId, context);
this.init(tabId, details);
}
static factory(tabId, context) {
static factory(tabId, details) {
let entry = PageStore.junkyard.pop();
if ( entry === undefined ) {
entry = new PageStore(tabId, context);
entry = new PageStore(tabId, details);
} else {
entry.init(tabId, context);
entry.init(tabId, details);
}
return entry;
}
@ -354,7 +354,7 @@ const PageStore = class {
// The context is used to determine whether we report behavior change
// to the logger.
init(tabId) {
init(tabId, details) {
const tabContext = µb.tabContextManager.mustLookup(tabId);
this.tabId = tabId;
@ -368,7 +368,6 @@ const PageStore = class {
}
this.tabHostname = tabContext.rootHostname;
this.title = tabContext.rawURL;
this.rawURL = tabContext.rawURL;
this.hostnameDetailsMap.reset();
this.contentLastModified = 0;
@ -385,13 +384,17 @@ const PageStore = class {
this.frames = new Map();
this.setFrameURL({ url: tabContext.rawURL });
if ( this.titleFromDetails(details) === false ) {
this.title = tabContext.rawURL;
}
// Evaluated on-demand
this._noCosmeticFiltering = undefined;
return this;
}
reuse(context) {
reuse(context, details) {
// When force refreshing a page, the page store data needs to be reset.
// If the hostname changes, we can't merely just update the context.
@ -411,6 +414,7 @@ const PageStore = class {
// URL changed, force a re-evaluation of filtering switch
this.rawURL = tabContext.rawURL;
this.setFrameURL({ url: this.rawURL });
this.titleFromDetails(details);
return this;
}
@ -420,7 +424,7 @@ const PageStore = class {
this.largeMediaTimer = null;
}
this.disposeFrameStores();
this.init(this.tabId, context);
this.init(this.tabId, details);
return this;
}
@ -450,6 +454,14 @@ const PageStore = class {
return null;
}
titleFromDetails(details) {
if ( details instanceof Object && details.title !== undefined ) {
this.title = details.title;
return true;
}
return false;
}
disposeFrameStores() {
for ( const frameStore of this.frames.values() ) {
frameStore.dispose();

View File

@ -69,7 +69,7 @@ const initializeTabs = async function() {
if ( tab.discarded === true ) { continue; }
const { id, url } = tab;
µb.tabContextManager.commit(id, url);
µb.bindTabToPageStore(id);
µb.bindTabToPageStore(id, 'tabCommitted', tab);
// https://github.com/chrisaljoudi/uBlock/issues/129
// Find out whether content scripts need to be injected
// programmatically. This may be necessary for web pages which

View File

@ -884,7 +884,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
const { frameId, tabId, url } = details;
if ( frameId === 0 ) {
µb.tabContextManager.commit(tabId, url);
const pageStore = µb.bindTabToPageStore(tabId, 'tabCommitted');
const pageStore = µb.bindTabToPageStore(tabId, 'tabCommitted', details);
if ( pageStore !== null ) {
pageStore.journalAddRootFrame('committed', url);
}
@ -910,7 +910,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
if ( !tab.url || tab.url === '' ) { return; }
if ( !changeInfo.url ) { return; }
µBlock.tabContextManager.commit(tabId, changeInfo.url);
µBlock.bindTabToPageStore(tabId, 'tabUpdated');
µBlock.bindTabToPageStore(tabId, 'tabUpdated', tab);
}
};
@ -921,7 +921,7 @@ vAPI.tabs = new vAPI.Tabs();
// Create an entry for the tab if it doesn't exist.
µBlock.bindTabToPageStore = function(tabId, context) {
µBlock.bindTabToPageStore = function(tabId, context, details = undefined) {
this.updateToolbarIcon(tabId, 0b111);
// Do not create a page store for URLs which are of no interests
@ -935,8 +935,7 @@ vAPI.tabs = new vAPI.Tabs();
// Tab is not bound
if ( pageStore === undefined ) {
this.updateTitle(tabId);
pageStore = this.PageStore.factory(tabId, context);
pageStore = this.PageStore.factory(tabId, details);
this.pageStores.set(tabId, pageStore);
this.pageStoresToken = Date.now();
return pageStore;
@ -958,9 +957,8 @@ vAPI.tabs = new vAPI.Tabs();
// Rebind according to context. We rebind even if the URL did not change,
// as maybe the tab was force-reloaded, in which case the page stats must
// be all reset.
pageStore.reuse(context);
pageStore.reuse(context, details);
this.updateTitle(tabId);
this.pageStoresToken = Date.now();
return pageStore;
@ -1094,58 +1092,6 @@ vAPI.tabs = new vAPI.Tabs();
/******************************************************************************/
µBlock.updateTitle = (( ) => {
const tabIdToCount = new Map();
const delay = 499;
const updateTitle = async function(tabId) {
let count = tabIdToCount.get(tabId);
if ( count === undefined ) { return; }
tabIdToCount.delete(tabId);
const tab = await vAPI.tabs.get(tabId);
if ( tab instanceof Object === false || tab.discarded === true ) {
return;
}
const µb = µBlock;
const pageStore = µb.pageStoreFromTabId(tabId);
if ( pageStore === null ) { return; }
// Firefox needs this: if you detach a tab, the new tab won't have
// its rawURL set. Concretely, this causes the logger to report an
// entry to itself in the logger's tab selector.
// TODO: Investigate for a fix vAPI-side.
pageStore.rawURL = tab.url;
µb.pageStoresToken = Date.now();
// https://github.com/gorhill/uMatrix/issues/225
// Sometimes title changes while page is loading.
const settled =
typeof tab.title === 'string' &&
tab.title !== '' &&
tab.title === pageStore.title;
pageStore.title = tab.title || tab.url || '';
if ( settled ) { return; }
if ( tabIdToCount.has(tabId) ) { return; }
count -= 1;
if ( count === 0 ) { return; }
tabIdToCount.set(tabId, count);
updateTitleAsync(tabId);
};
const updateTitleAsync = function(tabId) {
vAPI.setTimeout(( ) => { updateTitle(tabId); }, delay);
};
return function(tabId) {
if ( vAPI.isBehindTheSceneTabId(tabId) ) { return; }
const count = tabIdToCount.get(tabId);
tabIdToCount.set(tabId, 5);
if ( count === undefined ) {
updateTitleAsync(tabId);
}
};
})();
/******************************************************************************/
// https://github.com/chrisaljoudi/uBlock/issues/455
// Stale page store entries janitor