Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1205)

Side by Side Diff: chrome/test/data/dromaeo/lib/mootools.js

Issue 2499923002: Update dromaeo to upstream a876d5250befbc41e2deab9d10cf6085b511d5ed (Closed)
Patch Set: Modified readme Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/test/data/dromaeo/lib/jquery.2.0.3.js ('k') | chrome/test/data/dromaeo/lib/prototype.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 Script: Core.js 2 ---
3 » MooTools - My Object Oriented JavaScript Tools. 3 MooTools: the javascript framework
4 4
5 License: 5 web build:
6 » MIT-style license. 6 - http://mootools.net/core/76bf47062d6c1983d66ce47ad66aa0e0
7 7
8 Copyright: 8 packager build:
9 » Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/). 9 - packager build Core/Core Core/Array Core/String Core/Number Core/Function Cor e/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Elemen t.Delegation Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.M orph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/C ookie Core/JSON Core/DOMReady Core/Swiff
10 10
11 Code & Documentation: 11 /*
12 » [The MooTools production team](http://mootools.net/developers/). 12 ---
13 13
14 Inspiration: 14 name: Core
15 » - Class implementation inspired by [Base.js](http://dean.edwards.name/we blog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) 15
16 » - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/lice nses/mit-license.php) 16 description: The heart of MooTools.
17
18 license: MIT-style license.
19
20 copyright: Copyright (c) 2006-2010 [Valerio Proietti](http://mad4milk.net/).
21
22 authors: The MooTools production team (http://mootools.net/developers/)
23
24 inspiration:
25 - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2 006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public Licens e](http://opensource.org/licenses/lgpl-license.php)
26 - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyri ght (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/m it-license.php)
27
28 provides: [Core, MooTools, Type, typeOf, instanceOf, Native]
29
30 ...
17 */ 31 */
18 32
19 var MooTools = { 33 (function(){
20 » 'version': '1.2.1', 34
21 » 'build': '0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf' 35 this.MooTools = {
22 }; 36 » version: '1.4.1',
23 37 » build: 'd1fb25710e3c5482a219ab9dc675a4e0ad2176b6'
24 var Native = function(options){ 38 };
25 » options = options || {}; 39
26 » var name = options.name; 40 // typeOf, instanceOf
27 » var legacy = options.legacy; 41
28 » var protect = options.protect; 42 var typeOf = this.typeOf = function(item){
29 » var methods = options.implement; 43 » if (item == null) return 'null';
30 » var generics = options.generics; 44 » if (item.$family) return item.$family();
31 » var initialize = options.initialize; 45
32 » var afterImplement = options.afterImplement || function(){}; 46 » if (item.nodeName){
33 » var object = initialize || legacy; 47 » » if (item.nodeType == 1) return 'element';
34 » generics = generics !== false; 48 » » if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'te xtnode' : 'whitespace';
35 49 » } else if (typeof item.length == 'number'){
36 » object.constructor = Native; 50 » » if (item.callee) return 'arguments';
37 » object.$family = {name: 'native'}; 51 » » if ('item' in item) return 'collection';
38 » if (legacy && initialize) object.prototype = legacy.prototype; 52 » }
39 » object.prototype.constructor = object; 53
40 54 » return typeof item;
41 » if (name){ 55 };
42 » » var family = name.toLowerCase(); 56
43 » » object.prototype.$family = {name: family}; 57 var instanceOf = this.instanceOf = function(item, object){
44 » » Native.typize(object, family); 58 » if (item == null) return false;
45 » } 59 » var constructor = item.$constructor || item.constructor;
46 60 » while (constructor){
47 » var add = function(obj, name, method, force){ 61 » » if (constructor === object) return true;
48 » » if (!protect || force || !obj.prototype[name]) obj.prototype[nam e] = method; 62 » » constructor = constructor.parent;
49 » » if (generics) Native.genericize(obj, name, protect); 63 » }
50 » » afterImplement.call(obj, name, method); 64 » return item instanceof object;
51 » » return obj; 65 };
52 » }; 66
53 67 // Function overloading
54 » object.alias = function(a1, a2, a3){ 68
55 » » if (typeof a1 == 'string'){ 69 var Function = this.Function;
56 » » » if ((a1 = this.prototype[a1])) return add(this, a2, a1, a3); 70
57 » » } 71 var enumerables = true;
58 » » for (var a in a1) this.alias(a, a1[a], a2); 72 for (var i in {toString: 1}) enumerables = null;
73 if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'p ropertyIsEnumerable', 'toLocaleString', 'toString', 'constructor'];
74
75 Function.prototype.overloadSetter = function(usePlural){
76 » var self = this;
77 » return function(a, b){
78 » » if (a == null) return this;
79 » » if (usePlural || typeof a != 'string'){
80 » » » for (var k in a) self.call(this, k, a[k]);
81 » » » if (enumerables) for (var i = enumerables.length; i--;){
82 » » » » k = enumerables[i];
83 » » » » if (a.hasOwnProperty(k)) self.call(this, k, a[k] );
84 » » » }
85 » » } else {
86 » » » self.call(this, a, b);
87 » » }
59 return this; 88 return this;
60 }; 89 };
61 90 };
62 » object.implement = function(a1, a2, a3){ 91
63 » » if (typeof a1 == 'string') return add(this, a1, a2, a3); 92 Function.prototype.overloadGetter = function(usePlural){
64 » » for (var p in a1) add(this, p, a1[p], a2); 93 » var self = this;
94 » return function(a){
95 » » var args, result;
96 » » if (usePlural || typeof a != 'string') args = a;
97 » » else if (arguments.length > 1) args = arguments;
98 » » if (args){
99 » » » result = {};
100 » » » for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]);
101 » » } else {
102 » » » result = self.call(this, a);
103 » » }
104 » » return result;
105 » };
106 };
107
108 Function.prototype.extend = function(key, value){
109 » this[key] = value;
110 }.overloadSetter();
111
112 Function.prototype.implement = function(key, value){
113 » this.prototype[key] = value;
114 }.overloadSetter();
115
116 // From
117
118 var slice = Array.prototype.slice;
119
120 Function.from = function(item){
121 » return (typeOf(item) == 'function') ? item : function(){
122 » » return item;
123 » };
124 };
125
126 Array.from = function(item){
127 » if (item == null) return [];
128 » return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(it em) == 'array') ? item : slice.call(item) : [item];
129 };
130
131 Number.from = function(item){
132 » var number = parseFloat(item);
133 » return isFinite(number) ? number : null;
134 };
135
136 String.from = function(item){
137 » return item + '';
138 };
139
140 // hide, protect
141
142 Function.implement({
143
144 » hide: function(){
145 » » this.$hidden = true;
65 return this; 146 return this;
66 » }; 147 » },
67 148
68 » if (methods) object.implement(methods); 149 » protect: function(){
150 » » this.$protected = true;
151 » » return this;
152 » }
153
154 });
155
156 // Type
157
158 var Type = this.Type = function(name, object){
159 » if (name){
160 » » var lower = name.toLowerCase();
161 » » var typeCheck = function(item){
162 » » » return (typeOf(item) == lower);
163 » » };
164
165 » » Type['is' + name] = typeCheck;
166 » » if (object != null){
167 » » » object.prototype.$family = (function(){
168 » » » » return lower;
169 » » » }).hide();
170 » » » //<1.2compat>
171 » » » object.type = typeCheck;
172 » » » //</1.2compat>
173 » » }
174 » }
175
176 » if (object == null) return null;
177
178 » object.extend(this);
179 » object.$constructor = Type;
180 » object.prototype.$constructor = object;
69 181
70 return object; 182 return object;
71 }; 183 };
72 184
73 Native.genericize = function(object, property, check){ 185 var toString = Object.prototype.toString;
74 » if ((!check || !object[property]) && typeof object.prototype[property] = = 'function') object[property] = function(){ 186
75 » » var args = Array.prototype.slice.call(arguments); 187 Type.isEnumerable = function(item){
76 » » return object.prototype[property].apply(args.shift(), args); 188 » return (item != null && typeof item.length == 'number' && toString.call( item) != '[object Function]' );
77 » }; 189 };
78 }; 190
79 191 var hooks = {};
80 Native.implement = function(objects, properties){ 192
81 » for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(pro perties); 193 var hooksOf = function(object){
82 }; 194 » var type = typeOf(object.prototype);
83 195 » return hooks[type] || (hooks[type] = []);
84 Native.typize = function(object, family){ 196 };
85 » if (!object.type) object.type = function(item){ 197
86 » » return ($type(item) === family); 198 var implement = function(name, method){
87 » }; 199 » if (method && method.$hidden) return;
88 }; 200
89 201 » var hooks = hooksOf(this);
90 (function(){ 202
91 » var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Numb er': Number, 'RegExp': RegExp, 'String': String}; 203 » for (var i = 0; i < hooks.length; i++){
92 » for (var n in natives) new Native({name: n, initialize: natives[n], prot ect: true}); 204 » » var hook = hooks[i];
93 205 » » if (typeOf(hook) == 'type') implement.call(hook, name, method);
94 » var types = {'boolean': Boolean, 'native': Native, 'object': Object}; 206 » » else hook.call(this, name, method);
95 » for (var t in types) Native.typize(types[t], t); 207 » }
96 208
97 » var generics = { 209 » var previous = this.prototype[name];
98 » » 'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "pu sh", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valu eOf"], 210 » if (previous == null || !previous.$protected) this.prototype[name] = met hod;
99 » » 'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastInd exOf", "match", "replace", "search", "slice", "split", "substr", "substring", "t oLowerCase", "toUpperCase", "valueOf"] 211
100 » }; 212 » if (this[name] == null && typeOf(method) == 'function') extend.call(this , name, function(item){
101 » for (var g in generics){ 213 » » return method.apply(item, slice.call(arguments, 1));
102 » » for (var i = generics[g].length; i--;) Native.genericize(window[ g], generics[g][i], true); 214 » });
103 » }; 215 };
104 })(); 216
105 217 var extend = function(name, method){
106 var Hash = new Native({ 218 » if (method && method.$hidden) return;
107 219 » var previous = this[name];
108 » name: 'Hash', 220 » if (previous == null || !previous.$protected) this[name] = method;
109 221 };
110 » initialize: function(object){ 222
111 » » if ($type(object) == 'hash') object = $unlink(object.getClean()) ; 223 Type.implement({
112 » » for (var key in object) this[key] = object[key]; 224
225 » implement: implement.overloadSetter(),
226
227 » extend: extend.overloadSetter(),
228
229 » alias: function(name, existing){
230 » » implement.call(this, name, this.prototype[existing]);
231 » }.overloadSetter(),
232
233 » mirror: function(hook){
234 » » hooksOf(this).push(hook);
113 return this; 235 return this;
114 } 236 }
115 237
116 }); 238 });
117 239
240 new Type('Type', Type);
241
242 // Default Types
243
244 var force = function(name, object, methods){
245 var isType = (object != Object),
246 prototype = object.prototype;
247
248 if (isType) object = new Type(name, object);
249
250 for (var i = 0, l = methods.length; i < l; i++){
251 var key = methods[i],
252 generic = object[key],
253 proto = prototype[key];
254
255 if (generic) generic.protect();
256
257 if (isType && proto){
258 delete prototype[key];
259 prototype[key] = proto.protect();
260 }
261 }
262
263 if (isType) object.implement(prototype);
264
265 return force;
266 };
267
268 force('String', String, [
269 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'qu ote', 'replace', 'search',
270 'slice', 'split', 'substr', 'substring', 'trim', 'toLowerCase', 'toUpper Case'
271 ])('Array', Array, [
272 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat' , 'join', 'slice',
273 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', ' reduce', 'reduceRight'
274 ])('Number', Number, [
275 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision'
276 ])('Function', Function, [
277 'apply', 'call', 'bind'
278 ])('RegExp', RegExp, [
279 'exec', 'test'
280 ])('Object', Object, [
281 'create', 'defineProperty', 'defineProperties', 'keys',
282 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames',
283 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFr ozen'
284 ])('Date', Date, ['now']);
285
286 Object.extend = extend.overloadSetter();
287
288 Date.extend('now', function(){
289 return +(new Date);
290 });
291
292 new Type('Boolean', Boolean);
293
294 // fixes NaN returning as Number
295
296 Number.prototype.$family = function(){
297 return isFinite(this) ? 'number' : 'null';
298 }.hide();
299
300 // Number.random
301
302 Number.extend('random', function(min, max){
303 return Math.floor(Math.random() * (max - min + 1) + min);
304 });
305
306 // forEach, each
307
308 var hasOwnProperty = Object.prototype.hasOwnProperty;
309 Object.extend('forEach', function(object, fn, bind){
310 for (var key in object){
311 if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object);
312 }
313 });
314
315 Object.each = Object.forEach;
316
317 Array.implement({
318
319 forEach: function(fn, bind){
320 for (var i = 0, l = this.length; i < l; i++){
321 if (i in this) fn.call(bind, this[i], i, this);
322 }
323 },
324
325 each: function(fn, bind){
326 Array.forEach(this, fn, bind);
327 return this;
328 }
329
330 });
331
332 // Array & Object cloning, Object merging and appending
333
334 var cloneOf = function(item){
335 switch (typeOf(item)){
336 case 'array': return item.clone();
337 case 'object': return Object.clone(item);
338 default: return item;
339 }
340 };
341
342 Array.implement('clone', function(){
343 var i = this.length, clone = new Array(i);
344 while (i--) clone[i] = cloneOf(this[i]);
345 return clone;
346 });
347
348 var mergeOne = function(source, key, current){
349 switch (typeOf(current)){
350 case 'object':
351 if (typeOf(source[key]) == 'object') Object.merge(source [key], current);
352 else source[key] = Object.clone(current);
353 break;
354 case 'array': source[key] = current.clone(); break;
355 default: source[key] = current;
356 }
357 return source;
358 };
359
360 Object.extend({
361
362 merge: function(source, k, v){
363 if (typeOf(k) == 'string') return mergeOne(source, k, v);
364 for (var i = 1, l = arguments.length; i < l; i++){
365 var object = arguments[i];
366 for (var key in object) mergeOne(source, key, object[key ]);
367 }
368 return source;
369 },
370
371 clone: function(object){
372 var clone = {};
373 for (var key in object) clone[key] = cloneOf(object[key]);
374 return clone;
375 },
376
377 append: function(original){
378 for (var i = 1, l = arguments.length; i < l; i++){
379 var extended = arguments[i] || {};
380 for (var key in extended) original[key] = extended[key];
381 }
382 return original;
383 }
384
385 });
386
387 // Object-less types
388
389 ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(na me){
390 new Type(name);
391 });
392
393 // Unique ID
394
395 var UID = Date.now();
396
397 String.extend('uniqueID', function(){
398 return (UID++).toString(36);
399 });
400
401 //<1.2compat>
402
403 var Hash = this.Hash = new Type('Hash', function(object){
404 if (typeOf(object) == 'hash') object = Object.clone(object.getClean());
405 for (var key in object) this[key] = object[key];
406 return this;
407 });
408
118 Hash.implement({ 409 Hash.implement({
119 410
120 forEach: function(fn, bind){ 411 forEach: function(fn, bind){
121 » » for (var key in this){ 412 » » Object.forEach(this, fn, bind);
122 » » » if (this.hasOwnProperty(key)) fn.call(bind, this[key], k ey, this);
123 » » }
124 }, 413 },
125 414
126 getClean: function(){ 415 getClean: function(){
127 var clean = {}; 416 var clean = {};
128 for (var key in this){ 417 for (var key in this){
129 if (this.hasOwnProperty(key)) clean[key] = this[key]; 418 if (this.hasOwnProperty(key)) clean[key] = this[key];
130 } 419 }
131 return clean; 420 return clean;
132 }, 421 },
133 422
134 getLength: function(){ 423 getLength: function(){
135 var length = 0; 424 var length = 0;
136 for (var key in this){ 425 for (var key in this){
137 if (this.hasOwnProperty(key)) length++; 426 if (this.hasOwnProperty(key)) length++;
138 } 427 }
139 return length; 428 return length;
140 } 429 }
141 430
142 }); 431 });
143 432
144 Hash.alias('forEach', 'each'); 433 Hash.alias('each', 'forEach');
145 434
146 Array.implement({ 435 Object.type = Type.isObject;
147 436
148 » forEach: function(fn, bind){ 437 var Native = this.Native = function(properties){
149 » » for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[ i], i, this); 438 » return new Type(properties.name, properties.initialize);
150 » } 439 };
151 440
152 }); 441 Native.type = Type.type;
153 442
154 Array.alias('forEach', 'each'); 443 Native.implement = function(objects, methods){
155 444 » for (var i = 0; i < objects.length; i++) objects[i].implement(methods);
156 function $A(iterable){ 445 » return Native;
157 » if (iterable.item){ 446 };
158 » » var array = []; 447
159 » » for (var i = 0, l = iterable.length; i < l; i++) array[i] = iter able[i]; 448 var arrayType = Array.type;
160 » » return array; 449 Array.type = function(item){
161 » } 450 » return instanceOf(item, Array) || arrayType(item);
162 » return Array.prototype.slice.call(iterable); 451 };
163 }; 452
164 453 this.$A = function(item){
165 function $arguments(i){ 454 » return Array.from(item).slice();
455 };
456
457 this.$arguments = function(i){
166 return function(){ 458 return function(){
167 return arguments[i]; 459 return arguments[i];
168 }; 460 };
169 }; 461 };
170 462
171 function $chk(obj){ 463 this.$chk = function(obj){
172 return !!(obj || obj === 0); 464 return !!(obj || obj === 0);
173 }; 465 };
174 466
175 function $clear(timer){ 467 this.$clear = function(timer){
176 clearTimeout(timer); 468 clearTimeout(timer);
177 clearInterval(timer); 469 clearInterval(timer);
178 return null; 470 return null;
179 }; 471 };
180 472
181 function $defined(obj){ 473 this.$defined = function(obj){
182 » return (obj != undefined); 474 » return (obj != null);
183 }; 475 };
184 476
185 function $each(iterable, fn, bind){ 477 this.$each = function(iterable, fn, bind){
186 » var type = $type(iterable); 478 » var type = typeOf(iterable);
187 » ((type == 'arguments' || type == 'collection' || type == 'array') ? Arra y : Hash).each(iterable, fn, bind); 479 » ((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind);
188 }; 480 };
189 481
190 function $empty(){}; 482 this.$empty = function(){};
191 483
192 function $extend(original, extended){ 484 this.$extend = function(original, extended){
193 » for (var key in (extended || {})) original[key] = extended[key]; 485 » return Object.append(original, extended);
194 » return original; 486 };
195 }; 487
196 488 this.$H = function(object){
197 function $H(object){
198 return new Hash(object); 489 return new Hash(object);
199 }; 490 };
200 491
201 function $lambda(value){ 492 this.$merge = function(){
202 » return (typeof value == 'function') ? value : function(){ 493 » var args = Array.slice(arguments);
203 » » return value; 494 » args.unshift({});
204 » }; 495 » return Object.merge.apply(null, args);
205 }; 496 };
206 497
207 function $merge(){ 498 this.$lambda = Function.from;
208 » var mix = {}; 499 this.$mixin = Object.merge;
209 » for (var i = 0, l = arguments.length; i < l; i++){ 500 this.$random = Number.random;
210 » » var object = arguments[i]; 501 this.$splat = Array.from;
211 » » if ($type(object) != 'object') continue; 502 this.$time = Date.now;
212 » » for (var key in object){ 503
213 » » » var op = object[key], mp = mix[key]; 504 this.$type = function(object){
214 » » » mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $merge(mp, op) : $unlink(op); 505 » var type = typeOf(object);
215 » » } 506 » if (type == 'elements') return 'array';
216 » } 507 » return (type == 'null') ? false : type;
217 » return mix; 508 };
218 }; 509
219 510 this.$unlink = function(object){
220 function $pick(){ 511 » switch (typeOf(object)){
221 » for (var i = 0, l = arguments.length; i < l; i++){ 512 » » case 'object': return Object.clone(object);
222 » » if (arguments[i] != undefined) return arguments[i]; 513 » » case 'array': return Array.clone(object);
223 » } 514 » » case 'hash': return new Hash(object);
224 » return null;
225 };
226
227 function $random(min, max){
228 » return Math.floor(Math.random() * (max - min + 1) + min);
229 };
230
231 function $splat(obj){
232 » var type = $type(obj);
233 » return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : [];
234 };
235
236 var $time = Date.now || function(){
237 » return +new Date;
238 };
239
240 function $try(){
241 » for (var i = 0, l = arguments.length; i < l; i++){
242 » » try {
243 » » » return arguments[i]();
244 » » } catch(e){}
245 » }
246 » return null;
247 };
248
249 function $type(obj){
250 » if (obj == undefined) return false;
251 » if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name;
252 » if (obj.nodeName){
253 » » switch (obj.nodeType){
254 » » » case 1: return 'element';
255 » » » case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
256 » » }
257 » } else if (typeof obj.length == 'number'){
258 » » if (obj.callee) return 'arguments';
259 » » else if (obj.item) return 'collection';
260 » }
261 » return typeof obj;
262 };
263
264 function $unlink(object){
265 » var unlinked;
266 » switch ($type(object)){
267 » » case 'object':
268 » » » unlinked = {};
269 » » » for (var p in object) unlinked[p] = $unlink(object[p]);
270 » » break;
271 » » case 'hash':
272 » » » unlinked = new Hash(object);
273 » » break;
274 » » case 'array':
275 » » » unlinked = [];
276 » » » for (var i = 0, l = object.length; i < l; i++) unlinked[ i] = $unlink(object[i]);
277 » » break;
278 default: return object; 515 default: return object;
279 } 516 }
280 » return unlinked; 517 };
281 }; 518
519 //</1.2compat>
520
521 })();
282 522
283 523
284 /* 524 /*
285 Script: Browser.js 525 ---
286 » The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash. 526
287 527 name: Array
288 License: 528
289 » MIT-style license. 529 description: Contains Array Prototypes like each, contains, and erase.
530
531 license: MIT-style license.
532
533 requires: Type
534
535 provides: Array
536
537 ...
290 */ 538 */
291 539
292 var Browser = $merge({
293
294 Engine: {name: 'unknown', version: 0},
295
296 Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator .platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
297
298 Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
299
300 Plugins: {},
301
302 Engines: {
303
304 presto: function(){
305 return (!window.opera) ? false : ((arguments.callee.call er) ? 960 : ((document.getElementsByClassName) ? 950 : 925));
306 },
307
308 trident: function(){
309 return (!window.ActiveXObject) ? false : ((window.XMLHtt pRequest) ? 5 : 4);
310 },
311
312 webkit: function(){
313 return (navigator.taintEnabled) ? false : ((Browser.Feat ures.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);
314 },
315
316 gecko: function(){
317 return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18);
318 }
319
320 }
321
322 }, Browser || {});
323
324 Browser.Platform[Browser.Platform.name] = true;
325
326 Browser.detect = function(){
327
328 for (var engine in this.Engines){
329 var version = this.Engines[engine]();
330 if (version){
331 this.Engine = {name: engine, version: version};
332 this.Engine[engine] = this.Engine[engine + version] = tr ue;
333 break;
334 }
335 }
336
337 return {name: engine, version: version};
338
339 };
340
341 Browser.detect();
342
343 Browser.Request = function(){
344 return $try(function(){
345 return new XMLHttpRequest();
346 }, function(){
347 return new ActiveXObject('MSXML2.XMLHTTP');
348 });
349 };
350
351 Browser.Features.xhr = !!(Browser.Request());
352
353 Browser.Plugins.Flash = (function(){
354 var version = ($try(function(){
355 return navigator.plugins['Shockwave Flash'].description;
356 }, function(){
357 return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVar iable('$version');
358 }) || '0 r0').match(/\d+/g);
359 return {version: parseInt(version[0] || 0 + '.' + version[1] || 0), buil d: parseInt(version[2] || 0)};
360 })();
361
362 function $exec(text){
363 if (!text) return text;
364 if (window.execScript){
365 window.execScript(text);
366 } else {
367 var script = document.createElement('script');
368 script.setAttribute('type', 'text/javascript');
369 script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text;
370 document.head.appendChild(script);
371 document.head.removeChild(script);
372 }
373 return text;
374 };
375
376 Native.UID = 1;
377
378 var $uid = (Browser.Engine.trident) ? function(item){
379 return (item.uid || (item.uid = [Native.UID++]))[0];
380 } : function(item){
381 return item.uid || (item.uid = Native.UID++);
382 };
383
384 var Window = new Native({
385
386 name: 'Window',
387
388 legacy: (Browser.Engine.trident) ? null: window.Window,
389
390 initialize: function(win){
391 $uid(win);
392 if (!win.Element){
393 win.Element = $empty;
394 if (Browser.Engine.webkit) win.document.createElement("i frame"); //fixes safari 2
395 win.Element.prototype = (Browser.Engine.webkit) ? window ["[[DOMElement.prototype]]"] : {};
396 }
397 win.document.window = win;
398 return $extend(win, Window.Prototype);
399 },
400
401 afterImplement: function(property, value){
402 window[property] = Window.Prototype[property] = value;
403 }
404
405 });
406
407 Window.Prototype = {$family: {name: 'window'}};
408
409 new Window(window);
410
411 var Document = new Native({
412
413 name: 'Document',
414
415 legacy: (Browser.Engine.trident) ? null: window.Document,
416
417 initialize: function(doc){
418 $uid(doc);
419 doc.head = doc.getElementsByTagName('head')[0];
420 doc.html = doc.getElementsByTagName('html')[0];
421 if (Browser.Engine.trident && Browser.Engine.version <= 4) $try( function(){
422 doc.execCommand("BackgroundImageCache", false, true);
423 });
424 if (Browser.Engine.trident) doc.window.attachEvent('onunload', f unction() {
425 doc.window.detachEvent('onunload', arguments.callee);
426 doc.head = doc.html = doc.window = null;
427 });
428 return $extend(doc, Document.Prototype);
429 },
430
431 afterImplement: function(property, value){
432 document[property] = Document.Prototype[property] = value;
433 }
434
435 });
436
437 Document.Prototype = {$family: {name: 'document'}};
438
439 new Document(document);
440
441
442 /*
443 Script: Array.js
444 Contains Array Prototypes like each, contains, and erase.
445
446 License:
447 MIT-style license.
448 */
449
450 Array.implement({ 540 Array.implement({
451 541
542 /*<!ES5>*/
452 every: function(fn, bind){ 543 every: function(fn, bind){
453 » » for (var i = 0, l = this.length; i < l; i++){ 544 » » for (var i = 0, l = this.length >>> 0; i < l; i++){
454 » » » if (!fn.call(bind, this[i], i, this)) return false; 545 » » » if ((i in this) && !fn.call(bind, this[i], i, this)) ret urn false;
455 } 546 }
456 return true; 547 return true;
457 }, 548 },
458 549
459 filter: function(fn, bind){ 550 filter: function(fn, bind){
460 var results = []; 551 var results = [];
461 » » for (var i = 0, l = this.length; i < l; i++){ 552 » » for (var i = 0, l = this.length >>> 0; i < l; i++){
462 » » » if (fn.call(bind, this[i], i, this)) results.push(this[i ]); 553 » » » if ((i in this) && fn.call(bind, this[i], i, this)) resu lts.push(this[i]);
463 } 554 }
464 return results; 555 return results;
465 }, 556 },
466 557
467 clean: function() {
468 return this.filter($defined);
469 },
470
471 indexOf: function(item, from){ 558 indexOf: function(item, from){
472 » » var len = this.length; 559 » » var length = this.length >>> 0;
473 » » for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ 560 » » for (var i = (from < 0) ? Math.max(0, length + from) : from || 0 ; i < length; i++){
474 if (this[i] === item) return i; 561 if (this[i] === item) return i;
475 } 562 }
476 return -1; 563 return -1;
477 }, 564 },
478 565
479 map: function(fn, bind){ 566 map: function(fn, bind){
480 » » var results = []; 567 » » var length = this.length >>> 0, results = Array(length);
481 » » for (var i = 0, l = this.length; i < l; i++) results[i] = fn.cal l(bind, this[i], i, this); 568 » » for (var i = 0; i < length; i++){
569 » » » if (i in this) results[i] = fn.call(bind, this[i], i, th is);
570 » » }
482 return results; 571 return results;
483 }, 572 },
484 573
485 some: function(fn, bind){ 574 some: function(fn, bind){
486 » » for (var i = 0, l = this.length; i < l; i++){ 575 » » for (var i = 0, l = this.length >>> 0; i < l; i++){
487 » » » if (fn.call(bind, this[i], i, this)) return true; 576 » » » if ((i in this) && fn.call(bind, this[i], i, this)) retu rn true;
488 } 577 }
489 return false; 578 return false;
490 }, 579 },
580 /*</!ES5>*/
581
582 clean: function(){
583 return this.filter(function(item){
584 return item != null;
585 });
586 },
587
588 invoke: function(methodName){
589 var args = Array.slice(arguments, 1);
590 return this.map(function(item){
591 return item[methodName].apply(item, args);
592 });
593 },
491 594
492 associate: function(keys){ 595 associate: function(keys){
493 var obj = {}, length = Math.min(this.length, keys.length); 596 var obj = {}, length = Math.min(this.length, keys.length);
494 for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; 597 for (var i = 0; i < length; i++) obj[keys[i]] = this[i];
495 return obj; 598 return obj;
496 }, 599 },
497 600
498 link: function(object){ 601 link: function(object){
499 var result = {}; 602 var result = {};
500 for (var i = 0, l = this.length; i < l; i++){ 603 for (var i = 0, l = this.length; i < l; i++){
501 for (var key in object){ 604 for (var key in object){
502 if (object[key](this[i])){ 605 if (object[key](this[i])){
503 result[key] = this[i]; 606 result[key] = this[i];
504 delete object[key]; 607 delete object[key];
505 break; 608 break;
506 } 609 }
507 } 610 }
508 } 611 }
509 return result; 612 return result;
510 }, 613 },
511 614
512 contains: function(item, from){ 615 contains: function(item, from){
513 return this.indexOf(item, from) != -1; 616 return this.indexOf(item, from) != -1;
514 }, 617 },
515 618
516 » extend: function(array){ 619 » append: function(array){
517 » » for (var i = 0, j = array.length; i < j; i++) this.push(array[i] ); 620 » » this.push.apply(this, array);
518 return this; 621 return this;
519 }, 622 },
520 623
521 getLast: function(){ 624 getLast: function(){
522 return (this.length) ? this[this.length - 1] : null; 625 return (this.length) ? this[this.length - 1] : null;
523 }, 626 },
524 627
525 getRandom: function(){ 628 getRandom: function(){
526 » » return (this.length) ? this[$random(0, this.length - 1)] : null; 629 » » return (this.length) ? this[Number.random(0, this.length - 1)] : null;
527 }, 630 },
528 631
529 include: function(item){ 632 include: function(item){
530 if (!this.contains(item)) this.push(item); 633 if (!this.contains(item)) this.push(item);
531 return this; 634 return this;
532 }, 635 },
533 636
534 combine: function(array){ 637 combine: function(array){
535 for (var i = 0, l = array.length; i < l; i++) this.include(array [i]); 638 for (var i = 0, l = array.length; i < l; i++) this.include(array [i]);
536 return this; 639 return this;
537 }, 640 },
538 641
539 erase: function(item){ 642 erase: function(item){
540 » » for (var i = this.length; i--; i){ 643 » » for (var i = this.length; i--;){
541 if (this[i] === item) this.splice(i, 1); 644 if (this[i] === item) this.splice(i, 1);
542 } 645 }
543 return this; 646 return this;
544 }, 647 },
545 648
546 empty: function(){ 649 empty: function(){
547 this.length = 0; 650 this.length = 0;
548 return this; 651 return this;
549 }, 652 },
550 653
551 flatten: function(){ 654 flatten: function(){
552 var array = []; 655 var array = [];
553 for (var i = 0, l = this.length; i < l; i++){ 656 for (var i = 0, l = this.length; i < l; i++){
554 » » » var type = $type(this[i]); 657 » » » var type = typeOf(this[i]);
555 » » » if (!type) continue; 658 » » » if (type == 'null') continue;
556 » » » array = array.concat((type == 'array' || type == 'collec tion' || type == 'arguments') ? Array.flatten(this[i]) : this[i]); 659 » » » array = array.concat((type == 'array' || type == 'collec tion' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this [i]) : this[i]);
557 } 660 }
558 return array; 661 return array;
559 }, 662 },
560 663
664 pick: function(){
665 for (var i = 0, l = this.length; i < l; i++){
666 if (this[i] != null) return this[i];
667 }
668 return null;
669 },
670
561 hexToRgb: function(array){ 671 hexToRgb: function(array){
562 if (this.length != 3) return null; 672 if (this.length != 3) return null;
563 var rgb = this.map(function(value){ 673 var rgb = this.map(function(value){
564 if (value.length == 1) value += value; 674 if (value.length == 1) value += value;
565 return value.toInt(16); 675 return value.toInt(16);
566 }); 676 });
567 return (array) ? rgb : 'rgb(' + rgb + ')'; 677 return (array) ? rgb : 'rgb(' + rgb + ')';
568 }, 678 },
569 679
570 rgbToHex: function(array){ 680 rgbToHex: function(array){
571 if (this.length < 3) return null; 681 if (this.length < 3) return null;
572 if (this.length == 4 && this[3] == 0 && !array) return 'transpar ent'; 682 if (this.length == 4 && this[3] == 0 && !array) return 'transpar ent';
573 var hex = []; 683 var hex = [];
574 for (var i = 0; i < 3; i++){ 684 for (var i = 0; i < 3; i++){
575 var bit = (this[i] - 0).toString(16); 685 var bit = (this[i] - 0).toString(16);
576 hex.push((bit.length == 1) ? '0' + bit : bit); 686 hex.push((bit.length == 1) ? '0' + bit : bit);
577 } 687 }
578 return (array) ? hex : '#' + hex.join(''); 688 return (array) ? hex : '#' + hex.join('');
579 } 689 }
580 690
581 }); 691 });
582 692
693 //<1.2compat>
694
695 Array.alias('extend', 'append');
696
697 var $pick = function(){
698 return Array.from(arguments).pick();
699 };
700
701 //</1.2compat>
702
583 703
584 /* 704 /*
585 Script: Function.js 705 ---
586 » Contains Function Prototypes like create, bind, pass, and delay.
587 706
588 License: 707 name: String
589 » MIT-style license. 708
709 description: Contains String Prototypes like camelCase, capitalize, test, and to Int.
710
711 license: MIT-style license.
712
713 requires: Type
714
715 provides: String
716
717 ...
590 */ 718 */
591 719
592 Function.implement({ 720 String.implement({
593 721
594 » extend: function(properties){ 722 » test: function(regex, params){
595 » » for (var property in properties) this[property] = properties[pro perty]; 723 » » return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + re gex, params)).test(this);
596 » » return this;
597 }, 724 },
598 725
599 » create: function(options){ 726 » contains: function(string, separator){
600 » » var self = this; 727 » » return (separator) ? (separator + this + separator).indexOf(sepa rator + string + separator) > -1 : String(this).indexOf(string) > -1;
601 » » options = options || {};
602 » » return function(event){
603 » » » var args = options.arguments;
604 » » » args = (args != undefined) ? $splat(args) : Array.slice( arguments, (options.event) ? 1 : 0);
605 » » » if (options.event) args = [event || window.event].extend (args);
606 » » » var returns = function(){
607 » » » » return self.apply(options.bind || null, args);
608 » » » };
609 » » » if (options.delay) return setTimeout(returns, options.de lay);
610 » » » if (options.periodical) return setInterval(returns, opti ons.periodical);
611 » » » if (options.attempt) return $try(returns);
612 » » » return returns();
613 » » };
614 }, 728 },
615 729
616 » run: function(args, bind){ 730 » trim: function(){
617 » » return this.apply(bind, $splat(args)); 731 » » return String(this).replace(/^\s+|\s+$/g, '');
618 }, 732 },
619 733
620 » pass: function(args, bind){ 734 » clean: function(){
621 » » return this.create({bind: bind, arguments: args}); 735 » » return String(this).replace(/\s+/g, ' ').trim();
622 }, 736 },
623 737
624 » bind: function(bind, args){ 738 » camelCase: function(){
625 » » return this.create({bind: bind, arguments: args}); 739 » » return String(this).replace(/-\D/g, function(match){
740 » » » return match.charAt(1).toUpperCase();
741 » » });
626 }, 742 },
627 743
628 » bindWithEvent: function(bind, args){ 744 » hyphenate: function(){
629 » » return this.create({bind: bind, arguments: args, event: true}); 745 » » return String(this).replace(/[A-Z]/g, function(match){
746 » » » return ('-' + match.charAt(0).toLowerCase());
747 » » });
630 }, 748 },
631 749
632 » attempt: function(args, bind){ 750 » capitalize: function(){
633 » » return this.create({bind: bind, arguments: args, attempt: true}) (); 751 » » return String(this).replace(/\b[a-z]/g, function(match){
752 » » » return match.toUpperCase();
753 » » });
634 }, 754 },
635 755
636 » delay: function(delay, bind, args){ 756 » escapeRegExp: function(){
637 » » return this.create({bind: bind, arguments: args, delay: delay})( ); 757 » » return String(this).replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
638 }, 758 },
639 759
640 » periodical: function(periodical, bind, args){ 760 » toInt: function(base){
641 » » return this.create({bind: bind, arguments: args, periodical: per iodical})(); 761 » » return parseInt(this, base || 10);
762 » },
763
764 » toFloat: function(){
765 » » return parseFloat(this);
766 » },
767
768 » hexToRgb: function(array){
769 » » var hex = String(this).match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
770 » » return (hex) ? hex.slice(1).hexToRgb(array) : null;
771 » },
772
773 » rgbToHex: function(array){
774 » » var rgb = String(this).match(/\d{1,3}/g);
775 » » return (rgb) ? rgb.rgbToHex(array) : null;
776 » },
777
778 » substitute: function(object, regexp){
779 » » return String(this).replace(regexp || (/\\?\{([^{}]+)\}/g), func tion(match, name){
780 » » » if (match.charAt(0) == '\\') return match.slice(1);
781 » » » return (object[name] != null) ? object[name] : '';
782 » » });
642 } 783 }
643 784
644 }); 785 });
645 786
646 787
647 /* 788 /*
648 Script: Number.js 789 ---
649 » Contains Number Prototypes like limit, round, times, and ceil.
650 790
651 License: 791 name: Number
652 » MIT-style license. 792
793 description: Contains Number Prototypes like limit, round, times, and ceil.
794
795 license: MIT-style license.
796
797 requires: Type
798
799 provides: Number
800
801 ...
653 */ 802 */
654 803
655 Number.implement({ 804 Number.implement({
656 805
657 limit: function(min, max){ 806 limit: function(min, max){
658 return Math.min(max, Math.max(min, this)); 807 return Math.min(max, Math.max(min, this));
659 }, 808 },
660 809
661 round: function(precision){ 810 round: function(precision){
662 » » precision = Math.pow(10, precision || 0); 811 » » precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0);
663 return Math.round(this * precision) / precision; 812 return Math.round(this * precision) / precision;
664 }, 813 },
665 814
666 times: function(fn, bind){ 815 times: function(fn, bind){
667 for (var i = 0; i < this; i++) fn.call(bind, i, this); 816 for (var i = 0; i < this; i++) fn.call(bind, i, this);
668 }, 817 },
669 818
670 toFloat: function(){ 819 toFloat: function(){
671 return parseFloat(this); 820 return parseFloat(this);
672 }, 821 },
673 822
674 toInt: function(base){ 823 toInt: function(base){
675 return parseInt(this, base || 10); 824 return parseInt(this, base || 10);
676 } 825 }
677 826
678 }); 827 });
679 828
680 Number.alias('times', 'each'); 829 Number.alias('each', 'times');
681 830
682 (function(math){ 831 (function(math){
683 var methods = {}; 832 var methods = {};
684 math.each(function(name){ 833 math.each(function(name){
685 if (!Number[name]) methods[name] = function(){ 834 if (!Number[name]) methods[name] = function(){
686 » » » return Math[name].apply(null, [this].concat($A(arguments ))); 835 » » » return Math[name].apply(null, [this].concat(Array.from(a rguments)));
687 }; 836 };
688 }); 837 });
689 Number.implement(methods); 838 Number.implement(methods);
690 })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log' , 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); 839 })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log' , 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']);
691 840
692 841
693 /* 842 /*
694 Script: String.js 843 ---
695 » Contains String Prototypes like camelCase, capitalize, test, and toInt. 844
696 845 name: Function
697 License: 846
698 » MIT-style license. 847 description: Contains Function Prototypes like create, bind, pass, and delay.
848
849 license: MIT-style license.
850
851 requires: Type
852
853 provides: Function
854
855 ...
699 */ 856 */
700 857
701 String.implement({ 858 Function.extend({
702 859
703 » test: function(regex, params){ 860 » attempt: function(){
704 » » return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); 861 » » for (var i = 0, l = arguments.length; i < l; i++){
705 » }, 862 » » » try {
706 863 » » » » return arguments[i]();
707 » contains: function(string, separator){ 864 » » » } catch (e){}
708 » » return (separator) ? (separator + this + separator).indexOf(sepa rator + string + separator) > -1 : this.indexOf(string) > -1; 865 » » }
709 » }, 866 » » return null;
710 867 » }
711 » trim: function(){ 868
712 » » return this.replace(/^\s+|\s+$/g, ''); 869 });
713 » }, 870
714 871 Function.implement({
715 » clean: function(){ 872
716 » » return this.replace(/\s+/g, ' ').trim(); 873 » attempt: function(args, bind){
717 » }, 874 » » try {
718 875 » » » return this.apply(bind, Array.from(args));
719 » camelCase: function(){ 876 » » } catch (e){}
720 » » return this.replace(/-\D/g, function(match){ 877
721 » » » return match.charAt(1).toUpperCase(); 878 » » return null;
879 » },
880
881 » /*<!ES5-bind>*/
882 » bind: function(that){
883 » » var self = this,
884 » » » args = arguments.length > 1 ? Array.slice(arguments, 1) : null,
885 » » » F = function(){};
886
887 » » var bound = function(){
888 » » » var context = that, length = arguments.length;
889 » » » if (this instanceof bound){
890 » » » » F.prototype = self.prototype;
891 » » » » context = new F;
892 » » » }
893 » » » var result = (!args && !length)
894 » » » » ? self.call(context)
895 » » » » : self.apply(context, args && length ? args.conc at(Array.slice(arguments)) : args || arguments);
896 » » » return context == that ? result : context;
897 » » };
898 » » return bound;
899 » },
900 » /*</!ES5-bind>*/
901
902 » pass: function(args, bind){
903 » » var self = this;
904 » » if (args != null) args = Array.from(args);
905 » » return function(){
906 » » » return self.apply(bind, args || arguments);
907 » » };
908 » },
909
910 » delay: function(delay, bind, args){
911 » » return setTimeout(this.pass((args == null ? [] : args), bind), d elay);
912 » },
913
914 » periodical: function(periodical, bind, args){
915 » » return setInterval(this.pass((args == null ? [] : args), bind), periodical);
916 » }
917
918 });
919
920 //<1.2compat>
921
922 delete Function.prototype.bind;
923
924 Function.implement({
925
926 » create: function(options){
927 » » var self = this;
928 » » options = options || {};
929 » » return function(event){
930 » » » var args = options.arguments;
931 » » » args = (args != null) ? Array.from(args) : Array.slice(a rguments, (options.event) ? 1 : 0);
932 » » » if (options.event) args = [event || window.event].extend (args);
933 » » » var returns = function(){
934 » » » » return self.apply(options.bind || null, args);
935 » » » };
936 » » » if (options.delay) return setTimeout(returns, options.de lay);
937 » » » if (options.periodical) return setInterval(returns, opti ons.periodical);
938 » » » if (options.attempt) return Function.attempt(returns);
939 » » » return returns();
940 » » };
941 » },
942
943 » bind: function(bind, args){
944 » » var self = this;
945 » » if (args != null) args = Array.from(args);
946 » » return function(){
947 » » » return self.apply(bind, args || arguments);
948 » » };
949 » },
950
951 » bindWithEvent: function(bind, args){
952 » » var self = this;
953 » » if (args != null) args = Array.from(args);
954 » » return function(event){
955 » » » return self.apply(bind, (args == null) ? arguments : [ev ent].concat(args));
956 » » };
957 » },
958
959 » run: function(args, bind){
960 » » return this.apply(bind, Array.from(args));
961 » }
962
963 });
964
965 if (Object.create == Function.prototype.create) Object.create = null;
966
967 var $try = Function.attempt;
968
969 //</1.2compat>
970
971
972 /*
973 ---
974
975 name: Object
976
977 description: Object generic methods
978
979 license: MIT-style license.
980
981 requires: Type
982
983 provides: [Object, Hash]
984
985 ...
986 */
987
988 (function(){
989
990 var hasOwnProperty = Object.prototype.hasOwnProperty;
991
992 Object.extend({
993
994 » subset: function(object, keys){
995 » » var results = {};
996 » » for (var i = 0, l = keys.length; i < l; i++){
997 » » » var k = keys[i];
998 » » » if (k in object) results[k] = object[k];
999 » » }
1000 » » return results;
1001 » },
1002
1003 » map: function(object, fn, bind){
1004 » » var results = {};
1005 » » for (var key in object){
1006 » » » if (hasOwnProperty.call(object, key)) results[key] = fn. call(bind, object[key], key, object);
1007 » » }
1008 » » return results;
1009 » },
1010
1011 » filter: function(object, fn, bind){
1012 » » var results = {};
1013 » » for (var key in object){
1014 » » » var value = object[key];
1015 » » » if (hasOwnProperty.call(object, key) && fn.call(bind, va lue, key, object)) results[key] = value;
1016 » » }
1017 » » return results;
1018 » },
1019
1020 » every: function(object, fn, bind){
1021 » » for (var key in object){
1022 » » » if (hasOwnProperty.call(object, key) && !fn.call(bind, o bject[key], key)) return false;
1023 » » }
1024 » » return true;
1025 » },
1026
1027 » some: function(object, fn, bind){
1028 » » for (var key in object){
1029 » » » if (hasOwnProperty.call(object, key) && fn.call(bind, ob ject[key], key)) return true;
1030 » » }
1031 » » return false;
1032 » },
1033
1034 » keys: function(object){
1035 » » var keys = [];
1036 » » for (var key in object){
1037 » » » if (hasOwnProperty.call(object, key)) keys.push(key);
1038 » » }
1039 » » return keys;
1040 » },
1041
1042 » values: function(object){
1043 » » var values = [];
1044 » » for (var key in object){
1045 » » » if (hasOwnProperty.call(object, key)) values.push(object [key]);
1046 » » }
1047 » » return values;
1048 » },
1049
1050 » getLength: function(object){
1051 » » return Object.keys(object).length;
1052 » },
1053
1054 » keyOf: function(object, value){
1055 » » for (var key in object){
1056 » » » if (hasOwnProperty.call(object, key) && object[key] === value) return key;
1057 » » }
1058 » » return null;
1059 » },
1060
1061 » contains: function(object, value){
1062 » » return Object.keyOf(object, value) != null;
1063 » },
1064
1065 » toQueryString: function(object, base){
1066 » » var queryString = [];
1067
1068 » » Object.each(object, function(value, key){
1069 » » » if (base) key = base + '[' + key + ']';
1070 » » » var result;
1071 » » » switch (typeOf(value)){
1072 » » » » case 'object': result = Object.toQueryString(val ue, key); break;
1073 » » » » case 'array':
1074 » » » » » var qs = {};
1075 » » » » » value.each(function(val, i){
1076 » » » » » » qs[i] = val;
1077 » » » » » });
1078 » » » » » result = Object.toQueryString(qs, key);
1079 » » » » break;
1080 » » » » default: result = key + '=' + encodeURIComponent (value);
1081 » » » }
1082 » » » if (value != null) queryString.push(result);
722 }); 1083 });
723 » }, 1084
724 1085 » » return queryString.join('&');
725 » hyphenate: function(){ 1086 » }
726 » » return this.replace(/[A-Z]/g, function(match){ 1087
727 » » » return ('-' + match.charAt(0).toLowerCase()); 1088 });
728 » » }); 1089
729 » }, 1090 })();
730 1091
731 » capitalize: function(){ 1092 //<1.2compat>
732 » » return this.replace(/\b[a-z]/g, function(match){
733 » » » return match.toUpperCase();
734 » » });
735 » },
736
737 » escapeRegExp: function(){
738 » » return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1');
739 » },
740
741 » toInt: function(base){
742 » » return parseInt(this, base || 10);
743 » },
744
745 » toFloat: function(){
746 » » return parseFloat(this);
747 » },
748
749 » hexToRgb: function(array){
750 » » var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
751 » » return (hex) ? hex.slice(1).hexToRgb(array) : null;
752 » },
753
754 » rgbToHex: function(array){
755 » » var rgb = this.match(/\d{1,3}/g);
756 » » return (rgb) ? rgb.rgbToHex(array) : null;
757 » },
758
759 » stripScripts: function(option){
760 » » var scripts = '';
761 » » var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, f unction(){
762 » » » scripts += arguments[1] + '\n';
763 » » » return '';
764 » » });
765 » » if (option === true) $exec(scripts);
766 » » else if ($type(option) == 'function') option(scripts, text);
767 » » return text;
768 » },
769
770 » substitute: function(object, regexp){
771 » » return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(mat ch, name){
772 » » » if (match.charAt(0) == '\\') return match.slice(1);
773 » » » return (object[name] != undefined) ? object[name] : '';
774 » » });
775 » }
776
777 });
778
779
780 /*
781 Script: Hash.js
782 » Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects.
783
784 License:
785 » MIT-style license.
786 */
787 1093
788 Hash.implement({ 1094 Hash.implement({
789 1095
790 has: Object.prototype.hasOwnProperty, 1096 has: Object.prototype.hasOwnProperty,
791 1097
792 keyOf: function(value){ 1098 keyOf: function(value){
793 » » for (var key in this){ 1099 » » return Object.keyOf(this, value);
794 » » » if (this.hasOwnProperty(key) && this[key] === value) ret urn key;
795 » » }
796 » » return null;
797 }, 1100 },
798 1101
799 hasValue: function(value){ 1102 hasValue: function(value){
800 » » return (Hash.keyOf(this, value) !== null); 1103 » » return Object.contains(this, value);
801 }, 1104 },
802 1105
803 extend: function(properties){ 1106 extend: function(properties){
804 » » Hash.each(properties, function(value, key){ 1107 » » Hash.each(properties || {}, function(value, key){
805 Hash.set(this, key, value); 1108 Hash.set(this, key, value);
806 }, this); 1109 }, this);
807 return this; 1110 return this;
808 }, 1111 },
809 1112
810 combine: function(properties){ 1113 combine: function(properties){
811 » » Hash.each(properties, function(value, key){ 1114 » » Hash.each(properties || {}, function(value, key){
812 Hash.include(this, key, value); 1115 Hash.include(this, key, value);
813 }, this); 1116 }, this);
814 return this; 1117 return this;
815 }, 1118 },
816 1119
817 erase: function(key){ 1120 erase: function(key){
818 if (this.hasOwnProperty(key)) delete this[key]; 1121 if (this.hasOwnProperty(key)) delete this[key];
819 return this; 1122 return this;
820 }, 1123 },
821 1124
822 get: function(key){ 1125 get: function(key){
823 return (this.hasOwnProperty(key)) ? this[key] : null; 1126 return (this.hasOwnProperty(key)) ? this[key] : null;
824 }, 1127 },
825 1128
826 set: function(key, value){ 1129 set: function(key, value){
827 if (!this[key] || this.hasOwnProperty(key)) this[key] = value; 1130 if (!this[key] || this.hasOwnProperty(key)) this[key] = value;
828 return this; 1131 return this;
829 }, 1132 },
830 1133
831 empty: function(){ 1134 empty: function(){
832 Hash.each(this, function(value, key){ 1135 Hash.each(this, function(value, key){
833 delete this[key]; 1136 delete this[key];
834 }, this); 1137 }, this);
835 return this; 1138 return this;
836 }, 1139 },
837 1140
838 include: function(key, value){ 1141 include: function(key, value){
839 » » var k = this[key]; 1142 » » if (this[key] == null) this[key] = value;
840 » » if (k == undefined) this[key] = value;
841 return this; 1143 return this;
842 }, 1144 },
843 1145
844 map: function(fn, bind){ 1146 map: function(fn, bind){
845 » » var results = new Hash; 1147 » » return new Hash(Object.map(this, fn, bind));
846 » » Hash.each(this, function(value, key){
847 » » » results.set(key, fn.call(bind, value, key, this));
848 » » }, this);
849 » » return results;
850 }, 1148 },
851 1149
852 filter: function(fn, bind){ 1150 filter: function(fn, bind){
853 » » var results = new Hash; 1151 » » return new Hash(Object.filter(this, fn, bind));
854 » » Hash.each(this, function(value, key){
855 » » » if (fn.call(bind, value, key, this)) results.set(key, va lue);
856 » » }, this);
857 » » return results;
858 }, 1152 },
859 1153
860 every: function(fn, bind){ 1154 every: function(fn, bind){
861 » » for (var key in this){ 1155 » » return Object.every(this, fn, bind);
862 » » » if (this.hasOwnProperty(key) && !fn.call(bind, this[key] , key)) return false; 1156 » },
1157
1158 » some: function(fn, bind){
1159 » » return Object.some(this, fn, bind);
1160 » },
1161
1162 » getKeys: function(){
1163 » » return Object.keys(this);
1164 » },
1165
1166 » getValues: function(){
1167 » » return Object.values(this);
1168 » },
1169
1170 » toQueryString: function(base){
1171 » » return Object.toQueryString(this, base);
1172 » }
1173
1174 });
1175
1176 Hash.extend = Object.append;
1177
1178 Hash.alias({indexOf: 'keyOf', contains: 'hasValue'});
1179
1180 //</1.2compat>
1181
1182
1183 /*
1184 ---
1185
1186 name: Browser
1187
1188 description: The Browser Object. Contains Browser initialization, Window and Doc ument, and the Browser Hash.
1189
1190 license: MIT-style license.
1191
1192 requires: [Array, Function, Number, String]
1193
1194 provides: [Browser, Window, Document]
1195
1196 ...
1197 */
1198
1199 (function(){
1200
1201 var document = this.document;
1202 var window = document.window = this;
1203
1204 var UID = 1;
1205
1206 this.$uid = (window.ActiveXObject) ? function(item){
1207 » return (item.uid || (item.uid = [UID++]))[0];
1208 } : function(item){
1209 » return item.uid || (item.uid = UID++);
1210 };
1211
1212 $uid(window);
1213 $uid(document);
1214
1215 var ua = navigator.userAgent.toLowerCase(),
1216 » platform = navigator.platform.toLowerCase(),
1217 » UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(s afari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0],
1218 » mode = UA[1] == 'ie' && document.documentMode;
1219
1220 var Browser = this.Browser = {
1221
1222 » extend: Function.prototype.extend,
1223
1224 » name: (UA[1] == 'version') ? UA[3] : UA[1],
1225
1226 » version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]) ,
1227
1228 » Platform: {
1229 » » name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos |android)/) || platform.match(/mac|win|linux/) || ['other'])[0]
1230 » },
1231
1232 » Features: {
1233 » » xpath: !!(document.evaluate),
1234 » » air: !!(window.runtime),
1235 » » query: !!(document.querySelector),
1236 » » json: !!(window.JSON)
1237 » },
1238
1239 » Plugins: {}
1240
1241 };
1242
1243 Browser[Browser.name] = true;
1244 Browser[Browser.name + parseInt(Browser.version, 10)] = true;
1245 Browser.Platform[Browser.Platform.name] = true;
1246
1247 // Request
1248
1249 Browser.Request = (function(){
1250
1251 » var XMLHTTP = function(){
1252 » » return new XMLHttpRequest();
1253 » };
1254
1255 » var MSXML2 = function(){
1256 » » return new ActiveXObject('MSXML2.XMLHTTP');
1257 » };
1258
1259 » var MSXML = function(){
1260 » » return new ActiveXObject('Microsoft.XMLHTTP');
1261 » };
1262
1263 » return Function.attempt(function(){
1264 » » XMLHTTP();
1265 » » return XMLHTTP;
1266 » }, function(){
1267 » » MSXML2();
1268 » » return MSXML2;
1269 » }, function(){
1270 » » MSXML();
1271 » » return MSXML;
1272 » });
1273
1274 })();
1275
1276 Browser.Features.xhr = !!(Browser.Request);
1277
1278 // Flash detection
1279
1280 var version = (Function.attempt(function(){
1281 » return navigator.plugins['Shockwave Flash'].description;
1282 }, function(){
1283 » return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$ version');
1284 }) || '0 r0').match(/\d+/g);
1285
1286 Browser.Plugins.Flash = {
1287 » version: Number(version[0] || '0.' + version[1]) || 0,
1288 » build: Number(version[2]) || 0
1289 };
1290
1291 // String scripts
1292
1293 Browser.exec = function(text){
1294 » if (!text) return text;
1295 » if (window.execScript){
1296 » » window.execScript(text);
1297 » } else {
1298 » » var script = document.createElement('script');
1299 » » script.setAttribute('type', 'text/javascript');
1300 » » script.text = text;
1301 » » document.head.appendChild(script);
1302 » » document.head.removeChild(script);
1303 » }
1304 » return text;
1305 };
1306
1307 String.implement('stripScripts', function(exec){
1308 » var scripts = '';
1309 » var text = this.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function( all, code){
1310 » » scripts += code + '\n';
1311 » » return '';
1312 » });
1313 » if (exec === true) Browser.exec(scripts);
1314 » else if (typeOf(exec) == 'function') exec(scripts, text);
1315 » return text;
1316 });
1317
1318 // Window, Document
1319
1320 Browser.extend({
1321 » Document: this.Document,
1322 » Window: this.Window,
1323 » Element: this.Element,
1324 » Event: this.Event
1325 });
1326
1327 this.Window = this.$constructor = new Type('Window', function(){});
1328
1329 this.$family = Function.from('window').hide();
1330
1331 Window.mirror(function(name, method){
1332 » window[name] = method;
1333 });
1334
1335 this.Document = document.$constructor = new Type('Document', function(){});
1336
1337 document.$family = Function.from('document').hide();
1338
1339 Document.mirror(function(name, method){
1340 » document[name] = method;
1341 });
1342
1343 document.html = document.documentElement;
1344 if (!document.head) document.head = document.getElementsByTagName('head')[0];
1345
1346 if (document.execCommand) try {
1347 » document.execCommand("BackgroundImageCache", false, true);
1348 } catch (e){}
1349
1350 /*<ltIE9>*/
1351 if (this.attachEvent && !this.addEventListener){
1352 » var unloadEvent = function(){
1353 » » this.detachEvent('onunload', unloadEvent);
1354 » » document.head = document.html = document.window = null;
1355 » };
1356 » this.attachEvent('onunload', unloadEvent);
1357 }
1358
1359 // IE fails on collections and <select>.options (refers to <select>)
1360 var arrayFrom = Array.from;
1361 try {
1362 » arrayFrom(document.html.childNodes);
1363 } catch(e){
1364 » Array.from = function(item){
1365 » » if (typeof item != 'string' && Type.isEnumerable(item) && typeOf (item) != 'array'){
1366 » » » var i = item.length, array = new Array(i);
1367 » » » while (i--) array[i] = item[i];
1368 » » » return array;
863 } 1369 }
864 » » return true; 1370 » » return arrayFrom(item);
865 » }, 1371 » };
866 1372
867 » some: function(fn, bind){ 1373 » var prototype = Array.prototype,
868 » » for (var key in this){ 1374 » » slice = prototype.slice;
869 » » » if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true; 1375 » ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat ', 'join', 'slice'].each(function(name){
1376 » » var method = prototype[name];
1377 » » Array[name] = function(item){
1378 » » » return method.apply(Array.from(item), slice.call(argumen ts, 1));
1379 » » };
1380 » });
1381 }
1382 /*</ltIE9>*/
1383
1384 //<1.2compat>
1385
1386 if (Browser.Platform.ios) Browser.Platform.ipod = true;
1387
1388 Browser.Engine = {};
1389
1390 var setEngine = function(name, version){
1391 » Browser.Engine.name = name;
1392 » Browser.Engine[name + version] = true;
1393 » Browser.Engine.version = version;
1394 };
1395
1396 if (Browser.ie){
1397 » Browser.Engine.trident = true;
1398
1399 » switch (Browser.version){
1400 » » case 6: setEngine('trident', 4); break;
1401 » » case 7: setEngine('trident', 5); break;
1402 » » case 8: setEngine('trident', 6);
1403 » }
1404 }
1405
1406 if (Browser.firefox){
1407 » Browser.Engine.gecko = true;
1408
1409 » if (Browser.version >= 3) setEngine('gecko', 19);
1410 » else setEngine('gecko', 18);
1411 }
1412
1413 if (Browser.safari || Browser.chrome){
1414 » Browser.Engine.webkit = true;
1415
1416 » switch (Browser.version){
1417 » » case 2: setEngine('webkit', 419); break;
1418 » » case 3: setEngine('webkit', 420); break;
1419 » » case 4: setEngine('webkit', 525);
1420 » }
1421 }
1422
1423 if (Browser.opera){
1424 » Browser.Engine.presto = true;
1425
1426 » if (Browser.version >= 9.6) setEngine('presto', 960);
1427 » else if (Browser.version >= 9.5) setEngine('presto', 950);
1428 » else setEngine('presto', 925);
1429 }
1430
1431 if (Browser.name == 'unknown'){
1432 » switch ((ua.match(/(?:webkit|khtml|gecko)/) || [])[0]){
1433 » » case 'webkit':
1434 » » case 'khtml':
1435 » » » Browser.Engine.webkit = true;
1436 » » break;
1437 » » case 'gecko':
1438 » » » Browser.Engine.gecko = true;
1439 » }
1440 }
1441
1442 this.$exec = Browser.exec;
1443
1444 //</1.2compat>
1445
1446 })();
1447
1448
1449 /*
1450 ---
1451
1452 name: Event
1453
1454 description: Contains the Event Type, to make the event object cross-browser.
1455
1456 license: MIT-style license.
1457
1458 requires: [Window, Document, Array, Function, String, Object]
1459
1460 provides: Event
1461
1462 ...
1463 */
1464
1465 (function() {
1466
1467 var _keys = {};
1468
1469 var DOMEvent = this.DOMEvent = new Type('DOMEvent', function(event, win){
1470 » if (!win) win = window;
1471 » event = event || win.event;
1472 » if (event.$extended) return event;
1473 » this.event = event;
1474 » this.$extended = true;
1475 » this.shift = event.shiftKey;
1476 » this.control = event.ctrlKey;
1477 » this.alt = event.altKey;
1478 » this.meta = event.metaKey;
1479 » var type = this.type = event.type;
1480 » var target = event.target || event.srcElement;
1481 » while (target && target.nodeType == 3) target = target.parentNode;
1482 » this.target = document.id(target);
1483
1484 » if (type.indexOf('key') == 0){
1485 » » var code = this.code = (event.which || event.keyCode);
1486 » » this.key = _keys[code]/*<1.3compat>*/ || Object.keyOf(Event.Keys , code)/*</1.3compat>*/;
1487 » » if (type == 'keydown'){
1488 » » » if (code > 111 && code < 124) this.key = 'f' + (code - 1 11);
1489 » » » else if (code > 95 && code < 106) this.key = code - 96;
870 } 1490 }
871 » » return false; 1491 » » if (this.key == null) this.key = String.fromCharCode(code).toLow erCase();
872 » }, 1492 » } else if (type == 'click' || type == 'dblclick' || type == 'contextmenu ' || type == 'DOMMouseScroll' || type.indexOf('mouse') == 0){
873
874 » getKeys: function(){
875 » » var keys = [];
876 » » Hash.each(this, function(value, key){
877 » » » keys.push(key);
878 » » });
879 » » return keys;
880 » },
881
882 » getValues: function(){
883 » » var values = [];
884 » » Hash.each(this, function(value){
885 » » » values.push(value);
886 » » });
887 » » return values;
888 » },
889
890 » toQueryString: function(base){
891 » » var queryString = [];
892 » » Hash.each(this, function(value, key){
893 » » » if (base) key = base + '[' + key + ']';
894 » » » var result;
895 » » » switch ($type(value)){
896 » » » » case 'object': result = Hash.toQueryString(value , key); break;
897 » » » » case 'array':
898 » » » » » var qs = {};
899 » » » » » value.each(function(val, i){
900 » » » » » » qs[i] = val;
901 » » » » » });
902 » » » » » result = Hash.toQueryString(qs, key);
903 » » » » break;
904 » » » » default: result = key + '=' + encodeURIComponent (value);
905 » » » }
906 » » » if (value != undefined) queryString.push(result);
907 » » });
908
909 » » return queryString.join('&');
910 » }
911
912 });
913
914 Hash.alias({keyOf: 'indexOf', hasValue: 'contains'});
915
916
917 /*
918 Script: Event.js
919 » Contains the Event Native, to make the event object completely crossbrow ser.
920
921 License:
922 » MIT-style license.
923 */
924
925 var Event = new Native({
926
927 » name: 'Event',
928
929 » initialize: function(event, win){
930 » » win = win || window;
931 var doc = win.document; 1493 var doc = win.document;
932 » » event = event || win.event; 1494 » » doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc. html : doc.body;
933 » » if (event.$extended) return event; 1495 » » this.page = {
934 » » this.$extended = true; 1496 » » » x: (event.pageX != null) ? event.pageX : event.clientX + doc.scrollLeft,
935 » » var type = event.type; 1497 » » » y: (event.pageY != null) ? event.pageY : event.clientY + doc.scrollTop
936 » » var target = event.target || event.srcElement; 1498 » » };
937 » » while (target && target.nodeType == 3) target = target.parentNod e; 1499 » » this.client = {
938 1500 » » » x: (event.pageX != null) ? event.pageX - win.pageXOffset : event.clientX,
939 » » if (type.test(/key/)){ 1501 » » » y: (event.pageY != null) ? event.pageY - win.pageYOffset : event.clientY
940 » » » var code = event.which || event.keyCode; 1502 » » };
941 » » » var key = Event.Keys.keyOf(code); 1503 » » if (type == 'DOMMouseScroll' || type == 'mousewheel')
942 » » » if (type == 'keydown'){ 1504 » » » this.wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
943 » » » » var fKey = code - 111; 1505
944 » » » » if (fKey > 0 && fKey < 13) key = 'f' + fKey; 1506 » » this.rightClick = (event.which == 3 || event.button == 2);
945 » » » } 1507 » » if (type == 'mouseover' || type == 'mouseout'){
946 » » » key = key || String.fromCharCode(code).toLowerCase(); 1508 » » » var related = event.relatedTarget || event[(type == 'mou seover' ? 'from' : 'to') + 'Element'];
947 » » } else if (type.match(/(click|mouse|menu)/i)){ 1509 » » » while (related && related.nodeType == 3) related = relat ed.parentNode;
948 » » » doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat' ) ? doc.html : doc.body; 1510 » » » this.relatedTarget = document.id(related);
949 » » » var page = {
950 » » » » x: event.pageX || event.clientX + doc.scrollLeft ,
951 » » » » y: event.pageY || event.clientY + doc.scrollTop
952 » » » };
953 » » » var client = {
954 » » » » x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX,
955 » » » » y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY
956 » » » };
957 » » » if (type.match(/DOMMouseScroll|mousewheel/)){
958 » » » » var wheel = (event.wheelDelta) ? event.wheelDelt a / 120 : -(event.detail || 0) / 3;
959 » » » }
960 » » » var rightClick = (event.which == 3) || (event.button == 2);
961 » » » var related = null;
962 » » » if (type.match(/over|out/)){
963 » » » » switch (type){
964 » » » » » case 'mouseover': related = event.relate dTarget || event.fromElement; break;
965 » » » » » case 'mouseout': related = event.related Target || event.toElement;
966 » » » » }
967 » » » » if (!(function(){
968 » » » » » while (related && related.nodeType == 3) related = related.parentNode;
969 » » » » » return true;
970 » » » » }).create({attempt: Browser.Engine.gecko})()) re lated = false;
971 » » » }
972 } 1511 }
973 1512 » } else if (type.indexOf('touch') == 0 || type.indexOf('gesture') == 0){
974 » » return $extend(this, { 1513 » » this.rotation = event.rotation;
975 » » » event: event, 1514 » » this.scale = event.scale;
976 » » » type: type, 1515 » » this.targetTouches = event.targetTouches;
977 1516 » » this.changedTouches = event.changedTouches;
978 » » » page: page, 1517 » » var touches = this.touches = event.touches;
979 » » » client: client, 1518 » » if (touches && touches[0]){
980 » » » rightClick: rightClick, 1519 » » » var touch = touches[0];
981 1520 » » » this.page = {x: touch.pageX, y: touch.pageY};
982 » » » wheel: wheel, 1521 » » » this.client = {x: touch.clientX, y: touch.clientY};
983 1522 » » }
984 » » » relatedTarget: related, 1523 » }
985 » » » target: target, 1524
986 1525 » if (!this.client) this.client = {};
987 » » » code: code, 1526 » if (!this.page) this.page = {};
988 » » » key: key, 1527 });
989 1528
990 » » » shift: event.shiftKey, 1529 DOMEvent.implement({
991 » » » control: event.ctrlKey,
992 » » » alt: event.altKey,
993 » » » meta: event.metaKey
994 » » });
995 » }
996
997 });
998
999 Event.Keys = new Hash({
1000 » 'enter': 13,
1001 » 'up': 38,
1002 » 'down': 40,
1003 » 'left': 37,
1004 » 'right': 39,
1005 » 'esc': 27,
1006 » 'space': 32,
1007 » 'backspace': 8,
1008 » 'tab': 9,
1009 » 'delete': 46
1010 });
1011
1012 Event.implement({
1013 1530
1014 stop: function(){ 1531 stop: function(){
1015 » » return this.stopPropagation().preventDefault(); 1532 » » return this.preventDefault().stopPropagation();
1016 }, 1533 },
1017 1534
1018 stopPropagation: function(){ 1535 stopPropagation: function(){
1019 if (this.event.stopPropagation) this.event.stopPropagation(); 1536 if (this.event.stopPropagation) this.event.stopPropagation();
1020 else this.event.cancelBubble = true; 1537 else this.event.cancelBubble = true;
1021 return this; 1538 return this;
1022 }, 1539 },
1023 1540
1024 preventDefault: function(){ 1541 preventDefault: function(){
1025 if (this.event.preventDefault) this.event.preventDefault(); 1542 if (this.event.preventDefault) this.event.preventDefault();
1026 else this.event.returnValue = false; 1543 else this.event.returnValue = false;
1027 return this; 1544 return this;
1028 } 1545 }
1029 1546
1030 }); 1547 });
1031 1548
1549 DOMEvent.defineKey = function(code, key){
1550 _keys[code] = key;
1551 return this;
1552 };
1553
1554 DOMEvent.defineKeys = DOMEvent.defineKey.overloadSetter(true);
1555
1556 DOMEvent.defineKeys({
1557 '38': 'up', '40': 'down', '37': 'left', '39': 'right',
1558 '27': 'esc', '32': 'space', '8': 'backspace', '9': 'tab',
1559 '46': 'delete', '13': 'enter'
1560 });
1561
1562 })();
1563
1564 /*<1.3compat>*/
1565 var Event = DOMEvent;
1566 Event.Keys = {};
1567 /*</1.3compat>*/
1568
1569 /*<1.2compat>*/
1570
1571 Event.Keys = new Hash(Event.Keys);
1572
1573 /*</1.2compat>*/
1574
1032 1575
1033 /* 1576 /*
1034 Script: Class.js 1577 ---
1035 » Contains the Class Function for easily creating, extending, and implemen ting reusable Classes.
1036 1578
1037 License: 1579 name: Class
1038 » MIT-style license. 1580
1581 description: Contains the Class Function for easily creating, extending, and imp lementing reusable Classes.
1582
1583 license: MIT-style license.
1584
1585 requires: [Array, String, Function, Number]
1586
1587 provides: Class
1588
1589 ...
1039 */ 1590 */
1040 1591
1041 var Class = new Native({ 1592 (function(){
1042 1593
1043 » name: 'Class', 1594 var Class = this.Class = new Type('Class', function(params){
1595 » if (instanceOf(params, Function)) params = {initialize: params};
1044 1596
1045 » initialize: function(properties){ 1597 » var newClass = function(){
1046 » » properties = properties || {}; 1598 » » reset(this);
1047 » » var klass = function(){ 1599 » » if (newClass.$prototyping) return this;
1048 » » » for (var key in this){ 1600 » » this.$caller = null;
1049 » » » » if ($type(this[key]) != 'function') this[key] = $unlink(this[key]); 1601 » » var value = (this.initialize) ? this.initialize.apply(this, argu ments) : this;
1050 » » » } 1602 » » this.$caller = this.caller = null;
1051 » » » this.constructor = klass; 1603 » » return value;
1052 » » » if (Class.prototyping) return this; 1604 » }.extend(this).implement(params);
1053 » » » var instance = (this.initialize) ? this.initialize.apply (this, arguments) : this;
1054 » » » if (this.options && this.options.initialize) this.option s.initialize.call(this);
1055 » » » return instance;
1056 » » };
1057 1605
1058 » » for (var mutator in Class.Mutators){ 1606 » newClass.$constructor = Class;
1059 » » » if (!properties[mutator]) continue; 1607 » newClass.prototype.$constructor = newClass;
1060 » » » properties = Class.Mutators[mutator](properties, propert ies[mutator]); 1608 » newClass.prototype.parent = parent;
1061 » » » delete properties[mutator]; 1609
1610 » return newClass;
1611 });
1612
1613 var parent = function(){
1614 » if (!this.$caller) throw new Error('The method "parent" cannot be called .');
1615 » var name = this.$caller.$name,
1616 » » parent = this.$caller.$owner.parent,
1617 » » previous = (parent) ? parent.prototype[name] : null;
1618 » if (!previous) throw new Error('The method "' + name + '" has no parent. ');
1619 » return previous.apply(this, arguments);
1620 };
1621
1622 var reset = function(object){
1623 » for (var key in object){
1624 » » var value = object[key];
1625 » » switch (typeOf(value)){
1626 » » » case 'object':
1627 » » » » var F = function(){};
1628 » » » » F.prototype = value;
1629 » » » » object[key] = reset(new F);
1630 » » » break;
1631 » » » case 'array': object[key] = value.clone(); break;
1062 } 1632 }
1633 }
1634 return object;
1635 };
1063 1636
1064 » » $extend(klass, this); 1637 var wrap = function(self, key, method){
1065 » » klass.constructor = Class; 1638 » if (method.$origin) method = method.$origin;
1066 » » klass.prototype = properties; 1639 » var wrapper = function(){
1067 » » return klass; 1640 » » if (method.$protected && this.$caller == null) throw new Error(' The method "' + key + '" cannot be called.');
1641 » » var caller = this.caller, current = this.$caller;
1642 » » this.caller = current; this.$caller = wrapper;
1643 » » var result = method.apply(this, arguments);
1644 » » this.$caller = current; this.caller = caller;
1645 » » return result;
1646 » }.extend({$owner: self, $origin: method, $name: key});
1647 » return wrapper;
1648 };
1649
1650 var implement = function(key, value, retain){
1651 » if (Class.Mutators.hasOwnProperty(key)){
1652 » » value = Class.Mutators[key].call(this, value);
1653 » » if (value == null) return this;
1068 } 1654 }
1069 1655
1070 }); 1656 » if (typeOf(value) == 'function'){
1657 » » if (value.$hidden) return this;
1658 » » this.prototype[key] = (retain) ? value : wrap(this, key, value);
1659 » } else {
1660 » » Object.merge(this.prototype, key, value);
1661 » }
1662
1663 » return this;
1664 };
1665
1666 var getInstance = function(klass){
1667 » klass.$prototyping = true;
1668 » var proto = new klass;
1669 » delete klass.$prototyping;
1670 » return proto;
1671 };
1672
1673 Class.implement('implement', implement.overloadSetter());
1071 1674
1072 Class.Mutators = { 1675 Class.Mutators = {
1073 1676
1074 » Extends: function(self, klass){ 1677 » Extends: function(parent){
1075 » » Class.prototyping = klass.prototype; 1678 » » this.parent = parent;
1076 » » var subclass = new klass; 1679 » » this.prototype = getInstance(parent);
1077 » » delete subclass.parent;
1078 » » subclass = Class.inherit(subclass, self);
1079 » » delete Class.prototyping;
1080 » » return subclass;
1081 }, 1680 },
1082 1681
1083 » Implements: function(self, klasses){ 1682 » Implements: function(items){
1084 » » $splat(klasses).each(function(klass){ 1683 » » Array.from(items).each(function(item){
1085 » » » Class.prototying = klass; 1684 » » » var instance = new item;
1086 » » » $extend(self, ($type(klass) == 'class') ? new klass : kl ass); 1685 » » » for (var key in instance) implement.call(this, key, inst ance[key], true);
1087 » » » delete Class.prototyping; 1686 » » }, this);
1088 » » });
1089 » » return self;
1090 } 1687 }
1091
1092 }; 1688 };
1093 1689
1094 Class.extend({ 1690 })();
1095
1096 » inherit: function(object, properties){
1097 » » var caller = arguments.callee.caller;
1098 » » for (var key in properties){
1099 » » » var override = properties[key];
1100 » » » var previous = object[key];
1101 » » » var type = $type(override);
1102 » » » if (previous && type == 'function'){
1103 » » » » if (override != previous){
1104 » » » » » if (caller){
1105 » » » » » » override.__parent = previous;
1106 » » » » » » object[key] = override;
1107 » » » » » } else {
1108 » » » » » » Class.override(object, key, over ride);
1109 » » » » » }
1110 » » » » }
1111 » » » } else if(type == 'object'){
1112 » » » » object[key] = $merge(previous, override);
1113 » » » } else {
1114 » » » » object[key] = override;
1115 » » » }
1116 » » }
1117
1118 » » if (caller) object.parent = function(){
1119 » » » return arguments.callee.caller.__parent.apply(this, argu ments);
1120 » » };
1121
1122 » » return object;
1123 » },
1124
1125 » override: function(object, name, method){
1126 » » var parent = Class.prototyping;
1127 » » if (parent && object[name] != parent[name]) parent = null;
1128 » » var override = function(){
1129 » » » var previous = this.parent;
1130 » » » this.parent = parent ? parent[name] : object[name];
1131 » » » var value = method.apply(this, arguments);
1132 » » » this.parent = previous;
1133 » » » return value;
1134 » » };
1135 » » object[name] = override;
1136 » }
1137
1138 });
1139
1140 Class.implement({
1141
1142 » implement: function(){
1143 » » var proto = this.prototype;
1144 » » $each(arguments, function(properties){
1145 » » » Class.inherit(proto, properties);
1146 » » });
1147 » » return this;
1148 » }
1149
1150 });
1151 1691
1152 1692
1153 /* 1693 /*
1154 Script: Class.Extras.js 1694 ---
1155 » Contains Utility Classes that can be implemented into your own Classes t o ease the execution of many common tasks.
1156 1695
1157 License: 1696 name: Class.Extras
1158 » MIT-style license. 1697
1698 description: Contains Utility Classes that can be implemented into your own Clas ses to ease the execution of many common tasks.
1699
1700 license: MIT-style license.
1701
1702 requires: Class
1703
1704 provides: [Class.Extras, Chain, Events, Options]
1705
1706 ...
1159 */ 1707 */
1160 1708
1161 var Chain = new Class({ 1709 (function(){
1710
1711 this.Chain = new Class({
1162 1712
1163 $chain: [], 1713 $chain: [],
1164 1714
1165 chain: function(){ 1715 chain: function(){
1166 » » this.$chain.extend(Array.flatten(arguments)); 1716 » » this.$chain.append(Array.flatten(arguments));
1167 return this; 1717 return this;
1168 }, 1718 },
1169 1719
1170 callChain: function(){ 1720 callChain: function(){
1171 return (this.$chain.length) ? this.$chain.shift().apply(this, ar guments) : false; 1721 return (this.$chain.length) ? this.$chain.shift().apply(this, ar guments) : false;
1172 }, 1722 },
1173 1723
1174 clearChain: function(){ 1724 clearChain: function(){
1175 this.$chain.empty(); 1725 this.$chain.empty();
1176 return this; 1726 return this;
1177 } 1727 }
1178 1728
1179 }); 1729 });
1180 1730
1181 var Events = new Class({ 1731 var removeOn = function(string){
1732 » return string.replace(/^on([A-Z])/, function(full, first){
1733 » » return first.toLowerCase();
1734 » });
1735 };
1736
1737 this.Events = new Class({
1182 1738
1183 $events: {}, 1739 $events: {},
1184 1740
1185 addEvent: function(type, fn, internal){ 1741 addEvent: function(type, fn, internal){
1186 » » type = Events.removeOn(type); 1742 » » type = removeOn(type);
1187 » » if (fn != $empty){ 1743
1188 » » » this.$events[type] = this.$events[type] || []; 1744 » » /*<1.2compat>*/
1189 » » » this.$events[type].include(fn); 1745 » » if (fn == $empty) return this;
1190 » » » if (internal) fn.internal = true; 1746 » » /*</1.2compat>*/
1191 » » } 1747
1748 » » this.$events[type] = (this.$events[type] || []).include(fn);
1749 » » if (internal) fn.internal = true;
1192 return this; 1750 return this;
1193 }, 1751 },
1194 1752
1195 addEvents: function(events){ 1753 addEvents: function(events){
1196 for (var type in events) this.addEvent(type, events[type]); 1754 for (var type in events) this.addEvent(type, events[type]);
1197 return this; 1755 return this;
1198 }, 1756 },
1199 1757
1200 fireEvent: function(type, args, delay){ 1758 fireEvent: function(type, args, delay){
1201 » » type = Events.removeOn(type); 1759 » » type = removeOn(type);
1202 » » if (!this.$events || !this.$events[type]) return this; 1760 » » var events = this.$events[type];
1203 » » this.$events[type].each(function(fn){ 1761 » » if (!events) return this;
1204 » » » fn.create({'bind': this, 'delay': delay, 'arguments': ar gs})(); 1762 » » args = Array.from(args);
1763 » » events.each(function(fn){
1764 » » » if (delay) fn.delay(delay, this, args);
1765 » » » else fn.apply(this, args);
1205 }, this); 1766 }, this);
1206 return this; 1767 return this;
1207 }, 1768 },
1208 1769
1209 removeEvent: function(type, fn){ 1770 removeEvent: function(type, fn){
1210 » » type = Events.removeOn(type); 1771 » » type = removeOn(type);
1211 » » if (!this.$events[type]) return this; 1772 » » var events = this.$events[type];
1212 » » if (!fn.internal) this.$events[type].erase(fn); 1773 » » if (events && !fn.internal){
1774 » » » var index = events.indexOf(fn);
1775 » » » if (index != -1) delete events[index];
1776 » » }
1213 return this; 1777 return this;
1214 }, 1778 },
1215 1779
1216 removeEvents: function(events){ 1780 removeEvents: function(events){
1217 » » if ($type(events) == 'object'){ 1781 » » var type;
1218 » » » for (var type in events) this.removeEvent(type, events[t ype]); 1782 » » if (typeOf(events) == 'object'){
1783 » » » for (type in events) this.removeEvent(type, events[type] );
1219 return this; 1784 return this;
1220 } 1785 }
1221 » » if (events) events = Events.removeOn(events); 1786 » » if (events) events = removeOn(events);
1222 » » for (var type in this.$events){ 1787 » » for (type in this.$events){
1223 if (events && events != type) continue; 1788 if (events && events != type) continue;
1224 var fns = this.$events[type]; 1789 var fns = this.$events[type];
1225 » » » for (var i = fns.length; i--; i) this.removeEvent(type, fns[i]); 1790 » » » for (var i = fns.length; i--;) if (i in fns){
1226 » » } 1791 » » » » this.removeEvent(type, fns[i]);
1227 » » return this; 1792 » » » }
1228 » } 1793 » » }
1229 1794 » » return this;
1230 }); 1795 » }
1231 1796
1232 Events.removeOn = function(string){ 1797 });
1233 » return string.replace(/^on([A-Z])/, function(full, first) { 1798
1234 » » return first.toLowerCase(); 1799 this.Options = new Class({
1800
1801 » setOptions: function(){
1802 » » var options = this.options = Object.merge.apply(null, [{}, this. options].append(arguments));
1803 » » if (this.addEvent) for (var option in options){
1804 » » » if (typeOf(options[option]) != 'function' || !(/^on[A-Z] /).test(option)) continue;
1805 » » » this.addEvent(option, options[option]);
1806 » » » delete options[option];
1807 » » }
1808 » » return this;
1809 » }
1810
1811 });
1812
1813 })();
1814
1815
1816 /*
1817 ---
1818 name: Slick.Parser
1819 description: Standalone CSS3 Selector parser
1820 provides: Slick.Parser
1821 ...
1822 */
1823
1824 ;(function(){
1825
1826 var parsed,
1827 » separatorIndex,
1828 » combinatorIndex,
1829 » reversed,
1830 » cache = {},
1831 » reverseCache = {},
1832 » reUnescape = /\\/g;
1833
1834 var parse = function(expression, isReversed){
1835 » if (expression == null) return null;
1836 » if (expression.Slick === true) return expression;
1837 » expression = ('' + expression).replace(/^\s+|\s+$/g, '');
1838 » reversed = !!isReversed;
1839 » var currentCache = (reversed) ? reverseCache : cache;
1840 » if (currentCache[expression]) return currentCache[expression];
1841 » parsed = {
1842 » » Slick: true,
1843 » » expressions: [],
1844 » » raw: expression,
1845 » » reverse: function(){
1846 » » » return parse(this.raw, true);
1847 » » }
1848 » };
1849 » separatorIndex = -1;
1850 » while (expression != (expression = expression.replace(regexp, parser)));
1851 » parsed.length = parsed.expressions.length;
1852 » return currentCache[parsed.raw] = (reversed) ? reverse(parsed) : parsed;
1853 };
1854
1855 var reverseCombinator = function(combinator){
1856 » if (combinator === '!') return ' ';
1857 » else if (combinator === ' ') return '!';
1858 » else if ((/^!/).test(combinator)) return combinator.replace(/^!/, '');
1859 » else return '!' + combinator;
1860 };
1861
1862 var reverse = function(expression){
1863 » var expressions = expression.expressions;
1864 » for (var i = 0; i < expressions.length; i++){
1865 » » var exp = expressions[i];
1866 » » var last = {parts: [], tag: '*', combinator: reverseCombinator(e xp[0].combinator)};
1867
1868 » » for (var j = 0; j < exp.length; j++){
1869 » » » var cexp = exp[j];
1870 » » » if (!cexp.reverseCombinator) cexp.reverseCombinator = ' ';
1871 » » » cexp.combinator = cexp.reverseCombinator;
1872 » » » delete cexp.reverseCombinator;
1873 » » }
1874
1875 » » exp.reverse().push(last);
1876 » }
1877 » return expression;
1878 };
1879
1880 var escapeRegExp = function(string){// Credit: XRegExp 0.6.1 (c) 2007-2008 Steve n Levithan <http://stevenlevithan.com/regex/xregexp/> MIT License
1881 » return string.replace(/[-[\]{}()*+?.\\^$|,#\s]/g, function(match){
1882 » » return '\\' + match;
1235 }); 1883 });
1236 }; 1884 };
1237 1885
1238 var Options = new Class({ 1886 var regexp = new RegExp(
1239
1240 » setOptions: function(){
1241 » » this.options = $merge.run([this.options].extend(arguments));
1242 » » if (!this.addEvent) return this;
1243 » » for (var option in this.options){
1244 » » » if ($type(this.options[option]) != 'function' || !(/^on[ A-Z]/).test(option)) continue;
1245 » » » this.addEvent(option, this.options[option]);
1246 » » » delete this.options[option];
1247 » » }
1248 » » return this;
1249 » }
1250
1251 });
1252
1253
1254 /* 1887 /*
1255 Script: Element.js 1888 #!/usr/bin/env ruby
1256 » One of the most important items in MooTools. Contains the dollar functio n, the dollars function, and an handful of cross-browser, 1889 puts "\t\t" + DATA.read.gsub(/\(\?x\)|\s+#.*$|\s+|\\$|\\n/,'')
1257 » time-saver methods to let you easily work with HTML Elements. 1890 __END__
1258 1891 » "(?x)^(?:\
1259 License: 1892 » \\s* ( , ) \\s* # Separator \n\
1260 » MIT-style license. 1893 » | \\s* ( <combinator>+ ) \\s* # Combinator \n\
1894 » | ( \\s+ ) # CombinatorChildren \n\
1895 » | ( <unicode>+ | \\* ) # Tag \n\
1896 » | \\# ( <unicode>+ ) # ID \n\
1897 » | \\. ( <unicode>+ ) # ClassName \n\
1898 » | # Attribute \n\
1899 » \\[ \
1900 » » \\s* (<unicode1>+) (?: \
1901 » » » \\s* ([*^$!~|]?=) (?: \
1902 » » » » \\s* (?:\
1903 » » » » » ([\"']?)(.*?)\\9 \
1904 » » » » )\
1905 » » » ) \
1906 » » )? \\s* \
1907 » \\](?!\\]) \n\
1908 » | :+ ( <unicode>+ )(?:\
1909 » \\( (?:\
1910 » » (?:([\"'])([^\\12]*)\\12)|((?:\\([^)]+\\)|[^()]*)+)\
1911 » ) \\)\
1912 » )?\
1913 » )"
1261 */ 1914 */
1262 1915 "^(?:\\s*(,)\\s*|\\s*(<combinator>+)\\s*|(\\s+)|(<unicode>+|\\*)|\\#(<un icode>+)|\\.(<unicode>+)|\\[\\s*(<unicode1>+)(?:\\s*([*^$!~|]?=)(?:\\s*(?:([\"'] ?)(.*?)\\9)))?\\s*\\](?!\\])|(:+)(<unicode>+)(?:\\((?:(?:([\"'])([^\\13]*)\\13)| ((?:\\([^)]+\\)|[^()]*)+))\\))?)"
1263 var Element = new Native({ 1916 .replace(/<combinator>/, '[' + escapeRegExp(">+~`!@$%^&={}\\;</") + ']')
1264 1917 .replace(/<unicode>/g, '(?:[\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
1265 name: 'Element', 1918 .replace(/<unicode1>/g, '(?:[:\\w\\u00a1-\\uFFFF-]|\\\\[^\\s0-9a-f])')
1266 1919 );
1267 legacy: window.Element, 1920
1268 1921 function parser(
1269 initialize: function(tag, props){ 1922 rawMatch,
1270 var konstructor = Element.Constructors.get(tag); 1923
1271 if (konstructor) return konstructor(props); 1924 separator,
1272 if (typeof tag == 'string') return document.newElement(tag, prop s); 1925 combinator,
1273 return $(tag).set(props); 1926 combinatorChildren,
1274 }, 1927
1275 1928 tagName,
1276 afterImplement: function(key, value){ 1929 id,
1277 Element.Prototype[key] = value; 1930 className,
1278 if (Array[key]) return; 1931
1279 Elements.implement(key, function(){ 1932 attributeKey,
1280 var items = [], elements = true; 1933 attributeOperator,
1281 for (var i = 0, j = this.length; i < j; i++){ 1934 attributeQuote,
1282 var returns = this[i][key].apply(this[i], argume nts); 1935 attributeValue,
1283 items.push(returns); 1936
1284 if (elements) elements = ($type(returns) == 'ele ment'); 1937 pseudoMarker,
1938 pseudoClass,
1939 pseudoQuote,
1940 pseudoClassQuotedValue,
1941 pseudoClassValue
1942 ){
1943 if (separator || separatorIndex === -1){
1944 parsed.expressions[++separatorIndex] = [];
1945 combinatorIndex = -1;
1946 if (separator) return '';
1947 }
1948
1949 if (combinator || combinatorChildren || combinatorIndex === -1){
1950 combinator = combinator || ' ';
1951 var currentSeparator = parsed.expressions[separatorIndex];
1952 if (reversed && currentSeparator[combinatorIndex])
1953 currentSeparator[combinatorIndex].reverseCombinator = re verseCombinator(combinator);
1954 currentSeparator[++combinatorIndex] = {combinator: combinator, t ag: '*'};
1955 }
1956
1957 var currentParsed = parsed.expressions[separatorIndex][combinatorIndex];
1958
1959 if (tagName){
1960 currentParsed.tag = tagName.replace(reUnescape, '');
1961
1962 } else if (id){
1963 currentParsed.id = id.replace(reUnescape, '');
1964
1965 } else if (className){
1966 className = className.replace(reUnescape, '');
1967
1968 if (!currentParsed.classList) currentParsed.classList = [];
1969 if (!currentParsed.classes) currentParsed.classes = [];
1970 currentParsed.classList.push(className);
1971 currentParsed.classes.push({
1972 value: className,
1973 regexp: new RegExp('(^|\\s)' + escapeRegExp(className) + '(\\s|$)')
1974 });
1975
1976 } else if (pseudoClass){
1977 pseudoClassValue = pseudoClassValue || pseudoClassQuotedValue;
1978 pseudoClassValue = pseudoClassValue ? pseudoClassValue.replace(r eUnescape, '') : null;
1979
1980 if (!currentParsed.pseudos) currentParsed.pseudos = [];
1981 currentParsed.pseudos.push({
1982 key: pseudoClass.replace(reUnescape, ''),
1983 value: pseudoClassValue,
1984 type: pseudoMarker.length == 1 ? 'class' : 'element'
1985 });
1986
1987 } else if (attributeKey){
1988 attributeKey = attributeKey.replace(reUnescape, '');
1989 attributeValue = (attributeValue || '').replace(reUnescape, '');
1990
1991 var test, regexp;
1992
1993 switch (attributeOperator){
1994 case '^=' : regexp = new RegExp( '^'+ escapeRegExp (attributeValue) ); break;
1995 case '$=' : regexp = new RegExp( escapeRegExp (attributeValue) +'$' ); break;
1996 case '~=' : regexp = new RegExp( '(^|\\s)'+ escapeRegExp (attributeValue) +'(\\s|$)' ); break;
1997 case '|=' : regexp = new RegExp( '^'+ escapeRegExp (attributeValue) +'(-|$)' ); break;
1998 case '=' : test = function(value){
1999 return attributeValue == value;
2000 }; break;
2001 case '*=' : test = function(value){
2002 return value && value.indexOf(attributeValue) > -1;
2003 }; break;
2004 case '!=' : test = function(value){
2005 return attributeValue != value;
2006 }; break;
2007 default : test = function(value){
2008 return !!value;
2009 };
2010 }
2011
2012 if (attributeValue == '' && (/^[*$^]=$/).test(attributeOperator) ) test = function(){
2013 return false;
2014 };
2015
2016 if (!test) test = function(value){
2017 return value && regexp.test(value);
2018 };
2019
2020 if (!currentParsed.attributes) currentParsed.attributes = [];
2021 currentParsed.attributes.push({
2022 key: attributeKey,
2023 operator: attributeOperator,
2024 value: attributeValue,
2025 test: test
2026 });
2027
2028 }
2029
2030 return '';
2031 };
2032
2033 // Slick NS
2034
2035 var Slick = (this.Slick || {});
2036
2037 Slick.parse = function(expression){
2038 return parse(expression);
2039 };
2040
2041 Slick.escapeRegExp = escapeRegExp;
2042
2043 if (!this.Slick) this.Slick = Slick;
2044
2045 }).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS> */this);
2046
2047
2048 /*
2049 ---
2050 name: Slick.Finder
2051 description: The new, superfast css selector engine.
2052 provides: Slick.Finder
2053 requires: Slick.Parser
2054 ...
2055 */
2056
2057 ;(function(){
2058
2059 var local = {},
2060 featuresCache = {},
2061 toString = Object.prototype.toString;
2062
2063 // Feature / Bug detection
2064
2065 local.isNativeCode = function(fn){
2066 return (/\{\s*\[native code\]\s*\}/).test('' + fn);
2067 };
2068
2069 local.isXML = function(document){
2070 return (!!document.xmlVersion) || (!!document.xml) || (toString.call(doc ument) == '[object XMLDocument]') ||
2071 (document.nodeType == 9 && document.documentElement.nodeName != 'HTML');
2072 };
2073
2074 local.setDocument = function(document){
2075
2076 // convert elements / window arguments to document. if document cannot b e extrapolated, the function returns.
2077 var nodeType = document.nodeType;
2078 if (nodeType == 9); // document
2079 else if (nodeType) document = document.ownerDocument; // node
2080 else if (document.navigator) document = document.document; // window
2081 else return;
2082
2083 // check if it's the old document
2084
2085 if (this.document === document) return;
2086 this.document = document;
2087
2088 // check if we have done feature detection on this document before
2089
2090 var root = document.documentElement,
2091 rootUid = this.getUIDXML(root),
2092 features = featuresCache[rootUid],
2093 feature;
2094
2095 if (features){
2096 for (feature in features){
2097 this[feature] = features[feature];
2098 }
2099 return;
2100 }
2101
2102 features = featuresCache[rootUid] = {};
2103
2104 features.root = root;
2105 features.isXMLDocument = this.isXML(document);
2106
2107 features.brokenStarGEBTN
2108 = features.starSelectsClosedQSA
2109 = features.idGetsName
2110 = features.brokenMixedCaseQSA
2111 = features.brokenGEBCN
2112 = features.brokenCheckedQSA
2113 = features.brokenEmptyAttributeQSA
2114 = features.isHTMLDocument
2115 = features.nativeMatchesSelector
2116 = false;
2117
2118 var starSelectsClosed, starSelectsComments,
2119 brokenSecondClassNameGEBCN, cachedGetElementsByClassName,
2120 brokenFormAttributeGetter;
2121
2122 var selected, id = 'slick_uniqueid';
2123 var testNode = document.createElement('div');
2124
2125 var testRoot = document.body || document.getElementsByTagName('body')[0] || root;
2126 testRoot.appendChild(testNode);
2127
2128 // on non-HTML documents innerHTML and getElementsById doesnt work prope rly
2129 try {
2130 testNode.innerHTML = '<a id="'+id+'"></a>';
2131 features.isHTMLDocument = !!document.getElementById(id);
2132 } catch(e){};
2133
2134 if (features.isHTMLDocument){
2135
2136 testNode.style.display = 'none';
2137
2138 // IE returns comment nodes for getElementsByTagName('*') for so me documents
2139 testNode.appendChild(document.createComment(''));
2140 starSelectsComments = (testNode.getElementsByTagName('*').length > 1);
2141
2142 // IE returns closed nodes (EG:"</foo>") for getElementsByTagNam e('*') for some documents
2143 try {
2144 testNode.innerHTML = 'foo</foo>';
2145 selected = testNode.getElementsByTagName('*');
2146 starSelectsClosed = (selected && !!selected.length && se lected[0].nodeName.charAt(0) == '/');
2147 } catch(e){};
2148
2149 features.brokenStarGEBTN = starSelectsComments || starSelectsClo sed;
2150
2151 // IE returns elements with the name instead of just id for getE lementsById for some documents
2152 try {
2153 testNode.innerHTML = '<a name="'+ id +'"></a><b id="'+ i d +'"></b>';
2154 features.idGetsName = document.getElementById(id) === te stNode.firstChild;
2155 } catch(e){};
2156
2157 if (testNode.getElementsByClassName){
2158
2159 // Safari 3.2 getElementsByClassName caches results
2160 try {
2161 testNode.innerHTML = '<a class="f"></a><a class= "b"></a>';
2162 testNode.getElementsByClassName('b').length;
2163 testNode.firstChild.className = 'b';
2164 cachedGetElementsByClassName = (testNode.getElem entsByClassName('b').length != 2);
2165 } catch(e){};
2166
2167 // Opera 9.6 getElementsByClassName doesnt detects the c lass if its not the first one
2168 try {
2169 testNode.innerHTML = '<a class="a"></a><a class= "f b a"></a>';
2170 brokenSecondClassNameGEBCN = (testNode.getElemen tsByClassName('a').length != 2);
2171 } catch(e){};
2172
2173 features.brokenGEBCN = cachedGetElementsByClassName || b rokenSecondClassNameGEBCN;
2174 }
2175
2176 if (testNode.querySelectorAll){
2177 // IE 8 returns closed nodes (EG:"</foo>") for querySele ctorAll('*') for some documents
2178 try {
2179 testNode.innerHTML = 'foo</foo>';
2180 selected = testNode.querySelectorAll('*');
2181 features.starSelectsClosedQSA = (selected && !!s elected.length && selected[0].nodeName.charAt(0) == '/');
2182 } catch(e){};
2183
2184 // Safari 3.2 querySelectorAll doesnt work with mixedcas e on quirksmode
2185 try {
2186 testNode.innerHTML = '<a class="MiX"></a>';
2187 features.brokenMixedCaseQSA = !testNode.querySel ectorAll('.MiX').length;
2188 } catch(e){};
2189
2190 // Webkit and Opera dont return selected options on quer ySelectorAll
2191 try {
2192 testNode.innerHTML = '<select><option selected=" selected">a</option></select>';
2193 features.brokenCheckedQSA = (testNode.querySelec torAll(':checked').length == 0);
2194 } catch(e){};
2195
2196 // IE returns incorrect results for attr[*^$]="" selecto rs on querySelectorAll
2197 try {
2198 testNode.innerHTML = '<a class=""></a>';
2199 features.brokenEmptyAttributeQSA = (testNode.que rySelectorAll('[class*=""]').length != 0);
2200 } catch(e){};
2201
2202 }
2203
2204 // IE6-7, if a form has an input of id x, form.getAttribute(x) r eturns a reference to the input
2205 try {
2206 testNode.innerHTML = '<form action="s"><input id="action "/></form>';
2207 brokenFormAttributeGetter = (testNode.firstChild.getAttr ibute('action') != 's');
2208 } catch(e){};
2209
2210 // native matchesSelector function
2211
2212 features.nativeMatchesSelector = root.matchesSelector || /*root. msMatchesSelector ||*/ root.mozMatchesSelector || root.webkitMatchesSelector;
2213 if (features.nativeMatchesSelector) try {
2214 // if matchesSelector trows errors on incorrect sintaxes we can use it
2215 features.nativeMatchesSelector.call(root, ':slick');
2216 features.nativeMatchesSelector = null;
2217 } catch(e){};
2218
2219 }
2220
2221 try {
2222 root.slick_expando = 1;
2223 delete root.slick_expando;
2224 features.getUID = this.getUIDHTML;
2225 } catch(e) {
2226 features.getUID = this.getUIDXML;
2227 }
2228
2229 testRoot.removeChild(testNode);
2230 testNode = selected = testRoot = null;
2231
2232 // getAttribute
2233
2234 features.getAttribute = (features.isHTMLDocument && brokenFormAttributeG etter) ? function(node, name){
2235 var method = this.attributeGetters[name];
2236 if (method) return method.call(node);
2237 var attributeNode = node.getAttributeNode(name);
2238 return (attributeNode) ? attributeNode.nodeValue : null;
2239 } : function(node, name){
2240 var method = this.attributeGetters[name];
2241 return (method) ? method.call(node) : node.getAttribute(name);
2242 };
2243
2244 // hasAttribute
2245
2246 features.hasAttribute = (root && this.isNativeCode(root.hasAttribute)) ? function(node, attribute) {
2247 return node.hasAttribute(attribute);
2248 } : function(node, attribute) {
2249 node = node.getAttributeNode(attribute);
2250 return !!(node && (node.specified || node.nodeValue));
2251 };
2252
2253 // contains
2254 // FIXME: Add specs: local.contains should be different for xml and html documents?
2255 features.contains = (root && this.isNativeCode(root.contains)) ? functio n(context, node){
2256 return context.contains(node);
2257 } : (root && root.compareDocumentPosition) ? function(context, node){
2258 return context === node || !!(context.compareDocumentPosition(no de) & 16);
2259 } : function(context, node){
2260 if (node) do {
2261 if (node === context) return true;
2262 } while ((node = node.parentNode));
2263 return false;
2264 };
2265
2266 // document order sorting
2267 // credits to Sizzle (http://sizzlejs.com/)
2268
2269 features.documentSorter = (root.compareDocumentPosition) ? function(a, b ){
2270 if (!a.compareDocumentPosition || !b.compareDocumentPosition) re turn 0;
2271 return a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
2272 } : ('sourceIndex' in root) ? function(a, b){
2273 if (!a.sourceIndex || !b.sourceIndex) return 0;
2274 return a.sourceIndex - b.sourceIndex;
2275 } : (document.createRange) ? function(a, b){
2276 if (!a.ownerDocument || !b.ownerDocument) return 0;
2277 var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocu ment.createRange();
2278 aRange.setStart(a, 0);
2279 aRange.setEnd(a, 0);
2280 bRange.setStart(b, 0);
2281 bRange.setEnd(b, 0);
2282 return aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
2283 } : null ;
2284
2285 root = null;
2286
2287 for (feature in features){
2288 this[feature] = features[feature];
2289 }
2290 };
2291
2292 // Main Method
2293
2294 var reSimpleSelector = /^([#.]?)((?:[\w-]+|\*))$/,
2295 reEmptyAttribute = /\[.+[*$^]=(?:""|'')?\]/,
2296 qsaFailExpCache = {};
2297
2298 local.search = function(context, expression, append, first){
2299
2300 var found = this.found = (first) ? null : (append || []);
2301
2302 if (!context) return found;
2303 else if (context.navigator) context = context.document; // Convert the n ode from a window to a document
2304 else if (!context.nodeType) return found;
2305
2306 // setup
2307
2308 var parsed, i,
2309 uniques = this.uniques = {},
2310 hasOthers = !!(append && append.length),
2311 contextIsDocument = (context.nodeType == 9);
2312
2313 if (this.document !== (contextIsDocument ? context : context.ownerDocume nt)) this.setDocument(context);
2314
2315 // avoid duplicating items already in the append array
2316 if (hasOthers) for (i = found.length; i--;) uniques[this.getUID(found[i] )] = true;
2317
2318 // expression checks
2319
2320 if (typeof expression == 'string'){ // expression is a string
2321
2322 /*<simple-selectors-override>*/
2323 var simpleSelector = expression.match(reSimpleSelector);
2324 simpleSelectors: if (simpleSelector) {
2325
2326 var symbol = simpleSelector[1],
2327 name = simpleSelector[2],
2328 node, nodes;
2329
2330 if (!symbol){
2331
2332 if (name == '*' && this.brokenStarGEBTN) break s impleSelectors;
2333 nodes = context.getElementsByTagName(name);
2334 if (first) return nodes[0] || null;
2335 for (i = 0; node = nodes[i++];){
2336 if (!(hasOthers && uniques[this.getUID(n ode)])) found.push(node);
2337 }
2338
2339 } else if (symbol == '#'){
2340
2341 if (!this.isHTMLDocument || !contextIsDocument) break simpleSelectors;
2342 node = context.getElementById(name);
2343 if (!node) return found;
2344 if (this.idGetsName && node.getAttributeNode('id ').nodeValue != name) break simpleSelectors;
2345 if (first) return node || null;
2346 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
2347
2348 } else if (symbol == '.'){
2349
2350 if (!this.isHTMLDocument || ((!context.getElemen tsByClassName || this.brokenGEBCN) && context.querySelectorAll)) break simpleSel ectors;
2351 if (context.getElementsByClassName && !this.brok enGEBCN){
2352 nodes = context.getElementsByClassName(n ame);
2353 if (first) return nodes[0] || null;
2354 for (i = 0; node = nodes[i++];){
2355 if (!(hasOthers && uniques[this. getUID(node)])) found.push(node);
2356 }
2357 } else {
2358 var matchClass = new RegExp('(^|\\s)'+ S lick.escapeRegExp(name) +'(\\s|$)');
2359 nodes = context.getElementsByTagName('*' );
2360 for (i = 0; node = nodes[i++];){
2361 className = node.className;
2362 if (!(className && matchClass.te st(className))) continue;
2363 if (first) return node;
2364 if (!(hasOthers && uniques[this. getUID(node)])) found.push(node);
2365 }
2366 }
2367
1285 } 2368 }
1286 return (elements) ? new Elements(items) : items; 2369
1287 }); 2370 if (hasOthers) this.sort(found);
1288 } 2371 return (first) ? null : found;
1289 2372
1290 }); 2373 }
1291 2374 /*</simple-selectors-override>*/
1292 Element.Prototype = {$family: {name: 'element'}}; 2375
2376 /*<query-selector-override>*/
2377 querySelector: if (context.querySelectorAll) {
2378
2379 if (!this.isHTMLDocument
2380 || qsaFailExpCache[expression]
2381 //TODO: only skip when expression is actually mi xed case
2382 || this.brokenMixedCaseQSA
2383 || (this.brokenCheckedQSA && expression.indexOf( ':checked') > -1)
2384 || (this.brokenEmptyAttributeQSA && reEmptyAttri bute.test(expression))
2385 || (!contextIsDocument //Abort when !contextIsDo cument and...
2386 // there are multiple expressions in th e selector
2387 // since we currently only fix non-docu ment rooted QSA for single expression selectors
2388 && expression.indexOf(',') > -1
2389 )
2390 || Slick.disableQSA
2391 ) break querySelector;
2392
2393 var _expression = expression, _context = context;
2394 if (!contextIsDocument){
2395 // non-document rooted QSA
2396 // credits to Andrew Dupont
2397 var currentId = _context.getAttribute('id'), sli ckid = 'slickid__';
2398 _context.setAttribute('id', slickid);
2399 _expression = '#' + slickid + ' ' + _expression;
2400 context = _context.parentNode;
2401 }
2402
2403 try {
2404 if (first) return context.querySelector(_express ion) || null;
2405 else nodes = context.querySelectorAll(_expressio n);
2406 } catch(e) {
2407 qsaFailExpCache[expression] = 1;
2408 break querySelector;
2409 } finally {
2410 if (!contextIsDocument){
2411 if (currentId) _context.setAttribute('id ', currentId);
2412 else _context.removeAttribute('id');
2413 context = _context;
2414 }
2415 }
2416
2417 if (this.starSelectsClosedQSA) for (i = 0; node = nodes[ i++];){
2418 if (node.nodeName > '@' && !(hasOthers && unique s[this.getUID(node)])) found.push(node);
2419 } else for (i = 0; node = nodes[i++];){
2420 if (!(hasOthers && uniques[this.getUID(node)])) found.push(node);
2421 }
2422
2423 if (hasOthers) this.sort(found);
2424 return found;
2425
2426 }
2427 /*</query-selector-override>*/
2428
2429 parsed = this.Slick.parse(expression);
2430 if (!parsed.length) return found;
2431 } else if (expression == null){ // there is no expression
2432 return found;
2433 } else if (expression.Slick){ // expression is a parsed Slick object
2434 parsed = expression;
2435 } else if (this.contains(context.documentElement || context, expression) ){ // expression is a node
2436 (found) ? found.push(expression) : found = expression;
2437 return found;
2438 } else { // other junk
2439 return found;
2440 }
2441
2442 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
2443
2444 // cache elements for the nth selectors
2445
2446 this.posNTH = {};
2447 this.posNTHLast = {};
2448 this.posNTHType = {};
2449 this.posNTHTypeLast = {};
2450
2451 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
2452
2453 // if append is null and there is only a single selector with one expres sion use pushArray, else use pushUID
2454 this.push = (!hasOthers && (first || (parsed.length == 1 && parsed.expre ssions[0].length == 1))) ? this.pushArray : this.pushUID;
2455
2456 if (found == null) found = [];
2457
2458 // default engine
2459
2460 var j, m, n;
2461 var combinator, tag, id, classList, classes, attributes, pseudos;
2462 var currentItems, currentExpression, currentBit, lastBit, expressions = parsed.expressions;
2463
2464 search: for (i = 0; (currentExpression = expressions[i]); i++) for (j = 0; (currentBit = currentExpression[j]); j++){
2465
2466 combinator = 'combinator:' + currentBit.combinator;
2467 if (!this[combinator]) continue search;
2468
2469 tag = (this.isXMLDocument) ? currentBit.tag : currentBit. tag.toUpperCase();
2470 id = currentBit.id;
2471 classList = currentBit.classList;
2472 classes = currentBit.classes;
2473 attributes = currentBit.attributes;
2474 pseudos = currentBit.pseudos;
2475 lastBit = (j === (currentExpression.length - 1));
2476
2477 this.bitUniques = {};
2478
2479 if (lastBit){
2480 this.uniques = uniques;
2481 this.found = found;
2482 } else {
2483 this.uniques = {};
2484 this.found = [];
2485 }
2486
2487 if (j === 0){
2488 this[combinator](context, tag, id, classes, attributes, pseudos, classList);
2489 if (first && lastBit && found.length) break search;
2490 } else {
2491 if (first && lastBit) for (m = 0, n = currentItems.lengt h; m < n; m++){
2492 this[combinator](currentItems[m], tag, id, class es, attributes, pseudos, classList);
2493 if (found.length) break search;
2494 } else for (m = 0, n = currentItems.length; m < n; m++) this[combinator](currentItems[m], tag, id, classes, attributes, pseudos, classLi st);
2495 }
2496
2497 currentItems = this.found;
2498 }
2499
2500 // should sort if there are nodes in append and if you pass multiple exp ressions.
2501 if (hasOthers || (parsed.expressions.length > 1)) this.sort(found);
2502
2503 return (first) ? (found[0] || null) : found;
2504 };
2505
2506 // Utils
2507
2508 local.uidx = 1;
2509 local.uidk = 'slick-uniqueid';
2510
2511 local.getUIDXML = function(node){
2512 var uid = node.getAttribute(this.uidk);
2513 if (!uid){
2514 uid = this.uidx++;
2515 node.setAttribute(this.uidk, uid);
2516 }
2517 return uid;
2518 };
2519
2520 local.getUIDHTML = function(node){
2521 return node.uniqueNumber || (node.uniqueNumber = this.uidx++);
2522 };
2523
2524 // sort based on the setDocument documentSorter method.
2525
2526 local.sort = function(results){
2527 if (!this.documentSorter) return results;
2528 results.sort(this.documentSorter);
2529 return results;
2530 };
2531
2532 /*<pseudo-selectors>*//*<nth-pseudo-selectors>*/
2533
2534 local.cacheNTH = {};
2535
2536 local.matchNTH = /^([+-]?\d*)?([a-z]+)?([+-]\d+)?$/;
2537
2538 local.parseNTHArgument = function(argument){
2539 var parsed = argument.match(this.matchNTH);
2540 if (!parsed) return false;
2541 var special = parsed[2] || false;
2542 var a = parsed[1] || 1;
2543 if (a == '-') a = -1;
2544 var b = +parsed[3] || 0;
2545 parsed =
2546 (special == 'n') ? {a: a, b: b} :
2547 (special == 'odd') ? {a: 2, b: 1} :
2548 (special == 'even') ? {a: 2, b: 0} : {a: 0, b: a};
2549
2550 return (this.cacheNTH[argument] = parsed);
2551 };
2552
2553 local.createNTHPseudo = function(child, sibling, positions, ofType){
2554 return function(node, argument){
2555 var uid = this.getUID(node);
2556 if (!this[positions][uid]){
2557 var parent = node.parentNode;
2558 if (!parent) return false;
2559 var el = parent[child], count = 1;
2560 if (ofType){
2561 var nodeName = node.nodeName;
2562 do {
2563 if (el.nodeName != nodeName) continue;
2564 this[positions][this.getUID(el)] = count ++;
2565 } while ((el = el[sibling]));
2566 } else {
2567 do {
2568 if (el.nodeType != 1) continue;
2569 this[positions][this.getUID(el)] = count ++;
2570 } while ((el = el[sibling]));
2571 }
2572 }
2573 argument = argument || 'n';
2574 var parsed = this.cacheNTH[argument] || this.parseNTHArgument(ar gument);
2575 if (!parsed) return false;
2576 var a = parsed.a, b = parsed.b, pos = this[positions][uid];
2577 if (a == 0) return b == pos;
2578 if (a > 0){
2579 if (pos < b) return false;
2580 } else {
2581 if (b < pos) return false;
2582 }
2583 return ((pos - b) % a) == 0;
2584 };
2585 };
2586
2587 /*</nth-pseudo-selectors>*//*</pseudo-selectors>*/
2588
2589 local.pushArray = function(node, tag, id, classes, attributes, pseudos){
2590 if (this.matchSelector(node, tag, id, classes, attributes, pseudos)) thi s.found.push(node);
2591 };
2592
2593 local.pushUID = function(node, tag, id, classes, attributes, pseudos){
2594 var uid = this.getUID(node);
2595 if (!this.uniques[uid] && this.matchSelector(node, tag, id, classes, att ributes, pseudos)){
2596 this.uniques[uid] = true;
2597 this.found.push(node);
2598 }
2599 };
2600
2601 local.matchNode = function(node, selector){
2602 if (this.isHTMLDocument && this.nativeMatchesSelector){
2603 try {
2604 return this.nativeMatchesSelector.call(node, selector.re place(/\[([^=]+)=\s*([^'"\]]+?)\s*\]/g, '[$1="$2"]'));
2605 } catch(matchError) {}
2606 }
2607
2608 var parsed = this.Slick.parse(selector);
2609 if (!parsed) return true;
2610
2611 // simple (single) selectors
2612 var expressions = parsed.expressions, simpleExpCounter = 0, i;
2613 for (i = 0; (currentExpression = expressions[i]); i++){
2614 if (currentExpression.length == 1){
2615 var exp = currentExpression[0];
2616 if (this.matchSelector(node, (this.isXMLDocument) ? exp. tag : exp.tag.toUpperCase(), exp.id, exp.classes, exp.attributes, exp.pseudos)) return true;
2617 simpleExpCounter++;
2618 }
2619 }
2620
2621 if (simpleExpCounter == parsed.length) return false;
2622
2623 var nodes = this.search(this.document, parsed), item;
2624 for (i = 0; item = nodes[i++];){
2625 if (item === node) return true;
2626 }
2627 return false;
2628 };
2629
2630 local.matchPseudo = function(node, name, argument){
2631 var pseudoName = 'pseudo:' + name;
2632 if (this[pseudoName]) return this[pseudoName](node, argument);
2633 var attribute = this.getAttribute(node, name);
2634 return (argument) ? argument == attribute : !!attribute;
2635 };
2636
2637 local.matchSelector = function(node, tag, id, classes, attributes, pseudos){
2638 if (tag){
2639 var nodeName = (this.isXMLDocument) ? node.nodeName : node.nodeN ame.toUpperCase();
2640 if (tag == '*'){
2641 if (nodeName < '@') return false; // Fix for comment nod es and closed nodes
2642 } else {
2643 if (nodeName != tag) return false;
2644 }
2645 }
2646
2647 if (id && node.getAttribute('id') != id) return false;
2648
2649 var i, part, cls;
2650 if (classes) for (i = classes.length; i--;){
2651 cls = node.getAttribute('class') || node.className;
2652 if (!(cls && classes[i].regexp.test(cls))) return false;
2653 }
2654 if (attributes) for (i = attributes.length; i--;){
2655 part = attributes[i];
2656 if (part.operator ? !part.test(this.getAttribute(node, part.key) ) : !this.hasAttribute(node, part.key)) return false;
2657 }
2658 if (pseudos) for (i = pseudos.length; i--;){
2659 part = pseudos[i];
2660 if (!this.matchPseudo(node, part.key, part.value)) return false;
2661 }
2662 return true;
2663 };
2664
2665 var combinators = {
2666
2667 ' ': function(node, tag, id, classes, attributes, pseudos, classList){ / / all child nodes, any level
2668
2669 var i, item, children;
2670
2671 if (this.isHTMLDocument){
2672 getById: if (id){
2673 item = this.document.getElementById(id);
2674 if ((!item && node.all) || (this.idGetsName && i tem && item.getAttributeNode('id').nodeValue != id)){
2675 // all[id] returns all the elements with that name or id inside node
2676 // if theres just one it will return the element, else it will be a collection
2677 children = node.all[id];
2678 if (!children) return;
2679 if (!children[0]) children = [children];
2680 for (i = 0; item = children[i++];){
2681 var idNode = item.getAttributeNo de('id');
2682 if (idNode && idNode.nodeValue = = id){
2683 this.push(item, tag, nul l, classes, attributes, pseudos);
2684 break;
2685 }
2686 }
2687 return;
2688 }
2689 if (!item){
2690 // if the context is in the dom we retur n, else we will try GEBTN, breaking the getById label
2691 if (this.contains(this.root, node)) retu rn;
2692 else break getById;
2693 } else if (this.document !== node && !this.conta ins(node, item)) return;
2694 this.push(item, tag, null, classes, attributes, pseudos);
2695 return;
2696 }
2697 getByClass: if (classes && node.getElementsByClassName & & !this.brokenGEBCN){
2698 children = node.getElementsByClassName(classList .join(' '));
2699 if (!(children && children.length)) break getByC lass;
2700 for (i = 0; item = children[i++];) this.push(ite m, tag, id, null, attributes, pseudos);
2701 return;
2702 }
2703 }
2704 getByTag: {
2705 children = node.getElementsByTagName(tag);
2706 if (!(children && children.length)) break getByTag;
2707 if (!this.brokenStarGEBTN) tag = null;
2708 for (i = 0; item = children[i++];) this.push(item, tag, id, classes, attributes, pseudos);
2709 }
2710 },
2711
2712 '>': function(node, tag, id, classes, attributes, pseudos){ // direct ch ildren
2713 if ((node = node.firstChild)) do {
2714 if (node.nodeType == 1) this.push(node, tag, id, classes , attributes, pseudos);
2715 } while ((node = node.nextSibling));
2716 },
2717
2718 '+': function(node, tag, id, classes, attributes, pseudos){ // next sibl ing
2719 while ((node = node.nextSibling)) if (node.nodeType == 1){
2720 this.push(node, tag, id, classes, attributes, pseudos);
2721 break;
2722 }
2723 },
2724
2725 '^': function(node, tag, id, classes, attributes, pseudos){ // first chi ld
2726 node = node.firstChild;
2727 if (node){
2728 if (node.nodeType == 1) this.push(node, tag, id, classes , attributes, pseudos);
2729 else this['combinator:+'](node, tag, id, classes, attrib utes, pseudos);
2730 }
2731 },
2732
2733 '~': function(node, tag, id, classes, attributes, pseudos){ // next sibl ings
2734 while ((node = node.nextSibling)){
2735 if (node.nodeType != 1) continue;
2736 var uid = this.getUID(node);
2737 if (this.bitUniques[uid]) break;
2738 this.bitUniques[uid] = true;
2739 this.push(node, tag, id, classes, attributes, pseudos);
2740 }
2741 },
2742
2743 '++': function(node, tag, id, classes, attributes, pseudos){ // next sib ling and previous sibling
2744 this['combinator:+'](node, tag, id, classes, attributes, pseudos );
2745 this['combinator:!+'](node, tag, id, classes, attributes, pseudo s);
2746 },
2747
2748 '~~': function(node, tag, id, classes, attributes, pseudos){ // next sib lings and previous siblings
2749 this['combinator:~'](node, tag, id, classes, attributes, pseudos );
2750 this['combinator:!~'](node, tag, id, classes, attributes, pseudo s);
2751 },
2752
2753 '!': function(node, tag, id, classes, attributes, pseudos){ // all paren t nodes up to document
2754 while ((node = node.parentNode)) if (node !== this.document) thi s.push(node, tag, id, classes, attributes, pseudos);
2755 },
2756
2757 '!>': function(node, tag, id, classes, attributes, pseudos){ // direct p arent (one level)
2758 node = node.parentNode;
2759 if (node !== this.document) this.push(node, tag, id, classes, at tributes, pseudos);
2760 },
2761
2762 '!+': function(node, tag, id, classes, attributes, pseudos){ // previous sibling
2763 while ((node = node.previousSibling)) if (node.nodeType == 1){
2764 this.push(node, tag, id, classes, attributes, pseudos);
2765 break;
2766 }
2767 },
2768
2769 '!^': function(node, tag, id, classes, attributes, pseudos){ // last chi ld
2770 node = node.lastChild;
2771 if (node){
2772 if (node.nodeType == 1) this.push(node, tag, id, classes , attributes, pseudos);
2773 else this['combinator:!+'](node, tag, id, classes, attri butes, pseudos);
2774 }
2775 },
2776
2777 '!~': function(node, tag, id, classes, attributes, pseudos){ // previous siblings
2778 while ((node = node.previousSibling)){
2779 if (node.nodeType != 1) continue;
2780 var uid = this.getUID(node);
2781 if (this.bitUniques[uid]) break;
2782 this.bitUniques[uid] = true;
2783 this.push(node, tag, id, classes, attributes, pseudos);
2784 }
2785 }
2786
2787 };
2788
2789 for (var c in combinators) local['combinator:' + c] = combinators[c];
2790
2791 var pseudos = {
2792
2793 /*<pseudo-selectors>*/
2794
2795 'empty': function(node){
2796 var child = node.firstChild;
2797 return !(child && child.nodeType == 1) && !(node.innerText || no de.textContent || '').length;
2798 },
2799
2800 'not': function(node, expression){
2801 return !this.matchNode(node, expression);
2802 },
2803
2804 'contains': function(node, text){
2805 return (node.innerText || node.textContent || '').indexOf(text) > -1;
2806 },
2807
2808 'first-child': function(node){
2809 while ((node = node.previousSibling)) if (node.nodeType == 1) re turn false;
2810 return true;
2811 },
2812
2813 'last-child': function(node){
2814 while ((node = node.nextSibling)) if (node.nodeType == 1) return false;
2815 return true;
2816 },
2817
2818 'only-child': function(node){
2819 var prev = node;
2820 while ((prev = prev.previousSibling)) if (prev.nodeType == 1) re turn false;
2821 var next = node;
2822 while ((next = next.nextSibling)) if (next.nodeType == 1) return false;
2823 return true;
2824 },
2825
2826 /*<nth-pseudo-selectors>*/
2827
2828 'nth-child': local.createNTHPseudo('firstChild', 'nextSibling', 'posNTH' ),
2829
2830 'nth-last-child': local.createNTHPseudo('lastChild', 'previousSibling', 'posNTHLast'),
2831
2832 'nth-of-type': local.createNTHPseudo('firstChild', 'nextSibling', 'posNT HType', true),
2833
2834 'nth-last-of-type': local.createNTHPseudo('lastChild', 'previousSibling' , 'posNTHTypeLast', true),
2835
2836 'index': function(node, index){
2837 return this['pseudo:nth-child'](node, '' + index + 1);
2838 },
2839
2840 'even': function(node){
2841 return this['pseudo:nth-child'](node, '2n');
2842 },
2843
2844 'odd': function(node){
2845 return this['pseudo:nth-child'](node, '2n+1');
2846 },
2847
2848 /*</nth-pseudo-selectors>*/
2849
2850 /*<of-type-pseudo-selectors>*/
2851
2852 'first-of-type': function(node){
2853 var nodeName = node.nodeName;
2854 while ((node = node.previousSibling)) if (node.nodeName == nodeN ame) return false;
2855 return true;
2856 },
2857
2858 'last-of-type': function(node){
2859 var nodeName = node.nodeName;
2860 while ((node = node.nextSibling)) if (node.nodeName == nodeName) return false;
2861 return true;
2862 },
2863
2864 'only-of-type': function(node){
2865 var prev = node, nodeName = node.nodeName;
2866 while ((prev = prev.previousSibling)) if (prev.nodeName == nodeN ame) return false;
2867 var next = node;
2868 while ((next = next.nextSibling)) if (next.nodeName == nodeName) return false;
2869 return true;
2870 },
2871
2872 /*</of-type-pseudo-selectors>*/
2873
2874 // custom pseudos
2875
2876 'enabled': function(node){
2877 return !node.disabled;
2878 },
2879
2880 'disabled': function(node){
2881 return node.disabled;
2882 },
2883
2884 'checked': function(node){
2885 return node.checked || node.selected;
2886 },
2887
2888 'focus': function(node){
2889 return this.isHTMLDocument && this.document.activeElement === no de && (node.href || node.type || this.hasAttribute(node, 'tabindex'));
2890 },
2891
2892 'root': function(node){
2893 return (node === this.root);
2894 },
2895
2896 'selected': function(node){
2897 return node.selected;
2898 }
2899
2900 /*</pseudo-selectors>*/
2901 };
2902
2903 for (var p in pseudos) local['pseudo:' + p] = pseudos[p];
2904
2905 // attributes methods
2906
2907 var attributeGetters = local.attributeGetters = {
2908
2909 'class': function(){
2910 return this.getAttribute('class') || this.className;
2911 },
2912
2913 'for': function(){
2914 return ('htmlFor' in this) ? this.htmlFor : this.getAttribute('f or');
2915 },
2916
2917 'href': function(){
2918 return ('href' in this) ? this.getAttribute('href', 2) : this.ge tAttribute('href');
2919 },
2920
2921 'style': function(){
2922 return (this.style) ? this.style.cssText : this.getAttribute('st yle');
2923 },
2924
2925 'tabindex': function(){
2926 var attributeNode = this.getAttributeNode('tabindex');
2927 return (attributeNode && attributeNode.specified) ? attributeNod e.nodeValue : null;
2928 },
2929
2930 'type': function(){
2931 return this.getAttribute('type');
2932 },
2933
2934 'maxlength': function(){
2935 var attributeNode = this.getAttributeNode('maxLength');
2936 return (attributeNode && attributeNode.specified) ? attributeNod e.nodeValue : null;
2937 }
2938
2939 };
2940
2941 attributeGetters.MAXLENGTH = attributeGetters.maxLength = attributeGetters.maxle ngth;
2942
2943 // Slick
2944
2945 var Slick = local.Slick = (this.Slick || {});
2946
2947 Slick.version = '1.1.6';
2948
2949 // Slick finder
2950
2951 Slick.search = function(context, expression, append){
2952 return local.search(context, expression, append);
2953 };
2954
2955 Slick.find = function(context, expression){
2956 return local.search(context, expression, null, true);
2957 };
2958
2959 // Slick containment checker
2960
2961 Slick.contains = function(container, node){
2962 local.setDocument(container);
2963 return local.contains(container, node);
2964 };
2965
2966 // Slick attribute getter
2967
2968 Slick.getAttribute = function(node, name){
2969 local.setDocument(node);
2970 return local.getAttribute(node, name);
2971 };
2972
2973 Slick.hasAttribute = function(node, name){
2974 local.setDocument(node);
2975 return local.hasAttribute(node, name);
2976 };
2977
2978 // Slick matcher
2979
2980 Slick.match = function(node, selector){
2981 if (!(node && selector)) return false;
2982 if (!selector || selector === node) return true;
2983 local.setDocument(node);
2984 return local.matchNode(node, selector);
2985 };
2986
2987 // Slick attribute accessor
2988
2989 Slick.defineAttributeGetter = function(name, fn){
2990 local.attributeGetters[name] = fn;
2991 return this;
2992 };
2993
2994 Slick.lookupAttributeGetter = function(name){
2995 return local.attributeGetters[name];
2996 };
2997
2998 // Slick pseudo accessor
2999
3000 Slick.definePseudo = function(name, fn){
3001 local['pseudo:' + name] = function(node, argument){
3002 return fn.call(node, argument);
3003 };
3004 return this;
3005 };
3006
3007 Slick.lookupPseudo = function(name){
3008 var pseudo = local['pseudo:' + name];
3009 if (pseudo) return function(argument){
3010 return pseudo.call(this, argument);
3011 };
3012 return null;
3013 };
3014
3015 // Slick overrides accessor
3016
3017 Slick.override = function(regexp, fn){
3018 local.override(regexp, fn);
3019 return this;
3020 };
3021
3022 Slick.isXML = local.isXML;
3023
3024 Slick.uidOf = function(node){
3025 return local.getUIDHTML(node);
3026 };
3027
3028 if (!this.Slick) this.Slick = Slick;
3029
3030 }).apply(/*<CommonJS>*/(typeof exports != 'undefined') ? exports : /*</CommonJS> */this);
3031
3032
3033 /*
3034 ---
3035
3036 name: Element
3037
3038 description: One of the most important items in MooTools. Contains the dollar fu nction, the dollars function, and an handful of cross-browser, time-saver method s to let you easily work with HTML Elements.
3039
3040 license: MIT-style license.
3041
3042 requires: [Window, Document, Array, String, Function, Object, Number, Slick.Pars er, Slick.Finder]
3043
3044 provides: [Element, Elements, $, $$, Iframe, Selectors]
3045
3046 ...
3047 */
3048
3049 var Element = function(tag, props){
3050 var konstructor = Element.Constructors[tag];
3051 if (konstructor) return konstructor(props);
3052 if (typeof tag != 'string') return document.id(tag).set(props);
3053
3054 if (!props) props = {};
3055
3056 if (!(/^[\w-]+$/).test(tag)){
3057 var parsed = Slick.parse(tag).expressions[0][0];
3058 tag = (parsed.tag == '*') ? 'div' : parsed.tag;
3059 if (parsed.id && props.id == null) props.id = parsed.id;
3060
3061 var attributes = parsed.attributes;
3062 if (attributes) for (var attr, i = 0, l = attributes.length; i < l; i++){
3063 attr = attributes[i];
3064 if (props[attr.key] != null) continue;
3065
3066 if (attr.value != null && attr.operator == '=') props[at tr.key] = attr.value;
3067 else if (!attr.value && !attr.operator) props[attr.key] = true;
3068 }
3069
3070 if (parsed.classList && props['class'] == null) props['class'] = parsed.classList.join(' ');
3071 }
3072
3073 return document.newElement(tag, props);
3074 };
3075
3076 if (Browser.Element) Element.prototype = Browser.Element.prototype;
3077
3078 new Type('Element', Element).mirror(function(name){
3079 if (Array.prototype[name]) return;
3080
3081 var obj = {};
3082 obj[name] = function(){
3083 var results = [], args = arguments, elements = true;
3084 for (var i = 0, l = this.length; i < l; i++){
3085 var element = this[i], result = results[i] = element[nam e].apply(element, args);
3086 elements = (elements && typeOf(result) == 'element');
3087 }
3088 return (elements) ? new Elements(results) : results;
3089 };
3090
3091 Elements.implement(obj);
3092 });
3093
3094 if (!Browser.Element){
3095 Element.parent = Object;
3096
3097 Element.Prototype = {'$family': Function.from('element').hide()};
3098
3099 Element.mirror(function(name, method){
3100 Element.Prototype[name] = method;
3101 });
3102 }
3103
3104 Element.Constructors = {};
3105
3106 //<1.2compat>
1293 3107
1294 Element.Constructors = new Hash; 3108 Element.Constructors = new Hash;
1295 3109
1296 var IFrame = new Native({ 3110 //</1.2compat>
1297 3111
1298 » name: 'IFrame', 3112 var IFrame = new Type('IFrame', function(){
1299 3113 » var params = Array.link(arguments, {
1300 » generics: false, 3114 » » properties: Type.isObject,
1301 3115 » » iframe: function(obj){
1302 » initialize: function(){ 3116 » » » return (obj != null);
1303 » » var params = Array.link(arguments, {properties: Object.type, ifr ame: $defined}); 3117 » » }
1304 » » var props = params.properties || {}; 3118 » });
1305 » » var iframe = $(params.iframe) || false; 3119
1306 » » var onload = props.onload || $empty; 3120 » var props = params.properties || {}, iframe;
1307 » » delete props.onload; 3121 » if (params.iframe) iframe = document.id(params.iframe);
1308 » » props.id = props.name = $pick(props.id, props.name, iframe.id, i frame.name, 'IFrame_' + $time()); 3122 » var onload = props.onload || function(){};
1309 » » iframe = new Element(iframe || 'iframe', props); 3123 » delete props.onload;
1310 » » var onFrameLoad = function(){ 3124 » props.id = props.name = [props.id, props.name, iframe ? (iframe.id || if rame.name) : 'IFrame_' + String.uniqueID()].pick();
1311 » » » var host = $try(function(){ 3125 » iframe = new Element(iframe || 'iframe', props);
1312 » » » » return iframe.contentWindow.location.host; 3126
1313 » » » }); 3127 » var onLoad = function(){
1314 » » » if (host && host == window.location.host){ 3128 » » onload.call(iframe.contentWindow);
1315 » » » » var win = new Window(iframe.contentWindow); 3129 » };
1316 » » » » new Document(iframe.contentWindow.document); 3130
1317 » » » » $extend(win.Element.prototype, Element.Prototype ); 3131 » if (window.frames[props.id]) onLoad();
3132 » else iframe.addListener('load', onLoad);
3133 » return iframe;
3134 });
3135
3136 var Elements = this.Elements = function(nodes){
3137 » if (nodes && nodes.length){
3138 » » var uniques = {}, node;
3139 » » for (var i = 0; node = nodes[i++];){
3140 » » » var uid = Slick.uidOf(node);
3141 » » » if (!uniques[uid]){
3142 » » » » uniques[uid] = true;
3143 » » » » this.push(node);
1318 } 3144 }
1319 » » » onload.call(iframe.contentWindow, iframe.contentWindow.d ocument); 3145 » » }
1320 » » }; 3146 » }
1321 » » (window.frames[props.id]) ? onFrameLoad() : iframe.addListener(' load', onFrameLoad); 3147 };
1322 » » return iframe; 3148
1323 » } 3149 Elements.prototype = {length: 0};
1324 3150 Elements.parent = Array;
1325 }); 3151
1326 3152 new Type('Elements', Elements).implement({
1327 var Elements = new Native({
1328
1329 » initialize: function(elements, options){
1330 » » options = $extend({ddup: true, cash: true}, options);
1331 » » elements = elements || [];
1332 » » if (options.ddup || options.cash){
1333 » » » var uniques = {}, returned = [];
1334 » » » for (var i = 0, l = elements.length; i < l; i++){
1335 » » » » var el = $.element(elements[i], !options.cash);
1336 » » » » if (options.ddup){
1337 » » » » » if (uniques[el.uid]) continue;
1338 » » » » » uniques[el.uid] = true;
1339 » » » » }
1340 » » » » returned.push(el);
1341 » » » }
1342 » » » elements = returned;
1343 » » }
1344 » » return (options.cash) ? $extend(elements, this) : elements;
1345 » }
1346
1347 });
1348
1349 Elements.implement({
1350 3153
1351 filter: function(filter, bind){ 3154 filter: function(filter, bind){
1352 if (!filter) return this; 3155 if (!filter) return this;
1353 » » return new Elements(Array.filter(this, (typeof filter == 'string ') ? function(item){ 3156 » » return new Elements(Array.filter(this, (typeOf(filter) == 'strin g') ? function(item){
1354 return item.match(filter); 3157 return item.match(filter);
1355 } : filter, bind)); 3158 } : filter, bind));
1356 » } 3159 » }.protect(),
1357 3160
1358 }); 3161 » push: function(){
3162 » » var length = this.length;
3163 » » for (var i = 0, l = arguments.length; i < l; i++){
3164 » » » var item = document.id(arguments[i]);
3165 » » » if (item) this[length++] = item;
3166 » » }
3167 » » return (this.length = length);
3168 » }.protect(),
3169
3170 » unshift: function(){
3171 » » var items = [];
3172 » » for (var i = 0, l = arguments.length; i < l; i++){
3173 » » » var item = document.id(arguments[i]);
3174 » » » if (item) items.push(item);
3175 » » }
3176 » » return Array.prototype.unshift.apply(this, items);
3177 » }.protect(),
3178
3179 » concat: function(){
3180 » » var newElements = new Elements(this);
3181 » » for (var i = 0, l = arguments.length; i < l; i++){
3182 » » » var item = arguments[i];
3183 » » » if (Type.isEnumerable(item)) newElements.append(item);
3184 » » » else newElements.push(item);
3185 » » }
3186 » » return newElements;
3187 » }.protect(),
3188
3189 » append: function(collection){
3190 » » for (var i = 0, l = collection.length; i < l; i++) this.push(col lection[i]);
3191 » » return this;
3192 » }.protect(),
3193
3194 » empty: function(){
3195 » » while (this.length) delete this[--this.length];
3196 » » return this;
3197 » }.protect()
3198
3199 });
3200
3201 //<1.2compat>
3202
3203 Elements.alias('extend', 'append');
3204
3205 //</1.2compat>
3206
3207 (function(){
3208
3209 // FF, IE
3210 var splice = Array.prototype.splice, object = {'0': 0, '1': 1, length: 2};
3211
3212 splice.call(object, 1, 1);
3213 if (object[1] == 1) Elements.implement('splice', function(){
3214 » var length = this.length;
3215 » var result = splice.apply(this, arguments);
3216 » while (length >= this.length) delete this[length--];
3217 » return result;
3218 }.protect());
3219
3220 Elements.implement(Array.prototype);
3221
3222 Array.mirror(Elements);
3223
3224 /*<ltIE8>*/
3225 var createElementAcceptsHTML;
3226 try {
3227 » var x = document.createElement('<input name=x>');
3228 » createElementAcceptsHTML = (x.name == 'x');
3229 } catch(e){}
3230
3231 var escapeQuotes = function(html){
3232 » return ('' + html).replace(/&/g, '&amp;').replace(/"/g, '&quot;');
3233 };
3234 /*</ltIE8>*/
1359 3235
1360 Document.implement({ 3236 Document.implement({
1361 3237
1362 newElement: function(tag, props){ 3238 newElement: function(tag, props){
1363 » » if (Browser.Engine.trident && props){ 3239 » » if (props && props.checked != null) props.defaultChecked = props .checked;
1364 » » » ['name', 'type', 'checked'].each(function(attribute){ 3240 » » /*<ltIE8>*/// Fix for readonly name and type properties in IE < 8
1365 » » » » if (!props[attribute]) return; 3241 » » if (createElementAcceptsHTML && props){
1366 » » » » tag += ' ' + attribute + '="' + props[attribute] + '"'; 3242 » » » tag = '<' + tag;
1367 » » » » if (attribute != 'checked') delete props[attribu te]; 3243 » » » if (props.name) tag += ' name="' + escapeQuotes(props.na me) + '"';
1368 » » » }); 3244 » » » if (props.type) tag += ' type="' + escapeQuotes(props.ty pe) + '"';
1369 » » » tag = '<' + tag + '>'; 3245 » » » tag += '>';
1370 » » } 3246 » » » delete props.name;
1371 » » return $.element(this.createElement(tag)).set(props); 3247 » » » delete props.type;
1372 » }, 3248 » » }
3249 » » /*</ltIE8>*/
3250 » » return this.id(this.createElement(tag)).set(props);
3251 » }
3252
3253 });
3254
3255 })();
3256
3257 Document.implement({
1373 3258
1374 newTextNode: function(text){ 3259 newTextNode: function(text){
1375 return this.createTextNode(text); 3260 return this.createTextNode(text);
1376 }, 3261 },
1377 3262
1378 getDocument: function(){ 3263 getDocument: function(){
1379 return this; 3264 return this;
1380 }, 3265 },
1381 3266
1382 getWindow: function(){ 3267 getWindow: function(){
1383 return this.window; 3268 return this.window;
1384 » } 3269 » },
1385 3270
3271 » id: (function(){
3272
3273 » » var types = {
3274
3275 » » » string: function(id, nocash, doc){
3276 » » » » id = Slick.find(doc, '#' + id.replace(/(\W)/g, ' \\$1'));
3277 » » » » return (id) ? types.element(id, nocash) : null;
3278 » » » },
3279
3280 » » » element: function(el, nocash){
3281 » » » » $uid(el);
3282 » » » » if (!nocash && !el.$family && !(/^(?:object|embe d)$/i).test(el.tagName)){
3283 » » » » » Object.append(el, Element.Prototype);
3284 » » » » }
3285 » » » » return el;
3286 » » » },
3287
3288 » » » object: function(obj, nocash, doc){
3289 » » » » if (obj.toElement) return types.element(obj.toEl ement(doc), nocash);
3290 » » » » return null;
3291 » » » }
3292
3293 » » };
3294
3295 » » types.textnode = types.whitespace = types.window = types.documen t = function(zero){
3296 » » » return zero;
3297 » » };
3298
3299 » » return function(el, nocash, doc){
3300 » » » if (el && el.$family && el.uid) return el;
3301 » » » var type = typeOf(el);
3302 » » » return (types[type]) ? types[type](el, nocash, doc || do cument) : null;
3303 » » };
3304
3305 » })()
3306
3307 });
3308
3309 if (window.$ == null) Window.implement('$', function(el, nc){
3310 » return document.id(el, nc, this.document);
1386 }); 3311 });
1387 3312
1388 Window.implement({ 3313 Window.implement({
1389 3314
1390 $: function(el, nocash){
1391 if (el && el.$family && el.uid) return el;
1392 var type = $type(el);
1393 return ($[type]) ? $[type](el, nocash, this.document) : null;
1394 },
1395
1396 $$: function(selector){
1397 if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector);
1398 var elements = [];
1399 var args = Array.flatten(arguments);
1400 for (var i = 0, l = args.length; i < l; i++){
1401 var item = args[i];
1402 switch ($type(item)){
1403 case 'element': elements.push(item); break;
1404 case 'string': elements.extend(this.document.get Elements(item, true));
1405 }
1406 }
1407 return new Elements(elements);
1408 },
1409
1410 getDocument: function(){ 3315 getDocument: function(){
1411 return this.document; 3316 return this.document;
1412 }, 3317 },
1413 3318
1414 getWindow: function(){ 3319 getWindow: function(){
1415 return this; 3320 return this;
1416 } 3321 }
1417 3322
1418 }); 3323 });
1419 3324
1420 $.string = function(id, nocash, doc){ 3325 [Document, Element].invoke('implement', {
1421 » id = doc.getElementById(id); 3326
1422 » return (id) ? $.element(id, nocash) : null; 3327 » getElements: function(expression){
1423 }; 3328 » » return Slick.search(this, expression, new Elements);
1424 3329 » },
1425 $.element = function(el, nocash){ 3330
1426 » $uid(el); 3331 » getElement: function(expression){
1427 » if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){ 3332 » » return document.id(Slick.find(this, expression));
1428 » » var proto = Element.Prototype; 3333 » }
1429 » » for (var p in proto) el[p] = proto[p]; 3334
3335 });
3336
3337 var contains = {contains: function(element){
3338 » return Slick.contains(this, element);
3339 }};
3340
3341 if (!document.contains) Document.implement(contains);
3342 if (!document.createElement('div').contains) Element.implement(contains);
3343
3344 //<1.2compat>
3345
3346 Element.implement('hasChild', function(element){
3347 » return this !== element && this.contains(element);
3348 });
3349
3350 (function(search, find, match){
3351
3352 » this.Selectors = {};
3353 » var pseudos = this.Selectors.Pseudo = new Hash();
3354
3355 » var addSlickPseudos = function(){
3356 » » for (var name in pseudos) if (pseudos.hasOwnProperty(name)){
3357 » » » Slick.definePseudo(name, pseudos[name]);
3358 » » » delete pseudos[name];
3359 » » }
1430 }; 3360 };
1431 » return el; 3361
1432 }; 3362 » Slick.search = function(context, expression, append){
1433 3363 » » addSlickPseudos();
1434 $.object = function(obj, nocash, doc){ 3364 » » return search.call(this, context, expression, append);
1435 » if (obj.toElement) return $.element(obj.toElement(doc), nocash); 3365 » };
1436 » return null; 3366
1437 }; 3367 » Slick.find = function(context, expression){
1438 3368 » » addSlickPseudos();
1439 $.textnode = $.whitespace = $.window = $.document = $arguments(0); 3369 » » return find.call(this, context, expression);
1440 3370 » };
1441 Native.implement([Element, Document], { 3371
1442 3372 » Slick.match = function(node, selector){
1443 » getElement: function(selector, nocash){ 3373 » » addSlickPseudos();
1444 » » return $(this.getElements(selector, true)[0] || null, nocash); 3374 » » return match.call(this, node, selector);
1445 » }, 3375 » };
1446 3376
1447 » getElements: function(tags, nocash){ 3377 })(Slick.search, Slick.find, Slick.match);
1448 » » tags = tags.split(','); 3378
1449 » » var elements = []; 3379 //</1.2compat>
1450 » » var ddup = (tags.length > 1); 3380
1451 » » tags.each(function(tag){ 3381 // tree walking
1452 » » » var partial = this.getElementsByTagName(tag.trim()); 3382
1453 » » » (ddup) ? elements.extend(partial) : elements = partial; 3383 var injectCombinator = function(expression, combinator){
1454 » » }, this); 3384 » if (!expression) return combinator;
1455 » » return new Elements(elements, {ddup: ddup, cash: !nocash}); 3385
1456 » } 3386 » expression = Object.clone(Slick.parse(expression));
1457 3387
3388 » var expressions = expression.expressions;
3389 » for (var i = expressions.length; i--;)
3390 » » expressions[i][0].combinator = combinator;
3391
3392 » return expression;
3393 };
3394
3395 Object.forEach({
3396 » getNext: '~',
3397 » getPrevious: '!~',
3398 » getParent: '!'
3399 }, function(combinator, method){
3400 » Element.implement(method, function(expression){
3401 » » return this.getElement(injectCombinator(expression, combinator)) ;
3402 » });
3403 });
3404
3405 Object.forEach({
3406 » getAllNext: '~',
3407 » getAllPrevious: '!~',
3408 » getSiblings: '~~',
3409 » getChildren: '>',
3410 » getParents: '!'
3411 }, function(combinator, method){
3412 » Element.implement(method, function(expression){
3413 » » return this.getElements(injectCombinator(expression, combinator) );
3414 » });
3415 });
3416
3417 Element.implement({
3418
3419 » getFirst: function(expression){
3420 » » return document.id(Slick.search(this, injectCombinator(expressio n, '>'))[0]);
3421 » },
3422
3423 » getLast: function(expression){
3424 » » return document.id(Slick.search(this, injectCombinator(expressio n, '>')).getLast());
3425 » },
3426
3427 » getWindow: function(){
3428 » » return this.ownerDocument.window;
3429 » },
3430
3431 » getDocument: function(){
3432 » » return this.ownerDocument;
3433 » },
3434
3435 » getElementById: function(id){
3436 » » return document.id(Slick.find(this, '#' + ('' + id).replace(/(\W )/g, '\\$1')));
3437 » },
3438
3439 » match: function(expression){
3440 » » return !expression || Slick.match(this, expression);
3441 » }
3442
3443 });
3444
3445 //<1.2compat>
3446
3447 if (window.$$ == null) Window.implement('$$', function(selector){
3448 » var elements = new Elements;
3449 » if (arguments.length == 1 && typeof selector == 'string') return Slick.s earch(this.document, selector, elements);
3450 » var args = Array.flatten(arguments);
3451 » for (var i = 0, l = args.length; i < l; i++){
3452 » » var item = args[i];
3453 » » switch (typeOf(item)){
3454 » » » case 'element': elements.push(item); break;
3455 » » » case 'string': Slick.search(this.document, item, element s);
3456 » » }
3457 » }
3458 » return elements;
3459 });
3460
3461 //</1.2compat>
3462
3463 if (window.$$ == null) Window.implement('$$', function(selector){
3464 » if (arguments.length == 1){
3465 » » if (typeof selector == 'string') return Slick.search(this.docume nt, selector, new Elements);
3466 » » else if (Type.isEnumerable(selector)) return new Elements(select or);
3467 » }
3468 » return new Elements(arguments);
1458 }); 3469 });
1459 3470
1460 (function(){ 3471 (function(){
1461 3472
1462 var collected = {}, storage = {}; 3473 // Inserters
1463 var props = {input: 'checked', option: 'selected', textarea: (Browser.Engine.web kit && Browser.Engine.version < 420) ? 'innerHTML' : 'value'};
1464
1465 var get = function(uid){
1466 » return (storage[uid] || (storage[uid] = {}));
1467 };
1468
1469 var clean = function(item, retain){
1470 » if (!item) return;
1471 » var uid = item.uid;
1472 » if (Browser.Engine.trident){
1473 » » if (item.clearAttributes){
1474 » » » var clone = retain && item.cloneNode(false);
1475 » » » item.clearAttributes();
1476 » » » if (clone) item.mergeAttributes(clone);
1477 » » } else if (item.removeEvents){
1478 » » » item.removeEvents();
1479 » » }
1480 » » if ((/object/i).test(item.tagName)){
1481 » » » for (var p in item){
1482 » » » » if (typeof item[p] == 'function') item[p] = $emp ty;
1483 » » » }
1484 » » » Element.dispose(item);
1485 » » }
1486 » }»
1487 » if (!uid) return;
1488 » collected[uid] = storage[uid] = null;
1489 };
1490
1491 var purge = function(){
1492 » Hash.each(collected, clean);
1493 » if (Browser.Engine.trident) $A(document.getElementsByTagName('object')). each(clean);
1494 » if (window.CollectGarbage) CollectGarbage();
1495 » collected = storage = null;
1496 };
1497
1498 var walk = function(element, walk, start, match, all, nocash){
1499 » var el = element[start || walk];
1500 » var elements = [];
1501 » while (el){
1502 » » if (el.nodeType == 1 && (!match || Element.match(el, match))){
1503 » » » if (!all) return $(el, nocash);
1504 » » » elements.push(el);
1505 » » }
1506 » » el = el[walk];
1507 » }
1508 » return (all) ? new Elements(elements, {ddup: false, cash: !nocash}) : nu ll;
1509 };
1510
1511 var attributes = {
1512 » 'html': 'innerHTML',
1513 » 'class': 'className',
1514 » 'for': 'htmlFor',
1515 » 'text': (Browser.Engine.trident || (Browser.Engine.webkit && Browser.Eng ine.version < 420)) ? 'innerText' : 'textContent'
1516 };
1517 var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'dis abled', 'readonly', 'multiple', 'selected', 'noresize', 'defer'];
1518 var camels = ['value', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'fr ameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap'];
1519
1520 Hash.extend(attributes, bools.associate(bools));
1521 Hash.extend(attributes, camels.associate(camels.map(String.toLowerCase)));
1522 3474
1523 var inserters = { 3475 var inserters = {
1524 3476
1525 before: function(context, element){ 3477 before: function(context, element){
1526 » » if (element.parentNode) element.parentNode.insertBefore(context, element); 3478 » » var parent = element.parentNode;
3479 » » if (parent) parent.insertBefore(context, element);
1527 }, 3480 },
1528 3481
1529 after: function(context, element){ 3482 after: function(context, element){
1530 » » if (!element.parentNode) return; 3483 » » var parent = element.parentNode;
1531 » » var next = element.nextSibling; 3484 » » if (parent) parent.insertBefore(context, element.nextSibling);
1532 » » (next) ? element.parentNode.insertBefore(context, next) : elemen t.parentNode.appendChild(context);
1533 }, 3485 },
1534 3486
1535 bottom: function(context, element){ 3487 bottom: function(context, element){
1536 element.appendChild(context); 3488 element.appendChild(context);
1537 }, 3489 },
1538 3490
1539 top: function(context, element){ 3491 top: function(context, element){
1540 » » var first = element.firstChild; 3492 » » element.insertBefore(context, element.firstChild);
1541 » » (first) ? element.insertBefore(context, first) : element.appendC hild(context);
1542 } 3493 }
1543 3494
1544 }; 3495 };
1545 3496
1546 inserters.inside = inserters.bottom; 3497 inserters.inside = inserters.bottom;
1547 3498
1548 Hash.each(inserters, function(inserter, where){ 3499 //<1.2compat>
3500
3501 Object.each(inserters, function(inserter, where){
1549 3502
1550 where = where.capitalize(); 3503 where = where.capitalize();
1551 3504
1552 » Element.implement('inject' + where, function(el){ 3505 » var methods = {};
1553 » » inserter(this, $(el, true)); 3506
1554 » » return this; 3507 » methods['inject' + where] = function(el){
1555 » }); 3508 » » inserter(this, document.id(el, true));
1556 3509 » » return this;
1557 » Element.implement('grab' + where, function(el){ 3510 » };
1558 » » inserter($(el, true), this); 3511
1559 » » return this; 3512 » methods['grab' + where] = function(el){
1560 » }); 3513 » » inserter(document.id(el, true), this);
1561 3514 » » return this;
1562 }); 3515 » };
3516
3517 » Element.implement(methods);
3518
3519 });
3520
3521 //</1.2compat>
3522
3523 // getProperty / setProperty
3524
3525 var propertyGetters = {}, propertySetters = {};
3526
3527 // properties
3528
3529 var properties = {};
3530 Array.forEach([
3531 » 'type', 'value', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacin g', 'colSpan',
3532 » 'frameBorder', 'readOnly', 'rowSpan', 'tabIndex', 'useMap'
3533 ], function(property){
3534 » properties[property.toLowerCase()] = property;
3535 });
3536
3537 Object.append(properties, {
3538 » 'html': 'innerHTML',
3539 » 'text': (function(){
3540 » » var temp = document.createElement('div');
3541 » » return (temp.textContent == null) ? 'innerText': 'textContent';
3542 » })()
3543 });
3544
3545 Object.forEach(properties, function(real, key){
3546 » propertySetters[key] = function(node, value){
3547 » » node[real] = value;
3548 » };
3549 » propertyGetters[key] = function(node){
3550 » » return node[real];
3551 » };
3552 });
3553
3554 // Booleans
3555
3556 var bools = [
3557 » 'compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked',
3558 » 'disabled', 'readOnly', 'multiple', 'selected', 'noresize',
3559 » 'defer', 'defaultChecked', 'autofocus', 'controls', 'autoplay',
3560 » 'loop'
3561 ];
3562
3563 var booleans = {};
3564 Array.forEach(bools, function(bool){
3565 » var lower = bool.toLowerCase();
3566 » booleans[lower] = bool;
3567 » propertySetters[lower] = function(node, value){
3568 » » node[bool] = !!value;
3569 » };
3570 » propertyGetters[lower] = function(node){
3571 » » return !!node[bool];
3572 » };
3573 });
3574
3575 // Special cases
3576
3577 Object.append(propertySetters, {
3578
3579 » 'class': function(node, value){
3580 » » ('className' in node) ? node.className = value : node.setAttribu te('class', value);
3581 » },
3582
3583 » 'for': function(node, value){
3584 » » ('htmlFor' in node) ? node.htmlFor = value : node.setAttribute(' for', value);
3585 » },
3586
3587 » 'style': function(node, value){
3588 » » (node.style) ? node.style.cssText = value : node.setAttribute('s tyle', value);
3589 » }
3590
3591 });
3592
3593 /* getProperty, setProperty */
1563 3594
1564 Element.implement({ 3595 Element.implement({
1565 3596
1566 » set: function(prop, value){ 3597 » setProperty: function(name, value){
1567 » » switch ($type(prop)){ 3598 » » var lower = name.toLowerCase();
1568 » » » case 'object': 3599 » » if (value == null){
1569 » » » » for (var p in prop) this.set(p, prop[p]); 3600 » » » if (!booleans[lower]){
1570 » » » » break; 3601 » » » » this.removeAttribute(name);
1571 » » » case 'string': 3602 » » » » return this;
1572 » » » » var property = Element.Properties.get(prop); 3603 » » » }
1573 » » » » (property && property.set) ? property.set.apply( this, Array.slice(arguments, 1)) : this.setProperty(prop, value); 3604 » » » value = false;
1574 » » } 3605 » » }
1575 » » return this; 3606 » » var setter = propertySetters[lower];
1576 » }, 3607 » » if (setter) setter(this, value);
1577 3608 » » else this.setAttribute(name, value);
1578 » get: function(prop){
1579 » » var property = Element.Properties.get(prop);
1580 » » return (property && property.get) ? property.get.apply(this, Arr ay.slice(arguments, 1)) : this.getProperty(prop);
1581 » },
1582
1583 » erase: function(prop){
1584 » » var property = Element.Properties.get(prop);
1585 » » (property && property.erase) ? property.erase.apply(this) : this .removeProperty(prop);
1586 » » return this;
1587 » },
1588
1589 » setProperty: function(attribute, value){
1590 » » var key = attributes[attribute];
1591 » » if (value == undefined) return this.removeProperty(attribute);
1592 » » if (key && bools[attribute]) value = !!value;
1593 » » (key) ? this[key] = value : this.setAttribute(attribute, '' + va lue);
1594 return this; 3609 return this;
1595 }, 3610 },
1596 3611
1597 setProperties: function(attributes){ 3612 setProperties: function(attributes){
1598 for (var attribute in attributes) this.setProperty(attribute, at tributes[attribute]); 3613 for (var attribute in attributes) this.setProperty(attribute, at tributes[attribute]);
1599 return this; 3614 return this;
1600 }, 3615 },
1601 3616
1602 » getProperty: function(attribute){ 3617 » getProperty: function(name){
1603 » » var key = attributes[attribute]; 3618 » » var getter = propertyGetters[name.toLowerCase()];
1604 » » var value = (key) ? this[key] : this.getAttribute(attribute, 2); 3619 » » if (getter) return getter(this);
1605 » » return (bools[attribute]) ? !!value : (key) ? value : value || n ull; 3620 » » var result = Slick.getAttribute(this, name);
3621 » » return (!result && !Slick.hasAttribute(this, name)) ? null : res ult;
1606 }, 3622 },
1607 3623
1608 getProperties: function(){ 3624 getProperties: function(){
1609 » » var args = $A(arguments); 3625 » » var args = Array.from(arguments);
1610 return args.map(this.getProperty, this).associate(args); 3626 return args.map(this.getProperty, this).associate(args);
1611 }, 3627 },
1612 3628
1613 » removeProperty: function(attribute){ 3629 » removeProperty: function(name){
1614 » » var key = attributes[attribute]; 3630 » » return this.setProperty(name, null);
1615 » » (key) ? this[key] = (key && bools[attribute]) ? false : '' : thi s.removeAttribute(attribute);
1616 » » return this;
1617 }, 3631 },
1618 3632
1619 removeProperties: function(){ 3633 removeProperties: function(){
1620 Array.each(arguments, this.removeProperty, this); 3634 Array.each(arguments, this.removeProperty, this);
1621 return this; 3635 return this;
1622 }, 3636 },
1623 3637
3638 set: function(prop, value){
3639 var property = Element.Properties[prop];
3640 (property && property.set) ? property.set.call(this, value) : th is.setProperty(prop, value);
3641 }.overloadSetter(),
3642
3643 get: function(prop){
3644 var property = Element.Properties[prop];
3645 return (property && property.get) ? property.get.apply(this) : t his.getProperty(prop);
3646 }.overloadGetter(),
3647
3648 erase: function(prop){
3649 var property = Element.Properties[prop];
3650 (property && property.erase) ? property.erase.apply(this) : this .removeProperty(prop);
3651 return this;
3652 },
3653
1624 hasClass: function(className){ 3654 hasClass: function(className){
1625 » » return this.className.contains(className, ' '); 3655 » » return this.className.clean().contains(className, ' ');
1626 }, 3656 },
1627 3657
1628 addClass: function(className){ 3658 addClass: function(className){
1629 if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); 3659 if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean();
1630 return this; 3660 return this;
1631 }, 3661 },
1632 3662
1633 removeClass: function(className){ 3663 removeClass: function(className){
1634 this.className = this.className.replace(new RegExp('(^|\\s)' + c lassName + '(?:\\s|$)'), '$1'); 3664 this.className = this.className.replace(new RegExp('(^|\\s)' + c lassName + '(?:\\s|$)'), '$1');
1635 return this; 3665 return this;
1636 }, 3666 },
1637 3667
1638 » toggleClass: function(className){ 3668 » toggleClass: function(className, force){
1639 » » return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); 3669 » » if (force == null) force = !this.hasClass(className);
3670 » » return (force) ? this.addClass(className) : this.removeClass(cla ssName);
1640 }, 3671 },
1641 3672
1642 adopt: function(){ 3673 adopt: function(){
1643 » » Array.flatten(arguments).each(function(element){ 3674 » » var parent = this, fragment, elements = Array.flatten(arguments) , length = elements.length;
1644 » » » element = $(element, true); 3675 » » if (length > 1) parent = fragment = document.createDocumentFragm ent();
1645 » » » if (element) this.appendChild(element); 3676
1646 » » }, this); 3677 » » for (var i = 0; i < length; i++){
3678 » » » var element = document.id(elements[i], true);
3679 » » » if (element) parent.appendChild(element);
3680 » » }
3681
3682 » » if (fragment) this.appendChild(fragment);
3683
1647 return this; 3684 return this;
1648 }, 3685 },
1649 3686
1650 appendText: function(text, where){ 3687 appendText: function(text, where){
1651 return this.grab(this.getDocument().newTextNode(text), where); 3688 return this.grab(this.getDocument().newTextNode(text), where);
1652 }, 3689 },
1653 3690
1654 grab: function(el, where){ 3691 grab: function(el, where){
1655 » » inserters[where || 'bottom']($(el, true), this); 3692 » » inserters[where || 'bottom'](document.id(el, true), this);
1656 return this; 3693 return this;
1657 }, 3694 },
1658 3695
1659 inject: function(el, where){ 3696 inject: function(el, where){
1660 » » inserters[where || 'bottom'](this, $(el, true)); 3697 » » inserters[where || 'bottom'](this, document.id(el, true));
1661 return this; 3698 return this;
1662 }, 3699 },
1663 3700
1664 replaces: function(el){ 3701 replaces: function(el){
1665 » » el = $(el, true); 3702 » » el = document.id(el, true);
1666 el.parentNode.replaceChild(this, el); 3703 el.parentNode.replaceChild(this, el);
1667 return this; 3704 return this;
1668 }, 3705 },
1669 3706
1670 wraps: function(el, where){ 3707 wraps: function(el, where){
1671 » » el = $(el, true); 3708 » » el = document.id(el, true);
1672 return this.replaces(el).grab(el, where); 3709 return this.replaces(el).grab(el, where);
1673 }, 3710 },
1674 3711
1675 getPrevious: function(match, nocash){
1676 return walk(this, 'previousSibling', null, match, false, nocash) ;
1677 },
1678
1679 getAllPrevious: function(match, nocash){
1680 return walk(this, 'previousSibling', null, match, true, nocash);
1681 },
1682
1683 getNext: function(match, nocash){
1684 return walk(this, 'nextSibling', null, match, false, nocash);
1685 },
1686
1687 getAllNext: function(match, nocash){
1688 return walk(this, 'nextSibling', null, match, true, nocash);
1689 },
1690
1691 getFirst: function(match, nocash){
1692 return walk(this, 'nextSibling', 'firstChild', match, false, noc ash);
1693 },
1694
1695 getLast: function(match, nocash){
1696 return walk(this, 'previousSibling', 'lastChild', match, false, nocash);
1697 },
1698
1699 getParent: function(match, nocash){
1700 return walk(this, 'parentNode', null, match, false, nocash);
1701 },
1702
1703 getParents: function(match, nocash){
1704 return walk(this, 'parentNode', null, match, true, nocash);
1705 },
1706
1707 getChildren: function(match, nocash){
1708 return walk(this, 'nextSibling', 'firstChild', match, true, noca sh);
1709 },
1710
1711 getWindow: function(){
1712 return this.ownerDocument.window;
1713 },
1714
1715 getDocument: function(){
1716 return this.ownerDocument;
1717 },
1718
1719 getElementById: function(id, nocash){
1720 var el = this.ownerDocument.getElementById(id);
1721 if (!el) return null;
1722 for (var parent = el.parentNode; parent != this; parent = parent .parentNode){
1723 if (!parent) return null;
1724 }
1725 return $.element(el, nocash);
1726 },
1727
1728 getSelected: function(){ 3712 getSelected: function(){
1729 » » return new Elements($A(this.options).filter(function(option){ 3713 » » this.selectedIndex; // Safari 3.2.1
3714 » » return new Elements(Array.from(this.options).filter(function(opt ion){
1730 return option.selected; 3715 return option.selected;
1731 })); 3716 }));
1732 }, 3717 },
1733 3718
1734 getComputedStyle: function(property){
1735 if (this.currentStyle) return this.currentStyle[property.camelCa se()];
1736 var computed = this.getDocument().defaultView.getComputedStyle(t his, null);
1737 return (computed) ? computed.getPropertyValue([property.hyphenat e()]) : null;
1738 },
1739
1740 toQueryString: function(){ 3719 toQueryString: function(){
1741 var queryString = []; 3720 var queryString = [];
1742 » » this.getElements('input, select, textarea', true).each(function( el){ 3721 » » this.getElements('input, select, textarea').each(function(el){
1743 » » » if (!el.name || el.disabled) return; 3722 » » » var type = el.type;
1744 » » » var value = (el.tagName.toLowerCase() == 'select') ? Ele ment.getSelected(el).map(function(opt){ 3723 » » » if (!el.name || el.disabled || type == 'submit' || type == 'reset' || type == 'file' || type == 'image') return;
1745 » » » » return opt.value; 3724
1746 » » » }) : ((el.type == 'radio' || el.type == 'checkbox') && ! el.checked) ? null : el.value; 3725 » » » var value = (el.get('tag') == 'select') ? el.getSelected ().map(function(opt){
1747 » » » $splat(value).each(function(val){ 3726 » » » » // IE
1748 » » » » if (typeof val != 'undefined') queryString.push( el.name + '=' + encodeURIComponent(val)); 3727 » » » » return document.id(opt).get('value');
3728 » » » }) : ((type == 'radio' || type == 'checkbox') && !el.che cked) ? null : el.get('value');
3729
3730 » » » Array.from(value).each(function(val){
3731 » » » » if (typeof val != 'undefined') queryString.push( encodeURIComponent(el.name) + '=' + encodeURIComponent(val));
1749 }); 3732 });
1750 }); 3733 });
1751 return queryString.join('&'); 3734 return queryString.join('&');
3735 }
3736
3737 });
3738
3739 var collected = {}, storage = {};
3740
3741 var get = function(uid){
3742 return (storage[uid] || (storage[uid] = {}));
3743 };
3744
3745 var clean = function(item){
3746 var uid = item.uid;
3747 if (item.removeEvents) item.removeEvents();
3748 if (item.clearAttributes) item.clearAttributes();
3749 if (uid != null){
3750 delete collected[uid];
3751 delete storage[uid];
3752 }
3753 return item;
3754 };
3755
3756 var formProps = {input: 'checked', option: 'selected', textarea: 'value'};
3757
3758 Element.implement({
3759
3760 destroy: function(){
3761 var children = clean(this).getElementsByTagName('*');
3762 Array.each(children, clean);
3763 Element.dispose(this);
3764 return null;
3765 },
3766
3767 empty: function(){
3768 Array.from(this.childNodes).each(Element.dispose);
3769 return this;
3770 },
3771
3772 dispose: function(){
3773 return (this.parentNode) ? this.parentNode.removeChild(this) : t his;
1752 }, 3774 },
1753 3775
1754 clone: function(contents, keepid){ 3776 clone: function(contents, keepid){
1755 contents = contents !== false; 3777 contents = contents !== false;
1756 » » var clone = this.cloneNode(contents); 3778 » » var clone = this.cloneNode(contents), ce = [clone], te = [this], i;
1757 » » var clean = function(node, element){ 3779
3780 » » if (contents){
3781 » » » ce.append(Array.from(clone.getElementsByTagName('*')));
3782 » » » te.append(Array.from(this.getElementsByTagName('*')));
3783 » » }
3784
3785 » » for (i = ce.length; i--;){
3786 » » » var node = ce[i], element = te[i];
1758 if (!keepid) node.removeAttribute('id'); 3787 if (!keepid) node.removeAttribute('id');
1759 » » » if (Browser.Engine.trident){ 3788 » » » /*<ltIE9>*/
3789 » » » if (node.clearAttributes){
1760 node.clearAttributes(); 3790 node.clearAttributes();
1761 node.mergeAttributes(element); 3791 node.mergeAttributes(element);
1762 node.removeAttribute('uid'); 3792 node.removeAttribute('uid');
1763 if (node.options){ 3793 if (node.options){
1764 var no = node.options, eo = element.opti ons; 3794 var no = node.options, eo = element.opti ons;
1765 for (var j = no.length; j--;) no[j].sele cted = eo[j].selected; 3795 for (var j = no.length; j--;) no[j].sele cted = eo[j].selected;
1766 } 3796 }
1767 } 3797 }
1768 » » » var prop = props[element.tagName.toLowerCase()]; 3798 » » » /*</ltIE9>*/
3799 » » » var prop = formProps[element.tagName.toLowerCase()];
1769 if (prop && element[prop]) node[prop] = element[prop]; 3800 if (prop && element[prop]) node[prop] = element[prop];
1770 » » }; 3801 » » }
1771 3802
1772 » » if (contents){ 3803 » » /*<ltIE9>*/
1773 » » » var ce = clone.getElementsByTagName('*'), te = this.getE lementsByTagName('*'); 3804 » » if (Browser.ie){
1774 » » » for (var i = ce.length; i--;) clean(ce[i], te[i]); 3805 » » » var co = clone.getElementsByTagName('object'), to = this .getElementsByTagName('object');
1775 » » } 3806 » » » for (i = co.length; i--;) co[i].outerHTML = to[i].outerH TML;
1776 3807 » » }
1777 » » clean(clone, this); 3808 » » /*</ltIE9>*/
1778 » » return $(clone); 3809 » » return document.id(clone);
1779 » }, 3810 » }
1780 3811
1781 » destroy: function(){ 3812 });
1782 » » Element.empty(this); 3813
1783 » » Element.dispose(this); 3814 [Element, Window, Document].invoke('implement', {
1784 » » clean(this, true);
1785 » » return null;
1786 » },
1787
1788 » empty: function(){
1789 » » $A(this.childNodes).each(function(node){
1790 » » » Element.destroy(node);
1791 » » });
1792 » » return this;
1793 » },
1794
1795 » dispose: function(){
1796 » » return (this.parentNode) ? this.parentNode.removeChild(this) : t his;
1797 » },
1798
1799 » hasChild: function(el){
1800 » » el = $(el, true);
1801 » » if (!el) return false;
1802 » » if (Browser.Engine.webkit && Browser.Engine.version < 420) retur n $A(this.getElementsByTagName(el.tagName)).contains(el);
1803 » » return (this.contains) ? (this != el && this.contains(el)) : !!( this.compareDocumentPosition(el) & 16);
1804 » },
1805
1806 » match: function(tag){
1807 » » return (!tag || (tag == this) || (Element.get(this, 'tag') == ta g));
1808 » }
1809
1810 });
1811
1812 Native.implement([Element, Window, Document], {
1813 3815
1814 addListener: function(type, fn){ 3816 addListener: function(type, fn){
1815 if (type == 'unload'){ 3817 if (type == 'unload'){
1816 var old = fn, self = this; 3818 var old = fn, self = this;
1817 fn = function(){ 3819 fn = function(){
1818 self.removeListener('unload', fn); 3820 self.removeListener('unload', fn);
1819 old(); 3821 old();
1820 }; 3822 };
1821 } else { 3823 } else {
1822 » » » collected[this.uid] = this; 3824 » » » collected[$uid(this)] = this;
1823 » » } 3825 » » }
1824 » » if (this.addEventListener) this.addEventListener(type, fn, false ); 3826 » » if (this.addEventListener) this.addEventListener(type, fn, !!arg uments[2]);
1825 else this.attachEvent('on' + type, fn); 3827 else this.attachEvent('on' + type, fn);
1826 return this; 3828 return this;
1827 }, 3829 },
1828 3830
1829 removeListener: function(type, fn){ 3831 removeListener: function(type, fn){
1830 » » if (this.removeEventListener) this.removeEventListener(type, fn, false); 3832 » » if (this.removeEventListener) this.removeEventListener(type, fn, !!arguments[2]);
1831 else this.detachEvent('on' + type, fn); 3833 else this.detachEvent('on' + type, fn);
1832 return this; 3834 return this;
1833 }, 3835 },
1834 3836
1835 retrieve: function(property, dflt){ 3837 retrieve: function(property, dflt){
1836 » » var storage = get(this.uid), prop = storage[property]; 3838 » » var storage = get($uid(this)), prop = storage[property];
1837 » » if (dflt != undefined && prop == undefined) prop = storage[prope rty] = dflt; 3839 » » if (dflt != null && prop == null) prop = storage[property] = dfl t;
1838 » » return $pick(prop); 3840 » » return prop != null ? prop : null;
1839 }, 3841 },
1840 3842
1841 store: function(property, value){ 3843 store: function(property, value){
1842 » » var storage = get(this.uid); 3844 » » var storage = get($uid(this));
1843 storage[property] = value; 3845 storage[property] = value;
1844 return this; 3846 return this;
1845 }, 3847 },
1846 3848
1847 eliminate: function(property){ 3849 eliminate: function(property){
1848 » » var storage = get(this.uid); 3850 » » var storage = get($uid(this));
1849 delete storage[property]; 3851 delete storage[property];
1850 return this; 3852 return this;
1851 } 3853 }
1852 3854
1853 }); 3855 });
1854 3856
1855 window.addListener('unload', purge); 3857 /*<ltIE9>*/
1856 3858 if (window.attachEvent && !window.addEventListener) window.addListener('unload', function(){
1857 })(); 3859 » Object.each(collected, clean);
3860 » if (window.CollectGarbage) CollectGarbage();
3861 });
3862 /*</ltIE9>*/
3863
3864 Element.Properties = {};
3865
3866 //<1.2compat>
1858 3867
1859 Element.Properties = new Hash; 3868 Element.Properties = new Hash;
1860 3869
3870 //</1.2compat>
3871
1861 Element.Properties.style = { 3872 Element.Properties.style = {
1862 3873
1863 set: function(style){ 3874 set: function(style){
1864 this.style.cssText = style; 3875 this.style.cssText = style;
1865 }, 3876 },
1866 3877
1867 get: function(){ 3878 get: function(){
1868 return this.style.cssText; 3879 return this.style.cssText;
1869 }, 3880 },
1870 3881
1871 erase: function(){ 3882 erase: function(){
1872 this.style.cssText = ''; 3883 this.style.cssText = '';
1873 } 3884 }
1874 3885
1875 }; 3886 };
1876 3887
1877 Element.Properties.tag = { 3888 Element.Properties.tag = {
1878 3889
1879 get: function(){ 3890 get: function(){
1880 return this.tagName.toLowerCase(); 3891 return this.tagName.toLowerCase();
1881 } 3892 }
1882 3893
1883 }; 3894 };
1884 3895
3896 /*<!webkit>*/
1885 Element.Properties.html = (function(){ 3897 Element.Properties.html = (function(){
3898
3899 var tableTest = Function.attempt(function(){
3900 var table = document.createElement('table');
3901 table.innerHTML = '<tr><td></td></tr>';
3902 });
3903
1886 var wrapper = document.createElement('div'); 3904 var wrapper = document.createElement('div');
1887 3905
1888 var translations = { 3906 var translations = {
1889 table: [1, '<table>', '</table>'], 3907 table: [1, '<table>', '</table>'],
1890 select: [1, '<select>', '</select>'], 3908 select: [1, '<select>', '</select>'],
1891 tbody: [2, '<table><tbody>', '</tbody></table>'], 3909 tbody: [2, '<table><tbody>', '</tbody></table>'],
1892 tr: [3, '<table><tbody><tr>', '</tr></tbody></table>'] 3910 tr: [3, '<table><tbody><tr>', '</tr></tbody></table>']
1893 }; 3911 };
1894 translations.thead = translations.tfoot = translations.tbody; 3912 translations.thead = translations.tfoot = translations.tbody;
1895 3913
3914 /*<ltIE9>*/
3915 // technique by jdbarlett - http://jdbartlett.com/innershiv/
3916 wrapper.innerHTML = '<nav></nav>';
3917 var HTML5Test = wrapper.childNodes.length == 1;
3918 if (!HTML5Test){
3919 var tags = 'abbr article aside audio canvas datalist details fig caption figure footer header hgroup mark meter nav output progress section summa ry time video'.split(' '),
3920 fragment = document.createDocumentFragment(), l = tags.l ength;
3921 while (l--) fragment.createElement(tags[l]);
3922 fragment.appendChild(wrapper);
3923 }
3924 /*</ltIE9>*/
3925
1896 var html = { 3926 var html = {
1897 » » set: function(){ 3927 » » set: function(html){
1898 » » » var html = Array.flatten(arguments).join(''); 3928 » » » if (typeOf(html) == 'array') html = html.join('');
1899 » » » var wrap = Browser.Engine.trident && translations[this.g et('tag')]; 3929
3930 » » » var wrap = (!tableTest && translations[this.get('tag')]) ;
3931 » » » /*<ltIE9>*/
3932 » » » if (!wrap && !HTML5Test) wrap = [0, '', ''];
3933 » » » /*</ltIE9>*/
1900 if (wrap){ 3934 if (wrap){
1901 var first = wrapper; 3935 var first = wrapper;
1902 first.innerHTML = wrap[1] + html + wrap[2]; 3936 first.innerHTML = wrap[1] + html + wrap[2];
1903 for (var i = wrap[0]; i--;) first = first.firstC hild; 3937 for (var i = wrap[0]; i--;) first = first.firstC hild;
1904 this.empty().adopt(first.childNodes); 3938 this.empty().adopt(first.childNodes);
1905 } else { 3939 } else {
1906 this.innerHTML = html; 3940 this.innerHTML = html;
1907 } 3941 }
1908 } 3942 }
1909 }; 3943 };
1910 3944
1911 html.erase = html.set; 3945 html.erase = html.set;
1912 3946
1913 return html; 3947 return html;
1914 })(); 3948 })();
1915 3949 /*</!webkit>*/
1916 if (Browser.Engine.webkit && Browser.Engine.version < 420) Element.Properties.te xt = { 3950
3951 /*<ltIE9>*/
3952 var testForm = document.createElement('form');
3953 testForm.innerHTML = '<select><option>s</option></select>';
3954
3955 if (testForm.firstChild.value != 's') Element.Properties.value = {
3956
3957 » set: function(value){
3958 » » var tag = this.get('tag');
3959 » » if (tag != 'select') return this.setProperty('value', value);
3960 » » var options = this.getElements('option');
3961 » » for (var i = 0; i < options.length; i++){
3962 » » » var option = options[i],
3963 » » » » attr = option.getAttributeNode('value'),
3964 » » » » optionValue = (attr && attr.specified) ? option. value : option.get('text');
3965 » » » if (optionValue == value) return option.selected = true;
3966 » » }
3967 » },
3968
1917 get: function(){ 3969 get: function(){
1918 » » if (this.innerText) return this.innerText; 3970 » » var option = this, tag = option.get('tag');
1919 » » var temp = this.ownerDocument.newElement('div', {html: this.inne rHTML}).inject(this.ownerDocument.body); 3971
1920 » » var text = temp.innerText; 3972 » » if (tag != 'select' && tag != 'option') return this.getProperty( 'value');
1921 » » temp.destroy(); 3973
1922 » » return text; 3974 » » if (tag == 'select' && !(option = option.getSelected()[0])) retu rn '';
1923 » } 3975
1924 }; 3976 » » var attr = option.getAttributeNode('value');
3977 » » return (attr && attr.specified) ? option.value : option.get('tex t');
3978 » }
3979
3980 };
3981 /*</ltIE9>*/
3982
3983 })();
1925 3984
1926 3985
1927 /* 3986 /*
1928 Script: Element.Event.js 3987 ---
1929 » Contains Element methods for dealing with events, and custom Events. 3988
1930 3989 name: Element.Style
1931 License: 3990
1932 » MIT-style license. 3991 description: Contains methods for interacting with the styles of Elements in a f ashionable way.
3992
3993 license: MIT-style license.
3994
3995 requires: Element
3996
3997 provides: Element.Style
3998
3999 ...
1933 */ 4000 */
1934 4001
1935 Element.Properties.events = {set: function(events){
1936 this.addEvents(events);
1937 }};
1938
1939 Native.implement([Element, Window, Document], {
1940
1941 addEvent: function(type, fn){
1942 var events = this.retrieve('events', {});
1943 events[type] = events[type] || {'keys': [], 'values': []};
1944 if (events[type].keys.contains(fn)) return this;
1945 events[type].keys.push(fn);
1946 var realType = type, custom = Element.Events.get(type), conditio n = fn, self = this;
1947 if (custom){
1948 if (custom.onAdd) custom.onAdd.call(this, fn);
1949 if (custom.condition){
1950 condition = function(event){
1951 if (custom.condition.call(this, event)) return fn.call(this, event);
1952 return true;
1953 };
1954 }
1955 realType = custom.base || realType;
1956 }
1957 var defn = function(){
1958 return fn.call(self);
1959 };
1960 var nativeEvent = Element.NativeEvents[realType];
1961 if (nativeEvent){
1962 if (nativeEvent == 2){
1963 defn = function(event){
1964 event = new Event(event, self.getWindow( ));
1965 if (condition.call(self, event) === fals e) event.stop();
1966 };
1967 }
1968 this.addListener(realType, defn);
1969 }
1970 events[type].values.push(defn);
1971 return this;
1972 },
1973
1974 removeEvent: function(type, fn){
1975 var events = this.retrieve('events');
1976 if (!events || !events[type]) return this;
1977 var pos = events[type].keys.indexOf(fn);
1978 if (pos == -1) return this;
1979 events[type].keys.splice(pos, 1);
1980 var value = events[type].values.splice(pos, 1)[0];
1981 var custom = Element.Events.get(type);
1982 if (custom){
1983 if (custom.onRemove) custom.onRemove.call(this, fn);
1984 type = custom.base || type;
1985 }
1986 return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this;
1987 },
1988
1989 addEvents: function(events){
1990 for (var event in events) this.addEvent(event, events[event]);
1991 return this;
1992 },
1993
1994 removeEvents: function(events){
1995 if ($type(events) == 'object'){
1996 for (var type in events) this.removeEvent(type, events[t ype]);
1997 return this;
1998 }
1999 var attached = this.retrieve('events');
2000 if (!attached) return this;
2001 if (!events){
2002 for (var type in attached) this.removeEvents(type);
2003 this.eliminate('events');
2004 } else if (attached[events]){
2005 while (attached[events].keys[0]) this.removeEvent(events , attached[events].keys[0]);
2006 attached[events] = null;
2007 }
2008 return this;
2009 },
2010
2011 fireEvent: function(type, args, delay){
2012 var events = this.retrieve('events');
2013 if (!events || !events[type]) return this;
2014 events[type].keys.each(function(fn){
2015 fn.create({'bind': this, 'delay': delay, 'arguments': ar gs})();
2016 }, this);
2017 return this;
2018 },
2019
2020 cloneEvents: function(from, type){
2021 from = $(from);
2022 var fevents = from.retrieve('events');
2023 if (!fevents) return this;
2024 if (!type){
2025 for (var evType in fevents) this.cloneEvents(from, evTyp e);
2026 } else if (fevents[type]){
2027 fevents[type].keys.each(function(fn){
2028 this.addEvent(type, fn);
2029 }, this);
2030 }
2031 return this;
2032 }
2033
2034 });
2035
2036 Element.NativeEvents = {
2037 click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
2038 mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
2039 mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, / /mouse movement
2040 keydown: 2, keypress: 2, keyup: 2, //keyboard
2041 focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form ele ments
2042 load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoade d: 1, readystatechange: 1, //window
2043 error: 1, abort: 1, scroll: 1 //misc
2044 };
2045
2046 (function(){ 4002 (function(){
2047 4003
2048 var $check = function(event){ 4004 var html = document.html;
2049 » var related = event.relatedTarget;
2050 » if (related == undefined) return true;
2051 » if (related === false) return false;
2052 » return ($type(this) != 'document' && related != this && related.prefix ! = 'xul' && !this.hasChild(related));
2053 };
2054
2055 Element.Events = new Hash({
2056
2057 » mouseenter: {
2058 » » base: 'mouseover',
2059 » » condition: $check
2060 » },
2061
2062 » mouseleave: {
2063 » » base: 'mouseout',
2064 » » condition: $check
2065 » },
2066
2067 » mousewheel: {
2068 » » base: (Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel'
2069 » }
2070
2071 });
2072
2073 })();
2074
2075
2076 /*
2077 Script: Element.Style.js
2078 » Contains methods for interacting with the styles of Elements in a fashio nable way.
2079
2080 License:
2081 » MIT-style license.
2082 */
2083 4005
2084 Element.Properties.styles = {set: function(styles){ 4006 Element.Properties.styles = {set: function(styles){
2085 this.setStyles(styles); 4007 this.setStyles(styles);
2086 }}; 4008 }};
2087 4009
2088 Element.Properties.opacity = { 4010 var hasOpacity = (html.style.opacity != null),
2089 4011 » hasFilter = (html.style.filter != null),
2090 » set: function(opacity, novisibility){ 4012 » reAlpha = /alpha\(opacity=([\d.]+)\)/i;
2091 » » if (!novisibility){ 4013
2092 » » » if (opacity == 0){ 4014 var setVisibility = function(element, opacity){
2093 » » » » if (this.style.visibility != 'hidden') this.styl e.visibility = 'hidden'; 4015 » element.store('$opacity', opacity);
2094 » » » } else { 4016 » element.style.visibility = opacity > 0 ? 'visible' : 'hidden';
2095 » » » » if (this.style.visibility != 'visible') this.sty le.visibility = 'visible'; 4017 };
2096 » » » } 4018
2097 » » } 4019 var setOpacity = (hasOpacity ? function(element, opacity){
2098 » » if (!this.currentStyle || !this.currentStyle.hasLayout) this.sty le.zoom = 1; 4020 » element.style.opacity = opacity;
2099 » » if (Browser.Engine.trident) this.style.filter = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')'; 4021 } : (hasFilter ? function(element, opacity){
2100 » » this.style.opacity = opacity; 4022 » if (!element.currentStyle || !element.currentStyle.hasLayout) element.st yle.zoom = 1;
2101 » » this.store('opacity', opacity); 4023 » opacity = (opacity * 100).limit(0, 100).round();
2102 » }, 4024 » opacity = (opacity == 100) ? '' : 'alpha(opacity=' + opacity + ')';
2103 4025 » var filter = element.style.filter || element.getComputedStyle('filter') || '';
2104 » get: function(){ 4026 » element.style.filter = reAlpha.test(filter) ? filter.replace(reAlpha, op acity) : filter + opacity;
2105 » » return this.retrieve('opacity', 1); 4027 } : setVisibility));
2106 » } 4028
2107 4029 var getOpacity = (hasOpacity ? function(element){
2108 }; 4030 » var opacity = element.style.opacity || element.getComputedStyle('opacity ');
4031 » return (opacity == '') ? 1 : opacity.toFloat();
4032 } : (hasFilter ? function(element){
4033 » var filter = (element.style.filter || element.getComputedStyle('filter') ),
4034 » » opacity;
4035 » if (filter) opacity = filter.match(reAlpha);
4036 » return (opacity == null || filter == null) ? 1 : (opacity[1] / 100);
4037 } : function(element){
4038 » var opacity = element.retrieve('$opacity');
4039 » if (opacity == null) opacity = (element.style.visibility == 'hidden' ? 0 : 1);
4040 » return opacity;
4041 }));
4042
4043 var floatName = (html.style.cssFloat == null) ? 'styleFloat' : 'cssFloat';
2109 4044
2110 Element.implement({ 4045 Element.implement({
2111 4046
2112 » setOpacity: function(value){ 4047 » getComputedStyle: function(property){
2113 » » return this.set('opacity', value, true); 4048 » » if (this.currentStyle) return this.currentStyle[property.camelCa se()];
2114 » }, 4049 » » var defaultView = Element.getDocument(this).defaultView,
2115 4050 » » » computed = defaultView ? defaultView.getComputedStyle(th is, null) : null;
2116 » getOpacity: function(){ 4051 » » return (computed) ? computed.getPropertyValue((property == float Name) ? 'float' : property.hyphenate()) : null;
2117 » » return this.get('opacity');
2118 }, 4052 },
2119 4053
2120 setStyle: function(property, value){ 4054 setStyle: function(property, value){
2121 » » switch (property){ 4055 » » if (property == 'opacity'){
2122 » » » case 'opacity': return this.set('opacity', parseFloat(va lue)); 4056 » » » setOpacity(this, parseFloat(value));
2123 » » » case 'float': property = (Browser.Engine.trident) ? 'sty leFloat' : 'cssFloat'; 4057 » » » return this;
2124 » » } 4058 » » }
2125 » » property = property.camelCase(); 4059 » » property = (property == 'float' ? floatName : property).camelCas e();
2126 » » if ($type(value) != 'string'){ 4060 » » if (typeOf(value) != 'string'){
2127 » » » var map = (Element.Styles.get(property) || '@').split(' '); 4061 » » » var map = (Element.Styles[property] || '@').split(' ');
2128 » » » value = $splat(value).map(function(val, i){ 4062 » » » value = Array.from(value).map(function(val, i){
2129 if (!map[i]) return ''; 4063 if (!map[i]) return '';
2130 » » » » return ($type(val) == 'number') ? map[i].replace ('@', Math.round(val)) : val; 4064 » » » » return (typeOf(val) == 'number') ? map[i].replac e('@', Math.round(val)) : val;
2131 }).join(' '); 4065 }).join(' ');
2132 } else if (value == String(Number(value))){ 4066 } else if (value == String(Number(value))){
2133 value = Math.round(value); 4067 value = Math.round(value);
2134 } 4068 }
2135 this.style[property] = value; 4069 this.style[property] = value;
2136 return this; 4070 return this;
2137 }, 4071 },
2138 4072
2139 getStyle: function(property){ 4073 getStyle: function(property){
2140 » » switch (property){ 4074 » » if (property == 'opacity') return getOpacity(this);
2141 » » » case 'opacity': return this.get('opacity'); 4075 » » property = (property == 'float' ? floatName : property).camelCas e();
2142 » » » case 'float': property = (Browser.Engine.trident) ? 'sty leFloat' : 'cssFloat';
2143 » » }
2144 » » property = property.camelCase();
2145 var result = this.style[property]; 4076 var result = this.style[property];
2146 » » if (!$chk(result)){ 4077 » » if (!result || property == 'zIndex'){
2147 result = []; 4078 result = [];
2148 for (var style in Element.ShortStyles){ 4079 for (var style in Element.ShortStyles){
2149 if (property != style) continue; 4080 if (property != style) continue;
2150 for (var s in Element.ShortStyles[style]) result .push(this.getStyle(s)); 4081 for (var s in Element.ShortStyles[style]) result .push(this.getStyle(s));
2151 return result.join(' '); 4082 return result.join(' ');
2152 } 4083 }
2153 result = this.getComputedStyle(property); 4084 result = this.getComputedStyle(property);
2154 } 4085 }
2155 if (result){ 4086 if (result){
2156 result = String(result); 4087 result = String(result);
2157 var color = result.match(/rgba?\([\d\s,]+\)/); 4088 var color = result.match(/rgba?\([\d\s,]+\)/);
2158 if (color) result = result.replace(color[0], color[0].rg bToHex()); 4089 if (color) result = result.replace(color[0], color[0].rg bToHex());
2159 } 4090 }
2160 » » if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(pa rseInt(result)))){ 4091 » » if (Browser.opera || (Browser.ie && isNaN(parseFloat(result)))){
2161 » » » if (property.test(/^(height|width)$/)){ 4092 » » » if ((/^(height|width)$/).test(property)){
2162 var values = (property == 'width') ? ['left', 'r ight'] : ['top', 'bottom'], size = 0; 4093 var values = (property == 'width') ? ['left', 'r ight'] : ['top', 'bottom'], size = 0;
2163 values.each(function(value){ 4094 values.each(function(value){
2164 size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt(); 4095 size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt();
2165 }, this); 4096 }, this);
2166 return this['offset' + property.capitalize()] - size + 'px'; 4097 return this['offset' + property.capitalize()] - size + 'px';
2167 } 4098 }
2168 » » » if ((Browser.Engine.presto) && String(result).test('px') ) return result; 4099 » » » if (Browser.opera && String(result).indexOf('px') != -1) return result;
2169 » » » if (property.test(/(border(.+)Width|margin|padding)/)) r eturn '0px'; 4100 » » » if ((/^border(.+)Width|margin|padding/).test(property)) return '0px';
2170 } 4101 }
2171 return result; 4102 return result;
2172 }, 4103 },
2173 4104
2174 setStyles: function(styles){ 4105 setStyles: function(styles){
2175 for (var style in styles) this.setStyle(style, styles[style]); 4106 for (var style in styles) this.setStyle(style, styles[style]);
2176 return this; 4107 return this;
2177 }, 4108 },
2178 4109
2179 getStyles: function(){ 4110 getStyles: function(){
2180 var result = {}; 4111 var result = {};
2181 » » Array.each(arguments, function(key){ 4112 » » Array.flatten(arguments).each(function(key){
2182 result[key] = this.getStyle(key); 4113 result[key] = this.getStyle(key);
2183 }, this); 4114 }, this);
2184 return result; 4115 return result;
2185 } 4116 }
2186 4117
2187 }); 4118 });
2188 4119
2189 Element.Styles = new Hash({ 4120 Element.Styles = {
2190 left: '@px', top: '@px', bottom: '@px', right: '@px', 4121 left: '@px', top: '@px', bottom: '@px', right: '@px',
2191 width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth : '@px', minHeight: '@px', 4122 width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth : '@px', minHeight: '@px',
2192 backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: ' rgb(@, @, @)', 4123 backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: ' rgb(@, @, @)',
2193 fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@p x @px @px @px)', 4124 fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@p x @px @px @px)',
2194 margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rg b(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)', 4125 margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rg b(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)',
2195 borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rg b(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)', 4126 borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rg b(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)',
2196 zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: ' @' 4127 zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: ' @'
2197 }); 4128 };
4129
4130 //<1.3compat>
4131
4132 Element.implement({
4133
4134 » setOpacity: function(value){
4135 » » setOpacity(this, value);
4136 » » return this;
4137 » },
4138
4139 » getOpacity: function(){
4140 » » return getOpacity(this);
4141 » }
4142
4143 });
4144
4145 Element.Properties.opacity = {
4146
4147 » set: function(opacity){
4148 » » setOpacity(this, opacity);
4149 » » setVisibility(this, opacity);
4150 » },
4151
4152 » get: function(){
4153 » » return getOpacity(this);
4154 » }
4155
4156 };
4157
4158 //</1.3compat>
4159
4160 //<1.2compat>
4161
4162 Element.Styles = new Hash(Element.Styles);
4163
4164 //</1.2compat>
2198 4165
2199 Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, bor derStyle: {}, borderColor: {}}; 4166 Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, bor derStyle: {}, borderColor: {}};
2200 4167
2201 ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ 4168 ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){
2202 var Short = Element.ShortStyles; 4169 var Short = Element.ShortStyles;
2203 var All = Element.Styles; 4170 var All = Element.Styles;
2204 ['margin', 'padding'].each(function(style){ 4171 ['margin', 'padding'].each(function(style){
2205 var sd = style + direction; 4172 var sd = style + direction;
2206 Short[style][sd] = All[sd] = '@px'; 4173 Short[style][sd] = All[sd] = '@px';
2207 }); 4174 });
2208 var bd = 'border' + direction; 4175 var bd = 'border' + direction;
2209 Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)'; 4176 Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)';
2210 var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color'; 4177 var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color';
2211 Short[bd] = {}; 4178 Short[bd] = {};
2212 Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px'; 4179 Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px';
2213 Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@'; 4180 Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@';
2214 Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)'; 4181 Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)';
2215 }); 4182 });
2216 4183
4184 })();
4185
2217 4186
2218 /* 4187 /*
2219 Script: Element.Dimensions.js 4188 ---
2220 » Contains methods to work with size, scroll, or positioning of Elements a nd the window object. 4189
2221 4190 name: Element.Event
2222 License: 4191
2223 » MIT-style license. 4192 description: Contains Element methods for dealing with events. This file also in cludes mouseenter and mouseleave custom Element Events.
2224 4193
2225 Credits: 4194 license: MIT-style license.
2226 » - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code a nd smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html). 4195
2227 » - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) co de, [BSD License](http://developer.yahoo.com/yui/license.html). 4196 requires: [Element, Event]
4197
4198 provides: Element.Event
4199
4200 ...
2228 */ 4201 */
2229 4202
2230 (function(){ 4203 (function(){
2231 4204
4205 Element.Properties.events = {set: function(events){
4206 this.addEvents(events);
4207 }};
4208
4209 [Element, Window, Document].invoke('implement', {
4210
4211 addEvent: function(type, fn){
4212 var events = this.retrieve('events', {});
4213 if (!events[type]) events[type] = {keys: [], values: []};
4214 if (events[type].keys.contains(fn)) return this;
4215 events[type].keys.push(fn);
4216 var realType = type,
4217 custom = Element.Events[type],
4218 condition = fn,
4219 self = this;
4220 if (custom){
4221 if (custom.onAdd) custom.onAdd.call(this, fn, type);
4222 if (custom.condition){
4223 condition = function(event){
4224 if (custom.condition.call(this, event, t ype)) return fn.call(this, event);
4225 return true;
4226 };
4227 }
4228 if (custom.base) realType = Function.from(custom.base).c all(this, type);
4229 }
4230 var defn = function(){
4231 return fn.call(self);
4232 };
4233 var nativeEvent = Element.NativeEvents[realType];
4234 if (nativeEvent){
4235 if (nativeEvent == 2){
4236 defn = function(event){
4237 event = new DOMEvent(event, self.getWind ow());
4238 if (condition.call(self, event) === fals e) event.stop();
4239 };
4240 }
4241 this.addListener(realType, defn, arguments[2]);
4242 }
4243 events[type].values.push(defn);
4244 return this;
4245 },
4246
4247 removeEvent: function(type, fn){
4248 var events = this.retrieve('events');
4249 if (!events || !events[type]) return this;
4250 var list = events[type];
4251 var index = list.keys.indexOf(fn);
4252 if (index == -1) return this;
4253 var value = list.values[index];
4254 delete list.keys[index];
4255 delete list.values[index];
4256 var custom = Element.Events[type];
4257 if (custom){
4258 if (custom.onRemove) custom.onRemove.call(this, fn, type );
4259 if (custom.base) type = Function.from(custom.base).call( this, type);
4260 }
4261 return (Element.NativeEvents[type]) ? this.removeListener(type, value, arguments[2]) : this;
4262 },
4263
4264 addEvents: function(events){
4265 for (var event in events) this.addEvent(event, events[event]);
4266 return this;
4267 },
4268
4269 removeEvents: function(events){
4270 var type;
4271 if (typeOf(events) == 'object'){
4272 for (type in events) this.removeEvent(type, events[type] );
4273 return this;
4274 }
4275 var attached = this.retrieve('events');
4276 if (!attached) return this;
4277 if (!events){
4278 for (type in attached) this.removeEvents(type);
4279 this.eliminate('events');
4280 } else if (attached[events]){
4281 attached[events].keys.each(function(fn){
4282 this.removeEvent(events, fn);
4283 }, this);
4284 delete attached[events];
4285 }
4286 return this;
4287 },
4288
4289 fireEvent: function(type, args, delay){
4290 var events = this.retrieve('events');
4291 if (!events || !events[type]) return this;
4292 args = Array.from(args);
4293
4294 events[type].keys.each(function(fn){
4295 if (delay) fn.delay(delay, this, args);
4296 else fn.apply(this, args);
4297 }, this);
4298 return this;
4299 },
4300
4301 cloneEvents: function(from, type){
4302 from = document.id(from);
4303 var events = from.retrieve('events');
4304 if (!events) return this;
4305 if (!type){
4306 for (var eventType in events) this.cloneEvents(from, eve ntType);
4307 } else if (events[type]){
4308 events[type].keys.each(function(fn){
4309 this.addEvent(type, fn);
4310 }, this);
4311 }
4312 return this;
4313 }
4314
4315 });
4316
4317 Element.NativeEvents = {
4318 click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons
4319 mousewheel: 2, DOMMouseScroll: 2, //mouse wheel
4320 mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, / /mouse movement
4321 keydown: 2, keypress: 2, keyup: 2, //keyboard
4322 orientationchange: 2, // mobile
4323 touchstart: 2, touchmove: 2, touchend: 2, touchcancel: 2, // touch
4324 gesturestart: 2, gesturechange: 2, gestureend: 2, // gesture
4325 focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, paste: 2, input: 2, //form elements
4326 load: 2, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoade d: 1, readystatechange: 1, //window
4327 error: 1, abort: 1, scroll: 1 //misc
4328 };
4329
4330 var check = function(event){
4331 var related = event.relatedTarget;
4332 if (related == null) return true;
4333 if (!related) return false;
4334 return (related != this && related.prefix != 'xul' && typeOf(this) != 'd ocument' && !this.contains(related));
4335 };
4336
4337 Element.Events = {
4338
4339 mouseenter: {
4340 base: 'mouseover',
4341 condition: check
4342 },
4343
4344 mouseleave: {
4345 base: 'mouseout',
4346 condition: check
4347 },
4348
4349 mousewheel: {
4350 base: (Browser.firefox) ? 'DOMMouseScroll' : 'mousewheel'
4351 }
4352
4353 };
4354
4355 /*<ltIE9>*/
4356 if (!window.addEventListener){
4357 Element.NativeEvents.propertychange = 2;
4358 Element.Events.change = {
4359 base: function(){
4360 var type = this.type;
4361 return (this.get('tag') == 'input' && (type == 'radio' | | type == 'checkbox')) ? 'propertychange' : 'change'
4362 },
4363 condition: function(event){
4364 return !!(this.type != 'radio' || this.checked);
4365 }
4366 }
4367 }
4368 /*</ltIE9>*/
4369
4370 //<1.2compat>
4371
4372 Element.Events = new Hash(Element.Events);
4373
4374 //</1.2compat>
4375
4376 })();
4377
4378
4379 /*
4380 ---
4381
4382 name: Element.Delegation
4383
4384 description: Extends the Element native object to include the delegate method fo r more efficient event management.
4385
4386 license: MIT-style license.
4387
4388 requires: [Element.Event]
4389
4390 provides: [Element.Delegation]
4391
4392 ...
4393 */
4394
4395 (function(){
4396
4397 var eventListenerSupport = !!window.addEventListener;
4398
4399 Element.NativeEvents.focusin = Element.NativeEvents.focusout = 2;
4400
4401 var bubbleUp = function(self, match, fn, event, target){
4402 while (target && target != self){
4403 if (match(target, event)) return fn.call(target, event, target);
4404 target = document.id(target.parentNode);
4405 }
4406 };
4407
4408 var map = {
4409 mouseenter: {
4410 base: 'mouseover'
4411 },
4412 mouseleave: {
4413 base: 'mouseout'
4414 },
4415 focus: {
4416 base: 'focus' + (eventListenerSupport ? '' : 'in'),
4417 capture: true
4418 },
4419 blur: {
4420 base: eventListenerSupport ? 'blur' : 'focusout',
4421 capture: true
4422 }
4423 };
4424
4425 /*<ltIE9>*/
4426 var _key = '$delegation:';
4427 var formObserver = function(type){
4428
4429 return {
4430
4431 base: 'focusin',
4432
4433 remove: function(self, uid){
4434 var list = self.retrieve(_key + type + 'listeners', {})[ uid];
4435 if (list && list.forms) for (var i = list.forms.length; i--;){
4436 list.forms[i].removeEvent(type, list.fns[i]);
4437 }
4438 },
4439
4440 listen: function(self, match, fn, event, target, uid){
4441 var form = (target.get('tag') == 'form') ? target : even t.target.getParent('form');
4442 if (!form) return;
4443
4444 var listeners = self.retrieve(_key + type + 'listeners', {}),
4445 listener = listeners[uid] || {forms: [], fns: [] },
4446 forms = listener.forms, fns = listener.fns;
4447
4448 if (forms.indexOf(form) != -1) return;
4449 forms.push(form);
4450
4451 var _fn = function(event){
4452 bubbleUp(self, match, fn, event, target);
4453 };
4454 form.addEvent(type, _fn);
4455 fns.push(_fn);
4456
4457 listeners[uid] = listener;
4458 self.store(_key + type + 'listeners', listeners);
4459 }
4460 };
4461 };
4462
4463 var inputObserver = function(type){
4464 return {
4465 base: 'focusin',
4466 listen: function(self, match, fn, event, target){
4467 var events = {blur: function(){
4468 this.removeEvents(events);
4469 }};
4470 events[type] = function(event){
4471 bubbleUp(self, match, fn, event, target);
4472 };
4473 event.target.addEvents(events);
4474 }
4475 };
4476 };
4477
4478 if (!eventListenerSupport) Object.append(map, {
4479 submit: formObserver('submit'),
4480 reset: formObserver('reset'),
4481 change: inputObserver('change'),
4482 select: inputObserver('select')
4483 });
4484 /*</ltIE9>*/
4485
4486 var proto = Element.prototype,
4487 addEvent = proto.addEvent,
4488 removeEvent = proto.removeEvent;
4489
4490 var relay = function(old, method){
4491 return function(type, fn, useCapture){
4492 if (type.indexOf(':relay') == -1) return old.call(this, type, fn , useCapture);
4493 var parsed = Slick.parse(type).expressions[0][0];
4494 if (parsed.pseudos[0].key != 'relay') return old.call(this, type , fn, useCapture);
4495 var newType = parsed.tag;
4496 parsed.pseudos.slice(1).each(function(pseudo){
4497 newType += ':' + pseudo.key + (pseudo.value ? '(' + pseu do.value + ')' : '');
4498 });
4499 old.call(this, type, fn);
4500 return method.call(this, newType, parsed.pseudos[0].value, fn);
4501 };
4502 };
4503
4504 var delegation = {
4505
4506 addEvent: function(type, match, fn){
4507 var storage = this.retrieve('$delegates', {}), stored = storage[ type];
4508 if (stored) for (var _uid in stored){
4509 if (stored[_uid].fn == fn && stored[_uid].match == match ) return this;
4510 }
4511
4512 var _type = type, _match = match, _fn = fn, _map = map[type] || {};
4513 type = _map.base || _type;
4514
4515 match = function(target){
4516 return Slick.match(target, _match);
4517 };
4518
4519 var elementEvent = Element.Events[_type];
4520 if (elementEvent && elementEvent.condition){
4521 var __match = match, condition = elementEvent.condition;
4522 match = function(target, event){
4523 return __match(target, event) && condition.call( target, event, type);
4524 };
4525 }
4526
4527 var self = this, uid = String.uniqueID();
4528 var delegator = _map.listen ? function(event, target){
4529 if (!target && event && event.target) target = event.tar get;
4530 if (target) _map.listen(self, match, fn, event, target, uid);
4531 } : function(event, target){
4532 if (!target && event && event.target) target = event.tar get;
4533 if (target) bubbleUp(self, match, fn, event, target);
4534 };
4535
4536 if (!stored) stored = {};
4537 stored[uid] = {
4538 match: _match,
4539 fn: _fn,
4540 delegator: delegator
4541 };
4542 storage[_type] = stored;
4543 return addEvent.call(this, type, delegator, _map.capture);
4544 },
4545
4546 removeEvent: function(type, match, fn, _uid){
4547 var storage = this.retrieve('$delegates', {}), stored = storage[ type];
4548 if (!stored) return this;
4549
4550 if (_uid){
4551 var _type = type, delegator = stored[_uid].delegator, _m ap = map[type] || {};
4552 type = _map.base || _type;
4553 if (_map.remove) _map.remove(this, _uid);
4554 delete stored[_uid];
4555 storage[_type] = stored;
4556 return removeEvent.call(this, type, delegator);
4557 }
4558
4559 var __uid, s;
4560 if (fn) for (__uid in stored){
4561 s = stored[__uid];
4562 if (s.match == match && s.fn == fn) return delegation.re moveEvent.call(this, type, match, fn, __uid);
4563 } else for (__uid in stored){
4564 s = stored[__uid];
4565 if (s.match == match) delegation.removeEvent.call(this, type, match, s.fn, __uid);
4566 }
4567 return this;
4568 }
4569
4570 };
4571
4572 [Element, Window, Document].invoke('implement', {
4573 addEvent: relay(addEvent, delegation.addEvent),
4574 removeEvent: relay(removeEvent, delegation.removeEvent)
4575 });
4576
4577 })();
4578
4579
4580 /*
4581 ---
4582
4583 name: Element.Dimensions
4584
4585 description: Contains methods to work with size, scroll, or positioning of Eleme nts and the window object.
4586
4587 license: MIT-style license.
4588
4589 credits:
4590 - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and sma rt browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html).
4591 - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [B SD License](http://developer.yahoo.com/yui/license.html).
4592
4593 requires: [Element, Element.Style]
4594
4595 provides: [Element.Dimensions]
4596
4597 ...
4598 */
4599
4600 (function(){
4601
4602 var element = document.createElement('div'),
4603 child = document.createElement('div');
4604 element.style.height = '0';
4605 element.appendChild(child);
4606 var brokenOffsetParent = (child.offsetParent === element);
4607 element = child = null;
4608
4609 var isOffset = function(el){
4610 return styleString(el, 'position') != 'static' || isBody(el);
4611 };
4612
4613 var isOffsetStatic = function(el){
4614 return isOffset(el) || (/^(?:table|td|th)$/i).test(el.tagName);
4615 };
4616
2232 Element.implement({ 4617 Element.implement({
2233 4618
2234 scrollTo: function(x, y){ 4619 scrollTo: function(x, y){
2235 if (isBody(this)){ 4620 if (isBody(this)){
2236 this.getWindow().scrollTo(x, y); 4621 this.getWindow().scrollTo(x, y);
2237 } else { 4622 } else {
2238 this.scrollLeft = x; 4623 this.scrollLeft = x;
2239 this.scrollTop = y; 4624 this.scrollTop = y;
2240 } 4625 }
2241 return this; 4626 return this;
2242 }, 4627 },
2243 4628
2244 getSize: function(){ 4629 getSize: function(){
2245 if (isBody(this)) return this.getWindow().getSize(); 4630 if (isBody(this)) return this.getWindow().getSize();
2246 return {x: this.offsetWidth, y: this.offsetHeight}; 4631 return {x: this.offsetWidth, y: this.offsetHeight};
2247 }, 4632 },
2248 4633
2249 getScrollSize: function(){ 4634 getScrollSize: function(){
2250 if (isBody(this)) return this.getWindow().getScrollSize(); 4635 if (isBody(this)) return this.getWindow().getScrollSize();
2251 return {x: this.scrollWidth, y: this.scrollHeight}; 4636 return {x: this.scrollWidth, y: this.scrollHeight};
2252 }, 4637 },
2253 4638
2254 getScroll: function(){ 4639 getScroll: function(){
2255 if (isBody(this)) return this.getWindow().getScroll(); 4640 if (isBody(this)) return this.getWindow().getScroll();
2256 return {x: this.scrollLeft, y: this.scrollTop}; 4641 return {x: this.scrollLeft, y: this.scrollTop};
2257 }, 4642 },
2258 4643
2259 getScrolls: function(){ 4644 getScrolls: function(){
2260 » » var element = this, position = {x: 0, y: 0}; 4645 » » var element = this.parentNode, position = {x: 0, y: 0};
2261 while (element && !isBody(element)){ 4646 while (element && !isBody(element)){
2262 position.x += element.scrollLeft; 4647 position.x += element.scrollLeft;
2263 position.y += element.scrollTop; 4648 position.y += element.scrollTop;
2264 element = element.parentNode; 4649 element = element.parentNode;
2265 } 4650 }
2266 return position; 4651 return position;
2267 }, 4652 },
2268 4653
2269 » getOffsetParent: function(){ 4654 » getOffsetParent: brokenOffsetParent ? function(){
2270 var element = this; 4655 var element = this;
2271 » » if (isBody(element)) return null; 4656 » » if (isBody(element) || styleString(element, 'position') == 'fixe d') return null;
2272 » » if (!Browser.Engine.trident) return element.offsetParent; 4657
2273 » » while ((element = element.parentNode) && !isBody(element)){ 4658 » » var isOffsetCheck = (styleString(element, 'position') == 'static ') ? isOffsetStatic : isOffset;
2274 » » » if (styleString(element, 'position') != 'static') return element; 4659 » » while ((element = element.parentNode)){
4660 » » » if (isOffsetCheck(element)) return element;
2275 } 4661 }
2276 return null; 4662 return null;
4663 } : function(){
4664 var element = this;
4665 if (isBody(element) || styleString(element, 'position') == 'fixe d') return null;
4666
4667 try {
4668 return element.offsetParent;
4669 } catch(e) {}
4670 return null;
2277 }, 4671 },
2278 4672
2279 getOffsets: function(){ 4673 getOffsets: function(){
2280 » » if (Browser.Engine.trident){ 4674 » » if (this.getBoundingClientRect && !Browser.Platform.ios){
2281 » » » var bound = this.getBoundingClientRect(), html = this.ge tDocument().documentElement; 4675 » » » var bound = this.getBoundingClientRect(),
4676 » » » » html = document.id(this.getDocument().documentEl ement),
4677 » » » » htmlScroll = html.getScroll(),
4678 » » » » elemScrolls = this.getScrolls(),
4679 » » » » isFixed = (styleString(this, 'position') == 'fix ed');
4680
2282 return { 4681 return {
2283 » » » » x: bound.left + html.scrollLeft - html.clientLef t, 4682 » » » » x: bound.left.toInt() + elemScrolls.x + ((isFixe d) ? 0 : htmlScroll.x) - html.clientLeft,
2284 » » » » y: bound.top + html.scrollTop - html.clientTop 4683 » » » » y: bound.top.toInt() + elemScrolls.y + ((isFixe d) ? 0 : htmlScroll.y) - html.clientTop
2285 }; 4684 };
2286 } 4685 }
2287 4686
2288 var element = this, position = {x: 0, y: 0}; 4687 var element = this, position = {x: 0, y: 0};
2289 if (isBody(this)) return position; 4688 if (isBody(this)) return position;
2290 4689
2291 while (element && !isBody(element)){ 4690 while (element && !isBody(element)){
2292 position.x += element.offsetLeft; 4691 position.x += element.offsetLeft;
2293 position.y += element.offsetTop; 4692 position.y += element.offsetTop;
2294 4693
2295 » » » if (Browser.Engine.gecko){ 4694 » » » if (Browser.firefox){
2296 if (!borderBox(element)){ 4695 if (!borderBox(element)){
2297 position.x += leftBorder(element); 4696 position.x += leftBorder(element);
2298 position.y += topBorder(element); 4697 position.y += topBorder(element);
2299 } 4698 }
2300 var parent = element.parentNode; 4699 var parent = element.parentNode;
2301 if (parent && styleString(parent, 'overflow') != 'visible'){ 4700 if (parent && styleString(parent, 'overflow') != 'visible'){
2302 position.x += leftBorder(parent); 4701 position.x += leftBorder(parent);
2303 position.y += topBorder(parent); 4702 position.y += topBorder(parent);
2304 } 4703 }
2305 » » » } else if (element != this && Browser.Engine.webkit){ 4704 » » » } else if (element != this && Browser.safari){
2306 position.x += leftBorder(element); 4705 position.x += leftBorder(element);
2307 position.y += topBorder(element); 4706 position.y += topBorder(element);
2308 } 4707 }
2309 4708
2310 element = element.offsetParent; 4709 element = element.offsetParent;
2311 } 4710 }
2312 » » if (Browser.Engine.gecko && !borderBox(this)){ 4711 » » if (Browser.firefox && !borderBox(this)){
2313 position.x -= leftBorder(this); 4712 position.x -= leftBorder(this);
2314 position.y -= topBorder(this); 4713 position.y -= topBorder(this);
2315 } 4714 }
2316 return position; 4715 return position;
2317 }, 4716 },
2318 4717
2319 getPosition: function(relative){ 4718 getPosition: function(relative){
2320 » » if (isBody(this)) return {x: 0, y: 0}; 4719 » » var offset = this.getOffsets(),
2321 » » var offset = this.getOffsets(), scroll = this.getScrolls(); 4720 » » » scroll = this.getScrolls();
2322 » » var position = {x: offset.x - scroll.x, y: offset.y - scroll.y}; 4721 » » var position = {
2323 » » var relativePosition = (relative && (relative = $(relative))) ? relative.getPosition() : {x: 0, y: 0}; 4722 » » » x: offset.x - scroll.x,
2324 » » return {x: position.x - relativePosition.x, y: position.y - rela tivePosition.y}; 4723 » » » y: offset.y - scroll.y
4724 » » };
4725
4726 » » if (relative && (relative = document.id(relative))){
4727 » » » var relativePosition = relative.getPosition();
4728 » » » return {x: position.x - relativePosition.x - leftBorder( relative), y: position.y - relativePosition.y - topBorder(relative)};
4729 » » }
4730 » » return position;
2325 }, 4731 },
2326 4732
2327 getCoordinates: function(element){ 4733 getCoordinates: function(element){
2328 if (isBody(this)) return this.getWindow().getCoordinates(); 4734 if (isBody(this)) return this.getWindow().getCoordinates();
2329 » » var position = this.getPosition(element), size = this.getSize(); 4735 » » var position = this.getPosition(element),
2330 » » var obj = {left: position.x, top: position.y, width: size.x, hei ght: size.y}; 4736 » » » size = this.getSize();
4737 » » var obj = {
4738 » » » left: position.x,
4739 » » » top: position.y,
4740 » » » width: size.x,
4741 » » » height: size.y
4742 » » };
2331 obj.right = obj.left + obj.width; 4743 obj.right = obj.left + obj.width;
2332 obj.bottom = obj.top + obj.height; 4744 obj.bottom = obj.top + obj.height;
2333 return obj; 4745 return obj;
2334 }, 4746 },
2335 4747
2336 computePosition: function(obj){ 4748 computePosition: function(obj){
2337 » » return {left: obj.x - styleNumber(this, 'margin-left'), top: obj .y - styleNumber(this, 'margin-top')}; 4749 » » return {
2338 » }, 4750 » » » left: obj.x - styleNumber(this, 'margin-left'),
2339 4751 » » » top: obj.y - styleNumber(this, 'margin-top')
2340 » position: function(obj){ 4752 » » };
4753 » },
4754
4755 » setPosition: function(obj){
2341 return this.setStyles(this.computePosition(obj)); 4756 return this.setStyles(this.computePosition(obj));
2342 } 4757 }
2343 4758
2344 }); 4759 });
2345 4760
2346 Native.implement([Document, Window], { 4761
4762 [Document, Window].invoke('implement', {
2347 4763
2348 getSize: function(){ 4764 getSize: function(){
2349 var win = this.getWindow();
2350 if (Browser.Engine.presto || Browser.Engine.webkit) return {x: w in.innerWidth, y: win.innerHeight};
2351 var doc = getCompatElement(this); 4765 var doc = getCompatElement(this);
2352 return {x: doc.clientWidth, y: doc.clientHeight}; 4766 return {x: doc.clientWidth, y: doc.clientHeight};
2353 }, 4767 },
2354 4768
2355 getScroll: function(){ 4769 getScroll: function(){
2356 » » var win = this.getWindow(); 4770 » » var win = this.getWindow(), doc = getCompatElement(this);
2357 » » var doc = getCompatElement(this);
2358 return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop}; 4771 return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop};
2359 }, 4772 },
2360 4773
2361 getScrollSize: function(){ 4774 getScrollSize: function(){
2362 » » var doc = getCompatElement(this); 4775 » » var doc = getCompatElement(this),
2363 » » var min = this.getSize(); 4776 » » » min = this.getSize(),
2364 » » return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scr ollHeight, min.y)}; 4777 » » » body = this.getDocument().body;
4778
4779 » » return {x: Math.max(doc.scrollWidth, body.scrollWidth, min.x), y : Math.max(doc.scrollHeight, body.scrollHeight, min.y)};
2365 }, 4780 },
2366 4781
2367 getPosition: function(){ 4782 getPosition: function(){
2368 return {x: 0, y: 0}; 4783 return {x: 0, y: 0};
2369 }, 4784 },
2370 4785
2371 getCoordinates: function(){ 4786 getCoordinates: function(){
2372 var size = this.getSize(); 4787 var size = this.getSize();
2373 return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x}; 4788 return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x};
2374 } 4789 }
2375 4790
2376 }); 4791 });
2377 4792
2378 // private methods 4793 // private methods
2379 4794
2380 var styleString = Element.getComputedStyle; 4795 var styleString = Element.getComputedStyle;
2381 4796
2382 function styleNumber(element, style){ 4797 function styleNumber(element, style){
2383 return styleString(element, style).toInt() || 0; 4798 return styleString(element, style).toInt() || 0;
2384 }; 4799 }
2385 4800
2386 function borderBox(element){ 4801 function borderBox(element){
2387 return styleString(element, '-moz-box-sizing') == 'border-box'; 4802 return styleString(element, '-moz-box-sizing') == 'border-box';
2388 }; 4803 }
2389 4804
2390 function topBorder(element){ 4805 function topBorder(element){
2391 return styleNumber(element, 'border-top-width'); 4806 return styleNumber(element, 'border-top-width');
2392 }; 4807 }
2393 4808
2394 function leftBorder(element){ 4809 function leftBorder(element){
2395 return styleNumber(element, 'border-left-width'); 4810 return styleNumber(element, 'border-left-width');
2396 }; 4811 }
2397 4812
2398 function isBody(element){ 4813 function isBody(element){
2399 return (/^(?:body|html)$/i).test(element.tagName); 4814 return (/^(?:body|html)$/i).test(element.tagName);
2400 }; 4815 }
2401 4816
2402 function getCompatElement(element){ 4817 function getCompatElement(element){
2403 var doc = element.getDocument(); 4818 var doc = element.getDocument();
2404 return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; 4819 return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body;
2405 }; 4820 }
2406 4821
2407 })(); 4822 })();
2408 4823
2409 //aliases 4824 //aliases
2410 4825 Element.alias({position: 'setPosition'}); //compatability
2411 Native.implement([Window, Document, Element], { 4826
4827 [Window, Document, Element].invoke('implement', {
2412 4828
2413 getHeight: function(){ 4829 getHeight: function(){
2414 return this.getSize().y; 4830 return this.getSize().y;
2415 }, 4831 },
2416 4832
2417 getWidth: function(){ 4833 getWidth: function(){
2418 return this.getSize().x; 4834 return this.getSize().x;
2419 }, 4835 },
2420 4836
2421 getScrollTop: function(){ 4837 getScrollTop: function(){
(...skipping 17 matching lines...) Expand all
2439 }, 4855 },
2440 4856
2441 getLeft: function(){ 4857 getLeft: function(){
2442 return this.getPosition().x; 4858 return this.getPosition().x;
2443 } 4859 }
2444 4860
2445 }); 4861 });
2446 4862
2447 4863
2448 /* 4864 /*
2449 Script: Selectors.js 4865 ---
2450 » Adds advanced CSS Querying capabilities for targeting elements. Also inc ludes pseudoselectors support. 4866
2451 4867 name: Fx
2452 License: 4868
2453 » MIT-style license. 4869 description: Contains the basic animation logic to be extended by all other Fx C lasses.
4870
4871 license: MIT-style license.
4872
4873 requires: [Chain, Events, Options]
4874
4875 provides: Fx
4876
4877 ...
2454 */ 4878 */
2455 4879
2456 Native.implement([Document, Element], {
2457
2458 getElements: function(expression, nocash){
2459 expression = expression.split(',');
2460 var items, local = {};
2461 for (var i = 0, l = expression.length; i < l; i++){
2462 var selector = expression[i], elements = Selectors.Utils .search(this, selector, local);
2463 if (i != 0 && elements.item) elements = $A(elements);
2464 items = (i == 0) ? elements : (items.item) ? $A(items).c oncat(elements) : items.concat(elements);
2465 }
2466 return new Elements(items, {ddup: (expression.length > 1), cash: !nocash});
2467 }
2468
2469 });
2470
2471 Element.implement({
2472
2473 match: function(selector){
2474 if (!selector || (selector == this)) return true;
2475 var tagid = Selectors.Utils.parseTagAndID(selector);
2476 var tag = tagid[0], id = tagid[1];
2477 if (!Selectors.Filters.byID(this, id) || !Selectors.Filters.byTa g(this, tag)) return false;
2478 var parsed = Selectors.Utils.parseSelector(selector);
2479 return (parsed) ? Selectors.Utils.filter(this, parsed, {}) : tru e;
2480 }
2481
2482 });
2483
2484 var Selectors = {Cache: {nth: {}, parsed: {}}};
2485
2486 Selectors.RegExps = {
2487 id: (/#([\w-]+)/),
2488 tag: (/^(\w+|\*)/),
2489 quick: (/^(\w+|\*)$/),
2490 splitter: (/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),
2491 combined: (/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\ w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)
2492 };
2493
2494 Selectors.Utils = {
2495
2496 chk: function(item, uniques){
2497 if (!uniques) return true;
2498 var uid = $uid(item);
2499 if (!uniques[uid]) return uniques[uid] = true;
2500 return false;
2501 },
2502
2503 parseNthArgument: function(argument){
2504 if (Selectors.Cache.nth[argument]) return Selectors.Cache.nth[ar gument];
2505 var parsed = argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/) ;
2506 if (!parsed) return false;
2507 var inta = parseInt(parsed[1]);
2508 var a = (inta || inta === 0) ? inta : 1;
2509 var special = parsed[2] || false;
2510 var b = parseInt(parsed[3]) || 0;
2511 if (a != 0){
2512 b--;
2513 while (b < 1) b += a;
2514 while (b >= a) b -= a;
2515 } else {
2516 a = b;
2517 special = 'index';
2518 }
2519 switch (special){
2520 case 'n': parsed = {a: a, b: b, special: 'n'}; break;
2521 case 'odd': parsed = {a: 2, b: 0, special: 'n'}; break;
2522 case 'even': parsed = {a: 2, b: 1, special: 'n'}; break;
2523 case 'first': parsed = {a: 0, special: 'index'}; break;
2524 case 'last': parsed = {special: 'last-child'}; break;
2525 case 'only': parsed = {special: 'only-child'}; break;
2526 default: parsed = {a: (a - 1), special: 'index'};
2527 }
2528
2529 return Selectors.Cache.nth[argument] = parsed;
2530 },
2531
2532 parseSelector: function(selector){
2533 if (Selectors.Cache.parsed[selector]) return Selectors.Cache.par sed[selector];
2534 var m, parsed = {classes: [], pseudos: [], attributes: []};
2535 while ((m = Selectors.RegExps.combined.exec(selector))){
2536 var cn = m[1], an = m[2], ao = m[3], av = m[5], pn = m[6 ], pa = m[7];
2537 if (cn){
2538 parsed.classes.push(cn);
2539 } else if (pn){
2540 var parser = Selectors.Pseudo.get(pn);
2541 if (parser) parsed.pseudos.push({parser: parser, argument: pa});
2542 else parsed.attributes.push({name: pn, operator: '=', value: pa});
2543 } else if (an){
2544 parsed.attributes.push({name: an, operator: ao, value: av});
2545 }
2546 }
2547 if (!parsed.classes.length) delete parsed.classes;
2548 if (!parsed.attributes.length) delete parsed.attributes;
2549 if (!parsed.pseudos.length) delete parsed.pseudos;
2550 if (!parsed.classes && !parsed.attributes && !parsed.pseudos) pa rsed = null;
2551 return Selectors.Cache.parsed[selector] = parsed;
2552 },
2553
2554 parseTagAndID: function(selector){
2555 var tag = selector.match(Selectors.RegExps.tag);
2556 var id = selector.match(Selectors.RegExps.id);
2557 return [(tag) ? tag[1] : '*', (id) ? id[1] : false];
2558 },
2559
2560 filter: function(item, parsed, local){
2561 var i;
2562 if (parsed.classes){
2563 for (i = parsed.classes.length; i--; i){
2564 var cn = parsed.classes[i];
2565 if (!Selectors.Filters.byClass(item, cn)) return false;
2566 }
2567 }
2568 if (parsed.attributes){
2569 for (i = parsed.attributes.length; i--; i){
2570 var att = parsed.attributes[i];
2571 if (!Selectors.Filters.byAttribute(item, att.nam e, att.operator, att.value)) return false;
2572 }
2573 }
2574 if (parsed.pseudos){
2575 for (i = parsed.pseudos.length; i--; i){
2576 var psd = parsed.pseudos[i];
2577 if (!Selectors.Filters.byPseudo(item, psd.parser , psd.argument, local)) return false;
2578 }
2579 }
2580 return true;
2581 },
2582
2583 getByTagAndID: function(ctx, tag, id){
2584 if (id){
2585 var item = (ctx.getElementById) ? ctx.getElementById(id, true) : Element.getElementById(ctx, id, true);
2586 return (item && Selectors.Filters.byTag(item, tag)) ? [i tem] : [];
2587 } else {
2588 return ctx.getElementsByTagName(tag);
2589 }
2590 },
2591
2592 search: function(self, expression, local){
2593 var splitters = [];
2594
2595 var selectors = expression.trim().replace(Selectors.RegExps.spli tter, function(m0, m1, m2){
2596 splitters.push(m1);
2597 return ':)' + m2;
2598 }).split(':)');
2599
2600 var items, filtered, item;
2601
2602 for (var i = 0, l = selectors.length; i < l; i++){
2603
2604 var selector = selectors[i];
2605
2606 if (i == 0 && Selectors.RegExps.quick.test(selector)){
2607 items = self.getElementsByTagName(selector);
2608 continue;
2609 }
2610
2611 var splitter = splitters[i - 1];
2612
2613 var tagid = Selectors.Utils.parseTagAndID(selector);
2614 var tag = tagid[0], id = tagid[1];
2615
2616 if (i == 0){
2617 items = Selectors.Utils.getByTagAndID(self, tag, id);
2618 } else {
2619 var uniques = {}, found = [];
2620 for (var j = 0, k = items.length; j < k; j++) fo und = Selectors.Getters[splitter](found, items[j], tag, id, uniques);
2621 items = found;
2622 }
2623
2624 var parsed = Selectors.Utils.parseSelector(selector);
2625
2626 if (parsed){
2627 filtered = [];
2628 for (var m = 0, n = items.length; m < n; m++){
2629 item = items[m];
2630 if (Selectors.Utils.filter(item, parsed, local)) filtered.push(item);
2631 }
2632 items = filtered;
2633 }
2634
2635 }
2636
2637 return items;
2638
2639 }
2640
2641 };
2642
2643 Selectors.Getters = {
2644
2645 ' ': function(found, self, tag, id, uniques){
2646 var items = Selectors.Utils.getByTagAndID(self, tag, id);
2647 for (var i = 0, l = items.length; i < l; i++){
2648 var item = items[i];
2649 if (Selectors.Utils.chk(item, uniques)) found.push(item) ;
2650 }
2651 return found;
2652 },
2653
2654 '>': function(found, self, tag, id, uniques){
2655 var children = Selectors.Utils.getByTagAndID(self, tag, id);
2656 for (var i = 0, l = children.length; i < l; i++){
2657 var child = children[i];
2658 if (child.parentNode == self && Selectors.Utils.chk(chil d, uniques)) found.push(child);
2659 }
2660 return found;
2661 },
2662
2663 '+': function(found, self, tag, id, uniques){
2664 while ((self = self.nextSibling)){
2665 if (self.nodeType == 1){
2666 if (Selectors.Utils.chk(self, uniques) && Select ors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(sel f);
2667 break;
2668 }
2669 }
2670 return found;
2671 },
2672
2673 '~': function(found, self, tag, id, uniques){
2674 while ((self = self.nextSibling)){
2675 if (self.nodeType == 1){
2676 if (!Selectors.Utils.chk(self, uniques)) break;
2677 if (Selectors.Filters.byTag(self, tag) && Select ors.Filters.byID(self, id)) found.push(self);
2678 }
2679 }
2680 return found;
2681 }
2682
2683 };
2684
2685 Selectors.Filters = {
2686
2687 byTag: function(self, tag){
2688 return (tag == '*' || (self.tagName && self.tagName.toLowerCase( ) == tag));
2689 },
2690
2691 byID: function(self, id){
2692 return (!id || (self.id && self.id == id));
2693 },
2694
2695 byClass: function(self, klass){
2696 return (self.className && self.className.contains(klass, ' '));
2697 },
2698
2699 byPseudo: function(self, parser, argument, local){
2700 return parser.call(self, argument, local);
2701 },
2702
2703 byAttribute: function(self, name, operator, value){
2704 var result = Element.prototype.getProperty.call(self, name);
2705 if (!result) return (operator == '!=');
2706 if (!operator || value == undefined) return true;
2707 switch (operator){
2708 case '=': return (result == value);
2709 case '*=': return (result.contains(value));
2710 case '^=': return (result.substr(0, value.length) == val ue);
2711 case '$=': return (result.substr(result.length - value.l ength) == value);
2712 case '!=': return (result != value);
2713 case '~=': return result.contains(value, ' ');
2714 case '|=': return result.contains(value, '-');
2715 }
2716 return false;
2717 }
2718
2719 };
2720
2721 Selectors.Pseudo = new Hash({
2722
2723 // w3c pseudo selectors
2724
2725 checked: function(){
2726 return this.checked;
2727 },
2728
2729 empty: function(){
2730 return !(this.innerText || this.textContent || '').length;
2731 },
2732
2733 not: function(selector){
2734 return !Element.match(this, selector);
2735 },
2736
2737 contains: function(text){
2738 return (this.innerText || this.textContent || '').contains(text) ;
2739 },
2740
2741 'first-child': function(){
2742 return Selectors.Pseudo.index.call(this, 0);
2743 },
2744
2745 'last-child': function(){
2746 var element = this;
2747 while ((element = element.nextSibling)){
2748 if (element.nodeType == 1) return false;
2749 }
2750 return true;
2751 },
2752
2753 'only-child': function(){
2754 var prev = this;
2755 while ((prev = prev.previousSibling)){
2756 if (prev.nodeType == 1) return false;
2757 }
2758 var next = this;
2759 while ((next = next.nextSibling)){
2760 if (next.nodeType == 1) return false;
2761 }
2762 return true;
2763 },
2764
2765 'nth-child': function(argument, local){
2766 argument = (argument == undefined) ? 'n' : argument;
2767 var parsed = Selectors.Utils.parseNthArgument(argument);
2768 if (parsed.special != 'n') return Selectors.Pseudo[parsed.specia l].call(this, parsed.a, local);
2769 var count = 0;
2770 local.positions = local.positions || {};
2771 var uid = $uid(this);
2772 if (!local.positions[uid]){
2773 var self = this;
2774 while ((self = self.previousSibling)){
2775 if (self.nodeType != 1) continue;
2776 count ++;
2777 var position = local.positions[$uid(self)];
2778 if (position != undefined){
2779 count = position + count;
2780 break;
2781 }
2782 }
2783 local.positions[uid] = count;
2784 }
2785 return (local.positions[uid] % parsed.a == parsed.b);
2786 },
2787
2788 // custom pseudo selectors
2789
2790 index: function(index){
2791 var element = this, count = 0;
2792 while ((element = element.previousSibling)){
2793 if (element.nodeType == 1 && ++count > index) return fal se;
2794 }
2795 return (count == index);
2796 },
2797
2798 even: function(argument, local){
2799 return Selectors.Pseudo['nth-child'].call(this, '2n+1', local);
2800 },
2801
2802 odd: function(argument, local){
2803 return Selectors.Pseudo['nth-child'].call(this, '2n', local);
2804 }
2805
2806 });
2807
2808
2809 /*
2810 Script: Domready.js
2811 Contains the domready custom event.
2812
2813 License:
2814 MIT-style license.
2815 */
2816
2817 Element.Events.domready = {
2818
2819 onAdd: function(fn){
2820 if (Browser.loaded) fn.call(this);
2821 }
2822
2823 };
2824
2825 (function(){ 4880 (function(){
2826 4881
2827 » var domready = function(){ 4882 var Fx = this.Fx = new Class({
2828 » » if (Browser.loaded) return;
2829 » » Browser.loaded = true;
2830 » » window.fireEvent('domready');
2831 » » document.fireEvent('domready');
2832 » };
2833
2834 » if (Browser.Engine.trident){
2835 » » var temp = document.createElement('div');
2836 » » (function(){
2837 » » » ($try(function(){
2838 » » » » temp.doScroll('left');
2839 » » » » return $(temp).inject(document.body).set('html', 'temp').dispose();
2840 » » » })) ? domready() : arguments.callee.delay(50);
2841 » » })();
2842 » } else if (Browser.Engine.webkit && Browser.Engine.version < 525){
2843 » » (function(){
2844 » » » (['loaded', 'complete'].contains(document.readyState)) ? domready() : arguments.callee.delay(50);
2845 » » })();
2846 » } else {
2847 » » window.addEvent('load', domready);
2848 » » document.addEvent('DOMContentLoaded', domready);
2849 » }
2850
2851 })();
2852
2853
2854 /*
2855 Script: JSON.js
2856 » JSON encoder and decoder.
2857
2858 License:
2859 » MIT-style license.
2860
2861 See Also:
2862 » <http://www.json.org/>
2863 */
2864
2865 var JSON = new Hash({
2866
2867 » $specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r' : '\\r', '"' : '\\"', '\\': '\\\\'},
2868
2869 » $replaceChars: function(chr){
2870 » » return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charC odeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
2871 » },
2872
2873 » encode: function(obj){
2874 » » switch ($type(obj)){
2875 » » » case 'string':
2876 » » » » return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON .$replaceChars) + '"';
2877 » » » case 'array':
2878 » » » » return '[' + String(obj.map(JSON.encode).filter( $defined)) + ']';
2879 » » » case 'object': case 'hash':
2880 » » » » var string = [];
2881 » » » » Hash.each(obj, function(value, key){
2882 » » » » » var json = JSON.encode(value);
2883 » » » » » if (json) string.push(JSON.encode(key) + ':' + json);
2884 » » » » });
2885 » » » » return '{' + string + '}';
2886 » » » case 'number': case 'boolean': return String(obj);
2887 » » » case false: return 'null';
2888 » » }
2889 » » return null;
2890 » },
2891
2892 » decode: function(string, secure){
2893 » » if ($type(string) != 'string' || !string.length) return null;
2894 » » if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str ing.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
2895 » » return eval('(' + string + ')');
2896 » }
2897
2898 });
2899
2900 Native.implement([Hash, Array, String, Number], {
2901
2902 » toJSON: function(){
2903 » » return JSON.encode(this);
2904 » }
2905
2906 });
2907
2908
2909 /*
2910 Script: Cookie.js
2911 » Class for creating, loading, and saving browser Cookies.
2912
2913 License:
2914 » MIT-style license.
2915
2916 Credits:
2917 » Based on the functions by Peter-Paul Koch (http://quirksmode.org).
2918 */
2919
2920 var Cookie = new Class({
2921
2922 » Implements: Options,
2923
2924 » options: {
2925 » » path: false,
2926 » » domain: false,
2927 » » duration: false,
2928 » » secure: false,
2929 » » document: document
2930 » },
2931
2932 » initialize: function(key, options){
2933 » » this.key = key;
2934 » » this.setOptions(options);
2935 » },
2936
2937 » write: function(value){
2938 » » value = encodeURIComponent(value);
2939 » » if (this.options.domain) value += '; domain=' + this.options.dom ain;
2940 » » if (this.options.path) value += '; path=' + this.options.path;
2941 » » if (this.options.duration){
2942 » » » var date = new Date();
2943 » » » date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
2944 » » » value += '; expires=' + date.toGMTString();
2945 » » }
2946 » » if (this.options.secure) value += '; secure';
2947 » » this.options.document.cookie = this.key + '=' + value;
2948 » » return this;
2949 » },
2950
2951 » read: function(){
2952 » » var value = this.options.document.cookie.match('(?:^|;)\\s*' + t his.key.escapeRegExp() + '=([^;]*)');
2953 » » return (value) ? decodeURIComponent(value[1]) : null;
2954 » },
2955
2956 » dispose: function(){
2957 » » new Cookie(this.key, $merge(this.options, {duration: -1})).write ('');
2958 » » return this;
2959 » }
2960
2961 });
2962
2963 Cookie.write = function(key, value, options){
2964 » return new Cookie(key, options).write(value);
2965 };
2966
2967 Cookie.read = function(key){
2968 » return new Cookie(key).read();
2969 };
2970
2971 Cookie.dispose = function(key, options){
2972 » return new Cookie(key, options).dispose();
2973 };
2974
2975
2976 /*
2977 Script: Swiff.js
2978 » Wrapper for embedding SWF movies. Supports (and fixes) External Interfac e Communication.
2979
2980 License:
2981 » MIT-style license.
2982
2983 Credits:
2984 » Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWF Object.
2985 */
2986
2987 var Swiff = new Class({
2988
2989 » Implements: [Options],
2990
2991 » options: {
2992 » » id: null,
2993 » » height: 1,
2994 » » width: 1,
2995 » » container: null,
2996 » » properties: {},
2997 » » params: {
2998 » » » quality: 'high',
2999 » » » allowScriptAccess: 'always',
3000 » » » wMode: 'transparent',
3001 » » » swLiveConnect: true
3002 » » },
3003 » » callBacks: {},
3004 » » vars: {}
3005 » },
3006
3007 » toElement: function(){
3008 » » return this.object;
3009 » },
3010
3011 » initialize: function(path, options){
3012 » » this.instance = 'Swiff_' + $time();
3013
3014 » » this.setOptions(options);
3015 » » options = this.options;
3016 » » var id = this.id = options.id || this.instance;
3017 » » var container = $(options.container);
3018
3019 » » Swiff.CallBacks[this.instance] = {};
3020
3021 » » var params = options.params, vars = options.vars, callBacks = op tions.callBacks;
3022 » » var properties = $extend({height: options.height, width: options .width}, options.properties);
3023
3024 » » var self = this;
3025
3026 » » for (var callBack in callBacks){
3027 » » » Swiff.CallBacks[this.instance][callBack] = (function(opt ion){
3028 » » » » return function(){
3029 » » » » » return option.apply(self.object, argumen ts);
3030 » » » » };
3031 » » » })(callBacks[callBack]);
3032 » » » vars[callBack] = 'Swiff.CallBacks.' + this.instance + '. ' + callBack;
3033 » » }
3034
3035 » » params.flashVars = Hash.toQueryString(vars);
3036 » » if (Browser.Engine.trident){
3037 » » » properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-4445 53540000';
3038 » » » params.movie = path;
3039 » » } else {
3040 » » » properties.type = 'application/x-shockwave-flash';
3041 » » » properties.data = path;
3042 » » }
3043 » » var build = '<object id="' + id + '"';
3044 » » for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
3045 » » build += '>';
3046 » » for (var param in params){
3047 » » » if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
3048 » » }
3049 » » build += '</object>';
3050 » » this.object = ((container) ? container.empty() : new Element('di v')).set('html', build).firstChild;
3051 » },
3052
3053 » replaces: function(element){
3054 » » element = $(element, true);
3055 » » element.parentNode.replaceChild(this.toElement(), element);
3056 » » return this;
3057 » },
3058
3059 » inject: function(element){
3060 » » $(element, true).appendChild(this.toElement());
3061 » » return this;
3062 » },
3063
3064 » remote: function(){
3065 » » return Swiff.remote.apply(Swiff, [this.toElement()].extend(argum ents));
3066 » }
3067
3068 });
3069
3070 Swiff.CallBacks = {};
3071
3072 Swiff.remote = function(obj, fn){
3073 » var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascr ipt">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
3074 » return eval(rs);
3075 };
3076
3077
3078 /*
3079 Script: Fx.js
3080 » Contains the basic animation logic to be extended by all other Fx Classe s.
3081
3082 License:
3083 » MIT-style license.
3084 */
3085
3086 var Fx = new Class({
3087 4883
3088 Implements: [Chain, Events, Options], 4884 Implements: [Chain, Events, Options],
3089 4885
3090 options: { 4886 options: {
3091 /* 4887 /*
3092 » » onStart: $empty, 4888 » » onStart: nil,
3093 » » onCancel: $empty, 4889 » » onCancel: nil,
3094 » » onComplete: $empty, 4890 » » onComplete: nil,
3095 */ 4891 */
3096 » » fps: 50, 4892 » » fps: 60,
3097 unit: false, 4893 unit: false,
3098 duration: 500, 4894 duration: 500,
4895 frames: null,
4896 frameSkip: true,
3099 link: 'ignore' 4897 link: 'ignore'
3100 }, 4898 },
3101 4899
3102 initialize: function(options){ 4900 initialize: function(options){
3103 this.subject = this.subject || this; 4901 this.subject = this.subject || this;
3104 this.setOptions(options); 4902 this.setOptions(options);
3105 this.options.duration = Fx.Durations[this.options.duration] || t his.options.duration.toInt();
3106 var wait = this.options.wait;
3107 if (wait === false) this.options.link = 'cancel';
3108 }, 4903 },
3109 4904
3110 getTransition: function(){ 4905 getTransition: function(){
3111 return function(p){ 4906 return function(p){
3112 return -(Math.cos(Math.PI * p) - 1) / 2; 4907 return -(Math.cos(Math.PI * p) - 1) / 2;
3113 }; 4908 };
3114 }, 4909 },
3115 4910
3116 » step: function(){ 4911 » step: function(now){
3117 » » var time = $time(); 4912 » » if (this.options.frameSkip){
3118 » » if (time < this.time + this.options.duration){ 4913 » » » var diff = (this.time != null) ? (now - this.time) : 0, frames = diff / this.frameInterval;
3119 » » » var delta = this.transition((time - this.time) / this.op tions.duration); 4914 » » » this.time = now;
4915 » » » this.frame += frames;
4916 » » } else {
4917 » » » this.frame++;
4918 » » }
4919
4920 » » if (this.frame < this.frames){
4921 » » » var delta = this.transition(this.frame / this.frames);
3120 this.set(this.compute(this.from, this.to, delta)); 4922 this.set(this.compute(this.from, this.to, delta));
3121 } else { 4923 } else {
4924 this.frame = this.frames;
3122 this.set(this.compute(this.from, this.to, 1)); 4925 this.set(this.compute(this.from, this.to, 1));
3123 » » » this.complete(); 4926 » » » this.stop();
3124 } 4927 }
3125 }, 4928 },
3126 4929
3127 set: function(now){ 4930 set: function(now){
3128 return now; 4931 return now;
3129 }, 4932 },
3130 4933
3131 compute: function(from, to, delta){ 4934 compute: function(from, to, delta){
3132 return Fx.compute(from, to, delta); 4935 return Fx.compute(from, to, delta);
3133 }, 4936 },
3134 4937
3135 » check: function(caller){ 4938 » check: function(){
3136 » » if (!this.timer) return true; 4939 » » if (!this.isRunning()) return true;
3137 switch (this.options.link){ 4940 switch (this.options.link){
3138 case 'cancel': this.cancel(); return true; 4941 case 'cancel': this.cancel(); return true;
3139 » » » case 'chain': this.chain(caller.bind(this, Array.slice(a rguments, 1))); return false; 4942 » » » case 'chain': this.chain(this.caller.pass(arguments, thi s)); return false;
3140 } 4943 }
3141 return false; 4944 return false;
3142 }, 4945 },
3143 4946
3144 start: function(from, to){ 4947 start: function(from, to){
3145 » » if (!this.check(arguments.callee, from, to)) return this; 4948 » » if (!this.check(from, to)) return this;
3146 this.from = from; 4949 this.from = from;
3147 this.to = to; 4950 this.to = to;
3148 » » this.time = 0; 4951 » » this.frame = (this.options.frameSkip) ? 0 : -1;
4952 » » this.time = null;
3149 this.transition = this.getTransition(); 4953 this.transition = this.getTransition();
3150 » » this.startTimer(); 4954 » » var frames = this.options.frames, fps = this.options.fps, durati on = this.options.duration;
3151 » » this.onStart(); 4955 » » this.duration = Fx.Durations[duration] || duration.toInt();
3152 » » return this; 4956 » » this.frameInterval = 1000 / fps;
3153 » }, 4957 » » this.frames = frames || Math.round(this.duration / this.frameInt erval);
3154 4958 » » this.fireEvent('start', this.subject);
3155 » complete: function(){ 4959 » » pushInstance.call(this, fps);
3156 » » if (this.stopTimer()) this.onComplete(); 4960 » » return this;
4961 » },
4962
4963 » stop: function(){
4964 » » if (this.isRunning()){
4965 » » » this.time = null;
4966 » » » pullInstance.call(this, this.options.fps);
4967 » » » if (this.frames == this.frame){
4968 » » » » this.fireEvent('complete', this.subject);
4969 » » » » if (!this.callChain()) this.fireEvent('chainComp lete', this.subject);
4970 » » » } else {
4971 » » » » this.fireEvent('stop', this.subject);
4972 » » » }
4973 » » }
3157 return this; 4974 return this;
3158 }, 4975 },
3159 4976
3160 cancel: function(){ 4977 cancel: function(){
3161 » » if (this.stopTimer()) this.onCancel(); 4978 » » if (this.isRunning()){
3162 » » return this; 4979 » » » this.time = null;
3163 » }, 4980 » » » pullInstance.call(this, this.options.fps);
3164 4981 » » » this.frame = this.frames;
3165 » onStart: function(){ 4982 » » » this.fireEvent('cancel', this.subject).clearChain();
3166 » » this.fireEvent('start', this.subject); 4983 » » }
3167 » }, 4984 » » return this;
3168
3169 » onComplete: function(){
3170 » » this.fireEvent('complete', this.subject);
3171 » » if (!this.callChain()) this.fireEvent('chainComplete', this.subj ect);
3172 » },
3173
3174 » onCancel: function(){
3175 » » this.fireEvent('cancel', this.subject).clearChain();
3176 }, 4985 },
3177 4986
3178 pause: function(){ 4987 pause: function(){
3179 » » this.stopTimer(); 4988 » » if (this.isRunning()){
4989 » » » this.time = null;
4990 » » » pullInstance.call(this, this.options.fps);
4991 » » }
3180 return this; 4992 return this;
3181 }, 4993 },
3182 4994
3183 resume: function(){ 4995 resume: function(){
3184 » » this.startTimer(); 4996 » » if ((this.frame < this.frames) && !this.isRunning()) pushInstanc e.call(this, this.options.fps);
3185 » » return this; 4997 » » return this;
3186 » }, 4998 » },
3187 4999
3188 » stopTimer: function(){ 5000 » isRunning: function(){
3189 » » if (!this.timer) return false; 5001 » » var list = instances[this.options.fps];
3190 » » this.time = $time() - this.time; 5002 » » return list && list.contains(this);
3191 » » this.timer = $clear(this.timer);
3192 » » return true;
3193 » },
3194
3195 » startTimer: function(){
3196 » » if (this.timer) return false;
3197 » » this.time = $time() - this.time;
3198 » » this.timer = this.step.periodical(Math.round(1000 / this.options .fps), this);
3199 » » return true;
3200 } 5003 }
3201 5004
3202 }); 5005 });
3203 5006
3204 Fx.compute = function(from, to, delta){ 5007 Fx.compute = function(from, to, delta){
3205 return (to - from) * delta + from; 5008 return (to - from) * delta + from;
3206 }; 5009 };
3207 5010
3208 Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000}; 5011 Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000};
3209 5012
5013 // global timers
5014
5015 var instances = {}, timers = {};
5016
5017 var loop = function(){
5018 var now = Date.now();
5019 for (var i = this.length; i--;){
5020 var instance = this[i];
5021 if (instance) instance.step(now);
5022 }
5023 };
5024
5025 var pushInstance = function(fps){
5026 var list = instances[fps] || (instances[fps] = []);
5027 list.push(this);
5028 if (!timers[fps]) timers[fps] = loop.periodical(Math.round(1000 / fps), list);
5029 };
5030
5031 var pullInstance = function(fps){
5032 var list = instances[fps];
5033 if (list){
5034 list.erase(this);
5035 if (!list.length && timers[fps]){
5036 delete instances[fps];
5037 timers[fps] = clearInterval(timers[fps]);
5038 }
5039 }
5040 };
5041
5042 })();
5043
3210 5044
3211 /* 5045 /*
3212 Script: Fx.CSS.js 5046 ---
3213 » Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Element s. 5047
3214 5048 name: Fx.CSS
3215 License: 5049
3216 » MIT-style license. 5050 description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.El ements.
5051
5052 license: MIT-style license.
5053
5054 requires: [Fx, Element.Style]
5055
5056 provides: Fx.CSS
5057
5058 ...
3217 */ 5059 */
3218 5060
3219 Fx.CSS = new Class({ 5061 Fx.CSS = new Class({
3220 5062
3221 Extends: Fx, 5063 Extends: Fx,
3222 5064
3223 //prepares the base from/to object 5065 //prepares the base from/to object
3224 5066
3225 prepare: function(element, property, values){ 5067 prepare: function(element, property, values){
3226 » » values = $splat(values); 5068 » » values = Array.from(values);
3227 » » var values1 = values[1]; 5069 » » if (values[1] == null){
3228 » » if (!$chk(values1)){
3229 values[1] = values[0]; 5070 values[1] = values[0];
3230 values[0] = element.getStyle(property); 5071 values[0] = element.getStyle(property);
3231 } 5072 }
3232 var parsed = values.map(this.parse); 5073 var parsed = values.map(this.parse);
3233 return {from: parsed[0], to: parsed[1]}; 5074 return {from: parsed[0], to: parsed[1]};
3234 }, 5075 },
3235 5076
3236 //parses a value into an array 5077 //parses a value into an array
3237 5078
3238 parse: function(value){ 5079 parse: function(value){
3239 » » value = $lambda(value)(); 5080 » » value = Function.from(value)();
3240 » » value = (typeof value == 'string') ? value.split(' ') : $splat(v alue); 5081 » » value = (typeof value == 'string') ? value.split(' ') : Array.fr om(value);
3241 return value.map(function(val){ 5082 return value.map(function(val){
3242 val = String(val); 5083 val = String(val);
3243 var found = false; 5084 var found = false;
3244 » » » Fx.CSS.Parsers.each(function(parser, key){ 5085 » » » Object.each(Fx.CSS.Parsers, function(parser, key){
3245 if (found) return; 5086 if (found) return;
3246 var parsed = parser.parse(val); 5087 var parsed = parser.parse(val);
3247 » » » » if ($chk(parsed)) found = {value: parsed, parser : parser}; 5088 » » » » if (parsed || parsed === 0) found = {value: pars ed, parser: parser};
3248 }); 5089 });
3249 found = found || {value: val, parser: Fx.CSS.Parsers.Str ing}; 5090 found = found || {value: val, parser: Fx.CSS.Parsers.Str ing};
3250 return found; 5091 return found;
3251 }); 5092 });
3252 }, 5093 },
3253 5094
3254 //computes by a from and to prepared objects, using their parsers. 5095 //computes by a from and to prepared objects, using their parsers.
3255 5096
3256 compute: function(from, to, delta){ 5097 compute: function(from, to, delta){
3257 var computed = []; 5098 var computed = [];
3258 (Math.min(from.length, to.length)).times(function(i){ 5099 (Math.min(from.length, to.length)).times(function(i){
3259 computed.push({value: from[i].parser.compute(from[i].val ue, to[i].value, delta), parser: from[i].parser}); 5100 computed.push({value: from[i].parser.compute(from[i].val ue, to[i].value, delta), parser: from[i].parser});
3260 }); 5101 });
3261 » » computed.$family = {name: 'fx:css:value'}; 5102 » » computed.$family = Function.from('fx:css:value');
3262 return computed; 5103 return computed;
3263 }, 5104 },
3264 5105
3265 //serves the value as settable 5106 //serves the value as settable
3266 5107
3267 serve: function(value, unit){ 5108 serve: function(value, unit){
3268 » » if ($type(value) != 'fx:css:value') value = this.parse(value); 5109 » » if (typeOf(value) != 'fx:css:value') value = this.parse(value);
3269 var returned = []; 5110 var returned = [];
3270 value.each(function(bit){ 5111 value.each(function(bit){
3271 returned = returned.concat(bit.parser.serve(bit.value, u nit)); 5112 returned = returned.concat(bit.parser.serve(bit.value, u nit));
3272 }); 5113 });
3273 return returned; 5114 return returned;
3274 }, 5115 },
3275 5116
3276 //renders the change to an element 5117 //renders the change to an element
3277 5118
3278 render: function(element, property, value, unit){ 5119 render: function(element, property, value, unit){
3279 element.setStyle(property, this.serve(value, unit)); 5120 element.setStyle(property, this.serve(value, unit));
3280 }, 5121 },
3281 5122
3282 //searches inside the page css to find the values for a selector 5123 //searches inside the page css to find the values for a selector
3283 5124
3284 search: function(selector){ 5125 search: function(selector){
3285 if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector]; 5126 if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector];
3286 » » var to = {}; 5127 » » var to = {}, selectorTest = new RegExp('^' + selector.escapeRegE xp() + '$');
3287 Array.each(document.styleSheets, function(sheet, j){ 5128 Array.each(document.styleSheets, function(sheet, j){
3288 var href = sheet.href; 5129 var href = sheet.href;
3289 if (href && href.contains('://') && !href.contains(docum ent.domain)) return; 5130 if (href && href.contains('://') && !href.contains(docum ent.domain)) return;
3290 var rules = sheet.rules || sheet.cssRules; 5131 var rules = sheet.rules || sheet.cssRules;
3291 Array.each(rules, function(rule, i){ 5132 Array.each(rules, function(rule, i){
3292 if (!rule.style) return; 5133 if (!rule.style) return;
3293 var selectorText = (rule.selectorText) ? rule.se lectorText.replace(/^\w+/, function(m){ 5134 var selectorText = (rule.selectorText) ? rule.se lectorText.replace(/^\w+/, function(m){
3294 return m.toLowerCase(); 5135 return m.toLowerCase();
3295 }) : null; 5136 }) : null;
3296 » » » » if (!selectorText || !selectorText.test('^' + se lector + '$')) return; 5137 » » » » if (!selectorText || !selectorTest.test(selector Text)) return;
3297 » » » » Element.Styles.each(function(value, style){ 5138 » » » » Object.each(Element.Styles, function(value, styl e){
3298 if (!rule.style[style] || Element.ShortS tyles[style]) return; 5139 if (!rule.style[style] || Element.ShortS tyles[style]) return;
3299 value = String(rule.style[style]); 5140 value = String(rule.style[style]);
3300 » » » » » to[style] = (value.test(/^rgb/)) ? value .rgbToHex() : value; 5141 » » » » » to[style] = ((/^rgb/).test(value)) ? val ue.rgbToHex() : value;
3301 }); 5142 });
3302 }); 5143 });
3303 }); 5144 });
3304 return Fx.CSS.Cache[selector] = to; 5145 return Fx.CSS.Cache[selector] = to;
3305 } 5146 }
3306 5147
3307 }); 5148 });
3308 5149
3309 Fx.CSS.Cache = {}; 5150 Fx.CSS.Cache = {};
3310 5151
3311 Fx.CSS.Parsers = new Hash({ 5152 Fx.CSS.Parsers = {
3312 5153
3313 Color: { 5154 Color: {
3314 parse: function(value){ 5155 parse: function(value){
3315 if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexTo Rgb(true); 5156 if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexTo Rgb(true);
3316 return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/)) ) ? [value[1], value[2], value[3]] : false; 5157 return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/)) ) ? [value[1], value[2], value[3]] : false;
3317 }, 5158 },
3318 compute: function(from, to, delta){ 5159 compute: function(from, to, delta){
3319 return from.map(function(value, i){ 5160 return from.map(function(value, i){
3320 return Math.round(Fx.compute(from[i], to[i], del ta)); 5161 return Math.round(Fx.compute(from[i], to[i], del ta));
3321 }); 5162 });
3322 }, 5163 },
3323 serve: function(value){ 5164 serve: function(value){
3324 return value.map(Number); 5165 return value.map(Number);
3325 } 5166 }
3326 }, 5167 },
3327 5168
3328 Number: { 5169 Number: {
3329 parse: parseFloat, 5170 parse: parseFloat,
3330 compute: Fx.compute, 5171 compute: Fx.compute,
3331 serve: function(value, unit){ 5172 serve: function(value, unit){
3332 return (unit) ? value + unit : value; 5173 return (unit) ? value + unit : value;
3333 } 5174 }
3334 }, 5175 },
3335 5176
3336 String: { 5177 String: {
3337 » » parse: $lambda(false), 5178 » » parse: Function.from(false),
3338 » » compute: $arguments(1), 5179 » » compute: function(zero, one){
3339 » » serve: $arguments(0) 5180 » » » return one;
5181 » » },
5182 » » serve: function(zero){
5183 » » » return zero;
5184 » » }
3340 } 5185 }
3341 5186
3342 }); 5187 };
5188
5189 //<1.2compat>
5190
5191 Fx.CSS.Parsers = new Hash(Fx.CSS.Parsers);
5192
5193 //</1.2compat>
3343 5194
3344 5195
3345 /* 5196 /*
3346 Script: Fx.Tween.js 5197 ---
3347 » Formerly Fx.Style, effect to transition any CSS property for an element.
3348 5198
3349 License: 5199 name: Fx.Tween
3350 » MIT-style license. 5200
5201 description: Formerly Fx.Style, effect to transition any CSS property for an ele ment.
5202
5203 license: MIT-style license.
5204
5205 requires: Fx.CSS
5206
5207 provides: [Fx.Tween, Element.fade, Element.highlight]
5208
5209 ...
3351 */ 5210 */
3352 5211
3353 Fx.Tween = new Class({ 5212 Fx.Tween = new Class({
3354 5213
3355 Extends: Fx.CSS, 5214 Extends: Fx.CSS,
3356 5215
3357 initialize: function(element, options){ 5216 initialize: function(element, options){
3358 » » this.element = this.subject = $(element); 5217 » » this.element = this.subject = document.id(element);
3359 this.parent(options); 5218 this.parent(options);
3360 }, 5219 },
3361 5220
3362 set: function(property, now){ 5221 set: function(property, now){
3363 if (arguments.length == 1){ 5222 if (arguments.length == 1){
3364 now = property; 5223 now = property;
3365 property = this.property || this.options.property; 5224 property = this.property || this.options.property;
3366 } 5225 }
3367 this.render(this.element, property, now, this.options.unit); 5226 this.render(this.element, property, now, this.options.unit);
3368 return this; 5227 return this;
3369 }, 5228 },
3370 5229
3371 start: function(property, from, to){ 5230 start: function(property, from, to){
3372 » » if (!this.check(arguments.callee, property, from, to)) return th is; 5231 » » if (!this.check(property, from, to)) return this;
3373 var args = Array.flatten(arguments); 5232 var args = Array.flatten(arguments);
3374 this.property = this.options.property || args.shift(); 5233 this.property = this.options.property || args.shift();
3375 var parsed = this.prepare(this.element, this.property, args); 5234 var parsed = this.prepare(this.element, this.property, args);
3376 return this.parent(parsed.from, parsed.to); 5235 return this.parent(parsed.from, parsed.to);
3377 } 5236 }
3378 5237
3379 }); 5238 });
3380 5239
3381 Element.Properties.tween = { 5240 Element.Properties.tween = {
3382 5241
3383 set: function(options){ 5242 set: function(options){
3384 » » var tween = this.retrieve('tween'); 5243 » » this.get('tween').cancel().setOptions(options);
3385 » » if (tween) tween.cancel(); 5244 » » return this;
3386 » » return this.eliminate('tween').store('tween:options', $extend({l ink: 'cancel'}, options));
3387 }, 5245 },
3388 5246
3389 » get: function(options){ 5247 » get: function(){
3390 » » if (options || !this.retrieve('tween')){ 5248 » » var tween = this.retrieve('tween');
3391 » » » if (options || !this.retrieve('tween:options')) this.set ('tween', options); 5249 » » if (!tween){
3392 » » » this.store('tween', new Fx.Tween(this, this.retrieve('tw een:options'))); 5250 » » » tween = new Fx.Tween(this, {link: 'cancel'});
5251 » » » this.store('tween', tween);
3393 } 5252 }
3394 » » return this.retrieve('tween'); 5253 » » return tween;
3395 } 5254 }
3396 5255
3397 }; 5256 };
3398 5257
3399 Element.implement({ 5258 Element.implement({
3400 5259
3401 tween: function(property, from, to){ 5260 tween: function(property, from, to){
3402 » » this.get('tween').start(arguments); 5261 » » this.get('tween').start(property, from, to);
3403 return this; 5262 return this;
3404 }, 5263 },
3405 5264
3406 fade: function(how){ 5265 fade: function(how){
3407 » » var fade = this.get('tween'), o = 'opacity', toggle; 5266 » » var fade = this.get('tween'), method, to, toggle;
3408 » » how = $pick(how, 'toggle'); 5267 » » if (how == null) how = 'toggle';
3409 switch (how){ 5268 switch (how){
3410 » » » case 'in': fade.start(o, 1); break; 5269 » » » case 'in': method = 'start'; to = 1; break;
3411 » » » case 'out': fade.start(o, 0); break; 5270 » » » case 'out': method = 'start'; to = 0; break;
3412 » » » case 'show': fade.set(o, 1); break; 5271 » » » case 'show': method = 'set'; to = 1; break;
3413 » » » case 'hide': fade.set(o, 0); break; 5272 » » » case 'hide': method = 'set'; to = 0; break;
3414 case 'toggle': 5273 case 'toggle':
3415 » » » » var flag = this.retrieve('fade:flag', this.get(' opacity') == 1); 5274 » » » » var flag = this.retrieve('fade:flag', this.getSt yle('opacity') == 1);
3416 » » » » fade.start(o, (flag) ? 0 : 1); 5275 » » » » method = 'start';
5276 » » » » to = flag ? 0 : 1;
3417 this.store('fade:flag', !flag); 5277 this.store('fade:flag', !flag);
3418 toggle = true; 5278 toggle = true;
3419 break; 5279 break;
3420 » » » default: fade.start(o, arguments); 5280 » » » default: method = 'start'; to = how;
3421 } 5281 }
3422 if (!toggle) this.eliminate('fade:flag'); 5282 if (!toggle) this.eliminate('fade:flag');
5283 fade[method]('opacity', to);
5284 if (method == 'set' || to != 0) this.setStyle('visibility', to = = 0 ? 'hidden' : 'visible');
5285 else fade.chain(function(){
5286 this.element.setStyle('visibility', 'hidden');
5287 });
3423 return this; 5288 return this;
3424 }, 5289 },
3425 5290
3426 highlight: function(start, end){ 5291 highlight: function(start, end){
3427 if (!end){ 5292 if (!end){
3428 end = this.retrieve('highlight:original', this.getStyle( 'background-color')); 5293 end = this.retrieve('highlight:original', this.getStyle( 'background-color'));
3429 end = (end == 'transparent') ? '#fff' : end; 5294 end = (end == 'transparent') ? '#fff' : end;
3430 } 5295 }
3431 var tween = this.get('tween'); 5296 var tween = this.get('tween');
3432 tween.start('background-color', start || '#ffff88', end).chain(f unction(){ 5297 tween.start('background-color', start || '#ffff88', end).chain(f unction(){
3433 this.setStyle('background-color', this.retrieve('highlig ht:original')); 5298 this.setStyle('background-color', this.retrieve('highlig ht:original'));
3434 tween.callChain(); 5299 tween.callChain();
3435 }.bind(this)); 5300 }.bind(this));
3436 return this; 5301 return this;
3437 } 5302 }
3438 5303
3439 }); 5304 });
3440 5305
3441 5306
3442 /* 5307 /*
3443 Script: Fx.Morph.js 5308 ---
3444 » Formerly Fx.Styles, effect to transition any number of CSS properties fo r an element using an object of rules, or CSS based selector rules.
3445 5309
3446 License: 5310 name: Fx.Morph
3447 » MIT-style license. 5311
5312 description: Formerly Fx.Styles, effect to transition any number of CSS properti es for an element using an object of rules, or CSS based selector rules.
5313
5314 license: MIT-style license.
5315
5316 requires: Fx.CSS
5317
5318 provides: Fx.Morph
5319
5320 ...
3448 */ 5321 */
3449 5322
3450 Fx.Morph = new Class({ 5323 Fx.Morph = new Class({
3451 5324
3452 Extends: Fx.CSS, 5325 Extends: Fx.CSS,
3453 5326
3454 initialize: function(element, options){ 5327 initialize: function(element, options){
3455 » » this.element = this.subject = $(element); 5328 » » this.element = this.subject = document.id(element);
3456 this.parent(options); 5329 this.parent(options);
3457 }, 5330 },
3458 5331
3459 set: function(now){ 5332 set: function(now){
3460 if (typeof now == 'string') now = this.search(now); 5333 if (typeof now == 'string') now = this.search(now);
3461 for (var p in now) this.render(this.element, p, now[p], this.opt ions.unit); 5334 for (var p in now) this.render(this.element, p, now[p], this.opt ions.unit);
3462 return this; 5335 return this;
3463 }, 5336 },
3464 5337
3465 compute: function(from, to, delta){ 5338 compute: function(from, to, delta){
3466 var now = {}; 5339 var now = {};
3467 for (var p in from) now[p] = this.parent(from[p], to[p], delta); 5340 for (var p in from) now[p] = this.parent(from[p], to[p], delta);
3468 return now; 5341 return now;
3469 }, 5342 },
3470 5343
3471 start: function(properties){ 5344 start: function(properties){
3472 » » if (!this.check(arguments.callee, properties)) return this; 5345 » » if (!this.check(properties)) return this;
3473 if (typeof properties == 'string') properties = this.search(prop erties); 5346 if (typeof properties == 'string') properties = this.search(prop erties);
3474 var from = {}, to = {}; 5347 var from = {}, to = {};
3475 for (var p in properties){ 5348 for (var p in properties){
3476 var parsed = this.prepare(this.element, p, properties[p] ); 5349 var parsed = this.prepare(this.element, p, properties[p] );
3477 from[p] = parsed.from; 5350 from[p] = parsed.from;
3478 to[p] = parsed.to; 5351 to[p] = parsed.to;
3479 } 5352 }
3480 return this.parent(from, to); 5353 return this.parent(from, to);
3481 } 5354 }
3482 5355
3483 }); 5356 });
3484 5357
3485 Element.Properties.morph = { 5358 Element.Properties.morph = {
3486 5359
3487 set: function(options){ 5360 set: function(options){
3488 » » var morph = this.retrieve('morph'); 5361 » » this.get('morph').cancel().setOptions(options);
3489 » » if (morph) morph.cancel(); 5362 » » return this;
3490 » » return this.eliminate('morph').store('morph:options', $extend({l ink: 'cancel'}, options));
3491 }, 5363 },
3492 5364
3493 » get: function(options){ 5365 » get: function(){
3494 » » if (options || !this.retrieve('morph')){ 5366 » » var morph = this.retrieve('morph');
3495 » » » if (options || !this.retrieve('morph:options')) this.set ('morph', options); 5367 » » if (!morph){
3496 » » » this.store('morph', new Fx.Morph(this, this.retrieve('mo rph:options'))); 5368 » » » morph = new Fx.Morph(this, {link: 'cancel'});
5369 » » » this.store('morph', morph);
3497 } 5370 }
3498 » » return this.retrieve('morph'); 5371 » » return morph;
3499 } 5372 }
3500 5373
3501 }; 5374 };
3502 5375
3503 Element.implement({ 5376 Element.implement({
3504 5377
3505 morph: function(props){ 5378 morph: function(props){
3506 this.get('morph').start(props); 5379 this.get('morph').start(props);
3507 return this; 5380 return this;
3508 } 5381 }
3509 5382
3510 }); 5383 });
3511 5384
3512 5385
3513 /* 5386 /*
3514 Script: Fx.Transitions.js 5387 ---
3515 » Contains a set of advanced transitions to be used with any of the Fx Cla sses.
3516 5388
3517 License: 5389 name: Fx.Transitions
3518 » MIT-style license.
3519 5390
3520 Credits: 5391 description: Contains a set of advanced transitions to be used with any of the F x Classes.
3521 » Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/> , modified and optimized to be used with MooTools. 5392
5393 license: MIT-style license.
5394
5395 credits:
5396 - Easing Equations by Robert Penner, <http://www.robertpenner.com/easing/>, mo dified and optimized to be used with MooTools.
5397
5398 requires: Fx
5399
5400 provides: Fx.Transitions
5401
5402 ...
3522 */ 5403 */
3523 5404
3524 Fx.implement({ 5405 Fx.implement({
3525 5406
3526 getTransition: function(){ 5407 getTransition: function(){
3527 var trans = this.options.transition || Fx.Transitions.Sine.easeI nOut; 5408 var trans = this.options.transition || Fx.Transitions.Sine.easeI nOut;
3528 if (typeof trans == 'string'){ 5409 if (typeof trans == 'string'){
3529 var data = trans.split(':'); 5410 var data = trans.split(':');
3530 trans = Fx.Transitions; 5411 trans = Fx.Transitions;
3531 trans = trans[data[0]] || trans[data[0].capitalize()]; 5412 trans = trans[data[0]] || trans[data[0].capitalize()];
3532 if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')]; 5413 if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')];
3533 } 5414 }
3534 return trans; 5415 return trans;
3535 } 5416 }
3536 5417
3537 }); 5418 });
3538 5419
3539 Fx.Transition = function(transition, params){ 5420 Fx.Transition = function(transition, params){
3540 » params = $splat(params); 5421 » params = Array.from(params);
3541 » return $extend(transition, { 5422 » var easeIn = function(pos){
3542 » » easeIn: function(pos){ 5423 » » return transition(pos, params);
3543 » » » return transition(pos, params); 5424 » };
3544 » » }, 5425 » return Object.append(easeIn, {
5426 » » easeIn: easeIn,
3545 easeOut: function(pos){ 5427 easeOut: function(pos){
3546 return 1 - transition(1 - pos, params); 5428 return 1 - transition(1 - pos, params);
3547 }, 5429 },
3548 easeInOut: function(pos){ 5430 easeInOut: function(pos){
3549 » » » return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2; 5431 » » » return (pos <= 0.5 ? transition(2 * pos, params) : (2 - transition(2 * (1 - pos), params))) / 2;
3550 } 5432 }
3551 }); 5433 });
3552 }; 5434 };
3553 5435
3554 Fx.Transitions = new Hash({ 5436 Fx.Transitions = {
3555 5437
3556 » linear: $arguments(0) 5438 » linear: function(zero){
5439 » » return zero;
5440 » }
3557 5441
3558 }); 5442 };
5443
5444 //<1.2compat>
5445
5446 Fx.Transitions = new Hash(Fx.Transitions);
5447
5448 //</1.2compat>
3559 5449
3560 Fx.Transitions.extend = function(transitions){ 5450 Fx.Transitions.extend = function(transitions){
3561 for (var transition in transitions) Fx.Transitions[transition] = new Fx. Transition(transitions[transition]); 5451 for (var transition in transitions) Fx.Transitions[transition] = new Fx. Transition(transitions[transition]);
3562 }; 5452 };
3563 5453
3564 Fx.Transitions.extend({ 5454 Fx.Transitions.extend({
3565 5455
3566 Pow: function(p, x){ 5456 Pow: function(p, x){
3567 » » return Math.pow(p, x[0] || 6); 5457 » » return Math.pow(p, x && x[0] || 6);
3568 }, 5458 },
3569 5459
3570 Expo: function(p){ 5460 Expo: function(p){
3571 return Math.pow(2, 8 * (p - 1)); 5461 return Math.pow(2, 8 * (p - 1));
3572 }, 5462 },
3573 5463
3574 Circ: function(p){ 5464 Circ: function(p){
3575 return 1 - Math.sin(Math.acos(p)); 5465 return 1 - Math.sin(Math.acos(p));
3576 }, 5466 },
3577 5467
3578 Sine: function(p){ 5468 Sine: function(p){
3579 » » return 1 - Math.sin((1 - p) * Math.PI / 2); 5469 » » return 1 - Math.cos(p * Math.PI / 2);
3580 }, 5470 },
3581 5471
3582 Back: function(p, x){ 5472 Back: function(p, x){
3583 » » x = x[0] || 1.618; 5473 » » x = x && x[0] || 1.618;
3584 return Math.pow(p, 2) * ((x + 1) * p - x); 5474 return Math.pow(p, 2) * ((x + 1) * p - x);
3585 }, 5475 },
3586 5476
3587 Bounce: function(p){ 5477 Bounce: function(p){
3588 var value; 5478 var value;
3589 for (var a = 0, b = 1; 1; a += b, b /= 2){ 5479 for (var a = 0, b = 1; 1; a += b, b /= 2){
3590 if (p >= (7 - 4 * a) / 11){ 5480 if (p >= (7 - 4 * a) / 11){
3591 value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); 5481 value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
3592 break; 5482 break;
3593 } 5483 }
3594 } 5484 }
3595 return value; 5485 return value;
3596 }, 5486 },
3597 5487
3598 Elastic: function(p, x){ 5488 Elastic: function(p, x){
3599 » » return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3); 5489 » » return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x && x[0] || 1) / 3);
3600 } 5490 }
3601 5491
3602 }); 5492 });
3603 5493
3604 ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){ 5494 ['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){
3605 Fx.Transitions[transition] = new Fx.Transition(function(p){ 5495 Fx.Transitions[transition] = new Fx.Transition(function(p){
3606 » » return Math.pow(p, [i + 2]); 5496 » » return Math.pow(p, i + 2);
3607 }); 5497 });
3608 }); 5498 });
3609 5499
3610 5500
3611 /* 5501 /*
3612 Script: Request.js 5502 ---
3613 » Powerful all purpose Request Class. Uses XMLHTTPRequest.
3614 5503
3615 License: 5504 name: Request
3616 » MIT-style license. 5505
5506 description: Powerful all purpose Request Class. Uses XMLHTTPRequest.
5507
5508 license: MIT-style license.
5509
5510 requires: [Object, Element, Chain, Events, Options, Browser]
5511
5512 provides: Request
5513
5514 ...
3617 */ 5515 */
3618 5516
3619 var Request = new Class({ 5517 (function(){
5518
5519 var empty = function(){},
5520 » progressSupport = ('onprogress' in new Browser.Request);
5521
5522 var Request = this.Request = new Class({
3620 5523
3621 Implements: [Chain, Events, Options], 5524 Implements: [Chain, Events, Options],
3622 5525
3623 options: {/* 5526 options: {/*
3624 » » onRequest: $empty, 5527 » » onRequest: function(){},
3625 » » onComplete: $empty, 5528 » » onLoadstart: function(event, xhr){},
3626 » » onCancel: $empty, 5529 » » onProgress: function(event, xhr){},
3627 » » onSuccess: $empty, 5530 » » onComplete: function(){},
3628 » » onFailure: $empty, 5531 » » onCancel: function(){},
3629 » » onException: $empty,*/ 5532 » » onSuccess: function(responseText, responseXML){},
5533 » » onFailure: function(xhr){},
5534 » » onException: function(headerName, value){},
5535 » » onTimeout: function(){},
5536 » » user: '',
5537 » » password: '',*/
3630 url: '', 5538 url: '',
3631 data: '', 5539 data: '',
3632 headers: { 5540 headers: {
3633 'X-Requested-With': 'XMLHttpRequest', 5541 'X-Requested-With': 'XMLHttpRequest',
3634 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' 5542 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
3635 }, 5543 },
3636 async: true, 5544 async: true,
3637 format: false, 5545 format: false,
3638 method: 'post', 5546 method: 'post',
3639 link: 'ignore', 5547 link: 'ignore',
3640 isSuccess: null, 5548 isSuccess: null,
3641 emulation: true, 5549 emulation: true,
3642 urlEncoded: true, 5550 urlEncoded: true,
3643 encoding: 'utf-8', 5551 encoding: 'utf-8',
3644 evalScripts: false, 5552 evalScripts: false,
3645 » » evalResponse: false 5553 » » evalResponse: false,
5554 » » timeout: 0,
5555 » » noCache: false
3646 }, 5556 },
3647 5557
3648 initialize: function(options){ 5558 initialize: function(options){
3649 this.xhr = new Browser.Request(); 5559 this.xhr = new Browser.Request();
3650 this.setOptions(options); 5560 this.setOptions(options);
3651 » » this.options.isSuccess = this.options.isSuccess || this.isSucces s; 5561 » » this.headers = this.options.headers;
3652 » » this.headers = new Hash(this.options.headers);
3653 }, 5562 },
3654 5563
3655 onStateChange: function(){ 5564 onStateChange: function(){
3656 » » if (this.xhr.readyState != 4 || !this.running) return; 5565 » » var xhr = this.xhr;
5566 » » if (xhr.readyState != 4 || !this.running) return;
3657 this.running = false; 5567 this.running = false;
3658 this.status = 0; 5568 this.status = 0;
3659 » » $try(function(){ 5569 » » Function.attempt(function(){
3660 » » » this.status = this.xhr.status; 5570 » » » var status = xhr.status;
5571 » » » this.status = (status == 1223) ? 204 : status;
3661 }.bind(this)); 5572 }.bind(this));
3662 » » if (this.options.isSuccess.call(this, this.status)){ 5573 » » xhr.onreadystatechange = empty;
3663 » » » this.response = {text: this.xhr.responseText, xml: this. xhr.responseXML}; 5574 » » if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
5575 » » clearTimeout(this.timer);
5576
5577 » » this.response = {text: this.xhr.responseText || '', xml: this.xh r.responseXML};
5578 » » if (this.options.isSuccess.call(this, this.status))
3664 this.success(this.response.text, this.response.xml); 5579 this.success(this.response.text, this.response.xml);
3665 » » } else { 5580 » » else
3666 » » » this.response = {text: null, xml: null};
3667 this.failure(); 5581 this.failure();
3668 }
3669 this.xhr.onreadystatechange = $empty;
3670 }, 5582 },
3671 5583
3672 isSuccess: function(){ 5584 isSuccess: function(){
3673 » » return ((this.status >= 200) && (this.status < 300)); 5585 » » var status = this.status;
5586 » » return (status >= 200 && status < 300);
5587 » },
5588
5589 » isRunning: function(){
5590 » » return !!this.running;
3674 }, 5591 },
3675 5592
3676 processScripts: function(text){ 5593 processScripts: function(text){
3677 » » if (this.options.evalResponse || (/(ecma|java)script/).test(this .getHeader('Content-type'))) return $exec(text); 5594 » » if (this.options.evalResponse || (/(ecma|java)script/).test(this .getHeader('Content-type'))) return Browser.exec(text);
3678 return text.stripScripts(this.options.evalScripts); 5595 return text.stripScripts(this.options.evalScripts);
3679 }, 5596 },
3680 5597
3681 success: function(text, xml){ 5598 success: function(text, xml){
3682 this.onSuccess(this.processScripts(text), xml); 5599 this.onSuccess(this.processScripts(text), xml);
3683 }, 5600 },
3684 5601
3685 onSuccess: function(){ 5602 onSuccess: function(){
3686 this.fireEvent('complete', arguments).fireEvent('success', argum ents).callChain(); 5603 this.fireEvent('complete', arguments).fireEvent('success', argum ents).callChain();
3687 }, 5604 },
3688 5605
3689 failure: function(){ 5606 failure: function(){
3690 this.onFailure(); 5607 this.onFailure();
3691 }, 5608 },
3692 5609
3693 onFailure: function(){ 5610 onFailure: function(){
3694 this.fireEvent('complete').fireEvent('failure', this.xhr); 5611 this.fireEvent('complete').fireEvent('failure', this.xhr);
3695 }, 5612 },
3696 5613
5614 loadstart: function(event){
5615 this.fireEvent('loadstart', [event, this.xhr]);
5616 },
5617
5618 progress: function(event){
5619 this.fireEvent('progress', [event, this.xhr]);
5620 },
5621
5622 timeout: function(){
5623 this.fireEvent('timeout', this.xhr);
5624 },
5625
3697 setHeader: function(name, value){ 5626 setHeader: function(name, value){
3698 » » this.headers.set(name, value); 5627 » » this.headers[name] = value;
3699 return this; 5628 return this;
3700 }, 5629 },
3701 5630
3702 getHeader: function(name){ 5631 getHeader: function(name){
3703 » » return $try(function(){ 5632 » » return Function.attempt(function(){
3704 return this.xhr.getResponseHeader(name); 5633 return this.xhr.getResponseHeader(name);
3705 }.bind(this)); 5634 }.bind(this));
3706 }, 5635 },
3707 5636
3708 » check: function(caller){ 5637 » check: function(){
3709 if (!this.running) return true; 5638 if (!this.running) return true;
3710 switch (this.options.link){ 5639 switch (this.options.link){
3711 case 'cancel': this.cancel(); return true; 5640 case 'cancel': this.cancel(); return true;
3712 » » » case 'chain': this.chain(caller.bind(this, Array.slice(a rguments, 1))); return false; 5641 » » » case 'chain': this.chain(this.caller.pass(arguments, thi s)); return false;
3713 } 5642 }
3714 return false; 5643 return false;
3715 }, 5644 },
3716 5645
3717 send: function(options){ 5646 send: function(options){
3718 » » if (!this.check(arguments.callee, options)) return this; 5647 » » if (!this.check(options)) return this;
5648
5649 » » this.options.isSuccess = this.options.isSuccess || this.isSucces s;
3719 this.running = true; 5650 this.running = true;
3720 5651
3721 » » var type = $type(options); 5652 » » var type = typeOf(options);
3722 if (type == 'string' || type == 'element') options = {data: opti ons}; 5653 if (type == 'string' || type == 'element') options = {data: opti ons};
3723 5654
3724 var old = this.options; 5655 var old = this.options;
3725 » » options = $extend({data: old.data, url: old.url, method: old.met hod}, options); 5656 » » options = Object.append({data: old.data, url: old.url, method: o ld.method}, options);
3726 » » var data = options.data, url = options.url, method = options.met hod; 5657 » » var data = options.data, url = String(options.url), method = opt ions.method.toLowerCase();
3727 5658
3728 » » switch ($type(data)){ 5659 » » switch (typeOf(data)){
3729 » » » case 'element': data = $(data).toQueryString(); break; 5660 » » » case 'element': data = document.id(data).toQueryString() ; break;
3730 » » » case 'object': case 'hash': data = Hash.toQueryString(da ta); 5661 » » » case 'object': case 'hash': data = Object.toQueryString( data);
3731 } 5662 }
3732 5663
3733 if (this.options.format){ 5664 if (this.options.format){
3734 var format = 'format=' + this.options.format; 5665 var format = 'format=' + this.options.format;
3735 data = (data) ? format + '&' + data : format; 5666 data = (data) ? format + '&' + data : format;
3736 } 5667 }
3737 5668
3738 » » if (this.options.emulation && ['put', 'delete'].contains(method) ){ 5669 » » if (this.options.emulation && !['get', 'post'].contains(method)) {
3739 var _method = '_method=' + method; 5670 var _method = '_method=' + method;
3740 data = (data) ? _method + '&' + data : _method; 5671 data = (data) ? _method + '&' + data : _method;
3741 method = 'post'; 5672 method = 'post';
3742 } 5673 }
3743 5674
3744 » » if (this.options.urlEncoded && method == 'post'){ 5675 » » if (this.options.urlEncoded && ['post', 'put'].contains(method)) {
3745 var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; 5676 var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : '';
3746 » » » this.headers.set('Content-type', 'application/x-www-form -urlencoded' + encoding); 5677 » » » this.headers['Content-type'] = 'application/x-www-form-u rlencoded' + encoding;
3747 » » } 5678 » » }
5679
5680 » » if (!url) url = document.location.pathname;
5681
5682 » » var trimPosition = url.lastIndexOf('/');
5683 » » if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition);
5684
5685 » » if (this.options.noCache)
5686 » » » url += (url.contains('?') ? '&' : '?') + String.uniqueID ();
3748 5687
3749 if (data && method == 'get'){ 5688 if (data && method == 'get'){
3750 » » » url = url + (url.contains('?') ? '&' : '?') + data; 5689 » » » url += (url.contains('?') ? '&' : '?') + data;
3751 data = null; 5690 data = null;
3752 } 5691 }
3753 5692
3754 » » this.xhr.open(method.toUpperCase(), url, this.options.async); 5693 » » var xhr = this.xhr;
3755 5694 » » if (progressSupport){
3756 » » this.xhr.onreadystatechange = this.onStateChange.bind(this); 5695 » » » xhr.onloadstart = this.loadstart.bind(this);
3757 5696 » » » xhr.onprogress = this.progress.bind(this);
3758 » » this.headers.each(function(value, key){ 5697 » » }
5698
5699 » » xhr.open(method.toUpperCase(), url, this.options.async, this.opt ions.user, this.options.password);
5700 » » if (this.options.user && 'withCredentials' in xhr) xhr.withCrede ntials = true;
5701
5702 » » xhr.onreadystatechange = this.onStateChange.bind(this);
5703
5704 » » Object.each(this.headers, function(value, key){
3759 try { 5705 try {
3760 » » » » this.xhr.setRequestHeader(key, value); 5706 » » » » xhr.setRequestHeader(key, value);
3761 } catch (e){ 5707 } catch (e){
3762 this.fireEvent('exception', [key, value]); 5708 this.fireEvent('exception', [key, value]);
3763 } 5709 }
3764 }, this); 5710 }, this);
3765 5711
3766 this.fireEvent('request'); 5712 this.fireEvent('request');
3767 » » this.xhr.send(data); 5713 » » xhr.send(data);
3768 if (!this.options.async) this.onStateChange(); 5714 if (!this.options.async) this.onStateChange();
5715 if (this.options.timeout) this.timer = this.timeout.delay(this.o ptions.timeout, this);
3769 return this; 5716 return this;
3770 }, 5717 },
3771 5718
3772 cancel: function(){ 5719 cancel: function(){
3773 if (!this.running) return this; 5720 if (!this.running) return this;
3774 this.running = false; 5721 this.running = false;
3775 » » this.xhr.abort(); 5722 » » var xhr = this.xhr;
3776 » » this.xhr.onreadystatechange = $empty; 5723 » » xhr.abort();
5724 » » clearTimeout(this.timer);
5725 » » xhr.onreadystatechange = empty;
5726 » » if (progressSupport) xhr.onprogress = xhr.onloadstart = empty;
3777 this.xhr = new Browser.Request(); 5727 this.xhr = new Browser.Request();
3778 this.fireEvent('cancel'); 5728 this.fireEvent('cancel');
3779 return this; 5729 return this;
3780 } 5730 }
3781 5731
3782 }); 5732 });
3783 5733
3784 (function(){
3785
3786 var methods = {}; 5734 var methods = {};
3787 ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(m ethod){ 5735 ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(m ethod){
3788 » methods[method] = function(){ 5736 » methods[method] = function(data){
3789 » » var params = Array.link(arguments, {url: String.type, data: $def ined}); 5737 » » var object = {
3790 » » return this.send($extend(params, {method: method.toLowerCase()}) ); 5738 » » » method: method
5739 » » };
5740 » » if (data != null) object.data = data;
5741 » » return this.send(object);
3791 }; 5742 };
3792 }); 5743 });
3793 5744
3794 Request.implement(methods); 5745 Request.implement(methods);
3795 5746
3796 })();
3797
3798 Element.Properties.send = { 5747 Element.Properties.send = {
3799 5748
3800 set: function(options){ 5749 set: function(options){
5750 var send = this.get('send').cancel();
5751 send.setOptions(options);
5752 return this;
5753 },
5754
5755 get: function(){
3801 var send = this.retrieve('send'); 5756 var send = this.retrieve('send');
3802 » » if (send) send.cancel(); 5757 » » if (!send){
3803 » » return this.eliminate('send').store('send:options', $extend({ 5758 » » » send = new Request({
3804 » » » data: this, link: 'cancel', method: this.get('method') | | 'post', url: this.get('action') 5759 » » » » data: this, link: 'cancel', method: this.get('me thod') || 'post', url: this.get('action')
3805 » » }, options)); 5760 » » » });
3806 » }, 5761 » » » this.store('send', send);
3807 5762 » » }
3808 » get: function(options){ 5763 » » return send;
3809 » » if (options || !this.retrieve('send')){
3810 » » » if (options || !this.retrieve('send:options')) this.set( 'send', options);
3811 » » » this.store('send', new Request(this.retrieve('send:optio ns')));
3812 » » }
3813 » » return this.retrieve('send');
3814 } 5764 }
3815 5765
3816 }; 5766 };
3817 5767
3818 Element.implement({ 5768 Element.implement({
3819 5769
3820 send: function(url){ 5770 send: function(url){
3821 var sender = this.get('send'); 5771 var sender = this.get('send');
3822 sender.send({data: this, url: url || sender.options.url}); 5772 sender.send({data: this, url: url || sender.options.url});
3823 return this; 5773 return this;
3824 } 5774 }
3825 5775
3826 }); 5776 });
3827 5777
5778 })();
3828 5779
3829 /* 5780 /*
3830 Script: Request.HTML.js 5781 ---
3831 » Extends the basic Request Class with additional methods for interacting with HTML responses. 5782
3832 5783 name: Request.HTML
3833 License: 5784
3834 » MIT-style license. 5785 description: Extends the basic Request Class with additional methods for interac ting with HTML responses.
5786
5787 license: MIT-style license.
5788
5789 requires: [Element, Request]
5790
5791 provides: Request.HTML
5792
5793 ...
3835 */ 5794 */
3836 5795
3837 Request.HTML = new Class({ 5796 Request.HTML = new Class({
3838 5797
3839 Extends: Request, 5798 Extends: Request,
3840 5799
3841 options: { 5800 options: {
3842 update: false, 5801 update: false,
5802 append: false,
3843 evalScripts: true, 5803 evalScripts: true,
3844 » » filter: false 5804 » » filter: false,
3845 » }, 5805 » » headers: {
3846 5806 » » » Accept: 'text/html, application/xml, text/xml, */*'
3847 » processHTML: function(text){ 5807 » » }
3848 » » var match = text.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
3849 » » text = (match) ? match[1] : text;
3850
3851 » » var container = new Element('div');
3852
3853 » » return $try(function(){
3854 » » » var root = '<root>' + text + '</root>', doc;
3855 » » » if (Browser.Engine.trident){
3856 » » » » doc = new ActiveXObject('Microsoft.XMLDOM');
3857 » » » » doc.async = false;
3858 » » » » doc.loadXML(root);
3859 » » » } else {
3860 » » » » doc = new DOMParser().parseFromString(root, 'tex t/xml');
3861 » » » }
3862 » » » root = doc.getElementsByTagName('root')[0];
3863 » » » for (var i = 0, k = root.childNodes.length; i < k; i++){
3864 » » » » var child = Element.clone(root.childNodes[i], tr ue, true);
3865 » » » » if (child) container.grab(child);
3866 » » » }
3867 » » » return container;
3868 » » }) || container.set('html', text);
3869 }, 5808 },
3870 5809
3871 success: function(text){ 5810 success: function(text){
3872 var options = this.options, response = this.response; 5811 var options = this.options, response = this.response;
3873 5812
3874 response.html = text.stripScripts(function(script){ 5813 response.html = text.stripScripts(function(script){
3875 response.javascript = script; 5814 response.javascript = script;
3876 }); 5815 });
3877 5816
3878 » » var temp = this.processHTML(response.html); 5817 » » var match = response.html.match(/<body[^>]*>([\s\S]*?)<\/body>/i );
5818 » » if (match) response.html = match[1];
5819 » » var temp = new Element('div').set('html', response.html);
3879 5820
3880 response.tree = temp.childNodes; 5821 response.tree = temp.childNodes;
3881 » » response.elements = temp.getElements('*'); 5822 » » response.elements = temp.getElements(options.filter || '*');
3882 5823
3883 » » if (options.filter) response.tree = response.elements.filter(opt ions.filter); 5824 » » if (options.filter) response.tree = response.elements;
3884 » » if (options.update) $(options.update).empty().set('html', respon se.html); 5825 » » if (options.update){
3885 » » if (options.evalScripts) $exec(response.javascript); 5826 » » » var update = document.id(options.update).empty();
5827 » » » if (options.filter) update.adopt(response.elements);
5828 » » » else update.set('html', response.html);
5829 » » } else if (options.append){
5830 » » » var append = document.id(options.append);
5831 » » » if (options.filter) response.elements.reverse().inject(a ppend);
5832 » » » else append.adopt(temp.getChildren());
5833 » » }
5834 » » if (options.evalScripts) Browser.exec(response.javascript);
3886 5835
3887 this.onSuccess(response.tree, response.elements, response.html, response.javascript); 5836 this.onSuccess(response.tree, response.elements, response.html, response.javascript);
3888 } 5837 }
3889 5838
3890 }); 5839 });
3891 5840
3892 Element.Properties.load = { 5841 Element.Properties.load = {
3893 5842
3894 set: function(options){ 5843 set: function(options){
5844 var load = this.get('load').cancel();
5845 load.setOptions(options);
5846 return this;
5847 },
5848
5849 get: function(){
3895 var load = this.retrieve('load'); 5850 var load = this.retrieve('load');
3896 » » if (load) load.cancel(); 5851 » » if (!load){
3897 » » return this.eliminate('load').store('load:options', $extend({dat a: this, link: 'cancel', update: this, method: 'get'}, options)); 5852 » » » load = new Request.HTML({data: this, link: 'cancel', upd ate: this, method: 'get'});
3898 » }, 5853 » » » this.store('load', load);
3899 5854 » » }
3900 » get: function(options){ 5855 » » return load;
3901 » » if (options || ! this.retrieve('load')){
3902 » » » if (options || !this.retrieve('load:options')) this.set( 'load', options);
3903 » » » this.store('load', new Request.HTML(this.retrieve('load: options')));
3904 » » }
3905 » » return this.retrieve('load');
3906 } 5856 }
3907 5857
3908 }; 5858 };
3909 5859
3910 Element.implement({ 5860 Element.implement({
3911 5861
3912 load: function(){ 5862 load: function(){
3913 » » this.get('load').send(Array.link(arguments, {data: Object.type, url: String.type})); 5863 » » this.get('load').send(Array.link(arguments, {data: Type.isObject , url: Type.isString}));
3914 return this; 5864 return this;
3915 } 5865 }
3916 5866
3917 }); 5867 });
3918 5868
3919 5869
3920 /* 5870 /*
3921 Script: Request.JSON.js 5871 ---
3922 » Extends the basic Request Class with additional methods for sending and receiving JSON data. 5872
3923 5873 name: JSON
3924 License: 5874
3925 » MIT-style license. 5875 description: JSON encoder and decoder.
5876
5877 license: MIT-style license.
5878
5879 SeeAlso: <http://www.json.org/>
5880
5881 requires: [Array, String, Number, Function]
5882
5883 provides: JSON
5884
5885 ...
3926 */ 5886 */
3927 5887
5888 if (typeof JSON == 'undefined') this.JSON = {};
5889
5890 //<1.2compat>
5891
5892 JSON = new Hash({
5893 stringify: JSON.stringify,
5894 parse: JSON.parse
5895 });
5896
5897 //</1.2compat>
5898
5899 (function(){
5900
5901 var special = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
5902
5903 var escape = function(chr){
5904 return special[chr] || '\\u' + ('0000' + chr.charCodeAt(0).toString(16)) .slice(-4);
5905 };
5906
5907 JSON.validate = function(string){
5908 string = string.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
5909 replace(/"[^"\\\n\r]*"|true|false|null|- ?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
5910 replace(/(?:^|:|,)(?:\s*\[)+/g, '');
5911
5912 return (/^[\],:{}\s]*$/).test(string);
5913 };
5914
5915 JSON.encode = JSON.stringify ? function(obj){
5916 return JSON.stringify(obj);
5917 } : function(obj){
5918 if (obj && obj.toJSON) obj = obj.toJSON();
5919
5920 switch (typeOf(obj)){
5921 case 'string':
5922 return '"' + obj.replace(/[\x00-\x1f\\"]/g, escape) + '" ';
5923 case 'array':
5924 return '[' + obj.map(JSON.encode).clean() + ']';
5925 case 'object': case 'hash':
5926 var string = [];
5927 Object.each(obj, function(value, key){
5928 var json = JSON.encode(value);
5929 if (json) string.push(JSON.encode(key) + ':' + j son);
5930 });
5931 return '{' + string + '}';
5932 case 'number': case 'boolean': return '' + obj;
5933 case 'null': return 'null';
5934 }
5935
5936 return null;
5937 };
5938
5939 JSON.decode = function(string, secure){
5940 if (!string || typeOf(string) != 'string') return null;
5941
5942 if (secure || JSON.secure){
5943 if (JSON.parse) return JSON.parse(string);
5944 if (!JSON.validate(string)) throw new Error('JSON could not deco de the input; security is enabled and the value is not secure.');
5945 }
5946
5947 return eval('(' + string + ')');
5948 };
5949
5950 })();
5951
5952
5953 /*
5954 ---
5955
5956 name: Request.JSON
5957
5958 description: Extends the basic Request Class with additional methods for sending and receiving JSON data.
5959
5960 license: MIT-style license.
5961
5962 requires: [Request, JSON]
5963
5964 provides: Request.JSON
5965
5966 ...
5967 */
5968
3928 Request.JSON = new Class({ 5969 Request.JSON = new Class({
3929 5970
3930 Extends: Request, 5971 Extends: Request,
3931 5972
3932 options: { 5973 options: {
5974 /*onError: function(text, error){},*/
3933 secure: true 5975 secure: true
3934 }, 5976 },
3935 5977
3936 initialize: function(options){ 5978 initialize: function(options){
3937 this.parent(options); 5979 this.parent(options);
3938 » » this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'}); 5980 » » Object.append(this.headers, {
5981 » » » 'Accept': 'application/json',
5982 » » » 'X-Request': 'JSON'
5983 » » });
3939 }, 5984 },
3940 5985
3941 success: function(text){ 5986 success: function(text){
3942 » » this.response.json = JSON.decode(text, this.options.secure); 5987 » » var json;
3943 » » this.onSuccess(this.response.json, text); 5988 » » try {
3944 » } 5989 » » » json = this.response.json = JSON.decode(text, this.optio ns.secure);
3945 5990 » » } catch (error){
3946 }); 5991 » » » this.fireEvent('error', [text, error]);
5992 » » » return;
5993 » » }
5994 » » if (json == null) this.onFailure();
5995 » » else this.onSuccess(json, text);
5996 » }
5997
5998 });
5999
6000
6001 /*
6002 ---
6003
6004 name: Cookie
6005
6006 description: Class for creating, reading, and deleting browser Cookies.
6007
6008 license: MIT-style license.
6009
6010 credits:
6011 - Based on the functions by Peter-Paul Koch (http://quirksmode.org).
6012
6013 requires: [Options, Browser]
6014
6015 provides: Cookie
6016
6017 ...
6018 */
6019
6020 var Cookie = new Class({
6021
6022 » Implements: Options,
6023
6024 » options: {
6025 » » path: '/',
6026 » » domain: false,
6027 » » duration: false,
6028 » » secure: false,
6029 » » document: document,
6030 » » encode: true
6031 » },
6032
6033 » initialize: function(key, options){
6034 » » this.key = key;
6035 » » this.setOptions(options);
6036 » },
6037
6038 » write: function(value){
6039 » » if (this.options.encode) value = encodeURIComponent(value);
6040 » » if (this.options.domain) value += '; domain=' + this.options.dom ain;
6041 » » if (this.options.path) value += '; path=' + this.options.path;
6042 » » if (this.options.duration){
6043 » » » var date = new Date();
6044 » » » date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000);
6045 » » » value += '; expires=' + date.toGMTString();
6046 » » }
6047 » » if (this.options.secure) value += '; secure';
6048 » » this.options.document.cookie = this.key + '=' + value;
6049 » » return this;
6050 » },
6051
6052 » read: function(){
6053 » » var value = this.options.document.cookie.match('(?:^|;)\\s*' + t his.key.escapeRegExp() + '=([^;]*)');
6054 » » return (value) ? decodeURIComponent(value[1]) : null;
6055 » },
6056
6057 » dispose: function(){
6058 » » new Cookie(this.key, Object.merge({}, this.options, {duration: - 1})).write('');
6059 » » return this;
6060 » }
6061
6062 });
6063
6064 Cookie.write = function(key, value, options){
6065 » return new Cookie(key, options).write(value);
6066 };
6067
6068 Cookie.read = function(key){
6069 » return new Cookie(key).read();
6070 };
6071
6072 Cookie.dispose = function(key, options){
6073 » return new Cookie(key, options).dispose();
6074 };
6075
6076
6077 /*
6078 ---
6079
6080 name: DOMReady
6081
6082 description: Contains the custom event domready.
6083
6084 license: MIT-style license.
6085
6086 requires: [Browser, Element, Element.Event]
6087
6088 provides: [DOMReady, DomReady]
6089
6090 ...
6091 */
6092
6093 (function(window, document){
6094
6095 var ready,
6096 » loaded,
6097 » checks = [],
6098 » shouldPoll,
6099 » timer,
6100 » testElement = document.createElement('div');
6101
6102 var domready = function(){
6103 » clearTimeout(timer);
6104 » if (ready) return;
6105 » Browser.loaded = ready = true;
6106 » document.removeListener('DOMContentLoaded', domready).removeListener('re adystatechange', check);
6107
6108 » document.fireEvent('domready');
6109 » window.fireEvent('domready');
6110 };
6111
6112 var check = function(){
6113 » for (var i = checks.length; i--;) if (checks[i]()){
6114 » » domready();
6115 » » return true;
6116 » }
6117 » return false;
6118 };
6119
6120 var poll = function(){
6121 » clearTimeout(timer);
6122 » if (!check()) timer = setTimeout(poll, 10);
6123 };
6124
6125 document.addListener('DOMContentLoaded', domready);
6126
6127 /*<ltIE8>*/
6128 // doScroll technique by Diego Perini http://javascript.nwbox.com/IEContentLoade d/
6129 // testElement.doScroll() throws when the DOM is not ready, only in the top wind ow
6130 var doScrollWorks = function(){
6131 » try {
6132 » » testElement.doScroll();
6133 » » return true;
6134 » } catch (e){}
6135 » return false;
6136 };
6137 // If doScroll works already, it can't be used to determine domready
6138 // e.g. in an iframe
6139 if (testElement.doScroll && !doScrollWorks()){
6140 » checks.push(doScrollWorks);
6141 » shouldPoll = true;
6142 }
6143 /*</ltIE8>*/
6144
6145 if (document.readyState) checks.push(function(){
6146 » var state = document.readyState;
6147 » return (state == 'loaded' || state == 'complete');
6148 });
6149
6150 if ('onreadystatechange' in document) document.addListener('readystatechange', c heck);
6151 else shouldPoll = true;
6152
6153 if (shouldPoll) poll();
6154
6155 Element.Events.domready = {
6156 » onAdd: function(fn){
6157 » » if (ready) fn.call(this);
6158 » }
6159 };
6160
6161 // Make sure that domready fires before load
6162 Element.Events.load = {
6163 » base: 'load',
6164 » onAdd: function(fn){
6165 » » if (loaded && this == window) fn.call(this);
6166 » },
6167 » condition: function(){
6168 » » if (this == window){
6169 » » » domready();
6170 » » » delete Element.Events.load;
6171 » » }
6172 » » return true;
6173 » }
6174 };
6175
6176 // This is based on the custom load event
6177 window.addEvent('load', function(){
6178 » loaded = true;
6179 });
6180
6181 })(window, document);
6182
6183
6184 /*
6185 ---
6186
6187 name: Swiff
6188
6189 description: Wrapper for embedding SWF movies. Supports External Interface Commu nication.
6190
6191 license: MIT-style license.
6192
6193 credits:
6194 - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObje ct.
6195
6196 requires: [Options, Object, Element]
6197
6198 provides: Swiff
6199
6200 ...
6201 */
6202
6203 (function(){
6204
6205 var Swiff = this.Swiff = new Class({
6206
6207 » Implements: Options,
6208
6209 » options: {
6210 » » id: null,
6211 » » height: 1,
6212 » » width: 1,
6213 » » container: null,
6214 » » properties: {},
6215 » » params: {
6216 » » » quality: 'high',
6217 » » » allowScriptAccess: 'always',
6218 » » » wMode: 'window',
6219 » » » swLiveConnect: true
6220 » » },
6221 » » callBacks: {},
6222 » » vars: {}
6223 » },
6224
6225 » toElement: function(){
6226 » » return this.object;
6227 » },
6228
6229 » initialize: function(path, options){
6230 » » this.instance = 'Swiff_' + String.uniqueID();
6231
6232 » » this.setOptions(options);
6233 » » options = this.options;
6234 » » var id = this.id = options.id || this.instance;
6235 » » var container = document.id(options.container);
6236
6237 » » Swiff.CallBacks[this.instance] = {};
6238
6239 » » var params = options.params, vars = options.vars, callBacks = op tions.callBacks;
6240 » » var properties = Object.append({height: options.height, width: o ptions.width}, options.properties);
6241
6242 » » var self = this;
6243
6244 » » for (var callBack in callBacks){
6245 » » » Swiff.CallBacks[this.instance][callBack] = (function(opt ion){
6246 » » » » return function(){
6247 » » » » » return option.apply(self.object, argumen ts);
6248 » » » » };
6249 » » » })(callBacks[callBack]);
6250 » » » vars[callBack] = 'Swiff.CallBacks.' + this.instance + '. ' + callBack;
6251 » » }
6252
6253 » » params.flashVars = Object.toQueryString(vars);
6254 » » if (Browser.ie){
6255 » » » properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-4445 53540000';
6256 » » » params.movie = path;
6257 » » } else {
6258 » » » properties.type = 'application/x-shockwave-flash';
6259 » » }
6260 » » properties.data = path;
6261
6262 » » var build = '<object id="' + id + '"';
6263 » » for (var property in properties) build += ' ' + property + '="' + properties[property] + '"';
6264 » » build += '>';
6265 » » for (var param in params){
6266 » » » if (params[param]) build += '<param name="' + param + '" value="' + params[param] + '" />';
6267 » » }
6268 » » build += '</object>';
6269 » » this.object = ((container) ? container.empty() : new Element('di v')).set('html', build).firstChild;
6270 » },
6271
6272 » replaces: function(element){
6273 » » element = document.id(element, true);
6274 » » element.parentNode.replaceChild(this.toElement(), element);
6275 » » return this;
6276 » },
6277
6278 » inject: function(element){
6279 » » document.id(element, true).appendChild(this.toElement());
6280 » » return this;
6281 » },
6282
6283 » remote: function(){
6284 » » return Swiff.remote.apply(Swiff, [this.toElement()].append(argum ents));
6285 » }
6286
6287 });
6288
6289 Swiff.CallBacks = {};
6290
6291 Swiff.remote = function(obj, fn){
6292 » var rs = obj.CallFunction('<invoke name="' + fn + '" returntype="javascr ipt">' + __flash__argumentsToXML(arguments, 2) + '</invoke>');
6293 » return eval(rs);
6294 };
6295
6296 })();
6297
OLDNEW
« no previous file with comments | « chrome/test/data/dromaeo/lib/jquery.2.0.3.js ('k') | chrome/test/data/dromaeo/lib/prototype.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698