Index: chrome/ext/background.js |
diff --git a/chrome/ext/background.js b/chrome/ext/background.js |
index 8cec8296408b0cafb5452c7eb0afb6e67d59035b..8ab10ad920cf5d163d30d78c45adcefb05c8f4ea 100644 |
--- a/chrome/ext/background.js |
+++ b/chrome/ext/background.js |
@@ -118,44 +118,23 @@ |
return frame; |
} |
- chrome.webNavigation.onBeforeNavigate.addListener(details => |
- { |
- // Capture parent frame here because onCommitted doesn't get this info. |
- let frame = createFrame(details.tabId, details.frameId); |
- frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null; |
- }); |
- |
- let eagerlyUpdatedPages = new ext.PageMap(); |
- |
- ext._updatePageFrameStructure = (frameId, tabId, url, eager) => |
+ function updatePageFrameStructure(frameId, tabId, url) |
{ |
if (frameId == 0) |
{ |
let page = new Page({id: tabId, url: url}); |
- if (eagerlyUpdatedPages.get(page) != url) |
+ chrome.tabs.get(tabId, () => |
{ |
- ext._removeFromAllPageMaps(tabId); |
- |
- // When a sitekey header is received we must immediately update the page |
- // structure in order to record and use the key. We want to avoid |
- // trashing the page structure if the onCommitted event is then fired |
- // for the page. |
- if (eager) |
- eagerlyUpdatedPages.set(page, url); |
- |
- chrome.tabs.get(tabId, () => |
- { |
- // If the tab is prerendered, chrome.tabs.get() sets |
- // chrome.runtime.lastError and we have to dispatch the onLoading event, |
- // since the onUpdated event isn't dispatched for prerendered tabs. |
- // However, we have to keep relying on the unUpdated event for tabs that |
- // are already visible. Otherwise browser action changes get overridden |
- // when Chrome automatically resets them on navigation. |
- if (chrome.runtime.lastError) |
- ext.pages.onLoading._dispatch(page); |
- }); |
- } |
+ // If the tab is prerendered, chrome.tabs.get() sets |
+ // chrome.runtime.lastError and we have to dispatch the onLoading event, |
+ // since the onUpdated event isn't dispatched for prerendered tabs. |
+ // However, we have to keep relying on the unUpdated event for tabs that |
+ // are already visible. Otherwise browser action changes get overridden |
+ // when Chrome automatically resets them on navigation. |
+ if (chrome.runtime.lastError) |
+ ext.pages.onLoading._dispatch(page); |
+ }); |
} |
// Update frame URL in frame structure |
@@ -165,7 +144,36 @@ |
chrome.webNavigation.onCommitted.addListener(details => |
{ |
- ext._updatePageFrameStructure(details.frameId, details.tabId, details.url); |
+ updatePageFrameStructure(details.frameId, details.tabId, details.url); |
+ }); |
+ |
+ chrome.webRequest.onHeadersReceived.addListener(details => |
+ { |
+ // Ideally we would only need the above chrome.webNavigation.onCommitted |
+ // listener to update the page state but unfortunately pages can make web |
+ // requests before their onCommitted event fires[1]. |
+ // So for HTTP/S requests we can also use onHeadersReceived, being careful |
+ // to ignore responses which won't directly result in a navigation, for |
+ // example redirections. |
+ // [1] - https://bugs.chromium.org/p/chromium/issues/detail?id=665843 |
+ /**** FIXME - Check Chromium code to ensure we got these right! ****/ |
+ if (!(details.statusCode > 299 && details.statusCode < 400 && |
+ details.statusCode != 304) || details.statusCode == 204) |
+ updatePageFrameStructure(details.frameId, details.tabId, details.url); |
+ }, {types: ["main_frame", "sub_frame"], urls: ["http://*/*", "https://*/*"]}); |
+ |
+ chrome.webNavigation.onBeforeNavigate.addListener(details => |
+ { |
+ // Capture parent frame here because onCommitted doesn't get this info. |
+ let frame = createFrame(details.tabId, details.frameId); |
+ frame.parent = framesOfTabs[details.tabId][details.parentFrameId] || null; |
+ |
+ // Since we can only listen for HTTP/S requests with onHeadersReceived we |
+ // must update the page structure here for other navigations which might |
+ // result in further requests. |
+ let url = new URL(details.url); |
+ if (url.protocol == "about:" || url.protocol == "data:") |
+ updatePageFrameStructure(details.frameId, details.tabId, details.url); |
}); |
function forgetTab(tabId) |
@@ -234,7 +242,7 @@ |
}, |
_queueChanges() |
{ |
- chrome.tabs.get(this._tabId, function() |
+ chrome.tabs.get(this._tabId, () => |
{ |
// If the tab is prerendered, chrome.tabs.get() sets |
// chrome.runtime.lastError and we have to delay our changes |
@@ -256,7 +264,7 @@ |
{ |
this._applyChanges(); |
} |
- }.bind(this)); |
+ }); |
}, |
_addChange(name, value) |
{ |