1 /* See license.txt for terms of usage */
  2 
  3 define([
  4     "firebug/lib/object",
  5     "firebug/lib/xpcom",
  6 ],
  7 function(Obj, Xpcom) {
  8 
  9 // ********************************************************************************************* //
 10 // Constants
 11 
 12 var Cc = Components.classes;
 13 var Ci = Components.interfaces;
 14 
 15 var clipboard = Xpcom.CCSV("@mozilla.org/widget/clipboard;1", "nsIClipboard");
 16 var versionChecker = Xpcom.CCSV("@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator");
 17 var appInfo = Xpcom.CCSV("@mozilla.org/xre/app-info;1", "nsIXULAppInfo");
 18 
 19 // ********************************************************************************************* //
 20 // Clipboard helper
 21 
 22 /**
 23  * @class This class implements clibpoard functionality.
 24  */
 25 var CookieClipboard = Obj.extend(Object,
 26 /** @lends CookieClipboard */
 27 {
 28     cookieFlavour: "text/firebug-cookie",
 29     unicodeFlavour: "text/unicode",
 30 
 31     copyTo: function(cookie)
 32     {
 33         try
 34         {
 35             var trans = this.createTransferData(cookie);
 36             if (trans && clipboard)
 37                 clipboard.setData(trans, null, Ci.nsIClipboard.kGlobalClipboard);
 38         }
 39         catch (err)
 40         {
 41             if (FBTrace.DBG_ERRORS)
 42                 FBTrace.sysout("cookies.CookieClipboard.copyTo; EXCEPTION " + err, err);
 43         }
 44     },
 45 
 46     getFrom: function()
 47     {
 48         try
 49         {
 50             var str = this.getTransferData();
 51 
 52             if (FBTrace.DBG_COOKIES)
 53                 FBTrace.sysout("cookies.Get Cookie data from clipboard: " + str);
 54 
 55             return parseFromJSON(str);
 56         }
 57         catch (err)
 58         {
 59             if (FBTrace.DBG_ERRORS)
 60                 FBTrace.sysout("cookies.CookieClipboard.getFrom; EXCEPTION " + err, err);
 61         }
 62 
 63         return null;
 64     },
 65 
 66     isCookieAvailable: function()
 67     {
 68         try
 69         {
 70             if (!clipboard)
 71                 return false;
 72 
 73             // nsIClipboard interface has been changed in FF3.
 74             if (versionChecker.compare(appInfo.version, "3.0*") >= 0)
 75             {
 76                 // FF3
 77                 return clipboard.hasDataMatchingFlavors([this.cookieFlavour], 1,
 78                     Ci.nsIClipboard.kGlobalClipboard);
 79             }
 80             else
 81             {
 82                 // FF2
 83                 var array = Xpcom.CCIN("@mozilla.org/supports-array;1", "nsISupportsArray");
 84                 var element = Xpcom.CCIN("@mozilla.org/supports-cstring;1", "nsISupportsCString");
 85                 element.data = this.cookieFlavour;
 86                 array.AppendElement(element);
 87                 return clipboard.hasDataMatchingFlavors(array, Ci.nsIClipboard.kGlobalClipboard);
 88             }
 89         }
 90         catch (err)
 91         {
 92             if (FBTrace.DBG_ERRORS)
 93                 FBTrace.sysout("cookies.isCookieAvailable; EXCEPTION " + err, err);
 94         }
 95 
 96         return false;
 97     },
 98 
 99     createTransferData: function(cookie)
100     {
101         var trans = Xpcom.CCIN("@mozilla.org/widget/transferable;1", "nsITransferable");
102 
103         // See https://bugzilla.mozilla.org/show_bug.cgi?id=722872
104         if (typeof(trans.init) == "function")
105             trans.init(null);
106 
107         var json = cookie.toJSON();
108         var wrapper1 = Xpcom.CCIN("@mozilla.org/supports-string;1", "nsISupportsString");
109         wrapper1.data = json;
110         trans.addDataFlavor(this.cookieFlavour);
111         trans.setTransferData(this.cookieFlavour, wrapper1, json.length * 2);
112 
113         if (FBTrace.DBG_COOKIES)
114             FBTrace.sysout("cookies.Create JSON transfer data : " + json, cookie);
115 
116         var str = cookie.toString();
117         var wrapper2 = Xpcom.CCIN("@mozilla.org/supports-string;1", "nsISupportsString");
118         wrapper2.data = str;
119         trans.addDataFlavor(this.unicodeFlavour);
120         trans.setTransferData(this.unicodeFlavour, wrapper2, str.length * 2);
121 
122         if (FBTrace.DBG_COOKIES)
123             FBTrace.sysout("cookies.Create string transfer data : " + str, cookie);
124 
125         return trans;
126     },
127 
128     getTransferData: function()
129     {
130         var trans = Xpcom.CCIN("@mozilla.org/widget/transferable;1", "nsITransferable");
131 
132         // See https://bugzilla.mozilla.org/show_bug.cgi?id=722872
133         if (typeof(trans.init) == "function")
134             trans.init(null);
135 
136         trans.addDataFlavor(this.cookieFlavour);
137 
138         clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
139 
140         var str = new Object();
141         var strLength = new Object();
142 
143         trans.getTransferData(this.cookieFlavour, str, strLength);
144 
145         if (!str.value) 
146             return null;
147 
148         str = str.value.QueryInterface(Ci.nsISupportsString);
149         return str.data.substring(0, strLength.value / 2);
150     }
151 });
152 
153 // ********************************************************************************************* //
154 // Helpers
155 
156 function parseFromJSON(json)
157 {
158     try
159     {
160         // Parse JSON string. In case of Firefox 3.5 the native support is used,
161         // otherwise the cookie clipboard doesn't work.
162         return JSON.parse(json);
163     }
164     catch (err)
165     {
166         if (FBTrace.DBG_ERRORS || FBTrace.DBG_COOKIES)
167             FBTrace.sysout("Failed to parse a cookie from JSON data: " + err, err);
168     }
169 
170     return null;
171 }
172 
173 // ********************************************************************************************* //
174 // Registration
175 
176 return CookieClipboard;
177 
178 // ********************************************************************************************* //
179 });
180 
181