Advertisement
stuppid_bot

query string

Dec 24th, 2013
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. queryString = new (function QueryString() {
  2.     var self = this;
  3.  
  4.     /**
  5.      * Декодирует компонент URI.
  6.      *
  7.      * @param {string} str Исходная строка.
  8.      * @return {string}
  9.      */
  10.     self.decode = function (str) {
  11.         return decodeURIComponent(str.replace(/\+/g, ' '));
  12.     };
  13.  
  14.     /**
  15.      * Разбивает имя параметра на части.
  16.      *
  17.      * @param {string} str Имя параметра.
  18.      * @return {array}
  19.      */
  20.     function parseParamName(str) {
  21.         var a;
  22.         var b = 0;
  23.         var c = [];
  24.         var ret = [];
  25.         while (~(a = str.indexOf('[', b))) {
  26.             if (!c.length) {
  27.                 c.push(0, a);
  28.             }
  29.             // символы между группами скобок: foo[bar]_[baz]
  30.             if (b && a != b) {
  31.                 break;
  32.             }
  33.             b = str.indexOf(']', ++a);
  34.             // не найдена закрывающая скобка ]
  35.             if (b == -1) {
  36.                 break;
  37.             }
  38.             c.push(a, b++);
  39.         }
  40.         // символы после последней закрывающей скобки: foo[]_
  41.         // if (b && b != str.length) {}
  42.         for (var i = 0; i < c.length; i += 2) {
  43.             ret.push(str.slice(c[i], c[i + 1]));
  44.         }
  45.         return ret.length ? ret : [str];
  46.     }
  47.  
  48.     /**
  49.      * Парсит URI-параметры.
  50.      *
  51.      * @param {string} str Исходная строка.
  52.      * @param {string} sep Разделитель параметров.
  53.      * @param {string} eq Разделитель пар ключ-значение.
  54.      * @return {object}
  55.      */
  56.     self.parse = function (str, sep, eq) {
  57.         if (str == '') {
  58.             return null;
  59.         }
  60.         sep = sep || '&';
  61.         eq = eq || '=';
  62.         var ret = {};
  63.         var pairs = str.split(sep);
  64.         var pos;
  65.         var keys;
  66.         var name;
  67.         var cur;
  68.         var j;
  69.         for (var i = 0; i < pairs.length; ++i) {
  70.             pos = pairs[i].indexOf(eq);
  71.             pos = pos == -1 ? pairs[i].length : pos
  72.             keys = parseParamName(pairs[i].slice(0, pos));
  73.             cur = ret;
  74.             j = 0;
  75.             while (j < keys.length) {
  76.                 if (j) {
  77.                     if (!cur[name]) {
  78.                         cur[name] = /^(|\d|[1-9]\d+)$/.test(keys[j]) ? [] : {};
  79.                     }
  80.                     cur = cur[name];
  81.                     if (isArray(cur)) {
  82.                         name = keys[j] == '' ? cur.length - (cur._t ? 1 : 0) : parseInt(keys[j]);
  83.                         cur._t = keys[j] == '';
  84.                     }
  85.                     else {
  86.                         name = self.decode(keys[j]);
  87.                     }
  88.  
  89.                     name = isArray(cur) ? (keys[j] == '' ? cur.length : parseInt(keys[j])) : self.decode(keys[j]);
  90.                 }
  91.                 else {
  92.                     name = self.decode(keys[j]);
  93.                 }
  94.                 ++j;
  95.             }
  96.             cur[name] = self.decode(pairs[i].slice(++pos));
  97.         }
  98.         return ret;
  99.     };
  100.  
  101.     /**
  102.      * Вспомогательная функция для заполнения массива параметров.
  103.      * @param {array} params
  104.      * @param {string} name
  105.      * @param {object} data
  106.      */
  107.     function updateParams(params, name, data) {
  108.         if (isArray(data)) {
  109.             var inOrder;
  110.             for (var i = 0; i < data.length; ++i) {
  111.                 // пропускаем элементы с неустановленными значениями
  112.                 if (data[i] === undefined) {
  113.                     inOrder = false;
  114.                     continue;
  115.                 }
  116.                 // если элементы с установленными значениями идут по порядку, то индекс опускаем
  117.                 updateParams(params, name + '[' + (i == 0 || inOrder ? '' : i) + ']', data[i]);
  118.                 inOrder = true;
  119.             }
  120.         }
  121.         else if (isObject(data)) {
  122.             for (var i in data) {
  123.                 if (data.hasOwnProperty(i)) {
  124.                     updateParams(params, name + '[' + encodeURIComponent(i) + ']', data[i]);
  125.                 }
  126.             }
  127.         }
  128.         else {
  129.             params.push([name, encodeURIComponent(data)]);
  130.         }
  131.     }
  132.  
  133.     /**
  134.      * Создает из объекта строку с параметрами.
  135.      *
  136.      * @param {object} obj Параметры.
  137.      * @param {string} sep Разделитель параметров.
  138.      * @param {string} eq Разделитель пар ключ-значение.
  139.      * @return {string}
  140.      */
  141.     self.stringify = function (obj, sep, eq) {
  142.         sep = sep || '&';
  143.         eq = eq || '=';
  144.         var params = [];
  145.         var name;
  146.         var cur;
  147.         var value;
  148.         for (var i in obj) {
  149.             if (obj.hasOwnProperty(i)) {
  150.                 updateParams(params, encodeURIComponent(i), obj[i]);
  151.             }
  152.         }
  153.         return params.map(function (a) { return a[0] + eq + a[1]; }).join(sep);
  154.     };
  155. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement