webNavigation.onReferenceFragmentUpdated instead of tabs.onUpdated

Also send a Do-It-Yourself to our built-in pages to fetch the styles directly which is faster because IPC messaging JSON-ifies everything internally
This commit is contained in:
tophf 2017-03-27 12:11:29 +03:00
parent d32ad30f8f
commit 64c830caa9
3 changed files with 34 additions and 45 deletions

View File

@ -33,6 +33,17 @@ function requestStyles(options) {
function applyOnMessage(request, sender, sendResponse) { 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 // Also handle special request just for the pop-up
switch (request.method == 'updatePopup' ? request.reason : request.method) { switch (request.method == 'updatePopup' ? request.reason : request.method) {

View File

@ -1,27 +1,33 @@
/* global getDatabase, getStyles, reportError */ /* global getDatabase, getStyles, reportError */
'use strict'; 'use strict';
// This happens right away, sometimes so fast that the content script isn't even ready. That's chrome.webNavigation.onBeforeNavigate.addListener(data => {
// why the content script also asks for this stuff. webNavigationListener(null, data);
});
chrome.webNavigation.onCommitted.addListener(data => { chrome.webNavigation.onCommitted.addListener(data => {
webNavigationListener('styleApply', data); webNavigationListener('styleApply', data);
}); });
chrome.webNavigation.onHistoryStateUpdated.addListener(data => { chrome.webNavigation.onHistoryStateUpdated.addListener(data => {
webNavigationListener('styleReplaceAll', data); webNavigationListener('styleReplaceAll', data);
}); });
chrome.webNavigation.onBeforeNavigate.addListener(data => {
webNavigationListener(null, data); chrome.webNavigation.onReferenceFragmentUpdated.addListener(data => {
webNavigationListener('styleReplaceAll', data);
}); });
function webNavigationListener(method, data) { function webNavigationListener(method, data) {
getStyles({matchUrl: data.url, enabled: true, asHash: true}, styles => { getStyles({matchUrl: data.url, enabled: true, asHash: true}, styles => {
// we can't inject chrome:// and chrome-extension:// pages except our own // we can't inject chrome:// and chrome-extension:// pages
// that request the styles on their own, so we'll only update the icon // so we'll only inform our page of the change
if (method && !data.url.startsWith('chrome')) { // and it'll retrieve the styles directly
if (method && !data.url.startsWith('chrome:')) {
const isOwnPage = data.url.startsWith(OWN_ORIGIN);
chrome.tabs.sendMessage( chrome.tabs.sendMessage(
data.tabId, data.tabId,
{method, styles}, {method, styles: isOwnPage ? 'DIY' : styles},
{frameId: data.frameId}); {frameId: data.frameId});
} }
// main page frame id is 0 // 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 // messaging
chrome.runtime.onMessage.addListener(onBackgroundMessage); chrome.runtime.onMessage.addListener(onBackgroundMessage);

View File

@ -60,7 +60,8 @@ function refreshAllTabs() {
function updateIcon(tab, styles) { function updateIcon(tab, styles) {
// while NTP is still loading only process the request for its main frame with a real url // 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) // (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; return;
} }
if (styles) { if (styles) {
@ -72,16 +73,13 @@ function updateIcon(tab, styles) {
}); });
return; return;
} }
getTabRealURL(tab).then(url => { (isNTP ? getTabRealURL(tab) : Promise.resolve(tab.url))
// if we have access to this, call directly .then(url => getStylesSafe({
// (Chrome no longer sends messages to the page itself) matchUrl: url,
const options = {method: 'getStyles', matchUrl: url, enabled: true, asHash: true}; enabled: true,
if (typeof getStyles != 'undefined') { asHash: true,
getStyles(options, stylesReceived); }))
} else { .then(stylesReceived);
chrome.runtime.sendMessage(options, stylesReceived);
}
});
function stylesReceived(styles) { function stylesReceived(styles) {
let numStyles = styles.length; let numStyles = styles.length;