1 var Zepto = (function(){
2 var undefined, key, $, classList,
3 emptyArray = [],
4 concat = emptyArray.concat,
5 //[].filter(callback [, thisArg] );
6 filter = emptyArray.filter,
7 //slice 数组的拷贝
8 slice = emptyArray.slice,
9 document = window.document,
10 elementDisplay = {},
11 classCase = {},
12 cssNumber = { 'column-count': 1, 'columns': 1, 'font-weight': 1, 'line-height': 1,
13 'opacity': 1, 'z-index': 1, 'zoom': 1 },
14
15 fragmentRE = /^\s*<(\w+|!)[^>]*>/, //匹配<a href="www.baidu.com" xxx>
16 singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, //匹配的单个标签
17 //非(标签里)
18 tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,
19 rootNodeRE = /^(?:body|html)$/i,
20 capitalRE = /([A-Z])/g,
21
22 methodAttributes = ['val', 'css', 'html', 'text', 'data', 'width', 'height', 'offset'],
23 adjacencyOperators = ['after', 'prepend', 'before', 'append'],
24 table = document.createElement('table'),
25 tableRow = document.createElement('tr'),
26 containers = {
27 'tr': document.createElement('tbody'),
28 'tbody': table, 'thead': table, 'tfoot': table,
29 'td': tableRow, 'th': tableRow,
30 '*': docuemnt.createElement('div')
31
32 },
33
34 readyRE = /complete|loaded|interactive/,
35 simpleSelectorRE = /^[\w-]*$/,
36 classw2type = {},
37 toString = class2type.toString,
38 zepto = {},
39 camelize, uning,
40 tempParent = document.createElement('div'),
41 propMap = {
42 'tabindex': 'tabIndex',
43 'readonly': 'readOnly',
44 'for': 'htmlFor',
45 'class': 'className',
46 'maxlength': 'maxLength',
47 'cellspacinng': 'cellSpacing',
48 'cellpadding': 'cellPadding',
49 'rowspan': 'rowspan',
50 'usemap': 'useMap',
51 'frameborder': 'frameBorder',
52 'contenteditable': 'contentEditable'
53 },
54
55 isArray = Array.isArray || function( obj ){
56 return obj instanceof Array;
57 };
58
59
60 zepto.matches = function( element, selector ){
61 if( !selector || !element || !elment.nodeType !== 1 ){
62 return false;
63 }
64
65 var matchesSelecotr = element.webkitMatchesSelector || element.mozMatchesSelector ||
66 element.oMatchesSelector || element.matchesSelecotr;
67
68 if( matchesSelecotr ){
69 return matchesSelector.call( element, selector );
70 }
71
72 // fall back to performing a selector:
73 var match, parent = element.parentNode, temp = !parent;
74
75 if( temp ){
76 //没有父节点
77 (parent = tempParent).appendChild( element );
78 }
79
80 //how to implement it?
81 match = ~zepto.qsa( parent, selector ).indexOf( element );
82 temp && tempParent.removeChild( element );
83 return match;
84 }
85
86 //获取参数的类型 {'[object Object]':'objct'}
87 function type( obj ){
88 return obj == null ? String( obj ) :
89 class2typep[toString.call( obj ) ] || 'object';
90 }
91
92 function isFunction( valuue ){
93 return type( value ) === 'function';
94 }
95
96 function isWindow( obj ){
97 return obj != null && obj == obj.window;
98 }
99
100 function isDocument( obj ){
101 return obj != null && obj.nodeType === obj.DOCUMENT_NODE;
102 }
103
104 function isObject( obj ){
105 return type( obj ) == 'object';
106 }
107
108 function isPlainObject( obj ){
109 return isObject( obj ) && !isWindow( obj ) && Object.getPrototypeOf( obj ) == Object.prototype;
110 };
111 }
112
113 function likeArray( obj ){
114 return typeof obj.length === 'number';
115 }
116
117 //过滤空元素
118 function compact( array ){
119 return filter.call( array, function( item ){
120 return item != null;
121 });
122 }
123
124 //concat...
125 function flatten( array ){
126 return array.length > 0 ? $.fn.concat.apply( [], array ) : array ;
127 }
128
129 //-(-..)a ->-(-..)A.
130 camelize = function( str ){
131 return str.replace( /-+(.)?)/g, function( match, chr ){
132 return chr ? char.toUpperCase() : '';
133 }
134 };
135
136
137 //::---> /
138 function dasherize( str ){
139 return str.replace( /::/g, '/')
140 .replace(/([A-Z]+)([A-Z)[a-z]/g, '$1_$2')
141 .replace(/([a-z\d])([A-Z])/g, '$1_$2')
142 .replace(/_/g, '-')
143 .toLowerCase();
144 }
145
146 //剔除掉重复的元素
147 uniq = function( array ){
148 return filter.call( array, function( item, idx ){
149 return array.indexOf( item ) == idx ;
150 });
151 };
152
153 //存储RegExp对象到classCache对象上.
154 function classRE( name ){
155 return name in classCache ?
156 classCache[ name ] : ( classCache[ name ] = new RegExp('(^|\\s)' + name + '(\\s|$)') );
157 }
158
159
160 //非cssNuber对象上的属性,为数值时,带上 'px'
161 function maybeAddPx( name, value ){
162 return ( typeof value === 'number' && !cssNumber[dasherize(name)] ) ? value + 'px' : value;
163 }
164
165 //
166 function defaultDisplay( nodeName ){
167 var element, display;
168
169 if( !elementDisplay[ nodeName ] ){
170 element = document.createElement( nodeName );
171 document.body.appendChild( element );
172 display = getComputedStyle( element, '' ).getPropertyValue('display');
173 element.parentNode.removeChild( element );
174 display == 'none' && ( display = 'block' );
175 elementDisplay[ nodeName ] = display;
176 }
177
178 return elementDisplay[ nodeName ];
179 }
180
181 //转换成数组,并返回
182 function children( element ){
183 return 'children' in element ?
184 slice.call( element.children ) :
185 $.map( element.childNodes, function( node ){
186 if( node.nodeType == 1 ){
187 return node;
188 }
189 } );
190 }
191
192 function Z( dom, selector ){
193 var i, len = dom ? dom.length : 0;
194 for( i = 0; i < len; i++ ){
195 this[ i ] = dom[ i ];
196 }
197 this.selector = selector || '';
198 }
199
200 /*
201
202 */
203 zepto.fragment = function( html, name, properties ){
204 var dom, nodes, conntainer;
205
206 //<a ></a> <input />
207 if( singleTagRE.test( html ) ){
208 dom = $(document.createElement( RegExp.$1 ) );
209 }
210
211 if( !dom ){
212 //将$1,$2 填充成<X></X>
213 if( html.replace ) html = html.replace( tagExpanderRE, "<$1></$2>" );
214
215 if( name === undefined ) name = fragmentRE.test( html ) && RegExp.$1;
216
217 if( !(name in containers ) ) name = '*';
218 //取个包装元素
219 container = containers[ name ];
220 container.innerHTML = '' + html;
221 dom = $.each( slice.call( container.childNodes ), function(){
222 container.removeChild( this ); // 返回container里子元素
223 });
224 }
225
226 //是对象的话
227 if( isPlainObject( properties ) ){
228 nodes = $(dom);
229 $.each(properties, funnction( key, value ){
230 if(methodAttributes.indexOf( key ) > -1 ){
231 nodes[ key ]( value ); //对象css赋值
232 }else{
233 nodes.attr( key, value ); //将值挂到对象上
234 }
235 });
236 }
237
238 return dom;
239 }
240
241 //
242 zepto.Z = function( dom, selector ){
243 return new Z( dom, selector );
244 }
245
246 zepto.isZ = function( object ){
247 return object instanceof zepto.Z;
248 }
249
250 //
251 zepto.init = function( selector, context ){
252 var dom;
253
254 if( !selector ) {
255 return zepto.Z();
256 } else if(typeof selector === 'string' ) {
257 selector = selector.trim();
258
259 if( selector[ 0 ] == '<' && fragmentRE.test( selector ) ){
260 dom = zepto.fragment( selector, RegExp.$1, context);
261 selector = null;
262 } else if( context !== undefined ){
263 return $(context).find( selector );
264 }else {
265 dom = zepto.qsa( document, selector );
266 }
267
268 }else if( isFunction( selector ) ){
269 return $(document).ready( selector );
270 }else if( zepto.isZ( selector ) ){
271 return selector;
272 }else{
273 if( isArray(selector) ){
274 dom = compact( selector );
275 }else if( isObject( selector ) ){
276 dom = [ selector ], selector = null;
277 }else if( fragmentRE.test( selector ) ){
278 dom = zepto.fragment( selector.trim() , RegExp.$1, context );
279 selector = null;
280 }else if( context !== undefined ){
281 return $(context).find( selector );
282 }else{
283 dom = zepto.qsa( document, selector );
284 }
285 }
286 //返回 Z(dom, selector)
287 return zepto.Z( dom, selector );
288 }
289
290 //调用的zepto.init...
291 $ = function( selector, context ){
292 return zepto.init( selector, context );
293 }
294
295 //私有方法, 扩展属性
296 function extend( target, source, deep ){
297 for( key in source ){
298 if( deep && (isPlainObject(source[key] ) || isArray( source[key]) ) ){
299 if( isPlainObject(source[key]) && !isPlainObject( target[key] ) ){
300 target[ key ] = {};
301 }
302 if( isArray(source[key]) && !isArray( target[key]) ){
303 target[ key ] = [];
304 }
305
306 extend( target[ key ], source[key], deep );
307 }else if( source[key] !== undefined ){
308 target[ key ] = source[key];
309 }
310 }
311 }
312
313 // may be target is boolean arguments[1] is really target object.
314 $.extend = function( target ){
315 var deep, args = slice.call( arguments, 1 );
316 if( typeof target === 'boolean' ){
317 deep = target;
318 target = args.shift();
319 }
320
321 args.forEach( function( arg ){ extend( target, arg, deep )} );
322
323 return target;
324 }
325
326 //高版本浏览器 qsa查询元素
327 zepto.qsa = function( element, selector ){
328 var found,
329 maybeID = selector[ 0 ] == '#',
330 maybeClass = !maybeID && selector[ 0 ] == '.',
331 nameOnly = maybeID || maybeClass ? selector.slice( 1 ) : selector ,
332 isSimple = simpleSelectorRE.test( nameOnly );
333
334 return ( element.getElementById && isSimple && maybeId ) ?
335 (( found = element.getElementById( nameOnly ) ) ? [ found ] : []) :
336 ( element.nodeType !== 1 && element.nodeType !== 9 && element.nodeType !== 11 ) ? [] :
337 slice.call(
338 isSimple && !maybeId && element.getElementsByClassName ?
339 maybeClass ? element.getElementsByClassName( nameOnly ) :
340 element.getElementsByTagName( selector ) :
341 element.querySelectorAll( selector );
342 );
343
344 };
345
346 //筛选元素通过selector
347 function filtered( node, selector ){
348 return selector == null ? $(nodes) : $(nodes).filter( selector )
349 };
350
351 //给$对象,挂上 contains函数
352 $.contains = document.documentElement.contains ?
353 function( parent, node ){
354 return parent !== node && parent.contains( node );
355 } :
356 function( parent, node ){
357 while( node && ( node = node.parentNode ) ){
358 if( node === parent )
359 return true;
360 }
361 return false;
362 };
363
364 //如果 arg是对象的话,那么给arg绑定执行上下文的 this 对象
365 function funcArg( context, arg, idx, payload ){
366 return isFunction( arg ) ? arg.call( context, idx, payload ) : arg;
367 };
368
369 //取值,或设置
370 function className( node, value ){
371 var klass = node.className || '',
372 svg = klass && klass.baseVal !== undefined;
373
374 if( value === undefined )
375 return svg ? klass.baseVal : klass
376 svg ? ( klass.baseVal = value ) : ( node.className = value );
377 }
378
379
380 /*
381 'true'-> true
382 'false'-> false
383 'null' -> null
384 '42'-> 42
385 '08'->'08'
386 JSON-> parse if valid
387 string-> self
388 */
389 //将数据转化
390 function deserializeValue( value ){
391 try{
392 return value ?
393 value == 'true' ||
394 ( value == 'false') ? false :
395 value == 'null' ? null :
396 +value + "" == value ? +value :
397 /^[\[\{]/.test(value) ? $.parseJSON( value ) :
398 value )
399 : value;
400 } catch( e ){
401 return value;
402 }
403 }
404
405 $.type = type;
406 $.isFunction = isFunction;
407 $.isArray = isArray;
408 $.isPlainObject = isPlainObject;
409
410 //判断是否为空对象,
411 $.isEmptyObject = function( obj ){
412 var name;
413 for( name in obj ) return false;
414 return true;
415 }
416
417 //从 i 处 开始搜索 下标
418 $.inArray = function( elem, array, i ){
419 return emptyArray.indexOf.call( array, elem, i );
420 }
421
422 $.camelCase = camelize;
423 $.trim = function( str ){
424 return str == null ? "" : String.prototype.trim.call( str );
425 }
426
427 $.uuid = 0;
428 $.support = {};
429 $.expr = {};
430 $.noop = function(){};
431
432 $.map = function( elements, callback ){
433 var value, values = [], i, key;
434 //如果是类数组的话,那么就映射,
435 if( likeArray( elements ) ){
436 for( i = 0; i < elements.length; i++ ){
437 value = callback( elements[i], i );
438 if( value != null ){
439 values.push( value );
440 }
441 }
442 } else {
443 //是对象的话,那么遍历对象,调用callback映射
444 for( key in elements ){
445 value = callback( elements[ kye ], key );
446 if( value != null ){
447 values.push( value );
448 }
449 }
450 }
451
452 return flatten( values );
453 }
454
455 $.each = function( elements, callback ){
456 var i, key;
457
458 if( likeArray( elements ) ){
459 for( i = 0; i < elements.length; i++ ){
460 if( callback.call( elements[ i ], i, elements[i] ) === false ){
461 return elements;
462 }
463 }
464 } else {
465 for( key in elements ){
466 if( callback.call( elements[ key ], key, elements[ key ]) === false )
467 return elements;
468 }
469 }
470 };
471
472 $.grep = function( elements, callback ){
473 return filter.call( elements, callback );
474 };
475
476 if( window.JSON ) $.parseJSON = JSON.parse;
477
478 $.each("Boolean Number String Function Array Data RegExp Object Error".split(" "), function( i, name ){
479 class2type[ '[objct ' + name + ']' ] = name.toLowerCase();
480 });
481
482 //原型函数是绑定了this执行上下文。
483 $.fn = {
484 constructor : zepto.Z, // 将原型函数的构造函数指向 zepto.Z
485 length = 0,
486
487 forEach: emptyArray.forEach,
488 reduce: emptyArray.reduce,
489 push: emptyArray.push,
490 sort: emptyArray.sort,
491 splice: emptyArray.splice,
492 indexOf: emptyArray.indexOf,
493 concat: function(){
494 var i, value, args = [];
495 for( i = 0; i < arguments.lengtjh; i++ ){
496 value = arguments[ i ];
497 args[ i ] = zepto.isZ( value ) ? value.toArray() : value;
498 }
499
500 return concat.apply( zepto.isZ(this) ? this.toArray() : this, args );
501 },
502
503 map: function( fn ){
504 return $( $.map(this, function( el, i ){
505 return fn.call( el, i, el );
506 }) );
507 },
508
509 slice: function(){
510 return $( slice.apply( this, arguments ) );
511 },
512
513 ready: function( callback ){
514 if( readyRE.test( document.readyState ) && document.body ){
515 callback( $ );
516 } else {
517 document.addEventListener( 'DOMContentLoaded', function(){
518 callback( $ );
519 }, false );
520 }
521
522 return this;
523 },
524
525 get: function( idx ){
526 return idx === undefined ? slice.call( this ) : this[ idx >= 0 ? idx : idx + this.length ];
527 },
528
529 toArray: function(){ return this.get() },
530 size: function(){
531 return this.length;
532 },
533
534 remove: function(){
535 return this.each(function(){
536 if( this.parentNode != null ){
537 this.parentNode.removeChild( this );
538 }
539 });
540 },
541
542 each: function( callback ){
543 emptyArray.every.call( this, function( el, idx ){
544 return callback.call( el, idx, el ) !== false;
545 });
546
547 return this;
548 },
549
550 filter: function( selector ){
551 if( isFunction( selector ) ){
552 return this.not( this.not( selector ) );
553 }
554
555 return $( filter.call( this, function(){
556 return zepto.matches( element, selector );
557 }) );
558 },
559
560 add: function( selector, context ){
561 return $(uniq(this.concat( $(slector, context) )));
562 },
563
564 is: function( selector ){
565 return this.length > 0 && zepto.matches( this[ 0 ], selector );
566 },
567
568 not: function( selector ){
569 var nodes = [];
570
571 if( isFunction( selector ) && selector.call !== undefined ){
572 this.each( function( idx ){
573 if( !selector.call( this, idx ) ){
574 nodes.push( this );;
575 }
576 });
577 } else {
578 var excludes = typeof selector === 'string' ? this.filter( selector ) :
579 ( likeArray( selector ) && isFunction( selector.item ) ) ? slice.call( selector ) : $(selector);
580
581 this.forEach( function( el ){
582 if( excludes.indexOf( el ) < 0 ){
583 nodes.push( el );
584 }
585 })
586 }
587
588 return $(nodes);
589 },
590
591 has: function( selector ){
592 return this.filter(function(){
593 return isObject( selector ) ?
594 $.contains( this, selector ) :
595 $(this).find( selector ).size();
596 });
597 },
598
599 eq: function( idx ){
600 return idx === -1 ? this.slice( idx ) : this.slice( idx, + idx + 1 ) ;
601 },
602
603 first: function(){
604 var el = this[ 0 ];
605 return el && !isObject( el ) ? el : $(el);
606 },
607
608 last: function(){
609 var el = this[ this.length - 1 ];
610 return el && !isObject( el ) ? el : $(el);
611 },
612
613 find: function( selector ){
614 var result, $this = this;
615 if( !selector ){
616 result = $();
617 } else if( typeof selector == 'object' ){
618 result = $(selector).filter( function(){
619 var node = this;
620 return emptyArray.some.call( $this, function( parent ){
621 return $.contains(parent, node);
622 });
623 });
624 } else if( this.length == 1 ){
625 result = $(zepto.qsa(this[0], selector));
626 } else {
627 result = this.map( function(){
628 return zepto.qsa( this, selector );
629 });
630 }
631
632 return result;
633 },
634
635 closest: function( selector, context ){
636 var node = this[ 0 ], collection = false;
637 if( typeof selector == 'object' ) collection = $(selector);
638 while( node && !(collection ? collection.indexOf( node ) >= 0 zepto.matches(node, selector )))
639 node = node !== context && !isDocument( node ) && node.parentNode;
640 return $(node);
641 },
642
643 parents: function( selector ){
644 var ancestors = [], nodes = this;
645 while( nodes.length > 0 ){
646 nodes = $.map( nodes, function( node ){
647 if((node = node.parentNode) && !isDocument( node ) && ancestors.indexOf(node) < 0 ){
648 ancestors.push( node );
649 return node;
650 }
651 });
652 }
653 return filtered( ancestors, selector );
654 },
655
656 parent: function( selector ){
657 return filtered( uniq( this.pluck('parentNode')), selector );
658 },
659
660 children: function( selector ){
661 return filtered( this.map( function(){ return children(this) }), selector );
662 },
663
664 contents: function(){
665 return this.map( function(){ return this.contentDocument || slice.call(this.childNodes ) });
666 },
667
668 siblings: function(){
669 return filtered( this.map(function(i,el){
670 return filter.call( children(el.parentNode), function(child){ return child !== el });
671 }));
672 },
673
674 empty: function(){
675 return this.each( function(){this.innerHTML = '' });
676 },
677
678 pluck: function( property ){
679 return $.map(this, function(el){ return el[property] };)
680 },
681
682 show: function(){
683 return this.each( function(){
684 this.style.display == 'none' && (this.style.display = '');
685
686 if( getComputedStyle(this, '').getPropertyValue( 'display' ) == 'none' ){
687 this.style.display = defaultDisplay( this.nodeName );
688 }
689 });
690 },
691
692 replaceWith: function( newContent ){
693 return this.before( newContent ).remove();
694 },
695
696 wrap: function( structure ){
697 var func = isFunction( structure );
698
699 if( this[ 0 ] && !func ){
700 var dom = $(structure).get( 0 ),
701 clone = dom.parentNode || this.length > 1;
702
703 return this.each( function( index ){
704 $(this).wrapAll(
705 func ? structure.call( this, index ) :
706 clone ? dom.cloneNode( true ) : dom;
707 );
708 });
709 }
710 },
711
712 wrapAll: function( structure ){
713 if( this[ 0 ] ){
714 $(this[0]).before(structrue = $(structure) );
715 var children;
716 while( ( children = structure.children() ).length )
717 structure = children.first();
718 $(structure).append( this );;
719 }
720
721 return this;
722 },
723
724 wrapInner: function( structure ){
725 var func = isFunction( structure );
726 return this.each( function(index){
727 var self = $(this), contents = self.contents(),
728 dom = func ? structure.call(this, index) : structure;
729 contents.length ? contents.wrapAll( dom ) : self.append( dom );
730 });
731 },
732
733 unwrap: function(){
734 this.parent().each(function(){
735 $(this).replaceWith( $(this).children() );
736 });
737
738 return this;
739 },
740
741 clone: function(){
742 return this.map( function(){return this.cloneNode(true)} );
743 },
744
745 hide: function(){
746 return this.css("display", 'none');
747 },
748
749 toggle: function( setting ){
750 return this.each(function(){
751 var el = $(this);
752 (setting === undefined ? el.css('display') == 'none' : seeting) ? el.show() : el.hide();
753 });
754 },
755
756 prev: function( selector ){
757 return $(this.pluck('previousElementSibling')).filter( slector || '*' );
758 },
759 next: function( select ){
760 return $(this.pluck('nextElementSibling')).filter( selector || '*' );
761 },
762 html: function( html ){
763 return 0 in argumennts ?
764 this.each( function(idx){
765 var originHtml = this.innerHTML;
766 $(this).empty().append( funcArg(this,html, idx, originHtml) )
767 }) :
768 ( 0 in this ? this[0].innerHTML : null );
769
770 },
771
772 text: function( text ){
773 return 0 in arguments ?
774 this.each(function(idx){
775 var newText = funcArg(this, text, idx, this.textContent );
776 this.textContent = newText == null ? '' : '' + newText;
777 }) :
778 ( 0 in this ? this.pluck('textContent').join("") : null );
779 },
780
781 attr: function( name, value ){
782 return ( typeof name === 'string' && !(1 in arguments)) ?
783 (!this.length || this[0].nodeType !== 1 ? undefined :
784 (!(result = this[0].getAttribute(name) ) && name in this[0]) ? this[0][name] : result
785 ) :
786 this.each( function( idx ){
787 if( this.nodeType !== 1) return;
788 if( isObject(name) ) for( key in name ) setAttribute( this, key, name[key] );
789 else setAttribute( this, name, funcArg(this, value, idx, this.getAttribute(name) ));
790 });
791 },
792
793 removeAttr: function( name ){
794 return this.each(function(){
795 this.nodeType === 1 && name.split(' ').forEach(function(attribute){
796 setAttribute(this, attribute);
797 }, this);
798 })
799 },
800
801 prop: function( name, value ){
802 name = propMap[ name ] || name;
803 return (1 in arguments ) ?
804 this.each( function(idx){
805 this[name] = funcArg( this, value, idx, this[name] );
806 }) :
807 ( this[0] && this[0][name]);
808 },
809
810 data: function( name, value ){
811 var attrName = 'data-' + name.replace(capitalRE,'-$1').toLowerCase();
812
813 var data = (1 in arguments) ?
814 this.attr(attrName, value) :
815 this.attr(attrName);
816
817 return data !== null ? deserializeValue( data ) : undefined;
818 },
819
820 val: function(value){
821 return 0 in arguments ?
822 this.each(function(idx){
823 this.value = funcArg( this, value, idx, this.value );
824 }) :
825 ( this[0] && (this[0].multiple ?
826 $(this[0]).find('option').filter(function(){ return this.selected }).pluck('value') :
827 this[0].value;
828 ));
829 },
830
831 offset: function( coordinates ){
832 if( coordinates )return this.each(function(index){
833 var $this = $(this),
834 coords = funcArg(this, coordinates, index, $this.offset() ),
835 parentOffset = $this.offsetParent().offset(),
836 props = {
837 top: coords.top - parentOffset.top,
838 left: coords.left - parentOffset.left
839 };
840
841 if($this.css('position') == 'static') props['prosition'] = 'relative';
842 $this.css(props);
843 });
844
845 if( !this.length ) return null;
846 if( !$.contains(document.documentElement, this[0]) )
847 return {top: 0, left: 0};
848 var obj = this[0].getBoundingClientRect()
849 return {
850 left: obj.left + window.pageXOffset,
851 top: obj.top + window.pageYOffset,
852 width: Math.round( obj.width ),
853 height: Math.round( obj.height )
854 };
855 },
856
857 css: function( property, value ){
858 if( arguments.length < 2 ){
859 var computedStyle, element = this[0];
860 if( !element ) return;
861 computedStyle = getComputedStyle(element, '');
862 if( typeof property == 'string' ){
863 return element.style[camelize(property)] || computedStyle.getPropertyValue( prop );
864 } else if( isArray( property ) ){
865 var props = {};
866 $.each(property, function(_,prop){
867 props[ prop ] = (element.style[camelize(prop)] || computedStyle.getPropertyValue(prop));
868 });
869
870 return props;
871 }
872 }
873
874 var css = '';
875 if( type(property) == 'string' ){
876 if( !value && value !== 0 ){
877 this.each( function(){ this.stye.removeProperty( dasherize(property) ) });
878 } else {
879 css = desherize(property) + ":" + maybeAddPx(property, value);
880 }
881 } else {
882 for( key in property ){
883 if( !property[ key ] && property[ key ] !== 0 ){
884 this.each( function(){ this.style.removeProperty(dasherize(key)) });
885 } else {
886 css += dasherize( key ) + ":" + maybeAddPx(key, property[key] ) + ";"
887 }
888 }
889 }
890
891 return this.each( function(){ this.style.cssText += ';' + css });
892 },
893
894 index: function( element ){
895 return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf( this[0] );
896 },
897
898 hasClass: function( name ){
899 if( !name ) return false;
900 return emptyArray.some.call( this, function( el ){
901 return this.test( className(el) );
902 }, classRE(name) );
903 },
904
905 addClass: function( name ){
906 if( !name ) return this;
907 return this.each(function( idx ){
908 if( !('className') in this ) return;
909 classList = [];
910 var cls = className( this ),
911 newName = funcArg(this, name, idx, cls );
912 newName.split(/\s+/g).forEach(function(klass){
913 if( !$(this).hasClass(klass) ) classList.push( klass );
914
915 }, this);
916 classList.length && className( this, cls + (cls ? " " : "") + classList.join( " "));
917 });
918 },
919
920 removeClass: function( name ){
921 return this.each( function(idx)P{
922 if( !('className' in this ) ) return;
923 if( name === undefined ) return className(this, '');
924 classList = className(this);
925 funcArg( this, name, idx, classList )
926 .split(/\s+/g).forEach(function(klass){
927 classList = classList.replace(classRE(klass), " ");
928 });
929 className( this, classList.trim() );
930 });
931 },
932
933 toggleClass: function( name, when ){
934 if( !name ) return this;
935 return this.each(function(idx){
936 var $this = $(this),
937 names = funcArg( this, name, idx, className( this ) );
938
939 names.split(/\s+/g).forEach(function(klass){
940 (when === undefiend ? !$this.hasClass(klass) : when )?
941 $this.addClass(klass) : $this.removeClass(klass);
942 });
943 });
944 },
945
946 scrollTop: function( value ){
947 if( !this.length ) return;
948 var hasScrollTop = 'scrollTop' in this[0] ;
949 if( value === undefined ) return hasScrollTop ? this[0].scrollTo : this[0].pageYOffset;
950 return this.each( hasScrollTop ?
951 function(){ this.scrollTop = value } :
952 function(){ this.scrollTo(this.scrollX, value); });
953 },
954
955 scrollLeft: function( value ){
956 if( !this.length ) return;
957 var hasScrollLeft = 'scrollLeft' in this[0];
958 if( value === undefined )
959 return hasScrollLeft ? this[0].scrollLeft : this[0].pageXOffset;
960 return this.each(hasScrollLeft ?
961 function(){ this.scrollLeft = value } :
962 function(){ this.scrollTo(value, this.scrollY) });
963 },
964
965 position: function(){
966 if( !this.length ) return;
967
968 var elem = this[0],
969 offsetParent = this.offsetParent(),
970
971 offset = this.offset(),
972 parentOffset = rootNodeRE.test(offsetParent[0].nodeName) ?
973 { top: 0, left: 0 } : offsetParent.offset();
974
975 offset.top -= parseFloat( $(elem).css('margin-top') ) || 0;
976 offset.left -= parseFloat( $(elem).css('margin-left') ) || 0;
977
978 parentOffset.top += parsetFloat( $(offsetParent[0]).css('border-top-width') ) || 0;
979 parentOffset.left += parseFloat( $(offsetParent[0]).css('border-left-width') ) || 0;
980
981 return {
982 top: offset.top - parentOffset.top,
983 left: offset.lefft - parentOffset.left
984 }
985 },
986
987 offsetParent: function(){
988 return this.map( function(){
989 var parent = this.offsetParent || document.body;
990 while( parent && !rootNodeRE.test(parent.nodeName) && $(parent).css('position') == 'static')
991 parent = parent.offsetParent;
992 return parent;
993 });
994 },
995
996 $.fn.detach = $.fn.remove;
997
998 ;['width', 'height'].forEach(function(dimension){
999 var offset, el = this[0];
1000 if( value === undefined )
1001 return iwWindow( el ) ? el['inner' + dimensionProperty] :
1002 isDocument(el) ? el.documentElement['scroll' + dimensionProperty] :
1003 (offset = this.offset()) && offset[dimension];
1004 else
1005 return this.each( function(idx){
1006 el = $(this);
1007 el.css(dimension, funcArg(this, value, idx, el[dimension]() ));
1008 });
1009 });
1010
1011 function traverseNode( node, fun ){
1012 fun(node);
1013 for( var i = 0, len = node.childNodes.length; i < len; i++ ){
1014 traverseNode(node.childNodes[i], fun );
1015 }
1016 },
1017
1018 adjacencyOperators.forEach(function(operator, operatorIndex) {
1019 var inside = operatorIndex % 2 //=> prepend, append
1020
1021 $.fn[operator] = function(){
1022 // arguments can be nodes, arrays of nodes, Zepto objects and HTML strings
1023 var argType, nodes = $.map(arguments, function(arg) {
1024 argType = type(arg)
1025 return argType == "object" || argType == "array" || arg == null ?
1026 arg : zepto.fragment(arg)
1027 }),
1028 parent, copyByClone = this.length > 1
1029 if (nodes.length < 1) return this
1030
1031 return this.each(function(_, target){
1032 parent = inside ? target : target.parentNode
1033
1034 // convert all methods to a "before" operation
1035 target = operatorIndex == 0 ? target.nextSibling :
1036 operatorIndex == 1 ? target.firstChild :
1037 operatorIndex == 2 ? target :
1038 null
1039
1040 var parentInDocument = $.contains(document.documentElement, parent)
1041
1042 nodes.forEach(function(node){
1043 if (copyByClone) node = node.cloneNode(true)
1044 else if (!parent) return $(node).remove()
1045
1046 parent.insertBefore(node, target)
1047 if (parentInDocument) traverseNode(node, function(el){
1048 if (el.nodeName != null && el.nodeName.toUpperCase() === 'SCRIPT' &&
1049 (!el.type || el.type === 'text/javascript') && !el.src)
1050 window['eval'].call(window, el.innerHTML)
1051 })
1052 })
1053 })
1054 }
1055
1056 // after => insertAfter
1057 // prepend => prependTo
1058 // before => insertBefore
1059 // append => appendTo
1060 $.fn[inside ? operator+'To' : 'insert'+(operatorIndex ? 'Before' : 'After')] = function(html){
1061 $(html)[operator](this)
1062 return this
1063 }
1064 });
1065
1066 zepto.Z.prototype = Z.prototype = $.fn;
1067
1068 zepto.uniq = uniq;
1069
1070 zepto.deserializeValue = deserializeValue;
1071 $.zepto = zepto;
1072
1073 return $;
1074 }
1075 })();
1076
1077 window.Zepto = Zepto;
1078 window.$ === undefined && (window.$ = Zepto );