1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | !function(exports) {
|
14 | var undef
|
15 | , selectorRe = /([.#:[])([-\w]+)(?:\((.+?)\)|([~^$*|]?)=(("|')(?:\\?.)*?\6|[-\w]+))?]?/g
|
16 | , selectorLastRe = /([~\s>+]*)(?:("|')(?:\\?.)*?\2|\(.+?\)|[^\s+>])+$/
|
17 | , selectorSplitRe = /\s*,\s*(?=(?:[^'"()]|"(?:\\?.)*?"|'(?:\\?.)*?'|\(.+?\))+$)/
|
18 | , selectorCache = {}
|
19 | , selectorMap = {
|
20 | "any": "m(_,v)",
|
21 | "empty": "!_.lastChild",
|
22 | "enabled": "!m(_,':disabled')",
|
23 | "first-child": "(a=_.parentNode)&&a.firstChild==_",
|
24 | "first-of-type": "!p(_,_.tagName)",
|
25 | "lang": "m(c(_,'[lang]'),'[lang|='+v+']')",
|
26 | "last-child": "(a=_.parentNode)&&a.lastChild==_",
|
27 | "last-of-type": "!n(_,_.tagName)",
|
28 | "link": "m(_,'a[href]')",
|
29 | "not": "!m(_,v)",
|
30 | "nth-child": "(a=2,'odd'==v?b=1:'even'==v?b=0:a=1 in(v=v.split('n'))?(b=v[1],v[0]):(b=v[0],0),v=_.parentNode.childNodes,v=1+v.indexOf(_),0==a?v==b:('-'==a||0==(v-b)%a)&&(0<a||v<=b))",
|
31 | "only-child": "(a=_.parentNode)&&a.firstChild==a.lastChild",
|
32 | "only-of-type": "!p(_,_.tagName)&&!n(_,_.tagName)",
|
33 | "optional": "!m(_,':required')",
|
34 | "root": "(a=_.parentNode)&&!a.tagName",
|
35 | ".": "~_.className.split(/\\s+/).indexOf(a)",
|
36 | "#": "_.id==a",
|
37 | "^": "!a.indexOf(v)",
|
38 | "|": "a.split('-')[0]==v",
|
39 | "$": "a.slice(-v.length)==v",
|
40 | "~": "~a.split(/\\s+/).indexOf(v)",
|
41 | "*": "~a.indexOf(v)",
|
42 | ">>": "m(_.parentNode,v)",
|
43 | "++": "m(_.previousSibling,v)",
|
44 | "~~": "p(_,v)",
|
45 | "": "c(_.parentNode,v)"
|
46 | }
|
47 |
|
48 | selectorMap["nth-last-child"] = selectorMap["nth-child"].replace("1+", "v.length-")
|
49 |
|
50 | function selectorFn(str) {
|
51 |
|
52 | return selectorCache[str] ||
|
53 | (selectorCache[str] = Function("m,c,n,p", "return function(_,v,a,b){return " +
|
54 | str.split(selectorSplitRe).map(function(sel) {
|
55 | var relation, from
|
56 | , rules = ["_&&_.nodeType==1"]
|
57 | , parentSel = sel.replace(selectorLastRe, function(_, _rel, a, start) {
|
58 | from = start + _rel.length
|
59 | relation = _rel.trim()
|
60 | return ""
|
61 | })
|
62 | , tag = sel.slice(from).replace(selectorRe, function(_, op, key, subSel, fn, val, quotation) {
|
63 | rules.push(
|
64 | "((v='" +
|
65 | (subSel || (quotation ? val.slice(1, -1) : val) || "").replace(/'/g, "\\'") +
|
66 | "'),(a='" + key + "'),1)"
|
67 | ,
|
68 | selectorMap[op == ":" ? key : op] ||
|
69 | "(a=_.getAttribute(a))" +
|
70 | (fn ? "&&" + selectorMap[fn] : val ? "==v" : "")
|
71 | )
|
72 | return ""
|
73 | })
|
74 |
|
75 | if (tag && tag != "*") rules[0] += "&&_.tagName=='" + tag.toUpperCase() + "'"
|
76 | if (parentSel) rules.push("(v='" + parentSel + "')", selectorMap[relation + relation])
|
77 | return rules.join("&&")
|
78 | }).join("||") + "}"
|
79 | )(matches, closest, next, prev))
|
80 | }
|
81 |
|
82 |
|
83 | function walk(next, el, sel, first, nextFn) {
|
84 | var out = []
|
85 | sel = selectorFn(sel)
|
86 | for (; el; el = el[next] || nextFn && nextFn(el)) if (sel(el)) {
|
87 | if (first) return el
|
88 | out.push(el)
|
89 | }
|
90 | return first ? null : out
|
91 | }
|
92 |
|
93 | function find(node, sel, first) {
|
94 | return walk("firstChild", node.firstChild, sel, first, function(el) {
|
95 | var next = el.nextSibling
|
96 | while (!next && ((el = el.parentNode) !== node)) next = el.nextSibling
|
97 | return next
|
98 | })
|
99 | }
|
100 |
|
101 | function matches(el, sel) {
|
102 | return !!selectorFn(sel)(el)
|
103 | }
|
104 |
|
105 | function closest(el, sel) {
|
106 | return walk("parentNode", el, sel, 1)
|
107 | }
|
108 |
|
109 | function next(el, sel) {
|
110 | return walk("nextSibling", el.nextSibling, sel, 1)
|
111 | }
|
112 |
|
113 | function prev(el, sel) {
|
114 | return walk("previousSibling", el.previousSibling, sel, 1)
|
115 | }
|
116 |
|
117 |
|
118 | exports.find = find
|
119 | exports.fn = selectorFn
|
120 | exports.matches = matches
|
121 | exports.closest = closest
|
122 | exports.next = next
|
123 | exports.prev = prev
|
124 | exports.selectorMap = selectorMap
|
125 | }(this)
|
126 |
|