/toolkit/content/PageMenu.jsm
http://github.com/zpao/v8monkey · Unknown · 170 lines · 145 code · 25 blank · 0 comment · 0 complexity · db3c56cbe3556f6983825cf27bf775e9 MD5 · raw file
- # ***** BEGIN LICENSE BLOCK *****
- # Version: MPL 1.1/GPL 2.0/LGPL 2.1
- #
- # The contents of this file are subject to the Mozilla Public License Version
- # 1.1 (the "License"); you may not use this file except in compliance with
- # the License. You may obtain a copy of the License at
- # http://www.mozilla.org/MPL/
- #
- # Software distributed under the License is distributed on an "AS IS" basis,
- # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- # for the specific language governing rights and limitations under the
- # License.
- #
- # The Original Code is Mozilla code.
- #
- # The Initial Developer of the Original Code is Mozilla Foundation
- # Portions created by the Initial Developer are Copyright (C) 2011
- # the Initial Developer. All Rights Reserved.
- #
- # Contributor(s):
- #
- # Alternatively, the contents of this file may be used under the terms of
- # either the GNU General Public License Version 2 or later (the "GPL"), or
- # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- # in which case the provisions of the GPL or the LGPL are applicable instead
- # of those above. If you wish to allow use of your version of this file only
- # under the terms of either the GPL or the LGPL, and not to allow others to
- # use your version of this file under the terms of the MPL, indicate your
- # decision by deleting the provisions above and replace them with the notice
- # and other provisions required by the LGPL or the GPL. If you do not delete
- # the provisions above, a recipient may use your version of this file under
- # the terms of any one of the MPL, the GPL or the LGPL.
- #
- # ***** END LICENSE BLOCK ***** -->
- let EXPORTED_SYMBOLS = ["PageMenu"];
- function PageMenu() {
- }
- PageMenu.prototype = {
- PAGEMENU_ATTR: "pagemenu",
- GENERATEDITEMID_ATTR: "generateditemid",
- popup: null,
- builder: null,
- maybeBuildAndAttachMenu: function(aTarget, aPopup) {
- var pageMenu = null;
- var target = aTarget;
- while (target) {
- var contextMenu = target.contextMenu;
- if (contextMenu) {
- pageMenu = contextMenu;
- break;
- }
- target = target.parentNode;
- }
- if (!pageMenu) {
- return false;
- }
- var insertionPoint = this.getInsertionPoint(aPopup);
- if (!insertionPoint) {
- return false;
- }
- pageMenu.QueryInterface(Components.interfaces.nsIHTMLMenu);
- pageMenu.sendShowEvent();
- // the show event is not cancelable, so no need to check a result here
- var fragment = aPopup.ownerDocument.createDocumentFragment();
- var builder = pageMenu.createBuilder();
- if (!builder) {
- return false;
- }
- builder.QueryInterface(Components.interfaces.nsIXULContextMenuBuilder);
- builder.init(fragment, this.GENERATEDITEMID_ATTR);
- pageMenu.build(builder);
- var pos = insertionPoint.getAttribute(this.PAGEMENU_ATTR);
- if (pos == "start") {
- insertionPoint.insertBefore(fragment,
- insertionPoint.firstChild);
- } else {
- insertionPoint.appendChild(fragment);
- }
- this.builder = builder;
- this.popup = aPopup;
- this.popup.addEventListener("command", this);
- this.popup.addEventListener("popuphidden", this);
- return true;
- },
- handleEvent: function(event) {
- var type = event.type;
- var target = event.target;
- if (type == "command" && target.hasAttribute(this.GENERATEDITEMID_ATTR)) {
- 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;
- }
- },
- getImmediateChild: function(element, tag) {
- var child = element.firstChild;
- while (child) {
- if (child.localName == tag) {
- return child;
- }
- child = child.nextSibling;
- }
- return null;
- },
- getInsertionPoint: function(aPopup) {
- if (aPopup.hasAttribute(this.PAGEMENU_ATTR))
- return aPopup;
- var element = aPopup.firstChild;
- while (element) {
- if (element.localName == "menu") {
- var popup = this.getImmediateChild(element, "menupopup");
- if (popup) {
- var result = this.getInsertionPoint(popup);
- if (result) {
- return result;
- }
- }
- }
- element = element.nextSibling;
- }
- return null;
- },
- removeGeneratedContent: function(aPopup) {
- var ungenerated = [];
- ungenerated.push(aPopup);
- var count;
- while (0 != (count = ungenerated.length)) {
- var last = count - 1;
- var element = ungenerated[last];
- ungenerated.splice(last, 1);
- var i = element.childNodes.length;
- while (i-- > 0) {
- var child = element.childNodes[i];
- if (!child.hasAttribute(this.GENERATEDITEMID_ATTR)) {
- ungenerated.push(child);
- continue;
- }
- element.removeChild(child);
- }
- }
- }
- }