1 |
|
2 |
|
3 |
|
4 | !function(exports, Object) {
|
5 | "use strict";
|
6 | var getFns = Object.create(null)
|
7 | , setFns = Object.create(null)
|
8 | , filterFns = Object.create(null)
|
9 | , KEYS = Object.keys
|
10 | , FILTER_ERR = "Invalid filter: "
|
11 | , escRe = /['\n\r\u2028\u2029]|\\(?!x2e)/g
|
12 | , pathRe = /(^$|.+?)(?:\[([^\]]*)\](\*.*)?|\{([^}]*)})?(\.(?=[^.])|$)/g
|
13 | , reEscRe = /[.+^=:${}()|\/\\]/g
|
14 | , keyRe = /\[(.*?)\]/g
|
15 | , globRe = /\[.+?\]|[?*]/
|
16 | , globReplace = /\?|(?=\*)/g
|
17 | , globGroup = /\[!(?=.*\])/g
|
18 | , primitiveRe = /^(-?(\d*\.)?\d+|true|false|null)$/
|
19 | , valRe = /("|')(?:\\?[^\\])*?\1|(\w*)\{((?:("|')(?:\\?[^\\])*?\4|\w*\{(?:("|')(?:\\?[^\\])*?\5|[^}])*?\}|.)*?)\}|([@$]?)([^,]+)/g
|
20 | , filterRe = /(!?)(\$?)((?:[-+:.\/\w]+|\[[^\]]+\]|\{[^}]+}|\\x2e)+)(\[]|\{}|)(?:(!(?=\1)==?|(?=\1)[<>=]=?)((?:("|')(?:\\?[^\\])*?\7|\w*\{(?:("|')(?:\\?[^\\])*?\8|\w*\{(?:("|')(?:\\?[^\\])*?\9|[^}])*?\}|.)*?\}|[^|&()])*))?(?=[;)|&]|$)|(([;&|])\11*|([()])|.)/g
|
21 | , onlyFilterRe = RegExp("^(?:([@*])|" + filterRe.source.slice(0, -10) + "))+$")
|
22 | , cleanRe = /(\(o=d\)&&(?!.*o=o).*)\(o=d\)&&/g
|
23 | , fns = {
|
24 | "==": "a==d",
|
25 | "===": "a===d",
|
26 | ">": "a<d",
|
27 | ">=": "a<=d",
|
28 | "<": "a>d",
|
29 | "<=": "a>=d",
|
30 | "~": "typeof d==='string'&&a.test(d)"
|
31 | }
|
32 | , fnMap = {
|
33 | w: "Day()||7",
|
34 | Y: "FullYear()%100",
|
35 | M: "Month()+1",
|
36 | D: "Date()",
|
37 | h: "Hours()",
|
38 | H: "Hours()%12||12",
|
39 | m: "Minutes()",
|
40 | s: "Seconds()",
|
41 | S: "Milliseconds()"
|
42 | }
|
43 | , hasOwn = fns.hasOwnProperty
|
44 | , tmpDate = new Date()
|
45 | , isArray = Array.isArray
|
46 |
|
47 | exports.clone = clone
|
48 | exports.matcher = matcher
|
49 | exports.get = function(obj, pointer, fallback) { return pathFn(pointer)(obj, fallback) }
|
50 | exports.isObject = isObject
|
51 | exports.mergePatch = mergePatch
|
52 | exports.set = function(obj, pointer, value) { return pathFn(pointer, true)(obj, value) }
|
53 | exports.setForm = setForm
|
54 | exports.tr = tr
|
55 |
|
56 | exports.get.str = pathStr
|
57 | matcher.re = filterRe
|
58 | matcher.str = filterStr
|
59 | matcher.valRe = valRe
|
60 |
|
61 | |
62 |
|
63 |
|
64 |
|
65 |
|
66 | function mergePatch(target, patch, changed, previous, pointer) {
|
67 | var undef, key, oldVal, val, len, nextPointer
|
68 | if (isObject(patch)) {
|
69 | if (!pointer) {
|
70 | pointer = ""
|
71 | }
|
72 | if (!isObject(target)) {
|
73 | target = {}
|
74 | }
|
75 | for (key in patch) if (
|
76 | undef !== (oldVal = target[key], val = patch[key]) &&
|
77 | hasOwn.call(patch, key) &&
|
78 | (
|
79 | undef == val ?
|
80 | undef !== oldVal && delete target[key] :
|
81 | target[key] !== val
|
82 | )
|
83 | ) {
|
84 | nextPointer = pointer + "/" + key.replace(/~/g, "~0").replace(/\//g, "~1")
|
85 | len = changed && isObject(target[key]) && changed.length
|
86 | if (undef != val) {
|
87 | target[key] = mergePatch(target[key], val, changed, previous, nextPointer)
|
88 | }
|
89 | if (len === false || changed && len != changed.length) {
|
90 | changed.push(nextPointer)
|
91 | if (previous && !isObject(oldVal)) {
|
92 | previous[nextPointer] = oldVal
|
93 | }
|
94 | }
|
95 | }
|
96 | } else {
|
97 | if (changed && isObject(target)) {
|
98 | val = {}
|
99 | for (key in target) if (hasOwn.call(target, key)) {
|
100 | val[key] = null
|
101 | }
|
102 | mergePatch(target, val, changed, previous, pointer)
|
103 | }
|
104 | target = patch
|
105 | }
|
106 | return target
|
107 | }
|
108 |
|
109 | function escFn(str) {
|
110 | return escape(str).replace(/%u/g, "\\u").replace(/%/g, "\\x")
|
111 | }
|
112 |
|
113 | function pathStr(str, set) {
|
114 | return (
|
115 | str.charAt(0) === "/" ?
|
116 | str.slice(1).replace(/\./g, "\\x2e").replace(/\//g, ".").replace(/~1/g, "/").replace(/~0/g, "~") :
|
117 | str
|
118 | )
|
119 | .replace(escRe, escFn)
|
120 | .replace(pathRe, set === true ? pathSet : pathGet)
|
121 | }
|
122 |
|
123 | function pathGet(str, path, arr, arrExt, obj, dot) {
|
124 | var v = dot ? "(o=" : "(c="
|
125 | , sub = arr || obj
|
126 | if (sub && !(sub = onlyFilterRe.exec(sub))) throw Error(FILTER_ERR + str)
|
127 | return (
|
128 | sub ?
|
129 | pathGet(0, path, 0, 0, 0, 1) + (arr ? "i" : "j") + "(o)&&" + v + (
|
130 |
|
131 | arrExt ? "o.filter(m('" + sub[0] + "'))" + (arrExt === "*" ? "" : ".map(p('" + arrExt.slice(1) + "'))") :
|
132 | sub[1] ? (arr ? "o" : "K(o)") + (sub[0] === "*" ? "" : ".length") :
|
133 | +arr == arr ? "o[" + (arr < 0 ? "o.length" + arr : arr) + "]" :
|
134 | (arr ? "I" : "J") + "(o,m('" + sub[0] + "'))"
|
135 | ) + ")" :
|
136 | v + "o['" + path + "'])" + (
|
137 | arr === "" ? "&&i(c)&&c" :
|
138 | obj === "" ? "&&j(c)&&c" :
|
139 | ""
|
140 | )
|
141 | ) + (dot ? "&&" : "")
|
142 | }
|
143 |
|
144 | function pathSet(str, path, arr, arrExt, obj, dot) {
|
145 | var op = "o['" + path + "']"
|
146 | , out = ""
|
147 | , sub = arr || obj
|
148 | if (sub) {
|
149 | out = "(o=" + (arr ? "i(" : "j(") + op + ")?" + op + ":(" + op + (arr ? "=[]" : "={}") +"))&&"
|
150 | if (arr === "-") {
|
151 | op = "o[o.length]"
|
152 | } else if (+arr == arr) {
|
153 | op = "o[" + (arr < 0 ? "o.length" + arr : arr) + "]"
|
154 | } else {
|
155 | if (!onlyFilterRe.test(arr)) throw Error(FILTER_ERR + str)
|
156 | op = "o[t]"
|
157 | out += "(t=" + (arr ? "I" : "J") + "(o,m('" + sub + "'),1))!=null&&"
|
158 | }
|
159 | }
|
160 | return out + (dot ?
|
161 | "(o=typeof " + op + "==='object'&&" + op + "||(" + op + "={}))&&" :
|
162 | "((c=" + op + "),(" + op + "=v),c)"
|
163 | )
|
164 | }
|
165 |
|
166 | function pathFn(str, set) {
|
167 | var map = set === true ? setFns : getFns
|
168 | return map[str] || (map[str] = Function(
|
169 | "i,j,I,J,K,m,p",
|
170 | "return function(d,v,b){var c,o,t;return (o=d)&&" +
|
171 | pathStr(str, set) +
|
172 | (set ? ",c}": "!==void 0?c:v}")
|
173 | )(isArray, isObject, inArray, inObject, KEYS, matcher, pathFn))
|
174 | }
|
175 |
|
176 | function clone(obj) {
|
177 | var temp, key
|
178 | if (obj && typeof obj == "object") {
|
179 |
|
180 | temp = obj instanceof Date ? new Date(+obj) :
|
181 | obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
|
182 | obj.constructor()
|
183 | for (key in obj) if (hasOwn.call(obj, key)) {
|
184 | temp[key] = clone(obj[key])
|
185 | }
|
186 | obj = temp
|
187 | }
|
188 | return obj
|
189 | }
|
190 |
|
191 | function matcher(str, prefix, opts, getter, tmp) {
|
192 | var optimized
|
193 | , arr = []
|
194 | , key = (prefix || "") + (fns[str] || filterStr(str, opts, arr, getter))
|
195 | , fn = filterFns[key]
|
196 | if (!fn) {
|
197 | for (optimized = key; optimized != (optimized = optimized.replace(cleanRe, "$1")); );
|
198 | fn = filterFns[key] = Function(
|
199 | fns[str] ? "a" : "a,i,j,I,J,K,m,p,t",
|
200 | "return function(d,b){var o;return " + optimized + "}"
|
201 | )
|
202 | fn.source = optimized
|
203 | }
|
204 | return fns[str] ? fn : fn(
|
205 | arr, isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, tmp
|
206 | )
|
207 | }
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 |
|
217 |
|
218 | matcher.date = function(str) {
|
219 | return matcher(str, "(t.setTime(+d)>=0)&&", null, dateGetter, tmpDate)
|
220 | }
|
221 |
|
222 | function dateGetter(name) {
|
223 | return "(t.get" + fnMap[name] + ")"
|
224 | }
|
225 |
|
226 | function filterStr(qs, opts, arr, getter) {
|
227 | return qs.replace(filterRe, worker).replace(/^[1&]&+|&+1?$/g, "") || "1"
|
228 |
|
229 | function worker(all, not, isOption, attr, isArray, op, val, q1, q2, q3, ext, ok2, ok1) {
|
230 | if (ext) {
|
231 | if (!ok2 && !ok1) {
|
232 | throw Error(FILTER_ERR + qs)
|
233 | }
|
234 | return ok1 ? ok1 : ok2 == ";" ? "&&" : ok2 + ok2
|
235 | }
|
236 | if (isOption) {
|
237 | if (opts) opts[attr] = val
|
238 | return "1"
|
239 | }
|
240 |
|
241 | var idd, m, v, isRe
|
242 | , a = []
|
243 | , pre = "(o=d)&&"
|
244 |
|
245 | attr = (getter || pathStr)(attr)
|
246 |
|
247 | if (m = attr.match(/\(c=(.*?)\)$/)) {
|
248 | if (m[1] == "K(o)") {
|
249 | pre += attr + "&&"
|
250 | attr = "c"
|
251 | } else {
|
252 | if (m.index) pre += attr.slice(0, m.index)
|
253 | attr = m[1]
|
254 | }
|
255 | }
|
256 |
|
257 | if (op == "!=" || op == "!==") {
|
258 | not = "!"
|
259 | op = op.slice(1)
|
260 | }
|
261 | if (isArray) {
|
262 | pre += not + (isArray === "[]" ? "i(" : "j(") + attr + ")"
|
263 | }
|
264 |
|
265 | if (!op) {
|
266 | return isArray === "" ? pre + not + attr : pre
|
267 | }
|
268 |
|
269 | if (op == "=" || op == "==") op += "="
|
270 | if (val === "") val="''"
|
271 | for (; m = valRe.exec(val); ) {
|
272 |
|
273 |
|
274 | isRe = 0
|
275 | v = m[6] == "$" ? "b['"+ m[7] +"']" : arrIdx(arr,
|
276 | m[1] || m[3] ? m[0].slice(m[3] ? m[2].length + 1 : 1, -1) :
|
277 | m[6] ? m[7] :
|
278 | primitiveRe.test(m[0]) ? exports.parse(m[0]) :
|
279 | (isRe = globRe.test(m[0])) ? RegExp(
|
280 | "^" + m[0]
|
281 | .replace(reEscRe, "\\$&")
|
282 | .replace(globReplace, ".")
|
283 | .replace(globGroup, "[^") + "$",
|
284 | op === "==" ? "i" : ""
|
285 | ) :
|
286 | m[0]
|
287 | )
|
288 | idd = (
|
289 | m[2] ? "m." + m[2].toLowerCase() :
|
290 | m[3] ? "m" :
|
291 | isArray || attr === "c" ? arrIdx(arr, matcher(isRe ? "~" : op)) :
|
292 | ""
|
293 | ) + "(" + v
|
294 | a.push(
|
295 | isArray || attr === "c" ? (isArray == "{}" ? "J(" : "I(") + attr + "," + idd + "))" :
|
296 | m[2] || m[3] ? idd + ")(" + attr + ")" :
|
297 | isRe ? "typeof " + attr + "==='string'&&" + v + ".test(" + attr + ")" :
|
298 | m[6] ? attr + "!==void 0&&" + attr + op + (
|
299 | m[6] == "$" ? "b['"+ m[7] +"']" : "p(" + v + ")(o)"
|
300 | ) :
|
301 | attr + op + v
|
302 | )
|
303 | }
|
304 |
|
305 | return pre + (
|
306 | isArray ? (not ? "||" : "&&") : ""
|
307 | ) + not + "(" + a.join("||") + ")"
|
308 | }
|
309 | }
|
310 |
|
311 | function arrIdx(arr, val) {
|
312 | for (
|
313 | var i = arr.length;
|
314 | 0 <= --i && !(
|
315 | arr[i] === val ||
|
316 | val && val.source && val.source === arr[i].source
|
317 | );
|
318 | );
|
319 | return "a[" + (-1 < i ? i : arr.push(val) - 1) + "]"
|
320 | }
|
321 |
|
322 | function setForm(map, key_, val) {
|
323 | for (var match, key = key_, step = map; match = keyRe.exec(key_); ) {
|
324 | if (step === map) key = key.slice(0, match.index)
|
325 | match = match[1]
|
326 | step = step[key] || (
|
327 | step[key] = match && +match != match ? {} : []
|
328 | )
|
329 | key = match
|
330 | }
|
331 | if (isArray(step)) {
|
332 | step.push(val)
|
333 | } else if (isArray(step[key])) {
|
334 | step[key].push(val)
|
335 | } else {
|
336 | step[key] = step[key] != null ? [step[key], val] : val
|
337 | }
|
338 | }
|
339 |
|
340 | function tr(attrs, aclFn) {
|
341 | var attr, tmp
|
342 | , arr = []
|
343 | , map = {}
|
344 | , i = 0
|
345 | for (; attr = valRe.exec(attrs); ) {
|
346 | tmp = attr[0].split(":")
|
347 | exports.set(map, tmp[0], i)
|
348 | arr[i++] = pathFn(tmp[1] ? attr[0].slice(tmp[0].length+1) : tmp[0])
|
349 | }
|
350 | return Function(
|
351 | "g,a",
|
352 | "return function(o,a){return " +
|
353 | exports.stringify(map).replace(/:(\d+)/g,":g[$1](o)") + "}"
|
354 | )(arr, aclFn)
|
355 | }
|
356 |
|
357 | function isObject(obj) {
|
358 | return !!obj && obj.constructor === Object
|
359 | }
|
360 |
|
361 | function inArray(a, fn, idx) {
|
362 | for (var i = -1, len = a.length; ++i < len; ) {
|
363 | if (fn(a[i])) return idx == null ? a[i] : i
|
364 | }
|
365 | return idx != null && len
|
366 | }
|
367 |
|
368 | function inObject(o, fn, idx) {
|
369 | for (var key in o) {
|
370 | if (fn(o[key])) return idx == null ? o[key] : key
|
371 | }
|
372 | return null
|
373 | }
|
374 |
|
375 | }(JSON, Object)
|
376 |
|
377 |
|