1//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2009 Aaron Newton <http://clientcide.com/>, Valerio Proietti <http://mad4milk.net> & the MooTools team <http://mootools.net/developers>, MIT Style License. 2 3/* 4--- 5 6script: More.js 7 8description: MooTools More 9 10license: MIT-style license 11 12authors: 13- Guillermo Rauch 14- Thomas Aylott 15- Scott Kyle 16 17requires: 18- core:1.2.4/MooTools 19 20provides: [MooTools.More] 21 22... 23*/ 24 25MooTools.More = { 26 'version': '1.2.4.4', 27 'build': '6f6057dc645fdb7547689183b2311063bd653ddf' 28}; 29 30/* 31--- 32 33script: MooTools.Lang.js 34 35description: Provides methods for localization. 36 37license: MIT-style license 38 39authors: 40- Aaron Newton 41 42requires: 43- core:1.2.4/Events 44- /MooTools.More 45 46provides: [MooTools.Lang] 47 48... 49*/ 50 51(function(){ 52 53 var data = { 54 language: 'en-US', 55 languages: { 56 'en-US': {} 57 }, 58 cascades: ['en-US'] 59 }; 60 61 var cascaded; 62 63 MooTools.lang = new Events(); 64 65 $extend(MooTools.lang, { 66 67 setLanguage: function(lang){ 68 if (!data.languages[lang]) return this; 69 data.language = lang; 70 this.load(); 71 this.fireEvent('langChange', lang); 72 return this; 73 }, 74 75 load: function() { 76 var langs = this.cascade(this.getCurrentLanguage()); 77 cascaded = {}; 78 $each(langs, function(set, setName){ 79 cascaded[setName] = this.lambda(set); 80 }, this); 81 }, 82 83 getCurrentLanguage: function(){ 84 return data.language; 85 }, 86 87 addLanguage: function(lang){ 88 data.languages[lang] = data.languages[lang] || {}; 89 return this; 90 }, 91 92 cascade: function(lang){ 93 var cascades = (data.languages[lang] || {}).cascades || []; 94 cascades.combine(data.cascades); 95 cascades.erase(lang).push(lang); 96 var langs = cascades.map(function(lng){ 97 return data.languages[lng]; 98 }, this); 99 return $merge.apply(this, langs); 100 }, 101 102 lambda: function(set) { 103 (set || {}).get = function(key, args){ 104 return $lambda(set[key]).apply(this, $splat(args)); 105 }; 106 return set; 107 }, 108 109 get: function(set, key, args){ 110 if (cascaded && cascaded[set]) return (key ? cascaded[set].get(key, args) : cascaded[set]); 111 }, 112 113 set: function(lang, set, members){ 114 this.addLanguage(lang); 115 langData = data.languages[lang]; 116 if (!langData[set]) langData[set] = {}; 117 $extend(langData[set], members); 118 if (lang == this.getCurrentLanguage()){ 119 this.load(); 120 this.fireEvent('langChange', lang); 121 } 122 return this; 123 }, 124 125 list: function(){ 126 return Hash.getKeys(data.languages); 127 } 128 129 }); 130 131})(); 132 133/* 134--- 135 136script: Date.js 137 138description: Extends the Date native object to include methods useful in managing dates. 139 140license: MIT-style license 141 142authors: 143- Aaron Newton
144- Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/ 145- Harald Kirshner - mail [at] digitarald.de; http://digitarald.de 146- Scott Kyle - scott [at] appden.com; http://appden.com 147 148requires: 149- core:1.2.4/Array 150- core:1.2.4/String 151- core:1.2.4/Number 152- core:1.2.4/Lang 153- core:1.2.4/Date.English.US 154- /MooTools.More 155 156provides: [Date] 157 158... 159*/ 160 161(function(){ 162 163var Date = this.Date; 164 165if (!Date.now) Date.now = $time; 166 167Date.Methods = { 168 ms: 'Milliseconds', 169 year: 'FullYear', 170 min: 'Minutes', 171 mo: 'Month', 172 sec: 'Seconds', 173 hr: 'Hours' 174}; 175 176['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset', 177 'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear', 178 'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds'].each(function(method){ 179 Date.Methods[method.toLowerCase()] = method; 180}); 181 182var pad = function(what, length){ 183 return new Array(length - String(what).length + 1).join('0') + what; 184}; 185 186Date.implement({ 187 188 set: function(prop, value){ 189 switch ($type(prop)){ 190 case 'object': 191 for (var p in prop) this.set(p, prop[p]); 192 break; 193 case 'string': 194 prop = prop.toLowerCase(); 195 var m = Date.Methods; 196 if (m[prop]) this['set' + m[prop]](value); 197 } 198 return this; 199 }, 200 201 get: function(prop){ 202 prop = prop.toLowerCase(); 203 var m = Date.Methods; 204 if (m[prop]) return this['get' + m[prop]](); 205 return null; 206 }, 207 208 clone: function(){ 209 return new Date(this.get('time')); 210 }, 211 212 increment: function(interval, times){ 213 interval = interval || 'day'; 214 times = $pick(times, 1); 215 216 switch (interval){ 217 case 'year': 218 return this.increment('month', times * 12); 219 case 'month': 220 var d = this.get('date'); 221 this.set('date', 1).set('mo', this.get('mo') + times); 222 return this.set('date', d.min(this.get('lastdayofmonth'))); 223 case 'week': 224 return this.increment('day', times * 7); 225 case 'day': 226 return this.set('date', this.get('date') + times); 227 } 228 229 if (!Date.units[interval]) throw new Error(interval + ' is not a supported interval'); 230 231 return this.set('time', this.get('time') + times * Date.units[interval]()); 232 }, 233 234 decrement: function(interval, times){ 235 return this.increment(interval, -1 * $pick(times, 1)); 236 }, 237 238 isLeapYear: function(){ 239 return Date.isLeapYear(this.get('year')); 240 }, 241 242 clearTime: function(){ 243 return this.set({hr: 0, min: 0, sec: 0, ms: 0}); 244 }, 245 246 diff: function(date, resolution){ 247 if ($type(date) == 'string') date = Date.parse(date); 248 249 return ((date - this) / Date.units[resolution || 'day'](3, 3)).toInt(); // non-leap year, 30-day month 250 }, 251 252 getLastDayOfMonth: function(){ 253 return Date.daysInMonth(this.get('mo'), this.get('year')); 254 }, 255 256 getDayOfYear: function(){ 257 return (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1) 258 - Date.UTC(this.get('year'), 0, 1)) / Date.units.day(); 259 }, 260 261 getWeek: function(){ 262 return (this.get('dayofyear') / 7).ceil(); 263 }, 264 265 getOrdinal: function(day){ 266 return Date.getMsg('ordinal', day || this.get('date')); 267 }, 268 269 getTimezone: function(){ 270 return this.toString() 271 .replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1') 272 .replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, '$1$2$3'); 273 }, 274 275 getGMTOffset: function(){ 276 var off = this.get('timezoneOffset'); 277 return ((off > 0) ? '-' : '+') + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2); 278 }, 279 280 setAMPM: function(ampm){ 281 ampm = ampm.toUpperCase(); 282 var hr = this.get('hr'); 283 if (hr > 11 && ampm == 'AM') return this.decrement('hour', 12); 284 else if (hr < 12 && ampm == 'PM') return this.increment('hour', 12); 285 return this; 286 }, 287 288 getAMPM: function(){ 289 return (this.get('hr') < 12) ? 'AM' : 'PM'; 290 }, 291 292 parse: function(str){ 293 this.set('time', Date.parse(str)); 294 return this; 295 }, 296 297 isValid: function(date) { 298 return !!(date || this).valueOf(); 299 }, 300 301 format: function(f){ 302 if (!this.isValid()) return 'invalid date'; 303 f = f || '%x %X'; 304 f = formats[f.toLowerCase()] || f; // replace short-hand with actual format 305 var d = this; 306 return f.replace(/%([a-z%])/gi, 307 function($0, $1){ 308 switch ($1){ 309 case 'a': return Date.getMsg('days')[d.get('day')].substr(0, 3); 310 case 'A': return Date.getMsg('days')[d.get('day')]; 311 case 'b': return Date.getMsg('months')[d.get('month')].substr(0, 3); 312 case 'B': return Date.getMsg('months')[d.get('month')]; 313 case 'c': return d.toString(); 314 case 'd': return pad(d.get('date'), 2); 315 case 'H': return pad(d.get('hr'), 2); 316 case 'I': return ((d.get('hr') % 12) || 12); 317 case 'j': return pad(d.get('dayofyear'), 3); 318 case 'm': return pad((d.get('mo') + 1), 2); 319 case 'M': return pad(d.get('min'), 2); 320 case 'o': return d.get('ordinal'); 321 case 'p': return Date.getMsg(d.get('ampm')); 322 case 'S': return pad(d.get('seconds'), 2); 323 case 'U': return pad(d.get('week'), 2); 324 case 'w': return d.get('day'); 325 case 'x': return d.format(Date.getMsg('shortDate')); 326 case 'X': return d.format(Date.getMsg('shortTime')); 327 case 'y': return d.get('year').toString().substr(2); 328 case 'Y': return d.get('year'); 329 case 'T': return d.get('GMTOffset'); 330 case 'Z': return d.get('Timezone'); 331 } 332 return $1; 333 } 334 ); 335 }, 336 337 toISOString: function(){ 338 return this.format('iso8601'); 339 } 340 341}); 342 343Date.alias('toISOString', 'toJSON'); 344Date.alias('diff', 'compare'); 345Date.alias('format', 'strftime'); 346 347var formats = { 348 db: '%Y-%m-%d %H:%M:%S', 349 compact: '%Y%m%dT%H%M%S', 350 iso8601: '%Y-%m-%dT%H:%M:%S%T', 351 rfc822: '%a, %d %b %Y %H:%M:%S %Z', 352 'short': '%d %b %H:%M', 353 'long': '%B %d, %Y %H:%M' 354}; 355 356var parsePatterns = []; 357var nativeParse = Date.parse; 358 359var parseWord = function(type, word, num){ 360 var ret = -1; 361 var translated = Date.getMsg(type + 's'); 362 363 switch ($type(word)){ 364 case 'object': 365 ret = translated[word.get(type)]; 366 break; 367 case 'number': 368 ret = translated[month - 1]; 369 if (!ret) throw new Error('Invalid ' + type + ' index: ' + index); 370 break; 371 case 'string': 372 var match = translated.filter(function(name){ 373 return this.test(name); 374 }, new RegExp('^' + word, 'i')); 375 if (!match.length) throw new Error('Invalid ' + type + ' string'); 376 if (match.length > 1) throw new Error('Ambiguous ' + type); 377 ret = match[0]; 378 } 379 380 return (num) ? translated.indexOf(ret) : ret; 381}; 382 383Date.extend({ 384 385 getMsg: function(key, args) { 386 return MooTools.lang.get('Date', key, args); 387 }, 388 389 units: { 390 ms: $lambda(1), 391 second: $lambda(1000), 392 minute: $lambda(60000), 393 hour: $lambda(3600000), 394 day: $lambda(86400000), 395 week: $lambda(608400000), 396 month: function(month, year){ 397 var d = new Date; 398 return Date.daysInMonth($pick(month, d.get('mo')), $pick(year, d.get('year'))) * 86400000; 399 }, 400 year: function(year){
401 year = year || new Date().get('year'); 402 return Date.isLeapYear(year) ? 31622400000 : 31536000000; 403 } 404 }, 405 406 daysInMonth: function(month, year){ 407 return [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; 408 }, 409 410 isLeapYear: function(year){ 411 return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); 412 }, 413 414 parse: function(from){ 415 var t = $type(from); 416 if (t == 'number') return new Date(from); 417 if (t != 'string') return from; 418 from = from.clean(); 419 if (!from.length) return null; 420 421 var parsed; 422 parsePatterns.some(function(pattern){ 423 var bits = pattern.re.exec(from); 424 return (bits) ? (parsed = pattern.handler(bits)) : false; 425 }); 426 427 return parsed || new Date(nativeParse(from)); 428 }, 429 430 parseDay: function(day, num){ 431 return parseWord('day', day, num); 432 }, 433 434 parseMonth: function(month, num){ 435 return parseWord('month', month, num); 436 }, 437 438 parseUTC: function(value){ 439 var localDate = new Date(value); 440 var utcSeconds = Date.UTC( 441 localDate.get('year'), 442 localDate.get('mo'), 443 localDate.get('date'), 444 localDate.get('hr'), 445 localDate.get('min'), 446 localDate.get('sec') 447 ); 448 return new Date(utcSeconds); 449 }, 450 451 orderIndex: function(unit){ 452 return Date.getMsg('dateOrder').indexOf(unit) + 1; 453 }, 454 455 defineFormat: function(name, format){ 456 formats[name] = format; 457 }, 458 459 defineFormats: function(formats){ 460 for (var name in formats) Date.defineFormat(name, formats[name]); 461 }, 462 463 parsePatterns: parsePatterns, // this is deprecated 464 465 defineParser: function(pattern){ 466 parsePatterns.push((pattern.re && pattern.handler) ? pattern : build(pattern)); 467 }, 468 469 defineParsers: function(){ 470 Array.flatten(arguments).each(Date.defineParser); 471 }, 472 473 define2DigitYearStart: function(year){ 474 startYear = year % 100; 475 startCentury = year - startYear; 476 } 477 478}); 479 480var startCentury = 1900; 481var startYear = 70; 482 483var regexOf = function(type){ 484 return new RegExp('(?:' + Date.getMsg(type).map(function(name){ 485 return name.substr(0, 3); 486 }).join('|') + ')[a-z]*'); 487}; 488 489var replacers = function(key){ 490 switch(key){ 491 case 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first 492 return ((Date.orderIndex('month') == 1) ? '%m[.-/]%d' : '%d[.-/]%m') + '([.-/]%y)?'; 493 case 'X': 494 return '%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%T?'; 495 } 496 return null; 497}; 498 499var keys = { 500 d: /[0-2]?[0-9]|3[01]/, 501 H: /[01]?[0-9]|2[0-3]/, 502 I: /0?[1-9]|1[0-2]/, 503 M: /[0-5]?\d/, 504 s: /\d+/, 505 o: /[a-z]*/, 506 p: /[ap]\.?m\.?/, 507 y: /\d{2}|\d{4}/, 508 Y: /\d{4}/, 509 T: /Z|[+-]\d{2}(?::?\d{2})?/ 510}; 511 512keys.m = keys.I; 513keys.S = keys.M; 514 515var currentLanguage; 516 517var recompile = function(language){ 518 currentLanguage = language; 519 520 keys.a = keys.A = regexOf('days'); 521 keys.b = keys.B = regexOf('months'); 522 523 parsePatterns.each(function(pattern, i){ 524 if (pattern.format) parsePatterns[i] = build(pattern.format); 525 }); 526}; 527 528var build = function(format){ 529 if (!currentLanguage) return {format: format}; 530 531 var parsed = []; 532 var re = (format.source || format) // allow format to be regex 533 .replace(/%([a-z])/gi, 534 function($0, $1){ 535 return replacers($1) || $0; 536 } 537 ).replace(/\((?!\?)/g, '(?:') // make all groups non-capturing 538 .replace(/ (?!\?|\*)/g, ',? ') // be forgiving with spaces and commas 539 .replace(/%([a-z%])/gi, 540 function($0, $1){ 541 var p = keys[$1]; 542 if (!p) return $1; 543 parsed.push($1); 544 return '(' + p.source + ')'; 545 } 546 ).replace(/\[a-z\]/gi, '[a-z\\u00c0-\\uffff]'); // handle unicode words 547 548 return { 549 format: format, 550 re: new RegExp('^' + re + '$', 'i'), 551 handler: function(bits){ 552 bits = bits.slice(1).associate(parsed); 553 var date = new Date().clearTime(); 554 if ('d' in bits) handle.call(date, 'd', 1); 555 if ('m' in bits || 'b' in bits || 'B' in bits) handle.call(date, 'm', 1); 556 for (var key in bits) handle.call(date, key, bits[key]); 557 return date; 558 } 559 }; 560}; 561 562var handle = function(key, value){ 563 if (!value) return this; 564 565 switch(key){ 566 case 'a': case 'A': return this.set('day', Date.parseDay(value, true)); 567 case 'b': case 'B': return this.set('mo', Date.parseMonth(value, true)); 568 case 'd': return this.set('date', value); 569 case 'H': case 'I': return this.set('hr', value); 570 case 'm': return this.set('mo', value - 1); 571 case 'M': return this.set('min', value); 572 case 'p': return this.set('ampm', value.replace(/\./g, '')); 573 case 'S': return this.set('sec', value); 574 case 's': return this.set('ms', ('0.' + value) * 1000); 575 case 'w': return this.set('day', value); 576 case 'Y': return this.set('year', value); 577 case 'y': 578 value = +value; 579 if (value < 100) value += startCentury + (value < startYear ? 100 : 0); 580 return this.set('year', value); 581 case 'T': 582 if (value == 'Z') value = '+00'; 583 var offset = value.match(/([+-])(\d{2}):?(\d{2})?/); 584 offset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset(); 585 return this.set('time', this - offset * 60000); 586 } 587 588 return this; 589}; 590 591Date.defineParsers( 592 '%Y([-./]%m([-./]%d((T| )%X)?)?)?', // "1999-12-31", "1999-12-31 11:59pm", "1999-12-31 23:59:59", ISO8601 593 '%Y%m%d(T%H(%M%S?)?)?', // "19991231", "19991231T1159", compact 594 '%x( %X)?', // "12/31", "12.31.99", "12-31-1999", "12/31/2008 11:59 PM" 595 '%d%o( %b( %Y)?)?( %X)?', // "31st", "31st December", "31 Dec 1999", "31 Dec 1999 11:59pm" 596 '%b( %d%o)?( %Y)?( %X)?', // Same as above with month and day switched 597 '%Y %b( %d%o( %X)?)?', // Same as above with year coming first 598 '%o %b %d %X %T %Y' // "Thu Oct 22 08:11:23 +0000 2009" 599); 600 601MooTools.lang.addEvent('langChange', function(language){ 602 if (MooTools.lang.get('Date')) recompile(language); 603}).fireEvent('langChange', MooTools.lang.getCurrentLanguage()); 604 605})(); 606 607/* 608--- 609 610script: Element.Forms.js 611 612description: Extends the Element native object to include methods useful in managing inputs. 613 614license: MIT-style license 615 616authors: 617- Aaron Newton 618 619requires: 620- core:1.2.4/Element 621- /MooTools.More 622 623provides: [Element.Forms] 624 625... 626*/ 627 628Element.implement({ 629 630 tidy: function(){ 631 this.set('value', this.get('value').tidy()); 632 }, 633 634 getTextInRange: function(start, end){ 635 return this.get('value').substring(start, end); 636 }, 637 638 getSelectedText: function(){ 639 if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.get
639SelectionEnd()); 640 return document.selection.createRange().text; 641 }, 642 643 getSelectedRange: function() { 644 if ($defined(this.selectionStart)) return {start: this.selectionStart, end: this.selectionEnd}; 645 var pos = {start: 0, end: 0}; 646 var range = this.getDocument().selection.createRange(); 647 if (!range || range.parentElement() != this) return pos; 648 var dup = range.duplicate(); 649 if (this.type == 'text') { 650 pos.start = 0 - dup.moveStart('character', -100000); 651 pos.end = pos.start + range.text.length; 652 } else { 653 var value = this.get('value'); 654 var offset = value.length; 655 dup.moveToElementText(this); 656 dup.setEndPoint('StartToEnd', range); 657 if(dup.text.length) offset -= value.match(/[\n\r]*$/)[0].length; 658 pos.end = offset - dup.text.length; 659 dup.setEndPoint('StartToStart', range); 660 pos.start = offset - dup.text.length; 661 } 662 return pos; 663 }, 664 665 getSelectionStart: function(){ 666 return this.getSelectedRange().start; 667 }, 668 669 getSelectionEnd: function(){ 670 return this.getSelectedRange().end; 671 }, 672 673 setCaretPosition: function(pos){ 674 if (pos == 'end') pos = this.get('value').length; 675 this.selectRange(pos, pos); 676 return this; 677 }, 678 679 getCaretPosition: function(){ 680 return this.getSelectedRange().start; 681 }, 682 683 selectRange: function(start, end){ 684 if (this.setSelectionRange) { 685 this.focus(); 686 this.setSelectionRange(start, end); 687 } else { 688 var value = this.get('value'); 689 var diff = value.substr(start, end - start).replace(/\r/g, '').length; 690 start = value.substr(0, start).replace(/\r/g, '').length; 691 var range = this.createTextRange(); 692 range.collapse(true); 693 range.moveEnd('character', start + diff); 694 range.moveStart('character', start); 695 range.select(); 696 } 697 return this; 698 }, 699 700 insertAtCursor: function(value, select){ 701 var pos = this.getSelectedRange(); 702 var text = this.get('value'); 703 this.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length)); 704 if ($pick(select, true)) this.selectRange(pos.start, pos.start + value.length); 705 else this.setCaretPosition(pos.start + value.length); 706 return this; 707 }, 708 709 insertAroundCursor: function(options, select){ 710 options = $extend({ 711 before: '', 712 defaultMiddle: '', 713 after: '' 714 }, options); 715 var value = this.getSelectedText() || options.defaultMiddle; 716 var pos = this.getSelectedRange(); 717 var text = this.get('value'); 718 if (pos.start == pos.end){ 719 this.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length)); 720 this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length); 721 } else { 722 var current = text.substring(pos.start, pos.end); 723 this.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length)); 724 var selStart = pos.start + options.before.length; 725 if ($pick(select, true)) this.selectRange(selStart, selStart + current.length); 726 else this.setCaretPosition(selStart + text.length); 727 } 728 return this; 729 } 730 731}); 732 733/* 734--- 735 736script: Element.Measure.js 737 738description: Extends the Element native object to include methods useful in measuring dimensions. 739 740credits: "Element.measure / .expose methods by Daniel Steigerwald License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz" 741 742license: MIT-style license 743 744authors: 745- Aaron Newton 746 747requires: 748- core:1.2.4/Element.Style 749- core:1.2.4/Element.Dimensions 750- /MooTools.More 751 752provides: [Element.Measure] 753 754... 755*/ 756 757Element.implement({ 758 759 measure: function(fn){ 760 var vis = function(el) { 761 return !!(!el || el.offsetHeight || el.offsetWidth); 762 }; 763 if (vis(this)) return fn.apply(this); 764 var parent = this.getParent(), 765 restorers = [], 766 toMeasure = []; 767 while (!vis(parent) && parent != document.body) { 768 toMeasure.push(parent.expose()); 769 parent = parent.getParent(); 770 } 771 var restore = this.expose(); 772 var result = fn.apply(this);
773 restore(); 774 toMeasure.each(function(restore){ 775 restore(); 776 }); 777 return result; 778 }, 779 780 expose: function(){ 781 if (this.getStyle('display') != 'none') return $empty; 782 var before = this.style.cssText; 783 this.setStyles({ 784 display: 'block', 785 position: 'absolute', 786 visibility: 'hidden' 787 }); 788 return function(){ 789 this.style.cssText = before; 790 }.bind(this); 791 }, 792 793 getDimensions: function(options){ 794 options = $merge({computeSize: false},options); 795 var dim = {}; 796 var getSize = function(el, options){ 797 return (options.computeSize)?el.getComputedSize(options):el.getSize(); 798 }; 799 var parent = this.getParent('body'); 800 if (parent && this.getStyle('display') == 'none'){ 801 dim = this.measure(function(){ 802 return getSize(this, options); 803 }); 804 } else if (parent){ 805 try { //safari sometimes crashes here, so catch it 806 dim = getSize(this, options); 807 }catch(e){} 808 } else { 809 dim = {x: 0, y: 0}; 810 } 811 return $chk(dim.x) ? $extend(dim, {width: dim.x, height: dim.y}) : $extend(dim, {x: dim.width, y: dim.height}); 812 }, 813 814 getComputedSize: function(options){ 815 options = $merge({ 816 styles: ['padding','border'], 817 plains: { 818 height: ['top','bottom'], 819 width: ['left','right'] 820 }, 821 mode: 'both' 822 }, options); 823 var size = {width: 0,height: 0}; 824 switch (options.mode){ 825 case 'vertical': 826 delete size.width; 827 delete options.plains.width; 828 break; 829 case 'horizontal': 830 delete size.height; 831 delete options.plains.height; 832 break; 833 } 834 var getStyles = []; 835 //this function might be useful in other places; perhaps it should be outside this function? 836 $each(options.plains, function(plain, key){ 837 plain.each(function(edge){ 838 options.styles.each(function(style){ 839 getStyles.push((style == 'border') ? style + '-' + edge + '-' + 'width' : style + '-' + edge); 840 }); 841 }); 842 }); 843 var styles = {}; 844 getStyles.each(function(style){ styles[style] = this.getComputedStyle(style); }, this); 845 var subtracted = []; 846 $each(options.plains, function(plain, key){ //keys: width, height, plains: ['left', 'right'], ['top','bottom'] 847 var capitalized = key.capitalize(); 848 size['total' + capitalized] = size['computed' + capitalized] = 0; 849 plain.each(function(edge){ //top, left, right, bottom 850 size['computed' + edge.capitalize()] = 0; 851 getStyles.each(function(style, i){ //padding, border, etc. 852 //'padding-left'.test('left') size['totalWidth'] = size['width'] + [padding-left] 853 if (style.test(edge)){ 854 styles[style] = styles[style].toInt() || 0; //styles['padding-left'] = 5; 855 size['total' + capitalized] = size['total' + capitalized] + styles[style]; 856 size['computed' + edge.capitalize()] = size['computed' + edge.capitalize()] + styles[style]; 857 } 858 //if width != width (so, padding-left, for instance), then subtract that from the total 859 if (style.test(edge) && key != style && 860 (style.test('border') || style.test('padding')) && !subtracted.contains(style)){ 861 subtracted.push(style); 862 size['computed' + capitalized] = size['computed' + capitalized]-styles[style]; 863 } 864 }); 865 }); 866 }); 867 868 ['Width', 'Height'].each(function(value){ 869 var lower = value.toLowerCase(); 870 if(!$chk(size[lower])) return; 871 872 size[lower] = size[lower] + this['offset' + value] + size['computed' + value]; 873 size['total' + value] = size[lower] + size['total' + value]; 874 delete size['computed' + value]; 875 }, this); 876 877 return $extend(styles, size); 878 } 879 880}); 881 882/* 883--- 884 885script: Element.Position.js 886 887description: Extends the Element native object to include methods useful positioning elements relative to others. 888 889license: MIT-style license 890 891authors: 892- Aaron Newton 893 894requires: 895- core:1.2.4/Element.Dimensions 896- /Element.Measure 897 898provides: [Elements.Position] 899 900... 901*/ 902 903(function(){ 904 905var original = Element.prototype.position; 906 907Element.implement({ 908 909 position: function(options){ 910 //call original position if the options are x/y values 911 if (options && ($defined(options.x) || $defined(options.y))) return original ? original.apply(this, arguments) : this; 912 $each(options||{}, function(v, k){ if (!$defined(v)) delete options[k]; }); 913 options = $merge({ 914 // minimum: { x: 0, y: 0 }, 915 // maximum: { x: 0, y: 0}, 916 relativeTo: document.body, 917 position: { 918 x: 'center', //left, center, right 919 y: 'center' //top, center, bottom 920 }, 921 edge: false, 922 offset: {x: 0, y: 0}, 923 returnPos: false, 924 relFixedPosition: false, 925 ignoreMargins: false, 926 ignoreScroll: false, 927 allowNegative: false 928 }, options); 929 //compute the offset of the parent positioned element if this element is in one 930 var parentOffset = {x: 0, y: 0}, 931 parentPositioned = false;
932 /* dollar around getOffsetParent should not be necessary, but as it does not return 933 * a mootools extended element in IE, an error occurs on the call to expose. See: 934 * http://mootools.lighthouseapp.com/projects/2706/tickets/333-element-getoffsetparent-inconsistency-between-ie-and-other-browsers */ 935 var offsetParent = this.measure(function(){ 936 return document.id(this.getOffsetParent()); 937 }); 938 if (offsetParent && offsetParent != this.getDocument().body){ 939 parentOffset = offsetParent.measure(function(){ 940 return this.getPosition(); 941 }); 942 parentPositioned = offsetParent != document.id(options.relativeTo); 943 options.offset.x = options.offset.x - parentOffset.x; 944 options.offset.y = options.offset.y - parentOffset.y; 945 } 946 //upperRight, bottomRight, centerRight, upperLeft, bottomLeft, centerLeft 947 //topRight, topLeft, centerTop, centerBottom, center 948 var fixValue = function(option){ 949 if ($type(option) != 'string') return option; 950 option = option.toLowerCase(); 951 var val = {}; 952 if (option.test('left')) val.x = 'left'; 953 else if (option.test('right')) val.x = 'right'; 954 else val.x = 'center'; 955 if (option.test('upper') || option.test('top')) val.y = 'top'; 956 else if (option.test('bottom')) val.y = 'bottom'; 957 else val.y = 'center'; 958 return val; 959 }; 960 options.edge = fixValue(options.edge); 961 options.position = fixValue(options.position); 962 if (!options.edge){ 963 if (options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center', y:'center'}; 964 else options.edge = {x:'left', y:'top'}; 965 } 966 967 this.setStyle('position', 'absolute'); 968 var rel = document.id(options.relativeTo) || document.body, 969 calc = rel == document.body ? window.getScroll() : rel.getPosition(), 970 top = calc.y, left = calc.x; 971 972 var dim = this.getDimensions({computeSize: true, styles:['padding', 'border','margin']}); 973 var pos = {}, 974 prefY = options.offset.y, 975 prefX = options.offset.x, 976 winSize = window.getSize(); 977 switch(options.position.x){ 978 case 'left': 979 pos.x = left + prefX; 980 break; 981 case 'right': 982 pos.x = left + prefX + rel.offsetWidth; 983 break; 984 default: //center 985 pos.x = left + ((rel == document.body ? winSize.x : rel.offsetWidth)/2) + prefX; 986 break; 987 } 988 switch(options.position.y){ 989 case 'top': 990 pos.y = top + prefY; 991 break; 992 case 'bottom': 993 pos.y = top + prefY + rel.offsetHeight; 994 break; 995 default: //center 996 pos.y = top + ((rel == document.body ? winSize.y : rel.offsetHeight)/2) + prefY; 997 break; 998 } 999 if (options.edge){ 1000 var edgeOffset = {}; 1001 1002 switch(options.edge.x){ 1003 case 'left': 1004 edgeOffset.x = 0; 1005 break; 1006 case 'right': 1007 edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft; 1008 break; 1009 default: //center 1010 edgeOffset.x = -(dim.totalWidth/2); 1011 break; 1012 } 1013 switch(options.edge.y){ 1014 case 'top': 1015 edgeOffset.y = 0; 1016 break; 1017 case 'bottom': 1018 edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom; 1019 break; 1020 default: //center 1021 edgeOffset.y = -(dim.totalHeight/2); 1022 break; 1023 } 1024 pos.x += edgeOffset.x; 1025 pos.y += edgeOffset.y; 1026 } 1027 pos = { 1028 left: ((pos.x >= 0 || parentPositioned || options.allowNegative) ? pos.x : 0).toInt(), 1029 top: ((pos.y >= 0 || parentPositioned || options.allowNegative) ? pos.y : 0).toInt() 1030 }; 1031 var xy = {left: 'x', top: 'y'}; 1032 ['minimum', 'maximum'].each(function(minmax) { 1033 ['left', 'top'].each(function(lr) { 1034 var val = options[minmax] ? options[minmax][xy[lr]] : null; 1035 if (val != null && pos[lr] < val) pos[lr] = val; 1036 }); 1037 }); 1038 if (rel.getStyle('position') == 'fixed' || options.relFixedPosition){ 1039 var winScroll = window.getScroll(); 1040 pos.top+= winScroll.y; 1041 pos.left+= winScroll.x; 1042 } 1043 if (options.ignoreScroll) { 1044 var relScroll = rel.getScroll(); 1045 pos.top-= relScroll.y; 1046 pos.left-= relScroll.x; 1047 } 1048 if (options.ignoreMargins) { 1049 pos.left += ( 1050 options.edge.x == 'right' ? dim['margin-right'] : 1051 options.edge.x == 'center' ? -dim['margin-left'] + ((dim['margin-right'] + dim['margin-left'])/2) : 1052 - dim['margin-left'] 1053 ); 1054 pos.top += ( 1055 options.edge.y == 'bottom' ? dim['margin-bottom'] : 1056 options.edge.y == 'center' ? -dim['margin-top'] + ((dim['margin-bottom'] + dim['margin-top'])/2) : 1057 - dim['margin-top'] 1058 ); 1059 }
1060 pos.left = Math.ceil(pos.left); 1061 pos.top = Math.ceil(pos.top); 1062 if (options.returnPos) return pos; 1063 else this.setStyles(pos); 1064 return this; 1065 } 1066 1067}); 1068 1069})(); 1070 1071/* 1072--- 1073 1074script: Date.English.US.js 1075 1076description: Date messages for US English. 1077 1078license: MIT-style license 1079 1080authors: 1081- Aaron Newton 1082 1083requires: 1084- /Lang 1085- /Date 1086 1087provides: [Date.English.US] 1088 1089... 1090*/ 1091 1092MooTools.lang.set('en-US', 'Date', { 1093 1094 months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'], 1095 days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], 1096 //culture's date order: MM/DD/YYYY 1097 dateOrder: ['month', 'date', 'year'], 1098 shortDate: '%m/%d/%Y', 1099 shortTime: '%I:%M%p', 1100 AM: 'AM', 1101 PM: 'PM', 1102 1103 /* Date.Extras */ 1104 ordinal: function(dayOfMonth){ 1105 //1st, 2nd, 3rd, etc. 1106 return (dayOfMonth > 3 && dayOfMonth < 21) ? 'th' : ['th', 'st', 'nd', 'rd', 'th'][Math.min(dayOfMonth % 10, 4)]; 1107 }, 1108 1109 lessThanMinuteAgo: 'less than a minute ago', 1110 minuteAgo: 'about a minute ago', 1111 minutesAgo: '{delta} minutes ago', 1112 hourAgo: 'about an hour ago', 1113 hoursAgo: 'about {delta} hours ago', 1114 dayAgo: '1 day ago', 1115 daysAgo: '{delta} days ago', 1116 weekAgo: '1 week ago', 1117 weeksAgo: '{delta} weeks ago', 1118 monthAgo: '1 month ago', 1119 monthsAgo: '{delta} months ago', 1120 yearAgo: '1 year ago', 1121 yearsAgo: '{delta} years ago', 1122 lessThanMinuteUntil: 'less than a minute from now', 1123 minuteUntil: 'about a minute from now', 1124 minutesUntil: '{delta} minutes from now', 1125 hourUntil: 'about an hour from now', 1126 hoursUntil: 'about {delta} hours from now', 1127 dayUntil: '1 day from now', 1128 daysUntil: '{delta} days from now', 1129 weekUntil: '1 week from now', 1130 weeksUntil: '{delta} weeks from now', 1131 monthUntil: '1 month from now', 1132 monthsUntil: '{delta} months from now', 1133 yearUntil: '1 year from now', 1134 yearsUntil: '{delta} years from now' 1135 1136}); 1137
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.