Diffstat (limited to 'frontend/gamma/js/Zepto/selector.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/Zepto/selector.js | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/frontend/gamma/js/Zepto/selector.js b/frontend/gamma/js/Zepto/selector.js new file mode 100644 index 0000000..c0b035a --- a/dev/null +++ b/frontend/gamma/js/Zepto/selector.js | |||
@@ -0,0 +1,81 @@ | |||
1 | ;(function($){ | ||
2 | var zepto = $.zepto, oldQsa = zepto.qsa, oldMatches = zepto.matches | ||
3 | |||
4 | function visible(elem){ | ||
5 | elem = $(elem) | ||
6 | return !!(elem.width() || elem.height()) && elem.css("display") !== "none" | ||
7 | } | ||
8 | |||
9 | // Implements a subset from: | ||
10 | // http://api.jquery.com/category/selectors/jquery-selector-extensions/ | ||
11 | // | ||
12 | // Each filter function receives the current index, all nodes in the | ||
13 | // considered set, and a value if there were parentheses. The value | ||
14 | // of `this` is the node currently being considered. The function returns the | ||
15 | // resulting node(s), null, or undefined. | ||
16 | // | ||
17 | // Complex selectors are not supported: | ||
18 | // li:has(label:contains("foo")) + li:has(label:contains("bar")) | ||
19 | // ul.inner:first > li | ||
20 | var filters = $.expr[':'] = { | ||
21 | visible: function(){ if (visible(this)) return this }, | ||
22 | hidden: function(){ if (!visible(this)) return this }, | ||
23 | selected: function(){ if (this.selected) return this }, | ||
24 | checked: function(){ if (this.checked) return this }, | ||
25 | parent: function(){ return this.parentNode }, | ||
26 | first: function(idx){ if (idx === 0) return this }, | ||
27 | last: function(idx, nodes){ if (idx === nodes.length - 1) return this }, | ||
28 | eq: function(idx, _, value){ if (idx === value) return this }, | ||
29 | contains: function(idx, _, text){ if ($(this).text().indexOf(text) > -1) return this }, | ||
30 | has: function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this } | ||
31 | } | ||
32 | |||
33 | var filterRe = new RegExp('(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*'), | ||
34 | childRe = /^\s*>/, | ||
35 | classTag = 'Zepto' + (+new Date()) | ||
36 | |||
37 | function process(sel, fn) { | ||
38 | // quote the hash in `a[href^=#]` expression | ||
39 | sel = sel.replace(/=#\]/g, '="#"]') | ||
40 | var filter, arg, match = filterRe.exec(sel) | ||
41 | if (match && match[2] in filters) { | ||
42 | var filter = filters[match[2]], arg = match[3] | ||
43 | sel = match[1] | ||
44 | if (arg) { | ||
45 | var num = Number(arg) | ||
46 | if (isNaN(num)) arg = arg.replace(/^["']|["']$/g, '') | ||
47 | else arg = num | ||
48 | } | ||
49 | } | ||
50 | return fn(sel, filter, arg) | ||
51 | } | ||
52 | |||
53 | zepto.qsa = function(node, selector) { | ||
54 | return process(selector, function(sel, filter, arg){ | ||
55 | try { | ||
56 | var taggedParent | ||
57 | if (!sel && filter) sel = '*' | ||
58 | else if (childRe.test(sel)) | ||
59 | // support "> *" child queries by tagging the parent node with a | ||
60 | // unique class and prepending that classname onto the selector | ||
61 | taggedParent = $(node).addClass(classTag), sel = '.'+classTag+' '+sel | ||
62 | |||
63 | var nodes = oldQsa(node, sel) | ||
64 | } catch(e) { | ||
65 | console.error('error performing selector: %o', selector) | ||
66 | throw e | ||
67 | } finally { | ||
68 | if (taggedParent) taggedParent.removeClass(classTag) | ||
69 | } | ||
70 | return !filter ? nodes : | ||
71 | zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) })) | ||
72 | }) | ||
73 | } | ||
74 | |||
75 | zepto.matches = function(node, selector){ | ||
76 | return process(selector, function(sel, filter, arg){ | ||
77 | return (!sel || oldMatches(node, sel)) && | ||
78 | (!filter || filter.call(node, null, arg) === node) | ||
79 | }) | ||
80 | } | ||
81 | })(Zepto) | ||