~ubuntu-branches/ubuntu/karmic/ampache/karmic

« back to all changes in this revision

Viewing changes to modules/prototype/prototype.js

  • Committer: Bazaar Package Importer
  • Author(s): Charlie Smotherman
  • Date: 2009-07-07 07:23:35 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090707072335-soq0jyo59mgopzd2
Tags: 3.5.1-0ubuntu1
 * New upstream release.  Summary of new features:  (LP: #377016)
   - Make the PHP error a little clearer for windows users by indicating
     that their version of PHP is < 5.3 (required for windows)
   - Fix random methods not working for Localplay
   - Fix extra space on prefixed albums (Thx ibizaman)
   - Add missing operator on tag and rating searches so they will
     work with other methods (Thx kiehnet@netscape.net)
   - Fix get_art_url() so it returns something... 
   - Fix problem with creating new playlists where it doesn't work
     but appending to an existing did. 
   - Fixed issue with url_to_song, also cleaned up the code a bit
   - Fixed issue with Random All Catalogs
   - Fixed issues with API and Tag methods not working as advertised
   - Fix endless loop in getid3() with malformed genre tags in mp3s
   - Fixed show test page always returning false on web path
   - Update Man page to adhear to newer Debian rules
   - Fixed issue with Videos being incorrectly registered with stats
     and now playing as songs. 
   - Fixed missing > in HTML for song row
 * Bumped Standards-Version to 3.8.2, no changes needed.
 * Bumped debhelper to dh 7.
   - increased debian/compat to 7.
   - debian/rules removed dh_clean -k in favor of dh_prep
 * Lintian complains of FreeMonoMedium.ttf being an embeded fonts package.
   FreeMonoMedium.ttf is actually part of the ttf-freefont package.
   - added ttf-freefont to the Depends section of debian/control.
   - added -XFreeMono-Medium to dh_install in debian/rules.
   - added FreeMono.ttf symbolic link to debian/links.
 * Lintian complains of the wrong file permissions for 
   -  /locale/base/gather-messages.sh, added -Xgather-messages.sh to 
   debian/rules, gather-messages.sh is not used by ampache proper and 
   can be safely removed.  It is only utilized by developers who are 
   creating or editing the translation files.
   -  /locale/pl_PL/LC_MESSAGES/messages.po added find and chmod rule 
   to debian/rules.
   -  /locale/pl_PL/LC_MESSAGES/messages.mo added find and chmod rule 
   to debian/rules.
   -  /docs/CHANGELOG added find and chmod rule to debian/rules.
 * Lintian complains of wrong-name-for-upstream-changelog
   -  install upstream CHANGELOG to /usr/share/ampache/www/docs
   -  added find and gzip -9 rule to debian/rules
   -  added symlink creation to debian/links to link
      /usr/share/ampache/www/docs/CHANGELOG.gz to 
      /usr/share/doc/ampache/changelog.gz  
 * Lacy Marrow has responded and has stated that he is dropping the GPL-3 
   licensing of his work and is now releasing version 5.9.5 of the 
   XSPF JukeBox under the same BSD license that the original version of XSPF 
   Music Player was released under (XSPF JukeBox is based on XSPF Music 
   Player).  So now XSPF Music Player and XSPF JukeBox are now released under
   the same BSD type license.  This closes RC Bug #526719.  Closes: #526719
   - Updated debian/copyright to refect this.
 * Added dh_installman to debian/rules so the manpage now installs correctly.
   - Added debian/ampache.manpages.
 * debian/ampache.config downgraded db_input to medium
 * debian/copyright removed (C) in favor of the word copyright.
 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*  Prototype JavaScript framework, version 1.6.0.2
 
1
/*  Prototype JavaScript framework, version 1.6.0.3
2
2
 *  (c) 2005-2008 Sam Stephenson
3
3
 *
4
4
 *  Prototype is freely distributable under the terms of an MIT-style license.
7
7
 *--------------------------------------------------------------------------*/
8
8
 
9
9
var Prototype = {
10
 
  Version: '1.6.0.2',
 
10
  Version: '1.6.0.3',
11
11
 
12
12
  Browser: {
13
 
    IE:     !!(window.attachEvent && !window.opera),
14
 
    Opera:  !!window.opera,
 
13
    IE:     !!(window.attachEvent &&
 
14
      navigator.userAgent.indexOf('Opera') === -1),
 
15
    Opera:  navigator.userAgent.indexOf('Opera') > -1,
15
16
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
16
 
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
 
17
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
 
18
      navigator.userAgent.indexOf('KHTML') === -1,
17
19
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
18
20
  },
19
21
 
20
22
  BrowserFeatures: {
21
23
    XPath: !!document.evaluate,
 
24
    SelectorsAPI: !!document.querySelector,
22
25
    ElementExtensions: !!window.HTMLElement,
23
26
    SpecificElementExtensions:
24
 
      document.createElement('div').__proto__ &&
25
 
      document.createElement('div').__proto__ !==
26
 
        document.createElement('form').__proto__
 
27
      document.createElement('div')['__proto__'] &&
 
28
      document.createElement('div')['__proto__'] !==
 
29
        document.createElement('form')['__proto__']
27
30
  },
28
31
 
29
32
  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
83
86
      var property = properties[i], value = source[property];
84
87
      if (ancestor && Object.isFunction(value) &&
85
88
          value.argumentNames().first() == "$super") {
86
 
        var method = value, value = Object.extend((function(m) {
 
89
        var method = value;
 
90
        value = (function(m) {
87
91
          return function() { return ancestor[m].apply(this, arguments) };
88
 
        })(property).wrap(method), {
89
 
          valueOf:  function() { return method },
90
 
          toString: function() { return method.toString() }
91
 
        });
 
92
        })(property).wrap(method);
 
93
 
 
94
        value.valueOf = method.valueOf.bind(method);
 
95
        value.toString = method.toString.bind(method);
92
96
      }
93
97
      this.prototype[property] = value;
94
98
    }
167
171
  },
