Blame view

node_modules/node-forge/lib/form.js 3.79 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  /**
   * Functions for manipulating web forms.
   *
   * @author David I. Lehn <dlehn@digitalbazaar.com>
   * @author Dave Longley
   * @author Mike Johnson
   *
   * Copyright (c) 2011-2014 Digital Bazaar, Inc. All rights reserved.
   */
  var forge = require('./forge');
  
  /* Form API */
  var form = module.exports = forge.form = forge.form || {};
  
  (function($) {
  
  /**
   * Regex for parsing a single name property (handles array brackets).
   */
  var _regex = /([^\[]*?)\[(.*?)\]/g;
  
  /**
   * Parses a single name property into an array with the name and any
   * array indices.
   *
   * @param name the name to parse.
   *
   * @return the array of the name and its array indices in order.
   */
  var _parseName = function(name) {
    var rval = [];
  
    var matches;
    while(!!(matches = _regex.exec(name))) {
      if(matches[1].length > 0) {
        rval.push(matches[1]);
      }
      if(matches.length >= 2) {
        rval.push(matches[2]);
      }
    }
    if(rval.length === 0) {
      rval.push(name);
    }
  
    return rval;
  };
  
  /**
   * Adds a field from the given form to the given object.
   *
   * @param obj the object.
   * @param names the field as an array of object property names.
   * @param value the value of the field.
   * @param dict a dictionary of names to replace.
   */
  var _addField = function(obj, names, value, dict) {
    // combine array names that fall within square brackets
    var tmp = [];
    for(var i = 0; i < names.length; ++i) {
      // check name for starting square bracket but no ending one
      var name = names[i];
      if(name.indexOf('[') !== -1 && name.indexOf(']') === -1 &&
        i < names.length - 1) {
        do {
          name += '.' + names[++i];
        } while(i < names.length - 1 && names[i].indexOf(']') === -1);
      }
      tmp.push(name);
    }
    names = tmp;
  
    // split out array indexes
    var tmp = [];
    $.each(names, function(n, name) {
      tmp = tmp.concat(_parseName(name));
    });
    names = tmp;
  
    // iterate over object property names until value is set
    $.each(names, function(n, name) {
      // do dictionary name replacement
      if(dict && name.length !== 0 && name in dict) {
         name = dict[name];
      }
  
      // blank name indicates appending to an array, set name to
      // new last index of array
      if(name.length === 0) {
         name = obj.length;
      }
  
      // value already exists, append value
      if(obj[name]) {
        // last name in the field
        if(n == names.length - 1) {
          // more than one value, so convert into an array
          if(!$.isArray(obj[name])) {
            obj[name] = [obj[name]];
          }
          obj[name].push(value);
        } else {
          // not last name, go deeper into object
          obj = obj[name];
        }
      } else if(n == names.length - 1) {
        // new value, last name in the field, set value
        obj[name] = value;
      } else {
        // new value, not last name, go deeper
        // get next name
        var next = names[n + 1];
  
        // blank next value indicates array-appending, so create array
        if(next.length === 0) {
           obj[name] = [];
        } else {
          // if next name is a number create an array, otherwise a map
          var isNum = ((next - 0) == next && next.length > 0);
          obj[name] = isNum ? [] : {};
        }
        obj = obj[name];
      }
    });
  };
  
  /**
   * Serializes a form to a JSON object. Object properties will be separated
   * using the given separator (defaults to '.') and by square brackets.
   *
   * @param input the jquery form to serialize.
   * @param sep the object-property separator (defaults to '.').
   * @param dict a dictionary of names to replace (name=replace).
   *
   * @return the JSON-serialized form.
   */
  form.serialize = function(input, sep, dict) {
    var rval = {};
  
    // add all fields in the form to the object
    sep = sep || '.';
    $.each(input.serializeArray(), function() {
      _addField(rval, this.name.split(sep), this.value || '', dict);
    });
  
    return rval;
  };
  
  })(jQuery);