browser/components/tabview/test/head.js

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

mercurial