toolkit/modules/PageMenu.jsm

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 this.EXPORTED_SYMBOLS = ["PageMenu"];
michael@0 6
michael@0 7 this.PageMenu = function PageMenu() {
michael@0 8 }
michael@0 9
michael@0 10 PageMenu.prototype = {
michael@0 11 PAGEMENU_ATTR: "pagemenu",
michael@0 12 GENERATEDITEMID_ATTR: "generateditemid",
michael@0 13
michael@0 14 popup: null,
michael@0 15 builder: null,
michael@0 16
michael@0 17 maybeBuildAndAttachMenu: function(aTarget, aPopup) {
michael@0 18 var pageMenu = null;
michael@0 19 var target = aTarget;
michael@0 20 while (target) {
michael@0 21 var contextMenu = target.contextMenu;
michael@0 22 if (contextMenu) {
michael@0 23 pageMenu = contextMenu;
michael@0 24 break;
michael@0 25 }
michael@0 26 target = target.parentNode;
michael@0 27 }
michael@0 28
michael@0 29 if (!pageMenu) {
michael@0 30 return false;
michael@0 31 }
michael@0 32
michael@0 33 var insertionPoint = this.getInsertionPoint(aPopup);
michael@0 34 if (!insertionPoint) {
michael@0 35 return false;
michael@0 36 }
michael@0 37
michael@0 38 pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
michael@0 39 pageMenu.sendShowEvent();
michael@0 40 // the show event is not cancelable, so no need to check a result here
michael@0 41
michael@0 42 var fragment = aPopup.ownerDocument.createDocumentFragment();
michael@0 43
michael@0 44 var builder = pageMenu.createBuilder();
michael@0 45 if (!builder) {
michael@0 46 return false;
michael@0 47 }
michael@0 48 builder.QueryInterface(Components.interfaces.nsIXULContextMenuBuilder);
michael@0 49 builder.init(fragment, this.GENERATEDITEMID_ATTR);
michael@0 50
michael@0 51 pageMenu.build(builder);
michael@0 52
michael@0 53 var pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
michael@0 54 if (pos == "start") {
michael@0 55 insertionPoint.insertBefore(fragment,
michael@0 56 insertionPoint.firstChild);
michael@0 57 } else {
michael@0 58 insertionPoint.appendChild(fragment);
michael@0 59 }
michael@0 60
michael@0 61 this.builder = builder;
michael@0 62 this.popup = aPopup;
michael@0 63
michael@0 64 this.popup.addEventListener("command", this);
michael@0 65 this.popup.addEventListener("popuphidden", this);
michael@0 66
michael@0 67 return true;
michael@0 68 },
michael@0 69
michael@0 70 handleEvent: function(event) {
michael@0 71 var type = event.type;
michael@0 72 var target = event.target;
michael@0 73 if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
michael@0 74 this.builder.click(target.getAttribute(this.GENERATEDITEMID_ATTR));
michael@0 75 } else if (type == "popuphidden" && this.popup == target) {
michael@0 76 this.removeGeneratedContent(this.popup);
michael@0 77
michael@0 78 this.popup.removeEventListener("popuphidden", this);
michael@0 79 this.popup.removeEventListener("command", this);
michael@0 80
michael@0 81 this.popup = null;
michael@0 82 this.builder = null;
michael@0 83 }
michael@0 84 },
michael@0 85
michael@0 86 getImmediateChild: function(element, tag) {
michael@0 87 var child = element.firstChild;
michael@0 88 while (child) {
michael@0 89 if (child.localName == tag) {
michael@0 90 return child;
michael@0 91 }
michael@0 92 child = child.nextSibling;
michael@0 93 }
michael@0 94 return null;
michael@0 95 },
michael@0 96
michael@0 97 getInsertionPoint: function(aPopup) {
michael@0 98 if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
michael@0 99 return aPopup;
michael@0 100
michael@0 101 var element = aPopup.firstChild;
michael@0 102 while (element) {
michael@0 103 if (element.localName == "menu") {
michael@0 104 var popup = this.getImmediateChild(element, "menupopup");
michael@0 105 if (popup) {
michael@0 106 var result = this.getInsertionPoint(popup);
michael@0 107 if (result) {
michael@0 108 return result;
michael@0 109 }
michael@0 110 }
michael@0 111 }
michael@0 112 element = element.nextSibling;
michael@0 113 }
michael@0 114
michael@0 115 return null;
michael@0 116 },
michael@0 117
michael@0 118 removeGeneratedContent: function(aPopup) {
michael@0 119 var ungenerated = [];
michael@0 120 ungenerated.push(aPopup);
michael@0 121
michael@0 122 var count;
michael@0 123 while (0 != (count = ungenerated.length)) {
michael@0 124 var last = count - 1;
michael@0 125 var element = ungenerated[last];
michael@0 126 ungenerated.splice(last, 1);
michael@0 127
michael@0 128 var i = element.childNodes.length;
michael@0 129 while (i-- > 0) {
michael@0 130 var child = element.childNodes[i];
michael@0 131 if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
michael@0 132 ungenerated.push(child);
michael@0 133 continue;
michael@0 134 }
michael@0 135 element.removeChild(child);
michael@0 136 }
michael@0 137 }
michael@0 138 }
michael@0 139 }

mercurial