2632
3057
Element.cache = { };
2635
3061
document.viewport = {
2636
3063
getDimensions: function() {
2637
var dimensions = { };
2638
var B = Prototype.Browser;
2639
$w('width height').each(function(d) {
2640
var D = d.capitalize();
2641
dimensions[d] = (B.WebKit && !document.evaluate) ? self['inner' + D] :
2642
(B.Opera) ? document.body['client' + D] : document.documentElement['client' + D];
2647
getWidth: function() {
2648
return this.getDimensions().width;
2651
getHeight: function() {
2652
return this.getDimensions().height;
3064
return { width: this.getWidth(), height: this.getHeight() };
2655
3067
getScrollOffsets: function() {
2656
3068
return Element._returnOffset(
2657
3069
window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
2658
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
2661
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
2662
* part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
2663
* license. Please see http://www.yui-ext.com/ for more information. */
2665
var Selector = Class.create({
2666
initialize: function(expression) {
2667
this.expression = expression.strip();
2668
this.compileMatcher();
2671
shouldUseXPath: function() {
2672
if (!Prototype.BrowserFeatures.XPath) return false;
2674
var e = this.expression;
2676
// Safari 3 chokes on :*-of-type and :empty
2677
if (Prototype.Browser.WebKit &&
2678
(e.include("-of-type") || e.include(":empty")))
2681
// XPath can't do namespaced attributes, nor can it read
2682
// the "checked" property from DOM nodes
2683
if ((/(\[[\w-]*?:|:checked)/).test(this.expression))
3070
window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
3074
(function(viewport) {
3075
var B = Prototype.Browser, doc = document, element, property = {};
3077
function getRootElement() {
3078
if (B.WebKit && !doc.evaluate)
3081
if (B.Opera && window.parseFloat(window.opera.version()) < 9.5)
3082
return document.body;
3084
return document.documentElement;
3087
function define(D) {
3088
if (!element) element = getRootElement();
3090
property[D] = 'client' + D;
3092
viewport['get' + D] = function() { return element[property[D]] };
3093
return viewport['get' + D]();
3096
viewport.getWidth = define.curry('Width');
3098
viewport.getHeight = define.curry('Height');
3099
})(document.viewport);
3106
Element.addMethods({
3107
getStorage: function(element) {
3108
if (!(element = $(element))) return;
3111
if (element === window) {
3114
if (typeof element._prototypeUID === "undefined")
3115
element._prototypeUID = Element.Storage.UID++;
3116
uid = element._prototypeUID;
3119
if (!Element.Storage[uid])
3120
Element.Storage[uid] = $H();
3122
return Element.Storage[uid];
3125
store: function(element, key, value) {
3126
if (!(element = $(element))) return;
3128
if (arguments.length === 2) {
3129
Element.getStorage(element).update(key);
3131
Element.getStorage(element).set(key, value);
3137
retrieve: function(element, key, defaultValue) {
3138
if (!(element = $(element))) return;
3139
var hash = Element.getStorage(element), value = hash.get(key);
3141
if (Object.isUndefined(value)) {
3142
hash.set(key, defaultValue);
3143
value = defaultValue;
3149
clone: function(element, deep) {
3150
if (!(element = $(element))) return;
3151
var clone = element.cloneNode(deep);
3152
clone._prototypeUID = void 0;
3154
var descendants = Element.select(clone, '*'),
3155
i = descendants.length;
3157
descendants[i]._prototypeUID = void 0;
3160
return Element.extend(clone);
3163
purge: function(element) {
3164
if (!(element = $(element))) return;
3165
var purgeElement = Element._purgeElement;
3167
purgeElement(element);
3169
var descendants = element.getElementsByTagName('*'),
3170
i = descendants.length;
3172
while (i--) purgeElement(descendants[i]);
3180
function toDecimal(pctString) {
3181
var match = pctString.match(/^(\d+)%?$/i);
3182
if (!match) return null;
3183
return (Number(match[1]) / 100);
3186
function getPixelValue(value, property, context) {
3188
if (Object.isElement(value)) {
3190
value = element.getStyle(property);
3193
if (value === null) {
3197
if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3198
return window.parseFloat(value);
3201
var isPercentage = value.include('%'), isViewport = (context === document.viewport);
3203
if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
3204
var style = element.style.left, rStyle = element.runtimeStyle.left;
3205
element.runtimeStyle.left = element.currentStyle.left;
3206
element.style.left = value || 0;
3207
value = element.style.pixelLeft;
3208
element.style.left = style;
3209
element.runtimeStyle.left = rStyle;
3214
if (element && isPercentage) {
3215
context = context || element.parentNode;
3216
var decimal = toDecimal(value);
3218
var position = element.getStyle('position');
3220
var isHorizontal = property.include('left') || property.include('right') ||
3221
property.include('width');
3223
var isVertical = property.include('top') || property.include('bottom') ||
3224
property.include('height');
3226
if (context === document.viewport) {
3228
whole = document.viewport.getWidth();
3229
} else if (isVertical) {
3230
whole = document.viewport.getHeight();
3234
whole = $(context).measure('width');
3235
} else if (isVertical) {
3236
whole = $(context).measure('height');
3240
return (whole === null) ? 0 : whole * decimal;
3246
function toCSSPixels(number) {
3247
if (Object.isString(number) && number.endsWith('px')) {
3250
return number + 'px';
3253
function isDisplayed(element) {
3254
var originalElement = element;
3255
while (element && element.parentNode) {
3256
var display = element.getStyle('display');
3257
if (display === 'none') {
3260
element = $(element.parentNode);
2689
compileMatcher: function() {
2690
if (this.shouldUseXPath())
2691
return this.compileXPathMatcher();
2693
var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
2694
c = Selector.criteria, le, p, m;
2696
if (Selector._cache[e]) {
2697
this.matcher = Selector._cache[e];
2701
this.matcher = ["this.matcher = function(root) {",
2702
"var r = root, h = Selector.handlers, c = false, n;"];
2704
while (e && le != e && (/\S/).test(e)) {
2708
if (m = e.match(p)) {
2709
this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
2710
new Template(c[i]).evaluate(m));
2711
e = e.replace(m[0], '');
2717
this.matcher.push("return h.unique(n);\n}");
2718
eval(this.matcher.join('\n'));
2719
Selector._cache[this.expression] = this.matcher;
2722
compileXPathMatcher: function() {
2723
var e = this.expression, ps = Selector.patterns,
2724
x = Selector.xpath, le, m;
2726
if (Selector._cache[e]) {
2727
this.xpath = Selector._cache[e]; return;
2730
this.matcher = ['.//*'];
2731
while (e && le != e && (/\S/).test(e)) {
2734
if (m = e.match(ps[i])) {
2735
this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
2736
new Template(x[i]).evaluate(m));
2737
e = e.replace(m[0], '');
2743
this.xpath = this.matcher.join('');
2744
Selector._cache[this.expression] = this.xpath;
2747
findElements: function(root) {
2748
root = root || document;
2749
if (this.xpath) return document._getElementsByXPath(this.xpath, root);
2750
return this.matcher(root);
2753
match: function(element) {
2756
var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
2759
while (e && le !== e && (/\S/).test(e)) {
2763
if (m = e.match(p)) {
2764
// use the Selector.assertions methods unless the selector
2767
this.tokens.push([i, Object.clone(m)]);
2768
e = e.replace(m[0], '');
2770
// reluctantly do a document-wide search
2771
// and look for a match in the array
2772
return this.findElements(document).include(element);
2778
var match = true, name, matches;
2779
for (var i = 0, token; token = this.tokens[i]; i++) {
2780
name = token[0], matches = token[1];
2781
if (!Selector.assertions[name](element, matches)) {
2782
match = false; break;
2789
toString: function() {
2790
return this.expression;
2793
inspect: function() {
2794
return "#<Selector:" + this.expression.inspect() + ">";
2798
Object.extend(Selector, {
2804
adjacent: "/following-sibling::*[1]",
2805
laterSibling: '/following-sibling::*',
2806
tagName: function(m) {
2807
if (m[1] == '*') return '';
2808
return "[local-name()='" + m[1].toLowerCase() +
2809
"' or local-name()='" + m[1].toUpperCase() + "']";
2811
className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
2813
attrPresence: function(m) {
2814
m[1] = m[1].toLowerCase();
2815
return new Template("[@#{1}]").evaluate(m);
2818
m[1] = m[1].toLowerCase();
2819
m[3] = m[5] || m[6];
2820
return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
2822
pseudo: function(m) {
2823
var h = Selector.xpath.pseudos[m[1]];
2825
if (Object.isFunction(h)) return h(m);
2826
return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
2829
'=': "[@#{1}='#{3}']",
2830
'!=': "[@#{1}!='#{3}']",
2831
'^=': "[starts-with(@#{1}, '#{3}')]",
2832
'$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
2833
'*=': "[contains(@#{1}, '#{3}')]",
2834
'~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
2835
'|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
2838
'first-child': '[not(preceding-sibling::*)]',
2839
'last-child': '[not(following-sibling::*)]',
2840
'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
2841
'empty': "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
2842
'checked': "[@checked]",
2843
'disabled': "[@disabled]",
2844
'enabled': "[not(@disabled)]",
2845
'not': function(m) {
2846
var e = m[6], p = Selector.patterns,
2847
x = Selector.xpath, le, v;
2850
while (e && le != e && (/\S/).test(e)) {
2853
if (m = e.match(p[i])) {
2854
v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
2855
exclusion.push("(" + v.substring(1, v.length - 1) + ")");
2856
e = e.replace(m[0], '');
2861
return "[not(" + exclusion.join(" and ") + ")]";
2863
'nth-child': function(m) {
2864
return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
2866
'nth-last-child': function(m) {
2867
return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
2869
'nth-of-type': function(m) {
2870
return Selector.xpath.pseudos.nth("position() ", m);
2872
'nth-last-of-type': function(m) {
2873
return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
2875
'first-of-type': function(m) {
2876
m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
2878
'last-of-type': function(m) {
2879
m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
2881
'only-of-type': function(m) {
2882
var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
2884
nth: function(fragment, m) {
2885
var mm, formula = m[6], predicate;
2886
if (formula == 'even') formula = '2n+0';
2887
if (formula == 'odd') formula = '2n+1';
2888
if (mm = formula.match(/^(\d+)$/)) // digit only
2889
return '[' + fragment + "= " + mm[1] + ']';
2890
if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
2891
if (mm[1] == "-") mm[1] = -1;
2892
var a = mm[1] ? Number(mm[1]) : 1;
2893
var b = mm[2] ? Number(mm[2]) : 0;
2894
predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
2895
"((#{fragment} - #{b}) div #{a} >= 0)]";
2896
return new Template(predicate).evaluate({
2897
fragment: fragment, a: a, b: b });
2904
tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
2905
className: 'n = h.className(n, r, "#{1}", c); c = false;',
2906
id: 'n = h.id(n, r, "#{1}", c); c = false;',
2907
attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
2909
m[3] = (m[5] || m[6]);
2910
return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
2912
pseudo: function(m) {
2913
if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
2914
return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
2916
descendant: 'c = "descendant";',
2917
child: 'c = "child";',
2918
adjacent: 'c = "adjacent";',
2919
laterSibling: 'c = "laterSibling";'
2923
// combinators must be listed first
2924
// (and descendant needs to be last combinator)
2925
laterSibling: /^\s*~\s*/,
2927
adjacent: /^\s*\+\s*/,
2931
tagName: /^\s*(\*|[\w\-]+)(\b|$)?/,
2932
id: /^#([\w\-\*]+)(\b|$)/,
2933
className: /^\.([\w\-\*]+)(\b|$)/,
2935
/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
2936
attrPresence: /^\[([\w]+)\]/,
2937
attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
2940
// for Selector.match and Element#match
2942
tagName: function(element, matches) {
2943
return matches[1].toUpperCase() == element.tagName.toUpperCase();
2946
className: function(element, matches) {
2947
return Element.hasClassName(element, matches[1]);
2950
id: function(element, matches) {
2951
return element.id === matches[1];
2954
attrPresence: function(element, matches) {
2955
return Element.hasAttribute(element, matches[1]);
2958
attr: function(element, matches) {
2959
var nodeValue = Element.readAttribute(element, matches[1]);
2960
return Selector.operators[matches[2]](nodeValue, matches[3]);
2965
// UTILITY FUNCTIONS
2966
// joins two collections
2967
concat: function(a, b) {
2968
for (var i = 0, node; node = b[i]; i++)
2973
// marks an array of nodes for counting
2974
mark: function(nodes) {
2975
for (var i = 0, node; node = nodes[i]; i++)
2976
node._counted = true;
2980
unmark: function(nodes) {
2981
for (var i = 0, node; node = nodes[i]; i++)
2982
node._counted = undefined;
2986
// mark each child node with its position (for nth calls)
2987
// "ofType" flag indicates whether we're indexing for nth-of-type
2988
// rather than nth-child
2989
index: function(parentNode, reverse, ofType) {
2990
parentNode._counted = true;
2992
for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
2993
var node = nodes[i];
2994
if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
2997
for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
2998
if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
3002
// filters out duplicates and extends all nodes
3003
unique: function(nodes) {
3004
if (nodes.length == 0) return nodes;
3005
var results = [], n;
3006
for (var i = 0, l = nodes.length; i < l; i++)
3007
if (!(n = nodes[i])._counted) {
3009
results.push(Element.extend(n));
3011
return Selector.handlers.unmark(results);
3014
// COMBINATOR FUNCTIONS
3015
descendant: function(nodes) {
3016
var h = Selector.handlers;
3017
for (var i = 0, results = [], node; node = nodes[i]; i++)
3018
h.concat(results, node.getElementsByTagName('*'));
3022
child: function(nodes) {
3023
var h = Selector.handlers;
3024
for (var i = 0, results = [], node; node = nodes[i]; i++) {
3025
for (var j = 0, child; child = node.childNodes[j]; j++)
3026
if (child.nodeType == 1 && child.tagName != '!') results.push(child);
3031
adjacent: function(nodes) {
3032
for (var i = 0, results = [], node; node = nodes[i]; i++) {
3033
var next = this.nextElementSibling(node);
3034
if (next) results.push(next);
3039
laterSibling: function(nodes) {
3040
var h = Selector.handlers;
3041
for (var i = 0, results = [], node; node = nodes[i]; i++)
3042
h.concat(results, Element.nextSiblings(node));
3046
nextElementSibling: function(node) {
3047
while (node = node.nextSibling)
3048
if (node.nodeType == 1) return node;
3052
previousElementSibling: function(node) {
3053
while (node = node.previousSibling)
3054
if (node.nodeType == 1) return node;
3059
tagName: function(nodes, root, tagName, combinator) {
3060
var uTagName = tagName.toUpperCase();
3061
var results = [], h = Selector.handlers;
3064
// fastlane for ordinary descendant combinators
3065
if (combinator == "descendant") {
3066
for (var i = 0, node; node = nodes[i]; i++)
3067
h.concat(results, node.getElementsByTagName(tagName));
3069
} else nodes = this[combinator](nodes);
3070
if (tagName == "*") return nodes;
3072
for (var i = 0, node; node = nodes[i]; i++)
3073
if (node.tagName.toUpperCase() === uTagName) results.push(node);
3075
} else return root.getElementsByTagName(tagName);
3078
id: function(nodes, root, id, combinator) {
3079
var targetNode = $(id), h = Selector.handlers;
3080
if (!targetNode) return [];
3081
if (!nodes && root == document) return [targetNode];
3084
if (combinator == 'child') {
3085
for (var i = 0, node; node = nodes[i]; i++)
3086
if (targetNode.parentNode == node) return [targetNode];
3087
} else if (combinator == 'descendant') {
3088
for (var i = 0, node; node = nodes[i]; i++)
3089
if (Element.descendantOf(targetNode, node)) return [targetNode];
3090
} else if (combinator == 'adjacent') {
3091
for (var i = 0, node; node = nodes[i]; i++)
3092
if (Selector.handlers.previousElementSibling(targetNode) == node)
3093
return [targetNode];
3094
} else nodes = h[combinator](nodes);
3096
for (var i = 0, node; node = nodes[i]; i++)
3097
if (node == targetNode) return [targetNode];
3100
return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
3103
className: function(nodes, root, className, combinator) {
3104
if (nodes && combinator) nodes = this[combinator](nodes);
3105
return Selector.handlers.byClassName(nodes, root, className);
3108
byClassName: function(nodes, root, className) {
3109
if (!nodes) nodes = Selector.handlers.descendant([root]);
3110
var needle = ' ' + className + ' ';
3111
for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
3112
nodeClassName = node.className;
3113
if (nodeClassName.length == 0) continue;
3114
if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
3120
attrPresence: function(nodes, root, attr) {
3121
if (!nodes) nodes = root.getElementsByTagName("*");
3123
for (var i = 0, node; node = nodes[i]; i++)
3124
if (Element.hasAttribute(node, attr)) results.push(node);
3128
attr: function(nodes, root, attr, value, operator) {
3129
if (!nodes) nodes = root.getElementsByTagName("*");
3130
var handler = Selector.operators[operator], results = [];
3131
for (var i = 0, node; node = nodes[i]; i++) {
3132
var nodeValue = Element.readAttribute(node, attr);
3133
if (nodeValue === null) continue;
3134
if (handler(nodeValue, value)) results.push(node);
3139
pseudo: function(nodes, name, value, root, combinator) {
3140
if (nodes && combinator) nodes = this[combinator](nodes);
3141
if (!nodes) nodes = root.getElementsByTagName("*");
3142
return Selector.pseudos[name](nodes, value, root);
3147
'first-child': function(nodes, value, root) {
3148
for (var i = 0, results = [], node; node = nodes[i]; i++) {
3149
if (Selector.handlers.previousElementSibling(node)) continue;
3154
'last-child': function(nodes, value, root) {
3155
for (var i = 0, results = [], node; node = nodes[i]; i++) {
3156
if (Selector.handlers.nextElementSibling(node)) continue;
3161
'only-child': function(nodes, value, root) {
3162
var h = Selector.handlers;
3163
for (var i = 0, results = [], node; node = nodes[i]; i++)
3164
if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
3168
'nth-child': function(nodes, formula, root) {
3169
return Selector.pseudos.nth(nodes, formula, root);
3171
'nth-last-child': function(nodes, formula, root) {
3172
return Selector.pseudos.nth(nodes, formula, root, true);
3174
'nth-of-type': function(nodes, formula, root) {
3175
return Selector.pseudos.nth(nodes, formula, root, false, true);
3177
'nth-last-of-type': function(nodes, formula, root) {
3178
return Selector.pseudos.nth(nodes, formula, root, true, true);
3180
'first-of-type': function(nodes, formula, root) {
3181
return Selector.pseudos.nth(nodes, "1", root, false, true);
3183
'last-of-type': function(nodes, formula, root) {
3184
return Selector.pseudos.nth(nodes, "1", root, true, true);
3186
'only-of-type': function(nodes, formula, root) {
3187
var p = Selector.pseudos;
3188
return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
3191
// handles the an+b logic
3192
getIndices: function(a, b, total) {
3193
if (a == 0) return b > 0 ? [b] : [];
3194
return $R(1, total).inject([], function(memo, i) {
3195
if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
3265
var hasLayout = Prototype.K;
3266
if ('currentStyle' in document.documentElement) {
3267
hasLayout = function(element) {
3268
if (!element.currentStyle.hasLayout) {
3269
element.style.zoom = 1;
3275
function cssNameFor(key) {
3276
if (key.include('border')) key = key + '-width';
3277
return key.camelize();
3280
Element.Layout = Class.create(Hash, {
3281
initialize: function($super, element, preCompute) {
3283
this.element = $(element);
3285
Element.Layout.PROPERTIES.each( function(property) {
3286
this._set(property, null);
3290
this._preComputing = true;
3292
Element.Layout.PROPERTIES.each( this._compute, this );
3294
this._preComputing = false;
3298
_set: function(property, value) {
3299
return Hash.prototype.set.call(this, property, value);
3302
set: function(property, value) {
3303
throw "Properties of Element.Layout are read-only.";
3306
get: function($super, property) {
3307
var value = $super(property);
3308
return value === null ? this._compute(property) : value;
3311
_begin: function() {
3312
if (this._prepared) return;
3314
var element = this.element;
3315
if (isDisplayed(element)) {
3316
this._prepared = true;
3320
var originalStyles = {
3321
position: element.style.position || '',
3322
width: element.style.width || '',
3323
visibility: element.style.visibility || '',
3324
display: element.style.display || ''
3327
element.store('prototype_original_styles', originalStyles);
3329
var position = element.getStyle('position'),
3330
width = element.getStyle('width');
3332
if (width === "0px" || width === null) {
3333
element.style.display = 'block';
3334
width = element.getStyle('width');
3337
var context = (position === 'fixed') ? document.viewport :
3341
position: 'absolute',
3342
visibility: 'hidden',
3200
// handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
3201
nth: function(nodes, formula, root, reverse, ofType) {
3202
if (nodes.length == 0) return [];
3203
if (formula == 'even') formula = '2n+0';
3204
if (formula == 'odd') formula = '2n+1';
3205
var h = Selector.handlers, results = [], indexed = [], m;
3207
for (var i = 0, node; node = nodes[i]; i++) {
3208
if (!node.parentNode._counted) {
3209
h.index(node.parentNode, reverse, ofType);
3210
indexed.push(node.parentNode);
3213
if (formula.match(/^\d+$/)) { // just a number
3214
formula = Number(formula);
3215
for (var i = 0, node; node = nodes[i]; i++)
3216
if (node.nodeIndex == formula) results.push(node);
3217
} else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3218
if (m[1] == "-") m[1] = -1;
3219
var a = m[1] ? Number(m[1]) : 1;
3220
var b = m[2] ? Number(m[2]) : 0;
3221
var indices = Selector.pseudos.getIndices(a, b, nodes.length);
3222
for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
3223
for (var j = 0; j < l; j++)
3224
if (node.nodeIndex == indices[j]) results.push(node);
3232
'empty': function(nodes, value, root) {
3233
for (var i = 0, results = [], node; node = nodes[i]; i++) {
3234
// IE treats comments as element nodes
3235
if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
3241
'not': function(nodes, selector, root) {
3242
var h = Selector.handlers, selectorType, m;
3243
var exclusions = new Selector(selector).findElements(root);
3245
for (var i = 0, results = [], node; node = nodes[i]; i++)
3246
if (!node._counted) results.push(node);
3247
h.unmark(exclusions);
3251
'enabled': function(nodes, value, root) {
3252
for (var i = 0, results = [], node; node = nodes[i]; i++)
3253
if (!node.disabled) results.push(node);
3257
'disabled': function(nodes, value, root) {
3258
for (var i = 0, results = [], node; node = nodes[i]; i++)
3259
if (node.disabled) results.push(node);
3263
'checked': function(nodes, value, root) {
3264
for (var i = 0, results = [], node; node = nodes[i]; i++)
3265
if (node.checked) results.push(node);
3271
'=': function(nv, v) { return nv == v; },
3272
'!=': function(nv, v) { return nv != v; },
3273
'^=': function(nv, v) { return nv.startsWith(v); },
3274
'$=': function(nv, v) { return nv.endsWith(v); },
3275
'*=': function(nv, v) { return nv.include(v); },
3276
'~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
3277
'|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
3280
matchElements: function(elements, expression) {
3281
var matches = new Selector(expression).findElements(), h = Selector.handlers;
3283
for (var i = 0, results = [], element; element = elements[i]; i++)
3284
if (element._counted) results.push(element);
3289
findElement: function(elements, expression, index) {
3290
if (Object.isNumber(expression)) {
3291
index = expression; expression = false;
3293
return Selector.matchElements(elements, expression || '*')[index || 0];
3296
findChildElements: function(element, expressions) {
3297
var exprs = expressions.join(',');
3299
exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
3300
expressions.push(m[1].strip());
3302
var results = [], h = Selector.handlers;
3303
for (var i = 0, l = expressions.length, selector; i < l; i++) {
3304
selector = new Selector(expressions[i].strip());
3305
h.concat(results, selector.findElements(element));
3307
return (l > 1) ? h.unique(results) : results;
3311
if (Prototype.Browser.IE) {
3312
// IE returns comment nodes on getElementsByTagName("*").
3314
Selector.handlers.concat = function(a, b) {
3315
for (var i = 0, node; node = b[i]; i++)
3316
if (node.tagName !== "!") a.push(node);
3346
var positionedWidth = element.getStyle('width');
3349
if (width && (positionedWidth === width)) {
3350
newWidth = getPixelValue(element, 'width', context);
3351
} else if (position === 'absolute' || position === 'fixed') {
3352
newWidth = getPixelValue(element, 'width', context);
3354
var parent = element.parentNode, pLayout = $(parent).getLayout();
3356
newWidth = pLayout.get('width') -
3357
this.get('margin-left') -
3358
this.get('border-left') -
3359
this.get('padding-left') -
3360
this.get('padding-right') -
3361
this.get('border-right') -
3362
this.get('margin-right');
3365
element.setStyle({ width: newWidth + 'px' });
3367
this._prepared = true;
3371
var element = this.element;
3372
var originalStyles = element.retrieve('prototype_original_styles');
3373
element.store('prototype_original_styles', null);
3374
element.setStyle(originalStyles);
3375
this._prepared = false;
3378
_compute: function(property) {
3379
var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3380
if (!(property in COMPUTATIONS)) {
3381
throw "Property not found.";
3384
return this._set(property, COMPUTATIONS[property].call(this, this.element));
3387
toObject: function() {
3388
var args = $A(arguments);
3389
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3390
args.join(' ').split(' ');
3392
keys.each( function(key) {
3393
if (!Element.Layout.PROPERTIES.include(key)) return;
3394
var value = this.get(key);
3395
if (value != null) obj[key] = value;
3400
toHash: function() {
3401
var obj = this.toObject.apply(this, arguments);
3402
return new Hash(obj);
3406
var args = $A(arguments);
3407
var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3408
args.join(' ').split(' ');
3411
keys.each( function(key) {
3412
if (!Element.Layout.PROPERTIES.include(key)) return;
3413
if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3415
var value = this.get(key);
3416
if (value != null) css[cssNameFor(key)] = value + 'px';
3421
inspect: function() {
3422
return "#<Element.Layout>";
3426
Object.extend(Element.Layout, {
3427
PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3429
COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3432
'height': function(element) {
3433
if (!this._preComputing) this._begin();
3435
var bHeight = this.get('border-box-height');
3437
if (!this._preComputing) this._end();
3441
var bTop = this.get('border-top'),
3442
bBottom = this.get('border-bottom');
3444
var pTop = this.get('padding-top'),
3445
pBottom = this.get('padding-bottom');
3447
if (!this._preComputing) this._end();
3449
return bHeight - bTop - bBottom - pTop - pBottom;
3452
'width': function(element) {
3453
if (!this._preComputing) this._begin();
3455
var bWidth = this.get('border-box-width');
3457
if (!this._preComputing) this._end();
3461
var bLeft = this.get('border-left'),
3462
bRight = this.get('border-right');
3464
var pLeft = this.get('padding-left'),
3465
pRight = this.get('padding-right');
3467
if (!this._preComputing) this._end();
3469
return bWidth - bLeft - bRight - pLeft - pRight;
3472
'padding-box-height': function(element) {
3473
var height = this.get('height'),
3474
pTop = this.get('padding-top'),
3475
pBottom = this.get('padding-bottom');
3477
return height + pTop + pBottom;
3480
'padding-box-width': function(element) {
3481
var width = this.get('width'),
3482
pLeft = this.get('padding-left'),
3483
pRight = this.get('padding-right');
3485
return width + pLeft + pRight;
3488
'border-box-height': function(element) {
3489
if (!this._preComputing) this._begin();
3490
var height = element.offsetHeight;
3491
if (!this._preComputing) this._end();
3495
'border-box-width': function(element) {
3496
if (!this._preComputing) this._begin();
3497
var width = element.offsetWidth;
3498
if (!this._preComputing) this._end();
3502
'margin-box-height': function(element) {
3503
var bHeight = this.get('border-box-height'),
3504
mTop = this.get('margin-top'),
3505
mBottom = this.get('margin-bottom');
3507
if (bHeight <= 0) return 0;
3509
return bHeight + mTop + mBottom;
3512
'margin-box-width': function(element) {
3513
var bWidth = this.get('border-box-width'),
3514
mLeft = this.get('margin-left'),
3515
mRight = this.get('margin-right');
3517
if (bWidth <= 0) return 0;
3519
return bWidth + mLeft + mRight;
3522
'top': function(element) {
3523
var offset = element.positionedOffset();
3527
'bottom': function(element) {
3528
var offset = element.positionedOffset(),
3529
parent = element.getOffsetParent(),
3530
pHeight = parent.measure('height');
3532
var mHeight = this.get('border-box-height');
3534
return pHeight - mHeight - offset.top;
3537
'left': function(element) {
3538
var offset = element.positionedOffset();
3542
'right': function(element) {
3543
var offset = element.positionedOffset(),
3544
parent = element.getOffsetParent(),
3545
pWidth = parent.measure('width');
3547
var mWidth = this.get('border-box-width');
3549
return pWidth - mWidth - offset.left;
3552
'padding-top': function(element) {
3553
return getPixelValue(element, 'paddingTop');
3556
'padding-bottom': function(element) {
3557
return getPixelValue(element, 'paddingBottom');
3560
'padding-left': function(element) {
3561
return getPixelValue(element, 'paddingLeft');
3564
'padding-right': function(element) {
3565
return getPixelValue(element, 'paddingRight');
3568
'border-top': function(element) {
3569
return getPixelValue(element, 'borderTopWidth');
3572
'border-bottom': function(element) {
3573
return getPixelValue(element, 'borderBottomWidth');
3576
'border-left': function(element) {
3577
return getPixelValue(element, 'borderLeftWidth');
3580
'border-right': function(element) {
3581
return getPixelValue(element, 'borderRightWidth');
3584
'margin-top': function(element) {
3585
return getPixelValue(element, 'marginTop');
3588
'margin-bottom': function(element) {
3589
return getPixelValue(element, 'marginBottom');
3592
'margin-left': function(element) {
3593
return getPixelValue(element, 'marginLeft');
3596
'margin-right': function(element) {
3597
return getPixelValue(element, 'marginRight');
3602
if ('getBoundingClientRect' in document.documentElement) {
3603
Object.extend(Element.Layout.COMPUTATIONS, {
3604
'right': function(element) {
3605
var parent = hasLayout(element.getOffsetParent());
3606
var rect = element.getBoundingClientRect(),
3607
pRect = parent.getBoundingClientRect();
3609
return (pRect.right - rect.right).round();
3612
'bottom': function(element) {
3613
var parent = hasLayout(element.getOffsetParent());
3614
var rect = element.getBoundingClientRect(),
3615
pRect = parent.getBoundingClientRect();
3617
return (pRect.bottom - rect.bottom).round();
3622
Element.Offset = Class.create({
3623
initialize: function(left, top) {
3624
this.left = left.round();
3625
this.top = top.round();
3627
this[0] = this.left;
3631
relativeTo: function(offset) {
3632
return new Element.Offset(
3633
this.left - offset.left,
3634
this.top - offset.top
3638
inspect: function() {
3639
return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3642
toString: function() {
3643
return "[#{left}, #{top}]".interpolate(this);
3646
toArray: function() {
3647
return [this.left, this.top];
3651
function getLayout(element, preCompute) {
3652
return new Element.Layout(element, preCompute);
3655
function measure(element, property) {
3656
return $(element).getLayout().get(property);
3659
function getDimensions(element) {
3660
element = $(element);
3661
var display = Element.getStyle(element, 'display');
3663
if (display && display !== 'none') {
3664
return { width: element.offsetWidth, height: element.offsetHeight };
3667
var style = element.style;
3668
var originalStyles = {
3669
visibility: style.visibility,
3670
position: style.position,
3671
display: style.display
3675
visibility: 'hidden',
3679
if (originalStyles.position !== 'fixed')
3680
newStyles.position = 'absolute';
3682
Element.setStyle(element, newStyles);
3685
width: element.offsetWidth,
3686
height: element.offsetHeight
3689
Element.setStyle(element, originalStyles);
3694
function getOffsetParent(element) {
3695
element = $(element);
3697
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3698
return $(document.body);
3700
var isInline = (Element.getStyle(element, 'display') === 'inline');
3701
if (!isInline && element.offsetParent) return $(element.offsetParent);
3703
while ((element = element.parentNode) && element !== document.body) {
3704
if (Element.getStyle(element, 'position') !== 'static') {
3705
return isHtml(element) ? $(document.body) : $(element);
3709
return $(document.body);
3713
function cumulativeOffset(element) {
3714
element = $(element);
3715
var valueT = 0, valueL = 0;
3716
if (element.parentNode) {
3718
valueT += element.offsetTop || 0;
3719
valueL += element.offsetLeft || 0;
3720
element = element.offsetParent;
3723
return new Element.Offset(valueL, valueT);
3726
function positionedOffset(element) {
3727
element = $(element);
3729
var layout = element.getLayout();
3731
var valueT = 0, valueL = 0;
3733
valueT += element.offsetTop || 0;
3734
valueL += element.offsetLeft || 0;
3735
element = element.offsetParent;
3737
if (isBody(element)) break;
3738
var p = Element.getStyle(element, 'position');
3739
if (p !== 'static') break;
3743
valueL -= layout.get('margin-top');
3744
valueT -= layout.get('margin-left');
3746
return new Element.Offset(valueL, valueT);
3749
function cumulativeScrollOffset(element) {
3750
var valueT = 0, valueL = 0;
3752
valueT += element.scrollTop || 0;
3753
valueL += element.scrollLeft || 0;
3754
element = element.parentNode;
3756
return new Element.Offset(valueL, valueT);
3759
function viewportOffset(forElement) {
3760
element = $(element);
3761
var valueT = 0, valueL = 0, docBody = document.body;
3763
var element = forElement;
3765
valueT += element.offsetTop || 0;
3766
valueL += element.offsetLeft || 0;
3767
if (element.offsetParent == docBody &&
3768
Element.getStyle(element, 'position') == 'absolute') break;
3769
} while (element = element.offsetParent);
3771
element = forElement;
3773
if (element != docBody) {
3774
valueT -= element.scrollTop || 0;
3775
valueL -= element.scrollLeft || 0;
3777
} while (element = element.parentNode);
3778
return new Element.Offset(valueL, valueT);
3781
function absolutize(element) {
3782
element = $(element);
3784
if (Element.getStyle(element, 'position') === 'absolute') {
3788
var offsetParent = getOffsetParent(element);
3789
var eOffset = element.viewportOffset(),
3790
pOffset = offsetParent.viewportOffset();
3792
var offset = eOffset.relativeTo(pOffset);
3793
var layout = element.getLayout();
3795
element.store('prototype_absolutize_original_styles', {
3796
left: element.getStyle('left'),
3797
top: element.getStyle('top'),
3798
width: element.getStyle('width'),
3799
height: element.getStyle('height')
3803
position: 'absolute',
3804
top: offset.top + 'px',
3805
left: offset.left + 'px',
3806
width: layout.get('width') + 'px',
3807
height: layout.get('height') + 'px'
3813
function relativize(element) {
3814
element = $(element);
3815
if (Element.getStyle(element, 'position') === 'relative') {
3819
var originalStyles =
3820
element.retrieve('prototype_absolutize_original_styles');
3822
if (originalStyles) element.setStyle(originalStyles);
3826
if (Prototype.Browser.IE) {
3827
getOffsetParent = getOffsetParent.wrap(
3828
function(proceed, element) {
3829
element = $(element);
3831
if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(element))
3832
return $(document.body);
3834
var position = element.getStyle('position');
3835
if (position !== 'static') return proceed(element);
3837
element.setStyle({ position: 'relative' });
3838
var value = proceed(element);
3839
element.setStyle({ position: position });
3844
positionedOffset = positionedOffset.wrap(function(proceed, element) {
3845
element = $(element);
3846
if (!element.parentNode) return new Element.Offset(0, 0);
3847
var position = element.getStyle('position');
3848
if (position !== 'static') return proceed(element);
3850
var offsetParent = element.getOffsetParent();
3851
if (offsetParent && offsetParent.getStyle('position') === 'fixed')
3852
hasLayout(offsetParent);
3854
element.setStyle({ position: 'relative' });
3855
var value = proceed(element);
3856
element.setStyle({ position: position });
3859
} else if (Prototype.Browser.Webkit) {
3860
cumulativeOffset = function(element) {
3861
element = $(element);
3862
var valueT = 0, valueL = 0;
3864
valueT += element.offsetTop || 0;
3865
valueL += element.offsetLeft || 0;
3866
if (element.offsetParent == document.body)
3867
if (Element.getStyle(element, 'position') == 'absolute') break;
3869
element = element.offsetParent;
3872
return new Element.Offset(valueL, valueT);
3877
Element.addMethods({
3878
getLayout: getLayout,
3880
getDimensions: getDimensions,
3881
getOffsetParent: getOffsetParent,
3882
cumulativeOffset: cumulativeOffset,
3883
positionedOffset: positionedOffset,
3884
cumulativeScrollOffset: cumulativeScrollOffset,
3885
viewportOffset: viewportOffset,
3886
absolutize: absolutize,
3887
relativize: relativize
3890
function isBody(element) {
3891
return element.nodeName.toUpperCase() === 'BODY';
3894
function isHtml(element) {
3895
return element.nodeName.toUpperCase() === 'HTML';
3898
function isDocument(element) {
3899
return element.nodeType === Node.DOCUMENT_NODE;
3902
function isDetached(element) {
3903
return element !== document.body &&
3904
!Element.descendantOf(element, document.body);
3907
if ('getBoundingClientRect' in document.documentElement) {
3908
Element.addMethods({
3909
viewportOffset: function(element) {
3910
element = $(element);
3911
if (isDetached(element)) return new Element.Offset(0, 0);
3913
var rect = element.getBoundingClientRect(),
3914
docEl = document.documentElement;
3915
return new Element.Offset(rect.left - docEl.clientLeft,
3916
rect.top - docEl.clientTop);
3921
window.$$ = function() {
3922
var expression = $A(arguments).join(', ');
3923
return Prototype.Selector.select(expression, document);
3926
Prototype.Selector = (function() {
3929
throw new Error('Method "Prototype.Selector.select" must be defined.');
3933
throw new Error('Method "Prototype.Selector.match" must be defined.');
3936
function find(elements, expression, index) {
3938
var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
3940
for (i = 0; i < length; i++) {
3941
if (match(elements[i], expression) && index == matchIndex++) {
3942
return Element.extend(elements[i]);
3947
function extendElements(elements) {
3948
for (var i = 0, length = elements.length; i < length; i++) {
3949
Element.extend(elements[i]);
3955
var K = Prototype.K;
3961
extendElements: (Element.extend === K) ? K : extendElements,
3962
extendElement: Element.extend
3322
return Selector.findChildElements(document, $A(arguments));
3965
Prototype._original_property = window.Sizzle;
3967
* Sizzle CSS Selector Engine - v1.0
3968
* Copyright 2009, The Dojo Foundation
3969
* Released under the MIT, BSD, and GPL Licenses.
3970
* More information: http://sizzlejs.com/
3974
var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3976
toString = Object.prototype.toString,
3977
hasDuplicate = false,
3978
baseHasDuplicate = true;
3980
[0, 0].sort(function(){
3981
baseHasDuplicate = false;
3985
var Sizzle = function(selector, context, results, seed) {
3986
results = results || [];
3987
var origContext = context = context || document;
3989
if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3993
if ( !selector || typeof selector !== "string" ) {
3997
var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
4000
while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
4011
if ( parts.length > 1 && origPOS.exec( selector ) ) {
4012
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4013
set = posProcess( parts[0] + parts[1], context );
4015
set = Expr.relative[ parts[0] ] ?
4017
Sizzle( parts.shift(), context );
4019
while ( parts.length ) {
4020
selector = parts.shift();
4022
if ( Expr.relative[ selector ] )
4023
selector += parts.shift();
4025
set = posProcess( selector, set );
4029
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4030
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4031
var ret = Sizzle.find( parts.shift(), context, contextXML );
4032
context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
4037
{ expr: parts.pop(), set: makeArray(seed) } :
4038
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4039
set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
4041
if ( parts.length > 0 ) {
4042
checkSet = makeArray(set);
4047
while ( parts.length ) {
4048
var cur = parts.pop(), pop = cur;
4050
if ( !Expr.relative[ cur ] ) {
4056
if ( pop == null ) {
4060
Expr.relative[ cur ]( checkSet, pop, contextXML );
4063
checkSet = parts = [];
4072
throw "Syntax error, unrecognized expression: " + (cur || selector);
4075
if ( toString.call(checkSet) === "[object Array]" ) {
4077
results.push.apply( results, checkSet );
4078
} else if ( context && context.nodeType === 1 ) {
4079
for ( var i = 0; checkSet[i] != null; i++ ) {
4080
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4081
results.push( set[i] );
4085
for ( var i = 0; checkSet[i] != null; i++ ) {
4086
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4087
results.push( set[i] );
4092
makeArray( checkSet, results );
4096
Sizzle( extra, origContext, results, seed );
4097
Sizzle.uniqueSort( results );
4103
Sizzle.uniqueSort = function(results){
4105
hasDuplicate = baseHasDuplicate;
4106
results.sort(sortOrder);
4108
if ( hasDuplicate ) {
4109
for ( var i = 1; i < results.length; i++ ) {
4110
if ( results[i] === results[i-1] ) {
4111
results.splice(i--, 1);
4120
Sizzle.matches = function(expr, set){
4121
return Sizzle(expr, null, null, set);
4124
Sizzle.find = function(expr, context, isXML){
4131
for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4132
var type = Expr.order[i], match;
4134
if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4135
var left = match[1];
4138
if ( left.substr( left.length - 1 ) !== "\\" ) {
4139
match[1] = (match[1] || "").replace(/\\/g, "");
4140
set = Expr.find[ type ]( match, context, isXML );
4141
if ( set != null ) {
4142
expr = expr.replace( Expr.match[ type ], "" );
4150
set = context.getElementsByTagName("*");
4153
return {set: set, expr: expr};
4156
Sizzle.filter = function(expr, set, inplace, not){
4157
var old = expr, result = [], curLoop = set, match, anyFound,
4158
isXMLFilter = set && set[0] && isXML(set[0]);
4160
while ( expr && set.length ) {
4161
for ( var type in Expr.filter ) {
4162
if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4163
var filter = Expr.filter[ type ], found, item;
4166
if ( curLoop == result ) {
4170
if ( Expr.preFilter[ type ] ) {
4171
match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4174
anyFound = found = true;
4175
} else if ( match === true ) {
4181
for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4183
found = filter( item, match, i, curLoop );
4184
var pass = not ^ !!found;
4186
if ( inplace && found != null ) {
4192
} else if ( pass ) {
4193
result.push( item );
4200
if ( found !== undefined ) {
4205
expr = expr.replace( Expr.match[ type ], "" );
4216
if ( expr == old ) {
4217
if ( anyFound == null ) {
4218
throw "Syntax error, unrecognized expression: " + expr;
4230
var Expr = Sizzle.selectors = {
4231
order: [ "ID", "NAME", "TAG" ],
4233
ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4234
CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4235
NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
4236
ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
4237
TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4238
CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4239
POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4240
PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
4244
"class": "className",
4248
href: function(elem){
4249
return elem.getAttribute("href");
4253
"+": function(checkSet, part, isXML){
4254
var isPartStr = typeof part === "string",
4255
isTag = isPartStr && !/\W/.test(part),
4256
isPartStrNotTag = isPartStr && !isTag;
4258
if ( isTag && !isXML ) {
4259
part = part.toUpperCase();
4262
for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4263
if ( (elem = checkSet[i]) ) {
4264
while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4266
checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
4272
if ( isPartStrNotTag ) {
4273
Sizzle.filter( part, checkSet, true );
4276
">": function(checkSet, part, isXML){
4277
var isPartStr = typeof part === "string";
4279
if ( isPartStr && !/\W/.test(part) ) {
4280
part = isXML ? part : part.toUpperCase();
4282
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4283
var elem = checkSet[i];
4285
var parent = elem.parentNode;
4286
checkSet[i] = parent.nodeName === part ? parent : false;
4290
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4291
var elem = checkSet[i];
4293
checkSet[i] = isPartStr ?
4295
elem.parentNode === part;
4300
Sizzle.filter( part, checkSet, true );
4304
"": function(checkSet, part, isXML){
4305
var doneName = done++, checkFn = dirCheck;
4307
if ( !/\W/.test(part) ) {
4308
var nodeCheck = part = isXML ? part : part.toUpperCase();
4309
checkFn = dirNodeCheck;
4312
checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
4314
"~": function(checkSet, part, isXML){
4315
var doneName = done++, checkFn = dirCheck;
4317
if ( typeof part === "string" && !/\W/.test(part) ) {
4318
var nodeCheck = part = isXML ? part : part.toUpperCase();
4319
checkFn = dirNodeCheck;
4322
checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
4326
ID: function(match, context, isXML){
4327
if ( typeof context.getElementById !== "undefined" && !isXML ) {
4328
var m = context.getElementById(match[1]);
4329
return m ? [m] : [];
4332
NAME: function(match, context, isXML){
4333
if ( typeof context.getElementsByName !== "undefined" ) {
4334
var ret = [], results = context.getElementsByName(match[1]);
4336
for ( var i = 0, l = results.length; i < l; i++ ) {
4337
if ( results[i].getAttribute("name") === match[1] ) {
4338
ret.push( results[i] );
4342
return ret.length === 0 ? null : ret;
4345
TAG: function(match, context){
4346
return context.getElementsByTagName(match[1]);
4350
CLASS: function(match, curLoop, inplace, result, not, isXML){
4351
match = " " + match[1].replace(/\\/g, "") + " ";
4357
for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4359
if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
4361
result.push( elem );
4362
} else if ( inplace ) {
4370
ID: function(match){
4371
return match[1].replace(/\\/g, "");
4373
TAG: function(match, curLoop){
4374
for ( var i = 0; curLoop[i] === false; i++ ){}
4375
return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
4377
CHILD: function(match){
4378
if ( match[1] == "nth" ) {
4379
var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4380
match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
4381
!/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4383
match[2] = (test[1] + (test[2] || 1)) - 0;
4384
match[3] = test[3] - 0;
4391
ATTR: function(match, curLoop, inplace, result, not, isXML){
4392
var name = match[1].replace(/\\/g, "");
4394
if ( !isXML && Expr.attrMap[name] ) {
4395
match[1] = Expr.attrMap[name];
4398
if ( match[2] === "~=" ) {
4399
match[4] = " " + match[4] + " ";
4404
PSEUDO: function(match, curLoop, inplace, result, not){
4405
if ( match[1] === "not" ) {
4406
if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4407
match[3] = Sizzle(match[3], null, null, curLoop);
4409
var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4411
result.push.apply( result, ret );
4415
} else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4421
POS: function(match){
4422
match.unshift( true );
4427
enabled: function(elem){
4428
return elem.disabled === false && elem.type !== "hidden";
4430
disabled: function(elem){
4431
return elem.disabled === true;
4433
checked: function(elem){
4434
return elem.checked === true;
4436
selected: function(elem){
4437
elem.parentNode.selectedIndex;
4438
return elem.selected === true;
4440
parent: function(elem){
4441
return !!elem.firstChild;
4443
empty: function(elem){
4444
return !elem.firstChild;
4446
has: function(elem, i, match){
4447
return !!Sizzle( match[3], elem ).length;
4449
header: function(elem){
4450
return /h\d/i.test( elem.nodeName );
4452
text: function(elem){
4453
return "text" === elem.type;
4455
radio: function(elem){
4456
return "radio" === elem.type;
4458
checkbox: function(elem){
4459
return "checkbox" === elem.type;
4461
file: function(elem){
4462
return "file" === elem.type;
4464
password: function(elem){
4465
return "password" === elem.type;
4467
submit: function(elem){
4468
return "submit" === elem.type;
4470
image: function(elem){
4471
return "image" === elem.type;
4473
reset: function(elem){
4474
return "reset" === elem.type;
4476
button: function(elem){
4477
return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
4479
input: function(elem){
4480
return /input|select|textarea|button/i.test(elem.nodeName);
4484
first: function(elem, i){
4487
last: function(elem, i, match, array){
4488
return i === array.length - 1;
4490
even: function(elem, i){
4493
odd: function(elem, i){
4496
lt: function(elem, i, match){
4497
return i < match[3] - 0;
4499
gt: function(elem, i, match){
4500
return i > match[3] - 0;
4502
nth: function(elem, i, match){
4503
return match[3] - 0 == i;
4505
eq: function(elem, i, match){
4506
return match[3] - 0 == i;
4510
PSEUDO: function(elem, match, i, array){
4511
var name = match[1], filter = Expr.filters[ name ];
4514
return filter( elem, i, match, array );
4515
} else if ( name === "contains" ) {
4516
return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
4517
} else if ( name === "not" ) {
4520
for ( var i = 0, l = not.length; i < l; i++ ) {
4521
if ( not[i] === elem ) {
4529
CHILD: function(elem, match){
4530
var type = match[1], node = elem;
4534
while ( (node = node.previousSibling) ) {
4535
if ( node.nodeType === 1 ) return false;
4537
if ( type == 'first') return true;
4540
while ( (node = node.nextSibling) ) {
4541
if ( node.nodeType === 1 ) return false;
4545
var first = match[2], last = match[3];
4547
if ( first == 1 && last == 0 ) {
4551
var doneName = match[0],
4552
parent = elem.parentNode;
4554
if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4556
for ( node = parent.firstChild; node; node = node.nextSibling ) {
4557
if ( node.nodeType === 1 ) {
4558
node.nodeIndex = ++count;
4561
parent.sizcache = doneName;
4564
var diff = elem.nodeIndex - last;
4568
return ( diff % first == 0 && diff / first >= 0 );
4572
ID: function(elem, match){
4573
return elem.nodeType === 1 && elem.getAttribute("id") === match;
4575
TAG: function(elem, match){
4576
return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
4578
CLASS: function(elem, match){
4579
return (" " + (elem.className || elem.getAttribute("class")) + " ")
4580
.indexOf( match ) > -1;
4582
ATTR: function(elem, match){
4583
var name = match[1],
4584
result = Expr.attrHandle[ name ] ?
4585
Expr.attrHandle[ name ]( elem ) :
4586
elem[ name ] != null ?
4588
elem.getAttribute( name ),
4589
value = result + "",
4593
return result == null ?
4598
value.indexOf(check) >= 0 :
4600
(" " + value + " ").indexOf(check) >= 0 :
4602
value && result !== false :
4606
value.indexOf(check) === 0 :
4608
value.substr(value.length - check.length) === check :
4610
value === check || value.substr(0, check.length + 1) === check + "-" :
4613
POS: function(elem, match, i, array){
4614
var name = match[2], filter = Expr.setFilters[ name ];
4617
return filter( elem, i, match, array );
4623
var origPOS = Expr.match.POS;
4625
for ( var type in Expr.match ) {
4626
Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
4627
Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
4630
var makeArray = function(array, results) {
4631
array = Array.prototype.slice.call( array, 0 );
4634
results.push.apply( results, array );
4642
Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4645
makeArray = function(array, results) {
4646
var ret = results || [];
4648
if ( toString.call(array) === "[object Array]" ) {
4649
Array.prototype.push.apply( ret, array );
4651
if ( typeof array.length === "number" ) {
4652
for ( var i = 0, l = array.length; i < l; i++ ) {
4653
ret.push( array[i] );
4656
for ( var i = 0; array[i]; i++ ) {
4657
ret.push( array[i] );
4668
if ( document.documentElement.compareDocumentPosition ) {
4669
sortOrder = function( a, b ) {
4670
if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4672
hasDuplicate = true;
4677
var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
4679
hasDuplicate = true;
4683
} else if ( "sourceIndex" in document.documentElement ) {
4684
sortOrder = function( a, b ) {
4685
if ( !a.sourceIndex || !b.sourceIndex ) {
4687
hasDuplicate = true;
4692
var ret = a.sourceIndex - b.sourceIndex;
4694
hasDuplicate = true;
4698
} else if ( document.createRange ) {
4699
sortOrder = function( a, b ) {
4700
if ( !a.ownerDocument || !b.ownerDocument ) {
4702
hasDuplicate = true;
4707
var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
4708
aRange.setStart(a, 0);
4709
aRange.setEnd(a, 0);
4710
bRange.setStart(b, 0);
4711
bRange.setEnd(b, 0);
4712
var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4714
hasDuplicate = true;
4721
var form = document.createElement("div"),
4722
id = "script" + (new Date).getTime();
4723
form.innerHTML = "<a name='" + id + "'/>";
4725
var root = document.documentElement;
4726
root.insertBefore( form, root.firstChild );
4728
if ( !!document.getElementById( id ) ) {
4729
Expr.find.ID = function(match, context, isXML){
4730
if ( typeof context.getElementById !== "undefined" && !isXML ) {
4731
var m = context.getElementById(match[1]);
4732
return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
4736
Expr.filter.ID = function(elem, match){
4737
var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4738
return elem.nodeType === 1 && node && node.nodeValue === match;
4742
root.removeChild( form );
4743
root = form = null; // release memory in IE
4748
var div = document.createElement("div");
4749
div.appendChild( document.createComment("") );
4751
if ( div.getElementsByTagName("*").length > 0 ) {
4752
Expr.find.TAG = function(match, context){
4753
var results = context.getElementsByTagName(match[1]);
4755
if ( match[1] === "*" ) {
4758
for ( var i = 0; results[i]; i++ ) {
4759
if ( results[i].nodeType === 1 ) {
4760
tmp.push( results[i] );
4771
div.innerHTML = "<a href='#'></a>";
4772
if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4773
div.firstChild.getAttribute("href") !== "#" ) {
4774
Expr.attrHandle.href = function(elem){
4775
return elem.getAttribute("href", 2);
4779
div = null; // release memory in IE
4782
if ( document.querySelectorAll ) (function(){
4783
var oldSizzle = Sizzle, div = document.createElement("div");
4784
div.innerHTML = "<p class='TEST'></p>";
4786
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4790
Sizzle = function(query, context, extra, seed){
4791
context = context || document;
4793
if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4795
return makeArray( context.querySelectorAll(query), extra );
4799
return oldSizzle(query, context, extra, seed);
4802
for ( var prop in oldSizzle ) {
4803
Sizzle[ prop ] = oldSizzle[ prop ];
4806
div = null; // release memory in IE
4809
if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
4810
var div = document.createElement("div");
4811
div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4813
if ( div.getElementsByClassName("e").length === 0 )
4816
div.lastChild.className = "e";
4818
if ( div.getElementsByClassName("e").length === 1 )
4821
Expr.order.splice(1, 0, "CLASS");
4822
Expr.find.CLASS = function(match, context, isXML) {
4823
if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4824
return context.getElementsByClassName(match[1]);
4828
div = null; // release memory in IE
4831
function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4832
var sibDir = dir == "previousSibling" && !isXML;
4833
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4834
var elem = checkSet[i];
4836
if ( sibDir && elem.nodeType === 1 ){
4837
elem.sizcache = doneName;
4844
if ( elem.sizcache === doneName ) {
4845
match = checkSet[elem.sizset];
4849
if ( elem.nodeType === 1 && !isXML ){
4850
elem.sizcache = doneName;
4854
if ( elem.nodeName === cur ) {
4862
checkSet[i] = match;
4867
function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4868
var sibDir = dir == "previousSibling" && !isXML;
4869
for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4870
var elem = checkSet[i];
4872
if ( sibDir && elem.nodeType === 1 ) {
4873
elem.sizcache = doneName;
4880
if ( elem.sizcache === doneName ) {
4881
match = checkSet[elem.sizset];
4885
if ( elem.nodeType === 1 ) {
4887
elem.sizcache = doneName;
4890
if ( typeof cur !== "string" ) {
4891
if ( elem === cur ) {
4896
} else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4905
checkSet[i] = match;
4910
var contains = document.compareDocumentPosition ? function(a, b){
4911
return a.compareDocumentPosition(b) & 16;
4913
return a !== b && (a.contains ? a.contains(b) : true);
4916
var isXML = function(elem){
4917
return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4918
!!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
4921
var posProcess = function(selector, context){
4922
var tmpSet = [], later = "", match,
4923
root = context.nodeType ? [context] : context;
4925
while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4927
selector = selector.replace( Expr.match.PSEUDO, "" );
4930
selector = Expr.relative[selector] ? selector + "*" : selector;
4932
for ( var i = 0, l = root.length; i < l; i++ ) {
4933
Sizzle( selector, root[i], tmpSet );
4936
return Sizzle.filter( later, tmpSet );
4940
window.Sizzle = Sizzle;
4944
;(function(engine) {
4945
var extendElements = Prototype.Selector.extendElements;
4947
function select(selector, scope) {
4948
return extendElements(engine(selector, scope || document));
4951
function match(element, selector) {
4952
return engine.matches(selector, [element]).length == 1;
4955
Prototype.Selector.engine = engine;
4956
Prototype.Selector.select = select;
4957
Prototype.Selector.match = match;
4960
window.Sizzle = Prototype._original_property;
4961
delete Prototype._original_property;
3325
4964
reset: function(form) {
3330
4970
serializeElements: function(elements, options) {
3331
4971
if (typeof options != 'object') options = { hash: !!options };
3332
4972
else if (Object.isUndefined(options.hash)) options.hash = true;
3333
var key, value, submitted = false, submit = options.submit;
3335
var data = elements.inject({ }, function(result, element) {
4973
var key, value, submitted = false, submit = options.submit, accumulator, initial;
4977
accumulator = function(result, key, value) {
4978
if (key in result) {
4979
if (!Object.isArray(result[key])) result[key] = [result[key]];
4980
result[key].push(value);
4981
} else result[key] = value;
4986
accumulator = function(result, key, value) {
4987
return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value);
4991
return elements.inject(initial, function(result, element) {
3336
4992
if (!element.disabled && element.name) {
3337
4993
key = element.name; value = $(element).getValue();
3338
if (value != null && (element.type != 'submit' || (!submitted &&
4994
if (value != null && element.type != 'file' && (element.type != 'submit' || (!submitted &&
3339
4995
submit !== false && (!submit || key == submit) && (submitted = true)))) {
3340
if (key in result) {
3341
// a key is already present; construct an array of values
3342
if (!Object.isArray(result[key])) result[key] = [result[key]];
3343
result[key].push(value);
3345
else result[key] = value;
4996
result = accumulator(result, key, value);
3351
return options.hash ? data : Object.toQueryString(data);
3661
5328
return Form.serialize(this.element);
3664
if (!window.Event) var Event = { };
3666
Object.extend(Event, {
3684
relatedTarget: function(event) {
3686
switch(event.type) {
3687
case 'mouseover': element = event.fromElement; break;
3688
case 'mouseout': element = event.toElement; break;
3689
default: return null;
3691
return Element.extend(element);
3695
Event.Methods = (function() {
3698
if (Prototype.Browser.IE) {
3699
var buttonMap = { 0: 1, 1: 4, 2: 2 };
3700
isButton = function(event, code) {
3701
return event.button == buttonMap[code];
5352
var docEl = document.documentElement;
5353
var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl
5354
&& 'onmouseleave' in docEl;
5358
var isIELegacyEvent = function(event) { return false; };
5360
if (window.attachEvent) {
5361
if (window.addEventListener) {
5362
isIELegacyEvent = function(event) {
5363
return !(event instanceof window.Event);
5366
isIELegacyEvent = function(event) { return true; };
5372
function _isButtonForDOMEvents(event, code) {
5373
return event.which ? (event.which === code + 1) : (event.button === code);
5376
var legacyButtonMap = { 0: 1, 1: 4, 2: 2 };
5377
function _isButtonForLegacyEvents(event, code) {
5378
return event.button === legacyButtonMap[code];
5381
function _isButtonForWebKit(event, code) {
5383
case 0: return event.which == 1 && !event.metaKey;
5384
case 1: return event.which == 2 || (event.which == 1 && event.metaKey);
5385
case 2: return event.which == 3;
5386
default: return false;
5390
if (window.attachEvent) {
5391
if (!window.addEventListener) {
5392
_isButton = _isButtonForLegacyEvents;
5394
_isButton = function(event, code) {
5395
return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) :
5396
_isButtonForDOMEvents(event, code);
3704
5399
} else if (Prototype.Browser.WebKit) {
3705
isButton = function(event, code) {
3707
case 0: return event.which == 1 && !event.metaKey;
3708
case 1: return event.which == 1 && event.metaKey;
3709
default: return false;
5400
_isButton = _isButtonForWebKit;
5402
_isButton = _isButtonForDOMEvents;
5405
function isLeftClick(event) { return _isButton(event, 0) }
5407
function isMiddleClick(event) { return _isButton(event, 1) }
5409
function isRightClick(event) { return _isButton(event, 2) }
5411
function element(event) {
5412
event = Event.extend(event);
5414
var node = event.target, type = event.type,
5415
currentTarget = event.currentTarget;
5417
if (currentTarget && currentTarget.tagName) {
5418
if (type === 'load' || type === 'error' ||
5419
(type === 'click' && currentTarget.tagName.toLowerCase() === 'input'
5420
&& currentTarget.type === 'radio'))
5421
node = currentTarget;
5424
if (node.nodeType == Node.TEXT_NODE)
5425
node = node.parentNode;
5427
return Element.extend(node);
5430
function findElement(event, expression) {
5431
var element = Event.element(event);
5433
if (!expression) return element;
5435
if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
5436
return Element.extend(element);
3714
isButton = function(event, code) {
3715
return event.which ? (event.which === code + 1) : (event.button === code);
3720
isLeftClick: function(event) { return isButton(event, 0) },
3721
isMiddleClick: function(event) { return isButton(event, 1) },
3722
isRightClick: function(event) { return isButton(event, 2) },
3724
element: function(event) {
3725
var node = Event.extend(event).target;
3726
return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
3729
findElement: function(event, expression) {
3730
var element = Event.element(event);
3731
if (!expression) return element;
3732
var elements = [element].concat(element.ancestors());
3733
return Selector.findElement(elements, expression, 0);
3736
pointer: function(event) {
3738
x: event.pageX || (event.clientX +
3739
(document.documentElement.scrollLeft || document.body.scrollLeft)),
3740
y: event.pageY || (event.clientY +
3741
(document.documentElement.scrollTop || document.body.scrollTop))
3745
pointerX: function(event) { return Event.pointer(event).x },
3746
pointerY: function(event) { return Event.pointer(event).y },
3748
stop: function(event) {
3749
Event.extend(event);
3750
event.preventDefault();
3751
event.stopPropagation();
3752
event.stopped = true;
5438
element = element.parentNode;
5442
function pointer(event) {
5443
return { x: pointerX(event), y: pointerY(event) };
5446
function pointerX(event) {
5447
var docElement = document.documentElement,
5448
body = document.body || { scrollLeft: 0 };
5450
return event.pageX || (event.clientX +
5451
(docElement.scrollLeft || body.scrollLeft) -
5452
(docElement.clientLeft || 0));
5455
function pointerY(event) {
5456
var docElement = document.documentElement,
5457
body = document.body || { scrollTop: 0 };
5459
return event.pageY || (event.clientY +
5460
(docElement.scrollTop || body.scrollTop) -
5461
(docElement.clientTop || 0));
5465
function stop(event) {
5466
Event.extend(event);
5467
event.preventDefault();
5468
event.stopPropagation();
5470
event.stopped = true;
5475
isLeftClick: isLeftClick,
5476
isMiddleClick: isMiddleClick,
5477
isRightClick: isRightClick,
5480
findElement: findElement,
3757
Event.extend = (function() {
3758
5489
var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
3759
5490
m[name] = Event.Methods[name].methodize();
3763
if (Prototype.Browser.IE) {
3764
Object.extend(methods, {
5494
if (window.attachEvent) {
5495
function _relatedTarget(event) {
5497
switch (event.type) {
5500
element = event.fromElement;
5504
element = event.toElement;
5509
return Element.extend(element);
5512
var additionalMethods = {
3765
5513
stopPropagation: function() { this.cancelBubble = true },
3766
5514
preventDefault: function() { this.returnValue = false },
3767
inspect: function() { return "[object Event]" }
5515
inspect: function() { return '[object Event]' }
3770
return function(event) {
5518
Event.extend = function(event, element) {
3771
5519
if (!event) return false;
5521
if (!isIELegacyEvent(event)) return event;
3772
5523
if (event._extendedByPrototype) return event;
3774
5524
event._extendedByPrototype = Prototype.emptyFunction;
3775
5526
var pointer = Event.pointer(event);
3776
5528
Object.extend(event, {
3777
target: event.srcElement,
3778
relatedTarget: Event.relatedTarget(event),
5529
target: event.srcElement || element,
5530
relatedTarget: _relatedTarget(event),
3779
5531
pageX: pointer.x,
3780
5532
pageY: pointer.y
3782
return Object.extend(event, methods);
5535
Object.extend(event, methods);
5536
Object.extend(event, additionalMethods);
3786
Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
5541
Event.extend = Prototype.K;
5544
if (window.addEventListener) {
5545
Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents').__proto__;
3787
5546
Object.extend(Event.prototype, methods);
5549
function _createResponder(element, eventName, handler) {
5550
var registry = Element.retrieve(element, 'prototype_event_registry');
5552
if (Object.isUndefined(registry)) {
5553
CACHE.push(element);
5554
registry = Element.retrieve(element, 'prototype_event_registry', $H());
5557
var respondersForEvent = registry.get(eventName);
5558
if (Object.isUndefined(respondersForEvent)) {
5559
respondersForEvent = [];
5560
registry.set(eventName, respondersForEvent);
5563
if (respondersForEvent.pluck('handler').include(handler)) return false;
5566
if (eventName.include(":")) {
5567
responder = function(event) {
5568
if (Object.isUndefined(event.eventName))
5571
if (event.eventName !== eventName)
5574
Event.extend(event, element);
5575
handler.call(element, event);
5578
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED &&
5579
(eventName === "mouseenter" || eventName === "mouseleave")) {
5580
if (eventName === "mouseenter" || eventName === "mouseleave") {
5581
responder = function(event) {
5582
Event.extend(event, element);
5584
var parent = event.relatedTarget;
5585
while (parent && parent !== element) {
5586
try { parent = parent.parentNode; }
5587
catch(e) { parent = element; }
5590
if (parent === element) return;
5592
handler.call(element, event);
5596
responder = function(event) {
5597
Event.extend(event, element);
5598
handler.call(element, event);
5603
responder.handler = handler;
5604
respondersForEvent.push(responder);
5608
function _destroyCache() {
5609
for (var i = 0, length = CACHE.length; i < length; i++) {
5610
Event.stopObserving(CACHE[i]);
5617
if (Prototype.Browser.IE)
5618
window.attachEvent('onunload', _destroyCache);
5620
if (Prototype.Browser.WebKit)
5621
window.addEventListener('unload', Prototype.emptyFunction, false);
5624
var _getDOMEventName = Prototype.K,
5625
translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
5627
if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
5628
_getDOMEventName = function(eventName) {
5629
return (translations[eventName] || eventName);
5633
function observe(element, eventName, handler) {
5634
element = $(element);
5636
var responder = _createResponder(element, eventName, handler);
5638
if (!responder) return element;
5640
if (eventName.include(':')) {
5641
if (element.addEventListener)
5642
element.addEventListener("dataavailable", responder, false);
5644
element.attachEvent("ondataavailable", responder);
5645
element.attachEvent("onlosecapture", responder);
5648
var actualEventName = _getDOMEventName(eventName);
5650
if (element.addEventListener)
5651
element.addEventListener(actualEventName, responder, false);
5653
element.attachEvent("on" + actualEventName, responder);
5659
function stopObserving(element, eventName, handler) {
5660
element = $(element);
5662
var registry = Element.retrieve(element, 'prototype_event_registry');
5663
if (!registry) return element;
5666
registry.each( function(pair) {
5667
var eventName = pair.key;
5668
stopObserving(element, eventName);
5673
var responders = registry.get(eventName);
5674
if (!responders) return element;
5677
responders.each(function(r) {
5678
stopObserving(element, eventName, r.handler);
5683
var i = responders.length, responder;
5685
if (responders[i].handler === handler) {
5686
responder = responders[i];
5690
if (!responder) return element;
5692
if (eventName.include(':')) {
5693
if (element.removeEventListener)
5694
element.removeEventListener("dataavailable", responder, false);
5696
element.detachEvent("ondataavailable", responder);
5697
element.detachEvent("onlosecapture", responder);
5700
var actualEventName = _getDOMEventName(eventName);
5701
if (element.removeEventListener)
5702
element.removeEventListener(actualEventName, responder, false);
5704
element.detachEvent('on' + actualEventName, responder);
5707
registry.set(eventName, responders.without(responder));
5712
function fire(element, eventName, memo, bubble) {
5713
element = $(element);
5715
if (Object.isUndefined(bubble))
5718
if (element == document && document.createEvent && !element.dispatchEvent)
5719
element = document.documentElement;
5722
if (document.createEvent) {
5723
event = document.createEvent('HTMLEvents');
5724
event.initEvent('dataavailable', bubble, true);
5726
event = document.createEventObject();
5727
event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
5730
event.eventName = eventName;
5731
event.memo = memo || { };
5733
if (document.createEvent)
5734
element.dispatchEvent(event);
5736
element.fireEvent(event.eventType, event);
5738
return Event.extend(event);
5741
Event.Handler = Class.create({
5742
initialize: function(element, eventName, selector, callback) {
5743
this.element = $(element);
5744
this.eventName = eventName;
5745
this.selector = selector;
5746
this.callback = callback;
5747
this.handler = this.handleEvent.bind(this);
5751
Event.observe(this.element, this.eventName, this.handler);
5756
Event.stopObserving(this.element, this.eventName, this.handler);
5760
handleEvent: function(event) {
5761
var element = Event.findElement(event, this.selector);
5762
if (element) this.callback.call(this.element, event, element);
5766
function on(element, eventName, selector, callback) {
5767
element = $(element);
5768
if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5769
callback = selector, selector = null;
5772
return new Event.Handler(element, eventName, selector, callback).start();
5775
Object.extend(Event, Event.Methods);
5777
Object.extend(Event, {
5780
stopObserving: stopObserving,
5784
Element.addMethods({
5789
stopObserving: stopObserving,
5794
Object.extend(document, {
5795
fire: fire.methodize(),
5797
observe: observe.methodize(),
5799
stopObserving: stopObserving.methodize(),
5806
if (window.Event) Object.extend(window.Event, Event);
5807
else window.Event = Event;
3792
Object.extend(Event, (function() {
3793
var cache = Event.cache;
3795
function getEventID(element) {
3796
if (element._eventID) return element._eventID;
3797
arguments.callee.id = arguments.callee.id || 1;
3798
return element._eventID = ++arguments.callee.id;
3801
function getDOMEventName(eventName) {
3802
if (eventName && eventName.include(':')) return "dataavailable";
3806
function getCacheForID(id) {
3807
return cache[id] = cache[id] || { };
3810
function getWrappersForEventName(id, eventName) {
3811
var c = getCacheForID(id);
3812
return c[eventName] = c[eventName] || [];
3815
function createWrapper(element, eventName, handler) {
3816
var id = getEventID(element);
3817
var c = getWrappersForEventName(id, eventName);
3818
if (c.pluck("handler").include(handler)) return false;
3820
var wrapper = function(event) {
3821
if (!Event || !Event.extend ||
3822
(event.eventName && event.eventName != eventName))
3825
Event.extend(event);
3826
handler.call(element, event);
3829
wrapper.handler = handler;
3834
function findWrapper(id, eventName, handler) {
3835
var c = getWrappersForEventName(id, eventName);
3836
return c.find(function(wrapper) { return wrapper.handler == handler });
3839
function destroyWrapper(id, eventName, handler) {
3840
var c = getCacheForID(id);
3841
if (!c[eventName]) return false;
3842
c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
3845
function destroyCache() {
3846
for (var id in cache)
3847
for (var eventName in cache[id])
3848
cache[id][eventName] = null;
3851
if (window.attachEvent) {
3852
window.attachEvent("onunload", destroyCache);
3856
observe: function(element, eventName, handler) {
3857
element = $(element);
3858
var name = getDOMEventName(eventName);
3860
var wrapper = createWrapper(element, eventName, handler);
3861
if (!wrapper) return element;
3863
if (element.addEventListener) {
3864
element.addEventListener(name, wrapper, false);
3866
element.attachEvent("on" + name, wrapper);
3872
stopObserving: function(element, eventName, handler) {
3873
element = $(element);
3874
var id = getEventID(element), name = getDOMEventName(eventName);
3876
if (!handler && eventName) {
3877
getWrappersForEventName(id, eventName).each(function(wrapper) {
3878
element.stopObserving(eventName, wrapper.handler);
3882
} else if (!eventName) {
3883
Object.keys(getCacheForID(id)).each(function(eventName) {
3884
element.stopObserving(eventName);
3889
var wrapper = findWrapper(id, eventName, handler);
3890
if (!wrapper) return element;
3892
if (element.removeEventListener) {
3893
element.removeEventListener(name, wrapper, false);
3895
element.detachEvent("on" + name, wrapper);
3898
destroyWrapper(id, eventName, handler);
3903
fire: function(element, eventName, memo) {
3904
element = $(element);
3905
if (element == document && document.createEvent && !element.dispatchEvent)
3906
element = document.documentElement;
3909
if (document.createEvent) {
3910
event = document.createEvent("HTMLEvents");
3911
event.initEvent("dataavailable", true, true);
3913
event = document.createEventObject();
3914
event.eventType = "ondataavailable";
3917
event.eventName = eventName;
3918
event.memo = memo || { };
3920
if (document.createEvent) {
3921
element.dispatchEvent(event);
3923
element.fireEvent(event.eventType, event);
3926
return Event.extend(event);
3931
Object.extend(Event, Event.Methods);
3933
Element.addMethods({
3935
observe: Event.observe,
3936
stopObserving: Event.stopObserving
3939
Object.extend(document, {
3940
fire: Element.Methods.fire.methodize(),
3941
observe: Element.Methods.observe.methodize(),
3942
stopObserving: Element.Methods.stopObserving.methodize(),
3947
5811
/* Support for the DOMContentLoaded event is based on work by Dan Webb,
3948
Matthias Miller, Dean Edwards and John Resig. */
5812
Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */
3952
5816
function fireContentLoadedEvent() {
3953
5817
if (document.loaded) return;
3954
if (timer) window.clearInterval(timer);
3955
document.fire("dom:loaded");
5818
if (timer) window.clearTimeout(timer);
3956
5819
document.loaded = true;
5820
document.fire('dom:loaded');
5823
function checkReadyState() {
5824
if (document.readyState === 'complete') {
5825
document.stopObserving('readystatechange', checkReadyState);
5826
fireContentLoadedEvent();
5830
function pollDoScroll() {
5831
try { document.documentElement.doScroll('left'); }
5833
timer = pollDoScroll.defer();
5836
fireContentLoadedEvent();
3959
5839
if (document.addEventListener) {
3960
if (Prototype.Browser.WebKit) {
3961
timer = window.setInterval(function() {
3962
if (/loaded|complete/.test(document.readyState))
3963
fireContentLoadedEvent();
3966
Event.observe(window, "load", fireContentLoadedEvent);
3969
document.addEventListener("DOMContentLoaded",
3970
fireContentLoadedEvent, false);
5840
document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false);
3974
document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
3975
$("__onDOMContentLoaded").onreadystatechange = function() {
3976
if (this.readyState == "complete") {
3977
this.onreadystatechange = null;
3978
fireContentLoadedEvent();
5842
document.observe('readystatechange', checkReadyState);
5844
timer = pollDoScroll.defer();
5847
Event.observe(window, 'load', fireContentLoadedEvent);
5850
Element.addMethods();
3983
5852
/*------------------------------- DEPRECATED -------------------------------*/
3985
5854
Hash.toQueryString = Object.toQueryString;