mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 880382 - When customizing, dragging wide widgets in the panel should cause panel to break by rows. r=mconley
This commit is contained in:
parent
4951c566e9
commit
f1b3a3fbb3
@ -15,6 +15,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
||||
|
||||
const kNSXUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const kPrefCustomizationDebug = "browser.uiCustomization.debug";
|
||||
const kWidePanelItemClass = "panel-combined-item";
|
||||
|
||||
let gModuleName = "[CustomizableWidgets]";
|
||||
#include logging.js
|
||||
@ -32,6 +33,39 @@ function setAttributes(aNode, aAttrs) {
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called whenever an item gets moved in the menu panel. It
|
||||
// adjusts the position of widgets within the panel to reduce single-column
|
||||
// buttons from being placed in a row by themselves.
|
||||
function adjustPosition(aNode) {
|
||||
// TODO(bug 885574): Merge this constant with the one in CustomizeMode.jsm,
|
||||
// maybe just use a pref for this.
|
||||
const kColumnsInMenuPanel = 3;
|
||||
|
||||
// Make sure that there are n % columns = 0 narrow buttons before the widget.
|
||||
let prevSibling = aNode.previousElementSibling;
|
||||
let previousSiblingCount = 0;
|
||||
while (prevSibling) {
|
||||
if (!prevSibling.classList.contains(kWidePanelItemClass)) {
|
||||
previousSiblingCount++;
|
||||
}
|
||||
prevSibling = prevSibling.previousElementSibling;
|
||||
}
|
||||
if (previousSiblingCount % kColumnsInMenuPanel) {
|
||||
let previousElement = aNode.previousElementSibling;
|
||||
if (!previousElement ||
|
||||
previousElement.classList.contains(kWidePanelItemClass)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let position = Array.prototype.indexOf.call(aNode.parentNode.children, aNode);
|
||||
// We don't need to move all of the items in this pass, because
|
||||
// this move will trigger adjustPosition to get called again. The
|
||||
// function will stop recursing when it finds that there is no
|
||||
// more work that is needed.
|
||||
CustomizableUI.moveWidgetWithinArea(aNode.id, position - 1);
|
||||
}
|
||||
}
|
||||
|
||||
const CustomizableWidgets = [{
|
||||
id: "history-panelmenu",
|
||||
type: "view",
|
||||
@ -232,6 +266,7 @@ const CustomizableWidgets = [{
|
||||
if (inPanel)
|
||||
node.setAttribute("flex", "1");
|
||||
node.classList.add("chromeclass-toolbar-additional");
|
||||
node.classList.add(kWidePanelItemClass);
|
||||
|
||||
buttons.forEach(function(aButton) {
|
||||
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
@ -275,6 +310,10 @@ const CustomizableWidgets = [{
|
||||
|
||||
let listener = {
|
||||
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
|
||||
@ -282,6 +321,10 @@ const CustomizableWidgets = [{
|
||||
}.bind(this),
|
||||
|
||||
onWidgetRemoved: function(aWidgetId, aPrevArea) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
|
||||
@ -298,6 +341,10 @@ const CustomizableWidgets = [{
|
||||
}.bind(this),
|
||||
|
||||
onWidgetMoved: function(aWidgetId, aArea) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
|
||||
@ -357,6 +404,7 @@ const CustomizableWidgets = [{
|
||||
if (inPanel)
|
||||
node.setAttribute("flex", "1");
|
||||
node.classList.add("chromeclass-toolbar-additional");
|
||||
node.classList.add(kWidePanelItemClass);
|
||||
|
||||
buttons.forEach(function(aButton) {
|
||||
let btnNode = aDocument.createElementNS(kNSXUL, "toolbarbutton");
|
||||
@ -380,12 +428,20 @@ const CustomizableWidgets = [{
|
||||
|
||||
let listener = {
|
||||
onWidgetAdded: function(aWidgetId, aArea, aPosition) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
|
||||
}.bind(this),
|
||||
|
||||
onWidgetRemoved: function(aWidgetId, aPrevArea) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
// When a widget is demoted to the palette ('removed'), it's visual
|
||||
@ -400,6 +456,10 @@ const CustomizableWidgets = [{
|
||||
}.bind(this),
|
||||
|
||||
onWidgetMoved: function(aWidgetId, aArea) {
|
||||
if (this.currentArea == CustomizableUI.AREA_PANEL) {
|
||||
adjustPosition(node);
|
||||
}
|
||||
|
||||
if (aWidgetId != this.id)
|
||||
return;
|
||||
updateWidgetStyle(aArea == CustomizableUI.AREA_PANEL);
|
||||
|
@ -13,6 +13,9 @@ const kPaletteId = "customization-palette";
|
||||
const kAboutURI = "about:customizing";
|
||||
const kDragDataTypePrefix = "text/toolbarwrapper-id/";
|
||||
const kPlaceholderClass = "panel-customization-placeholder";
|
||||
// TODO(bug 885574): Merge this constant with the one in CustomizableWidgets.jsm,
|
||||
// maybe just use a pref for this.
|
||||
const kColumnsInMenuPanel = 3;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource:///modules/CustomizableUI.jsm");
|
||||
@ -449,6 +452,9 @@ CustomizeMode.prototype = {
|
||||
aWrapper.removeEventListener("mouseup", this);
|
||||
|
||||
let toolbarItem = aWrapper.firstChild;
|
||||
if (!toolbarItem) {
|
||||
ERROR("no toolbarItem child for " + aWrapper.tagName + "#" + aWrapper.id);
|
||||
}
|
||||
|
||||
if (aWrapper.hasAttribute("itemchecked")) {
|
||||
toolbarItem.checked = true;
|
||||
@ -493,23 +499,49 @@ CustomizeMode.prototype = {
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// TODO(bug 885575): Remove once CustomizeUI can handle moving wrapped widgets.
|
||||
_wrapToolbarItemsSync: function() {
|
||||
let window = this.window;
|
||||
// Add drag-and-drop event handlers to all of the customizable areas.
|
||||
this.areas = [];
|
||||
for (let area of CustomizableUI.areas) {
|
||||
let target = CustomizableUI.getCustomizeTargetForArea(area, window);
|
||||
target.addEventListener("dragstart", this, true);
|
||||
target.addEventListener("dragover", this, true);
|
||||
target.addEventListener("dragexit", this, true);
|
||||
target.addEventListener("drop", this, true);
|
||||
target.addEventListener("dragend", this, true);
|
||||
for (let child of target.children) {
|
||||
if (this.isCustomizableItem(child)) {
|
||||
this.wrapToolbarItem(child, getPlaceForItem(child));
|
||||
}
|
||||
}
|
||||
this.areas.push(target);
|
||||
}
|
||||
},
|
||||
|
||||
_unwrapToolbarItems: function() {
|
||||
return Task.spawn(function() {
|
||||
for (let target of this.areas) {
|
||||
for (let toolbarItem of target.children) {
|
||||
if (this.isWrappedToolbarItem(toolbarItem)) {
|
||||
this.unwrapToolbarItem(toolbarItem);
|
||||
}
|
||||
}
|
||||
target.removeEventListener("dragstart", this, true);
|
||||
target.removeEventListener("dragover", this, true);
|
||||
target.removeEventListener("dragexit", this, true);
|
||||
target.removeEventListener("drop", this, true);
|
||||
target.removeEventListener("dragend", this, true);
|
||||
}
|
||||
this._unwrapToolbarItemsSync();
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
// TODO(bug 885575): Merge into _unwrapToolbarItems.
|
||||
_unwrapToolbarItemsSync: function() {
|
||||
for (let target of this.areas) {
|
||||
for (let toolbarItem of target.children) {
|
||||
if (this.isWrappedToolbarItem(toolbarItem)) {
|
||||
this.unwrapToolbarItem(toolbarItem);
|
||||
}
|
||||
}
|
||||
target.removeEventListener("dragstart", this, true);
|
||||
target.removeEventListener("dragover", this, true);
|
||||
target.removeEventListener("dragexit", this, true);
|
||||
target.removeEventListener("drop", this, true);
|
||||
target.removeEventListener("dragend", this, true);
|
||||
}
|
||||
},
|
||||
|
||||
persistCurrentSets: function() {
|
||||
let document = this.document;
|
||||
let toolbars = document.querySelectorAll("toolbar[customizable='true']");
|
||||
@ -719,115 +751,122 @@ CustomizeMode.prototype = {
|
||||
_onDragDrop: function(aEvent) {
|
||||
__dumpDragData(aEvent);
|
||||
|
||||
this._setDragActive(this._dragOverItem, false);
|
||||
this._removePanelCustomizationPlaceholders();
|
||||
|
||||
let targetArea = this._getCustomizableParent(aEvent.currentTarget);
|
||||
let document = aEvent.target.ownerDocument;
|
||||
let documentId = document.documentElement.id;
|
||||
let {id: draggedItemId} =
|
||||
aEvent.dataTransfer.mozGetDataAt(kDragDataTypePrefix + documentId, 0);
|
||||
let draggedWrapper = document.getElementById("wrapper-" + draggedItemId);
|
||||
|
||||
draggedWrapper.hidden = false;
|
||||
draggedWrapper.removeAttribute("mousedown");
|
||||
|
||||
let targetArea = this._getCustomizableParent(aEvent.currentTarget);
|
||||
let originArea = this._getCustomizableParent(draggedWrapper);
|
||||
|
||||
// Do nothing if the target area or origin area are not customizable.
|
||||
if (!targetArea || !originArea) {
|
||||
return;
|
||||
}
|
||||
|
||||
let targetNode = this._getDragOverNode(aEvent.target, targetArea);
|
||||
if (targetNode.tagName == "toolbarpaletteitem") {
|
||||
targetNode = targetNode.firstChild;
|
||||
}
|
||||
|
||||
this._setDragActive(this._dragOverItem, false);
|
||||
this._removePanelCustomizationPlaceholders();
|
||||
|
||||
// TODO(bug 885575): Remove once CustomizeUI can handle moving wrapped widgets.
|
||||
this._unwrapToolbarItemsSync();
|
||||
let paletteChild = this.visiblePalette.firstChild;
|
||||
let nextChild;
|
||||
while (paletteChild) {
|
||||
nextChild = paletteChild.nextElementSibling;
|
||||
this.unwrapToolbarItem(paletteChild);
|
||||
paletteChild = nextChild;
|
||||
}
|
||||
|
||||
try {
|
||||
this._applyDrop(aEvent, targetArea, originArea, draggedItemId, targetNode);
|
||||
} catch (ex) {
|
||||
ERROR(ex, ex.stack);
|
||||
}
|
||||
|
||||
// TODO(bug 885575): Remove once CustomizeUI can handle moving wrapped widgets.
|
||||
this._wrapToolbarItemsSync();
|
||||
// Re-wrap palette items.
|
||||
let paletteChild = this.visiblePalette.firstChild;
|
||||
let nextChild;
|
||||
while (paletteChild) {
|
||||
nextChild = paletteChild.nextElementSibling;
|
||||
this.wrapToolbarItem(paletteChild, "palette");
|
||||
paletteChild = nextChild;
|
||||
}
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
},
|
||||
|
||||
_applyDrop: function(aEvent, aTargetArea, aOriginArea, aDraggedItemId, aTargetNode) {
|
||||
let document = aEvent.target.ownerDocument;
|
||||
let draggedItem = document.getElementById(aDraggedItemId);
|
||||
draggedItem.hidden = false;
|
||||
draggedItem.removeAttribute("mousedown");
|
||||
|
||||
// Do nothing if the target was dropped onto itself (ie, no change in area
|
||||
// or position).
|
||||
if (draggedWrapper == targetNode) {
|
||||
if (draggedItem == aTargetNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the target area the customization palette? If so, we have two cases -
|
||||
// either the originArea was the palette, or a customizable area.
|
||||
if (targetArea.id == kPaletteId) {
|
||||
if (originArea.id !== kPaletteId) {
|
||||
if (!CustomizableUI.isWidgetRemovable(draggedItemId)) {
|
||||
// either the origin area was the palette, or a customizable area.
|
||||
if (aTargetArea.id == kPaletteId) {
|
||||
if (aOriginArea.id !== kPaletteId) {
|
||||
if (!CustomizableUI.isWidgetRemovable(aDraggedItemId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let widget = this.unwrapToolbarItem(draggedWrapper);
|
||||
CustomizableUI.removeWidgetFromArea(draggedItemId);
|
||||
draggedWrapper = this.wrapToolbarItem(widget, "palette");
|
||||
CustomizableUI.removeWidgetFromArea(aDraggedItemId);
|
||||
}
|
||||
|
||||
// If the targetNode is the palette itself, just append
|
||||
if (targetNode == this.visiblePalette) {
|
||||
this.visiblePalette.appendChild(draggedWrapper);
|
||||
// If the target node is the palette itself, just append
|
||||
if (aTargetNode == this.visiblePalette) {
|
||||
this.visiblePalette.appendChild(draggedItem);
|
||||
} else {
|
||||
this.visiblePalette.insertBefore(draggedWrapper, targetNode);
|
||||
this.visiblePalette.insertBefore(draggedItem, aTargetNode);
|
||||
}
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CustomizableUI.canWidgetMoveToArea(draggedItemId, targetArea.id)) {
|
||||
if (!CustomizableUI.canWidgetMoveToArea(aDraggedItemId, aTargetArea.id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Is the target the customization area itself? If so, we just add the
|
||||
// widget to the end of the area.
|
||||
if (targetNode == targetArea.customizationTarget) {
|
||||
let widget = this.unwrapToolbarItem(draggedWrapper);
|
||||
CustomizableUI.addWidgetToArea(draggedItemId, targetArea.id);
|
||||
this.wrapToolbarItem(widget, getPlaceForItem(targetNode));
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
if (aTargetNode == aTargetArea.customizationTarget) {
|
||||
CustomizableUI.addWidgetToArea(aDraggedItemId, aTargetArea.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to determine the place that the widget is being dropped in
|
||||
// the target.
|
||||
let placement;
|
||||
if (!targetNode.classList.contains(kPlaceholderClass)) {
|
||||
let targetNodeId = (targetNode.nodeName == "toolbarpaletteitem") ?
|
||||
targetNode.firstChild && targetNode.firstChild.id :
|
||||
targetNode.id;
|
||||
if (!aTargetNode.classList.contains(kPlaceholderClass)) {
|
||||
let targetNodeId = (aTargetNode.nodeName == "toolbarpaletteitem") ?
|
||||
aTargetNode.firstChild && aTargetNode.firstChild.id :
|
||||
aTargetNode.id;
|
||||
placement = CustomizableUI.getPlacementOfWidget(targetNodeId);
|
||||
}
|
||||
if (!placement) {
|
||||
LOG("Could not get a position for " + targetNode + "#" + targetNode.id + "." + targetNode.className);
|
||||
LOG("Could not get a position for " + aTargetNode + "#" + aTargetNode.id + "." + aTargetNode.className);
|
||||
}
|
||||
let position = placement ? placement.position :
|
||||
targetArea.childElementCount;
|
||||
aTargetArea.childElementCount;
|
||||
|
||||
|
||||
// Is the target area the same as the origin? Since we've already handled
|
||||
// the possibility that the target is the customization palette, we know
|
||||
// that the widget is moving within a customizable area.
|
||||
if (targetArea == originArea) {
|
||||
let properPlace = getPlaceForItem(targetNode);
|
||||
// We unwrap the moving widget, as well as the widget that we're dropping
|
||||
// on (the target) so that moveWidgetWithinArea can correctly insert the
|
||||
// moving widget before the target widget.
|
||||
let widget = this.unwrapToolbarItem(draggedWrapper);
|
||||
let targetWidget = this.unwrapToolbarItem(targetNode);
|
||||
CustomizableUI.moveWidgetWithinArea(draggedItemId, position);
|
||||
this.wrapToolbarItem(targetWidget, properPlace);
|
||||
this.wrapToolbarItem(widget, properPlace);
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
if (aTargetArea == aOriginArea) {
|
||||
CustomizableUI.moveWidgetWithinArea(aDraggedItemId, position);
|
||||
return;
|
||||
}
|
||||
|
||||
// A little hackery - we quickly unwrap the item and use CustomizableUI's
|
||||
// addWidgetToArea to move the widget to the right place for every window,
|
||||
// then we re-wrap the widget. We have to unwrap the target widget too so
|
||||
// that addWidgetToArea inserts the new widget into the right place.
|
||||
let properPlace = getPlaceForItem(targetNode);
|
||||
let widget = this.unwrapToolbarItem(draggedWrapper);
|
||||
let targetWidget = this.unwrapToolbarItem(targetNode);
|
||||
CustomizableUI.addWidgetToArea(draggedItemId, targetArea.id, position);
|
||||
this.wrapToolbarItem(targetWidget, properPlace);
|
||||
draggedWrapper = this.wrapToolbarItem(widget, properPlace);
|
||||
this._showPanelCustomizationPlaceholders();
|
||||
CustomizableUI.addWidgetToArea(aDraggedItemId, aTargetArea.id, position);
|
||||
},
|
||||
|
||||
_onDragExit: function(aEvent) {
|
||||
@ -975,13 +1014,15 @@ CustomizeMode.prototype = {
|
||||
},
|
||||
|
||||
_showPanelCustomizationPlaceholders: function() {
|
||||
const kColumns = 3;
|
||||
this._removePanelCustomizationPlaceholders();
|
||||
let doc = this.document;
|
||||
let contents = this.panelUIContents;
|
||||
let visibleCombinedButtons = contents.querySelectorAll("toolbarpaletteitem:not([hidden]) > .panel-combined-item");
|
||||
let visibleChildren = contents.querySelectorAll("toolbarpaletteitem:not([hidden])");
|
||||
let hangingItems = visibleChildren.length % kColumns;
|
||||
let newPlaceholders = kColumns - hangingItems;
|
||||
// TODO(bug 885578): Still doesn't handle a hole when there is a wide
|
||||
// widget located at the bottom of the panel.
|
||||
let hangingItems = (visibleChildren.length - visibleCombinedButtons.length) % kColumnsInMenuPanel;
|
||||
let newPlaceholders = kColumnsInMenuPanel - hangingItems;
|
||||
while (newPlaceholders--) {
|
||||
let placeholder = doc.createElement("toolbarpaletteitem");
|
||||
placeholder.classList.add(kPlaceholderClass);
|
||||
|
@ -15,6 +15,7 @@ MOCHITEST_BROWSER_FILES = \
|
||||
browser_877178_unregisterArea.js \
|
||||
browser_877447_skip_missing_ids.js \
|
||||
browser_878452_drag_to_panel.js \
|
||||
browser_880382_drag_wide_widgets_in_panel.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -0,0 +1,413 @@
|
||||
/* 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: "Dragging the zoom controls to be before the print button " +
|
||||
"should not move any controls.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let printButton = document.getElementById("print-button");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"zoom-controls",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(zoomControls, printButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the zoom controls to be before the save button " +
|
||||
"should not move any controls.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let savePageButton = document.getElementById("save-page-button");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(zoomControls, savePageButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the zoom controls to be before the new-window " +
|
||||
"button should not move any widgets.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the zoom controls to be before the history-panelmenu " +
|
||||
"should move the zoom-controls in to the row higher than the " +
|
||||
"history-panelmenu.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let historyPanelMenu = document.getElementById("history-panelmenu");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"zoom-controls",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(zoomControls, historyPanelMenu);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the zoom controls to be before the preferences-button " +
|
||||
"should move the zoom-controls in to the row higher than the " +
|
||||
"preferences-button.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let preferencesButton = document.getElementById("preferences-button");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"zoom-controls",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(zoomControls, preferencesButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging an item from the palette to before the zoom-controls " +
|
||||
"should move it and two other buttons before the zoom controls.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let developerButton = document.getElementById("developer-button");
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let expectedPlacementsAfterInsert = ["edit-controls",
|
||||
"developer-button",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"zoom-controls",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(developerButton, zoomControls);
|
||||
// Currently, the developer-button is placed after the zoom-controls, but it should be
|
||||
// placed like expectedPlacementsAfterInsert describes.
|
||||
todoAssertAreaPlacements(CustomizableUI.AREA_PANEL, expectedPlacementsAfterInsert);
|
||||
let actualPlacementsAfterInsert = ["edit-controls",
|
||||
"zoom-controls",
|
||||
"developer-button",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, actualPlacementsAfterInsert);
|
||||
ok(!CustomizableUI.inDefaultState, "Should no longer be in default state.");
|
||||
let palette = document.getElementById("customization-palette");
|
||||
// Check that the palette items are re-wrapped correctly.
|
||||
let feedWrapper = document.getElementById("wrapper-feed-button");
|
||||
let feedButton = document.getElementById("feed-button");
|
||||
is(feedButton.parentNode, feedWrapper,
|
||||
"feed-button should be a child of wrapper-feed-button");
|
||||
is(feedWrapper.getAttribute("place"), "palette",
|
||||
"The feed-button wrapper should have it's place set to 'palette'");
|
||||
simulateItemDrag(developerButton, palette);
|
||||
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
|
||||
"The developer-button should be wrapped by a toolbarpaletteitem");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
simulateItemDrag(zoomControls, newWindowButton);
|
||||
ok(CustomizableUI.inDefaultState, "Should be in default state again.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to be before the zoom-controls button " +
|
||||
"should not move any widgets.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
let placementsAfterMove = ["edit-controls",
|
||||
"zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to be before the new-window-button should " +
|
||||
"move the zoom-controls before the edit-controls.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let newWindowButton = document.getElementById("new-window-button");
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(editControls, newWindowButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to be before the privatebrowsing-button " +
|
||||
"should move the edit-controls in to the row higher than the " +
|
||||
"privatebrowsing-button.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let privateBrowsingButton = document.getElementById("privatebrowsing-button");
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(editControls, privateBrowsingButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to be before the save-page-button " +
|
||||
"should move the edit-controls in to the row higher than the " +
|
||||
"save-page-button.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let savePageButton = document.getElementById("save-page-button");
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"edit-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
simulateItemDrag(editControls, savePageButton);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to the panel itself should append " +
|
||||
"the edit controls to the bottom of the panel.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"edit-controls"];
|
||||
simulateItemDrag(editControls, panel);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to the customization-palette and " +
|
||||
"back should work.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let palette = document.getElementById("customization-palette");
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button"];
|
||||
let paletteChildElementCount = palette.childElementCount;
|
||||
simulateItemDrag(editControls, palette);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
is(paletteChildElementCount + 1, palette.childElementCount,
|
||||
"The palette should have a new child, congratulations!");
|
||||
is(editControls.parentNode.id, "wrapper-edit-controls",
|
||||
"The edit-controls should be properly wrapped.");
|
||||
is(editControls.parentNode.getAttribute("place"), "palette",
|
||||
"The edit-controls should have the place of 'palette'.");
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
is(paletteChildElementCount, palette.childElementCount,
|
||||
"The palette child count should have returned to its prior value.");
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the edit-controls to each of the panel placeholders " +
|
||||
"should append the edit-controls to the bottom of the panel.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
let panel = document.getElementById(CustomizableUI.AREA_PANEL);
|
||||
for (let i = 0; i < 3; i++) {
|
||||
// NB: We can't just iterate over all of the placeholders
|
||||
// because each drag-drop action recreates them.
|
||||
let placeholder = panel.getElementsByClassName("panel-customization-placeholder")[i];
|
||||
let placementsAfterMove = ["zoom-controls",
|
||||
"new-window-button",
|
||||
"privatebrowsing-button",
|
||||
"save-page-button",
|
||||
"print-button",
|
||||
"history-panelmenu",
|
||||
"fullscreen-button",
|
||||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"edit-controls"];
|
||||
simulateItemDrag(editControls, placeholder);
|
||||
assertAreaPlacements(CustomizableUI.AREA_PANEL, placementsAfterMove);
|
||||
let zoomControls = document.getElementById("zoom-controls");
|
||||
simulateItemDrag(editControls, zoomControls);
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
}
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
{
|
||||
desc: "Dragging the developer-button back on to itself should work.",
|
||||
setup: startCustomizing,
|
||||
run: function() {
|
||||
let developerButton = document.getElementById("developer-button");
|
||||
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
|
||||
"developer-button should be wrapped by a toolbarpaletteitem");
|
||||
simulateItemDrag(developerButton, developerButton);
|
||||
is(developerButton.parentNode.tagName, "toolbarpaletteitem",
|
||||
"developer-button should be wrapped by a toolbarpaletteitem");
|
||||
let editControls = document.getElementById("edit-controls");
|
||||
is(editControls.parentNode.tagName, "toolbarpaletteitem",
|
||||
"edit-controls should be wrapped by a toolbarpaletteitem");
|
||||
ok(CustomizableUI.inDefaultState, "Should still be in default state.");
|
||||
},
|
||||
teardown: endCustomizing
|
||||
},
|
||||
];
|
||||
|
||||
function asyncCleanup() {
|
||||
yield resetCustomization();
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
runTests(gTests, asyncCleanup);
|
||||
}
|
||||
|
@ -70,6 +70,24 @@ function assertAreaPlacements(areaId, expectedPlacements) {
|
||||
}
|
||||
}
|
||||
|
||||
function todoAssertAreaPlacements(areaId, expectedPlacements) {
|
||||
let actualPlacements = getAreaWidgetIds(areaId);
|
||||
let isPassing = actualPlacements.length == expectedPlacements.length;
|
||||
let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
|
||||
for (let i = 0; i < minItems; i++) {
|
||||
if (typeof expectedPlacements[i] == "string") {
|
||||
isPassing = isPassing && actualPlacements[i] == expectedPlacements[i];
|
||||
} else if (expectedPlacements[i] instanceof RegExp) {
|
||||
isPassing = isPassing && expectedPlacements[i].test(actualPlacements[i]);
|
||||
} else {
|
||||
ok(false, "Unknown type of expected placement passed to " +
|
||||
" assertAreaPlacements. Is your test broken?");
|
||||
}
|
||||
}
|
||||
todo(isPassing, "The area placements for " + areaId +
|
||||
" should equal the expected placements.")
|
||||
}
|
||||
|
||||
function getAreaWidgetIds(areaId) {
|
||||
let widgetAry = CustomizableUI.getWidgetsInArea(areaId);
|
||||
return widgetAry.map(x => x.id);
|
||||
@ -146,7 +164,9 @@ function testRunner(testAry, asyncCleanup) {
|
||||
|
||||
function runTests(testAry, asyncCleanup) {
|
||||
Task.spawn(testRunner(gTests, asyncCleanup)).then(finish, ex => {
|
||||
ok(false, "Unexpected exception: " + ex);
|
||||
// The stack of ok() here is misleading due to Promises. The stack of the
|
||||
// actual exception is likely much more valuable, hence concatentating it.
|
||||
ok(false, "Unexpected exception: " + ex + " With stack: " + ex.stack);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user