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.

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

mercurial