author | Florian Quèze <florian@queze.net> |
Fri, 11 Aug 2017 10:19:48 +0200 | |
changeset 374275 | 3a7bd8419732cb5a944b331d168729b9c9e6e8de |
parent 374274 | 806a941c858051eceb8076b056fb278dcc259647 |
child 374276 | c4eb424ae51815c00c532dfb550d463b29dcd63a |
push id | 32318 |
push user | kwierso@gmail.com |
push date | Fri, 11 Aug 2017 20:16:01 +0000 |
treeherder | mozilla-central@80ff3f300e05 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | johannh |
bugs | 1372518 |
milestone | 57.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -1359,29 +1359,32 @@ var gBrowserInit = { document.documentElement.setAttribute("darkwindowframe", "true"); } } ToolbarIconColor.init(); gRemoteControl.updateVisualCue(Marionette.running); + let uriToLoad = this._getUriToLoad(); + gIdentityHandler.initIdentityBlock(uriToLoad); + // Wait until chrome is painted before executing code not critical to making the window visible - this._boundDelayedStartup = this._delayedStartup.bind(this); + this._boundDelayedStartup = this._delayedStartup.bind(this, uriToLoad); window.addEventListener("MozAfterPaint", this._boundDelayedStartup); this._loadHandled = true; }, _cancelDelayedStartup() { window.removeEventListener("MozAfterPaint", this._boundDelayedStartup); this._boundDelayedStartup = null; }, - _delayedStartup() { + _delayedStartup(uriToLoad) { let tmp = {}; Cu.import("resource://gre/modules/TelemetryTimestamps.jsm", tmp); let TelemetryTimestamps = tmp.TelemetryTimestamps; TelemetryTimestamps.add("delayedStartupStarted"); this._cancelDelayedStartup(); // We need to set the OfflineApps message listeners up before we @@ -1417,17 +1420,16 @@ var gBrowserInit = { gIdentityHandler.refreshIdentityBlock(); }); // Get the service so that it initializes and registers listeners for new // tab pages in order to be ready for any early-loading about:newtab pages, // e.g., start/home page, command line / startup uris to load, sessionstore gAboutNewTabService.QueryInterface(Ci.nsISupports); - let uriToLoad = this._getUriToLoad(); if (uriToLoad && uriToLoad != "about:blank") { if (uriToLoad instanceof Ci.nsIArray) { let count = uriToLoad.length; let specs = []; for (let i = 0; i < count; i++) { let urisstring = uriToLoad.queryElementAt(i, Ci.nsISupportsString); specs.push(urisstring.data); } @@ -7008,16 +7010,22 @@ var gIdentityHandler = { _state: 0, /** * This flag gets set if the identity popup was opened by a keypress, * to be able to focus it on the popupshown event. */ _popupTriggeredByKeyboard: false, + /** + * RegExp used to decide if an about url should be shown as being part of + * the browser UI. + */ + _secureInternalUIWhitelist: /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback)(?:[?#]|$)/i, + get _isBroken() { return this._state & Ci.nsIWebProgressListener.STATE_IS_BROKEN; }, get _isSecure() { // If a <browser> is included within a chrome document, then this._state // will refer to the security state for the <browser> and not the top level // document. In this case, don't upgrade the security state in the UI @@ -7636,27 +7644,35 @@ var gIdentityHandler = { this._identityPopupContentSupp.textContent = supplemental; this._identityPopupContentVerif.textContent = verifier; // Update per-site permissions section. this.updateSitePermissions(); }, setURI(uri) { + // Ignore about:blank loads until the window's initial URL has loaded, + // to avoid hiding the UI that initIdentityBlock could have prepared. + if (this._ignoreAboutBlankUntilFirstLoad) { + if (uri.spec == "about:blank") + return; + this._ignoreAboutBlankUntilFirstLoad = false; + } + this._uri = uri; try { this._uri.host; this._uriHasHost = true; } catch (ex) { this._uriHasHost = false; } - let whitelist = /^(?:accounts|addons|cache|config|crashes|customizing|downloads|healthreport|home|license|newaddon|permissions|preferences|privatebrowsing|rights|searchreset|sessionrestore|support|welcomeback)(?:[?#]|$)/i; - this._isSecureInternalUI = uri.schemeIs("about") && whitelist.test(uri.pathQueryRef); + this._isSecureInternalUI = uri.schemeIs("about") && + this._secureInternalUIWhitelist.test(uri.pathQueryRef); this._isExtensionPage = uri.schemeIs("moz-extension"); // Create a channel for the sole purpose of getting the resolved URI // of the request to determine if it's loaded from the file system. this._isURILoadedFromFile = false; let chanOptions = {uri: this._uri, loadUsingSystemPrincipal: true}; let resolvedURI; @@ -7670,16 +7686,35 @@ var gIdentityHandler = { // Check the URI again after resolving. this._isURILoadedFromFile = resolvedURI.schemeIs("file"); } catch (ex) { // NetUtil's methods will throw for malformed URIs and the like } }, /** + * Used to initialize the identity block before first paint to avoid + * flickering when opening a new window showing a secure internal page + * (eg. about:home) + */ + initIdentityBlock(initialURI) { + if ((typeof initialURI != "string") || !initialURI.startsWith("about:")) + return; + + let uri = Services.io.newURI(initialURI); + if (this._secureInternalUIWhitelist.test(uri.pathQueryRef)) { + this._isSecureInternalUI = true; + this._ignoreAboutBlankUntilFirstLoad = true; + this.refreshIdentityBlock(); + // The identity label won't be visible without setting this. + gURLBar.setAttribute("pageproxystate", "valid"); + } + }, + + /** * Click handler for the identity-box element in primary chrome. */ handleIdentityButtonEvent(event) { event.stopPropagation(); if ((event.type == "click" && event.button != 0) || (event.type == "keypress" && event.charCode != KeyEvent.DOM_VK_SPACE && event.keyCode != KeyEvent.DOM_VK_RETURN)) {