mirror of https://github.com/gorhill/uBlock.git
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:
parent
01cdf50f33
commit
ec7db30b2f
|
@ -328,7 +328,7 @@ const HostnameDetailsMap = class extends Map {
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
const PageStore = class {
|
const PageStore = class {
|
||||||
constructor(tabId, context) {
|
constructor(tabId, details) {
|
||||||
this.extraData = new Map();
|
this.extraData = new Map();
|
||||||
this.journal = [];
|
this.journal = [];
|
||||||
this.journalTimer = undefined;
|
this.journalTimer = undefined;
|
||||||
|
@ -337,15 +337,15 @@ const PageStore = class {
|
||||||
this.netFilteringCache = NetFilteringResultCache.factory();
|
this.netFilteringCache = NetFilteringResultCache.factory();
|
||||||
this.hostnameDetailsMap = new HostnameDetailsMap();
|
this.hostnameDetailsMap = new HostnameDetailsMap();
|
||||||
this.counts = new CountDetails();
|
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();
|
let entry = PageStore.junkyard.pop();
|
||||||
if ( entry === undefined ) {
|
if ( entry === undefined ) {
|
||||||
entry = new PageStore(tabId, context);
|
entry = new PageStore(tabId, details);
|
||||||
} else {
|
} else {
|
||||||
entry.init(tabId, context);
|
entry.init(tabId, details);
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -354,7 +354,7 @@ const PageStore = class {
|
||||||
// The context is used to determine whether we report behavior change
|
// The context is used to determine whether we report behavior change
|
||||||
// to the logger.
|
// to the logger.
|
||||||
|
|
||||||
init(tabId) {
|
init(tabId, details) {
|
||||||
const tabContext = µb.tabContextManager.mustLookup(tabId);
|
const tabContext = µb.tabContextManager.mustLookup(tabId);
|
||||||
this.tabId = tabId;
|
this.tabId = tabId;
|
||||||
|
|
||||||
|
@ -368,7 +368,6 @@ const PageStore = class {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tabHostname = tabContext.rootHostname;
|
this.tabHostname = tabContext.rootHostname;
|
||||||
this.title = tabContext.rawURL;
|
|
||||||
this.rawURL = tabContext.rawURL;
|
this.rawURL = tabContext.rawURL;
|
||||||
this.hostnameDetailsMap.reset();
|
this.hostnameDetailsMap.reset();
|
||||||
this.contentLastModified = 0;
|
this.contentLastModified = 0;
|
||||||
|
@ -385,13 +384,17 @@ const PageStore = class {
|
||||||
this.frames = new Map();
|
this.frames = new Map();
|
||||||
this.setFrameURL({ url: tabContext.rawURL });
|
this.setFrameURL({ url: tabContext.rawURL });
|
||||||
|
|
||||||
|
if ( this.titleFromDetails(details) === false ) {
|
||||||
|
this.title = tabContext.rawURL;
|
||||||
|
}
|
||||||
|
|
||||||
// Evaluated on-demand
|
// Evaluated on-demand
|
||||||
this._noCosmeticFiltering = undefined;
|
this._noCosmeticFiltering = undefined;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
reuse(context) {
|
reuse(context, details) {
|
||||||
// When force refreshing a page, the page store data needs to be reset.
|
// 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.
|
// 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
|
// URL changed, force a re-evaluation of filtering switch
|
||||||
this.rawURL = tabContext.rawURL;
|
this.rawURL = tabContext.rawURL;
|
||||||
this.setFrameURL({ url: this.rawURL });
|
this.setFrameURL({ url: this.rawURL });
|
||||||
|
this.titleFromDetails(details);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,7 +424,7 @@ const PageStore = class {
|
||||||
this.largeMediaTimer = null;
|
this.largeMediaTimer = null;
|
||||||
}
|
}
|
||||||
this.disposeFrameStores();
|
this.disposeFrameStores();
|
||||||
this.init(this.tabId, context);
|
this.init(this.tabId, details);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,6 +454,14 @@ const PageStore = class {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
titleFromDetails(details) {
|
||||||
|
if ( details instanceof Object && details.title !== undefined ) {
|
||||||
|
this.title = details.title;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
disposeFrameStores() {
|
disposeFrameStores() {
|
||||||
for ( const frameStore of this.frames.values() ) {
|
for ( const frameStore of this.frames.values() ) {
|
||||||
frameStore.dispose();
|
frameStore.dispose();
|
||||||
|
|
|
@ -69,7 +69,7 @@ const initializeTabs = async function() {
|
||||||
if ( tab.discarded === true ) { continue; }
|
if ( tab.discarded === true ) { continue; }
|
||||||
const { id, url } = tab;
|
const { id, url } = tab;
|
||||||
µb.tabContextManager.commit(id, url);
|
µb.tabContextManager.commit(id, url);
|
||||||
µb.bindTabToPageStore(id);
|
µb.bindTabToPageStore(id, 'tabCommitted', tab);
|
||||||
// https://github.com/chrisaljoudi/uBlock/issues/129
|
// https://github.com/chrisaljoudi/uBlock/issues/129
|
||||||
// Find out whether content scripts need to be injected
|
// Find out whether content scripts need to be injected
|
||||||
// programmatically. This may be necessary for web pages which
|
// programmatically. This may be necessary for web pages which
|
||||||
|
|
|
@ -884,7 +884,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
||||||
const { frameId, tabId, url } = details;
|
const { frameId, tabId, url } = details;
|
||||||
if ( frameId === 0 ) {
|
if ( frameId === 0 ) {
|
||||||
µb.tabContextManager.commit(tabId, url);
|
µb.tabContextManager.commit(tabId, url);
|
||||||
const pageStore = µb.bindTabToPageStore(tabId, 'tabCommitted');
|
const pageStore = µb.bindTabToPageStore(tabId, 'tabCommitted', details);
|
||||||
if ( pageStore !== null ) {
|
if ( pageStore !== null ) {
|
||||||
pageStore.journalAddRootFrame('committed', url);
|
pageStore.journalAddRootFrame('committed', url);
|
||||||
}
|
}
|
||||||
|
@ -910,7 +910,7 @@ vAPI.Tabs = class extends vAPI.Tabs {
|
||||||
if ( !tab.url || tab.url === '' ) { return; }
|
if ( !tab.url || tab.url === '' ) { return; }
|
||||||
if ( !changeInfo.url ) { return; }
|
if ( !changeInfo.url ) { return; }
|
||||||
µBlock.tabContextManager.commit(tabId, changeInfo.url);
|
µ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.
|
// 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);
|
this.updateToolbarIcon(tabId, 0b111);
|
||||||
|
|
||||||
// Do not create a page store for URLs which are of no interests
|
// 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
|
// Tab is not bound
|
||||||
if ( pageStore === undefined ) {
|
if ( pageStore === undefined ) {
|
||||||
this.updateTitle(tabId);
|
pageStore = this.PageStore.factory(tabId, details);
|
||||||
pageStore = this.PageStore.factory(tabId, context);
|
|
||||||
this.pageStores.set(tabId, pageStore);
|
this.pageStores.set(tabId, pageStore);
|
||||||
this.pageStoresToken = Date.now();
|
this.pageStoresToken = Date.now();
|
||||||
return pageStore;
|
return pageStore;
|
||||||
|
@ -958,9 +957,8 @@ vAPI.tabs = new vAPI.Tabs();
|
||||||
// Rebind according to context. We rebind even if the URL did not change,
|
// 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
|
// as maybe the tab was force-reloaded, in which case the page stats must
|
||||||
// be all reset.
|
// be all reset.
|
||||||
pageStore.reuse(context);
|
pageStore.reuse(context, details);
|
||||||
|
|
||||||
this.updateTitle(tabId);
|
|
||||||
this.pageStoresToken = Date.now();
|
this.pageStoresToken = Date.now();
|
||||||
|
|
||||||
return pageStore;
|
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
|
// https://github.com/chrisaljoudi/uBlock/issues/455
|
||||||
// Stale page store entries janitor
|
// Stale page store entries janitor
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue