diff --git a/src/js/pagestore.js b/src/js/pagestore.js index f30e88d67..86cfa67f9 100644 --- a/src/js/pagestore.js +++ b/src/js/pagestore.js @@ -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(); diff --git a/src/js/start.js b/src/js/start.js index 4cbba2220..3d48e903a 100644 --- a/src/js/start.js +++ b/src/js/start.js @@ -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 diff --git a/src/js/tab.js b/src/js/tab.js index 4d6e8df5c..b63b72863 100644 --- a/src/js/tab.js +++ b/src/js/tab.js @@ -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