Make WordPress Core

Changeset 12557


Ignore:
Timestamp:
12/27/2009 10:30:58 PM (16 years ago)
Author:
azaozz
Message:

Update Prototype.js to 1.6.1 and remove the second copy of it from wp-includes/js/scriptaculous, update Scriptaculous.js to 1.8.3, props Simek, fixes #11041

Location:
trunk/wp-includes
Files:
1 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/wp-includes/js/prototype.js

    r6512 r12557  
    1 /*  Prototype JavaScript framework, version 1.6.0
    2  *  (c) 2005-2007 Sam Stephenson
     1/*  Prototype JavaScript framework, version 1.6.1
     2 *  (c) 2005-2009 Sam Stephenson
    33 *
    44 *  Prototype is freely distributable under the terms of an MIT-style license.
     
    88
    99var Prototype = {
    10   Version: '1.6.0',
    11 
    12   Browser: {
    13     IE:     !!(window.attachEvent && !window.opera),
    14     Opera:  !!window.opera,
    15     WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    16     Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    17     MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
    18   },
     10  Version: '1.6.1',
     11
     12  Browser: (function(){
     13    var ua = navigator.userAgent;
     14    var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
     15    return {
     16      IE:             !!window.attachEvent && !isOpera,
     17      Opera:          isOpera,
     18      WebKit:         ua.indexOf('AppleWebKit/') > -1,
     19      Gecko:          ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
     20      MobileSafari:   /Apple.*Mobile.*Safari/.test(ua)
     21    }
     22  })(),
    1923
    2024  BrowserFeatures: {
    2125    XPath: !!document.evaluate,
    22     ElementExtensions: !!window.HTMLElement,
    23     SpecificElementExtensions:
    24       document.createElement('div').__proto__ &&
    25       document.createElement('div').__proto__ !==
    26         document.createElement('form').__proto__
     26    SelectorsAPI: !!document.querySelector,
     27    ElementExtensions: (function() {
     28      var constructor = window.Element || window.HTMLElement;
     29      return !!(constructor && constructor.prototype);
     30    })(),
     31    SpecificElementExtensions: (function() {
     32      if (typeof window.HTMLDivElement !== 'undefined')
     33        return true;
     34
     35      var div = document.createElement('div');
     36      var form = document.createElement('form');
     37      var isSupported = false;
     38
     39      if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
     40        isSupported = true;
     41      }
     42
     43      div = form = null;
     44
     45      return isSupported;
     46    })()
    2747  },
    2848
     
    3757  Prototype.BrowserFeatures.SpecificElementExtensions = false;
    3858
    39 if (Prototype.Browser.WebKit)
    40   Prototype.BrowserFeatures.XPath = false;
     59
     60var Abstract = { };
     61
     62
     63var Try = {
     64  these: function() {
     65    var returnValue;
     66
     67    for (var i = 0, length = arguments.length; i < length; i++) {
     68      var lambda = arguments[i];
     69      try {
     70        returnValue = lambda();
     71        break;
     72      } catch (e) { }
     73    }
     74
     75    return returnValue;
     76  }
     77};
    4178
    4279/* Based on Alex Arnell's inheritance implementation. */
    43 var Class = {
    44   create: function() {
     80
     81var Class = (function() {
     82  function subclass() {};
     83  function create() {
    4584    var parent = null, properties = $A(arguments);
    4685    if (Object.isFunction(properties[0]))
     
    5695
    5796    if (parent) {
    58       var subclass = function() { };
    5997      subclass.prototype = parent.prototype;
    6098      klass.prototype = new subclass;
     
    69107
    70108    klass.prototype.constructor = klass;
    71 
    72109    return klass;
    73110  }
    74 };
    75 
    76 Class.Methods = {
    77   addMethods: function(source) {
     111
     112  function addMethods(source) {
    78113    var ancestor   = this.superclass && this.superclass.prototype;
    79114    var properties = Object.keys(source);
    80115
    81     if (!Object.keys({ toString: true }).length)
    82       properties.push("toString", "valueOf");
     116    if (!Object.keys({ toString: true }).length) {
     117      if (source.toString != Object.prototype.toString)
     118        properties.push("toString");
     119      if (source.valueOf != Object.prototype.valueOf)
     120        properties.push("valueOf");
     121    }
    83122
    84123    for (var i = 0, length = properties.length; i < length; i++) {
     
    86125      if (ancestor && Object.isFunction(value) &&
    87126          value.argumentNames().first() == "$super") {
    88         var method = value, value = Object.extend((function(m) {
    89           return function() { return ancestor[m].apply(this, arguments) };
    90         })(property).wrap(method), {
    91           valueOf:  function() { return method },
    92           toString: function() { return method.toString() }
    93         });
     127        var method = value;
     128        value = (function(m) {
     129          return function() { return ancestor[m].apply(this, arguments); };
     130        })(property).wrap(method);
     131
     132        value.valueOf = method.valueOf.bind(method);
     133        value.toString = method.toString.bind(method);
    94134      }
    95135      this.prototype[property] = value;
     
    98138    return this;
    99139  }
    100 };
    101 
    102 var Abstract = { };
    103 
    104 Object.extend = function(destination, source) {
    105   for (var property in source)
    106     destination[property] = source[property];
    107   return destination;
    108 };
    109 
    110 Object.extend(Object, {
    111   inspect: function(object) {
     140
     141  return {
     142    create: create,
     143    Methods: {
     144      addMethods: addMethods
     145    }
     146  };
     147})();
     148(function() {
     149
     150  var _toString = Object.prototype.toString;
     151
     152  function extend(destination, source) {
     153    for (var property in source)
     154      destination[property] = source[property];
     155    return destination;
     156  }
     157
     158  function inspect(object) {
    112159    try {
    113       if (object === undefined) return 'undefined';
     160      if (isUndefined(object)) return 'undefined';
    114161      if (object === null) return 'null';
    115       return object.inspect ? object.inspect() : object.toString();
     162      return object.inspect ? object.inspect() : String(object);
    116163    } catch (e) {
    117164      if (e instanceof RangeError) return '...';
    118165      throw e;
    119166    }
    120   },
    121 
    122   toJSON: function(object) {
     167  }
     168
     169  function toJSON(object) {
    123170    var type = typeof object;
    124171    switch (type) {
     
    131178    if (object === null) return 'null';
    132179    if (object.toJSON) return object.toJSON();
    133     if (Object.isElement(object)) return;
     180    if (isElement(object)) return;
    134181
    135182    var results = [];
    136183    for (var property in object) {
    137       var value = Object.toJSON(object[property]);
    138       if (value !== undefined)
     184      var value = toJSON(object[property]);
     185      if (!isUndefined(value))
    139186        results.push(property.toJSON() + ': ' + value);
    140187    }
    141188
    142189    return '{' + results.join(', ') + '}';
    143   },
    144 
    145   toQueryString: function(object) {
     190  }
     191
     192  function toQueryString(object) {
    146193    return $H(object).toQueryString();
    147   },
    148 
    149   toHTML: function(object) {
     194  }
     195
     196  function toHTML(object) {
    150197    return object && object.toHTML ? object.toHTML() : String.interpret(object);
    151   },
    152 
    153   keys: function(object) {
    154     var keys = [];
     198  }
     199
     200  function keys(object) {
     201    var results = [];
    155202    for (var property in object)
    156       keys.push(property);
    157     return keys;
    158   },
    159 
    160   values: function(object) {
    161     var values = [];
     203      results.push(property);
     204    return results;
     205  }
     206
     207  function values(object) {
     208    var results = [];
    162209    for (var property in object)
    163       values.push(object[property]);
    164     return values;
    165   },
    166 
    167   clone: function(object) {
    168     return Object.extend({ }, object);
    169   },
    170 
    171   isElement: function(object) {
    172     return object && object.nodeType == 1;
    173   },
    174 
    175   isArray: function(object) {
    176     return object && object.constructor === Array;
    177   },
    178 
    179   isHash: function(object) {
     210      results.push(object[property]);
     211    return results;
     212  }
     213
     214  function clone(object) {
     215    return extend({ }, object);
     216  }
     217
     218  function isElement(object) {
     219    return !!(object && object.nodeType == 1);
     220  }
     221
     222  function isArray(object) {
     223    return _toString.call(object) == "[object Array]";
     224  }
     225
     226
     227  function isHash(object) {
    180228    return object instanceof Hash;
    181   },
    182 
    183   isFunction: function(object) {
    184     return typeof object == "function";
    185   },
    186 
    187   isString: function(object) {
    188     return typeof object == "string";
    189   },
    190 
    191   isNumber: function(object) {
    192     return typeof object == "number";
    193   },
    194 
    195   isUndefined: function(object) {
    196     return typeof object == "undefined";
    197   }
    198 });
    199 
    200 Object.extend(Function.prototype, {
    201   argumentNames: function() {
    202     var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
     229  }
     230
     231  function isFunction(object) {
     232    return typeof object === "function";
     233  }
     234
     235  function isString(object) {
     236    return _toString.call(object) == "[object String]";
     237  }
     238
     239  function isNumber(object) {
     240    return _toString.call(object) == "[object Number]";
     241  }
     242
     243  function isUndefined(object) {
     244    return typeof object === "undefined";
     245  }
     246
     247  extend(Object, {
     248    extend:        extend,
     249    inspect:       inspect,
     250    toJSON:        toJSON,
     251    toQueryString: toQueryString,
     252    toHTML:        toHTML,
     253    keys:          keys,
     254    values:        values,
     255    clone:         clone,
     256    isElement:     isElement,
     257    isArray:       isArray,
     258    isHash:        isHash,
     259    isFunction:    isFunction,
     260    isString:      isString,
     261    isNumber:      isNumber,
     262    isUndefined:   isUndefined
     263  });
     264})();
     265Object.extend(Function.prototype, (function() {
     266  var slice = Array.prototype.slice;
     267
     268  function update(array, args) {
     269    var arrayLength = array.length, length = args.length;
     270    while (length--) array[arrayLength + length] = args[length];
     271    return array;
     272  }
     273
     274  function merge(array, args) {
     275    array = slice.call(array, 0);
     276    return update(array, args);
     277  }
     278
     279  function argumentNames() {
     280    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
     281      .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
     282      .replace(/\s+/g, '').split(',');
    203283    return names.length == 1 && !names[0] ? [] : names;
    204   },
    205 
    206   bind: function() {
    207     if (arguments.length < 2 && arguments[0] === undefined) return this;
    208     var __method = this, args = $A(arguments), object = args.shift();
     284  }
     285
     286  function bind(context) {
     287    if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
     288    var __method = this, args = slice.call(arguments, 1);
    209289    return function() {
    210       return __method.apply(object, args.concat($A(arguments)));
    211     }
    212   },
    213 
    214   bindAsEventListener: function() {
    215     var __method = this, args = $A(arguments), object = args.shift();
     290      var a = merge(args, arguments);
     291      return __method.apply(context, a);
     292    }
     293  }
     294
     295  function bindAsEventListener(context) {
     296    var __method = this, args = slice.call(arguments, 1);
    216297    return function(event) {
    217       return __method.apply(object, [event || window.event].concat(args));
    218     }
    219   },
    220 
    221   curry: function() {
     298      var a = update([event || window.event], args);
     299      return __method.apply(context, a);
     300    }
     301  }
     302
     303  function curry() {
    222304    if (!arguments.length) return this;
    223     var __method = this, args = $A(arguments);
     305    var __method = this, args = slice.call(arguments, 0);
    224306    return function() {
    225       return __method.apply(this, args.concat($A(arguments)));
    226     }
    227   },
    228 
    229   delay: function() {
    230     var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
     307      var a = merge(args, arguments);
     308      return __method.apply(this, a);
     309    }
     310  }
     311
     312  function delay(timeout) {
     313    var __method = this, args = slice.call(arguments, 1);
     314    timeout = timeout * 1000
    231315    return window.setTimeout(function() {
    232316      return __method.apply(__method, args);
    233317    }, timeout);
    234   },
    235 
    236   wrap: function(wrapper) {
     318  }
     319
     320  function defer() {
     321    var args = update([0.01], arguments);
     322    return this.delay.apply(this, args);
     323  }
     324
     325  function wrap(wrapper) {
    237326    var __method = this;
    238327    return function() {
    239       return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    240     }
    241   },
    242 
    243   methodize: function() {
     328      var a = update([__method.bind(this)], arguments);
     329      return wrapper.apply(this, a);
     330    }
     331  }
     332
     333  function methodize() {
    244334    if (this._methodized) return this._methodized;
    245335    var __method = this;
    246336    return this._methodized = function() {
    247       return __method.apply(null, [this].concat($A(arguments)));
     337      var a = update([this], arguments);
     338      return __method.apply(null, a);
    248339    };
    249340  }
    250 });
    251 
    252 Function.prototype.defer = Function.prototype.delay.curry(0.01);
     341
     342  return {
     343    argumentNames:       argumentNames,
     344    bind:                bind,
     345    bindAsEventListener: bindAsEventListener,
     346    curry:               curry,
     347    delay:               delay,
     348    defer:               defer,
     349    wrap:                wrap,
     350    methodize:           methodize
     351  }
     352})());
     353
    253354
    254355Date.prototype.toJSON = function() {
     
    261362};
    262363
    263 var Try = {
    264   these: function() {
    265     var returnValue;
    266 
    267     for (var i = 0, length = arguments.length; i < length; i++) {
    268       var lambda = arguments[i];
    269       try {
    270         returnValue = lambda();
    271         break;
    272       } catch (e) { }
    273     }
    274 
    275     return returnValue;
    276   }
    277 };
    278364
    279365RegExp.prototype.match = RegExp.prototype.test;
     
    282368  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
    283369};
    284 
    285 /*--------------------------------------------------------------------------*/
    286 
    287370var PeriodicalExecuter = Class.create({
    288371  initialize: function(callback, frequency) {
     
    313396        this.currentlyExecuting = true;
    314397        this.execute();
    315       } finally {
    316398        this.currentlyExecuting = false;
     399      } catch(e) {
     400        this.currentlyExecuting = false;
     401        throw e;
    317402      }
    318403    }
     
    333418});
    334419
    335 Object.extend(String.prototype, {
    336   gsub: function(pattern, replacement) {
     420Object.extend(String.prototype, (function() {
     421
     422  function prepareReplacement(replacement) {
     423    if (Object.isFunction(replacement)) return replacement;
     424    var template = new Template(replacement);
     425    return function(match) { return template.evaluate(match) };
     426  }
     427
     428  function gsub(pattern, replacement) {
    337429    var result = '', source = this, match;
    338     replacement = arguments.callee.prepareReplacement(replacement);
     430    replacement = prepareReplacement(replacement);
     431
     432    if (Object.isString(pattern))
     433      pattern = RegExp.escape(pattern);
     434
     435    if (!(pattern.length || pattern.source)) {
     436      replacement = replacement('');
     437      return replacement + source.split('').join(replacement) + replacement;
     438    }
    339439
    340440    while (source.length > 0) {
     
    348448    }
    349449    return result;
    350   },
    351 
    352   sub: function(pattern, replacement, count) {
    353     replacement = this.gsub.prepareReplacement(replacement);
    354     count = count === undefined ? 1 : count;
     450  }
     451
     452  function sub(pattern, replacement, count) {
     453    replacement = prepareReplacement(replacement);
     454    count = Object.isUndefined(count) ? 1 : count;
    355455
    356456    return this.gsub(pattern, function(match) {
     
    358458      return replacement(match);
    359459    });
    360   },
    361 
    362   scan: function(pattern, iterator) {
     460  }
     461
     462  function scan(pattern, iterator) {
    363463    this.gsub(pattern, iterator);
    364464    return String(this);
    365   },
    366 
    367   truncate: function(length, truncation) {
     465  }
     466
     467  function truncate(length, truncation) {
    368468    length = length || 30;
    369     truncation = truncation === undefined ? '...' : truncation;
     469    truncation = Object.isUndefined(truncation) ? '...' : truncation;
    370470    return this.length > length ?
    371471      this.slice(0, length - truncation.length) + truncation : String(this);
    372   },
    373 
    374   strip: function() {
     472  }
     473
     474  function strip() {
    375475    return this.replace(/^\s+/, '').replace(/\s+$/, '');
    376   },
    377 
    378   stripTags: function() {
    379     return this.replace(/<\/?[^>]+>/gi, '');
    380   },
    381 
    382   stripScripts: function() {
     476  }
     477
     478  function stripTags() {
     479    return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
     480  }
     481
     482  function stripScripts() {
    383483    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
    384   },
    385 
    386   extractScripts: function() {
     484  }
     485
     486  function extractScripts() {
    387487    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    388488    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
     
    390490      return (scriptTag.match(matchOne) || ['', ''])[1];
    391491    });
    392   },
    393 
    394   evalScripts: function() {
     492  }
     493
     494  function evalScripts() {
    395495    return this.extractScripts().map(function(script) { return eval(script) });
    396   },
    397 
    398   escapeHTML: function() {
    399     var self = arguments.callee;
    400     self.text.data = this;
    401     return self.div.innerHTML;
    402   },
    403 
    404   unescapeHTML: function() {
    405     var div = new Element('div');
    406     div.innerHTML = this.stripTags();
    407     return div.childNodes[0] ? (div.childNodes.length > 1 ?
    408       $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
    409       div.childNodes[0].nodeValue) : '';
    410   },
    411 
    412   toQueryParams: function(separator) {
     496  }
     497
     498  function escapeHTML() {
     499    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
     500  }
     501
     502  function unescapeHTML() {
     503    return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
     504  }
     505
     506
     507  function toQueryParams(separator) {
    413508    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    414509    if (!match) return { };
     
    428523      return hash;
    429524    });
    430   },
    431 
    432   toArray: function() {
     525  }
     526
     527  function toArray() {
    433528    return this.split('');
    434   },
    435 
    436   succ: function() {
     529  }
     530
     531  function succ() {
    437532    return this.slice(0, this.length - 1) +
    438533      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
    439   },
    440 
    441   times: function(count) {
     534  }
     535
     536  function times(count) {
    442537    return count < 1 ? '' : new Array(count + 1).join(this);
    443   },
    444 
    445   camelize: function() {
     538  }
     539
     540  function camelize() {
    446541    var parts = this.split('-'), len = parts.length;
    447542    if (len == 1) return parts[0];
     
    455550
    456551    return camelized;
    457   },
    458 
    459   capitalize: function() {
     552  }
     553
     554  function capitalize() {
    460555    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
    461   },
    462 
    463   underscore: function() {
    464     return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
    465   },
    466 
    467   dasherize: function() {
    468     return this.gsub(/_/,'-');
    469   },
    470 
    471   inspect: function(useDoubleQuotes) {
    472     var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
    473       var character = String.specialChar[match[0]];
    474       return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
     556  }
     557
     558  function underscore() {
     559    return this.replace(/::/g, '/')
     560               .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
     561               .replace(/([a-z\d])([A-Z])/g, '$1_$2')
     562               .replace(/-/g, '_')
     563               .toLowerCase();
     564  }
     565
     566  function dasherize() {
     567    return this.replace(/_/g, '-');
     568  }
     569
     570  function inspect(useDoubleQuotes) {
     571    var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
     572      if (character in String.specialChar) {
     573        return String.specialChar[character];
     574      }
     575      return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
    475576    });
    476577    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    477578    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
    478   },
    479 
    480   toJSON: function() {
     579  }
     580
     581  function toJSON() {
    481582    return this.inspect(true);
    482   },
    483 
    484   unfilterJSON: function(filter) {
    485     return this.sub(filter || Prototype.JSONFilter, '#{1}');
    486   },
    487 
    488   isJSON: function() {
    489     var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
     583  }
     584
     585  function unfilterJSON(filter) {
     586    return this.replace(filter || Prototype.JSONFilter, '$1');
     587  }
     588
     589  function isJSON() {
     590    var str = this;
     591    if (str.blank()) return false;
     592    str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    490593    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
    491   },
    492 
    493   evalJSON: function(sanitize) {
     594  }
     595
     596  function evalJSON(sanitize) {
    494597    var json = this.unfilterJSON();
    495598    try {
     
    497600    } catch (e) { }
    498601    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
    499   },
    500 
    501   include: function(pattern) {
     602  }
     603
     604  function include(pattern) {
    502605    return this.indexOf(pattern) > -1;
    503   },
    504 
    505   startsWith: function(pattern) {
     606  }
     607
     608  function startsWith(pattern) {
    506609    return this.indexOf(pattern) === 0;
    507   },
    508 
    509   endsWith: function(pattern) {
     610  }
     611
     612  function endsWith(pattern) {
    510613    var d = this.length - pattern.length;
    511614    return d >= 0 && this.lastIndexOf(pattern) === d;
    512   },
    513 
    514   empty: function() {
     615  }
     616
     617  function empty() {
    515618    return this == '';
    516   },
    517 
    518   blank: function() {
     619  }
     620
     621  function blank() {
    519622    return /^\s*$/.test(this);
    520   },
    521 
    522   interpolate: function(object, pattern) {
     623  }
     624
     625  function interpolate(object, pattern) {
    523626    return new Template(this, pattern).evaluate(object);
    524627  }
    525 });
    526 
    527 if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
    528   escapeHTML: function() {
    529     return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
    530   },
    531   unescapeHTML: function() {
    532     return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
    533   }
    534 });
    535 
    536 String.prototype.gsub.prepareReplacement = function(replacement) {
    537   if (Object.isFunction(replacement)) return replacement;
    538   var template = new Template(replacement);
    539   return function(match) { return template.evaluate(match) };
    540 };
    541 
    542 String.prototype.parseQuery = String.prototype.toQueryParams;
    543 
    544 Object.extend(String.prototype.escapeHTML, {
    545   div:  document.createElement('div'),
    546   text: document.createTextNode('')
    547 });
    548 
    549 with (String.prototype.escapeHTML) div.appendChild(text);
     628
     629  return {
     630    gsub:           gsub,
     631    sub:            sub,
     632    scan:           scan,
     633    truncate:       truncate,
     634    strip:          String.prototype.trim ? String.prototype.trim : strip,
     635    stripTags:      stripTags,
     636    stripScripts:   stripScripts,
     637    extractScripts: extractScripts,
     638    evalScripts:    evalScripts,
     639    escapeHTML:     escapeHTML,
     640    unescapeHTML:   unescapeHTML,
     641    toQueryParams:  toQueryParams,
     642    parseQuery:     toQueryParams,
     643    toArray:        toArray,
     644    succ:           succ,
     645    times:          times,
     646    camelize:       camelize,
     647    capitalize:     capitalize,
     648    underscore:     underscore,
     649    dasherize:      dasherize,
     650    inspect:        inspect,
     651    toJSON:         toJSON,
     652    unfilterJSON:   unfilterJSON,
     653    isJSON:         isJSON,
     654    evalJSON:       evalJSON,
     655    include:        include,
     656    startsWith:     startsWith,
     657    endsWith:       endsWith,
     658    empty:          empty,
     659    blank:          blank,
     660    interpolate:    interpolate
     661  };
     662})());
    550663
    551664var Template = Class.create({
     
    556669
    557670  evaluate: function(object) {
    558     if (Object.isFunction(object.toTemplateReplacements))
     671    if (object && Object.isFunction(object.toTemplateReplacements))
    559672      object = object.toTemplateReplacements();
    560673
    561674    return this.template.gsub(this.pattern, function(match) {
    562       if (object == null) return '';
     675      if (object == null) return (match[1] + '');
    563676
    564677      var before = match[1] || '';
     
    566679
    567680      var ctx = object, expr = match[3];
    568       var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
     681      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
     682      match = pattern.exec(expr);
    569683      if (match == null) return before;
    570684
    571685      while (match != null) {
    572         var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
     686        var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
    573687        ctx = ctx[comp];
    574688        if (null == ctx || '' == match[3]) break;
     
    578692
    579693      return before + String.interpret(ctx);
    580     }.bind(this));
     694    });
    581695  }
    582696});
     
    585699var $break = { };
    586700
    587 var Enumerable = {
    588   each: function(iterator, context) {
     701var Enumerable = (function() {
     702  function each(iterator, context) {
    589703    var index = 0;
    590     iterator = iterator.bind(context);
    591704    try {
    592705      this._each(function(value) {
    593         iterator(value, index++);
     706        iterator.call(context, value, index++);
    594707      });
    595708    } catch (e) {
     
    597710    }
    598711    return this;
    599   },
    600 
    601   eachSlice: function(number, iterator, context) {
    602     iterator = iterator ? iterator.bind(context) : Prototype.K;
     712  }
     713
     714  function eachSlice(number, iterator, context) {
    603715    var index = -number, slices = [], array = this.toArray();
     716    if (number < 1) return array;
    604717    while ((index += number) < array.length)
    605718      slices.push(array.slice(index, index+number));
    606719    return slices.collect(iterator, context);
    607   },
    608 
    609   all: function(iterator, context) {
    610     iterator = iterator ? iterator.bind(context) : Prototype.K;
     720  }
     721
     722  function all(iterator, context) {
     723    iterator = iterator || Prototype.K;
    611724    var result = true;
    612725    this.each(function(value, index) {
    613       result = result && !!iterator(value, index);
     726      result = result && !!iterator.call(context, value, index);
    614727      if (!result) throw $break;
    615728    });
    616729    return result;
    617   },
    618 
    619   any: function(iterator, context) {
    620     iterator = iterator ? iterator.bind(context) : Prototype.K;
     730  }
     731
     732  function any(iterator, context) {
     733    iterator = iterator || Prototype.K;
    621734    var result = false;
    622735    this.each(function(value, index) {
    623       if (result = !!iterator(value, index))
     736      if (result = !!iterator.call(context, value, index))
    624737        throw $break;
    625738    });
    626739    return result;
    627   },
    628 
    629   collect: function(iterator, context) {
    630     iterator = iterator ? iterator.bind(context) : Prototype.K;
     740  }
     741
     742  function collect(iterator, context) {
     743    iterator = iterator || Prototype.K;
    631744    var results = [];
    632745    this.each(function(value, index) {
    633       results.push(iterator(value, index));
     746      results.push(iterator.call(context, value, index));
    634747    });
    635748    return results;
    636   },
    637 
    638   detect: function(iterator, context) {
    639     iterator = iterator.bind(context);
     749  }
     750
     751  function detect(iterator, context) {
    640752    var result;
    641753    this.each(function(value, index) {
    642       if (iterator(value, index)) {
     754      if (iterator.call(context, value, index)) {
    643755        result = value;
    644756        throw $break;
     
    646758    });
    647759    return result;
    648   },
    649 
    650   findAll: function(iterator, context) {
    651     iterator = iterator.bind(context);
     760  }
     761
     762  function findAll(iterator, context) {
    652763    var results = [];
    653764    this.each(function(value, index) {
    654       if (iterator(value, index))
     765      if (iterator.call(context, value, index))
    655766        results.push(value);
    656767    });
    657768    return results;
    658   },
    659 
    660   grep: function(filter, iterator, context) {
    661     iterator = iterator ? iterator.bind(context) : Prototype.K;
     769  }
     770
     771  function grep(filter, iterator, context) {
     772    iterator = iterator || Prototype.K;
    662773    var results = [];
    663774
    664775    if (Object.isString(filter))
    665       filter = new RegExp(filter);
     776      filter = new RegExp(RegExp.escape(filter));
    666777
    667778    this.each(function(value, index) {
    668779      if (filter.match(value))
    669         results.push(iterator(value, index));
     780        results.push(iterator.call(context, value, index));
    670781    });
    671782    return results;
    672   },
    673 
    674   include: function(object) {
     783  }
     784
     785  function include(object) {
    675786    if (Object.isFunction(this.indexOf))
    676787      if (this.indexOf(object) != -1) return true;
     
    684795    });
    685796    return found;
    686   },
    687 
    688   inGroupsOf: function(number, fillWith) {
    689     fillWith = fillWith === undefined ? null : fillWith;
     797  }
     798
     799  function inGroupsOf(number, fillWith) {
     800    fillWith = Object.isUndefined(fillWith) ? null : fillWith;
    690801    return this.eachSlice(number, function(slice) {
    691802      while(slice.length < number) slice.push(fillWith);
    692803      return slice;
    693804    });
    694   },
    695 
    696   inject: function(memo, iterator, context) {
    697     iterator = iterator.bind(context);
     805  }
     806
     807  function inject(memo, iterator, context) {
    698808    this.each(function(value, index) {
    699       memo = iterator(memo, value, index);
     809      memo = iterator.call(context, memo, value, index);
    700810    });
    701811    return memo;
    702   },
    703 
    704   invoke: function(method) {
     812  }
     813
     814  function invoke(method) {
    705815    var args = $A(arguments).slice(1);
    706816    return this.map(function(value) {
    707817      return value[method].apply(value, args);
    708818    });
    709   },
    710 
    711   max: function(iterator, context) {
    712     iterator = iterator ? iterator.bind(context) : Prototype.K;
     819  }
     820
     821  function max(iterator, context) {
     822    iterator = iterator || Prototype.K;
    713823    var result;
    714824    this.each(function(value, index) {
    715       value = iterator(value, index);
    716       if (result == undefined || value >= result)
     825      value = iterator.call(context, value, index);
     826      if (result == null || value >= result)
    717827        result = value;
    718828    });
    719829    return result;
    720   },
    721 
    722   min: function(iterator, context) {
    723     iterator = iterator ? iterator.bind(context) : Prototype.K;
     830  }
     831
     832  function min(iterator, context) {
     833    iterator = iterator || Prototype.K;
    724834    var result;
    725835    this.each(function(value, index) {
    726       value = iterator(value, index);
    727       if (result == undefined || value < result)
     836      value = iterator.call(context, value, index);
     837      if (result == null || value < result)
    728838        result = value;
    729839    });
    730840    return result;
    731   },
    732 
    733   partition: function(iterator, context) {
    734     iterator = iterator ? iterator.bind(context) : Prototype.K;
     841  }
     842
     843  function partition(iterator, context) {
     844    iterator = iterator || Prototype.K;
    735845    var trues = [], falses = [];
    736846    this.each(function(value, index) {
    737       (iterator(value, index) ?
     847      (iterator.call(context, value, index) ?
    738848        trues : falses).push(value);
    739849    });
    740850    return [trues, falses];
    741   },
    742 
    743   pluck: function(property) {
     851  }
     852
     853  function pluck(property) {
    744854    var results = [];
    745855    this.each(function(value) {
     
    747857    });
    748858    return results;
    749   },
    750 
    751   reject: function(iterator, context) {
    752     iterator = iterator.bind(context);
     859  }
     860
     861  function reject(iterator, context) {
    753862    var results = [];
    754863    this.each(function(value, index) {
    755       if (!iterator(value, index))
     864      if (!iterator.call(context, value, index))
    756865        results.push(value);
    757866    });
    758867    return results;
    759   },
    760 
    761   sortBy: function(iterator, context) {
    762     iterator = iterator.bind(context);
     868  }
     869
     870  function sortBy(iterator, context) {
    763871    return this.map(function(value, index) {
    764       return {value: value, criteria: iterator(value, index)};
     872      return {
     873        value: value,
     874        criteria: iterator.call(context, value, index)
     875      };
    765876    }).sort(function(left, right) {
    766877      var a = left.criteria, b = right.criteria;
    767878      return a < b ? -1 : a > b ? 1 : 0;
    768879    }).pluck('value');
    769   },
    770 
    771   toArray: function() {
     880  }
     881
     882  function toArray() {
    772883    return this.map();
    773   },
    774 
    775   zip: function() {
     884  }
     885
     886  function zip() {
    776887    var iterator = Prototype.K, args = $A(arguments);
    777888    if (Object.isFunction(args.last()))
     
    782893      return iterator(collections.pluck(index));
    783894    });
    784   },
    785 
    786   size: function() {
     895  }
     896
     897  function size() {
    787898    return this.toArray().length;
    788   },
    789 
    790   inspect: function() {
     899  }
     900
     901  function inspect() {
    791902    return '#<Enumerable:' + this.toArray().inspect() + '>';
    792903  }
    793 };
    794 
    795 Object.extend(Enumerable, {
    796   map:     Enumerable.collect,
    797   find:    Enumerable.detect,
    798   select:  Enumerable.findAll,
    799   filter:  Enumerable.findAll,
    800   member:  Enumerable.include,
    801   entries: Enumerable.toArray,
    802   every:   Enumerable.all,
    803   some:    Enumerable.any
    804 });
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913  return {
     914    each:       each,
     915    eachSlice:  eachSlice,
     916    all:        all,
     917    every:      all,
     918    any:        any,
     919    some:       any,
     920    collect:    collect,
     921    map:        collect,
     922    detect:     detect,
     923    findAll:    findAll,
     924    select:     findAll,
     925    filter:     findAll,
     926    grep:       grep,
     927    include:    include,
     928    member:     include,
     929    inGroupsOf: inGroupsOf,
     930    inject:     inject,
     931    invoke:     invoke,
     932    max:        max,
     933    min:        min,
     934    partition:  partition,
     935    pluck:      pluck,
     936    reject:     reject,
     937    sortBy:     sortBy,
     938    toArray:    toArray,
     939    entries:    toArray,
     940    zip:        zip,
     941    size:       size,
     942    inspect:    inspect,
     943    find:       detect
     944  };
     945})();
    805946function $A(iterable) {
    806947  if (!iterable) return [];
    807   if (iterable.toArray) return iterable.toArray();
    808   var length = iterable.length, results = new Array(length);
     948  if ('toArray' in Object(iterable)) return iterable.toArray();
     949  var length = iterable.length || 0, results = new Array(length);
    809950  while (length--) results[length] = iterable[length];
    810951  return results;
    811952}
    812953
    813 if (Prototype.Browser.WebKit) {
    814   function $A(iterable) {
    815     if (!iterable) return [];
    816     if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
    817         iterable.toArray) return iterable.toArray();
    818     var length = iterable.length, results = new Array(length);
    819     while (length--) results[length] = iterable[length];
    820     return results;
    821   }
     954function $w(string) {
     955  if (!Object.isString(string)) return [];
     956  string = string.strip();
     957  return string ? string.split(/\s+/) : [];
    822958}
    823959
    824960Array.from = $A;
    825961
    826 Object.extend(Array.prototype, Enumerable);
    827 
    828 if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;
    829 
    830 Object.extend(Array.prototype, {
    831   _each: function(iterator) {
     962
     963(function() {
     964  var arrayProto = Array.prototype,
     965      slice = arrayProto.slice,
     966      _each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
     967
     968  function each(iterator) {
    832969    for (var i = 0, length = this.length; i < length; i++)
    833970      iterator(this[i]);
    834   },
    835 
    836   clear: function() {
     971  }
     972  if (!_each) _each = each;
     973
     974  function clear() {
    837975    this.length = 0;
    838976    return this;
    839   },
    840 
    841   first: function() {
     977  }
     978
     979  function first() {
    842980    return this[0];
    843   },
    844 
    845   last: function() {
     981  }
     982
     983  function last() {
    846984    return this[this.length - 1];
    847   },
    848 
    849   compact: function() {
     985  }
     986
     987  function compact() {
    850988    return this.select(function(value) {
    851989      return value != null;
    852990    });
    853   },
    854 
    855   flatten: function() {
     991  }
     992
     993  function flatten() {
    856994    return this.inject([], function(array, value) {
    857       return array.concat(Object.isArray(value) ?
    858         value.flatten() : [value]);
     995      if (Object.isArray(value))
     996        return array.concat(value.flatten());
     997      array.push(value);
     998      return array;
    859999    });
    860   },
    861 
    862   without: function() {
    863     var values = $A(arguments);
     1000  }
     1001
     1002  function without() {
     1003    var values = slice.call(arguments, 0);
    8641004    return this.select(function(value) {
    8651005      return !values.include(value);
    8661006    });
    867   },
    868 
    869   reverse: function(inline) {
     1007  }
     1008
     1009  function reverse(inline) {
    8701010    return (inline !== false ? this : this.toArray())._reverse();
    871   },
    872 
    873   reduce: function() {
    874     return this.length > 1 ? this : this[0];
    875   },
    876 
    877   uniq: function(sorted) {
     1011  }
     1012
     1013  function uniq(sorted) {
    8781014    return this.inject([], function(array, value, index) {
    8791015      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
     
    8811017      return array;
    8821018    });
    883   },
    884 
    885   intersect: function(array) {
     1019  }
     1020
     1021  function intersect(array) {
    8861022    return this.uniq().findAll(function(item) {
    8871023      return array.detect(function(value) { return item === value });
    8881024    });
    889   },
    890 
    891   clone: function() {
    892     return [].concat(this);
    893   },
    894 
    895   size: function() {
     1025  }
     1026
     1027
     1028  function clone() {
     1029    return slice.call(this, 0);
     1030  }
     1031
     1032  function size() {
    8961033    return this.length;
    897   },
    898 
    899   inspect: function() {
     1034  }
     1035
     1036  function inspect() {
    9001037    return '[' + this.map(Object.inspect).join(', ') + ']';
    901   },
    902 
    903   toJSON: function() {
     1038  }
     1039
     1040  function toJSON() {
    9041041    var results = [];
    9051042    this.each(function(object) {
    9061043      var value = Object.toJSON(object);
    907       if (value !== undefined) results.push(value);
     1044      if (!Object.isUndefined(value)) results.push(value);
    9081045    });
    9091046    return '[' + results.join(', ') + ']';
    9101047  }
    911 });
    912 
    913 // use native browser JS 1.6 implementation if available
    914 if (Object.isFunction(Array.prototype.forEach))
    915   Array.prototype._each = Array.prototype.forEach;
    916 
    917 if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
    918   i || (i = 0);
    919   var length = this.length;
    920   if (i < 0) i = length + i;
    921   for (; i < length; i++)
    922     if (this[i] === item) return i;
    923   return -1;
    924 };
    925 
    926 if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
    927   i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
    928   var n = this.slice(0, i).reverse().indexOf(item);
    929   return (n < 0) ? n : i - n - 1;
    930 };
    931 
    932 Array.prototype.toArray = Array.prototype.clone;
    933 
    934 function $w(string) {
    935   if (!Object.isString(string)) return [];
    936   string = string.strip();
    937   return string ? string.split(/\s+/) : [];
    938 }
    939 
    940 if (Prototype.Browser.Opera){
    941   Array.prototype.concat = function() {
    942     var array = [];
    943     for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
     1048
     1049  function indexOf(item, i) {
     1050    i || (i = 0);
     1051    var length = this.length;
     1052    if (i < 0) i = length + i;
     1053    for (; i < length; i++)
     1054      if (this[i] === item) return i;
     1055    return -1;
     1056  }
     1057
     1058  function lastIndexOf(item, i) {
     1059    i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
     1060    var n = this.slice(0, i).reverse().indexOf(item);
     1061    return (n < 0) ? n : i - n - 1;
     1062  }
     1063
     1064  function concat() {
     1065    var array = slice.call(this, 0), item;
    9441066    for (var i = 0, length = arguments.length; i < length; i++) {
    945       if (Object.isArray(arguments[i])) {
    946         for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
    947           array.push(arguments[i][j]);
     1067      item = arguments[i];
     1068      if (Object.isArray(item) && !('callee' in item)) {
     1069        for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
     1070          array.push(item[j]);
    9481071      } else {
    949         array.push(arguments[i]);
     1072        array.push(item);
    9501073      }
    9511074    }
    9521075    return array;
    953   };
    954 }
    955 Object.extend(Number.prototype, {
    956   toColorPart: function() {
    957     return this.toPaddedString(2, 16);
    958   },
    959 
    960   succ: function() {
    961     return this + 1;
    962   },
    963 
    964   times: function(iterator) {
    965     $R(0, this, true).each(iterator);
    966     return this;
    967   },
    968 
    969   toPaddedString: function(length, radix) {
    970     var string = this.toString(radix || 10);
    971     return '0'.times(length - string.length) + string;
    972   },
    973 
    974   toJSON: function() {
    975     return isFinite(this) ? this.toString() : 'null';
    976   }
    977 });
    978 
    979 $w('abs round ceil floor').each(function(method){
    980   Number.prototype[method] = Math[method].methodize();
    981 });
     1076  }
     1077
     1078  Object.extend(arrayProto, Enumerable);
     1079
     1080  if (!arrayProto._reverse)
     1081    arrayProto._reverse = arrayProto.reverse;
     1082
     1083  Object.extend(arrayProto, {
     1084    _each:     _each,
     1085    clear:     clear,
     1086    first:     first,
     1087    last:      last,
     1088    compact:   compact,
     1089    flatten:   flatten,
     1090    without:   without,
     1091    reverse:   reverse,
     1092    uniq:      uniq,
     1093    intersect: intersect,
     1094    clone:     clone,
     1095    toArray:   clone,
     1096    size:      size,
     1097    inspect:   inspect,
     1098    toJSON:    toJSON
     1099  });
     1100
     1101  var CONCAT_ARGUMENTS_BUGGY = (function() {
     1102    return [].concat(arguments)[0][0] !== 1;
     1103  })(1,2)
     1104
     1105  if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
     1106
     1107  if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
     1108  if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
     1109})();
    9821110function $H(object) {
    9831111  return new Hash(object);
     
    9851113
    9861114var Hash = Class.create(Enumerable, (function() {
    987   if (function() {
    988     var i = 0, Test = function(value) { this.key = value };
    989     Test.prototype.key = 'foo';
    990     for (var property in new Test('bar')) i++;
    991     return i > 1;
    992   }()) {
    993     function each(iterator) {
    994       var cache = [];
    995       for (var key in this._object) {
    996         var value = this._object[key];
    997         if (cache.include(key)) continue;
    998         cache.push(key);
    999         var pair = [key, value];
    1000         pair.key = key;
    1001         pair.value = value;
    1002         iterator(pair);
    1003       }
    1004     }
    1005   } else {
    1006     function each(iterator) {
    1007       for (var key in this._object) {
    1008         var value = this._object[key], pair = [key, value];
    1009         pair.key = key;
    1010         pair.value = value;
    1011         iterator(pair);
    1012       }
    1013     }
     1115  function initialize(object) {
     1116    this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
     1117  }
     1118
     1119  function _each(iterator) {
     1120    for (var key in this._object) {
     1121      var value = this._object[key], pair = [key, value];
     1122      pair.key = key;
     1123      pair.value = value;
     1124      iterator(pair);
     1125    }
     1126  }
     1127
     1128  function set(key, value) {
     1129    return this._object[key] = value;
     1130  }
     1131
     1132  function get(key) {
     1133    if (this._object[key] !== Object.prototype[key])
     1134      return this._object[key];
     1135  }
     1136
     1137  function unset(key) {
     1138    var value = this._object[key];
     1139    delete this._object[key];
     1140    return value;
     1141  }
     1142
     1143  function toObject() {
     1144    return Object.clone(this._object);
     1145  }
     1146
     1147  function keys() {
     1148    return this.pluck('key');
     1149  }
     1150
     1151  function values() {
     1152    return this.pluck('value');
     1153  }
     1154
     1155  function index(value) {
     1156    var match = this.detect(function(pair) {
     1157      return pair.value === value;
     1158    });
     1159    return match && match.key;
     1160  }
     1161
     1162  function merge(object) {
     1163    return this.clone().update(object);
     1164  }
     1165
     1166  function update(object) {
     1167    return new Hash(object).inject(this, function(result, pair) {
     1168      result.set(pair.key, pair.value);
     1169      return result;
     1170    });
    10141171  }
    10151172
     
    10191176  }
    10201177
     1178  function toQueryString() {
     1179    return this.inject([], function(results, pair) {
     1180      var key = encodeURIComponent(pair.key), values = pair.value;
     1181
     1182      if (values && typeof values == 'object') {
     1183        if (Object.isArray(values))
     1184          return results.concat(values.map(toQueryPair.curry(key)));
     1185      } else results.push(toQueryPair(key, values));
     1186      return results;
     1187    }).join('&');
     1188  }
     1189
     1190  function inspect() {
     1191    return '#<Hash:{' + this.map(function(pair) {
     1192      return pair.map(Object.inspect).join(': ');
     1193    }).join(', ') + '}>';
     1194  }
     1195
     1196  function toJSON() {
     1197    return Object.toJSON(this.toObject());
     1198  }
     1199
     1200  function clone() {
     1201    return new Hash(this);
     1202  }
     1203
    10211204  return {
    1022     initialize: function(object) {
    1023       this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
    1024     },
    1025 
    1026     _each: each,
    1027 
    1028     set: function(key, value) {
    1029       return this._object[key] = value;
    1030     },
    1031 
    1032     get: function(key) {
    1033       return this._object[key];
    1034     },
    1035 
    1036     unset: function(key) {
    1037       var value = this._object[key];
    1038       delete this._object[key];
    1039       return value;
    1040     },
    1041 
    1042     toObject: function() {
    1043       return Object.clone(this._object);
    1044     },
    1045 
    1046     keys: function() {
    1047       return this.pluck('key');
    1048     },
    1049 
    1050     values: function() {
    1051       return this.pluck('value');
    1052     },
    1053 
    1054     index: function(value) {
    1055       var match = this.detect(function(pair) {
    1056         return pair.value === value;
    1057       });
    1058       return match && match.key;
    1059     },
    1060 
    1061     merge: function(object) {
    1062       return this.clone().update(object);
    1063     },
    1064 
    1065     update: function(object) {
    1066       return new Hash(object).inject(this, function(result, pair) {
    1067         result.set(pair.key, pair.value);
    1068         return result;
    1069       });
    1070     },
    1071 
    1072     toQueryString: function() {
    1073       return this.map(function(pair) {
    1074         var key = encodeURIComponent(pair.key), values = pair.value;
    1075 
    1076         if (values && typeof values == 'object') {
    1077           if (Object.isArray(values))
    1078             return values.map(toQueryPair.curry(key)).join('&');
    1079         }
    1080         return toQueryPair(key, values);
    1081       }).join('&');
    1082     },
    1083 
    1084     inspect: function() {
    1085       return '#<Hash:{' + this.map(function(pair) {
    1086         return pair.map(Object.inspect).join(': ');
    1087       }).join(', ') + '}>';
    1088     },
    1089 
    1090     toJSON: function() {
    1091       return Object.toJSON(this.toObject());
    1092     },
    1093 
    1094     clone: function() {
    1095       return new Hash(this);
    1096     }
    1097   }
     1205    initialize:             initialize,
     1206    _each:                  _each,
     1207    set:                    set,
     1208    get:                    get,
     1209    unset:                  unset,
     1210    toObject:               toObject,
     1211    toTemplateReplacements: toObject,
     1212    keys:                   keys,
     1213    values:                 values,
     1214    index:                  index,
     1215    merge:                  merge,
     1216    update:                 update,
     1217    toQueryString:          toQueryString,
     1218    inspect:                inspect,
     1219    toJSON:                 toJSON,
     1220    clone:                  clone
     1221  };
    10981222})());
    10991223
    1100 Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
    11011224Hash.from = $H;
    1102 var ObjectRange = Class.create(Enumerable, {
    1103   initialize: function(start, end, exclusive) {
     1225Object.extend(Number.prototype, (function() {
     1226  function toColorPart() {
     1227    return this.toPaddedString(2, 16);
     1228  }
     1229
     1230  function succ() {
     1231    return this + 1;
     1232  }
     1233
     1234  function times(iterator, context) {
     1235    $R(0, this, true).each(iterator, context);
     1236    return this;
     1237  }
     1238
     1239  function toPaddedString(length, radix) {
     1240    var string = this.toString(radix || 10);
     1241    return '0'.times(length - string.length) + string;
     1242  }
     1243
     1244  function toJSON() {
     1245    return isFinite(this) ? this.toString() : 'null';
     1246  }
     1247
     1248  function abs() {
     1249    return Math.abs(this);
     1250  }
     1251
     1252  function round() {
     1253    return Math.round(this);
     1254  }
     1255
     1256  function ceil() {
     1257    return Math.ceil(this);
     1258  }
     1259
     1260  function floor() {
     1261    return Math.floor(this);
     1262  }
     1263
     1264  return {
     1265    toColorPart:    toColorPart,
     1266    succ:           succ,
     1267    times:          times,
     1268    toPaddedString: toPaddedString,
     1269    toJSON:         toJSON,
     1270    abs:            abs,
     1271    round:          round,
     1272    ceil:           ceil,
     1273    floor:          floor
     1274  };
     1275})());
     1276
     1277function $R(start, end, exclusive) {
     1278  return new ObjectRange(start, end, exclusive);
     1279}
     1280
     1281var ObjectRange = Class.create(Enumerable, (function() {
     1282  function initialize(start, end, exclusive) {
    11041283    this.start = start;
    11051284    this.end = end;
    11061285    this.exclusive = exclusive;
    1107   },
    1108 
    1109   _each: function(iterator) {
     1286  }
     1287
     1288  function _each(iterator) {
    11101289    var value = this.start;
    11111290    while (this.include(value)) {
     
    11131292      value = value.succ();
    11141293    }
    1115   },
    1116 
    1117   include: function(value) {
     1294  }
     1295
     1296  function include(value) {
    11181297    if (value < this.start)
    11191298      return false;
     
    11221301    return value <= this.end;
    11231302  }
    1124 });
    1125 
    1126 var $R = function(start, end, exclusive) {
    1127   return new ObjectRange(start, end, exclusive);
    1128 };
     1303
     1304  return {
     1305    initialize: initialize,
     1306    _each:      _each,
     1307    include:    include
     1308  };
     1309})());
     1310
     1311
    11291312
    11301313var Ajax = {
     
    11731356  onComplete: function() { Ajax.activeRequestCount-- }
    11741357});
    1175 
    11761358Ajax.Base = Class.create({
    11771359  initialize: function(options) {
     
    11881370
    11891371    this.options.method = this.options.method.toLowerCase();
     1372
    11901373    if (Object.isString(this.options.parameters))
    11911374      this.options.parameters = this.options.parameters.toQueryParams();
     1375    else if (Object.isHash(this.options.parameters))
     1376      this.options.parameters = this.options.parameters.toObject();
    11921377  }
    11931378});
    1194 
    11951379Ajax.Request = Class.create(Ajax.Base, {
    11961380  _complete: false,
     
    12081392
    12091393    if (!['get', 'post'].include(this.method)) {
    1210       // simulate other verbs over post
    12111394      params['_method'] = this.method;
    12121395      this.method = 'post';
     
    12161399
    12171400    if (params = Object.toQueryString(params)) {
    1218       // when GET, append parameters to URL
    12191401      if (this.method == 'get')
    12201402        this.url += (this.url.include('?') ? '&' : '?') + params;
     
    12751457    }
    12761458
    1277     // user-defined headers
    12781459    if (typeof this.options.requestHeaders == 'object') {
    12791460      var extras = this.options.requestHeaders;
     
    13161497      var contentType = response.getHeader('Content-type');
    13171498      if (this.options.evalJS == 'force'
    1318           || (this.options.evalJS && contentType
     1499          || (this.options.evalJS && this.isSameOrigin() && contentType
    13191500          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
    13201501        this.evalResponse();
     
    13291510
    13301511    if (state == 'Complete') {
    1331       // avoid memory leak in MSIE: clean up
    13321512      this.transport.onreadystatechange = Prototype.emptyFunction;
    13331513    }
     1514  },
     1515
     1516  isSameOrigin: function() {
     1517    var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
     1518    return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
     1519      protocol: location.protocol,
     1520      domain: document.domain,
     1521      port: location.port ? ':' + location.port : ''
     1522    }));
    13341523  },
    13351524
    13361525  getHeader: function(name) {
    13371526    try {
    1338       return this.transport.getResponseHeader(name);
    1339     } catch (e) { return null }
     1527      return this.transport.getResponseHeader(name) || null;
     1528    } catch (e) { return null; }
    13401529  },
    13411530
     
    13571546  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
    13581547
     1548
     1549
     1550
     1551
     1552
     1553
     1554
    13591555Ajax.Response = Class.create({
    13601556  initialize: function(request){
     
    13721568    if(readyState == 4) {
    13731569      var xml = transport.responseXML;
    1374       this.responseXML  = xml === undefined ? null : xml;
     1570      this.responseXML  = Object.isUndefined(xml) ? null : xml;
    13751571      this.responseJSON = this._getResponseJSON();
    13761572    }
     
    13781574
    13791575  status:      0,
     1576
    13801577  statusText: '',
    13811578
     
    14091606    json = decodeURIComponent(escape(json));
    14101607    try {
    1411       return json.evalJSON(this.request.options.sanitizeJSON);
     1608      return json.evalJSON(this.request.options.sanitizeJSON ||
     1609        !this.request.isSameOrigin());
    14121610    } catch (e) {
    14131611      this.request.dispatchException(e);
     
    14181616    var options = this.request.options;
    14191617    if (!options.evalJSON || (options.evalJSON != 'force' &&
    1420       !(this.getHeader('Content-type') || '').include('application/json')))
    1421         return null;
     1618      !(this.getHeader('Content-type') || '').include('application/json')) ||
     1619        this.responseText.blank())
     1620          return null;
    14221621    try {
    1423       return this.transport.responseText.evalJSON(options.sanitizeJSON);
     1622      return this.responseText.evalJSON(options.sanitizeJSON ||
     1623        !this.request.isSameOrigin());
    14241624    } catch (e) {
    14251625      this.request.dispatchException(e);
     
    14351635    };
    14361636
    1437     options = options || { };
     1637    options = Object.clone(options);
    14381638    var onComplete = options.onComplete;
    1439     options.onComplete = (function(response, param) {
     1639    options.onComplete = (function(response, json) {
    14401640      this.updateContent(response.responseText);
    1441       if (Object.isFunction(onComplete)) onComplete(response, param);
     1641      if (Object.isFunction(onComplete)) onComplete(response, json);
    14421642    }).bind(this);
    14431643
     
    14611661      else receiver.update(responseText);
    14621662    }
    1463 
    1464     if (this.success()) {
    1465       if (this.onComplete) this.onComplete.bind(this).defer();
    1466     }
    14671663  }
    14681664});
     
    15081704  }
    15091705});
     1706
     1707
     1708
    15101709function $(element) {
    15111710  if (arguments.length > 1) {
     
    15351734
    15361735if (!Node.ELEMENT_NODE) {
    1537   // DOM level 2 ECMAScript Language Binding
    15381736  Object.extend(Node, {
    15391737    ELEMENT_NODE: 1,
     
    15521750}
    15531751
    1554 (function() {
    1555   var element = this.Element;
    1556   this.Element = function(tagName, attributes) {
     1752
     1753(function(global) {
     1754
     1755  var SETATTRIBUTE_IGNORES_NAME = (function(){
     1756    var elForm = document.createElement("form");
     1757    var elInput = document.createElement("input");
     1758    var root = document.documentElement;
     1759    elInput.setAttribute("name", "test");
     1760    elForm.appendChild(elInput);
     1761    root.appendChild(elForm);
     1762    var isBuggy = elForm.elements
     1763      ? (typeof elForm.elements.test == "undefined")
     1764      : null;
     1765    root.removeChild(elForm);
     1766    elForm = elInput = null;
     1767    return isBuggy;
     1768  })();
     1769
     1770  var element = global.Element;
     1771  global.Element = function(tagName, attributes) {
    15571772    attributes = attributes || { };
    15581773    tagName = tagName.toLowerCase();
    15591774    var cache = Element.cache;
    1560     if (Prototype.Browser.IE && attributes.name) {
     1775    if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
    15611776      tagName = '<' + tagName + ' name="' + attributes.name + '">';
    15621777      delete attributes.name;
     
    15661781    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
    15671782  };
    1568   Object.extend(this.Element, element || { });
    1569 }).call(window);
     1783  Object.extend(global.Element, element || { });
     1784  if (element) global.Element.prototype = element.prototype;
     1785})(this);
    15701786
    15711787Element.cache = { };
     1788Element.idCounter = 1;
    15721789
    15731790Element.Methods = {
     
    15821799  },
    15831800
     1801
    15841802  hide: function(element) {
    1585     $(element).style.display = 'none';
     1803    element = $(element);
     1804    element.style.display = 'none';
    15861805    return element;
    15871806  },
    15881807
    15891808  show: function(element) {
    1590     $(element).style.display = '';
     1809    element = $(element);
     1810    element.style.display = '';
    15911811    return element;
    15921812  },
     
    15981818  },
    15991819
    1600   update: function(element, content) {
    1601     element = $(element);
    1602     if (content && content.toElement) content = content.toElement();
    1603     if (Object.isElement(content)) return element.update().insert(content);
    1604     content = Object.toHTML(content);
    1605     element.innerHTML = content.stripScripts();
    1606     content.evalScripts.bind(content).defer();
    1607     return element;
    1608   },
     1820  update: (function(){
     1821
     1822    var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){
     1823      var el = document.createElement("select"),
     1824          isBuggy = true;
     1825      el.innerHTML = "<option value=\"test\">test</option>";
     1826      if (el.options && el.options[0]) {
     1827        isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION";
     1828      }
     1829      el = null;
     1830      return isBuggy;
     1831    })();
     1832
     1833    var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){
     1834      try {
     1835        var el = document.createElement("table");
     1836        if (el && el.tBodies) {
     1837          el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>";
     1838          var isBuggy = typeof el.tBodies[0] == "undefined";
     1839          el = null;
     1840          return isBuggy;
     1841        }
     1842      } catch (e) {
     1843        return true;
     1844      }
     1845    })();
     1846
     1847    var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () {
     1848      var s = document.createElement("script"),
     1849          isBuggy = false;
     1850      try {
     1851        s.appendChild(document.createTextNode(""));
     1852        isBuggy = !s.firstChild ||
     1853          s.firstChild && s.firstChild.nodeType !== 3;
     1854      } catch (e) {
     1855        isBuggy = true;
     1856      }
     1857      s = null;
     1858      return isBuggy;
     1859    })();
     1860
     1861    function update(element, content) {
     1862      element = $(element);
     1863
     1864      if (content && content.toElement)
     1865        content = content.toElement();
     1866
     1867      if (Object.isElement(content))
     1868        return element.update().insert(content);
     1869
     1870      content = Object.toHTML(content);
     1871
     1872      var tagName = element.tagName.toUpperCase();
     1873
     1874      if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) {
     1875        element.text = content;
     1876        return element;
     1877      }
     1878
     1879      if (SELECT_ELEMENT_INNERHTML_BUGGY || TABLE_ELEMENT_INNERHTML_BUGGY) {
     1880        if (tagName in Element._insertionTranslations.tags) {
     1881          while (element.firstChild) {
     1882            element.removeChild(element.firstChild);
     1883          }
     1884          Element._getContentFromAnonymousElement(tagName, content.stripScripts())
     1885            .each(function(node) {
     1886              element.appendChild(node)
     1887            });
     1888        }
     1889        else {
     1890          element.innerHTML = content.stripScripts();
     1891        }
     1892      }
     1893      else {
     1894        element.innerHTML = content.stripScripts();
     1895      }
     1896
     1897      content.evalScripts.bind(content).defer();
     1898      return element;
     1899    }
     1900
     1901    return update;
     1902  })(),
    16091903
    16101904  replace: function(element, content) {
     
    16291923          insertions = {bottom:insertions};
    16301924
    1631     var content, t, range;
    1632 
    1633     for (position in insertions) {
     1925    var content, insert, tagName, childNodes;
     1926
     1927    for (var position in insertions) {
    16341928      content  = insertions[position];
    16351929      position = position.toLowerCase();
    1636       t = Element._insertionTranslations[position];
     1930      insert = Element._insertionTranslations[position];
    16371931
    16381932      if (content && content.toElement) content = content.toElement();
    16391933      if (Object.isElement(content)) {
    1640         t.insert(element, content);
     1934        insert(element, content);
    16411935        continue;
    16421936      }
     
    16441938      content = Object.toHTML(content);
    16451939
    1646       range = element.ownerDocument.createRange();
    1647       t.initializeRange(element, range);
    1648       t.insert(element, range.createContextualFragment(content.stripScripts()));
     1940      tagName = ((position == 'before' || position == 'after')
     1941        ? element.parentNode : element).tagName.toUpperCase();
     1942
     1943      childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
     1944
     1945      if (position == 'top' || position == 'after') childNodes.reverse();
     1946      childNodes.each(insert.curry(element));
    16491947
    16501948      content.evalScripts.bind(content).defer();
     
    16871985
    16881986  ancestors: function(element) {
    1689     return $(element).recursivelyCollect('parentNode');
     1987    return Element.recursivelyCollect(element, 'parentNode');
    16901988  },
    16911989
    16921990  descendants: function(element) {
    1693     return $A($(element).getElementsByTagName('*')).each(Element.extend);
     1991    return Element.select(element, "*");
    16941992  },
    16951993
     
    17082006
    17092007  previousSiblings: function(element) {
    1710     return $(element).recursivelyCollect('previousSibling');
     2008    return Element.recursivelyCollect(element, 'previousSibling');
    17112009  },
    17122010
    17132011  nextSiblings: function(element) {
    1714     return $(element).recursivelyCollect('nextSibling');
     2012    return Element.recursivelyCollect(element, 'nextSibling');
    17152013  },
    17162014
    17172015  siblings: function(element) {
    17182016    element = $(element);
    1719     return element.previousSiblings().reverse().concat(element.nextSiblings());
     2017    return Element.previousSiblings(element).reverse()
     2018      .concat(Element.nextSiblings(element));
    17202019  },
    17212020
     
    17292028    element = $(element);
    17302029    if (arguments.length == 1) return $(element.parentNode);
    1731     var ancestors = element.ancestors();
    1732     return expression ? Selector.findElement(ancestors, expression, index) :
    1733       ancestors[index || 0];
     2030    var ancestors = Element.ancestors(element);
     2031    return Object.isNumber(expression) ? ancestors[expression] :
     2032      Selector.findElement(ancestors, expression, index);
    17342033  },
    17352034
    17362035  down: function(element, expression, index) {
    17372036    element = $(element);
    1738     if (arguments.length == 1) return element.firstDescendant();
    1739     var descendants = element.descendants();
    1740     return expression ? Selector.findElement(descendants, expression, index) :
    1741       descendants[index || 0];
     2037    if (arguments.length == 1) return Element.firstDescendant(element);
     2038    return Object.isNumber(expression) ? Element.descendants(element)[expression] :
     2039      Element.select(element, expression)[index || 0];
    17422040  },
    17432041
     
    17452043    element = $(element);
    17462044    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    1747     var previousSiblings = element.previousSiblings();
    1748     return expression ? Selector.findElement(previousSiblings, expression, index) :
    1749       previousSiblings[index || 0];
     2045    var previousSiblings = Element.previousSiblings(element);
     2046    return Object.isNumber(expression) ? previousSiblings[expression] :
     2047      Selector.findElement(previousSiblings, expression, index);
    17502048  },
    17512049
     
    17532051    element = $(element);
    17542052    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    1755     var nextSiblings = element.nextSiblings();
    1756     return expression ? Selector.findElement(nextSiblings, expression, index) :
    1757       nextSiblings[index || 0];
    1758   },
    1759 
    1760   select: function() {
    1761     var args = $A(arguments), element = $(args.shift());
     2053    var nextSiblings = Element.nextSiblings(element);
     2054    return Object.isNumber(expression) ? nextSiblings[expression] :
     2055      Selector.findElement(nextSiblings, expression, index);
     2056  },
     2057
     2058
     2059  select: function(element) {
     2060    var args = Array.prototype.slice.call(arguments, 1);
    17622061    return Selector.findChildElements(element, args);
    17632062  },
    17642063
    1765   adjacent: function() {
    1766     var args = $A(arguments), element = $(args.shift());
     2064  adjacent: function(element) {
     2065    var args = Array.prototype.slice.call(arguments, 1);
    17672066    return Selector.findChildElements(element.parentNode, args).without(element);
    17682067  },
     
    17702069  identify: function(element) {
    17712070    element = $(element);
    1772     var id = element.readAttribute('id'), self = arguments.callee;
     2071    var id = Element.readAttribute(element, 'id');
    17732072    if (id) return id;
    1774     do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    1775     element.writeAttribute('id', id);
     2073    do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id));
     2074    Element.writeAttribute(element, 'id', id);
    17762075    return id;
    17772076  },
     
    17962095
    17972096    if (typeof name == 'object') attributes = name;
    1798     else attributes[name] = value === undefined ? true : value;
     2097    else attributes[name] = Object.isUndefined(value) ? true : value;
    17992098
    18002099    for (var attr in attributes) {
    1801       var name = t.names[attr] || attr, value = attributes[attr];
     2100      name = t.names[attr] || attr;
     2101      value = attributes[attr];
    18022102      if (t.values[attr]) name = t.values[attr](element, value);
    18032103      if (value === false || value === null)
     
    18112111
    18122112  getHeight: function(element) {
    1813     return $(element).getDimensions().height;
     2113    return Element.getDimensions(element).height;
    18142114  },
    18152115
    18162116  getWidth: function(element) {
    1817     return $(element).getDimensions().width;
     2117    return Element.getDimensions(element).width;
    18182118  },
    18192119
     
    18312131  addClassName: function(element, className) {
    18322132    if (!(element = $(element))) return;
    1833     if (!element.hasClassName(className))
     2133    if (!Element.hasClassName(element, className))
    18342134      element.className += (element.className ? ' ' : '') + className;
    18352135    return element;
     
    18452145  toggleClassName: function(element, className) {
    18462146    if (!(element = $(element))) return;
    1847     return element[element.hasClassName(className) ?
    1848       'removeClassName' : 'addClassName'](className);
    1849   },
    1850 
    1851   // removes whitespace-only text node children
     2147    return Element[Element.hasClassName(element, className) ?
     2148      'removeClassName' : 'addClassName'](element, className);
     2149  },
     2150
    18522151  cleanWhitespace: function(element) {
    18532152    element = $(element);
     
    18722171      return (element.compareDocumentPosition(ancestor) & 8) === 8;
    18732172
    1874     if (element.sourceIndex && !Prototype.Browser.Opera) {
    1875       var e = element.sourceIndex, a = ancestor.sourceIndex,
    1876        nextAncestor = ancestor.nextSibling;
    1877       if (!nextAncestor) {
    1878         do { ancestor = ancestor.parentNode; }
    1879         while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
    1880       }
    1881       if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
    1882     }
     2173    if (ancestor.contains)
     2174      return ancestor.contains(element) && ancestor !== element;
    18832175
    18842176    while (element = element.parentNode)
    18852177      if (element == ancestor) return true;
     2178
    18862179    return false;
    18872180  },
     
    18892182  scrollTo: function(element) {
    18902183    element = $(element);
    1891     var pos = element.cumulativeOffset();
     2184    var pos = Element.cumulativeOffset(element);
    18922185    window.scrollTo(pos[0], pos[1]);
    18932186    return element;
     
    18982191    style = style == 'float' ? 'cssFloat' : style.camelize();
    18992192    var value = element.style[style];
    1900     if (!value) {
     2193    if (!value || value == 'auto') {
    19012194      var css = document.defaultView.getComputedStyle(element, null);
    19022195      value = css ? css[style] : null;
     
    19222215      else
    19232216        elementStyle[(property == 'float' || property == 'cssFloat') ?
    1924           (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
     2217          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
    19252218            property] = styles[property];
    19262219
     
    19372230  getDimensions: function(element) {
    19382231    element = $(element);
    1939     var display = $(element).getStyle('display');
     2232    var display = Element.getStyle(element, 'display');
    19402233    if (display != 'none' && display != null) // Safari bug
    19412234      return {width: element.offsetWidth, height: element.offsetHeight};
    19422235
    1943     // All *Width and *Height properties give 0 on elements with display none,
    1944     // so enable the element temporarily
    19452236    var els = element.style;
    19462237    var originalVisibility = els.visibility;
     
    19482239    var originalDisplay = els.display;
    19492240    els.visibility = 'hidden';
    1950     els.position = 'absolute';
     2241    if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
     2242      els.position = 'absolute';
    19512243    els.display = 'block';
    19522244    var originalWidth = element.clientWidth;
     
    19642256      element._madePositioned = true;
    19652257      element.style.position = 'relative';
    1966       // Opera returns the offset relative to the positioning context, when an
    1967       // element is position relative but top and left have not been defined
    1968       if (window.opera) {
     2258      if (Prototype.Browser.Opera) {
    19692259        element.style.top = 0;
    19702260        element.style.left = 0;
     
    20212311      element = element.offsetParent;
    20222312      if (element) {
    2023         if (element.tagName == 'BODY') break;
     2313        if (element.tagName.toUpperCase() == 'BODY') break;
    20242314        var p = Element.getStyle(element, 'position');
    2025         if (p == 'relative' || p == 'absolute') break;
     2315        if (p !== 'static') break;
    20262316      }
    20272317    } while (element);
     
    20312321  absolutize: function(element) {
    20322322    element = $(element);
    2033     if (element.getStyle('position') == 'absolute') return;
    2034     // Position.prepare(); // To be done manually by Scripty when it needs it.
    2035 
    2036     var offsets = element.positionedOffset();
     2323    if (Element.getStyle(element, 'position') == 'absolute') return element;
     2324
     2325    var offsets = Element.positionedOffset(element);
    20372326    var top     = offsets[1];
    20382327    var left    = offsets[0];
     
    20552344  relativize: function(element) {
    20562345    element = $(element);
    2057     if (element.getStyle('position') == 'relative') return;
    2058     // Position.prepare(); // To be done manually by Scripty when it needs it.
     2346    if (Element.getStyle(element, 'position') == 'relative') return element;
    20592347
    20602348    element.style.position = 'relative';
     
    20982386      valueL += element.offsetLeft || 0;
    20992387
    2100       // Safari fix
    21012388      if (element.offsetParent == document.body &&
    21022389        Element.getStyle(element, 'position') == 'absolute') break;
     
    21062393    element = forElement;
    21072394    do {
    2108       if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
     2395      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
    21092396        valueT -= element.scrollTop  || 0;
    21102397        valueL -= element.scrollLeft || 0;
     
    21252412    }, arguments[2] || { });
    21262413
    2127     // find page position of source
    21282414    source = $(source);
    2129     var p = source.viewportOffset();
    2130 
    2131     // find coordinate system to use
     2415    var p = Element.viewportOffset(source);
     2416
    21322417    element = $(element);
    21332418    var delta = [0, 0];
    21342419    var parent = null;
    2135     // delta [0,0] will do fine with position: fixed elements,
    2136     // position:absolute needs offsetParent deltas
    21372420    if (Element.getStyle(element, 'position') == 'absolute') {
    2138       parent = element.getOffsetParent();
    2139       delta = parent.viewportOffset();
    2140     }
    2141 
    2142     // correct by body offsets (fixes Safari)
     2421      parent = Element.getOffsetParent(element);
     2422      delta = Element.viewportOffset(parent);
     2423    }
     2424
    21432425    if (parent == document.body) {
    21442426      delta[0] -= document.body.offsetLeft;
     
    21462428    }
    21472429
    2148     // set position
    21492430    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    21502431    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
     
    21552436};
    21562437
    2157 Element.Methods.identify.counter = 1;
    2158 
    21592438Object.extend(Element.Methods, {
    21602439  getElementsBySelector: Element.Methods.select,
     2440
    21612441  childElements: Element.Methods.immediateDescendants
    21622442});
     
    21722452};
    21732453
    2174 
    2175 if (!document.createRange || Prototype.Browser.Opera) {
    2176   Element.Methods.insert = function(element, insertions) {
    2177     element = $(element);
    2178 
    2179     if (Object.isString(insertions) || Object.isNumber(insertions) ||
    2180         Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
    2181           insertions = { bottom: insertions };
    2182 
    2183     var t = Element._insertionTranslations, content, position, pos, tagName;
    2184 
    2185     for (position in insertions) {
    2186       content  = insertions[position];
    2187       position = position.toLowerCase();
    2188       pos      = t[position];
    2189 
    2190       if (content && content.toElement) content = content.toElement();
    2191       if (Object.isElement(content)) {
    2192         pos.insert(element, content);
    2193         continue;
    2194       }
    2195 
    2196       content = Object.toHTML(content);
    2197       tagName = ((position == 'before' || position == 'after')
    2198         ? element.parentNode : element).tagName.toUpperCase();
    2199 
    2200       if (t.tags[tagName]) {
    2201         var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
    2202         if (position == 'top' || position == 'after') fragments.reverse();
    2203         fragments.each(pos.insert.curry(element));
    2204       }
    2205       else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());
    2206 
    2207       content.evalScripts.bind(content).defer();
    2208     }
    2209 
    2210     return element;
    2211   };
     2454if (Prototype.Browser.Opera) {
     2455  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
     2456    function(proceed, element, style) {
     2457      switch (style) {
     2458        case 'left': case 'top': case 'right': case 'bottom':
     2459          if (proceed(element, 'position') === 'static') return null;
     2460        case 'height': case 'width':
     2461          if (!Element.visible(element)) return null;
     2462
     2463          var dim = parseInt(proceed(element, style), 10);
     2464
     2465          if (dim !== element['offset' + style.capitalize()])
     2466            return dim + 'px';
     2467
     2468          var properties;
     2469          if (style === 'height') {
     2470            properties = ['border-top-width', 'padding-top',
     2471             'padding-bottom', 'border-bottom-width'];
     2472          }
     2473          else {
     2474            properties = ['border-left-width', 'padding-left',
     2475             'padding-right', 'border-right-width'];
     2476          }
     2477          return properties.inject(dim, function(memo, property) {
     2478            var val = proceed(element, property);
     2479            return val === null ? memo : memo - parseInt(val, 10);
     2480          }) + 'px';
     2481        default: return proceed(element, style);
     2482      }
     2483    }
     2484  );
     2485
     2486  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
     2487    function(proceed, element, attribute) {
     2488      if (attribute === 'title') return element.title;
     2489      return proceed(element, attribute);
     2490    }
     2491  );
    22122492}
    22132493
    2214 if (Prototype.Browser.Opera) {
    2215   Element.Methods._getStyle = Element.Methods.getStyle;
    2216   Element.Methods.getStyle = function(element, style) {
    2217     switch(style) {
    2218       case 'left':
    2219       case 'top':
    2220       case 'right':
    2221       case 'bottom':
    2222         if (Element._getStyle(element, 'position') == 'static') return null;
    2223       default: return Element._getStyle(element, style);
    2224     }
    2225   };
    2226   Element.Methods._readAttribute = Element.Methods.readAttribute;
    2227   Element.Methods.readAttribute = function(element, attribute) {
    2228     if (attribute == 'title') return element.title;
    2229     return Element._readAttribute(element, attribute);
    2230   };
    2231 }
    2232 
    22332494else if (Prototype.Browser.IE) {
    2234   $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
     2495  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
     2496    function(proceed, element) {
     2497      element = $(element);
     2498      try { element.offsetParent }
     2499      catch(e) { return $(document.body) }
     2500      var position = element.getStyle('position');
     2501      if (position !== 'static') return proceed(element);
     2502      element.setStyle({ position: 'relative' });
     2503      var value = proceed(element);
     2504      element.setStyle({ position: position });
     2505      return value;
     2506    }
     2507  );
     2508
     2509  $w('positionedOffset viewportOffset').each(function(method) {
    22352510    Element.Methods[method] = Element.Methods[method].wrap(
    22362511      function(proceed, element) {
    22372512        element = $(element);
     2513        try { element.offsetParent }
     2514        catch(e) { return Element._returnOffset(0,0) }
    22382515        var position = element.getStyle('position');
    2239         if (position != 'static') return proceed(element);
     2516        if (position !== 'static') return proceed(element);
     2517        var offsetParent = element.getOffsetParent();
     2518        if (offsetParent && offsetParent.getStyle('position') === 'fixed')
     2519          offsetParent.setStyle({ zoom: 1 });
    22402520        element.setStyle({ position: 'relative' });
    22412521        var value = proceed(element);
     
    22452525    );
    22462526  });
     2527
     2528  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
     2529    function(proceed, element) {
     2530      try { element.offsetParent }
     2531      catch(e) { return Element._returnOffset(0,0) }
     2532      return proceed(element);
     2533    }
     2534  );
    22472535
    22482536  Element.Methods.getStyle = function(element, style) {
     
    22872575  };
    22882576
    2289   Element._attributeTranslations = {
    2290     read: {
    2291       names: {
    2292         'class': 'className',
    2293         'for':   'htmlFor'
    2294       },
    2295       values: {
    2296         _getAttr: function(element, attribute) {
    2297           return element.getAttribute(attribute, 2);
     2577  Element._attributeTranslations = (function(){
     2578
     2579    var classProp = 'className';
     2580    var forProp = 'for';
     2581
     2582    var el = document.createElement('div');
     2583
     2584    el.setAttribute(classProp, 'x');
     2585
     2586    if (el.className !== 'x') {
     2587      el.setAttribute('class', 'x');
     2588      if (el.className === 'x') {
     2589        classProp = 'class';
     2590      }
     2591    }
     2592    el = null;
     2593
     2594    el = document.createElement('label');
     2595    el.setAttribute(forProp, 'x');
     2596    if (el.htmlFor !== 'x') {
     2597      el.setAttribute('htmlFor', 'x');
     2598      if (el.htmlFor === 'x') {
     2599        forProp = 'htmlFor';
     2600      }
     2601    }
     2602    el = null;
     2603
     2604    return {
     2605      read: {
     2606        names: {
     2607          'class':      classProp,
     2608          'className':  classProp,
     2609          'for':        forProp,
     2610          'htmlFor':    forProp
    22982611        },
    2299         _getAttrNode: function(element, attribute) {
    2300           var node = element.getAttributeNode(attribute);
    2301           return node ? node.value : "";
    2302         },
    2303         _getEv: function(element, attribute) {
    2304           var attribute = element.getAttribute(attribute);
    2305           return attribute ? attribute.toString().slice(23, -2) : null;
    2306         },
    2307         _flag: function(element, attribute) {
    2308           return $(element).hasAttribute(attribute) ? attribute : null;
    2309         },
    2310         style: function(element) {
    2311           return element.style.cssText.toLowerCase();
    2312         },
    2313         title: function(element) {
    2314           return element.title;
     2612        values: {
     2613          _getAttr: function(element, attribute) {
     2614            return element.getAttribute(attribute);
     2615          },
     2616          _getAttr2: function(element, attribute) {
     2617            return element.getAttribute(attribute, 2);
     2618          },
     2619          _getAttrNode: function(element, attribute) {
     2620            var node = element.getAttributeNode(attribute);
     2621            return node ? node.value : "";
     2622          },
     2623          _getEv: (function(){
     2624
     2625            var el = document.createElement('div');
     2626            el.onclick = Prototype.emptyFunction;
     2627            var value = el.getAttribute('onclick');
     2628            var f;
     2629
     2630            if (String(value).indexOf('{') > -1) {
     2631              f = function(element, attribute) {
     2632                attribute = element.getAttribute(attribute);
     2633                if (!attribute) return null;
     2634                attribute = attribute.toString();
     2635                attribute = attribute.split('{')[1];
     2636                attribute = attribute.split('}')[0];
     2637                return attribute.strip();
     2638              };
     2639            }
     2640            else if (value === '') {
     2641              f = function(element, attribute) {
     2642                attribute = element.getAttribute(attribute);
     2643                if (!attribute) return null;
     2644                return attribute.strip();
     2645              };
     2646            }
     2647            el = null;
     2648            return f;
     2649          })(),
     2650          _flag: function(element, attribute) {
     2651            return $(element).hasAttribute(attribute) ? attribute : null;
     2652          },
     2653          style: function(element) {
     2654            return element.style.cssText.toLowerCase();
     2655          },
     2656          title: function(element) {
     2657            return element.title;
     2658          }
    23152659        }
    23162660      }
    23172661    }
    2318   };
     2662  })();
    23192663
    23202664  Element._attributeTranslations.write = {
    2321     names: Object.clone(Element._attributeTranslations.read.names),
     2665    names: Object.extend({
     2666      cellpadding: 'cellPadding',
     2667      cellspacing: 'cellSpacing'
     2668    }, Element._attributeTranslations.read.names),
    23222669    values: {
    23232670      checked: function(element, value) {
     
    23342681
    23352682  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
    2336       'encType maxLength readOnly longDesc').each(function(attr) {
     2683      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
    23372684    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    23382685    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
     
    23412688  (function(v) {
    23422689    Object.extend(v, {
    2343       href:        v._getAttr,
    2344       src:         v._getAttr,
     2690      href:        v._getAttr2,
     2691      src:         v._getAttr2,
    23452692      type:        v._getAttr,
    23462693      action:      v._getAttrNode,
     
    23692716    });
    23702717  })(Element._attributeTranslations.read.values);
     2718
     2719  if (Prototype.BrowserFeatures.ElementExtensions) {
     2720    (function() {
     2721      function _descendants(element) {
     2722        var nodes = element.getElementsByTagName('*'), results = [];
     2723        for (var i = 0, node; node = nodes[i]; i++)
     2724          if (node.tagName !== "!") // Filter out comment nodes.
     2725            results.push(node);
     2726        return results;
     2727      }
     2728
     2729      Element.Methods.down = function(element, expression, index) {
     2730        element = $(element);
     2731        if (arguments.length == 1) return element.firstDescendant();
     2732        return Object.isNumber(expression) ? _descendants(element)[expression] :
     2733          Element.select(element, expression)[index || 0];
     2734      }
     2735    })();
     2736  }
     2737
    23712738}
    23722739
     
    23872754
    23882755    if (value == 1)
    2389       if(element.tagName == 'IMG' && element.width) {
     2756      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
    23902757        element.width++; element.width--;
    23912758      } else try {
     
    23982765  };
    23992766
    2400   // Safari returns margins on body which is incorrect if the child is absolutely
    2401   // positioned.  For performance reasons, redefine Position.cumulativeOffset for
    2402   // KHTML/WebKit only.
    24032767  Element.Methods.cumulativeOffset = function(element) {
    24042768    var valueT = 0, valueL = 0;
     
    24162780}
    24172781
    2418 if (Prototype.Browser.IE || Prototype.Browser.Opera) {
    2419   // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
    2420   Element.Methods.update = function(element, content) {
    2421     element = $(element);
    2422 
    2423     if (content && content.toElement) content = content.toElement();
    2424     if (Object.isElement(content)) return element.update().insert(content);
    2425 
    2426     content = Object.toHTML(content);
    2427     var tagName = element.tagName.toUpperCase();
    2428 
    2429     if (tagName in Element._insertionTranslations.tags) {
    2430       $A(element.childNodes).each(function(node) { element.removeChild(node) });
    2431       Element._getContentFromAnonymousElement(tagName, content.stripScripts())
    2432         .each(function(node) { element.appendChild(node) });
    2433     }
    2434     else element.innerHTML = content.stripScripts();
    2435 
    2436     content.evalScripts.bind(content).defer();
    2437     return element;
    2438   };
    2439 }
    2440 
    2441 if (document.createElement('div').outerHTML) {
     2782if ('outerHTML' in document.documentElement) {
    24422783  Element.Methods.replace = function(element, content) {
    24432784    element = $(element);
     
    24772818Element._getContentFromAnonymousElement = function(tagName, html) {
    24782819  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
    2479   div.innerHTML = t[0] + html + t[1];
    2480   t[2].times(function() { div = div.firstChild });
     2820  if (t) {
     2821    div.innerHTML = t[0] + html + t[1];
     2822    t[2].times(function() { div = div.firstChild });
     2823  } else div.innerHTML = html;
    24812824  return $A(div.childNodes);
    24822825};
    24832826
    24842827Element._insertionTranslations = {
    2485   before: {
    2486     adjacency: 'beforeBegin',
    2487     insert: function(element, node) {
    2488       element.parentNode.insertBefore(node, element);
    2489     },
    2490     initializeRange: function(element, range) {
    2491       range.setStartBefore(element);
    2492     }
    2493   },
    2494   top: {
    2495     adjacency: 'afterBegin',
    2496     insert: function(element, node) {
    2497       element.insertBefore(node, element.firstChild);
    2498     },
    2499     initializeRange: function(element, range) {
    2500       range.selectNodeContents(element);
    2501       range.collapse(true);
    2502     }
    2503   },
    2504   bottom: {
    2505     adjacency: 'beforeEnd',
    2506     insert: function(element, node) {
    2507       element.appendChild(node);
    2508     }
    2509   },
    2510   after: {
    2511     adjacency: 'afterEnd',
    2512     insert: function(element, node) {
    2513       element.parentNode.insertBefore(node, element.nextSibling);
    2514     },
    2515     initializeRange: function(element, range) {
    2516       range.setStartAfter(element);
    2517     }
     2828  before: function(element, node) {
     2829    element.parentNode.insertBefore(node, element);
     2830  },
     2831  top: function(element, node) {
     2832    element.insertBefore(node, element.firstChild);
     2833  },
     2834  bottom: function(element, node) {
     2835    element.appendChild(node);
     2836  },
     2837  after: function(element, node) {
     2838    element.parentNode.insertBefore(node, element.nextSibling);
    25182839  },
    25192840  tags: {
     
    25272848
    25282849(function() {
    2529   this.bottom.initializeRange = this.top.initializeRange;
    2530   Object.extend(this.tags, {
    2531     THEAD: this.tags.TBODY,
    2532     TFOOT: this.tags.TBODY,
    2533     TH:    this.tags.TD
     2850  var tags = Element._insertionTranslations.tags;
     2851  Object.extend(tags, {
     2852    THEAD: tags.TBODY,
     2853    TFOOT: tags.TBODY,
     2854    TH:    tags.TD
    25342855  });
    2535 }).call(Element._insertionTranslations);
     2856})();
    25362857
    25372858Element.Methods.Simulated = {
     
    25392860    attribute = Element._attributeTranslations.has[attribute] || attribute;
    25402861    var node = $(element).getAttributeNode(attribute);
    2541     return node && node.specified;
     2862    return !!(node && node.specified);
    25422863  }
    25432864};
     
    25472868Object.extend(Element, Element.Methods);
    25482869
    2549 if (!Prototype.BrowserFeatures.ElementExtensions &&
    2550     document.createElement('div').__proto__) {
    2551   window.HTMLElement = { };
    2552   window.HTMLElement.prototype = document.createElement('div').__proto__;
    2553   Prototype.BrowserFeatures.ElementExtensions = true;
    2554 }
     2870(function(div) {
     2871
     2872  if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) {
     2873    window.HTMLElement = { };
     2874    window.HTMLElement.prototype = div['__proto__'];
     2875    Prototype.BrowserFeatures.ElementExtensions = true;
     2876  }
     2877
     2878  div = null;
     2879
     2880})(document.createElement('div'))
    25552881
    25562882Element.extend = (function() {
    2557   if (Prototype.BrowserFeatures.SpecificElementExtensions)
    2558     return Prototype.K;
    2559 
    2560   var Methods = { }, ByTag = Element.Methods.ByTag;
    2561 
    2562   var extend = Object.extend(function(element) {
    2563     if (!element || element._extendedByPrototype ||
    2564         element.nodeType != 1 || element == window) return element;
    2565 
    2566     var methods = Object.clone(Methods),
    2567       tagName = element.tagName, property, value;
    2568 
    2569     // extend methods for specific tags
    2570     if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
    2571 
    2572     for (property in methods) {
    2573       value = methods[property];
     2883
     2884  function checkDeficiency(tagName) {
     2885    if (typeof window.Element != 'undefined') {
     2886      var proto = window.Element.prototype;
     2887      if (proto) {
     2888        var id = '_' + (Math.random()+'').slice(2);
     2889        var el = document.createElement(tagName);
     2890        proto[id] = 'x';
     2891        var isBuggy = (el[id] !== 'x');
     2892        delete proto[id];
     2893        el = null;
     2894        return isBuggy;
     2895      }
     2896    }
     2897    return false;
     2898  }
     2899
     2900  function extendElementWith(element, methods) {
     2901    for (var property in methods) {
     2902      var value = methods[property];
    25742903      if (Object.isFunction(value) && !(property in element))
    25752904        element[property] = value.methodize();
    25762905    }
     2906  }
     2907
     2908  var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object');
     2909
     2910  if (Prototype.BrowserFeatures.SpecificElementExtensions) {
     2911    if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) {
     2912      return function(element) {
     2913        if (element && typeof element._extendedByPrototype == 'undefined') {
     2914          var t = element.tagName;
     2915          if (t && (/^(?:object|applet|embed)$/i.test(t))) {
     2916            extendElementWith(element, Element.Methods);
     2917            extendElementWith(element, Element.Methods.Simulated);
     2918            extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]);
     2919          }
     2920        }
     2921        return element;
     2922      }
     2923    }
     2924    return Prototype.K;
     2925  }
     2926
     2927  var Methods = { }, ByTag = Element.Methods.ByTag;
     2928
     2929  var extend = Object.extend(function(element) {
     2930    if (!element || typeof element._extendedByPrototype != 'undefined' ||
     2931        element.nodeType != 1 || element == window) return element;
     2932
     2933    var methods = Object.clone(Methods),
     2934        tagName = element.tagName.toUpperCase();
     2935
     2936    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
     2937
     2938    extendElementWith(element, methods);
    25772939
    25782940    element._extendedByPrototype = Prototype.emptyFunction;
     
    25812943  }, {
    25822944    refresh: function() {
    2583       // extend methods for all tags (Safari doesn't need this)
    25842945      if (!Prototype.BrowserFeatures.ElementExtensions) {
    25852946        Object.extend(Methods, Element.Methods);
     
    26603021    if (window[klass]) return window[klass];
    26613022
    2662     window[klass] = { };
    2663     window[klass].prototype = document.createElement(tagName).__proto__;
    2664     return window[klass];
    2665   }
     3023    var element = document.createElement(tagName);
     3024    var proto = element['__proto__'] || element.constructor.prototype;
     3025    element = null;
     3026    return proto;
     3027  }
     3028
     3029  var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
     3030   Element.prototype;
    26663031
    26673032  if (F.ElementExtensions) {
    2668     copy(Element.Methods, HTMLElement.prototype);
    2669     copy(Element.Methods.Simulated, HTMLElement.prototype, true);
     3033    copy(Element.Methods, elementPrototype);
     3034    copy(Element.Methods.Simulated, elementPrototype, true);
    26703035  }
    26713036
     
    26853050};
    26863051
     3052
    26873053document.viewport = {
     3054
    26883055  getDimensions: function() {
    2689     var dimensions = { };
    2690     $w('width height').each(function(d) {
    2691       var D = d.capitalize();
    2692       dimensions[d] = self['inner' + D] ||
    2693        (document.documentElement['client' + D] || document.body['client' + D]);
    2694     });
    2695     return dimensions;
    2696   },
    2697 
    2698   getWidth: function() {
    2699     return this.getDimensions().width;
    2700   },
    2701 
    2702   getHeight: function() {
    2703     return this.getDimensions().height;
     3056    return { width: this.getWidth(), height: this.getHeight() };
    27043057  },
    27053058
     
    27073060    return Element._returnOffset(
    27083061      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
    2709       window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
     3062      window.pageYOffset || document.documentElement.scrollTop  || document.body.scrollTop);
    27103063  }
    27113064};
    2712 /* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
     3065
     3066(function(viewport) {
     3067  var B = Prototype.Browser, doc = document, element, property = {};
     3068
     3069  function getRootElement() {
     3070    if (B.WebKit && !doc.evaluate)
     3071      return document;
     3072
     3073    if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
     3074      return document.body;
     3075
     3076    return document.documentElement;
     3077  }
     3078
     3079  function define(D) {
     3080    if (!element) element = getRootElement();
     3081
     3082    property[D] = 'client' + D;
     3083
     3084    viewport['get' + D] = function() { return element[property[D]] };
     3085    return viewport['get' + D]();
     3086  }
     3087
     3088  viewport.getWidth  = define.curry('Width');
     3089
     3090  viewport.getHeight = define.curry('Height');
     3091})(document.viewport);
     3092
     3093
     3094Element.Storage = {
     3095  UID: 1
     3096};
     3097
     3098Element.addMethods({
     3099  getStorage: function(element) {
     3100    if (!(element = $(element))) return;
     3101
     3102    var uid;
     3103    if (element === window) {
     3104      uid = 0;
     3105    } else {
     3106      if (typeof element._prototypeUID === "undefined")
     3107        element._prototypeUID = [Element.Storage.UID++];
     3108      uid = element._prototypeUID[0];
     3109    }
     3110
     3111    if (!Element.Storage[uid])
     3112      Element.Storage[uid] = $H();
     3113
     3114    return Element.Storage[uid];
     3115  },
     3116
     3117  store: function(element, key, value) {
     3118    if (!(element = $(element))) return;
     3119
     3120    if (arguments.length === 2) {
     3121      Element.getStorage(element).update(key);
     3122    } else {
     3123      Element.getStorage(element).set(key, value);
     3124    }
     3125
     3126    return element;
     3127  },
     3128
     3129  retrieve: function(element, key, defaultValue) {
     3130    if (!(element = $(element))) return;
     3131    var hash = Element.getStorage(element), value = hash.get(key);
     3132
     3133    if (Object.isUndefined(value)) {
     3134      hash.set(key, defaultValue);
     3135      value = defaultValue;
     3136    }
     3137
     3138    return value;
     3139  },
     3140
     3141  clone: function(element, deep) {
     3142    if (!(element = $(element))) return;
     3143    var clone = element.cloneNode(deep);
     3144    clone._prototypeUID = void 0;
     3145    if (deep) {
     3146      var descendants = Element.select(clone, '*'),
     3147          i = descendants.length;
     3148      while (i--) {
     3149        descendants[i]._prototypeUID = void 0;
     3150      }
     3151    }
     3152    return Element.extend(clone);
     3153  }
     3154});
     3155/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
    27133156 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
    27143157 * license.  Please see http://www.yui-ext.com/ for more information. */
     
    27173160  initialize: function(expression) {
    27183161    this.expression = expression.strip();
    2719     this.compileMatcher();
     3162
     3163    if (this.shouldUseSelectorsAPI()) {
     3164      this.mode = 'selectorsAPI';
     3165    } else if (this.shouldUseXPath()) {
     3166      this.mode = 'xpath';
     3167      this.compileXPathMatcher();
     3168    } else {
     3169      this.mode = "normal";
     3170      this.compileMatcher();
     3171    }
     3172
     3173  },
     3174
     3175  shouldUseXPath: (function() {
     3176
     3177    var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
     3178      var isBuggy = false;
     3179      if (document.evaluate && window.XPathResult) {
     3180        var el = document.createElement('div');
     3181        el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
     3182
     3183        var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
     3184          "//*[local-name()='li' or local-name()='LI']";
     3185
     3186        var result = document.evaluate(xpath, el, null,
     3187          XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
     3188
     3189        isBuggy = (result.snapshotLength !== 2);
     3190        el = null;
     3191      }
     3192      return isBuggy;
     3193    })();
     3194
     3195    return function() {
     3196      if (!Prototype.BrowserFeatures.XPath) return false;
     3197
     3198      var e = this.expression;
     3199
     3200      if (Prototype.Browser.WebKit &&
     3201       (e.include("-of-type") || e.include(":empty")))
     3202        return false;
     3203
     3204      if ((/(\[[\w-]*?:|:checked)/).test(e))
     3205        return false;
     3206
     3207      if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
     3208
     3209      return true;
     3210    }
     3211
     3212  })(),
     3213
     3214  shouldUseSelectorsAPI: function() {
     3215    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
     3216
     3217    if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
     3218
     3219    if (!Selector._div) Selector._div = new Element('div');
     3220
     3221    try {
     3222      Selector._div.querySelector(this.expression);
     3223    } catch(e) {
     3224      return false;
     3225    }
     3226
     3227    return true;
    27203228  },
    27213229
    27223230  compileMatcher: function() {
    2723     // Selectors with namespaced attributes can't use the XPath version
    2724     if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression))
    2725       return this.compileXPathMatcher();
    2726 
    27273231    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
    2728         c = Selector.criteria, le, p, m;
     3232        c = Selector.criteria, le, p, m, len = ps.length, name;
    27293233
    27303234    if (Selector._cache[e]) {
     
    27383242    while (e && le != e && (/\S/).test(e)) {
    27393243      le = e;
    2740       for (var i in ps) {
    2741         p = ps[i];
     3244      for (var i = 0; i<len; i++) {
     3245        p = ps[i].re;
     3246        name = ps[i].name;
    27423247        if (m = e.match(p)) {
    2743           this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
    2744               new Template(c[i]).evaluate(m));
     3248          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
     3249            new Template(c[name]).evaluate(m));
    27453250          e = e.replace(m[0], '');
    27463251          break;
     
    27563261  compileXPathMatcher: function() {
    27573262    var e = this.expression, ps = Selector.patterns,
    2758         x = Selector.xpath, le, m;
     3263        x = Selector.xpath, le, m, len = ps.length, name;
    27593264
    27603265    if (Selector._cache[e]) {
     
    27653270    while (e && le != e && (/\S/).test(e)) {
    27663271      le = e;
    2767       for (var i in ps) {
    2768         if (m = e.match(ps[i])) {
    2769           this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
    2770             new Template(x[i]).evaluate(m));
     3272      for (var i = 0; i<len; i++) {
     3273        name = ps[i].name;
     3274        if (m = e.match(ps[i].re)) {
     3275          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
     3276            new Template(x[name]).evaluate(m));
    27713277          e = e.replace(m[0], '');
    27723278          break;
     
    27813287  findElements: function(root) {
    27823288    root = root || document;
    2783     if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    2784     return this.matcher(root);
     3289    var e = this.expression, results;
     3290
     3291    switch (this.mode) {
     3292      case 'selectorsAPI':
     3293        if (root !== document) {
     3294          var oldId = root.id, id = $(root).identify();
     3295          id = id.replace(/([\.:])/g, "\\$1");
     3296          e = "#" + id + " " + e;
     3297        }
     3298
     3299        results = $A(root.querySelectorAll(e)).map(Element.extend);
     3300        root.id = oldId;
     3301
     3302        return results;
     3303      case 'xpath':
     3304        return document._getElementsByXPath(this.xpath, root);
     3305      default:
     3306       return this.matcher(root);
     3307    }
    27853308  },
    27863309
     
    27893312
    27903313    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    2791     var le, p, m;
     3314    var le, p, m, len = ps.length, name;
    27923315
    27933316    while (e && le !== e && (/\S/).test(e)) {
    27943317      le = e;
    2795       for (var i in ps) {
    2796         p = ps[i];
     3318      for (var i = 0; i<len; i++) {
     3319        p = ps[i].re;
     3320        name = ps[i].name;
    27973321        if (m = e.match(p)) {
    2798           // use the Selector.assertions methods unless the selector
    2799           // is too complex.
    2800           if (as[i]) {
    2801             this.tokens.push([i, Object.clone(m)]);
     3322          if (as[name]) {
     3323            this.tokens.push([name, Object.clone(m)]);
    28023324            e = e.replace(m[0], '');
    28033325          } else {
    2804             // reluctantly do a document-wide search
    2805             // and look for a match in the array
    28063326            return this.findElements(document).include(element);
    28073327          }
     
    28293349  }
    28303350});
     3351
     3352if (Prototype.BrowserFeatures.SelectorsAPI &&
     3353 document.compatMode === 'BackCompat') {
     3354  Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
     3355    var div = document.createElement('div'),
     3356     span = document.createElement('span');
     3357
     3358    div.id = "prototype_test_id";
     3359    span.className = 'Test';
     3360    div.appendChild(span);
     3361    var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
     3362    div = span = null;
     3363    return isIgnored;
     3364  })();
     3365}
    28313366
    28323367Object.extend(Selector, {
     
    28453380    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    28463381    id:           "[@id='#{1}']",
    2847     attrPresence: "[@#{1}]",
     3382    attrPresence: function(m) {
     3383      m[1] = m[1].toLowerCase();
     3384      return new Template("[@#{1}]").evaluate(m);
     3385    },
    28483386    attr: function(m) {
     3387      m[1] = m[1].toLowerCase();
    28493388      m[3] = m[5] || m[6];
    28503389      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
     
    28693408      'last-child':  '[not(following-sibling::*)]',
    28703409      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
    2871       'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
     3410      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
    28723411      'checked':     "[@checked]",
    2873       'disabled':    "[@disabled]",
    2874       'enabled':     "[not(@disabled)]",
     3412      'disabled':    "[(@disabled) and (@type!='hidden')]",
     3413      'enabled':     "[not(@disabled) and (@type!='hidden')]",
    28753414      'not': function(m) {
    28763415        var e = m[6], p = Selector.patterns,
    2877             x = Selector.xpath, le, m, v;
     3416            x = Selector.xpath, le, v, len = p.length, name;
    28783417
    28793418        var exclusion = [];
    28803419        while (e && le != e && (/\S/).test(e)) {
    28813420          le = e;
    2882           for (var i in p) {
    2883             if (m = e.match(p[i])) {
    2884               v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
     3421          for (var i = 0; i<len; i++) {
     3422            name = p[i].name
     3423            if (m = e.match(p[i].re)) {
     3424              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
    28853425              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
    28863426              e = e.replace(m[0], '');
     
    29323472
    29333473  criteria: {
    2934     tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
    2935     className:    'n = h.className(n, r, "#{1}", c); c = false;',
    2936     id:           'n = h.id(n, r, "#{1}", c);        c = false;',
    2937     attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
     3474    tagName:      'n = h.tagName(n, r, "#{1}", c);      c = false;',
     3475    className:    'n = h.className(n, r, "#{1}", c);    c = false;',
     3476    id:           'n = h.id(n, r, "#{1}", c);           c = false;',
     3477    attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
    29383478    attr: function(m) {
    29393479      m[3] = (m[5] || m[6]);
    2940       return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
     3480      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
    29413481    },
    29423482    pseudo: function(m) {
     
    29503490  },
    29513491
    2952   patterns: {
    2953     // combinators must be listed first
    2954     // (and descendant needs to be last combinator)
    2955     laterSibling: /^\s*~\s*/,
    2956     child:        /^\s*>\s*/,
    2957     adjacent:     /^\s*\+\s*/,
    2958     descendant:   /^\s/,
    2959 
    2960     // selectors follow
    2961     tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    2962     id:           /^#([\w\-\*]+)(\b|$)/,
    2963     className:    /^\.([\w\-\*]+)(\b|$)/,
    2964     pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
    2965     attrPresence: /^\[([\w]+)\]/,
    2966     attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
    2967   },
    2968 
    2969   // for Selector.match and Element#match
     3492  patterns: [
     3493    { name: 'laterSibling', re: /^\s*~\s*/ },
     3494    { name: 'child',        re: /^\s*>\s*/ },
     3495    { name: 'adjacent',     re: /^\s*\+\s*/ },
     3496    { name: 'descendant',   re: /^\s/ },
     3497
     3498    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
     3499    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
     3500    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
     3501    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
     3502    { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
     3503    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
     3504  ],
     3505
    29703506  assertions: {
    29713507    tagName: function(element, matches) {
     
    29873523    attr: function(element, matches) {
    29883524      var nodeValue = Element.readAttribute(element, matches[1]);
    2989       return Selector.operators[matches[2]](nodeValue, matches[3]);
     3525      return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
    29903526    }
    29913527  },
    29923528
    29933529  handlers: {
    2994     // UTILITY FUNCTIONS
    2995     // joins two collections
    29963530    concat: function(a, b) {
    29973531      for (var i = 0, node; node = b[i]; i++)
     
    30003534    },
    30013535
    3002     // marks an array of nodes for counting
    30033536    mark: function(nodes) {
     3537      var _true = Prototype.emptyFunction;
    30043538      for (var i = 0, node; node = nodes[i]; i++)
    3005         node._counted = true;
     3539        node._countedByPrototype = _true;
    30063540      return nodes;
    30073541    },
    30083542
    3009     unmark: function(nodes) {
    3010       for (var i = 0, node; node = nodes[i]; i++)
    3011         node._counted = undefined;
    3012       return nodes;
    3013     },
    3014 
    3015     // mark each child node with its position (for nth calls)
    3016     // "ofType" flag indicates whether we're indexing for nth-of-type
    3017     // rather than nth-child
     3543    unmark: (function(){
     3544
     3545      var PROPERTIES_ATTRIBUTES_MAP = (function(){
     3546        var el = document.createElement('div'),
     3547            isBuggy = false,
     3548            propName = '_countedByPrototype',
     3549            value = 'x'
     3550        el[propName] = value;
     3551        isBuggy = (el.getAttribute(propName) === value);
     3552        el = null;
     3553        return isBuggy;
     3554      })();
     3555
     3556      return PROPERTIES_ATTRIBUTES_MAP ?
     3557        function(nodes) {
     3558          for (var i = 0, node; node = nodes[i]; i++)
     3559            node.removeAttribute('_countedByPrototype');
     3560          return nodes;
     3561        } :
     3562        function(nodes) {
     3563          for (var i = 0, node; node = nodes[i]; i++)
     3564            node._countedByPrototype = void 0;
     3565          return nodes;
     3566        }
     3567    })(),
     3568
    30183569    index: function(parentNode, reverse, ofType) {
    3019       parentNode._counted = true;
     3570      parentNode._countedByPrototype = Prototype.emptyFunction;
    30203571      if (reverse) {
    30213572        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
    30223573          var node = nodes[i];
    3023           if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
     3574          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
    30243575        }
    30253576      } else {
    30263577        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
    3027           if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
     3578          if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
    30283579      }
    30293580    },
    30303581
    3031     // filters out duplicates and extends all nodes
    30323582    unique: function(nodes) {
    30333583      if (nodes.length == 0) return nodes;
    30343584      var results = [], n;
    30353585      for (var i = 0, l = nodes.length; i < l; i++)
    3036         if (!(n = nodes[i])._counted) {
    3037           n._counted = true;
     3586        if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
     3587          n._countedByPrototype = Prototype.emptyFunction;
    30383588          results.push(Element.extend(n));
    30393589        }
     
    30413591    },
    30423592
    3043     // COMBINATOR FUNCTIONS
    30443593    descendant: function(nodes) {
    30453594      var h = Selector.handlers;
     
    30523601      var h = Selector.handlers;
    30533602      for (var i = 0, results = [], node; node = nodes[i]; i++) {
    3054         for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
     3603        for (var j = 0, child; child = node.childNodes[j]; j++)
    30553604          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
    30563605      }
     
    30753624    nextElementSibling: function(node) {
    30763625      while (node = node.nextSibling)
    3077           if (node.nodeType == 1) return node;
     3626        if (node.nodeType == 1) return node;
    30783627      return null;
    30793628    },
     
    30853634    },
    30863635
    3087     // TOKEN FUNCTIONS
    30883636    tagName: function(nodes, root, tagName, combinator) {
    3089       tagName = tagName.toUpperCase();
     3637      var uTagName = tagName.toUpperCase();
    30903638      var results = [], h = Selector.handlers;
    30913639      if (nodes) {
    30923640        if (combinator) {
    3093           // fastlane for ordinary descendant combinators
    30943641          if (combinator == "descendant") {
    30953642            for (var i = 0, node; node = nodes[i]; i++)
     
    31003647        }
    31013648        for (var i = 0, node; node = nodes[i]; i++)
    3102           if (node.tagName.toUpperCase() == tagName) results.push(node);
     3649          if (node.tagName.toUpperCase() === uTagName) results.push(node);
    31033650        return results;
    31043651      } else return root.getElementsByTagName(tagName);
     
    31073654    id: function(nodes, root, id, combinator) {
    31083655      var targetNode = $(id), h = Selector.handlers;
    3109       if (!targetNode) return [];
    3110       if (!nodes && root == document) return [targetNode];
     3656
     3657      if (root == document) {
     3658        if (!targetNode) return [];
     3659        if (!nodes) return [targetNode];
     3660      } else {
     3661        if (!root.sourceIndex || root.sourceIndex < 1) {
     3662          var nodes = root.getElementsByTagName('*');
     3663          for (var j = 0, node; node = nodes[j]; j++) {
     3664            if (node.id === id) return [node];
     3665          }
     3666        }
     3667      }
     3668
    31113669      if (nodes) {
    31123670        if (combinator) {
     
    31473705    },
    31483706
    3149     attrPresence: function(nodes, root, attr) {
     3707    attrPresence: function(nodes, root, attr, combinator) {
    31503708      if (!nodes) nodes = root.getElementsByTagName("*");
     3709      if (nodes && combinator) nodes = this[combinator](nodes);
    31513710      var results = [];
    31523711      for (var i = 0, node; node = nodes[i]; i++)
     
    31553714    },
    31563715
    3157     attr: function(nodes, root, attr, value, operator) {
     3716    attr: function(nodes, root, attr, value, operator, combinator) {
    31583717      if (!nodes) nodes = root.getElementsByTagName("*");
     3718      if (nodes && combinator) nodes = this[combinator](nodes);
    31593719      var handler = Selector.operators[operator], results = [];
    31603720      for (var i = 0, node; node = nodes[i]; i++) {
     
    32183778    },
    32193779
    3220     // handles the an+b logic
    32213780    getIndices: function(a, b, total) {
    32223781      if (a == 0) return b > 0 ? [b] : [];
     
    32273786    },
    32283787
    3229     // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    32303788    nth: function(nodes, formula, root, reverse, ofType) {
    32313789      if (nodes.length == 0) return [];
     
    32353793      h.mark(nodes);
    32363794      for (var i = 0, node; node = nodes[i]; i++) {
    3237         if (!node.parentNode._counted) {
     3795        if (!node.parentNode._countedByPrototype) {
    32383796          h.index(node.parentNode, reverse, ofType);
    32393797          indexed.push(node.parentNode);
     
    32613819    'empty': function(nodes, value, root) {
    32623820      for (var i = 0, results = [], node; node = nodes[i]; i++) {
    3263         // IE treats comments as element nodes
    3264         if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
     3821        if (node.tagName == '!' || node.firstChild) continue;
    32653822        results.push(node);
    32663823      }
     
    32733830      h.mark(exclusions);
    32743831      for (var i = 0, results = [], node; node = nodes[i]; i++)
    3275         if (!node._counted) results.push(node);
     3832        if (!node._countedByPrototype) results.push(node);
    32763833      h.unmark(exclusions);
    32773834      return results;
     
    32803837    'enabled': function(nodes, value, root) {
    32813838      for (var i = 0, results = [], node; node = nodes[i]; i++)
    3282         if (!node.disabled) results.push(node);
     3839        if (!node.disabled && (!node.type || node.type !== 'hidden'))
     3840          results.push(node);
    32833841      return results;
    32843842    },
     
    33003858    '=':  function(nv, v) { return nv == v; },
    33013859    '!=': function(nv, v) { return nv != v; },
    3302     '^=': function(nv, v) { return nv.startsWith(v); },
    3303     '$=': function(nv, v) { return nv.endsWith(v); },
    3304     '*=': function(nv, v) { return nv.include(v); },
     3860    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
     3861    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
     3862    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
    33053863    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    3306     '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
     3864    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
     3865     '-').include('-' + (v || "").toUpperCase() + '-'); }
     3866  },
     3867
     3868  split: function(expression) {
     3869    var expressions = [];
     3870    expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
     3871      expressions.push(m[1].strip());
     3872    });
     3873    return expressions;
    33073874  },
    33083875
    33093876  matchElements: function(elements, expression) {
    3310     var matches = new Selector(expression).findElements(), h = Selector.handlers;
     3877    var matches = $$(expression), h = Selector.handlers;
    33113878    h.mark(matches);
    33123879    for (var i = 0, results = [], element; element = elements[i]; i++)
    3313       if (element._counted) results.push(element);
     3880      if (element._countedByPrototype) results.push(element);
    33143881    h.unmark(matches);
    33153882    return results;
     
    33243891
    33253892  findChildElements: function(element, expressions) {
    3326     var exprs = expressions.join(','), expressions = [];
    3327     exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
    3328       expressions.push(m[1].strip());
    3329     });
     3893    expressions = Selector.split(expressions.join(','));
    33303894    var results = [], h = Selector.handlers;
    33313895    for (var i = 0, l = expressions.length, selector; i < l; i++) {
     
    33373901});
    33383902
     3903if (Prototype.Browser.IE) {
     3904  Object.extend(Selector.handlers, {
     3905    concat: function(a, b) {
     3906      for (var i = 0, node; node = b[i]; i++)
     3907        if (node.tagName !== "!") a.push(node);
     3908      return a;
     3909    }
     3910  });
     3911}
     3912
    33393913function $$() {
    33403914  return Selector.findChildElements(document, $A(arguments));
    33413915}
     3916
    33423917var Form = {
    33433918  reset: function(form) {
    3344     $(form).reset();
     3919    form = $(form);
     3920    form.reset();
    33453921    return form;
    33463922  },
     
    33483924  serializeElements: function(elements, options) {
    33493925    if (typeof options != 'object') options = { hash: !!options };
    3350     else if (options.hash === undefined) options.hash = true;
     3926    else if (Object.isUndefined(options.hash)) options.hash = true;
    33513927    var key, value, submitted = false, submit = options.submit;
    33523928
     
    33543930      if (!element.disabled && element.name) {
    33553931        key = element.name; value = $(element).getValue();
    3356         if (value != null && (element.type != 'submit' || (!submitted &&
     3932        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
    33573933            submit !== false && (!submit || key == submit) && (submitted = true)))) {
    33583934          if (key in result) {
    3359             // a key is already present; construct an array of values
    33603935            if (!Object.isArray(result[key])) result[key] = [result[key]];
    33613936            result[key].push(value);
     
    33773952
    33783953  getElements: function(form) {
    3379     return $A($(form).getElementsByTagName('*')).inject([],
    3380       function(elements, child) {
    3381         if (Form.Element.Serializers[child.tagName.toLowerCase()])
    3382           elements.push(Element.extend(child));
    3383         return elements;
    3384       }
    3385     );
     3954    var elements = $(form).getElementsByTagName('*'),
     3955        element,
     3956        arr = [ ],
     3957        serializers = Form.Element.Serializers;
     3958    for (var i = 0; element = elements[i]; i++) {
     3959      arr.push(element);
     3960    }
     3961    return arr.inject([], function(elements, child) {
     3962      if (serializers[child.tagName.toLowerCase()])
     3963        elements.push(Element.extend(child));
     3964      return elements;
     3965    })
    33863966  },
    33873967
     
    34234003
    34244004    return firstByIndex ? firstByIndex : elements.find(function(element) {
    3425       return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
     4005      return /^(?:input|select|textarea)$/i.test(element.tagName);
    34264006    });
    34274007  },
     
    34544034/*--------------------------------------------------------------------------*/
    34554035
     4036
    34564037Form.Element = {
    34574038  focus: function(element) {
     
    34674048
    34684049Form.Element.Methods = {
     4050
    34694051  serialize: function(element) {
    34704052    element = $(element);
     
    35074089      element.focus();
    35084090      if (element.select && (element.tagName.toLowerCase() != 'input' ||
    3509           !['button', 'reset', 'submit'].include(element.type)))
     4091          !(/^(?:button|reset|submit)$/i.test(element.type))))
    35104092        element.select();
    35114093    } catch (e) { }
     
    35154097  disable: function(element) {
    35164098    element = $(element);
    3517     element.blur();
    35184099    element.disabled = true;
    35194100    return element;
     
    35304111
    35314112var Field = Form.Element;
     4113
    35324114var $F = Form.Element.Methods.getValue;
    35334115
     
    35464128
    35474129  inputSelector: function(element, value) {
    3548     if (value === undefined) return element.checked ? element.value : null;
     4130    if (Object.isUndefined(value)) return element.checked ? element.value : null;
    35494131    else element.checked = !!value;
    35504132  },
    35514133
    35524134  textarea: function(element, value) {
    3553     if (value === undefined) return element.value;
     4135    if (Object.isUndefined(value)) return element.value;
    35544136    else element.value = value;
    35554137  },
    35564138
    3557   select: function(element, index) {
    3558     if (index === undefined)
     4139  select: function(element, value) {
     4140    if (Object.isUndefined(value))
    35594141      return this[element.type == 'select-one' ?
    35604142        'selectOne' : 'selectMany'](element);
    35614143    else {
    3562       var opt, value, single = !Object.isArray(index);
     4144      var opt, currentValue, single = !Object.isArray(value);
    35634145      for (var i = 0, length = element.length; i < length; i++) {
    35644146        opt = element.options[i];
    3565         value = this.optionValue(opt);
     4147        currentValue = this.optionValue(opt);
    35664148        if (single) {
    3567           if (value == index) {
     4149          if (currentValue == value) {
    35684150            opt.selected = true;
    35694151            return;
    35704152          }
    35714153        }
    3572         else opt.selected = index.include(value);
     4154        else opt.selected = value.include(currentValue);
    35734155      }
    35744156    }
     
    35924174
    35934175  optionValue: function(opt) {
    3594     // extend element because hasAttribute may not be native
    35954176    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
    35964177  }
     
    35984179
    35994180/*--------------------------------------------------------------------------*/
     4181
    36004182
    36014183Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
     
    36804262  }
    36814263});
    3682 if (!window.Event) var Event = { };
    3683 
    3684 Object.extend(Event, {
    3685   KEY_BACKSPACE: 8,
    3686   KEY_TAB:       9,
    3687   KEY_RETURN:   13,
    3688   KEY_ESC:      27,
    3689   KEY_LEFT:     37,
    3690   KEY_UP:       38,
    3691   KEY_RIGHT:    39,
    3692   KEY_DOWN:     40,
    3693   KEY_DELETE:   46,
    3694   KEY_HOME:     36,
    3695   KEY_END:      35,
    3696   KEY_PAGEUP:   33,
    3697   KEY_PAGEDOWN: 34,
    3698   KEY_INSERT:   45,
    3699 
    3700   cache: { },
    3701 
    3702   relatedTarget: function(event) {
    3703     var element;
    3704     switch(event.type) {
    3705       case 'mouseover': element = event.fromElement; break;
    3706       case 'mouseout':  element = event.toElement;   break;
    3707       default: return null;
    3708     }
    3709     return Element.extend(element);
    3710   }
    3711 });
    3712 
    3713 Event.Methods = (function() {
    3714   var isButton;
    3715 
     4264(function() {
     4265
     4266  var Event = {
     4267    KEY_BACKSPACE: 8,
     4268    KEY_TAB:       9,
     4269    KEY_RETURN:   13,
     4270    KEY_ESC:      27,
     4271    KEY_LEFT:     37,
     4272    KEY_UP:       38,
     4273    KEY_RIGHT:    39,
     4274    KEY_DOWN:     40,
     4275    KEY_DELETE:   46,
     4276    KEY_HOME:     36,
     4277    KEY_END:      35,
     4278    KEY_PAGEUP:   33,
     4279    KEY_PAGEDOWN: 34,
     4280    KEY_INSERT:   45,
     4281
     4282    cache: {}
     4283  };
     4284
     4285  var docEl = document.documentElement;
     4286  var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
     4287    && 'onmouseleave' in docEl;
     4288
     4289  var _isButton;
    37164290  if (Prototype.Browser.IE) {
    37174291    var buttonMap = { 0: 1, 1: 4, 2: 2 };
    3718     isButton = function(event, code) {
    3719       return event.button == buttonMap[code];
     4292    _isButton = function(event, code) {
     4293      return event.button === buttonMap[code];
    37204294    };
    3721 
    37224295  } else if (Prototype.Browser.WebKit) {
    3723     isButton = function(event, code) {
     4296    _isButton = function(event, code) {
    37244297      switch (code) {
    37254298        case 0: return event.which == 1 && !event.metaKey;
     
    37284301      }
    37294302    };
    3730 
    37314303  } else {
    3732     isButton = function(event, code) {
     4304    _isButton = function(event, code) {
    37334305      return event.which ? (event.which === code + 1) : (event.button === code);
    37344306    };
    37354307  }
    37364308
    3737   return {
    3738     isLeftClick:   function(event) { return isButton(event, 0) },
    3739     isMiddleClick: function(event) { return isButton(event, 1) },
    3740     isRightClick:  function(event) { return isButton(event, 2) },
    3741 
    3742     element: function(event) {
    3743       var node = Event.extend(event).target;
    3744       return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
    3745     },
    3746 
    3747     findElement: function(event, expression) {
    3748       var element = Event.element(event);
    3749       return element.match(expression) ? element : element.up(expression);
    3750     },
    3751 
    3752     pointer: function(event) {
    3753       return {
    3754         x: event.pageX || (event.clientX +
    3755           (document.documentElement.scrollLeft || document.body.scrollLeft)),
    3756         y: event.pageY || (event.clientY +
    3757           (document.documentElement.scrollTop || document.body.scrollTop))
    3758       };
    3759     },
    3760 
    3761     pointerX: function(event) { return Event.pointer(event).x },
    3762     pointerY: function(event) { return Event.pointer(event).y },
    3763 
    3764     stop: function(event) {
    3765       Event.extend(event);
    3766       event.preventDefault();
    3767       event.stopPropagation();
    3768       event.stopped = true;
    3769     }
     4309  function isLeftClick(event)   { return _isButton(event, 0) }
     4310
     4311  function isMiddleClick(event) { return _isButton(event, 1) }
     4312
     4313  function isRightClick(event)  { return _isButton(event, 2) }
     4314
     4315  function element(event) {
     4316    event = Event.extend(event);
     4317
     4318    var node = event.target, type = event.type,
     4319     currentTarget = event.currentTarget;
     4320
     4321    if (currentTarget && currentTarget.tagName) {
     4322      if (type === 'load' || type === 'error' ||
     4323        (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
     4324          && currentTarget.type === 'radio'))
     4325            node = currentTarget;
     4326    }
     4327
     4328    if (node.nodeType == Node.TEXT_NODE)
     4329      node = node.parentNode;
     4330
     4331    return Element.extend(node);
     4332  }
     4333
     4334  function findElement(event, expression) {
     4335    var element = Event.element(event);
     4336    if (!expression) return element;
     4337    var elements = [element].concat(element.ancestors());
     4338    return Selector.findElement(elements, expression, 0);
     4339  }
     4340
     4341  function pointer(event) {
     4342    return { x: pointerX(event), y: pointerY(event) };
     4343  }
     4344
     4345  function pointerX(event) {
     4346    var docElement = document.documentElement,
     4347     body = document.body || { scrollLeft: 0 };
     4348
     4349    return event.pageX || (event.clientX +
     4350      (docElement.scrollLeft || body.scrollLeft) -
     4351      (docElement.clientLeft || 0));
     4352  }
     4353
     4354  function pointerY(event) {
     4355    var docElement = document.documentElement,
     4356     body = document.body || { scrollTop: 0 };
     4357
     4358    return  event.pageY || (event.clientY +
     4359       (docElement.scrollTop || body.scrollTop) -
     4360       (docElement.clientTop || 0));
     4361  }
     4362
     4363
     4364  function stop(event) {
     4365    Event.extend(event);
     4366    event.preventDefault();
     4367    event.stopPropagation();
     4368
     4369    event.stopped = true;
     4370  }
     4371
     4372  Event.Methods = {
     4373    isLeftClick: isLeftClick,
     4374    isMiddleClick: isMiddleClick,
     4375    isRightClick: isRightClick,
     4376
     4377    element: element,
     4378    findElement: findElement,
     4379
     4380    pointer: pointer,
     4381    pointerX: pointerX,
     4382    pointerY: pointerY,
     4383
     4384    stop: stop
    37704385  };
    3771 })();
    3772 
    3773 Event.extend = (function() {
     4386
     4387
    37744388  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    37754389    m[name] = Event.Methods[name].methodize();
     
    37784392
    37794393  if (Prototype.Browser.IE) {
     4394    function _relatedTarget(event) {
     4395      var element;
     4396      switch (event.type) {
     4397        case 'mouseover': element = event.fromElement; break;
     4398        case 'mouseout':  element = event.toElement;   break;
     4399        default: return null;
     4400      }
     4401      return Element.extend(element);
     4402    }
     4403
    37804404    Object.extend(methods, {
    37814405      stopPropagation: function() { this.cancelBubble = true },
    37824406      preventDefault:  function() { this.returnValue = false },
    3783       inspect: function() { return "[object Event]" }
     4407      inspect: function() { return '[object Event]' }
    37844408    });
    37854409
    3786     return function(event) {
     4410    Event.extend = function(event, element) {
    37874411      if (!event) return false;
    37884412      if (event._extendedByPrototype) return event;
     
    37904414      event._extendedByPrototype = Prototype.emptyFunction;
    37914415      var pointer = Event.pointer(event);
     4416
    37924417      Object.extend(event, {
    3793         target: event.srcElement,
    3794         relatedTarget: Event.relatedTarget(event),
     4418        target: event.srcElement || element,
     4419        relatedTarget: _relatedTarget(event),
    37954420        pageX:  pointer.x,
    37964421        pageY:  pointer.y
    37974422      });
     4423
    37984424      return Object.extend(event, methods);
    37994425    };
    3800 
    38014426  } else {
    3802     Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
     4427    Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
    38034428    Object.extend(Event.prototype, methods);
    3804     return Prototype.K;
    3805   }
     4429    Event.extend = Prototype.K;
     4430  }
     4431
     4432  function _createResponder(element, eventName, handler) {
     4433    var registry = Element.retrieve(element, 'prototype_event_registry');
     4434
     4435    if (Object.isUndefined(registry)) {
     4436      CACHE.push(element);
     4437      registry = Element.retrieve(element, 'prototype_event_registry', $H());
     4438    }
     4439
     4440    var respondersForEvent = registry.get(eventName);
     4441    if (Object.isUndefined(respondersForEvent)) {
     4442      respondersForEvent = [];
     4443      registry.set(eventName, respondersForEvent);
     4444    }
     4445
     4446    if (respondersForEvent.pluck('handler').include(handler)) return false;
     4447
     4448    var responder;
     4449    if (eventName.include(":")) {
     4450      responder = function(event) {
     4451        if (Object.isUndefined(event.eventName))
     4452          return false;
     4453
     4454        if (event.eventName !== eventName)
     4455          return false;
     4456
     4457        Event.extend(event, element);
     4458        handler.call(element, event);
     4459      };
     4460    } else {
     4461      if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
     4462       (eventName === "mouseenter" || eventName === "mouseleave")) {
     4463        if (eventName === "mouseenter" || eventName === "mouseleave") {
     4464          responder = function(event) {
     4465            Event.extend(event, element);
     4466
     4467            var parent = event.relatedTarget;
     4468            while (parent && parent !== element) {
     4469              try { parent = parent.parentNode; }
     4470              catch(e) { parent = element; }
     4471            }
     4472
     4473            if (parent === element) return;
     4474
     4475            handler.call(element, event);
     4476          };
     4477        }
     4478      } else {
     4479        responder = function(event) {
     4480          Event.extend(event, element);
     4481          handler.call(element, event);
     4482        };
     4483      }
     4484    }
     4485
     4486    responder.handler = handler;
     4487    respondersForEvent.push(responder);
     4488    return responder;
     4489  }
     4490
     4491  function _destroyCache() {
     4492    for (var i = 0, length = CACHE.length; i < length; i++) {
     4493      Event.stopObserving(CACHE[i]);
     4494      CACHE[i] = null;
     4495    }
     4496  }
     4497
     4498  var CACHE = [];
     4499
     4500  if (Prototype.Browser.IE)
     4501    window.attachEvent('onunload', _destroyCache);
     4502
     4503  if (Prototype.Browser.WebKit)
     4504    window.addEventListener('unload', Prototype.emptyFunction, false);
     4505
     4506
     4507  var _getDOMEventName = Prototype.K;
     4508
     4509  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
     4510    _getDOMEventName = function(eventName) {
     4511      var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
     4512      return eventName in translations ? translations[eventName] : eventName;
     4513    };
     4514  }
     4515
     4516  function observe(element, eventName, handler) {
     4517    element = $(element);
     4518
     4519    var responder = _createResponder(element, eventName, handler);
     4520
     4521    if (!responder) return element;
     4522
     4523    if (eventName.include(':')) {
     4524      if (element.addEventListener)
     4525        element.addEventListener("dataavailable", responder, false);
     4526      else {
     4527        element.attachEvent("ondataavailable", responder);
     4528        element.attachEvent("onfilterchange", responder);
     4529      }
     4530    } else {
     4531      var actualEventName = _getDOMEventName(eventName);
     4532
     4533      if (element.addEventListener)
     4534        element.addEventListener(actualEventName, responder, false);
     4535      else
     4536        element.attachEvent("on" + actualEventName, responder);
     4537    }
     4538
     4539    return element;
     4540  }
     4541
     4542  function stopObserving(element, eventName, handler) {
     4543    element = $(element);
     4544
     4545    var registry = Element.retrieve(element, 'prototype_event_registry');
     4546
     4547    if (Object.isUndefined(registry)) return element;
     4548
     4549    if (eventName && !handler) {
     4550      var responders = registry.get(eventName);
     4551
     4552      if (Object.isUndefined(responders)) return element;
     4553
     4554      responders.each( function(r) {
     4555        Element.stopObserving(element, eventName, r.handler);
     4556      });
     4557      return element;
     4558    } else if (!eventName) {
     4559      registry.each( function(pair) {
     4560        var eventName = pair.key, responders = pair.value;
     4561
     4562        responders.each( function(r) {
     4563          Element.stopObserving(element, eventName, r.handler);
     4564        });
     4565      });
     4566      return element;
     4567    }
     4568
     4569    var responders = registry.get(eventName);
     4570
     4571    if (!responders) return;
     4572
     4573    var responder = responders.find( function(r) { return r.handler === handler; });
     4574    if (!responder) return element;
     4575
     4576    var actualEventName = _getDOMEventName(eventName);
     4577
     4578    if (eventName.include(':')) {
     4579      if (element.removeEventListener)
     4580        element.removeEventListener("dataavailable", responder, false);
     4581      else {
     4582        element.detachEvent("ondataavailable", responder);
     4583        element.detachEvent("onfilterchange",  responder);
     4584      }
     4585    } else {
     4586      if (element.removeEventListener)
     4587        element.removeEventListener(actualEventName, responder, false);
     4588      else
     4589        element.detachEvent('on' + actualEventName, responder);
     4590    }
     4591
     4592    registry.set(eventName, responders.without(responder));
     4593
     4594    return element;
     4595  }
     4596
     4597  function fire(element, eventName, memo, bubble) {
     4598    element = $(element);
     4599
     4600    if (Object.isUndefined(bubble))
     4601      bubble = true;
     4602
     4603    if (element == document && document.createEvent && !element.dispatchEvent)
     4604      element = document.documentElement;
     4605
     4606    var event;
     4607    if (document.createEvent) {
     4608      event = document.createEvent('HTMLEvents');
     4609      event.initEvent('dataavailable', true, true);
     4610    } else {
     4611      event = document.createEventObject();
     4612      event.eventType = bubble ? 'ondataavailable' : 'onfilterchange';
     4613    }
     4614
     4615    event.eventName = eventName;
     4616    event.memo = memo || { };
     4617
     4618    if (document.createEvent)
     4619      element.dispatchEvent(event);
     4620    else
     4621      element.fireEvent(event.eventType, event);
     4622
     4623    return Event.extend(event);
     4624  }
     4625
     4626
     4627  Object.extend(Event, Event.Methods);
     4628
     4629  Object.extend(Event, {
     4630    fire:          fire,
     4631    observe:       observe,
     4632    stopObserving: stopObserving
     4633  });
     4634
     4635  Element.addMethods({
     4636    fire:          fire,
     4637
     4638    observe:       observe,
     4639
     4640    stopObserving: stopObserving
     4641  });
     4642
     4643  Object.extend(document, {
     4644    fire:          fire.methodize(),
     4645
     4646    observe:       observe.methodize(),
     4647
     4648    stopObserving: stopObserving.methodize(),
     4649
     4650    loaded:        false
     4651  });
     4652
     4653  if (window.Event) Object.extend(window.Event, Event);
     4654  else window.Event = Event;
    38064655})();
    3807 
    3808 Object.extend(Event, (function() {
    3809   var cache = Event.cache;
    3810 
    3811   function getEventID(element) {
    3812     if (element._eventID) return element._eventID;
    3813     arguments.callee.id = arguments.callee.id || 1;
    3814     return element._eventID = ++arguments.callee.id;
    3815   }
    3816 
    3817   function getDOMEventName(eventName) {
    3818     if (eventName && eventName.include(':')) return "dataavailable";
    3819     return eventName;
    3820   }
    3821 
    3822   function getCacheForID(id) {
    3823     return cache[id] = cache[id] || { };
    3824   }
    3825 
    3826   function getWrappersForEventName(id, eventName) {
    3827     var c = getCacheForID(id);
    3828     return c[eventName] = c[eventName] || [];
    3829   }
    3830 
    3831   function createWrapper(element, eventName, handler) {
    3832     var id = getEventID(element);
    3833     var c = getWrappersForEventName(id, eventName);
    3834     if (c.pluck("handler").include(handler)) return false;
    3835 
    3836     var wrapper = function(event) {
    3837       if (!Event || !Event.extend ||
    3838         (event.eventName && event.eventName != eventName))
    3839           return false;
    3840 
    3841       Event.extend(event);
    3842       handler.call(element, event)
    3843     };
    3844 
    3845     wrapper.handler = handler;
    3846     c.push(wrapper);
    3847     return wrapper;
    3848   }
    3849 
    3850   function findWrapper(id, eventName, handler) {
    3851     var c = getWrappersForEventName(id, eventName);
    3852     return c.find(function(wrapper) { return wrapper.handler == handler });
    3853   }
    3854 
    3855   function destroyWrapper(id, eventName, handler) {
    3856     var c = getCacheForID(id);
    3857     if (!c[eventName]) return false;
    3858     c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
    3859   }
    3860 
    3861   function destroyCache() {
    3862     for (var id in cache)
    3863       for (var eventName in cache[id])
    3864         cache[id][eventName] = null;
    3865   }
    3866 
    3867   if (window.attachEvent) {
    3868     window.attachEvent("onunload", destroyCache);
    3869   }
    3870 
    3871   return {
    3872     observe: function(element, eventName, handler) {
    3873       element = $(element);
    3874       var name = getDOMEventName(eventName);
    3875 
    3876       var wrapper = createWrapper(element, eventName, handler);
    3877       if (!wrapper) return element;
    3878 
    3879       if (element.addEventListener) {
    3880         element.addEventListener(name, wrapper, false);
    3881       } else {
    3882         element.attachEvent("on" + name, wrapper);
    3883       }
    3884 
    3885       return element;
    3886     },
    3887 
    3888     stopObserving: function(element, eventName, handler) {
    3889       element = $(element);
    3890       var id = getEventID(element), name = getDOMEventName(eventName);
    3891 
    3892       if (!handler && eventName) {
    3893         getWrappersForEventName(id, eventName).each(function(wrapper) {
    3894           element.stopObserving(eventName, wrapper.handler);
    3895         });
    3896         return element;
    3897 
    3898       } else if (!eventName) {
    3899         Object.keys(getCacheForID(id)).each(function(eventName) {
    3900           element.stopObserving(eventName);
    3901         });
    3902         return element;
    3903       }
    3904 
    3905       var wrapper = findWrapper(id, eventName, handler);
    3906       if (!wrapper) return element;
    3907 
    3908       if (element.removeEventListener) {
    3909         element.removeEventListener(name, wrapper, false);
    3910       } else {
    3911         element.detachEvent("on" + name, wrapper);
    3912       }
    3913 
    3914       destroyWrapper(id, eventName, handler);
    3915 
    3916       return element;
    3917     },
    3918 
    3919     fire: function(element, eventName, memo) {
    3920       element = $(element);
    3921       if (element == document && document.createEvent && !element.dispatchEvent)
    3922         element = document.documentElement;
    3923 
    3924       if (document.createEvent) {
    3925         var event = document.createEvent("HTMLEvents");
    3926         event.initEvent("dataavailable", true, true);
    3927       } else {
    3928         var event = document.createEventObject();
    3929         event.eventType = "ondataavailable";
    3930       }
    3931 
    3932       event.eventName = eventName;
    3933       event.memo = memo || { };
    3934 
    3935       if (document.createEvent) {
    3936         element.dispatchEvent(event);
    3937       } else {
    3938         element.fireEvent(event.eventType, event);
    3939       }
    3940 
    3941       return event;
    3942     }
    3943   };
    3944 })());
    3945 
    3946 Object.extend(Event, Event.Methods);
    3947 
    3948 Element.addMethods({
    3949   fire:          Event.fire,
    3950   observe:       Event.observe,
    3951   stopObserving: Event.stopObserving
    3952 });
    3953 
    3954 Object.extend(document, {
    3955   fire:          Element.Methods.fire.methodize(),
    3956   observe:       Element.Methods.observe.methodize(),
    3957   stopObserving: Element.Methods.stopObserving.methodize()
    3958 });
    39594656
    39604657(function() {
    39614658  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
    3962      Matthias Miller, Dean Edwards and John Resig. */
    3963 
    3964   var timer, fired = false;
     4659     Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
     4660
     4661  var timer;
    39654662
    39664663  function fireContentLoadedEvent() {
    3967     if (fired) return;
    3968     if (timer) window.clearInterval(timer);
    3969     document.fire("dom:loaded");
    3970     fired = true;
     4664    if (document.loaded) return;
     4665    if (timer) window.clearTimeout(timer);
     4666    document.loaded = true;
     4667    document.fire('dom:loaded');
     4668  }
     4669
     4670  function checkReadyState() {
     4671    if (document.readyState === 'complete') {
     4672      document.stopObserving('readystatechange', checkReadyState);
     4673      fireContentLoadedEvent();
     4674    }
     4675  }
     4676
     4677  function pollDoScroll() {
     4678    try { document.documentElement.doScroll('left'); }
     4679    catch(e) {
     4680      timer = pollDoScroll.defer();
     4681      return;
     4682    }
     4683    fireContentLoadedEvent();
    39714684  }
    39724685
    39734686  if (document.addEventListener) {
    3974     if (Prototype.Browser.WebKit) {
    3975       timer = window.setInterval(function() {
    3976         if (/loaded|complete/.test(document.readyState))
    3977           fireContentLoadedEvent();
    3978       }, 0);
    3979 
    3980       Event.observe(window, "load", fireContentLoadedEvent);
    3981 
    3982     } else {
    3983       document.addEventListener("DOMContentLoaded",
    3984         fireContentLoadedEvent, false);
    3985     }
    3986 
     4687    document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
    39874688  } else {
    3988     document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    3989     $("__onDOMContentLoaded").onreadystatechange = function() {
    3990       if (this.readyState == "complete") {
    3991         this.onreadystatechange = null;
    3992         fireContentLoadedEvent();
    3993       }
    3994     };
    3995   }
     4689    document.observe('readystatechange', checkReadyState);
     4690    if (window == top)
     4691      timer = pollDoScroll.defer();
     4692  }
     4693
     4694  Event.observe(window, 'load', fireContentLoadedEvent);
    39964695})();
     4696
     4697Element.addMethods();
     4698
    39974699/*------------------------------- DEPRECATED -------------------------------*/
    39984700
     
    40234725var $continue = new Error('"throw $continue" is deprecated, use "return" instead');
    40244726
    4025 // This should be moved to script.aculo.us; notice the deprecated methods
    4026 // further below, that map to the newer Element methods.
    40274727var Position = {
    4028   // set to true if needed, warning: firefox performance problems
    4029   // NOT neeeded for page scrolling, only if draggable contained in
    4030   // scrollable elements
    40314728  includeScrollOffsets: false,
    40324729
    4033   // must be called before calling withinIncludingScrolloffset, every time the
    4034   // page is scrolled
    40354730  prepare: function() {
    40364731    this.deltaX =  window.pageXOffset
     
    40444739  },
    40454740
    4046   // caches x/y coordinate pair to use with overlap
    40474741  within: function(element, x, y) {
    40484742    if (this.includeScrollOffsets)
     
    40714765  },
    40724766
    4073   // within must be called directly before
    40744767  overlap: function(mode, element) {
    40754768    if (!mode) return 0;
     
    40824775  },
    40834776
    4084   // Deprecation layer -- use newer Element methods now (1.5.2).
    40854777
    40864778  cumulativeOffset: Element.Methods.cumulativeOffset,
     
    41814873
    41824874/*--------------------------------------------------------------------------*/
    4183 
    4184 Element.addMethods();
  • trunk/wp-includes/js/scriptaculous/MIT-LICENSE

    r7131 r12557  
    1 Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     1Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    22
    33Permission is hereby granted, free of charge, to any person obtaining
  • trunk/wp-includes/js/scriptaculous/builder.js

    r7131 r12557  
    1 // script.aculo.us builder.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
     1// script.aculo.us builder.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
    22
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    44//
    55// script.aculo.us is freely distributable under the terms of an MIT-style license.
     
    2727  node: function(elementName) {
    2828    elementName = elementName.toUpperCase();
    29    
     29
    3030    // try innerHTML approach
    3131    var parentTag = this.NODEMAP[elementName] || 'div';
     
    3535    } catch(e) {}
    3636    var element = parentElement.firstChild || null;
    37      
     37
    3838    // see if browser added wrapping tags
    3939    if(element && (element.tagName.toUpperCase() != elementName))
    4040      element = element.getElementsByTagName(elementName)[0];
    41    
     41
    4242    // fallback to createElement approach
    4343    if(!element) element = document.createElement(elementName);
    44    
     44
    4545    // abort if nothing could be created
    4646    if(!element) return;
     
    6363            if(!element) {
    6464              element = document.createElement(elementName);
    65               for(attr in arguments[1]) 
     65              for(attr in arguments[1])
    6666                element[attr == 'class' ? 'className' : attr] = arguments[1][attr];
    6767            }
     
    6969              element = parentElement.getElementsByTagName(elementName)[0];
    7070          }
    71         } 
     71        }
    7272
    7373    // text, or array of children
     
    7575      this._children(element, arguments[2]);
    7676
    77      return element;
     77     return $(element);
    7878  },
    7979  _text: function(text) {
     
    101101      children.flatten().each( function(e) {
    102102        if(typeof e=='object')
    103           element.appendChild(e)
     103          element.appendChild(e);
    104104        else
    105105          if(Builder._isStringOrNumber(e))
     
    118118    return element.down();
    119119  },
    120   dump: function(scope) { 
    121     if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope 
    122  
     120  dump: function(scope) {
     121    if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope
     122
    123123    var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " +
    124124      "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " +
     
    127127      "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+
    128128      "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/);
    129  
    130     tags.each( function(tag){ 
    131       scope[tag] = function() { 
    132         return Builder.node.apply(Builder, [tag].concat($A(arguments))); 
    133       } 
     129
     130    tags.each( function(tag){
     131      scope[tag] = function() {
     132        return Builder.node.apply(Builder, [tag].concat($A(arguments)));
     133      };
    134134    });
    135135  }
    136 }
     136};
  • trunk/wp-includes/js/scriptaculous/controls.js

    r7131 r12557  
    1 // script.aculo.us controls.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
    2 
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    4 //           (c) 2005-2007 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
    5 //           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
     1// script.aculo.us controls.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     4//           (c) 2005-2009 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
     5//           (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
    66// Contributors:
    77//  Richard Livsey
    88//  Rahul Bhargava
    99//  Rob Wills
    10 // 
     10//
    1111// script.aculo.us is freely distributable under the terms of an MIT-style license.
    1212// For details, see the script.aculo.us web site: http://script.aculo.us/
    1313
    14 // Autocompleter.Base handles all the autocompletion functionality 
     14// Autocompleter.Base handles all the autocompletion functionality
    1515// that's independent of the data source for autocompletion. This
    1616// includes drawing the autocompletion menu, observing keyboard
    1717// and mouse events, and similar.
    1818//
    19 // Specific autocompleters need to provide, at the very least, 
     19// Specific autocompleters need to provide, at the very least,
    2020// a getUpdatedChoices function that will be invoked every time
    21 // the text inside the monitored textbox changes. This method 
     21// the text inside the monitored textbox changes. This method
    2222// should get the text for which to provide autocompletion by
    2323// invoking this.getToken(), NOT by directly accessing
     
    3333// Additionally, ',' in the above example can be replaced with
    3434// a token array, e.g. { tokens: [',', '\n'] } which
    35 // enables autocompletion on multiple tokens. This is most 
    36 // useful when one of the tokens is \n (a newline), as it 
     35// enables autocompletion on multiple tokens. This is most
     36// useful when one of the tokens is \n (a newline), as it
    3737// allows smart autocompletion after linebreaks.
    3838
     
    4040  throw("controls.js requires including script.aculo.us' effects.js library");
    4141
    42 var Autocompleter = { }
     42var Autocompleter = { };
    4343Autocompleter.Base = Class.create({
    4444  baseInitialize: function(element, update, options) {
    45     element          = $(element)
    46     this.element     = element; 
    47     this.update      = $(update); 
    48     this.hasFocus    = false; 
    49     this.changed     = false; 
    50     this.active      = false; 
    51     this.index       = 0;     
     45    element          = $(element);
     46    this.element     = element;
     47    this.update      = $(update);
     48    this.hasFocus    = false;
     49    this.changed     = false;
     50    this.active      = false;
     51    this.index       = 0;
    5252    this.entryCount  = 0;
    5353    this.oldElementValue = this.element.value;
     
    6262    this.options.frequency    = this.options.frequency || 0.4;
    6363    this.options.minChars     = this.options.minChars || 1;
    64     this.options.onShow       = this.options.onShow || 
    65       function(element, update){ 
     64    this.options.onShow       = this.options.onShow ||
     65      function(element, update){
    6666        if(!update.style.position || update.style.position=='absolute') {
    6767          update.style.position = 'absolute';
    6868          Position.clone(element, update, {
    69             setHeight: false, 
     69            setHeight: false,
    7070            offsetTop: element.offsetHeight
    7171          });
     
    7373        Effect.Appear(update,{duration:0.15});
    7474      };
    75     this.options.onHide = this.options.onHide || 
     75    this.options.onHide = this.options.onHide ||
    7676      function(element, update){ new Effect.Fade(update,{duration:0.15}) };
    7777
    78     if(typeof(this.options.tokens) == 'string') 
     78    if(typeof(this.options.tokens) == 'string')
    7979      this.options.tokens = new Array(this.options.tokens);
    8080    // Force carriage returns as token delimiters anyway
     
    8383
    8484    this.observer = null;
    85    
     85
    8686    this.element.setAttribute('autocomplete','off');
    8787
     
    8989
    9090    Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
    91     Event.observe(this.element, 'keypress', this.onKeyPress.bindAsEventListener(this));
     91    Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
    9292  },
    9393
    9494  show: function() {
    9595    if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);
    96     if(!this.iefix && 
     96    if(!this.iefix &&
    9797      (Prototype.Browser.IE) &&
    9898      (Element.getStyle(this.update, 'position')=='absolute')) {
    99       new Insertion.After(this.update, 
     99      new Insertion.After(this.update,
    100100       '<iframe id="' + this.update.id + '_iefix" '+
    101101       'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
     
    105105    if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
    106106  },
    107  
     107
    108108  fixIEOverlapping: function() {
    109109    Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
     
    145145         this.markPrevious();
    146146         this.render();
    147          if(Prototype.Browser.WebKit) Event.stop(event);
     147         Event.stop(event);
    148148         return;
    149149       case Event.KEY_DOWN:
    150150         this.markNext();
    151151         this.render();
    152          if(Prototype.Browser.WebKit) Event.stop(event);
     152         Event.stop(event);
    153153         return;
    154154      }
    155      else 
    156        if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN || 
     155     else
     156       if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
    157157         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
    158158
     
    161161
    162162    if(this.observer) clearTimeout(this.observer);
    163       this.observer = 
     163      this.observer =
    164164        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
    165165  },
     
    173173  onHover: function(event) {
    174174    var element = Event.findElement(event, 'LI');
    175     if(this.index != element.autocompleteIndex) 
     175    if(this.index != element.autocompleteIndex)
    176176    {
    177177        this.index = element.autocompleteIndex;
     
    180180    Event.stop(event);
    181181  },
    182  
     182
    183183  onClick: function(event) {
    184184    var element = Event.findElement(event, 'LI');
     
    187187    this.hide();
    188188  },
    189  
     189
    190190  onBlur: function(event) {
    191191    // needed to make click events working
    192192    setTimeout(this.hide.bind(this), 250);
    193193    this.hasFocus = false;
    194     this.active = false;     
    195   }, 
    196  
     194    this.active = false;
     195  },
     196
    197197  render: function() {
    198198    if(this.entryCount > 0) {
    199199      for (var i = 0; i < this.entryCount; i++)
    200         this.index==i ? 
    201           Element.addClassName(this.getEntry(i),"selected") : 
     200        this.index==i ?
     201          Element.addClassName(this.getEntry(i),"selected") :
    202202          Element.removeClassName(this.getEntry(i),"selected");
    203       if(this.hasFocus) { 
     203      if(this.hasFocus) {
    204204        this.show();
    205205        this.active = true;
     
    210210    }
    211211  },
    212  
     212
    213213  markPrevious: function() {
    214     if(this.index > 0) this.index--
     214    if(this.index > 0) this.index--;
    215215      else this.index = this.entryCount-1;
    216216    this.getEntry(this.index).scrollIntoView(true);
    217217  },
    218  
     218
    219219  markNext: function() {
    220     if(this.index < this.entryCount-1) this.index++
     220    if(this.index < this.entryCount-1) this.index++;
    221221      else this.index = 0;
    222222    this.getEntry(this.index).scrollIntoView(false);
    223223  },
    224  
     224
    225225  getEntry: function(index) {
    226226    return this.update.firstChild.childNodes[index];
    227227  },
    228  
     228
    229229  getCurrentEntry: function() {
    230230    return this.getEntry(this.index);
    231231  },
    232  
     232
    233233  selectEntry: function() {
    234234    this.active = false;
     
    247247    } else
    248248      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');
    249    
     249
    250250    var bounds = this.getTokenBounds();
    251251    if (bounds[0] != -1) {
     
    260260    this.oldElementValue = this.element.value;
    261261    this.element.focus();
    262    
     262
    263263    if (this.options.afterUpdateElement)
    264264      this.options.afterUpdateElement(this.element, selectedElement);
     
    272272
    273273      if(this.update.firstChild && this.update.down().childNodes) {
    274         this.entryCount = 
     274        this.entryCount =
    275275          this.update.down().childNodes.length;
    276276        for (var i = 0; i < this.entryCount; i++) {
     
    279279          this.addObservers(entry);
    280280        }
    281       } else { 
     281      } else {
    282282        this.entryCount = 0;
    283283      }
     
    285285      this.stopIndicator();
    286286      this.index = 0;
    287      
     287
    288288      if(this.entryCount==1 && this.options.autoSelect) {
    289289        this.selectEntry();
     
    301301
    302302  onObserverEvent: function() {
    303     this.changed = false;   
     303    this.changed = false;
    304304    this.tokenBounds = null;
    305305    if(this.getToken().length>=this.options.minChars) {
     
    354354  getUpdatedChoices: function() {
    355355    this.startIndicator();
    356    
    357     var entry = encodeURIComponent(this.options.paramName) + '=' + 
     356
     357    var entry = encodeURIComponent(this.options.paramName) + '=' +
    358358      encodeURIComponent(this.getToken());
    359359
     
    361361      this.options.callback(this.element, entry) : entry;
    362362
    363     if(this.options.defaultParams) 
     363    if(this.options.defaultParams)
    364364      this.options.parameters += '&' + this.options.defaultParams;
    365    
     365
    366366    new Ajax.Request(this.url, this.options);
    367367  },
     
    385385//
    386386// - partialSearch - If false, the autocompleter will match entered
    387 //                    text only at the beginning of strings in the 
     387//                    text only at the beginning of strings in the
    388388//                    autocomplete array. Defaults to true, which will
    389389//                    match text at the beginning of any *word* in the
     
    402402//                 Defaults to true.
    403403//
    404 // It's possible to pass in a custom function as the 'selector' 
     404// It's possible to pass in a custom function as the 'selector'
    405405// option, if you prefer to write your own autocompletion logic.
    406406// In that case, the other options above will not apply unless
     
    430430        var count     = 0;
    431431
    432         for (var i = 0; i < instance.options.array.length && 
    433           ret.length < instance.options.choices ; i++) { 
     432        for (var i = 0; i < instance.options.array.length &&
     433          ret.length < instance.options.choices ; i++) {
    434434
    435435          var elem = instance.options.array[i];
    436           var foundPos = instance.options.ignoreCase ? 
    437             elem.toLowerCase().indexOf(entry.toLowerCase()) : 
     436          var foundPos = instance.options.ignoreCase ?
     437            elem.toLowerCase().indexOf(entry.toLowerCase()) :
    438438            elem.indexOf(entry);
    439439
    440440          while (foundPos != -1) {
    441             if (foundPos == 0 && elem.length != entry.length) { 
    442               ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" + 
     441            if (foundPos == 0 && elem.length != entry.length) {
     442              ret.push("<li><strong>" + elem.substr(0, entry.length) + "</strong>" +
    443443                elem.substr(entry.length) + "</li>");
    444444              break;
    445             } else if (entry.length >= instance.options.partialChars && 
     445            } else if (entry.length >= instance.options.partialChars &&
    446446              instance.options.partialSearch && foundPos != -1) {
    447447              if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
     
    453453            }
    454454
    455             foundPos = instance.options.ignoreCase ? 
    456               elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
     455            foundPos = instance.options.ignoreCase ?
     456              elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
    457457              elem.indexOf(entry, foundPos + 1);
    458458
     
    460460        }
    461461        if (partial.length)
    462           ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
     462          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length));
    463463        return "<ul>" + ret.join('') + "</ul>";
    464464      }
     
    477477    Field.activate(field);
    478478  }, 1);
    479 }
     479};
    480480
    481481Ajax.InPlaceEditor = Class.create({
     
    607607  },
    608608  getText: function() {
    609     return this.element.innerHTML;
     609    return this.element.innerHTML.unescapeHTML();
    610610  },
    611611  handleAJAXFailure: function(transport) {
     
    783783        var js = transport.responseText.strip();
    784784        if (!/^\[.*\]$/.test(js)) // TODO: improve sanity check
    785           throw 'Server returned an invalid collection representation.';
     785          throw('Server returned an invalid collection representation.');
    786786        this._collection = eval(js);
    787787        this.checkForExternalText();
     
    940940};
    941941
    942 // Delayed observer, like Form.Element.Observer, 
     942// Delayed observer, like Form.Element.Observer,
    943943// but waits for delay after last key input
    944944// Ideal for live-search fields
     
    950950    this.callback  = callback;
    951951    this.timer     = null;
    952     this.lastValue = $F(this.element); 
     952    this.lastValue = $F(this.element);
    953953    Event.observe(this.element,'keyup',this.delayedListener.bindAsEventListener(this));
    954954  },
  • trunk/wp-includes/js/scriptaculous/dragdrop.js

    r7131 r12557  
    1 // script.aculo.us dragdrop.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
    2 
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    4 //           (c) 2005-2007 Sammi Williams (http://www.oriontransfer.co.nz, sammi@oriontransfer.co.nz)
    5 //
     1// script.aculo.us dragdrop.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     4//
    65// script.aculo.us is freely distributable under the terms of an MIT-style license.
    76// For details, see the script.aculo.us web site: http://script.aculo.us/
     
    3534      }
    3635    }
    37    
     36
    3837    if(options.accept) options.accept = [options.accept].flatten();
    3938
     
    4342    this.drops.push(options);
    4443  },
    45  
     44
    4645  findDeepestChild: function(drops) {
    4746    deepest = drops[0];
    48      
     47
    4948    for (i = 1; i < drops.length; ++i)
    5049      if (Element.isParent(drops[i].element, deepest.element))
    5150        deepest = drops[i];
    52    
     51
    5352    return deepest;
    5453  },
     
    5756    var containmentNode;
    5857    if(drop.tree) {
    59       containmentNode = element.treeNode; 
     58      containmentNode = element.treeNode;
    6059    } else {
    6160      containmentNode = element.parentNode;
     
    6362    return drop._containers.detect(function(c) { return containmentNode == c });
    6463  },
    65  
     64
    6665  isAffected: function(point, element, drop) {
    6766    return (
     
    7069        this.isContained(element, drop)) &&
    7170      ((!drop.accept) ||
    72         (Element.classNames(element).detect( 
     71        (Element.classNames(element).detect(
    7372          function(v) { return drop.accept.include(v) } ) )) &&
    7473      Position.within(drop.element, point[0], point[1]) );
     
    9089    if(!this.drops.length) return;
    9190    var drop, affected = [];
    92    
     91
    9392    this.drops.each( function(drop) {
    9493      if(Droppables.isAffected(point, element, drop))
    9594        affected.push(drop);
    9695    });
    97        
     96
    9897    if(affected.length>0)
    9998      drop = Droppables.findDeepestChild(affected);
     
    104103      if(drop.onHover)
    105104        drop.onHover(element, drop.element, Position.overlap(drop.overlap, drop.element));
    106      
     105
    107106      if (drop != this.last_active) Droppables.activate(drop);
    108107    }
     
    115114    if (this.isAffected([Event.pointerX(event), Event.pointerY(event)], element, this.last_active))
    116115      if (this.last_active.onDrop) {
    117         this.last_active.onDrop(element, this.last_active.element, event); 
    118         return true; 
     116        this.last_active.onDrop(element, this.last_active.element, event);
     117        return true;
    119118      }
    120119  },
     
    124123      this.deactivate(this.last_active);
    125124  }
    126 }
     125};
    127126
    128127var Draggables = {
    129128  drags: [],
    130129  observers: [],
    131  
     130
    132131  register: function(draggable) {
    133132    if(this.drags.length == 0) {
     
    135134      this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
    136135      this.eventKeypress  = this.keyPress.bindAsEventListener(this);
    137      
     136
    138137      Event.observe(document, "mouseup", this.eventMouseUp);
    139138      Event.observe(document, "mousemove", this.eventMouseMove);
     
    142141    this.drags.push(draggable);
    143142  },
    144  
     143
    145144  unregister: function(draggable) {
    146145    this.drags = this.drags.reject(function(d) { return d==draggable });
     
    151150    }
    152151  },
    153  
     152
    154153  activate: function(draggable) {
    155     if(draggable.options.delay) { 
    156       this._timeout = setTimeout(function() { 
    157         Draggables._timeout = null; 
    158         window.focus(); 
    159         Draggables.activeDraggable = draggable; 
    160       }.bind(this), draggable.options.delay); 
     154    if(draggable.options.delay) {
     155      this._timeout = setTimeout(function() {
     156        Draggables._timeout = null;
     157        window.focus();
     158        Draggables.activeDraggable = draggable;
     159      }.bind(this), draggable.options.delay);
    161160    } else {
    162161      window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
     
    164163    }
    165164  },
    166  
     165
    167166  deactivate: function() {
    168167    this.activeDraggable = null;
    169168  },
    170  
     169
    171170  updateDrag: function(event) {
    172171    if(!this.activeDraggable) return;
     
    176175    if(this._lastPointer && (this._lastPointer.inspect() == pointer.inspect())) return;
    177176    this._lastPointer = pointer;
    178    
     177
    179178    this.activeDraggable.updateDrag(event, pointer);
    180179  },
    181  
     180
    182181  endDrag: function(event) {
    183     if(this._timeout) { 
    184       clearTimeout(this._timeout); 
    185       this._timeout = null; 
     182    if(this._timeout) {
     183      clearTimeout(this._timeout);
     184      this._timeout = null;
    186185    }
    187186    if(!this.activeDraggable) return;
     
    190189    this.activeDraggable = null;
    191190  },
    192  
     191
    193192  keyPress: function(event) {
    194193    if(this.activeDraggable)
    195194      this.activeDraggable.keyPress(event);
    196195  },
    197  
     196
    198197  addObserver: function(observer) {
    199198    this.observers.push(observer);
    200199    this._cacheObserverCallbacks();
    201200  },
    202  
     201
    203202  removeObserver: function(element) {  // element instead of observer fixes mem leaks
    204203    this.observers = this.observers.reject( function(o) { return o.element==element });
    205204    this._cacheObserverCallbacks();
    206205  },
    207  
     206
    208207  notify: function(eventName, draggable, event) {  // 'onStart', 'onEnd', 'onDrag'
    209208    if(this[eventName+'Count'] > 0)
     
    213212    if(draggable.options[eventName]) draggable.options[eventName](draggable, event);
    214213  },
    215  
     214
    216215  _cacheObserverCallbacks: function() {
    217216    ['onStart','onEnd','onDrag'].each( function(eventName) {
     
    221220    });
    222221  }
    223 }
     222};
    224223
    225224/*--------------------------------------------------------------------------*/
     
    237236      endeffect: function(element) {
    238237        var toOpacity = Object.isNumber(element._opacity) ? element._opacity : 1.0;
    239         new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity, 
     238        new Effect.Opacity(element, {duration:0.2, from:0.7, to:toOpacity,
    240239          queue: {scope:'_draggable', position:'end'},
    241           afterFinish: function(){ 
    242             Draggable._dragging[element] = false 
     240          afterFinish: function(){
     241            Draggable._dragging[element] = false
    243242          }
    244         }); 
     243        });
    245244      },
    246245      zindex: 1000,
     
    253252      delay: 0
    254253    };
    255    
     254
    256255    if(!arguments[1] || Object.isUndefined(arguments[1].endeffect))
    257256      Object.extend(defaults, {
     
    259258          element._opacity = Element.getOpacity(element);
    260259          Draggable._dragging[element] = true;
    261           new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7}); 
     260          new Effect.Opacity(element, {duration:0.2, from:element._opacity, to:0.7});
    262261        }
    263262      });
    264    
     263
    265264    var options = Object.extend(defaults, arguments[1] || { });
    266265
    267266    this.element = $(element);
    268    
     267
    269268    if(options.handle && Object.isString(options.handle))
    270269      this.handle = this.element.down('.'+options.handle, 0);
    271    
     270
    272271    if(!this.handle) this.handle = $(options.handle);
    273272    if(!this.handle) this.handle = this.element;
    274    
     273
    275274    if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
    276275      options.scroll = $(options.scroll);
     
    278277    }
    279278
    280     Element.makePositioned(this.element); // fix IE   
     279    Element.makePositioned(this.element); // fix IE
    281280
    282281    this.options  = options;
    283     this.dragging = false;   
     282    this.dragging = false;
    284283
    285284    this.eventMouseDown = this.initDrag.bindAsEventListener(this);
    286285    Event.observe(this.handle, "mousedown", this.eventMouseDown);
    287    
     286
    288287    Draggables.register(this);
    289288  },
    290  
     289
    291290  destroy: function() {
    292291    Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
    293292    Draggables.unregister(this);
    294293  },
    295  
     294
    296295  currentDelta: function() {
    297296    return([
     
    299298      parseInt(Element.getStyle(this.element,'top') || '0')]);
    300299  },
    301  
     300
    302301  initDrag: function(event) {
    303302    if(!Object.isUndefined(Draggable._dragging[this.element]) &&
    304303      Draggable._dragging[this.element]) return;
    305     if(Event.isLeftClick(event)) {   
     304    if(Event.isLeftClick(event)) {
    306305      // abort on form elements, fixes a Firefox issue
    307306      var src = Event.element(event);
     
    312311        tag_name=='BUTTON' ||
    313312        tag_name=='TEXTAREA')) return;
    314        
     313
    315314      var pointer = [Event.pointerX(event), Event.pointerY(event)];
    316       var pos     = Position.cumulativeOffset(this.element);
     315      var pos     = this.element.cumulativeOffset();
    317316      this.offset = [0,1].map( function(i) { return (pointer[i] - pos[i]) });
    318      
     317
    319318      Draggables.activate(this);
    320319      Event.stop(event);
    321320    }
    322321  },
    323  
     322
    324323  startDrag: function(event) {
    325324    this.dragging = true;
    326325    if(!this.delta)
    327326      this.delta = this.currentDelta();
    328    
     327
    329328    if(this.options.zindex) {
    330329      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
    331330      this.element.style.zIndex = this.options.zindex;
    332331    }
    333    
     332
    334333    if(this.options.ghosting) {
    335334      this._clone = this.element.cloneNode(true);
    336       this.element._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
    337       if (!this.element._originallyAbsolute)
     335      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
     336      if (!this._originallyAbsolute)
    338337        Position.absolutize(this.element);
    339338      this.element.parentNode.insertBefore(this._clone, this.element);
    340339    }
    341    
     340
    342341    if(this.options.scroll) {
    343342      if (this.options.scroll == window) {
     
    350349      }
    351350    }
    352    
     351
    353352    Draggables.notify('onStart', this, event);
    354        
     353
    355354    if(this.options.starteffect) this.options.starteffect(this.element);
    356355  },
    357  
     356
    358357  updateDrag: function(event, pointer) {
    359358    if(!this.dragging) this.startDrag(event);
    360    
     359
    361360    if(!this.options.quiet){
    362361      Position.prepare();
    363362      Droppables.show(pointer, this.element);
    364363    }
    365    
     364
    366365    Draggables.notify('onDrag', this, event);
    367    
     366
    368367    this.draw(pointer);
    369368    if(this.options.change) this.options.change(this);
    370    
     369
    371370    if(this.options.scroll) {
    372371      this.stopScrolling();
    373      
     372
    374373      var p;
    375374      if (this.options.scroll == window) {
     
    389388      this.startScrolling(speed);
    390389    }
    391    
     390
    392391    // fix AppleWebKit rendering
    393392    if(Prototype.Browser.WebKit) window.scrollBy(0,0);
    394    
     393
    395394    Event.stop(event);
    396395  },
    397  
     396
    398397  finishDrag: function(event, success) {
    399398    this.dragging = false;
    400    
     399
    401400    if(this.options.quiet){
    402401      Position.prepare();
     
    406405
    407406    if(this.options.ghosting) {
    408       if (!this.element._originallyAbsolute)
     407      if (!this._originallyAbsolute)
    409408        Position.relativize(this.element);
    410       delete this.element._originallyAbsolute;
     409      delete this._originallyAbsolute;
    411410      Element.remove(this._clone);
    412411      this._clone = null;
    413412    }
    414413
    415     var dropped = false; 
    416     if(success) { 
    417       dropped = Droppables.fire(event, this.element); 
    418       if (!dropped) dropped = false; 
     414    var dropped = false;
     415    if(success) {
     416      dropped = Droppables.fire(event, this.element);
     417      if (!dropped) dropped = false;
    419418    }
    420419    if(dropped && this.options.onDropped) this.options.onDropped(this.element);
     
    423422    var revert = this.options.revert;
    424423    if(revert && Object.isFunction(revert)) revert = revert(this.element);
    425    
     424
    426425    var d = this.currentDelta();
    427426    if(revert && this.options.reverteffect) {
     
    436435      this.element.style.zIndex = this.originalZ;
    437436
    438     if(this.options.endeffect) 
     437    if(this.options.endeffect)
    439438      this.options.endeffect(this.element);
    440      
     439
    441440    Draggables.deactivate(this);
    442441    Droppables.reset();
    443442  },
    444  
     443
    445444  keyPress: function(event) {
    446445    if(event.keyCode!=Event.KEY_ESC) return;
     
    448447    Event.stop(event);
    449448  },
    450  
     449
    451450  endDrag: function(event) {
    452451    if(!this.dragging) return;
     
    455454    Event.stop(event);
    456455  },
    457  
     456
    458457  draw: function(point) {
    459     var pos = Position.cumulativeOffset(this.element);
     458    var pos = this.element.cumulativeOffset();
    460459    if(this.options.ghosting) {
    461460      var r   = Position.realOffset(this.element);
    462461      pos[0] += r[0] - Position.deltaX; pos[1] += r[1] - Position.deltaY;
    463462    }
    464    
     463
    465464    var d = this.currentDelta();
    466465    pos[0] -= d[0]; pos[1] -= d[1];
    467    
     466
    468467    if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
    469468      pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
    470469      pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
    471470    }
    472    
    473     var p = [0,1].map(function(i){ 
    474       return (point[i]-pos[i]-this.offset[i]) 
     471
     472    var p = [0,1].map(function(i){
     473      return (point[i]-pos[i]-this.offset[i])
    475474    }.bind(this));
    476    
     475
    477476    if(this.options.snap) {
    478477      if(Object.isFunction(this.options.snap)) {
     
    481480      if(Object.isArray(this.options.snap)) {
    482481        p = p.map( function(v, i) {
    483           return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this))
     482          return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
    484483      } else {
    485484        p = p.map( function(v) {
    486           return (v/this.options.snap).round()*this.options.snap }.bind(this))
     485          return (v/this.options.snap).round()*this.options.snap }.bind(this));
    487486      }
    488487    }}
    489    
     488
    490489    var style = this.element.style;
    491490    if((!this.options.constraint) || (this.options.constraint=='horizontal'))
     
    493492    if((!this.options.constraint) || (this.options.constraint=='vertical'))
    494493      style.top  = p[1] + "px";
    495    
     494
    496495    if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
    497496  },
    498  
     497
    499498  stopScrolling: function() {
    500499    if(this.scrollInterval) {
     
    504503    }
    505504  },
    506  
     505
    507506  startScrolling: function(speed) {
    508507    if(!(speed[0] || speed[1])) return;
     
    511510    this.scrollInterval = setInterval(this.scroll.bind(this), 10);
    512511  },
    513  
     512
    514513  scroll: function() {
    515514    var current = new Date();
     
    527526      this.options.scroll.scrollTop  += this.scrollSpeed[1] * delta / 1000;
    528527    }
    529    
     528
    530529    Position.prepare();
    531530    Droppables.show(Draggables._lastPointer, this.element);
     
    541540      this.draw(Draggables._lastScrollPointer);
    542541    }
    543    
     542
    544543    if(this.options.change) this.options.change(this);
    545544  },
    546  
     545
    547546  _getWindowScroll: function(w) {
    548547    var T, L, W, H;
     
    563562      } else {
    564563        W = body.offsetWidth;
    565         H = body.offsetHeight
     564        H = body.offsetHeight;
    566565      }
    567566    }
     
    580579    this.lastValue = Sortable.serialize(this.element);
    581580  },
    582  
     581
    583582  onStart: function() {
    584583    this.lastValue = Sortable.serialize(this.element);
    585584  },
    586  
     585
    587586  onEnd: function() {
    588587    Sortable.unmark();
     
    594593var Sortable = {
    595594  SERIALIZE_RULE: /^[^_\-](?:[A-Za-z0-9\-\_]*)[_](.*)$/,
    596  
     595
    597596  sortables: { },
    598  
     597
    599598  _findRootElement: function(element) {
    600     while (element.tagName.toUpperCase() != "BODY") { 
     599    while (element.tagName.toUpperCase() != "BODY") {
    601600      if(element.id && Sortable.sortables[element.id]) return element;
    602601      element = element.parentNode;
     
    609608    return Sortable.sortables[element.id];
    610609  },
    611  
     610
    612611  destroy: function(element){
    613     var s = Sortable.options(element);
    614    
     612    element = $(element);
     613    var s = Sortable.sortables[element.id];
     614
    615615    if(s) {
    616616      Draggables.removeObserver(s.element);
    617617      s.droppables.each(function(d){ Droppables.remove(d) });
    618618      s.draggables.invoke('destroy');
    619      
     619
    620620      delete Sortable.sortables[s.element.id];
    621621    }
     
    624624  create: function(element) {
    625625    element = $(element);
    626     var options = Object.extend({ 
     626    var options = Object.extend({
    627627      element:     element,
    628628      tag:         'li',       // assumes li children, override with tag: 'tagname'
     
    638638      hoverclass:  null,
    639639      ghosting:    false,
    640       quiet:       false, 
     640      quiet:       false,
    641641      scroll:      false,
    642642      scrollSensitivity: 20,
    643643      scrollSpeed: 15,
    644644      format:      this.SERIALIZE_RULE,
    645      
    646       // these take arrays of elements or ids and can be 
     645
     646      // these take arrays of elements or ids and can be
    647647      // used for better initialization performance
    648648      elements:    false,
    649649      handles:     false,
    650      
     650
    651651      onChange:    Prototype.emptyFunction,
    652652      onUpdate:    Prototype.emptyFunction
     
    685685      options_for_draggable.zindex = options.zindex;
    686686
    687     // build options for the droppables 
     687    // build options for the droppables
    688688    var options_for_droppable = {
    689689      overlap:     options.overlap,
     
    692692      hoverclass:  options.hoverclass,
    693693      onHover:     Sortable.onHover
    694     }
    695    
     694    };
     695
    696696    var options_for_tree = {
    697697      onHover:      Sortable.onEmptyHover,
     
    699699      containment:  options.containment,
    700700      hoverclass:   options.hoverclass
    701     }
     701    };
    702702
    703703    // fix for gecko engine
    704     Element.cleanWhitespace(element); 
     704    Element.cleanWhitespace(element);
    705705
    706706    options.draggables = [];
     
    715715    (options.elements || this.findElements(element, options) || []).each( function(e,i) {
    716716      var handle = options.handles ? $(options.handles[i]) :
    717         (options.handle ? $(e).select('.' + options.handle)[0] : e); 
     717        (options.handle ? $(e).select('.' + options.handle)[0] : e);
    718718      options.draggables.push(
    719719        new Draggable(e, Object.extend(options_for_draggable, { handle: handle })));
    720720      Droppables.add(e, options_for_droppable);
    721721      if(options.tree) e.treeNode = element;
    722       options.droppables.push(e);     
     722      options.droppables.push(e);
    723723    });
    724    
     724
    725725    if(options.tree) {
    726726      (Sortable.findTreeElements(element, options) || []).each( function(e) {
     
    732732
    733733    // keep reference
    734     this.sortables[element.id] = options;
     734    this.sortables[element.identify()] = options;
    735735
    736736    // for onupdate
     
    744744      element, options.only, options.tree ? true : false, options.tag);
    745745  },
    746  
     746
    747747  findTreeElements: function(element, options) {
    748748    return Element.findChildren(
     
    761761        element.style.visibility = "hidden"; // fix gecko rendering
    762762        dropon.parentNode.insertBefore(element, dropon);
    763         if(dropon.parentNode!=oldParentNode) 
     763        if(dropon.parentNode!=oldParentNode)
    764764          Sortable.options(oldParentNode).onChange(element);
    765765        Sortable.options(dropon.parentNode).onChange(element);
     
    772772        element.style.visibility = "hidden"; // fix gecko rendering
    773773        dropon.parentNode.insertBefore(element, nextElement);
    774         if(dropon.parentNode!=oldParentNode) 
     774        if(dropon.parentNode!=oldParentNode)
    775775          Sortable.options(oldParentNode).onChange(element);
    776776        Sortable.options(dropon.parentNode).onChange(element);
     
    778778    }
    779779  },
    780  
     780
    781781  onEmptyHover: function(element, dropon, overlap) {
    782782    var oldParentNode = element.parentNode;
    783783    var droponOptions = Sortable.options(dropon);
    784        
     784
    785785    if(!Element.isParent(dropon, element)) {
    786786      var index;
    787      
     787
    788788      var children = Sortable.findElements(dropon, {tag: droponOptions.tag, only: droponOptions.only});
    789789      var child = null;
    790            
     790
    791791      if(children) {
    792792        var offset = Element.offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
    793        
     793
    794794        for (index = 0; index < children.length; index += 1) {
    795795          if (offset - Element.offsetSize (children[index], droponOptions.overlap) >= 0) {
     
    804804        }
    805805      }
    806      
     806
    807807      dropon.insertBefore(element, child);
    808      
     808
    809809      Sortable.options(oldParentNode).onChange(element);
    810810      droponOptions.onChange(element);
     
    819819    // mark on ghosting only
    820820    var sortable = Sortable.options(dropon.parentNode);
    821     if(sortable && !sortable.ghosting) return; 
     821    if(sortable && !sortable.ghosting) return;
    822822
    823823    if(!Sortable._marker) {
    824       Sortable._marker = 
     824      Sortable._marker =
    825825        ($('dropmarker') || Element.extend(document.createElement('DIV'))).
    826826          hide().addClassName('dropmarker').setStyle({position:'absolute'});
    827827      document.getElementsByTagName("body").item(0).appendChild(Sortable._marker);
    828     }   
    829     var offsets = Position.cumulativeOffset(dropon);
     828    }
     829    var offsets = dropon.cumulativeOffset();
    830830    Sortable._marker.setStyle({left: offsets[0]+'px', top: offsets[1] + 'px'});
    831    
     831
    832832    if(position=='after')
    833       if(sortable.overlap == 'horizontal') 
     833      if(sortable.overlap == 'horizontal')
    834834        Sortable._marker.setStyle({left: (offsets[0]+dropon.clientWidth) + 'px'});
    835835      else
    836836        Sortable._marker.setStyle({top: (offsets[1]+dropon.clientHeight) + 'px'});
    837    
     837
    838838    Sortable._marker.show();
    839839  },
    840  
     840
    841841  _tree: function(element, options, parent) {
    842842    var children = Sortable.findElements(element, options) || [];
    843  
     843
    844844    for (var i = 0; i < children.length; ++i) {
    845845      var match = children[i].id.match(options.format);
    846846
    847847      if (!match) continue;
    848      
     848
    849849      var child = {
    850850        id: encodeURIComponent(match ? match[1] : null),
     
    854854        position: parent.children.length,
    855855        container: $(children[i]).down(options.treeTag)
    856       }
    857      
     856      };
     857
    858858      /* Get the element containing the children and recurse over it */
    859859      if (child.container)
    860         this._tree(child.container, options, child)
    861      
     860        this._tree(child.container, options, child);
     861
    862862      parent.children.push (child);
    863863    }
    864864
    865     return parent; 
     865    return parent;
    866866  },
    867867
     
    876876      format: sortableOptions.format
    877877    }, arguments[1] || { });
    878    
     878
    879879    var root = {
    880880      id: null,
     
    883883      container: element,
    884884      position: 0
    885     }
    886    
     885    };
     886
    887887    return Sortable._tree(element, options, root);
    888888  },
     
    900900    element = $(element);
    901901    var options = Object.extend(this.options(element), arguments[1] || { });
    902    
     902
    903903    return $(this.findElements(element, options) || []).map( function(item) {
    904904      return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
     
    909909    element = $(element);
    910910    var options = Object.extend(this.options(element), arguments[2] || { });
    911    
     911
    912912    var nodeMap = { };
    913913    this.findElements(element, options).each( function(n) {
     
    916916        n.parentNode.removeChild(n);
    917917    });
    918    
     918
    919919    new_sequence.each(function(ident) {
    920920      var n = nodeMap[ident];
     
    925925    });
    926926  },
    927  
     927
    928928  serialize: function(element) {
    929929    element = $(element);
     
    931931    var name = encodeURIComponent(
    932932      (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
    933    
     933
    934934    if (options.tree) {
    935935      return Sortable.tree(element, arguments[1]).children.map( function (item) {
    936         return [name + Sortable._constructIndex(item) + "[id]=" + 
     936        return [name + Sortable._constructIndex(item) + "[id]=" +
    937937                encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
    938938      }).flatten().join('&');
     
    943943    }
    944944  }
    945 }
     945};
    946946
    947947// Returns true if child is contained within element
     
    950950  if (child.parentNode == element) return true;
    951951  return Element.isParent(child.parentNode, element);
    952 }
    953 
    954 Element.findChildren = function(element, only, recursive, tagName) {   
     952};
     953
     954Element.findChildren = function(element, only, recursive, tagName) {
    955955  if(!element.hasChildNodes()) return null;
    956956  tagName = tagName.toUpperCase();
     
    968968
    969969  return (elements.length>0 ? elements.flatten() : []);
    970 }
     970};
    971971
    972972Element.offsetSize = function (element, type) {
    973973  return element['offset' + ((type=='vertical' || type=='height') ? 'Height' : 'Width')];
    974 }
     974};
  • trunk/wp-includes/js/scriptaculous/effects.js

    r7131 r12557  
    1 // script.aculo.us effects.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
    2 
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     1// script.aculo.us effects.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    44// Contributors:
    55//  Justin Palmer (http://encytemedia.com/)
    66//  Mark Pilgrim (http://diveintomark.org/)
    77//  Martin Bialasinki
    8 // 
     8//
    99// script.aculo.us is freely distributable under the terms of an MIT-style license.
    10 // For details, see the script.aculo.us web site: http://script.aculo.us/ 
    11 
    12 // converts rgb() and #xxx to #xxxxxx format, 
    13 // returns self (or first argument) if not convertable 
    14 String.prototype.parseColor = function() { 
     10// For details, see the script.aculo.us web site: http://script.aculo.us/
     11
     12// converts rgb() and #xxx to #xxxxxx format,
     13// returns self (or first argument) if not convertable
     14String.prototype.parseColor = function() {
    1515  var color = '#';
    16   if (this.slice(0,4) == 'rgb(') { 
    17     var cols = this.slice(4,this.length-1).split(','); 
    18     var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3); 
    19   } else { 
    20     if (this.slice(0,1) == '#') { 
    21       if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase(); 
    22       if (this.length==7) color = this.toLowerCase(); 
    23     } 
    24   } 
    25   return (color.length==7 ? color : (arguments[0] || this)); 
     16  if (this.slice(0,4) == 'rgb(') {
     17    var cols = this.slice(4,this.length-1).split(',');
     18    var i=0; do { color += parseInt(cols[i]).toColorPart() } while (++i<3);
     19  } else {
     20    if (this.slice(0,1) == '#') {
     21      if (this.length==4) for(var i=1;i<4;i++) color += (this.charAt(i) + this.charAt(i)).toLowerCase();
     22      if (this.length==7) color = this.toLowerCase();
     23    }
     24  }
     25  return (color.length==7 ? color : (arguments[0] || this));
    2626};
    2727
    2828/*--------------------------------------------------------------------------*/
    2929
    30 Element.collectTextNodes = function(element) { 
     30Element.collectTextNodes = function(element) {
    3131  return $A($(element).childNodes).collect( function(node) {
    32     return (node.nodeType==3 ? node.nodeValue : 
     32    return (node.nodeType==3 ? node.nodeValue :
    3333      (node.hasChildNodes() ? Element.collectTextNodes(node) : ''));
    3434  }).flatten().join('');
    3535};
    3636
    37 Element.collectTextNodesIgnoreClass = function(element, className) { 
     37Element.collectTextNodesIgnoreClass = function(element, className) {
    3838  return $A($(element).childNodes).collect( function(node) {
    39     return (node.nodeType==3 ? node.nodeValue : 
    40       ((node.hasChildNodes() && !Element.hasClassName(node,className)) ? 
     39    return (node.nodeType==3 ? node.nodeValue :
     40      ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
    4141        Element.collectTextNodesIgnoreClass(node, className) : ''));
    4242  }).flatten().join('');
     
    4444
    4545Element.setContentZoom = function(element, percent) {
    46   element = $(element); 
    47   element.setStyle({fontSize: (percent/100) + 'em'});   
     46  element = $(element);
     47  element.setStyle({fontSize: (percent/100) + 'em'});
    4848  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
    4949  return element;
     
    7373    linear: Prototype.K,
    7474    sinoidal: function(pos) {
    75       return (-Math.cos(pos*Math.PI)/2) + 0.5;
     75      return (-Math.cos(pos*Math.PI)/2) + .5;
    7676    },
    7777    reverse: function(pos) {
     
    7979    },
    8080    flicker: function(pos) {
    81       var pos = ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
     81      var pos = ((-Math.cos(pos*Math.PI)/4) + .75) + Math.random()/4;
    8282      return pos > 1 ? 1 : pos;
    8383    },
    8484    wobble: function(pos) {
    85       return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
    86     },
    87     pulse: function(pos, pulses) {
    88       pulses = pulses || 5;
    89       return (
    90         ((pos % (1/pulses)) * pulses).round() == 0 ?
    91               ((pos * pulses * 2) - (pos * pulses * 2).floor()) :
    92           1 - ((pos * pulses * 2) - (pos * pulses * 2).floor())
    93         );
    94     },
    95     spring: function(pos) {
    96       return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
     85      return (-Math.cos(pos*Math.PI*(9*pos))/2) + .5;
     86    },
     87    pulse: function(pos, pulses) {
     88      return (-Math.cos((pos*((pulses||5)-.5)*2)*Math.PI)/2) + .5;
     89    },
     90    spring: function(pos) {
     91      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
    9792    },
    9893    none: function(pos) {
     
    115110    var tagifyStyle = 'position:relative';
    116111    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';
    117    
     112
    118113    element = $(element);
    119114    $A(element.childNodes).each( function(child) {
     
    122117          element.insertBefore(
    123118            new Element('span', {style: tagifyStyle}).update(
    124               character == ' ' ? String.fromCharCode(160) : character), 
     119              character == ' ' ? String.fromCharCode(160) : character),
    125120              child);
    126121        });
     
    131126  multiple: function(element, effect) {
    132127    var elements;
    133     if (((typeof element == 'object') || 
    134         Object.isFunction(element)) && 
     128    if (((typeof element == 'object') ||
     129        Object.isFunction(element)) &&
    135130       (element.length))
    136131      elements = element;
    137132    else
    138133      elements = $(element).childNodes;
    139      
     134
    140135    var options = Object.extend({
    141136      speed: 0.1,
     
    153148    'appear': ['Appear','Fade']
    154149  },
    155   toggle: function(element, effect) {
     150  toggle: function(element, effect, options) {
    156151    element = $(element);
    157     effect = (effect || 'appear').toLowerCase();
    158     var options = Object.extend({
     152    effect  = (effect || 'appear').toLowerCase();
     153   
     154    return Effect[ Effect.PAIRS[ effect ][ element.visible() ? 1 : 0 ] ](element, Object.extend({
    159155      queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
    160     }, arguments[2] || { });
    161     Effect[element.visible() ?
    162       Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
     156    }, options || {}));
    163157  }
    164158};
     
    171165  initialize: function() {
    172166    this.effects  = [];
    173     this.interval = null;   
     167    this.interval = null;
    174168  },
    175169  _each: function(iterator) {
     
    178172  add: function(effect) {
    179173    var timestamp = new Date().getTime();
    180    
    181     var position = Object.isString(effect.options.queue) ? 
     174
     175    var position = Object.isString(effect.options.queue) ?
    182176      effect.options.queue : effect.options.queue.position;
    183    
     177
    184178    switch(position) {
    185179      case 'front':
    186         // move unstarted effects after this effect 
     180        // move unstarted effects after this effect
    187181        this.effects.findAll(function(e){ return e.state=='idle' }).each( function(e) {
    188182            e.startOn  += effect.finishOn;
     
    198192        break;
    199193    }
    200    
     194
    201195    effect.startOn  += timestamp;
    202196    effect.finishOn += timestamp;
     
    204198    if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
    205199      this.effects.push(effect);
    206    
     200
    207201    if (!this.interval)
    208202      this.interval = setInterval(this.loop.bind(this), 15);
     
    217211  loop: function() {
    218212    var timePos = new Date().getTime();
    219     for(var i=0, len=this.effects.length;i<len;i++) 
     213    for(var i=0, len=this.effects.length;i<len;i++)
    220214      this.effects[i] && this.effects[i].loop(timePos);
    221215  }
     
    226220  get: function(queueName) {
    227221    if (!Object.isString(queueName)) return queueName;
    228    
     222
    229223    return this.instances.get(queueName) ||
    230224      this.instances.set(queueName, new Effect.ScopedQueue());
     
    236230  position: null,
    237231  start: function(options) {
    238     function codeForEvent(options,eventName){
    239       return (
    240         (options[eventName+'Internal'] ? 'this.options.'+eventName+'Internal(this);' : '') +
    241         (options[eventName] ? 'this.options.'+eventName+'(this);' : '')
    242       );
    243     }
    244232    if (options && options.transition === false) options.transition = Effect.Transitions.linear;
    245233    this.options      = Object.extend(Object.extend({ },Effect.DefaultOptions), options || { });
     
    251239    this.totalTime    = this.finishOn-this.startOn;
    252240    this.totalFrames  = this.options.fps*this.options.duration;
    253    
    254     eval('this.render = function(pos){ '+
    255       'if (this.state=="idle"){this.state="running";'+
    256       codeForEvent(this.options,'beforeSetup')+
    257       (this.setup ? 'this.setup();':'')+
    258       codeForEvent(this.options,'afterSetup')+
    259       '};if (this.state=="running"){'+
    260       'pos=this.options.transition(pos)*'+this.fromToDelta+'+'+this.options.from+';'+
    261       'this.position=pos;'+
    262       codeForEvent(this.options,'beforeUpdate')+
    263       (this.update ? 'this.update(pos);':'')+
    264       codeForEvent(this.options,'afterUpdate')+
    265       '}}');
    266    
     241
     242    this.render = (function() {
     243      function dispatch(effect, eventName) {
     244        if (effect.options[eventName + 'Internal'])
     245          effect.options[eventName + 'Internal'](effect);
     246        if (effect.options[eventName])
     247          effect.options[eventName](effect);
     248      }
     249
     250      return function(pos) {
     251        if (this.state === "idle") {
     252          this.state = "running";
     253          dispatch(this, 'beforeSetup');
     254          if (this.setup) this.setup();
     255          dispatch(this, 'afterSetup');
     256        }
     257        if (this.state === "running") {
     258          pos = (this.options.transition(pos) * this.fromToDelta) + this.options.from;
     259          this.position = pos;
     260          dispatch(this, 'beforeUpdate');
     261          if (this.update) this.update(pos);
     262          dispatch(this, 'afterUpdate');
     263        }
     264      };
     265    })();
     266
    267267    this.event('beforeStart');
    268268    if (!this.options.sync)
    269       Effect.Queues.get(Object.isString(this.options.queue) ? 
     269      Effect.Queues.get(Object.isString(this.options.queue) ?
    270270        'global' : this.options.queue.scope).add(this);
    271271  },
     
    276276        this.cancel();
    277277        this.event('beforeFinish');
    278         if (this.finish) this.finish(); 
     278        if (this.finish) this.finish();
    279279        this.event('afterFinish');
    280         return; 
     280        return;
    281281      }
    282282      var pos   = (timePos - this.startOn) / this.totalTime,
     
    290290  cancel: function() {
    291291    if (!this.options.sync)
    292       Effect.Queues.get(Object.isString(this.options.queue) ? 
     292      Effect.Queues.get(Object.isString(this.options.queue) ?
    293293        'global' : this.options.queue.scope).remove(this);
    294294    this.state = 'finished';
     
    328328  initialize: function(object, from, to) {
    329329    object = Object.isString(object) ? $(object) : object;
    330     var args = $A(arguments), method = args.last(), 
     330    var args = $A(arguments), method = args.last(),
    331331      options = args.length == 5 ? args[3] : null;
    332332    this.method = Object.isFunction(method) ? method.bind(object) :
    333       Object.isFunction(object[method]) ? object[method].bind(object) : 
     333      Object.isFunction(object[method]) ? object[method].bind(object) :
    334334      function(value) { object[method] = value };
    335335    this.start(Object.extend({ from: from, to: to }, options || { }));
     
    395395// for backwards compatibility
    396396Effect.MoveBy = function(element, toTop, toLeft) {
    397   return new Effect.Move(element, 
     397  return new Effect.Move(element,
    398398    Object.extend({ x: toLeft, y: toTop }, arguments[3] || { }));
    399399};
     
    417417    this.restoreAfterFinish = this.options.restoreAfterFinish || false;
    418418    this.elementPositioning = this.element.getStyle('position');
    419    
     419
    420420    this.originalStyle = { };
    421421    ['top','left','width','height','fontSize'].each( function(k) {
    422422      this.originalStyle[k] = this.element.style[k];
    423423    }.bind(this));
    424      
     424
    425425    this.originalTop  = this.element.offsetTop;
    426426    this.originalLeft = this.element.offsetLeft;
    427    
     427
    428428    var fontSize = this.element.getStyle('font-size') || '100%';
    429429    ['em','px','%','pt'].each( function(fontSizeType) {
     
    433433      }
    434434    }.bind(this));
    435    
     435
    436436    this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
    437    
     437
    438438    this.dims = null;
    439439    if (this.options.scaleMode=='box')
     
    510510Effect.ScrollTo = function(element) {
    511511  var options = arguments[1] || { },
    512     scrollOffsets = document.viewport.getScrollOffsets(),
    513     elementOffsets = $(element).cumulativeOffset(),
    514     max = (window.height || document.body.scrollHeight) - document.viewport.getHeight(); 
     512  scrollOffsets = document.viewport.getScrollOffsets(),
     513  elementOffsets = $(element).cumulativeOffset();
    515514
    516515  if (options.offset) elementOffsets[1] += options.offset;
     
    518517  return new Effect.Tween(null,
    519518    scrollOffsets.top,
    520     elementOffsets[1] > max ? max : elementOffsets[1],
     519    elementOffsets[1],
    521520    options,
    522     function(p){ scrollTo(scrollOffsets.left, p.round()) }
     521    function(p){ scrollTo(scrollOffsets.left, p.round()); }
    523522  );
    524523};
     
    532531    from: element.getOpacity() || 1.0,
    533532    to:   0.0,
    534     afterFinishInternal: function(effect) { 
     533    afterFinishInternal: function(effect) {
    535534      if (effect.options.to!=0) return;
    536       effect.element.hide().setStyle({opacity: oldOpacity}); 
     535      effect.element.hide().setStyle({opacity: oldOpacity});
    537536    }
    538537  }, arguments[1] || { });
     
    550549  },
    551550  beforeSetup: function(effect) {
    552     effect.element.setOpacity(effect.options.from).show(); 
     551    effect.element.setOpacity(effect.options.from).show();
    553552  }}, arguments[1] || { });
    554553  return new Effect.Opacity(element,options);
     
    557556Effect.Puff = function(element) {
    558557  element = $(element);
    559   var oldStyle = { 
    560     opacity: element.getInlineOpacity(), 
     558  var oldStyle = {
     559    opacity: element.getInlineOpacity(),
    561560    position: element.getStyle('position'),
    562561    top:  element.style.top,
     
    566565  };
    567566  return new Effect.Parallel(
    568    [ new Effect.Scale(element, 200, 
    569       { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }), 
    570      new Effect.Opacity(element, { sync: true, to: 0.0 } ) ], 
    571      Object.extend({ duration: 1.0, 
     567   [ new Effect.Scale(element, 200,
     568      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
     569     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
     570     Object.extend({ duration: 1.0,
    572571      beforeSetupInternal: function(effect) {
    573         Position.absolutize(effect.effects[0].element)
     572        Position.absolutize(effect.effects[0].element);
    574573      },
    575574      afterFinishInternal: function(effect) {
     
    583582  element.makeClipping();
    584583  return new Effect.Scale(element, 0,
    585     Object.extend({ scaleContent: false, 
    586       scaleX: false, 
     584    Object.extend({ scaleContent: false,
     585      scaleX: false,
    587586      restoreAfterFinish: true,
    588587      afterFinishInternal: function(effect) {
    589588        effect.element.hide().undoClipping();
    590       } 
     589      }
    591590    }, arguments[1] || { })
    592591  );
     
    596595  element = $(element);
    597596  var elementDimensions = element.getDimensions();
    598   return new Effect.Scale(element, 100, Object.extend({ 
    599     scaleContent: false, 
     597  return new Effect.Scale(element, 100, Object.extend({
     598    scaleContent: false,
    600599    scaleX: false,
    601600    scaleFrom: 0,
     
    603602    restoreAfterFinish: true,
    604603    afterSetup: function(effect) {
    605       effect.element.makeClipping().setStyle({height: '0px'}).show(); 
    606     }, 
     604      effect.element.makeClipping().setStyle({height: '0px'}).show();
     605    },
    607606    afterFinishInternal: function(effect) {
    608607      effect.element.undoClipping();
     
    619618    transition: Effect.Transitions.flicker,
    620619    afterFinishInternal: function(effect) {
    621       new Effect.Scale(effect.element, 1, { 
     620      new Effect.Scale(effect.element, 1, {
    622621        duration: 0.3, scaleFromCenter: true,
    623622        scaleX: false, scaleContent: false, restoreAfterFinish: true,
    624         beforeSetup: function(effect) { 
     623        beforeSetup: function(effect) {
    625624          effect.element.makePositioned().makeClipping();
    626625        },
     
    628627          effect.element.hide().undoClipping().undoPositioned().setStyle({opacity: oldOpacity});
    629628        }
    630       })
     629      });
    631630    }
    632631  }, arguments[1] || { }));
     
    640639    opacity: element.getInlineOpacity() };
    641640  return new Effect.Parallel(
    642     [ new Effect.Move(element, {x: 0, y: 100, sync: true }), 
     641    [ new Effect.Move(element, {x: 0, y: 100, sync: true }),
    643642      new Effect.Opacity(element, { sync: true, to: 0.0 }) ],
    644643    Object.extend(
    645644      { duration: 0.5,
    646645        beforeSetup: function(effect) {
    647           effect.effects[0].element.makePositioned(); 
     646          effect.effects[0].element.makePositioned();
    648647        },
    649648        afterFinishInternal: function(effect) {
    650649          effect.effects[0].element.hide().undoPositioned().setStyle(oldStyle);
    651         } 
     650        }
    652651      }, arguments[1] || { }));
    653652};
     
    677676      { x: -distance, y: 0, duration: split, afterFinishInternal: function(effect) {
    678677        effect.element.undoPositioned().setStyle(oldStyle);
    679   }}) }}) }}) }}) }}) }});
     678  }}); }}); }}); }}); }}); }});
    680679};
    681680
     
    685684  var oldInnerBottom = element.down().getStyle('bottom');
    686685  var elementDimensions = element.getDimensions();
    687   return new Effect.Scale(element, 100, Object.extend({ 
    688     scaleContent: false, 
    689     scaleX: false, 
     686  return new Effect.Scale(element, 100, Object.extend({
     687    scaleContent: false,
     688    scaleX: false,
    690689    scaleFrom: window.opera ? 0 : 1,
    691690    scaleMode: {originalHeight: elementDimensions.height, originalWidth: elementDimensions.width},
     
    695694      effect.element.down().makePositioned();
    696695      if (window.opera) effect.element.setStyle({top: ''});
    697       effect.element.makeClipping().setStyle({height: '0px'}).show(); 
     696      effect.element.makeClipping().setStyle({height: '0px'}).show();
    698697    },
    699698    afterUpdateInternal: function(effect) {
    700699      effect.element.down().setStyle({bottom:
    701         (effect.dims[0] - effect.element.clientHeight) + 'px' }); 
     700        (effect.dims[0] - effect.element.clientHeight) + 'px' });
    702701    },
    703702    afterFinishInternal: function(effect) {
     
    713712  var elementDimensions = element.getDimensions();
    714713  return new Effect.Scale(element, window.opera ? 0 : 1,
    715    Object.extend({ scaleContent: false, 
    716     scaleX: false, 
     714   Object.extend({ scaleContent: false,
     715    scaleX: false,
    717716    scaleMode: 'box',
    718717    scaleFrom: 100,
     
    724723      if (window.opera) effect.element.setStyle({top: ''});
    725724      effect.element.makeClipping().show();
    726     }, 
     725    },
    727726    afterUpdateInternal: function(effect) {
    728727      effect.element.down().setStyle({bottom:
     
    737736};
    738737
    739 // Bug in opera makes the TD containing this element expand for a instance after finish 
     738// Bug in opera makes the TD containing this element expand for a instance after finish
    740739Effect.Squish = function(element) {
    741   return new Effect.Scale(element, window.opera ? 1 : 0, { 
     740  return new Effect.Scale(element, window.opera ? 1 : 0, {
    742741    restoreAfterFinish: true,
    743742    beforeSetup: function(effect) {
    744       effect.element.makeClipping(); 
    745     }, 
     743      effect.element.makeClipping();
     744    },
    746745    afterFinishInternal: function(effect) {
    747       effect.element.hide().undoClipping(); 
     746      effect.element.hide().undoClipping();
    748747    }
    749748  });
     
    765764    opacity: element.getInlineOpacity() };
    766765
    767   var dims = element.getDimensions();   
     766  var dims = element.getDimensions();
    768767  var initialMoveX, initialMoveY;
    769768  var moveX, moveY;
    770  
     769
    771770  switch (options.direction) {
    772771    case 'top-left':
    773       initialMoveX = initialMoveY = moveX = moveY = 0; 
     772      initialMoveX = initialMoveY = moveX = moveY = 0;
    774773      break;
    775774    case 'top-right':
     
    796795      break;
    797796  }
    798  
     797
    799798  return new Effect.Move(element, {
    800799    x: initialMoveX,
    801800    y: initialMoveY,
    802     duration: 0.01, 
     801    duration: 0.01,
    803802    beforeSetup: function(effect) {
    804803      effect.element.hide().makeClipping().makePositioned();
     
    809808          new Effect.Move(effect.element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition }),
    810809          new Effect.Scale(effect.element, 100, {
    811             scaleMode: { originalHeight: dims.height, originalWidth: dims.width }, 
     810            scaleMode: { originalHeight: dims.height, originalWidth: dims.width },
    812811            sync: true, scaleFrom: window.opera ? 1 : 0, transition: options.scaleTransition, restoreAfterFinish: true})
    813812        ], Object.extend({
    814813             beforeSetup: function(effect) {
    815                effect.effects[0].element.setStyle({height: '0px'}).show(); 
     814               effect.effects[0].element.setStyle({height: '0px'}).show();
    816815             },
    817816             afterFinishInternal: function(effect) {
    818                effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle); 
     817               effect.effects[0].element.undoClipping().undoPositioned().setStyle(oldStyle);
    819818             }
    820819           }, options)
    821       )
     820      );
    822821    }
    823822  });
     
    841840  var dims = element.getDimensions();
    842841  var moveX, moveY;
    843  
     842
    844843  switch (options.direction) {
    845844    case 'top-left':
     
    858857      moveY = dims.height;
    859858      break;
    860     case 'center': 
     859    case 'center':
    861860      moveX = dims.width / 2;
    862861      moveY = dims.height / 2;
    863862      break;
    864863  }
    865  
     864
    866865  return new Effect.Parallel(
    867866    [ new Effect.Opacity(element, { sync: true, to: 0.0, from: 1.0, transition: options.opacityTransition }),
    868867      new Effect.Scale(element, window.opera ? 1 : 0, { sync: true, transition: options.scaleTransition, restoreAfterFinish: true}),
    869868      new Effect.Move(element, { x: moveX, y: moveY, sync: true, transition: options.moveTransition })
    870     ], Object.extend({           
     869    ], Object.extend({
    871870         beforeStartInternal: function(effect) {
    872            effect.effects[0].element.makePositioned().makeClipping(); 
     871           effect.effects[0].element.makePositioned().makeClipping();
    873872         },
    874873         afterFinishInternal: function(effect) {
     
    880879Effect.Pulsate = function(element) {
    881880  element = $(element);
    882   var options    = arguments[1] || { };
    883   var oldOpacity = element.getInlineOpacity();
    884   var transition = options.transition || Effect.Transitions.sinoidal;
    885   var reverser   = function(pos){ return transition(1-Effect.Transitions.pulse(pos, options.pulses)) };
    886   reverser.bind(transition);
    887   return new Effect.Opacity(element,
     881  var options    = arguments[1] || { },
     882    oldOpacity = element.getInlineOpacity(),
     883    transition = options.transition || Effect.Transitions.linear,
     884    reverser   = function(pos){
     885      return 1 - transition((-Math.cos((pos*(options.pulses||5)*2)*Math.PI)/2) + .5);
     886    };
     887
     888  return new Effect.Opacity(element,
    888889    Object.extend(Object.extend({  duration: 2.0, from: 0,
    889890      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
     
    899900    height: element.style.height };
    900901  element.makeClipping();
    901   return new Effect.Scale(element, 5, Object.extend({   
     902  return new Effect.Scale(element, 5, Object.extend({
    902903    scaleContent: false,
    903904    scaleX: false,
    904905    afterFinishInternal: function(effect) {
    905     new Effect.Scale(element, 1, { 
    906       scaleContent: false, 
     906    new Effect.Scale(element, 1, {
     907      scaleContent: false,
    907908      scaleY: false,
    908909      afterFinishInternal: function(effect) {
     
    919920      style: { }
    920921    }, arguments[1] || { });
    921    
     922
    922923    if (!Object.isString(options.style)) this.style = $H(options.style);
    923924    else {
     
    937938            effect.element.style[transform.style] = '';
    938939          });
    939         }
     940        };
    940941      }
    941942    }
    942943    this.start(options);
    943944  },
    944  
     945
    945946  setup: function(){
    946947    function parseColor(color){
     
    948949      color = color.parseColor();
    949950      return $R(0,2).map(function(i){
    950         return parseInt( color.slice(i*2+1,i*2+3), 16 ) 
     951        return parseInt( color.slice(i*2+1,i*2+3), 16 );
    951952      });
    952953    }
     
    968969
    969970      var originalValue = this.element.getStyle(property);
    970       return { 
    971         style: property.camelize(), 
    972         originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0), 
     971      return {
     972        style: property.camelize(),
     973        originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
    973974        targetValue: unit=='color' ? parseColor(value) : value,
    974975        unit: unit
     
    981982          (isNaN(transform.originalValue) || isNaN(transform.targetValue))
    982983        )
    983       )
     984      );
    984985    });
    985986  },
     
    987988    var style = { }, transform, i = this.transforms.length;
    988989    while(i--)
    989       style[(transform = this.transforms[i]).style] = 
     990      style[(transform = this.transforms[i]).style] =
    990991        transform.unit=='color' ? '#'+
    991992          (Math.round(transform.originalValue[0]+
     
    996997            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
    997998        (transform.originalValue +
    998           (transform.targetValue - transform.originalValue) * position).toFixed(3) + 
     999          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
    9991000            (transform.unit === null ? '' : transform.unit);
    10001001    this.element.setStyle(style, true);
     
    10331034
    10341035Element.CSS_PROPERTIES = $w(
    1035   'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' + 
     1036  'backgroundColor backgroundPosition borderBottomColor borderBottomStyle ' +
    10361037  'borderBottomWidth borderLeftColor borderLeftStyle borderLeftWidth ' +
    10371038  'borderRightColor borderRightStyle borderRightWidth borderSpacing ' +
     
    10421043  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
    10431044  'right textIndent top width wordSpacing zIndex');
    1044  
     1045
    10451046Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;
    10461047
     
    10541055    style = String.__parseStyleElement.childNodes[0].style;
    10551056  }
    1056  
     1057
    10571058  Element.CSS_PROPERTIES.each(function(property){
    1058     if (style[property]) styleRules.set(property, style[property]); 
     1059    if (style[property]) styleRules.set(property, style[property]);
    10591060  });
    1060  
     1061
    10611062  if (Prototype.Browser.IE && this.include('opacity'))
    10621063    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);
     
    10771078    element = $(element);
    10781079    var css = element.currentStyle, styles;
    1079     styles = Element.CSS_PROPERTIES.inject({ }, function(hash, property) {
    1080       hash.set(property, css[property]);
    1081       return hash;
     1080    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
     1081      results[property] = css[property];
     1082      return results;
    10821083    });
    1083     if (!styles.opacity) styles.set('opacity', element.getOpacity());
     1084    if (!styles.opacity) styles.opacity = element.getOpacity();
    10841085    return styles;
    10851086  };
    1086 };
     1087}
    10871088
    10881089Effect.Methods = {
     
    10931094  },
    10941095  visualEffect: function(element, effect, options) {
    1095     element = $(element)
     1096    element = $(element);
    10961097    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    10971098    new Effect[klass](element, options);
     
    11071108$w('fade appear grow shrink fold blindUp blindDown slideUp slideDown '+
    11081109  'pulsate shake puff squish switchOff dropOut').each(
    1109   function(effect) { 
     1110  function(effect) {
    11101111    Effect.Methods[effect] = function(element, options){
    11111112      element = $(element);
    11121113      Effect[effect.charAt(0).toUpperCase() + effect.substring(1)](element, options);
    11131114      return element;
    1114     }
     1115    };
    11151116  }
    11161117);
    11171118
    1118 $w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each( 
     1119$w('getInlineOpacity forceRerendering setContentZoom collectTextNodes collectTextNodesIgnoreClass getStyles').each(
    11191120  function(f) { Effect.Methods[f] = Element[f]; }
    11201121);
  • trunk/wp-includes/js/scriptaculous/scriptaculous.js

    r7131 r12557  
    1 // script.aculo.us scriptaculous.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
     1// script.aculo.us scriptaculous.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
    22
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    4 // 
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     4//
    55// Permission is hereby granted, free of charge, to any person obtaining
    66// a copy of this software and associated documentation files (the
     
    1010// permit persons to whom the Software is furnished to do so, subject to
    1111// the following conditions:
    12 // 
     12//
    1313// The above copyright notice and this permission notice shall be
    1414// included in all copies or substantial portions of the Software.
     
    2525
    2626var Scriptaculous = {
    27   Version: '1.8.0',
     27  Version: '1.8.3',
    2828  require: function(libraryName) {
    29     // inserting via DOM fails in Safari 2.0, so brute force approach
    30     document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
     29    try{
     30      // inserting via DOM fails in Safari 2.0, so brute force approach
     31      document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
     32    } catch(e) {
     33      // for xhtml+xml served content, fall back to DOM methods
     34      var script = document.createElement('script');
     35      script.type = 'text/javascript';
     36      script.src = libraryName;
     37      document.getElementsByTagName('head')[0].appendChild(script);
     38    }
    3139  },
    32   REQUIRED_PROTOTYPE: '1.6.0',
     40  REQUIRED_PROTOTYPE: '1.6.0.3',
    3341  load: function() {
    34     function convertVersionString(versionString){
    35       var r = versionString.split('.');
    36       return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
     42    function convertVersionString(versionString) {
     43      var v = versionString.replace(/_.*|\./g, '');
     44      v = parseInt(v + '0'.times(4-v.length));
     45      return versionString.indexOf('_') > -1 ? v-1 : v;
    3746    }
    38  
    39     if((typeof Prototype=='undefined') || 
    40        (typeof Element == 'undefined') || 
     47
     48    if((typeof Prototype=='undefined') ||
     49       (typeof Element == 'undefined') ||
    4150       (typeof Element.Methods=='undefined') ||
    42        (convertVersionString(Prototype.Version) < 
     51       (convertVersionString(Prototype.Version) <
    4352        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
    4453       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
    4554        Scriptaculous.REQUIRED_PROTOTYPE);
    46    
    47     $A(document.getElementsByTagName("script")).findAll( function(s) {
    48       return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
    49     }).each( function(s) {
    50       var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
    51       var includes = s.src.match(/\?.*load=([a-z,]*)/);
     55
     56    var js = /scriptaculous\.js(\?.*)?$/;
     57    $$('head script[src]').findAll(function(s) {
     58      return s.src.match(js);
     59    }).each(function(s) {
     60      var path = s.src.replace(js, ''),
     61      includes = s.src.match(/\?.*load=([a-z,]*)/);
    5262      (includes ? includes[1] : 'builder,effects,dragdrop,controls,slider,sound').split(',').each(
    5363       function(include) { Scriptaculous.require(path+include+'.js') });
    5464    });
    5565  }
    56 }
     66};
    5767
    5868Scriptaculous.load();
  • trunk/wp-includes/js/scriptaculous/slider.js

    r7131 r12557  
    1 // script.aculo.us slider.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
    2 
    3 // Copyright (c) 2005-2007 Marty Haught, Thomas Fuchs
     1// script.aculo.us slider.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2
     3// Copyright (c) 2005-2009 Marty Haught, Thomas Fuchs
    44//
    55// script.aculo.us is freely distributable under the terms of an MIT-style license.
     
    1717  initialize: function(handle, track, options) {
    1818    var slider = this;
    19    
     19
    2020    if (Object.isArray(handle)) {
    2121      this.handles = handle.collect( function(e) { return $(e) });
     
    2323      this.handles = [$(handle)];
    2424    }
    25    
     25
    2626    this.track   = $(track);
    2727    this.options = options || { };
     
    3131    this.step      = parseInt(this.options.step || '1');
    3232    this.range     = this.options.range || $R(0,1);
    33    
     33
    3434    this.value     = 0; // assure backwards compat
    3535    this.values    = this.handles.map( function() { return 0 });
     
    4646    this.alignX = parseInt(this.options.alignX || '0');
    4747    this.alignY = parseInt(this.options.alignY || '0');
    48    
     48
    4949    this.trackLength = this.maximumOffset() - this.minimumOffset();
    5050
    51     this.handleLength = this.isVertical() ? 
    52       (this.handles[0].offsetHeight != 0 ? 
    53         this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) : 
    54       (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth : 
     51    this.handleLength = this.isVertical() ?
     52      (this.handles[0].offsetHeight != 0 ?
     53        this.handles[0].offsetHeight : this.handles[0].style.height.replace(/px$/,"")) :
     54      (this.handles[0].offsetWidth != 0 ? this.handles[0].offsetWidth :
    5555        this.handles[0].style.width.replace(/px$/,""));
    5656
     
    7676      i = slider.handles.length-1-i;
    7777      slider.setValue(parseFloat(
    78         (Object.isArray(slider.options.sliderValue) ? 
    79           slider.options.sliderValue[i] : slider.options.sliderValue) || 
     78        (Object.isArray(slider.options.sliderValue) ?
     79          slider.options.sliderValue[i] : slider.options.sliderValue) ||
    8080         slider.range.start), i);
    8181      h.makePositioned().observe("mousedown", slider.eventMouseDown);
    8282    });
    83    
     83
    8484    this.track.observe("mousedown", this.eventMouseDown);
    8585    document.observe("mouseup", this.eventMouseUp);
    8686    document.observe("mousemove", this.eventMouseMove);
    87    
     87
    8888    this.initialized = true;
    8989  },
    9090  dispose: function() {
    91     var slider = this;   
     91    var slider = this;
    9292    Event.stopObserving(this.track, "mousedown", this.eventMouseDown);
    9393    Event.stopObserving(document, "mouseup", this.eventMouseUp);
     
    102102  setEnabled: function(){
    103103    this.disabled = false;
    104   }, 
     104  },
    105105  getNearestValue: function(value){
    106106    if (this.allowedValues){
    107107      if (value >= this.allowedValues.max()) return(this.allowedValues.max());
    108108      if (value <= this.allowedValues.min()) return(this.allowedValues.min());
    109      
     109
    110110      var offset = Math.abs(this.allowedValues[0] - value);
    111111      var newValue = this.allowedValues[0];
     
    115115          newValue = v;
    116116          offset = currentOffset;
    117         } 
     117        }
    118118      });
    119119      return newValue;
     
    139139    this.values[handleIdx] = sliderValue;
    140140    this.value = this.values[0]; // assure backwards compat
    141    
    142     this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] = 
     141
     142    this.handles[handleIdx].style[this.isVertical() ? 'top' : 'left'] =
    143143      this.translateToPx(sliderValue);
    144    
     144
    145145    this.drawSpans();
    146146    if (!this.dragging || !this.event) this.updateFinished();
    147147  },
    148148  setValueBy: function(delta, handleIdx) {
    149     this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta, 
     149    this.setValue(this.values[handleIdx || this.activeHandleIdx || 0] + delta,
    150150      handleIdx || this.activeHandleIdx || 0);
    151151  },
    152152  translateToPx: function(value) {
    153153    return Math.round(
    154       ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) * 
     154      ((this.trackLength-this.handleLength)/(this.range.end-this.range.start)) *
    155155      (value - this.range.start)) + "px";
    156156  },
    157157  translateToValue: function(offset) {
    158     return ((offset/(this.trackLength-this.handleLength) * 
     158    return ((offset/(this.trackLength-this.handleLength) *
    159159      (this.range.end-this.range.start)) + this.range.start);
    160160  },
    161161  getRange: function(range) {
    162     var v = this.values.sortBy(Prototype.K); 
     162    var v = this.values.sortBy(Prototype.K);
    163163    range = range || 0;
    164164    return $R(v[range],v[range+1]);
     
    168168  },
    169169  maximumOffset: function(){
    170     return(this.isVertical() ? 
     170    return(this.isVertical() ?
    171171      (this.track.offsetHeight != 0 ? this.track.offsetHeight :
    172         this.track.style.height.replace(/px$/,"")) - this.alignY : 
    173       (this.track.offsetWidth != 0 ? this.track.offsetWidth : 
     172        this.track.style.height.replace(/px$/,"")) - this.alignY :
     173      (this.track.offsetWidth != 0 ? this.track.offsetWidth :
    174174        this.track.style.width.replace(/px$/,"")) - this.alignX);
    175   }, 
     175  },
    176176  isVertical:  function(){
    177177    return (this.axis == 'vertical');
     
    185185        $R(0, this.values.length>1 ? this.getRange(0).min() : this.value ));
    186186    if (this.options.endSpan)
    187       this.setSpan(this.options.endSpan, 
     187      this.setSpan(this.options.endSpan,
    188188        $R(this.values.length>1 ? this.getRange(this.spans.length-1).max() : this.value, this.maximum));
    189189  },
     
    205205      if (!this.disabled){
    206206        this.active = true;
    207        
     207
    208208        var handle = Event.element(event);
    209209        var pointer  = [Event.pointerX(event), Event.pointerY(event)];
    210210        var track = handle;
    211211        if (track==this.track) {
    212           var offsets  = Position.cumulativeOffset(this.track);
     212          var offsets  = this.track.cumulativeOffset();
    213213          this.event = event;
    214           this.setValue(this.translateToValue( 
     214          this.setValue(this.translateToValue(
    215215           (this.isVertical() ? pointer[1]-offsets[1] : pointer[0]-offsets[0])-(this.handleLength/2)
    216216          ));
    217           var offsets  = Position.cumulativeOffset(this.activeHandle);
     217          var offsets  = this.activeHandle.cumulativeOffset();
    218218          this.offsetX = (pointer[0] - offsets[0]);
    219219          this.offsetY = (pointer[1] - offsets[1]);
    220220        } else {
    221221          // find the handle (prevents issues with Safari)
    222           while((this.handles.indexOf(handle) == -1) && handle.parentNode) 
     222          while((this.handles.indexOf(handle) == -1) && handle.parentNode)
    223223            handle = handle.parentNode;
    224            
     224
    225225          if (this.handles.indexOf(handle)!=-1) {
    226226            this.activeHandle    = handle;
    227227            this.activeHandleIdx = this.handles.indexOf(this.activeHandle);
    228228            this.updateStyles();
    229            
    230             var offsets  = Position.cumulativeOffset(this.activeHandle);
     229
     230            var offsets  = this.activeHandle.cumulativeOffset();
    231231            this.offsetX = (pointer[0] - offsets[0]);
    232232            this.offsetY = (pointer[1] - offsets[1]);
     
    247247  draw: function(event) {
    248248    var pointer = [Event.pointerX(event), Event.pointerY(event)];
    249     var offsets = Position.cumulativeOffset(this.track);
     249    var offsets = this.track.cumulativeOffset();
    250250    pointer[0] -= this.offsetX + offsets[0];
    251251    pointer[1] -= this.offsetY + offsets[1];
     
    262262    this.active = false;
    263263    this.dragging = false;
    264   }, 
     264  },
    265265  finishDrag: function(event, success) {
    266266    this.active = false;
     
    269269  },
    270270  updateFinished: function() {
    271     if (this.initialized && this.options.onChange) 
     271    if (this.initialized && this.options.onChange)
    272272      this.options.onChange(this.values.length>1 ? this.values : this.value, this);
    273273    this.event = null;
  • trunk/wp-includes/js/scriptaculous/sound.js

    r7131 r12557  
    1 // script.aculo.us sound.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
     1// script.aculo.us sound.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
    22
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    44//
    55// Based on code created by Jules Gravinese (http://www.webveteran.com/)
     
    2424      track: 'global', url: url, replace: false
    2525    }, arguments[1] || {});
    26    
     26
    2727    if(options.replace && this.tracks[options.track]) {
    2828      $R(0, this.tracks[options.track].id).each(function(id){
     
    3030        sound.Stop && sound.Stop();
    3131        sound.remove();
    32       })
     32      });
    3333      this.tracks[options.track] = null;
    3434    }
    35      
     35
    3636    if(!this.tracks[options.track])
    37       this.tracks[options.track] = { id: 0 }
     37      this.tracks[options.track] = { id: 0 };
    3838    else
    3939      this.tracks[options.track].id++;
    40      
     40
    4141    options.id = this.tracks[options.track].id;
    42     $$('body')[0].insert( 
     42    $$('body')[0].insert(
    4343      Prototype.Browser.IE ? new Element('bgsound',{
    4444        id: 'sound_'+options.track+'_'+options.id,
     
    5050if(Prototype.Browser.Gecko && navigator.userAgent.indexOf("Win") > 0){
    5151  if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('QuickTime') != -1 }))
    52     Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>')
     52    Sound.template = new Template('<object id="sound_#{track}_#{id}" width="0" height="0" type="audio/mpeg" data="#{url}"/>');
     53  else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('Windows Media') != -1 }))
     54    Sound.template = new Template('<object id="sound_#{track}_#{id}" type="application/x-mplayer2" data="#{url}"></object>');
     55  else if(navigator.plugins && $A(navigator.plugins).detect(function(p){ return p.name.indexOf('RealPlayer') != -1 }))
     56    Sound.template = new Template('<embed type="audio/x-pn-realaudio-plugin" style="height:0" id="sound_#{track}_#{id}" src="#{url}" loop="false" autostart="true" hidden="true"/>');
    5357  else
    54     Sound.play = function(){}
    55 }
     58    Sound.play = function(){};
     59} 
  • trunk/wp-includes/js/scriptaculous/unittest.js

    r7131 r12557  
    1 // script.aculo.us unittest.js v1.8.0, Tue Nov 06 15:01:40 +0300 2007
    2 
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    4 //           (c) 2005-2007 Jon Tirsen (http://www.tirsen.com)
    5 //           (c) 2005-2007 Michael Schuerig (http://www.schuerig.de/michael/)
     1// script.aculo.us unittest.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
     2
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     4//           (c) 2005-2009 Jon Tirsen (http://www.tirsen.com)
     5//           (c) 2005-2009 Michael Schuerig (http://www.schuerig.de/michael/)
    66//
    77// script.aculo.us is freely distributable under the terms of an MIT-style license.
     
    3333  this.mark.style.width = "5px";
    3434  this.mark.style.height = "5px;";
    35   this.mark.style.borderTop = "1px solid red;"
    36   this.mark.style.borderLeft = "1px solid red;"
     35  this.mark.style.borderTop = "1px solid red;";
     36  this.mark.style.borderLeft = "1px solid red;";
    3737 
    3838  if(this.step)
     
    6868};
    6969
    70 var Test = {}
     70var Test = {};
    7171Test.Unit = {};
    7272
     
    118118    '<tbody id="loglines"></tbody>' +
    119119    '</table>';
    120     this.logsummary = $('logsummary')
     120    this.logsummary = $('logsummary');
    121121    this.loglines = $('loglines');
    122122  },
     
    126126  addLinksToResults: function(){
    127127    $$("tr.failed .nameCell").each( function(td){ // todo: limit to children of this.log
    128       td.title = "Run only this test"
     128      td.title = "Run only this test";
    129129      Event.observe(td, 'click', function(){ window.location.search = "?tests=" + td.innerHTML;});
    130130    });
    131131    $$("tr.passed .nameCell").each( function(td){ // todo: limit to children of this.log
    132       td.title = "Run all tests"
     132      td.title = "Run all tests";
    133133      Event.observe(td, 'click', function(){ window.location.search = "";});
    134134    });
    135135  }
    136 }
     136};
    137137
    138138Test.Unit.Runner = Class.create();
     
    247247      errors     + " errors");
    248248  }
    249 }
     249};
    250250
    251251Test.Unit.Assertions = Class.create();
     
    332332  },
    333333  assertNull: function(obj) {
    334     var message = arguments[1] || 'assertNull'
     334    var message = arguments[1] || 'assertNull';
    335335    try { (obj==null) ? this.pass() :
    336336      this.fail(message + ': got "' + Test.Unit.inspect(obj) + '"'); }
     
    462462    return timeTaken;
    463463  }
    464 }
     464};
    465465
    466466Test.Unit.Testcase = Class.create();
     
    527527  var makeAssertion = function(assertion, args, object) {
    528528    this[assertion].apply(this,(args || []).concat([object]));
    529   }
     529  };
    530530 
    531531  Test.BDDMethods = {};   
     
    540540    function(p){ Object.extend(p, Test.BDDMethods) }
    541541  );
    542 }
     542};
    543543
    544544Test.context = function(name, spec, log){
  • trunk/wp-includes/js/scriptaculous/wp-scriptaculous.js

    r7131 r12557  
    1 // script.aculo.us scriptaculous.js v1.7.1_beta3, Fri May 25 17:19:41 +0200 2007
     1// script.aculo.us scriptaculous.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009
    22
    3 // Copyright (c) 2005-2007 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
    4 // 
     3// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
     4//
    55// Permission is hereby granted, free of charge, to any person obtaining
    66// a copy of this software and associated documentation files (the
     
    1010// permit persons to whom the Software is furnished to do so, subject to
    1111// the following conditions:
    12 // 
     12//
    1313// The above copyright notice and this permission notice shall be
    1414// included in all copies or substantial portions of the Software.
     
    2525
    2626var Scriptaculous = {
    27   Version: '1.8.0',
     27  Version: '1.8.3',
    2828  require: function(libraryName) {
    29     // inserting via DOM fails in Safari 2.0, so brute force approach
    30     document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
     29    try{
     30      // inserting via DOM fails in Safari 2.0, so brute force approach
     31      document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
     32    } catch(e) {
     33      // for xhtml+xml served content, fall back to DOM methods
     34      var script = document.createElement('script');
     35      script.type = 'text/javascript';
     36      script.src = libraryName;
     37      document.getElementsByTagName('head')[0].appendChild(script);
     38    }
    3139  },
    32   REQUIRED_PROTOTYPE: '1.6',
     40  REQUIRED_PROTOTYPE: '1.6.0.3',
    3341  load: function() {
    34     function convertVersionString(versionString){
    35       var r = versionString.split('.');
    36       return parseInt(r[0])*100000 + parseInt(r[1])*1000 + parseInt(r[2]);
     42    function convertVersionString(versionString) {
     43      var v = versionString.replace(/_.*|\./g, '');
     44      v = parseInt(v + '0'.times(4-v.length));
     45      return versionString.indexOf('_') > -1 ? v-1 : v;
    3746    }
    38  
    39     if((typeof Prototype=='undefined') || 
    40        (typeof Element == 'undefined') || 
     47
     48    if((typeof Prototype=='undefined') ||
     49       (typeof Element == 'undefined') ||
    4150       (typeof Element.Methods=='undefined') ||
    42        (convertVersionString(Prototype.Version) < 
     51       (convertVersionString(Prototype.Version) <
    4352        convertVersionString(Scriptaculous.REQUIRED_PROTOTYPE)))
    4453       throw("script.aculo.us requires the Prototype JavaScript framework >= " +
    4554        Scriptaculous.REQUIRED_PROTOTYPE);
    46    
    47     $A(document.getElementsByTagName("script")).findAll( function(s) {
    48       return (s.src && s.src.match(/scriptaculous\.js(\?.*)?$/))
    49     }).each( function(s) {
    50       var path = s.src.replace(/scriptaculous\.js(\?.*)?$/,'');
    51       var includes = s.src.match(/\?.*load=([a-z,]*)/);
    52       if ( includes )
    53        includes[1].split(',').each(
    54        function(include) { Scriptaculous.require(path+include+'.js') });
     55
     56    var js = /scriptaculous\.js(\?.*)?$/;
     57    $$('head script[src]').findAll(function(s) {
     58      return s.src.match(js);
     59    }).each(function(s) {
     60        var path = s.src.replace(js, ''),
     61        includes = s.src.match(/\?.*load=([a-z,]*)/);
     62
     63        // Modified for WordPress to work with enqueue_script
     64        if ( includes ) {
     65            includes[1].split(',').each( function(include) {
     66                Scriptaculous.require(path+include+'.js')
     67            });
     68        }
    5569    });
    5670  }
    57 }
     71};
    5872
    5973Scriptaculous.load();
  • trunk/wp-includes/script-loader.php

    r12554 r12557  
    9090    $scripts->add( 'editor', "/wp-admin/js/editor$suffix.js", false, '20091124' );
    9191
    92     $scripts->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6');
     92    $scripts->add( 'prototype', '/wp-includes/js/prototype.js', false, '1.6.1');
    9393
    9494    $scripts->add( 'wp-ajax-response', "/wp-includes/js/wp-ajax-response$suffix.js", array('jquery'), '20091119' );
     
    106106    $scripts->add_data( 'wp-lists', 'group', 1 );
    107107
    108     $scripts->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/wp-scriptaculous.js', array('prototype'), '1.8.0');
    109     $scripts->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.8.0');
    110     $scripts->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.8.0');
    111     $scripts->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.8.0');
    112     $scripts->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.8.0');
    113     $scripts->add( 'scriptaculous-sound', '/wp-includes/js/scriptaculous/sound.js', array( 'scriptaculous-root' ), '1.8.0' );
    114     $scripts->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.8.0');
    115     $scripts->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.8.0');
     108    $scripts->add( 'scriptaculous-root', '/wp-includes/js/scriptaculous/wp-scriptaculous.js', array('prototype'), '1.8.3');
     109    $scripts->add( 'scriptaculous-builder', '/wp-includes/js/scriptaculous/builder.js', array('scriptaculous-root'), '1.8.3');
     110    $scripts->add( 'scriptaculous-dragdrop', '/wp-includes/js/scriptaculous/dragdrop.js', array('scriptaculous-builder', 'scriptaculous-effects'), '1.8.3');
     111    $scripts->add( 'scriptaculous-effects', '/wp-includes/js/scriptaculous/effects.js', array('scriptaculous-root'), '1.8.3');
     112    $scripts->add( 'scriptaculous-slider', '/wp-includes/js/scriptaculous/slider.js', array('scriptaculous-effects'), '1.8.3');
     113    $scripts->add( 'scriptaculous-sound', '/wp-includes/js/scriptaculous/sound.js', array( 'scriptaculous-root' ), '1.8.3' );
     114    $scripts->add( 'scriptaculous-controls', '/wp-includes/js/scriptaculous/controls.js', array('scriptaculous-root'), '1.8.3');
     115    $scripts->add( 'scriptaculous', '', array('scriptaculous-dragdrop', 'scriptaculous-slider', 'scriptaculous-controls'), '1.8.3');
    116116
    117117    // not used in core, replaced by Jcrop.js
Note: See TracChangeset for help on using the changeset viewer.