mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 22:32:46 +00:00
Bug 909779 - Toolbar Overflow isn't initialized correctly on newly opened windows. r=Gijs,jaws
This commit is contained in:
parent
a2d8e8b929
commit
1117925a69
@ -13,6 +13,8 @@
|
||||
<stylesheet src="chrome://global/skin/toolbar.css"/>
|
||||
</resources>
|
||||
<implementation implements="nsIAccessibleProvider">
|
||||
<field name="overflowedDuringConstruction">null</field>
|
||||
|
||||
<property name="accessibleType" readonly="true">
|
||||
<getter>
|
||||
return Components.interfaces.nsIAccessibleProvider.XULToolbar;
|
||||
@ -20,6 +22,15 @@
|
||||
</property>
|
||||
|
||||
<constructor><![CDATA[
|
||||
let scope = {};
|
||||
Cu.import("resource:///modules/CustomizableUI.jsm", scope);
|
||||
// Add an early overflow event listener that will mark if the
|
||||
// toolbar overflowed during construction.
|
||||
if (scope.CustomizableUI.isAreaOverflowable(this.id)) {
|
||||
this.addEventListener("overflow", this);
|
||||
this.addEventListener("underflow", this);
|
||||
}
|
||||
|
||||
if (document.readyState == "complete") {
|
||||
this._init();
|
||||
} else {
|
||||
@ -61,6 +72,21 @@
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
if (aEvent.type == "overflow" && aEvent.detail > 0) {
|
||||
if (this.overflowable && this.overflowable.initialized) {
|
||||
this.overflowable.onOverflow(aEvent);
|
||||
} else {
|
||||
this.overflowedDuringConstruction = aEvent;
|
||||
}
|
||||
} else if (aEvent.type == "underflow" && aEvent.detail > 0) {
|
||||
this.overflowedDuringConstruction = null;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="insertItem">
|
||||
<parameter name="aId"/>
|
||||
<parameter name="aBeforeElt"/>
|
||||
|
@ -2075,7 +2075,12 @@ this.CustomizableUI = {
|
||||
},
|
||||
onWidgetDrag: function(aWidgetId, aArea) {
|
||||
CustomizableUIInternal.notifyListeners("onWidgetDrag", aWidgetId, aArea);
|
||||
}
|
||||
},
|
||||
isAreaOverflowable: function(aAreaId) {
|
||||
let area = gAreas.get(aAreaId);
|
||||
return area ? area.get("type") == this.TYPE_TOOLBAR && area.get("overflowable")
|
||||
: false;
|
||||
},
|
||||
};
|
||||
Object.freeze(this.CustomizableUI);
|
||||
|
||||
@ -2299,13 +2304,12 @@ function OverflowableToolbar(aToolbarNode) {
|
||||
this._collapsed = new Map();
|
||||
this._enabled = true;
|
||||
|
||||
this._toolbar.customizationTarget.addEventListener("overflow", this);
|
||||
this._toolbar.setAttribute("overflowable", "true");
|
||||
Services.obs.addObserver(this, "browser-delayed-startup-finished", false);
|
||||
}
|
||||
|
||||
OverflowableToolbar.prototype = {
|
||||
_initialized: false,
|
||||
initialized: false,
|
||||
_forceOnOverflow: false,
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
@ -2338,19 +2342,21 @@ OverflowableToolbar.prototype = {
|
||||
|
||||
CustomizableUI.addListener(this);
|
||||
|
||||
this._initialized = true;
|
||||
|
||||
// The 'overflow' event may have been fired before init was called.
|
||||
if (this._forceOnOverflow) {
|
||||
this._onOverflow();
|
||||
if (this._toolbar.overflowedDuringConstruction) {
|
||||
this.onOverflow(this._toolbar.overflowedDuringConstruction);
|
||||
this._toolbar.overflowedDuringConstruction = null;
|
||||
}
|
||||
|
||||
this.initialized = true;
|
||||
},
|
||||
|
||||
uninit: function() {
|
||||
this._toolbar.customizationTarget.removeEventListener("overflow", this);
|
||||
this._toolbar.removeEventListener("overflow", this._toolbar);
|
||||
this._toolbar.removeEventListener("underflow", this._toolbar);
|
||||
this._toolbar.removeAttribute("overflowable");
|
||||
|
||||
if (!this._initialized) {
|
||||
if (!this.initialized) {
|
||||
Services.obs.removeObserver(this, "browser-delayed-startup-finished");
|
||||
return;
|
||||
}
|
||||
@ -2369,16 +2375,6 @@ OverflowableToolbar.prototype = {
|
||||
|
||||
handleEvent: function(aEvent) {
|
||||
switch(aEvent.type) {
|
||||
case "overflow":
|
||||
// Ignore vertical overflow:
|
||||
if (aEvent.detail > 0) {
|
||||
if (this._initialized) {
|
||||
this._onOverflow();
|
||||
} else {
|
||||
this._forceOnOverflow = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "resize":
|
||||
this._onResize(aEvent);
|
||||
break;
|
||||
@ -2413,13 +2409,14 @@ OverflowableToolbar.prototype = {
|
||||
this._chevron.open = false;
|
||||
},
|
||||
|
||||
_onOverflow: function() {
|
||||
if (!this._enabled)
|
||||
onOverflow: function(aEvent) {
|
||||
if (!this._enabled ||
|
||||
(aEvent && aEvent.target != this._toolbar.customizationTarget))
|
||||
return;
|
||||
|
||||
let child = this._target.lastChild;
|
||||
|
||||
while (child && this._target.clientWidth < this._target.scrollWidth) {
|
||||
while (child && this._target.scrollLeftMax > 0) {
|
||||
let prevChild = child.previousSibling;
|
||||
|
||||
if (child.getAttribute("overflows") != "false") {
|
||||
@ -2510,7 +2507,7 @@ OverflowableToolbar.prototype = {
|
||||
|
||||
_enable: function() {
|
||||
this._enabled = true;
|
||||
this._onOverflow();
|
||||
this.onOverflow();
|
||||
},
|
||||
|
||||
onWidgetBeforeDOMChange: function(aNode, aNextNode, aContainer) {
|
||||
|
@ -16,6 +16,7 @@ support-files =
|
||||
[browser_890262_destroyWidget_after_add_to_panel.js]
|
||||
[browser_892955_isWidgetRemovable_for_removed_widgets.js]
|
||||
[browser_892956_destroyWidget_defaultPlacements.js]
|
||||
[browser_909779_overflow_toolbars_new_window.js]
|
||||
[browser_913972_currentset_overflow.js]
|
||||
|
||||
[browser_914138_widget_API_overflowable_toolbar.js]
|
||||
|
@ -0,0 +1,38 @@
|
||||
/* 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/. */
|
||||
|
||||
let gTests = [
|
||||
{
|
||||
desc: "Resize to a small window, open a new window, check that new window handles overflow properly",
|
||||
run: function() {
|
||||
let originalWindowWidth = window.outerWidth;
|
||||
let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
|
||||
ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
|
||||
let oldChildCount = navbar.customizationTarget.childElementCount;
|
||||
window.resizeTo(400, window.outerHeight);
|
||||
yield waitForCondition(() => navbar.hasAttribute("overflowing"));
|
||||
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
|
||||
|
||||
ok(navbar.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
|
||||
let newWindow = yield openAndLoadWindow();
|
||||
let otherNavBar = newWindow.document.getElementById(CustomizableUI.AREA_NAVBAR);
|
||||
yield waitForCondition(() => otherNavBar.hasAttribute("overflowing"));
|
||||
ok(otherNavBar.hasAttribute("overflowing"), "Other window should have an overflowing toolbar.");
|
||||
newWindow.close();
|
||||
|
||||
window.resizeTo(originalWindowWidth, window.outerHeight);
|
||||
yield waitForCondition(() => !navbar.hasAttribute("overflowing"));
|
||||
ok(!navbar.hasAttribute("overflowing"), "Should no longer have an overflowing toolbar.");
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function asyncCleanup() {
|
||||
yield resetCustomization();
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
runTests(gTests, asyncCleanup);
|
||||
}
|
Loading…
Reference in New Issue
Block a user