Bug 1493594 - replace customizationTarget XBL property by CustomizableUI method, r=gijs
authorAlexander Surkov <surkov.alexander@gmail.com>
Thu, 08 Nov 2018 13:45:22 +0700
changeset 501520 b3da3f53f804
parent 501519 0f116bf89e5c
child 501535 d6757c8a7df1
child 501580 3f71db4aef73
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgijs
bugs1493594
milestone65.0a1
first release with
nightly linux32
b3da3f53f804 / 65.0a1 / 20181108100100 / files
nightly linux64
b3da3f53f804 / 65.0a1 / 20181108100100 / files
nightly mac
b3da3f53f804 / 65.0a1 / 20181108100100 / files
nightly win32
b3da3f53f804 / 65.0a1 / 20181108100100 / files
nightly win64
b3da3f53f804 / 65.0a1 / 20181108100100 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1493594 - replace customizationTarget XBL property by CustomizableUI method, r=gijs
browser/components/customizableui/CustomizableUI.jsm
browser/components/customizableui/CustomizeMode.jsm
browser/components/customizableui/content/toolbar.xml
browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js
browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js
browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js
browser/components/customizableui/test/browser_913972_currentset_overflow.js
browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
browser/components/customizableui/test/browser_934113_menubar_removable.js
browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js
browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
browser/components/customizableui/test/browser_976792_insertNodeInWindow.js
browser/components/customizableui/test/browser_978084_dragEnd_after_move.js
browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js
browser/components/customizableui/test/browser_customization_context_menus.js
browser/components/customizableui/test/browser_editcontrols_update.js
browser/components/customizableui/test/browser_insert_before_moved_node.js
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -547,16 +547,35 @@ var CustomizableUIInternal = {
       }
       // The loop above either inserts the item or doesn't - either way, we can get away
       // with doing nothing else now; if the item remains in gFuturePlacements, we'll
       // add it at the end in restoreStateForArea.
     }
     this.saveState();
   },
 
