diff --git a/apply.js b/apply.js index d54497ee..f8e4b881 100644 --- a/apply.js +++ b/apply.js @@ -33,6 +33,17 @@ function requestStyles(options) { function applyOnMessage(request, sender, sendResponse) { + // Do-It-Yourself tells our built-in pages to fetch the styles directly + // which is faster because IPC messaging JSON-ifies everything internally + if (request.styles == 'DIY') { + getStylesSafe({ + matchUrl: location.href, + enabled: true, + asHash: true, + }).then(styles => + applyOnMessage(Object.assign(request, {styles}))); + return; + } // Also handle special request just for the pop-up switch (request.method == 'updatePopup' ? request.reason : request.method) { diff --git a/background.js b/background.js index 988f1dec..117d29e3 100644 --- a/background.js +++ b/background.js @@ -1,27 +1,33 @@ /* global getDatabase, getStyles, reportError */ 'use strict'; -// This happens right away, sometimes so fast that the content script isn't even ready. That's -// why the content script also asks for this stuff. +chrome.webNavigation.onBeforeNavigate.addListener(data => { + webNavigationListener(null, data); +}); + chrome.webNavigation.onCommitted.addListener(data => { webNavigationListener('styleApply', data); }); + chrome.webNavigation.onHistoryStateUpdated.addListener(data => { webNavigationListener('styleReplaceAll', data); }); -chrome.webNavigation.onBeforeNavigate.addListener(data => { - webNavigationListener(null, data); + +chrome.webNavigation.onReferenceFragmentUpdated.addListener(data => { + webNavigationListener('styleReplaceAll', data); }); function webNavigationListener(method, data) { getStyles({matchUrl: data.url, enabled: true, asHash: true}, styles => { - // we can't inject chrome:// and chrome-extension:// pages except our own - // that request the styles on their own, so we'll only update the icon - if (method && !data.url.startsWith('chrome')) { + // we can't inject chrome:// and chrome-extension:// pages + // so we'll only inform our page of the change + // and it'll retrieve the styles directly + if (method && !data.url.startsWith('chrome:')) { + const isOwnPage = data.url.startsWith(OWN_ORIGIN); chrome.tabs.sendMessage( data.tabId, - {method, styles}, + {method, styles: isOwnPage ? 'DIY' : styles}, {frameId: data.frameId}); } // main page frame id is 0 @@ -31,32 +37,6 @@ function webNavigationListener(method, data) { }); } -// catch direct URL hash modifications not invoked via HTML5 history API -const tabUrlHasHash = new Set(); - -chrome.tabs.onUpdated.addListener((tabId, info, tab) => { - if (info.status != 'loading' || !info.url) { - return; - } - if (info.url.includes('#')) { - tabUrlHasHash.add(tabId); - } else if (tabUrlHasHash.has(tabId)) { - tabUrlHasHash.delete(tabId); - } else { - // do nothing since the tab neither had # before nor has # now - return; - } - webNavigationListener('styleReplaceAll', { - tabId: tabId, - frameId: 0, - url: info.url, - }); -}); - -chrome.tabs.onRemoved.addListener(tabId => { - tabUrlHasHash.delete(tabId); -}); - // messaging chrome.runtime.onMessage.addListener(onBackgroundMessage); diff --git a/messaging.js b/messaging.js index 40f9d113..09eaeabd 100644 --- a/messaging.js +++ b/messaging.js @@ -60,7 +60,8 @@ function refreshAllTabs() { function updateIcon(tab, styles) { // while NTP is still loading only process the request for its main frame with a real url // (but when it's loaded we should process style toggle requests from popups, for example) - if (tab.url == 'chrome://newtab/' && tab.status != 'complete') { + const isNTP = tab.url == 'chrome://newtab/'; + if (isNTP && tab.status != 'complete') { return; } if (styles) { @@ -72,16 +73,13 @@ function updateIcon(tab, styles) { }); return; } - getTabRealURL(tab).then(url => { - // if we have access to this, call directly - // (Chrome no longer sends messages to the page itself) - const options = {method: 'getStyles', matchUrl: url, enabled: true, asHash: true}; - if (typeof getStyles != 'undefined') { - getStyles(options, stylesReceived); - } else { - chrome.runtime.sendMessage(options, stylesReceived); - } - }); + (isNTP ? getTabRealURL(tab) : Promise.resolve(tab.url)) + .then(url => getStylesSafe({ + matchUrl: url, + enabled: true, + asHash: true, + })) + .then(stylesReceived); function stylesReceived(styles) { let numStyles = styles.length;