| 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; |
| } |
| }); |