1 /* See license.txt for terms of usage */ 2 3 define([ 4 "firebug/lib/locale", 5 "firebug/lib/xpcom", 6 "firebug/cookies/cookie", 7 ], 8 function(Locale, Xpcom, Cookie) { 9 10 // ********************************************************************************************* // 11 // Constants 12 13 const Cc = Components.classes; 14 const Ci = Components.interfaces; 15 16 const windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator); 17 18 // ********************************************************************************************* // 19 20 const ioService = Xpcom.CCSV("@mozilla.org/network/io-service;1", "nsIIOService"); 21 const versionChecker = Xpcom.CCSV("@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator"); 22 const appInfo = Xpcom.CCSV("@mozilla.org/xre/app-info;1", "nsIXULAppInfo"); 23 const prompts = Xpcom.CCSV("@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService"); 24 25 // ********************************************************************************************* // 26 27 /** 28 * @dialog Edit cookie dialog implementation. This dialog is used to create a new cookie 29 * and edit an existing cookies. 30 */ 31 function EditCookie(win) 32 { 33 this.window = win; 34 } 35 36 EditCookie.prototype = 37 { 38 cookie: null, 39 40 onLoad: function() 41 { 42 this.createDateTimeField(); 43 44 var params = this.window.arguments[0]; 45 this.params = params; 46 this.cookie = params.cookie; 47 48 this.nameNode = $("fcName", this.window); 49 this.valueNode = $("fcValue", this.window); 50 this.domainNode = $("fcDomain", this.window); 51 this.pathNode = $("fcPath", this.window); 52 this.expireNode = $("fcExpire", this.window); 53 this.sessionNode = $("fcSession", this.window); 54 this.secureNode = $("fcSecure", this.window); 55 this.httpOnly = $("fcHttpOnly", this.window); 56 this.URLEncodeValue = $("fbURLEncodeValue", this.window); 57 58 // Fix for issue 39: decode cookie name and value for usage in the dialog. 59 // It'll be encoded again when OK is pressed. 60 // Don't escape using encodeURIComponent sinc "+" would be changed, but 61 // it's valid replacement for space. 62 // This is also necessary for issue 45. 63 this.nameNode.value = unescape(this.cookie.name); 64 this.valueNode.value = unescape(this.cookie.rawValue); 65 66 this.domainNode.value = this.cookie.host; 67 this.pathNode.value = this.cookie.path; 68 this.secureNode.checked = this.cookie.isSecure; 69 this.httpOnly.checked = this.cookie.isHttpOnly; 70 this.URLEncodeValue.checked = this.cookie.rawValue != unescape(this.cookie.rawValue); 71 72 if (this.cookie.expires) 73 { 74 var expires = new Date(this.cookie.expires * 1000); 75 this.expireNode.value = expires.toGMTString(); 76 } 77 else 78 { 79 this.sessionNode.checked = true; 80 81 // Set default value for expire time (current time + some time, see prefs 82 // defaultInterval) so, the cookie doesn't disappear if the session box 83 // is just unchecked. 84 85 // xxxHonza: the default time is always set to the current time. 86 //if (!this.expireNode.value) 87 { 88 var expireTime = Firebug.CookieModule.getDefaultCookieExpireTime(); 89 var expires = new Date(expireTime * 1000); 90 this.expireNode.value = expires.toGMTString(); 91 } 92 } 93 94 // Update expire date-time picker. 95 this.onSession(); 96 97 // Translate all string in the UI. 98 this.fcInternationalizeUI(); 99 }, 100 101 fcInternationalizeUI: function() 102 { 103 var elements = ["fcEditCookieDlg", "fcNameLabel", "fcIsDomainLabel", "fcPathLabel", 104 "fcExpireLabel", "fcSession", "fcValueLabel", "fcSecure", "fcHttpOnly", 105 "fbURLEncodeValue"]; 106 107 for (var i=0; i<elements.length; i++) 108 { 109 var element = $(elements[i], this.window); 110 if (element.hasAttribute("title")) 111 Locale.internationalize(element, "title"); 112 113 if (element.hasAttribute("label")) 114 Locale.internationalize(element, "label"); 115 116 if (element.hasAttribute("value")) 117 Locale.internationalize(element, "value"); 118 } 119 }, 120 121 onOK: function() 122 { 123 if (!this.checkValues()) 124 return false; 125 126 var isSession = this.sessionNode.checked; 127 var host = this.domainNode.value; 128 129 var cookieName = this.nameNode.value; 130 var cookieValue = this.valueNode.value; 131 132 // Fix for issue 39: Can't create cookies with ';' in the name 133 // But do not escape all,see issue 60: "[" and "]" characters get badly encoded 134 // on cookie name upon editing 135 cookieName = cookieName.replace(/\;/g, "%3B"); 136 137 // According to the spec cookie value must be escaped 138 if (this.URLEncodeValue.checked) 139 cookieValue = escape(cookieValue); 140 141 // Issue 45: When I copy and paste or edit a cookie contents + (plus) signs 142 // get converted to spaces. 143 cookieValue = cookieValue.replace(/\+/g, "%2B"); 144 145 // Create a helper cookie object from the provided data. 146 var values = { 147 name: cookieName, 148 rawValue: cookieValue, 149 path: this.pathNode.value, 150 host: host, 151 isSecure: this.secureNode.checked, 152 isHttpOnly: this.httpOnly.checked, 153 isDomain: (host.charAt(0) == "."), 154 expires: null // is computed below 155 }; 156 157 // will be immediately removed. 158 if (!isSession) 159 { 160 // If it isn't a session cookie set the proper expire time. 161 var expires = new Date(); 162 expires.setTime(Date.parse(this.expireNode.value)); 163 values.expires = Math.floor(expires.valueOf() / 1000); 164 } 165 166 // Create/modify cookie. 167 var cookie = new Cookie(values); 168 Firebug.CookieModule.createCookie(cookie); 169 170 // Close dialog. 171 this.window.close(); 172 173 return true; 174 }, 175 176 /** 177 * Verify values before the OK button is pressed. 178 */ 179 checkValues: function() 180 { 181 var name = this.nameNode.value; 182 if (!name) 183 { 184 prompts.alert(this.window, Locale.$STR("Firebug"), 185 Locale.$STR("cookies.edit.invalidname")); 186 return false; 187 } 188 189 var domain = this.domainNode.value; 190 if (!this.checkHost(domain)) 191 { 192 prompts.alert(this.window, Locale.$STR("Firebug"), 193 Locale.$STR("cookies.edit.invalidhost")); 194 return false; 195 } 196 197 var path = this.pathNode.value; 198 if (!this.checkPath(domain, path)) 199 { 200 prompts.alert(this.window, Locale.$STR("Firebug"), 201 Locale.$STR("cookies.edit.invalidpath")); 202 return false; 203 } 204 205 return true; 206 }, 207 208 onCancel: function() 209 { 210 window.close(); 211 }, 212 213 onSession: function() 214 { 215 this.expireNode.disabled = this.sessionNode.checked; 216 }, 217 218 checkHost: function(host) 219 { 220 if (!host) 221 return false; 222 223 try 224 { 225 var uri = "http://" + host + "/"; 226 return ioService.newURI(uri, null, null) ? true : false; 227 } 228 catch (err) { 229 } 230 231 return false; 232 }, 233 234 checkPath: function(host, path) 235 { 236 if (!path) 237 return false; 238 239 try { 240 var uri = "http://" + host + "/" + path; 241 return ioService.newURI(uri, null, null) ? true : false; 242 } 243 catch(err) { 244 } 245 246 return false; 247 }, 248 249 createDateTimeField: function() 250 { 251 // Get the box element where the dateTime field should be located. 252 var expireBox = this.window.document.getElementById("fcExpireBox"); 253 254 var dateTimeField = null; 255 if (versionChecker.compare(appInfo.version, "3.0*") >= 0) 256 { 257 // Use new <datepicker> and <timepicker> XUL elements (introduced in Firefox 3) 258 dateTimeField = this.window.document.createElement("dateTimePicker"); 259 } 260 else 261 { 262 // Use simple text field with GMT time format. 263 dateTimeField = this.window.document.createElement("textbox"); 264 dateTimeField.setAttribute("cols", "12"); 265 dateTimeField.setAttribute("flex", "1"); 266 } 267 268 // Append it into the UI. 269 dateTimeField.id = "fcExpire"; 270 expireBox.appendChild(dateTimeField); 271 }, 272 273 getChromeWindow: function() 274 { 275 return windowMediator.getMostRecentWindow("navigator:browser"); 276 } 277 } 278 279 // ********************************************************************************************* // 280 // Helpers 281 282 function $(id, win) 283 { 284 return win.document.getElementById(id); 285 } 286 287 // ********************************************************************************************* // 288 // Registration 289 290 return EditCookie; 291 292 // ********************************************************************************************* // 293 }); 294