Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(306)

Side by Side Diff: bower_components/gif.js/site/contents/scripts/vendor/mootools.js

Issue 786953007: npm_modules: Fork bower_components into Polymer 0.4.0 and 0.5.0 versions (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 (function(){
2
3 this.MooTools = {
4 version: '1.4.5',
5 build: 'ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0'
6 };
7
8 // typeOf, instanceOf
9
10 var typeOf = this.typeOf = function(item){
11 if (item == null) return 'null';
12 if (item.$family != null) return item.$family();
13
14 if (item.nodeName){
15 if (item.nodeType == 1) return 'element';
16 if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'w hitespace';
17 } else if (typeof item.length == 'number'){
18 if (item.callee) return 'arguments';
19 if ('item' in item) return 'collection';
20 }
21
22 return typeof item;
23 };
24
25 var instanceOf = this.instanceOf = function(item, object){
26 if (item == null) return false;
27 var constructor = item.$constructor || item.constructor;
28 while (constructor){
29 if (constructor === object) return true;
30 constructor = constructor.parent;
31 }
32 /*<ltIE8>*/
33 if (!item.hasOwnProperty) return false;
34 /*</ltIE8>*/
35 return item instanceof object;
36 };
37
38 // Function overloading
39
40 var Function = this.Function;
41
42 var enumerables = true;
43 for (var i in {toString: 1}) enumerables = null;
44 if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'p ropertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
45
46 Function.prototype.overloadSetter = function(usePlural){
47 var self = this;
48 return function(a, b){
49 if (a == null) return this;
50 if (usePlural || typeof a != 'string'){
51 for (var k in a) self.call(this, k, a[k]);
52 if (enumerables) for (var i = enumerables.length; i--;){
53 k = enumerables[i];
54 if (a.hasOwnProperty(k)) self.call(this, k, a[k]);
55 }
56 } else {
57 self.call(this, a, b);
58 }
59 return this;
60 };
61 };
62
63 Function.prototype.overloadGetter = function(usePlural){
64 var self = this;
65 return function(a){
66 var args, result;
67 if (typeof a != 'string') args = a;
68 else if (arguments.length > 1) args = arguments;
69 else if (usePlural) args = [a];
70 if (args){
71 result = {};
72 for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, ar gs[i]);
73 } else {
74 result = self.call(this, a);
75 }
76 return result;
77 };
78 };
79
80 Function.prototype.extend = function(key, value){
81 this[key] = value;
82 }.overloadSetter();
83
84 Function.prototype.implement = function(key, value){
85 this.prototype[key] = value;
86 }.overloadSetter();
87
88 // From
89
90 var slice = Array.prototype.slice;
91
92 Function.from = function(item){
93 return (typeOf(item) == 'function') ? item : function(){
94 return item;
95 };
96 };
97
98 Array.from = function(item){
99 if (item == null) return [];
100 return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item];
101 };
102
103 Number.from = function(item){
104 var number = parseFloat(item);
105 return isFinite(number) ? number : null;
106 };
107
108 String.from = function(item){
109 return item + '';
110 };
111
112 // hide, protect
113
114 Function.implement({
115
116 hide: function(){
117 this.$hidden = true;
118 return this;
119 },
120
121 protect: function(){
122 this.$protected = true;
123 return this;
124 }
125
126 });
127
128 // Type
129
130 var Type = this.Type = function(name, object){
131 if (name){
132 var lower = name.toLowerCase();
133 var typeCheck = function(item){
134 return (typeOf(item) == lower);
135 };
136
137 Type['is' + name] = typeCheck;
138 if (object != null){
139 object.prototype.$family = (function(){
140 return lower;
141 }).hide();
142
143 }
144 }
145
146 if (object == null) return null;
147
148 object.extend(this);
149 object.$constructor = Type;
150 object.prototype.$constructor = object;
151
152 return object;
153 };
154
155 var toString = Object.prototype.toString;
156
157 Type.isEnumerable = function(item){
158 return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' );
159 };
160
161 var hooks = {};
162
163 var hooksOf = function(object){
164 var type = typeOf(object.prototype);
165 return hooks[type] || (hooks[type] = []);
166 };
167
168 var implement = function(name, method){
169 if (method && method.$hidden) return;
170
171 var hooks = hooksOf(this);
172
173 for (var i = 0; i < hooks.length; i++){
174 var hook = hooks[i];
175 if (typeOf(hook) == 'type') implement.call(hook, name, method);
176 else hook.call(this, name, method);
177 }
178
179 var previous = this.prototype[name];
180 if (previous == null || !previous.$protected) this.prototype[name] = method;
181
182 if (this[name] == null && typeOf(method) == 'function') extend.call(this, name , function(item){
183 return method.apply(item, slice.call(arguments, 1));
184 });
185 };
186
187 var extend = function(name, method){
188 if (method && method.$hidden) return;
189 var previous = this[name];
190 if (previous == null || !previous.$protected) this[name] = method;
191 };
192
193 Type.implement({
194
195 implement: implement.overloadSetter(),
196
197 extend: extend.overloadSetter(),
198
199 alias: function(name, existing){
200 implement.call(this, name, this.prototype[existing]);
201 }.overloadSetter(),
202
203 mirror: function(hook){
204 hooksOf(this).push(hook);
205 return this;
206 }
207
208 });
209
210 new Type('Type', Type);
211
212 // Default Types
213
214 var force = function(name, object, methods){
215 var isType = (object != Object),
216 prototype = object.prototype;
217
218 if (isType) object = new Type(name, object);
219
220 for (var i = 0, l = methods.length; i < l; i++){
221 var key = methods[i],
222 generic = object[key],
223 proto = prototype[key];
224
225 if (generic) generic.protect();
226 if (isType && proto) object.implement(key, proto.protect());
227 }
228
229 if (isType){
230 var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]);
231 object.forEachMethod = function(fn){
232 if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){
233 fn.call(prototype, prototype[methods[i]], methods[i]);
234 }
235 for (var key in prototype) fn.call(prototype, prototype[key], key)
236 };
237 }
238
239 return force;
240 };
241
242 force('String', String, [
243 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search',
244 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase'
245 ])('Array', Array, [
246 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'joi n', 'slice',
247 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce ', 'reduceRight'
248 ])('Number', Number, [
249 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
250 ])('Function', Function, [
251 'apply', 'call', 'bind'
252 ])('RegExp', RegExp, [
253 'exec', 'test'
254 ])('Object', Object, [
255 'create', 'defineProperty', 'defineProperties', 'keys',
256 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
257 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen'
258 ])('Date', Date, ['now']);
259
260 Object.extend = extend.overloadSetter();
261
262 Date.extend('now', function(){
263 return +(new Date);
264 });
265
266 new Type('Boolean', Boolean);
267
268 // fixes NaN returning as Number
269
270 Number.prototype.$family = function(){
271 return isFinite(this) ? 'number' : 'null';
272 }.hide();
273
274 // Number.random
275
276 Number.extend('random', function(min, max){
277 return Math.floor(Math.random() * (max - min + 1) + min);
278 });
279
280 // forEach, each
281
282 var hasOwnProperty = Object.prototype.hasOwnProperty;
283 Object.extend('forEach', function(object, fn, bind){
284 for (var key in object){
285 if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object );
286 }
287 });
288
289 Object.each = Object.forEach;
290
291 Array.implement({
292
293 forEach: function(fn, bind){
294 for (var i = 0, l = this.length; i < l; i++){
295 if (i in this) fn.call(bind, this[i], i, this);
296 }
297 },
298
299 each: function(fn, bind){
300 Array.forEach(this, fn, bind);
301 return this;
302 }
303
304 });
305
306 // Array & Object cloning, Object merging and appending
307
308 var cloneOf = function(item){
309 switch (typeOf(item)){
310 case 'array': return item.clone();
311 case 'object': return Object.clone(item);
312 default: return item;
313 }
314 };
315
316 Array.implement('clone', function(){
317 var i = this.length, clone = new Array(i);
318 while (i--) clone[i] = cloneOf(this[i]);
319 return clone;
320 });
321
322 var mergeOne = function(source, key, current){
323 switch (typeOf(current)){
324 case 'object':
325 if (typeOf(source[key]) == 'object') Object.merge(source[key], current);
326 else source[key] = Object.clone(current);
327 break;
328 case 'array': source[key] = current.clone(); break;
329 default: source[key] = current;
330 }
331 return source;
332 };
333
334 Object.extend({
335
336 merge: function(source, k, v){
337 if (typeOf(k) == 'string') return mergeOne(source, k, v);
338 for (var i = 1, l = arguments.length; i < l; i++){
339 var object = arguments[i];
340 for (var key in object) mergeOne(source, key, object[key]);
341 }
342 return source;
343 },
344
345 clone: function(object){
346 var clone = {};
347 for (var key in object) clone[key] = cloneOf(object[key]);
348 return clone;
349 },
350
351 append: function(original){
352 for (var i = 1, l = arguments.length; i < l; i++){
353 var extended = arguments[i] || {};
354 for (var key in extended) original[key] = extended[key];
355 }
356 return original;
357 }
358
359 });
360
361 // Object-less types
362
363 ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(na me){
364 new Type(name);
365 });
366
367 // Unique ID
368
369 var UID = Date.now();
370
371 String.extend('uniqueID', function(){
372 return (UID++).toString(36);
373 });
374
375
376
377 })();
378
379
380 /*
381 ---
382
383 name: Array
384
385 description: Contains Array Prototypes like each, contains, and erase.
386
387 license: MIT-style license.
388
389 requires: Type
390
391 provides: Array
392
393 ...
394 */
395
396 Array.implement({
397
398 /*<!ES5>*/
399 every: function(fn, bind){
400 for (var i = 0, l = this.length >>> 0; i < l; i++){
401 if ((i in this) && !fn.call(bind, this[i], i, this)) return false;
402 }
403 return true;
404 },
405
406 filter: function(fn, bind){
407 var results = [];
408 for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){
409 value = this[i];
410 if (fn.call(bind, value, i, this)) results.push(value);
411 }
412 return results;
413 },
414
415 indexOf: function(item, from){
416 var length = this.length >>> 0;
417 for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length ; i++){
418 if (this[i] === item) return i;
419 }
420 return -1;
421 },
422
423 map: function(fn, bind){
424 var length = this.length >>> 0, results = Array(length);
425 for (var i = 0; i < length; i++){
426 if (i in this) results[i] = fn.call(bind, this[i], i, this);
427 }
428 return results;
429 },
430
431 some: function(fn, bind){
432 for (var i = 0, l = this.length >>> 0; i < l; i++){
433 if ((i in this) && fn.call(bind, this[i], i, this)) return true;
434 }
435 return false;
436 },
437 /*</!ES5>*/
438
439 clean: function(){
440 return this.filter(function(item){
441 return item != null;
442 });
443 },
444
445 invoke: function(methodName){
446 var args = Array.slice(arguments, 1);
447 return this.map(function(item){
448 return item[methodName].apply(item, args);
449 });
450 },
451
452 associate: function(keys){
453 var obj = {}, length = Math.min(this.length, keys.length);
454 for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
455 return obj;
456 },
457
458 link: function(object){
459 var result = {};
460 for (var i = 0, l = this.length; i < l; i++){
461 for (var key in object){
462 if (object[key](this[i])){
463 result[key] = this[i];
464 delete object[key];
465 break;
466 }
467 }
468 }
469 return result;
470 },
471
472 contains: function(item, from){
473 return this.indexOf(item, from) != -1;
474 },
475
476 append: function(array){
477 this.push.apply(this, array);
478 return this;
479 },
480
481 getLast: function(){
482 return (this.length) ? this[this.length - 1] : null;
483 },
484
485 getRandom: function(){
486 return (this.length) ? this[Number.random(0, this.length - 1)] : null;
487 },
488
489 include: function(item){
490 if (!this.contains(item)) this.push(item);
491 return this;
492 },
493
494 combine: function(array){
495 for (var i = 0, l = array.length; i < l; i++) this.include(array[i]);
496 return this;
497 },
498
499 erase: function(item){
500 for (var i = this.length; i--;){
501 if (this[i] === item) this.splice(i, 1);
502 }
503 return this;
504 },
505
506 empty: function(){
507 this.length = 0;
508 return this;
509 },
510
511 flatten: function(){
512 var array = [];
513 for (var i = 0, l = this.length; i < l; i++){
514 var type = typeOf(this[i]);
515 if (type == 'null') continue;
516 array = array.concat((type == 'array' || type == 'collection' || type == ' arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]);
517 }
518 return array;
519 },
520
521 pick: function(){
522 for (var i = 0, l = this.length; i < l; i++){
523 if (this[i] != null) return this[i];
524 }
525 return null;
526 },
527
528 hexToRgb: function(array){
529 if (this.length != 3) return null;
530 var rgb = this.map(function(value){
531 if (value.length == 1) value += value;
532 return value.toInt(16);
533 });
534 return (array) ? rgb : 'rgb(' + rgb + ')';
535 },
536
537 rgbToHex: function(array){
538 if (this.length < 3) return null;
539 if (this.length == 4 && this[3] == 0 && !array) return 'transparent';
540 var hex = [];
541 for (var i = 0; i < 3; i++){
542 var bit = (this[i] - 0).toString(16);
543 hex.push((bit.length == 1) ? '0' + bit : bit);
544 }
545 return (array) ? hex : '#' + hex.join('');
546 }
547
548 });
549
550
551
552
553 /*
554 ---
555
556 name: Function
557
558 description: Contains Function Prototypes like create, bind, pass, and delay.
559
560 license: MIT-style license.
561
562 requires: Type
563
564 provides: Function
565
566 ...
567 */
568
569 Function.extend({
570
571 attempt: function(){
572 for (var i = 0, l = arguments.length; i < l; i++){
573 try {
574 return arguments[i]();
575 } catch (e){}
576 }
577 return null;
578 }
579
580 });
581
582 Function.implement({
583
584 attempt: function(args, bind){
585 try {
586 return this.apply(bind, Array.from(args));
587 } catch (e){}
588
589 return null;
590 },
591
592 /*<!ES5-bind>*/
593 bind: function(that){
594 var self = this,
595 args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
596 F = function(){};
597
598 var bound = function(){
599 var context = that, length = arguments.length;
600 if (this instanceof bound){
601 F.prototype = self.prototype;
602 context = new F;
603 }
604 var result = (!args && !length)
605 ? self.call(context)
606 : self.apply(context, args && length ? args.concat(Array.slice(arguments )) : args || arguments);
607 return context == that ? result : context;
608 };
609 return bound;
610 },
611 /*</!ES5-bind>*/
612
613 pass: function(args, bind){
614 var self = this;
615 if (args != null) args = Array.from(args);
616 return function(){
617 return self.apply(bind, args || arguments);
618 };
619 },
620
621 delay: function(delay, bind, args){
622 return setTimeout(this.pass((args == null ? [] : args), bind), delay);
623 },
624
625 periodical: function(periodical, bind, args){
626 return setInterval(this.pass((args == null ? [] : args), bind), periodical);
627 }
628
629 });
630
631
632
633
634 /*
635 ---
636
637 name: Number
638
639 description: Contains Number Prototypes like limit, round, times, and ceil.
640
641 license: MIT-style license.
642
643 requires: Type
644
645 provides: Number
646
647 ...
648 */
649
650 Number.implement({
651
652 limit: function(min, max){
653 return Math.min(max, Math.max(min, this));
654 },
655
656 round: function(precision){
657 precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
658 return Math.round(this * precision) / precision;
659 },
660
661 times: function(fn, bind){
662 for (var i = 0; i < this; i++) fn.call(bind, i, this);
663 },
664
665 toFloat: function(){
666 return parseFloat(this);
667 },
668
669 toInt: function(base){
670 return parseInt(this, base || 10);
671 }
672
673 });
674
675 Number.alias('each', 'times');
676
677 (function(math){
678 var methods = {};
679 math.each(function(name){
680 if (!Number[name]) methods[name] = function(){
681 return Math[name].apply(null, [this].concat(Array.from(arguments)));
682 };
683 });
684 Number.implement(methods);
685 })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log' , 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
686
687
688 /*
689 ---
690
691 name: String
692
693 description: Contains String Prototypes like camelCase, capitalize, test, and to Int.
694
695 license: MIT-style license.
696
697 requires: Type
698
699 provides: String
700
701 ...
702 */
703
704 String.implement({
705
706 test: function(regex, params){
707 return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params) ).test(this);
708 },
709
710 contains: function(string, separator){
711 return (separator) ? (separator + this + separator).indexOf(separator + stri ng + separator) > -1 : String(this).indexOf(string) > -1;
712 },
713
714 trim: function(){
715 return String(this).replace(/^\s+|\s+$/g, '');
716 },
717
718 clean: function(){
719 return String(this).replace(/\s+/g, ' ').trim();
720 },
721
722 camelCase: function(){
723 return String(this).replace(/-\D/g, function(match){
724 return match.charAt(1).toUpperCase();
725 });
726 },
727
728 hyphenate: function(){
729 return String(this).replace(/[A-Z]/g, function(match){
730 return ('-' + match.charAt(0).toLowerCase());
731 });
732 },
733
734 capitalize: function(){
735 return String(this).replace(/\b[a-z]/g, function(match){
736 return match.toUpperCase();
737 });
738 },
739
740 escapeRegExp: function(){
741 return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
742 },
743
744 toInt: function(base){
745 return parseInt(this, base || 10);
746 },
747
748 toFloat: function(){
749 return parseFloat(this);
750 },
751
752 hexToRgb: function(array){
753 var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
754 return (hex) ? hex.slice(1).hexToRgb(array) : null;
755 },
756
757 rgbToHex: function(array){
758 var rgb = String(this).match(/\d{1,3}/g);
759 return (rgb) ? rgb.rgbToHex(array) : null;
760 },
761
762 substitute: function(object, regexp){
763 return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){
764 if (match.charAt(0) == '\\') return match.slice(1);
765 return (object[name] != null) ? object[name] : '';
766 });
767 }
768
769 });
770
771
772 /*
773 ---
774
775 name: Browser
776
777 description: The Browser Object. Contains Browser initialization, Window and Doc ument, and the Browser Hash.
778
779 license: MIT-style license.
780
781 requires: [Array, Function, Number, String]
782
783 provides: [Browser, Window, Document]
784
785 ...
786 */
787
788 (function(){
789
790 var document = this.document;
791 var window = document.window = this;
792
793 var ua = navigator.userAgent.toLowerCase(),
794 platform = navigator.platform.toLowerCase(),
795 UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari| version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0],
796 mode = UA[1] == 'ie' && document.documentMode;
797
798 var Browser = this.Browser = {
799
800 extend: Function.prototype.extend,
801
802 name: (UA[1] == 'version') ? UA[3] : UA[1],
803
804 version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]),
805
806 Platform: {
807 name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0]
808 },
809
810 Features: {
811 xpath: !!(document.evaluate),
812 air: !!(window.runtime),
813 query: !!(document.querySelector),
814 json: !!(window.JSON)
815 },
816
817 Plugins: {}
818
819 };
820
821 Browser[Browser.name] = true;
822 Browser[Browser.name + parseInt(Browser.version, 10)] = true;
823 Browser.Platform[Browser.Platform.name] = true;
824
825 // Request
826
827 Browser.Request = (function(){
828
829 var XMLHTTP = function(){
830 return new XMLHttpRequest();
831 };
832
833 var MSXML2 = function(){
834 return new ActiveXObject('MSXML2.XMLHTTP');
835 };
836
837 var MSXML = function(){
838 return new ActiveXObject('Microsoft.XMLHTTP');
839 };
840
841 return Function.attempt(function(){
842 XMLHTTP();
843 return XMLHTTP;
844 }, function(){
845 MSXML2();
846 return MSXML2;
847 }, function(){
848 MSXML();
849 return MSXML;
850 });
851
852 })();
853
854 Browser.Features.xhr = !!(Browser.Request);
855
856 // Flash detection
857
858 var version = (Function.attempt(function(){
859 return navigator.plugins['Shockwave Flash'].description;
860 }, function(){
861 return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$versio n');
862 }) || '0 r0').match(/\d+/g);
863
864 Browser.Plugins.Flash = {
865 version: Number(version[0] || '0.' + version[1]) || 0,
866 build: Number(version[2]) || 0
867 };
868
869 // String scripts
870
871 Browser.exec = function(text){
872 if (!text) return text;
873 if (window.execScript){
874 window.execScript(text);
875 } else {
876 var script = document.createElement('script');
877 script.setAttribute('type', 'text/javascript');
878 script.text = text;
879 document.head.appendChild(script);
880 document.head.removeChild(script);
881 }
882 return text;
883 };
884
885 String.implement('stripScripts', function(exec){
886 var scripts = '';
887 var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, c ode){
888 scripts += code + '\n';
889 return '';
890 });
891 if (exec === true) Browser.exec(scripts);
892 else if (typeOf(exec) == 'function') exec(scripts, text);
893 return text;
894 });
895
896 // Window, Document
897
898 Browser.extend({
899 Document: this.Document,
900 Window: this.Window,
901 Element: this.Element,
902 Event: this.Event
903 });
904
905 this.Window = this.$constructor = new Type('Window', function(){});
906
907 this.$family = Function.from('window').hide();
908
909 Window.mirror(function(name, method){
910 window[name] = method;
911 });
912
913 this.Document = document.$constructor = new Type('Document', function(){});
914
915 document.$family = Function.from('document').hide();
916
917 Document.mirror(function(name, method){
918 document[name] = method;
919 });
920
921 document.html = document.documentElement;
922 if (!document.head) document.head = document.getElementsByTagName('head')[0];
923
924 if (document.execCommand) try {
925 document.execCommand("BackgroundImageCache", false, true);
926 } catch (e){}
927
928 /*<ltIE9>*/
929 if (this.attachEvent && !this.addEventListener){
930 var unloadEvent = function(){
931 this.detachEvent('onunload', unloadEvent);
932 document.head = document.html = document.window = null;
933 };
934 this.attachEvent('onunload', unloadEvent);
935 }
936
937 // IE fails on collections and <select>.options (refers to <select>)
938 var arrayFrom = Array.from;
939 try {
940 arrayFrom(document.html.childNodes);
941 } catch(e){
942 Array.from = function(item){
943 if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'a rray'){
944 var i = item.length, array = new Array(i);
945 while (i--) array[i] = item[i];
946 return array;
947 }
948 return arrayFrom(item);
949 };
950
951 var prototype = Array.prototype,
952 slice = prototype.slice;
953 ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'jo in', 'slice'].each(function(name){
954 var method = prototype[name];
955 Array[name] = function(item){
956 return method.apply(Array.from(item), slice.call(arguments, 1));
957 };
958 });
959 }
960 /*</ltIE9>*/
961
962
963
964 })();
965
966
967 /*
968 ---
969
970 name: Object
971
972 description: Object generic methods
973
974 license: MIT-style license.
975
976 requires: Type
977
978 provides: [Object, Hash]
979
980 ...
981 */
982
983 (function(){
984
985 var hasOwnProperty = Object.prototype.hasOwnProperty;
986
987 Object.extend({
988
989 subset: function(object, keys){
990 var results = {};
991 for (var i = 0, l = keys.length; i < l; i++){
992 var k = keys[i];
993 if (k in object) results[k] = object[k];
994 }
995 return results;
996 },
997
998 map: function(object, fn, bind){
999 var results = {};
1000 for (var key in object){
1001 if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[ key], key, object);
1002 }
1003 return results;
1004 },
1005
1006 filter: function(object, fn, bind){
1007 var results = {};
1008 for (var key in object){
1009 var value = object[key];
1010 if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value;
1011 }
1012 return results;
1013 },
1014
1015 every: function(object, fn, bind){
1016 for (var key in object){
1017 if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false;
1018 }
1019 return true;
1020 },
1021
1022 some: function(object, fn, bind){
1023 for (var key in object){
1024 if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) r eturn true;
1025 }
1026 return false;
1027 },
1028
1029 keys: function(object){
1030 var keys = [];
1031 for (var key in object){
1032 if (hasOwnProperty.call(object, key)) keys.push(key);
1033 }
1034 return keys;
1035 },
1036
1037 values: function(object){
1038 var values = [];
1039 for (var key in object){
1040 if (hasOwnProperty.call(object, key)) values.push(object[key]);
1041 }
1042 return values;
1043 },
1044
1045 getLength: function(object){
1046 return Object.keys(object).length;
1047 },
1048
1049 keyOf: function(object, value){
1050 for (var key in object){
1051 if (hasOwnProperty.call(object, key) && object[key] === value) return key;
1052 }
1053 return null;
1054 },
1055
1056 contains: function(object, value){
1057 return Object.keyOf(object, value) != null;
1058 },
1059
1060 toQueryString: function(object, base){
1061 var queryString = [];
1062
1063 Object.each(object, function(value, key){
1064 if (base) key = base + '[' + key + ']';
1065 var result;
1066 switch (typeOf(value)){
1067 case 'object': result = Object.toQueryString(value, key); break;
1068 case 'array':
1069 var qs = {};
1070 value.each(function(val, i){
1071 qs[i] = val;
1072 });
1073 result = Object.toQueryString(qs, key);
1074 break;
1075 default: result = key + '=' + encodeURIComponent(value);
1076 }
1077 if (value != null) queryString.push(result);
1078 });
1079
1080 return queryString.join('&');
1081 }
1082
1083 });
1084
1085 })();
1086
1087
1088
1089
1090 /*
1091 ---
1092
1093 name: Event
1094
1095 description: Contains the Event Type, to make the event object cross-browser.
1096
1097 license: MIT-style license.
1098
1099 requires: [Window, Document, Array, Function, String, Object]
1100
1101 provides: Event
1102
1103 ...
1104 */
1105
1106 (function() {
1107
1108 var _keys = {};
1109
1110 var DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){
1111 if (!win) win = window;
1112 event = event || win.event;
1113 if (event.$extended) return event;
1114 this.event = event;
1115 this.$extended = true;
1116 this.shift = event.shiftKey;
1117 this.control = event.ctrlKey;
1118 this.alt = event.altKey;
1119 this.meta = event.metaKey;
1120 var type = this.type = event.type;
1121 var target = event.target || event.srcElement;
1122 while (target && target.nodeType == 3) target = target.parentNode;
1123 this.target = document.id(target);
1124
1125 if (type.indexOf('key') == 0){
1126 var code = this.code = (event.which || event.keyCode);
1127 this.key = _keys[code];
1128 if (type == 'keydown'){
1129 if (code > 111 && code < 124) this.key = 'f' + (code - 111);
1130 else if (code > 95 && code < 106) this.key = code - 96;
1131 }
1132 if (this.key == null) this.key = String.fromCharCode(code).toLowerCase();
1133 } else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || t ype == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
1134 var doc = win.document;
1135 doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.b ody;
1136 this.page = {
1137 x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
1138 y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
1139 };
1140 this.client = {
1141 x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
1142 y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
1143 };
1144 if (type == 'DOMMouseScroll' || type == 'mousewheel')
1145 this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
1146
1147 this.rightClick = (event.which == 3 || event.button == 2);
1148 if (type == 'mouseover' || type == 'mouseout'){
1149 var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element'];
1150 while (related && related.nodeType == 3) related = related.parentNode;
1151 this.relatedTarget = document.id(related);
1152 }
1153 } else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
1154 this.rotation = event.rotation;
1155 this.scale = event.scale;
1156 this.targetTouches = event.targetTouches;
1157 this.changedTouches = event.changedTouches;
1158 var touches = this.touches = event.touches;
1159 if (touches && touches[0]){
1160 var touch = touches[0];
1161 this.page = {x: touch.pageX, y: touch.pageY};
1162 this.client = {x: touch.clientX, y: touch.clientY};
1163 }
1164 }
1165
1166 if (!this.client) this.client = {};
1167 if (!this.page) this.page = {};
1168 });
1169
1170 DOMEvent.implement({
1171
1172 stop: function(){
1173 return this.preventDefault().stopPropagation();
1174 },
1175
1176 stopPropagation: function(){
1177 if (this.event.stopPropagation) this.event.stopPropagation();
1178 else this.event.cancelBubble = true;
1179 return this;
1180 },
1181
1182 preventDefault: function(){
1183 if (this.event.preventDefault) this.event.preventDefault();
1184 else this.event.returnValue = false;
1185 return this;
1186 }
1187
1188 });
1189
1190 DOMEvent.defineKey = function(code, key){
1191 _keys[code] = key;
1192 return this;
1193 };
1194
1195 DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);
1196
1197 DOMEvent.defineKeys({
1198 '38': 'up', '40': 'down', '37': 'left', '39': 'right',
1199 '27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
1200 '46': 'delete', '13': 'enter'
1201 });
1202
1203 })();
1204
1205
1206
1207
1208
1209
1210 /*
1211 ---
1212 name: Slick.Parser
1213 description: Standalone CSS3 Selector parser
1214 provides: Slick.Parser
1215 ...
1216 */
1217
1218 ;(function(){
1219
1220 var parsed,
1221 separatorIndex,
1222 combinatorIndex,
1223 reversed,
1224 cache = {},
1225 reverseCache = {},
1226 reUnescape = /\\/g;
1227
1228 var parse = function(expression, isReversed){
1229 if (expression == null) return null;
1230 if (expression.Slick === true) return expression;
1231 expression = ('' + expression).replace(/^\s+|\s+$/g, '');
1232 reversed = !!isReversed;
1233 var currentCache = (reversed) ? reverseCache : cache;
1234 if (currentCache[expression]) return currentCache[expression];
1235 parsed = {
1236 Slick: true,
1237 expressions: [],
1238 raw: expression,
1239 reverse: function(){
1240 return parse(this.raw, true);
1241 }
1242 };
1243 separatorIndex = -1;
1244 while (expression != (expression = expression.replace(regexp, parser)));
1245 parsed.length = parsed.expressions.length;
1246 return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
1247 };
1248
1249 var reverseCombinator = function(combinator){
1250 if (combinator === '!') return ' ';
1251 else if (combinator === ' ') return '!';
1252 else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
1253 else return '!' + combinator;
1254 };
1255
1256 var reverse = function(expression){
1257 var expressions = expression.expressions;
1258 for (var i = 0; i < expressions.length; i++){
1259 var exp = expressions[i];
1260 var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combin ator)};
1261
1262 for (var j = 0; j < exp.length; j++){
1263 var cexp = exp[j];
1264 if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
1265 cexp.combinator = cexp.reverseCombinator;
1266 delete cexp.reverseCombinator;
1267 }
1268
1269 exp.reverse().push(last);
1270 }
1271 return expression;
1272 };
1273
1274 var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steve n Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
1275 return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
1276 return '\\' + match;
1277 });
1278 };
1279
1280 var regexp = new RegExp(
1281 /*
1282 #!/usr/bin/env ruby
1283 puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
1284 __END__
1285 "(?x)^(?:\
1286 \\s* ( , ) \\s* # Separator \n\
1287 | \\s* ( <combinator>+ ) \\s* # Combinator \n\
1288 | ( \\s+ ) # CombinatorChildren \n\
1289 | ( <unicode>+ | \\* ) # Tag \n\
1290 | \\# ( <unicode>+ ) # ID \n\
1291 | \\. ( <unicode>+ ) # ClassName \n\
1292 | # Attribute \n\
1293 \\[ \
1294 \\s* (<unicode1>+) (?: \
1295 \\s* ([*^$!~|]?=) (?: \
1296 \\s* (?:\
1297 ([\"']?)(.*?)\\9 \
1298 )\
1299 ) \
1300 )? \\s* \
1301 \\](?!\\]) \n\
1302 | :+ ( <unicode>+ )(?:\
1303 \\( (?:\
1304 (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
1305 ) \\)\
1306 )?\
1307 )"
1308 */
1309 "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode> +)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*? )\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\ ([^)]+\\)|[^()]*)+))\\))?)"
1310 .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
1311 .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
1312 .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
1313 );
1314
1315 function parser(
1316 rawMatch,
1317
1318 separator,
1319 combinator,
1320 combinatorChildren,
1321
1322 tagName,
1323 id,
1324 className,
1325
1326 attributeKey,
1327 attributeOperator,
1328 attributeQuote,
1329 attributeValue,
1330
1331 pseudoMarker,
1332 pseudoClass,
1333 pseudoQuote,
1334 pseudoClassQuotedValue,
1335 pseudoClassValue
1336 ){
1337 if (separator || separatorIndex === -1){
1338 parsed.expressions[++separatorIndex] = [];
1339 combinatorIndex = -1;
1340 if (separator) return '';
1341 }
1342
1343 if (combinator || combinatorChildren || combinatorIndex === -1){
1344 combinator = combinator || ' ';
1345 var currentSeparator = parsed.expressions[separatorIndex];
1346 if (reversed && currentSeparator[combinatorIndex])
1347 currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(co mbinator);
1348 currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'};
1349 }
1350
1351 var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
1352
1353 if (tagName){
1354 currentParsed.tag = tagName.replace(reUnescape, '');
1355
1356 } else if (id){
1357 currentParsed.id = id.replace(reUnescape, '');
1358
1359 } else if (className){
1360 className = className.replace(reUnescape, '');
1361
1362 if (!currentParsed.classList) currentParsed.classList = [];
1363 if (!currentParsed.classes) currentParsed.classes = [];
1364 currentParsed.classList.push(className);
1365 currentParsed.classes.push({
1366 value: className,
1367 regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
1368 });
1369
1370 } else if (pseudoClass){
1371 pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
1372 pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, ' ') : null;
1373
1374 if (!currentParsed.pseudos) currentParsed.pseudos = [];
1375 currentParsed.pseudos.push({
1376 key: pseudoClass.replace(reUnescape, ''),
1377 value: pseudoClassValue,
1378 type: pseudoMarker.length == 1 ? 'class' : 'element'
1379 });
1380
1381 } else if (attributeKey){
1382 attributeKey = attributeKey.replace(reUnescape, '');
1383 attributeValue = (attributeValue || '').replace(reUnescape, '');
1384
1385 var test, regexp;
1386
1387 switch (attributeOperator){
1388 case '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break;
1389 case '$=' : regexp = new RegExp( escapeRegExp(attributeValue) + '$' ); break;
1390 case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) + '(\\s|$)' ); break;
1391 case '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) + '(-|$)' ); break;
1392 case '=' : test = function(value){
1393 return attributeValue == value;
1394 }; break;
1395 case '*=' : test = function(value){
1396 return value && value.indexOf(attributeValue) > -1;
1397 }; break;
1398 case '!=' : test = function(value){
1399 return attributeValue != value;
1400 }; break;
1401 default : test = function(value){
1402 return !!value;
1403 };
1404 }
1405
1406 if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = fun ction(){
1407 return false;
1408 };
1409
1410 if (!test) test = function(value){
1411 return value && regexp.test(value);
1412 };
1413
1414 if (!currentParsed.attributes) currentParsed.attributes = [];
1415 currentParsed.attributes.push({
1416 key: attributeKey,
1417 operator: attributeOperator,
1418 value: attributeValue,
1419 test: test
1420 });
1421
1422 }
1423
1424 return '';
1425 };
1426
1427 // Slick NS
1428
1429 var Slick = (this.Slick || {});
1430
1431 Slick.parse = function(expression){
1432 return parse(expression);
1433 };
1434
1435 Slick.escapeRegExp = escapeRegExp;
1436
1437 if (!this.Slick) this.Slick = Slick;
1438
1439 }).apply(window);
1440
1441
1442 /*
1443 ---
1444 name: Slick.Finder
1445 description: The new, superfast css selector engine.
1446 provides: Slick.Finder
1447 requires: Slick.Parser
1448 ...
1449 */
1450
1451 ;(function(){
1452
1453 var local = {},
1454 featuresCache = {},
1455 toString = Object.prototype.toString;
1456
1457 // Feature / Bug detection
1458
1459 local.isNativeCode = function(fn){
1460 return (/\{\s*\[native code\]\s*\}/).test('' + fn);
1461 };
1462
1463 local.isXML = function(document){
1464 return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') ||
1465 (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
1466 };
1467
1468 local.setDocument = function(document){
1469
1470 // convert elements / window arguments to document. if document cannot be extr apolated, the function returns.
1471 var nodeType = document.nodeType;
1472 if (nodeType == 9); // document
1473 else if (nodeType) document = document.ownerDocument; // node
1474 else if (document.navigator) document = document.document; // window
1475 else return;
1476
1477 // check if it's the old document
1478
1479 if (this.document === document) return;
1480 this.document = document;
1481
1482 // check if we have done feature detection on this document before
1483
1484 var root = document.documentElement,
1485 rootUid = this.getUIDXML(root),
1486 features = featuresCache[rootUid],
1487 feature;
1488
1489 if (features){
1490 for (feature in features){
1491 this[feature] = features[feature];
1492 }
1493 return;
1494 }
1495
1496 features = featuresCache[rootUid] = {};
1497
1498 features.root = root;
1499 features.isXMLDocument = this.isXML(document);
1500
1501 features.brokenStarGEBTN
1502 = features.starSelectsClosedQSA
1503 = features.idGetsName
1504 = features.brokenMixedCaseQSA
1505 = features.brokenGEBCN
1506 = features.brokenCheckedQSA
1507 = features.brokenEmptyAttributeQSA
1508 = features.isHTMLDocument
1509 = features.nativeMatchesSelector
1510 = false;
1511
1512 var starSelectsClosed, starSelectsComments,
1513 brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
1514 brokenFormAttributeGetter;
1515
1516 var selected, id = 'slick_uniqueid';
1517 var testNode = document.createElement('div');
1518
1519 var testRoot = document.body || document.getElementsByTagName('body')[0] || ro ot;
1520 testRoot.appendChild(testNode);
1521
1522 // on non-HTML documents innerHTML and getElementsById doesnt work properly
1523 try {
1524 testNode.innerHTML = '<a id="'+id+'"></a>';
1525 features.isHTMLDocument = !!document.getElementById(id);
1526 } catch(e){};
1527
1528 if (features.isHTMLDocument){
1529
1530 testNode.style.display = 'none';
1531
1532 // IE returns comment nodes for getElementsByTagName('*') for some documents
1533 testNode.appendChild(document.createComment(''));
1534 starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
1535
1536 // IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for s ome documents
1537 try {
1538 testNode.innerHTML = 'foo</foo>';
1539 selected = testNode.getElementsByTagName('*');
1540 starSelectsClosed = (selected && !!selected.length && selected[0].nodeName .charAt(0) == '/');
1541 } catch(e){};
1542
1543 features.brokenStarGEBTN = starSelectsComments || starSelectsClosed;
1544
1545 // IE returns elements with the name instead of just id for getElementsById for some documents
1546 try {
1547 testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>';
1548 features.idGetsName = document.getElementById(id) === testNode.firstChild;
1549 } catch(e){};
1550
1551 if (testNode.getElementsByClassName){
1552
1553 // Safari 3.2 getElementsByClassName caches results
1554 try {
1555 testNode.innerHTML = '<a class="f"></a><a class="b"></a>';
1556 testNode.getElementsByClassName('b').length;
1557 testNode.firstChild.className = 'b';
1558 cachedGetElementsByClassName = (testNode.getElementsByClassName('b').len gth != 2);
1559 } catch(e){};
1560
1561 // Opera 9.6 getElementsByClassName doesnt detects the class if its not th e first one
1562 try {
1563 testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>';
1564 brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').lengt h != 2);
1565 } catch(e){};
1566
1567 features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNa meGEBCN;
1568 }
1569
1570 if (testNode.querySelectorAll){
1571 // IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for s ome documents
1572 try {
1573 testNode.innerHTML = 'foo</foo>';
1574 selected = testNode.querySelectorAll('*');
1575 features.starSelectsClosedQSA = (selected && !!selected.length && select ed[0].nodeName.charAt(0) == '/');
1576 } catch(e){};
1577
1578 // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode
1579 try {
1580 testNode.innerHTML = '<a class="MiX"></a>';
1581 features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length;
1582 } catch(e){};
1583
1584 // Webkit and Opera dont return selected options on querySelectorAll
1585 try {
1586 testNode.innerHTML = '<select><option selected="selected">a</option></se lect>';
1587 features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').lengt h == 0);
1588 } catch(e){};
1589
1590 // IE returns incorrect results for attr[*^$]="" selectors on querySelecto rAll
1591 try {
1592 testNode.innerHTML = '<a class=""></a>';
1593 features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=" "]').length != 0);
1594 } catch(e){};
1595
1596 }
1597
1598 // IE6-7, if a form has an input of id x, form.getAttribute(x) returns a ref erence to the input
1599 try {
1600 testNode.innerHTML = '<form action="s"><input id="action"/></form>';
1601 brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's');
1602 } catch(e){};
1603
1604 // native matchesSelector function
1605
1606 features.nativeMatchesSelector = root.matchesSelector || /*root.msMatchesSel ector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
1607 if (features.nativeMatchesSelector) try {
1608 // if matchesSelector trows errors on incorrect sintaxes we can use it
1609 features.nativeMatchesSelector.call(root, ':slick');
1610 features.nativeMatchesSelector = null;
1611 } catch(e){};
1612
1613 }
1614
1615 try {
1616 root.slick_expando = 1;
1617 delete root.slick_expando;
1618 features.getUID = this.getUIDHTML;
1619 } catch(e) {
1620 features.getUID = this.getUIDXML;
1621 }
1622
1623 testRoot.removeChild(testNode);
1624 testNode = selected = testRoot = null;
1625
1626 // getAttribute
1627
1628 features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){
1629 var method = this.attributeGetters[name];
1630 if (method) return method.call(node);
1631 var attributeNode = node.getAttributeNode(name);
1632 return (attributeNode) ? attributeNode.nodeValue : null;
1633 } : function(node, name){
1634 var method = this.attributeGetters[name];
1635 return (method) ? method.call(node) : node.getAttribute(name);
1636 };
1637
1638 // hasAttribute
1639
1640 features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? funct ion(node, attribute) {
1641 return node.hasAttribute(attribute);
1642 } : function(node, attribute) {
1643 node = node.getAttributeNode(attribute);
1644 return !!(node && (node.specified || node.nodeValue));
1645 };
1646
1647 // contains
1648 // FIXME: Add specs: local.contains should be different for xml and html docum ents?
1649 var nativeRootContains = root && this.isNativeCode(root.contains),
1650 nativeDocumentContains = document && this.isNativeCode(document.contains);
1651
1652 features.contains = (nativeRootContains && nativeDocumentContains) ? function( context, node){
1653 return context.contains(node);
1654 } : (nativeRootContains && !nativeDocumentContains) ? function(context, node){
1655 // IE8 does not have .contains on document.
1656 return context === node || ((context === document) ? document.documentElemen t : context).contains(node);
1657 } : (root && root.compareDocumentPosition) ? function(context, node){
1658 return context === node || !!(context.compareDocumentPosition(node) & 16);
1659 } : function(context, node){
1660 if (node) do {
1661 if (node === context) return true;
1662 } while ((node = node.parentNode));
1663 return false;
1664 };
1665
1666 // document order sorting
1667 // credits to Sizzle (http://sizzlejs.com/)
1668
1669 features.documentSorter = (root.compareDocumentPosition) ? function(a, b){
1670 if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0;
1671 return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
1672 } : ('sourceIndex' in root) ? function(a, b){
1673 if (!a.sourceIndex || !b.sourceIndex) return 0;
1674 return a.sourceIndex - b.sourceIndex;
1675 } : (document.createRange) ? function(a, b){
1676 if (!a.ownerDocument || !b.ownerDocument) return 0;
1677 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createR ange();
1678 aRange.setStart(a, 0);
1679 aRange.setEnd(a, 0);
1680 bRange.setStart(b, 0);
1681 bRange.setEnd(b, 0);
1682 return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
1683 } : null ;
1684
1685 root = null;
1686
1687 for (feature in features){
1688 this[feature] = features[feature];
1689 }
1690 };
1691
1692 // Main Method
1693
1694 var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/,
1695 reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
1696 qsaFailExpCache = {};
1697
1698 local.search = function(context, expression, append, first){
1699
1700 var found = this.found = (first) ? null : (append || []);
1701
1702 if (!context) return found;
1703 else if (context.navigator) context = context.document; // Convert the node fr om a window to a document
1704 else if (!context.nodeType) return found;
1705
1706 // setup
1707
1708 var parsed, i,
1709 uniques = this.uniques = {},
1710 hasOthers = !!(append && append.length),
1711 contextIsDocument = (context.nodeType == 9);
1712
1713 if (this.document !== (contextIsDocument ? context : context.ownerDocument)) t his.setDocument(context);
1714
1715 // avoid duplicating items already in the append array
1716 if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = t rue;
1717
1718 // expression checks
1719
1720 if (typeof expression == 'string'){ // expression is a string
1721
1722 /*<simple-selectors-override>*/
1723 var simpleSelector = expression.match(reSimpleSelector);
1724 simpleSelectors: if (simpleSelector) {
1725
1726 var symbol = simpleSelector[1],
1727 name = simpleSelector[2],
1728 node, nodes;
1729
1730 if (!symbol){
1731
1732 if (name == '*' && this.brokenStarGEBTN) break simpleSelectors;
1733 nodes = context.getElementsByTagName(name);
1734 if (first) return nodes[0] || null;
1735 for (i = 0; node = nodes[i++];){
1736 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
1737 }
1738
1739 } else if (symbol == '#'){
1740
1741 if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
1742 node = context.getElementById(name);
1743 if (!node) return found;
1744 if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) br eak simpleSelectors;
1745 if (first) return node || null;
1746 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
1747
1748 } else if (symbol == '.'){
1749
1750 if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.br okenGEBCN) && context.querySelectorAll)) break simpleSelectors;
1751 if (context.getElementsByClassName && !this.brokenGEBCN){
1752 nodes = context.getElementsByClassName(name);
1753 if (first) return nodes[0] || null;
1754 for (i = 0; node = nodes[i++];){
1755 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
1756 }
1757 } else {
1758 var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s |$)');
1759 nodes = context.getElementsByTagName('*');
1760 for (i = 0; node = nodes[i++];){
1761 className = node.className;
1762 if (!(className && matchClass.test(className))) continue;
1763 if (first) return node;
1764 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
1765 }
1766 }
1767
1768 }
1769
1770 if (hasOthers) this.sort(found);
1771 return (first) ? null : found;
1772
1773 }
1774 /*</simple-selectors-override>*/
1775
1776 /*<query-selector-override>*/
1777 querySelector: if (context.querySelectorAll) {
1778
1779 if (!this.isHTMLDocument
1780 || qsaFailExpCache[expression]
1781 //TODO: only skip when expression is actually mixed case
1782 || this.brokenMixedCaseQSA
1783 || (this.brokenCheckedQSA && expression.indexOf(':checked') > -1)
1784 || (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression))
1785 || (!contextIsDocument //Abort when !contextIsDocument and...
1786 // there are multiple expressions in the selector
1787 // since we currently only fix non-document rooted QSA for single exp ression selectors
1788 && expression.indexOf(',') > -1
1789 )
1790 || Slick.disableQSA
1791 ) break querySelector;
1792
1793 var _expression = expression, _context = context;
1794 if (!contextIsDocument){
1795 // non-document rooted QSA
1796 // credits to Andrew Dupont
1797 var currentId = _context.getAttribute('id'), slickid = 'slickid__';
1798 _context.setAttribute('id', slickid);
1799 _expression = '#' + slickid + ' ' + _expression;
1800 context = _context.parentNode;
1801 }
1802
1803 try {
1804 if (first) return context.querySelector(_expression) || null;
1805 else nodes = context.querySelectorAll(_expression);
1806 } catch(e) {
1807 qsaFailExpCache[expression] = 1;
1808 break querySelector;
1809 } finally {
1810 if (!contextIsDocument){
1811 if (currentId) _context.setAttribute('id', currentId);
1812 else _context.removeAttribute('id');
1813 context = _context;
1814 }
1815 }
1816
1817 if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){
1818 if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) f ound.push(node);
1819 } else for (i = 0; node = nodes[i++];){
1820 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
1821 }
1822
1823 if (hasOthers) this.sort(found);
1824 return found;
1825
1826 }
1827 /*</query-selector-override>*/
1828
1829 parsed = this.Slick.parse(expression);
1830 if (!parsed.length) return found;
1831 } else if (expression == null){ // there is no expression
1832 return found;
1833 } else if (expression.Slick){ // expression is a parsed Slick object
1834 parsed = expression;
1835 } else if (this.contains(context.documentElement || context, expression)){ // expression is a node
1836 (found) ? found.push(expression) : found = expression;
1837 return found;
1838 } else { // other junk
1839 return found;
1840 }
1841
1842 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
1843
1844 // cache elements for the nth selectors
1845
1846 this.posNTH = {};
1847 this.posNTHLast = {};
1848 this.posNTHType = {};
1849 this.posNTHTypeLast = {};
1850
1851 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
1852
1853 // if append is null and there is only a single selector with one expression u se pushArray, else use pushUID
1854 this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions [0].length == 1))) ? this.pushArray : this.pushUID;
1855
1856 if (found == null) found = [];
1857
1858 // default engine
1859
1860 var j, m, n;
1861 var combinator, tag, id, classList, classes, attributes, pseudos;
1862 var currentItems, currentExpression, currentBit, lastBit, expressions = parsed .expressions;
1863
1864 search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (cu rrentBit = currentExpression[j]); j++){
1865
1866 combinator = 'combinator:' + currentBit.combinator;
1867 if (!this[combinator]) continue search;
1868
1869 tag = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperC ase();
1870 id = currentBit.id;
1871 classList = currentBit.classList;
1872 classes = currentBit.classes;
1873 attributes = currentBit.attributes;
1874 pseudos = currentBit.pseudos;
1875 lastBit = (j === (currentExpression.length - 1));
1876
1877 this.bitUniques = {};
1878
1879 if (lastBit){
1880 this.uniques = uniques;
1881 this.found = found;
1882 } else {
1883 this.uniques = {};
1884 this.found = [];
1885 }
1886
1887 if (j === 0){
1888 this[combinator](context, tag, id, classes, attributes, pseudos, classList );
1889 if (first && lastBit && found.length) break search;
1890 } else {
1891 if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){
1892 this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList);
1893 if (found.length) break search;
1894 } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](c urrentItems[m], tag, id, classes, attributes, pseudos, classList);
1895 }
1896
1897 currentItems = this.found;
1898 }
1899
1900 // should sort if there are nodes in append and if you pass multiple expressio ns.
1901 if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
1902
1903 return (first) ? (found[0] || null) : found;
1904 };
1905
1906 // Utils
1907
1908 local.uidx = 1;
1909 local.uidk = 'slick-uniqueid';
1910
1911 local.getUIDXML = function(node){
1912 var uid = node.getAttribute(this.uidk);
1913 if (!uid){
1914 uid = this.uidx++;
1915 node.setAttribute(this.uidk, uid);
1916 }
1917 return uid;
1918 };
1919
1920 local.getUIDHTML = function(node){
1921 return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
1922 };
1923
1924 // sort based on the setDocument documentSorter method.
1925
1926 local.sort = function(results){
1927 if (!this.documentSorter) return results;
1928 results.sort(this.documentSorter);
1929 return results;
1930 };
1931
1932 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
1933
1934 local.cacheNTH = {};
1935
1936 local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
1937
1938 local.parseNTHArgument = function(argument){
1939 var parsed = argument.match(this.matchNTH);
1940 if (!parsed) return false;
1941 var special = parsed[2] || false;
1942 var a = parsed[1] || 1;
1943 if (a == '-') a = -1;
1944 var b = +parsed[3] || 0;
1945 parsed =
1946 (special == 'n') ? {a: a, b: b} :
1947 (special == 'odd') ? {a: 2, b: 1} :
1948 (special == 'even') ? {a: 2, b: 0} : {a: 0, b: a};
1949
1950 return (this.cacheNTH[argument] = parsed);
1951 };
1952
1953 local.createNTHPseudo = function(child, sibling, positions, ofType){
1954 return function(node, argument){
1955 var uid = this.getUID(node);
1956 if (!this[positions][uid]){
1957 var parent = node.parentNode;
1958 if (!parent) return false;
1959 var el = parent[child], count = 1;
1960 if (ofType){
1961 var nodeName = node.nodeName;
1962 do {
1963 if (el.nodeName != nodeName) continue;
1964 this[positions][this.getUID(el)] = count++;
1965 } while ((el = el[sibling]));
1966 } else {
1967 do {
1968 if (el.nodeType != 1) continue;
1969 this[positions][this.getUID(el)] = count++;
1970 } while ((el = el[sibling]));
1971 }
1972 }
1973 argument = argument || 'n';
1974 var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument);
1975 if (!parsed) return false;
1976 var a = parsed.a, b = parsed.b, pos = this[positions][uid];
1977 if (a == 0) return b == pos;
1978 if (a > 0){
1979 if (pos < b) return false;
1980 } else {
1981 if (b < pos) return false;
1982 }
1983 return ((pos - b) % a) == 0;
1984 };
1985 };
1986
1987 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
1988
1989 local.pushArray = function(node, tag, id, classes, attributes, pseudos){
1990 if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.foun d.push(node);
1991 };
1992
1993 local.pushUID = function(node, tag, id, classes, attributes, pseudos){
1994 var uid = this.getUID(node);
1995 if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attribute s, pseudos)){
1996 this.uniques[uid] = true;
1997 this.found.push(node);
1998 }
1999 };
2000
2001 local.matchNode = function(node, selector){
2002 if (this.isHTMLDocument && this.nativeMatchesSelector){
2003 try {
2004 return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\ s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
2005 } catch(matchError) {}
2006 }
2007
2008 var parsed = this.Slick.parse(selector);
2009 if (!parsed) return true;
2010
2011 // simple (single) selectors
2012 var expressions = parsed.expressions, simpleExpCounter = 0, i;
2013 for (i = 0; (currentExpression = expressions[i]); i++){
2014 if (currentExpression.length == 1){
2015 var exp = currentExpression[0];
2016 if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUp perCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
2017 simpleExpCounter++;
2018 }
2019 }
2020
2021 if (simpleExpCounter == parsed.length) return false;
2022
2023 var nodes = this.search(this.document, parsed), item;
2024 for (i = 0; item = nodes[i++];){
2025 if (item === node) return true;
2026 }
2027 return false;
2028 };
2029
2030 local.matchPseudo = function(node, name, argument){
2031 var pseudoName = 'pseudo:' + name;
2032 if (this[pseudoName]) return this[pseudoName](node, argument);
2033 var attribute = this.getAttribute(node, name);
2034 return (argument) ? argument == attribute : !!attribute;
2035 };
2036
2037 local.matchSelector = function(node, tag, id, classes, attributes, pseudos){
2038 if (tag){
2039 var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperC ase();
2040 if (tag == '*'){
2041 if (nodeName < '@') return false; // Fix for comment nodes and closed node s
2042 } else {
2043 if (nodeName != tag) return false;
2044 }
2045 }
2046
2047 if (id && node.getAttribute('id') != id) return false;
2048
2049 var i, part, cls;
2050 if (classes) for (i = classes.length; i--;){
2051 cls = this.getAttribute(node, 'class');
2052 if (!(cls && classes[i].regexp.test(cls))) return false;
2053 }
2054 if (attributes) for (i = attributes.length; i--;){
2055 part = attributes[i];
2056 if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.ha sAttribute(node, part.key)) return false;
2057 }
2058 if (pseudos) for (i = pseudos.length; i--;){
2059 part = pseudos[i];
2060 if (!this.matchPseudo(node, part.key, part.value)) return false;
2061 }
2062 return true;
2063 };
2064
2065 var combinators = {
2066
2067 ' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level
2068
2069 var i, item, children;
2070
2071 if (this.isHTMLDocument){
2072 getById: if (id){
2073 item = this.document.getElementById(id);
2074 if ((!item && node.all) || (this.idGetsName && item && item.getAttribute Node('id').nodeValue != id)){
2075 // all[id] returns all the elements with that name or id inside node
2076 // if theres just one it will return the element, else it will be a co llection
2077 children = node.all[id];
2078 if (!children) return;
2079 if (!children[0]) children = [children];
2080 for (i = 0; item = children[i++];){
2081 var idNode = item.getAttributeNode('id');
2082 if (idNode && idNode.nodeValue == id){
2083 this.push(item, tag, null, classes, attributes, pseudos);
2084 break;
2085 }
2086 }
2087 return;
2088 }
2089 if (!item){
2090 // if the context is in the dom we return, else we will try GEBTN, bre aking the getById label
2091 if (this.contains(this.root, node)) return;
2092 else break getById;
2093 } else if (this.document !== node && !this.contains(node, item)) return;
2094 this.push(item, tag, null, classes, attributes, pseudos);
2095 return;
2096 }
2097 getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBC N){
2098 children = node.getElementsByClassName(classList.join(' '));
2099 if (!(children && children.length)) break getByClass;
2100 for (i = 0; item = children[i++];) this.push(item, tag, id, null, attrib utes, pseudos);
2101 return;
2102 }
2103 }
2104 getByTag: {
2105 children = node.getElementsByTagName(tag);
2106 if (!(children && children.length)) break getByTag;
2107 if (!this.brokenStarGEBTN) tag = null;
2108 for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attri butes, pseudos);
2109 }
2110 },
2111
2112 '>': function(node, tag, id, classes, attributes, pseudos){ // direct children
2113 if ((node = node.firstChild)) do {
2114 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseu dos);
2115 } while ((node = node.nextSibling));
2116 },
2117
2118 '+': function(node, tag, id, classes, attributes, pseudos){ // next sibling
2119 while ((node = node.nextSibling)) if (node.nodeType == 1){
2120 this.push(node, tag, id, classes, attributes, pseudos);
2121 break;
2122 }
2123 },
2124
2125 '^': function(node, tag, id, classes, attributes, pseudos){ // first child
2126 node = node.firstChild;
2127 if (node){
2128 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseu dos);
2129 else this['combinator:+'](node, tag, id, classes, attributes, pseudos);
2130 }
2131 },
2132
2133 '~': function(node, tag, id, classes, attributes, pseudos){ // next siblings
2134 while ((node = node.nextSibling)){
2135 if (node.nodeType != 1) continue;
2136 var uid = this.getUID(node);
2137 if (this.bitUniques[uid]) break;
2138 this.bitUniques[uid] = true;
2139 this.push(node, tag, id, classes, attributes, pseudos);
2140 }
2141 },
2142
2143 '++': function(node, tag, id, classes, attributes, pseudos){ // next sibling a nd previous sibling
2144 this['combinator:+'](node, tag, id, classes, attributes, pseudos);
2145 this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
2146 },
2147
2148 '~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings
2149 this['combinator:~'](node, tag, id, classes, attributes, pseudos);
2150 this['combinator:!~'](node, tag, id, classes, attributes, pseudos);
2151 },
2152
2153 '!': function(node, tag, id, classes, attributes, pseudos){ // all parent node s up to document
2154 while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos);
2155 },
2156
2157 '!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level)
2158 node = node.parentNode;
2159 if (node !== this.document) this.push(node, tag, id, classes, attributes, ps eudos);
2160 },
2161
2162 '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibli ng
2163 while ((node = node.previousSibling)) if (node.nodeType == 1){
2164 this.push(node, tag, id, classes, attributes, pseudos);
2165 break;
2166 }
2167 },
2168
2169 '!^': function(node, tag, id, classes, attributes, pseudos){ // last child
2170 node = node.lastChild;
2171 if (node){
2172 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseu dos);
2173 else this['combinator:!+'](node, tag, id, classes, attributes, pseudos);
2174 }
2175 },
2176
2177 '!~': function(node, tag, id, classes, attributes, pseudos){ // previous sibli ngs
2178 while ((node = node.previousSibling)){
2179 if (node.nodeType != 1) continue;
2180 var uid = this.getUID(node);
2181 if (this.bitUniques[uid]) break;
2182 this.bitUniques[uid] = true;
2183 this.push(node, tag, id, classes, attributes, pseudos);
2184 }
2185 }
2186
2187 };
2188
2189 for (var c in combinators) local['combinator:' + c] = combinators[c];
2190
2191 var pseudos = {
2192
2193 /*<pseudo-selectors>*/
2194
2195 'empty': function(node){
2196 var child = node.firstChild;
2197 return !(child && child.nodeType == 1) && !(node.innerText || node.textConte nt || '').length;
2198 },
2199
2200 'not': function(node, expression){
2201 return !this.matchNode(node, expression);
2202 },
2203
2204 'contains': function(node, text){
2205 return (node.innerText || node.textContent || '').indexOf(text) > -1;
2206 },
2207
2208 'first-child': function(node){
2209 while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
2210 return true;
2211 },
2212
2213 'last-child': function(node){
2214 while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
2215 return true;
2216 },
2217
2218 'only-child': function(node){
2219 var prev = node;
2220 while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false;
2221 var next = node;
2222 while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
2223 return true;
2224 },
2225
2226 /*<nth-pseudo-selectors>*/
2227
2228 'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'),
2229
2230 'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNT HLast'),
2231
2232 'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType' , true),
2233
2234 'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'pos NTHTypeLast', true),
2235
2236 'index': function(node, index){
2237 return this['pseudo:nth-child'](node, '' + (index + 1));
2238 },
2239
2240 'even': function(node){
2241 return this['pseudo:nth-child'](node, '2n');
2242 },
2243
2244 'odd': function(node){
2245 return this['pseudo:nth-child'](node, '2n+1');
2246 },
2247
2248 /*</nth-pseudo-selectors>*/
2249
2250 /*<of-type-pseudo-selectors>*/
2251
2252 'first-of-type': function(node){
2253 var nodeName = node.nodeName;
2254 while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false;
2255 return true;
2256 },
2257
2258 'last-of-type': function(node){
2259 var nodeName = node.nodeName;
2260 while ((node = node.nextSibling)) if (node.nodeName == nodeName) return fals e;
2261 return true;
2262 },
2263
2264 'only-of-type': function(node){
2265 var prev = node, nodeName = node.nodeName;
2266 while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false;
2267 var next = node;
2268 while ((next = next.nextSibling)) if (next.nodeName == nodeName) return fals e;
2269 return true;
2270 },
2271
2272 /*</of-type-pseudo-selectors>*/
2273
2274 // custom pseudos
2275
2276 'enabled': function(node){
2277 return !node.disabled;
2278 },
2279
2280 'disabled': function(node){
2281 return node.disabled;
2282 },
2283
2284 'checked': function(node){
2285 return node.checked || node.selected;
2286 },
2287
2288 'focus': function(node){
2289 return this.isHTMLDocument && this.document.activeElement === node && (node. href || node.type || this.hasAttribute(node, 'tabindex'));
2290 },
2291
2292 'root': function(node){
2293 return (node === this.root);
2294 },
2295
2296 'selected': function(node){
2297 return node.selected;
2298 }
2299
2300 /*</pseudo-selectors>*/
2301 };
2302
2303 for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
2304
2305 // attributes methods
2306
2307 var attributeGetters = local.attributeGetters = {
2308
2309 'for': function(){
2310 return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for');
2311 },
2312
2313 'href': function(){
2314 return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute(' href');
2315 },
2316
2317 'style': function(){
2318 return (this.style) ? this.style.cssText : this.getAttribute('style');
2319 },
2320
2321 'tabindex': function(){
2322 var attributeNode = this.getAttributeNode('tabindex');
2323 return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
2324 },
2325
2326 'type': function(){
2327 return this.getAttribute('type');
2328 },
2329
2330 'maxlength': function(){
2331 var attributeNode = this.getAttributeNode('maxLength');
2332 return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null;
2333 }
2334
2335 };
2336
2337 attributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxle ngth;
2338
2339 // Slick
2340
2341 var Slick = local.Slick = (this.Slick || {});
2342
2343 Slick.version = '1.1.7';
2344
2345 // Slick finder
2346
2347 Slick.search = function(context, expression, append){
2348 return local.search(context, expression, append);
2349 };
2350
2351 Slick.find = function(context, expression){
2352 return local.search(context, expression, null, true);
2353 };
2354
2355 // Slick containment checker
2356
2357 Slick.contains = function(container, node){
2358 local.setDocument(container);
2359 return local.contains(container, node);
2360 };
2361
2362 // Slick attribute getter
2363
2364 Slick.getAttribute = function(node, name){
2365 local.setDocument(node);
2366 return local.getAttribute(node, name);
2367 };
2368
2369 Slick.hasAttribute = function(node, name){
2370 local.setDocument(node);
2371 return local.hasAttribute(node, name);
2372 };
2373
2374 // Slick matcher
2375
2376 Slick.match = function(node, selector){
2377 if (!(node && selector)) return false;
2378 if (!selector || selector === node) return true;
2379 local.setDocument(node);
2380 return local.matchNode(node, selector);
2381 };
2382
2383 // Slick attribute accessor
2384
2385 Slick.defineAttributeGetter = function(name, fn){
2386 local.attributeGetters[name] = fn;
2387 return this;
2388 };
2389
2390 Slick.lookupAttributeGetter = function(name){
2391 return local.attributeGetters[name];
2392 };
2393
2394 // Slick pseudo accessor
2395
2396 Slick.definePseudo = function(name, fn){
2397 local['pseudo:' + name] = function(node, argument){
2398 return fn.call(node, argument);
2399 };
2400 return this;
2401 };
2402
2403 Slick.lookupPseudo = function(name){
2404 var pseudo = local['pseudo:' + name];
2405 if (pseudo) return function(argument){
2406 return pseudo.call(this, argument);
2407 };
2408 return null;
2409 };
2410
2411 // Slick overrides accessor
2412
2413 Slick.override = function(regexp, fn){
2414 local.override(regexp, fn);
2415 return this;
2416 };
2417
2418 Slick.isXML = local.isXML;
2419
2420 Slick.uidOf = function(node){
2421 return local.getUIDHTML(node);
2422 };
2423
2424 if (!this.Slick) this.Slick = Slick;
2425
2426 }).apply(window);
2427
2428
2429 /*
2430 ---
2431
2432 name: Element
2433
2434 description: One of the most important items in MooTools. Contains the dollar fu nction, the dollars function, and an handful of cross-browser, time-saver method s to let you easily work with HTML Elements.
2435
2436 license: MIT-style license.
2437
2438 requires: [Window, Document, Array, String, Function, Object, Number, Slick.Pars er, Slick.Finder]
2439
2440 provides: [Element, Elements, $, $$, Iframe, Selectors]
2441
2442 ...
2443 */
2444
2445 var Element = function(tag, props){
2446 var konstructor = Element.Constructors[tag];
2447 if (konstructor) return konstructor(props);
2448 if (typeof tag != 'string') return document.id(tag).set(props);
2449
2450 if (!props) props = {};
2451
2452 if (!(/^[\w-]+$/).test(tag)){
2453 var parsed = Slick.parse(tag).expressions[0][0];
2454 tag = (parsed.tag == '*') ? 'div' : parsed.tag;
2455 if (parsed.id && props.id == null) props.id = parsed.id;
2456
2457 var attributes = parsed.attributes;
2458 if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
2459 attr = attributes[i];
2460 if (props[attr.key] != null) continue;
2461
2462 if (attr.value != null && attr.operator == '=') props[attr.key] = attr.val ue;
2463 else if (!attr.value && !attr.operator) props[attr.key] = true;
2464 }
2465
2466 if (parsed.classList && props['class'] == null) props['class'] = parsed.clas sList.join(' ');
2467 }
2468
2469 return document.newElement(tag, props);
2470 };
2471
2472
2473 if (Browser.Element){
2474 Element.prototype = Browser.Element.prototype;
2475 // IE8 and IE9 require the wrapping.
2476 Element.prototype._fireEvent = (function(fireEvent){
2477 return function(type, event){
2478 return fireEvent.call(this, type, event);
2479 };
2480 })(Element.prototype.fireEvent);
2481 }
2482
2483 new Type('Element', Element).mirror(function(name){
2484 if (Array.prototype[name]) return;
2485
2486 var obj = {};
2487 obj[name] = function(){
2488 var results = [], args = arguments, elements = true;
2489 for (var i = 0, l = this.length; i < l; i++){
2490 var element = this[i], result = results[i] = element[name].apply(element, args);
2491 elements = (elements && typeOf(result) == 'element');
2492 }
2493 return (elements) ? new Elements(results) : results;
2494 };
2495
2496 Elements.implement(obj);
2497 });
2498
2499 if (!Browser.Element){
2500 Element.parent = Object;
2501
2502 Element.Prototype = {
2503 '$constructor': Element,
2504 '$family': Function.from('element').hide()
2505 };
2506
2507 Element.mirror(function(name, method){
2508 Element.Prototype[name] = method;
2509 });
2510 }
2511
2512 Element.Constructors = {};
2513
2514
2515
2516 var IFrame = new Type('IFrame', function(){
2517 var params = Array.link(arguments, {
2518 properties: Type.isObject,
2519 iframe: function(obj){
2520 return (obj != null);
2521 }
2522 });
2523
2524 var props = params.properties || {}, iframe;
2525 if (params.iframe) iframe = document.id(params.iframe);
2526 var onload = props.onload || function(){};
2527 delete props.onload;
2528 props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.n ame) : 'IFrame_' + String.uniqueID()].pick();
2529 iframe = new Element(iframe || 'iframe', props);
2530
2531 var onLoad = function(){
2532 onload.call(iframe.contentWindow);
2533 };
2534
2535 if (window.frames[props.id]) onLoad();
2536 else iframe.addListener('load', onLoad);
2537 return iframe;
2538 });
2539
2540 var Elements = this.Elements = function(nodes){
2541 if (nodes && nodes.length){
2542 var uniques = {}, node;
2543 for (var i = 0; node = nodes[i++];){
2544 var uid = Slick.uidOf(node);
2545 if (!uniques[uid]){
2546 uniques[uid] = true;
2547 this.push(node);
2548 }
2549 }
2550 }
2551 };
2552
2553 Elements.prototype = {length: 0};
2554 Elements.parent = Array;
2555
2556 new Type('Elements', Elements).implement({
2557
2558 filter: function(filter, bind){
2559 if (!filter) return this;
2560 return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? functi on(item){
2561 return item.match(filter);
2562 } : filter, bind));
2563 }.protect(),
2564
2565 push: function(){
2566 var length = this.length;
2567 for (var i = 0, l = arguments.length; i < l; i++){
2568 var item = document.id(arguments[i]);
2569 if (item) this[length++] = item;
2570 }
2571 return (this.length = length);
2572 }.protect(),
2573
2574 unshift: function(){
2575 var items = [];
2576 for (var i = 0, l = arguments.length; i < l; i++){
2577 var item = document.id(arguments[i]);
2578 if (item) items.push(item);
2579 }
2580 return Array.prototype.unshift.apply(this, items);
2581 }.protect(),
2582
2583 concat: function(){
2584 var newElements = new Elements(this);
2585 for (var i = 0, l = arguments.length; i < l; i++){
2586 var item = arguments[i];
2587 if (Type.isEnumerable(item)) newElements.append(item);
2588 else newElements.push(item);
2589 }
2590 return newElements;
2591 }.protect(),
2592
2593 append: function(collection){
2594 for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]);
2595 return this;
2596 }.protect(),
2597
2598 empty: function(){
2599 while (this.length) delete this[--this.length];
2600 return this;
2601 }.protect()
2602
2603 });
2604
2605
2606
2607 (function(){
2608
2609 // FF, IE
2610 var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
2611
2612 splice.call(object, 1, 1);
2613 if (object[1] == 1) Elements.implement('splice', function(){
2614 var length = this.length;
2615 var result = splice.apply(this, arguments);
2616 while (length >= this.length) delete this[length--];
2617 return result;
2618 }.protect());
2619
2620 Array.forEachMethod(function(method, name){
2621 Elements.implement(name, method);
2622 });
2623
2624 Array.mirror(Elements);
2625
2626 /*<ltIE8>*/
2627 var createElementAcceptsHTML;
2628 try {
2629 createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x');
2630 } catch (e){}
2631
2632 var escapeQuotes = function(html){
2633 return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
2634 };
2635 /*</ltIE8>*/
2636
2637 Document.implement({
2638
2639 newElement: function(tag, props){
2640 if (props && props.checked != null) props.defaultChecked = props.checked;
2641 /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
2642 if (createElementAcceptsHTML && props){
2643 tag = '<' + tag;
2644 if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"';
2645 if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"';
2646 tag += '>';
2647 delete props.name;
2648 delete props.type;
2649 }
2650 /*</ltIE8>*/
2651 return this.id(this.createElement(tag)).set(props);
2652 }
2653
2654 });
2655
2656 })();
2657
2658 (function(){
2659
2660 Slick.uidOf(window);
2661 Slick.uidOf(document);
2662
2663 Document.implement({
2664
2665 newTextNode: function(text){
2666 return this.createTextNode(text);
2667 },
2668
2669 getDocument: function(){
2670 return this;
2671 },
2672
2673 getWindow: function(){
2674 return this.window;
2675 },
2676
2677 id: (function(){
2678
2679 var types = {
2680
2681 string: function(id, nocash, doc){
2682 id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1'));
2683 return (id) ? types.element(id, nocash) : null;
2684 },
2685
2686 element: function(el, nocash){
2687 Slick.uidOf(el);
2688 if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)) {
2689 var fireEvent = el.fireEvent;
2690 // wrapping needed in IE7, or else crash
2691 el._fireEvent = function(type, event){
2692 return fireEvent(type, event);
2693 };
2694 Object.append(el, Element.Prototype);
2695 }
2696 return el;
2697 },
2698
2699 object: function(obj, nocash, doc){
2700 if (obj.toElement) return types.element(obj.toElement(doc), nocash);
2701 return null;
2702 }
2703
2704 };
2705
2706 types.textnode = types.whitespace = types.window = types.document = function (zero){
2707 return zero;
2708 };
2709
2710 return function(el, nocash, doc){
2711 if (el && el.$family && el.uniqueNumber) return el;
2712 var type = typeOf(el);
2713 return (types[type]) ? types[type](el, nocash, doc || document) : null;
2714 };
2715
2716 })()
2717
2718 });
2719
2720 if (window.$ == null) Window.implement('$', function(el, nc){
2721 return document.id(el, nc, this.document);
2722 });
2723
2724 Window.implement({
2725
2726 getDocument: function(){
2727 return this.document;
2728 },
2729
2730 getWindow: function(){
2731 return this;
2732 }
2733
2734 });
2735
2736 [Document, Element].invoke('implement', {
2737
2738 getElements: function(expression){
2739 return Slick.search(this, expression, new Elements);
2740 },
2741
2742 getElement: function(expression){
2743 return document.id(Slick.find(this, expression));
2744 }
2745
2746 });
2747
2748 var contains = {contains: function(element){
2749 return Slick.contains(this, element);
2750 }};
2751
2752 if (!document.contains) Document.implement(contains);
2753 if (!document.createElement('div').contains) Element.implement(contains);
2754
2755
2756
2757 // tree walking
2758
2759 var injectCombinator = function(expression, combinator){
2760 if (!expression) return combinator;
2761
2762 expression = Object.clone(Slick.parse(expression));
2763
2764 var expressions = expression.expressions;
2765 for (var i = expressions.length; i--;)
2766 expressions[i][0].combinator = combinator;
2767
2768 return expression;
2769 };
2770
2771 Object.forEach({
2772 getNext: '~',
2773 getPrevious: '!~',
2774 getParent: '!'
2775 }, function(combinator, method){
2776 Element.implement(method, function(expression){
2777 return this.getElement(injectCombinator(expression, combinator));
2778 });
2779 });
2780
2781 Object.forEach({
2782 getAllNext: '~',
2783 getAllPrevious: '!~',
2784 getSiblings: '~~',
2785 getChildren: '>',
2786 getParents: '!'
2787 }, function(combinator, method){
2788 Element.implement(method, function(expression){
2789 return this.getElements(injectCombinator(expression, combinator));
2790 });
2791 });
2792
2793 Element.implement({
2794
2795 getFirst: function(expression){
2796 return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]) ;
2797 },
2798
2799 getLast: function(expression){
2800 return document.id(Slick.search(this, injectCombinator(expression, '>')).get Last());
2801 },
2802
2803 getWindow: function(){
2804 return this.ownerDocument.window;
2805 },
2806
2807 getDocument: function(){
2808 return this.ownerDocument;
2809 },
2810
2811 getElementById: function(id){
2812 return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1') ));
2813 },
2814
2815 match: function(expression){
2816 return !expression || Slick.match(this, expression);
2817 }
2818
2819 });
2820
2821
2822
2823 if (window.$$ == null) Window.implement('$$', function(selector){
2824 if (arguments.length == 1){
2825 if (typeof selector == 'string') return Slick.search(this.document, selector , new Elements);
2826 else if (Type.isEnumerable(selector)) return new Elements(selector);
2827 }
2828 return new Elements(arguments);
2829 });
2830
2831 // Inserters
2832
2833 var inserters = {
2834
2835 before: function(context, element){
2836 var parent = element.parentNode;
2837 if (parent) parent.insertBefore(context, element);
2838 },
2839
2840 after: function(context, element){
2841 var parent = element.parentNode;
2842 if (parent) parent.insertBefore(context, element.nextSibling);
2843 },
2844
2845 bottom: function(context, element){
2846 element.appendChild(context);
2847 },
2848
2849 top: function(context, element){
2850 element.insertBefore(context, element.firstChild);
2851 }
2852
2853 };
2854
2855 inserters.inside = inserters.bottom;
2856
2857
2858
2859 // getProperty / setProperty
2860
2861 var propertyGetters = {}, propertySetters = {};
2862
2863 // properties
2864
2865 var properties = {};
2866 Array.forEach([
2867 'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'c olSpan',
2868 'frameBorder', 'rowSpan', 'tabIndex', 'useMap'
2869 ], function(property){
2870 properties[property.toLowerCase()] = property;
2871 });
2872
2873 properties.html = 'innerHTML';
2874 properties.text = (document.createElement('div').textContent == null) ? 'innerTe xt': 'textContent';
2875
2876 Object.forEach(properties, function(real, key){
2877 propertySetters[key] = function(node, value){
2878 node[real] = value;
2879 };
2880 propertyGetters[key] = function(node){
2881 return node[real];
2882 };
2883 });
2884
2885 // Booleans
2886
2887 var bools = [
2888 'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
2889 'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
2890 'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
2891 'loop'
2892 ];
2893
2894 var booleans = {};
2895 Array.forEach(bools, function(bool){
2896 var lower = bool.toLowerCase();
2897 booleans[lower] = bool;
2898 propertySetters[lower] = function(node, value){
2899 node[bool] = !!value;
2900 };
2901 propertyGetters[lower] = function(node){
2902 return !!node[bool];
2903 };
2904 });
2905
2906 // Special cases
2907
2908 Object.append(propertySetters, {
2909
2910 'class': function(node, value){
2911 ('className' in node) ? node.className = (value || '') : node.setAttribute(' class', value);
2912 },
2913
2914 'for': function(node, value){
2915 ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value) ;
2916 },
2917
2918 'style': function(node, value){
2919 (node.style) ? node.style.cssText = value : node.setAttribute('style', value );
2920 },
2921
2922 'value': function(node, value){
2923 node.value = (value != null) ? value : '';
2924 }
2925
2926 });
2927
2928 propertyGetters['class'] = function(node){
2929 return ('className' in node) ? node.className || null : node.getAttribute('cla ss');
2930 };
2931
2932 /* <webkit> */
2933 var el = document.createElement('button');
2934 // IE sets type as readonly and throws
2935 try { el.type = 'button'; } catch(e){}
2936 if (el.type != 'button') propertySetters.type = function(node, value){
2937 node.setAttribute('type', value);
2938 };
2939 el = null;
2940 /* </webkit> */
2941
2942 /*<IE>*/
2943 var input = document.createElement('input');
2944 input.value = 't';
2945 input.type = 'submit';
2946 if (input.value != 't') propertySetters.type = function(node, type){
2947 var value = node.value;
2948 node.type = type;
2949 node.value = value;
2950 };
2951 input = null;
2952 /*</IE>*/
2953
2954 /* getProperty, setProperty */
2955
2956 /* <ltIE9> */
2957 var pollutesGetAttribute = (function(div){
2958 div.random = 'attribute';
2959 return (div.getAttribute('random') == 'attribute');
2960 })(document.createElement('div'));
2961
2962 /* <ltIE9> */
2963
2964 Element.implement({
2965
2966 setProperty: function(name, value){
2967 var setter = propertySetters[name.toLowerCase()];
2968 if (setter){
2969 setter(this, value);
2970 } else {
2971 /* <ltIE9> */
2972 if (pollutesGetAttribute) var attributeWhiteList = this.retrieve('$attribu teWhiteList', {});
2973 /* </ltIE9> */
2974
2975 if (value == null){
2976 this.removeAttribute(name);
2977 /* <ltIE9> */
2978 if (pollutesGetAttribute) delete attributeWhiteList[name];
2979 /* </ltIE9> */
2980 } else {
2981 this.setAttribute(name, '' + value);
2982 /* <ltIE9> */
2983 if (pollutesGetAttribute) attributeWhiteList[name] = true;
2984 /* </ltIE9> */
2985 }
2986 }
2987 return this;
2988 },
2989
2990 setProperties: function(attributes){
2991 for (var attribute in attributes) this.setProperty(attribute, attributes[att ribute]);
2992 return this;
2993 },
2994
2995 getProperty: function(name){
2996 var getter = propertyGetters[name.toLowerCase()];
2997 if (getter) return getter(this);
2998 /* <ltIE9> */
2999 if (pollutesGetAttribute){
3000 var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve ('$attributeWhiteList', {});
3001 if (!attr) return null;
3002 if (attr.expando && !attributeWhiteList[name]){
3003 var outer = this.outerHTML;
3004 // segment by the opening tag and find mention of attribute name
3005 if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(nam e) < 0) return null;
3006 attributeWhiteList[name] = true;
3007 }
3008 }
3009 /* </ltIE9> */
3010 var result = Slick.getAttribute(this, name);
3011 return (!result && !Slick.hasAttribute(this, name)) ? null : result;
3012 },
3013
3014 getProperties: function(){
3015 var args = Array.from(arguments);
3016 return args.map(this.getProperty, this).associate(args);
3017 },
3018
3019 removeProperty: function(name){
3020 return this.setProperty(name, null);
3021 },
3022
3023 removeProperties: function(){
3024 Array.each(arguments, this.removeProperty, this);
3025 return this;
3026 },
3027
3028 set: function(prop, value){
3029 var property = Element.Properties[prop];
3030 (property && property.set) ? property.set.call(this, value) : this.setProper ty(prop, value);
3031 }.overloadSetter(),
3032
3033 get: function(prop){
3034 var property = Element.Properties[prop];
3035 return (property && property.get) ? property.get.apply(this) : this.getPrope rty(prop);
3036 }.overloadGetter(),
3037
3038 erase: function(prop){
3039 var property = Element.Properties[prop];
3040 (property && property.erase) ? property.erase.apply(this) : this.removePrope rty(prop);
3041 return this;
3042 },
3043
3044 hasClass: function(className){
3045 return this.className.clean().contains(className, ' ');
3046 },
3047
3048 addClass: function(className){
3049 if (!this.hasClass(className)) this.className = (this.className + ' ' + clas sName).clean();
3050 return this;
3051 },
3052
3053 removeClass: function(className){
3054 this.className = this.className.replace(new RegExp('(^|\\s)' + className + ' (?:\\s|$)'), '$1');
3055 return this;
3056 },
3057
3058 toggleClass: function(className, force){
3059 if (force == null) force = !this.hasClass(className);
3060 return (force) ? this.addClass(className) : this.removeClass(className);
3061 },
3062
3063 adopt: function(){
3064 var parent = this, fragment, elements = Array.flatten(arguments), length = e lements.length;
3065 if (length > 1) parent = fragment = document.createDocumentFragment();
3066
3067 for (var i = 0; i < length; i++){
3068 var element = document.id(elements[i], true);
3069 if (element) parent.appendChild(element);
3070 }
3071
3072 if (fragment) this.appendChild(fragment);
3073
3074 return this;
3075 },
3076
3077 appendText: function(text, where){
3078 return this.grab(this.getDocument().newTextNode(text), where);
3079 },
3080
3081 grab: function(el, where){
3082 inserters[where || 'bottom'](document.id(el, true), this);
3083 return this;
3084 },
3085
3086 inject: function(el, where){
3087 inserters[where || 'bottom'](this, document.id(el, true));
3088 return this;
3089 },
3090
3091 replaces: function(el){
3092 el = document.id(el, true);
3093 el.parentNode.replaceChild(this, el);
3094 return this;
3095 },
3096
3097 wraps: function(el, where){
3098 el = document.id(el, true);
3099 return this.replaces(el).grab(el, where);
3100 },
3101
3102 getSelected: function(){
3103 this.selectedIndex; // Safari 3.2.1
3104 return new Elements(Array.from(this.options).filter(function(option){
3105 return option.selected;
3106 }));
3107 },
3108
3109 toQueryString: function(){
3110 var queryString = [];
3111 this.getElements('input, select, textarea').each(function(el){
3112 var type = el.type;
3113 if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
3114
3115 var value = (el.get('tag') == 'select') ? el.getSelected().map(function(op t){
3116 // IE
3117 return document.id(opt).get('value');
3118 }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el. get('value');
3119
3120 Array.from(value).each(function(val){
3121 if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.na me) + '=' + encodeURIComponent(val));
3122 });
3123 });
3124 return queryString.join('&');
3125 }
3126
3127 });
3128
3129 var collected = {}, storage = {};
3130
3131 var get = function(uid){
3132 return (storage[uid] || (storage[uid] = {}));
3133 };
3134
3135 var clean = function(item){
3136 var uid = item.uniqueNumber;
3137 if (item.removeEvents) item.removeEvents();
3138 if (item.clearAttributes) item.clearAttributes();
3139 if (uid != null){
3140 delete collected[uid];
3141 delete storage[uid];
3142 }
3143 return item;
3144 };
3145
3146 var formProps = {input: 'checked', option: 'selected', textarea: 'value'};
3147
3148 Element.implement({
3149
3150 destroy: function(){
3151 var children = clean(this).getElementsByTagName('*');
3152 Array.each(children, clean);
3153 Element.dispose(this);
3154 return null;
3155 },
3156
3157 empty: function(){
3158 Array.from(this.childNodes).each(Element.dispose);
3159 return this;
3160 },
3161
3162 dispose: function(){
3163 return (this.parentNode) ? this.parentNode.removeChild(this) : this;
3164 },
3165
3166 clone: function(contents, keepid){
3167 contents = contents !== false;
3168 var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
3169
3170 if (contents){
3171 ce.append(Array.from(clone.getElementsByTagName('*')));
3172 te.append(Array.from(this.getElementsByTagName('*')));
3173 }
3174
3175 for (i = ce.length; i--;){
3176 var node = ce[i], element = te[i];
3177 if (!keepid) node.removeAttribute('id');
3178 /*<ltIE9>*/
3179 if (node.clearAttributes){
3180 node.clearAttributes();
3181 node.mergeAttributes(element);
3182 node.removeAttribute('uniqueNumber');
3183 if (node.options){
3184 var no = node.options, eo = element.options;
3185 for (var j = no.length; j--;) no[j].selected = eo[j].selected;
3186 }
3187 }
3188 /*</ltIE9>*/
3189 var prop = formProps[element.tagName.toLowerCase()];
3190 if (prop && element[prop]) node[prop] = element[prop];
3191 }
3192
3193 /*<ltIE9>*/
3194 if (Browser.ie){
3195 var co = clone.getElementsByTagName('object'), to = this.getElementsByTagN ame('object');
3196 for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML;
3197 }
3198 /*</ltIE9>*/
3199 return document.id(clone);
3200 }
3201
3202 });
3203
3204 [Element, Window, Document].invoke('implement', {
3205
3206 addListener: function(type, fn){
3207 if (type == 'unload'){
3208 var old = fn, self = this;
3209 fn = function(){
3210 self.removeListener('unload', fn);
3211 old();
3212 };
3213 } else {
3214 collected[Slick.uidOf(this)] = this;
3215 }
3216 if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]);
3217 else this.attachEvent('on' + type, fn);
3218 return this;
3219 },
3220
3221 removeListener: function(type, fn){
3222 if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments [2]);
3223 else this.detachEvent('on' + type, fn);
3224 return this;
3225 },
3226
3227 retrieve: function(property, dflt){
3228 var storage = get(Slick.uidOf(this)), prop = storage[property];
3229 if (dflt != null && prop == null) prop = storage[property] = dflt;
3230 return prop != null ? prop : null;
3231 },
3232
3233 store: function(property, value){
3234 var storage = get(Slick.uidOf(this));
3235 storage[property] = value;
3236 return this;
3237 },
3238
3239 eliminate: function(property){
3240 var storage = get(Slick.uidOf(this));
3241 delete storage[property];
3242 return this;
3243 }
3244
3245 });
3246
3247 /*<ltIE9>*/
3248 if (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){
3249 Object.each(collected, clean);
3250 if (window.CollectGarbage) CollectGarbage();
3251 });
3252 /*</ltIE9>*/
3253
3254 Element.Properties = {};
3255
3256
3257
3258 Element.Properties.style = {
3259
3260 set: function(style){
3261 this.style.cssText = style;
3262 },
3263
3264 get: function(){
3265 return this.style.cssText;
3266 },
3267
3268 erase: function(){
3269 this.style.cssText = '';
3270 }
3271
3272 };
3273
3274 Element.Properties.tag = {
3275
3276 get: function(){
3277 return this.tagName.toLowerCase();
3278 }
3279
3280 };
3281
3282 Element.Properties.html = {
3283
3284 set: function(html){
3285 if (html == null) html = '';
3286 else if (typeOf(html) == 'array') html = html.join('');
3287 this.innerHTML = html;
3288 },
3289
3290 erase: function(){
3291 this.innerHTML = '';
3292 }
3293
3294 };
3295
3296 /*<ltIE9>*/
3297 // technique by jdbarlett - http://jdbartlett.com/innershiv/
3298 var div = document.createElement('div');
3299 div.innerHTML = '<nav></nav>';
3300 var supportsHTML5Elements = (div.childNodes.length == 1);
3301 if (!supportsHTML5Elements){
3302 var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video' .split(' '),
3303 fragment = document.createDocumentFragment(), l = tags.length;
3304 while (l--) fragment.createElement(tags[l]);
3305 }
3306 div = null;
3307 /*</ltIE9>*/
3308
3309 /*<IE>*/
3310 var supportsTableInnerHTML = Function.attempt(function(){
3311 var table = document.createElement('table');
3312 table.innerHTML = '<tr><td></td></tr>';
3313 return true;
3314 });
3315
3316 /*<ltFF4>*/
3317 var tr = document.createElement('tr'), html = '<td></td>';
3318 tr.innerHTML = html;
3319 var supportsTRInnerHTML = (tr.innerHTML == html);
3320 tr = null;
3321 /*</ltFF4>*/
3322
3323 if (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){
3324
3325 Element.Properties.html.set = (function(set){
3326
3327 var translations = {
3328 table: [1, '<table>', '</table>'],
3329 select: [1, '<select>', '</select>'],
3330 tbody: [2, '<table><tbody>', '</tbody></table>'],
3331 tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
3332 };
3333
3334 translations.thead = translations.tfoot = translations.tbody;
3335
3336 return function(html){
3337 var wrap = translations[this.get('tag')];
3338 if (!wrap && !supportsHTML5Elements) wrap = [0, '', ''];
3339 if (!wrap) return set.call(this, html);
3340
3341 var level = wrap[0], wrapper = document.createElement('div'), target = wra pper;
3342 if (!supportsHTML5Elements) fragment.appendChild(wrapper);
3343 wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join('');
3344 while (level--) target = target.firstChild;
3345 this.empty().adopt(target.childNodes);
3346 if (!supportsHTML5Elements) fragment.removeChild(wrapper);
3347 wrapper = null;
3348 };
3349
3350 })(Element.Properties.html.set);
3351 }
3352 /*</IE>*/
3353
3354 /*<ltIE9>*/
3355 var testForm = document.createElement('form');
3356 testForm.innerHTML = '<select><option>s</option></select>';
3357
3358 if (testForm.firstChild.value != 's') Element.Properties.value = {
3359
3360 set: function(value){
3361 var tag = this.get('tag');
3362 if (tag != 'select') return this.setProperty('value', value);
3363 var options = this.getElements('option');
3364 for (var i = 0; i < options.length; i++){
3365 var option = options[i],
3366 attr = option.getAttributeNode('value'),
3367 optionValue = (attr && attr.specified) ? option.value : option.get('text ');
3368 if (optionValue == value) return option.selected = true;
3369 }
3370 },
3371
3372 get: function(){
3373 var option = this, tag = option.get('tag');
3374
3375 if (tag != 'select' && tag != 'option') return this.getProperty('value');
3376
3377 if (tag == 'select' && !(option = option.getSelected()[0])) return '';
3378
3379 var attr = option.getAttributeNode('value');
3380 return (attr && attr.specified) ? option.value : option.get('text');
3381 }
3382
3383 };
3384 testForm = null;
3385 /*</ltIE9>*/
3386
3387 /*<IE>*/
3388 if (document.createElement('div').getAttributeNode('id')) Element.Properties.id = {
3389 set: function(id){
3390 this.id = this.getAttributeNode('id').value = id;
3391 },
3392 get: function(){
3393 return this.id || null;
3394 },
3395 erase: function(){
3396 this.id = this.getAttributeNode('id').value = '';
3397 }
3398 };
3399 /*</IE>*/
3400
3401 })();
3402
3403
3404 /*
3405 ---
3406
3407 name: Element.Style
3408
3409 description: Contains methods for interacting with the styles of Elements in a f ashionable way.
3410
3411 license: MIT-style license.
3412
3413 requires: Element
3414
3415 provides: Element.Style
3416
3417 ...
3418 */
3419
3420 (function(){
3421
3422 var html = document.html;
3423
3424 //<ltIE9>
3425 // Check for oldIE, which does not remove styles when they're set to null
3426 var el = document.createElement('div');
3427 el.style.color = 'red';
3428 el.style.color = null;
3429 var doesNotRemoveStyles = el.style.color == 'red';
3430 el = null;
3431 //</ltIE9>
3432
3433 Element.Properties.styles = {set: function(styles){
3434 this.setStyles(styles);
3435 }};
3436
3437 var hasOpacity = (html.style.opacity != null),
3438 hasFilter = (html.style.filter != null),
3439 reAlpha = /alpha\(opacity=([\d.]+)\)/i;
3440
3441 var setVisibility = function(element, opacity){
3442 element.store('$opacity', opacity);
3443 element.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidde n';
3444 };
3445
3446 var setOpacity = (hasOpacity ? function(element, opacity){
3447 element.style.opacity = opacity;
3448 } : (hasFilter ? function(element, opacity){
3449 var style = element.style;
3450 if (!element.currentStyle || !element.currentStyle.hasLayout) style.zoom = 1;
3451 if (opacity == null || opacity == 1) opacity = '';
3452 else opacity = 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')';
3453 var filter = style.filter || element.getComputedStyle('filter') || '';
3454 style.filter = reAlpha.test(filter) ? filter.replace(reAlpha, opacity) : filte r + opacity;
3455 if (!style.filter) style.removeAttribute('filter');
3456 } : setVisibility));
3457
3458 var getOpacity = (hasOpacity ? function(element){
3459 var opacity = element.style.opacity || element.getComputedStyle('opacity');
3460 return (opacity == '') ? 1 : opacity.toFloat();
3461 } : (hasFilter ? function(element){
3462 var filter = (element.style.filter || element.getComputedStyle('filter')),
3463 opacity;
3464 if (filter) opacity = filter.match(reAlpha);
3465 return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
3466 } : function(element){
3467 var opacity = element.retrieve('$opacity');
3468 if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);
3469 return opacity;
3470 }));
3471
3472 var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';
3473
3474 Element.implement({
3475
3476 getComputedStyle: function(property){
3477 if (this.currentStyle) return this.currentStyle[property.camelCase()];
3478 var defaultView = Element.getDocument(this).defaultView,
3479 computed = defaultView ? defaultView.getComputedStyle(this, null) : null;
3480 return (computed) ? computed.getPropertyValue((property == floatName) ? 'flo at' : property.hyphenate()) : null;
3481 },
3482
3483 setStyle: function(property, value){
3484 if (property == 'opacity'){
3485 if (value != null) value = parseFloat(value);
3486 setOpacity(this, value);
3487 return this;
3488 }
3489 property = (property == 'float' ? floatName : property).camelCase();
3490 if (typeOf(value) != 'string'){
3491 var map = (Element.Styles[property] || '@').split(' ');
3492 value = Array.from(value).map(function(val, i){
3493 if (!map[i]) return '';
3494 return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val;
3495 }).join(' ');
3496 } else if (value == String(Number(value))){
3497 value = Math.round(value);
3498 }
3499 this.style[property] = value;
3500 //<ltIE9>
3501 if ((value == '' || value == null) && doesNotRemoveStyles && this.style.remo veAttribute){
3502 this.style.removeAttribute(property);
3503 }
3504 //</ltIE9>
3505 return this;
3506 },
3507
3508 getStyle: function(property){
3509 if (property == 'opacity') return getOpacity(this);
3510 property = (property == 'float' ? floatName : property).camelCase();
3511 var result = this.style[property];
3512 if (!result || property == 'zIndex'){
3513 result = [];
3514 for (var style in Element.ShortStyles){
3515 if (property != style) continue;
3516 for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s));
3517 return result.join(' ');
3518 }
3519 result = this.getComputedStyle(property);
3520 }
3521 if (result){
3522 result = String(result);
3523 var color = result.match(/rgba?\([\d\s,]+\)/);
3524 if (color) result = result.replace(color[0], color[0].rgbToHex());
3525 }
3526 if (Browser.opera || Browser.ie){
3527 if ((/^(height|width)$/).test(property) && !(/px$/.test(result))){
3528 var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom '], size = 0;
3529 values.each(function(value){
3530 size += this.getStyle('border-' + value + '-width').toInt() + this.get Style('padding-' + value).toInt();
3531 }, this);
3532 return this['offset' + property.capitalize()] - size + 'px';
3533 }
3534 if (Browser.ie && (/^border(.+)Width|margin|padding/).test(property) && is NaN(parseFloat(result))){
3535 return '0px';
3536 }
3537 }
3538 return result;
3539 },
3540
3541 setStyles: function(styles){
3542 for (var style in styles) this.setStyle(style, styles[style]);
3543 return this;
3544 },
3545
3546 getStyles: function(){
3547 var result = {};
3548 Array.flatten(arguments).each(function(key){
3549 result[key] = this.getStyle(key);
3550 }, this);
3551 return result;
3552 }
3553
3554 });
3555
3556 Element.Styles = {
3557 left: '@px', top: '@px', bottom: '@px', right: '@px',
3558 width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px ', minHeight: '@px',
3559 backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)',
3560 fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)',
3561 margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @ , @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
3562 borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @ , @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
3563 zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@'
3564 };
3565
3566
3567
3568
3569
3570 Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, bor derStyle: {}, borderColor: {}};
3571
3572 ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
3573 var Short = Element.ShortStyles;
3574 var All = Element.Styles;
3575 ['margin', 'padding'].each(function(style){
3576 var sd = style + direction;
3577 Short[style][sd] = All[sd] = '@px';
3578 });
3579 var bd = 'border' + direction;
3580 Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
3581 var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
3582 Short[bd] = {};
3583 Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
3584 Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
3585 Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
3586 });
3587
3588 })();
3589
3590
3591 /*
3592 ---
3593
3594 name: Element.Event
3595
3596 description: Contains Element methods for dealing with events. This file also in cludes mouseenter and mouseleave custom Element Events, if necessary.
3597
3598 license: MIT-style license.
3599
3600 requires: [Element, Event]
3601
3602 provides: Element.Event
3603
3604 ...
3605 */
3606
3607 (function(){
3608
3609 Element.Properties.events = {set: function(events){
3610 this.addEvents(events);
3611 }};
3612
3613 [Element, Window, Document].invoke('implement', {
3614
3615 addEvent: function(type, fn){
3616 var events = this.retrieve('events', {});
3617 if (!events[type]) events[type] = {keys: [], values: []};
3618 if (events[type].keys.contains(fn)) return this;
3619 events[type].keys.push(fn);
3620 var realType = type,
3621 custom = Element.Events[type],
3622 condition = fn,
3623 self = this;
3624 if (custom){
3625 if (custom.onAdd) custom.onAdd.call(this, fn, type);
3626 if (custom.condition){
3627 condition = function(event){
3628 if (custom.condition.call(this, event, type)) return fn.call(this, eve nt);
3629 return true;
3630 };
3631 }
3632 if (custom.base) realType = Function.from(custom.base).call(this, type);
3633 }
3634 var defn = function(){
3635 return fn.call(self);
3636 };
3637 var nativeEvent = Element.NativeEvents[realType];
3638 if (nativeEvent){
3639 if (nativeEvent == 2){
3640 defn = function(event){
3641 event = new DOMEvent(event, self.getWindow());
3642 if (condition.call(self, event) === false) event.stop();
3643 };
3644 }
3645 this.addListener(realType, defn, arguments[2]);
3646 }
3647 events[type].values.push(defn);
3648 return this;
3649 },
3650
3651 removeEvent: function(type, fn){
3652 var events = this.retrieve('events');
3653 if (!events || !events[type]) return this;
3654 var list = events[type];
3655 var index = list.keys.indexOf(fn);
3656 if (index == -1) return this;
3657 var value = list.values[index];
3658 delete list.keys[index];
3659 delete list.values[index];
3660 var custom = Element.Events[type];
3661 if (custom){
3662 if (custom.onRemove) custom.onRemove.call(this, fn, type);
3663 if (custom.base) type = Function.from(custom.base).call(this, type);
3664 }
3665 return (Element.NativeEvents[type]) ? this.removeListener(type, value, argum ents[2]) : this;
3666 },
3667
3668 addEvents: function(events){
3669 for (var event in events) this.addEvent(event, events[event]);
3670 return this;
3671 },
3672
3673 removeEvents: function(events){
3674 var type;
3675 if (typeOf(events) == 'object'){
3676 for (type in events) this.removeEvent(type, events[type]);
3677 return this;
3678 }
3679 var attached = this.retrieve('events');
3680 if (!attached) return this;
3681 if (!events){
3682 for (type in attached) this.removeEvents(type);
3683 this.eliminate('events');
3684 } else if (attached[events]){
3685 attached[events].keys.each(function(fn){
3686 this.removeEvent(events, fn);
3687 }, this);
3688 delete attached[events];
3689 }
3690 return this;
3691 },
3692
3693 fireEvent: function(type, args, delay){
3694 var events = this.retrieve('events');
3695 if (!events || !events[type]) return this;
3696 args = Array.from(args);
3697
3698 events[type].keys.each(function(fn){
3699 if (delay) fn.delay(delay, this, args);
3700 else fn.apply(this, args);
3701 }, this);
3702 return this;
3703 },
3704
3705 cloneEvents: function(from, type){
3706 from = document.id(from);
3707 var events = from.retrieve('events');
3708 if (!events) return this;
3709 if (!type){
3710 for (var eventType in events) this.cloneEvents(from, eventType);
3711 } else if (events[type]){
3712 events[type].keys.each(function(fn){
3713 this.addEvent(type, fn);
3714 }, this);
3715 }
3716 return this;
3717 }
3718
3719 });
3720
3721 Element.NativeEvents = {
3722 click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse butto ns
3723 mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
3724 mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement
3725 keydown: 2, keypress: 2, keyup: 2, //keyboard
3726 orientationchange: 2, // mobile
3727 touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
3728 gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
3729 focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements
3730 load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window
3731 error: 1, abort: 1, scroll: 1 //misc
3732 };
3733
3734 Element.Events = {mousewheel: {
3735 base: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel'
3736 }};
3737
3738 if ('onmouseenter' in document.documentElement){
3739 Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2;
3740 } else {
3741 var check = function(event){
3742 var related = event.relatedTarget;
3743 if (related == null) return true;
3744 if (!related) return false;
3745 return (related != this && related.prefix != 'xul' && typeOf(this) != 'docum ent' && !this.contains(related));
3746 };
3747
3748 Element.Events.mouseenter = {
3749 base: 'mouseover',
3750 condition: check
3751 };
3752
3753 Element.Events.mouseleave = {
3754 base: 'mouseout',
3755 condition: check
3756 };
3757 }
3758
3759 /*<ltIE9>*/
3760 if (!window.addEventListener){
3761 Element.NativeEvents.propertychange = 2;
3762 Element.Events.change = {
3763 base: function(){
3764 var type = this.type;
3765 return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbo x')) ? 'propertychange' : 'change'
3766 },
3767 condition: function(event){
3768 return this.type != 'radio' || (event.event.propertyName == 'checked' && t his.checked);
3769 }
3770 }
3771 }
3772 /*</ltIE9>*/
3773
3774
3775
3776 })();
3777
3778
3779 /*
3780 ---
3781
3782 name: Element.Dimensions
3783
3784 description: Contains methods to work with size, scroll, or positioning of Eleme nts and the window object.
3785
3786 license: MIT-style license.
3787
3788 credits:
3789 - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and sma rt browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
3790 - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [B SD License](http://developer.yahoo.com/yui/license.html).
3791
3792 requires: [Element, Element.Style]
3793
3794 provides: [Element.Dimensions]
3795
3796 ...
3797 */
3798
3799 (function(){
3800
3801 var element = document.createElement('div'),
3802 child = document.createElement('div');
3803 element.style.height = '0';
3804 element.appendChild(child);
3805 var brokenOffsetParent = (child.offsetParent === element);
3806 element = child = null;
3807
3808 var isOffset = function(el){
3809 return styleString(el, 'position') != 'static' || isBody(el);
3810 };
3811
3812 var isOffsetStatic = function(el){
3813 return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
3814 };
3815
3816 Element.implement({
3817
3818 scrollTo: function(x, y){
3819 if (isBody(this)){
3820 this.getWindow().scrollTo(x, y);
3821 } else {
3822 this.scrollLeft = x;
3823 this.scrollTop = y;
3824 }
3825 return this;
3826 },
3827
3828 getSize: function(){
3829 if (isBody(this)) return this.getWindow().getSize();
3830 return {x: this.offsetWidth, y: this.offsetHeight};
3831 },
3832
3833 getScrollSize: function(){
3834 if (isBody(this)) return this.getWindow().getScrollSize();
3835 return {x: this.scrollWidth, y: this.scrollHeight};
3836 },
3837
3838 getScroll: function(){
3839 if (isBody(this)) return this.getWindow().getScroll();
3840 return {x: this.scrollLeft, y: this.scrollTop};
3841 },
3842
3843 getScrolls: function(){
3844 var element = this.parentNode, position = {x: 0, y: 0};
3845 while (element && !isBody(element)){
3846 position.x += element.scrollLeft;
3847 position.y += element.scrollTop;
3848 element = element.parentNode;
3849 }
3850 return position;
3851 },
3852
3853 getOffsetParent: brokenOffsetParent ? function(){
3854 var element = this;
3855 if (isBody(element) || styleString(element, 'position') == 'fixed') return n ull;
3856
3857 var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffse tStatic : isOffset;
3858 while ((element = element.parentNode)){
3859 if (isOffsetCheck(element)) return element;
3860 }
3861 return null;
3862 } : function(){
3863 var element = this;
3864 if (isBody(element) || styleString(element, 'position') == 'fixed') return n ull;
3865
3866 try {
3867 return element.offsetParent;
3868 } catch(e) {}
3869 return null;
3870 },
3871
3872 getOffsets: function(){
3873 if (this.getBoundingClientRect && !Browser.Platform.ios){
3874 var bound = this.getBoundingClientRect(),
3875 html = document.id(this.getDocument().documentElement),
3876 htmlScroll = html.getScroll(),
3877 elemScrolls = this.getScrolls(),
3878 isFixed = (styleString(this, 'position') == 'fixed');
3879
3880 return {
3881 x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft,
3882 y: bound.top.toInt() + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop
3883 };
3884 }
3885
3886 var element = this, position = {x: 0, y: 0};
3887 if (isBody(this)) return position;
3888
3889 while (element && !isBody(element)){
3890 position.x += element.offsetLeft;
3891 position.y += element.offsetTop;
3892
3893 if (Browser.firefox){
3894 if (!borderBox(element)){
3895 position.x += leftBorder(element);
3896 position.y += topBorder(element);
3897 }
3898 var parent = element.parentNode;
3899 if (parent && styleString(parent, 'overflow') != 'visible'){
3900 position.x += leftBorder(parent);
3901 position.y += topBorder(parent);
3902 }
3903 } else if (element != this && Browser.safari){
3904 position.x += leftBorder(element);
3905 position.y += topBorder(element);
3906 }
3907
3908 element = element.offsetParent;
3909 }
3910 if (Browser.firefox && !borderBox(this)){
3911 position.x -= leftBorder(this);
3912 position.y -= topBorder(this);
3913 }
3914 return position;
3915 },
3916
3917 getPosition: function(relative){
3918 var offset = this.getOffsets(),
3919 scroll = this.getScrolls();
3920 var position = {
3921 x: offset.x - scroll.x,
3922 y: offset.y - scroll.y
3923 };
3924
3925 if (relative && (relative = document.id(relative))){
3926 var relativePosition = relative.getPosition();
3927 return {x: position.x - relativePosition.x - leftBorder(relative), y: posi tion.y - relativePosition.y - topBorder(relative)};
3928 }
3929 return position;
3930 },
3931
3932 getCoordinates: function(element){
3933 if (isBody(this)) return this.getWindow().getCoordinates();
3934 var position = this.getPosition(element),
3935 size = this.getSize();
3936 var obj = {
3937 left: position.x,
3938 top: position.y,
3939 width: size.x,
3940 height: size.y
3941 };
3942 obj.right = obj.left + obj.width;
3943 obj.bottom = obj.top + obj.height;
3944 return obj;
3945 },
3946
3947 computePosition: function(obj){
3948 return {
3949 left: obj.x - styleNumber(this, 'margin-left'),
3950 top: obj.y - styleNumber(this, 'margin-top')
3951 };
3952 },
3953
3954 setPosition: function(obj){
3955 return this.setStyles(this.computePosition(obj));
3956 }
3957
3958 });
3959
3960
3961 [Document, Window].invoke('implement', {
3962
3963 getSize: function(){
3964 var doc = getCompatElement(this);
3965 return {x: doc.clientWidth, y: doc.clientHeight};
3966 },
3967
3968 getScroll: function(){
3969 var win = this.getWindow(), doc = getCompatElement(this);
3970 return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scro llTop};
3971 },
3972
3973 getScrollSize: function(){
3974 var doc = getCompatElement(this),
3975 min = this.getSize(),
3976 body = this.getDocument().body;
3977
3978 return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(d oc.scrollHeight, body.scrollHeight, min.y)};
3979 },
3980
3981 getPosition: function(){
3982 return {x: 0, y: 0};
3983 },
3984
3985 getCoordinates: function(){
3986 var size = this.getSize();
3987 return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, widt h: size.x};
3988 }
3989
3990 });
3991
3992 // private methods
3993
3994 var styleString = Element.getComputedStyle;
3995
3996 function styleNumber(element, style){
3997 return styleString(element, style).toInt() || 0;
3998 }
3999
4000 function borderBox(element){
4001 return styleString(element, '-moz-box-sizing') == 'border-box';
4002 }
4003
4004 function topBorder(element){
4005 return styleNumber(element, 'border-top-width');
4006 }
4007
4008 function leftBorder(element){
4009 return styleNumber(element, 'border-left-width');
4010 }
4011
4012 function isBody(element){
4013 return (/^(?:body|html)$/i).test(element.tagName);
4014 }
4015
4016 function getCompatElement(element){
4017 var doc = element.getDocument();
4018 return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.bo dy;
4019 }
4020
4021 })();
4022
4023 //aliases
4024 Element.alias({position: 'setPosition'}); //compatability
4025
4026 [Window, Document, Element].invoke('implement', {
4027
4028 getHeight: function(){
4029 return this.getSize().y;
4030 },
4031
4032 getWidth: function(){
4033 return this.getSize().x;
4034 },
4035
4036 getScrollTop: function(){
4037 return this.getScroll().y;
4038 },
4039
4040 getScrollLeft: function(){
4041 return this.getScroll().x;
4042 },
4043
4044 getScrollHeight: function(){
4045 return this.getScrollSize().y;
4046 },
4047
4048 getScrollWidth: function(){
4049 return this.getScrollSize().x;
4050 },
4051
4052 getTop: function(){
4053 return this.getPosition().y;
4054 },
4055
4056 getLeft: function(){
4057 return this.getPosition().x;
4058 }
4059
4060 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698