Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('json-stringify-shim', function (Y, NAME) {
2
 
3
// All internals kept private for security reasons
4
var Lang      = Y.Lang,
5
    isFunction= Lang.isFunction,
6
    isObject  = Lang.isObject,
7
    isArray   = Lang.isArray,
8
    _toStr    = Object.prototype.toString,
9
    UNDEFINED = 'undefined',
10
    OBJECT    = 'object',
11
    NULL      = 'null',
12
    STRING    = 'string',
13
    NUMBER    = 'number',
14
    BOOLEAN   = 'boolean',
15
    DATE      = 'date',
16
    _allowable= {
17
        'undefined'        : UNDEFINED,
18
        'string'           : STRING,
19
        '[object String]'  : STRING,
20
        'number'           : NUMBER,
21
        '[object Number]'  : NUMBER,
22
        'boolean'          : BOOLEAN,
23
        '[object Boolean]' : BOOLEAN,
24
        '[object Date]'    : DATE,
25
        '[object RegExp]'  : OBJECT
26
    },
27
    EMPTY     = '',
28
    OPEN_O    = '{',
29
    CLOSE_O   = '}',
30
    OPEN_A    = '[',
31
    CLOSE_A   = ']',
32
    COMMA     = ',',
33
    COMMA_CR  = ",\n",
34
    CR        = "\n",
35
    COLON     = ':',
36
    COLON_SP  = ': ',
37
    QUOTE     = '"',
38
 
39
    // Regex used to capture characters that need escaping before enclosing
40
    // their containing string in quotes.
41
    _SPECIAL = /[\x00-\x07\x0b\x0e-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
42
 
43
    // Character substitution map for common escapes and special characters.
44
    _COMMON = [
45
        [/\\/g, '\\\\'],
46
        [/\"/g, '\\"'],
47
        [/\x08/g, '\\b'],
48
        [/\x09/g, '\\t'],
49
        [/\x0a/g, '\\n'],
50
        [/\x0c/g, '\\f'],
51
        [/\x0d/g, '\\r']
52
    ],
53
    _COMMON_LENGTH = _COMMON.length,
54
 
55
    // In-process optimization for special character escapes that haven't yet
56
    // been promoted to _COMMON
57
    _CHAR = {},
58
 
59
    // Per-char counter to determine if it's worth fast tracking a special
60
    // character escape sequence.
61
    _CHAR_COUNT, _CACHE_THRESHOLD;
62
 
63
// Utility function used to determine how to serialize a variable.
64
function _type(o) {
65
    var t = typeof o;
66
    return  _allowable[t] ||              // number, string, boolean, undefined
67
            _allowable[_toStr.call(o)] || // Number, String, Boolean, Date
68
            (t === OBJECT ?
69
                (o ? OBJECT : NULL) :     // object, array, null, misc natives
70
                UNDEFINED);               // function, unknown
71
}
72
 
73
// Escapes a special character to a safe Unicode representation
74
function _char(c) {
75
    if (!_CHAR[c]) {
76
        _CHAR[c] = '\\u'+('0000'+(+(c.charCodeAt(0))).toString(16)).slice(-4);
77
        _CHAR_COUNT[c] = 0;
78
    }
79
 
80
    // === to avoid this conditional for the remainder of the current operation
81
    if (++_CHAR_COUNT[c] === _CACHE_THRESHOLD) {
82
        _COMMON.push([new RegExp(c, 'g'), _CHAR[c]]);
83
        _COMMON_LENGTH = _COMMON.length;
84
    }
85
 
86
    return _CHAR[c];
87
}
88
 
89
// Enclose escaped strings in quotes
90
function _string(s) {
91
    var i, chr;
92
 
93
    // Preprocess the string against common characters to avoid function
94
    // overhead associated with replacement via function.
95
    for (i = 0; i < _COMMON_LENGTH; i++) {
96
        chr = _COMMON[i];
97
        s = s.replace(chr[0], chr[1]);
98
    }
99
 
100
    // original function replace for the not-as-common set of chars
101
    return QUOTE + s.replace(_SPECIAL, _char) + QUOTE;
102
}
103
 
104
// Adds the provided space to the beginning of every line in the input string
105
function _indent(s,space) {
106
    return s.replace(/^/gm, space);
107
}
108
 
109
Y.JSON.stringify = function _stringify(o,w,space) {
110
    if (o === undefined) {
111
        return undefined;
112
    }
113
 
114
    var replacer = isFunction(w) ? w : null,
115
        format   = _toStr.call(space).match(/String|Number/) || [],
116
        _date    = Y.JSON.dateToString,
117
        stack    = [],
118
        tmp,i,len;
119
 
120
    _CHAR_COUNT      = {};
121
    _CACHE_THRESHOLD = Y.JSON.charCacheThreshold;
122
 
123
    if (replacer || !isArray(w)) {
124
        w = undefined;
125
    }
126
 
127
    // Ensure whitelist keys are unique (bug 2110391)
128
    if (w) {
129
        tmp = {};
130
        for (i = 0, len = w.length; i < len; ++i) {
131
            tmp[w[i]] = true;
132
        }
133
        w = tmp;
134
    }
135
 
136
    // Per the spec, strings are truncated to 10 characters and numbers
137
    // are converted to that number of spaces (max 10)
138
    space = format[0] === 'Number' ?
139
                new Array(Math.min(Math.max(0,space),10)+1).join(" ") :
140
                (space || EMPTY).slice(0,10);
141
 
142
    function _serialize(h,key) {
143
        var value = h[key],
144
            t     = _type(value),
145
            a     = [],
146
            colon = space ? COLON_SP : COLON,
147
            arr, i, keys, k, v;
148
 
149
        // Per the ECMA 5 spec, toJSON is applied before the replacer is
150
        // called.  Also per the spec, Date.prototype.toJSON has been added, so
151
        // Date instances should be serialized prior to exposure to the
152
        // replacer.  I disagree with this decision, but the spec is the spec.
153
        if (isObject(value) && isFunction(value.toJSON)) {
154
            value = value.toJSON(key);
155
        } else if (t === DATE) {
156
            value = _date(value);
157
        }
158
 
159
        if (isFunction(replacer)) {
160
            value = replacer.call(h,key,value);
161
        }
162
 
163
        if (value !== h[key]) {
164
            t = _type(value);
165
        }
166
 
167
        switch (t) {
168
            case DATE    : // intentional fallthrough.  Pre-replacer Dates are
169
                           // serialized in the toJSON stage.  Dates here would
170
                           // have been produced by the replacer.
171
            case OBJECT  : break;
172
            case STRING  : return _string(value);
173
            case NUMBER  : return isFinite(value) ? value+EMPTY : NULL;
174
            case BOOLEAN : return value+EMPTY;
175
            case NULL    : return NULL;
176
            default      : return undefined;
177
        }
178
 
179
        // Check for cyclical references in nested objects
180
        for (i = stack.length - 1; i >= 0; --i) {
181
            if (stack[i] === value) {
182
                throw new Error("JSON.stringify. Cyclical reference");
183
            }
184
        }
185
 
186
        arr = isArray(value);
187
 
188
        // Add the object to the processing stack
189
        stack.push(value);
190
 
191
        if (arr) { // Array
192
            for (i = value.length - 1; i >= 0; --i) {
193
                a[i] = _serialize(value, i) || NULL;
194
            }
195
        } else {   // Object
196
            // If whitelist provided, take only those keys
197
            keys = w || value;
198
            i = 0;
199
 
200
            for (k in keys) {
201
                if (keys.hasOwnProperty(k)) {
202
                    v = _serialize(value, k);
203
                    if (v) {
204
                        a[i++] = _string(k) + colon + v;
205
                    }
206
                }
207
            }
208
        }
209
 
210
        // remove the array from the stack
211
        stack.pop();
212
 
213
        if (space && a.length) {
214
            return arr ?
215
                OPEN_A + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_A :
216
                OPEN_O + CR + _indent(a.join(COMMA_CR), space) + CR + CLOSE_O;
217
        } else {
218
            return arr ?
219
                OPEN_A + a.join(COMMA) + CLOSE_A :
220
                OPEN_O + a.join(COMMA) + CLOSE_O;
221
        }
222
    }
223
 
224
    // process the input
225
    return _serialize({'':o},'');
226
};
227
 
228
// Property available for testing if the implementation being used
229
// is native or a shim
230
Y.JSON.stringify.isShim = true;
231
 
232
 
233
}, '3.18.1', {"requires": ["json-stringify"]});