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