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