Index: safari/ext/background.js |
=================================================================== |
--- a/safari/ext/background.js |
+++ b/safari/ext/background.js |
@@ -22,12 +22,11 @@ |
var pages = {__proto__: null}; |
var pageCounter = 0; |
- var Page = function(id, tab, url, prerendered) |
+ var Page = function(id, tab, url) |
{ |
this._id = id; |
this._tab = tab; |
this._frames = [{url: url, parent: null}]; |
- this._prerendered = prerendered; |
if (tab.page) |
this._messageProxy = new ext._MessageProxy(tab.page); |
@@ -64,20 +63,25 @@ |
var isPageActive = function(page) |
{ |
- return page._tab == page._tab.browserWindow.activeTab && !page._prerendered; |
+ var tab = page._tab; |
+ return tab == tab.browserWindow.activeTab && page == tab._visiblePage; |
}; |
var forgetPage = function(id) |
{ |
ext._removeFromAllPageMaps(id); |
+ |
+ delete pages[id]._tab._pages[id]; |
delete pages[id]; |
}; |
var replacePage = function(page) |
{ |
- for (var id in pages) |
+ page._tab._visiblePage = page; |
+ |
+ for (var id in page._tab._pages) |
{ |
- if (id != page._id && pages[id]._tab == page._tab) |
+ if (id != page._id) |
forgetPage(id); |
} |
@@ -139,11 +143,8 @@ |
// tab. Note that it wouldn't be sufficient do that when the old page |
// is unloading, because Safari dispatches window.onunload only when |
// reloading the page or following links, but not when closing the tab. |
- for (var id in pages) |
- { |
- if (pages[id]._tab == event.target) |
- forgetPage(id); |
- } |
+ for (var id in event.target._pages) |
+ forgetPage(id); |
}, true); |
@@ -227,18 +228,7 @@ |
// became active. If we can't find that page (e.g. when a page was |
// opened in a new tab, and our content script didn't run yet), the |
// toolbar item of the window, is reset to its intial configuration. |
- var activePage = null; |
- for (var id in pages) |
- { |
- var page = pages[id]; |
- if (page._tab == event.target && !page._prerendered) |
- { |
- activePage = page; |
- break; |
- } |
- } |
- |
- updateToolbarItemForPage(activePage, event.target.browserWindow); |
+ updateToolbarItemForPage(event.target._visiblePage, event.target.browserWindow); |
}, true); |
@@ -540,11 +530,9 @@ |
// by matching its referrer with the URL of frames previously |
// loaded in the same tab. If there is more than one match, |
// the most recent loaded page and frame is preferred. |
- for (var curPageId in pages) |
+ for (var curPageId in (tab ? tab._pages : pages)) |
{ |
var curPage = pages[curPageId]; |
- if (tab && curPage._tab != tab) |
- continue; |
for (var i = 0; i < curPage._frames.length; i++) |
{ |
@@ -580,36 +568,33 @@ |
switch (event.message.category) |
{ |
case "loading": |
+ var tab = event.target; |
+ var message = event.message; |
+ |
var pageId; |
var frameId; |
- if (event.message.isTopLevel) |
+ if (message.isTopLevel) |
{ |
pageId = ++pageCounter; |
frameId = 0; |
- var isPrerendered = event.message.isPrerendered; |
- var page = new Page( |
- pageId, |
- event.target, |
- event.message.url, |
- isPrerendered |
- ); |
+ var page = new Page(pageId, tab, message.url); |
- if (event.message.isPopup && !event.target._popupLoaded) |
+ if (message.isPopup && !tab._popupLoaded) |
{ |
- if (!("_opener" in event.target)) |
- event.target._opener = findPageAndFrame(null, event.message.referrer); |
+ if (!("_opener" in tab)) |
+ tab._opener = findPageAndFrame(null, message.referrer); |
if (page.url != "about:blank") |
- event.target._popupLoaded = true; |
+ tab._popupLoaded = true; |
- ext.pages.onPopup._dispatch(page, event.target._opener); |
+ ext.pages.onPopup._dispatch(page, tab._opener); |
} |
- if (event.target.browserWindow) |
+ if (tab.browserWindow) |
{ |
- pages[pageId] = page; |
+ pages[pageId] = (tab._pages || (tab._pages = {__proto__: null}))[pageId] = page; |
Wladimir Palant
2014/06/11 08:17:10
Seriously, don't be too clever - go for readable c
|
// when a new page is shown, forget the previous page associated |
// with its tab, and reset the toolbar item if necessary. |
@@ -617,7 +602,7 @@ |
// page is unloading, because Safari dispatches window.onunload |
// only when reloading the page or following links, but not when |
// you enter a new URL in the address bar. |
- if (!isPrerendered) |
+ if (!message.isPrerendered) |
replacePage(page); |
ext.pages.onLoading._dispatch(page); |
@@ -625,15 +610,12 @@ |
} |
else |
{ |
- var parent = findPageAndFrame(event.target, event.message.referrer); |
+ var parent = findPageAndFrame(tab, message.referrer); |
pageId = parent.page._id; |
frameId = parent.page._frames.length; |
- parent.page._frames.push({ |
- url: event.message.url, |
- parent: parent.frame |
- }); |
+ parent.page._frames.push({url: message.url, parent: parent.frame}); |
} |
event.message = {pageId: pageId, frameId: frameId}; |
@@ -662,16 +644,13 @@ |
pages[event.message.pageId]._messageProxy.handleResponse(event.message); |
break; |
case "replaced": |
- var page = pages[event.message.pageId]; |
- page._prerendered = false; |
- |
// when a prerendered page is shown, forget the previous page |
// associated with its tab, and reset the toolbar item if necessary. |
// Note that it wouldn't be sufficient to do that when the old |
// page is unloading, because Safari dispatches window.onunload |
// only when reloading the page or following links, but not when |
// the current page is replaced with a prerendered page. |
- replacePage(page); |
+ replacePage(pages[event.message.pageId]); |
break; |
} |
}); |