Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 "use strict";
6 const EXPECTED_REFLOWS = [
7 // handleEvent flushes layout to get the tabstrip width after a resize.
8 "handleEvent@chrome://browser/content/tabbrowser.xml|",
10 // Loading a tab causes a reflow.
11 "loadTabs@chrome://browser/content/tabbrowser.xml|" +
12 "loadOneOrMoreURIs@chrome://browser/content/browser.js|" +
13 "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
15 // Selecting the address bar causes a reflow.
16 "select@chrome://global/content/bindings/textbox.xml|" +
17 "focusAndSelectUrlBar@chrome://browser/content/browser.js|" +
18 "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
20 // Focusing the content area causes a reflow.
21 "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|",
23 // Sometimes sessionstore collects data during this test, which causes a sync reflow
24 // (https://bugzilla.mozilla.org/show_bug.cgi?id=892154 will fix this)
25 "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm",
26 ];
28 if (Services.appinfo.OS == "WINNT" || Services.appinfo.OS == "Darwin") {
29 // TabsInTitlebar._update causes a reflow on OS X and Windows trying to do calculations
30 // since layout info is already dirty. This doesn't seem to happen before
31 // MozAfterPaint on Linux.
32 EXPECTED_REFLOWS.push("rect@chrome://browser/content/browser.js|" +
33 "TabsInTitlebar._update@chrome://browser/content/browser.js|" +
34 "updateAppearance@chrome://browser/content/browser.js|" +
35 "handleEvent@chrome://browser/content/tabbrowser.xml|");
36 }
38 if (Services.appinfo.OS == "Darwin") {
39 // _onOverflow causes a reflow getting widths.
40 EXPECTED_REFLOWS.push("OverflowableToolbar.prototype._onOverflow@resource:///modules/CustomizableUI.jsm|" +
41 "OverflowableToolbar.prototype.init@resource:///modules/CustomizableUI.jsm|" +
42 "OverflowableToolbar.prototype.observe@resource:///modules/CustomizableUI.jsm|" +
43 "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|");
44 // Same as above since in packaged builds there are no function names and the resource URI includes "app"
45 EXPECTED_REFLOWS.push("@resource://app/modules/CustomizableUI.jsm|" +
46 "@resource://app/modules/CustomizableUI.jsm|" +
47 "@resource://app/modules/CustomizableUI.jsm|" +
48 "gBrowserInit._delayedStartup@chrome://browser/content/browser.js|");
49 }
51 /*
52 * This test ensures that there are no unexpected
53 * uninterruptible reflows when opening new windows.
54 */
55 function test() {
56 waitForExplicitFinish();
58 // Add a reflow observer and open a new window
59 let win = OpenBrowserWindow();
60 let docShell = win.QueryInterface(Ci.nsIInterfaceRequestor)
61 .getInterface(Ci.nsIWebNavigation)
62 .QueryInterface(Ci.nsIDocShell);
63 docShell.addWeakReflowObserver(observer);
65 // Wait until the mozafterpaint event occurs.
66 waitForMozAfterPaint(win, function paintListener() {
67 // Remove reflow observer and clean up.
68 docShell.removeWeakReflowObserver(observer);
69 win.close();
71 finish();
72 });
73 }
75 let observer = {
76 reflow: function (start, end) {
77 // Gather information about the current code path.
78 let stack = new Error().stack;
79 let path = stack.split("\n").slice(1).map(line => {
80 return line.replace(/:\d+:\d+$/, "");
81 }).join("|");
82 let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");
84 // Stack trace is empty. Reflow was triggered by native code.
85 if (path === "") {
86 return;
87 }
89 // Check if this is an expected reflow.
90 for (let expectedStack of EXPECTED_REFLOWS) {
91 if (path.startsWith(expectedStack) ||
92 // Accept an empty function name for gBrowserInit._delayedStartup or TabsInTitlebar._update to workaround bug 906578.
93 path.startsWith(expectedStack.replace(/(^|\|)(gBrowserInit\._delayedStartup|TabsInTitlebar\._update)@/, "$1@"))) {
94 ok(true, "expected uninterruptible reflow '" + expectedStack + "'");
95 return;
96 }
97 }
99 ok(false, "unexpected uninterruptible reflow '" + pathWithLineNumbers + "'");
100 },
102 reflowInterruptible: function (start, end) {
103 // We're not interested in interruptible reflows.
104 },
106 QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
107 Ci.nsISupportsWeakReference])
108 };
110 function waitForMozAfterPaint(win, callback) {
111 win.addEventListener("MozAfterPaint", function onEnd(event) {
112 if (event.target != win)
113 return;
114 win.removeEventListener("MozAfterPaint", onEnd);
115 executeSoon(callback);
116 });
117 }