summaryrefslogtreecommitdiffstats
path: root/application/palemoon/modules/PageMenu.jsm
diff options
context:
space:
mode:
Diffstat (limited to 'application/palemoon/modules/PageMenu.jsm')
-rw-r--r--application/palemoon/modules/PageMenu.jsm238
1 files changed, 0 insertions, 238 deletions
diff --git a/application/palemoon/modules/PageMenu.jsm b/application/palemoon/modules/PageMenu.jsm
deleted file mode 100644
index d01f62601..000000000
--- a/application/palemoon/modules/PageMenu.jsm
+++ /dev/null
@@ -1,238 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-this.EXPORTED_SYMBOLS = ["PageMenu"];
-
-this.PageMenu = function PageMenu() {
-}
-
-PageMenu.prototype = {
- PAGEMENU_ATTR: "pagemenu",
- GENERATEDITEMID_ATTR: "generateditemid",
-
- _popup: null,
- _builder: null,
-
- // Given a target node, get the context menu for it or its ancestor.
- getContextMenu: function(aTarget) {
- let target = aTarget;
- while (target) {
- let contextMenu = target.contextMenu;
- if (contextMenu) {
- return contextMenu;
- }
- target = target.parentNode;
- }
-
- return null;
- },
-
- // Given a target node, generate a JSON object for any context menu
- // associated with it, or null if there is no context menu.
- maybeBuild: function(aTarget) {
- let pageMenu = this.getContextMenu(aTarget);
- if (!pageMenu) {
- return null;
- }
-
- pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
- pageMenu.sendShowEvent();
- // the show event is not cancelable, so no need to check a result here
-
- this._builder = pageMenu.createBuilder();
- if (!this._builder) {
- return null;
- }
-
- pageMenu.build(this._builder);
-
- // This serializes then parses again, however this could be avoided in
- // the single-process case with further improvement.
- let menuString = this._builder.toJSONString();
- if (!menuString) {
- return null;
- }
-
- return JSON.parse(menuString);
- },
-
- // Given a JSON menu object and popup, add the context menu to the popup.
- buildAndAttachMenuWithObject: function(aMenu, aBrowser, aPopup) {
- if (!aMenu) {
- return false;
- }
-
- let insertionPoint = this.getInsertionPoint(aPopup);
- if (!insertionPoint) {
- return false;
- }
-
- let fragment = aPopup.ownerDocument.createDocumentFragment();
- this.buildXULMenu(aMenu, fragment);
-
- let pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
- if (pos == "start") {
- insertionPoint.insertBefore(fragment,
- insertionPoint.firstChild);
- } else if (pos.startsWith("#")) {
- insertionPoint.insertBefore(fragment, insertionPoint.querySelector(pos));
- } else {
- insertionPoint.appendChild(fragment);
- }
-
- this._popup = aPopup;
-
- this._popup.addEventListener("command", this);
- this._popup.addEventListener("popuphidden", this);
-
- return true;
- },
-
- // Construct the XUL menu structure for a given JSON object.
- buildXULMenu: function(aNode, aElementForAppending) {
- let document = aElementForAppending.ownerDocument;
-
- let children = aNode.children;
- for (let child of children) {
- let menuitem;
- switch (child.type) {
- case "menuitem":
- if (!child.id) {
- continue; // Ignore children without ids
- }
-
- menuitem = document.createElement("menuitem");
- if (child.checkbox) {
- menuitem.setAttribute("type", "checkbox");
- if (child.checked) {
- menuitem.setAttribute("checked", "true");
- }
- }
-
- if (child.label) {
- menuitem.setAttribute("label", child.label);
- }
- if (child.icon) {
- menuitem.setAttribute("image", child.icon);
- menuitem.className = "menuitem-iconic";
- }
- if (child.disabled) {
- menuitem.setAttribute("disabled", true);
- }
-
- break;
-
- case "separator":
- menuitem = document.createElement("menuseparator");
- break;
-
- case "menu":
- menuitem = document.createElement("menu");
- if (child.label) {
- menuitem.setAttribute("label", child.label);
- }
-
- let menupopup = document.createElement("menupopup");
- menuitem.appendChild(menupopup);
-
- this.buildXULMenu(child, menupopup);
- break;
- }
-
- menuitem.setAttribute(this.GENERATEDITEMID_ATTR, child.id ? child.id : 0);
- aElementForAppending.appendChild(menuitem);
- }
- },
-
- // Called when the generated menuitem is executed.
- handleEvent: function(event) {
- let type = event.type;
- let target = event.target;
- if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
- // If a builder is assigned, call click on it directly. Otherwise, this is
- // likely a menu with data from another process, so send a message to the
- // browser to execute the menuitem.
- if (this._builder) {
- this._builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
- }
- } else if (type == "popuphidden" && this._popup == target) {
- this.removeGeneratedContent(this._popup);
-
- this._popup.removeEventListener("popuphidden", this);
- this._popup.removeEventListener("command", this);
-
- this._popup = null;
- this._builder = null;
- }
- },
-
- // Get the first child of the given element with the given tag name.
- getImmediateChild: function(element, tag) {
- let child = element.firstChild;
- while (child) {
- if (child.localName == tag) {
- return child;
- }
- child = child.nextSibling;
- }
- return null;
- },
-
- // Return the location where the generated items should be inserted into the
- // given popup. They should be inserted as the next sibling of the returned
- // element.
- getInsertionPoint: function(aPopup) {
- if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
- return aPopup;
-
- let element = aPopup.firstChild;
- while (element) {
- if (element.localName == "menu") {
- let popup = this.getImmediateChild(element, "menupopup");
- if (popup) {
- let result = this.getInsertionPoint(popup);
- if (result) {
- return result;
- }
- }
- }
- element = element.nextSibling;
- }
-
- return null;
- },
-
- // Returns true if custom menu items were present.
- maybeBuildAndAttachMenu: function(aTarget, aPopup) {
- let menuObject = this.maybeBuild(aTarget);
- if (!menuObject) {
- return false;
- }
-
- return this.buildAndAttachMenuWithObject(menuObject, null, aPopup);
- },
-
- // Remove the generated content from the given popup.
- removeGeneratedContent: function(aPopup) {
- let ungenerated = [];
- ungenerated.push(aPopup);
-
- let count;
- while (0 != (count = ungenerated.length)) {
- let last = count - 1;
- let element = ungenerated[last];
- ungenerated.splice(last, 1);
-
- let i = element.childNodes.length;
- while (i-- > 0) {
- let child = element.childNodes[i];
- if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
- ungenerated.push(child);
- continue;
- }
- element.removeChild(child);
- }
- }
- }
-}