browser/base/content/test/general/browser_windowopen_reflows.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.

     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 }

mercurial