browser/components/tabview/test/head.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* Any copyright is dedicated to the Public Domain.
michael@0 2 http://creativecommons.org/publicdomain/zero/1.0/ */
michael@0 3
michael@0 4 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
michael@0 5
michael@0 6 // Some tests here assume that all restored tabs are loaded without waiting for
michael@0 7 // the user to bring them to the foreground. We ensure this by resetting the
michael@0 8 // related preference (see the "firefox.js" defaults file for details).
michael@0 9 Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", false);
michael@0 10 registerCleanupFunction(function () {
michael@0 11 Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
michael@0 12 });
michael@0 13
michael@0 14 // ----------
michael@0 15 function createEmptyGroupItem(contentWindow, width, height, padding, animate) {
michael@0 16 let pageBounds = contentWindow.Items.getPageBounds();
michael@0 17 pageBounds.inset(padding, padding);
michael@0 18
michael@0 19 let box = new contentWindow.Rect(pageBounds);
michael@0 20 box.width = width;
michael@0 21 box.height = height;
michael@0 22
michael@0 23 let emptyGroupItem =
michael@0 24 new contentWindow.GroupItem([], { bounds: box, immediately: !animate });
michael@0 25
michael@0 26 return emptyGroupItem;
michael@0 27 }
michael@0 28
michael@0 29 // ----------
michael@0 30 function createGroupItemWithTabs(win, width, height, padding, urls, animate) {
michael@0 31 let contentWindow = win.TabView.getContentWindow();
michael@0 32 let groupItemCount = contentWindow.GroupItems.groupItems.length;
michael@0 33 // create empty group item
michael@0 34 let groupItem = createEmptyGroupItem(contentWindow, width, height, padding, animate);
michael@0 35 ok(groupItem.isEmpty(), "This group is empty");
michael@0 36 is(contentWindow.GroupItems.groupItems.length, ++groupItemCount,
michael@0 37 "The number of groups is increased by 1");
michael@0 38 // add blank items
michael@0 39 contentWindow.UI.setActive(groupItem);
michael@0 40 let t = 0;
michael@0 41 urls.forEach( function(url) {
michael@0 42 let newItem = win.gBrowser.loadOneTab(url)._tabViewTabItem;
michael@0 43 ok(newItem.container, "Created element "+t+":"+newItem.container);
michael@0 44 ++t;
michael@0 45 });
michael@0 46 // to set one of tabItem to be active since we load tabs into a group
michael@0 47 // in a non-standard flow.
michael@0 48 contentWindow.UI.setActive(groupItem);
michael@0 49 return groupItem;
michael@0 50 }
michael@0 51
michael@0 52 // ----------
michael@0 53 function createGroupItemWithBlankTabs(win, width, height, padding, numNewTabs, animate) {
michael@0 54 let urls = [];
michael@0 55 while(numNewTabs--)
michael@0 56 urls.push("about:blank");
michael@0 57 return createGroupItemWithTabs(win, width, height, padding, urls, animate);
michael@0 58 }
michael@0 59
michael@0 60 // ----------
michael@0 61 function closeGroupItem(groupItem, callback) {
michael@0 62 if (callback) {
michael@0 63 groupItem.addSubscriber("close", function onClose() {
michael@0 64 groupItem.removeSubscriber("close", onClose);
michael@0 65 executeSoon(callback);
michael@0 66 });
michael@0 67 }
michael@0 68
michael@0 69 if (groupItem.getChildren().length) {
michael@0 70 groupItem.addSubscriber("groupHidden", function onHide() {
michael@0 71 groupItem.removeSubscriber("groupHidden", onHide);
michael@0 72 groupItem.closeHidden();
michael@0 73 });
michael@0 74 }
michael@0 75
michael@0 76 groupItem.closeAll();
michael@0 77 }
michael@0 78
michael@0 79 // ----------
michael@0 80 function afterAllTabItemsUpdated(callback, win) {
michael@0 81 win = win || window;
michael@0 82 let tabItems = win.document.getElementById("tab-view").contentWindow.TabItems;
michael@0 83 let counter = 0;
michael@0 84
michael@0 85 for (let a = 0; a < win.gBrowser.tabs.length; a++) {
michael@0 86 let tabItem = win.gBrowser.tabs[a]._tabViewTabItem;
michael@0 87 if (tabItem) {
michael@0 88 let tab = win.gBrowser.tabs[a];
michael@0 89 counter++;
michael@0 90 tabItem.addSubscriber("updated", function onUpdated() {
michael@0 91 tabItem.removeSubscriber("updated", onUpdated);
michael@0 92 if (--counter == 0)
michael@0 93 callback();
michael@0 94 });
michael@0 95 tabItems.update(tab);
michael@0 96 }
michael@0 97 }
michael@0 98 if (counter == 0)
michael@0 99 callback();
michael@0 100 }
michael@0 101
michael@0 102 // ---------
michael@0 103 function newWindowWithTabView(shownCallback, loadCallback, width, height) {
michael@0 104 let winWidth = width || 800;
michael@0 105 let winHeight = height || 800;
michael@0 106 let win = window.openDialog(getBrowserURL(), "_blank",
michael@0 107 "chrome,all,dialog=no,height=" + winHeight +
michael@0 108 ",width=" + winWidth, "about:blank");
michael@0 109
michael@0 110 whenWindowLoaded(win, function () {
michael@0 111 if (loadCallback)
michael@0 112 loadCallback(win);
michael@0 113 });
michael@0 114
michael@0 115 whenDelayedStartupFinished(win, function () {
michael@0 116 showTabView(function () shownCallback(win), win);
michael@0 117 });
michael@0 118 }
michael@0 119
michael@0 120 // ----------
michael@0 121 function afterAllTabsLoaded(callback, win) {
michael@0 122 const TAB_STATE_NEEDS_RESTORE = 1;
michael@0 123
michael@0 124 win = win || window;
michael@0 125
michael@0 126 let stillToLoad = 0;
michael@0 127 let restoreHiddenTabs = Services.prefs.getBoolPref(
michael@0 128 "browser.sessionstore.restore_hidden_tabs");
michael@0 129
michael@0 130 function onLoad() {
michael@0 131 this.removeEventListener("load", onLoad, true);
michael@0 132 stillToLoad--;
michael@0 133 if (!stillToLoad)
michael@0 134 executeSoon(callback);
michael@0 135 }
michael@0 136
michael@0 137 for (let a = 0; a < win.gBrowser.tabs.length; a++) {
michael@0 138 let tab = win.gBrowser.tabs[a];
michael@0 139 let browser = tab.linkedBrowser;
michael@0 140
michael@0 141 let isRestorable = !(tab.hidden && !restoreHiddenTabs &&
michael@0 142 browser.__SS_restoreState &&
michael@0 143 browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE);
michael@0 144
michael@0 145 if (isRestorable && browser.webProgress.isLoadingDocument) {
michael@0 146 stillToLoad++;
michael@0 147 browser.addEventListener("load", onLoad, true);
michael@0 148 }
michael@0 149 }
michael@0 150
michael@0 151 if (!stillToLoad)
michael@0 152 executeSoon(callback);
michael@0 153 }
michael@0 154
michael@0 155 // ----------
michael@0 156 function showTabView(callback, win) {
michael@0 157 win = win || window;
michael@0 158
michael@0 159 if (win.TabView.isVisible()) {
michael@0 160 waitForFocus(callback, win);
michael@0 161 return;
michael@0 162 }
michael@0 163
michael@0 164 whenTabViewIsShown(function () {
michael@0 165 waitForFocus(callback, win);
michael@0 166 }, win);
michael@0 167
michael@0 168 win.TabView.show();
michael@0 169 }
michael@0 170
michael@0 171 // ----------
michael@0 172 function hideTabView(callback, win) {
michael@0 173 win = win || window;
michael@0 174
michael@0 175 if (!win.TabView.isVisible()) {
michael@0 176 if (callback)
michael@0 177 callback();
michael@0 178 return;
michael@0 179 }
michael@0 180
michael@0 181 if (callback)
michael@0 182 whenTabViewIsHidden(callback, win);
michael@0 183
michael@0 184 win.TabView.hide();
michael@0 185 }
michael@0 186
michael@0 187 // ----------
michael@0 188 function whenTabViewIsHidden(callback, win) {
michael@0 189 win = win || window;
michael@0 190
michael@0 191 if (!win.TabView.isVisible()) {
michael@0 192 callback();
michael@0 193 return;
michael@0 194 }
michael@0 195
michael@0 196 win.addEventListener('tabviewhidden', function onHidden() {
michael@0 197 win.removeEventListener('tabviewhidden', onHidden, false);
michael@0 198 callback();
michael@0 199 }, false);
michael@0 200 }
michael@0 201
michael@0 202 // ----------
michael@0 203 function whenTabViewIsShown(callback, win) {
michael@0 204 win = win || window;
michael@0 205
michael@0 206 if (win.TabView.isVisible()) {
michael@0 207 callback();
michael@0 208 return;
michael@0 209 }
michael@0 210
michael@0 211 win.addEventListener('tabviewshown', function onShown() {
michael@0 212 win.removeEventListener('tabviewshown', onShown, false);
michael@0 213 callback();
michael@0 214 }, false);
michael@0 215 }
michael@0 216
michael@0 217 // ----------
michael@0 218 function hideSearch(callback, win) {
michael@0 219 win = win || window;
michael@0 220
michael@0 221 let contentWindow = win.TabView.getContentWindow();
michael@0 222 if (!contentWindow.Search.isEnabled()) {
michael@0 223 if (callback)
michael@0 224 callback();
michael@0 225 return;
michael@0 226 }
michael@0 227
michael@0 228 if (callback)
michael@0 229 whenSearchIsDisabled(callback, win);
michael@0 230
michael@0 231 contentWindow.Search.hide();
michael@0 232 }
michael@0 233
michael@0 234 // ----------
michael@0 235 function whenSearchIsEnabled(callback, win) {
michael@0 236 win = win || window;
michael@0 237
michael@0 238 let contentWindow = win.TabView.getContentWindow();
michael@0 239 if (contentWindow.Search.isEnabled()) {
michael@0 240 callback();
michael@0 241 return;
michael@0 242 }
michael@0 243
michael@0 244 contentWindow.addEventListener("tabviewsearchenabled", function onSearchEnabled() {
michael@0 245 contentWindow.removeEventListener("tabviewsearchenabled", onSearchEnabled, false);
michael@0 246 callback();
michael@0 247 }, false);
michael@0 248 }
michael@0 249
michael@0 250 // ----------
michael@0 251 function whenSearchIsDisabled(callback, win) {
michael@0 252 win = win || window;
michael@0 253
michael@0 254 let contentWindow = win.TabView.getContentWindow();
michael@0 255 if (!contentWindow.Search.isEnabled()) {
michael@0 256 callback();
michael@0 257 return;
michael@0 258 }
michael@0 259
michael@0 260 contentWindow.addEventListener("tabviewsearchdisabled", function onSearchDisabled() {
michael@0 261 contentWindow.removeEventListener("tabviewsearchdisabled", onSearchDisabled, false);
michael@0 262 callback();
michael@0 263 }, false);
michael@0 264 }
michael@0 265
michael@0 266 // ----------
michael@0 267 function hideGroupItem(groupItem, callback) {
michael@0 268 if (groupItem.hidden) {
michael@0 269 if (callback)
michael@0 270 callback();
michael@0 271 return;
michael@0 272 }
michael@0 273
michael@0 274 if (callback) {
michael@0 275 groupItem.addSubscriber("groupHidden", function onHide() {
michael@0 276 groupItem.removeSubscriber("groupHidden", onHide);
michael@0 277 callback();
michael@0 278 });
michael@0 279 }
michael@0 280
michael@0 281 groupItem.closeAll();
michael@0 282 }
michael@0 283
michael@0 284 // ----------
michael@0 285 function unhideGroupItem(groupItem, callback) {
michael@0 286 if (!groupItem.hidden) {
michael@0 287 if (callback)
michael@0 288 callback();
michael@0 289 return;
michael@0 290 }
michael@0 291
michael@0 292 if (callback) {
michael@0 293 groupItem.addSubscriber("groupShown", function onShown() {
michael@0 294 groupItem.removeSubscriber("groupShown", onShown);
michael@0 295 callback();
michael@0 296 });
michael@0 297 }
michael@0 298
michael@0 299 groupItem._unhide();
michael@0 300 }
michael@0 301
michael@0 302 // ----------
michael@0 303 function whenWindowLoaded(win, callback) {
michael@0 304 win.addEventListener("load", function onLoad() {
michael@0 305 win.removeEventListener("load", onLoad, false);
michael@0 306 executeSoon(callback);
michael@0 307 }, false);
michael@0 308 }
michael@0 309
michael@0 310 // ----------
michael@0 311 function whenWindowStateReady(win, callback) {
michael@0 312 win.addEventListener("SSWindowStateReady", function onReady() {
michael@0 313 win.removeEventListener("SSWindowStateReady", onReady, false);
michael@0 314 executeSoon(callback);
michael@0 315 }, false);
michael@0 316 }
michael@0 317
michael@0 318 // ----------
michael@0 319 function whenDelayedStartupFinished(win, callback) {
michael@0 320 let topic = "browser-delayed-startup-finished";
michael@0 321 Services.obs.addObserver(function onStartup(aSubject) {
michael@0 322 if (win != aSubject)
michael@0 323 return;
michael@0 324
michael@0 325 Services.obs.removeObserver(onStartup, topic);
michael@0 326 executeSoon(callback);
michael@0 327 }, topic, false);
michael@0 328 }
michael@0 329
michael@0 330 // ----------
michael@0 331 function newWindowWithState(state, callback) {
michael@0 332 const ss = Cc["@mozilla.org/browser/sessionstore;1"]
michael@0 333 .getService(Ci.nsISessionStore);
michael@0 334
michael@0 335 let opts = "chrome,all,dialog=no,height=800,width=800";
michael@0 336 let win = window.openDialog(getBrowserURL(), "_blank", opts, "about:blank");
michael@0 337
michael@0 338 let numConditions = 2;
michael@0 339 let check = function () {
michael@0 340 if (!--numConditions)
michael@0 341 callback(win);
michael@0 342 };
michael@0 343
michael@0 344 whenDelayedStartupFinished(win, function () {
michael@0 345 ss.setWindowState(win, JSON.stringify(state), true);
michael@0 346 win.close();
michael@0 347 // Give it time to close
michael@0 348 executeSoon(function() {
michael@0 349 win = ss.undoCloseWindow(0);
michael@0 350
michael@0 351 whenWindowLoaded(win, function () {
michael@0 352 afterAllTabsLoaded(check, win);
michael@0 353 });
michael@0 354
michael@0 355 whenDelayedStartupFinished(win, check);
michael@0 356 });
michael@0 357 });
michael@0 358 }
michael@0 359
michael@0 360 // ----------
michael@0 361 function restoreTab(callback, index, win) {
michael@0 362 win = win || window;
michael@0 363
michael@0 364 let tab = win.undoCloseTab(index || 0);
michael@0 365 let tabItem = tab._tabViewTabItem;
michael@0 366
michael@0 367 let finalize = function () {
michael@0 368 afterAllTabsLoaded(function () callback(tab), win);
michael@0 369 };
michael@0 370
michael@0 371 if (tabItem._reconnected) {
michael@0 372 finalize();
michael@0 373 return;
michael@0 374 }
michael@0 375
michael@0 376 tab._tabViewTabItem.addSubscriber("reconnected", function onReconnected() {
michael@0 377 tab._tabViewTabItem.removeSubscriber("reconnected", onReconnected);
michael@0 378 finalize();
michael@0 379 });
michael@0 380 }
michael@0 381
michael@0 382 // ----------
michael@0 383 function goToNextGroup(win) {
michael@0 384 win = win || window;
michael@0 385
michael@0 386 let utils =
michael@0 387 win.QueryInterface(Ci.nsIInterfaceRequestor).
michael@0 388 getInterface(Ci.nsIDOMWindowUtils);
michael@0 389
michael@0 390 const masks = Ci.nsIDOMNSEvent;
michael@0 391 let mval = 0;
michael@0 392 mval |= masks.CONTROL_MASK;
michael@0 393
michael@0 394 utils.sendKeyEvent("keypress", 0, 96, mval);
michael@0 395 }
michael@0 396
michael@0 397 // ----------
michael@0 398 function whenAppTabIconAdded(groupItem, callback) {
michael@0 399 groupItem.addSubscriber("appTabIconAdded", function onAppTabIconAdded() {
michael@0 400 groupItem.removeSubscriber("appTabIconAdded", onAppTabIconAdded);
michael@0 401 executeSoon(callback);
michael@0 402 });
michael@0 403 }
michael@0 404
michael@0 405 /**
michael@0 406 * Chrome windows aren't closed synchronously. Provide a helper method to close
michael@0 407 * a window and wait until we received the "domwindowclosed" notification for it.
michael@0 408 */
michael@0 409 function promiseWindowClosed(win) {
michael@0 410 let deferred = Promise.defer();
michael@0 411
michael@0 412 Services.obs.addObserver(function obs(subject, topic) {
michael@0 413 if (subject == win) {
michael@0 414 Services.obs.removeObserver(obs, topic);
michael@0 415 deferred.resolve();
michael@0 416 }
michael@0 417 }, "domwindowclosed", false);
michael@0 418
michael@0 419 win.close();
michael@0 420 return deferred.promise;
michael@0 421 }
michael@0 422
michael@0 423 // ----------
michael@0 424 function waitForOnBeforeUnloadDialog(browser, callback) {
michael@0 425 browser.addEventListener("DOMWillOpenModalDialog", function onModalDialog() {
michael@0 426 browser.removeEventListener("DOMWillOpenModalDialog", onModalDialog, true);
michael@0 427
michael@0 428 executeSoon(() => {
michael@0 429 let stack = browser.parentNode;
michael@0 430 let dialogs = stack.getElementsByTagNameNS(XUL_NS, "tabmodalprompt");
michael@0 431 let {button0, button1} = dialogs[0].ui;
michael@0 432 callback(button0, button1);
michael@0 433 });
michael@0 434 }, true);
michael@0 435 }
michael@0 436
michael@0 437 /**
michael@0 438 * Overrides browser.js' OpenBrowserWindow() function to enforce an initial
michael@0 439 * tab different from about:home to not hit the network.
michael@0 440 */
michael@0 441 function OpenBrowserWindow(aOptions) {
michael@0 442 let features = "";
michael@0 443 let url = "about:blank";
michael@0 444
michael@0 445 if (aOptions && aOptions.private || false) {
michael@0 446 features = ",private";
michael@0 447 url = "about:privatebrowsing";
michael@0 448 }
michael@0 449
michael@0 450 return openDialog(getBrowserURL(), "", "chrome,all,dialog=no" + features, url);
michael@0 451 }

mercurial