michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: "use strict"; michael@0: michael@0: const TOOLBARID = "test-toolbar-added-during-customize-mode"; michael@0: michael@0: add_task(function*() { michael@0: yield startCustomizing(); michael@0: let toolbar = createToolbarWithPlacements(TOOLBARID, []); michael@0: CustomizableUI.addWidgetToArea("sync-button", TOOLBARID); michael@0: let syncButton = document.getElementById("sync-button"); michael@0: ok(syncButton, "Sync button should exist."); michael@0: is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should be a wrapper."); michael@0: michael@0: simulateItemDrag(syncButton, gNavToolbox.palette); michael@0: ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); michael@0: ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); michael@0: michael@0: simulateItemDrag(syncButton, toolbar); michael@0: ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); michael@0: is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); michael@0: ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); michael@0: michael@0: yield endCustomizing(); michael@0: isnot(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should not be a wrapper outside customize mode."); michael@0: yield startCustomizing(); michael@0: michael@0: is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should be a wrapper back in customize mode."); michael@0: michael@0: simulateItemDrag(syncButton, gNavToolbox.palette); michael@0: ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); michael@0: ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); michael@0: michael@0: ok(!CustomizableUI.inDefaultState, "Not in default state while toolbar is not collapsed yet."); michael@0: setToolbarVisibility(toolbar, false); michael@0: ok(CustomizableUI.inDefaultState, "In default state while toolbar is collapsed."); michael@0: michael@0: setToolbarVisibility(toolbar, true); michael@0: michael@0: info("Check that removing the area registration from within customize mode works"); michael@0: CustomizableUI.unregisterArea(TOOLBARID); michael@0: ok(CustomizableUI.inDefaultState, "Now that the toolbar is no longer registered, should be in default state."); michael@0: ok(!(new Set(gCustomizeMode.areas)).has(toolbar), "Toolbar shouldn't be known to customize mode."); michael@0: michael@0: CustomizableUI.registerArea(TOOLBARID, {legacy: true, defaultPlacements: []}); michael@0: CustomizableUI.registerToolbarNode(toolbar, []); michael@0: ok(!CustomizableUI.inDefaultState, "Now that the toolbar is registered again, should no longer be in default state."); michael@0: ok((new Set(gCustomizeMode.areas)).has(toolbar), "Toolbar should be known to customize mode again."); michael@0: michael@0: simulateItemDrag(syncButton, toolbar); michael@0: ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); michael@0: is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); michael@0: ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); michael@0: michael@0: let otherWin = yield openAndLoadWindow({}, true); michael@0: let otherTB = otherWin.document.createElementNS(kNSXUL, "toolbar"); michael@0: otherTB.id = TOOLBARID; michael@0: otherTB.setAttribute("customizable", "true"); michael@0: let wasInformedCorrectlyOfAreaAppearing = false; michael@0: let listener = { michael@0: onAreaNodeRegistered: function(aArea, aNode) { michael@0: if (aNode == otherTB) { michael@0: wasInformedCorrectlyOfAreaAppearing = true; michael@0: } michael@0: } michael@0: }; michael@0: CustomizableUI.addListener(listener); michael@0: otherWin.gNavToolbox.appendChild(otherTB); michael@0: ok(wasInformedCorrectlyOfAreaAppearing, "Should have been told area was registered."); michael@0: CustomizableUI.removeListener(listener); michael@0: michael@0: ok(otherTB.querySelector("#sync-button"), "Sync button is on other toolbar, too."); michael@0: michael@0: simulateItemDrag(syncButton, gNavToolbox.palette); michael@0: ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); michael@0: ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); michael@0: ok(!otherTB.querySelector("#sync-button"), "Sync button is in palette in other window, too."); michael@0: michael@0: simulateItemDrag(syncButton, toolbar); michael@0: ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); michael@0: is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); michael@0: ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); michael@0: ok(otherTB.querySelector("#sync-button"), "Sync button is on other toolbar, too."); michael@0: michael@0: let wasInformedCorrectlyOfAreaDisappearing = false; michael@0: //XXXgijs So we could be using promiseWindowClosed here. However, after michael@0: // repeated random oranges, I'm instead relying on onWindowClosed below to michael@0: // fire appropriately - it is linked to an unload event as well, and so michael@0: // reusing it prevents a potential race between unload handlers where the michael@0: // one from promiseWindowClosed could fire before the onWindowClosed michael@0: // (and therefore onAreaNodeRegistered) one, causing the test to fail. michael@0: let windowCloseDeferred = Promise.defer(); michael@0: listener = { michael@0: onAreaNodeUnregistered: function(aArea, aNode, aReason) { michael@0: if (aArea == TOOLBARID) { michael@0: is(aNode, otherTB, "Should be informed about other toolbar"); michael@0: is(aReason, CustomizableUI.REASON_WINDOW_CLOSED, "Reason should be correct."); michael@0: wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_WINDOW_CLOSED); michael@0: } michael@0: }, michael@0: onWindowClosed: function(aWindow) { michael@0: if (aWindow == otherWin) { michael@0: windowCloseDeferred.resolve(aWindow); michael@0: } else { michael@0: info("Other window was closed!"); michael@0: info("Other window title: " + (aWindow.document && aWindow.document.title)); michael@0: info("Our window title: " + (otherWin.document && otherWin.document.title)); michael@0: } michael@0: }, michael@0: }; michael@0: CustomizableUI.addListener(listener); michael@0: otherWin.close(); michael@0: let windowClosed = yield windowCloseDeferred.promise; michael@0: michael@0: is(windowClosed, otherWin, "Window should have sent onWindowClosed notification."); michael@0: ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about window closing."); michael@0: // Closing the other window should not be counted against this window's customize mode: michael@0: is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should still be a wrapper."); michael@0: isnot(gCustomizeMode.areas.indexOf(toolbar), -1, "Toolbar should still be a customizable area for this customize mode instance."); michael@0: michael@0: yield gCustomizeMode.reset(); michael@0: michael@0: yield endCustomizing(); michael@0: michael@0: CustomizableUI.removeListener(listener); michael@0: wasInformedCorrectlyOfAreaDisappearing = false; michael@0: listener = { michael@0: onAreaNodeUnregistered: function(aArea, aNode, aReason) { michael@0: if (aArea == TOOLBARID) { michael@0: is(aNode, toolbar, "Should be informed about this window's toolbar"); michael@0: is(aReason, CustomizableUI.REASON_AREA_UNREGISTERED, "Reason for final removal should be correct."); michael@0: wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_AREA_UNREGISTERED); michael@0: } michael@0: }, michael@0: } michael@0: CustomizableUI.addListener(listener); michael@0: removeCustomToolbars(); michael@0: ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about area being unregistered."); michael@0: CustomizableUI.removeListener(listener); michael@0: ok(CustomizableUI.inDefaultState, "Should be fine after exiting customize mode."); michael@0: });