1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/customizableui/test/browser_995164_registerArea_during_customize_mode.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,143 @@ 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 TOOLBARID = "test-toolbar-added-during-customize-mode"; 1.11 + 1.12 +add_task(function*() { 1.13 + yield startCustomizing(); 1.14 + let toolbar = createToolbarWithPlacements(TOOLBARID, []); 1.15 + CustomizableUI.addWidgetToArea("sync-button", TOOLBARID); 1.16 + let syncButton = document.getElementById("sync-button"); 1.17 + ok(syncButton, "Sync button should exist."); 1.18 + is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should be a wrapper."); 1.19 + 1.20 + simulateItemDrag(syncButton, gNavToolbox.palette); 1.21 + ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); 1.22 + ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); 1.23 + 1.24 + simulateItemDrag(syncButton, toolbar); 1.25 + ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); 1.26 + is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); 1.27 + ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); 1.28 + 1.29 + yield endCustomizing(); 1.30 + isnot(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should not be a wrapper outside customize mode."); 1.31 + yield startCustomizing(); 1.32 + 1.33 + is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should be a wrapper back in customize mode."); 1.34 + 1.35 + simulateItemDrag(syncButton, gNavToolbox.palette); 1.36 + ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); 1.37 + ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); 1.38 + 1.39 + ok(!CustomizableUI.inDefaultState, "Not in default state while toolbar is not collapsed yet."); 1.40 + setToolbarVisibility(toolbar, false); 1.41 + ok(CustomizableUI.inDefaultState, "In default state while toolbar is collapsed."); 1.42 + 1.43 + setToolbarVisibility(toolbar, true); 1.44 + 1.45 + info("Check that removing the area registration from within customize mode works"); 1.46 + CustomizableUI.unregisterArea(TOOLBARID); 1.47 + ok(CustomizableUI.inDefaultState, "Now that the toolbar is no longer registered, should be in default state."); 1.48 + ok(!(new Set(gCustomizeMode.areas)).has(toolbar), "Toolbar shouldn't be known to customize mode."); 1.49 + 1.50 + CustomizableUI.registerArea(TOOLBARID, {legacy: true, defaultPlacements: []}); 1.51 + CustomizableUI.registerToolbarNode(toolbar, []); 1.52 + ok(!CustomizableUI.inDefaultState, "Now that the toolbar is registered again, should no longer be in default state."); 1.53 + ok((new Set(gCustomizeMode.areas)).has(toolbar), "Toolbar should be known to customize mode again."); 1.54 + 1.55 + simulateItemDrag(syncButton, toolbar); 1.56 + ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); 1.57 + is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); 1.58 + ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); 1.59 + 1.60 + let otherWin = yield openAndLoadWindow({}, true); 1.61 + let otherTB = otherWin.document.createElementNS(kNSXUL, "toolbar"); 1.62 + otherTB.id = TOOLBARID; 1.63 + otherTB.setAttribute("customizable", "true"); 1.64 + let wasInformedCorrectlyOfAreaAppearing = false; 1.65 + let listener = { 1.66 + onAreaNodeRegistered: function(aArea, aNode) { 1.67 + if (aNode == otherTB) { 1.68 + wasInformedCorrectlyOfAreaAppearing = true; 1.69 + } 1.70 + } 1.71 + }; 1.72 + CustomizableUI.addListener(listener); 1.73 + otherWin.gNavToolbox.appendChild(otherTB); 1.74 + ok(wasInformedCorrectlyOfAreaAppearing, "Should have been told area was registered."); 1.75 + CustomizableUI.removeListener(listener); 1.76 + 1.77 + ok(otherTB.querySelector("#sync-button"), "Sync button is on other toolbar, too."); 1.78 + 1.79 + simulateItemDrag(syncButton, gNavToolbox.palette); 1.80 + ok(!CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved to the palette"); 1.81 + ok(gNavToolbox.palette.querySelector("#sync-button"), "Sync button really is in palette."); 1.82 + ok(!otherTB.querySelector("#sync-button"), "Sync button is in palette in other window, too."); 1.83 + 1.84 + simulateItemDrag(syncButton, toolbar); 1.85 + ok(CustomizableUI.getPlacementOfWidget("sync-button"), "Button moved out of palette"); 1.86 + is(CustomizableUI.getPlacementOfWidget("sync-button").area, TOOLBARID, "Button's back on toolbar"); 1.87 + ok(toolbar.querySelector("#sync-button"), "Sync button really is on toolbar."); 1.88 + ok(otherTB.querySelector("#sync-button"), "Sync button is on other toolbar, too."); 1.89 + 1.90 + let wasInformedCorrectlyOfAreaDisappearing = false; 1.91 + //XXXgijs So we could be using promiseWindowClosed here. However, after 1.92 + // repeated random oranges, I'm instead relying on onWindowClosed below to 1.93 + // fire appropriately - it is linked to an unload event as well, and so 1.94 + // reusing it prevents a potential race between unload handlers where the 1.95 + // one from promiseWindowClosed could fire before the onWindowClosed 1.96 + // (and therefore onAreaNodeRegistered) one, causing the test to fail. 1.97 + let windowCloseDeferred = Promise.defer(); 1.98 + listener = { 1.99 + onAreaNodeUnregistered: function(aArea, aNode, aReason) { 1.100 + if (aArea == TOOLBARID) { 1.101 + is(aNode, otherTB, "Should be informed about other toolbar"); 1.102 + is(aReason, CustomizableUI.REASON_WINDOW_CLOSED, "Reason should be correct."); 1.103 + wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_WINDOW_CLOSED); 1.104 + } 1.105 + }, 1.106 + onWindowClosed: function(aWindow) { 1.107 + if (aWindow == otherWin) { 1.108 + windowCloseDeferred.resolve(aWindow); 1.109 + } else { 1.110 + info("Other window was closed!"); 1.111 + info("Other window title: " + (aWindow.document && aWindow.document.title)); 1.112 + info("Our window title: " + (otherWin.document && otherWin.document.title)); 1.113 + } 1.114 + }, 1.115 + }; 1.116 + CustomizableUI.addListener(listener); 1.117 + otherWin.close(); 1.118 + let windowClosed = yield windowCloseDeferred.promise; 1.119 + 1.120 + is(windowClosed, otherWin, "Window should have sent onWindowClosed notification."); 1.121 + ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about window closing."); 1.122 + // Closing the other window should not be counted against this window's customize mode: 1.123 + is(syncButton.parentNode.localName, "toolbarpaletteitem", "Sync button's parent node should still be a wrapper."); 1.124 + isnot(gCustomizeMode.areas.indexOf(toolbar), -1, "Toolbar should still be a customizable area for this customize mode instance."); 1.125 + 1.126 + yield gCustomizeMode.reset(); 1.127 + 1.128 + yield endCustomizing(); 1.129 + 1.130 + CustomizableUI.removeListener(listener); 1.131 + wasInformedCorrectlyOfAreaDisappearing = false; 1.132 + listener = { 1.133 + onAreaNodeUnregistered: function(aArea, aNode, aReason) { 1.134 + if (aArea == TOOLBARID) { 1.135 + is(aNode, toolbar, "Should be informed about this window's toolbar"); 1.136 + is(aReason, CustomizableUI.REASON_AREA_UNREGISTERED, "Reason for final removal should be correct."); 1.137 + wasInformedCorrectlyOfAreaDisappearing = (aReason === CustomizableUI.REASON_AREA_UNREGISTERED); 1.138 + } 1.139 + }, 1.140 + } 1.141 + CustomizableUI.addListener(listener); 1.142 + removeCustomToolbars(); 1.143 + ok(wasInformedCorrectlyOfAreaDisappearing, "Should be told about area being unregistered."); 1.144 + CustomizableUI.removeListener(listener); 1.145 + ok(CustomizableUI.inDefaultState, "Should be fine after exiting customize mode."); 1.146 +});