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, 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, 1) + (arr ? "i" : "j") + "(o)&&" + v + (
|
130 | sub[1] ? (arr ? "o" : "K(o)") + (sub[0] === "*" ? "" : ".length") :
|
131 | +arr == arr ? "o[" + (arr < 0 ? "o.length" + arr : arr) + "]" :
|
132 | (arr ? "I" : "J") + "(o,f('" + sub[0] + "'))"
|
133 | ) + ")" :
|
134 | v + "o['" + path + (
|
135 | arr === "" ? "'])&&i(c)&&c" :
|
136 | obj === "" ? "'])&&j(c)&&c" :
|
137 | "'])"
|
138 | )
|
139 | ) + (dot ? "&&" : "")
|
140 | }
|
141 |
|
142 | function pathSet(str, path, arr, obj, dot) {
|
143 | var op = "o['" + path + "']"
|
144 | , out = ""
|
145 | , sub = arr || obj
|
146 | if (sub) {
|
147 | out = "(o="+(arr?"i":"j")+"(o['" + path + "'])?o['" + path + "']:(o['" + path + "']="+(arr?"[]":"{}")+"))&&"
|
148 | if (arr === "-") {
|
149 | op = "o[o.length]"
|
150 | } else if (+arr == arr) {
|
151 | op = "o[" + (arr < 0 ? "o.length" + arr : arr) + "]"
|
152 | } else {
|
153 | if (!onlyFilterRe.test(arr)) throw Error(FILTER_ERR + str)
|
154 | op = "o[t]"
|
155 | out += "(t="+(arr?"I":"J")+"(o,f('" + sub + "'),1))!=null&&"
|
156 | }
|
157 | }
|
158 | return out + (dot ?
|
159 | "(o=typeof " + op + "==='object'&&" + op + "||(" + op + "={}))&&" :
|
160 | "((c=" + op + "),(" + op + "=v),c)"
|
161 | )
|
162 | }
|
163 |
|
164 | function pathFn(str, set) {
|
165 | var map = set === true ? setFns : getFns
|
166 | return map[str] || (map[str] = Function(
|
167 | "i,j,I,J,K,f",
|
168 | "return function(d,v,b){var c,o,t;return (o=d)&&" +
|
169 | pathStr(str, set) +
|
170 | (set ? ",c}": "!==void 0?c:v}")
|
171 | )(isArray, isObject, inArray, inObject, KEYS, matcher))
|
172 | }
|
173 |
|
174 | function clone(obj) {
|
175 | var temp, key
|
176 | if (obj && typeof obj == "object") {
|
177 |
|
178 | temp = obj instanceof Date ? new Date(+obj) :
|
179 | obj instanceof RegExp ? RegExp(obj.source, (""+obj).split("/").pop()) :
|
180 | obj.constructor()
|
181 | for (key in obj) if (hasOwn.call(obj, key)) {
|
182 | temp[key] = clone(obj[key])
|
183 | }
|
184 | obj = temp
|
185 | }
|
186 | return obj
|
187 | }
|
188 |
|
189 | function matcher(str, prefix, opts, getter, tmp) {
|
190 | var optimized
|
191 | , arr = []
|
192 | , key = (prefix || "") + (fns[str] || filterStr(str, opts, arr, getter))
|
193 | , fn = filterFns[key]
|
194 | if (!fn) {
|
195 | for (optimized = key; optimized != (optimized = optimized.replace(cleanRe, "$1")); );
|
196 | fn = filterFns[key] = Function(
|
197 | fns[str] ? "a" : "a,i,j,I,J,K,f,p,t",
|
198 | "return function(d,b){var o;return " + optimized + "}"
|
199 | )
|
200 | fn.source = optimized
|
201 | }
|
202 | return fns[str] ? fn : fn(
|
203 | arr, isArray, isObject, inArray, inObject, KEYS, matcher, pathFn, tmp
|
204 | )
|
205 | }
|
206 |
|
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | matcher.date = function(str) {
|
217 | return matcher(str, "(t.setTime(+d)>=0)&&", null, dateGetter, tmpDate)
|
218 | }
|
219 |
|
220 | function dateGetter(name) {
|
221 | return "(t.get" + fnMap[name] + ")"
|
222 | }
|
223 |
|
224 | function filterStr(qs, opts, arr, getter) {
|
225 | return qs.replace(filterRe, worker).replace(/^[1&]&+|&+1?$/g, "") || "1"
|
226 |
|
227 | function worker(all, not, isOption, attr, isArray, op, val, q1, q2, q3, ext, ok2, ok1) {
|
228 | if (ext) {
|
229 | if (!ok2 && !ok1) {
|
230 | throw Error(FILTER_ERR + qs)
|
231 | }
|
232 | return ok1 ? ok1 : ok2 == ";" ? "&&" : ok2 + ok2
|
233 | }
|
234 | if (isOption) {
|
235 | if (opts) opts[attr] = val
|
236 | return "1"
|
237 | }
|
238 |
|
239 | var idd, m, v, isRe
|
240 | , a = []
|
241 | , pre = "(o=d)&&"
|
242 |
|
243 | attr = (getter || pathStr)(attr)
|
244 |
|
245 | if (m = attr.match(/\(c=(.*?)\)$/)) {
|
246 | if (m[1] == "K(o)") {
|
247 | pre += attr + "&&"
|
248 | attr = "c"
|
249 | } else {
|
250 | if (m.index) pre += attr.slice(0, m.index)
|
251 | attr = m[1]
|
252 | }
|
253 | }
|
254 |
|
255 | if (op == "!=" || op == "!==") {
|
256 | not = "!"
|
257 | op = op.slice(1)
|
258 | }
|
259 | if (isArray) {
|
260 | pre += not + (isArray === "[]" ? "i(" : "j(") + attr + ")"
|
261 | }
|
262 |
|
263 | if (!op) {
|
264 | return isArray === "" ? pre + not + attr : pre
|
265 | }
|
266 |
|
267 | if (op == "=" || op == "==") op += "="
|
268 | if (val === "") val="''"
|
269 | for (; m = valRe.exec(val); ) {
|
270 |
|
271 |
|
272 | isRe = 0
|
273 | v = m[6] == "$" ? "b['"+ m[7] +"']" : arrIdx(arr,
|
274 | m[1] || m[3] ? m[0].slice(m[3] ? m[2].length + 1 : 1, -1) :
|
275 | m[6] ? m[7] :
|
276 | primitiveRe.test(m[0]) ? JSON.parse(m[0]) :
|
277 | (isRe = globRe.test(m[0])) ? RegExp(
|
278 | "^" + m[0]
|
279 | .replace(reEscRe, "\\$&")
|
280 | .replace(globReplace, ".")
|
281 | .replace(globGroup, "[^") + "$",
|
282 | op === "==" ? "i" : ""
|
283 | ) :
|
284 | m[0]
|
285 | )
|
286 | idd = (
|
287 | m[2] ? "f." + m[2].toLowerCase() :
|
288 | m[3] ? "f" :
|
289 | isArray || attr === "c" ? arrIdx(arr, matcher(isRe ? "~" : op)) :
|
290 | ""
|
291 | ) + "(" + v
|
292 | a.push(
|
293 | isArray || attr === "c" ? (isArray == "{}" ? "J(" : "I(") + attr + "," + idd + "))" :
|
294 | m[2] || m[3] ? idd + ")(" + attr + ")" :
|
295 | isRe ? "typeof " + attr + "==='string'&&" + v + ".test(" + attr + ")" :
|
296 | m[6] ? attr + "!==void 0&&" + attr + op + (
|
297 | m[6] == "$" ? "b['"+ m[7] +"']" : "p(" + v + ")(o)"
|
298 | ) :
|
299 | attr + op + v
|
300 | )
|
301 | }
|
302 |
|
303 | return pre + (
|
304 | isArray ? (not ? "||" : "&&") : ""
|
305 | ) + not + "(" + a.join("||") + ")"
|
306 | }
|
307 | }
|
308 |
|
309 | function arrIdx(arr, val) {
|
310 | for (
|
311 | var i = arr.length;
|
312 | 0 <= --i && !(
|
313 | arr[i] === val ||
|
314 | val && val.source && val.source === arr[i].source
|
315 | );
|
316 | );
|
317 | return "a[" + (-1 < i ? i : arr.push(val) - 1) + "]"
|
318 | }
|
319 |
|
320 | function setForm(map, key_, val) {
|
321 | for (var match, key = key_, step = map; match = keyRe.exec(key_); ) {
|
322 | if (step === map) key = key.slice(0, match.index)
|
323 | match = match[1]
|
324 | step = step[key] || (
|
325 | step[key] = match && +match != match ? {} : []
|
326 | )
|
327 | key = match
|
328 | }
|
329 | if (isArray(step)) {
|
330 | step.push(val)
|
331 | } else if (isArray(step[key])) {
|
332 | step[key].push(val)
|
333 | } else {
|
334 | step[key] = step[key] != null ? [step[key], val] : val
|
335 | }
|
336 | }
|
337 |
|
338 | function tr(attrs, aclFn) {
|
339 | var attr, tmp
|
340 | , arr = []
|
341 | , map = {}
|
342 | , i = 0
|
343 | for (; attr = valRe.exec(attrs); ) {
|
344 | tmp = attr[0].split(":")
|
345 | exports.set(map, tmp[0], i)
|
346 | arr[i++] = pathFn(tmp[1] ? attr[0].slice(tmp[0].length+1) : tmp[0])
|
347 | }
|
348 | return Function(
|
349 | "g,a",
|
350 | "return function(o,a){return " +
|
351 | JSON.stringify(map).replace(/:(\d+)/g,":g[$1](o)") + "}"
|
352 | )(arr, aclFn)
|
353 | }
|
354 |
|
355 | function isObject(obj) {
|
356 | return !!obj && obj.constructor === Object
|
357 | }
|
358 |
|
359 | function inArray(a, fn, idx) {
|
360 | for (var i = -1, len = a.length; ++i < len; ) {
|
361 | if (fn(a[i])) return idx == null ? a[i] : i
|
362 | }
|
363 | return idx != null && len
|
364 | }
|
365 |
|
366 | function inObject(o, fn, idx) {
|
367 | for (var key in o) {
|
368 | if (fn(o[key])) return idx == null ? o[key] : key
|
369 | }
|
370 | return null
|
371 | }
|
372 |
|
373 | }(JSON, Object)
|
374 |
|
375 |
|