1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/content/nsDragAndDrop.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,604 @@ 1.4 +// -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +//////////////////////////////////////////////////////////////////////// 1.11 +// 1.12 +// USE OF THIS API FOR DRAG AND DROP IS DEPRECATED! 1.13 +// Do not use this file for new code. 1.14 +// 1.15 +// For documentation about what to use instead, see: 1.16 +// http://developer.mozilla.org/En/DragDrop/Drag_and_Drop 1.17 +// 1.18 +//////////////////////////////////////////////////////////////////////// 1.19 + 1.20 + 1.21 +/** 1.22 + * nsTransferable - a wrapper for nsITransferable that simplifies 1.23 + * javascript clipboard and drag&drop. for use in 1.24 + * these situations you should use the nsClipboard 1.25 + * and nsDragAndDrop wrappers for more convenience 1.26 + **/ 1.27 + 1.28 +var nsTransferable = { 1.29 + /** 1.30 + * nsITransferable set (TransferData aTransferData) ; 1.31 + * 1.32 + * Creates a transferable with data for a list of supported types ("flavours") 1.33 + * 1.34 + * @param TransferData aTransferData 1.35 + * a javascript object in the format described above 1.36 + **/ 1.37 + set: function (aTransferDataSet) 1.38 + { 1.39 + var trans = this.createTransferable(); 1.40 + for (var i = 0; i < aTransferDataSet.dataList.length; ++i) 1.41 + { 1.42 + var currData = aTransferDataSet.dataList[i]; 1.43 + var currFlavour = currData.flavour.contentType; 1.44 + trans.addDataFlavor(currFlavour); 1.45 + var supports = null; // nsISupports data 1.46 + var length = 0; 1.47 + if (currData.flavour.dataIIDKey == "nsISupportsString") 1.48 + { 1.49 + supports = Components.classes["@mozilla.org/supports-string;1"] 1.50 + .createInstance(Components.interfaces.nsISupportsString); 1.51 + 1.52 + supports.data = currData.supports; 1.53 + length = supports.data.length; 1.54 + } 1.55 + else 1.56 + { 1.57 + // non-string data. 1.58 + supports = currData.supports; 1.59 + length = 0; // kFlavorHasDataProvider 1.60 + } 1.61 + trans.setTransferData(currFlavour, supports, length * 2); 1.62 + } 1.63 + return trans; 1.64 + }, 1.65 + 1.66 + /** 1.67 + * TransferData/TransferDataSet get (FlavourSet aFlavourSet, 1.68 + * Function aRetrievalFunc, Boolean aAnyFlag) ; 1.69 + * 1.70 + * Retrieves data from the transferable provided in aRetrievalFunc, formatted 1.71 + * for more convenient access. 1.72 + * 1.73 + * @param FlavourSet aFlavourSet 1.74 + * a FlavourSet object that contains a list of supported flavours. 1.75 + * @param Function aRetrievalFunc 1.76 + * a reference to a function that returns a nsISupportsArray of nsITransferables 1.77 + * for each item from the specified source (clipboard/drag&drop etc) 1.78 + * @param Boolean aAnyFlag 1.79 + * a flag specifying whether or not a specific flavour is requested. If false, 1.80 + * data of the type of the first flavour in the flavourlist parameter is returned, 1.81 + * otherwise the best flavour supported will be returned. 1.82 + **/ 1.83 + get: function (aFlavourSet, aRetrievalFunc, aAnyFlag) 1.84 + { 1.85 + if (!aRetrievalFunc) 1.86 + throw "No data retrieval handler provided!"; 1.87 + 1.88 + var supportsArray = aRetrievalFunc(aFlavourSet); 1.89 + var dataArray = []; 1.90 + var count = supportsArray.Count(); 1.91 + 1.92 + // Iterate over the number of items returned from aRetrievalFunc. For 1.93 + // clipboard operations, this is 1, for drag and drop (where multiple 1.94 + // items may have been dragged) this could be >1. 1.95 + for (var i = 0; i < count; i++) 1.96 + { 1.97 + var trans = supportsArray.GetElementAt(i); 1.98 + if (!trans) continue; 1.99 + trans = trans.QueryInterface(Components.interfaces.nsITransferable); 1.100 + 1.101 + var data = { }; 1.102 + var length = { }; 1.103 + 1.104 + var currData = null; 1.105 + if (aAnyFlag) 1.106 + { 1.107 + var flavour = { }; 1.108 + trans.getAnyTransferData(flavour, data, length); 1.109 + if (data && flavour) 1.110 + { 1.111 + var selectedFlavour = aFlavourSet.flavourTable[flavour.value]; 1.112 + if (selectedFlavour) 1.113 + dataArray[i] = FlavourToXfer(data.value, length.value, selectedFlavour); 1.114 + } 1.115 + } 1.116 + else 1.117 + { 1.118 + var firstFlavour = aFlavourSet.flavours[0]; 1.119 + trans.getTransferData(firstFlavour, data, length); 1.120 + if (data && firstFlavour) 1.121 + dataArray[i] = FlavourToXfer(data.value, length.value, firstFlavour); 1.122 + } 1.123 + } 1.124 + return new TransferDataSet(dataArray); 1.125 + }, 1.126 + 1.127 + /** 1.128 + * nsITransferable createTransferable (void) ; 1.129 + * 1.130 + * Creates and returns a transferable object. 1.131 + **/ 1.132 + createTransferable: function () 1.133 + { 1.134 + const kXferableContractID = "@mozilla.org/widget/transferable;1"; 1.135 + const kXferableIID = Components.interfaces.nsITransferable; 1.136 + var trans = Components.classes[kXferableContractID].createInstance(kXferableIID); 1.137 + trans.init(null); 1.138 + return trans; 1.139 + } 1.140 +}; 1.141 + 1.142 +/** 1.143 + * A FlavourSet is a simple type that represents a collection of Flavour objects. 1.144 + * FlavourSet is constructed from an array of Flavours, and stores this list as 1.145 + * an array and a hashtable. The rationale for the dual storage is as follows: 1.146 + * 1.147 + * Array: Ordering is important when adding data flavours to a transferable. 1.148 + * Flavours added first are deemed to be 'preferred' by the client. 1.149 + * Hash: Convenient lookup of flavour data using the content type (MIME type) 1.150 + * of data as a key. 1.151 + */ 1.152 +function FlavourSet(aFlavourList) 1.153 +{ 1.154 + this.flavours = aFlavourList || []; 1.155 + this.flavourTable = { }; 1.156 + 1.157 + this._XferID = "FlavourSet"; 1.158 + 1.159 + for (var i = 0; i < this.flavours.length; ++i) 1.160 + this.flavourTable[this.flavours[i].contentType] = this.flavours[i]; 1.161 +} 1.162 + 1.163 +FlavourSet.prototype = { 1.164 + appendFlavour: function (aFlavour, aFlavourIIDKey) 1.165 + { 1.166 + var flavour = new Flavour (aFlavour, aFlavourIIDKey); 1.167 + this.flavours.push(flavour); 1.168 + this.flavourTable[flavour.contentType] = flavour; 1.169 + } 1.170 +}; 1.171 + 1.172 +/** 1.173 + * A Flavour is a simple type that represents a data type that can be handled. 1.174 + * It takes a content type (MIME type) which is used when storing data on the 1.175 + * system clipboard/drag and drop, and an IIDKey (string interface name 1.176 + * which is used to QI data to an appropriate form. The default interface is 1.177 + * assumed to be wide-string. 1.178 + */ 1.179 +function Flavour(aContentType, aDataIIDKey) 1.180 +{ 1.181 + this.contentType = aContentType; 1.182 + this.dataIIDKey = aDataIIDKey || "nsISupportsString"; 1.183 + 1.184 + this._XferID = "Flavour"; 1.185 +} 1.186 + 1.187 +function TransferDataBase() {} 1.188 +TransferDataBase.prototype = { 1.189 + push: function (aItems) 1.190 + { 1.191 + this.dataList.push(aItems); 1.192 + }, 1.193 + 1.194 + get first () 1.195 + { 1.196 + return "dataList" in this && this.dataList.length ? this.dataList[0] : null; 1.197 + } 1.198 +}; 1.199 + 1.200 +/** 1.201 + * TransferDataSet is a list (array) of TransferData objects, which represents 1.202 + * data dragged from one or more elements. 1.203 + */ 1.204 +function TransferDataSet(aTransferDataList) 1.205 +{ 1.206 + this.dataList = aTransferDataList || []; 1.207 + 1.208 + this._XferID = "TransferDataSet"; 1.209 +} 1.210 +TransferDataSet.prototype = TransferDataBase.prototype; 1.211 + 1.212 +/** 1.213 + * TransferData is a list (array) of FlavourData for all the applicable content 1.214 + * types associated with a drag from a single item. 1.215 + */ 1.216 +function TransferData(aFlavourDataList) 1.217 +{ 1.218 + this.dataList = aFlavourDataList || []; 1.219 + 1.220 + this._XferID = "TransferData"; 1.221 +} 1.222 +TransferData.prototype = { 1.223 + __proto__: TransferDataBase.prototype, 1.224 + 1.225 + addDataForFlavour: function (aFlavourString, aData, aLength, aDataIIDKey) 1.226 + { 1.227 + this.dataList.push(new FlavourData(aData, aLength, 1.228 + new Flavour(aFlavourString, aDataIIDKey))); 1.229 + } 1.230 +}; 1.231 + 1.232 +/** 1.233 + * FlavourData is a type that represents data retrieved from the system 1.234 + * clipboard or drag and drop. It is constructed internally by the Transferable 1.235 + * using the raw (nsISupports) data from the clipboard, the length of the data, 1.236 + * and an object of type Flavour representing the type. Clients implementing 1.237 + * IDragDropObserver receive an object of this type in their implementation of 1.238 + * onDrop. They access the 'data' property to retrieve data, which is either data 1.239 + * QI'ed to a usable form, or unicode string. 1.240 + */ 1.241 +function FlavourData(aData, aLength, aFlavour) 1.242 +{ 1.243 + this.supports = aData; 1.244 + this.contentLength = aLength; 1.245 + this.flavour = aFlavour || null; 1.246 + 1.247 + this._XferID = "FlavourData"; 1.248 +} 1.249 + 1.250 +FlavourData.prototype = { 1.251 + get data () 1.252 + { 1.253 + if (this.flavour && 1.254 + this.flavour.dataIIDKey != "nsISupportsString") 1.255 + return this.supports.QueryInterface(Components.interfaces[this.flavour.dataIIDKey]); 1.256 + 1.257 + var supports = this.supports; 1.258 + if (supports instanceof Components.interfaces.nsISupportsString) 1.259 + return supports.data.substring(0, this.contentLength/2); 1.260 + 1.261 + return supports; 1.262 + } 1.263 +} 1.264 + 1.265 +/** 1.266 + * Create a TransferData object with a single FlavourData entry. Used when 1.267 + * unwrapping data of a specific flavour from the drag service. 1.268 + */ 1.269 +function FlavourToXfer(aData, aLength, aFlavour) 1.270 +{ 1.271 + return new TransferData([new FlavourData(aData, aLength, aFlavour)]); 1.272 +} 1.273 + 1.274 +var transferUtils = { 1.275 + 1.276 + retrieveURLFromData: function (aData, flavour) 1.277 + { 1.278 + switch (flavour) { 1.279 + case "text/unicode": 1.280 + case "text/plain": 1.281 + case "text/x-moz-text-internal": 1.282 + return aData.replace(/^\s+|\s+$/g, ""); 1.283 + case "text/x-moz-url": 1.284 + return ((aData instanceof Components.interfaces.nsISupportsString) ? aData.toString() : aData).split("\n")[0]; 1.285 + case "application/x-moz-file": 1.286 + var ioService = Components.classes["@mozilla.org/network/io-service;1"] 1.287 + .getService(Components.interfaces.nsIIOService); 1.288 + var fileHandler = ioService.getProtocolHandler("file") 1.289 + .QueryInterface(Components.interfaces.nsIFileProtocolHandler); 1.290 + return fileHandler.getURLSpecFromFile(aData); 1.291 + } 1.292 + return null; 1.293 + } 1.294 + 1.295 +} 1.296 + 1.297 +/** 1.298 + * nsDragAndDrop - a convenience wrapper for nsTransferable, nsITransferable 1.299 + * and nsIDragService/nsIDragSession. 1.300 + * 1.301 + * Use: map the handler functions to the 'ondraggesture', 'ondragover' and 1.302 + * 'ondragdrop' event handlers on your XML element, e.g. 1.303 + * <xmlelement ondraggesture="nsDragAndDrop.startDrag(event, observer);" 1.304 + * ondragover="nsDragAndDrop.dragOver(event, observer);" 1.305 + * ondragdrop="nsDragAndDrop.drop(event, observer);"/> 1.306 + * 1.307 + * You need to create an observer js object with the following member 1.308 + * functions: 1.309 + * Object onDragStart (event) // called when drag initiated, 1.310 + * // returns flavour list with data 1.311 + * // to stuff into transferable 1.312 + * void onDragOver (Object flavour) // called when element is dragged 1.313 + * // over, so that it can perform 1.314 + * // any drag-over feedback for provided 1.315 + * // flavour 1.316 + * void onDrop (Object data) // formatted data object dropped. 1.317 + * Object getSupportedFlavours () // returns a flavour list so that 1.318 + * // nsTransferable can determine 1.319 + * // whether or not to accept drop. 1.320 + **/ 1.321 + 1.322 +var nsDragAndDrop = { 1.323 + 1.324 + _mDS: null, 1.325 + get mDragService() 1.326 + { 1.327 + if (!this._mDS) 1.328 + { 1.329 + const kDSContractID = "@mozilla.org/widget/dragservice;1"; 1.330 + const kDSIID = Components.interfaces.nsIDragService; 1.331 + this._mDS = Components.classes[kDSContractID].getService(kDSIID); 1.332 + } 1.333 + return this._mDS; 1.334 + }, 1.335 + 1.336 + /** 1.337 + * void startDrag (DOMEvent aEvent, Object aDragDropObserver) ; 1.338 + * 1.339 + * called when a drag on an element is started. 1.340 + * 1.341 + * @param DOMEvent aEvent 1.342 + * the DOM event fired by the drag init 1.343 + * @param Object aDragDropObserver 1.344 + * javascript object of format described above that specifies 1.345 + * the way in which the element responds to drag events. 1.346 + **/ 1.347 + startDrag: function (aEvent, aDragDropObserver) 1.348 + { 1.349 + if (!("onDragStart" in aDragDropObserver)) 1.350 + return; 1.351 + 1.352 + const kDSIID = Components.interfaces.nsIDragService; 1.353 + var dragAction = { action: kDSIID.DRAGDROP_ACTION_COPY + kDSIID.DRAGDROP_ACTION_MOVE + kDSIID.DRAGDROP_ACTION_LINK }; 1.354 + 1.355 + var transferData = { data: null }; 1.356 + try 1.357 + { 1.358 + aDragDropObserver.onDragStart(aEvent, transferData, dragAction); 1.359 + } 1.360 + catch (e) 1.361 + { 1.362 + return; // not a draggable item, bail! 1.363 + } 1.364 + 1.365 + if (!transferData.data) return; 1.366 + transferData = transferData.data; 1.367 + 1.368 + var dt = aEvent.dataTransfer; 1.369 + var count = 0; 1.370 + do { 1.371 + var tds = transferData._XferID == "TransferData" 1.372 + ? transferData 1.373 + : transferData.dataList[count] 1.374 + for (var i = 0; i < tds.dataList.length; ++i) 1.375 + { 1.376 + var currData = tds.dataList[i]; 1.377 + var currFlavour = currData.flavour.contentType; 1.378 + var value = currData.supports; 1.379 + if (value instanceof Components.interfaces.nsISupportsString) 1.380 + value = value.toString(); 1.381 + dt.mozSetDataAt(currFlavour, value, count); 1.382 + } 1.383 + 1.384 + count++; 1.385 + } 1.386 + while (transferData._XferID == "TransferDataSet" && 1.387 + count < transferData.dataList.length); 1.388 + 1.389 + dt.effectAllowed = "all"; 1.390 + // a drag targeted at a tree should instead use the treechildren so that 1.391 + // the current selection is used as the drag feedback 1.392 + dt.addElement(aEvent.originalTarget.localName == "treechildren" ? 1.393 + aEvent.originalTarget : aEvent.target); 1.394 + aEvent.stopPropagation(); 1.395 + }, 1.396 + 1.397 + /** 1.398 + * void dragOver (DOMEvent aEvent, Object aDragDropObserver) ; 1.399 + * 1.400 + * called when a drag passes over this element 1.401 + * 1.402 + * @param DOMEvent aEvent 1.403 + * the DOM event fired by passing over the element 1.404 + * @param Object aDragDropObserver 1.405 + * javascript object of format described above that specifies 1.406 + * the way in which the element responds to drag events. 1.407 + **/ 1.408 + dragOver: function (aEvent, aDragDropObserver) 1.409 + { 1.410 + if (!("onDragOver" in aDragDropObserver)) 1.411 + return; 1.412 + if (!this.checkCanDrop(aEvent, aDragDropObserver)) 1.413 + return; 1.414 + var flavourSet = aDragDropObserver.getSupportedFlavours(); 1.415 + for (var flavour in flavourSet.flavourTable) 1.416 + { 1.417 + if (this.mDragSession.isDataFlavorSupported(flavour)) 1.418 + { 1.419 + aDragDropObserver.onDragOver(aEvent, 1.420 + flavourSet.flavourTable[flavour], 1.421 + this.mDragSession); 1.422 + aEvent.stopPropagation(); 1.423 + aEvent.preventDefault(); 1.424 + break; 1.425 + } 1.426 + } 1.427 + }, 1.428 + 1.429 + mDragSession: null, 1.430 + 1.431 + /** 1.432 + * void drop (DOMEvent aEvent, Object aDragDropObserver) ; 1.433 + * 1.434 + * called when the user drops on the element 1.435 + * 1.436 + * @param DOMEvent aEvent 1.437 + * the DOM event fired by the drop 1.438 + * @param Object aDragDropObserver 1.439 + * javascript object of format described above that specifies 1.440 + * the way in which the element responds to drag events. 1.441 + **/ 1.442 + drop: function (aEvent, aDragDropObserver) 1.443 + { 1.444 + if (!("onDrop" in aDragDropObserver)) 1.445 + return; 1.446 + if (!this.checkCanDrop(aEvent, aDragDropObserver)) 1.447 + return; 1.448 + 1.449 + var flavourSet = aDragDropObserver.getSupportedFlavours(); 1.450 + 1.451 + var dt = aEvent.dataTransfer; 1.452 + var dataArray = []; 1.453 + var count = dt.mozItemCount; 1.454 + for (var i = 0; i < count; ++i) { 1.455 + var types = dt.mozTypesAt(i); 1.456 + for (var j = 0; j < flavourSet.flavours.length; j++) { 1.457 + var type = flavourSet.flavours[j].contentType; 1.458 + // dataTransfer uses text/plain but older code used text/unicode, so 1.459 + // switch this for compatibility 1.460 + var modtype = (type == "text/unicode") ? "text/plain" : type; 1.461 + if (Array.indexOf(types, modtype) >= 0) { 1.462 + var data = dt.mozGetDataAt(modtype, i); 1.463 + if (data) { 1.464 + // Non-strings need some non-zero value used for their data length. 1.465 + const kNonStringDataLength = 4; 1.466 + 1.467 + var length = (typeof data == "string") ? data.length : kNonStringDataLength; 1.468 + dataArray[i] = FlavourToXfer(data, length, flavourSet.flavourTable[type]); 1.469 + break; 1.470 + } 1.471 + } 1.472 + } 1.473 + } 1.474 + 1.475 + var transferData = new TransferDataSet(dataArray) 1.476 + 1.477 + // hand over to the client to respond to dropped data 1.478 + var multiple = "canHandleMultipleItems" in aDragDropObserver && aDragDropObserver.canHandleMultipleItems; 1.479 + var dropData = multiple ? transferData : transferData.first.first; 1.480 + aDragDropObserver.onDrop(aEvent, dropData, this.mDragSession); 1.481 + aEvent.stopPropagation(); 1.482 + }, 1.483 + 1.484 + /** 1.485 + * void dragExit (DOMEvent aEvent, Object aDragDropObserver) ; 1.486 + * 1.487 + * called when a drag leaves this element 1.488 + * 1.489 + * @param DOMEvent aEvent 1.490 + * the DOM event fired by leaving the element 1.491 + * @param Object aDragDropObserver 1.492 + * javascript object of format described above that specifies 1.493 + * the way in which the element responds to drag events. 1.494 + **/ 1.495 + dragExit: function (aEvent, aDragDropObserver) 1.496 + { 1.497 + if (!this.checkCanDrop(aEvent, aDragDropObserver)) 1.498 + return; 1.499 + if ("onDragExit" in aDragDropObserver) 1.500 + aDragDropObserver.onDragExit(aEvent, this.mDragSession); 1.501 + }, 1.502 + 1.503 + /** 1.504 + * void dragEnter (DOMEvent aEvent, Object aDragDropObserver) ; 1.505 + * 1.506 + * called when a drag enters in this element 1.507 + * 1.508 + * @param DOMEvent aEvent 1.509 + * the DOM event fired by entering in the element 1.510 + * @param Object aDragDropObserver 1.511 + * javascript object of format described above that specifies 1.512 + * the way in which the element responds to drag events. 1.513 + **/ 1.514 + dragEnter: function (aEvent, aDragDropObserver) 1.515 + { 1.516 + if (!this.checkCanDrop(aEvent, aDragDropObserver)) 1.517 + return; 1.518 + if ("onDragEnter" in aDragDropObserver) 1.519 + aDragDropObserver.onDragEnter(aEvent, this.mDragSession); 1.520 + }, 1.521 + 1.522 + /** 1.523 + * Boolean checkCanDrop (DOMEvent aEvent, Object aDragDropObserver) ; 1.524 + * 1.525 + * Sets the canDrop attribute for the drag session. 1.526 + * returns false if there is no current drag session. 1.527 + * 1.528 + * @param DOMEvent aEvent 1.529 + * the DOM event fired by the drop 1.530 + * @param Object aDragDropObserver 1.531 + * javascript object of format described above that specifies 1.532 + * the way in which the element responds to drag events. 1.533 + **/ 1.534 + checkCanDrop: function (aEvent, aDragDropObserver) 1.535 + { 1.536 + if (!this.mDragSession) 1.537 + this.mDragSession = this.mDragService.getCurrentSession(); 1.538 + if (!this.mDragSession) 1.539 + return false; 1.540 + this.mDragSession.canDrop = this.mDragSession.sourceNode != aEvent.target; 1.541 + if ("canDrop" in aDragDropObserver) 1.542 + this.mDragSession.canDrop &= aDragDropObserver.canDrop(aEvent, this.mDragSession); 1.543 + return true; 1.544 + }, 1.545 + 1.546 + /** 1.547 + * Do a security check for drag n' drop. Make sure the source document 1.548 + * can load the dragged link. 1.549 + * 1.550 + * @param DOMEvent aEvent 1.551 + * the DOM event fired by leaving the element 1.552 + * @param Object aDragDropObserver 1.553 + * javascript object of format described above that specifies 1.554 + * the way in which the element responds to drag events. 1.555 + * @param String aDraggedText 1.556 + * the text being dragged 1.557 + **/ 1.558 + dragDropSecurityCheck: function (aEvent, aDragSession, aDraggedText) 1.559 + { 1.560 + // Strip leading and trailing whitespace, then try to create a 1.561 + // URI from the dropped string. If that succeeds, we're 1.562 + // dropping a URI and we need to do a security check to make 1.563 + // sure the source document can load the dropped URI. We don't 1.564 + // so much care about creating the real URI here 1.565 + // (i.e. encoding differences etc don't matter), we just want 1.566 + // to know if aDraggedText really is a URI. 1.567 + 1.568 + aDraggedText = aDraggedText.replace(/^\s*|\s*$/g, ''); 1.569 + 1.570 + var uri; 1.571 + var ioService = Components.classes["@mozilla.org/network/io-service;1"] 1.572 + .getService(Components.interfaces.nsIIOService); 1.573 + try { 1.574 + uri = ioService.newURI(aDraggedText, null, null); 1.575 + } catch (e) { 1.576 + } 1.577 + 1.578 + if (!uri) 1.579 + return; 1.580 + 1.581 + // aDraggedText is a URI, do the security check. 1.582 + const nsIScriptSecurityManager = Components.interfaces 1.583 + .nsIScriptSecurityManager; 1.584 + var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"] 1.585 + .getService(nsIScriptSecurityManager); 1.586 + 1.587 + if (!aDragSession) 1.588 + aDragSession = this.mDragService.getCurrentSession(); 1.589 + 1.590 + var sourceDoc = aDragSession.sourceDocument; 1.591 + // Use "file:///" as the default sourceURI so that drops of file:// URIs 1.592 + // are always allowed. 1.593 + var principal = sourceDoc ? sourceDoc.nodePrincipal 1.594 + : secMan.getSimpleCodebasePrincipal(ioService.newURI("file:///", null, null)); 1.595 + 1.596 + try { 1.597 + secMan.checkLoadURIStrWithPrincipal(principal, aDraggedText, 1.598 + nsIScriptSecurityManager.STANDARD); 1.599 + } catch (e) { 1.600 + // Stop event propagation right here. 1.601 + aEvent.stopPropagation(); 1.602 + 1.603 + throw "Drop of " + aDraggedText + " denied."; 1.604 + } 1.605 + } 1.606 +}; 1.607 +