Bug 1442377 - Move fillSubviewFromMenuItems/clearSubview to CustomizableUI.jsm. r?Gijs
MozReview-Commit-ID: BQ8V39C68WO
--- a/browser/components/customizableui/CustomizableUI.jsm
+++ b/browser/components/customizableui/CustomizableUI.jsm
@@ -3895,16 +3895,96 @@ var CustomizableUI = {
/**
* Create an instance of a spring, spacer or separator.
* @param aId the type of special widget (spring, spacer or separator)
* @param aDocument the document in which to create it.
*/
createSpecialWidget(aId, aDocument) {
return CustomizableUIInternal.createSpecialWidget(aId, aDocument);
},
+
+ /**
+ * Fills a submenu with menu items.
+ * @param aMenuItems the menu items to display.
+ * @param aSubview the subview to fill.
+ */
+ fillSubviewFromMenuItems(aMenuItems, aSubview) {
+ let attrs = ["oncommand", "onclick", "label", "key", "disabled",
+ "command", "observes", "hidden", "class", "origin",
+ "image", "checked", "style"];
+
+ let doc = aSubview.ownerDocument;
+ let fragment = doc.createDocumentFragment();
+ for (let menuChild of aMenuItems) {
+ if (menuChild.hidden)
+ continue;
+
+ let subviewItem;
+ if (menuChild.localName == "menuseparator") {
+ // Don't insert duplicate or leading separators. This can happen if there are
+ // menus (which we don't copy) above the separator.
+ if (!fragment.lastChild || fragment.lastChild.localName == "menuseparator") {
+ continue;
+ }
+ subviewItem = doc.createElementNS(kNSXUL, "menuseparator");
+ } else if (menuChild.localName == "menuitem") {
+ subviewItem = doc.createElementNS(kNSXUL, "toolbarbutton");
+ CustomizableUI.addShortcut(menuChild, subviewItem);
+
+ let item = menuChild;
+ if (!item.hasAttribute("onclick")) {
+ subviewItem.addEventListener("click", event => {
+ let newEvent = new doc.defaultView.MouseEvent(event.type, event);
+ item.dispatchEvent(newEvent);
+ });
+ }
+
+ if (!item.hasAttribute("oncommand")) {
+ subviewItem.addEventListener("command", event => {
+ let newEvent = doc.createEvent("XULCommandEvent");
+ newEvent.initCommandEvent(
+ event.type, event.bubbles, event.cancelable, event.view,
+ event.detail, event.ctrlKey, event.altKey, event.shiftKey,
+ event.metaKey, event.sourceEvent, 0);
+ item.dispatchEvent(newEvent);
+ });
+ }
+ } else {
+ continue;
+ }
+ for (let attr of attrs) {
+ let attrVal = menuChild.getAttribute(attr);
+ if (attrVal)
+ subviewItem.setAttribute(attr, attrVal);
+ }
+ // We do this after so the .subviewbutton class doesn't get overriden.
+ if (menuChild.localName == "menuitem") {
+ subviewItem.classList.add("subviewbutton");
+ }
+ fragment.appendChild(subviewItem);
+ }
+ aSubview.appendChild(fragment);
+ },
+
+ /**
+ * A helper function for clearing subviews.
+ * @param aSubview the subview to clear.
+ */
+ clearSubview(aSubview) {
+ let parent = aSubview.parentNode;
+ // We'll take the container out of the document before cleaning it out
+ // to avoid reflowing each time we remove something.
+ parent.removeChild(aSubview);
+
+ while (aSubview.firstChild) {
+ aSubview.firstChild.remove();
+ }
+
+ parent.appendChild(aSubview);
+ },
};
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.
*/
--- a/browser/components/customizableui/CustomizableWidgets.jsm
+++ b/browser/components/customizableui/CustomizableWidgets.jsm
@@ -70,87 +70,16 @@ function setAttributes(aNode, aAttrs) {
}
value = CustomizableUI.getLocalizedProperty({id: aAttrs.id}, stringId, additionalArgs);
}
aNode.setAttribute(name, value);
}
}
}
-function fillSubviewFromMenuItems(aMenuItems, aSubview) {
- let attrs = ["oncommand", "onclick", "label", "key", "disabled",
- "command", "observes", "hidden", "class", "origin",
- "image", "checked", "style"];
-
- let doc = aSubview.ownerDocument;
- let fragment = doc.createDocumentFragment();
- for (let menuChild of aMenuItems) {
- if (menuChild.hidden)
- continue;
-
- let subviewItem;
- if (menuChild.localName == "menuseparator") {
- // Don't insert duplicate or leading separators. This can happen if there are
- // menus (which we don't copy) above the separator.
- if (!fragment.lastChild || fragment.lastChild.localName == "menuseparator") {
- continue;
- }
- subviewItem = doc.createElementNS(kNSXUL, "menuseparator");
- } else if (menuChild.localName == "menuitem") {
- subviewItem = doc.createElementNS(kNSXUL, "toolbarbutton");
- CustomizableUI.addShortcut(menuChild, subviewItem);
-
- let item = menuChild;
- if (!item.hasAttribute("onclick")) {
- subviewItem.addEventListener("click", event => {
- let newEvent = new doc.defaultView.MouseEvent(event.type, event);
- item.dispatchEvent(newEvent);
- });
- }
-
- if (!item.hasAttribute("oncommand")) {
- subviewItem.addEventListener("command", event => {
- let newEvent = doc.createEvent("XULCommandEvent");
- newEvent.initCommandEvent(
- event.type, event.bubbles, event.cancelable, event.view,
- event.detail, event.ctrlKey, event.altKey, event.shiftKey,
- event.metaKey, event.sourceEvent, 0);
- item.dispatchEvent(newEvent);
- });
- }
- } else {
- continue;
- }
- for (let attr of attrs) {
- let attrVal = menuChild.getAttribute(attr);
- if (attrVal)
- subviewItem.setAttribute(attr, attrVal);
- }
- // We do this after so the .subviewbutton class doesn't get overriden.
- if (menuChild.localName == "menuitem") {
- subviewItem.classList.add("subviewbutton");
- }
- fragment.appendChild(subviewItem);
- }
- aSubview.appendChild(fragment);
-}
-
-function clearSubview(aSubview) {
- let parent = aSubview.parentNode;
- // We'll take the container out of the document before cleaning it out
- // to avoid reflowing each time we remove something.
- parent.removeChild(aSubview);
-
- while (aSubview.firstChild) {
- aSubview.firstChild.remove();
- }
-
- parent.appendChild(aSubview);
-}
-
const CustomizableWidgets = [
{
id: "history-panelmenu",
type: "view",
viewId: "PanelUI-history",
shortcutId: "key_gotoHistory",
tooltiptext: "history-panelmenu.tooltiptext2",
recentlyClosedTabsPanel: "appMenu-library-recentlyClosedTabs",
--- a/devtools/shim/devtools-startup.js
+++ b/devtools/shim/devtools-startup.js
@@ -392,21 +392,18 @@ DevToolsStartup.prototype = {
let menu = doc.getElementById("menuWebDeveloperPopup");
let itemsToDisplay = [...menu.children];
// Hardcode the addition of the "work offline" menuitem at the bottom:
itemsToDisplay.push({localName: "menuseparator", getAttribute: () => {}});
itemsToDisplay.push(doc.getElementById("goOfflineMenuitem"));
let developerItems = doc.getElementById("PanelUI-developerItems");
- // Import private helpers from CustomizableWidgets
- let { clearSubview, fillSubviewFromMenuItems } =
- ChromeUtils.import("resource:///modules/CustomizableWidgets.jsm", {});
- clearSubview(developerItems);
- fillSubviewFromMenuItems(itemsToDisplay, developerItems);
+ CustomizableUI.clearSubview(developerItems);
+ CustomizableUI.fillSubviewFromMenuItems(itemsToDisplay, developerItems);
},
onInit(anchor) {
// Since onBeforeCreated already bails out when initialized, we can call
// it right away.
this.onBeforeCreated(anchor.ownerDocument);
},
onBeforeCreated: (doc) => {
// The developer toggle needs the "key_toggleToolbox" <key> element.