home *** CD-ROM | disk | FTP | other *** search
/ PC World 2005 December / PCWorld_2005-12_cd.bin / komunikace / netscape / nsb-install-8-0.exe / chrome / toolkit.jar / content / global / nsTransferable.js < prev    next >
Text File  |  2005-09-26  |  12KB  |  327 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: NPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Netscape Public License
  6.  * Version 1.1 (the "License"); you may not use this file except in
  7.  * compliance with the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/NPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is 
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 1998
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Ben Goodger <ben@netscape.com> (Original Author)
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or 
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the NPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the NPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. ////////////////////////////////////////////////////////////////////////////
  40. // XXX - WARNING - DRAG AND DROP API CHANGE ALERT - XXX
  41. // This file has been extensively modified in a checkin planned for Mozilla
  42. // 0.8, and the API has been modified. DO NOT MODIFY THIS FILE without 
  43. // approval from ben@netscape.com, otherwise your changes will be lost. 
  44.  
  45. /** 
  46.  *  nsTransferable - a wrapper for nsITransferable that simplifies
  47.  *                   javascript clipboard and drag&drop. for use in
  48.  *                   these situations you should use the nsClipboard
  49.  *                   and nsDragAndDrop wrappers for more convenience
  50.  **/ 
  51.  
  52. var nsTransferable = {
  53.   /**
  54.    * nsITransferable set (TransferData aTransferData) ;
  55.    *
  56.    * Creates a transferable with data for a list of supported types ("flavours")
  57.    * 
  58.    * @param TransferData aTransferData
  59.    *        a javascript object in the format described above 
  60.    **/ 
  61.   set: function (aTransferDataSet)
  62.     {
  63.       var trans = this.createTransferable();
  64.       for (var i = 0; i < aTransferDataSet.dataList.length; ++i) 
  65.         {
  66.           var currData = aTransferDataSet.dataList[i];
  67.           var currFlavour = currData.flavour.contentType;
  68.           trans.addDataFlavor(currFlavour);
  69.           var supports = null; // nsISupports data
  70.           var length = 0;
  71.           if (currData.flavour.dataIIDKey == "nsISupportsString")
  72.             {
  73.               supports = Components.classes["@mozilla.org/supports-string;1"]
  74.                                    .createInstance(Components.interfaces.nsISupportsString);
  75.  
  76.               supports.data = currData.supports;
  77.               length = supports.data.length;
  78.             }
  79.           else 
  80.             {
  81.               // non-string data.
  82.               supports = currData.supports;
  83.               length = 0; // kFlavorHasDataProvider 
  84.             }
  85.           trans.setTransferData(currFlavour, supports, length * 2);
  86.         }
  87.       return trans;
  88.     },
  89.   
  90.   /**
  91.    * TransferData/TransferDataSet get (FlavourSet aFlavourSet, 
  92.    *                                   Function aRetrievalFunc, Boolean aAnyFlag) ;
  93.    *
  94.    * Retrieves data from the transferable provided in aRetrievalFunc, formatted
  95.    * for more convenient access.
  96.    *
  97.    * @param FlavourSet aFlavourSet
  98.    *        a FlavourSet object that contains a list of supported flavours.
  99.    * @param Function aRetrievalFunc
  100.    *        a reference to a function that returns a nsISupportsArray of nsITransferables
  101.    *        for each item from the specified source (clipboard/drag&drop etc)
  102.    * @param Boolean aAnyFlag
  103.    *        a flag specifying whether or not a specific flavour is requested. If false,
  104.    *        data of the type of the first flavour in the flavourlist parameter is returned,
  105.    *        otherwise the best flavour supported will be returned.
  106.    **/
  107.   get: function (aFlavourSet, aRetrievalFunc, aAnyFlag)
  108.     {
  109.       if (!aRetrievalFunc) 
  110.         throw "No data retrieval handler provided!";
  111.       
  112.       var supportsArray = aRetrievalFunc(aFlavourSet);
  113.       var dataArray = [];
  114.       var count = supportsArray.Count();
  115.       
  116.       // Iterate over the number of items returned from aRetrievalFunc. For
  117.       // clipboard operations, this is 1, for drag and drop (where multiple
  118.       // items may have been dragged) this could be >1.
  119.       for (var i = 0; i < count; i++)
  120.         {
  121.           var trans = supportsArray.GetElementAt(i);
  122.           if (!trans) continue;
  123.           trans = trans.QueryInterface(Components.interfaces.nsITransferable);
  124.             
  125.           var data = { };
  126.           var length = { };
  127.           
  128.           var currData = null;
  129.           if (aAnyFlag)
  130.             { 
  131.               var flavour = { };
  132.               trans.getAnyTransferData(flavour, data, length);
  133.               if (data && flavour)
  134.                 {
  135.                   var selectedFlavour = aFlavourSet.flavourTable[flavour.value];
  136.                   if (selectedFlavour) 
  137.                     dataArray[i] = FlavourToXfer(data.value, length.value, selectedFlavour);
  138.                 }
  139.             }
  140.           else
  141.             {
  142.               var firstFlavour = aFlavourSet.flavours[0];
  143.               trans.getTransferData(firstFlavour, data, length);
  144.               if (data && firstFlavour)
  145.                 dataArray[i] = FlavourToXfer(data.value, length.value, firstFlavour);
  146.             }
  147.         }
  148.       return new TransferDataSet(dataArray);
  149.     },
  150.  
  151.   /** 
  152.    * nsITransferable createTransferable (void) ;
  153.    *
  154.    * Creates and returns a transferable object.
  155.    **/    
  156.   createTransferable: function ()
  157.     {
  158.       const kXferableContractID = "@mozilla.org/widget/transferable;1";
  159.       const kXferableIID = Components.interfaces.nsITransferable;
  160.       return Components.classes[kXferableContractID].createInstance(kXferableIID);
  161.     }
  162. };  
  163.  
  164. /** 
  165.  * A FlavourSet is a simple type that represents a collection of Flavour objects.
  166.  * FlavourSet is constructed from an array of Flavours, and stores this list as
  167.  * an array and a hashtable. The rationale for the dual storage is as follows:
  168.  * 
  169.  * Array: Ordering is important when adding data flavours to a transferable. 
  170.  *        Flavours added first are deemed to be 'preferred' by the client. 
  171.  * Hash:  Convenient lookup of flavour data using the content type (MIME type)
  172.  *        of data as a key. 
  173.  */
  174. function FlavourSet(aFlavourList)
  175. {
  176.   this.flavours = aFlavourList || [];
  177.   this.flavourTable = { };
  178.  
  179.   this._XferID = "FlavourSet";
  180.   
  181.   for (var i = 0; i < this.flavours.length; ++i)
  182.     this.flavourTable[this.flavours[i].contentType] = this.flavours[i];
  183. }
  184.  
  185. FlavourSet.prototype = {
  186.   appendFlavour: function (aFlavour, aFlavourIIDKey)
  187.   {
  188.     var flavour = new Flavour (aFlavour, aFlavourIIDKey);
  189.     this.flavours.push(flavour);
  190.     this.flavourTable[flavour.contentType] = flavour;
  191.   }
  192. };
  193.  
  194. /** 
  195.  * A Flavour is a simple type that represents a data type that can be handled. 
  196.  * It takes a content type (MIME type) which is used when storing data on the
  197.  * system clipboard/drag and drop, and an IIDKey (string interface name
  198.  * which is used to QI data to an appropriate form. The default interface is
  199.  * assumed to be wide-string.
  200.  */ 
  201. function Flavour(aContentType, aDataIIDKey)
  202. {
  203.   this.contentType = aContentType;
  204.   this.dataIIDKey = aDataIIDKey || "nsISupportsString";
  205.  
  206.   this._XferID = "Flavour";
  207. }
  208.  
  209. function TransferDataBase() {}
  210. TransferDataBase.prototype = {
  211.   push: function (aItems)
  212.   {
  213.     this.dataList.push(aItems);
  214.   },
  215.  
  216.   get first ()
  217.   {
  218.     return "dataList" in this && this.dataList.length ? this.dataList[0] : null;
  219.   }
  220. };
  221.  
  222. /** 
  223.  * TransferDataSet is a list (array) of TransferData objects, which represents
  224.  * data dragged from one or more elements. 
  225.  */
  226. function TransferDataSet(aTransferDataList)
  227. {
  228.   this.dataList = aTransferDataList || [];
  229.  
  230.   this._XferID = "TransferDataSet";
  231. }
  232. TransferDataSet.prototype = TransferDataBase.prototype;
  233.  
  234. /** 
  235.  * TransferData is a list (array) of FlavourData for all the applicable content
  236.  * types associated with a drag from a single item. 
  237.  */
  238. function TransferData(aFlavourDataList)
  239. {
  240.   this.dataList = aFlavourDataList || [];
  241.  
  242.   this._XferID = "TransferData";
  243. }
  244. TransferData.prototype = {
  245.   __proto__: TransferDataBase.prototype,
  246.   
  247.   addDataForFlavour: function (aFlavourString, aData, aLength, aDataIIDKey)
  248.   {
  249.     this.dataList.push(new FlavourData(aData, aLength, 
  250.                        new Flavour(aFlavourString, aDataIIDKey)));
  251.   }
  252. };
  253.  
  254. /** 
  255.  * FlavourData is a type that represents data retrieved from the system 
  256.  * clipboard or drag and drop. It is constructed internally by the Transferable
  257.  * using the raw (nsISupports) data from the clipboard, the length of the data,
  258.  * and an object of type Flavour representing the type. Clients implementing
  259.  * IDragDropObserver receive an object of this type in their implementation of
  260.  * onDrop. They access the 'data' property to retrieve data, which is either data 
  261.  * QI'ed to a usable form, or unicode string. 
  262.  */
  263. function FlavourData(aData, aLength, aFlavour) 
  264. {
  265.   this.supports = aData;
  266.   this.contentLength = aLength;
  267.   this.flavour = aFlavour || null;
  268.   
  269.   this._XferID = "FlavourData";
  270. }
  271.  
  272. FlavourData.prototype = {
  273.   get data ()
  274.   {
  275.     if (this.flavour && 
  276.         this.flavour.dataIIDKey != "nsISupportsString" )
  277.       return this.supports.QueryInterface(Components.interfaces[this.flavour.dataIIDKey]); 
  278.     else {
  279.       var unicode = this.supports.QueryInterface(Components.interfaces.nsISupportsString);
  280.       if (unicode) 
  281.         return unicode.data.substring(0, this.contentLength/2);
  282.      
  283.       return this.supports;
  284.     }
  285.     return "";
  286.   }
  287. }
  288.  
  289. /** 
  290.  * Create a TransferData object with a single FlavourData entry. Used when 
  291.  * unwrapping data of a specific flavour from the drag service. 
  292.  */
  293. function FlavourToXfer(aData, aLength, aFlavour) 
  294. {
  295.   return new TransferData([new FlavourData(aData, aLength, aFlavour)]);
  296. }
  297.  
  298. var transferUtils = {
  299.  
  300.   retrieveURLFromData: function (aData, flavour)
  301.   {
  302.     switch (flavour) {
  303.       case "text/unicode":
  304.         return aData;
  305.       case "text/x-moz-url":
  306.         return aData.toString().split("\n")[0];
  307.       case "application/x-moz-file":
  308.         var ioService = Components.classes["@mozilla.org/network/io-service;1"]
  309.                                   .getService(Components.interfaces.nsIIOService);
  310.         var fileHandler = ioService.getProtocolHandler("file")
  311.                                    .QueryInterface(Components.interfaces.nsIFileProtocolHandler);
  312.         return fileHandler.getURLSpecFromFile(aData);
  313.     }
  314.     return null;                                                   
  315.   }
  316.  
  317. }
  318.  
  319. /*
  320. function DUMP_obj (aObj) 
  321. {
  322.   for (var i in aObj)
  323.     dump("*** aObj[" + i + "] = " + aObj[i] + "\n");
  324. }
  325. */
  326.  
  327.