1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,171 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +"use strict"; 1.9 + 1.10 +const kXULWidgetId = "sync-button"; 1.11 +const kAPIWidgetId = "feed-button"; 1.12 +const kPanel = CustomizableUI.AREA_PANEL; 1.13 +const kToolbar = CustomizableUI.AREA_NAVBAR; 1.14 +const kVisiblePalette = "customization-palette"; 1.15 +const kPlaceholderClass = "panel-customization-placeholder"; 1.16 + 1.17 +function checkWrapper(id) { 1.18 + is(document.querySelectorAll("#wrapper-" + id).length, 1, "There should be exactly 1 wrapper for " + id + " in the customizing window."); 1.19 +} 1.20 + 1.21 +let move = { 1.22 + "drag": function(id, target) { 1.23 + let targetNode = document.getElementById(target); 1.24 + if (targetNode.customizationTarget) { 1.25 + targetNode = targetNode.customizationTarget; 1.26 + } 1.27 + simulateItemDrag(document.getElementById(id), targetNode); 1.28 + }, 1.29 + "dragToItem": function(id, target) { 1.30 + let targetNode = document.getElementById(target); 1.31 + if (targetNode.customizationTarget) { 1.32 + targetNode = targetNode.customizationTarget; 1.33 + } 1.34 + let items = targetNode.querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")"); 1.35 + if (target == kPanel) { 1.36 + targetNode = items[items.length - 1]; 1.37 + } else { 1.38 + targetNode = items[0]; 1.39 + } 1.40 + simulateItemDrag(document.getElementById(id), targetNode); 1.41 + }, 1.42 + "API": function(id, target) { 1.43 + if (target == kVisiblePalette) { 1.44 + return CustomizableUI.removeWidgetFromArea(id); 1.45 + } 1.46 + return CustomizableUI.addWidgetToArea(id, target, null); 1.47 + } 1.48 +}; 1.49 + 1.50 +function isLast(containerId, defaultPlacements, id) { 1.51 + assertAreaPlacements(containerId, defaultPlacements.concat([id])); 1.52 + is(document.getElementById(containerId).customizationTarget.lastChild.firstChild.id, id, 1.53 + "Widget " + id + " should be in " + containerId + " in customizing window."); 1.54 + is(otherWin.document.getElementById(containerId).customizationTarget.lastChild.id, id, 1.55 + "Widget " + id + " should be in " + containerId + " in other window."); 1.56 +} 1.57 + 1.58 +function getLastVisibleNodeInToolbar(containerId, win=window) { 1.59 + let container = win.document.getElementById(containerId).customizationTarget; 1.60 + let rv = container.lastChild; 1.61 + while (rv && (rv.getAttribute('hidden') == 'true' || (rv.firstChild && rv.firstChild.getAttribute('hidden') == 'true'))) { 1.62 + rv = rv.previousSibling; 1.63 + } 1.64 + return rv; 1.65 +} 1.66 + 1.67 +function isLastVisibleInToolbar(containerId, defaultPlacements, id) { 1.68 + let newPlacements; 1.69 + for (let i = defaultPlacements.length - 1; i >= 0; i--) { 1.70 + let el = document.getElementById(defaultPlacements[i]); 1.71 + if (el && el.getAttribute('hidden') != 'true') { 1.72 + newPlacements = [...defaultPlacements]; 1.73 + newPlacements.splice(i + 1, 0, id); 1.74 + break; 1.75 + } 1.76 + } 1.77 + if (!newPlacements) { 1.78 + assertAreaPlacements(containerId, defaultPlacements.concat([id])); 1.79 + } else { 1.80 + assertAreaPlacements(containerId, newPlacements); 1.81 + } 1.82 + is(getLastVisibleNodeInToolbar(containerId).firstChild.id, id, 1.83 + "Widget " + id + " should be in " + containerId + " in customizing window."); 1.84 + is(getLastVisibleNodeInToolbar(containerId, otherWin).id, id, 1.85 + "Widget " + id + " should be in " + containerId + " in other window."); 1.86 +} 1.87 + 1.88 +function isFirst(containerId, defaultPlacements, id) { 1.89 + assertAreaPlacements(containerId, [id].concat(defaultPlacements)); 1.90 + is(document.getElementById(containerId).customizationTarget.firstChild.firstChild.id, id, 1.91 + "Widget " + id + " should be in " + containerId + " in customizing window."); 1.92 + is(otherWin.document.getElementById(containerId).customizationTarget.firstChild.id, id, 1.93 + "Widget " + id + " should be in " + containerId + " in other window."); 1.94 +} 1.95 + 1.96 +function checkToolbar(id, method) { 1.97 + // Place at start of the toolbar: 1.98 + let toolbarPlacements = getAreaWidgetIds(kToolbar); 1.99 + move[method](id, kToolbar); 1.100 + if (method == "dragToItem") { 1.101 + isFirst(kToolbar, toolbarPlacements, id); 1.102 + } else if (method == "drag") { 1.103 + isLastVisibleInToolbar(kToolbar, toolbarPlacements, id); 1.104 + } else { 1.105 + isLast(kToolbar, toolbarPlacements, id); 1.106 + } 1.107 + checkWrapper(id); 1.108 +} 1.109 + 1.110 +function checkPanel(id, method) { 1.111 + let panelPlacements = getAreaWidgetIds(kPanel); 1.112 + move[method](id, kPanel); 1.113 + let children = document.getElementById(kPanel).querySelectorAll("toolbarpaletteitem:not(." + kPlaceholderClass + ")"); 1.114 + let otherChildren = otherWin.document.getElementById(kPanel).children; 1.115 + let newPlacements = panelPlacements.concat([id]); 1.116 + // Relative position of the new item from the end: 1.117 + let position = -1; 1.118 + // For the drag to item case, we drag to the last item, making the dragged item the 1.119 + // penultimate item. We can't well use the first item because the panel has complicated 1.120 + // rules about rearranging wide items (which, by default, the first two items are). 1.121 + if (method == "dragToItem") { 1.122 + newPlacements.pop(); 1.123 + newPlacements.splice(panelPlacements.length - 1, 0, id); 1.124 + position = -2; 1.125 + } 1.126 + assertAreaPlacements(kPanel, newPlacements); 1.127 + is(children[children.length + position].firstChild.id, id, 1.128 + "Widget " + id + " should be in " + kPanel + " in customizing window."); 1.129 + is(otherChildren[otherChildren.length + position].id, id, 1.130 + "Widget " + id + " should be in " + kPanel + " in other window."); 1.131 + checkWrapper(id); 1.132 +} 1.133 + 1.134 +function checkPalette(id, method) { 1.135 + // Move back to palette: 1.136 + move[method](id, kVisiblePalette); 1.137 + ok(CustomizableUI.inDefaultState, "Should end in default state"); 1.138 + let visibleChildren = gCustomizeMode.visiblePalette.children; 1.139 + let expectedChild = method == "dragToItem" ? visibleChildren[0] : visibleChildren[visibleChildren.length - 1]; 1.140 + is(expectedChild.firstChild.id, id, "Widget " + id + " was moved using " + method + " and should now be wrapped in palette in customizing window."); 1.141 + if (id == kXULWidgetId) { 1.142 + ok(otherWin.gNavToolbox.palette.querySelector("#" + id), "Widget " + id + " should be in invisible palette in other window."); 1.143 + } 1.144 + checkWrapper(id); 1.145 +} 1.146 + 1.147 +let otherWin; 1.148 + 1.149 +// Moving widgets in two windows, one with customize mode and one without, should work. 1.150 +add_task(function MoveWidgetsInTwoWindows() { 1.151 + yield startCustomizing(); 1.152 + otherWin = yield openAndLoadWindow(null, true); 1.153 + yield otherWin.PanelUI.ensureReady(); 1.154 + ok(CustomizableUI.inDefaultState, "Should start in default state"); 1.155 + 1.156 + for (let widgetId of [kXULWidgetId, kAPIWidgetId]) { 1.157 + for (let method of ["API", "drag", "dragToItem"]) { 1.158 + info("Moving widget " + widgetId + " using " + method); 1.159 + checkToolbar(widgetId, method); 1.160 + checkPanel(widgetId, method); 1.161 + checkPalette(widgetId, method); 1.162 + checkPanel(widgetId, method); 1.163 + checkToolbar(widgetId, method); 1.164 + checkPalette(widgetId, method); 1.165 + } 1.166 + } 1.167 + yield promiseWindowClosed(otherWin); 1.168 + otherWin = null; 1.169 + yield endCustomizing(); 1.170 +}); 1.171 + 1.172 +add_task(function asyncCleanup() { 1.173 + yield resetCustomization(); 1.174 +});