168
172
 
169
173
  isElement: function(object) {
170
 
    return object && object.nodeType == 1;
 
174
    return !!(object && object.nodeType == 1);
171
175
  },
172
176
 
173
177
  isArray: function(object) {
198
202
 
199
203
Object.extend(Function.prototype, {
200
204
  argumentNames: function() {
201
 
    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
 
205
    var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1]
 
206
      .replace(/\s+/g, '').split(',');
202
207
    return names.length == 1 && !names[0] ? [] : names;
203
208
  },
204
209
 
232
237
    }, timeout);
233
238
  },
234
239
 
 
240
  defer: function() {
 
241
    var args = [0.01].concat($A(arguments));
 
242
    return this.delay.apply(this, args);
 
243
  },
 
244
 
235
245
  wrap: function(wrapper) {
236
246
    var __method = this;
237
247
    return function() {
248
258
  }
249
259
});
250
260
 
251
 
Function.prototype.defer = Function.prototype.delay.curry(0.01);
252
 
 
253
261
Date.prototype.toJSON = function() {
254
262
  return '"' + this.getUTCFullYear() + '-' +
255
263
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
530
538
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
531
539
  },
532
540
  unescapeHTML: function() {
533
 
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
 
541
    return this.stripTags().replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
534
542
  }
535
543
});
536
544
 
547
555
  text: document.createTextNode('')
548
556
});
549
557
 
550
 
with (String.prototype.escapeHTML) div.appendChild(text);
 
558
String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text);
551
559
 
