Bug 1444891 - Remove the statuspanel binding. r?jaws
MozReview-Commit-ID: KcpOYuObiNG
--- a/accessible/tests/mochitest/tree/test_tabbrowser.xul
+++ b/accessible/tests/mochitest/tree/test_tabbrowser.xul
@@ -158,16 +158,19 @@
role: ROLE_INTERNAL_FRAME,
children: [
{
// #document ("about:license")
role: ROLE_DOCUMENT
// children: [ ... ] // Ignore document content.
}
]
+ },
+ {
+ role: ROLE_STATUSBAR
}
]
},
{
// notificationbox
role: ROLE_PROPERTYPAGE,
children: [
{
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -971,61 +971,60 @@ html|*#fullscreen-exit-button {
}
browser[tabmodalPromptShowing] {
-moz-user-focus: none !important;
}
/* Status panel */
-statuspanel {
- -moz-binding: url("chrome://browser/content/tabbrowser.xml#statuspanel");
+#statuspanel {
position: fixed;
margin-top: -3em;
max-width: calc(100% - 5px);
pointer-events: none;
}
-statuspanel[mirror] {
+#statuspanel[mirror] {
offset-inline-start: auto;
offset-inline-end: 0;
}
-statuspanel[sizelimit] {
+#statuspanel[sizelimit] {
max-width: 50%;
}
-statuspanel[type=status] {
+#statuspanel[type=status] {
min-width: 23em;
}
@media all and (max-width: 800px) {
- statuspanel[type=status] {
+ #statuspanel[type=status] {
min-width: 33%;
}
}
-statuspanel[type=overLink] {
+#statuspanel[type=overLink] {
transition: opacity 120ms ease-out;
}
-statuspanel[type=overLink] > .statuspanel-inner {
+#statuspanel[type=overLink] > #statuspanel-inner {
direction: ltr;
}
-statuspanel[inactive] {
+#statuspanel[inactive] {
transition: none;
opacity: 0;
}
-statuspanel[inactive][previoustype=overLink] {
+#statuspanel[inactive][previoustype=overLink] {
transition: opacity 200ms ease-out;
}
-.statuspanel-inner {
+#statuspanel-inner {
height: 3em;
width: 100%;
-moz-box-align: end;
}
/* gcli */
html|*#gcli-tooltip-frame,
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1,14 +1,15 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* eslint-env mozilla/browser-window */
+/* globals StatusPanel */
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
ChromeUtils.import("resource://gre/modules/NotificationDB.jsm");
const {WebExtensionPolicy} = Cu.getGlobalForObject(Services);
@@ -4386,18 +4387,18 @@ function updateCharacterEncodingMenuStat
}
var XULBrowserWindow = {
// Stored Status, Link and Loading values
status: "",
defaultStatus: "",
overLink: "",
startTime: 0,
- statusText: "",
isBusy: false,
+ busyUI: false,
// Left here for add-on compatibility, see bug 752434
inContentWhitelist: [],
QueryInterface(aIID) {
if (aIID.equals(Ci.nsIWebProgressListener) ||
aIID.equals(Ci.nsIWebProgressListener2) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsIXULBrowserWindow) ||
@@ -4409,19 +4410,16 @@ var XULBrowserWindow = {
get stopCommand() {
delete this.stopCommand;
return this.stopCommand = document.getElementById("Browser:Stop");
},
get reloadCommand() {
delete this.reloadCommand;
return this.reloadCommand = document.getElementById("Browser:Reload");
},
- get statusTextField() {
- return gBrowser.getStatusPanel();
- },
get isImage() {
delete this.isImage;
return this.isImage = document.getElementById("isImage");
},
get canViewSource() {
delete this.canViewSource;
return this.canViewSource = document.getElementById("canViewSource");
},
@@ -4435,17 +4433,17 @@ var XULBrowserWindow = {
},
forceInitialBrowserNonRemote(aOpener) {
gBrowser.updateBrowserRemoteness(gBrowser.initialBrowser, false, { opener: aOpener });
},
setDefaultStatus(status) {
this.defaultStatus = status;
- this.updateStatusField();
+ StatusPanel.update();
},
setOverLink(url, anchorElt) {
if (url) {
url = Services.textToSubURI.unEscapeURIForUI("UTF-8", url);
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
@@ -4479,39 +4477,16 @@ var XULBrowserWindow = {
let elt = document.getElementById("remoteBrowserTooltip");
elt.hidePopup();
},
getTabCount() {
return gBrowser.tabs.length;
},
- updateStatusField() {
- var text, type, types = ["overLink"];
- if (this._busyUI)
- types.push("status");
- types.push("defaultStatus");
- for (type of types) {
- text = this[type];
- if (text)
- break;
- }
-
- // check the current value so we don't trigger an attribute change
- // and cause needless (slow!) UI updates
- if (this.statusText != text) {
- let field = this.statusTextField;
- field.setAttribute("previoustype", field.getAttribute("type"));
- field.setAttribute("type", type);
- field.label = text;
- field.setAttribute("crop", type == "overLink" ? "center" : "end");
- this.statusText = text;
- }
- },
-
// Called before links are navigated to to allow us to retarget them if needed.
onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab) {
return BrowserUtils.onBeforeLinkTraversal(originalTarget, linkURI, linkNode, isAppTab);
},
// Check whether this URI should load in the current process
shouldLoadURI(aDocShell, aURI, aReferrer, aHasPostData, aTriggeringPrincipal) {
if (!gMultiProcessBrowser)
@@ -4567,17 +4542,17 @@ var XULBrowserWindow = {
// clear out search-engine data
browser.engines = null;
}
this.isBusy = true;
if (!(aStateFlags & nsIWebProgressListener.STATE_RESTORING)) {
- this._busyUI = true;
+ this.busyUI = true;
// XXX: This needs to be based on window activity...
this.stopCommand.removeAttribute("disabled");
CombinedStopReload.switchToStop(aRequest, aWebProgress);
}
} else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
// This (thanks to the filter) is a network stop or the last
// request stop outside of loading the document, stop throbbers
@@ -4620,18 +4595,18 @@ var XULBrowserWindow = {
this.canViewSource.removeAttribute("disabled");
} else {
this.canViewSource.setAttribute("disabled", "true");
}
}
this.isBusy = false;
- if (this._busyUI) {
- this._busyUI = false;
+ if (this.busyUI) {
+ this.busyUI = false;
this.stopCommand.setAttribute("disabled", "true");
CombinedStopReload.switchToReload(aRequest, aWebProgress);
}
}
},
onLocationChange(aWebProgress, aRequest, aLocationURI, aFlags) {
@@ -4782,17 +4757,17 @@ var XULBrowserWindow = {
BrowserSearch.updateOpenSearchBadge();
},
// Left here for add-on compatibility, see bug 752434
hideChromeForLocation() {},
onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
this.status = aMessage;
- this.updateStatusField();
+ StatusPanel.update();
},
// Properties used to cache security state used to update the UI
_state: null,
_lastLocation: null,
// This is called in multiple ways:
// 1. Due to the nsIWebProgressListener.onSecurityChange notification.
@@ -4870,34 +4845,30 @@ var LinkTargetDisplay = {
get DELAY_SHOW() {
delete this.DELAY_SHOW;
return this.DELAY_SHOW = Services.prefs.getIntPref("browser.overlink-delay");
},
DELAY_HIDE: 250,
_timer: 0,
- get _isVisible() {
- return XULBrowserWindow.statusTextField.label != "";
- },
-
update() {
clearTimeout(this._timer);
window.removeEventListener("mousemove", this, true);
if (!XULBrowserWindow.overLink) {
if (XULBrowserWindow.hideOverLinkImmediately)
this._hide();
else
this._timer = setTimeout(this._hide.bind(this), this.DELAY_HIDE);
return;
}
- if (this._isVisible) {
- XULBrowserWindow.updateStatusField();
+ if (StatusPanel.isVisible) {
+ StatusPanel.update();
} else {
// Let the display appear when the mouse doesn't move within the delay
this._showDelayed();
window.addEventListener("mousemove", this, true);
}
},
handleEvent(event) {
@@ -4907,25 +4878,25 @@ var LinkTargetDisplay = {
clearTimeout(this._timer);
this._showDelayed();
break;
}
},
_showDelayed() {
this._timer = setTimeout(function(self) {
- XULBrowserWindow.updateStatusField();
+ StatusPanel.update();
window.removeEventListener("mousemove", self, true);
}, this.DELAY_SHOW, this);
},
_hide() {
clearTimeout(this._timer);
- XULBrowserWindow.updateStatusField();
+ StatusPanel.update();
}
};
var CombinedStopReload = {
// Try to initialize. Returns whether initialization was successful, which
// may mean we had already initialized.
ensureInitialized() {
if (this._initialized)
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -1227,16 +1227,25 @@
message="true" messagemanagergroup="browsers"
primary="true" blank="true"
tooltip="aHTMLTooltip"
contextmenu="contentAreaContextMenu"
autocompletepopup="PopupAutoComplete"
selectmenulist="ContentSelectDropdown"
datetimepicker="DateTimePickerPanel"/>
</stack>
+ <hbox id="statuspanel" inactive="true" layer="true">
+ <hbox id="statuspanel-inner">
+ <label id="statuspanel-label"
+ role="status"
+ aria-live="off"
+ flex="1"
+ crop="end"/>
+ </hbox>
+ </hbox>
</vbox>
</hbox>
</notificationbox>
</tabpanels>
</tabbox>
</vbox>
<vbox id="browser-border-end" hidden="true" layer="true"/>
</hbox>
--- a/browser/base/content/tabbrowser.js
+++ b/browser/base/content/tabbrowser.js
@@ -498,32 +498,20 @@ window._gBrowser = {
let event = document.createEvent("Events");
event.initEvent("TabFindInitialized", true, false);
aTab.dispatchEvent(event);
return findBar;
},
- getStatusPanel() {
- if (!this._statusPanel) {
- this._statusPanel = document.createElementNS(this._XUL_NS, "statuspanel");
- this._statusPanel.setAttribute("inactive", "true");
- this._statusPanel.setAttribute("layer", "true");
- this._appendStatusPanel();
- }
- return this._statusPanel;
- },
-
_appendStatusPanel() {
- if (this._statusPanel) {
- let browser = this.selectedBrowser;
- let browserContainer = this.getBrowserContainer(browser);
- browserContainer.insertBefore(this._statusPanel, browser.parentNode.nextSibling);
- }
+ let browser = this.selectedBrowser;
+ let browserContainer = this.getBrowserContainer(browser);
+ browserContainer.insertBefore(StatusPanel.panel, browser.parentNode.nextSibling);
},
pinTab(aTab) {
if (aTab.pinned)
return;
if (aTab.hidden)
this.showTab(aTab);
@@ -4609,8 +4597,135 @@ class TabProgressListener {
aIID.equals(Ci.nsIWebProgressListener2) ||
aIID.equals(Ci.nsISupportsWeakReference) ||
aIID.equals(Ci.nsISupports))
return this;
throw Cr.NS_NOINTERFACE;
}
}
+let StatusPanel = {
+ get panel() {
+ window.addEventListener("resize", this);
+
+ delete this.panel;
+ return this.panel = document.getElementById("statuspanel");
+ },
+
+ get isVisible() {
+ return !this.panel.hasAttribute("inactive");
+ },
+
+ update() {
+ let text;
+ let type;
+ let types = ["overLink"];
+ if (XULBrowserWindow.busyUI) {
+ types.push("status");
+ }
+ types.push("defaultStatus");
+ for (type of types) {
+ if ((text = XULBrowserWindow[type])) {
+ break;
+ }
+ }
+
+ if (this._labelElement.value != text) {
+ this.panel.setAttribute("previoustype", this.panel.getAttribute("type"));
+ this.panel.setAttribute("type", type);
+ this._label = text;
+ this._labelElement.setAttribute("crop", type == "overLink" ? "center" : "end");
+ }
+ },
+
+ get _labelElement() {
+ delete this._labelElement;
+ return this._labelElement = document.getElementById("statuspanel-label");
+ },
+
+ set _label(val) {
+ if (!this.isVisible) {
+ this.panel.removeAttribute("mirror");
+ this.panel.removeAttribute("sizelimit");
+ }
+
+ if (this.panel.getAttribute("type") == "status" &&
+ this.panel.getAttribute("previoustype") == "status") {
+ // Before updating the label, set the panel's current width as its
+ // min-width to let the panel grow but not shrink and prevent
+ // unnecessary flicker while loading pages. We only care about the
+ // panel's width once it has been painted, so we can do this
+ // without flushing layout.
+ this.panel.style.minWidth =
+ window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .getBoundsWithoutFlushing(this.panel).width + "px";
+ } else {
+ this.panel.style.minWidth = "";
+ }
+
+ if (val) {
+ this._labelElement.value = val;
+ this.panel.removeAttribute("inactive");
+ this._mouseTargetRect = null;
+ MousePosTracker.addListener(this);
+ } else {
+ this.panel.setAttribute("inactive", "true");
+ MousePosTracker.removeListener(this);
+ }
+
+ return val;
+ },
+
+ getMouseTargetRect() {
+ if (!this._mouseTargetRect) {
+ this._calcMouseTargetRect();
+ }
+ return this._mouseTargetRect;
+ },
+
+ onMouseEnter() {
+ this._mirror();
+ },
+
+ onMouseLeave() {
+ this._mirror();
+ },
+
+ handleEvent(event) {
+ if (!this.isVisible) {
+ return;
+ }
+ switch (event.type) {
+ case "resize":
+ this._mouseTargetRect = null;
+ break;
+ }
+ },
+
+ _calcMouseTargetRect() {
+ let container = this.panel.parentNode;
+ let alignRight = (getComputedStyle(container).direction == "rtl");
+ let panelRect = this.panel.getBoundingClientRect();
+ let containerRect = container.getBoundingClientRect();
+
+ this._mouseTargetRect = {
+ top: panelRect.top,
+ bottom: panelRect.bottom,
+ left: alignRight ? containerRect.right - panelRect.width : containerRect.left,
+ right: alignRight ? containerRect.right : containerRect.left + panelRect.width
+ };
+ },
+
+ _mirror() {
+ if (this.panel.hasAttribute("mirror")) {
+ this.panel.removeAttribute("mirror");
+ } else {
+ this.panel.setAttribute("mirror", "true");
+ }
+
+ if (!this.panel.hasAttribute("sizelimit")) {
+ this.panel.setAttribute("sizelimit", "true");
+ this._mouseTargetRect = null;
+ }
+ }
+};
+
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2222,144 +2222,16 @@
gBrowser.tabContainer._handleTabSelect();
}
}
]]></handler>
</handlers>
</binding>
- <binding id="statuspanel" display="xul:hbox">
- <content>
- <xul:hbox class="statuspanel-inner">
- <xul:label class="statuspanel-label"
- role="status"
- aria-live="off"
- xbl:inherits="value=label,crop,mirror"
- flex="1"
- crop="end"/>
- </xul:hbox>
- </content>
-
- <implementation implements="nsIDOMEventListener">
- <constructor><![CDATA[
- window.addEventListener("resize", this);
- ]]></constructor>
-
- <destructor><![CDATA[
- window.removeEventListener("resize", this);
- MousePosTracker.removeListener(this);
- ]]></destructor>
-
- <property name="label">
- <setter><![CDATA[
- if (!this.label) {
- this.removeAttribute("mirror");
- this.removeAttribute("sizelimit");
- }
-
- if (this.getAttribute("type") == "status" &&
- this.getAttribute("previoustype") == "status") {
- // Before updating the label, set the panel's current width as its
- // min-width to let the panel grow but not shrink and prevent
- // unnecessary flicker while loading pages. We only care about the
- // panel's width once it has been painted, so we can do this
- // without flushing layout.
- this.style.minWidth =
- window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils)
- .getBoundsWithoutFlushing(this).width + "px";
- } else {
- this.style.minWidth = "";
- }
-
- if (val) {
- this.setAttribute("label", val);
- this.removeAttribute("inactive");
- this._mouseTargetRect = null;
- MousePosTracker.addListener(this);
- } else {
- this.setAttribute("inactive", "true");
- MousePosTracker.removeListener(this);
- }
-
- return val;
- ]]></setter>
- <getter>
- return this.hasAttribute("inactive") ? "" : this.getAttribute("label");
- </getter>
- </property>
-
- <method name="getMouseTargetRect">
- <body><![CDATA[
- if (!this._mouseTargetRect) {
- this._calcMouseTargetRect();
- }
- return this._mouseTargetRect;
- ]]></body>
- </method>
-
- <method name="onMouseEnter">
- <body>
- this._mirror();
- </body>
- </method>
-
- <method name="onMouseLeave">
- <body>
- this._mirror();
- </body>
- </method>
-
- <method name="handleEvent">
- <parameter name="event"/>
- <body><![CDATA[
- if (!this.label)
- return;
-
- switch (event.type) {
- case "resize":
- this._mouseTargetRect = null;
- break;
- }
- ]]></body>
- </method>
-
- <method name="_calcMouseTargetRect">
- <body><![CDATA[
- let container = this.parentNode;
- let alignRight = (getComputedStyle(container).direction == "rtl");
- let panelRect = this.getBoundingClientRect();
- let containerRect = container.getBoundingClientRect();
-
- this._mouseTargetRect = {
- top: panelRect.top,
- bottom: panelRect.bottom,
- left: alignRight ? containerRect.right - panelRect.width : containerRect.left,
- right: alignRight ? containerRect.right : containerRect.left + panelRect.width
- };
- ]]></body>
- </method>
-
- <method name="_mirror">
- <body>
- if (this.hasAttribute("mirror"))
- this.removeAttribute("mirror");
- else
- this.setAttribute("mirror", "true");
-
- if (!this.hasAttribute("sizelimit")) {
- this.setAttribute("sizelimit", "true");
- this._mouseTargetRect = null;
- }
- </body>
- </method>
- </implementation>
- </binding>
-
<binding id="tabbrowser-tabpanels"
extends="chrome://global/content/bindings/tabbox.xml#tabpanels">
<implementation>
<field name="_selectedIndex">0</field>
<property name="selectedIndex">
<getter>
<![CDATA[
--- a/browser/themes/linux/browser.css
+++ b/browser/themes/linux/browser.css
@@ -521,35 +521,35 @@ notification[value="translation"] menuli
/* All tabs menupopup */
.alltabs-item[selected="true"] {
font-weight: bold;
}
/* Status panel */
-.statuspanel-label {
+#statuspanel-label {
margin: 0;
padding: 2px 4px;
background-color: -moz-dialog;
border: 1px none ThreeDShadow;
border-top-style: solid;
color: -moz-dialogText;
text-shadow: none;
}
-.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
-.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl) {
border-right-style: solid;
border-top-right-radius: .3em;
margin-right: 1em;
}
-.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
-.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr) {
border-left-style: solid;
border-top-left-radius: .3em;
margin-left: 1em;
}
%include ../shared/fullscreen/warning.inc.css
%include ../shared/ctrlTab.inc.css
%include ../shared/plugin-doorhanger.inc.css
--- a/browser/themes/osx/browser.css
+++ b/browser/themes/osx/browser.css
@@ -988,35 +988,35 @@ html|*.addon-webext-perm-list {
}
.addon-toolbar-icon {
list-style-image: url("chrome://browser/skin/menu.svg");
}
/* Status panel */
-.statuspanel-label {
+#statuspanel-label {
margin: 0;
padding: 2px 4px;
background-color: #f9f9fa;
border: 1px none #ddd;
border-top-style: solid;
color: #444;
text-shadow: none;
}
-.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
-.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl) {
border-right-style: solid;
border-top-right-radius: .3em;
margin-right: 1em;
}
-.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
-.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr) {
border-left-style: solid;
border-top-left-radius: .3em;
margin-left: 1em;
}
%include ../shared/fullscreen/warning.inc.css
%include ../shared/ctrlTab.inc.css
%include ../shared/plugin-doorhanger.inc.css
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -907,44 +907,44 @@ notification[value="translation"] {
#BMB_unsortedBookmarks,
#panelMenu_unsortedBookmarks {
list-style-image: url("chrome://browser/skin/places/unsortedBookmarks.png");
-moz-image-region: auto;
}
/* Status panel */
-.statuspanel-label {
+#statuspanel-label {
margin: 0;
padding: 2px 4px;
background-color: -moz-dialog;
border: 1px none ThreeDLightShadow;
border-top-style: solid;
color: -moz-dialogText;
text-shadow: none;
}
@media (-moz-windows-default-theme) {
- .statuspanel-label {
+ #statuspanel-label {
background-color: #f9f9fa;
color: #444;
}
}
-.statuspanel-label:-moz-locale-dir(ltr):not([mirror]),
-.statuspanel-label:-moz-locale-dir(rtl)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl) {
border-right-style: solid;
/* disabled for triggering grayscale AA (bug 659213)
border-top-right-radius: .3em;
*/
margin-right: 1em;
}
-.statuspanel-label:-moz-locale-dir(rtl):not([mirror]),
-.statuspanel-label:-moz-locale-dir(ltr)[mirror] {
+#statuspanel:not([mirror]) > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(rtl),
+#statuspanel[mirror] > #statuspanel-inner > #statuspanel-label:-moz-locale-dir(ltr) {
border-left-style: solid;
/* disabled for triggering grayscale AA (bug 659213)
border-top-left-radius: .3em;
*/
margin-left: 1em;
}
%include ../shared/fullscreen/warning.inc.css