+  getCustomizationTarget(aElement) {
+    if (!aElement) {
+      return null;
+    }
+
+    if (!aElement._customizationTarget && aElement.hasAttribute("customizable")) {
+      let id = aElement.getAttribute("customizationtarget");
+      if (id) {
+        aElement._customizationTarget = aElement.ownerDocument.getElementById(id);
+      }
+
+      if (!aElement._customizationTarget) {
+        aElement._customizationTarget = aElement;
+      }
+    }
+
+    return aElement._customizationTarget;
+  },
+
   wrapWidget(aWidgetId) {
     if (gGroupWrapperCache.has(aWidgetId)) {
       return gGroupWrapperCache.get(aWidgetId);
     }
 
     let provider = this.getWidgetProvider(aWidgetId);
     if (!provider) {
       return null;
@@ -679,17 +698,18 @@ var CustomizableUIInternal = {
         // Otherwise we need to re-set them, as removeFromArea will have emptied
         // them out:
         gPlacements.set(aName, placements);
       }
       gFuturePlacements.delete(aName);
       let existingAreaNodes = gBuildAreas.get(aName);
       if (existingAreaNodes) {
         for (let areaNode of existingAreaNodes) {
-          this.notifyListeners("onAreaNodeUnregistered", aName, areaNode.customizationTarget,
+          this.notifyListeners("onAreaNodeUnregistered", aName,
+                               this.getCustomizationTarget(areaNode),
                                CustomizableUI.REASON_AREA_UNREGISTERED);
         }
       }
       gBuildAreas.delete(aName);
     } finally {
       this.endBatchUpdate(true);
     }
   },
@@ -738,27 +758,28 @@ var CustomizableUIInternal = {
       // 2) The number of children of the toolbar does not match the length of
       //    the placements array for that area.
       //
       // This notion of being "dirty" is stored in a cache which is persisted
       // in the saved state.
       if (gDirtyAreaCache.has(area)) {
         this.buildArea(area, placements, aToolbar);
       }
-      this.notifyListeners("onAreaNodeRegistered", area, aToolbar.customizationTarget);
+      this.notifyListeners("onAreaNodeRegistered", area,
+                           this.getCustomizationTarget(aToolbar));
     } finally {
       this.endBatchUpdate();
     }
   },
 
   buildArea(aArea, aPlacements, aAreaNode) {
     let document = aAreaNode.ownerDocument;
     let window = document.defaultView;
     let inPrivateWindow = PrivateBrowsingUtils.isWindowPrivate(window);
-    let container = aAreaNode.customizationTarget;
+    let container = this.getCustomizationTarget(aAreaNode);
     let areaIsPanel = gAreas.get(aArea).get("type") == CustomizableUI.TYPE_MENU_PANEL;
 
     if (!container) {
       throw new Error("Expected area " + aArea
                       + " to have a customizationTarget attribute.");
     }
 
     // Restore nav-bar visibility since it may have been hidden
@@ -975,18 +996,17 @@ var CustomizableUIInternal = {
     return [null, null];
   },
 
   registerMenuPanel(aPanelContents, aArea) {
     if (gBuildAreas.has(aArea) && gBuildAreas.get(aArea).has(aPanelContents)) {
       return;
     }
 
-    aPanelContents.customizationTarget = aPanelContents;
-
+    aPanelContents._customizationTarget = aPanelContents;
     this.addPanelCloseListeners(this._getPanelForNode(aPanelContents));
 
     let placements = gPlacements.get(aArea);
     this.buildArea(aArea, placements, aPanelContents);
     this.notifyListeners("onAreaNodeRegistered", aArea, aPanelContents);
 
     for (let child of aPanelContents.children) {
       if (child.localName != "toolbarbutton") {
@@ -1024,17 +1044,17 @@ var CustomizableUIInternal = {
 
     for (let areaNode of areaNodes) {
       let window = areaNode.ownerGlobal;
       if (!showInPrivateBrowsing &&
           PrivateBrowsingUtils.isWindowPrivate(window)) {
         continue;
       }
 
-      let container = areaNode.customizationTarget;
+      let container = this.getCustomizationTarget(areaNode);
       let widgetNode = window.document.getElementById(aWidgetId);
       if (widgetNode && isOverflowable) {
         container = areaNode.overflowable.getContainerFor(widgetNode);
       }
 
       if (!widgetNode || !container.contains(widgetNode)) {
         log.info("Widget " + aWidgetId + " not found, unable to remove from " + aArea);
         continue;
@@ -1118,17 +1138,18 @@ var CustomizableUIInternal = {
     gBuildWindows.delete(aWindow);
     gSingleWrapperCache.delete(aWindow);
     let document = aWindow.document;
 
     for (let [areaId, areaNodes] of gBuildAreas) {
       let areaProperties = gAreas.get(areaId);
       for (let node of areaNodes) {
         if (node.ownerDocument == document) {
-          this.notifyListeners("onAreaNodeUnregistered", areaId, node.customizationTarget,
+          this.notifyListeners("onAreaNodeUnregistered", areaId,
+                               this.getCustomizationTarget(node),
                                CustomizableUI.REASON_WINDOW_CLOSED);
           if (areaProperties.has("overflowable")) {
             node.overflowable.uninit();
             node.overflowable = null;
           }
           areaNodes.delete(node);
         }
       }
@@ -1224,17 +1245,17 @@ var CustomizableUIInternal = {
     let areaId = aAreaNode.id;
     let props = gAreas.get(areaId);
 
     // For overflowable toolbars, rely on them (because the work is more complicated):
     if (props.get("type") == CustomizableUI.TYPE_TOOLBAR && props.get("overflowable")) {
       return aAreaNode.overflowable.findOverflowedInsertionPoints(aNode);
     }
 
-    let container = aAreaNode.customizationTarget;
+    let container = this.getCustomizationTarget(aAreaNode);
     let placements = gPlacements.get(areaId);
     let nodeIndex = placements.indexOf(aNode.id);
 
     while (++nodeIndex < placements.length) {
       let nextNodeId = placements[nodeIndex];
       let nextNode = aNode.ownerDocument.getElementById(nextNodeId);
       // If the next placed widget exists, and is a direct child of the
       // container, or wrapped in a customize mode wrapper (toolbarpaletteitem)
@@ -1353,35 +1374,35 @@ var CustomizableUIInternal = {
 
     let document = aWindow.document;
 
     // look for a node with the same id, as the node may be
     // in a different toolbar.
     let node = document.getElementById(aId);
     if (node) {
       let parent = node.parentNode;
-      while (parent && !(parent.customizationTarget ||
+      while (parent && !(this.getCustomizationTarget(parent) ||
                          parent == aWindow.gNavToolbox.palette)) {
         parent = parent.parentNode;
       }
 
       if (parent) {
         let nodeInArea = node.parentNode.localName == "toolbarpaletteitem" ?
                          node.parentNode : node;
         // Check if we're in a customization target, or in the palette:
-        if ((parent.customizationTarget == nodeInArea.parentNode &&
+        if ((this.getCustomizationTarget(parent) == nodeInArea.parentNode &&
              gBuildWindows.get(aWindow).has(aWindow.gNavToolbox)) ||
             aWindow.gNavToolbox.palette == nodeInArea.parentNode) {
           // Normalize the removable attribute. For backwards compat, if
           // the widget is not located in a toolbox palette then absence
           // of the "removable" attribute means it is not removable.
           if (!node.hasAttribute("removable")) {
             // If we first see this in customization mode, it may be in the
             // customization palette instead of the toolbox palette.
-            node.setAttribute("removable", !parent.customizationTarget);
+            node.setAttribute("removable", !this.getCustomizationTarget(parent));
           }
           return node;
         }
       }
     }
 
     let toolboxes = gBuildWindows.get(aWindow);
     for (let toolbox of toolboxes) {
@@ -2546,17 +2567,17 @@ var CustomizableUIInternal = {
   getCustomizeTargetForArea(aArea, aWindow) {
     let buildAreaNodes = gBuildAreas.get(aArea);
     if (!buildAreaNodes) {
       return null;
     }
 
     for (let node of buildAreaNodes) {
       if (node.ownerGlobal == aWindow) {
-        return node.customizationTarget ? node.customizationTarget : node;
+        return this.getCustomizationTarget(node) || node;
       }
     }
 
     return null;
   },
 
   reset() {
     gResetting = true;
@@ -2780,17 +2801,17 @@ var CustomizableUIInternal = {
     function addUnskippedChildren(parent) {
       for (let node of parent.children) {
         let realNode = node.localName == "toolbarpaletteitem" ? node.firstElementChild : node;
         if (realNode.getAttribute("skipintoolbarset") != "true") {
           currentWidgets.add(realNode.id);
         }
       }
     }
-    addUnskippedChildren(container.customizationTarget);
+    addUnskippedChildren(this.getCustomizationTarget(container));
     if (container.getAttribute("overflowing") == "true") {
       let overflowTarget = container.getAttribute("overflowtarget");
       addUnskippedChildren(container.ownerDocument.getElementById(overflowTarget));
     }
     // Then get the sorted list of placements, and filter based on the nodes
     // that are present. This avoids including items that don't exist (e.g. ids
     // of add-on items that the user has uninstalled).
     let orderedPlacements = CustomizableUI.getWidgetIdsInArea(container.id);
@@ -3919,16 +3940,20 @@ var CustomizableUI = {
     parent.removeChild(aSubview);
 
     while (aSubview.firstChild) {
       aSubview.firstChild.remove();
     }
 
     parent.appendChild(aSubview);
   },
+
+  getCustomizationTarget(aElement) {
+    return CustomizableUIInternal.getCustomizationTarget(aElement);
+  },
 };
 Object.freeze(this.CustomizableUI);
 Object.freeze(this.CustomizableUI.windows);
 
 /**
  * All external consumers of widgets are really interacting with these wrappers
  * which provide a common interface.
  */
@@ -4191,19 +4216,19 @@ function OverflowableToolbar(aToolbarNod
   this._toolbar = aToolbarNode;
   this._collapsed = new Map();
   this._enabled = true;
   this._toolbar.addEventListener("overflow", this);
   this._toolbar.addEventListener("underflow", this);
 
   this._toolbar.setAttribute("overflowable", "true");
   let doc = this._toolbar.ownerDocument;
-  this._target = this._toolbar.customizationTarget;
+  this._target = CustomizableUI.getCustomizationTarget(this._toolbar);
   this._list = doc.getElementById(this._toolbar.getAttribute("overflowtarget"));
-  this._list.customizationTarget = this._list;
+  this._list._customizationTarget = this._list;
 
   let window = this._toolbar.ownerGlobal;
   if (window.gBrowserInit.delayedStartupFinished) {
     this.init();
   } else {
     Services.obs.addObserver(this, "browser-delayed-startup-finished");
   }
 }
--- a/browser/components/customizableui/CustomizeMode.jsm
+++ b/browser/components/customizableui/CustomizeMode.jsm
@@ -505,17 +505,17 @@ CustomizeMode.prototype = {
     // (it's used during drags), and avoid multiple DOM loops
     let areas = CustomizableUI.areas;
     // Caching this length is important because otherwise we'll also iterate
     // over items we add to the end from within the loop.
     let numberOfAreas = areas.length;
     for (let i = 0; i < numberOfAreas; i++) {
       let area = areas[i];
       let areaNode = aNode.ownerDocument.getElementById(area);
-      let customizationTarget = areaNode && areaNode.customizationTarget;
+      let customizationTarget = CustomizableUI.getCustomizationTarget(areaNode);
       if (customizationTarget && customizationTarget != areaNode) {
         areas.push(customizationTarget.id);
       }
       let overflowTarget = areaNode && areaNode.getAttribute("overflowtarget");
       if (overflowTarget) {
         areas.push(overflowTarget);
       }
     }
@@ -1731,17 +1731,17 @@ CustomizeMode.prototype = {
     }
 
     let targetAreaType = CustomizableUI.getPlaceForItem(targetArea);
     let targetNode = this._getDragOverNode(aEvent, targetArea, targetAreaType, draggedItemId);
 
     // We need to determine the place that the widget is being dropped in
     // the target.
     let dragOverItem, dragValue;
-    if (targetNode == targetArea.customizationTarget) {
+    if (targetNode == CustomizableUI.getCustomizationTarget(targetArea)) {
       // We'll assume if the user is dragging directly over the target, that
       // they're attempting to append a child to that target.
       dragOverItem = (targetAreaType == "toolbar"
                         ? this._findVisiblePreviousSiblingNode(targetNode.lastElementChild)
                         : targetNode.lastElementChild) ||
                      targetNode;
       dragValue = "after";
     } else {
@@ -1783,17 +1783,17 @@ CustomizeMode.prototype = {
       }
     }
 
     if (this._dragOverItem && dragOverItem != this._dragOverItem) {
       this._cancelDragActive(this._dragOverItem, dragOverItem);
     }
 
     if (dragOverItem != this._dragOverItem || dragValue != dragOverItem.getAttribute("dragover")) {
-      if (dragOverItem != targetArea.customizationTarget) {
+      if (dragOverItem != CustomizableUI.getCustomizationTarget(targetArea)) {
         this._setDragActive(dragOverItem, dragValue, draggedItemId, targetAreaType);
       }
       this._dragOverItem = dragOverItem;
       targetArea.setAttribute("draggingover", "true");
     }
 
     aEvent.preventDefault();
     aEvent.stopPropagation();
@@ -1895,37 +1895,39 @@ CustomizeMode.prototype = {
       return;
     }
 
     if (!CustomizableUI.canWidgetMoveToArea(aDraggedItemId, aTargetArea.id)) {
       return;
     }
 
     // Skipintoolbarset items won't really be moved:
+    let areaCustomizationTarget =
+      CustomizableUI.getCustomizationTarget(aTargetArea);
     if (draggedItem.getAttribute("skipintoolbarset") == "true") {
       // These items should never leave their area:
       if (aTargetArea != aOriginArea) {
         return;
       }
       let place = draggedItem.parentNode.getAttribute("place");
       this.unwrapToolbarItem(draggedItem.parentNode);
-      if (aTargetNode == aTargetArea.customizationTarget) {
-        aTargetArea.customizationTarget.appendChild(draggedItem);
+      if (aTargetNode == areaCustomizationTarget) {
+        areaCustomizationTarget.appendChild(draggedItem);
       } else {
         this.unwrapToolbarItem(aTargetNode.parentNode);
-        aTargetArea.customizationTarget.insertBefore(draggedItem, aTargetNode);
+        areaCustomizationTarget.insertBefore(draggedItem, aTargetNode);
         this.wrapToolbarItem(aTargetNode, place);
       }
       this.wrapToolbarItem(draggedItem, place);
       return;
     }
 
     // Is the target the customization area itself? If so, we just add the
     // widget to the end of the area.
-    if (aTargetNode == aTargetArea.customizationTarget) {
+    if (aTargetNode == areaCustomizationTarget) {
       CustomizableUI.addWidgetToArea(aDraggedItemId, aTargetArea.id);
       this._onDragEnd(aEvent);
       return;
     }
 
     // We need to determine the place that the widget is being dropped in
     // the target.
     let placement;
@@ -2222,17 +2224,18 @@ CustomizeMode.prototype = {
     }
 
     let areas = CustomizableUI.areas;
     areas.push(kPaletteId);
     return aElement.closest(areas.map(a => "#" + CSS.escape(a)).join(","));
   },
 
   _getDragOverNode(aEvent, aAreaElement, aAreaType, aDraggedItemId) {
-    let expectedParent = aAreaElement.customizationTarget || aAreaElement;
+    let expectedParent =
+      CustomizableUI.getCustomizationTarget(aAreaElement) || aAreaElement;
     if (!expectedParent.contains(aEvent.target)) {
       return expectedParent;
     }
     // Offset the drag event's position with the offset to the center of
     // the thing we're dragging
     let dragX = aEvent.clientX - this._dragOffset.x;
     let dragY = aEvent.clientY - this._dragOffset.y;
 
--- a/browser/components/customizableui/content/toolbar.xml
+++ b/browser/components/customizableui/content/toolbar.xml
@@ -30,32 +30,16 @@
           }
 
           // pass the current set of children for comparison with placements:
           let children = Array.from(this.children)
                               .filter(node => node.getAttribute("skipintoolbarset") != "true" && node.id)
                               .map(node => node.id);
           CustomizableUI.registerToolbarNode(this, children);
       ]]></constructor>
-
-      <property name="customizationTarget" readonly="true">
-        <getter><![CDATA[
-          if (this._customizationTarget)
-            return this._customizationTarget;
-
-          let id = this.getAttribute("customizationtarget");
-          if (id)
-            this._customizationTarget = document.getElementById(id);
-
-          if (!this._customizationTarget)
-            this._customizationTarget = this;
-
-          return this._customizationTarget;
-        ]]></getter>
-      </property>
     </implementation>
   </binding>
 
   <!-- The toolbar-drag binding is almost a verbatim copy of its toolkit counterpart,
        but it inherits from the customizableui's toolbar binding instead of toolkit's.
        This functionality will move into CustomizableUI proper as part of our move
        away from XBL. -->
   <binding id="toolbar-drag"
--- a/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js
+++ b/browser/components/customizableui/test/browser_1008559_anchor_undo_restore.js
@@ -11,17 +11,17 @@ const kAnchorAttribute = "cui-anchorid";
  */
 add_task(async function() {
   CustomizableUI.addWidgetToArea("history-panelmenu", CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
   await startCustomizing();
   let button = document.getElementById("history-panelmenu");
   is(button.getAttribute(kAnchorAttribute), "nav-bar-overflow-button",
      "Button (" + button.id + ") starts out with correct anchor");
 
-  let navbar = document.getElementById("nav-bar").customizationTarget;
+  let navbar = CustomizableUI.getCustomizationTarget(document.getElementById("nav-bar"));
   let onMouseUp = BrowserTestUtils.waitForEvent(navbar, "mouseup");
   simulateItemDrag(button, navbar);
   await onMouseUp;
   is(CustomizableUI.getPlacementOfWidget(button.id).area, "nav-bar",
      "Button (" + button.id + ") ends up in nav-bar");
 
   ok(!button.hasAttribute(kAnchorAttribute),
      "Button (" + button.id + ") has no anchor in toolbar");
--- a/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
+++ b/browser/components/customizableui/test/browser_876926_customize_mode_wrapping.js
@@ -30,28 +30,28 @@ async function ensureVisible(node) {
     }
     return nodeBounds.height && nodeBounds.width;
   });
 }
 
 var move = {
   "drag": async function(id, target) {
     let targetNode = document.getElementById(target);
-    if (targetNode.customizationTarget) {
-      targetNode = targetNode.customizationTarget;
+    if (CustomizableUI.getCustomizationTarget(targetNode)) {
+      targetNode = CustomizableUI.getCustomizationTarget(targetNode);
     }
     let nodeToMove = document.getElementById(id);
     await ensureVisible(nodeToMove);
 
     simulateItemDrag(nodeToMove, targetNode, "end");
   },
   "dragToItem": async function(id, target) {
     let targetNode = document.getElementById(target);
-    if (targetNode.customizationTarget) {
-      targetNode = targetNode.customizationTarget;
+    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);
@@ -63,24 +63,28 @@ var move = {
       return CustomizableUI.removeWidgetFromArea(id);
     }
     return CustomizableUI.addWidgetToArea(id, target, null);
   },
 };
 
 function isLast(containerId, defaultPlacements, id) {
   assertAreaPlacements(containerId, defaultPlacements.concat([id]));
-  is(document.getElementById(containerId).customizationTarget.lastElementChild.firstElementChild.id, id,
+  let thisTarget =
+    CustomizableUI.getCustomizationTarget(document.getElementById(containerId));
+  is(thisTarget.lastElementChild.firstElementChild.id, id,
      "Widget " + id + " should be in " + containerId + " in customizing window.");
-  is(otherWin.document.getElementById(containerId).customizationTarget.lastElementChild.id, id,
+  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 = win.document.getElementById(containerId).customizationTarget;
+  let container = CustomizableUI.getCustomizationTarget(win.document.getElementById(containerId));
   let rv = container.lastElementChild;
   while (rv && (rv.getAttribute("hidden") == "true" || (rv.firstElementChild && rv.firstElementChild.getAttribute("hidden") == "true"))) {
     rv = rv.previousElementSibling;
   }
   return rv;
 }
 
 function isLastVisibleInToolbar(containerId, defaultPlacements, id) {
@@ -101,19 +105,23 @@ function isLastVisibleInToolbar(containe
   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));
-  is(document.getElementById(containerId).customizationTarget.firstElementChild.firstElementChild.id, id,
+  let thisTarget =
+    CustomizableUI.getCustomizationTarget(document.getElementById(containerId));
+  is(thisTarget.firstElementChild.firstElementChild.id, id,
      "Widget " + id + " should be in " + containerId + " in customizing window.");
-  is(otherWin.document.getElementById(containerId).customizationTarget.firstElementChild.id, id,
+  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") {
--- a/browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js
+++ b/browser/components/customizableui/test/browser_886323_buildArea_removable_nodes.js
@@ -9,35 +9,35 @@ const kLazyAreaId = "test-886323-lazy-ar
 
 var gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
 var gLazyArea;
 
 // Removable nodes shouldn't be moved by buildArea
 add_task(async function() {
   let dummyBtn = createDummyXULButton(kButtonId, "Dummy");
   dummyBtn.setAttribute("removable", "true");
-  gNavBar.customizationTarget.appendChild(dummyBtn);
+  CustomizableUI.getCustomizationTarget(gNavBar).appendChild(dummyBtn);
   let popupSet = document.getElementById("mainPopupSet");
   gLazyArea = document.createElementNS(kNSXUL, "panel");
   gLazyArea.id = kLazyAreaId;
   gLazyArea.setAttribute("hidden", "true");
   popupSet.appendChild(gLazyArea);
   CustomizableUI.registerArea(kLazyAreaId, {
     type: CustomizableUI.TYPE_MENU_PANEL,
     defaultPlacements: [],
   });
   CustomizableUI.addWidgetToArea(kButtonId, kLazyAreaId);
   assertAreaPlacements(kLazyAreaId, [kButtonId],
                        "Placements should have changed because widget is removable.");
   let btn = document.getElementById(kButtonId);
   btn.setAttribute("removable", "false");
-  gLazyArea.customizationTarget = gLazyArea;
+  gLazyArea._customizationTarget = gLazyArea;
   CustomizableUI.registerToolbarNode(gLazyArea, []);
   assertAreaPlacements(kLazyAreaId, [], "Placements should no longer include widget.");
-  is(btn.parentNode.id, gNavBar.customizationTarget.id,
+  is(btn.parentNode.id, CustomizableUI.getCustomizationTarget(gNavBar).id,
      "Button shouldn't actually have moved as it's not removable");
   btn = document.getElementById(kButtonId);
   if (btn) btn.remove();
   CustomizableUI.removeWidgetFromArea(kButtonId);
   CustomizableUI.unregisterArea(kLazyAreaId);
   gLazyArea.remove();
 });
 
--- a/browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js
+++ b/browser/components/customizableui/test/browser_909779_overflow_toolbars_new_window.js
@@ -4,22 +4,22 @@
 
 "use strict";
 
 // Resize to a small window, open a new window, check that new window handles overflow properly
 add_task(async function() {
   let originalWindowWidth = window.outerWidth;
   let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
   ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
-  let oldChildCount = navbar.customizationTarget.childElementCount;
+  let oldChildCount = CustomizableUI.getCustomizationTarget(navbar).childElementCount;
   window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
   await waitForCondition(() => navbar.hasAttribute("overflowing"));
   ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
 
-  ok(navbar.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
+  ok(CustomizableUI.getCustomizationTarget(navbar).childElementCount < oldChildCount, "Should have fewer children.");
   let newWindow = await openAndLoadWindow();
   let otherNavBar = newWindow.document.getElementById(CustomizableUI.AREA_NAVBAR);
   await waitForCondition(() => otherNavBar.hasAttribute("overflowing"));
   ok(otherNavBar.hasAttribute("overflowing"), "Other window should have an overflowing toolbar.");
   await promiseWindowClosed(newWindow);
 
   window.resizeTo(originalWindowWidth, window.outerHeight);
   await waitForCondition(() => !navbar.hasAttribute("overflowing"));
--- a/browser/components/customizableui/test/browser_913972_currentset_overflow.js
+++ b/browser/components/customizableui/test/browser_913972_currentset_overflow.js
@@ -10,38 +10,39 @@ registerCleanupFunction(async function a
   await resetCustomization();
 });
 
 // Resize to a small window, resize back, shouldn't affect default state.
 add_task(async function() {
   let originalWindowWidth = window.outerWidth;
   ok(!navbar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
   ok(CustomizableUI.inDefaultState, "Should start in default state.");
-  let oldChildCount = navbar.customizationTarget.childElementCount;
+  let navbarTarget = CustomizableUI.getCustomizationTarget(navbar);
+  let oldChildCount = navbarTarget.childElementCount;
   window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
   await waitForCondition(() => navbar.hasAttribute("overflowing"));
   ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
   ok(CustomizableUI.inDefaultState, "Should still be in default state when overflowing.");
-  ok(navbar.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
+  ok(navbarTarget.childElementCount < oldChildCount, "Should have fewer children.");
   window.resizeTo(originalWindowWidth, window.outerHeight);
   await waitForCondition(() => !navbar.hasAttribute("overflowing"));
   ok(!navbar.hasAttribute("overflowing"), "Should no longer have an overflowing toolbar.");
   ok(CustomizableUI.inDefaultState, "Should still be in default state now we're no longer overflowing.");
 
   // Verify actual physical placements match those of the placement array:
   let placementCounter = 0;
   let placements = CustomizableUI.getWidgetIdsInArea(CustomizableUI.AREA_NAVBAR);
-  for (let node of navbar.customizationTarget.children) {
+  for (let node of navbarTarget.children) {
     if (node.getAttribute("skipintoolbarset") == "true") {
       continue;
     }
     is(placements[placementCounter++], node.id, "Nodes should match after overflow");
   }
   is(placements.length, placementCounter, "Should have as many nodes as expected");
-  is(navbar.customizationTarget.childElementCount, oldChildCount, "Number of nodes should match");
+  is(navbarTarget.childElementCount, oldChildCount, "Number of nodes should match");
 });
 
 // Enter and exit customization mode, check that default state is correct.
 add_task(async function() {
   ok(CustomizableUI.inDefaultState, "Should start in default state.");
   await startCustomizing();
   ok(CustomizableUI.inDefaultState, "Should be in default state in customization mode.");
   await endCustomizing();
--- a/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
+++ b/browser/components/customizableui/test/browser_918049_skipintoolbarset_dnd.js
@@ -10,17 +10,17 @@ var skippedItem;
 // Attempting to drag a skipintoolbarset item should work.
 add_task(async function() {
   navbar = document.getElementById("nav-bar");
   skippedItem = document.createXULElement("toolbarbutton");
   skippedItem.id = "test-skipintoolbarset-item";
   skippedItem.setAttribute("label", "Test");
   skippedItem.setAttribute("skipintoolbarset", "true");
   skippedItem.setAttribute("removable", "true");
-  navbar.customizationTarget.appendChild(skippedItem);
+  CustomizableUI.getCustomizationTarget(navbar).appendChild(skippedItem);
   let libraryButton = document.getElementById("library-button");
   await startCustomizing();
   await waitForElementShown(skippedItem);
   ok(CustomizableUI.inDefaultState, "Should still be in default state");
   simulateItemDrag(skippedItem, libraryButton, "start");
   ok(CustomizableUI.inDefaultState, "Should still be in default state");
   let skippedItemWrapper = skippedItem.parentNode;
   is(skippedItemWrapper.nextElementSibling && skippedItemWrapper.nextElementSibling.id,
--- a/browser/components/customizableui/test/browser_934113_menubar_removable.js
+++ b/browser/components/customizableui/test/browser_934113_menubar_removable.js
@@ -8,17 +8,17 @@
 add_task(async function() {
   await startCustomizing();
   let menuItems = document.getElementById("menubar-items");
   let navbar = document.getElementById("nav-bar");
   let menubar = document.getElementById("toolbar-menubar");
   // Force the menu to be shown.
   const kAutohide = menubar.getAttribute("autohide");
   menubar.setAttribute("autohide", "false");
-  simulateItemDrag(menuItems, navbar.customizationTarget);
+  simulateItemDrag(menuItems, CustomizableUI.getCustomizationTarget(navbar));
 
   is(getAreaWidgetIds("nav-bar").indexOf("menubar-items"), -1, "Menu bar shouldn't be in the navbar.");
   ok(!navbar.querySelector("#menubar-items"), "Shouldn't find menubar items in the navbar.");
   ok(menubar.querySelector("#menubar-items"), "Should find menubar items in the menubar.");
   isnot(getAreaWidgetIds("toolbar-menubar").indexOf("menubar-items"), -1,
         "Menubar items shouldn't be missing from the navbar.");
   menubar.setAttribute("autohide", kAutohide);
   await endCustomizing();
--- a/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js
+++ b/browser/components/customizableui/test/browser_940946_removable_from_navbar_customizemode.js
@@ -4,17 +4,17 @@
 
 "use strict";
 
 const kTestBtnId = "test-removable-navbar-customize-mode";
 
 // Items without the removable attribute in the navbar should be considered non-removable
 add_task(async function() {
   let btn = createDummyXULButton(kTestBtnId, "Test removable in navbar in customize mode");
-  document.getElementById("nav-bar").customizationTarget.appendChild(btn);
+  CustomizableUI.getCustomizationTarget(document.getElementById("nav-bar")).appendChild(btn);
   await startCustomizing();
   ok(!CustomizableUI.isWidgetRemovable(kTestBtnId), "Widget should not be considered removable");
   await endCustomizing();
   document.getElementById(kTestBtnId).remove();
 });
 
 add_task(async function asyncCleanup() {
   await endCustomizing();
--- a/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
+++ b/browser/components/customizableui/test/browser_968565_insert_before_hidden_items.js
@@ -40,17 +40,18 @@ add_task(async function() {
   // Make sure we have some hidden items at the end of the nav-bar.
   CustomizableUI.addWidgetToArea(kHidden1Id, "nav-bar");
   CustomizableUI.addWidgetToArea(kHidden2Id, "nav-bar");
 
   // Drag an item and drop it onto the nav-bar customization target, but
   // not over a particular item.
   await startCustomizing();
   let homeButton = document.getElementById("home-button");
-  simulateItemDrag(homeButton, navbar.customizationTarget, "end");
+  let navbarTarget = CustomizableUI.getCustomizationTarget(navbar);
+  simulateItemDrag(homeButton, navbarTarget, "end");
 
   await endCustomizing();
 
   is(homeButton.previousElementSibling.id, lastVisible.id,
      "The downloads button should be placed after the last visible item.");
 
   await resetCustomization();
 });
--- a/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js
+++ b/browser/components/customizableui/test/browser_976792_insertNodeInWindow.js
@@ -227,21 +227,21 @@ add_task(async function() {
   let originalWindowWidth = window.outerWidth;
   window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
   // Wait for all the widgets to overflow. We can't just wait for the
   // `overflowing` attribute because we leave time for layout flushes
   // inbetween, so it's possible for the timeout to run before the
   // navbar has "settled"
   await waitForCondition(() => {
     return navbar.hasAttribute("overflowing") &&
-      navbar.customizationTarget.lastElementChild.getAttribute("overflows") == "false";
+      CustomizableUI.getCustomizationTarget(navbar).lastElementChild.getAttribute("overflows") == "false";
   });
 
   // Find last widget that doesn't allow overflowing
-  let nonOverflowing = navbar.customizationTarget.lastElementChild;
+  let nonOverflowing = CustomizableUI.getCustomizationTarget(navbar).lastElementChild;
   is(nonOverflowing.getAttribute("overflows"), "false", "Last child is expected to not allow overflowing");
   isnot(nonOverflowing.getAttribute("skipintoolbarset"), "true", "Last child is expected to not be skipintoolbarset");
 
   let testWidgetId = kTestWidgetPrefix + 10;
   CustomizableUI.destroyWidget(testWidgetId);
 
   let btn = createDummyXULButton(testWidgetId, "test");
   CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
--- a/browser/components/customizableui/test/browser_978084_dragEnd_after_move.js
+++ b/browser/components/customizableui/test/browser_978084_dragEnd_after_move.js
@@ -11,35 +11,35 @@ var draggedItem;
 
 // Drop on the palette
 add_task(async function() {
   draggedItem = document.createXULElement("toolbarbutton");
   draggedItem.id = "test-dragEnd-after-move1";
   draggedItem.setAttribute("label", "Test");
   draggedItem.setAttribute("removable", "true");
   let navbar = document.getElementById("nav-bar");
-  navbar.customizationTarget.appendChild(draggedItem);
+  CustomizableUI.getCustomizationTarget(navbar).appendChild(draggedItem);
   await startCustomizing();
   simulateItemDrag(draggedItem, gCustomizeMode.visiblePalette);
   is(document.documentElement.hasAttribute("customizing-movingItem"), false,
      "Make sure customizing-movingItem is removed after dragging to the palette");
   await endCustomizing();
 });
 
 // Drop on a customization target itself
 add_task(async function() {
   draggedItem = document.createXULElement("toolbarbutton");
   draggedItem.id = "test-dragEnd-after-move2";
   draggedItem.setAttribute("label", "Test");
   draggedItem.setAttribute("removable", "true");
   let dest = createToolbarWithPlacements("test-dragEnd");
   let navbar = document.getElementById("nav-bar");
-  navbar.customizationTarget.appendChild(draggedItem);
+  CustomizableUI.getCustomizationTarget(navbar).appendChild(draggedItem);
   await startCustomizing();
-  simulateItemDrag(draggedItem, dest.customizationTarget);
+  simulateItemDrag(draggedItem, CustomizableUI.getCustomizationTarget(dest));
   is(document.documentElement.hasAttribute("customizing-movingItem"), false,
      "Make sure customizing-movingItem is removed");
   await endCustomizing();
 });
 
 add_task(async function asyncCleanup() {
   await endCustomizing();
   await resetCustomization();
--- a/browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js
+++ b/browser/components/customizableui/test/browser_980155_add_overflow_toolbar.js
@@ -21,29 +21,29 @@ add_task(async function addOverflowingTo
   let toolbarNode = createOverflowableToolbarWithPlacements(kToolbarName, widgetIds);
   assertAreaPlacements(kToolbarName, widgetIds);
 
   for (let id of widgetIds) {
     document.getElementById(id).style.minWidth = "200px";
   }
 
   isnot(toolbarNode.overflowable, null, "Toolbar should have overflowable controller");
-  isnot(toolbarNode.customizationTarget, null, "Toolbar should have customization target");
-  isnot(toolbarNode.customizationTarget, toolbarNode, "Customization target should not be toolbar node");
+  isnot(CustomizableUI.getCustomizationTarget(toolbarNode), null, "Toolbar should have customization target");
+  isnot(CustomizableUI.getCustomizationTarget(toolbarNode), toolbarNode, "Customization target should not be toolbar node");
 
-  let oldChildCount = toolbarNode.customizationTarget.childElementCount;
+  let oldChildCount = CustomizableUI.getCustomizationTarget(toolbarNode).childElementCount;
   let overflowableList = document.getElementById(kToolbarName + "-overflow-list");
   let oldOverflowCount = overflowableList.childElementCount;
 
   isnot(oldChildCount, 0, "Toolbar should have non-overflowing widgets");
 
   window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
   await waitForCondition(() => toolbarNode.hasAttribute("overflowing"));
   ok(toolbarNode.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
-  ok(toolbarNode.customizationTarget.childElementCount < oldChildCount, "Should have fewer children.");
+  ok(CustomizableUI.getCustomizationTarget(toolbarNode).childElementCount < oldChildCount, "Should have fewer children.");
   ok(overflowableList.childElementCount > oldOverflowCount, "Should have more overflowed widgets.");
 
   window.resizeTo(originalWindowWidth, window.outerHeight);
 });
 
 
 add_task(async function asyncCleanup() {
   removeCustomToolbars();
--- a/browser/components/customizableui/test/browser_customization_context_menus.js
+++ b/browser/components/customizableui/test/browser_customization_context_menus.js
@@ -426,17 +426,17 @@ add_task(async function custom_context_m
   is(widget.getAttribute("context"), "", "Should not have own context menu in the toolbar now that we're customizing.");
   is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped when in toolbar.");
 
   let panel = document.getElementById("widget-overflow-fixed-list");
   simulateItemDrag(widget, panel);
   is(widget.getAttribute("context"), "", "Should not have own context menu when in the panel.");
   is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped now that we're in the panel.");
 
-  simulateItemDrag(widget, document.getElementById("nav-bar").customizationTarget);
+  simulateItemDrag(widget, CustomizableUI.getCustomizationTarget(document.getElementById("nav-bar")));
   is(widget.getAttribute("context"), "", "Should not have own context menu when back in toolbar because we're still customizing.");
   is(widget.getAttribute("wrapped-context"), expectedContext, "Should keep own context menu wrapped now that we're back in the toolbar.");
 
   await endCustomizing();
   is(widget.getAttribute("context"), expectedContext, "Should have context menu again now that we're out of customize mode.");
   CustomizableUI.removeWidgetFromArea(widgetId);
   widget.remove();
   ok(CustomizableUI.inDefaultState, "Should be in default state after removing button.");
--- a/browser/components/customizableui/test/browser_editcontrols_update.js
+++ b/browser/components/customizableui/test/browser_editcontrols_update.js
@@ -86,17 +86,17 @@ add_task(async function test_panelui_ope
   await overridePromise;
   checkState(true, "Update when edit-controls is on panel, hidden and selection changed");
 });
 
 // Test updating when the edit-controls are moved to the toolbar.
 add_task(async function test_panelui_customize_to_toolbar() {
   await startCustomizing();
   let navbar = document.getElementById("nav-bar");
-  simulateItemDrag(document.getElementById("edit-controls"), navbar.customizationTarget, "end");
+  simulateItemDrag(document.getElementById("edit-controls"), CustomizableUI.getCustomizationTarget(navbar), "end");
   await endCustomizing();
 
   // updateEditUIVisibility should be called when customization ends but isn't. See bug 1359790.
   updateEditUIVisibility();
 
   // The URL bar may have been focused to begin with, which means
   // that subsequent calls to focus it won't result in command
   // updates, so we'll make sure to blur it.
--- a/browser/components/customizableui/test/browser_insert_before_moved_node.js
+++ b/browser/components/customizableui/test/browser_insert_before_moved_node.js
@@ -20,17 +20,17 @@ add_task(async function() {
       gBrowser.tabContainer.appendChild(otherButton);
     }
     CustomizableUI.destroyWidget("real-button");
     CustomizableUI.createWidget({id: "real-button", label: "test real button"});
 
     let button = document.getElementById("real-button");
     ok(button, "Button should exist");
     if (button) {
-      let expectedContainer = document.getElementById(toolbar).customizationTarget;
+      let expectedContainer = CustomizableUI.getCustomizationTarget(document.getElementById(toolbar));
       is(button.parentNode, expectedContainer, "Button should be in the toolbar");
     }
 
     CustomizableUI.destroyWidget("real-button");
     otherButton.remove();
     CustomizableUI.reset();
   }
 });