1/* 2--- 3MooTools: the javascript framework 4 5web build: 6 - http://mootools.net/core/76bf47062d6c1983d66ce47ad66aa0e0 7 8packager build: 9 - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Delegation Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff 10 11... 12*/ 13 14/* 15--- 16 17name: Core 18 19description: The heart of MooTools. 20 21license: MIT-style license. 22 23copyright: Copyright (c) 2006-2012 [Valerio Proietti](http://mad4milk.net/). 24 25authors: The MooTools production team (http://mootools.net/developers/) 26 27inspiration: 28 - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) 29 - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) 30 31provides: [Core, MooTools, Type, typeOf, instanceOf, Native] 32 33... 34*/ 35 36(function(){ 37 38this.MooTools = { 39 version: '1.4.5', 40 build: 'ab8ea8824dc3b24b6666867a2c4ed58ebb762cf0' 41}; 42 43// typeOf, instanceOf 44 45var typeOf = this.typeOf = function(item){ 46 if (item == null) return 'null'; 47 if (item.$family != null) return item.$family(); 48 49 if (item.nodeName){ 50 if (item.nodeType == 1) return 'element'; 51 if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace'; 52 } else if (typeof item.length == 'number'){ 53 if (item.callee) return 'arguments'; 54 if ('item' in item) return 'collection'; 55 } 56 57 return typeof item; 58}; 59 60var instanceOf = this.instanceOf = function(item, object){ 61 if (item == null) return false; 62 var constructor = item.$constructor || item.constructor; 63 while (constructor){ 64 if (constructor === object) return true; 65 constructor = constructor.parent; 66 } 67 /*<ltIE8>*/ 68 if (!item.hasOwnProperty) return false; 69 /*</ltIE8>*/ 70 return item instanceof object; 71}; 72 73// Function overloading 74 75var Function = this.Function; 76 77var enumerables = true; 78for (var i in {toString: 1}) enumerables = null; 79if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor']; 80 81Function.prototype.overloadSetter = function(usePlural){ 82 var self = this; 83 return function(a, b){ 84 if (a == null) return this; 85 if (usePlural || typeof a != 'string'){ 86 for (var k in a) self.call(this, k, a[k]); 87 if (enumerables) for (var i = enumerables.length; i--;){ 88 k = enumerables[i]; 89 if (a.hasOwnProperty(k)) self.call(this, k, a[k]); 90 } 91 } else { 92 self.call(this, a, b); 93 } 94 return this; 95 }; 96}; 97 98Function.prototype.overloadGetter = function(usePlural){ 99 var self = this; 100 return function(a){ 101 var args, result; 102 if (typeof a != 'string') args = a; 103 else if (arguments.length > 1) args = arguments; 104 else if (usePlural) args = [a]; 105 if (args){ 106 result = {}; 107 for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]); 108 } else { 109 result = self.call(this, a); 110 } 111 return result; 112 }; 113}; 114 115Function.prototype.extend = function(key, value){ 116 this[key] = value; 117}.overloadSetter(); 118 119Function.prototype.implement = function(key, value){ 120 this.prototype[key] = value; 121}.overloadSetter(); 122 123// From 124 125var slice = Array.prototype.slice; 126 127Function.from = function(item){ 128 return (typeOf(item) == 'function') ? item : function(){ 129 return item; 130 }; 131}; 132 133Array.from = function(item){ 134 if (item == null) return []; 135 return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item]; 136}; 137 138Number.from = function(item){ 139 var number = parseFloat(item); 140 return isFinite(number) ? number : null; 141}; 142 143String.from = function(item){ 144 return item + ''; 145}; 146 147// hide, protect 148 149Function.implement({ 150 151 hide: function(){ 152 this.$hidden = true; 153 return this; 154 }, 155 156 protect: function(){ 157 this.$protected = true; 158 return this; 159 } 160 161}); 162 163// Type 164 165var Type = this.Type = function(name, object){ 166 if (name){ 167 var lower = name.toLowerCase(); 168 var typeCheck = function(item){ 169 return (typeOf(item) == lower); 170 }; 171 172 Type['is' + name] = typeCheck; 173 if (object != null){ 174 object.prototype.$family = (function(){ 175 return lower; 176 }).hide(); 177 //<1.2compat> 178 object.type = typeCheck; 179 //</1.2compat> 180 } 181 } 182 183 if (object == null) return null; 184 185 object.extend(this); 186 object.$constructor = Type; 187 object.prototype.$constructor = object; 188 189 return object; 190}; 191 192var toString = Object.prototype.toString; 193 194Type.isEnumerable = function(item){ 195 return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' ); 196}; 197 198var hooks = {}; 199 200var hooksOf = function(object){ 201 var type = typeOf(object.prototype); 202 return hooks[type] || (hooks[type] = []); 203}; 204 205var implement = function(name, method){ 206 if (method && method.$hidden) return; 207 208 var hooks = hooksOf(this); 209 210 for (var i = 0; i < hooks.length; i++){ 211 var hook = hooks[i]; 212 if (typeOf(hook) == 'type') implement.call(hook, name, method); 213 else hook.call(this, name, method); 214 } 215 216 var previous = this.prototype[name]; 217 if (previous == null || !previous.$protected) this.prototype[name] = method; 218 219 if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){ 220 return method.apply(item, slice.call(arguments, 1)); 221 }); 222}; 223 224var extend = function(name, method){ 225 if (method && method.$hidden) return; 226 var previous = this[name]; 227 if (previous == null || !previous.$protected) this[name] = method; 228}; 229 230Type.implement({ 231 232 implement: implement.overloadSetter(), 233 234 extend: extend.overloadSetter(), 235 236 alias: function(name, existing){ 237 implement.call(this, name, this.prototype[existing]); 238 }.overloadSetter(), 239 240 mirror: function(hook){ 241 hooksOf(this).push(hook); 242 return this; 243 } 244 245}); 246 247new Type('Type', Type); 248 249// Default Types 250 251var force = function(name, object, methods){ 252 var isType = (object != Object), 253 prototype = object.prototype; 254 255 if (isType) object = new Type(name, object); 256 257 for (var i = 0, l = methods.length; i < l; i++){ 258 var key = methods[i], 259 generic = object[key], 260 proto = prototype[key]; 261 262 if (generic) generic.protect(); 263 if (isType && proto) object.implement(key, proto.protect()); 264 } 265 266 if (isType){ 267 var methodsEnumerable = prototype.propertyIsEnumerable(methods[0]); 268 object.forEachMethod = function(fn){ 269 if (!methodsEnumerable) for (var i = 0, l = methods.length; i < l; i++){ 270 fn.call(prototype, prototype[methods[i]], methods[i]); 271 } 272 for (var key in prototype) fn.call(prototype, prototype[key], key) 273 }; 274 } 275 276 return force; 277}; 278 279force('String', String, [ 280 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search', 281 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpperCase' 282])('Array', Array, [ 283 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 284 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight' 285])('Number', Number, [
286 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision' 287])('Function', Function, [ 288 'apply', 'call', 'bind' 289])('RegExp', RegExp, [ 290 'exec', 'test' 291])('Object', Object, [ 292 'create', 'defineProperty', 'defineProperties', 'keys', 293 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 294 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen' 295])('Date', Date, ['now']); 296 297Object.extend = extend.overloadSetter(); 298 299Date.extend('now', function(){ 300 return +(new Date); 301}); 302 303new Type('Boolean', Boolean); 304 305// fixes NaN returning as Number 306 307Number.prototype.$family = function(){ 308 return isFinite(this) ? 'number' : 'null'; 309}.hide(); 310 311// Number.random 312 313Number.extend('random', function(min, max){ 314 return Math.floor(Math.random() * (max - min + 1) + min); 315}); 316 317// forEach, each 318 319var hasOwnProperty = Object.prototype.hasOwnProperty; 320Object.extend('forEach', function(object, fn, bind){ 321 for (var key in object){ 322 if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object); 323 } 324}); 325 326Object.each = Object.forEach; 327 328Array.implement({ 329 330 forEach: function(fn, bind){ 331 for (var i = 0, l = this.length; i < l; i++){ 332 if (i in this) fn.call(bind, this[i], i, this); 333 } 334 }, 335 336 each: function(fn, bind){ 337 Array.forEach(this, fn, bind); 338 return this; 339 } 340 341}); 342 343// Array & Object cloning, Object merging and appending 344 345var cloneOf = function(item){ 346 switch (typeOf(item)){ 347 case 'array': return item.clone(); 348 case 'object': return Object.clone(item); 349 default: return item; 350 } 351}; 352 353Array.implement('clone', function(){ 354 var i = this.length, clone = new Array(i); 355 while (i--) clone[i] = cloneOf(this[i]); 356 return clone; 357}); 358 359var mergeOne = function(source, key, current){ 360 switch (typeOf(current)){ 361 case 'object': 362 if (typeOf(source[key]) == 'object') Object.merge(source[key], current); 363 else source[key] = Object.clone(current); 364 break; 365 case 'array': source[key] = current.clone(); break; 366 default: source[key] = current; 367 } 368 return source; 369}; 370 371Object.extend({ 372 373 merge: function(source, k, v){ 374 if (typeOf(k) == 'string') return mergeOne(source, k, v); 375 for (var i = 1, l = arguments.length; i < l; i++){ 376 var object = arguments[i]; 377 for (var key in object) mergeOne(source, key, object[key]); 378 } 379 return source; 380 }, 381 382 clone: function(object){ 383 var clone = {}; 384 for (var key in object) clone[key] = cloneOf(object[key]); 385 return clone; 386 }, 387 388 append: function(original){ 389 for (var i = 1, l = arguments.length; i < l; i++){ 390 var extended = arguments[i] || {}; 391 for (var key in extended) original[key] = extended[key]; 392 } 393 return original; 394 } 395 396}); 397 398// Object-less types 399 400['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){ 401 new Type(name); 402}); 403 404// Unique ID 405 406var UID = Date.now(); 407 408String.extend('uniqueID', function(){ 409 return (UID++).toString(36); 410}); 411 412//<1.2compat> 413 414var Hash = this.Hash = new Type('Hash', function(object){ 415 if (typeOf(object) == 'hash') object = Object.clone(object.getClean()); 416 for (var key in object) this[key] = object[key]; 417 return this; 418}); 419 420Hash.implement({ 421 422 forEach: function(fn, bind){ 423 Object.forEach(this, fn, bind); 424 }, 425 426 getClean: function(){ 427 var clean = {}; 428 for (var key in this){ 429 if (this.hasOwnProperty(key)) clean[key] = this[key]; 430 } 431 return clean; 432 }, 433 434 getLength: function(){ 435 var length = 0; 436 for (var key in this){ 437 if (this.hasOwnProperty(key)) length++; 438 } 439 return length; 440 } 441 442}); 443 444Hash.alias('each', 'forEach'); 445 446Object.type = Type.isObject; 447 448var Native = this.Native = function(properties){ 449 return new Type(properties.name, properties.initialize); 450}; 451 452Native.type = Type.type; 453 454Native.implement = function(objects, methods){ 455 for (var i = 0; i < objects.length; i++) objects[i].implement(methods); 456 return Native; 457}; 458 459var arrayType = Array.type; 460Array.type = function(item){ 461 return instanceOf(item, Array) || arrayType(item); 462}; 463 464this.$A = function(item){ 465 return Array.from(item).slice(); 466}; 467 468this.$arguments = function(i){ 469 return function(){ 470 return arguments[i]; 471 }; 472}; 473 474this.$chk = function(obj){ 475 return !!(obj || obj === 0); 476}; 477 478this.$clear = function(timer){ 479 clearTimeout(timer); 480 clearInterval(timer); 481 return null; 482}; 483 484this.$defined = function(obj){ 485 return (obj != null); 486}; 487 488this.$each = function(iterable, fn, bind){ 489 var type = typeOf(iterable); 490 ((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind); 491}; 492 493this.$empty = function(){}; 494 495this.$extend = function(original, extended){ 496 return Object.append(original, extended); 497}; 498 499this.$H = function(object){ 500 return new Hash(object); 501}; 502 503this.$merge = function(){ 504 var args = Array.slice(arguments); 505 args.unshift({});
506 return Object.merge.apply(null, args); 507}; 508 509this.$lambda = Function.from; 510this.$mixin = Object.merge; 511this.$random = Number.random; 512this.$splat = Array.from; 513this.$time = Date.now; 514 515this.$type = function(object){ 516 var type = typeOf(object); 517 if (type == 'elements') return 'array'; 518 return (type == 'null') ? false : type; 519}; 520 521this.$unlink = function(object){ 522 switch (typeOf(object)){ 523 case 'object': return Object.clone(object); 524 case 'array': return Array.clone(object); 525 case 'hash': return new Hash(object); 526 default: return object; 527 } 528}; 529 530//</1.2compat> 531 532})(); 533 534 535/* 536--- 537 538name: Array 539 540description: Contains Array Prototypes like each, contains, and erase. 541 542license: MIT-style license. 543 544requires: Type 545 546provides: Array 547 548... 549*/ 550 551Array.implement({ 552 553 /*<!ES5>*/ 554 every: function(fn, bind){ 555 for (var i = 0, l = this.length >>> 0; i < l; i++){ 556 if ((i in this) && !fn.call(bind, this[i], i, this)) return false; 557 } 558 return true; 559 }, 560 561 filter: function(fn, bind){ 562 var results = []; 563 for (var value, i = 0, l = this.length >>> 0; i < l; i++) if (i in this){ 564 value = this[i]; 565 if (fn.call(bind, value, i, this)) results.push(value); 566 } 567 return results; 568 }, 569 570 indexOf: function(item, from){ 571 var length = this.length >>> 0; 572 for (var i = (from < 0) ? Math.max(0, length + from) : from || 0; i < length; i++){ 573 if (this[i] === item) return i; 574 } 575 return -1; 576 }, 577 578 map: function(fn, bind){ 579 var length = this.length >>> 0, results = Array(length); 580 for (var i = 0; i < length; i++){ 581 if (i in this) results[i] = fn.call(bind, this[i], i, this); 582 } 583 return results; 584 }, 585 586 some: function(fn, bind){ 587 for (var i = 0, l = this.length >>> 0; i < l; i++){ 588 if ((i in this) && fn.call(bind, this[i], i, this)) return true; 589 } 590 return false; 591 }, 592 /*</!ES5>*/ 593 594 clean: function(){ 595 return this.filter(function(item){ 596 return item != null; 597 }); 598 }, 599 600 invoke: function(methodName){ 601 var args = Array.slice(arguments, 1); 602 return this.map(function(item){ 603 return item[methodName].apply(item, args); 604 }); 605 }, 606 607 associate: function(keys){ 608 var obj = {}, length = Math.min(this.length, keys.length); 609 for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; 610 return obj; 611 }, 612 613 link: function(object){ 614 var result = {}; 615 for (var i = 0, l = this.length; i < l; i++){ 616 for (var key in object){ 617 if (object[key](this[i])){ 618 result[key] = this[i]; 619 delete object[key]; 620 break; 621 } 622 } 623 } 624 return result; 625 }, 626 627 contains: function(item, from){ 628 return this.indexOf(item, from) != -1; 629 }, 630 631 append: function(array){ 632 this.push.apply(this, array); 633 return this; 634 }, 635 636 getLast: function(){ 637 return (this.length) ? this[this.length - 1] : null; 638 }, 639 640 getRandom: function(){ 641 return (this.length) ? this[Number.random(0, this.length - 1)] : null; 642 }, 643 644 include: function(item){ 645 if (!this.contains(item)) this.push(item); 646 return this; 647 }, 648 649 combine: function(array){ 650 for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); 651 return this; 652 }, 653 654 erase: function(item){ 655 for (var i = this.length; i--;){ 656 if (this[i] === item) this.splice(i, 1); 657 } 658 return this; 659 }, 660 661 empty: function(){ 662 this.length = 0; 663 return this; 664 }, 665 666 flatten: function(){ 667 var array = []; 668 for (var i = 0, l = this.length; i < l; i++){ 669 var type = typeOf(this[i]); 670 if (type == 'null') continue; 671 array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]); 672 } 673 return array; 674 }, 675 676 pick: function(){ 677 for (var i = 0, l = this.length; i < l; i++){ 678 if (this[i] != null) return this[i]; 679 } 680 return null; 681 }, 682 683 hexToRgb: function(array){ 684 if (this.length != 3) return null; 685 var rgb = this.map(function(value){ 686 if (value.length == 1) value += value; 687 return value.toInt(16); 688 }); 689 return (array) ? rgb : 'rgb(' + rgb + ')'; 690 }, 691 692 rgbToHex: function(array){ 693 if (this.length < 3) return null; 694 if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; 695 var hex = []; 696 for (var i = 0; i < 3; i++){ 697 var bit = (this[i] - 0).toString(16); 698 hex.push((bit.length == 1) ? '0' + bit : bit); 699 } 700 return (array) ? hex : '#' + hex.join(''); 701 } 702 703}); 704 705//<1.2compat> 706 707Array.alias('extend', 'append'); 708 709var $pick = function(){ 710 return Array.from(arguments).pick(); 711}; 712 713//</1.2compat> 714 715 716/* 717--- 718 719name: String 720
721description: Contains String Prototypes like camelCase, capitalize, test, and toInt. 722 723license: MIT-style license. 724 725requires: Type 726 727provides: String 728 729... 730*/ 731 732String.implement({ 733 734 test: function(regex, params){ 735 return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this); 736 }, 737 738 contains: function(string, separator){ 739 return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : String(this).indexOf(string) > -1; 740 }, 741 742 trim: function(){ 743 return String(this).replace(/^\s+|\s+$/g, ''); 744 }, 745 746 clean: function(){ 747 return String(this).replace(/\s+/g, ' ').trim(); 748 }, 749 750 camelCase: function(){ 751 return String(this).replace(/-\D/g, function(match){ 752 return match.charAt(1).toUpperCase(); 753 }); 754 }, 755 756 hyphenate: function(){ 757 return String(this).replace(/[A-Z]/g, function(match){ 758 return ('-' + match.charAt(0).toLowerCase()); 759 }); 760 }, 761 762 capitalize: function(){ 763 return String(this).replace(/\b[a-z]/g, function(match){ 764 return match.toUpperCase(); 765 }); 766 }, 767 768 escapeRegExp: function(){ 769 return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); 770 }, 771 772 toInt: function(base){ 773 return parseInt(this, base || 10); 774 }, 775 776 toFloat: function(){ 777 return parseFloat(this); 778 }, 779 780 hexToRgb: function(array){ 781 var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); 782 return (hex) ? hex.slice(1).hexToRgb(array) : null; 783 }, 784 785 rgbToHex: function(array){ 786 var rgb = String(this).match(/\d{1,3}/g); 787 return (rgb) ? rgb.rgbToHex(array) : null; 788 }, 789 790 substitute: function(object, regexp){ 791 return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ 792 if (match.charAt(0) == '\\') return match.slice(1); 793 return (object[name] != null) ? object[name] : ''; 794 }); 795 } 796 797}); 798 799 800/* 801--- 802 803name: Number 804 805description: Contains Number Prototypes like limit, round, times, and ceil. 806 807license: MIT-style license. 808 809requires: Type 810 811provides: Number 812 813... 814*/ 815 816Number.implement({ 817 818 limit: function(min, max){ 819 return Math.min(max, Math.max(min, this)); 820 }, 821 822 round: function(precision){ 823 precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0); 824 return Math.round(this * precision) / precision; 825 }, 826 827 times: function(fn, bind){ 828 for (var i = 0; i < this; i++) fn.call(bind, i, this); 829 }, 830 831 toFloat: function(){ 832 return parseFloat(this); 833 }, 834 835 toInt: function(base){ 836 return parseInt(this, base || 10); 837 } 838 839}); 840 841Number.alias('each', 'times'); 842 843(function(math){ 844 var methods = {}; 845 math.each(function(name){ 846 if (!Number[name]) methods[name] = function(){ 847 return Math[name].apply(null, [this].concat(Array.from(arguments))); 848 }; 849 }); 850 Number.implement(methods); 851})(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); 852 853 854/* 855--- 856 857name: Function 858 859description: Contains Function Prototypes like create, bind, pass, and delay. 860 861license: MIT-style license. 862 863requires: Type 864 865provides: Function 866 867... 868*/ 869 870Function.extend({ 871 872 attempt: function(){ 873 for (var i = 0, l = arguments.length; i < l; i++){ 874 try { 875 return arguments[i](); 876 } catch (e){} 877 } 878 return null; 879 } 880 881}); 882 883Function.implement({ 884 885 attempt: function(args, bind){ 886 try { 887 return this.apply(bind, Array.from(args)); 888 } catch (e){} 889 890 return null; 891 }, 892 893 /*<!ES5-bind>*/ 894 bind: function(that){ 895 var self = this, 896 args = arguments.length > 1 ? Array.slice(arguments, 1) : null, 897 F = function(){}; 898 899 var bound = function(){ 900 var context = that, length = arguments.length; 901 if (this instanceof bound){ 902 F.prototype = self.prototype; 903 context = new F; 904 } 905 var result = (!args && !length) 906 ? self.call(context) 907 : self.apply(context, args && length ? args.concat(Array.slice(arguments)) : args || arguments); 908 return context == that ? result : context; 909 }; 910 return bound; 911 }, 912 /*</!ES5-bind>*/ 913 914 pass: function(args, bind){ 915 var self = this; 916 if (args != null) args = Array.from(args); 917 return function(){ 918 return self.apply(bind, args || arguments); 919 }; 920 }, 921 922 delay: function(delay, bind, args){ 923 return setTimeout(this.pass((args == null ? [] : args), bind), delay); 924 }, 925 926 periodical: function(periodical, bind, args){ 927 return setInterval(this.pass((args == null ? [] : args), bind), periodical); 928 } 929 930}); 931 932//<1.2compat> 933 934// delete Function.prototype.bind; 935 936Function.implement({ 937 938 create: function(options){ 939 var self = this; 940 options = options || {}; 941 return function(event){ 942 var args = options.arguments; 943 args = (args != null) ? Array.from(args) : Array.slice(arguments, (options.event) ? 1 : 0); 944 if (options.event) args = [event || window.event].extend(args); 945 var returns = function(){
946 return self.apply(options.bind || null, args); 947 }; 948 if (options.delay) return setTimeout(returns, options.delay); 949 if (options.periodical) return setInterval(returns, options.periodical); 950 if (options.attempt) return Function.attempt(returns); 951 return returns(); 952 }; 953 }, 954 955 // bind: function(bind, args){ 956 // var self = this; 957 // if (args != null) args = Array.from(args); 958 // return function(){ 959 // return self.apply(bind, args || arguments); 960 // }; 961 // }, 962 963 bindWithEvent: function(bind, args){ 964 var self = this; 965 if (args != null) args = Array.from(args); 966 return function(event){ 967 return self.apply(bind, (args == null) ? arguments : [event].concat(args)); 968 }; 969 }, 970 971 run: function(args, bind){ 972 return this.apply(bind, Array.from(args)); 973 } 974 975}); 976 977if (Object.create == Function.prototype.create) Object.create = null; 978 979var $try = Function.attempt; 980 981//</1.2compat> 982 983 984/* 985--- 986 987name: Object 988 989description: Object generic methods 990 991license: MIT-style license. 992 993requires: Type 994 995provides: [Object, Hash] 996 997... 998*/ 999 1000(function(){ 1001 1002var hasOwnProperty = Object.prototype.hasOwnProperty; 1003 1004Object.extend({ 1005 1006 subset: function(object, keys){ 1007 var results = {}; 1008 for (var i = 0, l = keys.length; i < l; i++){ 1009 var k = keys[i]; 1010 if (k in object) results[k] = object[k]; 1011 } 1012 return results; 1013 }, 1014 1015 map: function(object, fn, bind){ 1016 var results = {}; 1017 for (var key in object){ 1018 if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object); 1019 } 1020 return results; 1021 }, 1022 1023 filter: function(object, fn, bind){ 1024 var results = {}; 1025 for (var key in object){ 1026 var value = object[key]; 1027 if (hasOwnProperty.call(object, key) && fn.call(bind, value, key, object)) results[key] = value; 1028 } 1029 return results; 1030 }, 1031 1032 every: function(object, fn, bind){ 1033 for (var key in object){ 1034 if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false; 1035 } 1036 return true; 1037 }, 1038 1039 some: function(object, fn, bind){ 1040 for (var key in object){ 1041 if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true; 1042 } 1043 return false; 1044 }, 1045 1046 keys: function(object){ 1047 var keys = []; 1048 for (var key in object){ 1049 if (hasOwnProperty.call(object, key)) keys.push(key); 1050 } 1051 return keys; 1052 }, 1053 1054 values: function(object){ 1055 var values = []; 1056 for (var key in object){ 1057 if (hasOwnProperty.call(object, key)) values.push(object[key]); 1058 } 1059 return values; 1060 }, 1061 1062 getLength: function(object){ 1063 return Object.keys(object).length; 1064 }, 1065 1066 keyOf: function(object, value){ 1067 for (var key in object){ 1068 if (hasOwnProperty.call(object, key) && object[key] === value) return key; 1069 } 1070 return null; 1071 }, 1072 1073 contains: function(object, value){ 1074 return Object.keyOf(object, value) != null; 1075 }, 1076 1077 toQueryString: function(object, base){ 1078 var queryString = []; 1079 1080 Object.each(object, function(value, key){ 1081 if (base) key = base + '[' + key + ']'; 1082 var result; 1083 switch (typeOf(value)){ 1084 case 'object': result = Object.toQueryString(value, key); break; 1085 case 'array': 1086 var qs = {}; 1087 value.each(function(val, i){ 1088 qs[i] = val; 1089 }); 1090 result = Object.toQueryString(qs, key); 1091 break; 1092 default: result = key + '=' + encodeURIComponent(value); 1093 } 1094 if (value != null) queryString.push(result); 1095 }); 1096 1097 return queryString.join('&'); 1098 } 1099 1100}); 1101 1102})(); 1103 1104//<1.2compat> 1105 1106Hash.implement({ 1107 1108 has: Object.prototype.hasOwnProperty, 1109 1110 keyOf: function(value){ 1111 return Object.keyOf(this, value); 1112 }, 1113 1114 hasValue: function(value){ 1115 return Object.contains(this, value); 1116 }, 1117 1118 extend: function(properties){ 1119 Hash.each(properties || {}, function(value, key){ 1120 Hash.set(this, key, value); 1121 }, this); 1122 return this; 1123 }, 1124 1125 combine: function(properties){ 1126 Hash.each(properties || {}, function(value, key){ 1127 Hash.include(this, key, value); 1128 }, this); 1129 return this; 1130 }, 1131 1132 erase: function(key){ 1133 if (this.hasOwnProperty(key)) delete this[key]; 1134 return this; 1135 }, 1136 1137 get: function(key){ 1138 return (this.hasOwnProperty(key)) ? this[key] : null; 1139 }, 1140 1141 set: function(key, value){ 1142 if (!this[key] || this.hasOwnProperty(key)) this[key] = value; 1143 return this; 1144 }, 1145 1146 empty: function(){ 1147 Hash.each(this, function(value, key){ 1148 delete this[key]; 1149 }, this); 1150 return this; 1151 }, 1152 1153 include: function(key, value){ 1154 if (this[key] == null) this[key] = value; 1155 return this; 1156 }, 1157 1158 map: function(fn, bind){ 1159 return new Hash(Object.map(this, fn, bind)); 1160 }, 1161 1162 filter: function(fn, bind){ 1163 return new Hash(Object.filter(this, fn, bind)); 1164 }, 1165 1166 every: function(fn, bind){ 1167 return Object.every(this, fn, bind); 1168 }, 1169 1170 some: function(fn, bind){ 1171 return Object.some(this, fn, bind); 1172 }, 1173 1174 getKeys: function(){ 1175 return Object.keys(this); 1176 }, 1177 1178 getValues: function(){ 1179 return Object.values(this); 1180 }, 1181 1182 toQueryString: function(base){ 1183 return Object.toQueryString(this, base); 1184 } 1185 1186}); 1187 1188Hash.extend = Object.append; 1189 1190Hash.alias({indexOf: 'keyOf', contains: 'hasValue'}); 1191 1192//</1.2compat> 1193 1194 1195/* 1196--- 1197 1198name: Browser 1199 1200description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash. 1201 1202license: MIT-style license. 1203 1204requires: [Array, Function, Number, String] 1205 1206provides: [Browser, Window, Document] 1207 1208... 1209*/ 1210 1211(function(){ 1212 1213var document = this.document; 1214var window = document.window = this; 1215 1216var ua = navigator.userAgent.toLowerCase(), 1217 platform = navigator.platform.toLowerCase(), 1218 UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0], 1219 mode = UA[1] == 'ie' && document.documentMode; 1220 1221var Browser = this.Browser = { 1222 1223 extend: Function.prototype.extend, 1224 1225 name: (UA[1] == 'version') ? UA[3] : UA[1], 1226 1227 version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]), 1228 1229 Platform: { 1230 name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0] 1231 }, 1232 1233 Features: { 1234 xpath: !!(document.evaluate), 1235 air: !!(window.runtime), 1236 query: !!(document.querySelector), 1237 json: !!(window.JSON) 1238 },
1239 1240 Plugins: {} 1241 1242}; 1243 1244Browser[Browser.name] = true; 1245Browser[Browser.name + parseInt(Browser.version, 10)] = true; 1246Browser.Platform[Browser.Platform.name] = true; 1247 1248// Request 1249 1250Browser.Request = (function(){ 1251 1252 var XMLHTTP = function(){ 1253 return new XMLHttpRequest(); 1254 }; 1255 1256 var MSXML2 = function(){ 1257 return new ActiveXObject('MSXML2.XMLHTTP'); 1258 }; 1259 1260 var MSXML = function(){ 1261 return new ActiveXObject('Microsoft.XMLHTTP'); 1262 }; 1263 1264 return Function.attempt(function(){ 1265 XMLHTTP(); 1266 return XMLHTTP; 1267 }, function(){ 1268 MSXML2(); 1269 return MSXML2; 1270 }, function(){ 1271 MSXML(); 1272 return MSXML; 1273 }); 1274 1275})(); 1276 1277Browser.Features.xhr = !!(Browser.Request); 1278 1279// Flash detection 1280 1281var version = (Function.attempt(function(){ 1282 return navigator.plugins['Shockwave Flash'].description; 1283}, function(){ 1284 return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); 1285}) || '0 r0').match(/\d+/g); 1286 1287Browser.Plugins.Flash = { 1288 version: Number(version[0] || '0.' + version[1]) || 0, 1289 build: Number(version[2]) || 0 1290}; 1291 1292// String scripts 1293 1294Browser.exec = function(text){ 1295 if (!text) return text; 1296 if (window.execScript){ 1297 window.execScript(text); 1298 } else { 1299 var script = document.createElement('script'); 1300 script.setAttribute('type', 'text/javascript'); 1301 script.text = text; 1302 document.head.appendChild(script); 1303 document.head.removeChild(script); 1304 } 1305 return text; 1306}; 1307 1308String.implement('stripScripts', function(exec){ 1309 var scripts = ''; 1310 var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(all, code){ 1311 scripts += code + '\n'; 1312 return ''; 1313 }); 1314 if (exec === true) Browser.exec(scripts); 1315 else if (typeOf(exec) == 'function') exec(scripts, text); 1316 return text; 1317}); 1318 1319// Window, Document 1320 1321Browser.extend({ 1322 Document: this.Document, 1323 Window: this.Window, 1324 Element: this.Element, 1325 Event: this.Event 1326}); 1327 1328this.Window = this.$constructor = new Type('Window', function(){}); 1329 1330this.$family = Function.from('window').hide(); 1331 1332Window.mirror(function(name, method){ 1333 window[name] = method; 1334}); 1335 1336this.Document = document.$constructor = new Type('Document', function(){}); 1337 1338document.$family = Function.from('document').hide(); 1339 1340Document.mirror(function(name, method){ 1341 document[name] = method; 1342}); 1343 1344document.html = document.documentElement; 1345if (!document.head) document.head = document.getElementsByTagName('head')[0]; 1346 1347if (document.execCommand) try { 1348 document.execCommand("BackgroundImageCache", false, true); 1349} catch (e){} 1350 1351/*<ltIE9>*/ 1352if (this.attachEvent && !this.addEventListener){ 1353 var unloadEvent = function(){ 1354 this.detachEvent('onunload', unloadEvent); 1355 document.head = document.html = document.window = null; 1356 }; 1357 this.attachEvent('onunload', unloadEvent); 1358} 1359 1360// IE fails on collections and <select>.options (refers to <select>) 1361var arrayFrom = Array.from; 1362try { 1363 arrayFrom(document.html.childNodes); 1364} catch(e){ 1365 Array.from = function(item){ 1366 if (typeof item != 'string' && Type.isEnumerable(item) && typeOf(item) != 'array'){ 1367 var i = item.length, array = new Array(i); 1368 while (i--) array[i] = item[i]; 1369 return array; 1370 } 1371 return arrayFrom(item); 1372 }; 1373 1374 var prototype = Array.prototype, 1375 slice = prototype.slice; 1376 ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice'].each(function(name){ 1377 var method = prototype[name]; 1378 Array[name] = function(item){ 1379 return method.apply(Array.from(item), slice.call(arguments, 1)); 1380 }; 1381 }); 1382} 1383/*</ltIE9>*/ 1384 1385//<1.2compat> 1386 1387if (Browser.Platform.ios) Browser.Platform.ipod = true; 1388 1389Browser.Engine = {}; 1390 1391var setEngine = function(name, version){ 1392 Browser.Engine.name = name; 1393 Browser.Engine[name + version] = true; 1394 Browser.Engine.version = version; 1395}; 1396 1397if (Browser.ie){ 1398 Browser.Engine.trident = true; 1399 1400 switch (Browser.version){ 1401 case 6: setEngine('trident', 4); break; 1402 case 7: setEngine('trident', 5); break; 1403 case 8: setEngine('trident', 6); 1404 } 1405} 1406 1407if (Browser.firefox){ 1408 Browser.Engine.gecko = true; 1409 1410 if (Browser.version >= 3) setEngine('gecko', 19); 1411 else setEngine('gecko', 18); 1412} 1413 1414if (Browser.safari || Browser.chrome){ 1415 Browser.Engine.webkit = true; 1416 1417 switch (Browser.version){ 1418 case 2: setEngine('webkit', 419); break; 1419 case 3: setEngine('webkit', 420); break; 1420 case 4: setEngine('webkit', 525); 1421 } 1422} 1423 1424if (Browser.opera){ 1425 Browser.Engine.presto = true; 1426 1427 if (Browser.version >= 9.6) setEngine('presto', 960); 1428 else if (Browser.version >= 9.5) setEngine('presto', 950); 1429 else setEngine('presto', 925); 1430} 1431 1432if (Browser.name == 'unknown'){ 1433 switch ((ua.match(/(?:webkit|khtml|gecko)/) || [])[0]){ 1434 case 'webkit': 1435 case 'khtml': 1436 Browser.Engine.webkit = true; 1437 break; 1438 case 'gecko': 1439 Browser.Engine.gecko = true; 1440 } 1441} 1442 1443this.$exec = Browser.exec; 1444 1445//</1.2compat> 1446 1447}
1447)(); 1448 1449 1450/* 1451--- 1452 1453name: Event 1454 1455description: Contains the Event Type, to make the event object cross-browser. 1456 1457license: MIT-style license. 1458 1459requires: [Window, Document, Array, Function, String, Object] 1460 1461provides: Event 1462 1463... 1464*/ 1465 1466(function() { 1467 1468var _keys = {}; 1469 1470var DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){ 1471 if (!win) win = window; 1472 event = event || win.event; 1473 if (event.$extended) return event; 1474 this.event = event; 1475 this.$extended = true; 1476 this.shift = event.shiftKey; 1477 this.control = event.ctrlKey; 1478 this.alt = event.altKey; 1479 this.meta = event.metaKey; 1480 var type = this.type = event.type; 1481 var target = event.target || event.srcElement; 1482 while (target && target.nodeType == 3) target = target.parentNode; 1483 this.target = document.id(target); 1484 1485 if (type.indexOf('key') == 0){ 1486 var code = this.code = (event.which || event.keyCode); 1487 this.key = _keys[code]/*<1.3compat>*/ || Object.keyOf(Event.Keys, code)/*</1.3compat>*/; 1488 if (type == 'keydown'){ 1489 if (code > 111 && code < 124) this.key = 'f' + (code - 111); 1490 else if (code > 95 && code < 106) this.key = code - 96; 1491 } 1492 if (this.key == null) this.key = String.fromCharCode(code).toLowerCase(); 1493 } else if (type == 'click' || type == 'dblclick' || type == 'contextmenu' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){ 1494 var doc = win.document; 1495 doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; 1496 this.page = { 1497 x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft, 1498 y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop 1499 }; 1500 this.client = { 1501 x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX, 1502 y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY 1503 }; 1504 if (type == 'DOMMouseScroll' || type == 'mousewheel') 1505 this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; 1506 1507 this.rightClick = (event.which == 3 || event.button == 2); 1508 if (type == 'mouseover' || type == 'mouseout'){ 1509 var related = event.relatedTarget || event[(type == 'mouseover' ? 'from' : 'to') + 'Element']; 1510 while (related && related.nodeType == 3) related = related.parentNode; 1511 this.relatedTarget = document.id(related); 1512 } 1513 } else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){ 1514 this.rotation = event.rotation; 1515 this.scale = event.scale; 1516 this.targetTouches = event.targetTouches; 1517 this.changedTouches = event.changedTouches; 1518 var touches = this.touches = event.touches; 1519 if (touches && touches[0]){ 1520 var touch = touches[0]; 1521 this.page = {x: touch.pageX, y: touch.pageY}; 1522 this.client = {x: touch.clientX, y: touch.clientY}; 1523 } 1524 } 1525 1526 if (!this.client) this.client = {}; 1527 if (!this.page) this.page = {}; 1528}); 1529 1530DOMEvent.implement({ 1531 1532 stop: function(){ 1533 return this.preventDefault().stopPropagation(); 1534 }, 1535 1536 stopPropagation: function(){ 1537 if (this.event.stopPropagation) this.event.stopPropagation(); 1538 else this.event.cancelBubble = true; 1539 return this; 1540 }, 1541 1542 preventDefault: function(){ 1543 if (this.event.preventDefault) this.event.preventDefault(); 1544 else this.event.returnValue = false; 1545 return this; 1546 } 1547 1548}); 1549 1550DOMEvent.defineKey = function(code, key){ 1551 _keys[code] = key; 1552 return this; 1553}; 1554 1555DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true); 1556 1557DOMEvent.defineKeys({ 1558 '38': 'up', '40': 'down', '37': 'left', '39': 'right', 1559 '27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab', 1560 '46': 'delete', '13': 'enter' 1561}); 1562 1563})(); 1564 1565/*<1.3compat>*/ 1566var Event = DOMEvent; 1567Event.Keys = {}; 1568/*</1.3compat>*/ 1569 1570/*<1.2compat>*/ 1571 1572Event.Keys = new Hash(Event.Keys); 1573 1574/*</1.2compat>*/ 1575 1576 1577/* 1578--- 1579 1580name: Class 1581 1582description: Contains the Class Function for easily creating, extending, and implementing reusable Classes. 1583 1584license: MIT-style license. 1585 1586requires: [Array, String, Function, Number] 1587 1588provides: Class 1589 1590... 1591*/ 1592 1593(function(){ 1594 1595var Class = this.Class = new Type('Class', function(params){ 1596 if (instanceOf(params, Function)) params = {initialize: params}; 1597 1598 var newClass = function(){ 1599 reset(this); 1600 if (newClass.$prototyping) return this; 1601 this.$caller = null; 1602 var value = (this.initialize) ? this.initialize.apply(this, arguments) : this; 1603 this.$caller = this.caller = null; 1604 return value; 1605 }.extend(this).implement(params); 1606 1607 newClass.$constructor = Class; 1608 newClass.prototype.$constructor = newClass; 1609 newClass.prototype.parent = parent; 1610 1611 return newClass; 1612}); 1613 1614var parent = function(){
1615 if (!this.$caller) throw new Error('The method "parent" cannot be called.'); 1616 var name = this.$caller.$name, 1617 parent = this.$caller.$owner.parent, 1618 previous = (parent) ? parent.prototype[name] : null; 1619 if (!previous) throw new Error('The method "' + name + '" has no parent.'); 1620 return previous.apply(this, arguments); 1621}; 1622 1623var reset = function(object){ 1624 for (var key in object){ 1625 var value = object[key]; 1626 switch (typeOf(value)){ 1627 case 'object': 1628 var F = function(){}; 1629 F.prototype = value; 1630 object[key] = reset(new F); 1631 break; 1632 case 'array': object[key] = value.clone(); break; 1633 } 1634 } 1635 return object; 1636}; 1637 1638var wrap = function(self, key, method){ 1639 if (method.$origin) method = method.$origin; 1640 var wrapper = function(){ 1641 if (method.$protected && this.$caller == null) throw new Error('The method "' + key + '" cannot be called.'); 1642 var caller = this.caller, current = this.$caller; 1643 this.caller = current; this.$caller = wrapper; 1644 var result = method.apply(this, arguments); 1645 this.$caller = current; this.caller = caller; 1646 return result; 1647 }.extend({$owner: self, $origin: method, $name: key}); 1648 return wrapper; 1649}; 1650 1651var implement = function(key, value, retain){ 1652 if (Class.Mutators.hasOwnProperty(key)){ 1653 value = Class.Mutators[key].call(this, value); 1654 if (value == null) return this; 1655 } 1656 1657 if (typeOf(value) == 'function'){ 1658 if (value.$hidden) return this; 1659 this.prototype[key] = (retain) ? value : wrap(this, key, value); 1660 } else { 1661 Object.merge(this.prototype, key, value); 1662 } 1663 1664 return this; 1665}; 1666 1667var getInstance = function(klass){ 1668 klass.$prototyping = true; 1669 var proto = new klass; 1670 delete klass.$prototyping; 1671 return proto; 1672}; 1673 1674Class.implement('implement', implement.overloadSetter()); 1675 1676Class.Mutators = { 1677 1678 Extends: function(parent){ 1679 this.parent = parent; 1680 this.prototype = getInstance(parent); 1681 }, 1682 1683 Implements: function(items){ 1684 Array.from(items).each(function(item){ 1685 var instance = new item; 1686 for (var key in instance) implement.call(this, key, instance[key], true); 1687 }, this); 1688 } 1689}; 1690 1691})(); 1692 1693 1694/* 1695--- 1696 1697name: Class.Extras 1698 1699description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks. 1700 1701license: MIT-style license. 1702 1703requires: Class 1704 1705provides: [Class.Extras, Chain, Events, Options] 1706 1707... 1708*/ 1709 1710(function(){ 1711 1712this.Chain = new Class({ 1713 1714 $chain: [], 1715 1716 chain: function(){ 1717 this.$chain.append(Array.flatten(arguments)); 1718 return this; 1719 }, 1720 1721 callChain: function(){ 1722 return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false; 1723 }, 1724 1725 clearChain: function(){ 1726 this.$chain.empty(); 1727 return this; 1728 } 1729 1730}); 1731 1732var removeOn = function(string){ 1733 return string.replace(/^on([A-Z])/, function(full, first){ 1734 return first.toLowerCase(); 1735 }); 1736}; 1737 1738this.Events = new Class({ 1739 1740 $events: {}, 1741 1742 addEvent: function(type, fn, internal){ 1743 type = removeOn(type); 1744 1745 /*<1.2compat>*/ 1746 if (fn == $empty) return this; 1747 /*</1.2compat>*/ 1748 1749 this.$events[type] = (this.$events[type] || []).include(fn); 1750 if (internal) fn.internal = true; 1751 return this; 1752 }, 1753 1754 addEvents: function(events){ 1755 for (var type in events) this.addEvent(type, events[type]); 1756 return this; 1757 }, 1758 1759 fireEvent: function(type, args, delay){ 1760 type = removeOn(type); 1761 var events = this.$events[type]; 1762 if (!events) return this; 1763 args = Array.from(args); 1764 events.each(function(fn){ 1765 if (delay) fn.delay(delay, this, args); 1766 else fn.apply(this, args); 1767 }, this); 1768 return this; 1769 }, 1770 1771 removeEvent: function(type, fn){ 1772 type = removeOn(type); 1773 var events = this.$events[type]; 1774 if (events && !fn.internal){ 1775 var index = events.indexOf(fn); 1776 if (index != -1) delete events[index]; 1777 } 1778 return this; 1779 }, 1780 1781 removeEvents: function(events){ 1782 var type; 1783 if (typeOf(events) == 'object'){ 1784 for (type in events) this.removeEvent(type, events[type]); 1785 return this; 1786 } 1787 if (events) events = removeOn(events); 1788 for (type in this.$events){ 1789 if (events && events != type) continue; 1790 var fns = this.$events[type]; 1791 for (var i = fns.length; i--;) if (i in fns){ 1792 this.removeEvent(type, fns[i]); 1793 } 1794 } 1795 return this; 1796 } 1797 1798}); 1799 1800this.Options = new Class({ 1801 1802 setOptions: function(){ 1803 var options = this.options = Object.merge.apply(null, [{}, this.options].append(arguments)); 1804 if (this.addEvent) for (var option in options){ 1805 if (typeOf(options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; 1806 this.addEvent(option, options[option]); 1807 delete options[option]; 1808 } 1809 return this; 1810 } 1811 1812}); 1813 1814})(); 1815 1816 1817/* 1818--- 1819name: Slick.Parser 1820description: Standalone CSS3 Selector parser 1821provides: Slick.Parser 1822... 1823*/ 1824 1825;(function(){ 1826 1827var parsed, 1828 separatorIndex, 1829 combinatorIndex, 1830 reversed, 1831 cache = {}, 1832 reverseCache = {}, 1833 reUnescape = /\\/g; 1834 1835var parse = function(expression, isReversed){ 1836 if (expression == null) return null; 1837 if (expression.Slick === true) return expression; 1838 expression = ('' + expression).replace(/^\s+|\s+$/g, ''); 1839 reversed = !!isReversed; 1840 var currentCache = (reversed) ? reverseCache : cache; 1841 if (currentCache[expression]) return currentCache[expression]; 1842 parsed = { 1843 Slick: true, 1844 expressions: [], 1845 raw: expression, 1846 reverse: function(){ 1847 return parse(this.raw, true); 1848 } 1849 }; 1850 separatorIndex = -1; 1851 while (expression != (expression = expression.replace(regexp, parser))); 1852 parsed.length = parsed.expressions.length; 1853 return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed; 1854}; 1855 1856var reverseCombinator = function(combinator){ 1857 if (combinator === '!') return ' '; 1858 else if (combinator === ' ') return '!'; 1859 else if ((/^!/).test(combinator)) return combinator.replace(/^!/, ''); 1860 else return '!' + combinator; 1861}; 1862 1863var reverse = function(expression){ 1864 var expressions = expression.expressions; 1865 for (var i = 0; i < expressions.length; i++){ 1866 var exp = expressions[i]; 1867 var last = {parts: [], tag: '*', combinator: reverseCombinator(exp[0].combinator)}; 1868 1869 for (var j = 0; j < exp.length; j++){ 1870 var cexp = exp[j]; 1871 if (!cexp.reverseCombinator) cexp.reverseCombinator = ' '; 1872 cexp.combinator = cexp.reverseCombinator; 1873 delete cexp.reverseCombinator; 1874 } 1875 1876 exp.reverse().push(last); 1877 } 1878 return expression; 1879}; 1880 1881var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steven Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License 1882 return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){ 1883 return '\\' + match; 1884 }); 1885}; 1886 1887var regexp = new RegExp( 1888/* 1889#!/usr/bin/env ruby 1890puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'') 1891__END__ 1892 "(?x)^(?:\ 1893 \\s* ( , ) \\s* # Separator \n\ 1894 | \\s* ( <combinator>+ ) \\s* # Combinator \n\ 1895 | ( \\s+ ) # CombinatorChildren \n\ 1896 | ( <unicode>+ | \\* ) # Tag \n\ 1897 | \\# ( <unicode>+ ) # ID \n\ 1898 | \\. ( <unicode>+ ) # ClassName \n\ 1899 | # Attribute \n\ 1900 \\[ \ 1901 \\s* (<unicode1>+) (?: \ 1902 \\s* ([*^$!~|]?=) (?: \ 1903 \\s* (?:\ 1904 ([\"']?)(.*?)\\9 \ 1905 )\ 1906 ) \ 1907 )? \\s* \ 1908 \\](?!\\]) \n\ 1909 | :+ ( <unicode>+ )(?:\ 1910 \\( (?:\ 1911 (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\ 1912 ) \\)\ 1913 )?\ 1914 )" 1915*/ 1916 "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<unicode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"']?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)|((?:\\([^)]+\\)|[^()]*)+))\\))?)" 1917 .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']') 1918 .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])') 1919 .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])') 1920); 1921 1922function parser( 1923 rawMatch, 1924 1925 separator,
1926 combinator, 1927 combinatorChildren, 1928 1929 tagName, 1930 id, 1931 className, 1932 1933 attributeKey, 1934 attributeOperator, 1935 attributeQuote, 1936 attributeValue, 1937 1938 pseudoMarker, 1939 pseudoClass, 1940 pseudoQuote, 1941 pseudoClassQuotedValue, 1942 pseudoClassValue 1943){ 1944 if (separator || separatorIndex === -1){ 1945 parsed.expressions[++separatorIndex] = []; 1946 combinatorIndex = -1; 1947 if (separator) return ''; 1948 } 1949 1950 if (combinator || combinatorChildren || combinatorIndex === -1){ 1951 combinator = combinator || ' '; 1952 var currentSeparator = parsed.expressions[separatorIndex]; 1953 if (reversed && currentSeparator[combinatorIndex]) 1954 currentSeparator[combinatorIndex].reverseCombinator = reverseCombinator(combinator); 1955 currentSeparator[++combinatorIndex] = {combinator: combinator, tag: '*'}; 1956 } 1957 1958 var currentParsed = parsed.expressions[separatorIndex][combinatorIndex]; 1959 1960 if (tagName){ 1961 currentParsed.tag = tagName.replace(reUnescape, ''); 1962 1963 } else if (id){ 1964 currentParsed.id = id.replace(reUnescape, ''); 1965 1966 } else if (className){ 1967 className = className.replace(reUnescape, ''); 1968 1969 if (!currentParsed.classList) currentParsed.classList = []; 1970 if (!currentParsed.classes) currentParsed.classes = []; 1971 currentParsed.classList.push(className); 1972 currentParsed.classes.push({ 1973 value: className, 1974 regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)') 1975 }); 1976 1977 } else if (pseudoClass){ 1978 pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue; 1979 pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(reUnescape, '') : null; 1980 1981 if (!currentParsed.pseudos) currentParsed.pseudos = []; 1982 currentParsed.pseudos.push({ 1983 key: pseudoClass.replace(reUnescape, ''), 1984 value: pseudoClassValue, 1985 type: pseudoMarker.length == 1 ? 'class' : 'element' 1986 }); 1987 1988 } else if (attributeKey){ 1989 attributeKey = attributeKey.replace(reUnescape, ''); 1990 attributeValue = (attributeValue || '').replace(reUnescape, ''); 1991 1992 var test, regexp; 1993 1994 switch (attributeOperator){ 1995 case '^=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) ); break; 1996 case '$=' : regexp = new RegExp( escapeRegExp(attributeValue) +'$' ); break; 1997 case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp(attributeValue) +'(\\s|$)' ); break; 1998 case '|=' : regexp = new RegExp( '^'+ escapeRegExp(attributeValue) +'(-|$)' ); break; 1999 case '=' : test = function(value){ 2000 return attributeValue == value; 2001 }; break; 2002 case '*=' : test = function(value){ 2003 return value && value.indexOf(attributeValue) > -1; 2004 }; break; 2005 case '!=' : test = function(value){ 2006 return attributeValue != value; 2007 }; break; 2008 default : test = function(value){ 2009 return !!value; 2010 }; 2011 } 2012 2013 if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator)) test = function(){ 2014 return false; 2015 }; 2016 2017 if (!test) test = function(value){ 2018 return value && regexp.test(value); 2019 }; 2020 2021 if (!currentParsed.attributes) currentParsed.attributes = []; 2022 currentParsed.attributes.push({ 2023 key: attributeKey, 2024 operator: attributeOperator, 2025 value: attributeValue, 2026 test: test 2027 }); 2028 2029 } 2030 2031 return ''; 2032}; 2033 2034// Slick NS 2035 2036var Slick = (this.Slick || {}); 2037 2038Slick.parse = function(expression){ 2039 return parse(expression); 2040}; 2041 2042Slick.escapeRegExp = escapeRegExp; 2043 2044if (!this.Slick) this.Slick = Slick; 2045 2046}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this); 2047 2048 2049/* 2050--- 2051name: Slick.Finder 2052description: The new, superfast css selector engine. 2053provides: Slick.Finder 2054requires: Slick.Parser 2055... 2056*/ 2057 2058;(function(){ 2059 2060var local = {}, 2061 featuresCache = {}, 2062 toString = Object.prototype.toString; 2063 2064// Feature / Bug detection 2065 2066local.isNativeCode = function(fn){ 2067 return (/\{\s*\[native code\]\s*\}/).test('' + fn); 2068}; 2069 2070local.isXML = function(document){ 2071 return (!!document.xmlVersion) || (!!document.xml) || (toString.call(document) == '[object XMLDocument]') || 2072 (document.nodeType == 9 && document.documentElement.nodeName != 'HTML'); 2073}; 2074 2075local.setDocument = function(document){ 2076 2077 // convert elements / window arguments to document. if document cannot be extrapolated, the function returns. 2078 var nodeType = document.nodeType; 2079 if (nodeType == 9); // document 2080 else if (nodeType) document = document.ownerDocument; // node 2081 else if (document.navigator) document = document.document; // window 2082 else return; 2083 2084 // check if it's the old document 2085 2086 if (this.document === document) return; 2087 this.document = document; 2088 2089 // check if we have done feature detection on this document before 2090 2091 var root = document.documentElement, 2092 rootUid = this.getUIDXML(root), 2093 features = featuresCache[rootUid], 2094 feature; 2095 2096 if (features){ 2097 for (feature in features){ 2098 this[feature] = features[feature]; 2099 } 2100 return; 2101 } 2102 2103 features = featuresCache[rootUid] = {}; 2104 2105 features.root = root; 2106 features.isXMLDocument = this.isXML(document); 2107 2108 features.brokenStarGEBTN 2109 = features.starSelectsClosedQSA 2110 = features.idGetsName 2111 = features.brokenMixedCaseQSA 2112 = features.brokenGEBCN 2113 = features.brokenCheckedQSA 2114 = features.brokenEmptyAttributeQSA 2115 = features.isHTMLDocument 2116 = features.nativeMatchesSelector 2117 = false;
2118 2119 var starSelectsClosed, starSelectsComments, 2120 brokenSecondClassNameGEBCN, cachedGetElementsByClassName, 2121 brokenFormAttributeGetter; 2122 2123 var selected, id = 'slick_uniqueid'; 2124 var testNode = document.createElement('div'); 2125 2126 var testRoot = document.body || document.getElementsByTagName('body')[0] || root; 2127 testRoot.appendChild(testNode); 2128 2129 // on non-HTML documents innerHTML and getElementsById doesnt work properly 2130 try { 2131 testNode.innerHTML = '<a id="'+id+'"></a>'; 2132 features.isHTMLDocument = !!document.getElementById(id); 2133 } catch(e){}; 2134 2135 if (features.isHTMLDocument){ 2136 2137 testNode.style.display = 'none'; 2138 2139 // IE returns comment nodes for getElementsByTagName('*') for some documents 2140 testNode.appendChild(document.createComment('')); 2141 starSelectsComments = (testNode.getElementsByTagName('*').length > 1); 2142 2143 // IE returns closed nodes (EG:"</foo>") for getElementsByTagName('*') for some documents 2144 try { 2145 testNode.innerHTML = 'foo</foo>'; 2146 selected = testNode.getElementsByTagName('*'); 2147 starSelectsClosed = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/'); 2148 } catch(e){}; 2149 2150 features.brokenStarGEBTN = starSelectsComments || starSelectsClosed; 2151 2152 // IE returns elements with the name instead of just id for getElementsById for some documents 2153 try { 2154 testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ id +'"></b>'; 2155 features.idGetsName = document.getElementById(id) === testNode.firstChild; 2156 } catch(e){}; 2157 2158 if (testNode.getElementsByClassName){ 2159 2160 // Safari 3.2 getElementsByClassName caches results 2161 try { 2162 testNode.innerHTML = '<a class="f"></a><a class="b"></a>'; 2163 testNode.getElementsByClassName('b').length; 2164 testNode.firstChild.className = 'b'; 2165 cachedGetElementsByClassName = (testNode.getElementsByClassName('b').length != 2); 2166 } catch(e){}; 2167 2168 // Opera 9.6 getElementsByClassName doesnt detects the class if its not the first one 2169 try { 2170 testNode.innerHTML = '<a class="a"></a><a class="f b a"></a>'; 2171 brokenSecondClassNameGEBCN = (testNode.getElementsByClassName('a').length != 2); 2172 } catch(e){}; 2173 2174 features.brokenGEBCN = cachedGetElementsByClassName || brokenSecondClassNameGEBCN; 2175 } 2176 2177 if (testNode.querySelectorAll){ 2178 // IE 8 returns closed nodes (EG:"</foo>") for querySelectorAll('*') for some documents 2179 try { 2180 testNode.innerHTML = 'foo</foo>'; 2181 selected = testNode.querySelectorAll('*'); 2182 features.starSelectsClosedQSA = (selected && !!selected.length && selected[0].nodeName.charAt(0) == '/'); 2183 } catch(e){}; 2184 2185 // Safari 3.2 querySelectorAll doesnt work with mixedcase on quirksmode 2186 try { 2187 testNode.innerHTML = '<a class="MiX"></a>'; 2188 features.brokenMixedCaseQSA = !testNode.querySelectorAll('.MiX').length; 2189 } catch(e){}; 2190 2191 // Webkit and Opera dont return selected options on querySelectorAll 2192 try { 2193 testNode.innerHTML = '<select><option selected="selected">a</option></select>'; 2194 features.brokenCheckedQSA = (testNode.querySelectorAll(':checked').length == 0); 2195 } catch(e){}; 2196 2197 // IE returns incorrect results for attr[*^$]="" selectors on querySelectorAll 2198 try { 2199 testNode.innerHTML = '<a class=""></a>'; 2200 features.brokenEmptyAttributeQSA = (testNode.querySelectorAll('[class*=""]').length != 0); 2201 } catch(e){}; 2202 2203 } 2204 2205 // IE6-7, if a form has an input of id x, form.getAttribute(x) returns a reference to the input 2206 try { 2207 testNode.innerHTML = '<form action="s"><input id="action"/></form>'; 2208 brokenFormAttributeGetter = (testNode.firstChild.getAttribute('action') != 's'); 2209 } catch(e){}; 2210 2211 // native matchesSelector function 2212 2213 features.nativeMatchesSelector = root.matchesSelector || /*root.msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector; 2214 if (features.nativeMatchesSelector) try { 2215 // if matchesSelector trows errors on incorrect sintaxes we can use it 2216 features.nativeMatchesSelector.call(root, ':slick'); 2217 features.nativeMatchesSelector = null; 2218 } catch(e){}; 2219 2220 } 2221 2222 try { 2223 root.slick_expando = 1; 2224 delete root.slick_expando; 2225 features.getUID = this.getUIDHTML; 2226 } catch(e) { 2227 features.getUID = this.getUIDXML; 2228 } 2229 2230 testRoot.removeChild(testNode); 2231 testNode = selected = testRoot = null; 2232 2233 // getAttribute 2234 2235 features.getAttribute = (features.isHTMLDocument && brokenFormAttributeGetter) ? function(node, name){ 2236 var method = this.attributeGetters[name]; 2237 if (method) return method.call(node); 2238 var attributeNode = node.getAttributeNode(name); 2239 return (attributeNode) ? attributeNode.nodeValue : null; 2240 } : function(node, name){ 2241 var method = this.attributeGetters[name]; 2242 return (method) ? method.call(node) : node.getAttribute(name); 2243 }; 2244 2245 // hasAttribute 2246 2247 features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) { 2248 return node.hasAttribute(attribute); 2249 } : function(node, attribute) { 2250 node = node.getAttributeNode(attribute); 2251 return !!(node && (node.specified || node.nodeValue)); 2252 }; 2253 2254 // contains 2255 // FIXME: Add specs: local.contains should be different for xml and html documents? 2256 var nativeRootContains = root && this.isNativeCode(root.contains), 2257 nativeDocumentContains = document && this.isNativeCode(document.contains); 2258 2259 features.contains = (nativeRootContains && nativeDocumentContains) ? function(context, node){ 2260 return context.contains(node); 2261 } : (nativeRootContains && !nativeDocumentContains) ? function(context, node){ 2262 // IE8 does not have .contains on document. 2263 return context === node || ((context === document) ? document.documentElement : context).contains(node); 2264 } : (root && root.compareDocumentPosition) ? function(context, node){ 2265 return context === node || !!(context.compareDocumentPosition(node) & 16); 2266 } : function(context, node){ 2267 if (node) do { 2268 if (node === context) return true; 2269 } while ((node = node.parentNode)); 2270 return false;
2271 }; 2272 2273 // document order sorting 2274 // credits to Sizzle (http://sizzlejs.com/) 2275 2276 features.documentSorter = (root.compareDocumentPosition) ? function(a, b){ 2277 if (!a.compareDocumentPosition || !b.compareDocumentPosition) return 0; 2278 return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1; 2279 } : ('sourceIndex' in root) ? function(a, b){ 2280 if (!a.sourceIndex || !b.sourceIndex) return 0; 2281 return a.sourceIndex - b.sourceIndex; 2282 } : (document.createRange) ? function(a, b){ 2283 if (!a.ownerDocument || !b.ownerDocument) return 0; 2284 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange(); 2285 aRange.setStart(a, 0); 2286 aRange.setEnd(a, 0); 2287 bRange.setStart(b, 0); 2288 bRange.setEnd(b, 0); 2289 return aRange.compareBoundaryPoints(Range.START_TO_END, bRange); 2290 } : null ; 2291 2292 root = null; 2293 2294 for (feature in features){ 2295 this[feature] = features[feature]; 2296 } 2297}; 2298 2299// Main Method 2300 2301var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/, 2302 reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/, 2303 qsaFailExpCache = {}; 2304 2305local.search = function(context, expression, append, first){ 2306 2307 var found = this.found = (first) ? null : (append || []); 2308 2309 if (!context) return found; 2310 else if (context.navigator) context = context.document; // Convert the node from a window to a document 2311 else if (!context.nodeType) return found; 2312 2313 // setup 2314 2315 var parsed, i, 2316 uniques = this.uniques = {}, 2317 hasOthers = !!(append && append.length), 2318 contextIsDocument = (context.nodeType == 9); 2319 2320 if (this.document !== (contextIsDocument ? context : context.ownerDocument)) this.setDocument(context); 2321 2322 // avoid duplicating items already in the append array 2323 if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i])] = true; 2324 2325 // expression checks 2326 2327 if (typeof expression == 'string'){ // expression is a string 2328 2329 /*<simple-selectors-override>*/ 2330 var simpleSelector = expression.match(reSimpleSelector); 2331 simpleSelectors: if (simpleSelector) { 2332 2333 var symbol = simpleSelector[1], 2334 name = simpleSelector[2], 2335 node, nodes; 2336 2337 if (!symbol){ 2338 2339 if (name == '*' && this.brokenStarGEBTN) break simpleSelectors; 2340 nodes = context.getElementsByTagName(name); 2341 if (first) return nodes[0] || null; 2342 for (i = 0; node = nodes[i++];){ 2343 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); 2344 } 2345 2346 } else if (symbol == '#'){ 2347 2348 if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors; 2349 node = context.getElementById(name); 2350 if (!node) return found; 2351 if (this.idGetsName && node.getAttributeNode('id').nodeValue != name) break simpleSelectors; 2352 if (first) return node || null; 2353 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); 2354 2355 } else if (symbol == '.'){ 2356 2357 if (!this.isHTMLDocument || ((!context.getElementsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSelectors; 2358 if (context.getElementsByClassName && !this.brokenGEBCN){ 2359 nodes = context.getElementsByClassName(name); 2360 if (first) return nodes[0] || null; 2361 for (i = 0; node = nodes[i++];){ 2362 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); 2363 } 2364 } else { 2365 var matchClass = new RegExp('(^|\\s)'+ Slick.escapeRegExp(name) +'(\\s|$)'); 2366 nodes = context.getElementsByTagName('*'); 2367 for (i = 0; node = nodes[i++];){ 2368 className = node.className; 2369 if (!(className && matchClass.test(className))) continue; 2370 if (first) return node; 2371 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); 2372 } 2373 } 2374 2375 } 2376 2377 if (hasOthers) this.sort(found); 2378 return (first) ? null : found; 2379 2380 } 2381 /*</simple-selectors-override>*/ 2382 2383 /*<query-selector-override>*/ 2384 querySelector: if (context.querySelectorAll) { 2385 2386 if (!this.isHTMLDocument 2387 || qsaFailExpCache[expression] 2388 //TODO: only skip when expression is actually mixed case 2389 || this.brokenMixedCaseQSA 2390 || (this.brokenCheckedQSA && expression.indexOf(':checked') > -1) 2391 || (this.brokenEmptyAttributeQSA && reEmptyAttribute.test(expression)) 2392 || (!contextIsDocument //Abort when !contextIsDocument and... 2393 // there are multiple expressions in the selector 2394 // since we currently only fix non-document rooted QSA for single expression selectors 2395 && expression.indexOf(',') > -1 2396 ) 2397 || Slick.disableQSA 2398 ) break querySelector; 2399 2400 var _expression = expression, _context = context; 2401 if (!contextIsDocument){ 2402 // non-document rooted QSA 2403 // credits to Andrew Dupont 2404 var currentId = _context.getAttribute('id'), slickid = 'slickid__'; 2405 _context.setAttribute('id', slickid); 2406 _expression = '#' + slickid + ' ' + _expression; 2407 context = _context.parentNode; 2408 } 2409 2410 try { 2411 if (first) return context.querySelector(_expression) || null; 2412 else nodes = context.querySelectorAll(_expression); 2413 } catch(e) { 2414 qsaFailExpCache[expression] = 1; 2415 break querySelector; 2416 } finally { 2417 if (!contextIsDocument){ 2418 if (currentId) _context.setAttribute('id', currentId); 2419 else _context.removeAttribute('id'); 2420 context = _context; 2421 } 2422 } 2423 2424 if (this.starSelectsClosedQSA) for (i = 0; node = nodes[i++];){ 2425 if (node.nodeName > '@' && !(hasOthers && uniques[this.getUID(node)])) found.push(node); 2426 } else for (i = 0; node = nodes[i++];){ 2427 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node); 2428 } 2429 2430 if (hasOthers) this.sort(found); 2431 return found; 2432 2433 } 2434 /*</query-selector-override>*/ 2435 2436 parsed = this.Slick.parse(expression); 2437 if (!parsed.length) return found; 2438 } else if (expression == null){ // there is no expression 2439 return found; 2440 } else if (expression.Slick){ // expression is a parsed Slick object 2441 parsed = expression; 2442 } else if (this.contains(context.documentElement || context, expression)){ // expression is a node 2443 (found) ? found.push(expression) : found = expression; 2444 return found; 2445 } else { // other junk 2446 return found; 2447 } 2448 2449 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/ 2450 2451 // cache elements for the nth selectors 2452 2453 this.posNTH = {}; 2454 this.posNTHLast = {}; 2455 this.posNTHType = {}; 2456 this.posNTHTypeLast = {}; 2457 2458 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/ 2459 2460 // if append is null and there is only a single selector with one expression use pushArray, else use pushUID 2461 this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expressions[0].length == 1))) ? this.pushArray : this.pushUID; 2462 2463 if (found == null) found = []; 2464 2465 // default engine 2466 2467 var j, m, n; 2468 var combinator, tag, id, classList, classes, attributes, pseudos; 2469 var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions; 2470 2471 search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){ 2472 2473 combinator = 'combinator:' + currentBit.combinator; 2474 if (!this[combinator]) continue search; 2475 2476 tag = (this.isXMLDocument) ? currentBit.tag : currentBit.tag.toUpperCase(); 2477 id = currentBit.id; 2478 classList = currentBit.classList; 2479 classes = currentBit.classes; 2480 attributes = currentBit.attributes; 2481 pseudos = currentBit.pseudos; 2482 lastBit = (j === (currentExpression.length - 1)); 2483 2484 this.bitUniques = {}; 2485 2486 if (lastBit){ 2487 this.uniques = uniques; 2488 this.found = found; 2489 } else { 2490 this.uniques = {}; 2491 this.found = []; 2492 } 2493 2494 if (j === 0){ 2495 this[combinator](context, tag, id, classes, attributes, pseudos, classList); 2496 if (first && lastBit && found.length) break search; 2497 } else { 2498 if (first && lastBit) for (m = 0, n = currentItems.length; m < n; m++){ 2499 this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList); 2500 if (found.length) break search; 2501 } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classList); 2502 } 2503 2504 currentItems = this.found; 2505 } 2506 2507 // should sort if there are nodes in append and if you pass multiple expressions. 2508 if (hasOthers || (parsed.expressions.length > 1)) this.sort(found); 2509 2510 return (first) ? (found[0] || null) : found; 2511}; 2512 2513// Utils 2514 2515local.uidx = 1; 2516local.uidk = 'slick-uniqueid'; 2517 2518local.getUIDXML = function(node){ 2519 var uid = node.getAttribute(this.uidk); 2520 if (!uid){ 2521 uid = this.uidx++; 2522 node.setAttribute(this.uidk, uid); 2523 } 2524 return uid; 2525}; 2526 2527local.getUIDHTML = function(node){ 2528 return node.uniqueNumber || (node.uniqueNumber = this.uidx++); 2529}; 2530 2531// sort based on the setDocument documentSorter method. 2532 2533local.sort = function(results){ 2534 if (!this.documentSorter) return results; 2535 results.sort(this.documentSorter); 2536 return results; 2537}; 2538 2539/*<pseudo-selectors>*//*<nth-pseudo-selectors>*/ 2540 2541local.cacheNTH = {}; 2542 2543local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/; 2544 2545local.parseNTHArgument = function(argument){ 2546 var parsed = argument.match(this.matchNTH); 2547 if (!parsed) return false;
2548 var special = parsed[2] || false; 2549 var a = parsed[1] || 1; 2550 if (a == '-') a = -1; 2551 var b = +parsed[3] || 0; 2552 parsed = 2553 (special == 'n') ? {a: a, b: b} : 2554 (special == 'odd') ? {a: 2, b: 1} : 2555 (special == 'even') ? {a: 2, b: 0} : {a: 0, b: a}; 2556 2557 return (this.cacheNTH[argument] = parsed); 2558}; 2559 2560local.createNTHPseudo = function(child, sibling, positions, ofType){ 2561 return function(node, argument){ 2562 var uid = this.getUID(node); 2563 if (!this[positions][uid]){ 2564 var parent = node.parentNode; 2565 if (!parent) return false; 2566 var el = parent[child], count = 1; 2567 if (ofType){ 2568 var nodeName = node.nodeName; 2569 do { 2570 if (el.nodeName != nodeName) continue; 2571 this[positions][this.getUID(el)] = count++; 2572 } while ((el = el[sibling])); 2573 } else { 2574 do { 2575 if (el.nodeType != 1) continue; 2576 this[positions][this.getUID(el)] = count++; 2577 } while ((el = el[sibling])); 2578 } 2579 } 2580 argument = argument || 'n'; 2581 var parsed = this.cacheNTH[argument] || this.parseNTHArgument(argument); 2582 if (!parsed) return false; 2583 var a = parsed.a, b = parsed.b, pos = this[positions][uid]; 2584 if (a == 0) return b == pos; 2585 if (a > 0){ 2586 if (pos < b) return false; 2587 } else { 2588 if (b < pos) return false; 2589 } 2590 return ((pos - b) % a) == 0; 2591 }; 2592}; 2593 2594/*</nth-pseudo-selectors>*//*</pseudo-selectors>*/ 2595 2596local.pushArray = function(node, tag, id, classes, attributes, pseudos){ 2597 if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) this.found.push(node); 2598}; 2599 2600local.pushUID = function(node, tag, id, classes, attributes, pseudos){ 2601 var uid = this.getUID(node); 2602 if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, attributes, pseudos)){ 2603 this.uniques[uid] = true; 2604 this.found.push(node); 2605 } 2606}; 2607 2608local.matchNode = function(node, selector){ 2609 if (this.isHTMLDocument && this.nativeMatchesSelector){ 2610 try { 2611 return this.nativeMatchesSelector.call(node, selector.replace(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]')); 2612 } catch(matchError) {} 2613 } 2614 2615 var parsed = this.Slick.parse(selector); 2616 if (!parsed) return true; 2617 2618 // simple (single) selectors 2619 var expressions = parsed.expressions, simpleExpCounter = 0, i; 2620 for (i = 0; (currentExpression = expressions[i]); i++){ 2621 if (currentExpression.length == 1){ 2622 var exp = currentExpression[0]; 2623 if (this.matchSelector(node, (this.isXMLDocument) ? exp.tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true; 2624 simpleExpCounter++; 2625 } 2626 } 2627 2628 if (simpleExpCounter == parsed.length) return false; 2629 2630 var nodes = this.search(this.document, parsed), item; 2631 for (i = 0; item = nodes[i++];){ 2632 if (item === node) return true; 2633 } 2634 return false; 2635}; 2636 2637local.matchPseudo = function(node, name, argument){ 2638 var pseudoName = 'pseudo:' + name; 2639 if (this[pseudoName]) return this[pseudoName](node, argument); 2640 var attribute = this.getAttribute(node, name); 2641 return (argument) ? argument == attribute : !!attribute; 2642}; 2643 2644local.matchSelector = function(node, tag, id, classes, attributes, pseudos){ 2645 if (tag){ 2646 var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeName.toUpperCase(); 2647 if (tag == '*'){ 2648 if (nodeName < '@') return false; // Fix for comment nodes and closed nodes 2649 } else { 2650 if (nodeName != tag) return false; 2651 } 2652 } 2653 2654 if (id && node.getAttribute('id') != id) return false; 2655 2656 var i, part, cls; 2657 if (classes) for (i = classes.length; i--;){ 2658 cls = this.getAttribute(node, 'class'); 2659 if (!(cls && classes[i].regexp.test(cls))) return false; 2660 } 2661 if (attributes) for (i = attributes.length; i--;){ 2662 part = attributes[i]; 2663 if (part.operator ? !part.test(this.getAttribute(node, part.key)) : !this.hasAttribute(node, part.key)) return false; 2664 } 2665 if (pseudos) for (i = pseudos.length; i--;){ 2666 part = pseudos[i]; 2667 if (!this.matchPseudo(node, part.key, part.value)) return false; 2668 } 2669 return true; 2670}; 2671 2672var combinators = { 2673 2674 ' ': function(node, tag, id, classes, attributes, pseudos, classList){ // all child nodes, any level 2675 2676 var i, item, children; 2677 2678 if (this.isHTMLDocument){ 2679 getById: if (id){ 2680 item = this.document.getElementById(id); 2681 if ((!item && node.all) || (this.idGetsName && item && item.getAttributeNode('id').nodeValue != id)){ 2682 // all[id] returns all the elements with that name or id inside node 2683 // if theres just one it will return the element, else it will be a collection 2684 children = node.all[id]; 2685 if (!children) return; 2686 if (!children[0]) children = [children]; 2687 for (i = 0; item = children[i++];){ 2688 var idNode = item.getAttributeNode('id'); 2689 if (idNode && idNode.nodeValue == id){ 2690 this.push(item, tag, null, classes, attributes, pseudos); 2691 break; 2692 } 2693 } 2694 return; 2695 } 2696 if (!item){ 2697 // if the context is in the dom we return, else we will try GEBTN, breaking the getById label 2698 if (this.contains(this.root, node)) return; 2699 else break getById; 2700 } else if (this.document !== node && !this.contains(node, item)) return; 2701 this.push(item, tag, null, classes, attributes, pseudos); 2702 return; 2703 } 2704 getByClass: if (classes && node.getElementsByClassName && !this.brokenGEBCN){ 2705 children = node.getElementsByClassName(classList.join(' ')); 2706 if (!(children && children.length)) break getByClass; 2707 for (i = 0; item = children[i++];) this.push(item, tag, id, null, attributes, pseudos); 2708 return; 2709 } 2710 } 2711 getByTag: { 2712 children = node.getElementsByTagName(tag); 2713 if (!(children && children.length)) break getByTag; 2714 if (!this.brokenStarGEBTN) tag = null; 2715 for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos); 2716 } 2717 }, 2718 2719 '>': function(node, tag, id, classes, attributes, pseudos){ // direct children 2720 if ((node = node.firstChild)) do { 2721 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); 2722 } while ((node = node.nextSibling)); 2723 }, 2724 2725 '+': function(node, tag, id, classes, attributes, pseudos){ // next sibling 2726 while ((node = node.nextSibling)) if (node.nodeType == 1){ 2727 this.push(node, tag, id, classes, attributes, pseudos); 2728 break; 2729 } 2730 }, 2731 2732 '^': function(node, tag, id, classes, attributes, pseudos){ // first child 2733 node = node.firstChild; 2734 if (node){ 2735 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); 2736 else this['combinator:+'](node, tag, id, classes, attributes, pseudos); 2737 } 2738 }, 2739 2740 '~': function(node, tag, id, classes, attributes, pseudos){ // next siblings 2741 while ((node = node.nextSibling)){ 2742 if (node.nodeType != 1) continue; 2743 var uid = this.getUID(node); 2744 if (this.bitUniques[uid]) break; 2745 this.bitUniques[uid] = true; 2746 this.push(node, tag, id, classes, attributes, pseudos); 2747 } 2748 }, 2749 2750 '++': function(node, tag, id, classes, attributes, pseudos){ // next sibling and previous sibling 2751 this['combinator:+'](node, tag, id, classes, attributes, pseudos); 2752 this['combinator:!+'](node, tag, id, classes, attributes, pseudos); 2753 }, 2754 2755 '~~': function(node, tag, id, classes, attributes, pseudos){ // next siblings and previous siblings 2756 this['combinator:~'](node, tag, id, classes, attributes, pseudos); 2757 this['combinator:!~'](node, tag, id, classes, attributes, pseudos); 2758 }, 2759 2760 '!': function(node, tag, id, classes, attributes, pseudos){ // all parent nodes up to document 2761 while ((node = node.parentNode)) if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos); 2762 }, 2763 2764 '!>': function(node, tag, id, classes, attributes, pseudos){ // direct parent (one level) 2765 node = node.parentNode; 2766 if (node !== this.document) this.push(node, tag, id, classes, attributes, pseudos); 2767 }, 2768 2769 '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling 2770 while ((node = node.previousSibling)) if (node.nodeType == 1){ 2771 this.push(node, tag, id, classes, attributes, pseudos); 2772 break; 2773 } 2774 }, 2775 2776 '!^': function(node, tag, id, classes, attributes, pseudos){ // last child 2777 node = node.lastChild; 2778 if (node){ 2779 if (node.nodeType == 1) this.push(node, tag, id, classes, attributes, pseudos); 2780 else this['combinator:!+'](node, tag, id, classes, attributes, pseudos); 2781 } 2782 }, 2783 2784 '!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings 2785 while ((node = node.previousSibling)){ 2786 if (node.nodeType != 1) continue; 2787 var uid = this.getUID(node); 2788 if (this.bitUniques[uid]) break; 2789 this.bitUniques[uid] = true; 2790 this.push(node, tag, id, classes, attributes, pseudos); 2791 } 2792 } 2793 2794}; 2795 2796for (var c in combinators) local['combinator:' + c] = combinators[c]; 2797 2798var pseudos = { 2799 2800 /*<pseudo-selectors>*/ 2801 2802 'empty': function(node){ 2803 var child = node.firstChild; 2804 return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length; 2805 }, 2806 2807 'not': function(node, expression){ 2808 return !this.matchNode(node, expression); 2809 }, 2810 2811 'contains': function(node, text){ 2812 return (node.innerText || node.textContent || '').indexOf(text) > -1; 2813 }, 2814 2815 'first-child': function(node){ 2816 while ((node = node.previousSibling)) if (node.nodeType == 1) return false;
2817 return true; 2818 }, 2819 2820 'last-child': function(node){ 2821 while ((node = node.nextSibling)) if (node.nodeType == 1) return false; 2822 return true; 2823 }, 2824 2825 'only-child': function(node){ 2826 var prev = node; 2827 while ((prev = prev.previousSibling)) if (prev.nodeType == 1) return false; 2828 var next = node; 2829 while ((next = next.nextSibling)) if (next.nodeType == 1) return false; 2830 return true; 2831 }, 2832 2833 /*<nth-pseudo-selectors>*/ 2834 2835 'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH'), 2836 2837 'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'), 2838 2839 'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTHType', true), 2840 2841 'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHTypeLast', true), 2842 2843 'index': function(node, index){ 2844 return this['pseudo:nth-child'](node, '' + (index + 1)); 2845 }, 2846 2847 'even': function(node){ 2848 return this['pseudo:nth-child'](node, '2n'); 2849 }, 2850 2851 'odd': function(node){ 2852 return this['pseudo:nth-child'](node, '2n+1'); 2853 }, 2854 2855 /*</nth-pseudo-selectors>*/ 2856 2857 /*<of-type-pseudo-selectors>*/ 2858 2859 'first-of-type': function(node){ 2860 var nodeName = node.nodeName; 2861 while ((node = node.previousSibling)) if (node.nodeName == nodeName) return false; 2862 return true; 2863 }, 2864 2865 'last-of-type': function(node){ 2866 var nodeName = node.nodeName; 2867 while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false; 2868 return true; 2869 }, 2870 2871 'only-of-type': function(node){ 2872 var prev = node, nodeName = node.nodeName; 2873 while ((prev = prev.previousSibling)) if (prev.nodeName == nodeName) return false; 2874 var next = node; 2875 while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false; 2876 return true; 2877 }, 2878 2879 /*</of-type-pseudo-selectors>*/ 2880 2881 // custom pseudos 2882 2883 'enabled': function(node){ 2884 return !node.disabled; 2885 }, 2886 2887 'disabled': function(node){ 2888 return node.disabled; 2889 }, 2890 2891 'checked': function(node){ 2892 return node.checked || node.selected; 2893 }, 2894 2895 'focus': function(node){ 2896 return this.isHTMLDocument && this.document.activeElement === node && (node.href || node.type || this.hasAttribute(node, 'tabindex')); 2897 }, 2898 2899 'root': function(node){ 2900 return (node === this.root); 2901 }, 2902 2903 'selected': function(node){ 2904 return node.selected; 2905 } 2906 2907 /*</pseudo-selectors>*/ 2908}; 2909 2910for (var p in pseudos) local['pseudo:' + p] = pseudos[p]; 2911 2912// attributes methods 2913 2914var attributeGetters = local.attributeGetters = { 2915 2916 'for': function(){ 2917 return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('for'); 2918 }, 2919 2920 'href': function(){ 2921 return ('href' in this) ? this.getAttribute('href', 2) : this.getAttribute('href'); 2922 }, 2923 2924 'style': function(){ 2925 return (this.style) ? this.style.cssText : this.getAttribute('style'); 2926 }, 2927 2928 'tabindex': function(){ 2929 var attributeNode = this.getAttributeNode('tabindex'); 2930 return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null; 2931 }, 2932 2933 'type': function(){ 2934 return this.getAttribute('type'); 2935 }, 2936 2937 'maxlength': function(){ 2938 var attributeNode = this.getAttributeNode('maxLength'); 2939 return (attributeNode && attributeNode.specified) ? attributeNode.nodeValue : null; 2940 } 2941 2942}; 2943 2944attributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxlength; 2945 2946// Slick 2947 2948var Slick = local.Slick = (this.Slick || {}); 2949 2950Slick.version = '1.1.7'; 2951 2952// Slick finder 2953 2954Slick.search = function(context, expression, append){ 2955 return local.search(context, expression, append); 2956}; 2957 2958Slick.find = function(context, expression){ 2959 return local.search(context, expression, null, true); 2960}; 2961 2962// Slick containment checker 2963 2964Slick.contains = function(container, node){ 2965 local.setDocument(container); 2966 return local.contains(container, node); 2967}; 2968 2969// Slick attribute getter 2970 2971Slick.getAttribute = function(node, name){ 2972 local.setDocument(node); 2973 return local.getAttribute(node, name); 2974}; 2975 2976Slick.hasAttribute = function(node, name){ 2977 local.setDocument(node); 2978 return local.hasAttribute(node, name); 2979}; 2980 2981// Slick matcher 2982 2983Slick.match = function(node, selector){ 2984 if (!(node && selector)) return false; 2985 if (!selector || selector === node) return true; 2986 local.setDocument(node); 2987 return local.matchNode(node, selector); 2988}; 2989 2990// Slick attribute accessor 2991 2992Slick.defineAttributeGetter = function(name, fn){ 2993 local.attributeGetters[name] = fn; 2994 return this; 2995}; 2996 2997Slick.lookupAttributeGetter = function(name){ 2998 return local.attributeGetters[name]; 2999}; 3000 3001// Slick pseudo accessor 3002 3003Slick.definePseudo = function(name, fn){ 3004 local['pseudo:' + name] = function(node, argument){
3005 return fn.call(node, argument); 3006 }; 3007 return this; 3008}; 3009 3010Slick.lookupPseudo = function(name){ 3011 var pseudo = local['pseudo:' + name]; 3012 if (pseudo) return function(argument){ 3013 return pseudo.call(this, argument); 3014 }; 3015 return null; 3016}; 3017 3018// Slick overrides accessor 3019 3020Slick.override = function(regexp, fn){ 3021 local.override(regexp, fn); 3022 return this; 3023}; 3024 3025Slick.isXML = local.isXML; 3026 3027Slick.uidOf = function(node){ 3028 return local.getUIDHTML(node); 3029}; 3030 3031if (!this.Slick) this.Slick = Slick; 3032 3033}).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS>*/this); 3034 3035 3036/* 3037--- 3038 3039name: Element 3040 3041description: One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements. 3042 3043license: MIT-style license. 3044 3045requires: [Window, Document, Array, String, Function, Object, Number, Slick.Parser, Slick.Finder] 3046 3047provides: [Element, Elements, $, $$, Iframe, Selectors] 3048 3049... 3050*/ 3051 3052var Element = function(tag, props){ 3053 var konstructor = Element.Constructors[tag]; 3054 if (konstructor) return konstructor(props); 3055 if (typeof tag != 'string') return document.id(tag).set(props); 3056 3057 if (!props) props = {}; 3058 3059 if (!(/^[\w-]+$/).test(tag)){ 3060 var parsed = Slick.parse(tag).expressions[0][0]; 3061 tag = (parsed.tag == '*') ? 'div' : parsed.tag; 3062 if (parsed.id && props.id == null) props.id = parsed.id; 3063 3064 var attributes = parsed.attributes; 3065 if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){ 3066 attr = attributes[i]; 3067 if (props[attr.key] != null) continue; 3068 3069 if (attr.value != null && attr.operator == '=') props[attr.key] = attr.value; 3070 else if (!attr.value && !attr.operator) props[attr.key] = true; 3071 } 3072 3073 if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' '); 3074 } 3075 3076 return document.newElement(tag, props); 3077}; 3078 3079 3080if (Browser.Element){ 3081 Element.prototype = Browser.Element.prototype; 3082 // IE8 and IE9 require the wrapping. 3083 Element.prototype._fireEvent = (function(fireEvent){ 3084 return function(type, event){ 3085 return fireEvent.call(this, type, event); 3086 }; 3087 })(Element.prototype.fireEvent); 3088} 3089 3090new Type('Element', Element).mirror(function(name){ 3091 if (Array.prototype[name]) return; 3092 3093 var obj = {}; 3094 obj[name] = function(){ 3095 var results = [], args = arguments, elements = true; 3096 for (var i = 0, l = this.length; i < l; i++){ 3097 var element = this[i], result = results[i] = element[name].apply(element, args); 3098 elements = (elements && typeOf(result) == 'element'); 3099 } 3100 return (elements) ? new Elements(results) : results; 3101 }; 3102 3103 Elements.implement(obj); 3104}); 3105 3106if (!Browser.Element){ 3107 Element.parent = Object; 3108 3109 Element.Prototype = { 3110 '$constructor': Element, 3111 '$family': Function.from('element').hide() 3112 }; 3113 3114 Element.mirror(function(name, method){ 3115 Element.Prototype[name] = method; 3116 }); 3117} 3118 3119Element.Constructors = {}; 3120 3121//<1.2compat> 3122 3123Element.Constructors = new Hash; 3124 3125//</1.2compat> 3126 3127var IFrame = new Type('IFrame', function(){ 3128 var params = Array.link(arguments, { 3129 properties: Type.isObject, 3130 iframe: function(obj){ 3131 return (obj != null); 3132 } 3133 }); 3134 3135 var props = params.properties || {}, iframe; 3136 if (params.iframe) iframe = document.id(params.iframe); 3137 var onload = props.onload || function(){}; 3138 delete props.onload; 3139 props.id = props.name = [props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + String.uniqueID()].pick(); 3140 iframe = new Element(iframe || 'iframe', props); 3141 3142 var onLoad = function(){ 3143 onload.call(iframe.contentWindow); 3144 }; 3145 3146 if (window.frames[props.id]) onLoad(); 3147 else iframe.addListener('load', onLoad); 3148 return iframe; 3149}); 3150 3151var Elements = this.Elements = function(nodes){ 3152 if (nodes && nodes.length){ 3153 var uniques = {}, node; 3154 for (var i = 0; node = nodes[i++];){ 3155 var uid = Slick.uidOf(node); 3156 if (!uniques[uid]){ 3157 uniques[uid] = true; 3158 this.push(node); 3159 } 3160 } 3161 } 3162}; 3163 3164Elements.prototype = {length: 0}; 3165Elements.parent = Array; 3166 3167new Type('Elements', Elements).implement({ 3168 3169 filter: function(filter, bind){ 3170 if (!filter) return this; 3171 return new Elements(Array.filter(this, (typeOf(filter) == 'string') ? function(item){ 3172 return item.match(filter); 3173 } : filter, bind)); 3174 }.protect(), 3175 3176 push: function(){ 3177 var length = this.length; 3178 for (var i = 0, l = arguments.length; i < l; i++){ 3179 var item = document.id(arguments[i]); 3180 if (item) this[length++] = item; 3181 } 3182 return (this.length = length); 3183 }.protect(), 3184 3185 unshift: function(){ 3186 var items = []; 3187 for (var i = 0, l = arguments.length; i < l; i++){ 3188 var item = document.id(arguments[i]); 3189 if (item) items.push(item); 3190 } 3191 return Array.prototype.unshift.apply(this, items); 3192 }.protect(), 3193 3194 concat: function(){ 3195 var newElements = new Elements(this); 3196 for (var i = 0, l = arguments.length; i < l; i++){ 3197 var item = arguments[i]; 3198 if (Type.isEnumerable(item)) newElements.append(item); 3199 else newElements.push(item); 3200 } 3201 return newElements; 3202 }.protect(), 3203 3204 append: function(collection){ 3205 for (var i = 0, l = collection.length; i < l; i++) this.push(collection[i]); 3206 return this; 3207 }.protect(), 3208 3209 empty: function(){ 3210 while (this.length) delete this[--this.length]; 3211 return this; 3212 }.protect() 3213 3214}); 3215 3216//<1.2compat> 3217 3218Elements.alias('extend', 'append'); 3219 3220//</1.2compat> 3221 3222(function(){ 3223 3224// FF, IE 3225var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2}; 3226 3227splice.call(object, 1, 1); 3228if (object[1] == 1) Elements.implement('splice', function(){ 3229 var length = this.length; 3230 var result = splice.apply(this, arguments); 3231 while (length >= this.length) delete this[length--]; 3232 return result; 3233}.protect()); 3234 3235Array.forEachMethod(function(method, name){ 3236 Elements.implement(name, method); 3237}); 3238 3239Array.mirror(Elements); 3240 3241/*<ltIE8>*/ 3242var createElementAcceptsHTML; 3243try { 3244 createElementAcceptsHTML = (document.createElement('<input name=x>').name == 'x'); 3245} catch (e){} 3246 3247var escapeQuotes = function(html){ 3248 return ('' + html).replace(/&/g, '&').replace(/"/g, '"'); 3249}; 3250/*</ltIE8>*/ 3251 3252Document.implement({ 3253 3254 newElement: function(tag, props){ 3255 if (props && props.checked != null) props.defaultChecked = props.checked; 3256 /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8 3257 if (createElementAcceptsHTML && props){ 3258 tag = '<' + tag; 3259 if (props.name) tag += ' name="' + escapeQuotes(props.name) + '"'; 3260 if (props.type) tag += ' type="' + escapeQuotes(props.type) + '"'; 3261 tag += '>'; 3262 delete props.name; 3263 delete props.type; 3264 } 3265 /*</ltIE8>*/ 3266 return this.id(this.createElement(tag)).set(props); 3267 } 3268 3269}); 3270 3271})(); 3272 3273(function(){ 3274 3275Slick.uidOf(window); 3276Slick.uidOf(document); 3277 3278Document.implement({ 3279 3280 newTextNode: function(text){ 3281 return this.createTextNode(text); 3282 }, 3283 3284 getDocument: function(){ 3285 return this; 3286 }, 3287
3288 getWindow: function(){ 3289 return this.window; 3290 }, 3291 3292 id: (function(){ 3293 3294 var types = { 3295 3296 string: function(id, nocash, doc){ 3297 id = Slick.find(doc, '#' + id.replace(/(\W)/g, '\\$1')); 3298 return (id) ? types.element(id, nocash) : null; 3299 }, 3300 3301 element: function(el, nocash){ 3302 Slick.uidOf(el); 3303 if (!nocash && !el.$family && !(/^(?:object|embed)$/i).test(el.tagName)){ 3304 var fireEvent = el.fireEvent; 3305 // wrapping needed in IE7, or else crash 3306 el._fireEvent = function(type, event){ 3307 return fireEvent(type, event); 3308 }; 3309 Object.append(el, Element.Prototype); 3310 } 3311 return el; 3312 }, 3313 3314 object: function(obj, nocash, doc){ 3315 if (obj.toElement) return types.element(obj.toElement(doc), nocash); 3316 return null; 3317 } 3318 3319 }; 3320 3321 types.textnode = types.whitespace = types.window = types.document = function(zero){ 3322 return zero; 3323 }; 3324 3325 return function(el, nocash, doc){ 3326 if (el && el.$family && el.uniqueNumber) return el; 3327 var type = typeOf(el); 3328 return (types[type]) ? types[type](el, nocash, doc || document) : null; 3329 }; 3330 3331 })() 3332 3333}); 3334 3335if (window.$ == null) Window.implement('$', function(el, nc){ 3336 return document.id(el, nc, this.document); 3337}); 3338 3339Window.implement({ 3340 3341 getDocument: function(){ 3342 return this.document; 3343 }, 3344 3345 getWindow: function(){ 3346 return this; 3347 } 3348 3349}); 3350 3351[Document, Element].invoke('implement', { 3352 3353 getElements: function(expression){ 3354 return Slick.search(this, expression, new Elements); 3355 }, 3356 3357 getElement: function(expression){ 3358 return document.id(Slick.find(this, expression)); 3359 } 3360 3361}); 3362
3363var contains = {contains: function(element){ 3364 return Slick.contains(this, element); 3365}}; 3366 3367if (!document.contains) Document.implement(contains); 3368if (!document.createElement('div').contains) Element.implement(contains); 3369 3370//<1.2compat> 3371 3372Element.implement('hasChild', function(element){ 3373 return this !== element && this.contains(element); 3374}); 3375 3376(function(search, find, match){ 3377 3378 this.Selectors = {}; 3379 var pseudos = this.Selectors.Pseudo = new Hash(); 3380 3381 var addSlickPseudos = function(){ 3382 for (var name in pseudos) if (pseudos.hasOwnProperty(name)){ 3383 Slick.definePseudo(name, pseudos[name]); 3384 delete pseudos[name]; 3385 } 3386 }; 3387 3388 Slick.search = function(context, expression, append){ 3389 addSlickPseudos(); 3390 return search.call(this, context, expression, append); 3391 }; 3392 3393 Slick.find = function(context, expression){ 3394 addSlickPseudos(); 3395 return find.call(this, context, expression); 3396 }; 3397 3398 Slick.match = function(node, selector){ 3399 addSlickPseudos(); 3400 return match.call(this, node, selector); 3401 }; 3402 3403})(Slick.search, Slick.find, Slick.match); 3404 3405//</1.2compat> 3406 3407// tree walking 3408 3409var injectCombinator = function(expression, combinator){ 3410 if (!expression) return combinator; 3411 3412 expression = Object.clone(Slick.parse(expression)); 3413 3414 var expressions = expression.expressions; 3415 for (var i = expressions.length; i--;) 3416 expressions[i][0].combinator = combinator; 3417 3418 return expression; 3419}; 3420 3421Object.forEach({ 3422 getNext: '~', 3423 getPrevious: '!~', 3424 getParent: '!' 3425}, function(combinator, method){ 3426 Element.implement(method, function(expression){ 3427 return this.getElement(injectCombinator(expression, combinator)); 3428 }); 3429}); 3430 3431Object.forEach({ 3432 getAllNext: '~', 3433 getAllPrevious: '!~', 3434 getSiblings: '~~', 3435 getChildren: '>', 3436 getParents: '!' 3437}, function(combinator, method){ 3438 Element.implement(method, function(expression){ 3439 return this.getElements(injectCombinator(expression, combinator)); 3440 }); 3441}); 3442 3443Element.implement({ 3444 3445 getFirst: function(expression){ 3446 return document.id(Slick.search(this, injectCombinator(expression, '>'))[0]); 3447 }, 3448 3449 getLast: function(expression){ 3450 return document.id(Slick.search(this, injectCombinator(expression, '>')).getLast()); 3451 }, 3452 3453 getWindow: function(){ 3454 return this.ownerDocument.window; 3455 }, 3456 3457 getDocument: function(){ 3458 return this.ownerDocument; 3459 }, 3460 3461 getElementById: function(id){ 3462 return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W)/g, '\\$1'))); 3463 }, 3464 3465 match: function(expression){ 3466 return !expression || Slick.match(this, expression); 3467 } 3468 3469}); 3470 3471//<1.2compat> 3472 3473if (window.$$ == null) Window.implement('$$', function(selector){ 3474 var elements = new Elements; 3475 if (arguments.length == 1 && typeof selector == 'string') return Slick.search(this.document, selector, elements); 3476 var args = Array.flatten(arguments); 3477 for (var i = 0, l = args.length; i < l; i++){ 3478 var item = args[i]; 3479 switch (typeOf(item)){ 3480 case 'element': elements.push(item); break; 3481 case 'string': Slick.search(this.document, item, elements); 3482 } 3483 } 3484 return elements; 3485}); 3486 3487//</1.2compat> 3488 3489if (window.$$ == null) Window.implement('$$', function(selector){ 3490 if (arguments.length == 1){ 3491 if (typeof selector == 'string') return Slick.search(this.document, selector, new Elements); 3492 else if (Type.isEnumerable(selector)) return new Elements(selector); 3493 } 3494 return new Elements(arguments); 3495}); 3496 3497// Inserters 3498 3499var inserters = { 3500 3501 before: function(context, element){ 3502 var parent = element.parentNode; 3503 if (parent) parent.insertBefore(context, element); 3504 }, 3505 3506 after: function(context, element){ 3507 var parent = element.parentNode; 3508 if (parent) parent.insertBefore(context, element.nextSibling); 3509 }, 3510 3511 bottom: function(context, element){ 3512 element.appendChild(context); 3513 }, 3514 3515 top: function(context, element){ 3516 element.insertBefore(context, element.firstChild); 3517 } 3518 3519}; 3520 3521inserters.inside = inserters.bottom; 3522 3523//<1.2compat> 3524 3525Object.each(inserters, function(inserter, where){ 3526 3527 where = where.capitalize(); 3528 3529 var methods = {}; 3530 3531 methods['inject' + where] = function(el){ 3532 inserter(this, document.id(el, true)); 3533 return this; 3534 }; 3535 3536 methods['grab' + where] = function(el){ 3537 inserter(document.id(el, true), this); 3538 return this; 3539 }; 3540 3541 Element.implement(methods); 3542 3543}); 3544 3545//</1.2compat> 3546 3547// getProperty / setProperty 3548 3549var propertyGetters = {}, propertySetters = {}; 3550 3551// properties 3552 3553var properties = {}; 3554Array.forEach([ 3555 'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 3556 'frameBorder', 'rowSpan', 'tabIndex', 'useMap' 3557], function(property){ 3558 properties[property.toLowerCase()] = property; 3559}); 3560 3561properties.html = 'innerHTML'; 3562properties.text = (document.createElement('div').textContent == null) ? 'innerText': 'textContent'; 3563 3564Object.forEach(properties, function(real, key){ 3565 propertySetters[key] = function(node, value){ 3566 node[real] = value; 3567 }; 3568 propertyGetters[key] = function(node){ 3569 return node[real]; 3570 }; 3571}); 3572 3573// Booleans 3574 3575var bools = [ 3576 'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 3577 'disabled', 'readOnly', 'multiple', 'selected', 'noresize', 3578 'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay', 3579 'loop' 3580]; 3581 3582var booleans = {}; 3583Array.forEach(bools, function(bool){ 3584 var lower = bool.toLowerCase(); 3585 booleans[lower] = bool; 3586 propertySetters[lower] = function(node, value){ 3587 node[bool] = !!value; 3588 }; 3589 propertyGetters[lower] = function(node){ 3590 return !!node[bool]; 3591 }; 3592}); 3593 3594// Special cases 3595 3596Object.append(propertySetters, { 3597 3598 'class': function(node, value){ 3599 ('className' in node) ? node.className = (value || '') : node.setAttribute('class', value); 3600 }, 3601 3602 'for': function(node, value){ 3603 ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute('for', value); 3604 }, 3605 3606 'style': function(node, value){ 3607 (node.style) ? node.style.cssText = value : node.setAttribute('style', value); 3608 }, 3609 3610 'value': function(node, value){ 3611 node.value = (value != null) ? value : ''; 3612 } 3613 3614}); 3615 3616propertyGetters['class'] = function(node){ 3617 return ('className' in node) ? node.className || null : node.getAttribute('class'); 3618}; 3619 3620/* <webkit> */ 3621var el = document.createElement('button'); 3622// IE sets type as readonly and throws 3623try { el.type = 'button'; } catch(e){} 3624if (el.type != 'button') propertySetters.type = function(node, value){
3625 node.setAttribute('type', value); 3626}; 3627el = null; 3628/* </webkit> */ 3629 3630/*<IE>*/ 3631var input = document.createElement('input'); 3632input.value = 't'; 3633input.type = 'submit'; 3634if (input.value != 't') propertySetters.type = function(node, type){ 3635 var value = node.value; 3636 node.type = type; 3637 node.value = value; 3638}; 3639input = null; 3640/*</IE>*/ 3641 3642/* getProperty, setProperty */ 3643 3644/* <ltIE9> */ 3645var pollutesGetAttribute = (function(div){ 3646 div.random = 'attribute'; 3647 return (div.getAttribute('random') == 'attribute'); 3648})(document.createElement('div')); 3649 3650/* <ltIE9> */ 3651 3652Element.implement({ 3653 3654 setProperty: function(name, value){ 3655 var setter = propertySetters[name.toLowerCase()]; 3656 if (setter){ 3657 setter(this, value); 3658 } else { 3659 /* <ltIE9> */ 3660 if (pollutesGetAttribute) var attributeWhiteList = this.retrieve('$attributeWhiteList', {}); 3661 /* </ltIE9> */ 3662 3663 if (value == null){ 3664 this.removeAttribute(name); 3665 /* <ltIE9> */ 3666 if (pollutesGetAttribute) delete attributeWhiteList[name]; 3667 /* </ltIE9> */ 3668 } else { 3669 this.setAttribute(name, '' + value); 3670 /* <ltIE9> */ 3671 if (pollutesGetAttribute) attributeWhiteList[name] = true; 3672 /* </ltIE9> */ 3673 } 3674 } 3675 return this; 3676 }, 3677 3678 setProperties: function(attributes){ 3679 for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]); 3680 return this; 3681 }, 3682 3683 getProperty: function(name){ 3684 var getter = propertyGetters[name.toLowerCase()]; 3685 if (getter) return getter(this); 3686 /* <ltIE9> */ 3687 if (pollutesGetAttribute){ 3688 var attr = this.getAttributeNode(name), attributeWhiteList = this.retrieve('$attributeWhiteList', {}); 3689 if (!attr) return null; 3690 if (attr.expando && !attributeWhiteList[name]){ 3691 var outer = this.outerHTML; 3692 // segment by the opening tag and find mention of attribute name 3693 if (outer.substr(0, outer.search(/\/?['"]?>(?![^<]*<['"])/)).indexOf(name) < 0) return null; 3694 attributeWhiteList[name] = true; 3695 } 3696 } 3697 /* </ltIE9> */ 3698 var result = Slick.getAttribute(this, name); 3699 return (!result && !Slick.hasAttribute(this, name)) ? null : result; 3700 }, 3701 3702 getProperties: function(){ 3703 var args = Array.from(arguments); 3704 return args.map(this.getProperty, this).associate(args); 3705 }, 3706 3707 removeProperty: function(name){ 3708 return this.setProperty(name, null); 3709 }, 3710 3711 removeProperties: function(){ 3712 Array.each(arguments, this.removeProperty, this); 3713 return this; 3714 }, 3715 3716 set: function(prop, value){ 3717 var property = Element.Properties[prop]; 3718 (property && property.set) ? property.set.call(this, value) : this.setProperty(prop, value); 3719 }.overloadSetter(), 3720 3721 get: function(prop){ 3722 var property = Element.Properties[prop]; 3723 return (property && property.get) ? property.get.apply(this) : this.getProperty(prop); 3724 }.overloadGetter(), 3725 3726 erase: function(prop){ 3727 var property = Element.Properties[prop]; 3728 (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop); 3729 return this; 3730 }, 3731 3732 hasClass: function(className){ 3733 return this.className.clean().contains(className, ' '); 3734 }, 3735 3736 addClass: function(className){ 3737 if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); 3738 return this; 3739 }, 3740 3741 removeClass: function(className){ 3742 this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1'); 3743 return this; 3744 }, 3745 3746 toggleClass: function(className, force){ 3747 if (force == null) force = !this.hasClass(className); 3748 return (force) ? this.addClass(className) : this.removeClass(className); 3749 }, 3750 3751 adopt: function(){ 3752 var parent = this, fragment, elements = Array.flatten(arguments), length = elements.length; 3753 if (length > 1) parent = fragment = document.createDocumentFragment(); 3754 3755 for (var i = 0; i < length; i++){ 3756 var element = document.id(elements[i], true); 3757 if (element) parent.appendChild(element); 3758 } 3759 3760 if (fragment) this.appendChild(fragment); 3761 3762 return this; 3763 }, 3764 3765 appendText: function(text, where){ 3766 return this.grab(this.getDocument().newTextNode(text), where); 3767 }, 3768 3769 grab: function(el, where){ 3770 inserters[where || 'bottom'](document.id(el, true), this); 3771 return this; 3772 }, 3773 3774 inject: function(el, where){ 3775 inserters[where || 'bottom'](this, document.id(el, true)); 3776 return this; 3777 }, 3778 3779 replaces: function(el){ 3780 el = document.id(el, true); 3781 el.parentNode.replaceChild(this, el); 3782 return this; 3783 }, 3784 3785 wraps: function(el, where){ 3786 el = document.id(el, true); 3787 return this.replaces(el).grab(el, where); 3788 }, 3789 3790 getSelected: function(){ 3791 this.selectedIndex; // Safari 3.2.1 3792 return new Elements(Array.from(this.options).filter(function(option){ 3793 return option.selected; 3794 })); 3795 }, 3796 3797 toQueryString: function(){ 3798 var queryString = []; 3799 this.getElements('input, select, textarea').each(function(el){ 3800 var type = el.type; 3801 if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return; 3802 3803 var value = (el.get('tag') == 'select') ? el.getSelected().map(function(opt){ 3804 // IE 3805 return document.id(opt).get('value'); 3806 }) : ((type == 'radio' || type == 'checkbox') && !el.checked) ? null : el.get('value'); 3807 3808 Array.from(value).each(function(val){ 3809 if (typeof val != 'undefined') queryString.push(encodeURIComponent(el.name) + '=' + encodeURIComponent(val)); 3810 }); 3811 }); 3812 return queryString.join('&'); 3813 } 3814 3815}); 3816
3817var collected = {}, storage = {}; 3818 3819var get = function(uid){ 3820 return (storage[uid] || (storage[uid] = {})); 3821}; 3822 3823var clean = function(item){ 3824 var uid = item.uniqueNumber; 3825 if (item.removeEvents) item.removeEvents(); 3826 if (item.clearAttributes) item.clearAttributes(); 3827 if (uid != null){ 3828 delete collected[uid]; 3829 delete storage[uid]; 3830 } 3831 return item; 3832}; 3833 3834var formProps = {input: 'checked', option: 'selected', textarea: 'value'}; 3835 3836Element.implement({ 3837 3838 destroy: function(){ 3839 var children = clean(this).getElementsByTagName('*'); 3840 Array.each(children, clean); 3841 Element.dispose(this); 3842 return null; 3843 }, 3844 3845 empty: function(){ 3846 Array.from(this.childNodes).each(Element.dispose); 3847 return this; 3848 }, 3849 3850 dispose: function(){ 3851 return (this.parentNode) ? this.parentNode.removeChild(this) : this; 3852 }, 3853 3854 clone: function(contents, keepid){ 3855 contents = contents !== false; 3856 var clone = this.cloneNode(contents), ce = [clone], te = [this], i; 3857 3858 if (contents){ 3859 ce.append(Array.from(clone.getElementsByTagName('*'))); 3860 te.append(Array.from(this.getElementsByTagName('*'))); 3861 } 3862 3863 for (i = ce.length; i--;){ 3864 var node = ce[i], element = te[i]; 3865 if (!keepid) node.removeAttribute('id'); 3866 /*<ltIE9>*/ 3867 if (node.clearAttributes){ 3868 node.clearAttributes(); 3869 node.mergeAttributes(element); 3870 node.removeAttribute('uniqueNumber'); 3871 if (node.options){ 3872 var no = node.options, eo = element.options; 3873 for (var j = no.length; j--;) no[j].selected = eo[j].selected; 3874 } 3875 } 3876 /*</ltIE9>*/ 3877 var prop = formProps[element.tagName.toLowerCase()]; 3878 if (prop && element[prop]) node[prop] = element[prop]; 3879 } 3880 3881 /*<ltIE9>*/ 3882 if (Browser.ie){ 3883 var co = clone.getElementsByTagName('object'), to = this.getElementsByTagName('object'); 3884 for (i = co.length; i--;) co[i].outerHTML = to[i].outerHTML; 3885 } 3886 /*</ltIE9>*/ 3887 return document.id(clone); 3888 } 3889 3890}); 3891 3892[Element, Window, Document].invoke('implement', { 3893 3894 addListener: function(type, fn){ 3895 if (type == 'unload'){ 3896 var old = fn, self = this; 3897 fn = function(){ 3898 self.removeListener('unload', fn); 3899 old(); 3900 }; 3901 } else { 3902 collected[Slick.uidOf(this)] = this; 3903 } 3904 if (this.addEventListener) this.addEventListener(type, fn, !!arguments[2]); 3905 else this.attachEvent('on' + type, fn); 3906 return this; 3907 }, 3908 3909 removeListener: function(type, fn){ 3910 if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]); 3911 else this.detachEvent('on' + type, fn); 3912 return this; 3913 }, 3914 3915 retrieve: function(property, dflt){ 3916 var storage = get(Slick.uidOf(this)), prop = storage[property]; 3917 if (dflt != null && prop == null) prop = storage[property] = dflt; 3918 return prop != null ? prop : null; 3919 }, 3920 3921 store: function(property, value){ 3922 var storage = get(Slick.uidOf(this)); 3923 storage[property] = value; 3924 return this; 3925 }, 3926 3927 eliminate: function(property){ 3928 var storage = get(Slick.uidOf(this)); 3929 delete storage[property]; 3930 return this; 3931 } 3932 3933}); 3934 3935/*<ltIE9>*/ 3936if (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){ 3937 Object.each(collected, clean); 3938 if (window.CollectGarbage) CollectGarbage(); 3939}); 3940/*</ltIE9>*/ 3941 3942Element.Properties = {}; 3943 3944//<1.2compat> 3945 3946Element.Properties = new Hash; 3947 3948//</1.2compat> 3949 3950Element.Properties.style = { 3951 3952 set: function(style){ 3953 this.style.cssText = style; 3954 }, 3955 3956 get: function(){ 3957 return this.style.cssText; 3958 }, 3959 3960 erase: function(){ 3961 this.style.cssText = ''; 3962 } 3963 3964}; 3965 3966Element.Properties.tag = { 3967 3968 get: function(){ 3969 return this.tagName.toLowerCase(); 3970 } 3971 3972}; 3973 3974Element.Properties.html = { 3975 3976 set: function(html){ 3977 if (html == null) html = ''; 3978 else if (typeOf(html) == 'array') html = html.join(''); 3979 this.innerHTML = html; 3980 }, 3981 3982 erase: function(){ 3983 this.innerHTML = ''; 3984 } 3985 3986}; 3987 3988/*<ltIE9>*/ 3989// technique by jdbarlett - http://jdbartlett.com/innershiv/ 3990var div = document.createElement('div'); 3991div.innerHTML = '<nav></nav>'; 3992var supportsHTML5Elements = (div.childNodes.length == 1); 3993if (!supportsHTML5Elements){ 3994 var tags = 'abbr article aside audio canvas datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video'.split(' '), 3995 fragment = document.createDocumentFragment(), l = tags.length; 3996 while (l--) fragment.createElement(tags[l]); 3997} 3998div = null; 3999/*</ltIE9>*/ 4000 4001/*<IE>*/ 4002var supportsTableInnerHTML = Function.attempt(function(){ 4003 var table = document.createElement('table'); 4004 table.innerHTML = '<tr><td></td></tr>'; 4005 return true; 4006}); 4007 4008/*<ltFF4>*/ 4009var tr = document.createElement('tr'), html = '<td></td>'; 4010tr.innerHTML = html; 4011var supportsTRInnerHTML = (tr.innerHTML == html); 4012tr = null; 4013/*</ltFF4>*/ 4014 4015if (!supportsTableInnerHTML || !supportsTRInnerHTML || !supportsHTML5Elements){ 4016 4017 Element.Properties.html.set = (function(set){ 4018 4019 var translations = { 4020 table: [1, '<table>', '</table>'], 4021 select: [1, '<select>', '</select>'], 4022 tbody: [2, '<table><tbody>', '</tbody></table>'], 4023 tr: [3, '<table><tbody><tr>', '</tr></tbody></table>'] 4024 }; 4025 4026 translations.thead = translations.tfoot = translations.tbody; 4027 4028 return function(html){ 4029 var wrap = translations[this.get('tag')]; 4030 if (!wrap && !supportsHTML5Elements) wrap = [0, '', '']; 4031 if (!wrap) return set.call(this, html); 4032 4033 var level = wrap[0], wrapper = document.createElement('div'), target = wrapper; 4034 if (!supportsHTML5Elements) fragment.appendChild(wrapper); 4035 wrapper.innerHTML = [wrap[1], html, wrap[2]].flatten().join(''); 4036 while (level--) target = target.firstChild; 4037 this.empty().adopt(target.childNodes); 4038 if (!supportsHTML5Elements) fragment.removeChild(wrapper); 4039 wrapper = null; 4040 }; 4041 4042 })(Element.Properties.html.set); 4043} 4044/*</IE>*/ 4045 4046/*<ltIE9>*/ 4047var testForm = document.createElement('form'); 4048testForm.innerHTML = '<select><option>s</option></select>'; 4049 4050if (testForm.firstChild.value != 's') Element.Properties.value = { 4051 4052 set: function(value){ 4053 var tag = this.get('tag'); 4054 if (tag != 'select') return this.setProperty('value', value); 4055 var options = this.getElements('option'); 4056 for (var i = 0; i < options.length; i++){ 4057 var option = options[i], 4058 attr = option.getAttributeNode('value'), 4059 optionValue = (attr && attr.specified) ? option.value : option.get('text'); 4060 if (optionValue == value) return option.selected = true; 4061 } 4062 }, 4063 4064 get: function(){ 4065 var option = this, tag = option.get('tag'); 4066 4067 if (tag != 'select' && tag != 'option') return this.getProperty('value'); 4068 4069 if (tag == 'select' && !(option = option.getSelected()[0])) return ''; 4070 4071 var attr = option.getAttributeNode('value'); 4072 return (attr && attr.specified) ? option.value : option.get('text'); 4073 } 4074 4075}; 4076testForm = null; 4077/*</ltIE9>*/ 4078 4079/*<IE>*/ 4080if (document.createElement('div').getAttributeNode('id')) Element.Properties.id = { 4081 set: function(id){ 4082 this.id = this.getAttributeNode('id').value = id; 4083 }, 4084 get: function(){ 4085 return this.id || null; 4086 }, 4087 erase: function(){ 4088 this.id = this.getAttributeNode('id').value = ''; 4089 } 4090}; 4091/*</IE>*/ 4092 4093})(); 4094 4095 4096/* 4097--- 4098 4099name: Element.Style 4100 4101description: Contains methods for interacting with the styles of Elements in a fas
4101hionable way. 4102 4103license: MIT-style license. 4104 4105requires: Element 4106 4107provides: Element.Style 4108 4109... 4110*/ 4111 4112(function(){ 4113 4114var html = document.html; 4115 4116//<ltIE9> 4117// Check for oldIE, which does not remove styles when they're set to null 4118var el = document.createElement('div'); 4119el.style.color = 'red'; 4120el.style.color = null; 4121var doesNotRemoveStyles = el.style.color == 'red'; 4122el = null; 4123//</ltIE9> 4124 4125Element.Properties.styles = {set: function(styles){ 4126 this.setStyles(styles); 4127}}; 4128 4129var hasOpacity = (html.style.opacity != null), 4130 hasFilter = (html.style.filter != null), 4131 reAlpha = /alpha\(opacity=([\d.]+)\)/i; 4132 4133var setVisibility = function(element, opacity){ 4134 element.store('$opacity', opacity); 4135 element.style.visibility = opacity > 0 || opacity == null ? 'visible' : 'hidden'; 4136}; 4137 4138var setOpacity = (hasOpacity ? function(element, opacity){ 4139 element.style.opacity = opacity; 4140} : (hasFilter ? function(element, opacity){ 4141 var style = element.style; 4142 if (!element.currentStyle || !element.currentStyle.hasLayout) style.zoom = 1; 4143 if (opacity == null || opacity == 1) opacity = ''; 4144 else opacity = 'alpha(opacity=' + (opacity * 100).limit(0, 100).round() + ')'; 4145 var filter = style.filter || element.getComputedStyle('filter') || ''; 4146 style.filter = reAlpha.test(filter) ? filter.replace(reAlpha, opacity) : filter + opacity; 4147 if (!style.filter) style.removeAttribute('filter'); 4148} : setVisibility)); 4149 4150var getOpacity = (hasOpacity ? function(element){ 4151 var opacity = element.style.opacity || element.getComputedStyle('opacity'); 4152 return (opacity == '') ? 1 : opacity.toFloat(); 4153} : (hasFilter ? function(element){ 4154 var filter = (element.style.filter || element.getComputedStyle('filter')), 4155 opacity; 4156 if (filter) opacity = filter.match(reAlpha); 4157 return (opacity == null || filter == null) ? 1 : (opacity[1] / 100); 4158} : function(element){ 4159 var opacity = element.retrieve('$opacity'); 4160 if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1); 4161 return opacity; 4162})); 4163 4164var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat'; 4165 4166Element.implement({ 4167 4168 getComputedStyle: function(property){ 4169 if (this.currentStyle) return this.currentStyle[property.camelCase()]; 4170 var defaultView = Element.getDocument(this).defaultView, 4171 computed = defaultView ? defaultView.getComputedStyle(this, null) : null; 4172 return (computed) ? computed.getPropertyValue((property == floatName) ? 'float' : property.hyphenate()) : null; 4173 }, 4174 4175 setStyle: function(property, value){ 4176 if (property == 'opacity'){ 4177 if (value != null) value = parseFloat(value); 4178 setOpacity(this, value); 4179 return this; 4180 } 4181 property = (property == 'float' ? floatName : property).camelCase(); 4182 if (typeOf(value) != 'string'){ 4183 var map = (Element.Styles[property] || '@').split(' '); 4184 value = Array.from(value).map(function(val, i){ 4185 if (!map[i]) return ''; 4186 return (typeOf(val) == 'number') ? map[i].replace('@', Math.round(val)) : val; 4187 }).join(' '); 4188 } else if (value == String(Number(value))){ 4189 value = Math.round(value); 4190 } 4191 this.style[property] = value; 4192 //<ltIE9> 4193 if ((value == '' || value == null) && doesNotRemoveStyles && this.style.removeAttribute){ 4194 this.style.removeAttribute(property); 4195 } 4196 //</ltIE9> 4197 return this; 4198 }, 4199 4200 getStyle: function(property){ 4201 if (property == 'opacity') return getOpacity(this); 4202 property = (property == 'float' ? floatName : property).camelCase(); 4203 var result = this.style[property]; 4204 if (!result || property == 'zIndex'){ 4205 result = []; 4206 for (var style in Element.ShortStyles){ 4207 if (property != style) continue; 4208 for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s)); 4209 return result.join(' '); 4210 } 4211 result = this.getComputedStyle(property); 4212 } 4213 if (result){ 4214 result = String(result); 4215 var color = result.match(/rgba?\([\d\s,]+\)/); 4216 if (color) result = result.replace(color[0], color[0].rgbToHex()); 4217 } 4218 if (Browser.opera || Browser.ie){ 4219 if ((/^(height|width)$/).test(property) && !(/px$/.test(result))){ 4220 var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0; 4221 values.each(function(value){
4222 size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt(); 4223 }, this); 4224 return this['offset' + property.capitalize()] - size + 'px'; 4225 } 4226 if (Browser.ie && (/^border(.+)Width|margin|padding/).test(property) && isNaN(parseFloat(result))){ 4227 return '0px'; 4228 } 4229 } 4230 return result; 4231 }, 4232 4233 setStyles: function(styles){ 4234 for (var style in styles) this.setStyle(style, styles[style]); 4235 return this; 4236 }, 4237 4238 getStyles: function(){ 4239 var result = {}; 4240 Array.flatten(arguments).each(function(key){ 4241 result[key] = this.getStyle(key); 4242 }, this); 4243 return result; 4244 } 4245 4246}); 4247 4248Element.Styles = { 4249 left: '@px', top: '@px', bottom: '@px', right: '@px', 4250 width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px', 4251 backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)', 4252 fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)', 4253 margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)', 4254 borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)', 4255 zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@' 4256}; 4257 4258//<1.3compat> 4259 4260Element.implement({ 4261 4262 setOpacity: function(value){ 4263 setOpacity(this, value); 4264 return this; 4265 }, 4266 4267 getOpacity: function(){ 4268 return getOpacity(this); 4269 } 4270 4271}); 4272 4273Element.Properties.opacity = { 4274 4275 set: function(opacity){ 4276 setOpacity(this, opacity); 4277 setVisibility(this, opacity); 4278 }, 4279 4280 get: function(){ 4281 return getOpacity(this); 4282 } 4283 4284}; 4285 4286//</1.3compat> 4287 4288//<1.2compat> 4289 4290Element.Styles = new Hash(Element.Styles); 4291 4292//</1.2compat> 4293 4294Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}}; 4295 4296['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ 4297 var Short = Element.ShortStyles; 4298 var All = Element.Styles; 4299 ['margin', 'padding'].each(function(style){ 4300 var sd = style + direction; 4301 Short[style][sd] = All[sd] = '@px'; 4302 }); 4303 var bd = 'border' + direction; 4304 Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)'; 4305 var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color'; 4306 Short[bd] = {}; 4307 Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px'; 4308 Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@'; 4309 Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)'; 4310}); 4311 4312})(); 4313 4314 4315/* 4316--- 4317 4318name: Element.Event 4319 4320description: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events, if necessary. 4321 4322license: MIT-style license. 4323 4324requires: [Element, Event] 4325 4326provides: Element.Event 4327 4328... 4329*/ 4330 4331(function(){ 4332 4333Element.Properties.events = {set: function(events){ 4334 this.addEvents(events); 4335}}; 4336 4337[Element, Window, Document].invoke('implement', { 4338 4339 addEvent: function(type, fn){ 4340 var events = this.retrieve('events', {}); 4341 if (!events[type]) events[type] = {keys: [], values: []}; 4342 if (events[type].keys.contains(fn)) return this; 4343 events[type].keys.push(fn); 4344 var realType = type, 4345 custom = Element.Events[type], 4346 condition = fn, 4347 self = this; 4348 if (custom){ 4349 if (custom.onAdd) custom.onAdd.call(this, fn, type); 4350 if (custom.condition){ 4351 condition = function(event){ 4352 if (custom.condition.call(this, event, type)) return fn.call(this, event); 4353 return true; 4354 }; 4355 } 4356 if (custom.base) realType = Function.from(custom.base).call(this, type); 4357 } 4358 var defn = function(){ 4359 return fn.call(self); 4360 }; 4361 var nativeEvent = Element.NativeEvents[realType]; 4362 if (nativeEvent){ 4363 if (nativeEvent == 2){ 4364 defn = function(event){ 4365 event = new DOMEvent(event, self.getWindow()); 4366 if (condition.call(self, event) === false) event.stop(); 4367 }; 4368 } 4369 this.addListener(realType, defn, arguments[2]); 4370 } 4371 events[type].values.push(defn); 4372 return this; 4373 }, 4374 4375 removeEvent: function(type, fn){ 4376 var events = this.retrieve('events'); 4377 if (!events || !events[type]) return this; 4378 var list = events[type]; 4379 var index = list.keys.indexOf(fn); 4380 if (index == -1) return this; 4381 var value = list.values[index]; 4382 delete list.keys[index]; 4383 delete list.values[index]; 4384 var custom = Element.Events[type]; 4385 if (custom){ 4386 if (custom.onRemove) custom.onRemove.call(this, fn, type); 4387 if (custom.base) type = Function.from(custom.base).call(this, type); 4388 } 4389 return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this; 4390 }, 4391 4392 addEvents: function(events){ 4393 for (var event in events) this.addEvent(event, events[event]); 4394 return this; 4395 }, 4396 4397 removeEvents: function(events){ 4398 var type; 4399 if (typeOf(events) == 'object'){ 4400 for (type in events) this.removeEvent(type, events[type]); 4401 return this; 4402 } 4403 var attached = this.retrieve('events'); 4404 if (!attached) return this; 4405 if (!events){ 4406 for (type in attached) this.removeEvents(type); 4407 this.eliminate('events'); 4408 } else if (attached[events]){ 4409 attached[events].keys.each(function(fn){ 4410 this.removeEvent(events, fn); 4411 }, this); 4412 delete attached[events]; 4413 } 4414 return this; 4415 }, 4416 4417 fireEvent: function(type, args, delay){ 4418 var events = this.retrieve('events'); 4419 if (!events || !events[type]) return this; 4420 args = Array.from(args); 4421 4422 events[type].keys.each(function(fn){ 4423 if (delay) fn.delay(delay, this, args); 4424 else fn.apply(this, args); 4425 }, this); 4426 return this; 4427 }, 4428 4429 cloneEvents: function(from, type){ 4430 from = document.id(from); 4431 var events = from.retrieve('events'); 4432 if (!events) return this; 4433 if (!type){ 4434 for (var eventType in events) this.cloneEvents(from, eventType); 4435 } else if (events[type]){ 4436 events[type].keys.each(function(fn){
4437 this.addEvent(type, fn); 4438 }, this); 4439 } 4440 return this; 4441 } 4442 4443}); 4444 4445Element.NativeEvents = { 4446 click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons 4447 mousewheel: 2, DOMMouseScroll: 2, //mouse wheel 4448 mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement 4449 keydown: 2, keypress: 2, keyup: 2, //keyboard 4450 orientationchange: 2, // mobile 4451 touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch 4452 gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture 4453 focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements 4454 load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window 4455 error: 1, abort: 1, scroll: 1 //misc 4456}; 4457 4458Element.Events = {mousewheel: { 4459 base: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel' 4460}}; 4461 4462if ('onmouseenter' in document.documentElement){ 4463 Element.NativeEvents.mouseenter = Element.NativeEvents.mouseleave = 2; 4464} else { 4465 var check = function(event){ 4466 var related = event.relatedTarget; 4467 if (related == null) return true; 4468 if (!related) return false; 4469 return (related != this && related.prefix != 'xul' && typeOf(this) != 'document' && !this.contains(related)); 4470 }; 4471 4472 Element.Events.mouseenter = { 4473 base: 'mouseover', 4474 condition: check 4475 }; 4476 4477 Element.Events.mouseleave = { 4478 base: 'mouseout', 4479 condition: check 4480 }; 4481} 4482 4483/*<ltIE9>*/ 4484if (!window.addEventListener){ 4485 Element.NativeEvents.propertychange = 2; 4486 Element.Events.change = { 4487 base: function(){ 4488 var type = this.type; 4489 return (this.get('tag') == 'input' && (type == 'radio' || type == 'checkbox')) ? 'propertychange' : 'change' 4490 }, 4491 condition: function(event){ 4492 return this.type != 'radio' || (event.event.propertyName == 'checked' && this.checked); 4493 } 4494 } 4495} 4496/*</ltIE9>*/ 4497 4498//<1.2compat> 4499 4500Element.Events = new Hash(Element.Events); 4501 4502//</1.2compat> 4503 4504})(); 4505 4506 4507/* 4508--- 4509 4510name: Element.Delegation 4511 4512description: Extends the Element native object to include the delegate method for more efficient event management. 4513 4514license: MIT-style license. 4515 4516requires: [Element.Event] 4517 4518provides: [Element.Delegation] 4519 4520... 4521*/ 4522 4523(function(){ 4524 4525var eventListenerSupport = !!window.addEventListener; 4526 4527Element.NativeEvents.focusin = Element.NativeEvents.focusout = 2; 4528 4529var bubbleUp = function(self, match, fn, event, target){ 4530 while (target && target != self){ 4531 if (match(target, event)) return fn.call(target, event, target); 4532 target = document.id(target.parentNode); 4533 } 4534}; 4535 4536var map = { 4537 mouseenter: { 4538 base: 'mouseover' 4539 }, 4540 mouseleave: { 4541 base: 'mouseout' 4542 }, 4543 focus: { 4544 base: 'focus' + (eventListenerSupport ? '' : 'in'), 4545 capture: true 4546 }, 4547 blur: { 4548 base: eventListenerSupport ? 'blur' : 'focusout', 4549 capture: true 4550 } 4551}; 4552 4553/*<ltIE9>*/ 4554var _key = '$delegation:'; 4555var formObserver = function(type){ 4556 4557 return { 4558 4559 base: 'focusin', 4560 4561 remove: function(self, uid){ 4562 var list = self.retrieve(_key + type + 'listeners', {})[uid]; 4563 if (list && list.forms) for (var i = list.forms.length; i--;){ 4564 list.forms[i].removeEvent(type, list.fns[i]); 4565 } 4566 }, 4567 4568 listen: function(self, match, fn, event, target, uid){ 4569 var form = (target.get('tag') == 'form') ? target : event.target.getParent('form'); 4570 if (!form) return; 4571 4572 var listeners = self.retrieve(_key + type + 'listeners', {}), 4573 listener = listeners[uid] || {forms: [], fns: []}, 4574 forms = listener.forms, fns = listener.fns; 4575 4576 if (forms.indexOf(form) != -1) return; 4577 forms.push(form); 4578 4579 var _fn = function(event){ 4580 bubbleUp(self, match, fn, event, target); 4581 }; 4582 form.addEvent(type, _fn); 4583 fns.push(_fn); 4584 4585 listeners[uid] = listener; 4586 self.store(_key + type + 'listeners', listeners); 4587 } 4588 }; 4589}; 4590 4591var inputObserver = function(type){ 4592 return { 4593 base: 'focusin', 4594 listen: function(self, match, fn, event, target){ 4595 var events = {blur: function(){ 4596 this.removeEvents(events); 4597 }}; 4598 events[type] = function(event){ 4599 bubbleUp(self, match, fn, event, target); 4600 }; 4601 event.target.addEvents(events); 4602 } 4603 }; 4604}; 4605 4606if (!eventListenerSupport) Object.append(map, { 4607 submit: formObserver('submit'), 4608 reset: formObserver('reset'), 4609 change: inputObserver('change'), 4610 select: inputObserver('select') 4611}); 4612/*</ltIE9>*/ 4613 4614var proto = Element.prototype, 4615 addEvent = proto.addEvent, 4616 removeEvent = proto.removeEvent; 4617 4618var relay = function(old, method){ 4619 return function(type, fn, useCapture){ 4620 if (type.indexOf(':relay') == -1) return old.call(this, type, fn, useCapture); 4621 var parsed = Slick.parse(type).expressions[0][0]; 4622 if (parsed.pseudos[0].key != 'relay') return old.call(this, type, fn, useCapture); 4623 var newType = parsed.tag; 4624 parsed.pseudos.slice(1).each(function(pseudo){ 4625 newType += ':' + pseudo.key + (pseudo.value ? '(' + pseudo.value + ')' : ''); 4626 }); 4627 old.call(this, type, fn); 4628 return method.call(this, newType, parsed.pseudos[0].value, fn); 4629 }; 4630}; 4631 4632var delegation = { 4633 4634 addEvent: function(type, match, fn){ 4635 var storage = this.retrieve('$delegates', {}), stored = storage[type]; 4636 if (stored) for (var _uid in stored){ 4637 if (stored[_uid].fn == fn && stored[_uid].match == match) return this; 4638 } 4639 4640 var _type = type, _match = match, _fn = fn, _map = map[type] || {}; 4641 type = _map.base || _type; 4642 4643 match = function(target){ 4644 return Slick.match(target, _match); 4645 }; 4646 4647 var elementEvent = Element.Events[_type]; 4648 if (elementEvent && elementEvent.condition){ 4649 var __match = match, condition = elementEvent.condition; 4650 match = function(target, event){ 4651 return __match(target, event) && condition.call(target, event, type); 4652 }; 4653 } 4654 4655 var self = this, uid = String.uniqueID(); 4656 var delegator = _map.listen ? function(event, target){ 4657 if (!target && event && event.target) target = event.target; 4658 if (target) _map.listen(self, match, fn, event, target, uid); 4659 } : function(event, target){ 4660 if (!target && event && event.target) target = event.target; 4661 if (target) bubbleUp(self, match, fn, event, target); 4662 }; 4663 4664 if (!stored) stored = {}; 4665 stored[uid] = { 4666 match: _match, 4667 fn: _fn, 4668 delegator: delegator 4669 }; 4670 storage[_type] = stored; 4671 return addEvent.call(this, type, delegator, _map.capture); 4672 }, 4673 4674 removeEvent: function(type, match, fn, _uid){ 4675 var storage = this.retrieve('$delegates', {}), stored = storage[type]; 4676 if (!stored) return this; 4677 4678 if (_uid){ 4679 var _type = type, delegator = stored[_uid].delegator, _map = map[type] || {}; 4680 type = _map.base || _type; 4681 if (_map.remove) _map.remove(this, _uid); 4682 delete stored[_uid]; 4683 storage[_type] = stored; 4684 return removeEvent.call(this, type, delegator); 4685 } 4686 4687 var __uid, s; 4688 if (fn) for (__uid in stored){ 4689 s = stored[__uid]; 4690 if (s.match == match && s.fn == fn) return delegation.removeEvent.call(this, type, match, fn, __uid); 4691 } else for (__uid in stored){ 4692 s = stored[__uid]; 4693 if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid); 4694 } 4695 return this; 4696 } 4697 4698}; 4699 4700[Element, Window, Document].invoke('implement', { 4701 addEvent: relay(addEvent, delegation.addEvent), 4702 removeEvent: relay(removeEvent, delegation.removeEvent) 4703}); 4704 4705})(); 4706 4707 4708/* 4709--- 4710 4711name: Element.Dimensions 4712 4713description: Contains methods to work with size, scroll, or positioning of Elements and the window object. 4714 4715license: MIT-style license. 4716 4717credits: 4718 - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html). 4719 - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui
4719/) code, [BSD License](http://developer.yahoo.com/yui/license.html). 4720 4721requires: [Element, Element.Style] 4722 4723provides: [Element.Dimensions] 4724 4725... 4726*/ 4727 4728(function(){ 4729 4730var element = document.createElement('div'), 4731 child = document.createElement('div'); 4732element.style.height = '0'; 4733element.appendChild(child); 4734var brokenOffsetParent = (child.offsetParent === element); 4735element = child = null; 4736 4737var isOffset = function(el){ 4738 return styleString(el, 'position') != 'static' || isBody(el); 4739}; 4740 4741var isOffsetStatic = function(el){ 4742 return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName); 4743}; 4744 4745Element.implement({ 4746 4747 scrollTo: function(x, y){ 4748 if (isBody(this)){ 4749 this.getWindow().scrollTo(x, y); 4750 } else { 4751 this.scrollLeft = x; 4752 this.scrollTop = y; 4753 } 4754 return this; 4755 }, 4756 4757 getSize: function(){ 4758 if (isBody(this)) return this.getWindow().getSize(); 4759 return {x: this.offsetWidth, y: this.offsetHeight}; 4760 }, 4761 4762 getScrollSize: function(){ 4763 if (isBody(this)) return this.getWindow().getScrollSize(); 4764 return {x: this.scrollWidth, y: this.scrollHeight}; 4765 }, 4766 4767 getScroll: function(){ 4768 if (isBody(this)) return this.getWindow().getScroll(); 4769 return {x: this.scrollLeft, y: this.scrollTop}; 4770 }, 4771 4772 getScrolls: function(){ 4773 var element = this.parentNode, position = {x: 0, y: 0}; 4774 while (element && !isBody(element)){ 4775 position.x += element.scrollLeft; 4776 position.y += element.scrollTop; 4777 element = element.parentNode; 4778 } 4779 return position; 4780 }, 4781 4782 getOffsetParent: brokenOffsetParent ? function(){ 4783 var element = this; 4784 if (isBody(element) || styleString(element, 'position') == 'fixed') return null; 4785 4786 var isOffsetCheck = (styleString(element, 'position') == 'static') ? isOffsetStatic : isOffset; 4787 while ((element = element.parentNode)){ 4788 if (isOffsetCheck(element)) return element; 4789 } 4790 return null; 4791 } : function(){ 4792 var element = this; 4793 if (isBody(element) || styleString(element, 'position') == 'fixed') return null; 4794 4795 try { 4796 return element.offsetParent; 4797 } catch(e) {} 4798 return null; 4799 }, 4800 4801 getOffsets: function(){ 4802 if (this.getBoundingClientRect && !Browser.Platform.ios){ 4803 var bound = this.getBoundingClientRect(), 4804 html = document.id(this.getDocument().documentElement), 4805 htmlScroll = html.getScroll(), 4806 elemScrolls = this.getScrolls(), 4807 isFixed = (styleString(this, 'position') == 'fixed'); 4808 4809 return { 4810 x: bound.left.toInt() + elemScrolls.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft, 4811 y: bound.top.toInt() + elemScrolls.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop 4812 }; 4813 } 4814 4815 var element = this, position = {x: 0, y: 0}; 4816 if (isBody(this)) return position; 4817 4818 while (element && !isBody(element)){ 4819 position.x += element.offsetLeft; 4820 position.y += element.offsetTop; 4821 4822 if (Browser.firefox){ 4823 if (!borderBox(element)){ 4824 position.x += leftBorder(element); 4825 position.y += topBorder(element); 4826 } 4827 var parent = element.parentNode; 4828 if (parent && styleString(parent, 'overflow') != 'visible'){ 4829 position.x += leftBorder(parent); 4830 position.y += topBorder(parent); 4831 } 4832 } else if (element != this && Browser.safari){ 4833 position.x += leftBorder(element); 4834 position.y += topBorder(element); 4835 } 4836 4837 element = element.offsetParent; 4838 } 4839 if (Browser.firefox && !borderBox(this)){ 4840 position.x -= leftBorder(this); 4841 position.y -= topBorder(this); 4842 } 4843 return position; 4844 }, 4845 4846 getPosition: function(relative){ 4847 var offset = this.getOffsets(), 4848 scroll = this.getScrolls(); 4849 var position = { 4850 x: offset.x - scroll.x, 4851 y: offset.y - scroll.y 4852 }; 4853 4854 if (relative && (relative = document.id(relative))){ 4855 var relativePosition = relative.getPosition(); 4856 return {x: position.x - relativePosition.x - leftBorder(relative), y: position.y - relativePosition.y - topBorder(relative)}; 4857 } 4858 return position; 4859 }, 4860 4861 getCoordinates: function(element){ 4862 if (isBody(this)) return this.getWindow().getCoordinates(); 4863 var position = this.getPosition(element), 4864 size = this.getSize(); 4865 var obj = { 4866 left: position.x, 4867 top: position.y, 4868 width: size.x, 4869 height: size.y 4870 }; 4871 obj.right = obj.left + obj.width; 4872 obj.bottom = obj.top + obj.height; 4873 return obj; 4874 }, 4875 4876 computePosition: function(obj){ 4877 return { 4878 left: obj.x - styleNumber(this, 'margin-left'), 4879 top: obj.y - styleNumber(this, 'margin-top') 4880 }; 4881 }, 4882 4883 setPosition: function(obj){ 4884 return this.setStyles(this.computePosition(obj)); 4885 } 4886 4887}); 4888 4889 4890[Document, Window].invoke('implement', { 4891 4892 getSize: function(){ 4893 var doc = getCompatElement(this);
4894 return {x: doc.clientWidth, y: doc.clientHeight}; 4895 }, 4896 4897 getScroll: function(){ 4898 var win = this.getWindow(), doc = getCompatElement(this); 4899 return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop}; 4900 }, 4901 4902 getScrollSize: function(){ 4903 var doc = getCompatElement(this), 4904 min = this.getSize(), 4905 body = this.getDocument().body; 4906 4907 return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y: Math.max(doc.scrollHeight, body.scrollHeight, min.y)}; 4908 }, 4909 4910 getPosition: function(){ 4911 return {x: 0, y: 0}; 4912 }, 4913 4914 getCoordinates: function(){ 4915 var size = this.getSize(); 4916 return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x}; 4917 } 4918 4919}); 4920 4921// private methods 4922 4923var styleString = Element.getComputedStyle; 4924 4925function styleNumber(element, style){ 4926 return styleString(element, style).toInt() || 0; 4927} 4928 4929function borderBox(element){ 4930 return styleString(element, '-moz-box-sizing') == 'border-box'; 4931} 4932 4933function topBorder(element){ 4934 return styleNumber(element, 'border-top-width'); 4935} 4936 4937function leftBorder(element){ 4938 return styleNumber(element, 'border-left-width'); 4939} 4940 4941function isBody(element){ 4942 return (/^(?:body|html)$/i).test(element.tagName); 4943} 4944 4945function getCompatElement(element){ 4946 var doc = element.getDocument(); 4947 return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; 4948} 4949 4950})(); 4951 4952//aliases 4953Element.alias({position: 'setPosition'}); //compatability 4954 4955[Window, Document, Element].invoke('implement', { 4956 4957 getHeight: function(){ 4958 return this.getSize().y; 4959 }, 4960 4961 getWidth: function(){ 4962 return this.getSize().x; 4963 }, 4964 4965 getScrollTop: function(){ 4966 return this.getScroll().y; 4967 }, 4968 4969 getScrollLeft: function(){ 4970 return this.getScroll().x; 4971 }, 4972 4973 getScrollHeight: function(){ 4974 return this.getScrollSize().y; 4975 }, 4976 4977 getScrollWidth: function(){ 4978 return this.getScrollSize().x; 4979 }, 4980 4981 getTop: function(){ 4982 return this.getPosition().y; 4983 }, 4984 4985 getLeft: function(){ 4986 return this.getPosition().x; 4987 } 4988 4989}); 4990 4991 4992/* 4993--- 4994 4995name: Fx 4996 4997description: Contains the basic animation logic to be extended by all other Fx Classes. 4998 4999license: MIT-style license. 5000 5001requires: [Chain, Events, Options] 5002 5003provides: Fx 5004 5005... 5006*/ 5007 5008(function(){ 5009 5010var Fx = this.Fx = new Class({ 5011 5012 Implements: [Chain, Events, Options], 5013 5014 options: { 5015 /* 5016 onStart: nil, 5017 onCancel: nil, 5018 onComplete: nil, 5019 */ 5020 fps: 60, 5021 unit: false, 5022 duration: 500, 5023 frames: null, 5024 frameSkip: true, 5025 link: 'ignore' 5026 }, 5027 5028 initialize: function(options){ 5029 this.subject = this.subject || this; 5030 this.setOptions(options); 5031 }, 5032 5033 getTransition: function(){ 5034 return function(p){ 5035 return -(Math.cos(Math.PI * p) - 1) / 2; 5036 }; 5037 }, 5038 5039 step: function(now){ 5040 if (this.options.frameSkip){ 5041 var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval; 5042 this.time = now; 5043 this.frame += frames; 5044 } else { 5045 this.frame++; 5046 } 5047 5048 if (this.frame < this.frames){ 5049 var delta = this.transition(this.frame / this.frames); 5050 this.set(this.compute(this.from, this.to, delta)); 5051 } else { 5052 this.frame = this.frames; 5053 this.set(this.compute(this.from, this.to, 1)); 5054 this.stop(); 5055 } 5056 }, 5057 5058 set: function(now){ 5059 return now; 5060 }, 5061 5062 compute: function(from, to, delta){ 5063 return Fx.compute(from, to, delta); 5064 }, 5065 5066 check: function(){ 5067 if (!this.isRunning()) return true; 5068 switch (this.options.link){ 5069 case 'cancel': this.cancel(); return true; 5070 case 'chain': this.chain(this.caller.pass(arguments, this)); return false; 5071 } 5072 return false; 5073 }, 5074 5075 start: function(from, to){ 5076 if (!this.check(from, to)) return this; 5077 this.from = from; 5078 this.to = to; 5079 this.frame = (this.options.frameSkip) ? 0 : -1; 5080 this.time = null; 5081 this.transition = this.getTransition(); 5082 var frames = this.options.frames, fps = this.options.fps, duration = this.options.duration; 5083 this.duration = Fx.Durations[duration] || duration.toInt(); 5084 this.frameInterval = 1000 / fps; 5085 this.frames = frames || Math.round(this.duration / this.frameInterval); 5086 this.fireEvent('start', this.subject); 5087 pushInstance.call(this, fps); 5088 return this; 5089 }, 5090 5091 stop: function(){ 5092 if (this.isRunning()){ 5093 this.time = null; 5094 pullInstance.call(this, this.options.fps); 5095 if (this.frames == this.frame){ 5096 this.fireEvent('complete', this.subject); 5097 if (!this.callChain()) this.fireEvent('chainComplete', this.subject); 5098 } else { 5099 this.fireEvent('stop', this.subject); 5100 } 5101 } 5102 return this; 5103 }, 5104 5105 cancel: function(){ 5106 if (this.isRunning()){ 5107 this.time = null; 5108 pullInstance.call(this, this.options.fps); 5109 this.frame = this.frames; 5110 this.fireEvent('cancel', this.subject).clearChain(); 5111 } 5112 return this; 5113 }, 5114 5115 pause: function(){ 5116 if (this.isRunning()){ 5117 this.time = null; 5118 pullInstance.call(this, this.options.fps); 5119 } 5120 return this; 5121 }, 5122 5123 resume: function(){ 5124 if ((this.frame < this.frames) && !this.isRunning()) pushInstance.call(this, this.options.fps); 5125 return this; 5126 }, 5127 5128 isRunning: function(){ 5129 var list = instances[this.options.fps]; 5130 return list && list.contains(this); 5131 } 5132 5133}); 5134 5135Fx.compute = function(from, to, delta){ 5136 return (to - from) * delta + from; 5137}; 5138 5139Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000}; 5140 5141// global timers 5142 5143var instances = {}, timers = {}; 5144 5145var loop = function(){ 5146 var now = Date.now(); 5147 for (var i = this.length; i--;){ 5148 var instance = this[i]; 5149 if (instance) instance.step(now); 5150 } 5151}; 5152 5153var pushInstance = function(fps){ 5154 var list = instances[fps] || (instances[fps] = []); 5155 list.push(this); 5156 if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list); 5157}; 5158 5159var pullInstance = function(fps){ 5160 var list = instances[fps]; 5161 if (list){ 5162 list.erase(this); 5163 if (!list.length && timers[fps]){ 5164 delete instances[fps]; 5165 timers[fps] = clearInterval(timers[fps]); 5166 } 5167 } 5168}; 5169 5170}
5170)(); 5171 5172 5173/* 5174--- 5175 5176name: Fx.CSS 5177 5178description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements. 5179 5180license: MIT-style license. 5181 5182requires: [Fx, Element.Style] 5183 5184provides: Fx.CSS 5185 5186... 5187*/ 5188 5189Fx.CSS = new Class({ 5190 5191 Extends: Fx, 5192 5193 //prepares the base from/to object 5194 5195 prepare: function(element, property, values){ 5196 values = Array.from(values); 5197 var from = values[0], to = values[1]; 5198 if (to == null){ 5199 to = from; 5200 from = element.getStyle(property); 5201 var unit = this.options.unit; 5202 // adapted from: https://github.com/ryanmorr/fx/blob/master/fx.js#L299 5203 if (unit && from.slice(-unit.length) != unit && parseFloat(from) != 0){ 5204 element.setStyle(property, to + unit); 5205 var value = element.getComputedStyle(property); 5206 // IE and Opera support pixelLeft or pixelWidth 5207 if (!(/px$/.test(value))){ 5208 value = element.style[('pixel-' + property).camelCase()]; 5209 if (value == null){ 5210 // adapted from Dean Edwards' http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 5211 var left = element.style.left; 5212 element.style.left = to + unit; 5213 value = element.style.pixelLeft; 5214 element.style.left = left; 5215 } 5216 } 5217 from = (to || 1) / (parseFloat(value) || 1) * (parseFloat(from) || 0); 5218 element.setStyle(property, from + unit); 5219 } 5220 } 5221 return {from: this.parse(from), to: this.parse(to)}; 5222 }, 5223 5224 //parses a value into an array 5225 5226 parse: function(value){ 5227 value = Function.from(value)(); 5228 value = (typeof value == 'string') ? value.split(' ') : Array.from(value); 5229 return value.map(function(val){ 5230 val = String(val); 5231 var found = false; 5232 Object.each(Fx.CSS.Parsers, function(parser, key){ 5233 if (found) return; 5234 var parsed = parser.parse(val); 5235 if (parsed || parsed === 0) found = {value: parsed, parser: parser}; 5236 }); 5237 found = found || {value: val, parser: Fx.CSS.Parsers.String}; 5238 return found; 5239 }); 5240 }, 5241 5242 //computes by a from and to prepared objects, using their parsers. 5243 5244 compute: function(from, to, delta){ 5245 var computed = []; 5246 (Math.min(from.length, to.length)).times(function(i){ 5247 computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser}); 5248 }); 5249 computed.$family = Function.from('fx:css:value'); 5250 return computed; 5251 }, 5252 5253 //serves the value as settable 5254 5255 serve: function(value, unit){ 5256 if (typeOf(value) != 'fx:css:value') value = this.parse(value); 5257 var returned = []; 5258 value.each(function(bit){ 5259 returned = returned.concat(bit.parser.serve(bit.value, unit)); 5260 }); 5261 return returned; 5262 }, 5263 5264 //renders the change to an element 5265 5266 render: function(element, property, value, unit){ 5267 element.setStyle(property, this.serve(value, unit)); 5268 }, 5269 5270 //searches inside the page css to find the values for a selector 5271 5272 search: function(selector){ 5273 if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector]; 5274 var to = {}, selectorTest = new RegExp('^' + selector.escapeRegExp() + '$'); 5275 Array.each(document.styleSheets, function(sheet, j){ 5276 var href = sheet.href; 5277 if (href && href.contains('://') && !href.contains(document.domain)) return; 5278 var rules = sheet.rules || sheet.cssRules; 5279 Array.each(rules, function(rule, i){ 5280 if (!rule.style) return; 5281 var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){ 5282 return m.toLowerCase(); 5283 }) : null; 5284 if (!selectorText || !selectorTest.test(selectorText)) return; 5285 Object.each(Element.Styles, function(value, style){ 5286 if (!rule.style[style] || Element.ShortStyles[style]) return; 5287 value = String(rule.style[style]); 5288 to[style] = ((/^rgb/).test(value)) ? value.rgbToHex() : value; 5289 }); 5290 }); 5291 }); 5292 return Fx.CSS.Cache[selector] = to; 5293 } 5294 5295}); 5296 5297Fx.CSS.Cache = {}; 5298 5299Fx.CSS.Parsers = { 5300 5301 Color: { 5302 parse: function(value){ 5303 if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true); 5304 return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false; 5305 }, 5306 compute: function(from, to, delta){ 5307 return from.map(function(value, i){ 5308 return Math.round(Fx.compute(from[i], to[i], delta)); 5309 }); 5310 }, 5311 serve: function(value){ 5312 return value.map(Number); 5313 } 5314 }, 5315 5316 Number: { 5317 parse: parseFloat, 5318 compute: Fx.compute, 5319 serve: function(value, unit){ 5320 return (unit) ? value + unit : value; 5321 } 5322 }, 5323 5324 String: { 5325 parse: Function.from(false), 5326 compute: function(zero, one){ 5327 return one; 5328 }, 5329 serve: function(zero){ 5330 return zero; 5331 } 5332 } 5333 5334}; 5335 5336//<1.2compat> 5337 5338Fx.CSS.Parsers = new Hash(Fx.CSS.Parsers); 5339 5340//</1.2compat> 5341 5342 5343/* 5344--- 5345 5346name: Fx.Tween 5347 5348description: Formerly Fx.Style, effect to transition any CSS property for an element. 5349 5350license: MIT-style license. 5351 5352requires: Fx.CSS 5353 5354provides: [Fx.Tween, Element.fade, Element.highlight] 5355 5356... 5357*/ 5358 5359Fx.Tween = new Class({ 5360 5361 Extends: Fx.CSS, 5362 5363 initialize: function(element, options){ 5364 this.element = this.subject = document.id(element); 5365 this.parent(options); 5366 }, 5367 5368 set: function(property, now){ 5369 if (arguments.length == 1){ 5370 now = property; 5371 property = this.property || this.options.property; 5372 } 5373 this.render(this.element, property, now, this.options.unit); 5374 return this; 5375 }, 5376 5377 start: function(property, from, to){ 5378 if (!this.check(property, from, to)) return this; 5379 var args = Array.flatten(arguments); 5380 this.property = this.options.property || args.shift(); 5381 var parsed = this.prepare(this.element, this.property, args); 5382 return this.parent(parsed.from, parsed.to); 5383 } 5384 5385}); 5386 5387Element.Properties.tween = { 5388 5389 set: function(options){ 5390 this.get('tween').cancel().setOptions(options); 5391 return this; 5392 }, 5393 5394 get: function(){ 5395 var tween = this.retrieve('tween'); 5396 if (!tween){ 5397 tween = new Fx.Tween(this, {link: 'cancel'}); 5398 this.store('tween', tween); 5399 } 5400 return tween; 5401 } 5402 5403}; 5404 5405Element.implement({ 5406 5407 tween: function(property, from, to){ 5408 this.get('tween').start(property, from, to); 5409 return this; 5410 }, 5411 5412 fade: function(how){
5413 var fade = this.get('tween'), method, args = ['opacity'].append(arguments), toggle; 5414 if (args[1] == null) args[1] = 'toggle'; 5415 switch (args[1]){ 5416 case 'in': method = 'start'; args[1] = 1; break; 5417 case 'out': method = 'start'; args[1] = 0; break; 5418 case 'show': method = 'set'; args[1] = 1; break; 5419 case 'hide': method = 'set'; args[1] = 0; break; 5420 case 'toggle': 5421 var flag = this.retrieve('fade:flag', this.getStyle('opacity') == 1); 5422 method = 'start'; 5423 args[1] = flag ? 0 : 1; 5424 this.store('fade:flag', !flag); 5425 toggle = true; 5426 break; 5427 default: method = 'start'; 5428 } 5429 if (!toggle) this.eliminate('fade:flag'); 5430 fade[method].apply(fade, args); 5431 var to = args[args.length - 1]; 5432 if (method == 'set' || to != 0) this.setStyle('visibility', to == 0 ? 'hidden' : 'visible'); 5433 else fade.chain(function(){ 5434 this.element.setStyle('visibility', 'hidden'); 5435 this.callChain(); 5436 }); 5437 return this; 5438 }, 5439 5440 highlight: function(start, end){ 5441 if (!end){ 5442 end = this.retrieve('highlight:original', this.getStyle('background-color')); 5443 end = (end == 'transparent') ? '#fff' : end; 5444 } 5445 var tween = this.get('tween'); 5446 tween.start('background-color', start || '#ffff88', end).chain(function(){ 5447 this.setStyle('background-color', this.retrieve('highlight:original')); 5448 tween.callChain(); 5449 }.bind(this)); 5450 return this; 5451 } 5452 5453}); 5454 5455 5456/* 5457--- 5458 5459name: Fx.Morph 5460 5461description: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules. 5462 5463license: MIT-style license. 5464 5465requires: Fx.CSS 5466 5467provides: Fx.Morph 5468 5469... 5470*/ 5471 5472Fx.Morph = new Class({ 5473 5474 Extends: Fx.CSS, 5475 5476 initialize: function(element, options){ 5477 this.element = this.subject = document.id(element); 5478 this.parent(options); 5479 }, 5480 5481 set: function(now){ 5482 if (typeof now == 'string') now = this.search(now); 5483 for (var p in now) this.render(this.element, p, now[p], this.options.unit); 5484 return this; 5485 }, 5486 5487 compute: function(from, to, delta){ 5488 var now = {}; 5489 for (var p in from) now[p] = this.parent(from[p], to[p], delta); 5490 return now; 5491 }, 5492 5493 start: function(properties){ 5494 if (!this.check(properties)) return this; 5495 if (typeof properties == 'string') properties = this.search(properties); 5496 var from = {}, to = {}; 5497 for (var p in properties){ 5498 var parsed = this.prepare(this.element, p, properties[p]); 5499 from[p] = parsed.from; 5500 to[p] = parsed.to; 5501 } 5502 return this.parent(from, to); 5503 } 5504 5505}); 5506 5507Element.Properties.morph = { 5508 5509 set: function(options){ 5510 this.get('morph').cancel().setOptions(options); 5511 return this; 5512 }, 5513 5514 get: function(){ 5515 var morph = this.retrieve('morph'); 5516 if (!morph){ 5517 morph = new Fx.Morph(this, {link: 'cancel'}); 5518 this.store('morph', morph); 5519 } 5520 return morph; 5521 } 5522 5523}; 5524 5525Element.implement({ 5526 5527 morph: function(props){ 5528 this.get('morph').start(props); 5529 return this; 5530 } 5531 5532}); 5533 5534 5535/* 5536--- 5537 5538name: Fx.Transitions 5539 5540description: Contains a set of advanced transitions to be used with any of the Fx Classes. 5541 5542license: MIT-style license. 5543 5544credits: 5545 - Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, modified and optimized to be used with MooTools. 5546 5547requires: Fx 5548 5549provides: Fx.Transitions 5550 5551... 5552*/ 5553 5554Fx.implement({ 5555 5556 getTransition: function(){ 5557 var trans = this.options.transition || Fx.Transitions.Sine.easeInOut; 5558 if (typeof trans == 'string'){ 5559 var data = trans.split(':'); 5560 trans = Fx.Transitions; 5561 trans = trans[data[0]] || trans[data[0].capitalize()]; 5562 if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')]; 5563 } 5564 return trans; 5565 } 5566 5567}); 5568 5569Fx.Transition = function(transition, params){ 5570 params = Array.from(params); 5571 var easeIn = function(pos){ 5572 return transition(pos, params); 5573 }; 5574 return Object.append(easeIn, { 5575 easeIn: easeIn, 5576 easeOut: function(pos){ 5577 return 1 - transition(1 - pos, params); 5578 }, 5579 easeInOut: function(pos){ 5580 return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2; 5581 } 5582 }); 5583}; 5584 5585Fx.Transitions = { 5586 5587 linear: function(zero){ 5588 return zero; 5589 } 5590 5591}; 5592 5593//<1.2compat> 5594 5595Fx.Transitions = new Hash(Fx.Transitions); 5596 5597//</1.2compat> 5598 5599Fx.Transitions.extend = function(transitions){ 5600 for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]); 5601}; 5602 5603Fx.Transitions.extend({ 5604 5605 Pow: function(p, x){ 5606 return Math.pow(p, x && x[0] || 6); 5607 }, 5608 5609 Expo: function(p){ 5610 return Math.pow(2, 8 * (p - 1)); 5611 }, 5612
5613 Circ: function(p){ 5614 return 1 - Math.sin(Math.acos(p)); 5615 }, 5616 5617 Sine: function(p){ 5618 return 1 - Math.cos(p * Math.PI / 2); 5619 }, 5620 5621 Back: function(p, x){ 5622 x = x && x[0] || 1.618; 5623 return Math.pow(p, 2) * ((x + 1) * p - x); 5624 }, 5625 5626 Bounce: function(p){ 5627 var value; 5628 for (var a = 0, b = 1; 1; a += b, b /= 2){ 5629 if (p >= (7 - 4 * a) / 11){ 5630 value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); 5631 break; 5632 } 5633 } 5634 return value; 5635 }, 5636 5637 Elastic: function(p, x){ 5638 return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3); 5639 } 5640 5641}); 5642 5643['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){ 5644 Fx.Transitions[transition] = new Fx.Transition(function(p){ 5645 return Math.pow(p, i + 2); 5646 }); 5647}); 5648 5649 5650/* 5651--- 5652 5653name: Request 5654 5655description: Powerful all purpose Request Class. Uses XMLHTTPRequest. 5656 5657license: MIT-style license. 5658 5659requires: [Object, Element, Chain, Events, Options, Browser] 5660 5661provides: Request 5662 5663... 5664*/ 5665 5666(function(){ 5667 5668var empty = function(){}, 5669 progressSupport = ('onprogress' in new Browser.Request); 5670 5671var Request = this.Request = new Class({ 5672 5673 Implements: [Chain, Events, Options], 5674 5675 options: {/* 5676 onRequest: function(){}, 5677 onLoadstart: function(event, xhr){}, 5678 onProgress: function(event, xhr){}, 5679 onComplete: function(){}, 5680 onCancel: function(){}, 5681 onSuccess: function(responseText, responseXML){}, 5682 onFailure: function(xhr){}, 5683 onException: function(headerName, value){}, 5684 onTimeout: function(){}, 5685 user: '', 5686 password: '',*/ 5687 url: '', 5688 data: '', 5689 headers: { 5690 'X-Requested-With': 'XMLHttpRequest', 5691 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' 5692 }, 5693 async: true, 5694 format: false, 5695 method: 'post', 5696 link: 'ignore', 5697 isSuccess: null, 5698 emulation: true, 5699 urlEncoded: true, 5700 encoding: 'utf-8', 5701 evalScripts: false, 5702 evalResponse: false, 5703 timeout: 0, 5704 noCache: false 5705 }, 5706 5707 initialize: function(options){ 5708 this.xhr = new Browser.Request(); 5709 this.setOptions(options); 5710 this.headers = this.options.headers; 5711 }, 5712 5713 onStateChange: function(){ 5714 var xhr = this.xhr; 5715 if (xhr.readyState != 4 || !this.running) return; 5716 this.running = false; 5717 this.status = 0; 5718 Function.attempt(function(){ 5719 var status = xhr.status; 5720 this.status = (status == 1223) ? 204 : status; 5721 }.bind(this)); 5722 xhr.onreadystatechange = empty; 5723 if (progressSupport) xhr.onprogress = xhr.onloadstart = empty; 5724 clearTimeout(this.timer); 5725 5726 this.response = {text: this.xhr.responseText || '', xml: this.xhr.responseXML}; 5727 if (this.options.isSuccess.call(this, this.status)) 5728 this.success(this.response.text, this.response.xml); 5729 else 5730 this.failure(); 5731 }, 5732 5733 isSuccess: function(){ 5734 var status = this.status; 5735 return (status >= 200 && status < 300); 5736 }, 5737 5738 isRunning: function(){ 5739 return !!this.running; 5740 }, 5741 5742 processScripts: function(text){ 5743 if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return Browser.exec(text); 5744 return text.stripScripts(this.options.evalScripts); 5745 }, 5746 5747 success: function(text, xml){ 5748 this.onSuccess(this.processScripts(text), xml); 5749 }, 5750 5751 onSuccess: function(){ 5752 this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain(); 5753 }, 5754 5755 failure: function(){ 5756 this.onFailure(); 5757 }, 5758 5759 onFailure: function(){ 5760 this.fireEvent('complete').fireEvent('failure', this.xhr); 5761 }, 5762 5763 loadstart: function(event){ 5764 this.fireEvent('loadstart', [event, this.xhr]); 5765 }, 5766 5767 progress: function(event){ 5768 this.fireEvent('progress', [event, this.xhr]); 5769 }, 5770 5771 timeout: function(){ 5772 this.fireEvent('timeout', this.xhr); 5773 }, 5774 5775 setHeader: function(name, value){ 5776 this.headers[name] = value; 5777 return this; 5778 }, 5779 5780 getHeader: function(name){ 5781 return Function.attempt(function(){ 5782 return this.xhr.getResponseHeader(name); 5783 }.bind(this)); 5784 }, 5785 5786 check: function(){ 5787 if (!this.running) return true; 5788 switch (this.options.link){ 5789 case 'cancel': this.cancel(); return true; 5790 case 'chain': this.chain(this.caller.pass(arguments, this)); return false; 5791 } 5792 return false; 5793 }, 5794 5795 send: function(options){ 5796 if (!this.check(options)) return this; 5797 5798 this.options.isSuccess = this.options.isSuccess || this.isSuccess; 5799 this.running = true; 5800 5801 var type = typeOf(options); 5802 if (type == 'string' || type == 'element') options = {data: options}; 5803 5804 var old = this.options; 5805 options = Object.append({data: old.data, url: old.url, method: old.method}, options); 5806 var data = options.data, url = String(options.url), method = options.method.toLowerCase(); 5807 5808 switch (typeOf(data)){ 5809 case 'element': data = document.id(data).toQueryString(); break; 5810 case 'object': case 'hash': data = Object.toQueryString(data); 5811 } 5812 5813 if (this.options.format){ 5814 var format = 'format=' + this.options.format; 5815 data = (data) ? format + '&' + data : format; 5816 } 5817 5818 if (this.options.emulation && !['get', 'post'].contains(method)){ 5819 var _method = '_method=' + method; 5820 data = (data) ? _method + '&' + data : _method; 5821 method = 'post'; 5822 } 5823 5824 if (this.options.urlEncoded && ['post', 'put'].contains(method)){ 5825 var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; 5826 this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding; 5827 } 5828 5829 if (!url) url = document.location.pathname; 5830 5831 var trimPosition = url.lastIndexOf('/'); 5832 if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition); 5833 5834 if (this.options.noCache) 5835 url += (url.contains('?') ? '&' : '?') + String.uniqueID(); 5836 5837 if (data && method == 'get'){ 5838 url += (url.contains('?') ? '&' : '?') + data; 5839 data = null; 5840 } 5841 5842 var xhr = this.xhr; 5843 if (progressSupport){ 5844 xhr.onloadstart = this.loadstart.bind(this); 5845 xhr.onprogress = this.progress.bind(this); 5846 } 5847 5848 xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password); 5849 if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true; 5850 5851 xhr.onreadystatechange = this.onStateChange.bind(this); 5852 5853 Object.each(this.headers, function(value, key){ 5854 try { 5855 xhr.setRequestHeader(key, value); 5856 } catch (e){ 5857 this.fireEvent('exception', [key, value]); 5858 } 5859 }, this); 5860 5861 this.fireEvent('request'); 5862 xhr.send(data); 5863 if (!this.options.async) this.onStateChange(); 5864 else if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this); 5865 return this; 5866 }, 5867 5868 cancel: function(){ 5869 if (!this.running) return this; 5870 this.running = false;
5871 var xhr = this.xhr; 5872 xhr.abort(); 5873 clearTimeout(this.timer); 5874 xhr.onreadystatechange = empty; 5875 if (progressSupport) xhr.onprogress = xhr.onloadstart = empty; 5876 this.xhr = new Browser.Request(); 5877 this.fireEvent('cancel'); 5878 return this; 5879 } 5880 5881}); 5882 5883var methods = {}; 5884['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){ 5885 methods[method] = function(data){ 5886 var object = { 5887 method: method 5888 }; 5889 if (data != null) object.data = data; 5890 return this.send(object); 5891 }; 5892}); 5893 5894Request.implement(methods); 5895 5896Element.Properties.send = { 5897 5898 set: function(options){ 5899 var send = this.get('send').cancel(); 5900 send.setOptions(options); 5901 return this; 5902 }, 5903 5904 get: function(){ 5905 var send = this.retrieve('send'); 5906 if (!send){ 5907 send = new Request({ 5908 data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action') 5909 }); 5910 this.store('send', send); 5911 } 5912 return send; 5913 } 5914 5915}; 5916 5917Element.implement({ 5918 5919 send: function(url){ 5920 var sender = this.get('send'); 5921 sender.send({data: this, url: url || sender.options.url}); 5922 return this; 5923 } 5924 5925}); 5926 5927})(); 5928 5929 5930/* 5931--- 5932 5933name: Request.HTML 5934 5935description: Extends the basic Request Class with additional methods for interacting with HTML responses. 5936 5937license: MIT-style license. 5938 5939requires: [Element, Request] 5940 5941provides: Request.HTML 5942 5943... 5944*/ 5945 5946Request.HTML = new Class({ 5947 5948 Extends: Request, 5949 5950 options: { 5951 update: false, 5952 append: false, 5953 evalScripts: true, 5954 filter: false, 5955 headers: { 5956 Accept: 'text/html, application/xml, text/xml, */*' 5957 } 5958 }, 5959 5960 success: function(text){ 5961 var options = this.options, response = this.response; 5962 5963 response.html = text.stripScripts(function(script){ 5964 response.javascript = script; 5965 }); 5966 5967 var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i); 5968 if (match) response.html = match[1]; 5969 var temp = new Element('div').set('html', response.html); 5970 5971 response.tree = temp.childNodes; 5972 response.elements = temp.getElements(options.filter || '*'); 5973 5974 if (options.filter) response.tree = response.elements; 5975 if (options.update){ 5976 var update = document.id(options.update).empty(); 5977 if (options.filter) update.adopt(response.elements); 5978 else update.set('html', response.html); 5979 } else if (options.append){ 5980 var append = document.id(options.append); 5981 if (options.filter) response.elements.reverse().inject(append); 5982 else append.adopt(temp.getChildren()); 5983 } 5984 if (options.evalScripts) Browser.exec(response.javascript); 5985 5986 this.onSuccess(response.tree, response.elements, response.html, response.javascript); 5987 } 5988 5989}); 5990 5991Element.Properties.load = { 5992 5993 set: function(options){ 5994 var load = this.get('load').cancel(); 5995 load.setOptions(options); 5996 return this; 5997 }, 5998 5999 get: function(){ 6000 var load = this.retrieve('load'); 6001 if (!load){ 6002 load = new Request.HTML({data: this, link: 'cancel', update: this, method: 'get'}); 6003 this.store('load', load); 6004 } 6005 return load; 6006 } 6007 6008}; 6009 6010Element.implement({ 6011 6012 load: function(){ 6013 this.get('load').send(Array.link(arguments, {data: Type.isObject, url: Type.isString})); 6014 return this; 6015 } 6016 6017}); 6018 6019 6020/* 6021--- 6022 6023name: JSON 6024 6025description: JSON encoder and decoder. 6026 6027license: MIT-style license. 6028 6029SeeAlso: <http://www.json.org/> 6030 6031requires: [Array, String, Number, Function] 6032 6033provides: JSON 6034 6035... 6036*/ 6037 6038if (typeof JSON == 'undefined') this.JSON = {}; 6039 6040//<1.2compat> 6041 6042JSON = new Hash({ 6043 stringify: JSON.stringify, 6044 parse: JSON.parse 6045}); 6046 6047//</1.2compat> 6048 6049(function(){ 6050 6051var special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'}; 6052 6053var escape = function(chr){ 6054 return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)).slice(-4); 6055}; 6056 6057JSON.validate = function(string){ 6058 string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). 6059 replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). 6060 replace(/(?:^|:|,)(?:\s*\[)+/g, ''); 6061 6062 return (/^[\],:{}\s]*$/).test(string); 6063}; 6064 6065JSON.encode = JSON.stringify ? function(obj){ 6066 return JSON.stringify(obj); 6067} : function(obj){ 6068 if (obj && obj.toJSON) obj = obj.toJSON(); 6069 6070 switch (typeOf(obj)){ 6071 case 'string': 6072 return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '"'; 6073 case 'array': 6074 return '[' + obj.map(JSON.encode).clean() + ']'; 6075 case 'object': case 'hash': 6076 var string = []; 6077 Object.each(obj, function(value, key){ 6078 var json = JSON.encode(value); 6079 if (json) string.push(JSON.encode(key) + ':' + json); 6080 }); 6081 return '{' + string + '}'; 6082 case 'number': case 'boolean': return '' + obj; 6083 case 'null': return 'null';
6084 } 6085 6086 return null; 6087}; 6088 6089JSON.decode = function(string, secure){ 6090 if (!string || typeOf(string) != 'string') return null; 6091 6092 if (secure || JSON.secure){ 6093 if (JSON.parse) return JSON.parse(string); 6094 if (!JSON.validate(string)) throw new Error('JSON could not decode the input; security is enabled and the value is not secure.'); 6095 } 6096 6097 return eval('(' + string + ')'); 6098}; 6099 6100})(); 6101 6102 6103/* 6104--- 6105 6106name: Request.JSON 6107 6108description: Extends the basic Request Class with additional methods for sending and receiving JSON data. 6109 6110license: MIT-style license. 6111 6112requires: [Request, JSON] 6113 6114provides: Request.JSON 6115 6116... 6117*/ 6118 6119Request.JSON = new Class({ 6120 6121 Extends: Request, 6122 6123 options: { 6124 /*onError: function(text, error){},*/ 6125 secure: true 6126 }, 6127 6128 initialize: function(options){ 6129 this.parent(options); 6130 Object.append(this.headers, { 6131 'Accept': 'application/json', 6132 'X-Request': 'JSON' 6133 }); 6134 }, 6135 6136 success: function(text){ 6137 var json; 6138 try { 6139 json = this.response.json = JSON.decode(text, this.options.secure); 6140 } catch (error){ 6141 this.fireEvent('error', [text, error]); 6142 return; 6143 } 6144 if (json == null) this.onFailure(); 6145 else this.onSuccess(json, text); 6146 } 6147 6148}); 6149 6150 6151/* 6152--- 6153 6154name: Cookie 6155 6156description: Class for creating, reading, and deleting browser Cookies. 6157 6158license: MIT-style license. 6159 6160credits: 6161 - Based on the functions by Peter-Paul Koch (http://quirksmode.org). 6162 6163requires: [Options, Browser] 6164 6165provides: Cookie 6166 6167... 6168*/ 6169 6170var Cookie = new Class({ 6171 6172 Implements: Options, 6173 6174 options: { 6175 path: '/', 6176 domain: false, 6177 duration: false, 6178 secure: false, 6179 document: document, 6180 encode: true 6181 }, 6182 6183 initialize: function(key, options){ 6184 this.key = key; 6185 this.setOptions(options); 6186 }, 6187 6188 write: function(value){ 6189 if (this.options.encode) value = encodeURIComponent(value); 6190 if (this.options.domain) value += '; domain=' + this.options.domain; 6191 if (this.options.path) value += '; path=' + this.options.path; 6192 if (this.options.duration){ 6193 var date = new Date(); 6194 date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000); 6195 value += '; expires=' + date.toGMTString(); 6196 } 6197 if (this.options.secure) value += '; secure'; 6198 this.options.document.cookie = this.key + '=' + value; 6199 return this; 6200 }, 6201 6202 read: function(){ 6203 var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)'); 6204 return (value) ? decodeURIComponent(value[1]) : null; 6205 }, 6206 6207 dispose: function(){ 6208 new Cookie(this.key, Object.merge({}, this.options, {duration: -1})).write(''); 6209 return this; 6210 } 6211 6212}); 6213 6214Cookie.write = function(key, value, options){ 6215 return new Cookie(key, options).write(value); 6216}; 6217 6218Cookie.read = function(key){ 6219 return new Cookie(key).read(); 6220}; 6221 6222Cookie.dispose = function(key, options){ 6223 return new Cookie(key, options).dispose(); 6224}; 6225 6226 6227/* 6228--- 6229 6230name: DOMReady 6231 6232description: Contains the custom event domready. 6233 6234license: MIT-style license. 6235 6236requires: [Browser, Element, Element.Event] 6237 6238provides: [DOMReady, DomReady] 6239 6240... 6241*/ 6242 6243(function(window, document){ 6244 6245var ready, 6246 loaded, 6247 checks = [], 6248 shouldPoll, 6249 timer, 6250 testElement = document.createElement('div'); 6251 6252var domready = function(){ 6253 clearTimeout(timer); 6254 if (ready) return; 6255 Browser.loaded = ready = true; 6256 document.removeListener('DOMContentLoaded', domready).removeListener('readystatechange', check); 6257 6258 document.fireEvent('domready'); 6259 window.fireEvent('domready'); 6260}; 6261 6262var check = function(){ 6263 for (var i = checks.length; i--;) if (checks[i]()){ 6264 domready(); 6265 return true; 6266 } 6267 return false; 6268}; 6269 6270var poll = function(){ 6271 clearTimeout(timer); 6272 if (!check()) timer = setTimeout(poll, 10); 6273}; 6274 6275document.addListener('DOMContentLoaded', domready); 6276 6277/*<ltIE8>*/ 6278// doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoaded/ 6279// testElement.doScroll() throws when the DOM is not ready, only in the top window 6280var doScrollWorks = function(){ 6281 try { 6282 testElement.doScroll(); 6283 return true; 6284 } catch (e){} 6285 return false; 6286}; 6287// If doScroll works already, it can't be used to determine domready 6288// e.g. in an iframe 6289if (testElement.doScroll && !doScrollWorks()){ 6290 checks.push(doScrollWorks); 6291 shouldPoll = true; 6292} 6293/*</ltIE8>*/ 6294 6295if (document.readyState) checks.push(function(){ 6296 var state = document.readyState; 6297 return (state == 'loaded' || state == 'complete'); 6298}); 6299 6300if ('onreadystatechange' in document) document.addListener('readystatechange', check); 6301else shouldPoll = true; 6302 6303if (shouldPoll) poll(); 6304 6305Element.Events.domready = { 6306 onAdd: function(fn){ 6307 if (ready) fn.call(this); 6308 } 6309}; 6310 6311// Make sure that domready fires before load 6312Element.Events.load = { 6313 base: 'load', 6314 onAdd: function(fn){ 6315 if (loaded && this == window) fn.call(this); 6316 }, 6317 condition: function(){ 6318 if (this == window){ 6319 domready(); 6320 delete Element.Events.load; 6321 } 6322 return true; 6323 } 6324}; 6325 6326// This is based on the custom load event 6327window.addEvent('load', function(){ 6328 loaded = true; 6329}); 6330 6331})(window, document); 6332 6333 6334/* 6335--- 6336 6337name: Swiff 6338 6339description: Wrapper for embedding SWF movies. Supports External Interface Communication. 6340 6341license: MIT-style license. 6342 6343credits: 6344 - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject. 6345 6346requires: [Options, Object, Element] 6347 6348provides: Swiff 6349 6350... 6351*/ 6352 6353(function(){ 6354 6355var Swiff = this.Swiff = new Class({ 6356 6357 Implements: Options, 6358 6359 options: { 6360 id: null, 6361 height: 1, 6362 width: 1, 6363 container: null, 6364 properties: {}, 6365 params: { 6366 quality: 'high', 6367 allowScriptAccess: 'always',
6368 wMode: 'window', 6369 swLiveConnect: true 6370 }, 6371 callBacks: {}, 6372 vars: {} 6373 }, 6374 6375 toElement: function(){ 6376 return this.object; 6377 }, 6378 6379 initialize: function(path, options){ 6380 this.instance = 'Swiff_' + String.uniqueID(); 6381 6382 this.setOptions(options); 6383 options = this.options; 6384 var id = this.id = options.id || this.instance; 6385 var container = document.id(options.container); 6386 6387 Swiff.CallBacks[this.instance] = {}; 6388 6389 var params = options.params, vars = options.vars, callBacks = options.callBacks; 6390 var properties = Object.append({height: options.height, width: options.width}, options.properties); 6391 6392 var self = this; 6393 6394 for (var callBack in callBacks){ 6395 Swiff.CallBacks[this.instance][callBack] = (function(option){ 6396 return function(){ 6397 return option.apply(self.object, arguments); 6398 }; 6399 })(callBacks[callBack]); 6400 vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack; 6401 } 6402 6403 params.flashVars = Object.toQueryString(vars); 6404 if (Browser.ie){ 6405 properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; 6406 params.movie = path; 6407 } else { 6408 properties.type = 'application/x-shockwave-flash'; 6409 } 6410 properties.data = path; 6411 6412 var build = '<object id="' + id + '"'; 6413 for (var property in properties) build += ' ' + property + '="' + properties[property] + '"'; 6414 build += '>'; 6415 for (var param in params){ 6416 if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />'; 6417 } 6418 build += '</object>'; 6419 this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild; 6420 }, 6421 6422 replaces: function(element){ 6423 element = document.id(element, true); 6424 element.parentNode.replaceChild(this.toElement(), element); 6425 return this; 6426 }, 6427 6428 inject: function(element){ 6429 document.id(element, true).appendChild(this.toElement()); 6430 return this; 6431 }, 6432 6433 remote: function(){ 6434 return Swiff.remote.apply(Swiff, [this.toElement()].append(arguments)); 6435 } 6436 6437}); 6438 6439Swiff.CallBacks = {}; 6440 6441Swiff.remote = function(obj, fn){ 6442 var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascript">' + __flash__argumentsToXML(arguments, 2) + '</invoke>'); 6443 return eval(rs); 6444}; 6445 6446})(); 6447
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.