From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test/browser_876926_customize_mode_wrapping.js | 295 +++++++++++++++++++++ 1 file changed, 295 insertions(+) create mode 100644 browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js (limited to 'browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js') diff --git a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js new file mode 100644 index 0000000000..cf73326e53 --- /dev/null +++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js @@ -0,0 +1,295 @@ +/* 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/. */ + +"use strict"; + +const kXULWidgetId = "a-test-button"; // we'll create a button with this ID. +const kAPIWidgetId = "save-page-button"; +const kPanel = CustomizableUI.AREA_FIXED_OVERFLOW_PANEL; +const kToolbar = CustomizableUI.AREA_NAVBAR; +const kVisiblePalette = "customization-palette"; + +function checkWrapper(id) { + is( + document.querySelectorAll("#wrapper-" + id).length, + 1, + "There should be exactly 1 wrapper for " + + id + + " in the customizing window." + ); +} + +async function ensureVisible(node) { + let isInPalette = node.parentNode.parentNode == gNavToolbox.palette; + if (isInPalette) { + node.scrollIntoView(); + } + let dwu = window.windowUtils; + await BrowserTestUtils.waitForCondition(() => { + let nodeBounds = dwu.getBoundsWithoutFlushing(node); + if (isInPalette) { + let paletteBounds = dwu.getBoundsWithoutFlushing(gNavToolbox.palette); + if ( + !( + nodeBounds.top >= paletteBounds.top && + nodeBounds.bottom <= paletteBounds.bottom + ) + ) { + return false; + } + } + return nodeBounds.height && nodeBounds.width; + }); +} + +var move = { + async drag(id, target) { + let targetNode = document.getElementById(target); + if (CustomizableUI.getCustomizationTarget(targetNode)) { + targetNode = CustomizableUI.getCustomizationTarget(targetNode); + } + let nodeToMove = document.getElementById(id); + await ensureVisible(nodeToMove); + + simulateItemDrag(nodeToMove, targetNode, "end"); + }, + async dragToItem(id, target) { + let targetNode = document.getElementById(target); + if (CustomizableUI.getCustomizationTarget(targetNode)) { + targetNode = CustomizableUI.getCustomizationTarget(targetNode); + } + let items = targetNode.querySelectorAll("toolbarpaletteitem"); + if (target == kPanel) { + targetNode = items[items.length - 1]; + } else { + targetNode = items[0]; + } + let nodeToMove = document.getElementById(id); + await ensureVisible(nodeToMove); + simulateItemDrag(nodeToMove, targetNode, "start"); + }, + API(id, target) { + if (target == kVisiblePalette) { + return CustomizableUI.removeWidgetFromArea(id); + } + return CustomizableUI.addWidgetToArea(id, target, null); + }, +}; + +function isLast(containerId, defaultPlacements, id) { + assertAreaPlacements(containerId, defaultPlacements.concat([id])); + let thisTarget = CustomizableUI.getCustomizationTarget( + document.getElementById(containerId) + ); + is( + thisTarget.lastElementChild.firstElementChild.id, + id, + "Widget " + id + " should be in " + containerId + " in customizing window." + ); + let otherTarget = CustomizableUI.getCustomizationTarget( + otherWin.document.getElementById(containerId) + ); + is( + otherTarget.lastElementChild.id, + id, + "Widget " + id + " should be in " + containerId + " in other window." + ); +} + +function getLastVisibleNodeInToolbar(containerId, win = window) { + let container = CustomizableUI.getCustomizationTarget( + win.document.getElementById(containerId) + ); + let rv = container.lastElementChild; + while (rv?.hidden || rv?.firstElementChild?.hidden) { + rv = rv.previousElementSibling; + } + return rv; +} + +function isLastVisibleInToolbar(containerId, defaultPlacements, id) { + let newPlacements; + for (let i = defaultPlacements.length - 1; i >= 0; i--) { + let el = document.getElementById(defaultPlacements[i]); + if (el && !el.hidden) { + newPlacements = [...defaultPlacements]; + newPlacements.splice(i + 1, 0, id); + break; + } + } + if (!newPlacements) { + assertAreaPlacements(containerId, defaultPlacements.concat([id])); + } else { + assertAreaPlacements(containerId, newPlacements); + } + is( + getLastVisibleNodeInToolbar(containerId).firstElementChild.id, + id, + "Widget " + id + " should be in " + containerId + " in customizing window." + ); + is( + getLastVisibleNodeInToolbar(containerId, otherWin).id, + id, + "Widget " + id + " should be in " + containerId + " in other window." + ); +} + +function isFirst(containerId, defaultPlacements, id) { + assertAreaPlacements(containerId, [id].concat(defaultPlacements)); + let thisTarget = CustomizableUI.getCustomizationTarget( + document.getElementById(containerId) + ); + is( + thisTarget.firstElementChild.firstElementChild.id, + id, + "Widget " + id + " should be in " + containerId + " in customizing window." + ); + let otherTarget = CustomizableUI.getCustomizationTarget( + otherWin.document.getElementById(containerId) + ); + is( + otherTarget.firstElementChild.id, + id, + "Widget " + id + " should be in " + containerId + " in other window." + ); +} + +async function checkToolbar(id, method) { + // Place at start of the toolbar: + let toolbarPlacements = getAreaWidgetIds(kToolbar); + await move[method](id, kToolbar); + if (method == "dragToItem") { + isFirst(kToolbar, toolbarPlacements, id); + } else if (method == "drag") { + isLastVisibleInToolbar(kToolbar, toolbarPlacements, id); + } else { + isLast(kToolbar, toolbarPlacements, id); + } + checkWrapper(id); +} + +async function checkPanel(id, method) { + let panelPlacements = getAreaWidgetIds(kPanel); + await move[method](id, kPanel); + let children = document + .getElementById(kPanel) + .querySelectorAll("toolbarpaletteitem"); + let otherChildren = otherWin.document.getElementById(kPanel).children; + let newPlacements = panelPlacements.concat([id]); + // Relative position of the new item from the end: + let position = -1; + // For the drag to item case, we drag to the last item, making the dragged item the + // penultimate item. We can't well use the first item because the panel has complicated + // rules about rearranging wide items (which, by default, the first two items are). + if (method == "dragToItem") { + newPlacements.pop(); + newPlacements.splice(panelPlacements.length - 1, 0, id); + position = -2; + } + assertAreaPlacements(kPanel, newPlacements); + is( + children[children.length + position].firstElementChild.id, + id, + "Widget " + id + " should be in " + kPanel + " in customizing window." + ); + is( + otherChildren[otherChildren.length + position].id, + id, + "Widget " + id + " should be in " + kPanel + " in other window." + ); + checkWrapper(id); +} + +async function checkPalette(id, method) { + // Move back to palette: + await move[method](id, kVisiblePalette); + ok(CustomizableUI.inDefaultState, "Should end in default state"); + let visibleChildren = gCustomizeMode.visiblePalette.children; + let expectedChild = + method == "dragToItem" + ? visibleChildren[0] + : visibleChildren[visibleChildren.length - 1]; + // Items dragged to the end of the palette should be the final item. That they're the penultimate + // item when dragged is tracked in bug 1395950. Once that's fixed, this hack can be removed. + if (method == "drag") { + expectedChild = expectedChild.previousElementSibling; + } + is( + expectedChild.firstElementChild.id, + id, + "Widget " + + id + + " was moved using " + + method + + " and should now be wrapped in palette in customizing window." + ); + if (id == kXULWidgetId) { + ok( + otherWin.gNavToolbox.palette.querySelector("#" + id), + "Widget " + id + " should be in invisible palette in other window." + ); + } + checkWrapper(id); +} + +// This test needs a XUL button that's in the palette by default. No such +// button currently exists, so we create a simple one. +function createXULButtonForWindow(win) { + createDummyXULButton(kXULWidgetId, "test-button", win); +} + +function removeXULButtonForWindow(win) { + win.gNavToolbox.palette.querySelector(`#${kXULWidgetId}`).remove(); +} + +var otherWin; + +// Moving widgets in two windows, one with customize mode and one without, should work. +add_task(async function MoveWidgetsInTwoWindows() { + CustomizableUI.createWidget({ + id: "cui-mode-wrapping-some-panel-item", + label: "Test panel wrapping", + }); + await startCustomizing(); + otherWin = await openAndLoadWindow(null, true); + await otherWin.PanelUI.ensureReady(); + // Create the XUL button to use in the test in both windows. + createXULButtonForWindow(window); + createXULButtonForWindow(otherWin); + ok(CustomizableUI.inDefaultState, "Should start in default state"); + + for (let widgetId of [kXULWidgetId, kAPIWidgetId]) { + for (let method of ["API", "drag", "dragToItem"]) { + info("Moving widget " + widgetId + " using " + method); + await checkToolbar(widgetId, method); + // We add an item to the panel because otherwise we can't test dragging + // to items that are already there. We remove it because + // 'checkPalette' checks that we leave the browser in the default state. + CustomizableUI.addWidgetToArea( + "cui-mode-wrapping-some-panel-item", + CustomizableUI.AREA_FIXED_OVERFLOW_PANEL + ); + await checkPanel(widgetId, method); + CustomizableUI.removeWidgetFromArea("cui-mode-wrapping-some-panel-item"); + await checkPalette(widgetId, method); + CustomizableUI.addWidgetToArea( + "cui-mode-wrapping-some-panel-item", + CustomizableUI.AREA_FIXED_OVERFLOW_PANEL + ); + await checkPanel(widgetId, method); + await checkToolbar(widgetId, method); + CustomizableUI.removeWidgetFromArea("cui-mode-wrapping-some-panel-item"); + await checkPalette(widgetId, method); + } + } + await promiseWindowClosed(otherWin); + otherWin = null; + await endCustomizing(); + removeXULButtonForWindow(window); +}); + +add_task(async function asyncCleanup() { + CustomizableUI.destroyWidget("cui-mode-wrapping-some-panel-item"); + await resetCustomization(); +}); -- cgit v1.2.3