| /* |
| * Utilities: A classic collection of JavaScript utilities |
| * Copyright 2112 Matthew Eernisse (mde@fleegix.org) |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| var uri |
| , string = require('./string'); |
| |
| /** |
| @name uri |
| @namespace uri |
| */ |
| |
| uri = new (function () { |
| var _isArray = function (obj) { |
| return obj && |
| typeof obj === 'object' && |
| typeof obj.length === 'number' && |
| typeof obj.splice === 'function' && |
| !(obj.propertyIsEnumerable('length')); |
| }; |
| |
| /** |
| @name uri#getFileExtension |
| @public |
| @function |
| @return {String} Returns the file extension for a given path |
| @description Gets the file extension for a path and returns it |
| @param {String} path The path to get the extension for |
| */ |
| this.getFileExtension = function (path) { |
| var match; |
| if (path) { |
| match = /.+\.(\w{2,4}$)/.exec(path); |
| } |
| return (match && match[1]) || ''; |
| }; |
| |
| /** |
| @name uri#paramify |
| @public |
| @function |
| @return {String} Returns a querystring contains the given values |
| @description Convert a JS Object to a querystring (key=val&key=val). Values in arrays |
| will be added as multiple parameters |
| @param {Object} obj An Object containing only scalars and arrays |
| @param {Object} o The options to use for formatting |
| @param {Boolean} [o.consolidate=false] take values from elements that can return |
| multiple values (multi-select, checkbox groups) and collapse into a single, |
| comman-delimited value. |
| @param {Boolean} [o.includeEmpty=false] include keys in the string for all elements, even |
| they have no value set (e.g., even if elemB has no value: elemA=foo&elemB=&elemC=bar). |
| Note that some false-y values are always valid even without this option, [0, '']. |
| This option extends coverage to [null, undefined, NaN] |
| @param {Boolean} [o.snakeize=false] change param names from camelCase to snake_case. |
| @param {Boolean} [o.escapeVals=false] escape the values for XML entities. |
| */ |
| this.paramify = function (obj, o) { |
| var opts = o || {}, |
| str = '', |
| key, |
| val, |
| isValid, |
| itemArray, |
| arr = [], |
| arrVal; |
| |
| for (var p in obj) { |
| if (Object.prototype.hasOwnProperty.call(obj, p)) { |
| val = obj[p]; |
| |
| // This keeps valid falsy values like false and 0 |
| // It's duplicated in the array block below. Could |
| // put it in a function but don't want the overhead |
| isValid = !( val === null || val === undefined || |
| (typeof val === 'number' && isNaN(val)) ); |
| |
| key = opts.snakeize ? string.snakeize(p) : p; |
| if (isValid) { |
| // Multiple vals -- array |
| if (_isArray(val) && val.length) { |
| itemArray = []; |
| for (var i = 0, ii = val.length; i < ii; i++) { |
| arrVal = val[i]; |
| // This keeps valid falsy values like false and 0 |
| isValid = !( arrVal === null || arrVal === undefined || |
| (typeof arrVal === 'number' && isNaN(arrVal)) ); |
| |
| itemArray[i] = isValid ? encodeURIComponent(arrVal) : ''; |
| if (opts.escapeVals) { |
| itemArray[i] = string.escapeXML(itemArray[i]); |
| } |
| } |
| // Consolidation mode -- single value joined on comma |
| if (opts.consolidate) { |
| arr.push(key + '=' + itemArray.join(',')); |
| } |
| // Normal mode -- multiple, same-named params with each val |
| else { |
| // {foo: [1, 2, 3]} => 'foo=1&foo=2&foo=3' |
| // Add into results array, as this just ends up getting |
| // joined on ampersand at the end anyhow |
| arr.push(key + '=' + itemArray.join('&' + key + '=')); |
| } |
| } |
| // Single val -- string |
| else { |
| if (opts.escapeVals) { |
| val = string.escapeXML(val); |
| } |
| arr.push(key + '=' + encodeURIComponent(val)); |
| } |
| str += '&'; |
| } |
| else { |
| if (opts.includeEmpty) { arr.push(key + '='); } |
| } |
| } |
| } |
| return arr.join('&'); |
| }; |
| |
| /** |
| @name uri#objectify |
| @public |
| @function |
| @return {Object} JavaScript key/val object with the values from the querystring |
| @description Convert the values in a query string (key=val&key=val) to an Object |
| @param {String} str The querystring to convert to an object |
| @param {Object} o The options to use for formatting |
| @param {Boolean} [o.consolidate=true] Convert multiple instances of the same |
| key into an array of values instead of overwriting |
| */ |
| this.objectify = function (str, o) { |
| var opts = o || {}; |
| var d = {}; |
| var consolidate = typeof opts.consolidate == 'undefined' ? |
| true : opts.consolidate; |
| if (str) { |
| var arr = str.split('&'); |
| for (var i = 0; i < arr.length; i++) { |
| var pair = arr[i].split('='); |
| var name = pair[0]; |
| var val = decodeURIComponent(pair[1] || ''); |
| // "We've already got one!" -- arrayize if the flag |
| // is set |
| if (typeof d[name] != 'undefined' && consolidate) { |
| if (typeof d[name] == 'string') { |
| d[name] = [d[name]]; |
| } |
| d[name].push(val); |
| } |
| // Otherwise just set the value |
| else { |
| d[name] = val; |
| } |
| } |
| } |
| return d; |
| }; |
| |
| })(); |
| |
| module.exports = uri; |
| |