├── .gitignore ├── vendor ├── sabajs-logo.png └── zepto.js ├── examples ├── ajax.html └── selector.html ├── LICENSE ├── README.md ├── saba.min.js └── saba.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | bower_components 5 | .idea -------------------------------------------------------------------------------- /vendor/sabajs-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudist/sabajs/HEAD/vendor/sabajs-logo.png -------------------------------------------------------------------------------- /examples/ajax.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 |

SabaJS Ajax Demo

20 | 21 |

22 | api will request a local jquery js file. and fill the following block with the content. 23 |

24 | 25 | 26 | 27 | Waiting for content... 28 | 29 | 30 | 31 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Cloudist Technology Co., Ltd. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /examples/selector.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 |

SabaJS Selector Demo

17 | 18 |
19 |

select the sub elements

20 | 21 | 27 | 28 | 29 | 30 | 43 |
44 | 45 | 46 |
47 |

Select By Class

48 | 49 | 55 | 56 | 57 | 58 | 69 | 70 |
71 | 72 |
73 |

Val

74 | 75 |
76 | 77 | 78 |
79 | 80 | 81 | 82 | 83 | 92 |
93 | 94 |
95 |

Empty & HTML

96 | 97 |

98 | This is test Aera 99 |

100 | 101 | 102 | 103 | 104 | 105 | 120 | 121 |
122 | 123 |
124 |

Attr

125 | 126 |

127 | attr test 128 |

129 | 130 | 131 | 136 |
137 | 138 |
139 |

Text

