1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,256 @@ 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 +let gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR); 1.11 +let gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget")); 1.12 + 1.13 +const kBookmarksButton = "bookmarks-menu-button"; 1.14 +const kBookmarksItems = "personal-bookmarks"; 1.15 +const kOriginalWindowWidth = window.outerWidth; 1.16 +const kSmallWidth = 400; 1.17 + 1.18 +/** 1.19 + * Helper function that opens the bookmarks menu, and returns a Promise that 1.20 + * resolves as soon as the menu is ready for interaction. 1.21 + */ 1.22 +function bookmarksMenuPanelShown() { 1.23 + let deferred = Promise.defer(); 1.24 + let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup"); 1.25 + let onTransitionEnd = (e) => { 1.26 + if (e.target == bookmarksMenuPopup) { 1.27 + bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd); 1.28 + deferred.resolve(); 1.29 + } 1.30 + } 1.31 + bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd); 1.32 + return deferred.promise; 1.33 +} 1.34 + 1.35 +/** 1.36 + * Checks that the placesContext menu is correctly attached to the 1.37 + * controller of some view. Returns a Promise that resolves as soon 1.38 + * as the context menu is closed. 1.39 + * 1.40 + * @param aItemWithContextMenu the item that we need to synthesize hte 1.41 + * right click on in order to open the context menu. 1.42 + */ 1.43 +function checkPlacesContextMenu(aItemWithContextMenu) { 1.44 + return Task.spawn(function* () { 1.45 + let contextMenu = document.getElementById("placesContext"); 1.46 + let newBookmarkItem = document.getElementById("placesContext_new:bookmark"); 1.47 + let shownPromise = popupShown(contextMenu); 1.48 + EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu, 1.49 + {type: "contextmenu", button: 2}); 1.50 + yield shownPromise; 1.51 + 1.52 + ok(!newBookmarkItem.hasAttribute("disabled"), 1.53 + "New bookmark item shouldn't be disabled"); 1.54 + 1.55 + yield closePopup(contextMenu); 1.56 + }); 1.57 +} 1.58 + 1.59 +/** 1.60 + * Opens the bookmarks menu panel, and then opens each of the "special" 1.61 + * submenus in that list. Then it checks that those submenu's context menus 1.62 + * are properly hooked up to a controller. 1.63 + */ 1.64 +function checkSpecialContextMenus() { 1.65 + return Task.spawn(function* () { 1.66 + let contextMenu = document.getElementById("placesContext"); 1.67 + let bookmarksMenuButton = document.getElementById(kBookmarksButton); 1.68 + let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup"); 1.69 + 1.70 + const kSpecialItemIDs = { 1.71 + "BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup", 1.72 + "BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup", 1.73 + }; 1.74 + 1.75 + // Open the bookmarks menu button context menus and ensure that 1.76 + // they have the proper views attached. 1.77 + let shownPromise = bookmarksMenuPanelShown(); 1.78 + let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton, 1.79 + "anonid", "dropmarker"); 1.80 + EventUtils.synthesizeMouseAtCenter(dropmarker, {}); 1.81 + info("Waiting for bookmarks menu popup to show after clicking dropmarker.") 1.82 + yield shownPromise; 1.83 + 1.84 + for (let menuID in kSpecialItemIDs) { 1.85 + let menuItem = document.getElementById(menuID); 1.86 + let menuPopup = document.getElementById(kSpecialItemIDs[menuID]); 1.87 + let shownPromise = popupShown(menuPopup); 1.88 + menuPopup.openPopup(menuItem, null, 0, 0, false, false, null); 1.89 1.90 + yield shownPromise; 1.91 + 1.92 + yield checkPlacesContextMenu(menuPopup); 1.93 + yield closePopup(menuPopup); 1.94 + } 1.95 + 1.96 + yield closePopup(bookmarksMenuPopup); 1.97 + }); 1.98 +} 1.99 + 1.100 +/** 1.101 + * Closes a focused popup by simulating pressing the Escape key, 1.102 + * and returns a Promise that resolves as soon as the popup is closed. 1.103 + * 1.104 + * @param aPopup the popup node to close. 1.105 + */ 1.106 +function closePopup(aPopup) { 1.107 + let hiddenPromise = popupHidden(aPopup); 1.108 + EventUtils.synthesizeKey("VK_ESCAPE", {}); 1.109 + return hiddenPromise; 1.110 +} 1.111 + 1.112 +/** 1.113 + * Helper function that checks that the context menu of the 1.114 + * bookmark toolbar items chevron popup is correctly hooked up 1.115 + * to the controller of a view. 1.116 + */ 1.117 +function checkBookmarksItemsChevronContextMenu() { 1.118 + return Task.spawn(function*() { 1.119 + let chevronPopup = document.getElementById("PlacesChevronPopup"); 1.120 + let shownPromise = popupShown(chevronPopup); 1.121 + let chevron = document.getElementById("PlacesChevron"); 1.122 + EventUtils.synthesizeMouseAtCenter(chevron, {}); 1.123 + yield shownPromise; 1.124 + yield waitForCondition(() => { 1.125 + for (let child of chevronPopup.children) { 1.126 + if (child.style.visibility != "hidden") 1.127 + return true; 1.128 + } 1.129 + }); 1.130 + yield checkPlacesContextMenu(chevronPopup); 1.131 + yield closePopup(chevronPopup); 1.132 + }); 1.133 +} 1.134 + 1.135 +/** 1.136 + * Forces the window to a width that causes the nav-bar to overflow 1.137 + * its contents. Returns a Promise that resolves as soon as the 1.138 + * overflowable nav-bar is showing its chevron. 1.139 + */ 1.140 +function overflowEverything() { 1.141 + window.resizeTo(kSmallWidth, window.outerHeight); 1.142 + return waitForCondition(() => gNavBar.hasAttribute("overflowing")); 1.143 +} 1.144 + 1.145 +/** 1.146 + * Returns the window to its original size from the start of the test, 1.147 + * and returns a Promise that resolves when the nav-bar is no longer 1.148 + * overflowing. 1.149 + */ 1.150 +function stopOverflowing() { 1.151 + window.resizeTo(kOriginalWindowWidth, window.outerHeight); 1.152 + return waitForCondition(() => !gNavBar.hasAttribute("overflowing")); 1.153 +} 1.154 + 1.155 +/** 1.156 + * Checks that an item with ID aID is overflowing in the nav-bar. 1.157 + * 1.158 + * @param aID the ID of the node to check for overflowingness. 1.159 + */ 1.160 +function checkOverflowing(aID) { 1.161 + ok(!gNavBar.querySelector("#" + aID), 1.162 + "Item with ID " + aID + " should no longer be in the gNavBar"); 1.163 + let item = gOverflowList.querySelector("#" + aID); 1.164 + ok(item, "Item with ID " + aID + " should be overflowing"); 1.165 + is(item.getAttribute("overflowedItem"), "true", 1.166 + "Item with ID " + aID + " should have overflowedItem attribute"); 1.167 +} 1.168 + 1.169 +/** 1.170 + * Checks that an item with ID aID is not overflowing in the nav-bar. 1.171 + * 1.172 + * @param aID the ID of hte node to check for non-overflowingness. 1.173 + */ 1.174 +function checkNotOverflowing(aID) { 1.175 + ok(!gOverflowList.querySelector("#" + aID), 1.176 + "Item with ID " + aID + " should no longer be overflowing"); 1.177 + let item = gNavBar.querySelector("#" + aID); 1.178 + ok(item, "Item with ID " + aID + " should be in the nav bar"); 1.179 + ok(!item.hasAttribute("overflowedItem"), 1.180 + "Item with ID " + aID + " should not have overflowedItem attribute"); 1.181 +} 1.182 + 1.183 +/** 1.184 + * Test that overflowing the bookmarks menu button doesn't break the 1.185 + * context menus for the Unsorted and Bookmarks Toolbar menu items. 1.186 + */ 1.187 +add_task(function* testOverflowingBookmarksButtonContextMenu() { 1.188 + ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar."); 1.189 + ok(CustomizableUI.inDefaultState, "Should start in default state."); 1.190 + 1.191 + // Open the Unsorted and Bookmarks Toolbar context menus and ensure 1.192 + // that they have views attached. 1.193 + yield checkSpecialContextMenus(); 1.194 + 1.195 + yield overflowEverything(); 1.196 + checkOverflowing(kBookmarksButton); 1.197 + 1.198 + yield stopOverflowing(); 1.199 + checkNotOverflowing(kBookmarksButton); 1.200 + 1.201 + yield checkSpecialContextMenus(); 1.202 +}); 1.203 + 1.204 +/** 1.205 + * Test that the bookmarks toolbar items context menu still works if moved 1.206 + * to the menu from the overflow panel, and then back to the toolbar. 1.207 + */ 1.208 +add_task(function* testOverflowingBookmarksItemsContextMenu() { 1.209 + yield PanelUI.ensureReady(); 1.210 + 1.211 + let bookmarksToolbarItems = document.getElementById(kBookmarksItems); 1.212 + gCustomizeMode.addToToolbar(bookmarksToolbarItems); 1.213 + yield checkPlacesContextMenu(bookmarksToolbarItems); 1.214 + 1.215 + yield overflowEverything(); 1.216 + checkOverflowing(kBookmarksItems) 1.217 + 1.218 + gCustomizeMode.addToPanel(bookmarksToolbarItems); 1.219 + 1.220 + yield stopOverflowing(); 1.221 + 1.222 + gCustomizeMode.addToToolbar(bookmarksToolbarItems); 1.223 + yield checkPlacesContextMenu(bookmarksToolbarItems); 1.224 +}); 1.225 + 1.226 +/** 1.227 + * Test that overflowing the bookmarks toolbar items doesn't cause the 1.228 + * context menu in the bookmarks toolbar items chevron to stop working. 1.229 + */ 1.230 +add_task(function* testOverflowingBookmarksItemsChevronContextMenu() { 1.231 + // If it's not already there, let's move the bookmarks toolbar items to 1.232 + // the nav-bar. 1.233 + let bookmarksToolbarItems = document.getElementById(kBookmarksItems); 1.234 + gCustomizeMode.addToToolbar(bookmarksToolbarItems); 1.235 + 1.236 + // We make the PlacesToolbarItems element be super tiny in order to force 1.237 + // the bookmarks toolbar items into overflowing and making the chevron 1.238 + // show itself. 1.239 + let placesToolbarItems = document.getElementById("PlacesToolbarItems"); 1.240 + let placesChevron = document.getElementById("PlacesChevron"); 1.241 + placesToolbarItems.style.maxWidth = "10px"; 1.242 + yield waitForCondition(() => !placesChevron.collapsed); 1.243 + 1.244 + yield checkBookmarksItemsChevronContextMenu(); 1.245 + 1.246 + yield overflowEverything(); 1.247 + checkOverflowing(kBookmarksItems); 1.248 + 1.249 + yield stopOverflowing(); 1.250 + checkNotOverflowing(kBookmarksItems); 1.251 + 1.252 + yield checkBookmarksItemsChevronContextMenu(); 1.253 + 1.254 + placesToolbarItems.style.removeProperty("max-width"); 1.255 +}); 1.256 + 1.257 +add_task(function* asyncCleanup() { 1.258 + window.resizeTo(kOriginalWindowWidth, window.outerHeight); 1.259 + yield resetCustomization(); 1.260 +});