Bug 651311 - Race condition in TabView._initFrame() [f=raymond, r=ian]

This commit is contained in:
Tim Taubert 2011-04-22 23:44:06 +02:00
parent 540ca93080
commit dc0488031b
4 changed files with 81 additions and 24 deletions

View File

@ -42,6 +42,8 @@ let TabView = {
_window: null,
_firstUseExperienced: false,
_browserKeyHandlerInitialized: false,
_isFrameLoading: false,
_initFrameCallbacks: [],
VISIBILITY_IDENTIFIER: "tabview-visibility",
// ----------
@ -128,34 +130,52 @@ let TabView = {
// Creates the frame and calls the callback once it's loaded.
// If the frame already exists, calls the callback immediately.
_initFrame: function TabView__initFrame(callback) {
let hasCallback = typeof callback == "function";
if (this._window) {
if (typeof callback == "function")
if (hasCallback)
callback();
} else {
// ___ find the deck
this._deck = document.getElementById("tab-view-deck");
return;
}
// ___ create the frame
this._iframe = document.createElement("iframe");
this._iframe.id = "tab-view";
this._iframe.setAttribute("transparent", "true");
this._iframe.flex = 1;
if (hasCallback)
this._initFrameCallbacks.push(callback);
if (typeof callback == "function")
window.addEventListener("tabviewframeinitialized", callback, false);
if (this._isFrameLoading)
return;
this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
this._deck.appendChild(this._iframe);
this._window = this._iframe.contentWindow;
this._isFrameLoading = true;
if (this._tabShowEventListener) {
// ___ find the deck
this._deck = document.getElementById("tab-view-deck");
// ___ create the frame
this._iframe = document.createElement("iframe");
this._iframe.id = "tab-view";
this._iframe.setAttribute("transparent", "true");
this._iframe.flex = 1;
let self = this;
window.addEventListener("tabviewframeinitialized", function onInit() {
window.removeEventListener("tabviewframeinitialized", onInit, false);
self._isFrameLoading = false;
self._window = self._iframe.contentWindow;
self._setBrowserKeyHandlers();
if (self._tabShowEventListener) {
gBrowser.tabContainer.removeEventListener(
"TabShow", this._tabShowEventListener, true);
this._tabShowEventListener = null;
"TabShow", self._tabShowEventListener, true);
self._tabShowEventListener = null;
}
this._setBrowserKeyHandlers();
}
self._initFrameCallbacks.forEach(function (cb) cb());
self._initFrameCallbacks = [];
}, false);
this._iframe.setAttribute("src", "chrome://browser/content/tabview.html");
this._deck.appendChild(this._iframe);
},
// ----------

View File

@ -132,6 +132,7 @@ _BROWSER_FILES = \
browser_tabview_bug645653.js \
browser_tabview_bug649006.js \
browser_tabview_bug649307.js \
browser_tabview_bug651311.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \
browser_tabview_expander.js \

View File

@ -34,7 +34,7 @@ function setupTwo(win) {
// force all canvases to update, and hook in imageData save detection
tabItems.forEach(function(tabItem) {
contentWindow.TabItems._update(tabItem.tab);
contentWindow.TabItems.update(tabItem.tab);
tabItem.addSubscriber(tabItem, "savedCachedImageData", function(item) {
item.removeSubscriber(item, "savedCachedImageData");
--numTabsToSave;
@ -70,8 +70,7 @@ function setupTwo(win) {
restoredWin.removeEventListener(
"tabviewframeinitialized", onTabViewFrameInitialized, false);
let restoredContentWindow =
restoredWin.document.getElementById("tab-view").contentWindow;
let restoredContentWindow = restoredWin.TabView.getContentWindow();
// prevent TabItems._update being called before checking cached images
restoredContentWindow.TabItems._pauseUpdateForTest = true;
@ -134,8 +133,7 @@ let gTabsProgressListener = {
function updateAndCheck() {
// force all canvas to update
let contentWindow =
restoredWin.document.getElementById("tab-view").contentWindow;
let contentWindow = restoredWin.TabView.getContentWindow();
contentWindow.TabItems._pauseUpdateForTest = false;

View File

@ -0,0 +1,38 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let callCount = 0;
newWindow(function (win) {
registerCleanupFunction(function () win.close());
win.TabView._initFrame(function () {
is(callCount++, 0, "call count is zero");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
});
win.TabView._initFrame(function () {
is(callCount++, 1, "call count is one");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
});
win.TabView._initFrame(function () {
is(callCount, 2, "call count is two");
ok(win.TabView.getContentWindow().UI, "content window is loaded");
finish();
});
});
}
function newWindow(callback) {
let opts = "chrome,all,dialog=no,height=800,width=800";
let win = window.openDialog(getBrowserURL(), "_blank", opts);
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
callback(win);
}, false);
}