Wed, 31 Dec 2014 13:27:57 +0100
Ignore runtime configuration files generated during quality assurance.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 "use strict";
7 const kXULWidgetId = "sync-button";
8 const kAPIWidgetId = "feed-button";
9 const kPanel = CustomizableUI.AREA_PANEL;
10 const kToolbar = CustomizableUI.AREA_NAVBAR;
11 const kVisiblePalette = "customization-palette";
12 const kPlaceholderClass = "panel-customization-placeholder";
14 function checkWrapper(id) {
15 is(document.querySelectorAll("#wrapper-" + id).length, 1, "There should be exactly 1 wrapper for " + id + " in the customizing window.");
16 }
18 let move = {
19 "drag": function(id, target) {
20 let targetNode = document.getElementById(target);
21 if (targetNode.customizationTarget) {
22 targetNode = targetNode.customizationTarget;
23 }
24 simulateItemDrag(document.getElementById(id), targetNode);
25 },
26 "dragToItem": function(id, target) {
27 let targetNode = document.getElementById(target);
28 if (targetNode.customizationTarget) {
29 targetNode = targetNode.customizationTarget;
30 }
31 let items = targetNode.querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")");
32 if (target == kPanel) {
33 targetNode = items[items.length - 1];
34 } else {
35 targetNode = items[0];
36 }
37 simulateItemDrag(document.getElementById(id), targetNode);
38 },
39 "API": function(id, target) {
40 if (target == kVisiblePalette) {
41 return CustomizableUI.removeWidgetFromArea(id);
42 }
43 return CustomizableUI.addWidgetToArea(id, target, null);
44 }
45 };
47 function isLast(containerId, defaultPlacements, id) {
48 assertAreaPlacements(containerId, defaultPlacements.concat([id]));
49 is(document.getElementById(containerId).customizationTarget.lastChild.firstChild.id, id,
50 "Widget " + id + " should be in " + containerId + " in customizing window.");
51 is(otherWin.document.getElementById(containerId).customizationTarget.lastChild.id, id,
52 "Widget " + id + " should be in " + containerId + " in other window.");
53 }
55 function getLastVisibleNodeInToolbar(containerId, win=window) {
56 let container = win.document.getElementById(containerId).customizationTarget;
57 let rv = container.lastChild;
58 while (rv && (rv.getAttribute('hidden') == 'true' || (rv.firstChild && rv.firstChild.getAttribute('hidden') == 'true'))) {
59 rv = rv.previousSibling;
60 }
61 return rv;
62 }
64 function isLastVisibleInToolbar(containerId, defaultPlacements, id) {
65 let newPlacements;
66 for (let i = defaultPlacements.length - 1; i >= 0; i--) {
67 let el = document.getElementById(defaultPlacements[i]);
68 if (el && el.getAttribute('hidden') != 'true') {
69 newPlacements = [...defaultPlacements];
70 newPlacements.splice(i + 1, 0, id);
71 break;
72 }
73 }
74 if (!newPlacements) {
75 assertAreaPlacements(containerId, defaultPlacements.concat([id]));
76 } else {
77 assertAreaPlacements(containerId, newPlacements);
78 }
79 is(getLastVisibleNodeInToolbar(containerId).firstChild.id, id,
80 "Widget " + id + " should be in " + containerId + " in customizing window.");
81 is(getLastVisibleNodeInToolbar(containerId, otherWin).id, id,
82 "Widget " + id + " should be in " + containerId + " in other window.");
83 }
85 function isFirst(containerId, defaultPlacements, id) {
86 assertAreaPlacements(containerId, [id].concat(defaultPlacements));
87 is(document.getElementById(containerId).customizationTarget.firstChild.firstChild.id, id,
88 "Widget " + id + " should be in " + containerId + " in customizing window.");
89 is(otherWin.document.getElementById(containerId).customizationTarget.firstChild.id, id,
90 "Widget " + id + " should be in " + containerId + " in other window.");
91 }
93 function checkToolbar(id, method) {
94 // Place at start of the toolbar:
95 let toolbarPlacements = getAreaWidgetIds(kToolbar);
96 move[method](id, kToolbar);
97 if (method == "dragToItem") {
98 isFirst(kToolbar, toolbarPlacements, id);
99 } else if (method == "drag") {
100 isLastVisibleInToolbar(kToolbar, toolbarPlacements, id);
101 } else {
102 isLast(kToolbar, toolbarPlacements, id);
103 }
104 checkWrapper(id);
105 }
107 function checkPanel(id, method) {
108 let panelPlacements = getAreaWidgetIds(kPanel);
109 move[method](id, kPanel);
110 let children = document.getElementById(kPanel).querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")");
111 let otherChildren = otherWin.document.getElementById(kPanel).children;
112 let newPlacements = panelPlacements.concat([id]);
113 // Relative position of the new item from the end:
114 let position = -1;
115 // For the drag to item case, we drag to the last item, making the dragged item the
116 // penultimate item. We can't well use the first item because the panel has complicated
117 // rules about rearranging wide items (which, by default, the first two items are).
118 if (method == "dragToItem") {
119 newPlacements.pop();
120 newPlacements.splice(panelPlacements.length - 1, 0, id);
121 position = -2;
122 }
123 assertAreaPlacements(kPanel, newPlacements);
124 is(children[children.length + position].firstChild.id, id,
125 "Widget " + id + " should be in " + kPanel + " in customizing window.");
126 is(otherChildren[otherChildren.length + position].id, id,
127 "Widget " + id + " should be in " + kPanel + " in other window.");
128 checkWrapper(id);
129 }
131 function checkPalette(id, method) {
132 // Move back to palette:
133 move[method](id, kVisiblePalette);
134 ok(CustomizableUI.inDefaultState, "Should end in default state");
135 let visibleChildren = gCustomizeMode.visiblePalette.children;
136 let expectedChild = method == "dragToItem" ? visibleChildren[0] : visibleChildren[visibleChildren.length - 1];
137 is(expectedChild.firstChild.id, id, "Widget " + id + " was moved using " + method + " and should now be wrapped in palette in customizing window.");
138 if (id == kXULWidgetId) {
139 ok(otherWin.gNavToolbox.palette.querySelector("#" + id), "Widget " + id + " should be in invisible palette in other window.");
140 }
141 checkWrapper(id);
142 }
144 let otherWin;
146 // Moving widgets in two windows, one with customize mode and one without, should work.
147 add_task(function MoveWidgetsInTwoWindows() {
148 yield startCustomizing();
149 otherWin = yield openAndLoadWindow(null, true);
150 yield otherWin.PanelUI.ensureReady();
151 ok(CustomizableUI.inDefaultState, "Should start in default state");
153 for (let widgetId of [kXULWidgetId, kAPIWidgetId]) {
154 for (let method of ["API", "drag", "dragToItem"]) {
155 info("Moving widget " + widgetId + " using " + method);
156 checkToolbar(widgetId, method);
157 checkPanel(widgetId, method);
158 checkPalette(widgetId, method);
159 checkPanel(widgetId, method);
160 checkToolbar(widgetId, method);
161 checkPalette(widgetId, method);
162 }
163 }
164 yield promiseWindowClosed(otherWin);
165 otherWin = null;
166 yield endCustomizing();
167 });
169 add_task(function asyncCleanup() {
170 yield resetCustomization();
171 });