OLD | NEW |
1 /* Prototype JavaScript framework, version 1.6.0.3 | 1 /* Prototype JavaScript framework, version 1.7 |
2 * (c) 2005-2008 Sam Stephenson | 2 * (c) 2005-2010 Sam Stephenson |
3 * | 3 * |
4 * Prototype is freely distributable under the terms of an MIT-style license. | 4 * Prototype is freely distributable under the terms of an MIT-style license. |
5 * For details, see the Prototype web site: http://www.prototypejs.org/ | 5 * For details, see the Prototype web site: http://www.prototypejs.org/ |
6 * | 6 * |
7 *--------------------------------------------------------------------------*/ | 7 *--------------------------------------------------------------------------*/ |
8 | 8 |
9 var Prototype = { | 9 var Prototype = { |
10 Version: '1.6.0.3', | |
11 | 10 |
12 Browser: { | 11 Version: '1.7', |
13 IE: !!(window.attachEvent && | 12 |
14 navigator.userAgent.indexOf('Opera') === -1), | 13 Browser: (function(){ |
15 Opera: navigator.userAgent.indexOf('Opera') > -1, | 14 var ua = navigator.userAgent; |
16 WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1, | 15 var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera
]'; |
17 Gecko: navigator.userAgent.indexOf('Gecko') > -1 && | 16 return { |
18 navigator.userAgent.indexOf('KHTML') === -1, | 17 IE: !!window.attachEvent && !isOpera, |
19 MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/) | 18 Opera: isOpera, |
20 }, | 19 WebKit: ua.indexOf('AppleWebKit/') > -1, |
| 20 Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1, |
| 21 MobileSafari: /Apple.*Mobile/.test(ua) |
| 22 } |
| 23 })(), |
21 | 24 |
22 BrowserFeatures: { | 25 BrowserFeatures: { |
23 XPath: !!document.evaluate, | 26 XPath: !!document.evaluate, |
| 27 |
24 SelectorsAPI: !!document.querySelector, | 28 SelectorsAPI: !!document.querySelector, |
25 ElementExtensions: !!window.HTMLElement, | 29 |
26 SpecificElementExtensions: | 30 ElementExtensions: (function() { |
27 document.createElement('div')['__proto__'] && | 31 var constructor = window.Element || window.HTMLElement; |
28 document.createElement('div')['__proto__'] !== | 32 return !!(constructor && constructor.prototype); |
29 document.createElement('form')['__proto__'] | 33 })(), |
| 34 SpecificElementExtensions: (function() { |
| 35 if (typeof window.HTMLDivElement !== 'undefined') |
| 36 return true; |
| 37 |
| 38 var div = document.createElement('div'), |
| 39 form = document.createElement('form'), |
| 40 isSupported = false; |
| 41 |
| 42 if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) { |
| 43 isSupported = true; |
| 44 } |
| 45 |
| 46 div = form = null; |
| 47 |
| 48 return isSupported; |
| 49 })() |
30 }, | 50 }, |
31 | 51 |
32 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', | 52 ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>', |
33 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, | 53 JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, |
34 | 54 |
35 emptyFunction: function() { }, | 55 emptyFunction: function() { }, |
| 56 |
36 K: function(x) { return x } | 57 K: function(x) { return x } |
37 }; | 58 }; |
38 | 59 |
39 if (Prototype.Browser.MobileSafari) | 60 if (Prototype.Browser.MobileSafari) |
40 Prototype.BrowserFeatures.SpecificElementExtensions = false; | 61 Prototype.BrowserFeatures.SpecificElementExtensions = false; |
41 | 62 |
42 | 63 |
| 64 var Abstract = { }; |
| 65 |
| 66 |
| 67 var Try = { |
| 68 these: function() { |
| 69 var returnValue; |
| 70 |
| 71 for (var i = 0, length = arguments.length; i < length; i++) { |
| 72 var lambda = arguments[i]; |
| 73 try { |
| 74 returnValue = lambda(); |
| 75 break; |
| 76 } catch (e) { } |
| 77 } |
| 78 |
| 79 return returnValue; |
| 80 } |
| 81 }; |
| 82 |
43 /* Based on Alex Arnell's inheritance implementation. */ | 83 /* Based on Alex Arnell's inheritance implementation. */ |
44 var Class = { | 84 |
45 create: function() { | 85 var Class = (function() { |
| 86 |
| 87 var IS_DONTENUM_BUGGY = (function(){ |
| 88 for (var p in { toString: 1 }) { |
| 89 if (p === 'toString') return false; |
| 90 } |
| 91 return true; |
| 92 })(); |
| 93 |
| 94 function subclass() {}; |
| 95 function create() { |
46 var parent = null, properties = $A(arguments); | 96 var parent = null, properties = $A(arguments); |
47 if (Object.isFunction(properties[0])) | 97 if (Object.isFunction(properties[0])) |
48 parent = properties.shift(); | 98 parent = properties.shift(); |
49 | 99 |
50 function klass() { | 100 function klass() { |
51 this.initialize.apply(this, arguments); | 101 this.initialize.apply(this, arguments); |
52 } | 102 } |
53 | 103 |
54 Object.extend(klass, Class.Methods); | 104 Object.extend(klass, Class.Methods); |
55 klass.superclass = parent; | 105 klass.superclass = parent; |
56 klass.subclasses = []; | 106 klass.subclasses = []; |
57 | 107 |
58 if (parent) { | 108 if (parent) { |
59 var subclass = function() { }; | |
60 subclass.prototype = parent.prototype; | 109 subclass.prototype = parent.prototype; |
61 klass.prototype = new subclass; | 110 klass.prototype = new subclass; |
62 parent.subclasses.push(klass); | 111 parent.subclasses.push(klass); |
63 } | 112 } |
64 | 113 |
65 for (var i = 0; i < properties.length; i++) | 114 for (var i = 0, length = properties.length; i < length; i++) |
66 klass.addMethods(properties[i]); | 115 klass.addMethods(properties[i]); |
67 | 116 |
68 if (!klass.prototype.initialize) | 117 if (!klass.prototype.initialize) |
69 klass.prototype.initialize = Prototype.emptyFunction; | 118 klass.prototype.initialize = Prototype.emptyFunction; |
70 | 119 |
71 klass.prototype.constructor = klass; | 120 klass.prototype.constructor = klass; |
72 | |
73 return klass; | 121 return klass; |
74 } | 122 } |
75 }; | |
76 | 123 |
77 Class.Methods = { | 124 function addMethods(source) { |
78 addMethods: function(source) { | 125 var ancestor = this.superclass && this.superclass.prototype, |
79 var ancestor = this.superclass && this.superclass.prototype; | 126 properties = Object.keys(source); |
80 var properties = Object.keys(source); | |
81 | 127 |
82 if (!Object.keys({ toString: true }).length) | 128 if (IS_DONTENUM_BUGGY) { |
83 properties.push("toString", "valueOf"); | 129 if (source.toString != Object.prototype.toString) |
| 130 properties.push("toString"); |
| 131 if (source.valueOf != Object.prototype.valueOf) |
| 132 properties.push("valueOf"); |
| 133 } |
84 | 134 |
85 for (var i = 0, length = properties.length; i < length; i++) { | 135 for (var i = 0, length = properties.length; i < length; i++) { |
86 var property = properties[i], value = source[property]; | 136 var property = properties[i], value = source[property]; |
87 if (ancestor && Object.isFunction(value) && | 137 if (ancestor && Object.isFunction(value) && |
88 value.argumentNames().first() == "$super") { | 138 value.argumentNames()[0] == "$super") { |
89 var method = value; | 139 var method = value; |
90 value = (function(m) { | 140 value = (function(m) { |
91 return function() { return ancestor[m].apply(this, arguments) }; | 141 return function() { return ancestor[m].apply(this, arguments); }; |
92 })(property).wrap(method); | 142 })(property).wrap(method); |
93 | 143 |
94 value.valueOf = method.valueOf.bind(method); | 144 value.valueOf = method.valueOf.bind(method); |
95 value.toString = method.toString.bind(method); | 145 value.toString = method.toString.bind(method); |
96 } | 146 } |
97 this.prototype[property] = value; | 147 this.prototype[property] = value; |
98 } | 148 } |
99 | 149 |
100 return this; | 150 return this; |
101 } | 151 } |
102 }; | 152 |
103 | 153 return { |
104 var Abstract = { }; | 154 create: create, |
105 | 155 Methods: { |
106 Object.extend = function(destination, source) { | 156 addMethods: addMethods |
107 for (var property in source) | 157 } |
108 destination[property] = source[property]; | 158 }; |
109 return destination; | 159 })(); |
110 }; | 160 (function() { |
111 | 161 |
112 Object.extend(Object, { | 162 var _toString = Object.prototype.toString, |
113 inspect: function(object) { | 163 NULL_TYPE = 'Null', |
| 164 UNDEFINED_TYPE = 'Undefined', |
| 165 BOOLEAN_TYPE = 'Boolean', |
| 166 NUMBER_TYPE = 'Number', |
| 167 STRING_TYPE = 'String', |
| 168 OBJECT_TYPE = 'Object', |
| 169 FUNCTION_CLASS = '[object Function]', |
| 170 BOOLEAN_CLASS = '[object Boolean]', |
| 171 NUMBER_CLASS = '[object Number]', |
| 172 STRING_CLASS = '[object String]', |
| 173 ARRAY_CLASS = '[object Array]', |
| 174 DATE_CLASS = '[object Date]', |
| 175 NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON && |
| 176 typeof JSON.stringify === 'function' && |
| 177 JSON.stringify(0) === '0' && |
| 178 typeof JSON.stringify(Prototype.K) === 'undefined'; |
| 179 |
| 180 function Type(o) { |
| 181 switch(o) { |
| 182 case null: return NULL_TYPE; |
| 183 case (void 0): return UNDEFINED_TYPE; |
| 184 } |
| 185 var type = typeof o; |
| 186 switch(type) { |
| 187 case 'boolean': return BOOLEAN_TYPE; |
| 188 case 'number': return NUMBER_TYPE; |
| 189 case 'string': return STRING_TYPE; |
| 190 } |
| 191 return OBJECT_TYPE; |
| 192 } |
| 193 |
| 194 function extend(destination, source) { |
| 195 for (var property in source) |
| 196 destination[property] = source[property]; |
| 197 return destination; |
| 198 } |
| 199 |
| 200 function inspect(object) { |
114 try { | 201 try { |
115 if (Object.isUndefined(object)) return 'undefined'; | 202 if (isUndefined(object)) return 'undefined'; |
116 if (object === null) return 'null'; | 203 if (object === null) return 'null'; |
117 return object.inspect ? object.inspect() : String(object); | 204 return object.inspect ? object.inspect() : String(object); |
118 } catch (e) { | 205 } catch (e) { |
119 if (e instanceof RangeError) return '...'; | 206 if (e instanceof RangeError) return '...'; |
120 throw e; | 207 throw e; |
121 } | 208 } |
122 }, | 209 } |
123 | 210 |
124 toJSON: function(object) { | 211 function toJSON(value) { |
125 var type = typeof object; | 212 return Str('', { '': value }, []); |
| 213 } |
| 214 |
| 215 function Str(key, holder, stack) { |
| 216 var value = holder[key], |
| 217 type = typeof value; |
| 218 |
| 219 if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') { |
| 220 value = value.toJSON(key); |
| 221 } |
| 222 |
| 223 var _class = _toString.call(value); |
| 224 |
| 225 switch (_class) { |
| 226 case NUMBER_CLASS: |
| 227 case BOOLEAN_CLASS: |
| 228 case STRING_CLASS: |
| 229 value = value.valueOf(); |
| 230 } |
| 231 |
| 232 switch (value) { |
| 233 case null: return 'null'; |
| 234 case true: return 'true'; |
| 235 case false: return 'false'; |
| 236 } |
| 237 |
| 238 type = typeof value; |
126 switch (type) { | 239 switch (type) { |
127 case 'undefined': | 240 case 'string': |
128 case 'function': | 241 return value.inspect(true); |
129 case 'unknown': return; | 242 case 'number': |
130 case 'boolean': return object.toString(); | 243 return isFinite(value) ? String(value) : 'null'; |
131 } | 244 case 'object': |
132 | 245 |
133 if (object === null) return 'null'; | 246 for (var i = 0, length = stack.length; i < length; i++) { |
134 if (object.toJSON) return object.toJSON(); | 247 if (stack[i] === value) { throw new TypeError(); } |
135 if (Object.isElement(object)) return; | 248 } |
136 | 249 stack.push(value); |
| 250 |
| 251 var partial = []; |
| 252 if (_class === ARRAY_CLASS) { |
| 253 for (var i = 0, length = value.length; i < length; i++) { |
| 254 var str = Str(i, value, stack); |
| 255 partial.push(typeof str === 'undefined' ? 'null' : str); |
| 256 } |
| 257 partial = '[' + partial.join(',') + ']'; |
| 258 } else { |
| 259 var keys = Object.keys(value); |
| 260 for (var i = 0, length = keys.length; i < length; i++) { |
| 261 var key = keys[i], str = Str(key, value, stack); |
| 262 if (typeof str !== "undefined") { |
| 263 partial.push(key.inspect(true)+ ':' + str); |
| 264 } |
| 265 } |
| 266 partial = '{' + partial.join(',') + '}'; |
| 267 } |
| 268 stack.pop(); |
| 269 return partial; |
| 270 } |
| 271 } |
| 272 |
| 273 function stringify(object) { |
| 274 return JSON.stringify(object); |
| 275 } |
| 276 |
| 277 function toQueryString(object) { |
| 278 return $H(object).toQueryString(); |
| 279 } |
| 280 |
| 281 function toHTML(object) { |
| 282 return object && object.toHTML ? object.toHTML() : String.interpret(object); |
| 283 } |
| 284 |
| 285 function keys(object) { |
| 286 if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); } |
137 var results = []; | 287 var results = []; |
138 for (var property in object) { | 288 for (var property in object) { |
139 var value = Object.toJSON(object[property]); | 289 if (object.hasOwnProperty(property)) { |
140 if (!Object.isUndefined(value)) | 290 results.push(property); |
141 results.push(property.toJSON() + ': ' + value); | 291 } |
142 } | 292 } |
143 | 293 return results; |
144 return '{' + results.join(', ') + '}'; | 294 } |
145 }, | 295 |
146 | 296 function values(object) { |
147 toQueryString: function(object) { | 297 var results = []; |
148 return $H(object).toQueryString(); | |
149 }, | |
150 | |
151 toHTML: function(object) { | |
152 return object && object.toHTML ? object.toHTML() : String.interpret(object); | |
153 }, | |
154 | |
155 keys: function(object) { | |
156 var keys = []; | |
157 for (var property in object) | 298 for (var property in object) |
158 keys.push(property); | 299 results.push(object[property]); |
159 return keys; | 300 return results; |
160 }, | 301 } |
161 | 302 |
162 values: function(object) { | 303 function clone(object) { |
163 var values = []; | 304 return extend({ }, object); |
164 for (var property in object) | 305 } |
165 values.push(object[property]); | 306 |
166 return values; | 307 function isElement(object) { |
167 }, | |
168 | |
169 clone: function(object) { | |
170 return Object.extend({ }, object); | |
171 }, | |
172 | |
173 isElement: function(object) { | |
174 return !!(object && object.nodeType == 1); | 308 return !!(object && object.nodeType == 1); |
175 }, | 309 } |
176 | 310 |
177 isArray: function(object) { | 311 function isArray(object) { |
178 return object != null && typeof object == "object" && | 312 return _toString.call(object) === ARRAY_CLASS; |
179 'splice' in object && 'join' in object; | 313 } |
180 }, | 314 |
181 | 315 var hasNativeIsArray = (typeof Array.isArray == 'function') |
182 isHash: function(object) { | 316 && Array.isArray([]) && !Array.isArray({}); |
| 317 |
| 318 if (hasNativeIsArray) { |
| 319 isArray = Array.isArray; |
| 320 } |
| 321 |
| 322 function isHash(object) { |
183 return object instanceof Hash; | 323 return object instanceof Hash; |
184 }, | 324 } |
185 | 325 |
186 isFunction: function(object) { | 326 function isFunction(object) { |
187 return typeof object == "function"; | 327 return _toString.call(object) === FUNCTION_CLASS; |
188 }, | 328 } |
189 | 329 |
190 isString: function(object) { | 330 function isString(object) { |
191 return typeof object == "string"; | 331 return _toString.call(object) === STRING_CLASS; |
192 }, | 332 } |
193 | 333 |
194 isNumber: function(object) { | 334 function isNumber(object) { |
195 return typeof object == "number"; | 335 return _toString.call(object) === NUMBER_CLASS; |
196 }, | 336 } |
197 | 337 |
198 isUndefined: function(object) { | 338 function isDate(object) { |
199 return typeof object == "undefined"; | 339 return _toString.call(object) === DATE_CLASS; |
200 } | 340 } |
201 }); | 341 |
202 | 342 function isUndefined(object) { |
203 Object.extend(Function.prototype, { | 343 return typeof object === "undefined"; |
204 argumentNames: function() { | 344 } |
205 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^\)]*)\)/)[1] | 345 |
| 346 extend(Object, { |
| 347 extend: extend, |
| 348 inspect: inspect, |
| 349 toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON, |
| 350 toQueryString: toQueryString, |
| 351 toHTML: toHTML, |
| 352 keys: Object.keys || keys, |
| 353 values: values, |
| 354 clone: clone, |
| 355 isElement: isElement, |
| 356 isArray: isArray, |
| 357 isHash: isHash, |
| 358 isFunction: isFunction, |
| 359 isString: isString, |
| 360 isNumber: isNumber, |
| 361 isDate: isDate, |
| 362 isUndefined: isUndefined |
| 363 }); |
| 364 })(); |
| 365 Object.extend(Function.prototype, (function() { |
| 366 var slice = Array.prototype.slice; |
| 367 |
| 368 function update(array, args) { |
| 369 var arrayLength = array.length, length = args.length; |
| 370 while (length--) array[arrayLength + length] = args[length]; |
| 371 return array; |
| 372 } |
| 373 |
| 374 function merge(array, args) { |
| 375 array = slice.call(array, 0); |
| 376 return update(array, args); |
| 377 } |
| 378 |
| 379 function argumentNames() { |
| 380 var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] |
| 381 .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') |
206 .replace(/\s+/g, '').split(','); | 382 .replace(/\s+/g, '').split(','); |
207 return names.length == 1 && !names[0] ? [] : names; | 383 return names.length == 1 && !names[0] ? [] : names; |
208 }, | 384 } |
209 | 385 |
210 bind: function() { | 386 function bind(context) { |
211 if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; | 387 if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this; |
212 var __method = this, args = $A(arguments), object = args.shift(); | 388 var __method = this, args = slice.call(arguments, 1); |
213 return function() { | 389 return function() { |
214 return __method.apply(object, args.concat($A(arguments))); | 390 var a = merge(args, arguments); |
215 } | 391 return __method.apply(context, a); |
216 }, | 392 } |
217 | 393 } |
218 bindAsEventListener: function() { | 394 |
219 var __method = this, args = $A(arguments), object = args.shift(); | 395 function bindAsEventListener(context) { |
| 396 var __method = this, args = slice.call(arguments, 1); |
220 return function(event) { | 397 return function(event) { |
221 return __method.apply(object, [event || window.event].concat(args)); | 398 var a = update([event || window.event], args); |
222 } | 399 return __method.apply(context, a); |
223 }, | 400 } |
224 | 401 } |
225 curry: function() { | 402 |
| 403 function curry() { |
226 if (!arguments.length) return this; | 404 if (!arguments.length) return this; |
227 var __method = this, args = $A(arguments); | 405 var __method = this, args = slice.call(arguments, 0); |
228 return function() { | 406 return function() { |
229 return __method.apply(this, args.concat($A(arguments))); | 407 var a = merge(args, arguments); |
230 } | 408 return __method.apply(this, a); |
231 }, | 409 } |
232 | 410 } |
233 delay: function() { | 411 |
234 var __method = this, args = $A(arguments), timeout = args.shift() * 1000; | 412 function delay(timeout) { |
| 413 var __method = this, args = slice.call(arguments, 1); |
| 414 timeout = timeout * 1000; |
235 return window.setTimeout(function() { | 415 return window.setTimeout(function() { |
236 return __method.apply(__method, args); | 416 return __method.apply(__method, args); |
237 }, timeout); | 417 }, timeout); |
238 }, | 418 } |
239 | 419 |
240 defer: function() { | 420 function defer() { |
241 var args = [0.01].concat($A(arguments)); | 421 var args = update([0.01], arguments); |
242 return this.delay.apply(this, args); | 422 return this.delay.apply(this, args); |
243 }, | 423 } |
244 | 424 |
245 wrap: function(wrapper) { | 425 function wrap(wrapper) { |
246 var __method = this; | 426 var __method = this; |
247 return function() { | 427 return function() { |
248 return wrapper.apply(this, [__method.bind(this)].concat($A(arguments))); | 428 var a = update([__method.bind(this)], arguments); |
249 } | 429 return wrapper.apply(this, a); |
250 }, | 430 } |
251 | 431 } |
252 methodize: function() { | 432 |
| 433 function methodize() { |
253 if (this._methodized) return this._methodized; | 434 if (this._methodized) return this._methodized; |
254 var __method = this; | 435 var __method = this; |
255 return this._methodized = function() { | 436 return this._methodized = function() { |
256 return __method.apply(null, [this].concat($A(arguments))); | 437 var a = update([this], arguments); |
| 438 return __method.apply(null, a); |
257 }; | 439 }; |
258 } | 440 } |
259 }); | 441 |
260 | 442 return { |
261 Date.prototype.toJSON = function() { | 443 argumentNames: argumentNames, |
262 return '"' + this.getUTCFullYear() + '-' + | 444 bind: bind, |
263 (this.getUTCMonth() + 1).toPaddedString(2) + '-' + | 445 bindAsEventListener: bindAsEventListener, |
264 this.getUTCDate().toPaddedString(2) + 'T' + | 446 curry: curry, |
265 this.getUTCHours().toPaddedString(2) + ':' + | 447 delay: delay, |
266 this.getUTCMinutes().toPaddedString(2) + ':' + | 448 defer: defer, |
267 this.getUTCSeconds().toPaddedString(2) + 'Z"'; | 449 wrap: wrap, |
268 }; | 450 methodize: methodize |
269 | 451 } |
270 var Try = { | 452 })()); |
271 these: function() { | 453 |
272 var returnValue; | 454 |
273 | 455 |
274 for (var i = 0, length = arguments.length; i < length; i++) { | 456 (function(proto) { |
275 var lambda = arguments[i]; | 457 |
276 try { | 458 |
277 returnValue = lambda(); | 459 function toISOString() { |
278 break; | 460 return this.getUTCFullYear() + '-' + |
279 } catch (e) { } | 461 (this.getUTCMonth() + 1).toPaddedString(2) + '-' + |
280 } | 462 this.getUTCDate().toPaddedString(2) + 'T' + |
281 | 463 this.getUTCHours().toPaddedString(2) + ':' + |
282 return returnValue; | 464 this.getUTCMinutes().toPaddedString(2) + ':' + |
283 } | 465 this.getUTCSeconds().toPaddedString(2) + 'Z'; |
284 }; | 466 } |
| 467 |
| 468 |
| 469 function toJSON() { |
| 470 return this.toISOString(); |
| 471 } |
| 472 |
| 473 if (!proto.toISOString) proto.toISOString = toISOString; |
| 474 if (!proto.toJSON) proto.toJSON = toJSON; |
| 475 |
| 476 })(Date.prototype); |
| 477 |
285 | 478 |
286 RegExp.prototype.match = RegExp.prototype.test; | 479 RegExp.prototype.match = RegExp.prototype.test; |
287 | 480 |
288 RegExp.escape = function(str) { | 481 RegExp.escape = function(str) { |
289 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); | 482 return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1'); |
290 }; | 483 }; |
291 | |
292 /*--------------------------------------------------------------------------*/ | |
293 | |
294 var PeriodicalExecuter = Class.create({ | 484 var PeriodicalExecuter = Class.create({ |
295 initialize: function(callback, frequency) { | 485 initialize: function(callback, frequency) { |
296 this.callback = callback; | 486 this.callback = callback; |
297 this.frequency = frequency; | 487 this.frequency = frequency; |
298 this.currentlyExecuting = false; | 488 this.currentlyExecuting = false; |
299 | 489 |
300 this.registerCallback(); | 490 this.registerCallback(); |
301 }, | 491 }, |
302 | 492 |
303 registerCallback: function() { | 493 registerCallback: function() { |
304 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000
); | 494 this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000
); |
305 }, | 495 }, |
306 | 496 |
307 execute: function() { | 497 execute: function() { |
308 this.callback(this); | 498 this.callback(this); |
309 }, | 499 }, |
310 | 500 |
311 stop: function() { | 501 stop: function() { |
312 if (!this.timer) return; | 502 if (!this.timer) return; |
313 clearInterval(this.timer); | 503 clearInterval(this.timer); |
314 this.timer = null; | 504 this.timer = null; |
315 }, | 505 }, |
316 | 506 |
317 onTimerEvent: function() { | 507 onTimerEvent: function() { |
318 if (!this.currentlyExecuting) { | 508 if (!this.currentlyExecuting) { |
319 try { | 509 try { |
320 this.currentlyExecuting = true; | 510 this.currentlyExecuting = true; |
321 this.execute(); | 511 this.execute(); |
322 } finally { | |
323 this.currentlyExecuting = false; | 512 this.currentlyExecuting = false; |
| 513 } catch(e) { |
| 514 this.currentlyExecuting = false; |
| 515 throw e; |
324 } | 516 } |
325 } | 517 } |
326 } | 518 } |
327 }); | 519 }); |
328 Object.extend(String, { | 520 Object.extend(String, { |
329 interpret: function(value) { | 521 interpret: function(value) { |
330 return value == null ? '' : String(value); | 522 return value == null ? '' : String(value); |
331 }, | 523 }, |
332 specialChar: { | 524 specialChar: { |
333 '\b': '\\b', | 525 '\b': '\\b', |
334 '\t': '\\t', | 526 '\t': '\\t', |
335 '\n': '\\n', | 527 '\n': '\\n', |
336 '\f': '\\f', | 528 '\f': '\\f', |
337 '\r': '\\r', | 529 '\r': '\\r', |
338 '\\': '\\\\' | 530 '\\': '\\\\' |
339 } | 531 } |
340 }); | 532 }); |
341 | 533 |
342 Object.extend(String.prototype, { | 534 Object.extend(String.prototype, (function() { |
343 gsub: function(pattern, replacement) { | 535 var NATIVE_JSON_PARSE_SUPPORT = window.JSON && |
| 536 typeof JSON.parse === 'function' && |
| 537 JSON.parse('{"test": true}').test; |
| 538 |
| 539 function prepareReplacement(replacement) { |
| 540 if (Object.isFunction(replacement)) return replacement; |
| 541 var template = new Template(replacement); |
| 542 return function(match) { return template.evaluate(match) }; |
| 543 } |
| 544 |
| 545 function gsub(pattern, replacement) { |
344 var result = '', source = this, match; | 546 var result = '', source = this, match; |
345 replacement = arguments.callee.prepareReplacement(replacement); | 547 replacement = prepareReplacement(replacement); |
| 548 |
| 549 if (Object.isString(pattern)) |
| 550 pattern = RegExp.escape(pattern); |
| 551 |
| 552 if (!(pattern.length || pattern.source)) { |
| 553 replacement = replacement(''); |
| 554 return replacement + source.split('').join(replacement) + replacement; |
| 555 } |
346 | 556 |
347 while (source.length > 0) { | 557 while (source.length > 0) { |
348 if (match = source.match(pattern)) { | 558 if (match = source.match(pattern)) { |
349 result += source.slice(0, match.index); | 559 result += source.slice(0, match.index); |
350 result += String.interpret(replacement(match)); | 560 result += String.interpret(replacement(match)); |
351 source = source.slice(match.index + match[0].length); | 561 source = source.slice(match.index + match[0].length); |
352 } else { | 562 } else { |
353 result += source, source = ''; | 563 result += source, source = ''; |
354 } | 564 } |
355 } | 565 } |
356 return result; | 566 return result; |
357 }, | 567 } |
358 | 568 |
359 sub: function(pattern, replacement, count) { | 569 function sub(pattern, replacement, count) { |
360 replacement = this.gsub.prepareReplacement(replacement); | 570 replacement = prepareReplacement(replacement); |
361 count = Object.isUndefined(count) ? 1 : count; | 571 count = Object.isUndefined(count) ? 1 : count; |
362 | 572 |
363 return this.gsub(pattern, function(match) { | 573 return this.gsub(pattern, function(match) { |
364 if (--count < 0) return match[0]; | 574 if (--count < 0) return match[0]; |
365 return replacement(match); | 575 return replacement(match); |
366 }); | 576 }); |
367 }, | 577 } |
368 | 578 |
369 scan: function(pattern, iterator) { | 579 function scan(pattern, iterator) { |
370 this.gsub(pattern, iterator); | 580 this.gsub(pattern, iterator); |
371 return String(this); | 581 return String(this); |
372 }, | 582 } |
373 | 583 |
374 truncate: function(length, truncation) { | 584 function truncate(length, truncation) { |
375 length = length || 30; | 585 length = length || 30; |
376 truncation = Object.isUndefined(truncation) ? '...' : truncation; | 586 truncation = Object.isUndefined(truncation) ? '...' : truncation; |
377 return this.length > length ? | 587 return this.length > length ? |
378 this.slice(0, length - truncation.length) + truncation : String(this); | 588 this.slice(0, length - truncation.length) + truncation : String(this); |
379 }, | 589 } |
380 | 590 |
381 strip: function() { | 591 function strip() { |
382 return this.replace(/^\s+/, '').replace(/\s+$/, ''); | 592 return this.replace(/^\s+/, '').replace(/\s+$/, ''); |
383 }, | 593 } |
384 | 594 |
385 stripTags: function() { | 595 function stripTags() { |
386 return this.replace(/<\/?[^>]+>/gi, ''); | 596 return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, ''); |
387 }, | 597 } |
388 | 598 |
389 stripScripts: function() { | 599 function stripScripts() { |
390 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); | 600 return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), ''); |
391 }, | 601 } |
392 | 602 |
393 extractScripts: function() { | 603 function extractScripts() { |
394 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'); | 604 var matchAll = new RegExp(Prototype.ScriptFragment, 'img'), |
395 var matchOne = new RegExp(Prototype.ScriptFragment, 'im'); | 605 matchOne = new RegExp(Prototype.ScriptFragment, 'im'); |
396 return (this.match(matchAll) || []).map(function(scriptTag) { | 606 return (this.match(matchAll) || []).map(function(scriptTag) { |
397 return (scriptTag.match(matchOne) || ['', ''])[1]; | 607 return (scriptTag.match(matchOne) || ['', ''])[1]; |
398 }); | 608 }); |
399 }, | 609 } |
400 | 610 |
401 evalScripts: function() { | 611 function evalScripts() { |
402 return this.extractScripts().map(function(script) { return eval(script) }); | 612 return this.extractScripts().map(function(script) { return eval(script) }); |
403 }, | 613 } |
404 | 614 |
405 escapeHTML: function() { | 615 function escapeHTML() { |
406 var self = arguments.callee; | 616 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); |
407 self.text.data = this; | 617 } |
408 return self.div.innerHTML; | |
409 }, | |
410 | 618 |
411 unescapeHTML: function() { | 619 function unescapeHTML() { |
412 var div = new Element('div'); | 620 return this.stripTags().replace(/</g,'<').replace(/>/g,'>').replace(/&
amp;/g,'&'); |
413 div.innerHTML = this.stripTags(); | 621 } |
414 return div.childNodes[0] ? (div.childNodes.length > 1 ? | |
415 $A(div.childNodes).inject('', function(memo, node) { return memo+node.node
Value }) : | |
416 div.childNodes[0].nodeValue) : ''; | |
417 }, | |
418 | 622 |
419 toQueryParams: function(separator) { | 623 |
| 624 function toQueryParams(separator) { |
420 var match = this.strip().match(/([^?#]*)(#.*)?$/); | 625 var match = this.strip().match(/([^?#]*)(#.*)?$/); |
421 if (!match) return { }; | 626 if (!match) return { }; |
422 | 627 |
423 return match[1].split(separator || '&').inject({ }, function(hash, pair) { | 628 return match[1].split(separator || '&').inject({ }, function(hash, pair) { |
424 if ((pair = pair.split('='))[0]) { | 629 if ((pair = pair.split('='))[0]) { |
425 var key = decodeURIComponent(pair.shift()); | 630 var key = decodeURIComponent(pair.shift()), |
426 var value = pair.length > 1 ? pair.join('=') : pair[0]; | 631 value = pair.length > 1 ? pair.join('=') : pair[0]; |
| 632 |
427 if (value != undefined) value = decodeURIComponent(value); | 633 if (value != undefined) value = decodeURIComponent(value); |
428 | 634 |
429 if (key in hash) { | 635 if (key in hash) { |
430 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; | 636 if (!Object.isArray(hash[key])) hash[key] = [hash[key]]; |
431 hash[key].push(value); | 637 hash[key].push(value); |
432 } | 638 } |
433 else hash[key] = value; | 639 else hash[key] = value; |
434 } | 640 } |
435 return hash; | 641 return hash; |
436 }); | 642 }); |
437 }, | 643 } |
438 | 644 |
439 toArray: function() { | 645 function toArray() { |
440 return this.split(''); | 646 return this.split(''); |
441 }, | 647 } |
442 | 648 |
443 succ: function() { | 649 function succ() { |
444 return this.slice(0, this.length - 1) + | 650 return this.slice(0, this.length - 1) + |
445 String.fromCharCode(this.charCodeAt(this.length - 1) + 1); | 651 String.fromCharCode(this.charCodeAt(this.length - 1) + 1); |
446 }, | 652 } |
447 | 653 |
448 times: function(count) { | 654 function times(count) { |
449 return count < 1 ? '' : new Array(count + 1).join(this); | 655 return count < 1 ? '' : new Array(count + 1).join(this); |
450 }, | 656 } |
451 | 657 |
452 camelize: function() { | 658 function camelize() { |
453 var parts = this.split('-'), len = parts.length; | 659 return this.replace(/-+(.)?/g, function(match, chr) { |
454 if (len == 1) return parts[0]; | 660 return chr ? chr.toUpperCase() : ''; |
| 661 }); |
| 662 } |
455 | 663 |
456 var camelized = this.charAt(0) == '-' | 664 function capitalize() { |
457 ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1) | 665 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); |
458 : parts[0]; | 666 } |
459 | 667 |
460 for (var i = 1; i < len; i++) | 668 function underscore() { |
461 camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1); | 669 return this.replace(/::/g, '/') |
| 670 .replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2') |
| 671 .replace(/([a-z\d])([A-Z])/g, '$1_$2') |
| 672 .replace(/-/g, '_') |
| 673 .toLowerCase(); |
| 674 } |
462 | 675 |
463 return camelized; | 676 function dasherize() { |
464 }, | 677 return this.replace(/_/g, '-'); |
| 678 } |
465 | 679 |
466 capitalize: function() { | 680 function inspect(useDoubleQuotes) { |
467 return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase(); | 681 var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) { |
468 }, | 682 if (character in String.specialChar) { |
469 | 683 return String.specialChar[character]; |
470 underscore: function() { | 684 } |
471 return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/(
[a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase(); | 685 return '\\u00' + character.charCodeAt().toPaddedString(2, 16); |
472 }, | |
473 | |
474 dasherize: function() { | |
475 return this.gsub(/_/,'-'); | |
476 }, | |
477 | |
478 inspect: function(useDoubleQuotes) { | |
479 var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) { | |
480 var character = String.specialChar[match[0]]; | |
481 return character ? character : '\\u00' + match[0].charCodeAt().toPaddedStr
ing(2, 16); | |
482 }); | 686 }); |
483 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; | 687 if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"'; |
484 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; | 688 return "'" + escapedString.replace(/'/g, '\\\'') + "'"; |
485 }, | 689 } |
486 | 690 |
487 toJSON: function() { | 691 function unfilterJSON(filter) { |
488 return this.inspect(true); | 692 return this.replace(filter || Prototype.JSONFilter, '$1'); |
489 }, | 693 } |
490 | 694 |
491 unfilterJSON: function(filter) { | 695 function isJSON() { |
492 return this.sub(filter || Prototype.JSONFilter, '#{1}'); | |
493 }, | |
494 | |
495 isJSON: function() { | |
496 var str = this; | 696 var str = this; |
497 if (str.blank()) return false; | 697 if (str.blank()) return false; |
498 str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''); | 698 str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); |
499 return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str); | 699 str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]
?\d+)?/g, ']'); |
500 }, | 700 str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); |
| 701 return (/^[\],:{}\s]*$/).test(str); |
| 702 } |
501 | 703 |
502 evalJSON: function(sanitize) { | 704 function evalJSON(sanitize) { |
503 var json = this.unfilterJSON(); | 705 var json = this.unfilterJSON(), |
| 706 cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u
202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; |
| 707 if (cx.test(json)) { |
| 708 json = json.replace(cx, function (a) { |
| 709 return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); |
| 710 }); |
| 711 } |
504 try { | 712 try { |
505 if (!sanitize || json.isJSON()) return eval('(' + json + ')'); | 713 if (!sanitize || json.isJSON()) return eval('(' + json + ')'); |
506 } catch (e) { } | 714 } catch (e) { } |
507 throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); | 715 throw new SyntaxError('Badly formed JSON string: ' + this.inspect()); |
508 }, | 716 } |
509 | 717 |
510 include: function(pattern) { | 718 function parseJSON() { |
| 719 var json = this.unfilterJSON(); |
| 720 return JSON.parse(json); |
| 721 } |
| 722 |
| 723 function include(pattern) { |
511 return this.indexOf(pattern) > -1; | 724 return this.indexOf(pattern) > -1; |
512 }, | 725 } |
513 | 726 |
514 startsWith: function(pattern) { | 727 function startsWith(pattern) { |
515 return this.indexOf(pattern) === 0; | 728 return this.lastIndexOf(pattern, 0) === 0; |
516 }, | 729 } |
517 | 730 |
518 endsWith: function(pattern) { | 731 function endsWith(pattern) { |
519 var d = this.length - pattern.length; | 732 var d = this.length - pattern.length; |
520 return d >= 0 && this.lastIndexOf(pattern) === d; | 733 return d >= 0 && this.indexOf(pattern, d) === d; |
521 }, | 734 } |
522 | 735 |
523 empty: function() { | 736 function empty() { |
524 return this == ''; | 737 return this == ''; |
525 }, | 738 } |
526 | 739 |
527 blank: function() { | 740 function blank() { |
528 return /^\s*$/.test(this); | 741 return /^\s*$/.test(this); |
529 }, | 742 } |
530 | 743 |
531 interpolate: function(object, pattern) { | 744 function interpolate(object, pattern) { |
532 return new Template(this, pattern).evaluate(object); | 745 return new Template(this, pattern).evaluate(object); |
533 } | 746 } |
534 }); | |
535 | 747 |
536 if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.proto
type, { | 748 return { |
537 escapeHTML: function() { | 749 gsub: gsub, |
538 return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>'); | 750 sub: sub, |
539 }, | 751 scan: scan, |
540 unescapeHTML: function() { | 752 truncate: truncate, |
541 return this.stripTags().replace(/&/g,'&').replace(/</g,'<').replace(/
>/g,'>'); | 753 strip: String.prototype.trim || strip, |
542 } | 754 stripTags: stripTags, |
543 }); | 755 stripScripts: stripScripts, |
544 | 756 extractScripts: extractScripts, |
545 String.prototype.gsub.prepareReplacement = function(replacement) { | 757 evalScripts: evalScripts, |
546 if (Object.isFunction(replacement)) return replacement; | 758 escapeHTML: escapeHTML, |
547 var template = new Template(replacement); | 759 unescapeHTML: unescapeHTML, |
548 return function(match) { return template.evaluate(match) }; | 760 toQueryParams: toQueryParams, |
549 }; | 761 parseQuery: toQueryParams, |
550 | 762 toArray: toArray, |
551 String.prototype.parseQuery = String.prototype.toQueryParams; | 763 succ: succ, |
552 | 764 times: times, |
553 Object.extend(String.prototype.escapeHTML, { | 765 camelize: camelize, |
554 div: document.createElement('div'), | 766 capitalize: capitalize, |
555 text: document.createTextNode('') | 767 underscore: underscore, |
556 }); | 768 dasherize: dasherize, |
557 | 769 inspect: inspect, |
558 String.prototype.escapeHTML.div.appendChild(String.prototype.escapeHTML.text); | 770 unfilterJSON: unfilterJSON, |
| 771 isJSON: isJSON, |
| 772 evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON, |
| 773 include: include, |
| 774 startsWith: startsWith, |
| 775 endsWith: endsWith, |
| 776 empty: empty, |
| 777 blank: blank, |
| 778 interpolate: interpolate |
| 779 }; |
| 780 })()); |
559 | 781 |
560 var Template = Class.create({ | 782 var Template = Class.create({ |
561 initialize: function(template, pattern) { | 783 initialize: function(template, pattern) { |
562 this.template = template.toString(); | 784 this.template = template.toString(); |
563 this.pattern = pattern || Template.Pattern; | 785 this.pattern = pattern || Template.Pattern; |
564 }, | 786 }, |
565 | 787 |
566 evaluate: function(object) { | 788 evaluate: function(object) { |
567 if (Object.isFunction(object.toTemplateReplacements)) | 789 if (object && Object.isFunction(object.toTemplateReplacements)) |
568 object = object.toTemplateReplacements(); | 790 object = object.toTemplateReplacements(); |
569 | 791 |
570 return this.template.gsub(this.pattern, function(match) { | 792 return this.template.gsub(this.pattern, function(match) { |
571 if (object == null) return ''; | 793 if (object == null) return (match[1] + ''); |
572 | 794 |
573 var before = match[1] || ''; | 795 var before = match[1] || ''; |
574 if (before == '\\') return match[2]; | 796 if (before == '\\') return match[2]; |
575 | 797 |
576 var ctx = object, expr = match[3]; | 798 var ctx = object, expr = match[3], |
577 var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; | 799 pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/; |
| 800 |
578 match = pattern.exec(expr); | 801 match = pattern.exec(expr); |
579 if (match == null) return before; | 802 if (match == null) return before; |
580 | 803 |
581 while (match != null) { | 804 while (match != null) { |
582 var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : matc
h[1]; | 805 var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') :
match[1]; |
583 ctx = ctx[comp]; | 806 ctx = ctx[comp]; |
584 if (null == ctx || '' == match[3]) break; | 807 if (null == ctx || '' == match[3]) break; |
585 expr = expr.substring('[' == match[3] ? match[1].length : match[0].lengt
h); | 808 expr = expr.substring('[' == match[3] ? match[1].length : match[0].lengt
h); |
586 match = pattern.exec(expr); | 809 match = pattern.exec(expr); |
587 } | 810 } |
588 | 811 |
589 return before + String.interpret(ctx); | 812 return before + String.interpret(ctx); |
590 }); | 813 }); |
591 } | 814 } |
592 }); | 815 }); |
593 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; | 816 Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/; |
594 | 817 |
595 var $break = { }; | 818 var $break = { }; |
596 | 819 |
597 var Enumerable = { | 820 var Enumerable = (function() { |
598 each: function(iterator, context) { | 821 function each(iterator, context) { |
599 var index = 0; | 822 var index = 0; |
600 try { | 823 try { |
601 this._each(function(value) { | 824 this._each(function(value) { |
602 iterator.call(context, value, index++); | 825 iterator.call(context, value, index++); |
603 }); | 826 }); |
604 } catch (e) { | 827 } catch (e) { |
605 if (e != $break) throw e; | 828 if (e != $break) throw e; |
606 } | 829 } |
607 return this; | 830 return this; |
608 }, | 831 } |
609 | 832 |
610 eachSlice: function(number, iterator, context) { | 833 function eachSlice(number, iterator, context) { |
611 var index = -number, slices = [], array = this.toArray(); | 834 var index = -number, slices = [], array = this.toArray(); |
612 if (number < 1) return array; | 835 if (number < 1) return array; |
613 while ((index += number) < array.length) | 836 while ((index += number) < array.length) |
614 slices.push(array.slice(index, index+number)); | 837 slices.push(array.slice(index, index+number)); |
615 return slices.collect(iterator, context); | 838 return slices.collect(iterator, context); |
616 }, | 839 } |
617 | 840 |
618 all: function(iterator, context) { | 841 function all(iterator, context) { |
619 iterator = iterator || Prototype.K; | 842 iterator = iterator || Prototype.K; |
620 var result = true; | 843 var result = true; |
621 this.each(function(value, index) { | 844 this.each(function(value, index) { |
622 result = result && !!iterator.call(context, value, index); | 845 result = result && !!iterator.call(context, value, index); |
623 if (!result) throw $break; | 846 if (!result) throw $break; |
624 }); | 847 }); |
625 return result; | 848 return result; |
626 }, | 849 } |
627 | 850 |
628 any: function(iterator, context) { | 851 function any(iterator, context) { |
629 iterator = iterator || Prototype.K; | 852 iterator = iterator || Prototype.K; |
630 var result = false; | 853 var result = false; |
631 this.each(function(value, index) { | 854 this.each(function(value, index) { |
632 if (result = !!iterator.call(context, value, index)) | 855 if (result = !!iterator.call(context, value, index)) |
633 throw $break; | 856 throw $break; |
634 }); | 857 }); |
635 return result; | 858 return result; |
636 }, | 859 } |
637 | 860 |
638 collect: function(iterator, context) { | 861 function collect(iterator, context) { |
639 iterator = iterator || Prototype.K; | 862 iterator = iterator || Prototype.K; |
640 var results = []; | 863 var results = []; |
641 this.each(function(value, index) { | 864 this.each(function(value, index) { |
642 results.push(iterator.call(context, value, index)); | 865 results.push(iterator.call(context, value, index)); |
643 }); | 866 }); |
644 return results; | 867 return results; |
645 }, | 868 } |
646 | 869 |
647 detect: function(iterator, context) { | 870 function detect(iterator, context) { |
648 var result; | 871 var result; |
649 this.each(function(value, index) { | 872 this.each(function(value, index) { |
650 if (iterator.call(context, value, index)) { | 873 if (iterator.call(context, value, index)) { |
651 result = value; | 874 result = value; |
652 throw $break; | 875 throw $break; |
653 } | 876 } |
654 }); | 877 }); |
655 return result; | 878 return result; |
656 }, | 879 } |
657 | 880 |
658 findAll: function(iterator, context) { | 881 function findAll(iterator, context) { |
659 var results = []; | 882 var results = []; |
660 this.each(function(value, index) { | 883 this.each(function(value, index) { |
661 if (iterator.call(context, value, index)) | 884 if (iterator.call(context, value, index)) |
662 results.push(value); | 885 results.push(value); |
663 }); | 886 }); |
664 return results; | 887 return results; |
665 }, | 888 } |
666 | 889 |
667 grep: function(filter, iterator, context) { | 890 function grep(filter, iterator, context) { |
668 iterator = iterator || Prototype.K; | 891 iterator = iterator || Prototype.K; |
669 var results = []; | 892 var results = []; |
670 | 893 |
671 if (Object.isString(filter)) | 894 if (Object.isString(filter)) |
672 filter = new RegExp(filter); | 895 filter = new RegExp(RegExp.escape(filter)); |
673 | 896 |
674 this.each(function(value, index) { | 897 this.each(function(value, index) { |
675 if (filter.match(value)) | 898 if (filter.match(value)) |
676 results.push(iterator.call(context, value, index)); | 899 results.push(iterator.call(context, value, index)); |
677 }); | 900 }); |
678 return results; | 901 return results; |
679 }, | 902 } |
680 | 903 |
681 include: function(object) { | 904 function include(object) { |
682 if (Object.isFunction(this.indexOf)) | 905 if (Object.isFunction(this.indexOf)) |
683 if (this.indexOf(object) != -1) return true; | 906 if (this.indexOf(object) != -1) return true; |
684 | 907 |
685 var found = false; | 908 var found = false; |
686 this.each(function(value) { | 909 this.each(function(value) { |
687 if (value == object) { | 910 if (value == object) { |
688 found = true; | 911 found = true; |
689 throw $break; | 912 throw $break; |
690 } | 913 } |
691 }); | 914 }); |
692 return found; | 915 return found; |
693 }, | 916 } |
694 | 917 |
695 inGroupsOf: function(number, fillWith) { | 918 function inGroupsOf(number, fillWith) { |
696 fillWith = Object.isUndefined(fillWith) ? null : fillWith; | 919 fillWith = Object.isUndefined(fillWith) ? null : fillWith; |
697 return this.eachSlice(number, function(slice) { | 920 return this.eachSlice(number, function(slice) { |
698 while(slice.length < number) slice.push(fillWith); | 921 while(slice.length < number) slice.push(fillWith); |
699 return slice; | 922 return slice; |
700 }); | 923 }); |
701 }, | 924 } |
702 | 925 |
703 inject: function(memo, iterator, context) { | 926 function inject(memo, iterator, context) { |
704 this.each(function(value, index) { | 927 this.each(function(value, index) { |
705 memo = iterator.call(context, memo, value, index); | 928 memo = iterator.call(context, memo, value, index); |
706 }); | 929 }); |
707 return memo; | 930 return memo; |
708 }, | 931 } |
709 | 932 |
710 invoke: function(method) { | 933 function invoke(method) { |
711 var args = $A(arguments).slice(1); | 934 var args = $A(arguments).slice(1); |
712 return this.map(function(value) { | 935 return this.map(function(value) { |
713 return value[method].apply(value, args); | 936 return value[method].apply(value, args); |
714 }); | 937 }); |
715 }, | 938 } |
716 | 939 |
717 max: function(iterator, context) { | 940 function max(iterator, context) { |
718 iterator = iterator || Prototype.K; | 941 iterator = iterator || Prototype.K; |
719 var result; | 942 var result; |
720 this.each(function(value, index) { | 943 this.each(function(value, index) { |
721 value = iterator.call(context, value, index); | 944 value = iterator.call(context, value, index); |
722 if (result == null || value >= result) | 945 if (result == null || value >= result) |
723 result = value; | 946 result = value; |
724 }); | 947 }); |
725 return result; | 948 return result; |
726 }, | 949 } |
727 | 950 |
728 min: function(iterator, context) { | 951 function min(iterator, context) { |
729 iterator = iterator || Prototype.K; | 952 iterator = iterator || Prototype.K; |
730 var result; | 953 var result; |
731 this.each(function(value, index) { | 954 this.each(function(value, index) { |
732 value = iterator.call(context, value, index); | 955 value = iterator.call(context, value, index); |
733 if (result == null || value < result) | 956 if (result == null || value < result) |
734 result = value; | 957 result = value; |
735 }); | 958 }); |
736 return result; | 959 return result; |
737 }, | 960 } |
738 | 961 |
739 partition: function(iterator, context) { | 962 function partition(iterator, context) { |
740 iterator = iterator || Prototype.K; | 963 iterator = iterator || Prototype.K; |
741 var trues = [], falses = []; | 964 var trues = [], falses = []; |
742 this.each(function(value, index) { | 965 this.each(function(value, index) { |
743 (iterator.call(context, value, index) ? | 966 (iterator.call(context, value, index) ? |
744 trues : falses).push(value); | 967 trues : falses).push(value); |
745 }); | 968 }); |
746 return [trues, falses]; | 969 return [trues, falses]; |
747 }, | 970 } |
748 | 971 |
749 pluck: function(property) { | 972 function pluck(property) { |
750 var results = []; | 973 var results = []; |
751 this.each(function(value) { | 974 this.each(function(value) { |
752 results.push(value[property]); | 975 results.push(value[property]); |
753 }); | 976 }); |
754 return results; | 977 return results; |
755 }, | 978 } |
756 | 979 |
757 reject: function(iterator, context) { | 980 function reject(iterator, context) { |
758 var results = []; | 981 var results = []; |
759 this.each(function(value, index) { | 982 this.each(function(value, index) { |
760 if (!iterator.call(context, value, index)) | 983 if (!iterator.call(context, value, index)) |
761 results.push(value); | 984 results.push(value); |
762 }); | 985 }); |
763 return results; | 986 return results; |
764 }, | 987 } |
765 | 988 |
766 sortBy: function(iterator, context) { | 989 function sortBy(iterator, context) { |
767 return this.map(function(value, index) { | 990 return this.map(function(value, index) { |
768 return { | 991 return { |
769 value: value, | 992 value: value, |
770 criteria: iterator.call(context, value, index) | 993 criteria: iterator.call(context, value, index) |
771 }; | 994 }; |
772 }).sort(function(left, right) { | 995 }).sort(function(left, right) { |
773 var a = left.criteria, b = right.criteria; | 996 var a = left.criteria, b = right.criteria; |
774 return a < b ? -1 : a > b ? 1 : 0; | 997 return a < b ? -1 : a > b ? 1 : 0; |
775 }).pluck('value'); | 998 }).pluck('value'); |
776 }, | 999 } |
777 | 1000 |
778 toArray: function() { | 1001 function toArray() { |
779 return this.map(); | 1002 return this.map(); |
780 }, | 1003 } |
781 | 1004 |
782 zip: function() { | 1005 function zip() { |
783 var iterator = Prototype.K, args = $A(arguments); | 1006 var iterator = Prototype.K, args = $A(arguments); |
784 if (Object.isFunction(args.last())) | 1007 if (Object.isFunction(args.last())) |
785 iterator = args.pop(); | 1008 iterator = args.pop(); |
786 | 1009 |
787 var collections = [this].concat(args).map($A); | 1010 var collections = [this].concat(args).map($A); |
788 return this.map(function(value, index) { | 1011 return this.map(function(value, index) { |
789 return iterator(collections.pluck(index)); | 1012 return iterator(collections.pluck(index)); |
790 }); | 1013 }); |
791 }, | 1014 } |
792 | 1015 |
793 size: function() { | 1016 function size() { |
794 return this.toArray().length; | 1017 return this.toArray().length; |
795 }, | 1018 } |
796 | 1019 |
797 inspect: function() { | 1020 function inspect() { |
798 return '#<Enumerable:' + this.toArray().inspect() + '>'; | 1021 return '#<Enumerable:' + this.toArray().inspect() + '>'; |
799 } | 1022 } |
800 }; | 1023 |
801 | 1024 |
802 Object.extend(Enumerable, { | 1025 |
803 map: Enumerable.collect, | 1026 |
804 find: Enumerable.detect, | 1027 |
805 select: Enumerable.findAll, | 1028 |
806 filter: Enumerable.findAll, | 1029 |
807 member: Enumerable.include, | 1030 |
808 entries: Enumerable.toArray, | 1031 |
809 every: Enumerable.all, | 1032 return { |
810 some: Enumerable.any | 1033 each: each, |
811 }); | 1034 eachSlice: eachSlice, |
| 1035 all: all, |
| 1036 every: all, |
| 1037 any: any, |
| 1038 some: any, |
| 1039 collect: collect, |
| 1040 map: collect, |
| 1041 detect: detect, |
| 1042 findAll: findAll, |
| 1043 select: findAll, |
| 1044 filter: findAll, |
| 1045 grep: grep, |
| 1046 include: include, |
| 1047 member: include, |
| 1048 inGroupsOf: inGroupsOf, |
| 1049 inject: inject, |
| 1050 invoke: invoke, |
| 1051 max: max, |
| 1052 min: min, |
| 1053 partition: partition, |
| 1054 pluck: pluck, |
| 1055 reject: reject, |
| 1056 sortBy: sortBy, |
| 1057 toArray: toArray, |
| 1058 entries: toArray, |
| 1059 zip: zip, |
| 1060 size: size, |
| 1061 inspect: inspect, |
| 1062 find: detect |
| 1063 }; |
| 1064 })(); |
| 1065 |
812 function $A(iterable) { | 1066 function $A(iterable) { |
813 if (!iterable) return []; | 1067 if (!iterable) return []; |
814 if (iterable.toArray) return iterable.toArray(); | 1068 if ('toArray' in Object(iterable)) return iterable.toArray(); |
815 var length = iterable.length || 0, results = new Array(length); | 1069 var length = iterable.length || 0, results = new Array(length); |
816 while (length--) results[length] = iterable[length]; | 1070 while (length--) results[length] = iterable[length]; |
817 return results; | 1071 return results; |
818 } | 1072 } |
819 | 1073 |
820 if (Prototype.Browser.WebKit) { | |
821 $A = function(iterable) { | |
822 if (!iterable) return []; | |
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(); | |
829 var length = iterable.length || 0, results = new Array(length); | |
830 while (length--) results[length] = iterable[length]; | |
831 return results; | |
832 }; | |
833 } | |
834 | |
835 Array.from = $A; | |
836 | |
837 Object.extend(Array.prototype, Enumerable); | |
838 | |
839 if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.revers
e; | |
840 | |
841 Object.extend(Array.prototype, { | |
842 _each: function(iterator) { | |
843 for (var i = 0, length = this.length; i < length; i++) | |
844 iterator(this[i]); | |
845 }, | |
846 | |
847 clear: function() { | |
848 this.length = 0; | |
849 return this; | |
850 }, | |
851 | |
852 first: function() { | |
853 return this[0]; | |
854 }, | |
855 | |
856 last: function() { | |
857 return this[this.length - 1]; | |
858 }, | |
859 | |
860 compact: function() { | |
861 return this.select(function(value) { | |
862 return value != null; | |
863 }); | |
864 }, | |
865 | |
866 flatten: function() { | |
867 return this.inject([], function(array, value) { | |
868 return array.concat(Object.isArray(value) ? | |
869 value.flatten() : [value]); | |
870 }); | |
871 }, | |
872 | |
873 without: function() { | |
874 var values = $A(arguments); | |
875 return this.select(function(value) { | |
876 return !values.include(value); | |
877 }); | |
878 }, | |
879 | |
880 reverse: function(inline) { | |
881 return (inline !== false ? this : this.toArray())._reverse(); | |
882 }, | |
883 | |
884 reduce: function() { | |
885 return this.length > 1 ? this : this[0]; | |
886 }, | |
887 | |
888 uniq: function(sorted) { | |
889 return this.inject([], function(array, value, index) { | |
890 if (0 == index || (sorted ? array.last() != value : !array.include(value))
) | |
891 array.push(value); | |
892 return array; | |
893 }); | |
894 }, | |
895 | |
896 intersect: function(array) { | |
897 return this.uniq().findAll(function(item) { | |
898 return array.detect(function(value) { return item === value }); | |
899 }); | |
900 }, | |
901 | |
902 clone: function() { | |
903 return [].concat(this); | |
904 }, | |
905 | |
906 size: function() { | |
907 return this.length; | |
908 }, | |
909 | |
910 inspect: function() { | |
911 return '[' + this.map(Object.inspect).join(', ') + ']'; | |
912 }, | |
913 | |
914 toJSON: function() { | |
915 var results = []; | |
916 this.each(function(object) { | |
917 var value = Object.toJSON(object); | |
918 if (!Object.isUndefined(value)) results.push(value); | |
919 }); | |
920 return '[' + results.join(', ') + ']'; | |
921 } | |
922 }); | |
923 | |
924 // use native browser JS 1.6 implementation if available | |
925 if (Object.isFunction(Array.prototype.forEach)) | |
926 Array.prototype._each = Array.prototype.forEach; | |
927 | |
928 if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) { | |
929 i || (i = 0); | |
930 var length = this.length; | |
931 if (i < 0) i = length + i; | |
932 for (; i < length; i++) | |
933 if (this[i] === item) return i; | |
934 return -1; | |
935 }; | |
936 | |
937 if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i
) { | |
938 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; | |
939 var n = this.slice(0, i).reverse().indexOf(item); | |
940 return (n < 0) ? n : i - n - 1; | |
941 }; | |
942 | |
943 Array.prototype.toArray = Array.prototype.clone; | |
944 | 1074 |
945 function $w(string) { | 1075 function $w(string) { |
946 if (!Object.isString(string)) return []; | 1076 if (!Object.isString(string)) return []; |
947 string = string.strip(); | 1077 string = string.strip(); |
948 return string ? string.split(/\s+/) : []; | 1078 return string ? string.split(/\s+/) : []; |
949 } | 1079 } |
950 | 1080 |
951 if (Prototype.Browser.Opera){ | 1081 Array.from = $A; |
952 Array.prototype.concat = function() { | 1082 |
953 var array = []; | 1083 |
954 for (var i = 0, length = this.length; i < length; i++) array.push(this[i]); | 1084 (function() { |
| 1085 var arrayProto = Array.prototype, |
| 1086 slice = arrayProto.slice, |
| 1087 _each = arrayProto.forEach; // use native browser JS 1.6 implementation if
available |
| 1088 |
| 1089 function each(iterator, context) { |
| 1090 for (var i = 0, length = this.length >>> 0; i < length; i++) { |
| 1091 if (i in this) iterator.call(context, this[i], i, this); |
| 1092 } |
| 1093 } |
| 1094 if (!_each) _each = each; |
| 1095 |
| 1096 function clear() { |
| 1097 this.length = 0; |
| 1098 return this; |
| 1099 } |
| 1100 |
| 1101 function first() { |
| 1102 return this[0]; |
| 1103 } |
| 1104 |
| 1105 function last() { |
| 1106 return this[this.length - 1]; |
| 1107 } |
| 1108 |
| 1109 function compact() { |
| 1110 return this.select(function(value) { |
| 1111 return value != null; |
| 1112 }); |
| 1113 } |
| 1114 |
| 1115 function flatten() { |
| 1116 return this.inject([], function(array, value) { |
| 1117 if (Object.isArray(value)) |
| 1118 return array.concat(value.flatten()); |
| 1119 array.push(value); |
| 1120 return array; |
| 1121 }); |
| 1122 } |
| 1123 |
| 1124 function without() { |
| 1125 var values = slice.call(arguments, 0); |
| 1126 return this.select(function(value) { |
| 1127 return !values.include(value); |
| 1128 }); |
| 1129 } |
| 1130 |
| 1131 function reverse(inline) { |
| 1132 return (inline === false ? this.toArray() : this)._reverse(); |
| 1133 } |
| 1134 |
| 1135 function uniq(sorted) { |
| 1136 return this.inject([], function(array, value, index) { |
| 1137 if (0 == index || (sorted ? array.last() != value : !array.include(value))
) |
| 1138 array.push(value); |
| 1139 return array; |
| 1140 }); |
| 1141 } |
| 1142 |
| 1143 function intersect(array) { |
| 1144 return this.uniq().findAll(function(item) { |
| 1145 return array.detect(function(value) { return item === value }); |
| 1146 }); |
| 1147 } |
| 1148 |
| 1149 |
| 1150 function clone() { |
| 1151 return slice.call(this, 0); |
| 1152 } |
| 1153 |
| 1154 function size() { |
| 1155 return this.length; |
| 1156 } |
| 1157 |
| 1158 function inspect() { |
| 1159 return '[' + this.map(Object.inspect).join(', ') + ']'; |
| 1160 } |
| 1161 |
| 1162 function indexOf(item, i) { |
| 1163 i || (i = 0); |
| 1164 var length = this.length; |
| 1165 if (i < 0) i = length + i; |
| 1166 for (; i < length; i++) |
| 1167 if (this[i] === item) return i; |
| 1168 return -1; |
| 1169 } |
| 1170 |
| 1171 function lastIndexOf(item, i) { |
| 1172 i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1; |
| 1173 var n = this.slice(0, i).reverse().indexOf(item); |
| 1174 return (n < 0) ? n : i - n - 1; |
| 1175 } |
| 1176 |
| 1177 function concat() { |
| 1178 var array = slice.call(this, 0), item; |
955 for (var i = 0, length = arguments.length; i < length; i++) { | 1179 for (var i = 0, length = arguments.length; i < length; i++) { |
956 if (Object.isArray(arguments[i])) { | 1180 item = arguments[i]; |
957 for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++) | 1181 if (Object.isArray(item) && !('callee' in item)) { |
958 array.push(arguments[i][j]); | 1182 for (var j = 0, arrayLength = item.length; j < arrayLength; j++) |
| 1183 array.push(item[j]); |
959 } else { | 1184 } else { |
960 array.push(arguments[i]); | 1185 array.push(item); |
961 } | 1186 } |
962 } | 1187 } |
963 return array; | 1188 return array; |
964 }; | 1189 } |
965 } | 1190 |
966 Object.extend(Number.prototype, { | 1191 Object.extend(arrayProto, Enumerable); |
967 toColorPart: function() { | 1192 |
968 return this.toPaddedString(2, 16); | 1193 if (!arrayProto._reverse) |
969 }, | 1194 arrayProto._reverse = arrayProto.reverse; |
970 | 1195 |
971 succ: function() { | 1196 Object.extend(arrayProto, { |
972 return this + 1; | 1197 _each: _each, |
973 }, | 1198 clear: clear, |
974 | 1199 first: first, |
975 times: function(iterator, context) { | 1200 last: last, |
976 $R(0, this, true).each(iterator, context); | 1201 compact: compact, |
977 return this; | 1202 flatten: flatten, |
978 }, | 1203 without: without, |
979 | 1204 reverse: reverse, |
980 toPaddedString: function(length, radix) { | 1205 uniq: uniq, |
981 var string = this.toString(radix || 10); | 1206 intersect: intersect, |
982 return '0'.times(length - string.length) + string; | 1207 clone: clone, |
983 }, | 1208 toArray: clone, |
984 | 1209 size: size, |
985 toJSON: function() { | 1210 inspect: inspect |
986 return isFinite(this) ? this.toString() : 'null'; | 1211 }); |
987 } | 1212 |
988 }); | 1213 var CONCAT_ARGUMENTS_BUGGY = (function() { |
989 | 1214 return [].concat(arguments)[0][0] !== 1; |
990 $w('abs round ceil floor').each(function(method){ | 1215 })(1,2) |
991 Number.prototype[method] = Math[method].methodize(); | 1216 |
992 }); | 1217 if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat; |
| 1218 |
| 1219 if (!arrayProto.indexOf) arrayProto.indexOf = indexOf; |
| 1220 if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf; |
| 1221 })(); |
993 function $H(object) { | 1222 function $H(object) { |
994 return new Hash(object); | 1223 return new Hash(object); |
995 }; | 1224 }; |
996 | 1225 |
997 var Hash = Class.create(Enumerable, (function() { | 1226 var Hash = Class.create(Enumerable, (function() { |
| 1227 function initialize(object) { |
| 1228 this._object = Object.isHash(object) ? object.toObject() : Object.clone(obje
ct); |
| 1229 } |
| 1230 |
| 1231 |
| 1232 function _each(iterator) { |
| 1233 for (var key in this._object) { |
| 1234 var value = this._object[key], pair = [key, value]; |
| 1235 pair.key = key; |
| 1236 pair.value = value; |
| 1237 iterator(pair); |
| 1238 } |
| 1239 } |
| 1240 |
| 1241 function set(key, value) { |
| 1242 return this._object[key] = value; |
| 1243 } |
| 1244 |
| 1245 function get(key) { |
| 1246 if (this._object[key] !== Object.prototype[key]) |
| 1247 return this._object[key]; |
| 1248 } |
| 1249 |
| 1250 function unset(key) { |
| 1251 var value = this._object[key]; |
| 1252 delete this._object[key]; |
| 1253 return value; |
| 1254 } |
| 1255 |
| 1256 function toObject() { |
| 1257 return Object.clone(this._object); |
| 1258 } |
| 1259 |
| 1260 |
| 1261 |
| 1262 function keys() { |
| 1263 return this.pluck('key'); |
| 1264 } |
| 1265 |
| 1266 function values() { |
| 1267 return this.pluck('value'); |
| 1268 } |
| 1269 |
| 1270 function index(value) { |
| 1271 var match = this.detect(function(pair) { |
| 1272 return pair.value === value; |
| 1273 }); |
| 1274 return match && match.key; |
| 1275 } |
| 1276 |
| 1277 function merge(object) { |
| 1278 return this.clone().update(object); |
| 1279 } |
| 1280 |
| 1281 function update(object) { |
| 1282 return new Hash(object).inject(this, function(result, pair) { |
| 1283 result.set(pair.key, pair.value); |
| 1284 return result; |
| 1285 }); |
| 1286 } |
998 | 1287 |
999 function toQueryPair(key, value) { | 1288 function toQueryPair(key, value) { |
1000 if (Object.isUndefined(value)) return key; | 1289 if (Object.isUndefined(value)) return key; |
1001 return key + '=' + encodeURIComponent(String.interpret(value)); | 1290 return key + '=' + encodeURIComponent(String.interpret(value)); |
1002 } | 1291 } |
1003 | 1292 |
| 1293 function toQueryString() { |
| 1294 return this.inject([], function(results, pair) { |
| 1295 var key = encodeURIComponent(pair.key), values = pair.value; |
| 1296 |
| 1297 if (values && typeof values == 'object') { |
| 1298 if (Object.isArray(values)) { |
| 1299 var queryValues = []; |
| 1300 for (var i = 0, len = values.length, value; i < len; i++) { |
| 1301 value = values[i]; |
| 1302 queryValues.push(toQueryPair(key, value)); |
| 1303 } |
| 1304 return results.concat(queryValues); |
| 1305 } |
| 1306 } else results.push(toQueryPair(key, values)); |
| 1307 return results; |
| 1308 }).join('&'); |
| 1309 } |
| 1310 |
| 1311 function inspect() { |
| 1312 return '#<Hash:{' + this.map(function(pair) { |
| 1313 return pair.map(Object.inspect).join(': '); |
| 1314 }).join(', ') + '}>'; |
| 1315 } |
| 1316 |
| 1317 function clone() { |
| 1318 return new Hash(this); |
| 1319 } |
| 1320 |
1004 return { | 1321 return { |
1005 initialize: function(object) { | 1322 initialize: initialize, |
1006 this._object = Object.isHash(object) ? object.toObject() : Object.clone(ob
ject); | 1323 _each: _each, |
1007 }, | 1324 set: set, |
1008 | 1325 get: get, |
1009 _each: function(iterator) { | 1326 unset: unset, |
1010 for (var key in this._object) { | 1327 toObject: toObject, |
1011 var value = this._object[key], pair = [key, value]; | 1328 toTemplateReplacements: toObject, |
1012 pair.key = key; | 1329 keys: keys, |
1013 pair.value = value; | 1330 values: values, |
1014 iterator(pair); | 1331 index: index, |
1015 } | 1332 merge: merge, |
1016 }, | 1333 update: update, |
1017 | 1334 toQueryString: toQueryString, |
1018 set: function(key, value) { | 1335 inspect: inspect, |
1019 return this._object[key] = value; | 1336 toJSON: toObject, |
1020 }, | 1337 clone: clone |
1021 | 1338 }; |
1022 get: function(key) { | |
1023 // simulating poorly supported hasOwnProperty | |
1024 if (this._object[key] !== Object.prototype[key]) | |
1025 return this._object[key]; | |
1026 }, | |
1027 | |
1028 unset: function(key) { | |
1029 var value = this._object[key]; | |
1030 delete this._object[key]; | |
1031 return value; | |
1032 }, | |
1033 | |
1034 toObject: function() { | |
1035 return Object.clone(this._object); | |
1036 }, | |
1037 | |
1038 keys: function() { | |
1039 return this.pluck('key'); | |
1040 }, | |
1041 | |
1042 values: function() { | |
1043 return this.pluck('value'); | |
1044 }, | |
1045 | |
1046 index: function(value) { | |
1047 var match = this.detect(function(pair) { | |
1048 return pair.value === value; | |
1049 }); | |
1050 return match && match.key; | |
1051 }, | |
1052 | |
1053 merge: function(object) { | |
1054 return this.clone().update(object); | |
1055 }, | |
1056 | |
1057 update: function(object) { | |
1058 return new Hash(object).inject(this, function(result, pair) { | |
1059 result.set(pair.key, pair.value); | |
1060 return result; | |
1061 }); | |
1062 }, | |
1063 | |
1064 toQueryString: function() { | |
1065 return this.inject([], function(results, pair) { | |
1066 var key = encodeURIComponent(pair.key), values = pair.value; | |
1067 | |
1068 if (values && typeof values == 'object') { | |
1069 if (Object.isArray(values)) | |
1070 return results.concat(values.map(toQueryPair.curry(key))); | |
1071 } else results.push(toQueryPair(key, values)); | |
1072 return results; | |
1073 }).join('&'); | |
1074 }, | |
1075 | |
1076 inspect: function() { | |
1077 return '#<Hash:{' + this.map(function(pair) { | |
1078 return pair.map(Object.inspect).join(': '); | |
1079 }).join(', ') + '}>'; | |
1080 }, | |
1081 | |
1082 toJSON: function() { | |
1083 return Object.toJSON(this.toObject()); | |
1084 }, | |
1085 | |
1086 clone: function() { | |
1087 return new Hash(this); | |
1088 } | |
1089 } | |
1090 })()); | 1339 })()); |
1091 | 1340 |
1092 Hash.prototype.toTemplateReplacements = Hash.prototype.toObject; | |
1093 Hash.from = $H; | 1341 Hash.from = $H; |
1094 var ObjectRange = Class.create(Enumerable, { | 1342 Object.extend(Number.prototype, (function() { |
1095 initialize: function(start, end, exclusive) { | 1343 function toColorPart() { |
| 1344 return this.toPaddedString(2, 16); |
| 1345 } |
| 1346 |
| 1347 function succ() { |
| 1348 return this + 1; |
| 1349 } |
| 1350 |
| 1351 function times(iterator, context) { |
| 1352 $R(0, this, true).each(iterator, context); |
| 1353 return this; |
| 1354 } |
| 1355 |
| 1356 function toPaddedString(length, radix) { |
| 1357 var string = this.toString(radix || 10); |
| 1358 return '0'.times(length - string.length) + string; |
| 1359 } |
| 1360 |
| 1361 function abs() { |
| 1362 return Math.abs(this); |
| 1363 } |
| 1364 |
| 1365 function round() { |
| 1366 return Math.round(this); |
| 1367 } |
| 1368 |
| 1369 function ceil() { |
| 1370 return Math.ceil(this); |
| 1371 } |
| 1372 |
| 1373 function floor() { |
| 1374 return Math.floor(this); |
| 1375 } |
| 1376 |
| 1377 return { |
| 1378 toColorPart: toColorPart, |
| 1379 succ: succ, |
| 1380 times: times, |
| 1381 toPaddedString: toPaddedString, |
| 1382 abs: abs, |
| 1383 round: round, |
| 1384 ceil: ceil, |
| 1385 floor: floor |
| 1386 }; |
| 1387 })()); |
| 1388 |
| 1389 function $R(start, end, exclusive) { |
| 1390 return new ObjectRange(start, end, exclusive); |
| 1391 } |
| 1392 |
| 1393 var ObjectRange = Class.create(Enumerable, (function() { |
| 1394 function initialize(start, end, exclusive) { |
1096 this.start = start; | 1395 this.start = start; |
1097 this.end = end; | 1396 this.end = end; |
1098 this.exclusive = exclusive; | 1397 this.exclusive = exclusive; |
1099 }, | 1398 } |
1100 | 1399 |
1101 _each: function(iterator) { | 1400 function _each(iterator) { |
1102 var value = this.start; | 1401 var value = this.start; |
1103 while (this.include(value)) { | 1402 while (this.include(value)) { |
1104 iterator(value); | 1403 iterator(value); |
1105 value = value.succ(); | 1404 value = value.succ(); |
1106 } | 1405 } |
1107 }, | 1406 } |
1108 | 1407 |
1109 include: function(value) { | 1408 function include(value) { |
1110 if (value < this.start) | 1409 if (value < this.start) |
1111 return false; | 1410 return false; |
1112 if (this.exclusive) | 1411 if (this.exclusive) |
1113 return value < this.end; | 1412 return value < this.end; |
1114 return value <= this.end; | 1413 return value <= this.end; |
1115 } | 1414 } |
1116 }); | 1415 |
1117 | 1416 return { |
1118 var $R = function(start, end, exclusive) { | 1417 initialize: initialize, |
1119 return new ObjectRange(start, end, exclusive); | 1418 _each: _each, |
1120 }; | 1419 include: include |
| 1420 }; |
| 1421 })()); |
| 1422 |
| 1423 |
1121 | 1424 |
1122 var Ajax = { | 1425 var Ajax = { |
1123 getTransport: function() { | 1426 getTransport: function() { |
1124 return Try.these( | 1427 return Try.these( |
1125 function() {return new XMLHttpRequest()}, | 1428 function() {return new XMLHttpRequest()}, |
1126 function() {return new ActiveXObject('Msxml2.XMLHTTP')}, | 1429 function() {return new ActiveXObject('Msxml2.XMLHTTP')}, |
1127 function() {return new ActiveXObject('Microsoft.XMLHTTP')} | 1430 function() {return new ActiveXObject('Microsoft.XMLHTTP')} |
1128 ) || false; | 1431 ) || false; |
1129 }, | 1432 }, |
1130 | 1433 |
(...skipping 26 matching lines...) Expand all Loading... |
1157 }); | 1460 }); |
1158 } | 1461 } |
1159 }; | 1462 }; |
1160 | 1463 |
1161 Object.extend(Ajax.Responders, Enumerable); | 1464 Object.extend(Ajax.Responders, Enumerable); |
1162 | 1465 |
1163 Ajax.Responders.register({ | 1466 Ajax.Responders.register({ |
1164 onCreate: function() { Ajax.activeRequestCount++ }, | 1467 onCreate: function() { Ajax.activeRequestCount++ }, |
1165 onComplete: function() { Ajax.activeRequestCount-- } | 1468 onComplete: function() { Ajax.activeRequestCount-- } |
1166 }); | 1469 }); |
1167 | |
1168 Ajax.Base = Class.create({ | 1470 Ajax.Base = Class.create({ |
1169 initialize: function(options) { | 1471 initialize: function(options) { |
1170 this.options = { | 1472 this.options = { |
1171 method: 'post', | 1473 method: 'post', |
1172 asynchronous: true, | 1474 asynchronous: true, |
1173 contentType: 'application/x-www-form-urlencoded', | 1475 contentType: 'application/x-www-form-urlencoded', |
1174 encoding: 'UTF-8', | 1476 encoding: 'UTF-8', |
1175 parameters: '', | 1477 parameters: '', |
1176 evalJSON: true, | 1478 evalJSON: true, |
1177 evalJS: true | 1479 evalJS: true |
1178 }; | 1480 }; |
1179 Object.extend(this.options, options || { }); | 1481 Object.extend(this.options, options || { }); |
1180 | 1482 |
1181 this.options.method = this.options.method.toLowerCase(); | 1483 this.options.method = this.options.method.toLowerCase(); |
1182 | 1484 |
1183 if (Object.isString(this.options.parameters)) | 1485 if (Object.isHash(this.options.parameters)) |
1184 this.options.parameters = this.options.parameters.toQueryParams(); | |
1185 else if (Object.isHash(this.options.parameters)) | |
1186 this.options.parameters = this.options.parameters.toObject(); | 1486 this.options.parameters = this.options.parameters.toObject(); |
1187 } | 1487 } |
1188 }); | 1488 }); |
1189 | |
1190 Ajax.Request = Class.create(Ajax.Base, { | 1489 Ajax.Request = Class.create(Ajax.Base, { |
1191 _complete: false, | 1490 _complete: false, |
1192 | 1491 |
1193 initialize: function($super, url, options) { | 1492 initialize: function($super, url, options) { |
1194 $super(options); | 1493 $super(options); |
1195 this.transport = Ajax.getTransport(); | 1494 this.transport = Ajax.getTransport(); |
1196 this.request(url); | 1495 this.request(url); |
1197 }, | 1496 }, |
1198 | 1497 |
1199 request: function(url) { | 1498 request: function(url) { |
1200 this.url = url; | 1499 this.url = url; |
1201 this.method = this.options.method; | 1500 this.method = this.options.method; |
1202 var params = Object.clone(this.options.parameters); | 1501 var params = Object.isString(this.options.parameters) ? |
| 1502 this.options.parameters : |
| 1503 Object.toQueryString(this.options.parameters); |
1203 | 1504 |
1204 if (!['get', 'post'].include(this.method)) { | 1505 if (!['get', 'post'].include(this.method)) { |
1205 // simulate other verbs over post | 1506 params += (params ? '&' : '') + "_method=" + this.method; |
1206 params['_method'] = this.method; | |
1207 this.method = 'post'; | 1507 this.method = 'post'; |
1208 } | 1508 } |
1209 | 1509 |
1210 this.parameters = params; | 1510 if (params && this.method === 'get') { |
| 1511 this.url += (this.url.include('?') ? '&' : '?') + params; |
| 1512 } |
1211 | 1513 |
1212 if (params = Object.toQueryString(params)) { | 1514 this.parameters = params.toQueryParams(); |
1213 // when GET, append parameters to URL | |
1214 if (this.method == 'get') | |
1215 this.url += (this.url.include('?') ? '&' : '?') + params; | |
1216 else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) | |
1217 params += '&_='; | |
1218 } | |
1219 | 1515 |
1220 try { | 1516 try { |
1221 var response = new Ajax.Response(this); | 1517 var response = new Ajax.Response(this); |
1222 if (this.options.onCreate) this.options.onCreate(response); | 1518 if (this.options.onCreate) this.options.onCreate(response); |
1223 Ajax.Responders.dispatch('onCreate', this, response); | 1519 Ajax.Responders.dispatch('onCreate', this, response); |
1224 | 1520 |
1225 this.transport.open(this.method.toUpperCase(), this.url, | 1521 this.transport.open(this.method.toUpperCase(), this.url, |
1226 this.options.asynchronous); | 1522 this.options.asynchronous); |
1227 | 1523 |
1228 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1
); | 1524 if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1
); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 | 1558 |
1263 /* Force "Connection: close" for older Mozilla browsers to work | 1559 /* Force "Connection: close" for older Mozilla browsers to work |
1264 * around a bug where XMLHttpRequest sends an incorrect | 1560 * around a bug where XMLHttpRequest sends an incorrect |
1265 * Content-length header. See Mozilla Bugzilla #246651. | 1561 * Content-length header. See Mozilla Bugzilla #246651. |
1266 */ | 1562 */ |
1267 if (this.transport.overrideMimeType && | 1563 if (this.transport.overrideMimeType && |
1268 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) | 1564 (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005) |
1269 headers['Connection'] = 'close'; | 1565 headers['Connection'] = 'close'; |
1270 } | 1566 } |
1271 | 1567 |
1272 // user-defined headers | |
1273 if (typeof this.options.requestHeaders == 'object') { | 1568 if (typeof this.options.requestHeaders == 'object') { |
1274 var extras = this.options.requestHeaders; | 1569 var extras = this.options.requestHeaders; |
1275 | 1570 |
1276 if (Object.isFunction(extras.push)) | 1571 if (Object.isFunction(extras.push)) |
1277 for (var i = 0, length = extras.length; i < length; i += 2) | 1572 for (var i = 0, length = extras.length; i < length; i += 2) |
1278 headers[extras[i]] = extras[i+1]; | 1573 headers[extras[i]] = extras[i+1]; |
1279 else | 1574 else |
1280 $H(extras).each(function(pair) { headers[pair.key] = pair.value }); | 1575 $H(extras).each(function(pair) { headers[pair.key] = pair.value }); |
1281 } | 1576 } |
1282 | 1577 |
1283 for (var name in headers) | 1578 for (var name in headers) |
1284 this.transport.setRequestHeader(name, headers[name]); | 1579 this.transport.setRequestHeader(name, headers[name]); |
1285 }, | 1580 }, |
1286 | 1581 |
1287 success: function() { | 1582 success: function() { |
1288 var status = this.getStatus(); | 1583 var status = this.getStatus(); |
1289 return !status || (status >= 200 && status < 300); | 1584 return !status || (status >= 200 && status < 300) || status == 304; |
1290 }, | 1585 }, |
1291 | 1586 |
1292 getStatus: function() { | 1587 getStatus: function() { |
1293 try { | 1588 try { |
| 1589 if (this.transport.status === 1223) return 204; |
1294 return this.transport.status || 0; | 1590 return this.transport.status || 0; |
1295 } catch (e) { return 0 } | 1591 } catch (e) { return 0 } |
1296 }, | 1592 }, |
1297 | 1593 |
1298 respondToReadyState: function(readyState) { | 1594 respondToReadyState: function(readyState) { |
1299 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(th
is); | 1595 var state = Ajax.Request.Events[readyState], response = new Ajax.Response(th
is); |
1300 | 1596 |
1301 if (state == 'Complete') { | 1597 if (state == 'Complete') { |
1302 try { | 1598 try { |
1303 this._complete = true; | 1599 this._complete = true; |
(...skipping 12 matching lines...) Expand all Loading... |
1316 } | 1612 } |
1317 | 1613 |
1318 try { | 1614 try { |
1319 (this.options['on' + state] || Prototype.emptyFunction)(response, response
.headerJSON); | 1615 (this.options['on' + state] || Prototype.emptyFunction)(response, response
.headerJSON); |
1320 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON
); | 1616 Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON
); |
1321 } catch (e) { | 1617 } catch (e) { |
1322 this.dispatchException(e); | 1618 this.dispatchException(e); |
1323 } | 1619 } |
1324 | 1620 |
1325 if (state == 'Complete') { | 1621 if (state == 'Complete') { |
1326 // avoid memory leak in MSIE: clean up | |
1327 this.transport.onreadystatechange = Prototype.emptyFunction; | 1622 this.transport.onreadystatechange = Prototype.emptyFunction; |
1328 } | 1623 } |
1329 }, | 1624 }, |
1330 | 1625 |
1331 isSameOrigin: function() { | 1626 isSameOrigin: function() { |
1332 var m = this.url.match(/^\s*https?:\/\/[^\/]*/); | 1627 var m = this.url.match(/^\s*https?:\/\/[^\/]*/); |
1333 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ | 1628 return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({ |
1334 protocol: location.protocol, | 1629 protocol: location.protocol, |
1335 domain: document.domain, | 1630 domain: document.domain, |
1336 port: location.port ? ':' + location.port : '' | 1631 port: location.port ? ':' + location.port : '' |
1337 })); | 1632 })); |
1338 }, | 1633 }, |
1339 | 1634 |
1340 getHeader: function(name) { | 1635 getHeader: function(name) { |
1341 try { | 1636 try { |
1342 return this.transport.getResponseHeader(name) || null; | 1637 return this.transport.getResponseHeader(name) || null; |
1343 } catch (e) { return null } | 1638 } catch (e) { return null; } |
1344 }, | 1639 }, |
1345 | 1640 |
1346 evalResponse: function() { | 1641 evalResponse: function() { |
1347 try { | 1642 try { |
1348 return eval((this.transport.responseText || '').unfilterJSON()); | 1643 return eval((this.transport.responseText || '').unfilterJSON()); |
1349 } catch (e) { | 1644 } catch (e) { |
1350 this.dispatchException(e); | 1645 this.dispatchException(e); |
1351 } | 1646 } |
1352 }, | 1647 }, |
1353 | 1648 |
1354 dispatchException: function(exception) { | 1649 dispatchException: function(exception) { |
1355 (this.options.onException || Prototype.emptyFunction)(this, exception); | 1650 (this.options.onException || Prototype.emptyFunction)(this, exception); |
1356 Ajax.Responders.dispatch('onException', this, exception); | 1651 Ajax.Responders.dispatch('onException', this, exception); |
1357 } | 1652 } |
1358 }); | 1653 }); |
1359 | 1654 |
1360 Ajax.Request.Events = | 1655 Ajax.Request.Events = |
1361 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; | 1656 ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete']; |
1362 | 1657 |
| 1658 |
| 1659 |
| 1660 |
| 1661 |
| 1662 |
| 1663 |
| 1664 |
1363 Ajax.Response = Class.create({ | 1665 Ajax.Response = Class.create({ |
1364 initialize: function(request){ | 1666 initialize: function(request){ |
1365 this.request = request; | 1667 this.request = request; |
1366 var transport = this.transport = request.transport, | 1668 var transport = this.transport = request.transport, |
1367 readyState = this.readyState = transport.readyState; | 1669 readyState = this.readyState = transport.readyState; |
1368 | 1670 |
1369 if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { | 1671 if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) { |
1370 this.status = this.getStatus(); | 1672 this.status = this.getStatus(); |
1371 this.statusText = this.getStatusText(); | 1673 this.statusText = this.getStatusText(); |
1372 this.responseText = String.interpret(transport.responseText); | 1674 this.responseText = String.interpret(transport.responseText); |
1373 this.headerJSON = this._getHeaderJSON(); | 1675 this.headerJSON = this._getHeaderJSON(); |
1374 } | 1676 } |
1375 | 1677 |
1376 if(readyState == 4) { | 1678 if (readyState == 4) { |
1377 var xml = transport.responseXML; | 1679 var xml = transport.responseXML; |
1378 this.responseXML = Object.isUndefined(xml) ? null : xml; | 1680 this.responseXML = Object.isUndefined(xml) ? null : xml; |
1379 this.responseJSON = this._getResponseJSON(); | 1681 this.responseJSON = this._getResponseJSON(); |
1380 } | 1682 } |
1381 }, | 1683 }, |
1382 | 1684 |
1383 status: 0, | 1685 status: 0, |
| 1686 |
1384 statusText: '', | 1687 statusText: '', |
1385 | 1688 |
1386 getStatus: Ajax.Request.prototype.getStatus, | 1689 getStatus: Ajax.Request.prototype.getStatus, |
1387 | 1690 |
1388 getStatusText: function() { | 1691 getStatusText: function() { |
1389 try { | 1692 try { |
1390 return this.transport.statusText || ''; | 1693 return this.transport.statusText || ''; |
1391 } catch (e) { return '' } | 1694 } catch (e) { return '' } |
1392 }, | 1695 }, |
1393 | 1696 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1503 | 1806 |
1504 this.lastText = response.responseText; | 1807 this.lastText = response.responseText; |
1505 } | 1808 } |
1506 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency)
; | 1809 this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency)
; |
1507 }, | 1810 }, |
1508 | 1811 |
1509 onTimerEvent: function() { | 1812 onTimerEvent: function() { |
1510 this.updater = new Ajax.Updater(this.container, this.url, this.options); | 1813 this.updater = new Ajax.Updater(this.container, this.url, this.options); |
1511 } | 1814 } |
1512 }); | 1815 }); |
| 1816 |
| 1817 |
1513 function $(element) { | 1818 function $(element) { |
1514 if (arguments.length > 1) { | 1819 if (arguments.length > 1) { |
1515 for (var i = 0, elements = [], length = arguments.length; i < length; i++) | 1820 for (var i = 0, elements = [], length = arguments.length; i < length; i++) |
1516 elements.push($(arguments[i])); | 1821 elements.push($(arguments[i])); |
1517 return elements; | 1822 return elements; |
1518 } | 1823 } |
1519 if (Object.isString(element)) | 1824 if (Object.isString(element)) |
1520 element = document.getElementById(element); | 1825 element = document.getElementById(element); |
1521 return Element.extend(element); | 1826 return Element.extend(element); |
1522 } | 1827 } |
1523 | 1828 |
1524 if (Prototype.BrowserFeatures.XPath) { | 1829 if (Prototype.BrowserFeatures.XPath) { |
1525 document._getElementsByXPath = function(expression, parentElement) { | 1830 document._getElementsByXPath = function(expression, parentElement) { |
1526 var results = []; | 1831 var results = []; |
1527 var query = document.evaluate(expression, $(parentElement) || document, | 1832 var query = document.evaluate(expression, $(parentElement) || document, |
1528 null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); | 1833 null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); |
1529 for (var i = 0, length = query.snapshotLength; i < length; i++) | 1834 for (var i = 0, length = query.snapshotLength; i < length; i++) |
1530 results.push(Element.extend(query.snapshotItem(i))); | 1835 results.push(Element.extend(query.snapshotItem(i))); |
1531 return results; | 1836 return results; |
1532 }; | 1837 }; |
1533 } | 1838 } |
1534 | 1839 |
1535 /*--------------------------------------------------------------------------*/ | 1840 /*--------------------------------------------------------------------------*/ |
1536 | 1841 |
1537 if (!window.Node) var Node = { }; | 1842 if (!Node) var Node = { }; |
1538 | 1843 |
1539 if (!Node.ELEMENT_NODE) { | 1844 if (!Node.ELEMENT_NODE) { |
1540 // DOM level 2 ECMAScript Language Binding | |
1541 Object.extend(Node, { | 1845 Object.extend(Node, { |
1542 ELEMENT_NODE: 1, | 1846 ELEMENT_NODE: 1, |
1543 ATTRIBUTE_NODE: 2, | 1847 ATTRIBUTE_NODE: 2, |
1544 TEXT_NODE: 3, | 1848 TEXT_NODE: 3, |
1545 CDATA_SECTION_NODE: 4, | 1849 CDATA_SECTION_NODE: 4, |
1546 ENTITY_REFERENCE_NODE: 5, | 1850 ENTITY_REFERENCE_NODE: 5, |
1547 ENTITY_NODE: 6, | 1851 ENTITY_NODE: 6, |
1548 PROCESSING_INSTRUCTION_NODE: 7, | 1852 PROCESSING_INSTRUCTION_NODE: 7, |
1549 COMMENT_NODE: 8, | 1853 COMMENT_NODE: 8, |
1550 DOCUMENT_NODE: 9, | 1854 DOCUMENT_NODE: 9, |
1551 DOCUMENT_TYPE_NODE: 10, | 1855 DOCUMENT_TYPE_NODE: 10, |
1552 DOCUMENT_FRAGMENT_NODE: 11, | 1856 DOCUMENT_FRAGMENT_NODE: 11, |
1553 NOTATION_NODE: 12 | 1857 NOTATION_NODE: 12 |
1554 }); | 1858 }); |
1555 } | 1859 } |
1556 | 1860 |
1557 (function() { | 1861 |
1558 var element = this.Element; | 1862 |
1559 this.Element = function(tagName, attributes) { | 1863 (function(global) { |
| 1864 function shouldUseCache(tagName, attributes) { |
| 1865 if (tagName === 'select') return false; |
| 1866 if ('type' in attributes) return false; |
| 1867 return true; |
| 1868 } |
| 1869 |
| 1870 var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){ |
| 1871 try { |
| 1872 var el = document.createElement('<input name="x">'); |
| 1873 return el.tagName.toLowerCase() === 'input' && el.name === 'x'; |
| 1874 } |
| 1875 catch(err) { |
| 1876 return false; |
| 1877 } |
| 1878 })(); |
| 1879 |
| 1880 var element = global.Element; |
| 1881 |
| 1882 global.Element = function(tagName, attributes) { |
1560 attributes = attributes || { }; | 1883 attributes = attributes || { }; |
1561 tagName = tagName.toLowerCase(); | 1884 tagName = tagName.toLowerCase(); |
1562 var cache = Element.cache; | 1885 var cache = Element.cache; |
1563 if (Prototype.Browser.IE && attributes.name) { | 1886 |
| 1887 if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) { |
1564 tagName = '<' + tagName + ' name="' + attributes.name + '">'; | 1888 tagName = '<' + tagName + ' name="' + attributes.name + '">'; |
1565 delete attributes.name; | 1889 delete attributes.name; |
1566 return Element.writeAttribute(document.createElement(tagName), attributes)
; | 1890 return Element.writeAttribute(document.createElement(tagName), attributes)
; |
1567 } | 1891 } |
| 1892 |
1568 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(
tagName)); | 1893 if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(
tagName)); |
1569 return Element.writeAttribute(cache[tagName].cloneNode(false), attributes); | 1894 |
| 1895 var node = shouldUseCache(tagName, attributes) ? |
| 1896 cache[tagName].cloneNode(false) : document.createElement(tagName); |
| 1897 |
| 1898 return Element.writeAttribute(node, attributes); |
1570 }; | 1899 }; |
1571 Object.extend(this.Element, element || { }); | |
1572 if (element) this.Element.prototype = element.prototype; | |
1573 }).call(window); | |
1574 | 1900 |
| 1901 Object.extend(global.Element, element || { }); |
| 1902 if (element) global.Element.prototype = element.prototype; |
| 1903 |
| 1904 })(this); |
| 1905 |
| 1906 Element.idCounter = 1; |
1575 Element.cache = { }; | 1907 Element.cache = { }; |
1576 | 1908 |
| 1909 Element._purgeElement = function(element) { |
| 1910 var uid = element._prototypeUID; |
| 1911 if (uid) { |
| 1912 Element.stopObserving(element); |
| 1913 element._prototypeUID = void 0; |
| 1914 delete Element.Storage[uid]; |
| 1915 } |
| 1916 } |
| 1917 |
1577 Element.Methods = { | 1918 Element.Methods = { |
1578 visible: function(element) { | 1919 visible: function(element) { |
1579 return $(element).style.display != 'none'; | 1920 return $(element).style.display != 'none'; |
1580 }, | 1921 }, |
1581 | 1922 |
1582 toggle: function(element) { | 1923 toggle: function(element) { |
1583 element = $(element); | 1924 element = $(element); |
1584 Element[Element.visible(element) ? 'hide' : 'show'](element); | 1925 Element[Element.visible(element) ? 'hide' : 'show'](element); |
1585 return element; | 1926 return element; |
1586 }, | 1927 }, |
1587 | 1928 |
1588 hide: function(element) { | 1929 hide: function(element) { |
1589 element = $(element); | 1930 element = $(element); |
1590 element.style.display = 'none'; | 1931 element.style.display = 'none'; |
1591 return element; | 1932 return element; |
1592 }, | 1933 }, |
1593 | 1934 |
1594 show: function(element) { | 1935 show: function(element) { |
1595 element = $(element); | 1936 element = $(element); |
1596 element.style.display = ''; | 1937 element.style.display = ''; |
1597 return element; | 1938 return element; |
1598 }, | 1939 }, |
1599 | 1940 |
1600 remove: function(element) { | 1941 remove: function(element) { |
1601 element = $(element); | 1942 element = $(element); |
1602 element.parentNode.removeChild(element); | 1943 element.parentNode.removeChild(element); |
1603 return element; | 1944 return element; |
1604 }, | 1945 }, |
1605 | 1946 |
1606 update: function(element, content) { | 1947 update: (function(){ |
1607 element = $(element); | 1948 |
1608 if (content && content.toElement) content = content.toElement(); | 1949 var SELECT_ELEMENT_INNERHTML_BUGGY = (function(){ |
1609 if (Object.isElement(content)) return element.update().insert(content); | 1950 var el = document.createElement("select"), |
1610 content = Object.toHTML(content); | 1951 isBuggy = true; |
1611 element.innerHTML = content.stripScripts(); | 1952 el.innerHTML = "<option value=\"test\">test</option>"; |
1612 content.evalScripts.bind(content).defer(); | 1953 if (el.options && el.options[0]) { |
1613 return element; | 1954 isBuggy = el.options[0].nodeName.toUpperCase() !== "OPTION"; |
1614 }, | 1955 } |
| 1956 el = null; |
| 1957 return isBuggy; |
| 1958 })(); |
| 1959 |
| 1960 var TABLE_ELEMENT_INNERHTML_BUGGY = (function(){ |
| 1961 try { |
| 1962 var el = document.createElement("table"); |
| 1963 if (el && el.tBodies) { |
| 1964 el.innerHTML = "<tbody><tr><td>test</td></tr></tbody>"; |
| 1965 var isBuggy = typeof el.tBodies[0] == "undefined"; |
| 1966 el = null; |
| 1967 return isBuggy; |
| 1968 } |
| 1969 } catch (e) { |
| 1970 return true; |
| 1971 } |
| 1972 })(); |
| 1973 |
| 1974 var LINK_ELEMENT_INNERHTML_BUGGY = (function() { |
| 1975 try { |
| 1976 var el = document.createElement('div'); |
| 1977 el.innerHTML = "<link>"; |
| 1978 var isBuggy = (el.childNodes.length === 0); |
| 1979 el = null; |
| 1980 return isBuggy; |
| 1981 } catch(e) { |
| 1982 return true; |
| 1983 } |
| 1984 })(); |
| 1985 |
| 1986 var ANY_INNERHTML_BUGGY = SELECT_ELEMENT_INNERHTML_BUGGY || |
| 1987 TABLE_ELEMENT_INNERHTML_BUGGY || LINK_ELEMENT_INNERHTML_BUGGY; |
| 1988 |
| 1989 var SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING = (function () { |
| 1990 var s = document.createElement("script"), |
| 1991 isBuggy = false; |
| 1992 try { |
| 1993 s.appendChild(document.createTextNode("")); |
| 1994 isBuggy = !s.firstChild || |
| 1995 s.firstChild && s.firstChild.nodeType !== 3; |
| 1996 } catch (e) { |
| 1997 isBuggy = true; |
| 1998 } |
| 1999 s = null; |
| 2000 return isBuggy; |
| 2001 })(); |
| 2002 |
| 2003 |
| 2004 function update(element, content) { |
| 2005 element = $(element); |
| 2006 var purgeElement = Element._purgeElement; |
| 2007 |
| 2008 var descendants = element.getElementsByTagName('*'), |
| 2009 i = descendants.length; |
| 2010 while (i--) purgeElement(descendants[i]); |
| 2011 |
| 2012 if (content && content.toElement) |
| 2013 content = content.toElement(); |
| 2014 |
| 2015 if (Object.isElement(content)) |
| 2016 return element.update().insert(content); |
| 2017 |
| 2018 content = Object.toHTML(content); |
| 2019 |
| 2020 var tagName = element.tagName.toUpperCase(); |
| 2021 |
| 2022 if (tagName === 'SCRIPT' && SCRIPT_ELEMENT_REJECTS_TEXTNODE_APPENDING) { |
| 2023 element.text = content; |
| 2024 return element; |
| 2025 } |
| 2026 |
| 2027 if (ANY_INNERHTML_BUGGY) { |
| 2028 if (tagName in Element._insertionTranslations.tags) { |
| 2029 while (element.firstChild) { |
| 2030 element.removeChild(element.firstChild); |
| 2031 } |
| 2032 Element._getContentFromAnonymousElement(tagName, content.stripScripts(
)) |
| 2033 .each(function(node) { |
| 2034 element.appendChild(node) |
| 2035 }); |
| 2036 } else if (LINK_ELEMENT_INNERHTML_BUGGY && Object.isString(content) && c
ontent.indexOf('<link') > -1) { |
| 2037 while (element.firstChild) { |
| 2038 element.removeChild(element.firstChild); |
| 2039 } |
| 2040 var nodes = Element._getContentFromAnonymousElement(tagName, content.s
tripScripts(), true); |
| 2041 nodes.each(function(node) { element.appendChild(node) }); |
| 2042 } |
| 2043 else { |
| 2044 element.innerHTML = content.stripScripts(); |
| 2045 } |
| 2046 } |
| 2047 else { |
| 2048 element.innerHTML = content.stripScripts(); |
| 2049 } |
| 2050 |
| 2051 content.evalScripts.bind(content).defer(); |
| 2052 return element; |
| 2053 } |
| 2054 |
| 2055 return update; |
| 2056 })(), |
1615 | 2057 |
1616 replace: function(element, content) { | 2058 replace: function(element, content) { |
1617 element = $(element); | 2059 element = $(element); |
1618 if (content && content.toElement) content = content.toElement(); | 2060 if (content && content.toElement) content = content.toElement(); |
1619 else if (!Object.isElement(content)) { | 2061 else if (!Object.isElement(content)) { |
1620 content = Object.toHTML(content); | 2062 content = Object.toHTML(content); |
1621 var range = element.ownerDocument.createRange(); | 2063 var range = element.ownerDocument.createRange(); |
1622 range.selectNode(element); | 2064 range.selectNode(element); |
1623 content.evalScripts.bind(content).defer(); | 2065 content.evalScripts.bind(content).defer(); |
1624 content = range.createContextualFragment(content.stripScripts()); | 2066 content = range.createContextualFragment(content.stripScripts()); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1672 if (element.parentNode) | 2114 if (element.parentNode) |
1673 element.parentNode.replaceChild(wrapper, element); | 2115 element.parentNode.replaceChild(wrapper, element); |
1674 wrapper.appendChild(element); | 2116 wrapper.appendChild(element); |
1675 return wrapper; | 2117 return wrapper; |
1676 }, | 2118 }, |
1677 | 2119 |
1678 inspect: function(element) { | 2120 inspect: function(element) { |
1679 element = $(element); | 2121 element = $(element); |
1680 var result = '<' + element.tagName.toLowerCase(); | 2122 var result = '<' + element.tagName.toLowerCase(); |
1681 $H({'id': 'id', 'className': 'class'}).each(function(pair) { | 2123 $H({'id': 'id', 'className': 'class'}).each(function(pair) { |
1682 var property = pair.first(), attribute = pair.last(); | 2124 var property = pair.first(), |
1683 var value = (element[property] || '').toString(); | 2125 attribute = pair.last(), |
| 2126 value = (element[property] || '').toString(); |
1684 if (value) result += ' ' + attribute + '=' + value.inspect(true); | 2127 if (value) result += ' ' + attribute + '=' + value.inspect(true); |
1685 }); | 2128 }); |
1686 return result + '>'; | 2129 return result + '>'; |
1687 }, | 2130 }, |
1688 | 2131 |
1689 recursivelyCollect: function(element, property) { | 2132 recursivelyCollect: function(element, property, maximumLength) { |
1690 element = $(element); | 2133 element = $(element); |
| 2134 maximumLength = maximumLength || -1; |
1691 var elements = []; | 2135 var elements = []; |
1692 while (element = element[property]) | 2136 |
| 2137 while (element = element[property]) { |
1693 if (element.nodeType == 1) | 2138 if (element.nodeType == 1) |
1694 elements.push(Element.extend(element)); | 2139 elements.push(Element.extend(element)); |
| 2140 if (elements.length == maximumLength) |
| 2141 break; |
| 2142 } |
| 2143 |
1695 return elements; | 2144 return elements; |
1696 }, | 2145 }, |
1697 | 2146 |
1698 ancestors: function(element) { | 2147 ancestors: function(element) { |
1699 return $(element).recursivelyCollect('parentNode'); | 2148 return Element.recursivelyCollect(element, 'parentNode'); |
1700 }, | 2149 }, |
1701 | 2150 |
1702 descendants: function(element) { | 2151 descendants: function(element) { |
1703 return $(element).select("*"); | 2152 return Element.select(element, "*"); |
1704 }, | 2153 }, |
1705 | 2154 |
1706 firstDescendant: function(element) { | 2155 firstDescendant: function(element) { |
1707 element = $(element).firstChild; | 2156 element = $(element).firstChild; |
1708 while (element && element.nodeType != 1) element = element.nextSibling; | 2157 while (element && element.nodeType != 1) element = element.nextSibling; |
1709 return $(element); | 2158 return $(element); |
1710 }, | 2159 }, |
1711 | 2160 |
1712 immediateDescendants: function(element) { | 2161 immediateDescendants: function(element) { |
1713 if (!(element = $(element).firstChild)) return []; | 2162 var results = [], child = $(element).firstChild; |
1714 while (element && element.nodeType != 1) element = element.nextSibling; | 2163 while (child) { |
1715 if (element) return [element].concat($(element).nextSiblings()); | 2164 if (child.nodeType === 1) { |
1716 return []; | 2165 results.push(Element.extend(child)); |
| 2166 } |
| 2167 child = child.nextSibling; |
| 2168 } |
| 2169 return results; |
1717 }, | 2170 }, |
1718 | 2171 |
1719 previousSiblings: function(element) { | 2172 previousSiblings: function(element, maximumLength) { |
1720 return $(element).recursivelyCollect('previousSibling'); | 2173 return Element.recursivelyCollect(element, 'previousSibling'); |
1721 }, | 2174 }, |
1722 | 2175 |
1723 nextSiblings: function(element) { | 2176 nextSiblings: function(element) { |
1724 return $(element).recursivelyCollect('nextSibling'); | 2177 return Element.recursivelyCollect(element, 'nextSibling'); |
1725 }, | 2178 }, |
1726 | 2179 |
1727 siblings: function(element) { | 2180 siblings: function(element) { |
1728 element = $(element); | 2181 element = $(element); |
1729 return element.previousSiblings().reverse().concat(element.nextSiblings()); | 2182 return Element.previousSiblings(element).reverse() |
| 2183 .concat(Element.nextSiblings(element)); |
1730 }, | 2184 }, |
1731 | 2185 |
1732 match: function(element, selector) { | 2186 match: function(element, selector) { |
| 2187 element = $(element); |
1733 if (Object.isString(selector)) | 2188 if (Object.isString(selector)) |
1734 selector = new Selector(selector); | 2189 return Prototype.Selector.match(element, selector); |
1735 return selector.match($(element)); | 2190 return selector.match(element); |
1736 }, | 2191 }, |
1737 | 2192 |
1738 up: function(element, expression, index) { | 2193 up: function(element, expression, index) { |
1739 element = $(element); | 2194 element = $(element); |
1740 if (arguments.length == 1) return $(element.parentNode); | 2195 if (arguments.length == 1) return $(element.parentNode); |
1741 var ancestors = element.ancestors(); | 2196 var ancestors = Element.ancestors(element); |
1742 return Object.isNumber(expression) ? ancestors[expression] : | 2197 return Object.isNumber(expression) ? ancestors[expression] : |
1743 Selector.findElement(ancestors, expression, index); | 2198 Prototype.Selector.find(ancestors, expression, index); |
1744 }, | 2199 }, |
1745 | 2200 |
1746 down: function(element, expression, index) { | 2201 down: function(element, expression, index) { |
1747 element = $(element); | 2202 element = $(element); |
1748 if (arguments.length == 1) return element.firstDescendant(); | 2203 if (arguments.length == 1) return Element.firstDescendant(element); |
1749 return Object.isNumber(expression) ? element.descendants()[expression] : | 2204 return Object.isNumber(expression) ? Element.descendants(element)[expression
] : |
1750 Element.select(element, expression)[index || 0]; | 2205 Element.select(element, expression)[index || 0]; |
1751 }, | 2206 }, |
1752 | 2207 |
1753 previous: function(element, expression, index) { | 2208 previous: function(element, expression, index) { |
1754 element = $(element); | 2209 element = $(element); |
1755 if (arguments.length == 1) return $(Selector.handlers.previousElementSibling
(element)); | 2210 if (Object.isNumber(expression)) index = expression, expression = false; |
1756 var previousSiblings = element.previousSiblings(); | 2211 if (!Object.isNumber(index)) index = 0; |
1757 return Object.isNumber(expression) ? previousSiblings[expression] : | 2212 |
1758 Selector.findElement(previousSiblings, expression, index); | 2213 if (expression) { |
| 2214 return Prototype.Selector.find(element.previousSiblings(), expression, ind
ex); |
| 2215 } else { |
| 2216 return element.recursivelyCollect("previousSibling", index + 1)[index]; |
| 2217 } |
1759 }, | 2218 }, |
1760 | 2219 |
1761 next: function(element, expression, index) { | 2220 next: function(element, expression, index) { |
1762 element = $(element); | 2221 element = $(element); |
1763 if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(ele
ment)); | 2222 if (Object.isNumber(expression)) index = expression, expression = false; |
1764 var nextSiblings = element.nextSiblings(); | 2223 if (!Object.isNumber(index)) index = 0; |
1765 return Object.isNumber(expression) ? nextSiblings[expression] : | 2224 |
1766 Selector.findElement(nextSiblings, expression, index); | 2225 if (expression) { |
| 2226 return Prototype.Selector.find(element.nextSiblings(), expression, index); |
| 2227 } else { |
| 2228 var maximumLength = Object.isNumber(index) ? index + 1 : 1; |
| 2229 return element.recursivelyCollect("nextSibling", index + 1)[index]; |
| 2230 } |
1767 }, | 2231 }, |
1768 | 2232 |
1769 select: function() { | 2233 |
1770 var args = $A(arguments), element = $(args.shift()); | 2234 select: function(element) { |
1771 return Selector.findChildElements(element, args); | 2235 element = $(element); |
| 2236 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); |
| 2237 return Prototype.Selector.select(expressions, element); |
1772 }, | 2238 }, |
1773 | 2239 |
1774 adjacent: function() { | 2240 adjacent: function(element) { |
1775 var args = $A(arguments), element = $(args.shift()); | 2241 element = $(element); |
1776 return Selector.findChildElements(element.parentNode, args).without(element)
; | 2242 var expressions = Array.prototype.slice.call(arguments, 1).join(', '); |
| 2243 return Prototype.Selector.select(expressions, element.parentNode).without(el
ement); |
1777 }, | 2244 }, |
1778 | 2245 |
1779 identify: function(element) { | 2246 identify: function(element) { |
1780 element = $(element); | 2247 element = $(element); |
1781 var id = element.readAttribute('id'), self = arguments.callee; | 2248 var id = Element.readAttribute(element, 'id'); |
1782 if (id) return id; | 2249 if (id) return id; |
1783 do { id = 'anonymous_element_' + self.counter++ } while ($(id)); | 2250 do { id = 'anonymous_element_' + Element.idCounter++ } while ($(id)); |
1784 element.writeAttribute('id', id); | 2251 Element.writeAttribute(element, 'id', id); |
1785 return id; | 2252 return id; |
1786 }, | 2253 }, |
1787 | 2254 |
1788 readAttribute: function(element, name) { | 2255 readAttribute: function(element, name) { |
1789 element = $(element); | 2256 element = $(element); |
1790 if (Prototype.Browser.IE) { | 2257 if (Prototype.Browser.IE) { |
1791 var t = Element._attributeTranslations.read; | 2258 var t = Element._attributeTranslations.read; |
1792 if (t.values[name]) return t.values[name](element, name); | 2259 if (t.values[name]) return t.values[name](element, name); |
1793 if (t.names[name]) name = t.names[name]; | 2260 if (t.names[name]) name = t.names[name]; |
1794 if (name.include(':')) { | 2261 if (name.include(':')) { |
(...skipping 18 matching lines...) Expand all Loading... |
1813 if (value === false || value === null) | 2280 if (value === false || value === null) |
1814 element.removeAttribute(name); | 2281 element.removeAttribute(name); |
1815 else if (value === true) | 2282 else if (value === true) |
1816 element.setAttribute(name, name); | 2283 element.setAttribute(name, name); |
1817 else element.setAttribute(name, value); | 2284 else element.setAttribute(name, value); |
1818 } | 2285 } |
1819 return element; | 2286 return element; |
1820 }, | 2287 }, |
1821 | 2288 |
1822 getHeight: function(element) { | 2289 getHeight: function(element) { |
1823 return $(element).getDimensions().height; | 2290 return Element.getDimensions(element).height; |
1824 }, | 2291 }, |
1825 | 2292 |
1826 getWidth: function(element) { | 2293 getWidth: function(element) { |
1827 return $(element).getDimensions().width; | 2294 return Element.getDimensions(element).width; |
1828 }, | 2295 }, |
1829 | 2296 |
1830 classNames: function(element) { | 2297 classNames: function(element) { |
1831 return new Element.ClassNames(element); | 2298 return new Element.ClassNames(element); |
1832 }, | 2299 }, |
1833 | 2300 |
1834 hasClassName: function(element, className) { | 2301 hasClassName: function(element, className) { |
1835 if (!(element = $(element))) return; | 2302 if (!(element = $(element))) return; |
1836 var elementClassName = element.className; | 2303 var elementClassName = element.className; |
1837 return (elementClassName.length > 0 && (elementClassName == className || | 2304 return (elementClassName.length > 0 && (elementClassName == className || |
1838 new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); | 2305 new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName))); |
1839 }, | 2306 }, |
1840 | 2307 |
1841 addClassName: function(element, className) { | 2308 addClassName: function(element, className) { |
1842 if (!(element = $(element))) return; | 2309 if (!(element = $(element))) return; |
1843 if (!element.hasClassName(className)) | 2310 if (!Element.hasClassName(element, className)) |
1844 element.className += (element.className ? ' ' : '') + className; | 2311 element.className += (element.className ? ' ' : '') + className; |
1845 return element; | 2312 return element; |
1846 }, | 2313 }, |
1847 | 2314 |
1848 removeClassName: function(element, className) { | 2315 removeClassName: function(element, className) { |
1849 if (!(element = $(element))) return; | 2316 if (!(element = $(element))) return; |
1850 element.className = element.className.replace( | 2317 element.className = element.className.replace( |
1851 new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); | 2318 new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip(); |
1852 return element; | 2319 return element; |
1853 }, | 2320 }, |
1854 | 2321 |
1855 toggleClassName: function(element, className) { | 2322 toggleClassName: function(element, className) { |
1856 if (!(element = $(element))) return; | 2323 if (!(element = $(element))) return; |
1857 return element[element.hasClassName(className) ? | 2324 return Element[Element.hasClassName(element, className) ? |
1858 'removeClassName' : 'addClassName'](className); | 2325 'removeClassName' : 'addClassName'](element, className); |
1859 }, | 2326 }, |
1860 | 2327 |
1861 // removes whitespace-only text node children | |
1862 cleanWhitespace: function(element) { | 2328 cleanWhitespace: function(element) { |
1863 element = $(element); | 2329 element = $(element); |
1864 var node = element.firstChild; | 2330 var node = element.firstChild; |
1865 while (node) { | 2331 while (node) { |
1866 var nextNode = node.nextSibling; | 2332 var nextNode = node.nextSibling; |
1867 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) | 2333 if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) |
1868 element.removeChild(node); | 2334 element.removeChild(node); |
1869 node = nextNode; | 2335 node = nextNode; |
1870 } | 2336 } |
1871 return element; | 2337 return element; |
(...skipping 13 matching lines...) Expand all Loading... |
1885 return ancestor.contains(element) && ancestor !== element; | 2351 return ancestor.contains(element) && ancestor !== element; |
1886 | 2352 |
1887 while (element = element.parentNode) | 2353 while (element = element.parentNode) |
1888 if (element == ancestor) return true; | 2354 if (element == ancestor) return true; |
1889 | 2355 |
1890 return false; | 2356 return false; |
1891 }, | 2357 }, |
1892 | 2358 |
1893 scrollTo: function(element) { | 2359 scrollTo: function(element) { |
1894 element = $(element); | 2360 element = $(element); |
1895 var pos = element.cumulativeOffset(); | 2361 var pos = Element.cumulativeOffset(element); |
1896 window.scrollTo(pos[0], pos[1]); | 2362 window.scrollTo(pos[0], pos[1]); |
1897 return element; | 2363 return element; |
1898 }, | 2364 }, |
1899 | 2365 |
1900 getStyle: function(element, style) { | 2366 getStyle: function(element, style) { |
1901 element = $(element); | 2367 element = $(element); |
1902 style = style == 'float' ? 'cssFloat' : style.camelize(); | 2368 style = style == 'float' ? 'cssFloat' : style.camelize(); |
1903 var value = element.style[style]; | 2369 var value = element.style[style]; |
1904 if (!value || value == 'auto') { | 2370 if (!value || value == 'auto') { |
1905 var css = document.defaultView.getComputedStyle(element, null); | 2371 var css = document.defaultView.getComputedStyle(element, null); |
(...skipping 25 matching lines...) Expand all Loading... |
1931 return element; | 2397 return element; |
1932 }, | 2398 }, |
1933 | 2399 |
1934 setOpacity: function(element, value) { | 2400 setOpacity: function(element, value) { |
1935 element = $(element); | 2401 element = $(element); |
1936 element.style.opacity = (value == 1 || value === '') ? '' : | 2402 element.style.opacity = (value == 1 || value === '') ? '' : |
1937 (value < 0.00001) ? 0 : value; | 2403 (value < 0.00001) ? 0 : value; |
1938 return element; | 2404 return element; |
1939 }, | 2405 }, |
1940 | 2406 |
1941 getDimensions: function(element) { | |
1942 element = $(element); | |
1943 var display = element.getStyle('display'); | |
1944 if (display != 'none' && display != null) // Safari bug | |
1945 return {width: element.offsetWidth, height: element.offsetHeight}; | |
1946 | |
1947 // All *Width and *Height properties give 0 on elements with display none, | |
1948 // so enable the element temporarily | |
1949 var els = element.style; | |
1950 var originalVisibility = els.visibility; | |
1951 var originalPosition = els.position; | |
1952 var originalDisplay = els.display; | |
1953 els.visibility = 'hidden'; | |
1954 els.position = 'absolute'; | |
1955 els.display = 'block'; | |
1956 var originalWidth = element.clientWidth; | |
1957 var originalHeight = element.clientHeight; | |
1958 els.display = originalDisplay; | |
1959 els.position = originalPosition; | |
1960 els.visibility = originalVisibility; | |
1961 return {width: originalWidth, height: originalHeight}; | |
1962 }, | |
1963 | |
1964 makePositioned: function(element) { | 2407 makePositioned: function(element) { |
1965 element = $(element); | 2408 element = $(element); |
1966 var pos = Element.getStyle(element, 'position'); | 2409 var pos = Element.getStyle(element, 'position'); |
1967 if (pos == 'static' || !pos) { | 2410 if (pos == 'static' || !pos) { |
1968 element._madePositioned = true; | 2411 element._madePositioned = true; |
1969 element.style.position = 'relative'; | 2412 element.style.position = 'relative'; |
1970 // Opera returns the offset relative to the positioning context, when an | |
1971 // element is position relative but top and left have not been defined | |
1972 if (Prototype.Browser.Opera) { | 2413 if (Prototype.Browser.Opera) { |
1973 element.style.top = 0; | 2414 element.style.top = 0; |
1974 element.style.left = 0; | 2415 element.style.left = 0; |
1975 } | 2416 } |
1976 } | 2417 } |
1977 return element; | 2418 return element; |
1978 }, | 2419 }, |
1979 | 2420 |
1980 undoPositioned: function(element) { | 2421 undoPositioned: function(element) { |
1981 element = $(element); | 2422 element = $(element); |
(...skipping 18 matching lines...) Expand all Loading... |
2000 }, | 2441 }, |
2001 | 2442 |
2002 undoClipping: function(element) { | 2443 undoClipping: function(element) { |
2003 element = $(element); | 2444 element = $(element); |
2004 if (!element._overflow) return element; | 2445 if (!element._overflow) return element; |
2005 element.style.overflow = element._overflow == 'auto' ? '' : element._overflo
w; | 2446 element.style.overflow = element._overflow == 'auto' ? '' : element._overflo
w; |
2006 element._overflow = null; | 2447 element._overflow = null; |
2007 return element; | 2448 return element; |
2008 }, | 2449 }, |
2009 | 2450 |
2010 cumulativeOffset: function(element) { | |
2011 var valueT = 0, valueL = 0; | |
2012 do { | |
2013 valueT += element.offsetTop || 0; | |
2014 valueL += element.offsetLeft || 0; | |
2015 element = element.offsetParent; | |
2016 } while (element); | |
2017 return Element._returnOffset(valueL, valueT); | |
2018 }, | |
2019 | |
2020 positionedOffset: function(element) { | |
2021 var valueT = 0, valueL = 0; | |
2022 do { | |
2023 valueT += element.offsetTop || 0; | |
2024 valueL += element.offsetLeft || 0; | |
2025 element = element.offsetParent; | |
2026 if (element) { | |
2027 if (element.tagName.toUpperCase() == 'BODY') break; | |
2028 var p = Element.getStyle(element, 'position'); | |
2029 if (p !== 'static') break; | |
2030 } | |
2031 } while (element); | |
2032 return Element._returnOffset(valueL, valueT); | |
2033 }, | |
2034 | |
2035 absolutize: function(element) { | |
2036 element = $(element); | |
2037 if (element.getStyle('position') == 'absolute') return element; | |
2038 // Position.prepare(); // To be done manually by Scripty when it needs it. | |
2039 | |
2040 var offsets = element.positionedOffset(); | |
2041 var top = offsets[1]; | |
2042 var left = offsets[0]; | |
2043 var width = element.clientWidth; | |
2044 var height = element.clientHeight; | |
2045 | |
2046 element._originalLeft = left - parseFloat(element.style.left || 0); | |
2047 element._originalTop = top - parseFloat(element.style.top || 0); | |
2048 element._originalWidth = element.style.width; | |
2049 element._originalHeight = element.style.height; | |
2050 | |
2051 element.style.position = 'absolute'; | |
2052 element.style.top = top + 'px'; | |
2053 element.style.left = left + 'px'; | |
2054 element.style.width = width + 'px'; | |
2055 element.style.height = height + 'px'; | |
2056 return element; | |
2057 }, | |
2058 | |
2059 relativize: function(element) { | |
2060 element = $(element); | |
2061 if (element.getStyle('position') == 'relative') return element; | |
2062 // Position.prepare(); // To be done manually by Scripty when it needs it. | |
2063 | |
2064 element.style.position = 'relative'; | |
2065 var top = parseFloat(element.style.top || 0) - (element._originalTop || 0)
; | |
2066 var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0
); | |
2067 | |
2068 element.style.top = top + 'px'; | |
2069 element.style.left = left + 'px'; | |
2070 element.style.height = element._originalHeight; | |
2071 element.style.width = element._originalWidth; | |
2072 return element; | |
2073 }, | |
2074 | |
2075 cumulativeScrollOffset: function(element) { | |
2076 var valueT = 0, valueL = 0; | |
2077 do { | |
2078 valueT += element.scrollTop || 0; | |
2079 valueL += element.scrollLeft || 0; | |
2080 element = element.parentNode; | |
2081 } while (element); | |
2082 return Element._returnOffset(valueL, valueT); | |
2083 }, | |
2084 | |
2085 getOffsetParent: function(element) { | |
2086 if (element.offsetParent) return $(element.offsetParent); | |
2087 if (element == document.body) return $(element); | |
2088 | |
2089 while ((element = element.parentNode) && element != document.body) | |
2090 if (Element.getStyle(element, 'position') != 'static') | |
2091 return $(element); | |
2092 | |
2093 return $(document.body); | |
2094 }, | |
2095 | |
2096 viewportOffset: function(forElement) { | |
2097 var valueT = 0, valueL = 0; | |
2098 | |
2099 var element = forElement; | |
2100 do { | |
2101 valueT += element.offsetTop || 0; | |
2102 valueL += element.offsetLeft || 0; | |
2103 | |
2104 // Safari fix | |
2105 if (element.offsetParent == document.body && | |
2106 Element.getStyle(element, 'position') == 'absolute') break; | |
2107 | |
2108 } while (element = element.offsetParent); | |
2109 | |
2110 element = forElement; | |
2111 do { | |
2112 if (!Prototype.Browser.Opera || (element.tagName && (element.tagName.toUpp
erCase() == 'BODY'))) { | |
2113 valueT -= element.scrollTop || 0; | |
2114 valueL -= element.scrollLeft || 0; | |
2115 } | |
2116 } while (element = element.parentNode); | |
2117 | |
2118 return Element._returnOffset(valueL, valueT); | |
2119 }, | |
2120 | |
2121 clonePosition: function(element, source) { | 2451 clonePosition: function(element, source) { |
2122 var options = Object.extend({ | 2452 var options = Object.extend({ |
2123 setLeft: true, | 2453 setLeft: true, |
2124 setTop: true, | 2454 setTop: true, |
2125 setWidth: true, | 2455 setWidth: true, |
2126 setHeight: true, | 2456 setHeight: true, |
2127 offsetTop: 0, | 2457 offsetTop: 0, |
2128 offsetLeft: 0 | 2458 offsetLeft: 0 |
2129 }, arguments[2] || { }); | 2459 }, arguments[2] || { }); |
2130 | 2460 |
2131 // find page position of source | |
2132 source = $(source); | 2461 source = $(source); |
2133 var p = source.viewportOffset(); | 2462 var p = Element.viewportOffset(source), delta = [0, 0], parent = null; |
2134 | 2463 |
2135 // find coordinate system to use | |
2136 element = $(element); | 2464 element = $(element); |
2137 var delta = [0, 0]; | 2465 |
2138 var parent = null; | |
2139 // delta [0,0] will do fine with position: fixed elements, | |
2140 // position:absolute needs offsetParent deltas | |
2141 if (Element.getStyle(element, 'position') == 'absolute') { | 2466 if (Element.getStyle(element, 'position') == 'absolute') { |
2142 parent = element.getOffsetParent(); | 2467 parent = Element.getOffsetParent(element); |
2143 delta = parent.viewportOffset(); | 2468 delta = Element.viewportOffset(parent); |
2144 } | 2469 } |
2145 | 2470 |
2146 // correct by body offsets (fixes Safari) | |
2147 if (parent == document.body) { | 2471 if (parent == document.body) { |
2148 delta[0] -= document.body.offsetLeft; | 2472 delta[0] -= document.body.offsetLeft; |
2149 delta[1] -= document.body.offsetTop; | 2473 delta[1] -= document.body.offsetTop; |
2150 } | 2474 } |
2151 | 2475 |
2152 // set position | |
2153 if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offs
etLeft) + 'px'; | 2476 if (options.setLeft) element.style.left = (p[0] - delta[0] + options.offs
etLeft) + 'px'; |
2154 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offs
etTop) + 'px'; | 2477 if (options.setTop) element.style.top = (p[1] - delta[1] + options.offs
etTop) + 'px'; |
2155 if (options.setWidth) element.style.width = source.offsetWidth + 'px'; | 2478 if (options.setWidth) element.style.width = source.offsetWidth + 'px'; |
2156 if (options.setHeight) element.style.height = source.offsetHeight + 'px'; | 2479 if (options.setHeight) element.style.height = source.offsetHeight + 'px'; |
2157 return element; | 2480 return element; |
2158 } | 2481 } |
2159 }; | 2482 }; |
2160 | 2483 |
2161 Element.Methods.identify.counter = 1; | |
2162 | |
2163 Object.extend(Element.Methods, { | 2484 Object.extend(Element.Methods, { |
2164 getElementsBySelector: Element.Methods.select, | 2485 getElementsBySelector: Element.Methods.select, |
| 2486 |
2165 childElements: Element.Methods.immediateDescendants | 2487 childElements: Element.Methods.immediateDescendants |
2166 }); | 2488 }); |
2167 | 2489 |
2168 Element._attributeTranslations = { | 2490 Element._attributeTranslations = { |
2169 write: { | 2491 write: { |
2170 names: { | 2492 names: { |
2171 className: 'class', | 2493 className: 'class', |
2172 htmlFor: 'for' | 2494 htmlFor: 'for' |
2173 }, | 2495 }, |
2174 values: { } | 2496 values: { } |
2175 } | 2497 } |
2176 }; | 2498 }; |
2177 | 2499 |
2178 if (Prototype.Browser.Opera) { | 2500 if (Prototype.Browser.Opera) { |
2179 Element.Methods.getStyle = Element.Methods.getStyle.wrap( | 2501 Element.Methods.getStyle = Element.Methods.getStyle.wrap( |
2180 function(proceed, element, style) { | 2502 function(proceed, element, style) { |
2181 switch (style) { | 2503 switch (style) { |
2182 case 'left': case 'top': case 'right': case 'bottom': | |
2183 if (proceed(element, 'position') === 'static') return null; | |
2184 case 'height': case 'width': | 2504 case 'height': case 'width': |
2185 // returns '0px' for hidden elements; we want it to return null | |
2186 if (!Element.visible(element)) return null; | 2505 if (!Element.visible(element)) return null; |
2187 | 2506 |
2188 // returns the border-box dimensions rather than the content-box | |
2189 // dimensions, so we subtract padding and borders from the value | |
2190 var dim = parseInt(proceed(element, style), 10); | 2507 var dim = parseInt(proceed(element, style), 10); |
2191 | 2508 |
2192 if (dim !== element['offset' + style.capitalize()]) | 2509 if (dim !== element['offset' + style.capitalize()]) |
2193 return dim + 'px'; | 2510 return dim + 'px'; |
2194 | 2511 |
2195 var properties; | 2512 var properties; |
2196 if (style === 'height') { | 2513 if (style === 'height') { |
2197 properties = ['border-top-width', 'padding-top', | 2514 properties = ['border-top-width', 'padding-top', |
2198 'padding-bottom', 'border-bottom-width']; | 2515 'padding-bottom', 'border-bottom-width']; |
2199 } | 2516 } |
(...skipping 12 matching lines...) Expand all Loading... |
2212 | 2529 |
2213 Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( | 2530 Element.Methods.readAttribute = Element.Methods.readAttribute.wrap( |
2214 function(proceed, element, attribute) { | 2531 function(proceed, element, attribute) { |
2215 if (attribute === 'title') return element.title; | 2532 if (attribute === 'title') return element.title; |
2216 return proceed(element, attribute); | 2533 return proceed(element, attribute); |
2217 } | 2534 } |
2218 ); | 2535 ); |
2219 } | 2536 } |
2220 | 2537 |
2221 else if (Prototype.Browser.IE) { | 2538 else if (Prototype.Browser.IE) { |
2222 // IE doesn't report offsets correctly for static elements, so we change them | |
2223 // to "relative" to get the values, then change them back. | |
2224 Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap( | |
2225 function(proceed, element) { | |
2226 element = $(element); | |
2227 // IE throws an error if element is not in document | |
2228 try { element.offsetParent } | |
2229 catch(e) { return $(document.body) } | |
2230 var position = element.getStyle('position'); | |
2231 if (position !== 'static') return proceed(element); | |
2232 element.setStyle({ position: 'relative' }); | |
2233 var value = proceed(element); | |
2234 element.setStyle({ position: position }); | |
2235 return value; | |
2236 } | |
2237 ); | |
2238 | |
2239 $w('positionedOffset viewportOffset').each(function(method) { | |
2240 Element.Methods[method] = Element.Methods[method].wrap( | |
2241 function(proceed, element) { | |
2242 element = $(element); | |
2243 try { element.offsetParent } | |
2244 catch(e) { return Element._returnOffset(0,0) } | |
2245 var position = element.getStyle('position'); | |
2246 if (position !== 'static') return proceed(element); | |
2247 // Trigger hasLayout on the offset parent so that IE6 reports | |
2248 // accurate offsetTop and offsetLeft values for position: fixed. | |
2249 var offsetParent = element.getOffsetParent(); | |
2250 if (offsetParent && offsetParent.getStyle('position') === 'fixed') | |
2251 offsetParent.setStyle({ zoom: 1 }); | |
2252 element.setStyle({ position: 'relative' }); | |
2253 var value = proceed(element); | |
2254 element.setStyle({ position: position }); | |
2255 return value; | |
2256 } | |
2257 ); | |
2258 }); | |
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 | |
2268 Element.Methods.getStyle = function(element, style) { | 2539 Element.Methods.getStyle = function(element, style) { |
2269 element = $(element); | 2540 element = $(element); |
2270 style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.cam
elize(); | 2541 style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.cam
elize(); |
2271 var value = element.style[style]; | 2542 var value = element.style[style]; |
2272 if (!value && element.currentStyle) value = element.currentStyle[style]; | 2543 if (!value && element.currentStyle) value = element.currentStyle[style]; |
2273 | 2544 |
2274 if (style == 'opacity') { | 2545 if (style == 'opacity') { |
2275 if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\
)/)) | 2546 if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\
)/)) |
2276 if (value[1]) return parseFloat(value[1]) / 100; | 2547 if (value[1]) return parseFloat(value[1]) / 100; |
2277 return 1.0; | 2548 return 1.0; |
(...skipping 21 matching lines...) Expand all Loading... |
2299 if (value == 1 || value === '') { | 2570 if (value == 1 || value === '') { |
2300 (filter = stripAlpha(filter)) ? | 2571 (filter = stripAlpha(filter)) ? |
2301 style.filter = filter : style.removeAttribute('filter'); | 2572 style.filter = filter : style.removeAttribute('filter'); |
2302 return element; | 2573 return element; |
2303 } else if (value < 0.00001) value = 0; | 2574 } else if (value < 0.00001) value = 0; |
2304 style.filter = stripAlpha(filter) + | 2575 style.filter = stripAlpha(filter) + |
2305 'alpha(opacity=' + (value * 100) + ')'; | 2576 'alpha(opacity=' + (value * 100) + ')'; |
2306 return element; | 2577 return element; |
2307 }; | 2578 }; |
2308 | 2579 |
2309 Element._attributeTranslations = { | 2580 Element._attributeTranslations = (function(){ |
2310 read: { | 2581 |
2311 names: { | 2582 var classProp = 'className', |
2312 'class': 'className', | 2583 forProp = 'for', |
2313 'for': 'htmlFor' | 2584 el = document.createElement('div'); |
2314 }, | 2585 |
2315 values: { | 2586 el.setAttribute(classProp, 'x'); |
2316 _getAttr: function(element, attribute) { | 2587 |
2317 return element.getAttribute(attribute, 2); | 2588 if (el.className !== 'x') { |
| 2589 el.setAttribute('class', 'x'); |
| 2590 if (el.className === 'x') { |
| 2591 classProp = 'class'; |
| 2592 } |
| 2593 } |
| 2594 el = null; |
| 2595 |
| 2596 el = document.createElement('label'); |
| 2597 el.setAttribute(forProp, 'x'); |
| 2598 if (el.htmlFor !== 'x') { |
| 2599 el.setAttribute('htmlFor', 'x'); |
| 2600 if (el.htmlFor === 'x') { |
| 2601 forProp = 'htmlFor'; |
| 2602 } |
| 2603 } |
| 2604 el = null; |
| 2605 |
| 2606 return { |
| 2607 read: { |
| 2608 names: { |
| 2609 'class': classProp, |
| 2610 'className': classProp, |
| 2611 'for': forProp, |
| 2612 'htmlFor': forProp |
2318 }, | 2613 }, |
2319 _getAttrNode: function(element, attribute) { | 2614 values: { |
2320 var node = element.getAttributeNode(attribute); | 2615 _getAttr: function(element, attribute) { |
2321 return node ? node.value : ""; | 2616 return element.getAttribute(attribute); |
2322 }, | 2617 }, |
2323 _getEv: function(element, attribute) { | 2618 _getAttr2: function(element, attribute) { |
2324 attribute = element.getAttribute(attribute); | 2619 return element.getAttribute(attribute, 2); |
2325 return attribute ? attribute.toString().slice(23, -2) : null; | 2620 }, |
2326 }, | 2621 _getAttrNode: function(element, attribute) { |
2327 _flag: function(element, attribute) { | 2622 var node = element.getAttributeNode(attribute); |
2328 return $(element).hasAttribute(attribute) ? attribute : null; | 2623 return node ? node.value : ""; |
2329 }, | 2624 }, |
2330 style: function(element) { | 2625 _getEv: (function(){ |
2331 return element.style.cssText.toLowerCase(); | 2626 |
2332 }, | 2627 var el = document.createElement('div'), f; |
2333 title: function(element) { | 2628 el.onclick = Prototype.emptyFunction; |
2334 return element.title; | 2629 var value = el.getAttribute('onclick'); |
| 2630 |
| 2631 if (String(value).indexOf('{') > -1) { |
| 2632 f = function(element, attribute) { |
| 2633 attribute = element.getAttribute(attribute); |
| 2634 if (!attribute) return null; |
| 2635 attribute = attribute.toString(); |
| 2636 attribute = attribute.split('{')[1]; |
| 2637 attribute = attribute.split('}')[0]; |
| 2638 return attribute.strip(); |
| 2639 }; |
| 2640 } |
| 2641 else if (value === '') { |
| 2642 f = function(element, attribute) { |
| 2643 attribute = element.getAttribute(attribute); |
| 2644 if (!attribute) return null; |
| 2645 return attribute.strip(); |
| 2646 }; |
| 2647 } |
| 2648 el = null; |
| 2649 return f; |
| 2650 })(), |
| 2651 _flag: function(element, attribute) { |
| 2652 return $(element).hasAttribute(attribute) ? attribute : null; |
| 2653 }, |
| 2654 style: function(element) { |
| 2655 return element.style.cssText.toLowerCase(); |
| 2656 }, |
| 2657 title: function(element) { |
| 2658 return element.title; |
| 2659 } |
2335 } | 2660 } |
2336 } | 2661 } |
2337 } | 2662 } |
2338 }; | 2663 })(); |
2339 | 2664 |
2340 Element._attributeTranslations.write = { | 2665 Element._attributeTranslations.write = { |
2341 names: Object.extend({ | 2666 names: Object.extend({ |
2342 cellpadding: 'cellPadding', | 2667 cellpadding: 'cellPadding', |
2343 cellspacing: 'cellSpacing' | 2668 cellspacing: 'cellSpacing' |
2344 }, Element._attributeTranslations.read.names), | 2669 }, Element._attributeTranslations.read.names), |
2345 values: { | 2670 values: { |
2346 checked: function(element, value) { | 2671 checked: function(element, value) { |
2347 element.checked = !!value; | 2672 element.checked = !!value; |
2348 }, | 2673 }, |
2349 | 2674 |
2350 style: function(element, value) { | 2675 style: function(element, value) { |
2351 element.style.cssText = value ? value : ''; | 2676 element.style.cssText = value ? value : ''; |
2352 } | 2677 } |
2353 } | 2678 } |
2354 }; | 2679 }; |
2355 | 2680 |
2356 Element._attributeTranslations.has = {}; | 2681 Element._attributeTranslations.has = {}; |
2357 | 2682 |
2358 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + | 2683 $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' + |
2359 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { | 2684 'encType maxLength readOnly longDesc frameBorder').each(function(attr) { |
2360 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; | 2685 Element._attributeTranslations.write.names[attr.toLowerCase()] = attr; |
2361 Element._attributeTranslations.has[attr.toLowerCase()] = attr; | 2686 Element._attributeTranslations.has[attr.toLowerCase()] = attr; |
2362 }); | 2687 }); |
2363 | 2688 |
2364 (function(v) { | 2689 (function(v) { |
2365 Object.extend(v, { | 2690 Object.extend(v, { |
2366 href: v._getAttr, | 2691 href: v._getAttr2, |
2367 src: v._getAttr, | 2692 src: v._getAttr2, |
2368 type: v._getAttr, | 2693 type: v._getAttr, |
2369 action: v._getAttrNode, | 2694 action: v._getAttrNode, |
2370 disabled: v._flag, | 2695 disabled: v._flag, |
2371 checked: v._flag, | 2696 checked: v._flag, |
2372 readonly: v._flag, | 2697 readonly: v._flag, |
2373 multiple: v._flag, | 2698 multiple: v._flag, |
2374 onload: v._getEv, | 2699 onload: v._getEv, |
2375 onunload: v._getEv, | 2700 onunload: v._getEv, |
2376 onclick: v._getEv, | 2701 onclick: v._getEv, |
2377 ondblclick: v._getEv, | 2702 ondblclick: v._getEv, |
2378 onmousedown: v._getEv, | 2703 onmousedown: v._getEv, |
2379 onmouseup: v._getEv, | 2704 onmouseup: v._getEv, |
2380 onmouseover: v._getEv, | 2705 onmouseover: v._getEv, |
2381 onmousemove: v._getEv, | 2706 onmousemove: v._getEv, |
2382 onmouseout: v._getEv, | 2707 onmouseout: v._getEv, |
2383 onfocus: v._getEv, | 2708 onfocus: v._getEv, |
2384 onblur: v._getEv, | 2709 onblur: v._getEv, |
2385 onkeypress: v._getEv, | 2710 onkeypress: v._getEv, |
2386 onkeydown: v._getEv, | 2711 onkeydown: v._getEv, |
2387 onkeyup: v._getEv, | 2712 onkeyup: v._getEv, |
2388 onsubmit: v._getEv, | 2713 onsubmit: v._getEv, |
2389 onreset: v._getEv, | 2714 onreset: v._getEv, |
2390 onselect: v._getEv, | 2715 onselect: v._getEv, |
2391 onchange: v._getEv | 2716 onchange: v._getEv |
2392 }); | 2717 }); |
2393 })(Element._attributeTranslations.read.values); | 2718 })(Element._attributeTranslations.read.values); |
| 2719 |
| 2720 if (Prototype.BrowserFeatures.ElementExtensions) { |
| 2721 (function() { |
| 2722 function _descendants(element) { |
| 2723 var nodes = element.getElementsByTagName('*'), results = []; |
| 2724 for (var i = 0, node; node = nodes[i]; i++) |
| 2725 if (node.tagName !== "!") // Filter out comment nodes. |
| 2726 results.push(node); |
| 2727 return results; |
| 2728 } |
| 2729 |
| 2730 Element.Methods.down = function(element, expression, index) { |
| 2731 element = $(element); |
| 2732 if (arguments.length == 1) return element.firstDescendant(); |
| 2733 return Object.isNumber(expression) ? _descendants(element)[expression] : |
| 2734 Element.select(element, expression)[index || 0]; |
| 2735 } |
| 2736 })(); |
| 2737 } |
| 2738 |
2394 } | 2739 } |
2395 | 2740 |
2396 else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { | 2741 else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) { |
2397 Element.Methods.setOpacity = function(element, value) { | 2742 Element.Methods.setOpacity = function(element, value) { |
2398 element = $(element); | 2743 element = $(element); |
2399 element.style.opacity = (value == 1) ? 0.999999 : | 2744 element.style.opacity = (value == 1) ? 0.999999 : |
2400 (value === '') ? '' : (value < 0.00001) ? 0 : value; | 2745 (value === '') ? '' : (value < 0.00001) ? 0 : value; |
2401 return element; | 2746 return element; |
2402 }; | 2747 }; |
2403 } | 2748 } |
2404 | 2749 |
2405 else if (Prototype.Browser.WebKit) { | 2750 else if (Prototype.Browser.WebKit) { |
2406 Element.Methods.setOpacity = function(element, value) { | 2751 Element.Methods.setOpacity = function(element, value) { |
2407 element = $(element); | 2752 element = $(element); |
2408 element.style.opacity = (value == 1 || value === '') ? '' : | 2753 element.style.opacity = (value == 1 || value === '') ? '' : |
2409 (value < 0.00001) ? 0 : value; | 2754 (value < 0.00001) ? 0 : value; |
2410 | 2755 |
2411 if (value == 1) | 2756 if (value == 1) |
2412 if(element.tagName.toUpperCase() == 'IMG' && element.width) { | 2757 if (element.tagName.toUpperCase() == 'IMG' && element.width) { |
2413 element.width++; element.width--; | 2758 element.width++; element.width--; |
2414 } else try { | 2759 } else try { |
2415 var n = document.createTextNode(' '); | 2760 var n = document.createTextNode(' '); |
2416 element.appendChild(n); | 2761 element.appendChild(n); |
2417 element.removeChild(n); | 2762 element.removeChild(n); |
2418 } catch (e) { } | 2763 } catch (e) { } |
2419 | 2764 |
2420 return element; | 2765 return element; |
2421 }; | 2766 }; |
2422 | |
2423 // Safari returns margins on body which is incorrect if the child is absolutel
y | |
2424 // positioned. For performance reasons, redefine Element#cumulativeOffset for | |
2425 // KHTML/WebKit only. | |
2426 Element.Methods.cumulativeOffset = function(element) { | |
2427 var valueT = 0, valueL = 0; | |
2428 do { | |
2429 valueT += element.offsetTop || 0; | |
2430 valueL += element.offsetLeft || 0; | |
2431 if (element.offsetParent == document.body) | |
2432 if (Element.getStyle(element, 'position') == 'absolute') break; | |
2433 | |
2434 element = element.offsetParent; | |
2435 } while (element); | |
2436 | |
2437 return Element._returnOffset(valueL, valueT); | |
2438 }; | |
2439 } | |
2440 | |
2441 if (Prototype.Browser.IE || Prototype.Browser.Opera) { | |
2442 // IE and Opera are missing .innerHTML support for TABLE-related and SELECT el
ements | |
2443 Element.Methods.update = function(element, content) { | |
2444 element = $(element); | |
2445 | |
2446 if (content && content.toElement) content = content.toElement(); | |
2447 if (Object.isElement(content)) return element.update().insert(content); | |
2448 | |
2449 content = Object.toHTML(content); | |
2450 var tagName = element.tagName.toUpperCase(); | |
2451 | |
2452 if (tagName in Element._insertionTranslations.tags) { | |
2453 $A(element.childNodes).each(function(node) { element.removeChild(node) }); | |
2454 Element._getContentFromAnonymousElement(tagName, content.stripScripts()) | |
2455 .each(function(node) { element.appendChild(node) }); | |
2456 } | |
2457 else element.innerHTML = content.stripScripts(); | |
2458 | |
2459 content.evalScripts.bind(content).defer(); | |
2460 return element; | |
2461 }; | |
2462 } | 2767 } |
2463 | 2768 |
2464 if ('outerHTML' in document.createElement('div')) { | 2769 if ('outerHTML' in document.documentElement) { |
2465 Element.Methods.replace = function(element, content) { | 2770 Element.Methods.replace = function(element, content) { |
2466 element = $(element); | 2771 element = $(element); |
2467 | 2772 |
2468 if (content && content.toElement) content = content.toElement(); | 2773 if (content && content.toElement) content = content.toElement(); |
2469 if (Object.isElement(content)) { | 2774 if (Object.isElement(content)) { |
2470 element.parentNode.replaceChild(content, element); | 2775 element.parentNode.replaceChild(content, element); |
2471 return element; | 2776 return element; |
2472 } | 2777 } |
2473 | 2778 |
2474 content = Object.toHTML(content); | 2779 content = Object.toHTML(content); |
2475 var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); | 2780 var parent = element.parentNode, tagName = parent.tagName.toUpperCase(); |
2476 | 2781 |
2477 if (Element._insertionTranslations.tags[tagName]) { | 2782 if (Element._insertionTranslations.tags[tagName]) { |
2478 var nextSibling = element.next(); | 2783 var nextSibling = element.next(), |
2479 var fragments = Element._getContentFromAnonymousElement(tagName, content.s
tripScripts()); | 2784 fragments = Element._getContentFromAnonymousElement(tagName, content.s
tripScripts()); |
2480 parent.removeChild(element); | 2785 parent.removeChild(element); |
2481 if (nextSibling) | 2786 if (nextSibling) |
2482 fragments.each(function(node) { parent.insertBefore(node, nextSibling) }
); | 2787 fragments.each(function(node) { parent.insertBefore(node, nextSibling) }
); |
2483 else | 2788 else |
2484 fragments.each(function(node) { parent.appendChild(node) }); | 2789 fragments.each(function(node) { parent.appendChild(node) }); |
2485 } | 2790 } |
2486 else element.outerHTML = content.stripScripts(); | 2791 else element.outerHTML = content.stripScripts(); |
2487 | 2792 |
2488 content.evalScripts.bind(content).defer(); | 2793 content.evalScripts.bind(content).defer(); |
2489 return element; | 2794 return element; |
2490 }; | 2795 }; |
2491 } | 2796 } |
2492 | 2797 |
2493 Element._returnOffset = function(l, t) { | 2798 Element._returnOffset = function(l, t) { |
2494 var result = [l, t]; | 2799 var result = [l, t]; |
2495 result.left = l; | 2800 result.left = l; |
2496 result.top = t; | 2801 result.top = t; |
2497 return result; | 2802 return result; |
2498 }; | 2803 }; |
2499 | 2804 |
2500 Element._getContentFromAnonymousElement = function(tagName, html) { | 2805 Element._getContentFromAnonymousElement = function(tagName, html, force) { |
2501 var div = new Element('div'), t = Element._insertionTranslations.tags[tagName]
; | 2806 var div = new Element('div'), |
2502 if (t) { | 2807 t = Element._insertionTranslations.tags[tagName]; |
2503 div.innerHTML = t[0] + html + t[1]; | 2808 |
2504 t[2].times(function() { div = div.firstChild }); | 2809 var workaround = false; |
2505 } else div.innerHTML = html; | 2810 if (t) workaround = true; |
| 2811 else if (force) { |
| 2812 workaround = true; |
| 2813 t = ['', '', 0]; |
| 2814 } |
| 2815 |
| 2816 if (workaround) { |
| 2817 div.innerHTML = ' ' + t[0] + html + t[1]; |
| 2818 div.removeChild(div.firstChild); |
| 2819 for (var i = t[2]; i--; ) { |
| 2820 div = div.firstChild; |
| 2821 } |
| 2822 } |
| 2823 else { |
| 2824 div.innerHTML = html; |
| 2825 } |
2506 return $A(div.childNodes); | 2826 return $A(div.childNodes); |
2507 }; | 2827 }; |
2508 | 2828 |
2509 Element._insertionTranslations = { | 2829 Element._insertionTranslations = { |
2510 before: function(element, node) { | 2830 before: function(element, node) { |
2511 element.parentNode.insertBefore(node, element); | 2831 element.parentNode.insertBefore(node, element); |
2512 }, | 2832 }, |
2513 top: function(element, node) { | 2833 top: function(element, node) { |
2514 element.insertBefore(node, element.firstChild); | 2834 element.insertBefore(node, element.firstChild); |
2515 }, | 2835 }, |
2516 bottom: function(element, node) { | 2836 bottom: function(element, node) { |
2517 element.appendChild(node); | 2837 element.appendChild(node); |
2518 }, | 2838 }, |
2519 after: function(element, node) { | 2839 after: function(element, node) { |
2520 element.parentNode.insertBefore(node, element.nextSibling); | 2840 element.parentNode.insertBefore(node, element.nextSibling); |
2521 }, | 2841 }, |
2522 tags: { | 2842 tags: { |
2523 TABLE: ['<table>', '</table>', 1], | 2843 TABLE: ['<table>', '</table>', 1], |
2524 TBODY: ['<table><tbody>', '</tbody></table>', 2], | 2844 TBODY: ['<table><tbody>', '</tbody></table>', 2], |
2525 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], | 2845 TR: ['<table><tbody><tr>', '</tr></tbody></table>', 3], |
2526 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], | 2846 TD: ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4], |
2527 SELECT: ['<select>', '</select>', 1] | 2847 SELECT: ['<select>', '</select>', 1] |
2528 } | 2848 } |
2529 }; | 2849 }; |
2530 | 2850 |
2531 (function() { | 2851 (function() { |
2532 Object.extend(this.tags, { | 2852 var tags = Element._insertionTranslations.tags; |
2533 THEAD: this.tags.TBODY, | 2853 Object.extend(tags, { |
2534 TFOOT: this.tags.TBODY, | 2854 THEAD: tags.TBODY, |
2535 TH: this.tags.TD | 2855 TFOOT: tags.TBODY, |
| 2856 TH: tags.TD |
2536 }); | 2857 }); |
2537 }).call(Element._insertionTranslations); | 2858 })(); |
2538 | 2859 |
2539 Element.Methods.Simulated = { | 2860 Element.Methods.Simulated = { |
2540 hasAttribute: function(element, attribute) { | 2861 hasAttribute: function(element, attribute) { |
2541 attribute = Element._attributeTranslations.has[attribute] || attribute; | 2862 attribute = Element._attributeTranslations.has[attribute] || attribute; |
2542 var node = $(element).getAttributeNode(attribute); | 2863 var node = $(element).getAttributeNode(attribute); |
2543 return !!(node && node.specified); | 2864 return !!(node && node.specified); |
2544 } | 2865 } |
2545 }; | 2866 }; |
2546 | 2867 |
2547 Element.Methods.ByTag = { }; | 2868 Element.Methods.ByTag = { }; |
2548 | 2869 |
2549 Object.extend(Element, Element.Methods); | 2870 Object.extend(Element, Element.Methods); |
2550 | 2871 |
2551 if (!Prototype.BrowserFeatures.ElementExtensions && | 2872 (function(div) { |
2552 document.createElement('div')['__proto__']) { | 2873 |
2553 window.HTMLElement = { }; | 2874 if (!Prototype.BrowserFeatures.ElementExtensions && div['__proto__']) { |
2554 window.HTMLElement.prototype = document.createElement('div')['__proto__']; | 2875 window.HTMLElement = { }; |
2555 Prototype.BrowserFeatures.ElementExtensions = true; | 2876 window.HTMLElement.prototype = div['__proto__']; |
2556 } | 2877 Prototype.BrowserFeatures.ElementExtensions = true; |
| 2878 } |
| 2879 |
| 2880 div = null; |
| 2881 |
| 2882 })(document.createElement('div')); |
2557 | 2883 |
2558 Element.extend = (function() { | 2884 Element.extend = (function() { |
2559 if (Prototype.BrowserFeatures.SpecificElementExtensions) | 2885 |
| 2886 function checkDeficiency(tagName) { |
| 2887 if (typeof window.Element != 'undefined') { |
| 2888 var proto = window.Element.prototype; |
| 2889 if (proto) { |
| 2890 var id = '_' + (Math.random()+'').slice(2), |
| 2891 el = document.createElement(tagName); |
| 2892 proto[id] = 'x'; |
| 2893 var isBuggy = (el[id] !== 'x'); |
| 2894 delete proto[id]; |
| 2895 el = null; |
| 2896 return isBuggy; |
| 2897 } |
| 2898 } |
| 2899 return false; |
| 2900 } |
| 2901 |
| 2902 function extendElementWith(element, methods) { |
| 2903 for (var property in methods) { |
| 2904 var value = methods[property]; |
| 2905 if (Object.isFunction(value) && !(property in element)) |
| 2906 element[property] = value.methodize(); |
| 2907 } |
| 2908 } |
| 2909 |
| 2910 var HTMLOBJECTELEMENT_PROTOTYPE_BUGGY = checkDeficiency('object'); |
| 2911 |
| 2912 if (Prototype.BrowserFeatures.SpecificElementExtensions) { |
| 2913 if (HTMLOBJECTELEMENT_PROTOTYPE_BUGGY) { |
| 2914 return function(element) { |
| 2915 if (element && typeof element._extendedByPrototype == 'undefined') { |
| 2916 var t = element.tagName; |
| 2917 if (t && (/^(?:object|applet|embed)$/i.test(t))) { |
| 2918 extendElementWith(element, Element.Methods); |
| 2919 extendElementWith(element, Element.Methods.Simulated); |
| 2920 extendElementWith(element, Element.Methods.ByTag[t.toUpperCase()]); |
| 2921 } |
| 2922 } |
| 2923 return element; |
| 2924 } |
| 2925 } |
2560 return Prototype.K; | 2926 return Prototype.K; |
| 2927 } |
2561 | 2928 |
2562 var Methods = { }, ByTag = Element.Methods.ByTag; | 2929 var Methods = { }, ByTag = Element.Methods.ByTag; |
2563 | 2930 |
2564 var extend = Object.extend(function(element) { | 2931 var extend = Object.extend(function(element) { |
2565 if (!element || element._extendedByPrototype || | 2932 if (!element || typeof element._extendedByPrototype != 'undefined' || |
2566 element.nodeType != 1 || element == window) return element; | 2933 element.nodeType != 1 || element == window) return element; |
2567 | 2934 |
2568 var methods = Object.clone(Methods), | 2935 var methods = Object.clone(Methods), |
2569 tagName = element.tagName.toUpperCase(), property, value; | 2936 tagName = element.tagName.toUpperCase(); |
2570 | 2937 |
2571 // extend methods for specific tags | |
2572 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); | 2938 if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]); |
2573 | 2939 |
2574 for (property in methods) { | 2940 extendElementWith(element, methods); |
2575 value = methods[property]; | |
2576 if (Object.isFunction(value) && !(property in element)) | |
2577 element[property] = value.methodize(); | |
2578 } | |
2579 | 2941 |
2580 element._extendedByPrototype = Prototype.emptyFunction; | 2942 element._extendedByPrototype = Prototype.emptyFunction; |
2581 return element; | 2943 return element; |
2582 | 2944 |
2583 }, { | 2945 }, { |
2584 refresh: function() { | 2946 refresh: function() { |
2585 // extend methods for all tags (Safari doesn't need this) | |
2586 if (!Prototype.BrowserFeatures.ElementExtensions) { | 2947 if (!Prototype.BrowserFeatures.ElementExtensions) { |
2587 Object.extend(Methods, Element.Methods); | 2948 Object.extend(Methods, Element.Methods); |
2588 Object.extend(Methods, Element.Methods.Simulated); | 2949 Object.extend(Methods, Element.Methods.Simulated); |
2589 } | 2950 } |
2590 } | 2951 } |
2591 }); | 2952 }); |
2592 | 2953 |
2593 extend.refresh(); | 2954 extend.refresh(); |
2594 return extend; | 2955 return extend; |
2595 })(); | 2956 })(); |
2596 | 2957 |
2597 Element.hasAttribute = function(element, attribute) { | 2958 if (document.documentElement.hasAttribute) { |
2598 if (element.hasAttribute) return element.hasAttribute(attribute); | 2959 Element.hasAttribute = function(element, attribute) { |
2599 return Element.Methods.Simulated.hasAttribute(element, attribute); | 2960 return element.hasAttribute(attribute); |
2600 }; | 2961 }; |
| 2962 } |
| 2963 else { |
| 2964 Element.hasAttribute = Element.Methods.Simulated.hasAttribute; |
| 2965 } |
2601 | 2966 |
2602 Element.addMethods = function(methods) { | 2967 Element.addMethods = function(methods) { |
2603 var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; | 2968 var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag; |
2604 | 2969 |
2605 if (!methods) { | 2970 if (!methods) { |
2606 Object.extend(Form, Form.Methods); | 2971 Object.extend(Form, Form.Methods); |
2607 Object.extend(Form.Element, Form.Element.Methods); | 2972 Object.extend(Form.Element, Form.Element.Methods); |
2608 Object.extend(Element.Methods.ByTag, { | 2973 Object.extend(Element.Methods.ByTag, { |
2609 "FORM": Object.clone(Form.Methods), | 2974 "FORM": Object.clone(Form.Methods), |
2610 "INPUT": Object.clone(Form.Element.Methods), | 2975 "INPUT": Object.clone(Form.Element.Methods), |
2611 "SELECT": Object.clone(Form.Element.Methods), | 2976 "SELECT": Object.clone(Form.Element.Methods), |
2612 "TEXTAREA": Object.clone(Form.Element.Methods) | 2977 "TEXTAREA": Object.clone(Form.Element.Methods), |
| 2978 "BUTTON": Object.clone(Form.Element.Methods) |
2613 }); | 2979 }); |
2614 } | 2980 } |
2615 | 2981 |
2616 if (arguments.length == 2) { | 2982 if (arguments.length == 2) { |
2617 var tagName = methods; | 2983 var tagName = methods; |
2618 methods = arguments[1]; | 2984 methods = arguments[1]; |
2619 } | 2985 } |
2620 | 2986 |
2621 if (!tagName) Object.extend(Element.Methods, methods || { }); | 2987 if (!tagName) Object.extend(Element.Methods, methods || { }); |
2622 else { | 2988 else { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2654 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": | 3020 "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET": |
2655 "FrameSet", "IFRAME": "IFrame" | 3021 "FrameSet", "IFRAME": "IFrame" |
2656 }; | 3022 }; |
2657 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; | 3023 if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element'; |
2658 if (window[klass]) return window[klass]; | 3024 if (window[klass]) return window[klass]; |
2659 klass = 'HTML' + tagName + 'Element'; | 3025 klass = 'HTML' + tagName + 'Element'; |
2660 if (window[klass]) return window[klass]; | 3026 if (window[klass]) return window[klass]; |
2661 klass = 'HTML' + tagName.capitalize() + 'Element'; | 3027 klass = 'HTML' + tagName.capitalize() + 'Element'; |
2662 if (window[klass]) return window[klass]; | 3028 if (window[klass]) return window[klass]; |
2663 | 3029 |
2664 window[klass] = { }; | 3030 var element = document.createElement(tagName), |
2665 window[klass].prototype = document.createElement(tagName)['__proto__']; | 3031 proto = element['__proto__'] || element.constructor.prototype; |
2666 return window[klass]; | 3032 |
| 3033 element = null; |
| 3034 return proto; |
2667 } | 3035 } |
2668 | 3036 |
| 3037 var elementPrototype = window.HTMLElement ? HTMLElement.prototype : |
| 3038 Element.prototype; |
| 3039 |
2669 if (F.ElementExtensions) { | 3040 if (F.ElementExtensions) { |
2670 copy(Element.Methods, HTMLElement.prototype); | 3041 copy(Element.Methods, elementPrototype); |
2671 copy(Element.Methods.Simulated, HTMLElement.prototype, true); | 3042 copy(Element.Methods.Simulated, elementPrototype, true); |
2672 } | 3043 } |
2673 | 3044 |
2674 if (F.SpecificElementExtensions) { | 3045 if (F.SpecificElementExtensions) { |
2675 for (var tag in Element.Methods.ByTag) { | 3046 for (var tag in Element.Methods.ByTag) { |
2676 var klass = findDOMClass(tag); | 3047 var klass = findDOMClass(tag); |
2677 if (Object.isUndefined(klass)) continue; | 3048 if (Object.isUndefined(klass)) continue; |
2678 copy(T[tag], klass.prototype); | 3049 copy(T[tag], klass.prototype); |
2679 } | 3050 } |
2680 } | 3051 } |
2681 | 3052 |
2682 Object.extend(Element, Element.Methods); | 3053 Object.extend(Element, Element.Methods); |
2683 delete Element.ByTag; | 3054 delete Element.ByTag; |
2684 | 3055 |
2685 if (Element.extend.refresh) Element.extend.refresh(); | 3056 if (Element.extend.refresh) Element.extend.refresh(); |
2686 Element.cache = { }; | 3057 Element.cache = { }; |
2687 }; | 3058 }; |
2688 | 3059 |
| 3060 |
2689 document.viewport = { | 3061 document.viewport = { |
| 3062 |
2690 getDimensions: function() { | 3063 getDimensions: function() { |
2691 var dimensions = { }, B = Prototype.Browser; | 3064 return { width: this.getWidth(), height: this.getHeight() }; |
2692 $w('width height').each(function(d) { | |
2693 var D = d.capitalize(); | |
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 } | |
2703 }); | |
2704 return dimensions; | |
2705 }, | |
2706 | |
2707 getWidth: function() { | |
2708 return this.getDimensions().width; | |
2709 }, | |
2710 | |
2711 getHeight: function() { | |
2712 return this.getDimensions().height; | |
2713 }, | 3065 }, |
2714 | 3066 |
2715 getScrollOffsets: function() { | 3067 getScrollOffsets: function() { |
2716 return Element._returnOffset( | 3068 return Element._returnOffset( |
2717 window.pageXOffset || document.documentElement.scrollLeft || document.body
.scrollLeft, | 3069 window.pageXOffset || document.documentElement.scrollLeft || document.body
.scrollLeft, |
2718 window.pageYOffset || document.documentElement.scrollTop || document.body.
scrollTop); | 3070 window.pageYOffset || document.documentElement.scrollTop || document.body
.scrollTop); |
2719 } | 3071 } |
2720 }; | 3072 }; |
2721 /* Portions of the Selector class are derived from Jack Slocum's DomQuery, | 3073 |
2722 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style | 3074 (function(viewport) { |
2723 * license. Please see http://www.yui-ext.com/ for more information. */ | 3075 var B = Prototype.Browser, doc = document, element, property = {}; |
2724 | 3076 |
2725 var Selector = Class.create({ | 3077 function getRootElement() { |
2726 initialize: function(expression) { | 3078 if (B.WebKit && !doc.evaluate) |
2727 this.expression = expression.strip(); | 3079 return document; |
2728 | 3080 |
2729 if (this.shouldUseSelectorsAPI()) { | 3081 if (B.Opera && window.parseFloat(window.opera.version()) < 9.5) |
2730 this.mode = 'selectorsAPI'; | 3082 return document.body; |
2731 } else if (this.shouldUseXPath()) { | 3083 |
2732 this.mode = 'xpath'; | 3084 return document.documentElement; |
2733 this.compileXPathMatcher(); | 3085 } |
| 3086 |
| 3087 function define(D) { |
| 3088 if (!element) element = getRootElement(); |
| 3089 |
| 3090 property[D] = 'client' + D; |
| 3091 |
| 3092 viewport['get' + D] = function() { return element[property[D]] }; |
| 3093 return viewport['get' + D](); |
| 3094 } |
| 3095 |
| 3096 viewport.getWidth = define.curry('Width'); |
| 3097 |
| 3098 viewport.getHeight = define.curry('Height'); |
| 3099 })(document.viewport); |
| 3100 |
| 3101 |
| 3102 Element.Storage = { |
| 3103 UID: 1 |
| 3104 }; |
| 3105 |
| 3106 Element.addMethods({ |
| 3107 getStorage: function(element) { |
| 3108 if (!(element = $(element))) return; |
| 3109 |
| 3110 var uid; |
| 3111 if (element === window) { |
| 3112 uid = 0; |
2734 } else { | 3113 } else { |
2735 this.mode = "normal"; | 3114 if (typeof element._prototypeUID === "undefined") |
2736 this.compileMatcher(); | 3115 element._prototypeUID = Element.Storage.UID++; |
2737 } | 3116 uid = element._prototypeUID; |
2738 | 3117 } |
| 3118 |
| 3119 if (!Element.Storage[uid]) |
| 3120 Element.Storage[uid] = $H(); |
| 3121 |
| 3122 return Element.Storage[uid]; |
2739 }, | 3123 }, |
2740 | 3124 |
2741 shouldUseXPath: function() { | 3125 store: function(element, key, value) { |
2742 if (!Prototype.BrowserFeatures.XPath) return false; | 3126 if (!(element = $(element))) return; |
2743 | 3127 |
2744 var e = this.expression; | 3128 if (arguments.length === 2) { |
2745 | 3129 Element.getStorage(element).update(key); |
2746 // Safari 3 chokes on :*-of-type and :empty | 3130 } else { |
2747 if (Prototype.Browser.WebKit && | 3131 Element.getStorage(element).set(key, value); |
2748 (e.include("-of-type") || e.include(":empty"))) | 3132 } |
2749 return false; | 3133 |
2750 | 3134 return element; |
2751 // XPath can't do namespaced attributes, nor can it read | |
2752 // the "checked" property from DOM nodes | |
2753 if ((/(\[[\w-]*?:|:checked)/).test(e)) | |
2754 return false; | |
2755 | |
2756 return true; | |
2757 }, | 3135 }, |
2758 | 3136 |
2759 shouldUseSelectorsAPI: function() { | 3137 retrieve: function(element, key, defaultValue) { |
2760 if (!Prototype.BrowserFeatures.SelectorsAPI) return false; | 3138 if (!(element = $(element))) return; |
2761 | 3139 var hash = Element.getStorage(element), value = hash.get(key); |
2762 if (!Selector._div) Selector._div = new Element('div'); | 3140 |
2763 | 3141 if (Object.isUndefined(value)) { |
2764 // Make sure the browser treats the selector as valid. Test on an | 3142 hash.set(key, defaultValue); |
2765 // isolated element to minimize cost of this check. | 3143 value = defaultValue; |
2766 try { | 3144 } |
2767 Selector._div.querySelector(this.expression); | 3145 |
2768 } catch(e) { | 3146 return value; |
2769 return false; | |
2770 } | |
2771 | |
2772 return true; | |
2773 }, | 3147 }, |
2774 | 3148 |
2775 compileMatcher: function() { | 3149 clone: function(element, deep) { |
2776 var e = this.expression, ps = Selector.patterns, h = Selector.handlers, | 3150 if (!(element = $(element))) return; |
2777 c = Selector.criteria, le, p, m; | 3151 var clone = element.cloneNode(deep); |
2778 | 3152 clone._prototypeUID = void 0; |
2779 if (Selector._cache[e]) { | 3153 if (deep) { |
2780 this.matcher = Selector._cache[e]; | 3154 var descendants = Element.select(clone, '*'), |
2781 return; | 3155 i = descendants.length; |
2782 } | 3156 while (i--) { |
2783 | 3157 descendants[i]._prototypeUID = void 0; |
2784 this.matcher = ["this.matcher = function(root) {", | 3158 } |
2785 "var r = root, h = Selector.handlers, c = false, n;"]; | 3159 } |
2786 | 3160 return Element.extend(clone); |
2787 while (e && le != e && (/\S/).test(e)) { | 3161 }, |
2788 le = e; | 3162 |
2789 for (var i in ps) { | 3163 purge: function(element) { |
2790 p = ps[i]; | 3164 if (!(element = $(element))) return; |
2791 if (m = e.match(p)) { | 3165 var purgeElement = Element._purgeElement; |
2792 this.matcher.push(Object.isFunction(c[i]) ? c[i](m) : | 3166 |
2793 new Template(c[i]).evaluate(m)); | 3167 purgeElement(element); |
2794 e = e.replace(m[0], ''); | 3168 |
2795 break; | 3169 var descendants = element.getElementsByTagName('*'), |
| 3170 i = descendants.length; |
| 3171 |
| 3172 while (i--) purgeElement(descendants[i]); |
| 3173 |
| 3174 return null; |
| 3175 } |
| 3176 }); |
| 3177 |
| 3178 (function() { |
| 3179 |
| 3180 function toDecimal(pctString) { |
| 3181 var match = pctString.match(/^(\d+)%?$/i); |
| 3182 if (!match) return null; |
| 3183 return (Number(match[1]) / 100); |
| 3184 } |
| 3185 |
| 3186 function getPixelValue(value, property, context) { |
| 3187 var element = null; |
| 3188 if (Object.isElement(value)) { |
| 3189 element = value; |
| 3190 value = element.getStyle(property); |
| 3191 } |
| 3192 |
| 3193 if (value === null) { |
| 3194 return null; |
| 3195 } |
| 3196 |
| 3197 if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) { |
| 3198 return window.parseFloat(value); |
| 3199 } |
| 3200 |
| 3201 var isPercentage = value.include('%'), isViewport = (context === document.vi
ewport); |
| 3202 |
| 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; |
| 3210 |
| 3211 return value; |
| 3212 } |
| 3213 |
| 3214 if (element && isPercentage) { |
| 3215 context = context || element.parentNode; |
| 3216 var decimal = toDecimal(value); |
| 3217 var whole = null; |
| 3218 var position = element.getStyle('position'); |
| 3219 |
| 3220 var isHorizontal = property.include('left') || property.include('right') |
| |
| 3221 property.include('width'); |
| 3222 |
| 3223 var isVertical = property.include('top') || property.include('bottom') || |
| 3224 property.include('height'); |
| 3225 |
| 3226 if (context === document.viewport) { |
| 3227 if (isHorizontal) { |
| 3228 whole = document.viewport.getWidth(); |
| 3229 } else if (isVertical) { |
| 3230 whole = document.viewport.getHeight(); |
| 3231 } |
| 3232 } else { |
| 3233 if (isHorizontal) { |
| 3234 whole = $(context).measure('width'); |
| 3235 } else if (isVertical) { |
| 3236 whole = $(context).measure('height'); |
2796 } | 3237 } |
2797 } | 3238 } |
2798 } | 3239 |
2799 | 3240 return (whole === null) ? 0 : whole * decimal; |
2800 this.matcher.push("return h.unique(n);\n}"); | 3241 } |
2801 eval(this.matcher.join('\n')); | 3242 |
2802 Selector._cache[this.expression] = this.matcher; | 3243 return 0; |
2803 }, | 3244 } |
2804 | 3245 |
2805 compileXPathMatcher: function() { | 3246 function toCSSPixels(number) { |
2806 var e = this.expression, ps = Selector.patterns, | 3247 if (Object.isString(number) && number.endsWith('px')) { |
2807 x = Selector.xpath, le, m; | 3248 return number; |
2808 | 3249 } |
2809 if (Selector._cache[e]) { | 3250 return number + 'px'; |
2810 this.xpath = Selector._cache[e]; return; | 3251 } |
2811 } | 3252 |
2812 | 3253 function isDisplayed(element) { |
2813 this.matcher = ['.//*']; | 3254 var originalElement = element; |
2814 while (e && le != e && (/\S/).test(e)) { | 3255 while (element && element.parentNode) { |
2815 le = e; | 3256 var display = element.getStyle('display'); |
2816 for (var i in ps) { | 3257 if (display === 'none') { |
2817 if (m = e.match(ps[i])) { | 3258 return false; |
2818 this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : | |
2819 new Template(x[i]).evaluate(m)); | |
2820 e = e.replace(m[0], ''); | |
2821 break; | |
2822 } | |
2823 } | 3259 } |
2824 } | 3260 element = $(element.parentNode); |
2825 | 3261 } |
2826 this.xpath = this.matcher.join(''); | 3262 return true; |
2827 Selector._cache[this.expression] = this.xpath; | 3263 } |
2828 }, | 3264 |
2829 | 3265 var hasLayout = Prototype.K; |
2830 findElements: function(root) { | 3266 if ('currentStyle' in document.documentElement) { |
2831 root = root || document; | 3267 hasLayout = function(element) { |
2832 var e = this.expression, results; | 3268 if (!element.currentStyle.hasLayout) { |
2833 | 3269 element.style.zoom = 1; |
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 } | |
2853 }, | |
2854 | |
2855 match: function(element) { | |
2856 this.tokens = []; | |
2857 | |
2858 var e = this.expression, ps = Selector.patterns, as = Selector.assertions; | |
2859 var le, p, m; | |
2860 | |
2861 while (e && le !== e && (/\S/).test(e)) { | |
2862 le = e; | |
2863 for (var i in ps) { | |
2864 p = ps[i]; | |
2865 if (m = e.match(p)) { | |
2866 // use the Selector.assertions methods unless the selector | |
2867 // is too complex. | |
2868 if (as[i]) { | |
2869 this.tokens.push([i, Object.clone(m)]); | |
2870 e = e.replace(m[0], ''); | |
2871 } else { | |
2872 // reluctantly do a document-wide search | |
2873 // and look for a match in the array | |
2874 return this.findElements(document).include(element); | |
2875 } | |
2876 } | |
2877 } | 3270 } |
2878 } | 3271 return element; |
2879 | 3272 }; |
2880 var match = true, name, matches; | 3273 } |
2881 for (var i = 0, token; token = this.tokens[i]; i++) { | 3274 |
2882 name = token[0], matches = token[1]; | 3275 function cssNameFor(key) { |
2883 if (!Selector.assertions[name](element, matches)) { | 3276 if (key.include('border')) key = key + '-width'; |
2884 match = false; break; | 3277 return key.camelize(); |
2885 } | 3278 } |
2886 } | 3279 |
2887 | 3280 Element.Layout = Class.create(Hash, { |
2888 return match; | 3281 initialize: function($super, element, preCompute) { |
2889 }, | 3282 $super(); |
2890 | 3283 this.element = $(element); |
2891 toString: function() { | 3284 |
2892 return this.expression; | 3285 Element.Layout.PROPERTIES.each( function(property) { |
2893 }, | 3286 this._set(property, null); |
2894 | 3287 }, this); |
2895 inspect: function() { | 3288 |
2896 return "#<Selector:" + this.expression.inspect() + ">"; | 3289 if (preCompute) { |
2897 } | 3290 this._preComputing = true; |
2898 }); | 3291 this._begin(); |
2899 | 3292 Element.Layout.PROPERTIES.each( this._compute, this ); |
2900 Object.extend(Selector, { | 3293 this._end(); |
2901 _cache: { }, | 3294 this._preComputing = false; |
2902 | |
2903 xpath: { | |
2904 descendant: "//*", | |
2905 child: "/*", | |
2906 adjacent: "/following-sibling::*[1]", | |
2907 laterSibling: '/following-sibling::*', | |
2908 tagName: function(m) { | |
2909 if (m[1] == '*') return ''; | |
2910 return "[local-name()='" + m[1].toLowerCase() + | |
2911 "' or local-name()='" + m[1].toUpperCase() + "']"; | |
2912 }, | |
2913 className: "[contains(concat(' ', @class, ' '), ' #{1} ')]", | |
2914 id: "[@id='#{1}']", | |
2915 attrPresence: function(m) { | |
2916 m[1] = m[1].toLowerCase(); | |
2917 return new Template("[@#{1}]").evaluate(m); | |
2918 }, | |
2919 attr: function(m) { | |
2920 m[1] = m[1].toLowerCase(); | |
2921 m[3] = m[5] || m[6]; | |
2922 return new Template(Selector.xpath.operators[m[2]]).evaluate(m); | |
2923 }, | |
2924 pseudo: function(m) { | |
2925 var h = Selector.xpath.pseudos[m[1]]; | |
2926 if (!h) return ''; | |
2927 if (Object.isFunction(h)) return h(m); | |
2928 return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m); | |
2929 }, | |
2930 operators: { | |
2931 '=': "[@#{1}='#{3}']", | |
2932 '!=': "[@#{1}!='#{3}']", | |
2933 '^=': "[starts-with(@#{1}, '#{3}')]", | |
2934 '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1
))='#{3}']", | |
2935 '*=': "[contains(@#{1}, '#{3}')]", | |
2936 '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]", | |
2937 '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]" | |
2938 }, | |
2939 pseudos: { | |
2940 'first-child': '[not(preceding-sibling::*)]', | |
2941 'last-child': '[not(following-sibling::*)]', | |
2942 'only-child': '[not(preceding-sibling::* or following-sibling::*)]', | |
2943 'empty': "[count(*) = 0 and (count(text()) = 0)]", | |
2944 'checked': "[@checked]", | |
2945 'disabled': "[(@disabled) and (@type!='hidden')]", | |
2946 'enabled': "[not(@disabled) and (@type!='hidden')]", | |
2947 'not': function(m) { | |
2948 var e = m[6], p = Selector.patterns, | |
2949 x = Selector.xpath, le, v; | |
2950 | |
2951 var exclusion = []; | |
2952 while (e && le != e && (/\S/).test(e)) { | |
2953 le = e; | |
2954 for (var i in p) { | |
2955 if (m = e.match(p[i])) { | |
2956 v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluat
e(m); | |
2957 exclusion.push("(" + v.substring(1, v.length - 1) + ")"); | |
2958 e = e.replace(m[0], ''); | |
2959 break; | |
2960 } | |
2961 } | |
2962 } | |
2963 return "[not(" + exclusion.join(" and ") + ")]"; | |
2964 }, | |
2965 'nth-child': function(m) { | |
2966 return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) "
, m); | |
2967 }, | |
2968 'nth-last-child': function(m) { | |
2969 return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) "
, m); | |
2970 }, | |
2971 'nth-of-type': function(m) { | |
2972 return Selector.xpath.pseudos.nth("position() ", m); | |
2973 }, | |
2974 'nth-last-of-type': function(m) { | |
2975 return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m); | |
2976 }, | |
2977 'first-of-type': function(m) { | |
2978 m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m); | |
2979 }, | |
2980 'last-of-type': function(m) { | |
2981 m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m); | |
2982 }, | |
2983 'only-of-type': function(m) { | |
2984 var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-o
f-type'](m); | |
2985 }, | |
2986 nth: function(fragment, m) { | |
2987 var mm, formula = m[6], predicate; | |
2988 if (formula == 'even') formula = '2n+0'; | |
2989 if (formula == 'odd') formula = '2n+1'; | |
2990 if (mm = formula.match(/^(\d+)$/)) // digit only | |
2991 return '[' + fragment + "= " + mm[1] + ']'; | |
2992 if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b | |
2993 if (mm[1] == "-") mm[1] = -1; | |
2994 var a = mm[1] ? Number(mm[1]) : 1; | |
2995 var b = mm[2] ? Number(mm[2]) : 0; | |
2996 predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " + | |
2997 "((#{fragment} - #{b}) div #{a} >= 0)]"; | |
2998 return new Template(predicate).evaluate({ | |
2999 fragment: fragment, a: a, b: b }); | |
3000 } | |
3001 } | |
3002 } | |
3003 }, | |
3004 | |
3005 criteria: { | |
3006 tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;', | |
3007 className: 'n = h.className(n, r, "#{1}", c); c = false;', | |
3008 id: 'n = h.id(n, r, "#{1}", c); c = false;', | |
3009 attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;', | |
3010 attr: function(m) { | |
3011 m[3] = (m[5] || m[6]); | |
3012 return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = fals
e;').evaluate(m); | |
3013 }, | |
3014 pseudo: function(m) { | |
3015 if (m[6]) m[6] = m[6].replace(/"/g, '\\"'); | |
3016 return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').e
valuate(m); | |
3017 }, | |
3018 descendant: 'c = "descendant";', | |
3019 child: 'c = "child";', | |
3020 adjacent: 'c = "adjacent";', | |
3021 laterSibling: 'c = "laterSibling";' | |
3022 }, | |
3023 | |
3024 patterns: { | |
3025 // combinators must be listed first | |
3026 // (and descendant needs to be last combinator) | |
3027 laterSibling: /^\s*~\s*/, | |
3028 child: /^\s*>\s*/, | |
3029 adjacent: /^\s*\+\s*/, | |
3030 descendant: /^\s/, | |
3031 | |
3032 // selectors follow | |
3033 tagName: /^\s*(\*|[\w\-]+)(\b|$)?/, | |
3034 id: /^#([\w\-\*]+)(\b|$)/, | |
3035 className: /^\.([\w\-\*]+)(\b|$)/, | |
3036 pseudo: | |
3037 /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|
not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/, | |
3038 attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/, | |
3039 attr: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4
|([^'"][^\]]*?)))?\]/ | |
3040 }, | |
3041 | |
3042 // for Selector.match and Element#match | |
3043 assertions: { | |
3044 tagName: function(element, matches) { | |
3045 return matches[1].toUpperCase() == element.tagName.toUpperCase(); | |
3046 }, | |
3047 | |
3048 className: function(element, matches) { | |
3049 return Element.hasClassName(element, matches[1]); | |
3050 }, | |
3051 | |
3052 id: function(element, matches) { | |
3053 return element.id === matches[1]; | |
3054 }, | |
3055 | |
3056 attrPresence: function(element, matches) { | |
3057 return Element.hasAttribute(element, matches[1]); | |
3058 }, | |
3059 | |
3060 attr: function(element, matches) { | |
3061 var nodeValue = Element.readAttribute(element, matches[1]); | |
3062 return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] |
| matches[6]); | |
3063 } | |
3064 }, | |
3065 | |
3066 handlers: { | |
3067 // UTILITY FUNCTIONS | |
3068 // joins two collections | |
3069 concat: function(a, b) { | |
3070 for (var i = 0, node; node = b[i]; i++) | |
3071 a.push(node); | |
3072 return a; | |
3073 }, | |
3074 | |
3075 // marks an array of nodes for counting | |
3076 mark: function(nodes) { | |
3077 var _true = Prototype.emptyFunction; | |
3078 for (var i = 0, node; node = nodes[i]; i++) | |
3079 node._countedByPrototype = _true; | |
3080 return nodes; | |
3081 }, | |
3082 | |
3083 unmark: function(nodes) { | |
3084 for (var i = 0, node; node = nodes[i]; i++) | |
3085 node._countedByPrototype = undefined; | |
3086 return nodes; | |
3087 }, | |
3088 | |
3089 // mark each child node with its position (for nth calls) | |
3090 // "ofType" flag indicates whether we're indexing for nth-of-type | |
3091 // rather than nth-child | |
3092 index: function(parentNode, reverse, ofType) { | |
3093 parentNode._countedByPrototype = Prototype.emptyFunction; | |
3094 if (reverse) { | |
3095 for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >
= 0; i--) { | |
3096 var node = nodes[i]; | |
3097 if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.
nodeIndex = j++; | |
3098 } | |
3099 } else { | |
3100 for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i
++) | |
3101 if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.
nodeIndex = j++; | |
3102 } | 3295 } |
3103 }, | 3296 }, |
3104 | 3297 |
3105 // filters out duplicates and extends all nodes | 3298 _set: function(property, value) { |
3106 unique: function(nodes) { | 3299 return Hash.prototype.set.call(this, property, value); |
3107 if (nodes.length == 0) return nodes; | 3300 }, |
3108 var results = [], n; | 3301 |
3109 for (var i = 0, l = nodes.length; i < l; i++) | 3302 set: function(property, value) { |
3110 if (!(n = nodes[i])._countedByPrototype) { | 3303 throw "Properties of Element.Layout are read-only."; |
3111 n._countedByPrototype = Prototype.emptyFunction; | 3304 }, |
3112 results.push(Element.extend(n)); | 3305 |
| 3306 get: function($super, property) { |
| 3307 var value = $super(property); |
| 3308 return value === null ? this._compute(property) : value; |
| 3309 }, |
| 3310 |
| 3311 _begin: function() { |
| 3312 if (this._prepared) return; |
| 3313 |
| 3314 var element = this.element; |
| 3315 if (isDisplayed(element)) { |
| 3316 this._prepared = true; |
| 3317 return; |
| 3318 } |
| 3319 |
| 3320 var originalStyles = { |
| 3321 position: element.style.position || '', |
| 3322 width: element.style.width || '', |
| 3323 visibility: element.style.visibility || '', |
| 3324 display: element.style.display || '' |
| 3325 }; |
| 3326 |
| 3327 element.store('prototype_original_styles', originalStyles); |
| 3328 |
| 3329 var position = element.getStyle('position'), |
| 3330 width = element.getStyle('width'); |
| 3331 |
| 3332 if (width === "0px" || width === null) { |
| 3333 element.style.display = 'block'; |
| 3334 width = element.getStyle('width'); |
| 3335 } |
| 3336 |
| 3337 var context = (position === 'fixed') ? document.viewport : |
| 3338 element.parentNode; |
| 3339 |
| 3340 element.setStyle({ |
| 3341 position: 'absolute', |
| 3342 visibility: 'hidden', |
| 3343 display: 'block' |
| 3344 }); |
| 3345 |
| 3346 var positionedWidth = element.getStyle('width'); |
| 3347 |
| 3348 var newWidth; |
| 3349 if (width && (positionedWidth === width)) { |
| 3350 newWidth = getPixelValue(element, 'width', context); |
| 3351 } else if (position === 'absolute' || position === 'fixed') { |
| 3352 newWidth = getPixelValue(element, 'width', context); |
| 3353 } else { |
| 3354 var parent = element.parentNode, pLayout = $(parent).getLayout(); |
| 3355 |
| 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'); |
| 3363 } |
| 3364 |
| 3365 element.setStyle({ width: newWidth + 'px' }); |
| 3366 |
| 3367 this._prepared = true; |
| 3368 }, |
| 3369 |
| 3370 _end: function() { |
| 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; |
| 3376 }, |
| 3377 |
| 3378 _compute: function(property) { |
| 3379 var COMPUTATIONS = Element.Layout.COMPUTATIONS; |
| 3380 if (!(property in COMPUTATIONS)) { |
| 3381 throw "Property not found."; |
| 3382 } |
| 3383 |
| 3384 return this._set(property, COMPUTATIONS[property].call(this, this.element)
); |
| 3385 }, |
| 3386 |
| 3387 toObject: function() { |
| 3388 var args = $A(arguments); |
| 3389 var keys = (args.length === 0) ? Element.Layout.PROPERTIES : |
| 3390 args.join(' ').split(' '); |
| 3391 var obj = {}; |
| 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; |
| 3396 }, this); |
| 3397 return obj; |
| 3398 }, |
| 3399 |
| 3400 toHash: function() { |
| 3401 var obj = this.toObject.apply(this, arguments); |
| 3402 return new Hash(obj); |
| 3403 }, |
| 3404 |
| 3405 toCSS: function() { |
| 3406 var args = $A(arguments); |
| 3407 var keys = (args.length === 0) ? Element.Layout.PROPERTIES : |
| 3408 args.join(' ').split(' '); |
| 3409 var css = {}; |
| 3410 |
| 3411 keys.each( function(key) { |
| 3412 if (!Element.Layout.PROPERTIES.include(key)) return; |
| 3413 if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return; |
| 3414 |
| 3415 var value = this.get(key); |
| 3416 if (value != null) css[cssNameFor(key)] = value + 'px'; |
| 3417 }, this); |
| 3418 return css; |
| 3419 }, |
| 3420 |
| 3421 inspect: function() { |
| 3422 return "#<Element.Layout>"; |
| 3423 } |
| 3424 }); |
| 3425 |
| 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 m
argin-top margin-bottom margin-left margin-right padding-box-width padding-box-h
eight border-box-width border-box-height margin-box-width margin-box-height'), |
| 3428 |
| 3429 COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-wi
dth margin-box-height border-box-width border-box-height'), |
| 3430 |
| 3431 COMPUTATIONS: { |
| 3432 'height': function(element) { |
| 3433 if (!this._preComputing) this._begin(); |
| 3434 |
| 3435 var bHeight = this.get('border-box-height'); |
| 3436 if (bHeight <= 0) { |
| 3437 if (!this._preComputing) this._end(); |
| 3438 return 0; |
3113 } | 3439 } |
3114 return Selector.handlers.unmark(results); | 3440 |
| 3441 var bTop = this.get('border-top'), |
| 3442 bBottom = this.get('border-bottom'); |
| 3443 |
| 3444 var pTop = this.get('padding-top'), |
| 3445 pBottom = this.get('padding-bottom'); |
| 3446 |
| 3447 if (!this._preComputing) this._end(); |
| 3448 |
| 3449 return bHeight - bTop - bBottom - pTop - pBottom; |
| 3450 }, |
| 3451 |
| 3452 'width': function(element) { |
| 3453 if (!this._preComputing) this._begin(); |
| 3454 |
| 3455 var bWidth = this.get('border-box-width'); |
| 3456 if (bWidth <= 0) { |
| 3457 if (!this._preComputing) this._end(); |
| 3458 return 0; |
| 3459 } |
| 3460 |
| 3461 var bLeft = this.get('border-left'), |
| 3462 bRight = this.get('border-right'); |
| 3463 |
| 3464 var pLeft = this.get('padding-left'), |
| 3465 pRight = this.get('padding-right'); |
| 3466 |
| 3467 if (!this._preComputing) this._end(); |
| 3468 |
| 3469 return bWidth - bLeft - bRight - pLeft - pRight; |
| 3470 }, |
| 3471 |
| 3472 'padding-box-height': function(element) { |
| 3473 var height = this.get('height'), |
| 3474 pTop = this.get('padding-top'), |
| 3475 pBottom = this.get('padding-bottom'); |
| 3476 |
| 3477 return height + pTop + pBottom; |
| 3478 }, |
| 3479 |
| 3480 'padding-box-width': function(element) { |
| 3481 var width = this.get('width'), |
| 3482 pLeft = this.get('padding-left'), |
| 3483 pRight = this.get('padding-right'); |
| 3484 |
| 3485 return width + pLeft + pRight; |
| 3486 }, |
| 3487 |
| 3488 'border-box-height': function(element) { |
| 3489 if (!this._preComputing) this._begin(); |
| 3490 var height = element.offsetHeight; |
| 3491 if (!this._preComputing) this._end(); |
| 3492 return height; |
| 3493 }, |
| 3494 |
| 3495 'border-box-width': function(element) { |
| 3496 if (!this._preComputing) this._begin(); |
| 3497 var width = element.offsetWidth; |
| 3498 if (!this._preComputing) this._end(); |
| 3499 return width; |
| 3500 }, |
| 3501 |
| 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'); |
| 3506 |
| 3507 if (bHeight <= 0) return 0; |
| 3508 |
| 3509 return bHeight + mTop + mBottom; |
| 3510 }, |
| 3511 |
| 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'); |
| 3516 |
| 3517 if (bWidth <= 0) return 0; |
| 3518 |
| 3519 return bWidth + mLeft + mRight; |
| 3520 }, |
| 3521 |
| 3522 'top': function(element) { |
| 3523 var offset = element.positionedOffset(); |
| 3524 return offset.top; |
| 3525 }, |
| 3526 |
| 3527 'bottom': function(element) { |
| 3528 var offset = element.positionedOffset(), |
| 3529 parent = element.getOffsetParent(), |
| 3530 pHeight = parent.measure('height'); |
| 3531 |
| 3532 var mHeight = this.get('border-box-height'); |
| 3533 |
| 3534 return pHeight - mHeight - offset.top; |
| 3535 }, |
| 3536 |
| 3537 'left': function(element) { |
| 3538 var offset = element.positionedOffset(); |
| 3539 return offset.left; |
| 3540 }, |
| 3541 |
| 3542 'right': function(element) { |
| 3543 var offset = element.positionedOffset(), |
| 3544 parent = element.getOffsetParent(), |
| 3545 pWidth = parent.measure('width'); |
| 3546 |
| 3547 var mWidth = this.get('border-box-width'); |
| 3548 |
| 3549 return pWidth - mWidth - offset.left; |
| 3550 }, |
| 3551 |
| 3552 'padding-top': function(element) { |
| 3553 return getPixelValue(element, 'paddingTop'); |
| 3554 }, |
| 3555 |
| 3556 'padding-bottom': function(element) { |
| 3557 return getPixelValue(element, 'paddingBottom'); |
| 3558 }, |
| 3559 |
| 3560 'padding-left': function(element) { |
| 3561 return getPixelValue(element, 'paddingLeft'); |
| 3562 }, |
| 3563 |
| 3564 'padding-right': function(element) { |
| 3565 return getPixelValue(element, 'paddingRight'); |
| 3566 }, |
| 3567 |
| 3568 'border-top': function(element) { |
| 3569 return getPixelValue(element, 'borderTopWidth'); |
| 3570 }, |
| 3571 |
| 3572 'border-bottom': function(element) { |
| 3573 return getPixelValue(element, 'borderBottomWidth'); |
| 3574 }, |
| 3575 |
| 3576 'border-left': function(element) { |
| 3577 return getPixelValue(element, 'borderLeftWidth'); |
| 3578 }, |
| 3579 |
| 3580 'border-right': function(element) { |
| 3581 return getPixelValue(element, 'borderRightWidth'); |
| 3582 }, |
| 3583 |
| 3584 'margin-top': function(element) { |
| 3585 return getPixelValue(element, 'marginTop'); |
| 3586 }, |
| 3587 |
| 3588 'margin-bottom': function(element) { |
| 3589 return getPixelValue(element, 'marginBottom'); |
| 3590 }, |
| 3591 |
| 3592 'margin-left': function(element) { |
| 3593 return getPixelValue(element, 'marginLeft'); |
| 3594 }, |
| 3595 |
| 3596 'margin-right': function(element) { |
| 3597 return getPixelValue(element, 'marginRight'); |
| 3598 } |
| 3599 } |
| 3600 }); |
| 3601 |
| 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(); |
| 3608 |
| 3609 return (pRect.right - rect.right).round(); |
| 3610 }, |
| 3611 |
| 3612 'bottom': function(element) { |
| 3613 var parent = hasLayout(element.getOffsetParent()); |
| 3614 var rect = element.getBoundingClientRect(), |
| 3615 pRect = parent.getBoundingClientRect(); |
| 3616 |
| 3617 return (pRect.bottom - rect.bottom).round(); |
| 3618 } |
| 3619 }); |
| 3620 } |
| 3621 |
| 3622 Element.Offset = Class.create({ |
| 3623 initialize: function(left, top) { |
| 3624 this.left = left.round(); |
| 3625 this.top = top.round(); |
| 3626 |
| 3627 this[0] = this.left; |
| 3628 this[1] = this.top; |
3115 }, | 3629 }, |
3116 | 3630 |
3117 // COMBINATOR FUNCTIONS | 3631 relativeTo: function(offset) { |
3118 descendant: function(nodes) { | 3632 return new Element.Offset( |
3119 var h = Selector.handlers; | 3633 this.left - offset.left, |
3120 for (var i = 0, results = [], node; node = nodes[i]; i++) | 3634 this.top - offset.top |
3121 h.concat(results, node.getElementsByTagName('*')); | 3635 ); |
3122 return results; | |
3123 }, | 3636 }, |
3124 | 3637 |
3125 child: function(nodes) { | 3638 inspect: function() { |
3126 var h = Selector.handlers; | 3639 return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this); |
3127 for (var i = 0, results = [], node; node = nodes[i]; i++) { | 3640 }, |
3128 for (var j = 0, child; child = node.childNodes[j]; j++) | 3641 |
3129 if (child.nodeType == 1 && child.tagName != '!') results.push(child); | 3642 toString: function() { |
| 3643 return "[#{left}, #{top}]".interpolate(this); |
| 3644 }, |
| 3645 |
| 3646 toArray: function() { |
| 3647 return [this.left, this.top]; |
| 3648 } |
| 3649 }); |
| 3650 |
| 3651 function getLayout(element, preCompute) { |
| 3652 return new Element.Layout(element, preCompute); |
| 3653 } |
| 3654 |
| 3655 function measure(element, property) { |
| 3656 return $(element).getLayout().get(property); |
| 3657 } |
| 3658 |
| 3659 function getDimensions(element) { |
| 3660 element = $(element); |
| 3661 var display = Element.getStyle(element, 'display'); |
| 3662 |
| 3663 if (display && display !== 'none') { |
| 3664 return { width: element.offsetWidth, height: element.offsetHeight }; |
| 3665 } |
| 3666 |
| 3667 var style = element.style; |
| 3668 var originalStyles = { |
| 3669 visibility: style.visibility, |
| 3670 position: style.position, |
| 3671 display: style.display |
| 3672 }; |
| 3673 |
| 3674 var newStyles = { |
| 3675 visibility: 'hidden', |
| 3676 display: 'block' |
| 3677 }; |
| 3678 |
| 3679 if (originalStyles.position !== 'fixed') |
| 3680 newStyles.position = 'absolute'; |
| 3681 |
| 3682 Element.setStyle(element, newStyles); |
| 3683 |
| 3684 var dimensions = { |
| 3685 width: element.offsetWidth, |
| 3686 height: element.offsetHeight |
| 3687 }; |
| 3688 |
| 3689 Element.setStyle(element, originalStyles); |
| 3690 |
| 3691 return dimensions; |
| 3692 } |
| 3693 |
| 3694 function getOffsetParent(element) { |
| 3695 element = $(element); |
| 3696 |
| 3697 if (isDocument(element) || isDetached(element) || isBody(element) || isHtml(
element)) |
| 3698 return $(document.body); |
| 3699 |
| 3700 var isInline = (Element.getStyle(element, 'display') === 'inline'); |
| 3701 if (!isInline && element.offsetParent) return $(element.offsetParent); |
| 3702 |
| 3703 while ((element = element.parentNode) && element !== document.body) { |
| 3704 if (Element.getStyle(element, 'position') !== 'static') { |
| 3705 return isHtml(element) ? $(document.body) : $(element); |
3130 } | 3706 } |
3131 return results; | 3707 } |
3132 }, | 3708 |
3133 | 3709 return $(document.body); |
3134 adjacent: function(nodes) { | 3710 } |
3135 for (var i = 0, results = [], node; node = nodes[i]; i++) { | 3711 |
3136 var next = this.nextElementSibling(node); | 3712 |
3137 if (next) results.push(next); | 3713 function cumulativeOffset(element) { |
| 3714 element = $(element); |
| 3715 var valueT = 0, valueL = 0; |
| 3716 if (element.parentNode) { |
| 3717 do { |
| 3718 valueT += element.offsetTop || 0; |
| 3719 valueL += element.offsetLeft || 0; |
| 3720 element = element.offsetParent; |
| 3721 } while (element); |
| 3722 } |
| 3723 return new Element.Offset(valueL, valueT); |
| 3724 } |
| 3725 |
| 3726 function positionedOffset(element) { |
| 3727 element = $(element); |
| 3728 |
| 3729 var layout = element.getLayout(); |
| 3730 |
| 3731 var valueT = 0, valueL = 0; |
| 3732 do { |
| 3733 valueT += element.offsetTop || 0; |
| 3734 valueL += element.offsetLeft || 0; |
| 3735 element = element.offsetParent; |
| 3736 if (element) { |
| 3737 if (isBody(element)) break; |
| 3738 var p = Element.getStyle(element, 'position'); |
| 3739 if (p !== 'static') break; |
3138 } | 3740 } |
3139 return results; | 3741 } while (element); |
3140 }, | 3742 |
3141 | 3743 valueL -= layout.get('margin-top'); |
3142 laterSibling: function(nodes) { | 3744 valueT -= layout.get('margin-left'); |
3143 var h = Selector.handlers; | 3745 |
3144 for (var i = 0, results = [], node; node = nodes[i]; i++) | 3746 return new Element.Offset(valueL, valueT); |
3145 h.concat(results, Element.nextSiblings(node)); | 3747 } |
3146 return results; | 3748 |
3147 }, | 3749 function cumulativeScrollOffset(element) { |
3148 | 3750 var valueT = 0, valueL = 0; |
3149 nextElementSibling: function(node) { | 3751 do { |
3150 while (node = node.nextSibling) | 3752 valueT += element.scrollTop || 0; |
3151 if (node.nodeType == 1) return node; | 3753 valueL += element.scrollLeft || 0; |
3152 return null; | 3754 element = element.parentNode; |
3153 }, | 3755 } while (element); |
3154 | 3756 return new Element.Offset(valueL, valueT); |
3155 previousElementSibling: function(node) { | 3757 } |
3156 while (node = node.previousSibling) | 3758 |
3157 if (node.nodeType == 1) return node; | 3759 function viewportOffset(forElement) { |
3158 return null; | 3760 element = $(element); |
3159 }, | 3761 var valueT = 0, valueL = 0, docBody = document.body; |
3160 | 3762 |
3161 // TOKEN FUNCTIONS | 3763 var element = forElement; |
3162 tagName: function(nodes, root, tagName, combinator) { | 3764 do { |
3163 var uTagName = tagName.toUpperCase(); | 3765 valueT += element.offsetTop || 0; |
3164 var results = [], h = Selector.handlers; | 3766 valueL += element.offsetLeft || 0; |
3165 if (nodes) { | 3767 if (element.offsetParent == docBody && |
3166 if (combinator) { | 3768 Element.getStyle(element, 'position') == 'absolute') break; |
3167 // fastlane for ordinary descendant combinators | 3769 } while (element = element.offsetParent); |
3168 if (combinator == "descendant") { | 3770 |
3169 for (var i = 0, node; node = nodes[i]; i++) | 3771 element = forElement; |
3170 h.concat(results, node.getElementsByTagName(tagName)); | 3772 do { |
3171 return results; | 3773 if (element != docBody) { |
3172 } else nodes = this[combinator](nodes); | 3774 valueT -= element.scrollTop || 0; |
3173 if (tagName == "*") return nodes; | 3775 valueL -= element.scrollLeft || 0; |
3174 } | |
3175 for (var i = 0, node; node = nodes[i]; i++) | |
3176 if (node.tagName.toUpperCase() === uTagName) results.push(node); | |
3177 return results; | |
3178 } else return root.getElementsByTagName(tagName); | |
3179 }, | |
3180 | |
3181 id: function(nodes, root, id, combinator) { | |
3182 var targetNode = $(id), h = Selector.handlers; | |
3183 if (!targetNode) return []; | |
3184 if (!nodes && root == document) return [targetNode]; | |
3185 if (nodes) { | |
3186 if (combinator) { | |
3187 if (combinator == 'child') { | |
3188 for (var i = 0, node; node = nodes[i]; i++) | |
3189 if (targetNode.parentNode == node) return [targetNode]; | |
3190 } else if (combinator == 'descendant') { | |
3191 for (var i = 0, node; node = nodes[i]; i++) | |
3192 if (Element.descendantOf(targetNode, node)) return [targetNode]; | |
3193 } else if (combinator == 'adjacent') { | |
3194 for (var i = 0, node; node = nodes[i]; i++) | |
3195 if (Selector.handlers.previousElementSibling(targetNode) == node) | |
3196 return [targetNode]; | |
3197 } else nodes = h[combinator](nodes); | |
3198 } | |
3199 for (var i = 0, node; node = nodes[i]; i++) | |
3200 if (node == targetNode) return [targetNode]; | |
3201 return []; | |
3202 } | 3776 } |
3203 return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNod
e] : []; | 3777 } while (element = element.parentNode); |
3204 }, | 3778 return new Element.Offset(valueL, valueT); |
3205 | 3779 } |
3206 className: function(nodes, root, className, combinator) { | 3780 |
3207 if (nodes && combinator) nodes = this[combinator](nodes); | 3781 function absolutize(element) { |
3208 return Selector.handlers.byClassName(nodes, root, className); | 3782 element = $(element); |
3209 }, | 3783 |
3210 | 3784 if (Element.getStyle(element, 'position') === 'absolute') { |
3211 byClassName: function(nodes, root, className) { | 3785 return element; |
3212 if (!nodes) nodes = Selector.handlers.descendant([root]); | 3786 } |
3213 var needle = ' ' + className + ' '; | 3787 |
3214 for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) { | 3788 var offsetParent = getOffsetParent(element); |
3215 nodeClassName = node.className; | 3789 var eOffset = element.viewportOffset(), |
3216 if (nodeClassName.length == 0) continue; | 3790 pOffset = offsetParent.viewportOffset(); |
3217 if (nodeClassName == className || (' ' + nodeClassName + ' ').include(ne
edle)) | 3791 |
3218 results.push(node); | 3792 var offset = eOffset.relativeTo(pOffset); |
| 3793 var layout = element.getLayout(); |
| 3794 |
| 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') |
| 3800 }); |
| 3801 |
| 3802 element.setStyle({ |
| 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' |
| 3808 }); |
| 3809 |
| 3810 return element; |
| 3811 } |
| 3812 |
| 3813 function relativize(element) { |
| 3814 element = $(element); |
| 3815 if (Element.getStyle(element, 'position') === 'relative') { |
| 3816 return element; |
| 3817 } |
| 3818 |
| 3819 var originalStyles = |
| 3820 element.retrieve('prototype_absolutize_original_styles'); |
| 3821 |
| 3822 if (originalStyles) element.setStyle(originalStyles); |
| 3823 return element; |
| 3824 } |
| 3825 |
| 3826 if (Prototype.Browser.IE) { |
| 3827 getOffsetParent = getOffsetParent.wrap( |
| 3828 function(proceed, element) { |
| 3829 element = $(element); |
| 3830 |
| 3831 if (isDocument(element) || isDetached(element) || isBody(element) || isH
tml(element)) |
| 3832 return $(document.body); |
| 3833 |
| 3834 var position = element.getStyle('position'); |
| 3835 if (position !== 'static') return proceed(element); |
| 3836 |
| 3837 element.setStyle({ position: 'relative' }); |
| 3838 var value = proceed(element); |
| 3839 element.setStyle({ position: position }); |
| 3840 return value; |
3219 } | 3841 } |
3220 return results; | 3842 ); |
3221 }, | 3843 |
3222 | 3844 positionedOffset = positionedOffset.wrap(function(proceed, element) { |
3223 attrPresence: function(nodes, root, attr, combinator) { | 3845 element = $(element); |
3224 if (!nodes) nodes = root.getElementsByTagName("*"); | 3846 if (!element.parentNode) return new Element.Offset(0, 0); |
3225 if (nodes && combinator) nodes = this[combinator](nodes); | 3847 var position = element.getStyle('position'); |
3226 var results = []; | 3848 if (position !== 'static') return proceed(element); |
3227 for (var i = 0, node; node = nodes[i]; i++) | 3849 |
3228 if (Element.hasAttribute(node, attr)) results.push(node); | 3850 var offsetParent = element.getOffsetParent(); |
3229 return results; | 3851 if (offsetParent && offsetParent.getStyle('position') === 'fixed') |
3230 }, | 3852 hasLayout(offsetParent); |
3231 | 3853 |
3232 attr: function(nodes, root, attr, value, operator, combinator) { | 3854 element.setStyle({ position: 'relative' }); |
3233 if (!nodes) nodes = root.getElementsByTagName("*"); | 3855 var value = proceed(element); |
3234 if (nodes && combinator) nodes = this[combinator](nodes); | 3856 element.setStyle({ position: position }); |
3235 var handler = Selector.operators[operator], results = []; | 3857 return value; |
3236 for (var i = 0, node; node = nodes[i]; i++) { | 3858 }); |
3237 var nodeValue = Element.readAttribute(node, attr); | 3859 } else if (Prototype.Browser.Webkit) { |
3238 if (nodeValue === null) continue; | 3860 cumulativeOffset = function(element) { |
3239 if (handler(nodeValue, value)) results.push(node); | 3861 element = $(element); |
| 3862 var valueT = 0, valueL = 0; |
| 3863 do { |
| 3864 valueT += element.offsetTop || 0; |
| 3865 valueL += element.offsetLeft || 0; |
| 3866 if (element.offsetParent == document.body) |
| 3867 if (Element.getStyle(element, 'position') == 'absolute') break; |
| 3868 |
| 3869 element = element.offsetParent; |
| 3870 } while (element); |
| 3871 |
| 3872 return new Element.Offset(valueL, valueT); |
| 3873 }; |
| 3874 } |
| 3875 |
| 3876 |
| 3877 Element.addMethods({ |
| 3878 getLayout: getLayout, |
| 3879 measure: measure, |
| 3880 getDimensions: getDimensions, |
| 3881 getOffsetParent: getOffsetParent, |
| 3882 cumulativeOffset: cumulativeOffset, |
| 3883 positionedOffset: positionedOffset, |
| 3884 cumulativeScrollOffset: cumulativeScrollOffset, |
| 3885 viewportOffset: viewportOffset, |
| 3886 absolutize: absolutize, |
| 3887 relativize: relativize |
| 3888 }); |
| 3889 |
| 3890 function isBody(element) { |
| 3891 return element.nodeName.toUpperCase() === 'BODY'; |
| 3892 } |
| 3893 |
| 3894 function isHtml(element) { |
| 3895 return element.nodeName.toUpperCase() === 'HTML'; |
| 3896 } |
| 3897 |
| 3898 function isDocument(element) { |
| 3899 return element.nodeType === Node.DOCUMENT_NODE; |
| 3900 } |
| 3901 |
| 3902 function isDetached(element) { |
| 3903 return element !== document.body && |
| 3904 !Element.descendantOf(element, document.body); |
| 3905 } |
| 3906 |
| 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); |
| 3912 |
| 3913 var rect = element.getBoundingClientRect(), |
| 3914 docEl = document.documentElement; |
| 3915 return new Element.Offset(rect.left - docEl.clientLeft, |
| 3916 rect.top - docEl.clientTop); |
3240 } | 3917 } |
3241 return results; | 3918 }); |
3242 }, | 3919 } |
3243 | 3920 })(); |
3244 pseudo: function(nodes, name, value, root, combinator) { | 3921 window.$$ = function() { |
3245 if (nodes && combinator) nodes = this[combinator](nodes); | 3922 var expression = $A(arguments).join(', '); |
3246 if (!nodes) nodes = root.getElementsByTagName("*"); | 3923 return Prototype.Selector.select(expression, document); |
3247 return Selector.pseudos[name](nodes, value, root); | 3924 }; |
3248 } | 3925 |
3249 }, | 3926 Prototype.Selector = (function() { |
3250 | 3927 |
3251 pseudos: { | 3928 function select() { |
3252 'first-child': function(nodes, value, root) { | 3929 throw new Error('Method "Prototype.Selector.select" must be defined.'); |
3253 for (var i = 0, results = [], node; node = nodes[i]; i++) { | 3930 } |
3254 if (Selector.handlers.previousElementSibling(node)) continue; | 3931 |
3255 results.push(node); | 3932 function match() { |
| 3933 throw new Error('Method "Prototype.Selector.match" must be defined.'); |
| 3934 } |
| 3935 |
| 3936 function find(elements, expression, index) { |
| 3937 index = index || 0; |
| 3938 var match = Prototype.Selector.match, length = elements.length, matchIndex =
0, i; |
| 3939 |
| 3940 for (i = 0; i < length; i++) { |
| 3941 if (match(elements[i], expression) && index == matchIndex++) { |
| 3942 return Element.extend(elements[i]); |
3256 } | 3943 } |
3257 return results; | 3944 } |
3258 }, | 3945 } |
3259 'last-child': function(nodes, value, root) { | 3946 |
3260 for (var i = 0, results = [], node; node = nodes[i]; i++) { | 3947 function extendElements(elements) { |
3261 if (Selector.handlers.nextElementSibling(node)) continue; | 3948 for (var i = 0, length = elements.length; i < length; i++) { |
3262 results.push(node); | 3949 Element.extend(elements[i]); |
3263 } | 3950 } |
3264 return results; | 3951 return elements; |
3265 }, | 3952 } |
3266 'only-child': function(nodes, value, root) { | 3953 |
3267 var h = Selector.handlers; | 3954 |
3268 for (var i = 0, results = [], node; node = nodes[i]; i++) | 3955 var K = Prototype.K; |
3269 if (!h.previousElementSibling(node) && !h.nextElementSibling(node)) | 3956 |
3270 results.push(node); | 3957 return { |
3271 return results; | 3958 select: select, |
3272 }, | 3959 match: match, |
3273 'nth-child': function(nodes, formula, root) { | 3960 find: find, |
3274 return Selector.pseudos.nth(nodes, formula, root); | 3961 extendElements: (Element.extend === K) ? K : extendElements, |
3275 }, | 3962 extendElement: Element.extend |
3276 'nth-last-child': function(nodes, formula, root) { | 3963 }; |
3277 return Selector.pseudos.nth(nodes, formula, root, true); | 3964 })(); |
3278 }, | 3965 Prototype._original_property = window.Sizzle; |
3279 'nth-of-type': function(nodes, formula, root) { | 3966 /*! |
3280 return Selector.pseudos.nth(nodes, formula, root, false, true); | 3967 * Sizzle CSS Selector Engine - v1.0 |
3281 }, | 3968 * Copyright 2009, The Dojo Foundation |
3282 'nth-last-of-type': function(nodes, formula, root) { | 3969 * Released under the MIT, BSD, and GPL Licenses. |
3283 return Selector.pseudos.nth(nodes, formula, root, true, true); | 3970 * More information: http://sizzlejs.com/ |
3284 }, | 3971 */ |
3285 'first-of-type': function(nodes, formula, root) { | 3972 (function(){ |
3286 return Selector.pseudos.nth(nodes, "1", root, false, true); | 3973 |
3287 }, | 3974 var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^
[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, |
3288 'last-of-type': function(nodes, formula, root) { | 3975 » done = 0, |
3289 return Selector.pseudos.nth(nodes, "1", root, true, true); | 3976 » toString = Object.prototype.toString, |
3290 }, | 3977 » hasDuplicate = false, |
3291 'only-of-type': function(nodes, formula, root) { | 3978 » baseHasDuplicate = true; |
3292 var p = Selector.pseudos; | 3979 |
3293 return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula
, root); | 3980 [0, 0].sort(function(){ |
3294 }, | 3981 » baseHasDuplicate = false; |
3295 | 3982 » return 0; |
3296 // handles the an+b logic | |
3297 getIndices: function(a, b, total) { | |
3298 if (a == 0) return b > 0 ? [b] : []; | |
3299 return $R(1, total).inject([], function(memo, i) { | |
3300 if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i); | |
3301 return memo; | |
3302 }); | |
3303 }, | |
3304 | |
3305 // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type | |
3306 nth: function(nodes, formula, root, reverse, ofType) { | |
3307 if (nodes.length == 0) return []; | |
3308 if (formula == 'even') formula = '2n+0'; | |
3309 if (formula == 'odd') formula = '2n+1'; | |
3310 var h = Selector.handlers, results = [], indexed = [], m; | |
3311 h.mark(nodes); | |
3312 for (var i = 0, node; node = nodes[i]; i++) { | |
3313 if (!node.parentNode._countedByPrototype) { | |
3314 h.index(node.parentNode, reverse, ofType); | |
3315 indexed.push(node.parentNode); | |
3316 } | |
3317 } | |
3318 if (formula.match(/^\d+$/)) { // just a number | |
3319 formula = Number(formula); | |
3320 for (var i = 0, node; node = nodes[i]; i++) | |
3321 if (node.nodeIndex == formula) results.push(node); | |
3322 } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b | |
3323 if (m[1] == "-") m[1] = -1; | |
3324 var a = m[1] ? Number(m[1]) : 1; | |
3325 var b = m[2] ? Number(m[2]) : 0; | |
3326 var indices = Selector.pseudos.getIndices(a, b, nodes.length); | |
3327 for (var i = 0, node, l = indices.length; node = nodes[i]; i++) { | |
3328 for (var j = 0; j < l; j++) | |
3329 if (node.nodeIndex == indices[j]) results.push(node); | |
3330 } | |
3331 } | |
3332 h.unmark(nodes); | |
3333 h.unmark(indexed); | |
3334 return results; | |
3335 }, | |
3336 | |
3337 'empty': function(nodes, value, root) { | |
3338 for (var i = 0, results = [], node; node = nodes[i]; i++) { | |
3339 // IE treats comments as element nodes | |
3340 if (node.tagName == '!' || node.firstChild) continue; | |
3341 results.push(node); | |
3342 } | |
3343 return results; | |
3344 }, | |
3345 | |
3346 'not': function(nodes, selector, root) { | |
3347 var h = Selector.handlers, selectorType, m; | |
3348 var exclusions = new Selector(selector).findElements(root); | |
3349 h.mark(exclusions); | |
3350 for (var i = 0, results = [], node; node = nodes[i]; i++) | |
3351 if (!node._countedByPrototype) results.push(node); | |
3352 h.unmark(exclusions); | |
3353 return results; | |
3354 }, | |
3355 | |
3356 'enabled': function(nodes, value, root) { | |
3357 for (var i = 0, results = [], node; node = nodes[i]; i++) | |
3358 if (!node.disabled && (!node.type || node.type !== 'hidden')) | |
3359 results.push(node); | |
3360 return results; | |
3361 }, | |
3362 | |
3363 'disabled': function(nodes, value, root) { | |
3364 for (var i = 0, results = [], node; node = nodes[i]; i++) | |
3365 if (node.disabled) results.push(node); | |
3366 return results; | |
3367 }, | |
3368 | |
3369 'checked': function(nodes, value, root) { | |
3370 for (var i = 0, results = [], node; node = nodes[i]; i++) | |
3371 if (node.checked) results.push(node); | |
3372 return results; | |
3373 } | |
3374 }, | |
3375 | |
3376 operators: { | |
3377 '=': function(nv, v) { return nv == v; }, | |
3378 '!=': function(nv, v) { return nv != 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); }, | |
3382 '$=': function(nv, v) { return nv.endsWith(v); }, | |
3383 '*=': function(nv, v) { return nv.include(v); }, | |
3384 '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); }, | |
3385 '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() + | |
3386 '-').include('-' + (v || "").toUpperCase() + '-'); } | |
3387 }, | |
3388 | |
3389 split: function(expression) { | |
3390 var expressions = []; | |
3391 expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) { | |
3392 expressions.push(m[1].strip()); | |
3393 }); | |
3394 return expressions; | |
3395 }, | |
3396 | |
3397 matchElements: function(elements, expression) { | |
3398 var matches = $$(expression), h = Selector.handlers; | |
3399 h.mark(matches); | |
3400 for (var i = 0, results = [], element; element = elements[i]; i++) | |
3401 if (element._countedByPrototype) results.push(element); | |
3402 h.unmark(matches); | |
3403 return results; | |
3404 }, | |
3405 | |
3406 findElement: function(elements, expression, index) { | |
3407 if (Object.isNumber(expression)) { | |
3408 index = expression; expression = false; | |
3409 } | |
3410 return Selector.matchElements(elements, expression || '*')[index || 0]; | |
3411 }, | |
3412 | |
3413 findChildElements: function(element, expressions) { | |
3414 expressions = Selector.split(expressions.join(',')); | |
3415 var results = [], h = Selector.handlers; | |
3416 for (var i = 0, l = expressions.length, selector; i < l; i++) { | |
3417 selector = new Selector(expressions[i].strip()); | |
3418 h.concat(results, selector.findElements(element)); | |
3419 } | |
3420 return (l > 1) ? h.unique(results) : results; | |
3421 } | |
3422 }); | 3983 }); |
3423 | 3984 |
3424 if (Prototype.Browser.IE) { | 3985 var Sizzle = function(selector, context, results, seed) { |
3425 Object.extend(Selector.handlers, { | 3986 results = results || []; |
3426 // IE returns comment nodes on getElementsByTagName("*"). | 3987 var origContext = context = context || document; |
3427 // Filter them out. | 3988 |
3428 concat: function(a, b) { | 3989 if ( context.nodeType !== 1 && context.nodeType !== 9 ) { |
3429 for (var i = 0, node; node = b[i]; i++) | 3990 return []; |
3430 if (node.tagName !== "!") a.push(node); | 3991 } |
3431 return a; | 3992 |
3432 }, | 3993 if ( !selector || typeof selector !== "string" ) { |
3433 | 3994 return results; |
3434 // IE improperly serializes _countedByPrototype in (inner|outer)HTML. | 3995 } |
3435 unmark: function(nodes) { | 3996 |
3436 for (var i = 0, node; node = nodes[i]; i++) | 3997 var parts = [], m, set, checkSet, check, mode, extra, prune = true, cont
extXML = isXML(context), |
3437 node.removeAttribute('_countedByPrototype'); | 3998 soFar = selector; |
3438 return nodes; | 3999 |
3439 } | 4000 while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) { |
3440 }); | 4001 soFar = m[3]; |
| 4002 |
| 4003 parts.push( m[1] ); |
| 4004 |
| 4005 if ( m[2] ) { |
| 4006 extra = m[3]; |
| 4007 break; |
| 4008 } |
| 4009 } |
| 4010 |
| 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 ); |
| 4014 } else { |
| 4015 set = Expr.relative[ parts[0] ] ? |
| 4016 [ context ] : |
| 4017 Sizzle( parts.shift(), context ); |
| 4018 |
| 4019 while ( parts.length ) { |
| 4020 selector = parts.shift(); |
| 4021 |
| 4022 if ( Expr.relative[ selector ] ) |
| 4023 selector += parts.shift(); |
| 4024 |
| 4025 set = posProcess( selector, set ); |
| 4026 } |
| 4027 } |
| 4028 } else { |
| 4029 if ( !seed && parts.length > 1 && context.nodeType === 9 && !con
textXML && |
| 4030 Expr.match.ID.test(parts[0]) && !Expr.match.ID.t
est(parts[parts.length - 1]) ) { |
| 4031 var ret = Sizzle.find( parts.shift(), context, contextXM
L ); |
| 4032 context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[
0] : ret.set[0]; |
| 4033 } |
| 4034 |
| 4035 if ( context ) { |
| 4036 var ret = seed ? |
| 4037 { expr: parts.pop(), set: makeArray(seed) } : |
| 4038 Sizzle.find( parts.pop(), parts.length === 1 &&
(parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNod
e : context, contextXML ); |
| 4039 set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : re
t.set; |
| 4040 |
| 4041 if ( parts.length > 0 ) { |
| 4042 checkSet = makeArray(set); |
| 4043 } else { |
| 4044 prune = false; |
| 4045 } |
| 4046 |
| 4047 while ( parts.length ) { |
| 4048 var cur = parts.pop(), pop = cur; |
| 4049 |
| 4050 if ( !Expr.relative[ cur ] ) { |
| 4051 cur = ""; |
| 4052 } else { |
| 4053 pop = parts.pop(); |
| 4054 } |
| 4055 |
| 4056 if ( pop == null ) { |
| 4057 pop = context; |
| 4058 } |
| 4059 |
| 4060 Expr.relative[ cur ]( checkSet, pop, contextXML
); |
| 4061 } |
| 4062 } else { |
| 4063 checkSet = parts = []; |
| 4064 } |
| 4065 } |
| 4066 |
| 4067 if ( !checkSet ) { |
| 4068 checkSet = set; |
| 4069 } |
| 4070 |
| 4071 if ( !checkSet ) { |
| 4072 throw "Syntax error, unrecognized expression: " + (cur || select
or); |
| 4073 } |
| 4074 |
| 4075 if ( toString.call(checkSet) === "[object Array]" ) { |
| 4076 if ( !prune ) { |
| 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 || che
ckSet[i].nodeType === 1 && contains(context, checkSet[i])) ) { |
| 4081 results.push( set[i] ); |
| 4082 } |
| 4083 } |
| 4084 } else { |
| 4085 for ( var i = 0; checkSet[i] != null; i++ ) { |
| 4086 if ( checkSet[i] && checkSet[i].nodeType === 1 )
{ |
| 4087 results.push( set[i] ); |
| 4088 } |
| 4089 } |
| 4090 } |
| 4091 } else { |
| 4092 makeArray( checkSet, results ); |
| 4093 } |
| 4094 |
| 4095 if ( extra ) { |
| 4096 Sizzle( extra, origContext, results, seed ); |
| 4097 Sizzle.uniqueSort( results ); |
| 4098 } |
| 4099 |
| 4100 return results; |
| 4101 }; |
| 4102 |
| 4103 Sizzle.uniqueSort = function(results){ |
| 4104 if ( sortOrder ) { |
| 4105 hasDuplicate = baseHasDuplicate; |
| 4106 results.sort(sortOrder); |
| 4107 |
| 4108 if ( hasDuplicate ) { |
| 4109 for ( var i = 1; i < results.length; i++ ) { |
| 4110 if ( results[i] === results[i-1] ) { |
| 4111 results.splice(i--, 1); |
| 4112 } |
| 4113 } |
| 4114 } |
| 4115 } |
| 4116 |
| 4117 return results; |
| 4118 }; |
| 4119 |
| 4120 Sizzle.matches = function(expr, set){ |
| 4121 return Sizzle(expr, null, null, set); |
| 4122 }; |
| 4123 |
| 4124 Sizzle.find = function(expr, context, isXML){ |
| 4125 var set, match; |
| 4126 |
| 4127 if ( !expr ) { |
| 4128 return []; |
| 4129 } |
| 4130 |
| 4131 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { |
| 4132 var type = Expr.order[i], match; |
| 4133 |
| 4134 if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { |
| 4135 var left = match[1]; |
| 4136 match.splice(1,1); |
| 4137 |
| 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 ],
"" ); |
| 4143 break; |
| 4144 } |
| 4145 } |
| 4146 } |
| 4147 } |
| 4148 |
| 4149 if ( !set ) { |
| 4150 set = context.getElementsByTagName("*"); |
| 4151 } |
| 4152 |
| 4153 return {set: set, expr: expr}; |
| 4154 }; |
| 4155 |
| 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]); |
| 4159 |
| 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; |
| 4164 anyFound = false; |
| 4165 |
| 4166 if ( curLoop == result ) { |
| 4167 result = []; |
| 4168 } |
| 4169 |
| 4170 if ( Expr.preFilter[ type ] ) { |
| 4171 match = Expr.preFilter[ type ]( match, c
urLoop, inplace, result, not, isXMLFilter ); |
| 4172 |
| 4173 if ( !match ) { |
| 4174 anyFound = found = true; |
| 4175 } else if ( match === true ) { |
| 4176 continue; |
| 4177 } |
| 4178 } |
| 4179 |
| 4180 if ( match ) { |
| 4181 for ( var i = 0; (item = curLoop[i]) !=
null; i++ ) { |
| 4182 if ( item ) { |
| 4183 found = filter( item, ma
tch, i, curLoop ); |
| 4184 var pass = not ^ !!found
; |
| 4185 |
| 4186 if ( inplace && found !=
null ) { |
| 4187 if ( pass ) { |
| 4188 anyFound
= true; |
| 4189 } else { |
| 4190 curLoop[
i] = false; |
| 4191 } |
| 4192 } else if ( pass ) { |
| 4193 result.push( ite
m ); |
| 4194 anyFound = true; |
| 4195 } |
| 4196 } |
| 4197 } |
| 4198 } |
| 4199 |
| 4200 if ( found !== undefined ) { |
| 4201 if ( !inplace ) { |
| 4202 curLoop = result; |
| 4203 } |
| 4204 |
| 4205 expr = expr.replace( Expr.match[ type ],
"" ); |
| 4206 |
| 4207 if ( !anyFound ) { |
| 4208 return []; |
| 4209 } |
| 4210 |
| 4211 break; |
| 4212 } |
| 4213 } |
| 4214 } |
| 4215 |
| 4216 if ( expr == old ) { |
| 4217 if ( anyFound == null ) { |
| 4218 throw "Syntax error, unrecognized expression: "
+ expr; |
| 4219 } else { |
| 4220 break; |
| 4221 } |
| 4222 } |
| 4223 |
| 4224 old = expr; |
| 4225 } |
| 4226 |
| 4227 return curLoop; |
| 4228 }; |
| 4229 |
| 4230 var Expr = Sizzle.selectors = { |
| 4231 order: [ "ID", "NAME", "TAG" ], |
| 4232 match: { |
| 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\))?/ |
| 4241 }, |
| 4242 leftMatch: {}, |
| 4243 attrMap: { |
| 4244 "class": "className", |
| 4245 "for": "htmlFor" |
| 4246 }, |
| 4247 attrHandle: { |
| 4248 href: function(elem){ |
| 4249 return elem.getAttribute("href"); |
| 4250 } |
| 4251 }, |
| 4252 relative: { |
| 4253 "+": function(checkSet, part, isXML){ |
| 4254 var isPartStr = typeof part === "string", |
| 4255 isTag = isPartStr && !/\W/.test(part), |
| 4256 isPartStrNotTag = isPartStr && !isTag; |
| 4257 |
| 4258 if ( isTag && !isXML ) { |
| 4259 part = part.toUpperCase(); |
| 4260 } |
| 4261 |
| 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 ) {} |
| 4265 |
| 4266 checkSet[i] = isPartStrNotTag || elem &&
elem.nodeName === part ? |
| 4267 elem || false : |
| 4268 elem === part; |
| 4269 } |
| 4270 } |
| 4271 |
| 4272 if ( isPartStrNotTag ) { |
| 4273 Sizzle.filter( part, checkSet, true ); |
| 4274 } |
| 4275 }, |
| 4276 ">": function(checkSet, part, isXML){ |
| 4277 var isPartStr = typeof part === "string"; |
| 4278 |
| 4279 if ( isPartStr && !/\W/.test(part) ) { |
| 4280 part = isXML ? part : part.toUpperCase(); |
| 4281 |
| 4282 for ( var i = 0, l = checkSet.length; i < l; i++
) { |
| 4283 var elem = checkSet[i]; |
| 4284 if ( elem ) { |
| 4285 var parent = elem.parentNode; |
| 4286 checkSet[i] = parent.nodeName ==
= part ? parent : false; |
| 4287 } |
| 4288 } |
| 4289 } else { |
| 4290 for ( var i = 0, l = checkSet.length; i < l; i++
) { |
| 4291 var elem = checkSet[i]; |
| 4292 if ( elem ) { |
| 4293 checkSet[i] = isPartStr ? |
| 4294 elem.parentNode : |
| 4295 elem.parentNode === part
; |
| 4296 } |
| 4297 } |
| 4298 |
| 4299 if ( isPartStr ) { |
| 4300 Sizzle.filter( part, checkSet, true ); |
| 4301 } |
| 4302 } |
| 4303 }, |
| 4304 "": function(checkSet, part, isXML){ |
| 4305 var doneName = done++, checkFn = dirCheck; |
| 4306 |
| 4307 if ( !/\W/.test(part) ) { |
| 4308 var nodeCheck = part = isXML ? part : part.toUpp
erCase(); |
| 4309 checkFn = dirNodeCheck; |
| 4310 } |
| 4311 |
| 4312 checkFn("parentNode", part, doneName, checkSet, nodeChec
k, isXML); |
| 4313 }, |
| 4314 "~": function(checkSet, part, isXML){ |
| 4315 var doneName = done++, checkFn = dirCheck; |
| 4316 |
| 4317 if ( typeof part === "string" && !/\W/.test(part) ) { |
| 4318 var nodeCheck = part = isXML ? part : part.toUpp
erCase(); |
| 4319 checkFn = dirNodeCheck; |
| 4320 } |
| 4321 |
| 4322 checkFn("previousSibling", part, doneName, checkSet, nod
eCheck, isXML); |
| 4323 } |
| 4324 }, |
| 4325 find: { |
| 4326 ID: function(match, context, isXML){ |
| 4327 if ( typeof context.getElementById !== "undefined" && !i
sXML ) { |
| 4328 var m = context.getElementById(match[1]); |
| 4329 return m ? [m] : []; |
| 4330 } |
| 4331 }, |
| 4332 NAME: function(match, context, isXML){ |
| 4333 if ( typeof context.getElementsByName !== "undefined" )
{ |
| 4334 var ret = [], results = context.getElementsByNam
e(match[1]); |
| 4335 |
| 4336 for ( var i = 0, l = results.length; i < l; i++
) { |
| 4337 if ( results[i].getAttribute("name") ===
match[1] ) { |
| 4338 ret.push( results[i] ); |
| 4339 } |
| 4340 } |
| 4341 |
| 4342 return ret.length === 0 ? null : ret; |
| 4343 } |
| 4344 }, |
| 4345 TAG: function(match, context){ |
| 4346 return context.getElementsByTagName(match[1]); |
| 4347 } |
| 4348 }, |
| 4349 preFilter: { |
| 4350 CLASS: function(match, curLoop, inplace, result, not, isXML){ |
| 4351 match = " " + match[1].replace(/\\/g, "") + " "; |
| 4352 |
| 4353 if ( isXML ) { |
| 4354 return match; |
| 4355 } |
| 4356 |
| 4357 for ( var i = 0, elem; (elem = curLoop[i]) != null; i++
) { |
| 4358 if ( elem ) { |
| 4359 if ( not ^ (elem.className && (" " + ele
m.className + " ").indexOf(match) >= 0) ) { |
| 4360 if ( !inplace ) |
| 4361 result.push( elem ); |
| 4362 } else if ( inplace ) { |
| 4363 curLoop[i] = false; |
| 4364 } |
| 4365 } |
| 4366 } |
| 4367 |
| 4368 return false; |
| 4369 }, |
| 4370 ID: function(match){ |
| 4371 return match[1].replace(/\\/g, ""); |
| 4372 }, |
| 4373 TAG: function(match, curLoop){ |
| 4374 for ( var i = 0; curLoop[i] === false; i++ ){} |
| 4375 return curLoop[i] && isXML(curLoop[i]) ? match[1] : matc
h[1].toUpperCase(); |
| 4376 }, |
| 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]); |
| 4382 |
| 4383 match[2] = (test[1] + (test[2] || 1)) - 0; |
| 4384 match[3] = test[3] - 0; |
| 4385 } |
| 4386 |
| 4387 match[0] = done++; |
| 4388 |
| 4389 return match; |
| 4390 }, |
| 4391 ATTR: function(match, curLoop, inplace, result, not, isXML){ |
| 4392 var name = match[1].replace(/\\/g, ""); |
| 4393 |
| 4394 if ( !isXML && Expr.attrMap[name] ) { |
| 4395 match[1] = Expr.attrMap[name]; |
| 4396 } |
| 4397 |
| 4398 if ( match[2] === "~=" ) { |
| 4399 match[4] = " " + match[4] + " "; |
| 4400 } |
| 4401 |
| 4402 return match; |
| 4403 }, |
| 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); |
| 4408 } else { |
| 4409 var ret = Sizzle.filter(match[3], curLoo
p, inplace, true ^ not); |
| 4410 if ( !inplace ) { |
| 4411 result.push.apply( result, ret )
; |
| 4412 } |
| 4413 return false; |
| 4414 } |
| 4415 } else if ( Expr.match.POS.test( match[0] ) || Expr.matc
h.CHILD.test( match[0] ) ) { |
| 4416 return true; |
| 4417 } |
| 4418 |
| 4419 return match; |
| 4420 }, |
| 4421 POS: function(match){ |
| 4422 match.unshift( true ); |
| 4423 return match; |
| 4424 } |
| 4425 }, |
| 4426 filters: { |
| 4427 enabled: function(elem){ |
| 4428 return elem.disabled === false && elem.type !== "hidden"
; |
| 4429 }, |
| 4430 disabled: function(elem){ |
| 4431 return elem.disabled === true; |
| 4432 }, |
| 4433 checked: function(elem){ |
| 4434 return elem.checked === true; |
| 4435 }, |
| 4436 selected: function(elem){ |
| 4437 elem.parentNode.selectedIndex; |
| 4438 return elem.selected === true; |
| 4439 }, |
| 4440 parent: function(elem){ |
| 4441 return !!elem.firstChild; |
| 4442 }, |
| 4443 empty: function(elem){ |
| 4444 return !elem.firstChild; |
| 4445 }, |
| 4446 has: function(elem, i, match){ |
| 4447 return !!Sizzle( match[3], elem ).length; |
| 4448 }, |
| 4449 header: function(elem){ |
| 4450 return /h\d/i.test( elem.nodeName ); |
| 4451 }, |
| 4452 text: function(elem){ |
| 4453 return "text" === elem.type; |
| 4454 }, |
| 4455 radio: function(elem){ |
| 4456 return "radio" === elem.type; |
| 4457 }, |
| 4458 checkbox: function(elem){ |
| 4459 return "checkbox" === elem.type; |
| 4460 }, |
| 4461 file: function(elem){ |
| 4462 return "file" === elem.type; |
| 4463 }, |
| 4464 password: function(elem){ |
| 4465 return "password" === elem.type; |
| 4466 }, |
| 4467 submit: function(elem){ |
| 4468 return "submit" === elem.type; |
| 4469 }, |
| 4470 image: function(elem){ |
| 4471 return "image" === elem.type; |
| 4472 }, |
| 4473 reset: function(elem){ |
| 4474 return "reset" === elem.type; |
| 4475 }, |
| 4476 button: function(elem){ |
| 4477 return "button" === elem.type || elem.nodeName.toUpperCa
se() === "BUTTON"; |
| 4478 }, |
| 4479 input: function(elem){ |
| 4480 return /input|select|textarea|button/i.test(elem.nodeNam
e); |
| 4481 } |
| 4482 }, |
| 4483 setFilters: { |
| 4484 first: function(elem, i){ |
| 4485 return i === 0; |
| 4486 }, |
| 4487 last: function(elem, i, match, array){ |
| 4488 return i === array.length - 1; |
| 4489 }, |
| 4490 even: function(elem, i){ |
| 4491 return i % 2 === 0; |
| 4492 }, |
| 4493 odd: function(elem, i){ |
| 4494 return i % 2 === 1; |
| 4495 }, |
| 4496 lt: function(elem, i, match){ |
| 4497 return i < match[3] - 0; |
| 4498 }, |
| 4499 gt: function(elem, i, match){ |
| 4500 return i > match[3] - 0; |
| 4501 }, |
| 4502 nth: function(elem, i, match){ |
| 4503 return match[3] - 0 == i; |
| 4504 }, |
| 4505 eq: function(elem, i, match){ |
| 4506 return match[3] - 0 == i; |
| 4507 } |
| 4508 }, |
| 4509 filter: { |
| 4510 PSEUDO: function(elem, match, i, array){ |
| 4511 var name = match[1], filter = Expr.filters[ name ]; |
| 4512 |
| 4513 if ( filter ) { |
| 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" ) { |
| 4518 var not = match[3]; |
| 4519 |
| 4520 for ( var i = 0, l = not.length; i < l; i++ ) { |
| 4521 if ( not[i] === elem ) { |
| 4522 return false; |
| 4523 } |
| 4524 } |
| 4525 |
| 4526 return true; |
| 4527 } |
| 4528 }, |
| 4529 CHILD: function(elem, match){ |
| 4530 var type = match[1], node = elem; |
| 4531 switch (type) { |
| 4532 case 'only': |
| 4533 case 'first': |
| 4534 while ( (node = node.previousSibling) )
{ |
| 4535 if ( node.nodeType === 1 ) retur
n false; |
| 4536 } |
| 4537 if ( type == 'first') return true; |
| 4538 node = elem; |
| 4539 case 'last': |
| 4540 while ( (node = node.nextSibling) ) { |
| 4541 if ( node.nodeType === 1 ) retur
n false; |
| 4542 } |
| 4543 return true; |
| 4544 case 'nth': |
| 4545 var first = match[2], last = match[3]; |
| 4546 |
| 4547 if ( first == 1 && last == 0 ) { |
| 4548 return true; |
| 4549 } |
| 4550 |
| 4551 var doneName = match[0], |
| 4552 parent = elem.parentNode; |
| 4553 |
| 4554 if ( parent && (parent.sizcache !== done
Name || !elem.nodeIndex) ) { |
| 4555 var count = 0; |
| 4556 for ( node = parent.firstChild;
node; node = node.nextSibling ) { |
| 4557 if ( node.nodeType === 1
) { |
| 4558 node.nodeIndex =
++count; |
| 4559 } |
| 4560 } |
| 4561 parent.sizcache = doneName; |
| 4562 } |
| 4563 |
| 4564 var diff = elem.nodeIndex - last; |
| 4565 if ( first == 0 ) { |
| 4566 return diff == 0; |
| 4567 } else { |
| 4568 return ( diff % first == 0 && di
ff / first >= 0 ); |
| 4569 } |
| 4570 } |
| 4571 }, |
| 4572 ID: function(elem, match){ |
| 4573 return elem.nodeType === 1 && elem.getAttribute("id") ==
= match; |
| 4574 }, |
| 4575 TAG: function(elem, match){ |
| 4576 return (match === "*" && elem.nodeType === 1) || elem.no
deName === match; |
| 4577 }, |
| 4578 CLASS: function(elem, match){ |
| 4579 return (" " + (elem.className || elem.getAttribute("clas
s")) + " ") |
| 4580 .indexOf( match ) > -1; |
| 4581 }, |
| 4582 ATTR: function(elem, match){ |
| 4583 var name = match[1], |
| 4584 result = Expr.attrHandle[ name ] ? |
| 4585 Expr.attrHandle[ name ]( elem ) : |
| 4586 elem[ name ] != null ? |
| 4587 elem[ name ] : |
| 4588 elem.getAttribute( name ), |
| 4589 value = result + "", |
| 4590 type = match[2], |
| 4591 check = match[4]; |
| 4592 |
| 4593 return result == null ? |
| 4594 type === "!=" : |
| 4595 type === "=" ? |
| 4596 value === check : |
| 4597 type === "*=" ? |
| 4598 value.indexOf(check) >= 0 : |
| 4599 type === "~=" ? |
| 4600 (" " + value + " ").indexOf(check) >= 0 : |
| 4601 !check ? |
| 4602 value && result !== false : |
| 4603 type === "!=" ? |
| 4604 value != check : |
| 4605 type === "^=" ? |
| 4606 value.indexOf(check) === 0 : |
| 4607 type === "$=" ? |
| 4608 value.substr(value.length - check.length) === ch
eck : |
| 4609 type === "|=" ? |
| 4610 value === check || value.substr(0, check.length
+ 1) === check + "-" : |
| 4611 false; |
| 4612 }, |
| 4613 POS: function(elem, match, i, array){ |
| 4614 var name = match[2], filter = Expr.setFilters[ name ]; |
| 4615 |
| 4616 if ( filter ) { |
| 4617 return filter( elem, i, match, array ); |
| 4618 } |
| 4619 } |
| 4620 } |
| 4621 }; |
| 4622 |
| 4623 var origPOS = Expr.match.POS; |
| 4624 |
| 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.ma
tch[ type ].source ); |
3441 } | 4628 } |
3442 | 4629 |
3443 function $$() { | 4630 var makeArray = function(array, results) { |
3444 return Selector.findChildElements(document, $A(arguments)); | 4631 » array = Array.prototype.slice.call( array, 0 ); |
| 4632 |
| 4633 » if ( results ) { |
| 4634 » » results.push.apply( results, array ); |
| 4635 » » return results; |
| 4636 » } |
| 4637 |
| 4638 » return array; |
| 4639 }; |
| 4640 |
| 4641 try { |
| 4642 » Array.prototype.slice.call( document.documentElement.childNodes, 0 ); |
| 4643 |
| 4644 } catch(e){ |
| 4645 » makeArray = function(array, results) { |
| 4646 » » var ret = results || []; |
| 4647 |
| 4648 » » if ( toString.call(array) === "[object Array]" ) { |
| 4649 » » » Array.prototype.push.apply( ret, array ); |
| 4650 » » } else { |
| 4651 » » » if ( typeof array.length === "number" ) { |
| 4652 » » » » for ( var i = 0, l = array.length; i < l; i++ )
{ |
| 4653 » » » » » ret.push( array[i] ); |
| 4654 » » » » } |
| 4655 » » » } else { |
| 4656 » » » » for ( var i = 0; array[i]; i++ ) { |
| 4657 » » » » » ret.push( array[i] ); |
| 4658 » » » » } |
| 4659 » » » } |
| 4660 » » } |
| 4661 |
| 4662 » » return ret; |
| 4663 » }; |
3445 } | 4664 } |
| 4665 |
| 4666 var sortOrder; |
| 4667 |
| 4668 if ( document.documentElement.compareDocumentPosition ) { |
| 4669 sortOrder = function( a, b ) { |
| 4670 if ( !a.compareDocumentPosition || !b.compareDocumentPosition )
{ |
| 4671 if ( a == b ) { |
| 4672 hasDuplicate = true; |
| 4673 } |
| 4674 return 0; |
| 4675 } |
| 4676 |
| 4677 var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 :
1; |
| 4678 if ( ret === 0 ) { |
| 4679 hasDuplicate = true; |
| 4680 } |
| 4681 return ret; |
| 4682 }; |
| 4683 } else if ( "sourceIndex" in document.documentElement ) { |
| 4684 sortOrder = function( a, b ) { |
| 4685 if ( !a.sourceIndex || !b.sourceIndex ) { |
| 4686 if ( a == b ) { |
| 4687 hasDuplicate = true; |
| 4688 } |
| 4689 return 0; |
| 4690 } |
| 4691 |
| 4692 var ret = a.sourceIndex - b.sourceIndex; |
| 4693 if ( ret === 0 ) { |
| 4694 hasDuplicate = true; |
| 4695 } |
| 4696 return ret; |
| 4697 }; |
| 4698 } else if ( document.createRange ) { |
| 4699 sortOrder = function( a, b ) { |
| 4700 if ( !a.ownerDocument || !b.ownerDocument ) { |
| 4701 if ( a == b ) { |
| 4702 hasDuplicate = true; |
| 4703 } |
| 4704 return 0; |
| 4705 } |
| 4706 |
| 4707 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocu
ment.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, bRang
e); |
| 4713 if ( ret === 0 ) { |
| 4714 hasDuplicate = true; |
| 4715 } |
| 4716 return ret; |
| 4717 }; |
| 4718 } |
| 4719 |
| 4720 (function(){ |
| 4721 var form = document.createElement("div"), |
| 4722 id = "script" + (new Date).getTime(); |
| 4723 form.innerHTML = "<a name='" + id + "'/>"; |
| 4724 |
| 4725 var root = document.documentElement; |
| 4726 root.insertBefore( form, root.firstChild ); |
| 4727 |
| 4728 if ( !!document.getElementById( id ) ) { |
| 4729 Expr.find.ID = function(match, context, isXML){ |
| 4730 if ( typeof context.getElementById !== "undefined" && !i
sXML ) { |
| 4731 var m = context.getElementById(match[1]); |
| 4732 return m ? m.id === match[1] || typeof m.getAttr
ibuteNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [
m] : undefined : []; |
| 4733 } |
| 4734 }; |
| 4735 |
| 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; |
| 4739 }; |
| 4740 } |
| 4741 |
| 4742 root.removeChild( form ); |
| 4743 root = form = null; // release memory in IE |
| 4744 })(); |
| 4745 |
| 4746 (function(){ |
| 4747 |
| 4748 var div = document.createElement("div"); |
| 4749 div.appendChild( document.createComment("") ); |
| 4750 |
| 4751 if ( div.getElementsByTagName("*").length > 0 ) { |
| 4752 Expr.find.TAG = function(match, context){ |
| 4753 var results = context.getElementsByTagName(match[1]); |
| 4754 |
| 4755 if ( match[1] === "*" ) { |
| 4756 var tmp = []; |
| 4757 |
| 4758 for ( var i = 0; results[i]; i++ ) { |
| 4759 if ( results[i].nodeType === 1 ) { |
| 4760 tmp.push( results[i] ); |
| 4761 } |
| 4762 } |
| 4763 |
| 4764 results = tmp; |
| 4765 } |
| 4766 |
| 4767 return results; |
| 4768 }; |
| 4769 } |
| 4770 |
| 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); |
| 4776 }; |
| 4777 } |
| 4778 |
| 4779 div = null; // release memory in IE |
| 4780 })(); |
| 4781 |
| 4782 if ( document.querySelectorAll ) (function(){ |
| 4783 var oldSizzle = Sizzle, div = document.createElement("div"); |
| 4784 div.innerHTML = "<p class='TEST'></p>"; |
| 4785 |
| 4786 if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0
) { |
| 4787 return; |
| 4788 } |
| 4789 |
| 4790 Sizzle = function(query, context, extra, seed){ |
| 4791 context = context || document; |
| 4792 |
| 4793 if ( !seed && context.nodeType === 9 && !isXML(context) ) { |
| 4794 try { |
| 4795 return makeArray( context.querySelectorAll(query
), extra ); |
| 4796 } catch(e){} |
| 4797 } |
| 4798 |
| 4799 return oldSizzle(query, context, extra, seed); |
| 4800 }; |
| 4801 |
| 4802 for ( var prop in oldSizzle ) { |
| 4803 Sizzle[ prop ] = oldSizzle[ prop ]; |
| 4804 } |
| 4805 |
| 4806 div = null; // release memory in IE |
| 4807 })(); |
| 4808 |
| 4809 if ( document.getElementsByClassName && document.documentElement.getElementsByCl
assName ) (function(){ |
| 4810 var div = document.createElement("div"); |
| 4811 div.innerHTML = "<div class='test e'></div><div class='test'></div>"; |
| 4812 |
| 4813 if ( div.getElementsByClassName("e").length === 0 ) |
| 4814 return; |
| 4815 |
| 4816 div.lastChild.className = "e"; |
| 4817 |
| 4818 if ( div.getElementsByClassName("e").length === 1 ) |
| 4819 return; |
| 4820 |
| 4821 Expr.order.splice(1, 0, "CLASS"); |
| 4822 Expr.find.CLASS = function(match, context, isXML) { |
| 4823 if ( typeof context.getElementsByClassName !== "undefined" && !i
sXML ) { |
| 4824 return context.getElementsByClassName(match[1]); |
| 4825 } |
| 4826 }; |
| 4827 |
| 4828 div = null; // release memory in IE |
| 4829 })(); |
| 4830 |
| 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]; |
| 4835 if ( elem ) { |
| 4836 if ( sibDir && elem.nodeType === 1 ){ |
| 4837 elem.sizcache = doneName; |
| 4838 elem.sizset = i; |
| 4839 } |
| 4840 elem = elem[dir]; |
| 4841 var match = false; |
| 4842 |
| 4843 while ( elem ) { |
| 4844 if ( elem.sizcache === doneName ) { |
| 4845 match = checkSet[elem.sizset]; |
| 4846 break; |
| 4847 } |
| 4848 |
| 4849 if ( elem.nodeType === 1 && !isXML ){ |
| 4850 elem.sizcache = doneName; |
| 4851 elem.sizset = i; |
| 4852 } |
| 4853 |
| 4854 if ( elem.nodeName === cur ) { |
| 4855 match = elem; |
| 4856 break; |
| 4857 } |
| 4858 |
| 4859 elem = elem[dir]; |
| 4860 } |
| 4861 |
| 4862 checkSet[i] = match; |
| 4863 } |
| 4864 } |
| 4865 } |
| 4866 |
| 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]; |
| 4871 if ( elem ) { |
| 4872 if ( sibDir && elem.nodeType === 1 ) { |
| 4873 elem.sizcache = doneName; |
| 4874 elem.sizset = i; |
| 4875 } |
| 4876 elem = elem[dir]; |
| 4877 var match = false; |
| 4878 |
| 4879 while ( elem ) { |
| 4880 if ( elem.sizcache === doneName ) { |
| 4881 match = checkSet[elem.sizset]; |
| 4882 break; |
| 4883 } |
| 4884 |
| 4885 if ( elem.nodeType === 1 ) { |
| 4886 if ( !isXML ) { |
| 4887 elem.sizcache = doneName; |
| 4888 elem.sizset = i; |
| 4889 } |
| 4890 if ( typeof cur !== "string" ) { |
| 4891 if ( elem === cur ) { |
| 4892 match = true; |
| 4893 break; |
| 4894 } |
| 4895 |
| 4896 } else if ( Sizzle.filter( cur, [elem] )
.length > 0 ) { |
| 4897 match = elem; |
| 4898 break; |
| 4899 } |
| 4900 } |
| 4901 |
| 4902 elem = elem[dir]; |
| 4903 } |
| 4904 |
| 4905 checkSet[i] = match; |
| 4906 } |
| 4907 } |
| 4908 } |
| 4909 |
| 4910 var contains = document.compareDocumentPosition ? function(a, b){ |
| 4911 return a.compareDocumentPosition(b) & 16; |
| 4912 } : function(a, b){ |
| 4913 return a !== b && (a.contains ? a.contains(b) : true); |
| 4914 }; |
| 4915 |
| 4916 var isXML = function(elem){ |
| 4917 return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" |
| |
| 4918 !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeN
ame !== "HTML"; |
| 4919 }; |
| 4920 |
| 4921 var posProcess = function(selector, context){ |
| 4922 var tmpSet = [], later = "", match, |
| 4923 root = context.nodeType ? [context] : context; |
| 4924 |
| 4925 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { |
| 4926 later += match[0]; |
| 4927 selector = selector.replace( Expr.match.PSEUDO, "" ); |
| 4928 } |
| 4929 |
| 4930 selector = Expr.relative[selector] ? selector + "*" : selector; |
| 4931 |
| 4932 for ( var i = 0, l = root.length; i < l; i++ ) { |
| 4933 Sizzle( selector, root[i], tmpSet ); |
| 4934 } |
| 4935 |
| 4936 return Sizzle.filter( later, tmpSet ); |
| 4937 }; |
| 4938 |
| 4939 |
| 4940 window.Sizzle = Sizzle; |
| 4941 |
| 4942 })(); |
| 4943 |
| 4944 ;(function(engine) { |
| 4945 var extendElements = Prototype.Selector.extendElements; |
| 4946 |
| 4947 function select(selector, scope) { |
| 4948 return extendElements(engine(selector, scope || document)); |
| 4949 } |
| 4950 |
| 4951 function match(element, selector) { |
| 4952 return engine.matches(selector, [element]).length == 1; |
| 4953 } |
| 4954 |
| 4955 Prototype.Selector.engine = engine; |
| 4956 Prototype.Selector.select = select; |
| 4957 Prototype.Selector.match = match; |
| 4958 })(Sizzle); |
| 4959 |
| 4960 window.Sizzle = Prototype._original_property; |
| 4961 delete Prototype._original_property; |
| 4962 |
3446 var Form = { | 4963 var Form = { |
3447 reset: function(form) { | 4964 reset: function(form) { |
3448 $(form).reset(); | 4965 form = $(form); |
| 4966 form.reset(); |
3449 return form; | 4967 return form; |
3450 }, | 4968 }, |
3451 | 4969 |
3452 serializeElements: function(elements, options) { | 4970 serializeElements: function(elements, options) { |
3453 if (typeof options != 'object') options = { hash: !!options }; | 4971 if (typeof options != 'object') options = { hash: !!options }; |
3454 else if (Object.isUndefined(options.hash)) options.hash = true; | 4972 else if (Object.isUndefined(options.hash)) options.hash = true; |
3455 var key, value, submitted = false, submit = options.submit; | 4973 var key, value, submitted = false, submit = options.submit, accumulator, ini
tial; |
3456 | 4974 |
3457 var data = elements.inject({ }, function(result, element) { | 4975 if (options.hash) { |
| 4976 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; |
| 4982 return result; |
| 4983 }; |
| 4984 } else { |
| 4985 initial = ''; |
| 4986 accumulator = function(result, key, value) { |
| 4987 return result + (result ? '&' : '') + encodeURIComponent(key) + '=' + en
codeURIComponent(value); |
| 4988 } |
| 4989 } |
| 4990 |
| 4991 return elements.inject(initial, function(result, element) { |
3458 if (!element.disabled && element.name) { | 4992 if (!element.disabled && element.name) { |
3459 key = element.name; value = $(element).getValue(); | 4993 key = element.name; value = $(element).getValue(); |
3460 if (value != null && element.type != 'file' && (element.type != 'submit'
|| (!submitted && | 4994 if (value != null && element.type != 'file' && (element.type != 'submit'
|| (!submitted && |
3461 submit !== false && (!submit || key == submit) && (submitted = true)
))) { | 4995 submit !== false && (!submit || key == submit) && (submitted = true)
))) { |
3462 if (key in result) { | 4996 result = accumulator(result, key, value); |
3463 // a key is already present; construct an array of values | |
3464 if (!Object.isArray(result[key])) result[key] = [result[key]]; | |
3465 result[key].push(value); | |
3466 } | |
3467 else result[key] = value; | |
3468 } | 4997 } |
3469 } | 4998 } |
3470 return result; | 4999 return result; |
3471 }); | 5000 }); |
3472 | |
3473 return options.hash ? data : Object.toQueryString(data); | |
3474 } | 5001 } |
3475 }; | 5002 }; |
3476 | 5003 |
3477 Form.Methods = { | 5004 Form.Methods = { |
3478 serialize: function(form, options) { | 5005 serialize: function(form, options) { |
3479 return Form.serializeElements(Form.getElements(form), options); | 5006 return Form.serializeElements(Form.getElements(form), options); |
3480 }, | 5007 }, |
3481 | 5008 |
3482 getElements: function(form) { | 5009 getElements: function(form) { |
3483 return $A($(form).getElementsByTagName('*')).inject([], | 5010 var elements = $(form).getElementsByTagName('*'), |
3484 function(elements, child) { | 5011 element, |
3485 if (Form.Element.Serializers[child.tagName.toLowerCase()]) | 5012 arr = [ ], |
3486 elements.push(Element.extend(child)); | 5013 serializers = Form.Element.Serializers; |
3487 return elements; | 5014 for (var i = 0; element = elements[i]; i++) { |
3488 } | 5015 arr.push(element); |
3489 ); | 5016 } |
| 5017 return arr.inject([], function(elements, child) { |
| 5018 if (serializers[child.tagName.toLowerCase()]) |
| 5019 elements.push(Element.extend(child)); |
| 5020 return elements; |
| 5021 }) |
3490 }, | 5022 }, |
3491 | 5023 |
3492 getInputs: function(form, typeName, name) { | 5024 getInputs: function(form, typeName, name) { |
3493 form = $(form); | 5025 form = $(form); |
3494 var inputs = form.getElementsByTagName('input'); | 5026 var inputs = form.getElementsByTagName('input'); |
3495 | 5027 |
3496 if (!typeName && !name) return $A(inputs).map(Element.extend); | 5028 if (!typeName && !name) return $A(inputs).map(Element.extend); |
3497 | 5029 |
3498 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++
) { | 5030 for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++
) { |
3499 var input = inputs[i]; | 5031 var input = inputs[i]; |
(...skipping 19 matching lines...) Expand all Loading... |
3519 | 5051 |
3520 findFirstElement: function(form) { | 5052 findFirstElement: function(form) { |
3521 var elements = $(form).getElements().findAll(function(element) { | 5053 var elements = $(form).getElements().findAll(function(element) { |
3522 return 'hidden' != element.type && !element.disabled; | 5054 return 'hidden' != element.type && !element.disabled; |
3523 }); | 5055 }); |
3524 var firstByIndex = elements.findAll(function(element) { | 5056 var firstByIndex = elements.findAll(function(element) { |
3525 return element.hasAttribute('tabIndex') && element.tabIndex >= 0; | 5057 return element.hasAttribute('tabIndex') && element.tabIndex >= 0; |
3526 }).sortBy(function(element) { return element.tabIndex }).first(); | 5058 }).sortBy(function(element) { return element.tabIndex }).first(); |
3527 | 5059 |
3528 return firstByIndex ? firstByIndex : elements.find(function(element) { | 5060 return firstByIndex ? firstByIndex : elements.find(function(element) { |
3529 return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase
()); | 5061 return /^(?:input|select|textarea)$/i.test(element.tagName); |
3530 }); | 5062 }); |
3531 }, | 5063 }, |
3532 | 5064 |
3533 focusFirstElement: function(form) { | 5065 focusFirstElement: function(form) { |
3534 form = $(form); | 5066 form = $(form); |
3535 form.findFirstElement().activate(); | 5067 var element = form.findFirstElement(); |
| 5068 if (element) element.activate(); |
3536 return form; | 5069 return form; |
3537 }, | 5070 }, |
3538 | 5071 |
3539 request: function(form, options) { | 5072 request: function(form, options) { |
3540 form = $(form), options = Object.clone(options || { }); | 5073 form = $(form), options = Object.clone(options || { }); |
3541 | 5074 |
3542 var params = options.parameters, action = form.readAttribute('action') || ''
; | 5075 var params = options.parameters, action = form.readAttribute('action') || ''
; |
3543 if (action.blank()) action = window.location.href; | 5076 if (action.blank()) action = window.location.href; |
3544 options.parameters = form.serialize(true); | 5077 options.parameters = form.serialize(true); |
3545 | 5078 |
3546 if (params) { | 5079 if (params) { |
3547 if (Object.isString(params)) params = params.toQueryParams(); | 5080 if (Object.isString(params)) params = params.toQueryParams(); |
3548 Object.extend(options.parameters, params); | 5081 Object.extend(options.parameters, params); |
3549 } | 5082 } |
3550 | 5083 |
3551 if (form.hasAttribute('method') && !options.method) | 5084 if (form.hasAttribute('method') && !options.method) |
3552 options.method = form.method; | 5085 options.method = form.method; |
3553 | 5086 |
3554 return new Ajax.Request(action, options); | 5087 return new Ajax.Request(action, options); |
3555 } | 5088 } |
3556 }; | 5089 }; |
3557 | 5090 |
3558 /*--------------------------------------------------------------------------*/ | 5091 /*--------------------------------------------------------------------------*/ |
3559 | 5092 |
| 5093 |
3560 Form.Element = { | 5094 Form.Element = { |
3561 focus: function(element) { | 5095 focus: function(element) { |
3562 $(element).focus(); | 5096 $(element).focus(); |
3563 return element; | 5097 return element; |
3564 }, | 5098 }, |
3565 | 5099 |
3566 select: function(element) { | 5100 select: function(element) { |
3567 $(element).select(); | 5101 $(element).select(); |
3568 return element; | 5102 return element; |
3569 } | 5103 } |
3570 }; | 5104 }; |
3571 | 5105 |
3572 Form.Element.Methods = { | 5106 Form.Element.Methods = { |
| 5107 |
3573 serialize: function(element) { | 5108 serialize: function(element) { |
3574 element = $(element); | 5109 element = $(element); |
3575 if (!element.disabled && element.name) { | 5110 if (!element.disabled && element.name) { |
3576 var value = element.getValue(); | 5111 var value = element.getValue(); |
3577 if (value != undefined) { | 5112 if (value != undefined) { |
3578 var pair = { }; | 5113 var pair = { }; |
3579 pair[element.name] = value; | 5114 pair[element.name] = value; |
3580 return Object.toQueryString(pair); | 5115 return Object.toQueryString(pair); |
3581 } | 5116 } |
3582 } | 5117 } |
(...skipping 20 matching lines...) Expand all Loading... |
3603 | 5138 |
3604 present: function(element) { | 5139 present: function(element) { |
3605 return $(element).value != ''; | 5140 return $(element).value != ''; |
3606 }, | 5141 }, |
3607 | 5142 |
3608 activate: function(element) { | 5143 activate: function(element) { |
3609 element = $(element); | 5144 element = $(element); |
3610 try { | 5145 try { |
3611 element.focus(); | 5146 element.focus(); |
3612 if (element.select && (element.tagName.toLowerCase() != 'input' || | 5147 if (element.select && (element.tagName.toLowerCase() != 'input' || |
3613 !['button', 'reset', 'submit'].include(element.type))) | 5148 !(/^(?:button|reset|submit)$/i.test(element.type)))) |
3614 element.select(); | 5149 element.select(); |
3615 } catch (e) { } | 5150 } catch (e) { } |
3616 return element; | 5151 return element; |
3617 }, | 5152 }, |
3618 | 5153 |
3619 disable: function(element) { | 5154 disable: function(element) { |
3620 element = $(element); | 5155 element = $(element); |
3621 element.disabled = true; | 5156 element.disabled = true; |
3622 return element; | 5157 return element; |
3623 }, | 5158 }, |
3624 | 5159 |
3625 enable: function(element) { | 5160 enable: function(element) { |
3626 element = $(element); | 5161 element = $(element); |
3627 element.disabled = false; | 5162 element.disabled = false; |
3628 return element; | 5163 return element; |
3629 } | 5164 } |
3630 }; | 5165 }; |
3631 | 5166 |
3632 /*--------------------------------------------------------------------------*/ | 5167 /*--------------------------------------------------------------------------*/ |
3633 | 5168 |
3634 var Field = Form.Element; | 5169 var Field = Form.Element; |
| 5170 |
3635 var $F = Form.Element.Methods.getValue; | 5171 var $F = Form.Element.Methods.getValue; |
3636 | 5172 |
3637 /*--------------------------------------------------------------------------*/ | 5173 /*--------------------------------------------------------------------------*/ |
3638 | 5174 |
3639 Form.Element.Serializers = { | 5175 Form.Element.Serializers = (function() { |
3640 input: function(element, value) { | 5176 function input(element, value) { |
3641 switch (element.type.toLowerCase()) { | 5177 switch (element.type.toLowerCase()) { |
3642 case 'checkbox': | 5178 case 'checkbox': |
3643 case 'radio': | 5179 case 'radio': |
3644 return Form.Element.Serializers.inputSelector(element, value); | 5180 return inputSelector(element, value); |
3645 default: | 5181 default: |
3646 return Form.Element.Serializers.textarea(element, value); | 5182 return valueSelector(element, value); |
3647 } | 5183 } |
3648 }, | 5184 } |
3649 | 5185 |
3650 inputSelector: function(element, value) { | 5186 function inputSelector(element, value) { |
3651 if (Object.isUndefined(value)) return element.checked ? element.value : null
; | 5187 if (Object.isUndefined(value)) |
| 5188 return element.checked ? element.value : null; |
3652 else element.checked = !!value; | 5189 else element.checked = !!value; |
3653 }, | 5190 } |
3654 | 5191 |
3655 textarea: function(element, value) { | 5192 function valueSelector(element, value) { |
3656 if (Object.isUndefined(value)) return element.value; | 5193 if (Object.isUndefined(value)) return element.value; |
3657 else element.value = value; | 5194 else element.value = value; |
3658 }, | 5195 } |
3659 | 5196 |
3660 select: function(element, value) { | 5197 function select(element, value) { |
3661 if (Object.isUndefined(value)) | 5198 if (Object.isUndefined(value)) |
3662 return this[element.type == 'select-one' ? | 5199 return (element.type === 'select-one' ? selectOne : selectMany)(element); |
3663 'selectOne' : 'selectMany'](element); | 5200 |
3664 else { | 5201 var opt, currentValue, single = !Object.isArray(value); |
3665 var opt, currentValue, single = !Object.isArray(value); | 5202 for (var i = 0, length = element.length; i < length; i++) { |
3666 for (var i = 0, length = element.length; i < length; i++) { | 5203 opt = element.options[i]; |
3667 opt = element.options[i]; | 5204 currentValue = this.optionValue(opt); |
3668 currentValue = this.optionValue(opt); | 5205 if (single) { |
3669 if (single) { | 5206 if (currentValue == value) { |
3670 if (currentValue == value) { | 5207 opt.selected = true; |
3671 opt.selected = true; | 5208 return; |
3672 return; | |
3673 } | |
3674 } | 5209 } |
3675 else opt.selected = value.include(currentValue); | |
3676 } | 5210 } |
| 5211 else opt.selected = value.include(currentValue); |
3677 } | 5212 } |
3678 }, | 5213 } |
3679 | 5214 |
3680 selectOne: function(element) { | 5215 function selectOne(element) { |
3681 var index = element.selectedIndex; | 5216 var index = element.selectedIndex; |
3682 return index >= 0 ? this.optionValue(element.options[index]) : null; | 5217 return index >= 0 ? optionValue(element.options[index]) : null; |
3683 }, | 5218 } |
3684 | 5219 |
3685 selectMany: function(element) { | 5220 function selectMany(element) { |
3686 var values, length = element.length; | 5221 var values, length = element.length; |
3687 if (!length) return null; | 5222 if (!length) return null; |
3688 | 5223 |
3689 for (var i = 0, values = []; i < length; i++) { | 5224 for (var i = 0, values = []; i < length; i++) { |
3690 var opt = element.options[i]; | 5225 var opt = element.options[i]; |
3691 if (opt.selected) values.push(this.optionValue(opt)); | 5226 if (opt.selected) values.push(optionValue(opt)); |
3692 } | 5227 } |
3693 return values; | 5228 return values; |
3694 }, | 5229 } |
3695 | 5230 |
3696 optionValue: function(opt) { | 5231 function optionValue(opt) { |
3697 // extend element because hasAttribute may not be native | 5232 return Element.hasAttribute(opt, 'value') ? opt.value : opt.text; |
3698 return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text; | |
3699 } | 5233 } |
3700 }; | 5234 |
| 5235 return { |
| 5236 input: input, |
| 5237 inputSelector: inputSelector, |
| 5238 textarea: valueSelector, |
| 5239 select: select, |
| 5240 selectOne: selectOne, |
| 5241 selectMany: selectMany, |
| 5242 optionValue: optionValue, |
| 5243 button: valueSelector |
| 5244 }; |
| 5245 })(); |
3701 | 5246 |
3702 /*--------------------------------------------------------------------------*/ | 5247 /*--------------------------------------------------------------------------*/ |
3703 | 5248 |
| 5249 |
3704 Abstract.TimedObserver = Class.create(PeriodicalExecuter, { | 5250 Abstract.TimedObserver = Class.create(PeriodicalExecuter, { |
3705 initialize: function($super, element, frequency, callback) { | 5251 initialize: function($super, element, frequency, callback) { |
3706 $super(callback, frequency); | 5252 $super(callback, frequency); |
3707 this.element = $(element); | 5253 this.element = $(element); |
3708 this.lastValue = this.getValue(); | 5254 this.lastValue = this.getValue(); |
3709 }, | 5255 }, |
3710 | 5256 |
3711 execute: function() { | 5257 execute: function() { |
3712 var value = this.getValue(); | 5258 var value = this.getValue(); |
3713 if (Object.isString(this.lastValue) && Object.isString(value) ? | 5259 if (Object.isString(this.lastValue) && Object.isString(value) ? |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3775 getValue: function() { | 5321 getValue: function() { |
3776 return Form.Element.getValue(this.element); | 5322 return Form.Element.getValue(this.element); |
3777 } | 5323 } |
3778 }); | 5324 }); |
3779 | 5325 |
3780 Form.EventObserver = Class.create(Abstract.EventObserver, { | 5326 Form.EventObserver = Class.create(Abstract.EventObserver, { |
3781 getValue: function() { | 5327 getValue: function() { |
3782 return Form.serialize(this.element); | 5328 return Form.serialize(this.element); |
3783 } | 5329 } |
3784 }); | 5330 }); |
3785 if (!window.Event) var Event = { }; | 5331 (function() { |
3786 | 5332 |
3787 Object.extend(Event, { | 5333 var Event = { |
3788 KEY_BACKSPACE: 8, | 5334 KEY_BACKSPACE: 8, |
3789 KEY_TAB: 9, | 5335 KEY_TAB: 9, |
3790 KEY_RETURN: 13, | 5336 KEY_RETURN: 13, |
3791 KEY_ESC: 27, | 5337 KEY_ESC: 27, |
3792 KEY_LEFT: 37, | 5338 KEY_LEFT: 37, |
3793 KEY_UP: 38, | 5339 KEY_UP: 38, |
3794 KEY_RIGHT: 39, | 5340 KEY_RIGHT: 39, |
3795 KEY_DOWN: 40, | 5341 KEY_DOWN: 40, |
3796 KEY_DELETE: 46, | 5342 KEY_DELETE: 46, |
3797 KEY_HOME: 36, | 5343 KEY_HOME: 36, |
3798 KEY_END: 35, | 5344 KEY_END: 35, |
3799 KEY_PAGEUP: 33, | 5345 KEY_PAGEUP: 33, |
3800 KEY_PAGEDOWN: 34, | 5346 KEY_PAGEDOWN: 34, |
3801 KEY_INSERT: 45, | 5347 KEY_INSERT: 45, |
3802 | 5348 |
3803 cache: { }, | 5349 cache: {} |
3804 | 5350 }; |
3805 relatedTarget: function(event) { | 5351 |
3806 var element; | 5352 var docEl = document.documentElement; |
3807 switch(event.type) { | 5353 var MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED = 'onmouseenter' in docEl |
3808 case 'mouseover': element = event.fromElement; break; | 5354 && 'onmouseleave' in docEl; |
3809 case 'mouseout': element = event.toElement; break; | 5355 |
3810 default: return null; | 5356 |
3811 } | 5357 |
3812 return Element.extend(element); | 5358 var isIELegacyEvent = function(event) { return false; }; |
3813 } | 5359 |
3814 }); | 5360 if (window.attachEvent) { |
3815 | 5361 if (window.addEventListener) { |
3816 Event.Methods = (function() { | 5362 isIELegacyEvent = function(event) { |
3817 var isButton; | 5363 return !(event instanceof window.Event); |
3818 | 5364 }; |
3819 if (Prototype.Browser.IE) { | 5365 } else { |
3820 var buttonMap = { 0: 1, 1: 4, 2: 2 }; | 5366 isIELegacyEvent = function(event) { return true; }; |
3821 isButton = function(event, code) { | 5367 } |
3822 return event.button == buttonMap[code]; | 5368 } |
3823 }; | 5369 |
3824 | 5370 var _isButton; |
| 5371 |
| 5372 function _isButtonForDOMEvents(event, code) { |
| 5373 return event.which ? (event.which === code + 1) : (event.button === code); |
| 5374 } |
| 5375 |
| 5376 var legacyButtonMap = { 0: 1, 1: 4, 2: 2 }; |
| 5377 function _isButtonForLegacyEvents(event, code) { |
| 5378 return event.button === legacyButtonMap[code]; |
| 5379 } |
| 5380 |
| 5381 function _isButtonForWebKit(event, code) { |
| 5382 switch (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; |
| 5387 } |
| 5388 } |
| 5389 |
| 5390 if (window.attachEvent) { |
| 5391 if (!window.addEventListener) { |
| 5392 _isButton = _isButtonForLegacyEvents; |
| 5393 } else { |
| 5394 _isButton = function(event, code) { |
| 5395 return isIELegacyEvent(event) ? _isButtonForLegacyEvents(event, code) : |
| 5396 _isButtonForDOMEvents(event, code); |
| 5397 } |
| 5398 } |
3825 } else if (Prototype.Browser.WebKit) { | 5399 } else if (Prototype.Browser.WebKit) { |
3826 isButton = function(event, code) { | 5400 _isButton = _isButtonForWebKit; |
3827 switch (code) { | |
3828 case 0: return event.which == 1 && !event.metaKey; | |
3829 case 1: return event.which == 1 && event.metaKey; | |
3830 default: return false; | |
3831 } | |
3832 }; | |
3833 | |
3834 } else { | 5401 } else { |
3835 isButton = function(event, code) { | 5402 _isButton = _isButtonForDOMEvents; |
3836 return event.which ? (event.which === code + 1) : (event.button === code); | 5403 } |
3837 }; | 5404 |
3838 } | 5405 function isLeftClick(event) { return _isButton(event, 0) } |
3839 | 5406 |
3840 return { | 5407 function isMiddleClick(event) { return _isButton(event, 1) } |
3841 isLeftClick: function(event) { return isButton(event, 0) }, | 5408 |
3842 isMiddleClick: function(event) { return isButton(event, 1) }, | 5409 function isRightClick(event) { return _isButton(event, 2) } |
3843 isRightClick: function(event) { return isButton(event, 2) }, | 5410 |
3844 | 5411 function element(event) { |
3845 element: function(event) { | 5412 event = Event.extend(event); |
3846 event = Event.extend(event); | 5413 |
3847 | 5414 var node = event.target, type = event.type, |
3848 var node = event.target, | 5415 currentTarget = event.currentTarget; |
3849 type = event.type, | 5416 |
3850 currentTarget = event.currentTarget; | 5417 if (currentTarget && currentTarget.tagName) { |
3851 | 5418 if (type === 'load' || type === 'error' || |
3852 if (currentTarget && currentTarget.tagName) { | 5419 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' |
3853 // Firefox screws up the "click" event when moving between radio buttons | 5420 && currentTarget.type === 'radio')) |
3854 // via arrow keys. It also screws up the "load" and "error" events on im
ages, | 5421 node = currentTarget; |
3855 // reporting the document as the target instead of the original image. | 5422 } |
3856 if (type === 'load' || type === 'error' || | 5423 |
3857 (type === 'click' && currentTarget.tagName.toLowerCase() === 'input' | 5424 if (node.nodeType == Node.TEXT_NODE) |
3858 && currentTarget.type === 'radio')) | 5425 node = node.parentNode; |
3859 node = currentTarget; | 5426 |
3860 } | 5427 return Element.extend(node); |
3861 if (node.nodeType == Node.TEXT_NODE) node = node.parentNode; | 5428 } |
3862 return Element.extend(node); | 5429 |
3863 }, | 5430 function findElement(event, expression) { |
3864 | 5431 var element = Event.element(event); |
3865 findElement: function(event, expression) { | 5432 |
3866 var element = Event.element(event); | 5433 if (!expression) return element; |
3867 if (!expression) return element; | 5434 while (element) { |
3868 var elements = [element].concat(element.ancestors()); | 5435 if (Object.isElement(element) && Prototype.Selector.match(element, express
ion)) { |
3869 return Selector.findElement(elements, expression, 0); | 5436 return Element.extend(element); |
3870 }, | 5437 } |
3871 | 5438 element = element.parentNode; |
3872 pointer: function(event) { | 5439 } |
3873 var docElement = document.documentElement, | 5440 } |
3874 body = document.body || { scrollLeft: 0, scrollTop: 0 }; | 5441 |
3875 return { | 5442 function pointer(event) { |
3876 x: event.pageX || (event.clientX + | 5443 return { x: pointerX(event), y: pointerY(event) }; |
3877 (docElement.scrollLeft || body.scrollLeft) - | 5444 } |
3878 (docElement.clientLeft || 0)), | 5445 |
3879 y: event.pageY || (event.clientY + | 5446 function pointerX(event) { |
3880 (docElement.scrollTop || body.scrollTop) - | 5447 var docElement = document.documentElement, |
3881 (docElement.clientTop || 0)) | 5448 body = document.body || { scrollLeft: 0 }; |
3882 }; | 5449 |
3883 }, | 5450 return event.pageX || (event.clientX + |
3884 | 5451 (docElement.scrollLeft || body.scrollLeft) - |
3885 pointerX: function(event) { return Event.pointer(event).x }, | 5452 (docElement.clientLeft || 0)); |
3886 pointerY: function(event) { return Event.pointer(event).y }, | 5453 } |
3887 | 5454 |
3888 stop: function(event) { | 5455 function pointerY(event) { |
3889 Event.extend(event); | 5456 var docElement = document.documentElement, |
3890 event.preventDefault(); | 5457 body = document.body || { scrollTop: 0 }; |
3891 event.stopPropagation(); | 5458 |
3892 event.stopped = true; | 5459 return event.pageY || (event.clientY + |
3893 } | 5460 (docElement.scrollTop || body.scrollTop) - |
| 5461 (docElement.clientTop || 0)); |
| 5462 } |
| 5463 |
| 5464 |
| 5465 function stop(event) { |
| 5466 Event.extend(event); |
| 5467 event.preventDefault(); |
| 5468 event.stopPropagation(); |
| 5469 |
| 5470 event.stopped = true; |
| 5471 } |
| 5472 |
| 5473 |
| 5474 Event.Methods = { |
| 5475 isLeftClick: isLeftClick, |
| 5476 isMiddleClick: isMiddleClick, |
| 5477 isRightClick: isRightClick, |
| 5478 |
| 5479 element: element, |
| 5480 findElement: findElement, |
| 5481 |
| 5482 pointer: pointer, |
| 5483 pointerX: pointerX, |
| 5484 pointerY: pointerY, |
| 5485 |
| 5486 stop: stop |
3894 }; | 5487 }; |
3895 })(); | 5488 |
3896 | |
3897 Event.extend = (function() { | |
3898 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { | 5489 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { |
3899 m[name] = Event.Methods[name].methodize(); | 5490 m[name] = Event.Methods[name].methodize(); |
3900 return m; | 5491 return m; |
3901 }); | 5492 }); |
3902 | 5493 |
3903 if (Prototype.Browser.IE) { | 5494 if (window.attachEvent) { |
3904 Object.extend(methods, { | 5495 function _relatedTarget(event) { |
| 5496 var element; |
| 5497 switch (event.type) { |
| 5498 case 'mouseover': |
| 5499 case 'mouseenter': |
| 5500 element = event.fromElement; |
| 5501 break; |
| 5502 case 'mouseout': |
| 5503 case 'mouseleave': |
| 5504 element = event.toElement; |
| 5505 break; |
| 5506 default: |
| 5507 return null; |
| 5508 } |
| 5509 return Element.extend(element); |
| 5510 } |
| 5511 |
| 5512 var additionalMethods = { |
3905 stopPropagation: function() { this.cancelBubble = true }, | 5513 stopPropagation: function() { this.cancelBubble = true }, |
3906 preventDefault: function() { this.returnValue = false }, | 5514 preventDefault: function() { this.returnValue = false }, |
3907 inspect: function() { return "[object Event]" } | 5515 inspect: function() { return '[object Event]' } |
3908 }); | 5516 }; |
3909 | 5517 |
3910 return function(event) { | 5518 Event.extend = function(event, element) { |
3911 if (!event) return false; | 5519 if (!event) return false; |
| 5520 |
| 5521 if (!isIELegacyEvent(event)) return event; |
| 5522 |
3912 if (event._extendedByPrototype) return event; | 5523 if (event._extendedByPrototype) return event; |
3913 | |
3914 event._extendedByPrototype = Prototype.emptyFunction; | 5524 event._extendedByPrototype = Prototype.emptyFunction; |
| 5525 |
3915 var pointer = Event.pointer(event); | 5526 var pointer = Event.pointer(event); |
| 5527 |
3916 Object.extend(event, { | 5528 Object.extend(event, { |
3917 target: event.srcElement, | 5529 target: event.srcElement || element, |
3918 relatedTarget: Event.relatedTarget(event), | 5530 relatedTarget: _relatedTarget(event), |
3919 pageX: pointer.x, | 5531 pageX: pointer.x, |
3920 pageY: pointer.y | 5532 pageY: pointer.y |
3921 }); | 5533 }); |
3922 return Object.extend(event, methods); | 5534 |
| 5535 Object.extend(event, methods); |
| 5536 Object.extend(event, additionalMethods); |
| 5537 |
| 5538 return event; |
3923 }; | 5539 }; |
3924 | |
3925 } else { | 5540 } else { |
3926 Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__p
roto__']; | 5541 Event.extend = Prototype.K; |
| 5542 } |
| 5543 |
| 5544 if (window.addEventListener) { |
| 5545 Event.prototype = window.Event.prototype || document.createEvent('HTMLEvents
').__proto__; |
3927 Object.extend(Event.prototype, methods); | 5546 Object.extend(Event.prototype, methods); |
3928 return Prototype.K; | 5547 } |
3929 } | 5548 |
| 5549 function _createResponder(element, eventName, handler) { |
| 5550 var registry = Element.retrieve(element, 'prototype_event_registry'); |
| 5551 |
| 5552 if (Object.isUndefined(registry)) { |
| 5553 CACHE.push(element); |
| 5554 registry = Element.retrieve(element, 'prototype_event_registry', $H()); |
| 5555 } |
| 5556 |
| 5557 var respondersForEvent = registry.get(eventName); |
| 5558 if (Object.isUndefined(respondersForEvent)) { |
| 5559 respondersForEvent = []; |
| 5560 registry.set(eventName, respondersForEvent); |
| 5561 } |
| 5562 |
| 5563 if (respondersForEvent.pluck('handler').include(handler)) return false; |
| 5564 |
| 5565 var responder; |
| 5566 if (eventName.include(":")) { |
| 5567 responder = function(event) { |
| 5568 if (Object.isUndefined(event.eventName)) |
| 5569 return false; |
| 5570 |
| 5571 if (event.eventName !== eventName) |
| 5572 return false; |
| 5573 |
| 5574 Event.extend(event, element); |
| 5575 handler.call(element, event); |
| 5576 }; |
| 5577 } else { |
| 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); |
| 5583 |
| 5584 var parent = event.relatedTarget; |
| 5585 while (parent && parent !== element) { |
| 5586 try { parent = parent.parentNode; } |
| 5587 catch(e) { parent = element; } |
| 5588 } |
| 5589 |
| 5590 if (parent === element) return; |
| 5591 |
| 5592 handler.call(element, event); |
| 5593 }; |
| 5594 } |
| 5595 } else { |
| 5596 responder = function(event) { |
| 5597 Event.extend(event, element); |
| 5598 handler.call(element, event); |
| 5599 }; |
| 5600 } |
| 5601 } |
| 5602 |
| 5603 responder.handler = handler; |
| 5604 respondersForEvent.push(responder); |
| 5605 return responder; |
| 5606 } |
| 5607 |
| 5608 function _destroyCache() { |
| 5609 for (var i = 0, length = CACHE.length; i < length; i++) { |
| 5610 Event.stopObserving(CACHE[i]); |
| 5611 CACHE[i] = null; |
| 5612 } |
| 5613 } |
| 5614 |
| 5615 var CACHE = []; |
| 5616 |
| 5617 if (Prototype.Browser.IE) |
| 5618 window.attachEvent('onunload', _destroyCache); |
| 5619 |
| 5620 if (Prototype.Browser.WebKit) |
| 5621 window.addEventListener('unload', Prototype.emptyFunction, false); |
| 5622 |
| 5623 |
| 5624 var _getDOMEventName = Prototype.K, |
| 5625 translations = { mouseenter: "mouseover", mouseleave: "mouseout" }; |
| 5626 |
| 5627 if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) { |
| 5628 _getDOMEventName = function(eventName) { |
| 5629 return (translations[eventName] || eventName); |
| 5630 }; |
| 5631 } |
| 5632 |
| 5633 function observe(element, eventName, handler) { |
| 5634 element = $(element); |
| 5635 |
| 5636 var responder = _createResponder(element, eventName, handler); |
| 5637 |
| 5638 if (!responder) return element; |
| 5639 |
| 5640 if (eventName.include(':')) { |
| 5641 if (element.addEventListener) |
| 5642 element.addEventListener("dataavailable", responder, false); |
| 5643 else { |
| 5644 element.attachEvent("ondataavailable", responder); |
| 5645 element.attachEvent("onlosecapture", responder); |
| 5646 } |
| 5647 } else { |
| 5648 var actualEventName = _getDOMEventName(eventName); |
| 5649 |
| 5650 if (element.addEventListener) |
| 5651 element.addEventListener(actualEventName, responder, false); |
| 5652 else |
| 5653 element.attachEvent("on" + actualEventName, responder); |
| 5654 } |
| 5655 |
| 5656 return element; |
| 5657 } |
| 5658 |
| 5659 function stopObserving(element, eventName, handler) { |
| 5660 element = $(element); |
| 5661 |
| 5662 var registry = Element.retrieve(element, 'prototype_event_registry'); |
| 5663 if (!registry) return element; |
| 5664 |
| 5665 if (!eventName) { |
| 5666 registry.each( function(pair) { |
| 5667 var eventName = pair.key; |
| 5668 stopObserving(element, eventName); |
| 5669 }); |
| 5670 return element; |
| 5671 } |
| 5672 |
| 5673 var responders = registry.get(eventName); |
| 5674 if (!responders) return element; |
| 5675 |
| 5676 if (!handler) { |
| 5677 responders.each(function(r) { |
| 5678 stopObserving(element, eventName, r.handler); |
| 5679 }); |
| 5680 return element; |
| 5681 } |
| 5682 |
| 5683 var i = responders.length, responder; |
| 5684 while (i--) { |
| 5685 if (responders[i].handler === handler) { |
| 5686 responder = responders[i]; |
| 5687 break; |
| 5688 } |
| 5689 } |
| 5690 if (!responder) return element; |
| 5691 |
| 5692 if (eventName.include(':')) { |
| 5693 if (element.removeEventListener) |
| 5694 element.removeEventListener("dataavailable", responder, false); |
| 5695 else { |
| 5696 element.detachEvent("ondataavailable", responder); |
| 5697 element.detachEvent("onlosecapture", responder); |
| 5698 } |
| 5699 } else { |
| 5700 var actualEventName = _getDOMEventName(eventName); |
| 5701 if (element.removeEventListener) |
| 5702 element.removeEventListener(actualEventName, responder, false); |
| 5703 else |
| 5704 element.detachEvent('on' + actualEventName, responder); |
| 5705 } |
| 5706 |
| 5707 registry.set(eventName, responders.without(responder)); |
| 5708 |
| 5709 return element; |
| 5710 } |
| 5711 |
| 5712 function fire(element, eventName, memo, bubble) { |
| 5713 element = $(element); |
| 5714 |
| 5715 if (Object.isUndefined(bubble)) |
| 5716 bubble = true; |
| 5717 |
| 5718 if (element == document && document.createEvent && !element.dispatchEvent) |
| 5719 element = document.documentElement; |
| 5720 |
| 5721 var event; |
| 5722 if (document.createEvent) { |
| 5723 event = document.createEvent('HTMLEvents'); |
| 5724 event.initEvent('dataavailable', bubble, true); |
| 5725 } else { |
| 5726 event = document.createEventObject(); |
| 5727 event.eventType = bubble ? 'ondataavailable' : 'onlosecapture'; |
| 5728 } |
| 5729 |
| 5730 event.eventName = eventName; |
| 5731 event.memo = memo || { }; |
| 5732 |
| 5733 if (document.createEvent) |
| 5734 element.dispatchEvent(event); |
| 5735 else |
| 5736 element.fireEvent(event.eventType, event); |
| 5737 |
| 5738 return Event.extend(event); |
| 5739 } |
| 5740 |
| 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); |
| 5748 }, |
| 5749 |
| 5750 start: function() { |
| 5751 Event.observe(this.element, this.eventName, this.handler); |
| 5752 return this; |
| 5753 }, |
| 5754 |
| 5755 stop: function() { |
| 5756 Event.stopObserving(this.element, this.eventName, this.handler); |
| 5757 return this; |
| 5758 }, |
| 5759 |
| 5760 handleEvent: function(event) { |
| 5761 var element = Event.findElement(event, this.selector); |
| 5762 if (element) this.callback.call(this.element, event, element); |
| 5763 } |
| 5764 }); |
| 5765 |
| 5766 function on(element, eventName, selector, callback) { |
| 5767 element = $(element); |
| 5768 if (Object.isFunction(selector) && Object.isUndefined(callback)) { |
| 5769 callback = selector, selector = null; |
| 5770 } |
| 5771 |
| 5772 return new Event.Handler(element, eventName, selector, callback).start(); |
| 5773 } |
| 5774 |
| 5775 Object.extend(Event, Event.Methods); |
| 5776 |
| 5777 Object.extend(Event, { |
| 5778 fire: fire, |
| 5779 observe: observe, |
| 5780 stopObserving: stopObserving, |
| 5781 on: on |
| 5782 }); |
| 5783 |
| 5784 Element.addMethods({ |
| 5785 fire: fire, |
| 5786 |
| 5787 observe: observe, |
| 5788 |
| 5789 stopObserving: stopObserving, |
| 5790 |
| 5791 on: on |
| 5792 }); |
| 5793 |
| 5794 Object.extend(document, { |
| 5795 fire: fire.methodize(), |
| 5796 |
| 5797 observe: observe.methodize(), |
| 5798 |
| 5799 stopObserving: stopObserving.methodize(), |
| 5800 |
| 5801 on: on.methodize(), |
| 5802 |
| 5803 loaded: false |
| 5804 }); |
| 5805 |
| 5806 if (window.Event) Object.extend(window.Event, Event); |
| 5807 else window.Event = Event; |
3930 })(); | 5808 })(); |
3931 | 5809 |
3932 Object.extend(Event, (function() { | |
3933 var cache = Event.cache; | |
3934 | |
3935 function getEventID(element) { | |
3936 if (element._prototypeEventID) return element._prototypeEventID[0]; | |
3937 arguments.callee.id = arguments.callee.id || 1; | |
3938 return element._prototypeEventID = [++arguments.callee.id]; | |
3939 } | |
3940 | |
3941 function getDOMEventName(eventName) { | |
3942 if (eventName && eventName.include(':')) return "dataavailable"; | |
3943 return eventName; | |
3944 } | |
3945 | |
3946 function getCacheForID(id) { | |
3947 return cache[id] = cache[id] || { }; | |
3948 } | |
3949 | |
3950 function getWrappersForEventName(id, eventName) { | |
3951 var c = getCacheForID(id); | |
3952 return c[eventName] = c[eventName] || []; | |
3953 } | |
3954 | |
3955 function createWrapper(element, eventName, handler) { | |
3956 var id = getEventID(element); | |
3957 var c = getWrappersForEventName(id, eventName); | |
3958 if (c.pluck("handler").include(handler)) return false; | |
3959 | |
3960 var wrapper = function(event) { | |
3961 if (!Event || !Event.extend || | |
3962 (event.eventName && event.eventName != eventName)) | |
3963 return false; | |
3964 | |
3965 Event.extend(event); | |
3966 handler.call(element, event); | |
3967 }; | |
3968 | |
3969 wrapper.handler = handler; | |
3970 c.push(wrapper); | |
3971 return wrapper; | |
3972 } | |
3973 | |
3974 function findWrapper(id, eventName, handler) { | |
3975 var c = getWrappersForEventName(id, eventName); | |
3976 return c.find(function(wrapper) { return wrapper.handler == handler }); | |
3977 } | |
3978 | |
3979 function destroyWrapper(id, eventName, handler) { | |
3980 var c = getCacheForID(id); | |
3981 if (!c[eventName]) return false; | |
3982 c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); | |
3983 } | |
3984 | |
3985 function destroyCache() { | |
3986 for (var id in cache) | |
3987 for (var eventName in cache[id]) | |
3988 cache[id][eventName] = null; | |
3989 } | |
3990 | |
3991 | |
3992 // Internet Explorer needs to remove event handlers on page unload | |
3993 // in order to avoid memory leaks. | |
3994 if (window.attachEvent) { | |
3995 window.attachEvent("onunload", destroyCache); | |
3996 } | |
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 | |
4005 return { | |
4006 observe: function(element, eventName, handler) { | |
4007 element = $(element); | |
4008 var name = getDOMEventName(eventName); | |
4009 | |
4010 var wrapper = createWrapper(element, eventName, handler); | |
4011 if (!wrapper) return element; | |
4012 | |
4013 if (element.addEventListener) { | |
4014 element.addEventListener(name, wrapper, false); | |
4015 } else { | |
4016 element.attachEvent("on" + name, wrapper); | |
4017 } | |
4018 | |
4019 return element; | |
4020 }, | |
4021 | |
4022 stopObserving: function(element, eventName, handler) { | |
4023 element = $(element); | |
4024 var id = getEventID(element), name = getDOMEventName(eventName); | |
4025 | |
4026 if (!handler && eventName) { | |
4027 getWrappersForEventName(id, eventName).each(function(wrapper) { | |
4028 element.stopObserving(eventName, wrapper.handler); | |
4029 }); | |
4030 return element; | |
4031 | |
4032 } else if (!eventName) { | |
4033 Object.keys(getCacheForID(id)).each(function(eventName) { | |
4034 element.stopObserving(eventName); | |
4035 }); | |
4036 return element; | |
4037 } | |
4038 | |
4039 var wrapper = findWrapper(id, eventName, handler); | |
4040 if (!wrapper) return element; | |
4041 | |
4042 if (element.removeEventListener) { | |
4043 element.removeEventListener(name, wrapper, false); | |
4044 } else { | |
4045 element.detachEvent("on" + name, wrapper); | |
4046 } | |
4047 | |
4048 destroyWrapper(id, eventName, handler); | |
4049 | |
4050 return element; | |
4051 }, | |
4052 | |
4053 fire: function(element, eventName, memo) { | |
4054 element = $(element); | |
4055 if (element == document && document.createEvent && !element.dispatchEvent) | |
4056 element = document.documentElement; | |
4057 | |
4058 var event; | |
4059 if (document.createEvent) { | |
4060 event = document.createEvent("HTMLEvents"); | |
4061 event.initEvent("dataavailable", true, true); | |
4062 } else { | |
4063 event = document.createEventObject(); | |
4064 event.eventType = "ondataavailable"; | |
4065 } | |
4066 | |
4067 event.eventName = eventName; | |
4068 event.memo = memo || { }; | |
4069 | |
4070 if (document.createEvent) { | |
4071 element.dispatchEvent(event); | |
4072 } else { | |
4073 element.fireEvent(event.eventType, event); | |
4074 } | |
4075 | |
4076 return Event.extend(event); | |
4077 } | |
4078 }; | |
4079 })()); | |
4080 | |
4081 Object.extend(Event, Event.Methods); | |
4082 | |
4083 Element.addMethods({ | |
4084 fire: Event.fire, | |
4085 observe: Event.observe, | |
4086 stopObserving: Event.stopObserving | |
4087 }); | |
4088 | |
4089 Object.extend(document, { | |
4090 fire: Element.Methods.fire.methodize(), | |
4091 observe: Element.Methods.observe.methodize(), | |
4092 stopObserving: Element.Methods.stopObserving.methodize(), | |
4093 loaded: false | |
4094 }); | |
4095 | |
4096 (function() { | 5810 (function() { |
4097 /* Support for the DOMContentLoaded event is based on work by Dan Webb, | 5811 /* Support for the DOMContentLoaded event is based on work by Dan Webb, |
4098 Matthias Miller, Dean Edwards and John Resig. */ | 5812 Matthias Miller, Dean Edwards, John Resig, and Diego Perini. */ |
4099 | 5813 |
4100 var timer; | 5814 var timer; |
4101 | 5815 |
4102 function fireContentLoadedEvent() { | 5816 function fireContentLoadedEvent() { |
4103 if (document.loaded) return; | 5817 if (document.loaded) return; |
4104 if (timer) window.clearInterval(timer); | 5818 if (timer) window.clearTimeout(timer); |
4105 document.fire("dom:loaded"); | |
4106 document.loaded = true; | 5819 document.loaded = true; |
| 5820 document.fire('dom:loaded'); |
| 5821 } |
| 5822 |
| 5823 function checkReadyState() { |
| 5824 if (document.readyState === 'complete') { |
| 5825 document.stopObserving('readystatechange', checkReadyState); |
| 5826 fireContentLoadedEvent(); |
| 5827 } |
| 5828 } |
| 5829 |
| 5830 function pollDoScroll() { |
| 5831 try { document.documentElement.doScroll('left'); } |
| 5832 catch(e) { |
| 5833 timer = pollDoScroll.defer(); |
| 5834 return; |
| 5835 } |
| 5836 fireContentLoadedEvent(); |
4107 } | 5837 } |
4108 | 5838 |
4109 if (document.addEventListener) { | 5839 if (document.addEventListener) { |
4110 if (Prototype.Browser.WebKit) { | 5840 document.addEventListener('DOMContentLoaded', fireContentLoadedEvent, false)
; |
4111 timer = window.setInterval(function() { | |
4112 if (/loaded|complete/.test(document.readyState)) | |
4113 fireContentLoadedEvent(); | |
4114 }, 0); | |
4115 | |
4116 Event.observe(window, "load", fireContentLoadedEvent); | |
4117 | |
4118 } else { | |
4119 document.addEventListener("DOMContentLoaded", | |
4120 fireContentLoadedEvent, false); | |
4121 } | |
4122 | |
4123 } else { | 5841 } else { |
4124 document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>"); | 5842 document.observe('readystatechange', checkReadyState); |
4125 $("__onDOMContentLoaded").onreadystatechange = function() { | 5843 if (window == top) |
4126 if (this.readyState == "complete") { | 5844 timer = pollDoScroll.defer(); |
4127 this.onreadystatechange = null; | 5845 } |
4128 fireContentLoadedEvent(); | 5846 |
4129 } | 5847 Event.observe(window, 'load', fireContentLoadedEvent); |
4130 }; | |
4131 } | |
4132 })(); | 5848 })(); |
| 5849 |
| 5850 Element.addMethods(); |
| 5851 |
4133 /*------------------------------- DEPRECATED -------------------------------*/ | 5852 /*------------------------------- DEPRECATED -------------------------------*/ |
4134 | 5853 |
4135 Hash.toQueryString = Object.toQueryString; | 5854 Hash.toQueryString = Object.toQueryString; |
4136 | 5855 |
4137 var Toggle = { display: Element.toggle }; | 5856 var Toggle = { display: Element.toggle }; |
4138 | 5857 |
4139 Element.Methods.childOf = Element.Methods.descendantOf; | 5858 Element.Methods.childOf = Element.Methods.descendantOf; |
4140 | 5859 |
4141 var Insertion = { | 5860 var Insertion = { |
4142 Before: function(element, content) { | 5861 Before: function(element, content) { |
4143 return Element.insert(element, {before:content}); | 5862 return Element.insert(element, {before:content}); |
4144 }, | 5863 }, |
4145 | 5864 |
4146 Top: function(element, content) { | 5865 Top: function(element, content) { |
4147 return Element.insert(element, {top:content}); | 5866 return Element.insert(element, {top:content}); |
4148 }, | 5867 }, |
4149 | 5868 |
4150 Bottom: function(element, content) { | 5869 Bottom: function(element, content) { |
4151 return Element.insert(element, {bottom:content}); | 5870 return Element.insert(element, {bottom:content}); |
4152 }, | 5871 }, |
4153 | 5872 |
4154 After: function(element, content) { | 5873 After: function(element, content) { |
4155 return Element.insert(element, {after:content}); | 5874 return Element.insert(element, {after:content}); |
4156 } | 5875 } |
4157 }; | 5876 }; |
4158 | 5877 |
4159 var $continue = new Error('"throw $continue" is deprecated, use "return" instead
'); | 5878 var $continue = new Error('"throw $continue" is deprecated, use "return" instead
'); |
4160 | 5879 |
4161 // This should be moved to script.aculo.us; notice the deprecated methods | |
4162 // further below, that map to the newer Element methods. | |
4163 var Position = { | 5880 var Position = { |
4164 // set to true if needed, warning: firefox performance problems | |
4165 // NOT neeeded for page scrolling, only if draggable contained in | |
4166 // scrollable elements | |
4167 includeScrollOffsets: false, | 5881 includeScrollOffsets: false, |
4168 | 5882 |
4169 // must be called before calling withinIncludingScrolloffset, every time the | |
4170 // page is scrolled | |
4171 prepare: function() { | 5883 prepare: function() { |
4172 this.deltaX = window.pageXOffset | 5884 this.deltaX = window.pageXOffset |
4173 || document.documentElement.scrollLeft | 5885 || document.documentElement.scrollLeft |
4174 || document.body.scrollLeft | 5886 || document.body.scrollLeft |
4175 || 0; | 5887 || 0; |
4176 this.deltaY = window.pageYOffset | 5888 this.deltaY = window.pageYOffset |
4177 || document.documentElement.scrollTop | 5889 || document.documentElement.scrollTop |
4178 || document.body.scrollTop | 5890 || document.body.scrollTop |
4179 || 0; | 5891 || 0; |
4180 }, | 5892 }, |
4181 | 5893 |
4182 // caches x/y coordinate pair to use with overlap | |
4183 within: function(element, x, y) { | 5894 within: function(element, x, y) { |
4184 if (this.includeScrollOffsets) | 5895 if (this.includeScrollOffsets) |
4185 return this.withinIncludingScrolloffsets(element, x, y); | 5896 return this.withinIncludingScrolloffsets(element, x, y); |
4186 this.xcomp = x; | 5897 this.xcomp = x; |
4187 this.ycomp = y; | 5898 this.ycomp = y; |
4188 this.offset = Element.cumulativeOffset(element); | 5899 this.offset = Element.cumulativeOffset(element); |
4189 | 5900 |
4190 return (y >= this.offset[1] && | 5901 return (y >= this.offset[1] && |
4191 y < this.offset[1] + element.offsetHeight && | 5902 y < this.offset[1] + element.offsetHeight && |
4192 x >= this.offset[0] && | 5903 x >= this.offset[0] && |
4193 x < this.offset[0] + element.offsetWidth); | 5904 x < this.offset[0] + element.offsetWidth); |
4194 }, | 5905 }, |
4195 | 5906 |
4196 withinIncludingScrolloffsets: function(element, x, y) { | 5907 withinIncludingScrolloffsets: function(element, x, y) { |
4197 var offsetcache = Element.cumulativeScrollOffset(element); | 5908 var offsetcache = Element.cumulativeScrollOffset(element); |
4198 | 5909 |
4199 this.xcomp = x + offsetcache[0] - this.deltaX; | 5910 this.xcomp = x + offsetcache[0] - this.deltaX; |
4200 this.ycomp = y + offsetcache[1] - this.deltaY; | 5911 this.ycomp = y + offsetcache[1] - this.deltaY; |
4201 this.offset = Element.cumulativeOffset(element); | 5912 this.offset = Element.cumulativeOffset(element); |
4202 | 5913 |
4203 return (this.ycomp >= this.offset[1] && | 5914 return (this.ycomp >= this.offset[1] && |
4204 this.ycomp < this.offset[1] + element.offsetHeight && | 5915 this.ycomp < this.offset[1] + element.offsetHeight && |
4205 this.xcomp >= this.offset[0] && | 5916 this.xcomp >= this.offset[0] && |
4206 this.xcomp < this.offset[0] + element.offsetWidth); | 5917 this.xcomp < this.offset[0] + element.offsetWidth); |
4207 }, | 5918 }, |
4208 | 5919 |
4209 // within must be called directly before | |
4210 overlap: function(mode, element) { | 5920 overlap: function(mode, element) { |
4211 if (!mode) return 0; | 5921 if (!mode) return 0; |
4212 if (mode == 'vertical') | 5922 if (mode == 'vertical') |
4213 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / | 5923 return ((this.offset[1] + element.offsetHeight) - this.ycomp) / |
4214 element.offsetHeight; | 5924 element.offsetHeight; |
4215 if (mode == 'horizontal') | 5925 if (mode == 'horizontal') |
4216 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / | 5926 return ((this.offset[0] + element.offsetWidth) - this.xcomp) / |
4217 element.offsetWidth; | 5927 element.offsetWidth; |
4218 }, | 5928 }, |
4219 | 5929 |
4220 // Deprecation layer -- use newer Element methods now (1.5.2). | |
4221 | 5930 |
4222 cumulativeOffset: Element.Methods.cumulativeOffset, | 5931 cumulativeOffset: Element.Methods.cumulativeOffset, |
4223 | 5932 |
4224 positionedOffset: Element.Methods.positionedOffset, | 5933 positionedOffset: Element.Methods.positionedOffset, |
4225 | 5934 |
4226 absolutize: function(element) { | 5935 absolutize: function(element) { |
4227 Position.prepare(); | 5936 Position.prepare(); |
4228 return Element.absolutize(element); | 5937 return Element.absolutize(element); |
4229 }, | 5938 }, |
4230 | 5939 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4310 | 6019 |
4311 toString: function() { | 6020 toString: function() { |
4312 return $A(this).join(' '); | 6021 return $A(this).join(' '); |
4313 } | 6022 } |
4314 }; | 6023 }; |
4315 | 6024 |
4316 Object.extend(Element.ClassNames.prototype, Enumerable); | 6025 Object.extend(Element.ClassNames.prototype, Enumerable); |
4317 | 6026 |
4318 /*--------------------------------------------------------------------------*/ | 6027 /*--------------------------------------------------------------------------*/ |
4319 | 6028 |
4320 Element.addMethods(); | 6029 (function() { |
| 6030 window.Selector = Class.create({ |
| 6031 initialize: function(expression) { |
| 6032 this.expression = expression.strip(); |
| 6033 }, |
| 6034 |
| 6035 findElements: function(rootElement) { |
| 6036 return Prototype.Selector.select(this.expression, rootElement); |
| 6037 }, |
| 6038 |
| 6039 match: function(element) { |
| 6040 return Prototype.Selector.match(element, this.expression); |
| 6041 }, |
| 6042 |
| 6043 toString: function() { |
| 6044 return this.expression; |
| 6045 }, |
| 6046 |
| 6047 inspect: function() { |
| 6048 return "#<Selector: " + this.expression + ">"; |
| 6049 } |
| 6050 }); |
| 6051 |
| 6052 Object.extend(Selector, { |
| 6053 matchElements: function(elements, expression) { |
| 6054 var match = Prototype.Selector.match, |
| 6055 results = []; |
| 6056 |
| 6057 for (var i = 0, length = elements.length; i < length; i++) { |
| 6058 var element = elements[i]; |
| 6059 if (match(element, expression)) { |
| 6060 results.push(Element.extend(element)); |
| 6061 } |
| 6062 } |
| 6063 return results; |
| 6064 }, |
| 6065 |
| 6066 findElement: function(elements, expression, index) { |
| 6067 index = index || 0; |
| 6068 var matchIndex = 0, element; |
| 6069 for (var i = 0, length = elements.length; i < length; i++) { |
| 6070 element = elements[i]; |
| 6071 if (Prototype.Selector.match(element, expression) && index === matchInde
x++) { |
| 6072 return Element.extend(element); |
| 6073 } |
| 6074 } |
| 6075 }, |
| 6076 |
| 6077 findChildElements: function(element, expressions) { |
| 6078 var selector = expressions.toArray().join(', '); |
| 6079 return Prototype.Selector.select(selector, element || document); |
| 6080 } |
| 6081 }); |
| 6082 })(); |
OLD | NEW |