forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			121 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| 'use strict';
 | |
| 
 | |
| module.metadata = {
 | |
|   "stability": "unstable"
 | |
| };
 | |
| 
 | |
| var unescape = decodeURIComponent;
 | |
| exports.unescape = unescape;
 | |
| 
 | |
| // encodes a string safely for application/x-www-form-urlencoded
 | |
| // adheres to RFC 3986
 | |
| // see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent
 | |
| function escape(query) {
 | |
|   return encodeURIComponent(query).
 | |
|     replace(/%20/g, '+').
 | |
|     replace(/!/g, '%21').
 | |
|     replace(/'/g, '%27').
 | |
|     replace(/\(/g, '%28').
 | |
|     replace(/\)/g, '%29').
 | |
|     replace(/\*/g, '%2A');
 | |
| }
 | |
| exports.escape = escape;
 | |
| 
 | |
| // Converts an object of unordered key-vals to a string that can be passed
 | |
| // as part of a request
 | |
| function stringify(options, separator, assigner) {
 | |
|   separator = separator || '&';
 | |
|   assigner = assigner || '=';
 | |
|   // Explicitly return null if we have null, and empty string, or empty object.
 | |
|   if (!options)
 | |
|     return '';
 | |
| 
 | |
|   // If content is already a string, just return it as is.
 | |
|   if (typeof(options) == 'string')
 | |
|     return options;
 | |
| 
 | |
|   // At this point we have a k:v object. Iterate over it and encode each value.
 | |
|   // Arrays and nested objects will get encoded as needed. For example...
 | |
|   //
 | |
|   //   { foo: [1, 2, { omg: 'bbq', 'all your base!': 'are belong to us' }], bar: 'baz' }
 | |
|   //
 | |
|   // will be encoded as
 | |
|   //
 | |
|   //   foo[0]=1&foo[1]=2&foo[2][omg]=bbq&foo[2][all+your+base!]=are+belong+to+us&bar=baz
 | |
|   //
 | |
|   // Keys (including '[' and ']') and values will be encoded with
 | |
|   // `escape` before returning.
 | |
|   //
 | |
|   // Execution was inspired by jQuery, but some details have changed and numeric
 | |
|   // array keys are included (whereas they are not in jQuery).
 | |
| 
 | |
|   let encodedContent = [];
 | |
|   function add(key, val) {
 | |
|     encodedContent.push(escape(key) + assigner + escape(val));
 | |
|   }
 | |
| 
 | |
|   function make(key, value) {
 | |
|     if (value && typeof(value) === 'object')
 | |
|       Object.keys(value).forEach(function(name) {
 | |
|         make(key + '[' + name + ']', value[name]);
 | |
|       });
 | |
|     else
 | |
|       add(key, value);
 | |
|   }
 | |
| 
 | |
|   Object.keys(options).forEach(function(name) { make(name, options[name]); });
 | |
|   return encodedContent.join(separator);
 | |
| 
 | |
|   //XXXzpao In theory, we can just use a FormData object on 1.9.3, but I had
 | |
|   //        trouble getting that working. It would also be nice to stay
 | |
|   //        backwards-compat as long as possible. Keeping this in for now...
 | |
|   // let formData = Cc['@mozilla.org/files/formdata;1'].
 | |
|   //                createInstance(Ci.nsIDOMFormData);
 | |
|   // for ([k, v] in Iterator(content)) {
 | |
|   //   formData.append(k, v);
 | |
|   // }
 | |
|   // return formData;
 | |
| }
 | |
| exports.stringify = stringify;
 | |
| 
 | |
| // Exporting aliases that nodejs implements just for the sake of
 | |
| // interoperability.
 | |
| exports.encode = stringify;
 | |
| exports.serialize = stringify;
 | |
| 
 | |
| // Note: That `stringify` and `parse` aren't bijective as we use `stringify`
 | |
| // as it was implement in request module, but implement `parse` to match nodejs
 | |
| // behavior.
 | |
| // TODO: Make `stringify` implement API as in nodejs and figure out backwards
 | |
| // compatibility.
 | |
| function parse(query, separator, assigner) {
 | |
|   separator = separator || '&';
 | |
|   assigner = assigner || '=';
 | |
|   let result = {};
 | |
| 
 | |
|   if (typeof query !== 'string' || query.length === 0)
 | |
|     return result;
 | |
| 
 | |
|   query.split(separator).forEach(function(chunk) {
 | |
|     let pair = chunk.split(assigner);
 | |
|     let key = unescape(pair[0]);
 | |
|     let value = unescape(pair.slice(1).join(assigner));
 | |
| 
 | |
|     if (!(key in result))
 | |
|       result[key] = value;
 | |
|     else if (Array.isArray(result[key]))
 | |
|       result[key].push(value);
 | |
|     else
 | |
|       result[key] = [result[key], value];
 | |
|   });
 | |
| 
 | |
|   return result;
 | |
| };
 | |
| exports.parse = parse;
 | |
| // Exporting aliases that nodejs implements just for the sake of
 | |
| // interoperability.
 | |
| exports.decode = parse;
 | 
