content/base/src/contentAreaDropListener.js

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     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 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
     7 const Cc = Components.classes;
     8 const Ci = Components.interfaces;
    10 // This component is used for handling dragover and drop of urls.
    11 //
    12 // It checks to see whether a drop of a url is allowed. For instance, a url
    13 // cannot be dropped if it is not a valid uri or the source of the drag cannot
    14 // access the uri. This prevents, for example, a source document from tricking
    15 // the user into dragging a chrome url.
    17 function ContentAreaDropListener() { };
    19 ContentAreaDropListener.prototype =
    20 {
    21   classID:          Components.ID("{1f34bc80-1bc7-11d6-a384-d705dd0746fc}"),
    22   QueryInterface:   XPCOMUtils.generateQI([Ci.nsIDroppedLinkHandler, Ci.nsISupports]),
    24   _getDropURL : function (dt)
    25   {
    26     let types = dt.types;
    27     for (let t = 0; t < types.length; t++) {
    28       let type = types[t];
    29       switch (type) {
    30         case "text/uri-list":
    31           var url = dt.getData("URL").replace(/^\s+|\s+$/g, "");
    32           return [url, url];
    33         case "text/plain":
    34         case "text/x-moz-text-internal":
    35           var url = dt.getData(type).replace(/^\s+|\s+$/g, "");
    36           return [url, url];
    37         case "text/x-moz-url":
    38           return dt.getData(type).split("\n");
    39       }
    40     }
    42     // For shortcuts, we want to check for the file type last, so that the
    43     // url pointed to in one of the url types is found first before the file
    44     // type, which points to the actual file.
    45     let file = dt.mozGetDataAt("application/x-moz-file", 0);
    46     if (file instanceof Ci.nsIFile) {
    47       let ioService = Cc["@mozilla.org/network/io-service;1"].
    48                         getService(Ci.nsIIOService);
    49       let fileHandler = ioService.getProtocolHandler("file")
    50                                  .QueryInterface(Ci.nsIFileProtocolHandler);
    51       return [fileHandler.getURLSpecFromFile(file), file.leafName];
    52     }
    54     return [ ];
    55   },
    57   _validateURI: function(dataTransfer, uriString, disallowInherit)
    58   {
    59     if (!uriString)
    60       return "";
    62     // Strip leading and trailing whitespace, then try to create a
    63     // URI from the dropped string. If that succeeds, we're
    64     // dropping a URI and we need to do a security check to make
    65     // sure the source document can load the dropped URI.
    66     uriString = uriString.replace(/^\s*|\s*$/g, '');
    68     let uri;
    69     let ioService = Cc["@mozilla.org/network/io-service;1"]
    70                       .getService(Components.interfaces.nsIIOService);
    71     try {
    72       // Check that the uri is valid first and return an empty string if not.
    73       // It may just be plain text and should be ignored here
    74       uri = ioService.newURI(uriString, null, null);
    75     } catch (ex) { }
    76     if (!uri)
    77       return uriString;
    79     // uriString is a valid URI, so do the security check.
    80     let secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
    81                    getService(Ci.nsIScriptSecurityManager);
    82     let sourceNode = dataTransfer.mozSourceNode;
    83     let flags = secMan.STANDARD;
    84     if (disallowInherit)
    85       flags |= secMan.DISALLOW_INHERIT_PRINCIPAL;
    87     // Use file:/// as the default uri so that drops of file URIs are always allowed
    88     let principal = sourceNode ? sourceNode.nodePrincipal
    89                                : secMan.getSimpleCodebasePrincipal(ioService.newURI("file:///", null, null));
    91     secMan.checkLoadURIStrWithPrincipal(principal, uriString, flags);
    93     return uriString;
    94   },
    96   canDropLink: function(aEvent, aAllowSameDocument)
    97   {
    98     if (this._eventTargetIsDisabled(aEvent))
    99       return false;
   101     let dataTransfer = aEvent.dataTransfer;
   102     let types = dataTransfer.types;
   103     if (!types.contains("application/x-moz-file") &&
   104         !types.contains("text/x-moz-url") &&
   105         !types.contains("text/uri-list") &&
   106         !types.contains("text/x-moz-text-internal") &&
   107         !types.contains("text/plain"))
   108       return false;
   110     if (aAllowSameDocument)
   111       return true;
   113     let sourceNode = dataTransfer.mozSourceNode;
   114     if (!sourceNode)
   115       return true;
   117     // don't allow a drop of a node from the same document onto this one
   118     let sourceDocument = sourceNode.ownerDocument;
   119     let eventDocument = aEvent.originalTarget.ownerDocument;
   120     if (sourceDocument == eventDocument)
   121       return false;
   123     // also check for nodes in other child or sibling frames by checking
   124     // if both have the same top window.
   125     if (sourceDocument && eventDocument) {
   126       let sourceRoot = sourceDocument.defaultView.top;
   127       if (sourceRoot && sourceRoot == eventDocument.defaultView.top)
   128         return false;
   129     }
   131     return true;
   132   },
   134   dropLink: function(aEvent, aName, aDisallowInherit)
   135   {
   136     aName.value = "";
   137     if (this._eventTargetIsDisabled(aEvent))
   138       return "";
   140     let dataTransfer = aEvent.dataTransfer;
   141     let [url, name] = this._getDropURL(dataTransfer);
   143     try {
   144       url = this._validateURI(dataTransfer, url, aDisallowInherit);
   145     } catch (ex) {
   146       aEvent.stopPropagation();
   147       aEvent.preventDefault();
   148       throw ex;
   149     }
   151     if (name)
   152       aName.value = name;
   154     return url;
   155   },
   157   _eventTargetIsDisabled: function(aEvent)
   158   {
   159     let ownerDoc = aEvent.originalTarget.ownerDocument;
   160     if (!ownerDoc || !ownerDoc.defaultView)
   161       return false;
   163     return ownerDoc.defaultView
   164                    .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
   165                    .getInterface(Components.interfaces.nsIDOMWindowUtils)
   166                    .isNodeDisabledForEvents(aEvent.originalTarget);
   167   }
   168 };
   170 var components = [ContentAreaDropListener];
   171 this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

mercurial