552
560
var Template = Class.create({
553
561
  initialize: function(template, pattern) {
589
597
var Enumerable = {
590
598
  each: function(iterator, context) {
591
599
    var index = 0;
592
 
    iterator = iterator.bind(context);
593
600
    try {
594
601
      this._each(function(value) {
595
 
        iterator(value, index++);
 
602
        iterator.call(context, value, index++);
596
603
      });
597
604
    } catch (e) {
598
605
      if (e != $break) throw e;
601
608
  },
602
609
 
603
610
  eachSlice: function(number, iterator, context) {
604
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
605
611
    var index = -number, slices = [], array = this.toArray();
 
612
    if (number < 1) return array;
606
613
    while ((index += number) < array.length)
607
614
      slices.push(array.slice(index, index+number));
608
615
    return slices.collect(iterator, context);
609
616
  },
610
617
 
611
618
  all: function(iterator, context) {
612
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
619
    iterator = iterator || Prototype.K;
613
620
    var result = true;
614
621
    this.each(function(value, index) {
615
 
      result = result && !!iterator(value, index);
 
622
      result = result && !!iterator.call(context, value, index);
616
623
      if (!result) throw $break;
617
624
    });
618
625
    return result;
619
626
  },
620
627
 
621
628
  any: function(iterator, context) {
622
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
629
    iterator = iterator || Prototype.K;
623
630
    var result = false;
624
631
    this.each(function(value, index) {
625
 
      if (result = !!iterator(value, index))
 
632
      if (result = !!iterator.call(context, value, index))
626
633
        throw $break;
627
634
    });
628
635
    return result;
629
636
  },
630
637
 
631
638
  collect: function(iterator, context) {
632
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
639
    iterator = iterator || Prototype.K;
633
640
    var results = [];
634
641
    this.each(function(value, index) {
635
 
      results.push(iterator(value, index));
 
642
      results.push(iterator.call(context, value, index));
636
643
    });
637
644
    return results;
638
645
  },
639
646
 
640
647
  detect: function(iterator, context) {
641
 
    iterator = iterator.bind(context);
642
648
    var result;
643
649
    this.each(function(value, index) {
644
 
      if (iterator(value, index)) {
 
650
      if (iterator.call(context, value, index)) {
645
651
        result = value;
646
652
        throw $break;
647
653
      }
650
656
  },
651
657
 
652
658
  findAll: function(iterator, context) {
653
 
    iterator = iterator.bind(context);
654
659
    var results = [];
655
660
    this.each(function(value, index) {
656
 
      if (iterator(value, index))
 
661
      if (iterator.call(context, value, index))
657
662
        results.push(value);
658
663
    });
659
664
    return results;
660
665
  },
661
666
 
662
667
  grep: function(filter, iterator, context) {
663
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
668
    iterator = iterator || Prototype.K;
664
669
    var results = [];
665
670
 
666
671
    if (Object.isString(filter))
668
673
 
669
674
    this.each(function(value, index) {
670
675
      if (filter.match(value))
671
 
        results.push(iterator(value, index));
 
676
        results.push(iterator.call(context, value, index));
672
677
    });
673
678
    return results;
674
679
  },
696
701
  },
697
702
 
698
703
  inject: function(memo, iterator, context) {
699
 
    iterator = iterator.bind(context);
700
704
    this.each(function(value, index) {
701
 
      memo = iterator(memo, value, index);
 
705
      memo = iterator.call(context, memo, value, index);
702
706
    });
703
707
    return memo;
704
708
  },
711
715
  },
712
716
 
713
717
  max: function(iterator, context) {
714
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
718
    iterator = iterator || Prototype.K;
715
719
    var result;
716
720
    this.each(function(value, index) {
717
 
      value = iterator(value, index);
 
721
      value = iterator.call(context, value, index);
718
722
      if (result == null || value >= result)
719
723
        result = value;
720
724
    });
722
726
  },
723
727
 
724
728
  min: function(iterator, context) {
725
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
729
    iterator = iterator || Prototype.K;
726
730
    var result;
727
731
    this.each(function(value, index) {
728
 
      value = iterator(value, index);
 
732
      value = iterator.call(context, value, index);
729
733
      if (result == null || value < result)
730
734
        result = value;
731
735
    });
733
737
  },
734
738
 
735
739
  partition: function(iterator, context) {
736
 
    iterator = iterator ? iterator.bind(context) : Prototype.K;
 
740
    iterator = iterator || Prototype.K;
737
741
    var trues = [], falses = [];
738
742
    this.each(function(value, index) {
739
 
      (iterator(value, index) ?
 
743
      (iterator.call(context, value, index) ?
740
744
        trues : falses).push(value);
741
745
    });
742
746
    return [trues, falses];
751
755
  },
752
756
 
753
757
  reject: function(iterator, context) {
754
 
    iterator = iterator.bind(context);
755
758
    var results = [];
756
759
    this.each(function(value, index) {
757
 
      if (!iterator(value, index))
 
760
      if (!iterator.call(context, value, index))
758
761
        results.push(value);
759
762
    });
760
763
    return results;
761
764
  },
762
765
 
763
766
  sortBy: function(iterator, context) {
764
 
    iterator = iterator.bind(context);
765
767
    return this.map(function(value, index) {
766
 
      return {value: value, criteria: iterator(value, index)};
 
768
      return {
 
769
        value: value,
 
770
        criteria: iterator.call(context, value, index)
 
771
      };
767
772
    }).sort(function(left, right) {
768
773
      var a = left.criteria, b = right.criteria;
769
774
      return a < b ? -1 : a > b ? 1 : 0;
815
820
if (Prototype.Browser.WebKit) {
816
821
  $A = function(iterable) {
817
822
    if (!iterable) return [];
818
 
    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
819
 
        iterable.toArray) return iterable.toArray();
 
823
    // In Safari, only use the `toArray` method if it's not a NodeList.
 
824
    // A NodeList is a function, has an function `item` property, and a numeric
 
825
    // `length` property. Adapted from Google Doctype.
 
826
    if (!(typeof iterable === 'function' && typeof iterable.length ===
 
827
        'number' && typeof iterable.item === 'function') && iterable.toArray)
 
828
      return iterable.toArray();
820
829
    var length = iterable.length || 0, results = new Array(length);
821
830
    while (length--) results[length] = iterable[length];
822
831
    return results;
963
972
    return this + 1;
964
973
  },
965
974
 
966
 
  times: function(iterator) {
967
 
    $R(0, this, true).each(iterator);
 
975
  times: function(iterator, context) {
 
976
    $R(0, this, true).each(iterator, context);
968
977
    return this;
969
978
  },
970
979
 
1011
1020
    },
1012
1021
 
1013
1022
    get: function(key) {
1014
 
      return this._object[key];
 
1023
      // simulating poorly supported hasOwnProperty
 
1024
      if (this._object[key] !== Object.prototype[key])
 
1025
        return this._object[key];
1015
1026
    },
1016
1027
 
1017
1028
    unset: function(key) {
1051
1062
    },
1052
1063
 
1053
1064
    toQueryString: function() {
1054
 
      return this.map(function(pair) {
 
1065
      return this.inject([], function(results, pair) {
1055
1066
        var key = encodeURIComponent(pair.key), values = pair.value;
1056
1067
 
1057
1068
        if (values && typeof values == 'object') {
1058
1069
          if (Object.isArray(values))
1059
 
            return values.map(toQueryPair.curry(key)).join('&');
1060
 
        }
1061
 
        return toQueryPair(key, values);
 
1070
            return results.concat(values.map(toQueryPair.curry(key)));
 
1071
        } else results.push(toQueryPair(key, values));
 
1072
        return results;
1062
1073
      }).join('&');
1063
1074
    },
1064
1075
 
1558
1569
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
1559
1570
  };
1560
1571
  Object.extend(this.Element, element || { });
 
1572
  if (element) this.Element.prototype = element.prototype;
1561
1573
}).call(window);
1562
1574
 
1563
1575
Element.cache = { };
1574
1586
  },
1575
1587
 
1576
1588
  hide: function(element) {
1577
 
    $(element).style.display = 'none';
 
1589
    element = $(element);
 
1590
    element.style.display = 'none';
1578
1591
    return element;
1579
1592
  },
1580
1593
 
1581
1594
  show: function(element) {
1582
 
    $(element).style.display = '';
 
1595
    element = $(element);
 
1596
    element.style.display = '';
1583
1597
    return element;
1584
1598
  },
1585
1599
 
1733
1747
    element = $(element);
1734
1748
    if (arguments.length == 1) return element.firstDescendant();
1735
1749
    return Object.isNumber(expression) ? element.descendants()[expression] :
1736
 
      element.select(expression)[index || 0];
 
1750
      Element.select(element, expression)[index || 0];
1737
1751
  },
1738
1752
 
1739
1753
  previous: function(element, expression, index) {
1863
1877
 
1864
1878
  descendantOf: function(element, ancestor) {
1865
1879
    element = $(element), ancestor = $(ancestor);
1866
 
    var originalAncestor = ancestor;
1867
1880
 
1868
1881
    if (element.compareDocumentPosition)
1869
1882
      return (element.compareDocumentPosition(ancestor) & 8) === 8;
1870
1883
 
1871
 
    if (element.sourceIndex && !Prototype.Browser.Opera) {
1872
 
      var e = element.sourceIndex, a = ancestor.sourceIndex,
1873
 
       nextAncestor = ancestor.nextSibling;
1874
 
      if (!nextAncestor) {
1875
 
        do { ancestor = ancestor.parentNode; }
1876
 
        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
1877
 
      }
1878
 
      if (nextAncestor && nextAncestor.sourceIndex)
1879
 
       return (e > a && e < nextAncestor.sourceIndex);
1880
 
    }
 
1884
    if (ancestor.contains)
 
1885
      return ancestor.contains(element) && ancestor !== element;
1881
1886
 
1882
1887
    while (element = element.parentNode)
1883
 
      if (element == originalAncestor) return true;
 
1888
      if (element == ancestor) return true;
 
1889
 
1884
1890
    return false;
1885
1891
  },
1886
1892
 
1895
1901
    element = $(element);
1896
1902
    style = style == 'float' ? 'cssFloat' : style.camelize();
1897
1903
    var value = element.style[style];
1898
 
    if (!value) {
 
1904
    if (!value || value == 'auto') {
1899
1905
      var css = document.defaultView.getComputedStyle(element, null);
1900
1906
      value = css ? css[style] : null;
1901
1907
    }
1934
1940
 
1935
1941
  getDimensions: function(element) {
1936
1942
    element = $(element);
1937
 
    var display = $(element).getStyle('display');
 
1943
    var display = element.getStyle('display');
1938
1944
    if (display != 'none' && display != null) // Safari bug
1939
1945
      return {width: element.offsetWidth, height: element.offsetHeight};
1940
1946
 
1963
1969
      element.style.position = 'relative';
1964
1970
      // Opera returns the offset relative to the positioning context, when an
1965
1971
      // element is position relative but top and left have not been defined
1966
 
      if (window.opera) {
 
1972
      if (Prototype.Browser.Opera) {
1967
1973
        element.style.top = 0;
1968
1974
        element.style.left = 0;
1969
1975
      }
2018
2024
      valueL += element.offsetLeft || 0;
2019
2025
      element = element.offsetParent;
2020
2026
      if (element) {
2021
 
        if (element.tagName == 'BODY') break;
 
2027
        if (element.tagName.toUpperCase() == 'BODY') break;
2022
2028
        var p = Element.getStyle(element, 'position');
2023
2029
        if (p !== 'static') break;
2024
2030
      }
2028
2034
 
2029
2035
  absolutize: function(element) {
2030
2036
    element = $(element);
2031
 
    if (element.getStyle('position') == 'absolute') return;
 
2037
    if (element.getStyle('position') == 'absolute') return element;
2032
2038
    // Position.prepare(); // To be done manually by Scripty when it needs it.
2033
2039
 
2034
2040
    var offsets = element.positionedOffset();
2052
2058
 
2053
2059
  relativize: function(element) {
2054
2060
    element = $(element);
2055
 
    if (element.getStyle('position') == 'relative') return;
 
2061
    if (element.getStyle('position') == 'relative') return element;
2056
2062
    // Position.prepare(); // To be done manually by Scripty when it needs it.
2057
2063
 
2058
2064
    element.style.position = 'relative';
2103
2109
 
2104
2110
    element = forElement;
2105
2111
    do {
2106
 
      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
 
2112
      if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpperCase() == 'BODY'))) {
2107
2113
        valueT -= element.scrollTop  || 0;
2108
2114
        valueL -= element.scrollLeft || 0;
2109
2115
      }
2218
2224
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
2219
2225
    function(proceed, element) {
2220
2226
      element = $(element);
 
2227
      // IE throws an error if element is not in document
 
2228
      try { element.offsetParent }
 
2229
      catch(e) { return $(document.body) }
2221
2230
      var position = element.getStyle('position');
2222
2231
      if (position !== 'static') return proceed(element);
2223
2232
      element.setStyle({ position: 'relative' });
2231
2240
    Element.Methods[method] = Element.Methods[method].wrap(
2232
2241
      function(proceed, element) {
2233
2242
        element = $(element);
 
2243
        try { element.offsetParent }
 
2244
        catch(e) { return Element._returnOffset(0,0) }
2234
2245
        var position = element.getStyle('position');
2235
2246
        if (position !== 'static') return proceed(element);
2236
2247
        // Trigger hasLayout on the offset parent so that IE6 reports
2246
2257
    );
2247
2258
  });
2248
2259
 
 
2260
  Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
 
2261
    function(proceed, element) {
 
2262
      try { element.offsetParent }
 
2263
      catch(e) { return Element._returnOffset(0,0) }
 
2264
      return proceed(element);
 
2265
    }
 
2266
  );
 
2267
 
2249
2268
  Element.Methods.getStyle = function(element, style) {
2250
2269
    element = $(element);
2251
2270
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
2337
2356
  Element._attributeTranslations.has = {};
2338
2357
 
2339
2358
  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
2340
 
      'encType maxLength readOnly longDesc').each(function(attr) {
 
2359
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
2341
2360
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
2342
2361
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
2343
2362
  });
2390
2409
      (value < 0.00001) ? 0 : value;
2391
2410
 
2392
2411
    if (value == 1)
2393
 
      if(element.tagName == 'IMG' && element.width) {
 
2412
      if(element.tagName.toUpperCase() == 'IMG' && element.width) {
2394
2413
        element.width++; element.width--;
2395
2414
      } else try {
2396
2415
        var n = document.createTextNode(' ');
2521
2540
  hasAttribute: function(element, attribute) {
2522
2541
    attribute = Element._attributeTranslations.has[attribute] || attribute;
2523
2542
    var node = $(element).getAttributeNode(attribute);
2524
 
    return node && node.specified;
 
2543
    return !!(node && node.specified);
2525
2544
  }
2526
2545
};
2527
2546
 
2530
2549
Object.extend(Element, Element.Methods);
2531
2550
 
2532
2551
if (!Prototype.BrowserFeatures.ElementExtensions &&
2533
 
    document.createElement('div').__proto__) {
 
2552
    document.createElement('div')['__proto__']) {
2534
2553
  window.HTMLElement = { };
2535
 
  window.HTMLElement.prototype = document.createElement('div').__proto__;
 
2554
  window.HTMLElement.prototype = document.createElement('div')['__proto__'];
2536
2555
  Prototype.BrowserFeatures.ElementExtensions = true;
2537
2556
}
2538
2557
 
2547
2566
        element.nodeType != 1 || element == window) return element;
2548
2567
 
2549
2568
    var methods = Object.clone(Methods),
2550
 
      tagName = element.tagName, property, value;
 
2569
      tagName = element.tagName.toUpperCase(), property, value;
2551
2570
 
2552
2571
    // extend methods for specific tags
2553
2572
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);
2643
2662
    if (window[klass]) return window[klass];
2644
2663
 
2645
2664
    window[klass] = { };
2646
 
    window[klass].prototype = document.createElement(tagName).__proto__;
 
2665
    window[klass].prototype = document.createElement(tagName)['__proto__'];
2647
2666
    return window[klass];
2648
2667
  }
2649
2668
 
2669
2688
 
2670
2689
document.viewport = {
2671
2690
  getDimensions: function() {
2672
 
    var dimensions = { };
2673
 
    var B = Prototype.Browser;
 
2691
    var dimensions = { }, B = Prototype.Browser;
2674
2692
    $w('width height').each(function(d) {
2675
2693
      var D = d.capitalize();
2676
 
      dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
2677
 
        (B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
 
2694
      if (B.WebKit && !document.evaluate) {
 
2695
        // Safari <3.0 needs self.innerWidth/Height
 
2696
        dimensions[d] = self['inner' + D];
 
2697
      } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
 
2698
        // Opera <9.5 needs document.body.clientWidth/Height
 
2699
        dimensions[d] = document.body['client' + D]
 
2700
      } else {
 
2701
        dimensions[d] = document.documentElement['client' + D];
 
2702
      }
2678
2703
    });
2679
2704
    return dimensions;
2680
2705
  },
2693
2718
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
2694
2719
  }
2695
2720
};
2696
 
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
 
2721
/* Portions of the Selector class are derived from Jack Slocum's DomQuery,
2697
2722
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2698
2723
 * license.  Please see http://www.yui-ext.com/ for more information. */
2699
2724
 
2700
2725
var Selector = Class.create({
2701
2726
  initialize: function(expression) {
2702
2727
    this.expression = expression.strip();
2703
 
    this.compileMatcher();
 
2728
 
 
2729
    if (this.shouldUseSelectorsAPI()) {
 
2730
      this.mode = 'selectorsAPI';
 
2731
    } else if (this.shouldUseXPath()) {
 
2732
      this.mode = 'xpath';
 
2733
      this.compileXPathMatcher();
 
2734
    } else {
 
2735
      this.mode = "normal";
 
2736
      this.compileMatcher();
 
2737
    }
 
2738
 
2704
2739
  },
2705
2740
 
2706
2741
  shouldUseXPath: function() {
2715
2750
 
2716
2751
    // XPath can't do namespaced attributes, nor can it read
2717
2752
    // the "checked" property from DOM nodes
2718
 
    if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
2719
 
      return false;
 
2753
    if ((/(\[[\w-]*?:|:checked)/).test(e))
 
2754
      return false;
 
2755
 
 
2756
    return true;
 
2757
  },
 
2758
 
 
2759
  shouldUseSelectorsAPI: function() {
 
2760
    if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
 
2761
 
 
2762
    if (!Selector._div) Selector._div = new Element('div');
 
2763
 
 
2764
    // Make sure the browser treats the selector as valid. Test on an
 
2765
    // isolated element to minimize cost of this check.
 
2766
    try {
 
2767
      Selector._div.querySelector(this.expression);
 
2768
    } catch(e) {
 
2769
      return false;
 
2770
    }
2720
2771
 
2721
2772
    return true;
2722
2773
  },
2723
2774
 
2724
2775
  compileMatcher: function() {
2725
 
    if (this.shouldUseXPath())
2726
 
      return this.compileXPathMatcher();
2727
 
 
2728
2776
    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
2729
2777
        c = Selector.criteria, le, p, m;
2730
2778
 
2742
2790
        p = ps[i];
2743
2791
        if (m = e.match(p)) {
2744
2792
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
2745
 
              new Template(c[i]).evaluate(m));
 
2793
            new Template(c[i]).evaluate(m));
2746
2794
          e = e.replace(m[0], '');
2747
2795
          break;
2748
2796
        }
2781
2829
 
2782
2830
  findElements: function(root) {
2783
2831
    root = root || document;
2784
 
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
2785
 
    return this.matcher(root);
 
2832
    var e = this.expression, results;
 
2833
 
 
2834
    switch (this.mode) {
 
2835
      case 'selectorsAPI':
 
2836
        // querySelectorAll queries document-wide, then filters to descendants
 
2837
        // of the context element. That's not what we want.
 
2838
        // Add an explicit context to the selector if necessary.
 
2839
        if (root !== document) {
 
2840
          var oldId = root.id, id = $(root).identify();
 
2841
          e = "#" + id + " " + e;
 
2842
        }
 
2843
 
 
2844
        results = $A(root.querySelectorAll(e)).map(Element.extend);
 
2845
        root.id = oldId;
 
2846
 
 
2847
        return results;
 
2848
      case 'xpath':
 
2849
        return document._getElementsByXPath(this.xpath, root);
 
2850
      default:
 
2851
       return this.matcher(root);
 
2852
    }
2786
2853
  },
2787
2854
 
2788
2855
  match: function(element) {
2873
2940
      'first-child': '[not(preceding-sibling::*)]',
2874
2941
      'last-child':  '[not(following-sibling::*)]',
2875
2942
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
2876
 
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
 
2943
      'empty':       "[count(*) = 0 and (count(text()) = 0)]",
2877
2944
      'checked':     "[@checked]",
2878
 
      'disabled':    "[@disabled]",
2879
 
      'enabled':     "[not(@disabled)]",
 
2945
      'disabled':    "[(@disabled) and (@type!='hidden')]",
 
2946
      'enabled':     "[not(@disabled) and (@type!='hidden')]",
2880
2947
      'not': function(m) {
2881
2948
        var e = m[6], p = Selector.patterns,
2882
2949
            x = Selector.xpath, le, v;
2968
3035
    className:    /^\.([\w\-\*]+)(\b|$)/,
2969
3036
    pseudo:
2970
3037
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
2971
 
    attrPresence: /^\[([\w]+)\]/,
 
3038
    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
2972
3039
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
2973
3040
  },
2974
3041
 
3081
3148
 
3082
3149
    nextElementSibling: function(node) {
3083
3150
      while (node = node.nextSibling)
3084
 
              if (node.nodeType == 1) return node;
 
3151
        if (node.nodeType == 1) return node;
3085
3152
      return null;
3086
3153
    },
3087
3154
 
3270
3337
    'empty': function(nodes, value, root) {
3271
3338
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
3272
3339
        // IE treats comments as element nodes
3273
 
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
 
3340
        if (node.tagName == '!' || node.firstChild) continue;
3274
3341
        results.push(node);
3275
3342
      }
3276
3343
      return results;
3288
3355
 
3289
3356
    'enabled': function(nodes, value, root) {
3290
3357
      for (var i = 0, results = [], node; node = nodes[i]; i++)
3291
 
        if (!node.disabled) results.push(node);
 
3358
        if (!node.disabled && (!node.type || node.type !== 'hidden'))
 
3359
          results.push(node);
3292
3360
      return results;
3293
3361
    },
3294
3362
 
3308
3376
  operators: {
3309
3377
    '=':  function(nv, v) { return nv == v; },
3310
3378
    '!=': function(nv, v) { return nv != v; },
3311
 
    '^=': function(nv, v) { return nv.startsWith(v); },
 
3379
    '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
 
3380
    '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
 
3381
    '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
3312
3382
    '$=': function(nv, v) { return nv.endsWith(v); },
3313
3383
    '*=': function(nv, v) { return nv.include(v); },
3314
3384
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
3315
 
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
 
3385
    '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
 
3386
     '-').include('-' + (v || "").toUpperCase() + '-'); }
3316
3387
  },
3317
3388
 
3318
3389
  split: function(expression) {
3386
3457
    var data = elements.inject({ }, function(result, element) {
3387
3458
      if (!element.disabled && element.name) {
3388
3459
        key = element.name; value = $(element).getValue();
3389
 
        if (value != null && (element.type != 'submit' || (!submitted &&
 
3460
        if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
3390
3461
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
3391
3462
          if (key in result) {
3392
3463
            // a key is already present; construct an array of values
3547
3618
 
3548
3619
  disable: function(element) {
3549
3620
    element = $(element);
3550
 
    element.blur();
3551
3621
    element.disabled = true;
3552
3622
    return element;
3553
3623
  },
3587
3657
    else element.value = value;
3588
3658
  },
3589
3659
 
3590
 
  select: function(element, index) {
3591
 
    if (Object.isUndefined(index))
 
3660
  select: function(element, value) {
 
3661
    if (Object.isUndefined(value))
3592
3662
      return this[element.type == 'select-one' ?
3593
3663
        'selectOne' : 'selectMany'](element);
3594
3664
    else {
3595
 
      var opt, value, single = !Object.isArray(index);
 
3665
      var opt, currentValue, single = !Object.isArray(value);
3596
3666
      for (var i = 0, length = element.length; i < length; i++) {
3597
3667
        opt = element.options[i];
3598
 
        value = this.optionValue(opt);
 
3668
        currentValue = this.optionValue(opt);
3599
3669
        if (single) {
3600
 
          if (value == index) {
 
3670
          if (currentValue == value) {
3601
3671
            opt.selected = true;
3602
3672
            return;
3603
3673
          }
3604
3674
        }
3605
 
        else opt.selected = index.include(value);
 
3675
        else opt.selected = value.include(currentValue);
3606
3676
      }
3607
3677
    }
3608
3678
  },
3773
3843
    isRightClick:  function(event) { return isButton(event, 2) },
3774
3844
 
3775
3845
    element: function(event) {
3776
 
      var node = Event.extend(event).target;
3777
 
      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
 
3846
      event = Event.extend(event);
 
3847
 
 
3848
      var node          = event.target,
 
3849
          type          = event.type,
 
3850
          currentTarget = event.currentTarget;
 
3851
 
 
3852
      if (currentTarget && currentTarget.tagName) {
 
3853
        // Firefox screws up the "click" event when moving between radio buttons
 
3854
        // via arrow keys. It also screws up the "load" and "error" events on images,
 
3855
        // reporting the document as the target instead of the original image.
 
3856
        if (type === 'load' || type === 'error' ||
 
3857
          (type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
 
3858
            && currentTarget.type === 'radio'))
 
3859
              node = currentTarget;
 
3860
      }
 
3861
      if (node.nodeType == Node.TEXT_NODE) node = node.parentNode;
 
3862
      return Element.extend(node);
3778
3863
    },
3779
3864
 
3780
3865
    findElement: function(event, expression) {
3785
3870
    },
3786
3871
 
3787
3872
    pointer: function(event) {
 
3873
      var docElement = document.documentElement,
 
3874
      body = document.body || { scrollLeft: 0, scrollTop: 0 };
3788
3875
      return {
3789
3876
        x: event.pageX || (event.clientX +
3790
 
          (document.documentElement.scrollLeft || document.body.scrollLeft)),
 
3877
          (docElement.scrollLeft || body.scrollLeft) -
 
3878
          (docElement.clientLeft || 0)),
3791
3879
        y: event.pageY || (event.clientY +
3792
 
          (document.documentElement.scrollTop || document.body.scrollTop))
 
3880
          (docElement.scrollTop || body.scrollTop) -
 
3881
          (docElement.clientTop || 0))
3793
3882
      };
3794
3883
    },
3795
3884
 
3834
3923
    };
3835
3924
 
3836
3925
  } else {
3837
 
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
 
3926
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__'];
3838
3927
    Object.extend(Event.prototype, methods);
3839
3928
    return Prototype.K;
3840
3929
  }
3899
3988
        cache[id][eventName] = null;
3900
3989
  }
3901
3990
 
 
3991
 
 
3992
  // Internet Explorer needs to remove event handlers on page unload
 
3993
  // in order to avoid memory leaks.
3902
3994
  if (window.attachEvent) {
3903
3995
    window.attachEvent("onunload", destroyCache);
3904
3996
  }
3905
3997
 
 
3998
  // Safari has a dummy event handler on page unload so that it won't
 
3999
  // use its bfcache. Safari <= 3.1 has an issue with restoring the "document"
 
4000
  // object when page is returned to via the back button using its bfcache.
 
4001
  if (Prototype.Browser.WebKit) {
 
4002
    window.addEventListener('unload', Prototype.emptyFunction, false);
 
4003
  }
 
4004
 
3906
4005
  return {
3907
4006
    observe: function(element, eventName, handler) {
3908
4007
      element = $(element);