browser/base/content/test/general/browser_tabopen_reflows.js

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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 XPCOMUtils.defineLazyGetter(this, "docShell", () => {
michael@0 5 return window.QueryInterface(Ci.nsIInterfaceRequestor)
michael@0 6 .getInterface(Ci.nsIWebNavigation)
michael@0 7 .QueryInterface(Ci.nsIDocShell);
michael@0 8 });
michael@0 9
michael@0 10 const EXPECTED_REFLOWS = [
michael@0 11 // tabbrowser.adjustTabstrip() call after tabopen animation has finished
michael@0 12 "adjustTabstrip@chrome://browser/content/tabbrowser.xml|" +
michael@0 13 "_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
michael@0 14 "onxbltransitionend@chrome://browser/content/tabbrowser.xml|",
michael@0 15
michael@0 16 // switching focus in updateCurrentBrowser() causes reflows
michael@0 17 "updateCurrentBrowser@chrome://browser/content/tabbrowser.xml|" +
michael@0 18 "onselect@chrome://browser/content/browser.xul|",
michael@0 19
michael@0 20 // switching focus in openLinkIn() causes reflows
michael@0 21 "openLinkIn@chrome://browser/content/utilityOverlay.js|" +
michael@0 22 "openUILinkIn@chrome://browser/content/utilityOverlay.js|" +
michael@0 23 "BrowserOpenTab@chrome://browser/content/browser.js|",
michael@0 24
michael@0 25 // accessing element.scrollPosition in _fillTrailingGap() flushes layout
michael@0 26 "get_scrollPosition@chrome://global/content/bindings/scrollbox.xml|" +
michael@0 27 "_fillTrailingGap@chrome://browser/content/tabbrowser.xml|" +
michael@0 28 "_handleNewTab@chrome://browser/content/tabbrowser.xml|" +
michael@0 29 "onxbltransitionend@chrome://browser/content/tabbrowser.xml|",
michael@0 30
michael@0 31 // The TabView iframe causes reflows in the parent document.
michael@0 32 "iQClass_height@chrome://browser/content/tabview.js|" +
michael@0 33 "GroupItem_getContentBounds@chrome://browser/content/tabview.js|" +
michael@0 34 "GroupItem_shouldStack@chrome://browser/content/tabview.js|" +
michael@0 35 "GroupItem_arrange@chrome://browser/content/tabview.js|" +
michael@0 36 "GroupItem_add@chrome://browser/content/tabview.js|" +
michael@0 37 "GroupItems_newTab@chrome://browser/content/tabview.js|" +
michael@0 38 "TabItem__reconnect@chrome://browser/content/tabview.js|" +
michael@0 39 "TabItem@chrome://browser/content/tabview.js|" +
michael@0 40 "TabItems_link@chrome://browser/content/tabview.js|" +
michael@0 41 "TabItems_init/this._eventListeners.open@chrome://browser/content/tabview.js|",
michael@0 42
michael@0 43 // SessionStore.getWindowDimensions()
michael@0 44 "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm|" +
michael@0 45 "ssi_updateWindowFeatures/<@resource:///modules/sessionstore/SessionStore.jsm|" +
michael@0 46 "ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" +
michael@0 47 "ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|",
michael@0 48
michael@0 49 // tabPreviews.capture()
michael@0 50 "tabPreviews_capture@chrome://browser/content/browser.js|" +
michael@0 51 "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|",
michael@0 52
michael@0 53 // tabPreviews.capture()
michael@0 54 "tabPreviews_capture@chrome://browser/content/browser.js|" +
michael@0 55 "@chrome://browser/content/browser.js|"
michael@0 56 ];
michael@0 57
michael@0 58 const PREF_PRELOAD = "browser.newtab.preload";
michael@0 59 const PREF_NEWTAB_DIRECTORYSOURCE = "browser.newtabpage.directorySource";
michael@0 60
michael@0 61 /*
michael@0 62 * This test ensures that there are no unexpected
michael@0 63 * uninterruptible reflows when opening new tabs.
michael@0 64 */
michael@0 65 function test() {
michael@0 66 waitForExplicitFinish();
michael@0 67
michael@0 68 Services.prefs.setBoolPref(PREF_PRELOAD, false);
michael@0 69 Services.prefs.setCharPref(PREF_NEWTAB_DIRECTORYSOURCE, "data:application/json,{}");
michael@0 70 registerCleanupFunction(() => {
michael@0 71 Services.prefs.clearUserPref(PREF_PRELOAD);
michael@0 72 Services.prefs.clearUserPref(PREF_NEWTAB_DIRECTORYSOURCE);
michael@0 73 });
michael@0 74
michael@0 75 // Add a reflow observer and open a new tab.
michael@0 76 docShell.addWeakReflowObserver(observer);
michael@0 77 BrowserOpenTab();
michael@0 78
michael@0 79 // Wait until the tabopen animation has finished.
michael@0 80 waitForTransitionEnd(function () {
michael@0 81 // Remove reflow observer and clean up.
michael@0 82 docShell.removeWeakReflowObserver(observer);
michael@0 83 gBrowser.removeCurrentTab();
michael@0 84
michael@0 85 finish();
michael@0 86 });
michael@0 87 }
michael@0 88
michael@0 89 let observer = {
michael@0 90 reflow: function (start, end) {
michael@0 91 // Gather information about the current code path.
michael@0 92 let path = (new Error().stack).split("\n").slice(1).map(line => {
michael@0 93 return line.replace(/:\d+:\d+$/, "");
michael@0 94 }).join("|");
michael@0 95 let pathWithLineNumbers = (new Error().stack).split("\n").slice(1).join("|");
michael@0 96
michael@0 97 // Stack trace is empty. Reflow was triggered by native code.
michael@0 98 if (path === "") {
michael@0 99 return;
michael@0 100 }
michael@0 101
michael@0 102 // Check if this is an expected reflow.
michael@0 103 for (let stack of EXPECTED_REFLOWS) {
michael@0 104 if (path.startsWith(stack)) {
michael@0 105 ok(true, "expected uninterruptible reflow '" + stack + "'");
michael@0 106 return;
michael@0 107 }
michael@0 108 }
michael@0 109
michael@0 110 ok(false, "unexpected uninterruptible reflow '" + pathWithLineNumbers + "'");
michael@0 111 },
michael@0 112
michael@0 113 reflowInterruptible: function (start, end) {
michael@0 114 // We're not interested in interruptible reflows.
michael@0 115 },
michael@0 116
michael@0 117 QueryInterface: XPCOMUtils.generateQI([Ci.nsIReflowObserver,
michael@0 118 Ci.nsISupportsWeakReference])
michael@0 119 };
michael@0 120
michael@0 121 function waitForTransitionEnd(callback) {
michael@0 122 let tab = gBrowser.selectedTab;
michael@0 123 tab.addEventListener("transitionend", function onEnd(event) {
michael@0 124 if (event.propertyName === "max-width") {
michael@0 125 tab.removeEventListener("transitionend", onEnd);
michael@0 126 executeSoon(callback);
michael@0 127 }
michael@0 128 });
michael@0 129 }

mercurial