140 | 141 | 142 | Text1 143 | 144 | 145 | 146 | 147 | 148 | 158 |
159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SabaJS 2 | 3 | ![SabaJS](vendor/sabajs-logo.png) 4 | 5 | SabaJS is a light-weight cross-platform JavaScript library that provides some frequently used functions. 6 | 7 | Insipred by Qwery and Underscore. 8 | 9 | > saba: 青花鱼 10 | > 作者 Tomi 在居酒屋做兼职,那里的烤青花鱼是我们的最爱。 11 | 12 | 13 | ## Browser Support 14 | 15 | - IE 6+ 16 | - Chrome 1+ 17 | - Safari 3+ 18 | - Firefox 4+ 19 | 20 | 21 | ## API 22 | 23 | ### AJAX 24 | 25 | **Usage:** 26 | 27 | _.ajax({options}) 28 | 29 | **Example:** 30 | 31 | _.ajax({ 32 | url: URL, 33 | method: 'get' 34 | }).fail(function (xhr) { 35 | // do with xhr 36 | }).done(function (data) { 37 | // do with data 38 | }); 39 | 40 | **Options:** 41 | 42 | url: URL string 43 | method: HTTP method ['get', 'post'] 44 | headers: HTTP headers 45 | data: HTTP request data 46 | json: boolean, trigger JSON response wrapping 47 | 48 | ### Element Selector 49 | 50 | **Usage:** 51 | 52 | _.el(selector) 53 | 54 | **Selector Support:** 55 | 56 | /* basic */ 57 | #foo {} /* id */ 58 | .bar {} /* class */ 59 | a#foo.bar {} /* element attribute combinations */ 60 | 61 | /* attributes */ 62 | #foo a[href] {} /* simple */ 63 | #foo a[href=bar] {} /* attribute values */ 64 | #foo a[lang|=en] {} /* subcodes */ 65 | #foo a[title~=hello] {} /* attribute contains */ 66 | #foo a[href^="http://"] {} /* attribute starts with */ 67 | #foo a[href$=com] {} /* attribute ends with */ 68 | #foo a[href*=twitter] /* {} attribute wildcards */ 69 | 70 | /* descendants */ 71 | #foo a {} /* all descendants */ 72 | ul#list > li {} /* direct children */ 73 | 74 | /* siblings */ 75 | span ~ strong {} /* all adjacent */ 76 | p + p {} /* immediate adjacent */ 77 | 78 | /* combos */ 79 | div,p {} 80 | 81 | /* variations */ 82 | #foo.bar.baz {} 83 | div#baz.thunk a[-data-info*="hello world"] span + strong {} 84 | #thunk[title$='huzza'] {} 85 | 86 | ### Element Methods 87 | 88 | #### html 89 | 90 | **\_.el(selector).html([HTML])** 91 | 92 | return the inner HTML of element or set the element's HTML 93 | 94 | **Returns:** 95 | 96 | With HTML argument: will return a string. 97 | Without HTML argument will return None. 98 | 99 | **Example:** 100 | 101 | _.el(selector).html() 102 | => return the html of the selected element or the first elements selected. 103 | 104 | _.el(selector).html(HTML_String) 105 | => set the innerHTML to the specified HTML string. 106 | 107 | 108 | #### each 109 | 110 | **\_.el(selector).each( callback(index, item ) )** 111 | 112 | 113 | **Returns:** 114 | 115 | None 116 | 117 | **Example:** 118 | 119 | _.el(selector).each(function(index, item){ 120 | console.log(item); 121 | }) 122 | 123 | #### empty 124 | 125 | **\_.el(selector).empty()** 126 | 127 | empty the content of selected element(s). 128 | 129 | **Returns:** 130 | 131 | None 132 | 133 | **Example:** 134 | 135 | _.el(selector).empty() 136 | => _.el(selector).html() === '' -> true 137 | 138 | 139 | #### addClass 140 | 141 | **\_.el(selector).addClass(className)** 142 | 143 | add a class to the selected element(s). 144 | 145 | **Returns:** 146 | 147 | None 148 | 149 | **Example:** 150 | 151 | _.el(selector).addClass('active') 152 | => _.el(selector).hasClass('active') -> true 153 | 154 | 155 | #### hasClass 156 | 157 | **\_.el(selector).hasClass(className)** 158 | 159 | add a class to the selected element(s). 160 | 161 | **Returns:** 162 | 163 | Boolean 164 | 165 | **Example:** 166 | 167 | _.el(selector).addClass('active') 168 | => _.el(selector).hasClass('active') -> true 169 | 170 | 171 | 172 | #### removeClass 173 | 174 | **\_.el(selector).removeClass(className)** 175 | 176 | remove a class from the selected element(s). 177 | 178 | **Returns:** 179 | 180 | None 181 | 182 | **Example:** 183 | 184 | _.el(selector).addClass('active') 185 | => _.el(selector).hasClass('active') -> true 186 | _.el(selector).removeClass('active') 187 | => _.el(selector).hasClass('active') -> false 188 | 189 | 190 | 191 | #### val 192 | 193 | **\_.el(selector).val([value])** 194 | 195 | get the value of selected element(s). 196 | or set the value to selected element(s). 197 | 198 | **Returns:** 199 | 200 | With value argument: will return a string that is the value of the selected element(s). 201 | Without value argument: None. 202 | 203 | **Example:** 204 | 205 | console.log(_.el(selector).val()); 206 | 207 | _.el(selector).val('some value') 208 | => _.el(selector).val() === 'some value' -> true 209 | 210 | #### text 211 | 212 | **\_.el(selector).text([text])** 213 | 214 | set the text content of the selected element(s). 215 | or get the text content of selected element(s). 216 | 217 | **Returns:** 218 | 219 | With text argument: None. 220 | Without text argument: String of text content. 221 | 222 | **Example:** 223 | 224 | console.log(_.el(selector).text()); 225 | 226 | _.el(selector).text('some text') 227 | => _.el(selector).text() === 'some text' -> true 228 | 229 | #### on 230 | 231 | **\_.el(selector).on( event, callback )** 232 | 233 | add a event listener to selected element(s). 234 | 235 | **Returns:** 236 | 237 | None 238 | 239 | **Example:** 240 | 241 | _.el(selector).on('click', function() { alert('clicked') }); 242 | 243 | #### off 244 | 245 | **\_.el(selector).on( event, callback )** 246 | 247 | remove a event listener from selected element(s). 248 | 249 | **Returns:** 250 | 251 | None 252 | 253 | **Example:** 254 | 255 | _.el(selector).off('click', function() { alert('clicked') }); 256 | 257 | 258 | #### attr 259 | 260 | **\_.el(selector).attr( name, [value] )** 261 | 262 | set the attribute to the selected element(s). 263 | or get the attribute value from selected element(s) 264 | 265 | **Returns:** 266 | 267 | None 268 | 269 | **Example:** 270 | 271 | _.el(selector).attr('id', 'someThing'); 272 | _.el(selector).attr('id') === 'someThing' => true; 273 | 274 | 275 | #### removeAttr 276 | 277 | **\_.el(selector).removeAttr( name )** 278 | 279 | remove an attribute from the selected element(s). 280 | 281 | **Returns:** 282 | 283 | None 284 | 285 | **Example:** 286 | 287 | _.el(selector).attr('id', 'someThing'); 288 | _.el(selector).attr('id') === 'someThing' => true; 289 | 290 | _.el(selector).removeAttr('id'); 291 | _.el(selector).attr('id') === undefined => true; 292 | 293 | 294 | ## License 295 | 296 | MIT License, see the included file. 297 | -------------------------------------------------------------------------------- /saba.min.js: -------------------------------------------------------------------------------- 1 | (function(){function t(t){return"function"==typeof t}function e(t){return"object"==typeof t}function n(e,n,r,i){return t(n)?n.call(e,r,i):n}function r(t,e){var n=t.className||"",r=n&&void 0!==n.baseVal;return void 0===e?r?n.baseVal:n:void(r?n.baseVal=e:t.className=e)}function i(t){return t in f?f[t]:f[t]=new RegExp("(^|\\s)"+t+"(\\s|$)")}function s(t,e,n){null==n?t.removeAttribute(e):t.setAttribute(e,n)}function u(){if(window.ActiveXObject)return new ActiveXObject("Microsoft.XMLHTTP");if(window.XMLHttpRequest)return new XMLHttpRequest;throw new Error("Cannot create XML HTTP request")}function o(t,e,n){t.attachEvent?(t["e"+e+n]=n,t[e+n]=function(){t["e"+e+n](window.event)},t.attachEvent("on"+e,t[e+n])):t.addEventListener(e,n,!1)}function a(t,e,n){t.detachEvent?(t.detachEvent("on"+e,t[e+n]),t[e+n]=null):t.removeEventListener(e,n,!1)}var c,h,f={},l=function(t){return t instanceof l?t:this instanceof l?void(this._wrapped=t):new l(t)};l.VERSION="0.0.1";var p=function(){function t(){this.c={}}function e(t){return G.g(t)||G.s(t,"(^|\\s+)"+t+"(\\s+|$)",1)}function n(t,e){for(var n=0,r=t.length;r>n;n++)e(t[n])}function r(t){for(var e=[],n=0,r=t.length;r>n;++n)g(t[n])?e=e.concat(t[n]):e[e.length]=t[n];return e}function i(t){for(var e=0,n=t.length,r=[];n>e;e++)r[e]=t[e];return r}function s(t){for(;(t=t.previousSibling)&&1!=t[H];);return t}function u(t){return t.match(Q)}function o(t,n,r,i,s,u,o,a,h,f,l){var p,d,g,v,m;if(1!==this[H])return!1;if(n&&"*"!==n&&this[T]&&this[T].toLowerCase()!==n)return!1;if(r&&(d=r.match(L))&&d[1]!==this.id)return!1;if(r&&(m=r.match(k)))for(p=m.length;p--;)if(!e(m[p].slice(1)).test(this.className))return!1;if(h&&w.pseudos[h]&&!w.pseudos[h](this,l))return!1;if(i&&!o){v=this.attributes;for(g in v)if(Object.prototype.hasOwnProperty.call(v,g)&&(v[g].name||g)==s)return this}return i&&!c(u,Z(this,s)||"",o)?!1:this}function a(t){return U.g(t)||U.s(t,t.replace(D,"\\$1"))}function c(t,e,n){switch(t){case"=":return e==n;case"^=":return e.match(W.g("^="+n)||W.s("^="+n,"^"+a(n),1));case"$=":return e.match(W.g("$="+n)||W.s("$="+n,a(n)+"$",1));case"*=":return e.match(W.g(n)||W.s(n,a(n),1));case"~=":return e.match(W.g("~="+n)||W.s("~="+n,"(?:^|\\s+)"+a(n)+"(?:\\s+|$)",1));case"|=":return e.match(W.g("|="+n)||W.s("|="+n,"^"+a(n)+"(-|$)",1))}return 0}function h(t,e){var r,i,s,a,c,h,f,p=[],d=[],g=e,v=K.g(t)||K.s(t,t.split(J)),w=t.match(_);if(!v.length)return p;if(a=(v=v.slice(0)).pop(),v.length&&(s=v[v.length-1].match(R))&&(g=m(e,s[1])),!g)return p;for(h=u(a),c=g!==e&&9!==g[H]&&w&&/^[+~]$/.test(w[w.length-1])?function(t){for(;g=g.nextSibling;)1==g[H]&&(h[1]?h[1]==g[T].toLowerCase():1)&&(t[t.length]=g);return t}([]):g[N](h[1]||"*"),r=0,i=c.length;i>r;r++)(f=o.apply(c[r],h))&&(p[p.length]=f);return v.length?(n(p,function(t){l(t,v,w)&&(d[d.length]=t)}),d):p}function f(t,e,n){if(p(e))return t==e;if(g(e))return!!~r(e).indexOf(t);for(var i,s,a=e.split(",");e=a.pop();)if(i=K.g(e)||K.s(e,e.split(J)),s=e.match(_),i=i.slice(0),o.apply(t,u(i.pop()))&&(!i.length||l(t,i,s,n)))return!0;return!1}function l(t,e,n,r){function i(t,r,a){for(;a=z[n[r]](a,t);)if(p(a)&&o.apply(a,u(e[r]))){if(!r)return a;if(s=i(a,r-1,a))return s}}var s;return(s=i(t,e.length-1,t))&&(!r||Y(s,r))}function p(t,e){return t&&"object"==typeof t&&(e=t[H])&&(1==e||9==e)}function d(t){var e,n,r=[];t:for(e=0;e~+]/,O=/^\s+|\s*([,\s\+\~>]|$)\s*/g,X=/[\s\>\+\~]/,F=/(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/,D=/([.*+?\^=!:${}()|\[\]\/\\])/g,P=/^(\*|[a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/,B=/\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/,I=/:([\w\-]+)(\(['"]?([^()]+)['"]?\))?/,V=new RegExp(R.source+"|"+S.source+"|"+q.source),_=new RegExp("("+X.source+")"+F.source,"g"),J=new RegExp(X.source+F.source),Q=new RegExp(P.source+"("+B.source+")?("+I.source+")?"),z={" ":function(t){return t&&t!==C&&t.parentNode},">":function(t,e){return t&&t.parentNode==e.parentNode&&t.parentNode},"~":function(t){return t&&t.previousSibling},"+":function(t,e,n,r){return t?(n=s(t))&&(r=s(e))&&n==r&&n:!1}};t.prototype={g:function(t){return this.c[t]||void 0},s:function(t,e,n){return e=n?new RegExp(e):e,this.c[t]=e}};var G=new t,U=new t,W=new t,K=new t,Y="compareDocumentPosition"in C?function(t,e){return 16==(16&e.compareDocumentPosition(t))}:"contains"in C?function(t,e){return e=9===e[H]||e==window?C:e,e!==t&&e.contains(t)}:function(t,e){for(;t=t.parentNode;)if(t===e)return 1;return 0},Z=function(){var t=b.createElement("p");return(t.innerHTML='x')&&"#x"!=t.firstChild.getAttribute("href")?function(t,e){return"class"===e?t.className:"href"===e||"src"===e?t.getAttribute(e,2):t.getAttribute(e)}:function(t,e){return t.getAttribute(e)}}(),tt=!!b[E],et=b.querySelector&&b[A],nt=function(t,e){var r,s,u=[];try{return 9!==e[H]&&M.test(t)?(n(r=t.split(","),y(e,function(t,e){s=t[A](e),1==s.length?u[u.length]=s.item(0):s.length&&(u=u.concat(i(s)))})),r.length>1&&u.length>1?d(u):u):i(e[A](t))}catch(o){}return rt(t,e)},rt=function(t,r){var i,s,u,o,a,c,f=[];if(t=t.replace(O,"$1"),s=t.match(j)){for(a=e(s[2]),i=r[N](s[1]||"*"),u=0,o=i.length;o>u;u++)a.test(i[u].className)&&(f[f.length]=i[u]);return f}return n(c=t.split(","),y(r,function(t,e,n){for(a=h(e,t),u=0,o=a.length;o>u;u++)(9===t[H]||n||Y(a[u],r))&&(f[f.length]=a[u])})),c.length>1&&f.length>1?d(f):f},it=function(t){"undefined"!=typeof t[$]&&(x=t[$]&&et?nt:rt)};return it({useNativeQSA:!0}),w.configure=it,w.uniq=d,w.is=f,w.pseudos={},w}();l.el=function(t){return c(t)};var d={request:function(t){"string"==typeof t&&(t={url:t}),t.url=t.url||"",t.method=t.method||"get",t.data=t.data||{};var e=function(t,e){var n,r=[];for(var i in t)r.push(i+"="+encodeURIComponent(t[i]));return n=r.join("&"),""!=n?e?e.indexOf("?")<0?"?"+n:"&"+n:n:""},n={host:{},process:function(t){var n=this;return this.xhr=u(),this.xhr.onreadystatechange=function(){if(4==n.xhr.readyState&&200==n.xhr.status){var e=n.xhr.responseText;t.json===!0&&"undefined"!=typeof JSON&&(e=JSON.parse(e)),n.doneCallback&&n.doneCallback.apply(n.host,[e,n.xhr])}else 4==n.xhr.readyState&&n.failCallback&&n.failCallback.apply(n.host,[n.xhr]);n.alwaysCallback&&n.alwaysCallback.apply(n.host,[n.xhr])},"get"==t.method?this.xhr.open("GET",t.url+e(t.data,t.url),!0):(this.xhr.open(t.method,t.url,!0),this.setHeaders({"X-Requested-With":"XMLHttpRequest","Content-type":"application/x-www-form-urlencoded"})),t.headers&&"object"==typeof t.headers&&this.setHeaders(t.headers),setTimeout(function(){"get"===t.method?n.xhr.send():n.xhr.send(e(t.data))},20),this},done:function(t){return this.doneCallback=t,this},fail:function(t){return this.failCallback=t,this},always:function(t){return this.alwaysCallback=t,this},setHeaders:function(t){for(var e in t)this.xhr.setRequestHeader(e,t[e])}};return n.process(t)}};l.ajax=d.request,c=function(t){var e=p(t);return e.html=c.fn.html,e.each=c.fn.each,e.empty=c.fn.empty,e.addClass=c.fn.addClass,e.hasClass=c.fn.hasClass,e.removeClass=c.fn.removeClass,e.trim=c.fn.trim,e.val=c.fn.val,e.on=c.fn.on,e.off=c.fn.off,e.attr=c.fn.attr,e.removeAttr=c.fn.removeAttr,e.text=c.fn.text,e},c.fn={trim:function(t){var e=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;return null==t?"":(t+"").replace(e,"")},each:function(t){for(var e=0;er;r++)if(1===this[r].nodeType&&(" "+this[r].className+" ").replace(e," ").indexOf(n)>=0)return!0;return!1},addClass:function(t){return t?this.each(function(e){if("className"in this){h=[];for(var i=r(this),s=n(this,t,e,i),u=s.split(/\s+/g),o=0;o~+]/ 104 | , normalizr = /^\s+|\s*([,\s\+\~>]|$)\s*/g 105 | , splitters = /[\s\>\+\~]/ 106 | , splittersMore = /(?![\s\w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^'"]*\]|[\s\w\+\-]*\))/ 107 | , specialChars = /([.*+?\^=!:${}()|\[\]\/\\])/g 108 | , simple = /^(\*|[a-z0-9]+)?(?:([\.\#]+[\w\-\.#]+)?)/ 109 | , attr = /\[([\w\-]+)(?:([\|\^\$\*\~]?\=)['"]?([ \w\-\/\?\&\=\:\.\(\)\!,@#%<>\{\}\$\*\^]+)["']?)?\]/ 110 | , pseudo = /:([\w\-]+)(\(['"]?([^()]+)['"]?\))?/ 111 | , easy = new RegExp(idOnly.source + '|' + tagOnly.source + '|' + classOnly.source) 112 | , dividers = new RegExp('(' + splitters.source + ')' + splittersMore.source, 'g') 113 | , tokenizr = new RegExp(splitters.source + splittersMore.source) 114 | , chunker = new RegExp(simple.source + '(' + attr.source + ')?' + '(' + pseudo.source + ')?') 115 | 116 | var walker = { 117 | ' ': function (node) { 118 | return node && node !== html && node.parentNode 119 | } 120 | , '>': function (node, contestant) { 121 | return node && node.parentNode == contestant.parentNode && node.parentNode 122 | } 123 | , '~': function (node) { 124 | return node && node.previousSibling 125 | } 126 | , '+': function (node, contestant, p1, p2) { 127 | if (!node) return false 128 | return (p1 = previous(node)) && (p2 = previous(contestant)) && p1 == p2 && p1 129 | } 130 | } 131 | 132 | function cache() { 133 | this.c = {} 134 | } 135 | 136 | cache.prototype = { 137 | g: function (k) { 138 | return this.c[k] || undefined 139 | } 140 | , s: function (k, v, r) { 141 | v = r ? new RegExp(v) : v 142 | return (this.c[k] = v) 143 | } 144 | } 145 | 146 | var classCache = new cache() 147 | , cleanCache = new cache() 148 | , attrCache = new cache() 149 | , tokenCache = new cache() 150 | 151 | function classRegex(c) { 152 | return classCache.g(c) || classCache.s(c, '(^|\\s+)' + c + '(\\s+|$)', 1) 153 | } 154 | 155 | // not quite as fast as inline loops in older browsers so don't use liberally 156 | function each(a, fn) { 157 | var i = 0, l = a.length 158 | for (; i < l; i++) fn(a[i]) 159 | } 160 | 161 | function flatten(ar) { 162 | for (var r = [], i = 0, l = ar.length; i < l; ++i) arrayLike(ar[i]) ? (r = r.concat(ar[i])) : (r[r.length] = ar[i]) 163 | return r 164 | } 165 | 166 | function arrayify(ar) { 167 | var i = 0, l = ar.length, r = [] 168 | for (; i < l; i++) r[i] = ar[i] 169 | return r 170 | } 171 | 172 | function previous(n) { 173 | while (n = n.previousSibling) if (n[nodeType] == 1) break; 174 | return n 175 | } 176 | 177 | function q(query) { 178 | return query.match(chunker) 179 | } 180 | 181 | // called using `this` as element and arguments from regex group results. 182 | // given => div.hello[title="world"]:foo('bar') 183 | // div.hello[title="world"]:foo('bar'), div, .hello, [title="world"], title, =, world, :foo('bar'), foo, ('bar'), bar] 184 | function interpret(whole, tag, idsAndClasses, wholeAttribute, attribute, qualifier, value, wholePseudo, pseudo, wholePseudoVal, pseudoVal) { 185 | var i, m, k, o, classes 186 | if (this[nodeType] !== 1) return false 187 | if (tag && tag !== '*' && this[tagName] && this[tagName].toLowerCase() !== tag) return false 188 | if (idsAndClasses && (m = idsAndClasses.match(id)) && m[1] !== this.id) return false 189 | if (idsAndClasses && (classes = idsAndClasses.match(clas))) { 190 | for (i = classes.length; i--;) if (!classRegex(classes[i].slice(1)).test(this.className)) return false 191 | } 192 | if (pseudo && qwery.pseudos[pseudo] && !qwery.pseudos[pseudo](this, pseudoVal)) return false 193 | if (wholeAttribute && !value) { // select is just for existance of attrib 194 | o = this.attributes 195 | for (k in o) { 196 | if (Object.prototype.hasOwnProperty.call(o, k) && (o[k].name || k) == attribute) { 197 | return this 198 | } 199 | } 200 | } 201 | if (wholeAttribute && !checkAttr(qualifier, getAttr(this, attribute) || '', value)) { 202 | // select is for attrib equality 203 | return false 204 | } 205 | return this 206 | } 207 | 208 | function clean(s) { 209 | return cleanCache.g(s) || cleanCache.s(s, s.replace(specialChars, '\\$1')) 210 | } 211 | 212 | function checkAttr(qualify, actual, val) { 213 | switch (qualify) { 214 | case '=': 215 | return actual == val 216 | case '^=': 217 | return actual.match(attrCache.g('^=' + val) || attrCache.s('^=' + val, '^' + clean(val), 1)) 218 | case '$=': 219 | return actual.match(attrCache.g('$=' + val) || attrCache.s('$=' + val, clean(val) + '$', 1)) 220 | case '*=': 221 | return actual.match(attrCache.g(val) || attrCache.s(val, clean(val), 1)) 222 | case '~=': 223 | return actual.match(attrCache.g('~=' + val) || attrCache.s('~=' + val, '(?:^|\\s+)' + clean(val) + '(?:\\s+|$)', 1)) 224 | case '|=': 225 | return actual.match(attrCache.g('|=' + val) || attrCache.s('|=' + val, '^' + clean(val) + '(-|$)', 1)) 226 | } 227 | return 0 228 | } 229 | 230 | // given a selector, first check for simple cases then collect all base candidate matches and filter 231 | function _qwery(selector, _root) { 232 | var r = [], ret = [], i, l, m, token, tag, els, intr, item, root = _root 233 | , tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr)) 234 | , dividedTokens = selector.match(dividers) 235 | 236 | if (!tokens.length) return r 237 | 238 | token = (tokens = tokens.slice(0)).pop() // copy cached tokens, take the last one 239 | if (tokens.length && (m = tokens[tokens.length - 1].match(idOnly))) root = byId(_root, m[1]) 240 | if (!root) return r 241 | 242 | intr = q(token) 243 | // collect base candidates to filter 244 | els = root !== _root && root[nodeType] !== 9 && dividedTokens && /^[+~]$/.test(dividedTokens[dividedTokens.length - 1]) ? 245 | function (r) { 246 | while (root = root.nextSibling) { 247 | root[nodeType] == 1 && (intr[1] ? intr[1] == root[tagName].toLowerCase() : 1) && (r[r.length] = root) 248 | } 249 | return r 250 | }([]) : 251 | root[byTag](intr[1] || '*') 252 | // filter elements according to the right-most part of the selector 253 | for (i = 0, l = els.length; i < l; i++) { 254 | if (item = interpret.apply(els[i], intr)) r[r.length] = item 255 | } 256 | if (!tokens.length) return r 257 | 258 | // filter further according to the rest of the selector (the left side) 259 | each(r, function (e) { 260 | if (ancestorMatch(e, tokens, dividedTokens)) ret[ret.length] = e 261 | }) 262 | return ret 263 | } 264 | 265 | // compare element to a selector 266 | function is(el, selector, root) { 267 | if (isNode(selector)) return el == selector 268 | if (arrayLike(selector)) return !!~flatten(selector).indexOf(el) // if selector is an array, is el a member? 269 | 270 | var selectors = selector.split(','), tokens, dividedTokens 271 | while (selector = selectors.pop()) { 272 | tokens = tokenCache.g(selector) || tokenCache.s(selector, selector.split(tokenizr)) 273 | dividedTokens = selector.match(dividers) 274 | tokens = tokens.slice(0) // copy array 275 | if (interpret.apply(el, q(tokens.pop())) && (!tokens.length || ancestorMatch(el, tokens, dividedTokens, root))) { 276 | return true 277 | } 278 | } 279 | return false 280 | } 281 | 282 | // given elements matching the right-most part of a selector, filter out any that don't match the rest 283 | function ancestorMatch(el, tokens, dividedTokens, root) { 284 | var cand 285 | // recursively work backwards through the tokens and up the dom, covering all options 286 | function crawl(e, i, p) { 287 | while (p = walker[dividedTokens[i]](p, e)) { 288 | if (isNode(p) && (interpret.apply(p, q(tokens[i])))) { 289 | if (i) { 290 | if (cand = crawl(p, i - 1, p)) return cand 291 | } else return p 292 | } 293 | } 294 | } 295 | 296 | return (cand = crawl(el, tokens.length - 1, el)) && (!root || isAncestor(cand, root)) 297 | } 298 | 299 | function isNode(el, t) { 300 | return el && typeof el === 'object' && (t = el[nodeType]) && (t == 1 || t == 9) 301 | } 302 | 303 | function uniq(ar) { 304 | var a = [], i, j; 305 | o: 306 | for (i = 0; i < ar.length; ++i) { 307 | for (j = 0; j < a.length; ++j) if (a[j] == ar[i]) continue o 308 | a[a.length] = ar[i] 309 | } 310 | return a 311 | } 312 | 313 | function arrayLike(o) { 314 | return (typeof o === 'object' && isFinite(o.length)) 315 | } 316 | 317 | function normalizeRoot(root) { 318 | if (!root) return doc 319 | if (typeof root == 'string') return qwery(root)[0] 320 | if (!root[nodeType] && arrayLike(root)) return root[0] 321 | return root 322 | } 323 | 324 | function byId(root, id, el) { 325 | // if doc, query on it, else query the parent doc or if a detached fragment rewrite the query and run on the fragment 326 | return root[nodeType] === 9 ? root.getElementById(id) : 327 | root.ownerDocument && 328 | (((el = root.ownerDocument.getElementById(id)) && isAncestor(el, root) && el) || 329 | (!isAncestor(root, root.ownerDocument) && select('[id="' + id + '"]', root)[0])) 330 | } 331 | 332 | function qwery(selector, _root) { 333 | var m, el, root = normalizeRoot(_root) 334 | 335 | // easy, fast cases that we can dispatch with simple DOM calls 336 | if (!root || !selector) return [] 337 | if (selector === window || isNode(selector)) { 338 | return !_root || (selector !== window && isNode(root) && isAncestor(selector, root)) ? [selector] : [] 339 | } 340 | if (selector && arrayLike(selector)) return flatten(selector) 341 | if (m = selector.match(easy)) { 342 | if (m[1]) return (el = byId(root, m[1])) ? [el] : [] 343 | if (m[2]) return arrayify(root[byTag](m[2])) 344 | if (hasByClass && m[3]) return arrayify(root[byClass](m[3])) 345 | } 346 | 347 | return select(selector, root) 348 | } 349 | 350 | // where the root is not document and a relationship selector is first we have to 351 | // do some awkward adjustments to get it to work, even with qSA 352 | function collectSelector(root, collector) { 353 | return function (s) { 354 | var oid, nid 355 | if (splittable.test(s)) { 356 | if (root[nodeType] !== 9) { 357 | // make sure the el has an id, rewrite the query, set root to doc and run it 358 | if (!(nid = oid = root.getAttribute('id'))) root.setAttribute('id', nid = '__qwerymeupscotty') 359 | s = '[id="' + nid + '"]' + s // avoid byId and allow us to match context element 360 | collector(root.parentNode || root, s, true) 361 | oid || root.removeAttribute('id') 362 | } 363 | return; 364 | } 365 | s.length && collector(root, s, false) 366 | } 367 | } 368 | 369 | var isAncestor = 'compareDocumentPosition' in html ? 370 | function (element, container) { 371 | return (container.compareDocumentPosition(element) & 16) == 16 372 | } : 'contains' in html ? 373 | function (element, container) { 374 | container = container[nodeType] === 9 || container == window ? html : container 375 | return container !== element && container.contains(element) 376 | } : 377 | function (element, container) { 378 | while (element = element.parentNode) if (element === container) return 1 379 | return 0 380 | } 381 | , getAttr = function () { 382 | // detect buggy IE src/href getAttribute() call 383 | var e = doc.createElement('p') 384 | return ((e.innerHTML = 'x') && e.firstChild.getAttribute('href') != '#x') ? 385 | function (e, a) { 386 | return a === 'class' ? e.className : (a === 'href' || a === 'src') ? 387 | e.getAttribute(a, 2) : e.getAttribute(a) 388 | } : 389 | function (e, a) { 390 | return e.getAttribute(a) 391 | } 392 | }() 393 | , hasByClass = !!doc[byClass] 394 | // has native qSA support 395 | , hasQSA = doc.querySelector && doc[qSA] 396 | // use native qSA 397 | , selectQSA = function (selector, root) { 398 | var result = [], ss, e 399 | try { 400 | if (root[nodeType] === 9 || !splittable.test(selector)) { 401 | // most work is done right here, defer to qSA 402 | return arrayify(root[qSA](selector)) 403 | } 404 | // special case where we need the services of `collectSelector()` 405 | each(ss = selector.split(','), collectSelector(root, function (ctx, s) { 406 | e = ctx[qSA](s) 407 | if (e.length == 1) result[result.length] = e.item(0) 408 | else if (e.length) result = result.concat(arrayify(e)) 409 | })) 410 | return ss.length > 1 && result.length > 1 ? uniq(result) : result 411 | } catch (ex) { 412 | } 413 | return selectNonNative(selector, root) 414 | } 415 | // no native selector support 416 | , selectNonNative = function (selector, root) { 417 | var result = [], items, m, i, l, r, ss 418 | selector = selector.replace(normalizr, '$1') 419 | if (m = selector.match(tagAndOrClass)) { 420 | r = classRegex(m[2]) 421 | items = root[byTag](m[1] || '*') 422 | for (i = 0, l = items.length; i < l; i++) { 423 | if (r.test(items[i].className)) result[result.length] = items[i] 424 | } 425 | return result 426 | } 427 | // more complex selector, get `_qwery()` to do the work for us 428 | each(ss = selector.split(','), collectSelector(root, function (ctx, s, rewrite) { 429 | r = _qwery(s, ctx) 430 | for (i = 0, l = r.length; i < l; i++) { 431 | if (ctx[nodeType] === 9 || rewrite || isAncestor(r[i], root)) result[result.length] = r[i] 432 | } 433 | })) 434 | return ss.length > 1 && result.length > 1 ? uniq(result) : result 435 | } 436 | , configure = function (options) { 437 | // configNativeQSA: use fully-internal selector or native qSA where present 438 | if (typeof options[useNativeQSA] !== 'undefined') 439 | select = !options[useNativeQSA] ? selectNonNative : hasQSA ? selectQSA : selectNonNative 440 | } 441 | 442 | configure({useNativeQSA: true}) 443 | 444 | qwery.configure = configure 445 | qwery.uniq = uniq 446 | qwery.is = is 447 | qwery.pseudos = {} 448 | 449 | return qwery 450 | })(); 451 | 452 | base.el = function (queryString) { 453 | return B(queryString); 454 | }; 455 | 456 | /** 457 | * Ajax 458 | */ 459 | var Ajax = { 460 | request: function (ops) { 461 | if (typeof ops == 'string') ops = {url: ops}; 462 | ops.url = ops.url || ''; 463 | ops.method = ops.method || 'get'; 464 | ops.data = ops.data || {}; 465 | var getParams = function (data, url) { 466 | var arr = [], str; 467 | for (var name in data) { 468 | arr.push(name + '=' + encodeURIComponent(data[name])); 469 | } 470 | str = arr.join('&'); 471 | if (str != '') { 472 | return url ? (url.indexOf('?') < 0 ? '?' + str : '&' + str) : str; 473 | } 474 | return ''; 475 | }; 476 | var api = { 477 | host: {}, 478 | process: function (ops) { 479 | var self = this; 480 | 481 | this.xhr = getXMLHttpRequest(); 482 | this.xhr.onreadystatechange = function () { 483 | if (self.xhr.readyState == 4 && self.xhr.status == 200) { 484 | var result = self.xhr.responseText; 485 | if (ops.json === true && typeof JSON != 'undefined') { 486 | result = JSON.parse(result); 487 | } 488 | self.doneCallback && self.doneCallback.apply(self.host, [result, self.xhr]); 489 | } else if (self.xhr.readyState == 4) { 490 | self.failCallback && self.failCallback.apply(self.host, [self.xhr]); 491 | } 492 | self.alwaysCallback && self.alwaysCallback.apply(self.host, [self.xhr]); 493 | } 494 | 495 | if (ops.method == 'get') { 496 | this.xhr.open('GET', ops.url + getParams(ops.data, ops.url), true); 497 | } else { 498 | this.xhr.open(ops.method, ops.url, true); 499 | this.setHeaders({ 500 | 'X-Requested-With': 'XMLHttpRequest', 501 | 'Content-type': 'application/x-www-form-urlencoded' 502 | }); 503 | } 504 | if (ops.headers && typeof ops.headers == 'object') { 505 | this.setHeaders(ops.headers); 506 | } 507 | 508 | setTimeout(function () { 509 | ops.method === 'get' ? self.xhr.send() : self.xhr.send(getParams(ops.data)); 510 | }, 20); 511 | return this; 512 | }, 513 | done: function (callback) { 514 | this.doneCallback = callback; 515 | return this; 516 | }, 517 | fail: function (callback) { 518 | this.failCallback = callback; 519 | return this; 520 | }, 521 | always: function (callback) { 522 | this.alwaysCallback = callback; 523 | return this; 524 | }, 525 | setHeaders: function (headers) { 526 | for (var name in headers) { 527 | this.xhr.setRequestHeader(name, headers[name]); 528 | } 529 | } 530 | }; 531 | return api.process(ops); 532 | } 533 | }; 534 | 535 | base.ajax = Ajax.request; 536 | 537 | /** 538 | * Functions 539 | */ 540 | B = function (selector) { 541 | var dom = Qwery(selector); 542 | dom.html = B.fn.html; 543 | dom.each = B.fn.each; 544 | dom.empty = B.fn.empty; 545 | dom.addClass = B.fn.addClass; 546 | dom.hasClass = B.fn.hasClass; 547 | dom.removeClass = B.fn.removeClass; 548 | dom.trim = B.fn.trim; 549 | dom.val = B.fn.val; 550 | dom.on = B.fn.on; 551 | dom.off = B.fn.off; 552 | dom.attr = B.fn.attr; 553 | dom.removeAttr = B.fn.removeAttr; 554 | dom.text = B.fn.text; 555 | return dom; 556 | }; 557 | 558 | // Define methods that will be available on all 559 | B.fn = { 560 | trim: function (text) { 561 | var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 562 | return text == null ? "" : ( text + "" ).replace(rtrim, ""); 563 | }, 564 | each: function (callback) { 565 | for (var i = 0; i < this.length; i++) { 566 | callback.call(this[i], i, this[i]) 567 | } 568 | return this 569 | }, 570 | empty: function () { 571 | return this.each(function () { 572 | this.innerHTML = '' 573 | }) 574 | }, 575 | html: function (html) { 576 | return 0 in arguments ? 577 | this.each(function (idx) { 578 | var originHtml = this.innerHTML; 579 | B(this).empty(); 580 | this.innerHTML = funcArg(this, html, idx, originHtml) 581 | }) : 582 | (0 in this ? this[0].innerHTML : null) 583 | }, 584 | val: function (value) { 585 | return 0 in arguments ? 586 | this.each(function (idx) { 587 | this.value = funcArg(this, value, idx, this.value) 588 | }) : 589 | (this[0] && (this[0].multiple ? 590 | B(this[0]).find('option').filter(function () { 591 | return this.selected 592 | }).pluck('value') : 593 | this[0].value) 594 | ) 595 | }, 596 | hasClass: function (selector) { 597 | 598 | var rclass = /[\t\r\n\f]/g; 599 | if (!selector) return false; 600 | 601 | var className = " " + selector + " ", 602 | i = 0, 603 | l = this.length; 604 | for (; i < l; i++) { 605 | if (this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf(className) >= 0) { 606 | return true; 607 | } 608 | } 609 | 610 | return false; 611 | }, 612 | addClass: function (name) { 613 | if (!name) return this; 614 | return this.each(function (idx) { 615 | if (!('className' in this)) return; 616 | classList = []; 617 | var cls = className(this), newName = funcArg(this, name, idx, cls); 618 | 619 | var names = newName.split(/\s+/g); 620 | for (var i = 0; i < names.length; i++) { 621 | if (!B.fn.hasClass(names[i])) classList.push(names[i]) 622 | } 623 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 624 | }) 625 | }, 626 | removeClass: function (name) { 627 | return this.each(function (idx) { 628 | if (!('className' in this)) return; 629 | if (name === undefined) return className(this, ''); 630 | classList = className(this); 631 | var names = funcArg(this, name, idx, classList).split(/\s+/g); 632 | for (var i = 0; i < names.length; i++) { 633 | classList = classList.replace(classRE(names[i]), " ") 634 | } 635 | className(this, B.fn.trim(classList)); 636 | }) 637 | }, 638 | attr: function (name, value) { 639 | var result; 640 | return (typeof name == 'string' && !(1 in arguments)) ? 641 | (!this.length || this[0].nodeType !== 1 ? undefined : 642 | (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result 643 | ) : 644 | this.each(function (idx) { 645 | if (this.nodeType !== 1) return 646 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 647 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 648 | }) 649 | }, 650 | removeAttr: function (name) { 651 | return this.each(function () { 652 | this.nodeType === 1 && name.split(' ').forEach(function (attribute) { 653 | setAttribute(this, attribute) 654 | }, this) 655 | }) 656 | }, 657 | on: function (event, fn) { 658 | return this.each(function (idx, el) { 659 | addEvent(el, event, fn); 660 | }, this) 661 | }, 662 | off: function (event, fn) { 663 | return this.each(function (idx, el) { 664 | removeEvent(el, event, fn); 665 | }, this) 666 | }, 667 | text: function (text) { 668 | return text !== undefined ? 669 | this.each(function () { 670 | var newText = text; 671 | this.textContent = this.innerText = newText; 672 | }) : 673 | (0 in this ? this[0].textContent || this[0].innerText : null) 674 | } 675 | }; 676 | 677 | // Establish the root object 678 | var root = this; 679 | root._ = base; 680 | 681 | }.call(this) 682 | ); 683 | -------------------------------------------------------------------------------- /vendor/zepto.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by Tomi on 6/2/2015. 3 | */ 4 | 5 | /* Zepto v1.1.6 - zepto event ajax form ie - zeptojs.com/license */ 6 | 7 | var Zepto = (function() { 8 | var undefined, key, $, classList, emptyArray = [], slice = emptyArray.slice, filter = emptyArray.filter, 9 | document = window.document, 10 | elementDisplay = {}, classCache = {}, 11 | cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,'opacity': 1, 'z-index': 1, 'zoom': 1 }, 12 | fragmentRE = /^\s*<(\w+|!)[^>]*>/, 13 | singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, 14 | tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig, 15 | rootNodeRE = /^(?:body|html)$/i, 16 | capitalRE = /([A-Z])/g, 17 | 18 | // special attributes that should be get/set via method calls 19 | methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'], 20 | 21 | adjacencyOperators = [ 'after', 'prepend', 'before', 'append' ], 22 | table = document.createElement('table'), 23 | tableRow = document.createElement('tr'), 24 | containers = { 25 | 'tr': document.createElement('tbody'), 26 | 'tbody': table, 'thead': table, 'tfoot': table, 27 | 'td': tableRow, 'th': tableRow, 28 | '*': document.createElement('div') 29 | }, 30 | readyRE = /complete|loaded|interactive/, 31 | simpleSelectorRE = /^[\w-]*$/, 32 | class2type = {}, 33 | toString = class2type.toString, 34 | zepto = {}, 35 | camelize, uniq, 36 | tempParent = document.createElement('div'), 37 | propMap = { 38 | 'tabindex': 'tabIndex', 39 | 'readonly': 'readOnly', 40 | 'for': 'htmlFor', 41 | 'class': 'className', 42 | 'maxlength': 'maxLength', 43 | 'cellspacing': 'cellSpacing', 44 | 'cellpadding': 'cellPadding', 45 | 'rowspan': 'rowSpan', 46 | 'colspan': 'colSpan', 47 | 'usemap': 'useMap', 48 | 'frameborder': 'frameBorder', 49 | 'contenteditable': 'contentEditable' 50 | }, 51 | isArray = Array.isArray || 52 | function(object){ return object instanceof Array } 53 | 54 | zepto.matches = function(element, selector) { 55 | if (!selector || !element || element.nodeType !== 1) return false 56 | var matchesSelector = element.webkitMatchesSelector || element.mozMatchesSelector || 57 | element.oMatchesSelector || element.matchesSelector 58 | if (matchesSelector) return matchesSelector.call(element, selector) 59 | // fall back to performing a selector: 60 | var match, parent = element.parentNode, temp = !parent 61 | if (temp) (parent = tempParent).appendChild(element) 62 | match = ~zepto.qsa(parent, selector).indexOf(element) 63 | temp && tempParent.removeChild(element) 64 | return match 65 | } 66 | 67 | function type(obj) { 68 | return obj == null ? String(obj) : 69 | class2type[toString.call(obj)] || "object" 70 | } 71 | 72 | function isFunction(value) { return type(value) == "function" } 73 | function isWindow(obj) { return obj != null && obj == obj.window } 74 | function isDocument(obj) { return obj != null && obj.nodeType == obj.DOCUMENT_NODE } 75 | function isObject(obj) { return type(obj) == "object" } 76 | function isPlainObject(obj) { 77 | return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype 78 | } 79 | function likeArray(obj) { return typeof obj.length == 'number' } 80 | 81 | function compact(array) { return filter.call(array, function(item){ return item != null }) } 82 | function flatten(array) { return array.length > 0 ? $.fn.concat.apply([], array) : array } 83 | camelize = function(str){ return str.replace(/-+(.)?/g, function(match, chr){ return chr ? chr.toUpperCase() : '' }) } 84 | function dasherize(str) { 85 | return str.replace(/::/g, '/') 86 | .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') 87 | .replace(/([a-z\d])([A-Z])/g, '$1_$2') 88 | .replace(/_/g, '-') 89 | .toLowerCase() 90 | } 91 | uniq = function(array){ return filter.call(array, function(item, idx){ return array.indexOf(item) == idx }) } 92 | 93 | function classRE(name) { 94 | return name in classCache ? 95 | classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name + '(\\s|$)')) 96 | } 97 | 98 | function maybeAddPx(name, value) { 99 | return (typeof value == "number" && !cssNumber[dasherize(name)]) ? value + "px" : value 100 | } 101 | 102 | function defaultDisplay(nodeName) { 103 | var element, display 104 | if (!elementDisplay[nodeName]) { 105 | element = document.createElement(nodeName) 106 | document.body.appendChild(element) 107 | display = getComputedStyle(element, '').getPropertyValue("display") 108 | element.parentNode.removeChild(element) 109 | display == "none" && (display = "block") 110 | elementDisplay[nodeName] = display 111 | } 112 | return elementDisplay[nodeName] 113 | } 114 | 115 | function children(element) { 116 | return 'children' in element ? 117 | slice.call(element.children) : 118 | $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node }) 119 | } 120 | 121 | // `$.zepto.fragment` takes a html string and an optional tag name 122 | // to generate DOM nodes nodes from the given html string. 123 | // The generated DOM nodes are returned as an array. 124 | // This function can be overriden in plugins for example to make 125 | // it compatible with browsers that don't support the DOM fully. 126 | zepto.fragment = function(html, name, properties) { 127 | var dom, nodes, container 128 | 129 | // A special case optimization for a single tag 130 | if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1)) 131 | 132 | if (!dom) { 133 | if (html.replace) html = html.replace(tagExpanderRE, "<$1>") 134 | if (name === undefined) name = fragmentRE.test(html) && RegExp.$1 135 | if (!(name in containers)) name = '*' 136 | 137 | container = containers[name] 138 | container.innerHTML = '' + html 139 | dom = $.each(slice.call(container.childNodes), function(){ 140 | container.removeChild(this) 141 | }) 142 | } 143 | 144 | if (isPlainObject(properties)) { 145 | nodes = $(dom) 146 | $.each(properties, function(key, value) { 147 | if (methodAttributes.indexOf(key) > -1) nodes[key](value) 148 | else nodes.attr(key, value) 149 | }) 150 | } 151 | 152 | return dom 153 | } 154 | 155 | // `$.zepto.Z` swaps out the prototype of the given `dom` array 156 | // of nodes with `$.fn` and thus supplying all the Zepto functions 157 | // to the array. Note that `__proto__` is not supported on Internet 158 | // Explorer. This method can be overriden in plugins. 159 | zepto.Z = function(dom, selector) { 160 | dom = dom || [] 161 | dom.__proto__ = $.fn 162 | dom.selector = selector || '' 163 | return dom 164 | } 165 | 166 | // `$.zepto.isZ` should return `true` if the given object is a Zepto 167 | // collection. This method can be overriden in plugins. 168 | zepto.isZ = function(object) { 169 | return object instanceof zepto.Z 170 | } 171 | 172 | // `$.zepto.init` is Zepto's counterpart to jQuery's `$.fn.init` and 173 | // takes a CSS selector and an optional context (and handles various 174 | // special cases). 175 | // This method can be overriden in plugins. 176 | zepto.init = function(selector, context) { 177 | var dom 178 | // If nothing given, return an empty Zepto collection 179 | if (!selector) return zepto.Z() 180 | // Optimize for string selectors 181 | else if (typeof selector == 'string') { 182 | selector = selector.trim() 183 | // If it's a html fragment, create nodes from it 184 | // Note: In both Chrome 21 and Firefox 15, DOM error 12 185 | // is thrown if the fragment doesn't begin with < 186 | if (selector[0] == '<' && fragmentRE.test(selector)) 187 | dom = zepto.fragment(selector, RegExp.$1, context), selector = null 188 | // If there's a context, create a collection on that context first, and select 189 | // nodes from there 190 | else if (context !== undefined) return $(context).find(selector) 191 | // If it's a CSS selector, use it to select nodes. 192 | else dom = zepto.qsa(document, selector) 193 | } 194 | // If a function is given, call it when the DOM is ready 195 | else if (isFunction(selector)) return $(document).ready(selector) 196 | // If a Zepto collection is given, just return it 197 | else if (zepto.isZ(selector)) return selector 198 | else { 199 | // normalize array if an array of nodes is given 200 | if (isArray(selector)) dom = compact(selector) 201 | // Wrap DOM nodes. 202 | else if (isObject(selector)) 203 | dom = [selector], selector = null 204 | // If it's a html fragment, create nodes from it 205 | else if (fragmentRE.test(selector)) 206 | dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null 207 | // If there's a context, create a collection on that context first, and select 208 | // nodes from there 209 | else if (context !== undefined) return $(context).find(selector) 210 | // And last but no least, if it's a CSS selector, use it to select nodes. 211 | else dom = zepto.qsa(document, selector) 212 | } 213 | // create a new Zepto collection from the nodes found 214 | return zepto.Z(dom, selector) 215 | } 216 | 217 | // `$` will be the base `Zepto` object. When calling this 218 | // function just call `$.zepto.init, which makes the implementation 219 | // details of selecting nodes and creating Zepto collections 220 | // patchable in plugins. 221 | $ = function(selector, context){ 222 | return zepto.init(selector, context) 223 | } 224 | 225 | function extend(target, source, deep) { 226 | for (key in source) 227 | if (deep && (isPlainObject(source[key]) || isArray(source[key]))) { 228 | if (isPlainObject(source[key]) && !isPlainObject(target[key])) 229 | target[key] = {} 230 | if (isArray(source[key]) && !isArray(target[key])) 231 | target[key] = [] 232 | extend(target[key], source[key], deep) 233 | } 234 | else if (source[key] !== undefined) target[key] = source[key] 235 | } 236 | 237 | // Copy all but undefined properties from one or more 238 | // objects to the `target` object. 239 | $.extend = function(target){ 240 | var deep, args = slice.call(arguments, 1) 241 | if (typeof target == 'boolean') { 242 | deep = target 243 | target = args.shift() 244 | } 245 | args.forEach(function(arg){ extend(target, arg, deep) }) 246 | return target 247 | } 248 | 249 | // `$.zepto.qsa` is Zepto's CSS selector implementation which 250 | // uses `document.querySelectorAll` and optimizes for some special cases, like `#id`. 251 | // This method can be overriden in plugins. 252 | zepto.qsa = function(element, selector){ 253 | var found, 254 | maybeID = selector[0] == '#', 255 | maybeClass = !maybeID && selector[0] == '.', 256 | nameOnly = maybeID || maybeClass ? selector.slice(1) : selector, // Ensure that a 1 char tag name still gets checked 257 | isSimple = simpleSelectorRE.test(nameOnly) 258 | return (isDocument(element) && isSimple && maybeID) ? 259 | ( (found = element.getElementById(nameOnly)) ? [found] : [] ) : 260 | (element.nodeType !== 1 && element.nodeType !== 9) ? [] : 261 | slice.call( 262 | isSimple && !maybeID ? 263 | maybeClass ? element.getElementsByClassName(nameOnly) : // If it's simple, it could be a class 264 | element.getElementsByTagName(selector) : // Or a tag 265 | element.querySelectorAll(selector) // Or it's not simple, and we need to query all 266 | ) 267 | } 268 | 269 | function filtered(nodes, selector) { 270 | return selector == null ? $(nodes) : $(nodes).filter(selector) 271 | } 272 | 273 | $.contains = document.documentElement.contains ? 274 | function(parent, node) { 275 | return parent !== node && parent.contains(node) 276 | } : 277 | function(parent, node) { 278 | while (node && (node = node.parentNode)) 279 | if (node === parent) return true 280 | return false 281 | } 282 | 283 | function funcArg(context, arg, idx, payload) { 284 | return isFunction(arg) ? arg.call(context, idx, payload) : arg 285 | } 286 | 287 | function setAttribute(node, name, value) { 288 | value == null ? node.removeAttribute(name) : node.setAttribute(name, value) 289 | } 290 | 291 | // access className property while respecting SVGAnimatedString 292 | function className(node, value){ 293 | var klass = node.className || '', 294 | svg = klass && klass.baseVal !== undefined 295 | 296 | if (value === undefined) return svg ? klass.baseVal : klass 297 | svg ? (klass.baseVal = value) : (node.className = value) 298 | } 299 | 300 | // "true" => true 301 | // "false" => false 302 | // "null" => null 303 | // "42" => 42 304 | // "42.5" => 42.5 305 | // "08" => "08" 306 | // JSON => parse if valid 307 | // String => self 308 | function deserializeValue(value) { 309 | try { 310 | return value ? 311 | value == "true" || 312 | ( value == "false" ? false : 313 | value == "null" ? null : 314 | +value + "" == value ? +value : 315 | /^[\[\{]/.test(value) ? $.parseJSON(value) : 316 | value ) 317 | : value 318 | } catch(e) { 319 | return value 320 | } 321 | } 322 | 323 | $.type = type 324 | $.isFunction = isFunction 325 | $.isWindow = isWindow 326 | $.isArray = isArray 327 | $.isPlainObject = isPlainObject 328 | 329 | $.isEmptyObject = function(obj) { 330 | var name 331 | for (name in obj) return false 332 | return true 333 | } 334 | 335 | $.inArray = function(elem, array, i){ 336 | return emptyArray.indexOf.call(array, elem, i) 337 | } 338 | 339 | $.camelCase = camelize 340 | $.trim = function(str) { 341 | return str == null ? "" : String.prototype.trim.call(str) 342 | } 343 | 344 | // plugin compatibility 345 | $.uuid = 0 346 | $.support = { } 347 | $.expr = { } 348 | 349 | $.map = function(elements, callback){ 350 | var value, values = [], i, key 351 | if (likeArray(elements)) 352 | for (i = 0; i < elements.length; i++) { 353 | value = callback(elements[i], i) 354 | if (value != null) values.push(value) 355 | } 356 | else 357 | for (key in elements) { 358 | value = callback(elements[key], key) 359 | if (value != null) values.push(value) 360 | } 361 | return flatten(values) 362 | } 363 | 364 | $.each = function(elements, callback){ 365 | var i, key 366 | if (likeArray(elements)) { 367 | for (i = 0; i < elements.length; i++) 368 | if (callback.call(elements[i], i, elements[i]) === false) return elements 369 | } else { 370 | for (key in elements) 371 | if (callback.call(elements[key], key, elements[key]) === false) return elements 372 | } 373 | 374 | return elements 375 | } 376 | 377 | $.grep = function(elements, callback){ 378 | return filter.call(elements, callback) 379 | } 380 | 381 | if (window.JSON) $.parseJSON = JSON.parse 382 | 383 | // Populate the class2type map 384 | $.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { 385 | class2type[ "[object " + name + "]" ] = name.toLowerCase() 386 | }) 387 | 388 | // Define methods that will be available on all 389 | // Zepto collections 390 | $.fn = { 391 | // Because a collection acts like an array 392 | // copy over these useful array functions. 393 | forEach: emptyArray.forEach, 394 | reduce: emptyArray.reduce, 395 | push: emptyArray.push, 396 | sort: emptyArray.sort, 397 | indexOf: emptyArray.indexOf, 398 | concat: emptyArray.concat, 399 | 400 | // `map` and `slice` in the jQuery API work differently 401 | // from their array counterparts 402 | map: function(fn){ 403 | return $($.map(this, function(el, i){ return fn.call(el, i, el) })) 404 | }, 405 | slice: function(){ 406 | return $(slice.apply(this, arguments)) 407 | }, 408 | 409 | ready: function(callback){ 410 | // need to check if document.body exists for IE as that browser reports 411 | // document ready when it hasn't yet created the body element 412 | if (readyRE.test(document.readyState) && document.body) callback($) 413 | else document.addEventListener('DOMContentLoaded', function(){ callback($) }, false) 414 | return this 415 | }, 416 | get: function(idx){ 417 | return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length] 418 | }, 419 | toArray: function(){ return this.get() }, 420 | size: function(){ 421 | return this.length 422 | }, 423 | remove: function(){ 424 | return this.each(function(){ 425 | if (this.parentNode != null) 426 | this.parentNode.removeChild(this) 427 | }) 428 | }, 429 | each: function(callback){ 430 | emptyArray.every.call(this, function(el, idx){ 431 | return callback.call(el, idx, el) !== false 432 | }) 433 | return this 434 | }, 435 | filter: function(selector){ 436 | if (isFunction(selector)) return this.not(this.not(selector)) 437 | return $(filter.call(this, function(element){ 438 | return zepto.matches(element, selector) 439 | })) 440 | }, 441 | add: function(selector,context){ 442 | return $(uniq(this.concat($(selector,context)))) 443 | }, 444 | is: function(selector){ 445 | return this.length > 0 && zepto.matches(this[0], selector) 446 | }, 447 | not: function(selector){ 448 | var nodes=[] 449 | if (isFunction(selector) && selector.call !== undefined) 450 | this.each(function(idx){ 451 | if (!selector.call(this,idx)) nodes.push(this) 452 | }) 453 | else { 454 | var excludes = typeof selector == 'string' ? this.filter(selector) : 455 | (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector) 456 | this.forEach(function(el){ 457 | if (excludes.indexOf(el) < 0) nodes.push(el) 458 | }) 459 | } 460 | return $(nodes) 461 | }, 462 | has: function(selector){ 463 | return this.filter(function(){ 464 | return isObject(selector) ? 465 | $.contains(this, selector) : 466 | $(this).find(selector).size() 467 | }) 468 | }, 469 | eq: function(idx){ 470 | return idx === -1 ? this.slice(idx) : this.slice(idx, + idx + 1) 471 | }, 472 | first: function(){ 473 | var el = this[0] 474 | return el && !isObject(el) ? el : $(el) 475 | }, 476 | last: function(){ 477 | var el = this[this.length - 1] 478 | return el && !isObject(el) ? el : $(el) 479 | }, 480 | find: function(selector){ 481 | var result, $this = this 482 | if (!selector) result = $() 483 | else if (typeof selector == 'object') 484 | result = $(selector).filter(function(){ 485 | var node = this 486 | return emptyArray.some.call($this, function(parent){ 487 | return $.contains(parent, node) 488 | }) 489 | }) 490 | else if (this.length == 1) result = $(zepto.qsa(this[0], selector)) 491 | else result = this.map(function(){ return zepto.qsa(this, selector) }) 492 | return result 493 | }, 494 | closest: function(selector, context){ 495 | var node = this[0], collection = false 496 | if (typeof selector == 'object') collection = $(selector) 497 | while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))) 498 | node = node !== context && !isDocument(node) && node.parentNode 499 | return $(node) 500 | }, 501 | parents: function(selector){ 502 | var ancestors = [], nodes = this 503 | while (nodes.length > 0) 504 | nodes = $.map(nodes, function(node){ 505 | if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) { 506 | ancestors.push(node) 507 | return node 508 | } 509 | }) 510 | return filtered(ancestors, selector) 511 | }, 512 | parent: function(selector){ 513 | return filtered(uniq(this.pluck('parentNode')), selector) 514 | }, 515 | children: function(selector){ 516 | return filtered(this.map(function(){ return children(this) }), selector) 517 | }, 518 | contents: function() { 519 | return this.map(function() { return slice.call(this.childNodes) }) 520 | }, 521 | siblings: function(selector){ 522 | return filtered(this.map(function(i, el){ 523 | return filter.call(children(el.parentNode), function(child){ return child!==el }) 524 | }), selector) 525 | }, 526 | empty: function(){ 527 | return this.each(function(){ this.innerHTML = '' }) 528 | }, 529 | // `pluck` is borrowed from Prototype.js 530 | pluck: function(property){ 531 | return $.map(this, function(el){ return el[property] }) 532 | }, 533 | show: function(){ 534 | return this.each(function(){ 535 | this.style.display == "none" && (this.style.display = '') 536 | if (getComputedStyle(this, '').getPropertyValue("display") == "none") 537 | this.style.display = defaultDisplay(this.nodeName) 538 | }) 539 | }, 540 | replaceWith: function(newContent){ 541 | return this.before(newContent).remove() 542 | }, 543 | wrap: function(structure){ 544 | var func = isFunction(structure) 545 | if (this[0] && !func) 546 | var dom = $(structure).get(0), 547 | clone = dom.parentNode || this.length > 1 548 | 549 | return this.each(function(index){ 550 | $(this).wrapAll( 551 | func ? structure.call(this, index) : 552 | clone ? dom.cloneNode(true) : dom 553 | ) 554 | }) 555 | }, 556 | wrapAll: function(structure){ 557 | if (this[0]) { 558 | $(this[0]).before(structure = $(structure)) 559 | var children 560 | // drill down to the inmost element 561 | while ((children = structure.children()).length) structure = children.first() 562 | $(structure).append(this) 563 | } 564 | return this 565 | }, 566 | wrapInner: function(structure){ 567 | var func = isFunction(structure) 568 | return this.each(function(index){ 569 | var self = $(this), contents = self.contents(), 570 | dom = func ? structure.call(this, index) : structure 571 | contents.length ? contents.wrapAll(dom) : self.append(dom) 572 | }) 573 | }, 574 | unwrap: function(){ 575 | this.parent().each(function(){ 576 | $(this).replaceWith($(this).children()) 577 | }) 578 | return this 579 | }, 580 | clone: function(){ 581 | return this.map(function(){ return this.cloneNode(true) }) 582 | }, 583 | hide: function(){ 584 | return this.css("display", "none") 585 | }, 586 | toggle: function(setting){ 587 | return this.each(function(){ 588 | var el = $(this) 589 | ;(setting === undefined ? el.css("display") == "none" : setting) ? el.show() : el.hide() 590 | }) 591 | }, 592 | prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') }, 593 | next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') }, 594 | html: function(html){ 595 | return 0 in arguments ? 596 | this.each(function(idx){ 597 | var originHtml = this.innerHTML 598 | $(this).empty().append( funcArg(this, html, idx, originHtml) ) 599 | }) : 600 | (0 in this ? this[0].innerHTML : null) 601 | }, 602 | text: function(text){ 603 | return 0 in arguments ? 604 | this.each(function(idx){ 605 | var newText = funcArg(this, text, idx, this.textContent) 606 | this.textContent = newText == null ? '' : ''+newText 607 | }) : 608 | (0 in this ? this[0].textContent : null) 609 | }, 610 | attr: function(name, value){ 611 | var result 612 | return (typeof name == 'string' && !(1 in arguments)) ? 613 | (!this.length || this[0].nodeType !== 1 ? undefined : 614 | (!(result = this[0].getAttribute(name)) && name in this[0]) ? this[0][name] : result 615 | ) : 616 | this.each(function(idx){ 617 | if (this.nodeType !== 1) return 618 | if (isObject(name)) for (key in name) setAttribute(this, key, name[key]) 619 | else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name))) 620 | }) 621 | }, 622 | removeAttr: function(name){ 623 | return this.each(function(){ this.nodeType === 1 && name.split(' ').forEach(function(attribute){ 624 | setAttribute(this, attribute) 625 | }, this)}) 626 | }, 627 | prop: function(name, value){ 628 | name = propMap[name] || name 629 | return (1 in arguments) ? 630 | this.each(function(idx){ 631 | this[name] = funcArg(this, value, idx, this[name]) 632 | }) : 633 | (this[0] && this[0][name]) 634 | }, 635 | data: function(name, value){ 636 | var attrName = 'data-' + name.replace(capitalRE, '-$1').toLowerCase() 637 | 638 | var data = (1 in arguments) ? 639 | this.attr(attrName, value) : 640 | this.attr(attrName) 641 | 642 | return data !== null ? deserializeValue(data) : undefined 643 | }, 644 | val: function(value){ 645 | return 0 in arguments ? 646 | this.each(function(idx){ 647 | this.value = funcArg(this, value, idx, this.value) 648 | }) : 649 | (this[0] && (this[0].multiple ? 650 | $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') : 651 | this[0].value) 652 | ) 653 | }, 654 | offset: function(coordinates){ 655 | if (coordinates) return this.each(function(index){ 656 | var $this = $(this), 657 | coords = funcArg(this, coordinates, index, $this.offset()), 658 | parentOffset = $this.offsetParent().offset(), 659 | props = { 660 | top: coords.top - parentOffset.top, 661 | left: coords.left - parentOffset.left 662 | } 663 | 664 | if ($this.css('position') == 'static') props['position'] = 'relative' 665 | $this.css(props) 666 | }) 667 | if (!this.length) return null 668 | var obj = this[0].getBoundingClientRect() 669 | return { 670 | left: obj.left + window.pageXOffset, 671 | top: obj.top + window.pageYOffset, 672 | width: Math.round(obj.width), 673 | height: Math.round(obj.height) 674 | } 675 | }, 676 | css: function(property, value){ 677 | if (arguments.length < 2) { 678 | var computedStyle, element = this[0] 679 | if(!element) return 680 | computedStyle = getComputedStyle(element, '') 681 | if (typeof property == 'string') 682 | return element.style[camelize(property)] || computedStyle.getPropertyValue(property) 683 | else if (isArray(property)) { 684 | var props = {} 685 | $.each(property, function(_, prop){ 686 | props[prop] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop)) 687 | }) 688 | return props 689 | } 690 | } 691 | 692 | var css = '' 693 | if (type(property) == 'string') { 694 | if (!value && value !== 0) 695 | this.each(function(){ this.style.removeProperty(dasherize(property)) }) 696 | else 697 | css = dasherize(property) + ":" + maybeAddPx(property, value) 698 | } else { 699 | for (key in property) 700 | if (!property[key] && property[key] !== 0) 701 | this.each(function(){ this.style.removeProperty(dasherize(key)) }) 702 | else 703 | css += dasherize(key) + ':' + maybeAddPx(key, property[key]) + ';' 704 | } 705 | 706 | return this.each(function(){ this.style.cssText += ';' + css }) 707 | }, 708 | index: function(element){ 709 | return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0]) 710 | }, 711 | hasClass: function(name){ 712 | if (!name) return false 713 | return emptyArray.some.call(this, function(el){ 714 | return this.test(className(el)) 715 | }, classRE(name)) 716 | }, 717 | addClass: function(name){ 718 | if (!name) return this 719 | return this.each(function(idx){ 720 | if (!('className' in this)) return 721 | classList = [] 722 | var cls = className(this), newName = funcArg(this, name, idx, cls) 723 | newName.split(/\s+/g).forEach(function(klass){ 724 | if (!$(this).hasClass(klass)) classList.push(klass) 725 | }, this) 726 | classList.length && className(this, cls + (cls ? " " : "") + classList.join(" ")) 727 | }) 728 | }, 729 | removeClass: function(name){ 730 | return this.each(function(idx){ 731 | if (!('className' in this)) return 732 | if (name === undefined) return className(this, '') 733 | classList = className(this) 734 | funcArg(this, name, idx, classList).split(/\s+/g).forEach(function(klass){ 735 | classList = classList.replace(classRE(klass), " ") 736 | }) 737 | className(this, classList.trim()) 738 | }) 739 | }, 740 | toggleClass: function(name, when){ 741 | if (!name) return this 742 | return this.each(function(idx){ 743 | var $this = $(this), names = funcArg(this, name, idx, className(this)) 744 | names.split(/\s+/g).forEach(function(klass){ 745 | (when === undefined ? !$this.hasClass(klass) : when) ? 746 | $this.addClass(klass) : $this.removeClass(klass) 747 | }) 748 | }) 749 | }, 750 | scrollTop: function(value){ 751 | if (!this.length) return 752 | var hasScrollTop = 'scrollTop' in this[0] 753 | if (value === undefined) return hasScrollTop ? this[0].scrollTop : this[0].pageYOffset 754 | return this.each(hasScrollTop ? 755 | function(){ this.scrollTop = value } : 756 | function(){ this.scrollTo(this.scrollX, value) }) 757 | }, 758 | scrollLeft: function(value){ 759 | if (!this.length) return 760 | var hasScrollLeft = 'scrollLeft' in this[0] 761 | if (value === undefined) return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset 762 | return this.each(hasScrollLeft ? 763 | function(){ this.scrollLeft = value } : 764 | function(){ this.scrollTo(value, this.scrollY) }) 765 | }, 766 | position: function() { 767 | if (!this.length) return 768 | 769 | var elem = this[0], 770 | // Get *real* offsetParent 771 | offsetParent = this.offsetParent(), 772 | // Get correct offsets 773 | offset = this.offset(), 774 | parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset() 775 | 776 | // Subtract element margins 777 | // note: when an element has margin: auto the offsetLeft and marginLeft 778 | // are the same in Safari causing offset.left to incorrectly be 0 779 | offset.top -= parseFloat( $(elem).css('margin-top') ) || 0 780 | offset.left -= parseFloat( $(elem).css('margin-left') ) || 0 781 | 782 | // Add offsetParent borders 783 | parentOffset.top += parseFloat( $(offsetParent[0]).css('border-top-width') ) || 0 784 | parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0 785 | 786 | // Subtract the two offsets 787 | return { 788 | top: offset.top - parentOffset.top, 789 | left: offset.left - parentOffset.left 790 | } 791 | }, 792 | offsetParent: function() { 793 | return this.map(function(){ 794 | var parent = this.offsetParent || document.body 795 | while (parent && !rootNodeRE.test(parent.nodeName) && $(parent).css("position") == "static") 796 | parent = parent.offsetParent 797 | return parent 798 | }) 799 | } 800 | } 801 | 802 | // for now 803 | $.fn.detach = $.fn.remove 804 | 805 | // Generate the `width` and `height` functions 806 | ;['width', 'height'].forEach(function(dimension){ 807 | var dimensionProperty = 808 | dimension.replace(/./, function(m){ return m[0].toUpperCase() }) 809 | 810 | $.fn[dimension] = function(value){ 811 | var offset, el = this[0] 812 | if (value === undefined) return isWindow(el) ? el['inner' + dimensionProperty] : 813 | isDocument(el) ? el.documentElement['scroll' + dimensionProperty] : 814 | (offset = this.offset()) && offset[dimension] 815 | else return this.each(function(idx){ 816 | el = $(this) 817 | el.css(dimension, funcArg(this, value, idx, el[dimension]())) 818 | }) 819 | } 820 | }) 821 | 822 | function traverseNode(node, fun) { 823 | fun(node) 824 | for (var i = 0, len = node.childNodes.length; i < len; i++) 825 | traverseNode(node.childNodes[i], fun) 826 | } 827 | 828 | // Generate the `after`, `prepend`, `before`, `append`, 829 | // `insertAfter`, `insertBefore`, `appendTo`, and `prependTo` methods. 830 | adjacencyOperators.forEach(function(operator, operatorIndex) { 831 | var inside = operatorIndex % 2 //=> prepend, append 832 | 833 | $.fn[operator] = function(){ 834 | // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings 835 | var argType, nodes = $.map(arguments, function(arg) { 836 | argType = type(arg) 837 | return argType == "object" || argType == "array" || arg == null ? 838 | arg : zepto.fragment(arg) 839 | }), 840 | parent, copyByClone = this.length > 1 841 | if (nodes.length < 1) return this 842 | 843 | return this.each(function(_, target){ 844 | parent = inside ? target : target.parentNode 845 | 846 | // convert all methods to a "before" operation 847 | target = operatorIndex == 0 ? target.nextSibling : 848 | operatorIndex == 1 ? target.firstChild : 849 | operatorIndex == 2 ? target : 850 | null 851 | 852 | var parentInDocument = $.contains(document.documentElement, parent) 853 | 854 | nodes.forEach(function(node){ 855 | if (copyByClone) node = node.cloneNode(true) 856 | else if (!parent) return $(node).remove() 857 | 858 | parent.insertBefore(node, target) 859 | if (parentInDocument) traverseNode(node, function(el){ 860 | if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' && 861 | (!el.type || el.type === 'text/javascript') && !el.src) 862 | window['eval'].call(window, el.innerHTML) 863 | }) 864 | }) 865 | }) 866 | } 867 | 868 | // after => insertAfter 869 | // prepend => prependTo 870 | // before => insertBefore 871 | // append => appendTo 872 | $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){ 873 | $(html)[operator](this) 874 | return this 875 | } 876 | }) 877 | 878 | zepto.Z.prototype = $.fn 879 | 880 | // Export internal API functions in the `$.zepto` namespace 881 | zepto.uniq = uniq 882 | zepto.deserializeValue = deserializeValue 883 | $.zepto = zepto 884 | 885 | return $ 886 | })() 887 | 888 | window.Zepto = Zepto 889 | window.$ === undefined && (window.$ = Zepto) 890 | 891 | ;(function($){ 892 | var _zid = 1, undefined, 893 | slice = Array.prototype.slice, 894 | isFunction = $.isFunction, 895 | isString = function(obj){ return typeof obj == 'string' }, 896 | handlers = {}, 897 | specialEvents={}, 898 | focusinSupported = 'onfocusin' in window, 899 | focus = { focus: 'focusin', blur: 'focusout' }, 900 | hover = { mouseenter: 'mouseover', mouseleave: 'mouseout' } 901 | 902 | specialEvents.click = specialEvents.mousedown = specialEvents.mouseup = specialEvents.mousemove = 'MouseEvents' 903 | 904 | function zid(element) { 905 | return element._zid || (element._zid = _zid++) 906 | } 907 | function findHandlers(element, event, fn, selector) { 908 | event = parse(event) 909 | if (event.ns) var matcher = matcherFor(event.ns) 910 | return (handlers[zid(element)] || []).filter(function(handler) { 911 | return handler 912 | && (!event.e || handler.e == event.e) 913 | && (!event.ns || matcher.test(handler.ns)) 914 | && (!fn || zid(handler.fn) === zid(fn)) 915 | && (!selector || handler.sel == selector) 916 | }) 917 | } 918 | function parse(event) { 919 | var parts = ('' + event).split('.') 920 | return {e: parts[0], ns: parts.slice(1).sort().join(' ')} 921 | } 922 | function matcherFor(ns) { 923 | return new RegExp('(?:^| )' + ns.replace(' ', ' .* ?') + '(?: |$)') 924 | } 925 | 926 | function eventCapture(handler, captureSetting) { 927 | return handler.del && 928 | (!focusinSupported && (handler.e in focus)) || 929 | !!captureSetting 930 | } 931 | 932 | function realEvent(type) { 933 | return hover[type] || (focusinSupported && focus[type]) || type 934 | } 935 | 936 | function add(element, events, fn, data, selector, delegator, capture){ 937 | var id = zid(element), set = (handlers[id] || (handlers[id] = [])) 938 | events.split(/\s/).forEach(function(event){ 939 | if (event == 'ready') return $(document).ready(fn) 940 | var handler = parse(event) 941 | handler.fn = fn 942 | handler.sel = selector 943 | // emulate mouseenter, mouseleave 944 | if (handler.e in hover) fn = function(e){ 945 | var related = e.relatedTarget 946 | if (!related || (related !== this && !$.contains(this, related))) 947 | return handler.fn.apply(this, arguments) 948 | } 949 | handler.del = delegator 950 | var callback = delegator || fn 951 | handler.proxy = function(e){ 952 | e = compatible(e) 953 | if (e.isImmediatePropagationStopped()) return 954 | e.data = data 955 | var result = callback.apply(element, e._args == undefined ? [e] : [e].concat(e._args)) 956 | if (result === false) e.preventDefault(), e.stopPropagation() 957 | return result 958 | } 959 | handler.i = set.length 960 | set.push(handler) 961 | if ('addEventListener' in element) 962 | element.addEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 963 | }) 964 | } 965 | function remove(element, events, fn, selector, capture){ 966 | var id = zid(element) 967 | ;(events || '').split(/\s/).forEach(function(event){ 968 | findHandlers(element, event, fn, selector).forEach(function(handler){ 969 | delete handlers[id][handler.i] 970 | if ('removeEventListener' in element) 971 | element.removeEventListener(realEvent(handler.e), handler.proxy, eventCapture(handler, capture)) 972 | }) 973 | }) 974 | } 975 | 976 | $.event = { add: add, remove: remove } 977 | 978 | $.proxy = function(fn, context) { 979 | var args = (2 in arguments) && slice.call(arguments, 2) 980 | if (isFunction(fn)) { 981 | var proxyFn = function(){ return fn.apply(context, args ? args.concat(slice.call(arguments)) : arguments) } 982 | proxyFn._zid = zid(fn) 983 | return proxyFn 984 | } else if (isString(context)) { 985 | if (args) { 986 | args.unshift(fn[context], fn) 987 | return $.proxy.apply(null, args) 988 | } else { 989 | return $.proxy(fn[context], fn) 990 | } 991 | } else { 992 | throw new TypeError("expected function") 993 | } 994 | } 995 | 996 | $.fn.bind = function(event, data, callback){ 997 | return this.on(event, data, callback) 998 | } 999 | $.fn.unbind = function(event, callback){ 1000 | return this.off(event, callback) 1001 | } 1002 | $.fn.one = function(event, selector, data, callback){ 1003 | return this.on(event, selector, data, callback, 1) 1004 | } 1005 | 1006 | var returnTrue = function(){return true}, 1007 | returnFalse = function(){return false}, 1008 | ignoreProperties = /^([A-Z]|returnValue$|layer[XY]$)/, 1009 | eventMethods = { 1010 | preventDefault: 'isDefaultPrevented', 1011 | stopImmediatePropagation: 'isImmediatePropagationStopped', 1012 | stopPropagation: 'isPropagationStopped' 1013 | } 1014 | 1015 | function compatible(event, source) { 1016 | if (source || !event.isDefaultPrevented) { 1017 | source || (source = event) 1018 | 1019 | $.each(eventMethods, function(name, predicate) { 1020 | var sourceMethod = source[name] 1021 | event[name] = function(){ 1022 | this[predicate] = returnTrue 1023 | return sourceMethod && sourceMethod.apply(source, arguments) 1024 | } 1025 | event[predicate] = returnFalse 1026 | }) 1027 | 1028 | if (source.defaultPrevented !== undefined ? source.defaultPrevented : 1029 | 'returnValue' in source ? source.returnValue === false : 1030 | source.getPreventDefault && source.getPreventDefault()) 1031 | event.isDefaultPrevented = returnTrue 1032 | } 1033 | return event 1034 | } 1035 | 1036 | function createProxy(event) { 1037 | var key, proxy = { originalEvent: event } 1038 | for (key in event) 1039 | if (!ignoreProperties.test(key) && event[key] !== undefined) proxy[key] = event[key] 1040 | 1041 | return compatible(proxy, event) 1042 | } 1043 | 1044 | $.fn.delegate = function(selector, event, callback){ 1045 | return this.on(event, selector, callback) 1046 | } 1047 | $.fn.undelegate = function(selector, event, callback){ 1048 | return this.off(event, selector, callback) 1049 | } 1050 | 1051 | $.fn.live = function(event, callback){ 1052 | $(document.body).delegate(this.selector, event, callback) 1053 | return this 1054 | } 1055 | $.fn.die = function(event, callback){ 1056 | $(document.body).undelegate(this.selector, event, callback) 1057 | return this 1058 | } 1059 | 1060 | $.fn.on = function(event, selector, data, callback, one){ 1061 | var autoRemove, delegator, $this = this 1062 | if (event && !isString(event)) { 1063 | $.each(event, function(type, fn){ 1064 | $this.on(type, selector, data, fn, one) 1065 | }) 1066 | return $this 1067 | } 1068 | 1069 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1070 | callback = data, data = selector, selector = undefined 1071 | if (isFunction(data) || data === false) 1072 | callback = data, data = undefined 1073 | 1074 | if (callback === false) callback = returnFalse 1075 | 1076 | return $this.each(function(_, element){ 1077 | if (one) autoRemove = function(e){ 1078 | remove(element, e.type, callback) 1079 | return callback.apply(this, arguments) 1080 | } 1081 | 1082 | if (selector) delegator = function(e){ 1083 | var evt, match = $(e.target).closest(selector, element).get(0) 1084 | if (match && match !== element) { 1085 | evt = $.extend(createProxy(e), {currentTarget: match, liveFired: element}) 1086 | return (autoRemove || callback).apply(match, [evt].concat(slice.call(arguments, 1))) 1087 | } 1088 | } 1089 | 1090 | add(element, event, callback, data, selector, delegator || autoRemove) 1091 | }) 1092 | } 1093 | $.fn.off = function(event, selector, callback){ 1094 | var $this = this 1095 | if (event && !isString(event)) { 1096 | $.each(event, function(type, fn){ 1097 | $this.off(type, selector, fn) 1098 | }) 1099 | return $this 1100 | } 1101 | 1102 | if (!isString(selector) && !isFunction(callback) && callback !== false) 1103 | callback = selector, selector = undefined 1104 | 1105 | if (callback === false) callback = returnFalse 1106 | 1107 | return $this.each(function(){ 1108 | remove(this, event, callback, selector) 1109 | }) 1110 | } 1111 | 1112 | $.fn.trigger = function(event, args){ 1113 | event = (isString(event) || $.isPlainObject(event)) ? $.Event(event) : compatible(event) 1114 | event._args = args 1115 | return this.each(function(){ 1116 | // handle focus(), blur() by calling them directly 1117 | if (event.type in focus && typeof this[event.type] == "function") this[event.type]() 1118 | // items in the collection might not be DOM elements 1119 | else if ('dispatchEvent' in this) this.dispatchEvent(event) 1120 | else $(this).triggerHandler(event, args) 1121 | }) 1122 | } 1123 | 1124 | // triggers event handlers on current element just as if an event occurred, 1125 | // doesn't trigger an actual event, doesn't bubble 1126 | $.fn.triggerHandler = function(event, args){ 1127 | var e, result 1128 | this.each(function(i, element){ 1129 | e = createProxy(isString(event) ? $.Event(event) : event) 1130 | e._args = args 1131 | e.target = element 1132 | $.each(findHandlers(element, event.type || event), function(i, handler){ 1133 | result = handler.proxy(e) 1134 | if (e.isImmediatePropagationStopped()) return false 1135 | }) 1136 | }) 1137 | return result 1138 | } 1139 | 1140 | // shortcut methods for `.bind(event, fn)` for each event type 1141 | ;('focusin focusout focus blur load resize scroll unload click dblclick '+ 1142 | 'mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave '+ 1143 | 'change select keydown keypress keyup error').split(' ').forEach(function(event) { 1144 | $.fn[event] = function(callback) { 1145 | return (0 in arguments) ? 1146 | this.bind(event, callback) : 1147 | this.trigger(event) 1148 | } 1149 | }) 1150 | 1151 | $.Event = function(type, props) { 1152 | if (!isString(type)) props = type, type = props.type 1153 | var event = document.createEvent(specialEvents[type] || 'Events'), bubbles = true 1154 | if (props) for (var name in props) (name == 'bubbles') ? (bubbles = !!props[name]) : (event[name] = props[name]) 1155 | event.initEvent(type, bubbles, true) 1156 | return compatible(event) 1157 | } 1158 | 1159 | })(Zepto) 1160 | 1161 | ;(function($){ 1162 | var jsonpID = 0, 1163 | document = window.document, 1164 | key, 1165 | name, 1166 | rscript = /)<[^<]*)*<\/script>/gi, 1167 | scriptTypeRE = /^(?:text|application)\/javascript/i, 1168 | xmlTypeRE = /^(?:text|application)\/xml/i, 1169 | jsonType = 'application/json', 1170 | htmlType = 'text/html', 1171 | blankRE = /^\s*$/, 1172 | originAnchor = document.createElement('a') 1173 | 1174 | originAnchor.href = window.location.href 1175 | 1176 | // trigger a custom event and return false if it was cancelled 1177 | function triggerAndReturn(context, eventName, data) { 1178 | var event = $.Event(eventName) 1179 | $(context).trigger(event, data) 1180 | return !event.isDefaultPrevented() 1181 | } 1182 | 1183 | // trigger an Ajax "global" event 1184 | function triggerGlobal(settings, context, eventName, data) { 1185 | if (settings.global) return triggerAndReturn(context || document, eventName, data) 1186 | } 1187 | 1188 | // Number of active Ajax requests 1189 | $.active = 0 1190 | 1191 | function ajaxStart(settings) { 1192 | if (settings.global && $.active++ === 0) triggerGlobal(settings, null, 'ajaxStart') 1193 | } 1194 | function ajaxStop(settings) { 1195 | if (settings.global && !(--$.active)) triggerGlobal(settings, null, 'ajaxStop') 1196 | } 1197 | 1198 | // triggers an extra global event "ajaxBeforeSend" that's like "ajaxSend" but cancelable 1199 | function ajaxBeforeSend(xhr, settings) { 1200 | var context = settings.context 1201 | if (settings.beforeSend.call(context, xhr, settings) === false || 1202 | triggerGlobal(settings, context, 'ajaxBeforeSend', [xhr, settings]) === false) 1203 | return false 1204 | 1205 | triggerGlobal(settings, context, 'ajaxSend', [xhr, settings]) 1206 | } 1207 | function ajaxSuccess(data, xhr, settings, deferred) { 1208 | var context = settings.context, status = 'success' 1209 | settings.success.call(context, data, status, xhr) 1210 | if (deferred) deferred.resolveWith(context, [data, status, xhr]) 1211 | triggerGlobal(settings, context, 'ajaxSuccess', [xhr, settings, data]) 1212 | ajaxComplete(status, xhr, settings) 1213 | } 1214 | // type: "timeout", "error", "abort", "parsererror" 1215 | function ajaxError(error, type, xhr, settings, deferred) { 1216 | var context = settings.context 1217 | settings.error.call(context, xhr, type, error) 1218 | if (deferred) deferred.rejectWith(context, [xhr, type, error]) 1219 | triggerGlobal(settings, context, 'ajaxError', [xhr, settings, error || type]) 1220 | ajaxComplete(type, xhr, settings) 1221 | } 1222 | // status: "success", "notmodified", "error", "timeout", "abort", "parsererror" 1223 | function ajaxComplete(status, xhr, settings) { 1224 | var context = settings.context 1225 | settings.complete.call(context, xhr, status) 1226 | triggerGlobal(settings, context, 'ajaxComplete', [xhr, settings]) 1227 | ajaxStop(settings) 1228 | } 1229 | 1230 | // Empty function, used as default callback 1231 | function empty() {} 1232 | 1233 | $.ajaxJSONP = function(options, deferred){ 1234 | if (!('type' in options)) return $.ajax(options) 1235 | 1236 | var _callbackName = options.jsonpCallback, 1237 | callbackName = ($.isFunction(_callbackName) ? 1238 | _callbackName() : _callbackName) || ('jsonp' + (++jsonpID)), 1239 | script = document.createElement('script'), 1240 | originalCallback = window[callbackName], 1241 | responseData, 1242 | abort = function(errorType) { 1243 | $(script).triggerHandler('error', errorType || 'abort') 1244 | }, 1245 | xhr = { abort: abort }, abortTimeout 1246 | 1247 | if (deferred) deferred.promise(xhr) 1248 | 1249 | $(script).on('load error', function(e, errorType){ 1250 | clearTimeout(abortTimeout) 1251 | $(script).off().remove() 1252 | 1253 | if (e.type == 'error' || !responseData) { 1254 | ajaxError(null, errorType || 'error', xhr, options, deferred) 1255 | } else { 1256 | ajaxSuccess(responseData[0], xhr, options, deferred) 1257 | } 1258 | 1259 | window[callbackName] = originalCallback 1260 | if (responseData && $.isFunction(originalCallback)) 1261 | originalCallback(responseData[0]) 1262 | 1263 | originalCallback = responseData = undefined 1264 | }) 1265 | 1266 | if (ajaxBeforeSend(xhr, options) === false) { 1267 | abort('abort') 1268 | return xhr 1269 | } 1270 | 1271 | window[callbackName] = function(){ 1272 | responseData = arguments 1273 | } 1274 | 1275 | script.src = options.url.replace(/\?(.+)=\?/, '?$1=' + callbackName) 1276 | document.head.appendChild(script) 1277 | 1278 | if (options.timeout > 0) abortTimeout = setTimeout(function(){ 1279 | abort('timeout') 1280 | }, options.timeout) 1281 | 1282 | return xhr 1283 | } 1284 | 1285 | $.ajaxSettings = { 1286 | // Default type of request 1287 | type: 'GET', 1288 | // Callback that is executed before request 1289 | beforeSend: empty, 1290 | // Callback that is executed if the request succeeds 1291 | success: empty, 1292 | // Callback that is executed the the server drops error 1293 | error: empty, 1294 | // Callback that is executed on request complete (both: error and success) 1295 | complete: empty, 1296 | // The context for the callbacks 1297 | context: null, 1298 | // Whether to trigger "global" Ajax events 1299 | global: true, 1300 | // Transport 1301 | xhr: function () { 1302 | return new window.XMLHttpRequest() 1303 | }, 1304 | // MIME types mapping 1305 | // IIS returns Javascript as "application/x-javascript" 1306 | accepts: { 1307 | script: 'text/javascript, application/javascript, application/x-javascript', 1308 | json: jsonType, 1309 | xml: 'application/xml, text/xml', 1310 | html: htmlType, 1311 | text: 'text/plain' 1312 | }, 1313 | // Whether the request is to another domain 1314 | crossDomain: false, 1315 | // Default timeout 1316 | timeout: 0, 1317 | // Whether data should be serialized to string 1318 | processData: true, 1319 | // Whether the browser should be allowed to cache GET responses 1320 | cache: true 1321 | } 1322 | 1323 | function mimeToDataType(mime) { 1324 | if (mime) mime = mime.split(';', 2)[0] 1325 | return mime && ( mime == htmlType ? 'html' : 1326 | mime == jsonType ? 'json' : 1327 | scriptTypeRE.test(mime) ? 'script' : 1328 | xmlTypeRE.test(mime) && 'xml' ) || 'text' 1329 | } 1330 | 1331 | function appendQuery(url, query) { 1332 | if (query == '') return url 1333 | return (url + '&' + query).replace(/[&?]{1,2}/, '?') 1334 | } 1335 | 1336 | // serialize payload and append it to the URL for GET requests 1337 | function serializeData(options) { 1338 | if (options.processData && options.data && $.type(options.data) != "string") 1339 | options.data = $.param(options.data, options.traditional) 1340 | if (options.data && (!options.type || options.type.toUpperCase() == 'GET')) 1341 | options.url = appendQuery(options.url, options.data), options.data = undefined 1342 | } 1343 | 1344 | $.ajax = function(options){ 1345 | var settings = $.extend({}, options || {}), 1346 | deferred = $.Deferred && $.Deferred(), 1347 | urlAnchor 1348 | for (key in $.ajaxSettings) if (settings[key] === undefined) settings[key] = $.ajaxSettings[key] 1349 | 1350 | ajaxStart(settings) 1351 | 1352 | if (!settings.crossDomain) { 1353 | urlAnchor = document.createElement('a') 1354 | urlAnchor.href = settings.url 1355 | urlAnchor.href = urlAnchor.href 1356 | settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host) 1357 | } 1358 | 1359 | if (!settings.url) settings.url = window.location.toString() 1360 | serializeData(settings) 1361 | 1362 | var dataType = settings.dataType, hasPlaceholder = /\?.+=\?/.test(settings.url) 1363 | if (hasPlaceholder) dataType = 'jsonp' 1364 | 1365 | if (settings.cache === false || ( 1366 | (!options || options.cache !== true) && 1367 | ('script' == dataType || 'jsonp' == dataType) 1368 | )) 1369 | settings.url = appendQuery(settings.url, '_=' + Date.now()) 1370 | 1371 | if ('jsonp' == dataType) { 1372 | if (!hasPlaceholder) 1373 | settings.url = appendQuery(settings.url, 1374 | settings.jsonp ? (settings.jsonp + '=?') : settings.jsonp === false ? '' : 'callback=?') 1375 | return $.ajaxJSONP(settings, deferred) 1376 | } 1377 | 1378 | var mime = settings.accepts[dataType], 1379 | headers = { }, 1380 | setHeader = function(name, value) { headers[name.toLowerCase()] = [name, value] }, 1381 | protocol = /^([\w-]+:)\/\//.test(settings.url) ? RegExp.$1 : window.location.protocol, 1382 | xhr = settings.xhr(), 1383 | nativeSetHeader = xhr.setRequestHeader, 1384 | abortTimeout 1385 | 1386 | if (deferred) deferred.promise(xhr) 1387 | 1388 | if (!settings.crossDomain) setHeader('X-Requested-With', 'XMLHttpRequest') 1389 | setHeader('Accept', mime || '*/*') 1390 | if (mime = settings.mimeType || mime) { 1391 | if (mime.indexOf(',') > -1) mime = mime.split(',', 2)[0] 1392 | xhr.overrideMimeType && xhr.overrideMimeType(mime) 1393 | } 1394 | if (settings.contentType || (settings.contentType !== false && settings.data && settings.type.toUpperCase() != 'GET')) 1395 | setHeader('Content-Type', settings.contentType || 'application/x-www-form-urlencoded') 1396 | 1397 | if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name]) 1398 | xhr.setRequestHeader = setHeader 1399 | 1400 | xhr.onreadystatechange = function(){ 1401 | if (xhr.readyState == 4) { 1402 | xhr.onreadystatechange = empty 1403 | clearTimeout(abortTimeout) 1404 | var result, error = false 1405 | if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304 || (xhr.status == 0 && protocol == 'file:')) { 1406 | dataType = dataType || mimeToDataType(settings.mimeType || xhr.getResponseHeader('content-type')) 1407 | result = xhr.responseText 1408 | 1409 | try { 1410 | // http://perfectionkills.com/global-eval-what-are-the-options/ 1411 | if (dataType == 'script') (1,eval)(result) 1412 | else if (dataType == 'xml') result = xhr.responseXML 1413 | else if (dataType == 'json') result = blankRE.test(result) ? null : $.parseJSON(result) 1414 | } catch (e) { error = e } 1415 | 1416 | if (error) ajaxError(error, 'parsererror', xhr, settings, deferred) 1417 | else ajaxSuccess(result, xhr, settings, deferred) 1418 | } else { 1419 | ajaxError(xhr.statusText || null, xhr.status ? 'error' : 'abort', xhr, settings, deferred) 1420 | } 1421 | } 1422 | } 1423 | 1424 | if (ajaxBeforeSend(xhr, settings) === false) { 1425 | xhr.abort() 1426 | ajaxError(null, 'abort', xhr, settings, deferred) 1427 | return xhr 1428 | } 1429 | 1430 | if (settings.xhrFields) for (name in settings.xhrFields) xhr[name] = settings.xhrFields[name] 1431 | 1432 | var async = 'async' in settings ? settings.async : true 1433 | xhr.open(settings.type, settings.url, async, settings.username, settings.password) 1434 | 1435 | for (name in headers) nativeSetHeader.apply(xhr, headers[name]) 1436 | 1437 | if (settings.timeout > 0) abortTimeout = setTimeout(function(){ 1438 | xhr.onreadystatechange = empty 1439 | xhr.abort() 1440 | ajaxError(null, 'timeout', xhr, settings, deferred) 1441 | }, settings.timeout) 1442 | 1443 | // avoid sending empty string (#319) 1444 | xhr.send(settings.data ? settings.data : null) 1445 | return xhr 1446 | } 1447 | 1448 | // handle optional data/success arguments 1449 | function parseArguments(url, data, success, dataType) { 1450 | if ($.isFunction(data)) dataType = success, success = data, data = undefined 1451 | if (!$.isFunction(success)) dataType = success, success = undefined 1452 | return { 1453 | url: url 1454 | , data: data 1455 | , success: success 1456 | , dataType: dataType 1457 | } 1458 | } 1459 | 1460 | $.get = function(/* url, data, success, dataType */){ 1461 | return $.ajax(parseArguments.apply(null, arguments)) 1462 | } 1463 | 1464 | $.post = function(/* url, data, success, dataType */){ 1465 | var options = parseArguments.apply(null, arguments) 1466 | options.type = 'POST' 1467 | return $.ajax(options) 1468 | } 1469 | 1470 | $.getJSON = function(/* url, data, success */){ 1471 | var options = parseArguments.apply(null, arguments) 1472 | options.dataType = 'json' 1473 | return $.ajax(options) 1474 | } 1475 | 1476 | $.fn.load = function(url, data, success){ 1477 | if (!this.length) return this 1478 | var self = this, parts = url.split(/\s/), selector, 1479 | options = parseArguments(url, data, success), 1480 | callback = options.success 1481 | if (parts.length > 1) options.url = parts[0], selector = parts[1] 1482 | options.success = function(response){ 1483 | self.html(selector ? 1484 | $('
').html(response.replace(rscript, "")).find(selector) 1485 | : response) 1486 | callback && callback.apply(self, arguments) 1487 | } 1488 | $.ajax(options) 1489 | return this 1490 | } 1491 | 1492 | var escape = encodeURIComponent 1493 | 1494 | function serialize(params, obj, traditional, scope){ 1495 | var type, array = $.isArray(obj), hash = $.isPlainObject(obj) 1496 | $.each(obj, function(key, value) { 1497 | type = $.type(value) 1498 | if (scope) key = traditional ? scope : 1499 | scope + '[' + (hash || type == 'object' || type == 'array' ? key : '') + ']' 1500 | // handle data in serializeArray() format 1501 | if (!scope && array) params.add(value.name, value.value) 1502 | // recurse into nested objects 1503 | else if (type == "array" || (!traditional && type == "object")) 1504 | serialize(params, value, traditional, key) 1505 | else params.add(key, value) 1506 | }) 1507 | } 1508 | 1509 | $.param = function(obj, traditional){ 1510 | var params = [] 1511 | params.add = function(key, value) { 1512 | if ($.isFunction(value)) value = value() 1513 | if (value == null) value = "" 1514 | this.push(escape(key) + '=' + escape(value)) 1515 | } 1516 | serialize(params, obj, traditional) 1517 | return params.join('&').replace(/%20/g, '+') 1518 | } 1519 | })(Zepto) 1520 | 1521 | ;(function($){ 1522 | $.fn.serializeArray = function() { 1523 | var name, type, result = [], 1524 | add = function(value) { 1525 | if (value.forEach) return value.forEach(add) 1526 | result.push({ name: name, value: value }) 1527 | } 1528 | if (this[0]) $.each(this[0].elements, function(_, field){ 1529 | type = field.type, name = field.name 1530 | if (name && field.nodeName.toLowerCase() != 'fieldset' && 1531 | !field.disabled && type != 'submit' && type != 'reset' && type != 'button' && type != 'file' && 1532 | ((type != 'radio' && type != 'checkbox') || field.checked)) 1533 | add($(field).val()) 1534 | }) 1535 | return result 1536 | } 1537 | 1538 | $.fn.serialize = function(){ 1539 | var result = [] 1540 | this.serializeArray().forEach(function(elm){ 1541 | result.push(encodeURIComponent(elm.name) + '=' + encodeURIComponent(elm.value)) 1542 | }) 1543 | return result.join('&') 1544 | } 1545 | 1546 | $.fn.submit = function(callback) { 1547 | if (0 in arguments) this.bind('submit', callback) 1548 | else if (this.length) { 1549 | var event = $.Event('submit') 1550 | this.eq(0).trigger(event) 1551 | if (!event.isDefaultPrevented()) this.get(0).submit() 1552 | } 1553 | return this 1554 | } 1555 | 1556 | })(Zepto) 1557 | 1558 | ;(function($){ 1559 | // __proto__ doesn't exist on IE<11, so redefine 1560 | // the Z function to use object extension instead 1561 | if (!('__proto__' in {})) { 1562 | $.extend($.zepto, { 1563 | Z: function(dom, selector){ 1564 | dom = dom || [] 1565 | $.extend(dom, $.fn) 1566 | dom.selector = selector || '' 1567 | dom.__Z = true 1568 | return dom 1569 | }, 1570 | // this is a kludge but works 1571 | isZ: function(object){ 1572 | return $.type(object) === 'array' && '__Z' in object 1573 | } 1574 | }) 1575 | } 1576 | 1577 | // getComputedStyle shouldn't freak out when called 1578 | // without a valid element as argument 1579 | try { 1580 | getComputedStyle(undefined) 1581 | } catch(e) { 1582 | var nativeGetComputedStyle = getComputedStyle; 1583 | window.getComputedStyle = function(element){ 1584 | try { 1585 | return nativeGetComputedStyle(element) 1586 | } catch(e) { 1587 | return null 1588 | } 1589 | } 1590 | } 1591 | })(Zepto) --------------------------------------------------------------------------------