//MooTools, , My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2009 Valerio Proietti, , MIT Style License. //MooTools More, . Copyright (c) 2006-2009 Aaron Newton , Valerio Proietti & the MooTools team , MIT Style License. /* Clientcide Copyright (c) 2006-2009, http://www.clientcide.com/wiki/cnet-libraries#license*/ //Contents: Core, Browser, Array, String, Function, Number, Hash, Class, Class.Extras, Cookie, Swiff, More, Element, Event, Element.Event, Request, Request.HTML, Class.Binds, Class.Occlude, Class.Refactor, Fx, Element.Style, Fx.CSS, Fx.Tween, Element.Dimensions, Element.Measure, Element.Position, IframeShim, Mask, Spinner, String.QueryString, Form.Request, Lang, Selectors, JSON, Date.English.US, Date, Element.Forms, Form.Validator.English, Element.Shortcuts, Form.Validator, Form.Validator.Extras, OverText, Fx.Scroll, Fx.SmoothScroll, Date.Russian, Form.Validator.Russian, DomReady, Clientcide, Class.ToElement, Element.Pin, dbug, StyleWriter, StickyWin, StickyWin.Modal, Tips, Hash.Extras, String.Extras, StickyWin.UI, StickyWin.UI.Pointy, StickyWin.PointyTip, Tips.Pointy, Fx.Slide, HoverGroup, MenuSlider, Fx.Morph, TabSwapper, DatePicker, Form.Validator.Inline, Form.Validator.Tips, Autocompleter.Observer, Autocompleter, Request.JSON, Autocompleter.Remote //This lib: http://www.clientcide.com/js/build.php?require[]=Cookie&require[]=Swiff&require[]=Form.Request&require[]=Form.Validator.Extras&require[]=OverText&require[]=Fx.SmoothScroll&require[]=Spinner&require[]=Date.Russian&require[]=Form.Validator.Russian&require[]=StickyWin.Modal&require[]=Tips.Pointy&require[]=MenuSlider&require[]=TabSwapper&require[]=DatePicker&require[]=Form.Validator.Tips&require[]=Autocompleter.Remote&compression=none /* --- script: Core.js description: The core of MooTools, contains all the base functions and the Native and Hash implementations. Required by all the other scripts. license: MIT-style license. copyright: Copyright (c) 2006-2008 [Valerio Proietti](http://mad4milk.net/). authors: The MooTools production team (http://mootools.net/developers/) inspiration: - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) provides: [Mootools, Native, Hash.base, Array.each, $util] ... */ var MooTools = { 'version': '1.2.4', 'build': '0d9113241a90b9cd5643b926795852a2026710d4' }; var Native = function(options){ options = options || {}; var name = options.name; var legacy = options.legacy; var protect = options.protect; var methods = options.implement; var generics = options.generics; var initialize = options.initialize; var afterImplement = options.afterImplement || function(){}; var object = initialize || legacy; generics = generics !== false; object.constructor = Native; object.$family = {name: 'native'}; if (legacy && initialize) object.prototype = legacy.prototype; object.prototype.constructor = object; if (name){ var family = name.toLowerCase(); object.prototype.$family = {name: family}; Native.typize(object, family); } var add = function(obj, name, method, force){ if (!protect || force || !obj.prototype[name]) obj.prototype[name] = method; if (generics) Native.genericize(obj, name, protect); afterImplement.call(obj, name, method); return obj; }; object.alias = function(a1, a2, a3){ if (typeof a1 == 'string'){ var pa1 = this.prototype[a1]; if ((a1 = pa1)) return add(this, a2, a1, a3); } for (var a in a1) this.alias(a, a1[a], a2); return this; }; object.implement = function(a1, a2, a3){ if (typeof a1 == 'string') return add(this, a1, a2, a3); for (var p in a1) add(this, p, a1[p], a2); return this; }; if (methods) object.implement(methods); return object; }; Native.genericize = function(object, property, check){ if ((!check || !object[property]) && typeof object.prototype[property] == 'function') object[property] = function(){ var args = Array.prototype.slice.call(arguments); return object.prototype[property].apply(args.shift(), args); }; }; Native.implement = function(objects, properties){ for (var i = 0, l = objects.length; i < l; i++) objects[i].implement(properties); }; Native.typize = function(object, family){ if (!object.type) object.type = function(item){ return ($type(item) === family); }; }; (function(){ var natives = {'Array': Array, 'Date': Date, 'Function': Function, 'Number': Number, 'RegExp': RegExp, 'String': String}; for (var n in natives) new Native({name: n, initialize: natives[n], protect: true}); var types = {'boolean': Boolean, 'native': Native, 'object': Object}; for (var t in types) Native.typize(types[t], t); var generics = { 'Array': ["concat", "indexOf", "join", "lastIndexOf", "pop", "push", "reverse", "shift", "slice", "sort", "splice", "toString", "unshift", "valueOf"], 'String': ["charAt", "charCodeAt", "concat", "indexOf", "lastIndexOf", "match", "replace", "search", "slice", "split", "substr", "substring", "toLowerCase", "toUpperCase", "valueOf"] }; for (var g in generics){ for (var i = generics[g].length; i--;) Native.genericize(natives[g], generics[g][i], true); } })(); var Hash = new Native({ name: 'Hash', initialize: function(object){ if ($type(object) == 'hash') object = $unlink(object.getClean()); for (var key in object) this[key] = object[key]; return this; } }); Hash.implement({ forEach: function(fn, bind){ for (var key in this){ if (this.hasOwnProperty(key)) fn.call(bind, this[key], key, this); } }, getClean: function(){ var clean = {}; for (var key in this){ if (this.hasOwnProperty(key)) clean[key] = this[key]; } return clean; }, getLength: function(){ var length = 0; for (var key in this){ if (this.hasOwnProperty(key)) length++; } return length; } }); Hash.alias('forEach', 'each'); Array.implement({ forEach: function(fn, bind){ for (var i = 0, l = this.length; i < l; i++) fn.call(bind, this[i], i, this); } }); Array.alias('forEach', 'each'); function $A(iterable){ if (iterable.item){ var l = iterable.length, array = new Array(l); while (l--) array[l] = iterable[l]; return array; } return Array.prototype.slice.call(iterable); }; function $arguments(i){ return function(){ return arguments[i]; }; }; function $chk(obj){ return !!(obj || obj === 0); }; function $clear(timer){ clearTimeout(timer); clearInterval(timer); return null; }; function $defined(obj){ return (obj != undefined); }; function $each(iterable, fn, bind){ var type = $type(iterable); ((type == 'arguments' || type == 'collection' || type == 'array') ? Array : Hash).each(iterable, fn, bind); }; function $empty(){}; function $extend(original, extended){ for (var key in (extended || {})) original[key] = extended[key]; return original; }; function $H(object){ return new Hash(object); }; function $lambda(value){ return ($type(value) == 'function') ? value : function(){ return value; }; }; function $merge(){ var args = Array.slice(arguments); args.unshift({}); return $mixin.apply(null, args); }; function $mixin(mix){ for (var i = 1, l = arguments.length; i < l; i++){ var object = arguments[i]; if ($type(object) != 'object') continue; for (var key in object){ var op = object[key], mp = mix[key]; mix[key] = (mp && $type(op) == 'object' && $type(mp) == 'object') ? $mixin(mp, op) : $unlink(op); } } return mix; }; function $pick(){ for (var i = 0, l = arguments.length; i < l; i++){ if (arguments[i] != undefined) return arguments[i]; } return null; }; function $random(min, max){ return Math.floor(Math.random() * (max - min + 1) + min); }; function $splat(obj){ var type = $type(obj); return (type) ? ((type != 'array' && type != 'arguments') ? [obj] : obj) : []; }; var $time = Date.now || function(){ return +new Date; }; function $try(){ for (var i = 0, l = arguments.length; i < l; i++){ try { return arguments[i](); } catch(e){} } return null; }; function $type(obj){ if (obj == undefined) return false; if (obj.$family) return (obj.$family.name == 'number' && !isFinite(obj)) ? false : obj.$family.name; if (obj.nodeName){ switch (obj.nodeType){ case 1: return 'element'; case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace'; } } else if (typeof obj.length == 'number'){ if (obj.callee) return 'arguments'; else if (obj.item) return 'collection'; } return typeof obj; }; function $unlink(object){ var unlinked; switch ($type(object)){ case 'object': unlinked = {}; for (var p in object) unlinked[p] = $unlink(object[p]); break; case 'hash': unlinked = new Hash(object); break; case 'array': unlinked = []; for (var i = 0, l = object.length; i < l; i++) unlinked[i] = $unlink(object[i]); break; default: return object; } return unlinked; }; /* --- script: Browser.js description: The Browser Core. Contains Browser initialization, Window and Document, and the Browser Hash. license: MIT-style license. requires: - /Native - /$util provides: [Browser, Window, Document, $exec] ... */ var Browser = $merge({ Engine: {name: 'unknown', version: 0}, Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()}, Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}, Plugins: {}, Engines: { presto: function(){ return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }, trident: function(){ return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }, webkit: function(){ return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419); }, gecko: function(){ return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); } } }, Browser || {}); Browser.Platform[Browser.Platform.name] = true; Browser.detect = function(){ for (var engine in this.Engines){ var version = this.Engines[engine](); if (version){ this.Engine = {name: engine, version: version}; this.Engine[engine] = this.Engine[engine + version] = true; break; } } return {name: engine, version: version}; }; Browser.detect(); Browser.Request = function(){ return $try(function(){ return new XMLHttpRequest(); }, function(){ return new ActiveXObject('MSXML2.XMLHTTP'); }, function(){ return new ActiveXObject('Microsoft.XMLHTTP'); }); }; Browser.Features.xhr = !!(Browser.Request()); Browser.Plugins.Flash = (function(){ var version = ($try(function(){ return navigator.plugins['Shockwave Flash'].description; }, function(){ return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); }) || '0 r0').match(/\d+/g); return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; })(); function $exec(text){ if (!text) return text; if (window.execScript){ window.execScript(text); } else { var script = document.createElement('script'); script.setAttribute('type', 'text/javascript'); script[(Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerText' : 'text'] = text; document.head.appendChild(script); document.head.removeChild(script); } return text; }; Native.UID = 1; var $uid = (Browser.Engine.trident) ? function(item){ return (item.uid || (item.uid = [Native.UID++]))[0]; } : function(item){ return item.uid || (item.uid = Native.UID++); }; var Window = new Native({ name: 'Window', legacy: (Browser.Engine.trident) ? null: window.Window, initialize: function(win){ $uid(win); if (!win.Element){ win.Element = $empty; if (Browser.Engine.webkit) win.document.createElement("iframe"); //fixes safari 2 win.Element.prototype = (Browser.Engine.webkit) ? window["[[DOMElement.prototype]]"] : {}; } win.document.window = win; return $extend(win, Window.Prototype); }, afterImplement: function(property, value){ window[property] = Window.Prototype[property] = value; } }); Window.Prototype = {$family: {name: 'window'}}; new Window(window); var Document = new Native({ name: 'Document', legacy: (Browser.Engine.trident) ? null: window.Document, initialize: function(doc){ $uid(doc); doc.head = doc.getElementsByTagName('head')[0]; doc.html = doc.getElementsByTagName('html')[0]; if (Browser.Engine.trident && Browser.Engine.version <= 4) $try(function(){ doc.execCommand("BackgroundImageCache", false, true); }); if (Browser.Engine.trident) doc.window.attachEvent('onunload', function(){ doc.window.detachEvent('onunload', arguments.callee); doc.head = doc.html = doc.window = null; }); return $extend(doc, Document.Prototype); }, afterImplement: function(property, value){ document[property] = Document.Prototype[property] = value; } }); Document.Prototype = {$family: {name: 'document'}}; new Document(document); /* --- script: Array.js description: Contains Array Prototypes like each, contains, and erase. license: MIT-style license. requires: - /$util - /Array.each provides: [Array] ... */ Array.implement({ every: function(fn, bind){ for (var i = 0, l = this.length; i < l; i++){ if (!fn.call(bind, this[i], i, this)) return false; } return true; }, filter: function(fn, bind){ var results = []; for (var i = 0, l = this.length; i < l; i++){ if (fn.call(bind, this[i], i, this)) results.push(this[i]); } return results; }, clean: function(){ return this.filter($defined); }, indexOf: function(item, from){ var len = this.length; for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ if (this[i] === item) return i; } return -1; }, map: function(fn, bind){ var results = []; for (var i = 0, l = this.length; i < l; i++) results[i] = fn.call(bind, this[i], i, this); return results; }, some: function(fn, bind){ for (var i = 0, l = this.length; i < l; i++){ if (fn.call(bind, this[i], i, this)) return true; } return false; }, associate: function(keys){ var obj = {}, length = Math.min(this.length, keys.length); for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; return obj; }, link: function(object){ var result = {}; for (var i = 0, l = this.length; i < l; i++){ for (var key in object){ if (object[key](this[i])){ result[key] = this[i]; delete object[key]; break; } } } return result; }, contains: function(item, from){ return this.indexOf(item, from) != -1; }, extend: function(array){ for (var i = 0, j = array.length; i < j; i++) this.push(array[i]); return this; }, getLast: function(){ return (this.length) ? this[this.length - 1] : null; }, getRandom: function(){ return (this.length) ? this[$random(0, this.length - 1)] : null; }, include: function(item){ if (!this.contains(item)) this.push(item); return this; }, combine: function(array){ for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); return this; }, erase: function(item){ for (var i = this.length; i--; i){ if (this[i] === item) this.splice(i, 1); } return this; }, empty: function(){ this.length = 0; return this; }, flatten: function(){ var array = []; for (var i = 0, l = this.length; i < l; i++){ var type = $type(this[i]); if (!type) continue; array = array.concat((type == 'array' || type == 'collection' || type == 'arguments') ? Array.flatten(this[i]) : this[i]); } return array; }, hexToRgb: function(array){ if (this.length != 3) return null; var rgb = this.map(function(value){ if (value.length == 1) value += value; return value.toInt(16); }); return (array) ? rgb : 'rgb(' + rgb + ')'; }, rgbToHex: function(array){ if (this.length < 3) return null; if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; var hex = []; for (var i = 0; i < 3; i++){ var bit = (this[i] - 0).toString(16); hex.push((bit.length == 1) ? '0' + bit : bit); } return (array) ? hex : '#' + hex.join(''); } }); /* --- script: String.js description: Contains String Prototypes like camelCase, capitalize, test, and toInt. license: MIT-style license. requires: - /Native provides: [String] ... */ String.implement({ test: function(regex, params){ return ((typeof regex == 'string') ? new RegExp(regex, params) : regex).test(this); }, contains: function(string, separator){ return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1; }, trim: function(){ return this.replace(/^\s+|\s+$/g, ''); }, clean: function(){ return this.replace(/\s+/g, ' ').trim(); }, camelCase: function(){ return this.replace(/-\D/g, function(match){ return match.charAt(1).toUpperCase(); }); }, hyphenate: function(){ return this.replace(/[A-Z]/g, function(match){ return ('-' + match.charAt(0).toLowerCase()); }); }, capitalize: function(){ return this.replace(/\b[a-z]/g, function(match){ return match.toUpperCase(); }); }, escapeRegExp: function(){ return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); }, toInt: function(base){ return parseInt(this, base || 10); }, toFloat: function(){ return parseFloat(this); }, hexToRgb: function(array){ var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); return (hex) ? hex.slice(1).hexToRgb(array) : null; }, rgbToHex: function(array){ var rgb = this.match(/\d{1,3}/g); return (rgb) ? rgb.rgbToHex(array) : null; }, stripScripts: function(option){ var scripts = ''; var text = this.replace(/]*>([\s\S]*?)<\/script>/gi, function(){ scripts += arguments[1] + '\n'; return ''; }); if (option === true) $exec(scripts); else if ($type(option) == 'function') option(scripts, text); return text; }, substitute: function(object, regexp){ return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ if (match.charAt(0) == '\\') return match.slice(1); return (object[name] != undefined) ? object[name] : ''; }); } }); /* --- script: Function.js description: Contains Function Prototypes like create, bind, pass, and delay. license: MIT-style license. requires: - /Native - /$util provides: [Function] ... */ Function.implement({ extend: function(properties){ for (var property in properties) this[property] = properties[property]; return this; }, create: function(options){ var self = this; options = options || {}; return function(event){ var args = options.arguments; args = (args != undefined) ? $splat(args) : Array.slice(arguments, (options.event) ? 1 : 0); if (options.event) args = [event || window.event].extend(args); var returns = function(){ return self.apply(options.bind || null, args); }; if (options.delay) return setTimeout(returns, options.delay); if (options.periodical) return setInterval(returns, options.periodical); if (options.attempt) return $try(returns); return returns(); }; }, run: function(args, bind){ return this.apply(bind, $splat(args)); }, pass: function(args, bind){ return this.create({bind: bind, arguments: args}); }, bind: function(bind, args){ return this.create({bind: bind, arguments: args}); }, bindWithEvent: function(bind, args){ return this.create({bind: bind, arguments: args, event: true}); }, attempt: function(args, bind){ return this.create({bind: bind, arguments: args, attempt: true})(); }, delay: function(delay, bind, args){ return this.create({bind: bind, arguments: args, delay: delay})(); }, periodical: function(periodical, bind, args){ return this.create({bind: bind, arguments: args, periodical: periodical})(); } }); /* --- script: Number.js description: Contains Number Prototypes like limit, round, times, and ceil. license: MIT-style license. requires: - /Native - /$util provides: [Number] ... */ Number.implement({ limit: function(min, max){ return Math.min(max, Math.max(min, this)); }, round: function(precision){ precision = Math.pow(10, precision || 0); return Math.round(this * precision) / precision; }, times: function(fn, bind){ for (var i = 0; i < this; i++) fn.call(bind, i, this); }, toFloat: function(){ return parseFloat(this); }, toInt: function(base){ return parseInt(this, base || 10); } }); Number.alias('times', 'each'); (function(math){ var methods = {}; math.each(function(name){ if (!Number[name]) methods[name] = function(){ return Math[name].apply(null, [this].concat($A(arguments))); }; }); Number.implement(methods); })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); /* --- script: Hash.js description: Contains Hash Prototypes. Provides a means for overcoming the JavaScript practical impossibility of extending native Objects. license: MIT-style license. requires: - /Hash.base provides: [Hash] ... */ Hash.implement({ has: Object.prototype.hasOwnProperty, keyOf: function(value){ for (var key in this){ if (this.hasOwnProperty(key) && this[key] === value) return key; } return null; }, hasValue: function(value){ return (Hash.keyOf(this, value) !== null); }, extend: function(properties){ Hash.each(properties || {}, function(value, key){ Hash.set(this, key, value); }, this); return this; }, combine: function(properties){ Hash.each(properties || {}, function(value, key){ Hash.include(this, key, value); }, this); return this; }, erase: function(key){ if (this.hasOwnProperty(key)) delete this[key]; return this; }, get: function(key){ return (this.hasOwnProperty(key)) ? this[key] : null; }, set: function(key, value){ if (!this[key] || this.hasOwnProperty(key)) this[key] = value; return this; }, empty: function(){ Hash.each(this, function(value, key){ delete this[key]; }, this); return this; }, include: function(key, value){ if (this[key] == undefined) this[key] = value; return this; }, map: function(fn, bind){ var results = new Hash; Hash.each(this, function(value, key){ results.set(key, fn.call(bind, value, key, this)); }, this); return results; }, filter: function(fn, bind){ var results = new Hash; Hash.each(this, function(value, key){ if (fn.call(bind, value, key, this)) results.set(key, value); }, this); return results; }, every: function(fn, bind){ for (var key in this){ if (this.hasOwnProperty(key) && !fn.call(bind, this[key], key)) return false; } return true; }, some: function(fn, bind){ for (var key in this){ if (this.hasOwnProperty(key) && fn.call(bind, this[key], key)) return true; } return false; }, getKeys: function(){ var keys = []; Hash.each(this, function(value, key){ keys.push(key); }); return keys; }, getValues: function(){ var values = []; Hash.each(this, function(value){ values.push(value); }); return values; }, toQueryString: function(base){ var queryString = []; Hash.each(this, function(value, key){ if (base) key = base + '[' + key + ']'; var result; switch ($type(value)){ case 'object': result = Hash.toQueryString(value, key); break; case 'array': var qs = {}; value.each(function(val, i){ qs[i] = val; }); result = Hash.toQueryString(qs, key); break; default: result = key + '=' + encodeURIComponent(value); } if (value != undefined) queryString.push(result); }); return queryString.join('&'); } }); Hash.alias({keyOf: 'indexOf', hasValue: 'contains'}); /* --- script: Class.js description: Contains the Class Function for easily creating, extending, and implementing reusable Classes. license: MIT-style license. requires: - /$util - /Native - /Array - /String - /Function - /Number - /Hash provides: [Class] ... */ function Class(params){ if (params instanceof Function) params = {initialize: params}; var newClass = function(){ Object.reset(this); if (newClass._prototyping) return this; this._current = $empty; var value = (this.initialize) ? this.initialize.apply(this, arguments) : this; delete this._current; delete this.caller; return value; }.extend(this); newClass.implement(params); newClass.constructor = Class; newClass.prototype.constructor = newClass; return newClass; }; Function.prototype.protect = function(){ this._protected = true; return this; }; Object.reset = function(object, key){ if (key == null){ for (var p in object) Object.reset(object, p); return object; } delete object[key]; switch ($type(object[key])){ case 'object': var F = function(){}; F.prototype = object[key]; var i = new F; object[key] = Object.reset(i); break; case 'array': object[key] = $unlink(object[key]); break; } return object; }; new Native({name: 'Class', initialize: Class}).extend({ instantiate: function(F){ F._prototyping = true; var proto = new F; delete F._prototyping; return proto; }, wrap: function(self, key, method){ if (method._origin) method = method._origin; return function(){ if (method._protected && this._current == null) throw new Error('The method "' + key + '" cannot be called.'); var caller = this.caller, current = this._current; this.caller = current; this._current = arguments.callee; var result = method.apply(this, arguments); this._current = current; this.caller = caller; return result; }.extend({_owner: self, _origin: method, _name: key}); } }); Class.implement({ implement: function(key, value){ if ($type(key) == 'object'){ for (var p in key) this.implement(p, key[p]); return this; } var mutator = Class.Mutators[key]; if (mutator){ value = mutator.call(this, value); if (value == null) return this; } var proto = this.prototype; switch ($type(value)){ case 'function': if (value._hidden) return this; proto[key] = Class.wrap(this, key, value); break; case 'object': var previous = proto[key]; if ($type(previous) == 'object') $mixin(previous, value); else proto[key] = $unlink(value); break; case 'array': proto[key] = $unlink(value); break; default: proto[key] = value; } return this; } }); Class.Mutators = { Extends: function(parent){ this.parent = parent; this.prototype = Class.instantiate(parent); this.implement('parent', function(){ var name = this.caller._name, previous = this.caller._owner.parent.prototype[name]; if (!previous) throw new Error('The method "' + name + '" has no parent.'); return previous.apply(this, arguments); }.protect()); }, Implements: function(items){ $splat(items).each(function(item){ if (item instanceof Function) item = Class.instantiate(item); this.implement(item); }, this); } }; /* --- script: Class.Extras.js description: Contains Utility Classes that can be implemented into your own Classes to ease the execution of many common tasks. license: MIT-style license. requires: - /Class provides: [Chain, Events, Options] ... */ var Chain = new Class({ $chain: [], chain: function(){ this.$chain.extend(Array.flatten(arguments)); return this; }, callChain: function(){ return (this.$chain.length) ? this.$chain.shift().apply(this, arguments) : false; }, clearChain: function(){ this.$chain.empty(); return this; } }); var Events = new Class({ $events: {}, addEvent: function(type, fn, internal){ type = Events.removeOn(type); if (fn != $empty){ this.$events[type] = this.$events[type] || []; this.$events[type].include(fn); if (internal) fn.internal = true; } return this; }, addEvents: function(events){ for (var type in events) this.addEvent(type, events[type]); return this; }, fireEvent: function(type, args, delay){ type = Events.removeOn(type); if (!this.$events || !this.$events[type]) return this; this.$events[type].each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); return this; }, removeEvent: function(type, fn){ type = Events.removeOn(type); if (!this.$events[type]) return this; if (!fn.internal) this.$events[type].erase(fn); return this; }, removeEvents: function(events){ var type; if ($type(events) == 'object'){ for (type in events) this.removeEvent(type, events[type]); return this; } if (events) events = Events.removeOn(events); for (type in this.$events){ if (events && events != type) continue; var fns = this.$events[type]; for (var i = fns.length; i--; i) this.removeEvent(type, fns[i]); } return this; } }); Events.removeOn = function(string){ return string.replace(/^on([A-Z])/, function(full, first){ return first.toLowerCase(); }); }; var Options = new Class({ setOptions: function(){ this.options = $merge.run([this.options].extend(arguments)); if (!this.addEvent) return this; for (var option in this.options){ if ($type(this.options[option]) != 'function' || !(/^on[A-Z]/).test(option)) continue; this.addEvent(option, this.options[option]); delete this.options[option]; } return this; } }); /* --- script: Cookie.js description: Class for creating, reading, and deleting browser Cookies. license: MIT-style license. credits: - Based on the functions by Peter-Paul Koch (http://quirksmode.org). requires: - /Options provides: [Cookie] ... */ var Cookie = new Class({ Implements: Options, options: { path: false, domain: false, duration: false, secure: false, document: document }, initialize: function(key, options){ this.key = key; this.setOptions(options); }, write: function(value){ value = encodeURIComponent(value); if (this.options.domain) value += '; domain=' + this.options.domain; if (this.options.path) value += '; path=' + this.options.path; if (this.options.duration){ var date = new Date(); date.setTime(date.getTime() + this.options.duration * 24 * 60 * 60 * 1000); value += '; expires=' + date.toGMTString(); } if (this.options.secure) value += '; secure'; this.options.document.cookie = this.key + '=' + value; return this; }, read: function(){ var value = this.options.document.cookie.match('(?:^|;)\\s*' + this.key.escapeRegExp() + '=([^;]*)'); return (value) ? decodeURIComponent(value[1]) : null; }, dispose: function(){ new Cookie(this.key, $merge(this.options, {duration: -1})).write(''); return this; } }); Cookie.write = function(key, value, options){ return new Cookie(key, options).write(value); }; Cookie.read = function(key){ return new Cookie(key).read(); }; Cookie.dispose = function(key, options){ return new Cookie(key, options).dispose(); }; /* --- script: Swiff.js description: Wrapper for embedding SWF movies. Supports External Interface Communication. license: MIT-style license. credits: - Flash detection & Internet Explorer + Flash Player 9 fix inspired by SWFObject. requires: - /Options - /$util provides: [Swiff] ... */ var Swiff = new Class({ Implements: [Options], options: { id: null, height: 1, width: 1, container: null, properties: {}, params: { quality: 'high', allowScriptAccess: 'always', wMode: 'transparent', swLiveConnect: true }, callBacks: {}, vars: {} }, toElement: function(){ return this.object; }, initialize: function(path, options){ this.instance = 'Swiff_' + $time(); this.setOptions(options); options = this.options; var id = this.id = options.id || this.instance; var container = document.id(options.container); Swiff.CallBacks[this.instance] = {}; var params = options.params, vars = options.vars, callBacks = options.callBacks; var properties = $extend({height: options.height, width: options.width}, options.properties); var self = this; for (var callBack in callBacks){ Swiff.CallBacks[this.instance][callBack] = (function(option){ return function(){ return option.apply(self.object, arguments); }; })(callBacks[callBack]); vars[callBack] = 'Swiff.CallBacks.' + this.instance + '.' + callBack; } params.flashVars = Hash.toQueryString(vars); if (Browser.Engine.trident){ properties.classid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000'; params.movie = path; } else { properties.type = 'application/x-shockwave-flash'; properties.data = path; } var build = ''; } build += ''; this.object = ((container) ? container.empty() : new Element('div')).set('html', build).firstChild; }, replaces: function(element){ element = document.id(element, true); element.parentNode.replaceChild(this.toElement(), element); return this; }, inject: function(element){ document.id(element, true).appendChild(this.toElement()); return this; }, remote: function(){ return Swiff.remote.apply(Swiff, [this.toElement()].extend(arguments)); } }); Swiff.CallBacks = {}; Swiff.remote = function(obj, fn){ var rs = obj.CallFunction('' + __flash__argumentsToXML(arguments, 2) + ''); return eval(rs); }; /* --- script: More.js description: MooTools More license: MIT-style license authors: - Guillermo Rauch - Thomas Aylott - Scott Kyle requires: - core:1.2.4/MooTools provides: [MooTools.More] ... */ MooTools.More = { 'version': '1.2.4.4', 'build': '6f6057dc645fdb7547689183b2311063bd653ddf' };/* --- script: Element.js description: One of the most important items in MooTools. Contains the dollar function, the dollars function, and an handful of cross-browser, time-saver methods to let you easily work with HTML Elements. license: MIT-style license. requires: - /Window - /Document - /Array - /String - /Function - /Number - /Hash provides: [Element, Elements, $, $$, Iframe] ... */ var Element = new Native({ name: 'Element', legacy: window.Element, initialize: function(tag, props){ var konstructor = Element.Constructors.get(tag); if (konstructor) return konstructor(props); if (typeof tag == 'string') return document.newElement(tag, props); return document.id(tag).set(props); }, afterImplement: function(key, value){ Element.Prototype[key] = value; if (Array[key]) return; Elements.implement(key, function(){ var items = [], elements = true; for (var i = 0, j = this.length; i < j; i++){ var returns = this[i][key].apply(this[i], arguments); items.push(returns); if (elements) elements = ($type(returns) == 'element'); } return (elements) ? new Elements(items) : items; }); } }); Element.Prototype = {$family: {name: 'element'}}; Element.Constructors = new Hash; var IFrame = new Native({ name: 'IFrame', generics: false, initialize: function(){ var params = Array.link(arguments, {properties: Object.type, iframe: $defined}); var props = params.properties || {}; var iframe = document.id(params.iframe); var onload = props.onload || $empty; delete props.onload; props.id = props.name = $pick(props.id, props.name, iframe ? (iframe.id || iframe.name) : 'IFrame_' + $time()); iframe = new Element(iframe || 'iframe', props); var onFrameLoad = function(){ var host = $try(function(){ return iframe.contentWindow.location.host; }); if (!host || host == window.location.host){ var win = new Window(iframe.contentWindow); new Document(iframe.contentWindow.document); $extend(win.Element.prototype, Element.Prototype); } onload.call(iframe.contentWindow, iframe.contentWindow.document); }; var contentWindow = $try(function(){ return iframe.contentWindow; }); ((contentWindow && contentWindow.document.body) || window.frames[props.id]) ? onFrameLoad() : iframe.addListener('load', onFrameLoad); return iframe; } }); var Elements = new Native({ initialize: function(elements, options){ options = $extend({ddup: true, cash: true}, options); elements = elements || []; if (options.ddup || options.cash){ var uniques = {}, returned = []; for (var i = 0, l = elements.length; i < l; i++){ var el = document.id(elements[i], !options.cash); if (options.ddup){ if (uniques[el.uid]) continue; uniques[el.uid] = true; } if (el) returned.push(el); } elements = returned; } return (options.cash) ? $extend(elements, this) : elements; } }); Elements.implement({ filter: function(filter, bind){ if (!filter) return this; return new Elements(Array.filter(this, (typeof filter == 'string') ? function(item){ return item.match(filter); } : filter, bind)); } }); Document.implement({ newElement: function(tag, props){ if (Browser.Engine.trident && props){ ['name', 'type', 'checked'].each(function(attribute){ if (!props[attribute]) return; tag += ' ' + attribute + '="' + props[attribute] + '"'; if (attribute != 'checked') delete props[attribute]; }); tag = '<' + tag + '>'; } return document.id(this.createElement(tag)).set(props); }, newTextNode: function(text){ return this.createTextNode(text); }, getDocument: function(){ return this; }, getWindow: function(){ return this.window; }, id: (function(){ var types = { string: function(id, nocash, doc){ id = doc.getElementById(id); return (id) ? types.element(id, nocash) : null; }, element: function(el, nocash){ $uid(el); if (!nocash && !el.$family && !(/^object|embed$/i).test(el.tagName)){ var proto = Element.Prototype; for (var p in proto) el[p] = proto[p]; }; return el; }, object: function(obj, nocash, doc){ if (obj.toElement) return types.element(obj.toElement(doc), nocash); return null; } }; types.textnode = types.whitespace = types.window = types.document = $arguments(0); return function(el, nocash, doc){ if (el && el.$family && el.uid) return el; var type = $type(el); return (types[type]) ? types[type](el, nocash, doc || document) : null; }; })() }); if (window.$ == null) Window.implement({ $: function(el, nc){ return document.id(el, nc, this.document); } }); Window.implement({ $$: function(selector){ if (arguments.length == 1 && typeof selector == 'string') return this.document.getElements(selector); var elements = []; var args = Array.flatten(arguments); for (var i = 0, l = args.length; i < l; i++){ var item = args[i]; switch ($type(item)){ case 'element': elements.push(item); break; case 'string': elements.extend(this.document.getElements(item, true)); } } return new Elements(elements); }, getDocument: function(){ return this.document; }, getWindow: function(){ return this; } }); Native.implement([Element, Document], { getElement: function(selector, nocash){ return document.id(this.getElements(selector, true)[0] || null, nocash); }, getElements: function(tags, nocash){ tags = tags.split(','); var elements = []; var ddup = (tags.length > 1); tags.each(function(tag){ var partial = this.getElementsByTagName(tag.trim()); (ddup) ? elements.extend(partial) : elements = partial; }, this); return new Elements(elements, {ddup: ddup, cash: !nocash}); } }); (function(){ var collected = {}, storage = {}; var props = {input: 'checked', option: 'selected', textarea: (Browser.Engine.webkit && Browser.Engine.version < 420) ? 'innerHTML' : 'value'}; var get = function(uid){ return (storage[uid] || (storage[uid] = {})); }; var clean = function(item, retain){ if (!item) return; var uid = item.uid; if (Browser.Engine.trident){ if (item.clearAttributes){ var clone = retain && item.cloneNode(false); item.clearAttributes(); if (clone) item.mergeAttributes(clone); } else if (item.removeEvents){ item.removeEvents(); } if ((/object/i).test(item.tagName)){ for (var p in item){ if (typeof item[p] == 'function') item[p] = $empty; } Element.dispose(item); } } if (!uid) return; collected[uid] = storage[uid] = null; }; var purge = function(){ Hash.each(collected, clean); if (Browser.Engine.trident) $A(document.getElementsByTagName('object')).each(clean); if (window.CollectGarbage) CollectGarbage(); collected = storage = null; }; var walk = function(element, walk, start, match, all, nocash){ var el = element[start || walk]; var elements = []; while (el){ if (el.nodeType == 1 && (!match || Element.match(el, match))){ if (!all) return document.id(el, nocash); elements.push(el); } el = el[walk]; } return (all) ? new Elements(elements, {ddup: false, cash: !nocash}) : null; }; var attributes = { 'html': 'innerHTML', 'class': 'className', 'for': 'htmlFor', 'defaultValue': 'defaultValue', 'text': (Browser.Engine.trident || (Browser.Engine.webkit && Browser.Engine.version < 420)) ? 'innerText' : 'textContent' }; var bools = ['compact', 'nowrap', 'ismap', 'declare', 'noshade', 'checked', 'disabled', 'readonly', 'multiple', 'selected', 'noresize', 'defer']; var camels = ['value', 'type', 'defaultValue', 'accessKey', 'cellPadding', 'cellSpacing', 'colSpan', 'frameBorder', 'maxLength', 'readOnly', 'rowSpan', 'tabIndex', 'useMap']; bools = bools.associate(bools); Hash.extend(attributes, bools); Hash.extend(attributes, camels.associate(camels.map(String.toLowerCase))); var inserters = { before: function(context, element){ if (element.parentNode) element.parentNode.insertBefore(context, element); }, after: function(context, element){ if (!element.parentNode) return; var next = element.nextSibling; (next) ? element.parentNode.insertBefore(context, next) : element.parentNode.appendChild(context); }, bottom: function(context, element){ element.appendChild(context); }, top: function(context, element){ var first = element.firstChild; (first) ? element.insertBefore(context, first) : element.appendChild(context); } }; inserters.inside = inserters.bottom; Hash.each(inserters, function(inserter, where){ where = where.capitalize(); Element.implement('inject' + where, function(el){ inserter(this, document.id(el, true)); return this; }); Element.implement('grab' + where, function(el){ inserter(document.id(el, true), this); return this; }); }); Element.implement({ set: function(prop, value){ switch ($type(prop)){ case 'object': for (var p in prop) this.set(p, prop[p]); break; case 'string': var property = Element.Properties.get(prop); (property && property.set) ? property.set.apply(this, Array.slice(arguments, 1)) : this.setProperty(prop, value); } return this; }, get: function(prop){ var property = Element.Properties.get(prop); return (property && property.get) ? property.get.apply(this, Array.slice(arguments, 1)) : this.getProperty(prop); }, erase: function(prop){ var property = Element.Properties.get(prop); (property && property.erase) ? property.erase.apply(this) : this.removeProperty(prop); return this; }, setProperty: function(attribute, value){ var key = attributes[attribute]; if (value == undefined) return this.removeProperty(attribute); if (key && bools[attribute]) value = !!value; (key) ? this[key] = value : this.setAttribute(attribute, '' + value); return this; }, setProperties: function(attributes){ for (var attribute in attributes) this.setProperty(attribute, attributes[attribute]); return this; }, getProperty: function(attribute){ var key = attributes[attribute]; var value = (key) ? this[key] : this.getAttribute(attribute, 2); return (bools[attribute]) ? !!value : (key) ? value : value || null; }, getProperties: function(){ var args = $A(arguments); return args.map(this.getProperty, this).associate(args); }, removeProperty: function(attribute){ var key = attributes[attribute]; (key) ? this[key] = (key && bools[attribute]) ? false : '' : this.removeAttribute(attribute); return this; }, removeProperties: function(){ Array.each(arguments, this.removeProperty, this); return this; }, hasClass: function(className){ return this.className.contains(className, ' '); }, addClass: function(className){ if (!this.hasClass(className)) this.className = (this.className + ' ' + className).clean(); return this; }, removeClass: function(className){ this.className = this.className.replace(new RegExp('(^|\\s)' + className + '(?:\\s|$)'), '$1'); return this; }, toggleClass: function(className){ return this.hasClass(className) ? this.removeClass(className) : this.addClass(className); }, adopt: function(){ Array.flatten(arguments).each(function(element){ element = document.id(element, true); if (element) this.appendChild(element); }, this); return this; }, appendText: function(text, where){ return this.grab(this.getDocument().newTextNode(text), where); }, grab: function(el, where){ inserters[where || 'bottom'](document.id(el, true), this); return this; }, inject: function(el, where){ inserters[where || 'bottom'](this, document.id(el, true)); return this; }, replaces: function(el){ el = document.id(el, true); el.parentNode.replaceChild(this, el); return this; }, wraps: function(el, where){ el = document.id(el, true); return this.replaces(el).grab(el, where); }, getPrevious: function(match, nocash){ return walk(this, 'previousSibling', null, match, false, nocash); }, getAllPrevious: function(match, nocash){ return walk(this, 'previousSibling', null, match, true, nocash); }, getNext: function(match, nocash){ return walk(this, 'nextSibling', null, match, false, nocash); }, getAllNext: function(match, nocash){ return walk(this, 'nextSibling', null, match, true, nocash); }, getFirst: function(match, nocash){ return walk(this, 'nextSibling', 'firstChild', match, false, nocash); }, getLast: function(match, nocash){ return walk(this, 'previousSibling', 'lastChild', match, false, nocash); }, getParent: function(match, nocash){ return walk(this, 'parentNode', null, match, false, nocash); }, getParents: function(match, nocash){ return walk(this, 'parentNode', null, match, true, nocash); }, getSiblings: function(match, nocash){ return this.getParent().getChildren(match, nocash).erase(this); }, getChildren: function(match, nocash){ return walk(this, 'nextSibling', 'firstChild', match, true, nocash); }, getWindow: function(){ return this.ownerDocument.window; }, getDocument: function(){ return this.ownerDocument; }, getElementById: function(id, nocash){ var el = this.ownerDocument.getElementById(id); if (!el) return null; for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ if (!parent) return null; } return document.id(el, nocash); }, getSelected: function(){ return new Elements($A(this.options).filter(function(option){ return option.selected; })); }, getComputedStyle: function(property){ if (this.currentStyle) return this.currentStyle[property.camelCase()]; var computed = this.getDocument().defaultView.getComputedStyle(this, null); return (computed) ? computed.getPropertyValue([property.hyphenate()]) : null; }, toQueryString: function(){ var queryString = []; this.getElements('input, select, textarea', true).each(function(el){ if (!el.name || el.disabled || el.type == 'submit' || el.type == 'reset' || el.type == 'file') return; var value = (el.tagName.toLowerCase() == 'select') ? Element.getSelected(el).map(function(opt){ return opt.value; }) : ((el.type == 'radio' || el.type == 'checkbox') && !el.checked) ? null : el.value; $splat(value).each(function(val){ if (typeof val != 'undefined') queryString.push(el.name + '=' + encodeURIComponent(val)); }); }); return queryString.join('&'); }, clone: function(contents, keepid){ contents = contents !== false; var clone = this.cloneNode(contents); var clean = function(node, element){ if (!keepid) node.removeAttribute('id'); if (Browser.Engine.trident){ node.clearAttributes(); node.mergeAttributes(element); node.removeAttribute('uid'); if (node.options){ var no = node.options, eo = element.options; for (var j = no.length; j--;) no[j].selected = eo[j].selected; } } var prop = props[element.tagName.toLowerCase()]; if (prop && element[prop]) node[prop] = element[prop]; }; if (contents){ var ce = clone.getElementsByTagName('*'), te = this.getElementsByTagName('*'); for (var i = ce.length; i--;) clean(ce[i], te[i]); } clean(clone, this); return document.id(clone); }, destroy: function(){ Element.empty(this); Element.dispose(this); clean(this, true); return null; }, empty: function(){ $A(this.childNodes).each(function(node){ Element.destroy(node); }); return this; }, dispose: function(){ return (this.parentNode) ? this.parentNode.removeChild(this) : this; }, hasChild: function(el){ el = document.id(el, true); if (!el) return false; if (Browser.Engine.webkit && Browser.Engine.version < 420) return $A(this.getElementsByTagName(el.tagName)).contains(el); return (this.contains) ? (this != el && this.contains(el)) : !!(this.compareDocumentPosition(el) & 16); }, match: function(tag){ return (!tag || (tag == this) || (Element.get(this, 'tag') == tag)); } }); Native.implement([Element, Window, Document], { addListener: function(type, fn){ if (type == 'unload'){ var old = fn, self = this; fn = function(){ self.removeListener('unload', fn); old(); }; } else { collected[this.uid] = this; } if (this.addEventListener) this.addEventListener(type, fn, false); else this.attachEvent('on' + type, fn); return this; }, removeListener: function(type, fn){ if (this.removeEventListener) this.removeEventListener(type, fn, false); else this.detachEvent('on' + type, fn); return this; }, retrieve: function(property, dflt){ var storage = get(this.uid), prop = storage[property]; if (dflt != undefined && prop == undefined) prop = storage[property] = dflt; return $pick(prop); }, store: function(property, value){ var storage = get(this.uid); storage[property] = value; return this; }, eliminate: function(property){ var storage = get(this.uid); delete storage[property]; return this; } }); window.addListener('unload', purge); })(); Element.Properties = new Hash; Element.Properties.style = { set: function(style){ this.style.cssText = style; }, get: function(){ return this.style.cssText; }, erase: function(){ this.style.cssText = ''; } }; Element.Properties.tag = { get: function(){ return this.tagName.toLowerCase(); } }; Element.Properties.html = (function(){ var wrapper = document.createElement('div'); var translations = { table: [1, '', '
'], select: [1, ''], tbody: [2, '', '
'], tr: [3, '', '
'] }; translations.thead = translations.tfoot = translations.tbody; var html = { set: function(){ var html = Array.flatten(arguments).join(''); var wrap = Browser.Engine.trident && translations[this.get('tag')]; if (wrap){ var first = wrapper; first.innerHTML = wrap[1] + html + wrap[2]; for (var i = wrap[0]; i--;) first = first.firstChild; this.empty().adopt(first.childNodes); } else { this.innerHTML = html; } } }; html.erase = html.set; return html; })(); if (Browser.Engine.webkit && Browser.Engine.version < 420) Element.Properties.text = { get: function(){ if (this.innerText) return this.innerText; var temp = this.ownerDocument.newElement('div', {html: this.innerHTML}).inject(this.ownerDocument.body); var text = temp.innerText; temp.destroy(); return text; } }; /* --- script: Event.js description: Contains the Event Class, to make the event object cross-browser. license: MIT-style license. requires: - /Window - /Document - /Hash - /Array - /Function - /String provides: [Event] ... */ var Event = new Native({ name: 'Event', initialize: function(event, win){ win = win || window; var doc = win.document; event = event || win.event; if (event.$extended) return event; this.$extended = true; var type = event.type; var target = event.target || event.srcElement; while (target && target.nodeType == 3) target = target.parentNode; if (type.test(/key/)){ var code = event.which || event.keyCode; var key = Event.Keys.keyOf(code); if (type == 'keydown'){ var fKey = code - 111; if (fKey > 0 && fKey < 13) key = 'f' + fKey; } key = key || String.fromCharCode(code).toLowerCase(); } else if (type.match(/(click|mouse|menu)/i)){ doc = (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; var page = { x: event.pageX || event.clientX + doc.scrollLeft, y: event.pageY || event.clientY + doc.scrollTop }; var client = { x: (event.pageX) ? event.pageX - win.pageXOffset : event.clientX, y: (event.pageY) ? event.pageY - win.pageYOffset : event.clientY }; if (type.match(/DOMMouseScroll|mousewheel/)){ var wheel = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3; } var rightClick = (event.which == 3) || (event.button == 2); var related = null; if (type.match(/over|out/)){ switch (type){ case 'mouseover': related = event.relatedTarget || event.fromElement; break; case 'mouseout': related = event.relatedTarget || event.toElement; } if (!(function(){ while (related && related.nodeType == 3) related = related.parentNode; return true; }).create({attempt: Browser.Engine.gecko})()) related = false; } } return $extend(this, { event: event, type: type, page: page, client: client, rightClick: rightClick, wheel: wheel, relatedTarget: related, target: target, code: code, key: key, shift: event.shiftKey, control: event.ctrlKey, alt: event.altKey, meta: event.metaKey }); } }); Event.Keys = new Hash({ 'enter': 13, 'up': 38, 'down': 40, 'left': 37, 'right': 39, 'esc': 27, 'space': 32, 'backspace': 8, 'tab': 9, 'delete': 46 }); Event.implement({ stop: function(){ return this.stopPropagation().preventDefault(); }, stopPropagation: function(){ if (this.event.stopPropagation) this.event.stopPropagation(); else this.event.cancelBubble = true; return this; }, preventDefault: function(){ if (this.event.preventDefault) this.event.preventDefault(); else this.event.returnValue = false; return this; } }); /* --- script: Element.Event.js description: Contains Element methods for dealing with events. This file also includes mouseenter and mouseleave custom Element Events. license: MIT-style license. requires: - /Element - /Event provides: [Element.Event] ... */ Element.Properties.events = {set: function(events){ this.addEvents(events); }}; Native.implement([Element, Window, Document], { addEvent: function(type, fn){ var events = this.retrieve('events', {}); events[type] = events[type] || {'keys': [], 'values': []}; if (events[type].keys.contains(fn)) return this; events[type].keys.push(fn); var realType = type, custom = Element.Events.get(type), condition = fn, self = this; if (custom){ if (custom.onAdd) custom.onAdd.call(this, fn); if (custom.condition){ condition = function(event){ if (custom.condition.call(this, event)) return fn.call(this, event); return true; }; } realType = custom.base || realType; } var defn = function(){ return fn.call(self); }; var nativeEvent = Element.NativeEvents[realType]; if (nativeEvent){ if (nativeEvent == 2){ defn = function(event){ event = new Event(event, self.getWindow()); if (condition.call(self, event) === false) event.stop(); }; } this.addListener(realType, defn); } events[type].values.push(defn); return this; }, removeEvent: function(type, fn){ var events = this.retrieve('events'); if (!events || !events[type]) return this; var pos = events[type].keys.indexOf(fn); if (pos == -1) return this; events[type].keys.splice(pos, 1); var value = events[type].values.splice(pos, 1)[0]; var custom = Element.Events.get(type); if (custom){ if (custom.onRemove) custom.onRemove.call(this, fn); type = custom.base || type; } return (Element.NativeEvents[type]) ? this.removeListener(type, value) : this; }, addEvents: function(events){ for (var event in events) this.addEvent(event, events[event]); return this; }, removeEvents: function(events){ var type; if ($type(events) == 'object'){ for (type in events) this.removeEvent(type, events[type]); return this; } var attached = this.retrieve('events'); if (!attached) return this; if (!events){ for (type in attached) this.removeEvents(type); this.eliminate('events'); } else if (attached[events]){ while (attached[events].keys[0]) this.removeEvent(events, attached[events].keys[0]); attached[events] = null; } return this; }, fireEvent: function(type, args, delay){ var events = this.retrieve('events'); if (!events || !events[type]) return this; events[type].keys.each(function(fn){ fn.create({'bind': this, 'delay': delay, 'arguments': args})(); }, this); return this; }, cloneEvents: function(from, type){ from = document.id(from); var fevents = from.retrieve('events'); if (!fevents) return this; if (!type){ for (var evType in fevents) this.cloneEvents(from, evType); } else if (fevents[type]){ fevents[type].keys.each(function(fn){ this.addEvent(type, fn); }, this); } return this; } }); Element.NativeEvents = { click: 2, dblclick: 2, mouseup: 2, mousedown: 2, contextmenu: 2, //mouse buttons mousewheel: 2, DOMMouseScroll: 2, //mouse wheel mouseover: 2, mouseout: 2, mousemove: 2, selectstart: 2, selectend: 2, //mouse movement keydown: 2, keypress: 2, keyup: 2, //keyboard focus: 2, blur: 2, change: 2, reset: 2, select: 2, submit: 2, //form elements load: 1, unload: 1, beforeunload: 2, resize: 1, move: 1, DOMContentLoaded: 1, readystatechange: 1, //window error: 1, abort: 1, scroll: 1 //misc }; (function(){ var $check = function(event){ var related = event.relatedTarget; if (related == undefined) return true; if (related === false) return false; return ($type(this) != 'document' && related != this && related.prefix != 'xul' && !this.hasChild(related)); }; Element.Events = new Hash({ mouseenter: { base: 'mouseover', condition: $check }, mouseleave: { base: 'mouseout', condition: $check }, mousewheel: { base: (Browser.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel' } }); })(); /* --- script: Request.js description: Powerful all purpose Request Class. Uses XMLHTTPRequest. license: MIT-style license. requires: - /Element - /Chain - /Events - /Options - /Browser provides: [Request] ... */ var Request = new Class({ Implements: [Chain, Events, Options], options: {/* onRequest: $empty, onComplete: $empty, onCancel: $empty, onSuccess: $empty, onFailure: $empty, onException: $empty,*/ url: '', data: '', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }, async: true, format: false, method: 'post', link: 'ignore', isSuccess: null, emulation: true, urlEncoded: true, encoding: 'utf-8', evalScripts: false, evalResponse: false, timeout: 10000, noCache: false }, initialize: function(options){ this.xhr = new Browser.Request(); this.setOptions(options); this.options.isSuccess = this.options.isSuccess || this.isSuccess; this.headers = new Hash(this.options.headers); }, onStateChange: function(){ if (this.xhr.readyState != 4 || !this.running) return; this.running = false; this.status = 0; $try(function(){ this.status = this.xhr.status; }.bind(this)); this.xhr.onreadystatechange = $empty; clearTimeout(this.timer); if (this.options.isSuccess.call(this, this.status)){ this.response = {text: this.xhr.responseText, xml: this.xhr.responseXML}; this.success(this.response.text, this.response.xml); } else { this.response = {text: null, xml: null}; this.failure(); } }, isSuccess: function(){ return ((this.status >= 200) && (this.status < 300)); }, processScripts: function(text){ if (this.options.evalResponse || (/(ecma|java)script/).test(this.getHeader('Content-type'))) return $exec(text); return text.stripScripts(this.options.evalScripts); }, success: function(text, xml){ this.onSuccess(this.processScripts(text), xml); }, onSuccess: function(){ this.fireEvent('complete', arguments).fireEvent('success', arguments).callChain(); }, failure: function(){ this.onFailure(); }, onFailure: function(){ this.fireEvent('complete').fireEvent('failure', this.xhr); }, setHeader: function(name, value){ this.headers.set(name, value); return this; }, getHeader: function(name){ return $try(function(){ return this.xhr.getResponseHeader(name); }.bind(this)); }, check: function(){ if (!this.running) return true; switch (this.options.link){ case 'cancel': this.cancel(); return true; case 'chain': this.chain(this.caller.bind(this, arguments)); return false; } return false; }, send: function(options){ if (!this.check(options)) return this; this.running = true; var type = $type(options); if (type == 'string' || type == 'element') options = {data: options}; var old = this.options; options = $extend({data: old.data, url: old.url, method: old.method}, options); var data = options.data, url = String(options.url), method = options.method.toLowerCase(); switch ($type(data)){ case 'element': data = document.id(data).toQueryString(); break; case 'object': case 'hash': data = Hash.toQueryString(data); } if (this.options.format){ var format = 'format=' + this.options.format; data = (data) ? format + '&' + data : format; } if (this.options.emulation && !['get', 'post'].contains(method)){ var _method = '_method=' + method; data = (data) ? _method + '&' + data : _method; method = 'post'; } if (this.options.urlEncoded && method == 'post'){ var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; this.headers.set('Content-type', 'application/x-www-form-urlencoded' + encoding); } if (this.options.noCache){ var noCache = 'noCache=' + new Date().getTime(); data = (data) ? noCache + '&' + data : noCache; } var trimPosition = url.lastIndexOf('/'); if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition); if (data && method == 'get'){ url = url + (url.contains('?') ? '&' : '?') + data; data = null; } this.xhr.open(method.toUpperCase(), url, this.options.async); this.xhr.onreadystatechange = this.onStateChange.bind(this); this.headers.each(function(value, key){ try { this.xhr.setRequestHeader(key, value); } catch (e){ this.fireEvent('exception', [key, value]); } }, this); this.fireEvent('request'); this.xhr.send(data); if (!this.options.async) this.onStateChange(); if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this); return this; }, cancel: function(){ if (!this.running) return this; this.running = false; this.xhr.abort(); this.xhr.onreadystatechange = $empty; this.xhr = new Browser.Request(); this.fireEvent('cancel'); return this; }, timeout: function(){ alert('Âðåìÿ îæèäàíèÿ îòâåòà ñåðâåðà èñòåêëî, ïîïðîáóéòå ñíîâà'); } }); (function(){ var methods = {}; ['get', 'post', 'put', 'delete', 'GET', 'POST', 'PUT', 'DELETE'].each(function(method){ methods[method] = function(){ var params = Array.link(arguments, {url: String.type, data: $defined}); return this.send($extend(params, {method: method})); }; }); Request.implement(methods); })(); Element.Properties.send = { set: function(options){ var send = this.retrieve('send'); if (send) send.cancel(); return this.eliminate('send').store('send:options', $extend({ data: this, link: 'cancel', method: this.get('method') || 'post', url: this.get('action') }, options)); }, get: function(options){ if (options || !this.retrieve('send')){ if (options || !this.retrieve('send:options')) this.set('send', options); this.store('send', new Request(this.retrieve('send:options'))); } return this.retrieve('send'); } }; Element.implement({ send: function(url){ var sender = this.get('send'); sender.send({data: this, url: url || sender.options.url}); return this; } }); /* --- script: Request.HTML.js description: Extends the basic Request Class with additional methods for interacting with HTML responses. license: MIT-style license. requires: - /Request - /Element provides: [Request.HTML] ... */ Request.HTML = new Class({ Extends: Request, options: { update: false, append: false, evalScripts: true, filter: false }, processHTML: function(text){ var match = text.match(/]*>([\s\S]*?)<\/body>/i); text = (match) ? match[1] : text; var container = new Element('div'); return $try(function(){ var root = '' + text + '', doc; if (Browser.Engine.trident){ doc = new ActiveXObject('Microsoft.XMLDOM'); doc.async = false; doc.loadXML(root); } else { doc = new DOMParser().parseFromString(root, 'text/xml'); } root = doc.getElementsByTagName('root')[0]; if (!root) return null; for (var i = 0, k = root.childNodes.length; i < k; i++){ var child = Element.clone(root.childNodes[i], true, true); if (child) container.grab(child); } return container; }) || container.set('html', text); }, success: function(text){ var options = this.options, response = this.response; response.html = text.stripScripts(function(script){ response.javascript = script; }); var temp = this.processHTML(response.html); response.tree = temp.childNodes; response.elements = temp.getElements('*'); if (options.filter) response.tree = response.elements.filter(options.filter); if (options.update) document.id(options.update).empty().set('html', response.html); else if (options.append) document.id(options.append).adopt(temp.getChildren()); if (options.evalScripts) $exec(response.javascript); this.onSuccess(response.tree, response.elements, response.html, response.javascript); } }); Element.Properties.load = { set: function(options){ var load = this.retrieve('load'); if (load) load.cancel(); return this.eliminate('load').store('load:options', $extend({data: this, link: 'cancel', update: this, method: 'get'}, options)); }, get: function(options){ if (options || ! this.retrieve('load')){ if (options || !this.retrieve('load:options')) this.set('load', options); this.store('load', new Request.HTML(this.retrieve('load:options'))); } return this.retrieve('load'); } }; Element.implement({ load: function(){ this.get('load').send(Array.link(arguments, {data: Object.type, url: String.type})); return this; } }); /* --- script: Class.Binds.js description: Automagically binds specified methods in a class to the instance of the class. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Class - /MooTools.More provides: [Class.Binds] ... */ Class.Mutators.Binds = function(binds){ return binds; }; Class.Mutators.initialize = function(initialize){ return function(){ $splat(this.Binds).each(function(name){ var original = this[name]; if (original) this[name] = original.bind(this); }, this); return initialize.apply(this, arguments); }; }; /* --- script: Class.Occlude.js description: Prevents a class from being applied to a DOM element twice. license: MIT-style license. authors: - Aaron Newton requires: - core/1.2.4/Class - core:1.2.4/Element - /MooTools.More provides: [Class.Occlude] ... */ Class.Occlude = new Class({ occlude: function(property, element){ element = document.id(element || this.element); var instance = element.retrieve(property || this.property); if (instance && !$defined(this.occluded)) return this.occluded = instance; this.occluded = false; element.store(property || this.property, this); return this.occluded; } });/* --- script: Class.Refactor.js description: Extends a class onto itself with new property, preserving any items attached to the class's namespace. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Class - /MooTools.More provides: [Class.refactor] ... */ Class.refactor = function(original, refactors){ $each(refactors, function(item, name){ var origin = original.prototype[name]; if (origin && (origin = origin._origin) && typeof item == 'function') original.implement(name, function(){ var old = this.previous; this.previous = origin; var value = item.apply(this, arguments); this.previous = old; return value; }); else original.implement(name, item); }); return original; };/* --- script: Fx.js description: Contains the basic animation logic to be extended by all other Fx Classes. license: MIT-style license. requires: - /Chain - /Events - /Options provides: [Fx] ... */ var Fx = new Class({ Implements: [Chain, Events, Options], options: { /* onStart: $empty, onCancel: $empty, onComplete: $empty, */ fps: 50, unit: false, duration: 500, link: 'ignore' }, initialize: function(options){ this.subject = this.subject || this; this.setOptions(options); this.options.duration = Fx.Durations[this.options.duration] || this.options.duration.toInt(); var wait = this.options.wait; if (wait === false) this.options.link = 'cancel'; }, getTransition: function(){ return function(p){ return -(Math.cos(Math.PI * p) - 1) / 2; }; }, step: function(){ var time = $time(); if (time < this.time + this.options.duration){ var delta = this.transition((time - this.time) / this.options.duration); this.set(this.compute(this.from, this.to, delta)); } else { this.set(this.compute(this.from, this.to, 1)); this.complete(); } }, set: function(now){ return now; }, compute: function(from, to, delta){ return Fx.compute(from, to, delta); }, check: function(){ if (!this.timer) return true; switch (this.options.link){ case 'cancel': this.cancel(); return true; case 'chain': this.chain(this.caller.bind(this, arguments)); return false; } return false; }, start: function(from, to){ if (!this.check(from, to)) return this; this.from = from; this.to = to; this.time = 0; this.transition = this.getTransition(); this.startTimer(); this.onStart(); return this; }, complete: function(){ if (this.stopTimer()) this.onComplete(); return this; }, cancel: function(){ if (this.stopTimer()) this.onCancel(); return this; }, onStart: function(){ this.fireEvent('start', this.subject); }, onComplete: function(){ this.fireEvent('complete', this.subject); if (!this.callChain()) this.fireEvent('chainComplete', this.subject); }, onCancel: function(){ this.fireEvent('cancel', this.subject).clearChain(); }, pause: function(){ this.stopTimer(); return this; }, resume: function(){ this.startTimer(); return this; }, stopTimer: function(){ if (!this.timer) return false; this.time = $time() - this.time; this.timer = $clear(this.timer); return true; }, startTimer: function(){ if (this.timer) return false; this.time = $time() - this.time; this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this); return true; } }); Fx.compute = function(from, to, delta){ return (to - from) * delta + from; }; Fx.Durations = {'short': 250, 'normal': 500, 'long': 1000}; /* --- script: Element.Style.js description: Contains methods for interacting with the styles of Elements in a fashionable way. license: MIT-style license. requires: - /Element provides: [Element.Style] ... */ Element.Properties.styles = {set: function(styles){ this.setStyles(styles); }}; Element.Properties.opacity = { set: function(opacity, novisibility){ if (!novisibility){ if (opacity == 0){ if (this.style.visibility != 'hidden') this.style.visibility = 'hidden'; } else { if (this.style.visibility != 'visible') this.style.visibility = 'visible'; } } if (!this.currentStyle || !this.currentStyle.hasLayout) this.style.zoom = 1; if (Browser.Engine.trident) this.style.filter = (opacity == 1) ? '' : 'alpha(opacity=' + opacity * 100 + ')'; this.style.opacity = opacity; this.store('opacity', opacity); }, get: function(){ return this.retrieve('opacity', 1); } }; Element.implement({ setOpacity: function(value){ return this.set('opacity', value, true); }, getOpacity: function(){ return this.get('opacity'); }, setStyle: function(property, value){ switch (property){ case 'opacity': return this.set('opacity', parseFloat(value)); case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat'; } property = property.camelCase(); if ($type(value) != 'string'){ var map = (Element.Styles.get(property) || '@').split(' '); value = $splat(value).map(function(val, i){ if (!map[i]) return ''; return ($type(val) == 'number') ? map[i].replace('@', Math.round(val)) : val; }).join(' '); } else if (value == String(Number(value))){ value = Math.round(value); } this.style[property] = value; return this; }, getStyle: function(property){ switch (property){ case 'opacity': return this.get('opacity'); case 'float': property = (Browser.Engine.trident) ? 'styleFloat' : 'cssFloat'; } property = property.camelCase(); var result = this.style[property]; if (!$chk(result)){ result = []; for (var style in Element.ShortStyles){ if (property != style) continue; for (var s in Element.ShortStyles[style]) result.push(this.getStyle(s)); return result.join(' '); } result = this.getComputedStyle(property); } if (result){ result = String(result); var color = result.match(/rgba?\([\d\s,]+\)/); if (color) result = result.replace(color[0], color[0].rgbToHex()); } if (Browser.Engine.presto || (Browser.Engine.trident && !$chk(parseInt(result, 10)))){ if (property.test(/^(height|width)$/)){ var values = (property == 'width') ? ['left', 'right'] : ['top', 'bottom'], size = 0; values.each(function(value){ size += this.getStyle('border-' + value + '-width').toInt() + this.getStyle('padding-' + value).toInt(); }, this); return this['offset' + property.capitalize()] - size + 'px'; } if ((Browser.Engine.presto) && String(result).test('px')) return result; if (property.test(/(border(.+)Width|margin|padding)/)) return '0px'; } return result; }, setStyles: function(styles){ for (var style in styles) this.setStyle(style, styles[style]); return this; }, getStyles: function(){ var result = {}; Array.flatten(arguments).each(function(key){ result[key] = this.getStyle(key); }, this); return result; } }); Element.Styles = new Hash({ left: '@px', top: '@px', bottom: '@px', right: '@px', width: '@px', height: '@px', maxWidth: '@px', maxHeight: '@px', minWidth: '@px', minHeight: '@px', backgroundColor: 'rgb(@, @, @)', backgroundPosition: '@px @px', color: 'rgb(@, @, @)', fontSize: '@px', letterSpacing: '@px', lineHeight: '@px', clip: 'rect(@px @px @px @px)', margin: '@px @px @px @px', padding: '@px @px @px @px', border: '@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)', borderWidth: '@px @px @px @px', borderStyle: '@ @ @ @', borderColor: 'rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)', zIndex: '@', 'zoom': '@', fontWeight: '@', textIndent: '@px', opacity: '@' }); Element.ShortStyles = {margin: {}, padding: {}, border: {}, borderWidth: {}, borderStyle: {}, borderColor: {}}; ['Top', 'Right', 'Bottom', 'Left'].each(function(direction){ var Short = Element.ShortStyles; var All = Element.Styles; ['margin', 'padding'].each(function(style){ var sd = style + direction; Short[style][sd] = All[sd] = '@px'; }); var bd = 'border' + direction; Short.border[bd] = All[bd] = '@px @ rgb(@, @, @)'; var bdw = bd + 'Width', bds = bd + 'Style', bdc = bd + 'Color'; Short[bd] = {}; Short.borderWidth[bdw] = Short[bd][bdw] = All[bdw] = '@px'; Short.borderStyle[bds] = Short[bd][bds] = All[bds] = '@'; Short.borderColor[bdc] = Short[bd][bdc] = All[bdc] = 'rgb(@, @, @)'; }); /* --- script: Fx.CSS.js description: Contains the CSS animation logic. Used by Fx.Tween, Fx.Morph, Fx.Elements. license: MIT-style license. requires: - /Fx - /Element.Style provides: [Fx.CSS] ... */ Fx.CSS = new Class({ Extends: Fx, //prepares the base from/to object prepare: function(element, property, values){ values = $splat(values); var values1 = values[1]; if (!$chk(values1)){ values[1] = values[0]; values[0] = element.getStyle(property); } var parsed = values.map(this.parse); return {from: parsed[0], to: parsed[1]}; }, //parses a value into an array parse: function(value){ value = $lambda(value)(); value = (typeof value == 'string') ? value.split(' ') : $splat(value); return value.map(function(val){ val = String(val); var found = false; Fx.CSS.Parsers.each(function(parser, key){ if (found) return; var parsed = parser.parse(val); if ($chk(parsed)) found = {value: parsed, parser: parser}; }); found = found || {value: val, parser: Fx.CSS.Parsers.String}; return found; }); }, //computes by a from and to prepared objects, using their parsers. compute: function(from, to, delta){ var computed = []; (Math.min(from.length, to.length)).times(function(i){ computed.push({value: from[i].parser.compute(from[i].value, to[i].value, delta), parser: from[i].parser}); }); computed.$family = {name: 'fx:css:value'}; return computed; }, //serves the value as settable serve: function(value, unit){ if ($type(value) != 'fx:css:value') value = this.parse(value); var returned = []; value.each(function(bit){ returned = returned.concat(bit.parser.serve(bit.value, unit)); }); return returned; }, //renders the change to an element render: function(element, property, value, unit){ element.setStyle(property, this.serve(value, unit)); }, //searches inside the page css to find the values for a selector search: function(selector){ if (Fx.CSS.Cache[selector]) return Fx.CSS.Cache[selector]; var to = {}; Array.each(document.styleSheets, function(sheet, j){ var href = sheet.href; if (href && href.contains('://') && !href.contains(document.domain)) return; var rules = sheet.rules || sheet.cssRules; Array.each(rules, function(rule, i){ if (!rule.style) return; var selectorText = (rule.selectorText) ? rule.selectorText.replace(/^\w+/, function(m){ return m.toLowerCase(); }) : null; if (!selectorText || !selectorText.test('^' + selector + '$')) return; Element.Styles.each(function(value, style){ if (!rule.style[style] || Element.ShortStyles[style]) return; value = String(rule.style[style]); to[style] = (value.test(/^rgb/)) ? value.rgbToHex() : value; }); }); }); return Fx.CSS.Cache[selector] = to; } }); Fx.CSS.Cache = {}; Fx.CSS.Parsers = new Hash({ Color: { parse: function(value){ if (value.match(/^#[0-9a-f]{3,6}$/i)) return value.hexToRgb(true); return ((value = value.match(/(\d+),\s*(\d+),\s*(\d+)/))) ? [value[1], value[2], value[3]] : false; }, compute: function(from, to, delta){ return from.map(function(value, i){ return Math.round(Fx.compute(from[i], to[i], delta)); }); }, serve: function(value){ return value.map(Number); } }, Number: { parse: parseFloat, compute: Fx.compute, serve: function(value, unit){ return (unit) ? value + unit : value; } }, String: { parse: $lambda(false), compute: $arguments(1), serve: $arguments(0) } }); /* --- script: Fx.Tween.js description: Formerly Fx.Style, effect to transition any CSS property for an element. license: MIT-style license. requires: - /Fx.CSS provides: [Fx.Tween, Element.fade, Element.highlight] ... */ Fx.Tween = new Class({ Extends: Fx.CSS, initialize: function(element, options){ this.element = this.subject = document.id(element); this.parent(options); }, set: function(property, now){ if (arguments.length == 1){ now = property; property = this.property || this.options.property; } this.render(this.element, property, now, this.options.unit); return this; }, start: function(property, from, to){ if (!this.check(property, from, to)) return this; var args = Array.flatten(arguments); this.property = this.options.property || args.shift(); var parsed = this.prepare(this.element, this.property, args); return this.parent(parsed.from, parsed.to); } }); Element.Properties.tween = { set: function(options){ var tween = this.retrieve('tween'); if (tween) tween.cancel(); return this.eliminate('tween').store('tween:options', $extend({link: 'cancel'}, options)); }, get: function(options){ if (options || !this.retrieve('tween')){ if (options || !this.retrieve('tween:options')) this.set('tween', options); this.store('tween', new Fx.Tween(this, this.retrieve('tween:options'))); } return this.retrieve('tween'); } }; Element.implement({ tween: function(property, from, to){ this.get('tween').start(arguments); return this; }, fade: function(how){ var fade = this.get('tween'), o = 'opacity', toggle; how = $pick(how, 'toggle'); switch (how){ case 'in': fade.start(o, 1); break; case 'out': fade.start(o, 0); break; case 'show': fade.set(o, 1); break; case 'hide': fade.set(o, 0); break; case 'toggle': var flag = this.retrieve('fade:flag', this.get('opacity') == 1); fade.start(o, (flag) ? 0 : 1); this.store('fade:flag', !flag); toggle = true; break; default: fade.start(o, arguments); } if (!toggle) this.eliminate('fade:flag'); return this; }, highlight: function(start, end){ if (!end){ end = this.retrieve('highlight:original', this.getStyle('background-color')); end = (end == 'transparent') ? '#fff' : end; } var tween = this.get('tween'); tween.start('background-color', start || '#ffff88', end).chain(function(){ this.setStyle('background-color', this.retrieve('highlight:original')); tween.callChain(); }.bind(this)); return this; } }); /* --- script: Element.Dimensions.js description: Contains methods to work with size, scroll, or positioning of Elements and the window object. license: MIT-style license. credits: - Element positioning based on the [qooxdoo](http://qooxdoo.org/) code and smart browser fixes, [LGPL License](http://www.gnu.org/licenses/lgpl.html). - Viewport dimensions based on [YUI](http://developer.yahoo.com/yui/) code, [BSD License](http://developer.yahoo.com/yui/license.html). requires: - /Element provides: [Element.Dimensions] ... */ (function(){ Element.implement({ scrollTo: function(x, y){ if (isBody(this)){ this.getWindow().scrollTo(x, y); } else { this.scrollLeft = x; this.scrollTop = y; } return this; }, getSize: function(){ if (isBody(this)) return this.getWindow().getSize(); return {x: this.offsetWidth, y: this.offsetHeight}; }, getScrollSize: function(){ if (isBody(this)) return this.getWindow().getScrollSize(); return {x: this.scrollWidth, y: this.scrollHeight}; }, getScroll: function(){ if (isBody(this)) return this.getWindow().getScroll(); return {x: this.scrollLeft, y: this.scrollTop}; }, getScrolls: function(){ var element = this, position = {x: 0, y: 0}; while (element && !isBody(element)){ position.x += element.scrollLeft; position.y += element.scrollTop; element = element.parentNode; } return position; }, getOffsetParent: function(){ var element = this; if (isBody(element)) return null; if (!Browser.Engine.trident) return element.offsetParent; while ((element = element.parentNode) && !isBody(element)){ if (styleString(element, 'position') != 'static') return element; } return null; }, getOffsets: function(){ if (this.getBoundingClientRect){ var bound = this.getBoundingClientRect(), html = document.id(this.getDocument().documentElement), htmlScroll = html.getScroll(), elemScrolls = this.getScrolls(), elemScroll = this.getScroll(), isFixed = (styleString(this, 'position') == 'fixed'); return { x: bound.left.toInt() + elemScrolls.x - elemScroll.x + ((isFixed) ? 0 : htmlScroll.x) - html.clientLeft, y: bound.top.toInt() + elemScrolls.y - elemScroll.y + ((isFixed) ? 0 : htmlScroll.y) - html.clientTop }; } var element = this, position = {x: 0, y: 0}; if (isBody(this)) return position; while (element && !isBody(element)){ position.x += element.offsetLeft; position.y += element.offsetTop; if (Browser.Engine.gecko){ if (!borderBox(element)){ position.x += leftBorder(element); position.y += topBorder(element); } var parent = element.parentNode; if (parent && styleString(parent, 'overflow') != 'visible'){ position.x += leftBorder(parent); position.y += topBorder(parent); } } else if (element != this && Browser.Engine.webkit){ position.x += leftBorder(element); position.y += topBorder(element); } element = element.offsetParent; } if (Browser.Engine.gecko && !borderBox(this)){ position.x -= leftBorder(this); position.y -= topBorder(this); } return position; }, getPosition: function(relative){ if (isBody(this)) return {x: 0, y: 0}; var offset = this.getOffsets(), scroll = this.getScrolls(); var position = { x: offset.x - scroll.x, y: offset.y - scroll.y }; var relativePosition = (relative && (relative = document.id(relative))) ? relative.getPosition() : {x: 0, y: 0}; return {x: position.x - relativePosition.x, y: position.y - relativePosition.y}; }, getCoordinates: function(element){ if (isBody(this)) return this.getWindow().getCoordinates(); var position = this.getPosition(element), size = this.getSize(); var obj = { left: position.x, top: position.y, width: size.x, height: size.y }; obj.right = obj.left + obj.width; obj.bottom = obj.top + obj.height; return obj; }, computePosition: function(obj){ return { left: obj.x - styleNumber(this, 'margin-left'), top: obj.y - styleNumber(this, 'margin-top') }; }, setPosition: function(obj){ return this.setStyles(this.computePosition(obj)); } }); Native.implement([Document, Window], { getSize: function(){ if (Browser.Engine.presto || Browser.Engine.webkit){ var win = this.getWindow(); return {x: win.innerWidth, y: win.innerHeight}; } var doc = getCompatElement(this); return {x: doc.clientWidth, y: doc.clientHeight}; }, getScroll: function(){ var win = this.getWindow(), doc = getCompatElement(this); return {x: win.pageXOffset || doc.scrollLeft, y: win.pageYOffset || doc.scrollTop}; }, getScrollSize: function(){ var doc = getCompatElement(this), min = this.getSize(); return {x: Math.max(doc.scrollWidth, min.x), y: Math.max(doc.scrollHeight, min.y)}; }, getPosition: function(){ return {x: 0, y: 0}; }, getCoordinates: function(){ var size = this.getSize(); return {top: 0, left: 0, bottom: size.y, right: size.x, height: size.y, width: size.x}; } }); // private methods var styleString = Element.getComputedStyle; function styleNumber(element, style){ return styleString(element, style).toInt() || 0; }; function borderBox(element){ return styleString(element, '-moz-box-sizing') == 'border-box'; }; function topBorder(element){ return styleNumber(element, 'border-top-width'); }; function leftBorder(element){ return styleNumber(element, 'border-left-width'); }; function isBody(element){ return (/^(?:body|html)$/i).test(element.tagName); }; function getCompatElement(element){ var doc = element.getDocument(); return (!doc.compatMode || doc.compatMode == 'CSS1Compat') ? doc.html : doc.body; }; })(); //aliases Element.alias('setPosition', 'position'); //compatability Native.implement([Window, Document, Element], { getHeight: function(){ return this.getSize().y; }, getWidth: function(){ return this.getSize().x; }, getScrollTop: function(){ return this.getScroll().y; }, getScrollLeft: function(){ return this.getScroll().x; }, getScrollHeight: function(){ return this.getScrollSize().y; }, getScrollWidth: function(){ return this.getScrollSize().x; }, getTop: function(){ return this.getPosition().y; }, getLeft: function(){ return this.getPosition().x; } }); /* --- script: Element.Measure.js description: Extends the Element native object to include methods useful in measuring dimensions. credits: "Element.measure / .expose methods by Daniel Steigerwald License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz" license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element.Style - core:1.2.4/Element.Dimensions - /MooTools.More provides: [Element.Measure] ... */ Element.implement({ measure: function(fn){ var vis = function(el) { return !!(!el || el.offsetHeight || el.offsetWidth); }; if (vis(this)) return fn.apply(this); var parent = this.getParent(), restorers = [], toMeasure = []; while (!vis(parent) && parent != document.body) { toMeasure.push(parent.expose()); parent = parent.getParent(); } var restore = this.expose(); var result = fn.apply(this); restore(); toMeasure.each(function(restore){ restore(); }); return result; }, expose: function(){ if (this.getStyle('display') != 'none') return $empty; var before = this.style.cssText; this.setStyles({ display: 'block', position: 'absolute', visibility: 'hidden' }); return function(){ this.style.cssText = before; }.bind(this); }, getDimensions: function(options){ options = $merge({computeSize: false},options); var dim = {}; var getSize = function(el, options){ return (options.computeSize)?el.getComputedSize(options):el.getSize(); }; var parent = this.getParent('body'); if (parent && this.getStyle('display') == 'none'){ dim = this.measure(function(){ return getSize(this, options); }); } else if (parent){ try { //safari sometimes crashes here, so catch it dim = getSize(this, options); }catch(e){} } else { dim = {x: 0, y: 0}; } return $chk(dim.x) ? $extend(dim, {width: dim.x, height: dim.y}) : $extend(dim, {x: dim.width, y: dim.height}); }, getComputedSize: function(options){ options = $merge({ styles: ['padding','border'], plains: { height: ['top','bottom'], width: ['left','right'] }, mode: 'both' }, options); var size = {width: 0,height: 0}; switch (options.mode){ case 'vertical': delete size.width; delete options.plains.width; break; case 'horizontal': delete size.height; delete options.plains.height; break; } var getStyles = []; //this function might be useful in other places; perhaps it should be outside this function? $each(options.plains, function(plain, key){ plain.each(function(edge){ options.styles.each(function(style){ getStyles.push((style == 'border') ? style + '-' + edge + '-' + 'width' : style + '-' + edge); }); }); }); var styles = {}; getStyles.each(function(style){ styles[style] = this.getComputedStyle(style); }, this); var subtracted = []; $each(options.plains, function(plain, key){ //keys: width, height, plains: ['left', 'right'], ['top','bottom'] var capitalized = key.capitalize(); size['total' + capitalized] = size['computed' + capitalized] = 0; plain.each(function(edge){ //top, left, right, bottom size['computed' + edge.capitalize()] = 0; getStyles.each(function(style, i){ //padding, border, etc. //'padding-left'.test('left') size['totalWidth'] = size['width'] + [padding-left] if (style.test(edge)){ styles[style] = styles[style].toInt() || 0; //styles['padding-left'] = 5; size['total' + capitalized] = size['total' + capitalized] + styles[style]; size['computed' + edge.capitalize()] = size['computed' + edge.capitalize()] + styles[style]; } //if width != width (so, padding-left, for instance), then subtract that from the total if (style.test(edge) && key != style && (style.test('border') || style.test('padding')) && !subtracted.contains(style)){ subtracted.push(style); size['computed' + capitalized] = size['computed' + capitalized]-styles[style]; } }); }); }); ['Width', 'Height'].each(function(value){ var lower = value.toLowerCase(); if(!$chk(size[lower])) return; size[lower] = size[lower] + this['offset' + value] + size['computed' + value]; size['total' + value] = size[lower] + size['total' + value]; delete size['computed' + value]; }, this); return $extend(styles, size); } });/* --- script: Element.Position.js description: Extends the Element native object to include methods useful positioning elements relative to others. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element.Dimensions - /Element.Measure provides: [Elements.Position] ... */ (function(){ var original = Element.prototype.position; Element.implement({ position: function(options){ //call original position if the options are x/y values if (options && ($defined(options.x) || $defined(options.y))) return original ? original.apply(this, arguments) : this; $each(options||{}, function(v, k){ if (!$defined(v)) delete options[k]; }); options = $merge({ // minimum: { x: 0, y: 0 }, // maximum: { x: 0, y: 0}, relativeTo: document.body, position: { x: 'center', //left, center, right y: 'center' //top, center, bottom }, edge: false, offset: {x: 0, y: 0}, returnPos: false, relFixedPosition: false, ignoreMargins: false, ignoreScroll: false, allowNegative: false }, options); //compute the offset of the parent positioned element if this element is in one var parentOffset = {x: 0, y: 0}, parentPositioned = false; /* dollar around getOffsetParent should not be necessary, but as it does not return * a mootools extended element in IE, an error occurs on the call to expose. See: * http://mootools.lighthouseapp.com/projects/2706/tickets/333-element-getoffsetparent-inconsistency-between-ie-and-other-browsers */ var offsetParent = this.measure(function(){ return document.id(this.getOffsetParent()); }); if (offsetParent && offsetParent != this.getDocument().body){ parentOffset = offsetParent.measure(function(){ return this.getPosition(); }); parentPositioned = offsetParent != document.id(options.relativeTo); options.offset.x = options.offset.x - parentOffset.x; options.offset.y = options.offset.y - parentOffset.y; } //upperRight, bottomRight, centerRight, upperLeft, bottomLeft, centerLeft //topRight, topLeft, centerTop, centerBottom, center var fixValue = function(option){ if ($type(option) != 'string') return option; option = option.toLowerCase(); var val = {}; if (option.test('left')) val.x = 'left'; else if (option.test('right')) val.x = 'right'; else val.x = 'center'; if (option.test('upper') || option.test('top')) val.y = 'top'; else if (option.test('bottom')) val.y = 'bottom'; else val.y = 'center'; return val; }; options.edge = fixValue(options.edge); options.position = fixValue(options.position); if (!options.edge){ if (options.position.x == 'center' && options.position.y == 'center') options.edge = {x:'center', y:'center'}; else options.edge = {x:'left', y:'top'}; } this.setStyle('position', 'absolute'); var rel = document.id(options.relativeTo) || document.body, calc = rel == document.body ? window.getScroll() : rel.getPosition(), top = calc.y, left = calc.x; var dim = this.getDimensions({computeSize: true, styles:['padding', 'border','margin']}); var pos = {}, prefY = options.offset.y, prefX = options.offset.x, winSize = window.getSize(); switch(options.position.x){ case 'left': pos.x = left + prefX; break; case 'right': pos.x = left + prefX + rel.offsetWidth; break; default: //center pos.x = left + ((rel == document.body ? winSize.x : rel.offsetWidth)/2) + prefX; break; } switch(options.position.y){ case 'top': pos.y = top + prefY; break; case 'bottom': pos.y = top + prefY + rel.offsetHeight; break; default: //center pos.y = top + ((rel == document.body ? winSize.y : rel.offsetHeight)/2) + prefY; break; } if (options.edge){ var edgeOffset = {}; switch(options.edge.x){ case 'left': edgeOffset.x = 0; break; case 'right': edgeOffset.x = -dim.x-dim.computedRight-dim.computedLeft; break; default: //center edgeOffset.x = -(dim.totalWidth/2); break; } switch(options.edge.y){ case 'top': edgeOffset.y = 0; break; case 'bottom': edgeOffset.y = -dim.y-dim.computedTop-dim.computedBottom; break; default: //center edgeOffset.y = -(dim.totalHeight/2); break; } pos.x += edgeOffset.x; pos.y += edgeOffset.y; } pos = { left: ((pos.x >= 0 || parentPositioned || options.allowNegative) ? pos.x : 0).toInt(), top: ((pos.y >= 0 || parentPositioned || options.allowNegative) ? pos.y : 0).toInt() }; var xy = {left: 'x', top: 'y'}; ['minimum', 'maximum'].each(function(minmax) { ['left', 'top'].each(function(lr) { var val = options[minmax] ? options[minmax][xy[lr]] : null; if (val != null && pos[lr] < val) pos[lr] = val; }); }); if (rel.getStyle('position') == 'fixed' || options.relFixedPosition){ var winScroll = window.getScroll(); pos.top+= winScroll.y; pos.left+= winScroll.x; } if (options.ignoreScroll) { var relScroll = rel.getScroll(); pos.top-= relScroll.y; pos.left-= relScroll.x; } if (options.ignoreMargins) { pos.left += ( options.edge.x == 'right' ? dim['margin-right'] : options.edge.x == 'center' ? -dim['margin-left'] + ((dim['margin-right'] + dim['margin-left'])/2) : - dim['margin-left'] ); pos.top += ( options.edge.y == 'bottom' ? dim['margin-bottom'] : options.edge.y == 'center' ? -dim['margin-top'] + ((dim['margin-bottom'] + dim['margin-top'])/2) : - dim['margin-top'] ); } pos.left = Math.ceil(pos.left); pos.top = Math.ceil(pos.top); if (options.returnPos) return pos; else this.setStyles(pos); return this; } }); })();/* --- script: IframeShim.js description: Defines IframeShim, a class for obscuring select lists and flash objects in IE. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element.Event - core:1.2.4/Element.Style - core:1.2.4/Options Events - /Element.Position - /Class.Occlude provides: [IframeShim] ... */ var IframeShim = new Class({ Implements: [Options, Events, Class.Occlude], options: { className: 'iframeShim', src: 'javascript:false;document.write("");', display: false, zIndex: null, margin: 0, offset: {x: 0, y: 0}, browsers: (Browser.Engine.trident4 || (Browser.Engine.gecko && !Browser.Engine.gecko19 && Browser.Platform.mac)) }, property: 'IframeShim', initialize: function(element, options){ this.element = document.id(element); if (this.occlude()) return this.occluded; this.setOptions(options); this.makeShim(); return this; }, makeShim: function(){ if(this.options.browsers){ var zIndex = this.element.getStyle('zIndex').toInt(); if (!zIndex){ zIndex = 1; var pos = this.element.getStyle('position'); if (pos == 'static' || !pos) this.element.setStyle('position', 'relative'); this.element.setStyle('zIndex', zIndex); } zIndex = ($chk(this.options.zIndex) && zIndex > this.options.zIndex) ? this.options.zIndex : zIndex - 1; if (zIndex < 0) zIndex = 1; this.shim = new Element('iframe', { src: this.options.src, scrolling: 'no', frameborder: 0, styles: { zIndex: zIndex, position: 'absolute', border: 'none', filter: 'progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)' }, 'class': this.options.className }).store('IframeShim', this); var inject = (function(){ this.shim.inject(this.element, 'after'); this[this.options.display ? 'show' : 'hide'](); this.fireEvent('inject'); }).bind(this); if (!IframeShim.ready) window.addEvent('load', inject); else inject(); } else { this.position = this.hide = this.show = this.dispose = $lambda(this); } }, position: function(){ if (!IframeShim.ready || !this.shim) return this; var size = this.element.measure(function(){ return this.getSize(); }); if (this.options.margin != undefined){ size.x = size.x - (this.options.margin * 2); size.y = size.y - (this.options.margin * 2); this.options.offset.x += this.options.margin; this.options.offset.y += this.options.margin; } this.shim.set({width: size.x, height: size.y}).position({ relativeTo: this.element, offset: this.options.offset }); return this; }, hide: function(){ if (this.shim) this.shim.setStyle('display', 'none'); return this; }, show: function(){ if (this.shim) this.shim.setStyle('display', 'block'); return this.position(); }, dispose: function(){ if (this.shim) this.shim.dispose(); return this; }, destroy: function(){ if (this.shim) this.shim.destroy(); return this; } }); window.addEvent('load', function(){ IframeShim.ready = true; });/* --- script: Mask.js description: Creates a mask element to cover another. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Options - core:1.2.4/Events - core:1.2.4/Element.Event - /Class.Binds - /Element.Position - /IframeShim provides: [Mask] ... */ var Mask = new Class({ Implements: [Options, Events], Binds: ['position'], options: { // onShow: $empty, // onHide: $empty, // onDestroy: $empty, // onClick: $empty, //inject: { // where: 'after', // target: null, //}, // hideOnClick: false, // id: null, // destroyOnHide: false, style: {}, 'class': 'mask', maskMargins: false, useIframeShim: true, iframeShimOptions: {} }, initialize: function(target, options){ this.target = document.id(target) || document.id(document.body); this.target.store('Mask', this); this.setOptions(options); this.render(); this.inject(); }, render: function() { this.element = new Element('div', { 'class': this.options['class'], id: this.options.id || 'mask-' + $time(), styles: $merge(this.options.style, { display: 'none' }), events: { click: function(){ this.fireEvent('click'); if (this.options.hideOnClick) this.hide(); }.bind(this) } }); this.hidden = true; }, toElement: function(){ return this.element; }, inject: function(target, where){ where = where || this.options.inject ? this.options.inject.where : '' || this.target == document.body ? 'inside' : 'after'; target = target || this.options.inject ? this.options.inject.target : '' || this.target; this.element.inject(target, where); if (this.options.useIframeShim) { this.shim = new IframeShim(this.element, this.options.iframeShimOptions); this.addEvents({ show: this.shim.show.bind(this.shim), hide: this.shim.hide.bind(this.shim), destroy: this.shim.destroy.bind(this.shim) }); } }, position: function(){ this.resize(this.options.width, this.options.height); this.element.position({ relativeTo: this.target, position: 'topLeft', ignoreMargins: !this.options.maskMargins, ignoreScroll: this.target == document.body }); return this; }, resize: function(x, y){ var opt = { styles: ['padding', 'border'] }; if (this.options.maskMargins) opt.styles.push('margin'); var dim = this.target.getComputedSize(opt); if (this.target == document.body) { var win = window.getSize(); if (dim.totalHeight < win.y) dim.totalHeight = win.y; if (dim.totalWidth < win.x) dim.totalWidth = win.x; } this.element.setStyles({ width: $pick(x, dim.totalWidth, dim.x), height: $pick(y, dim.totalHeight, dim.y) }); return this; }, show: function(){ if (!this.hidden) return this; window.addEvent('resize', this.position); this.position(); this.showMask.apply(this, arguments); return this; }, showMask: function(){ this.element.setStyle('display', 'block'); this.hidden = false; this.fireEvent('show'); }, hide: function(){ if (this.hidden) return this; window.removeEvent('resize', this.position); this.hideMask.apply(this, arguments); if (this.options.destroyOnHide) return this.destroy(); return this; }, hideMask: function(){ this.element.setStyle('display', 'none'); this.hidden = true; this.fireEvent('hide'); }, toggle: function(){ this[this.hidden ? 'show' : 'hide'](); }, destroy: function(){ this.hide(); this.element.destroy(); this.fireEvent('destroy'); this.target.eliminate('mask'); } }); Element.Properties.mask = { set: function(options){ var mask = this.retrieve('mask'); return this.eliminate('mask').store('mask:options', options); }, get: function(options){ if (options || !this.retrieve('mask')){ if (this.retrieve('mask')) this.retrieve('mask').destroy(); if (options || !this.retrieve('mask:options')) this.set('mask', options); this.store('mask', new Mask(this, this.retrieve('mask:options'))); } return this.retrieve('mask'); } }; Element.implement({ mask: function(options){ this.get('mask', options).show(); return this; }, unmask: function(){ this.get('mask').hide(); return this; } });/* --- script: Spinner.js description: Adds a semi-transparent overlay over a dom element with a spinnin ajax icon. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Fx.Tween - /Class.refactor - /Mask provides: [Spinner] ... */ var Spinner = new Class({ Extends: Mask, options: { /*message: false,*/ 'class':'spinner', containerPosition: {}, content: { 'class':'spinner-content' }, messageContainer: { 'class':'spinner-msg' }, img: { 'class':'spinner-img' }, fxOptions: { link: 'chain' } }, initialize: function(){ this.parent.apply(this, arguments); this.target.store('spinner', this); //add this to events for when noFx is true; parent methods handle hide/show var deactivate = function(){ this.active = false; }.bind(this); this.addEvents({ hide: deactivate, show: deactivate }); }, render: function(){ this.parent(); this.element.set('id', this.options.id || 'spinner-'+$time()); this.content = document.id(this.options.content) || new Element('div', this.options.content); this.content.inject(this.element); if (this.options.message) { this.msg = document.id(this.options.message) || new Element('p', this.options.messageContainer).appendText(this.options.message); this.msg.inject(this.content); } if (this.options.img) { this.img = document.id(this.options.img) || new Element('div', this.options.img); this.img.inject(this.content); } this.element.set('tween', this.options.fxOptions); }, show: function(noFx){ if (this.active) return this.chain(this.show.bind(this)); if (!this.hidden) { this.callChain.delay(20, this); return this; } this.active = true; return this.parent(noFx); }, showMask: function(noFx){ var pos = function(){ this.content.position($merge({ relativeTo: this.element }, this.options.containerPosition)); }.bind(this); if (noFx) { this.parent(); pos(); } else { this.element.setStyles({ display: 'block', opacity: 0 }).tween('opacity', this.options.style.opacity || 0.9); pos(); this.hidden = false; this.fireEvent('show'); this.callChain(); } }, hide: function(noFx){ if (this.active) return this.chain(this.hide.bind(this)); if (this.hidden) { this.callChain.delay(20, this); return this; } this.active = true; return this.parent(noFx); }, hideMask: function(noFx){ if (noFx) return this.parent(); this.element.tween('opacity', 0).get('tween').chain(function(){ this.element.setStyle('display', 'none'); this.hidden = true; this.fireEvent('hide'); this.callChain(); }.bind(this)); }, destroy: function(){ this.content.destroy(); this.parent(); this.target.eliminate('spinner'); } }); Spinner.implement(new Chain); if (window.Request) { Request = Class.refactor(Request, { options: { useSpinner: false, spinnerOptions: {}, spinnerTarget: false }, initialize: function(options){ this._send = this.send; this.send = function(options){ if (this.spinner) this.spinner.chain(this._send.bind(this, options)).show(); else this._send(options); return this; }; this.previous(options); var update = document.id(this.options.spinnerTarget) || document.id(this.options.update); if (this.options.useSpinner && update) { this.spinner = update.get('spinner', this.options.spinnerOptions); ['onComplete', 'onException', 'onCancel'].each(function(event){ this.addEvent(event, this.spinner.hide.bind(this.spinner)); }, this); } }, getSpinner: function(){ return this.spinner; } }); } Element.Properties.spinner = { set: function(options){ var spinner = this.retrieve('spinner'); return this.eliminate('spinner').store('spinner:options', options); }, get: function(options){ if (options || !this.retrieve('spinner')){ if (this.retrieve('spinner')) this.retrieve('spinner').destroy(); if (options || !this.retrieve('spinner:options')) this.set('spinner', options); new Spinner(this, this.retrieve('spinner:options')); } return this.retrieve('spinner'); } }; Element.implement({ spin: function(options){ this.get('spinner', options).show(); return this; }, unspin: function(){ var opt = Array.link(arguments, {options: Object.type, callback: Function.type}); this.get('spinner', opt.options).hide(opt.callback); return this; } });/* --- script: String.QueryString.js description: Methods for dealing with URI query strings. license: MIT-style license authors: - Sebastian Markb?ge, Aaron Newton, Lennart Pilon, Valerio Proietti requires: - core:1.2.4/Array - core:1.2.4/String - /MooTools.More provides: [String.QueryString] ... */ String.implement({ parseQueryString: function(){ var vars = this.split(/[&;]/), res = {}; if (vars.length) vars.each(function(val){ var index = val.indexOf('='), keys = index < 0 ? [''] : val.substr(0, index).match(/[^\]\[]+/g), value = decodeURIComponent(val.substr(index + 1)), obj = res; keys.each(function(key, i){ var current = obj[key]; if(i < keys.length - 1) obj = obj[key] = current || {}; else if($type(current) == 'array') current.push(value); else obj[key] = $defined(current) ? [current, value] : value; }); }); return res; }, cleanQueryString: function(method){ return this.split('&').filter(function(val){ var index = val.indexOf('='), key = index < 0 ? '' : val.substr(0, index), value = val.substr(index + 1); return method ? method.run([key, value]) : $chk(value); }).join('&'); } });/* --- script: Form.Request.js description: Handles the basic functionality of submitting a form and updating a dom element with the result. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element.Event - core:1.2.4/Request.HTML - /Class.Binds - /Class.Occlude - /Spinner - /String.QueryString provides: [Form.Request] ... */ if (!window.Form) window.Form = {}; (function(){ Form.Request = new Class({ Binds: ['onSubmit', 'onFormValidate'], Implements: [Options, Events, Class.Occlude], options: { //onFailure: $empty, //onSuccess: #empty, //aliased to onComplete, //onSend: $empty requestOptions: { evalScripts: true, useSpinner: true, emulation: false, link: 'ignore' }, extraData: {}, resetForm: true }, property: 'form.request', initialize: function(form, update, options) { this.element = document.id(form); if (this.occlude()) return this.occluded; this.update = document.id(update); this.setOptions(options); this.makeRequest(); if (this.options.resetForm) { this.request.addEvent('success', function(){ $try(function(){ this.element.reset(); }.bind(this)); if (window.OverText) OverText.update(); }.bind(this)); } this.attach(); }, toElement: function() { return this.element; }, makeRequest: function(){ this.request = new Request.HTML($merge({ update: this.update, emulation: false, spinnerTarget: this.element, method: this.element.get('method') || 'post' }, this.options.requestOptions)).addEvents({ success: function(text, xml){ ['complete', 'success'].each(function(evt){ this.fireEvent(evt, [this.update, text, xml]); }, this); }.bind(this), failure: function(xhr){ this.fireEvent('complete').fireEvent('failure', xhr); }.bind(this), exception: function(){ this.fireEvent('failure', xhr); }.bind(this) }); }, attach: function(attach){ attach = $pick(attach, true); method = attach ? 'addEvent' : 'removeEvent'; var fv = this.element.retrieve('validator'); if (fv) fv[method]('onFormValidate', this.onFormValidate); if (!fv || !attach) this.element[method]('submit', this.onSubmit); }, detach: function(){ this.attach(false); }, //public method enable: function(){ this.attach(); }, //public method disable: function(){ this.detach(); }, onFormValidate: function(valid, form, e) { var fv = this.element.retrieve('validator'); if (valid || (fv && !fv.options.stopOnFailure)) { if (e && e.stop) e.stop(); this.send(); } }, onSubmit: function(e){ if (this.element.retrieve('validator')) { //form validator was created after Form.Request this.detach(); return; } e.stop(); this.send(); }, send: function(){ var str = this.element.toQueryString().trim(); var data = $H(this.options.extraData).toQueryString(); if (str) str += "&" + data; else str = data; this.fireEvent('send', [this.element, str.parseQueryString()]); this.request.send({data: str, url: this.element.get("action")}); return this; } }); Element.Properties.formRequest = { set: function(){ var opt = Array.link(arguments, {options: Object.type, update: Element.type, updateId: String.type}); var update = opt.update || opt.updateId; var updater = this.retrieve('form.request'); if (update) { if (updater) updater.update = document.id(update); this.store('form.request:update', update); } if (opt.options) { if (updater) updater.setOptions(opt.options); this.store('form.request:options', opt.options); } return this; }, get: function(){ var opt = Array.link(arguments, {options: Object.type, update: Element.type, updateId: String.type}); var update = opt.update || opt.updateId; if (opt.options || update || !this.retrieve('form.request')){ if (opt.options || !this.retrieve('form.request:options')) this.set('form.request', opt.options); if (update) this.set('form.request', update); this.store('form.request', new Form.Request(this, this.retrieve('form.request:update'), this.retrieve('form.request:options'))); } return this.retrieve('form.request'); } }; Element.implement({ formUpdate: function(update, options){ this.get('form.request', update, options).send(); return this; } }); })();/* --- script: MooTools.Lang.js description: Provides methods for localization. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Events - /MooTools.More provides: [MooTools.Lang] ... */ (function(){ var data = { language: 'en-US', languages: { 'en-US': {} }, cascades: ['en-US'] }; var cascaded; MooTools.lang = new Events(); $extend(MooTools.lang, { setLanguage: function(lang){ if (!data.languages[lang]) return this; data.language = lang; this.load(); this.fireEvent('langChange', lang); return this; }, load: function() { var langs = this.cascade(this.getCurrentLanguage()); cascaded = {}; $each(langs, function(set, setName){ cascaded[setName] = this.lambda(set); }, this); }, getCurrentLanguage: function(){ return data.language; }, addLanguage: function(lang){ data.languages[lang] = data.languages[lang] || {}; return this; }, cascade: function(lang){ var cascades = (data.languages[lang] || {}).cascades || []; cascades.combine(data.cascades); cascades.erase(lang).push(lang); var langs = cascades.map(function(lng){ return data.languages[lng]; }, this); return $merge.apply(this, langs); }, lambda: function(set) { (set || {}).get = function(key, args){ return $lambda(set[key]).apply(this, $splat(args)); }; return set; }, get: function(set, key, args){ if (cascaded && cascaded[set]) return (key ? cascaded[set].get(key, args) : cascaded[set]); }, set: function(lang, set, members){ this.addLanguage(lang); langData = data.languages[lang]; if (!langData[set]) langData[set] = {}; $extend(langData[set], members); if (lang == this.getCurrentLanguage()){ this.load(); this.fireEvent('langChange', lang); } return this; }, list: function(){ return Hash.getKeys(data.languages); } }); })();/* --- script: Selectors.js description: Adds advanced CSS-style querying capabilities for targeting HTML Elements. Includes pseudo selectors. license: MIT-style license. requires: - /Element provides: [Selectors] ... */ Native.implement([Document, Element], { getElements: function(expression, nocash){ expression = expression.split(','); var items, local = {}; for (var i = 0, l = expression.length; i < l; i++){ var selector = expression[i], elements = Selectors.Utils.search(this, selector, local); if (i != 0 && elements.item) elements = $A(elements); items = (i == 0) ? elements : (items.item) ? $A(items).concat(elements) : items.concat(elements); } return new Elements(items, {ddup: (expression.length > 1), cash: !nocash}); } }); Element.implement({ match: function(selector){ if (!selector || (selector == this)) return true; var tagid = Selectors.Utils.parseTagAndID(selector); var tag = tagid[0], id = tagid[1]; if (!Selectors.Filters.byID(this, id) || !Selectors.Filters.byTag(this, tag)) return false; var parsed = Selectors.Utils.parseSelector(selector); return (parsed) ? Selectors.Utils.filter(this, parsed, {}) : true; } }); var Selectors = {Cache: {nth: {}, parsed: {}}}; Selectors.RegExps = { id: (/#([\w-]+)/), tag: (/^(\w+|\*)/), quick: (/^(\w+|\*)$/), splitter: (/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g), combined: (/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g) }; Selectors.Utils = { chk: function(item, uniques){ if (!uniques) return true; var uid = $uid(item); if (!uniques[uid]) return uniques[uid] = true; return false; }, parseNthArgument: function(argument){ if (Selectors.Cache.nth[argument]) return Selectors.Cache.nth[argument]; var parsed = argument.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/); if (!parsed) return false; var inta = parseInt(parsed[1], 10); var a = (inta || inta === 0) ? inta : 1; var special = parsed[2] || false; var b = parseInt(parsed[3], 10) || 0; if (a != 0){ b--; while (b < 1) b += a; while (b >= a) b -= a; } else { a = b; special = 'index'; } switch (special){ case 'n': parsed = {a: a, b: b, special: 'n'}; break; case 'odd': parsed = {a: 2, b: 0, special: 'n'}; break; case 'even': parsed = {a: 2, b: 1, special: 'n'}; break; case 'first': parsed = {a: 0, special: 'index'}; break; case 'last': parsed = {special: 'last-child'}; break; case 'only': parsed = {special: 'only-child'}; break; default: parsed = {a: (a - 1), special: 'index'}; } return Selectors.Cache.nth[argument] = parsed; }, parseSelector: function(selector){ if (Selectors.Cache.parsed[selector]) return Selectors.Cache.parsed[selector]; var m, parsed = {classes: [], pseudos: [], attributes: []}; while ((m = Selectors.RegExps.combined.exec(selector))){ var cn = m[1], an = m[2], ao = m[3], av = m[5], pn = m[6], pa = m[7]; if (cn){ parsed.classes.push(cn); } else if (pn){ var parser = Selectors.Pseudo.get(pn); if (parser) parsed.pseudos.push({parser: parser, argument: pa}); else parsed.attributes.push({name: pn, operator: '=', value: pa}); } else if (an){ parsed.attributes.push({name: an, operator: ao, value: av}); } } if (!parsed.classes.length) delete parsed.classes; if (!parsed.attributes.length) delete parsed.attributes; if (!parsed.pseudos.length) delete parsed.pseudos; if (!parsed.classes && !parsed.attributes && !parsed.pseudos) parsed = null; return Selectors.Cache.parsed[selector] = parsed; }, parseTagAndID: function(selector){ var tag = selector.match(Selectors.RegExps.tag); var id = selector.match(Selectors.RegExps.id); return [(tag) ? tag[1] : '*', (id) ? id[1] : false]; }, filter: function(item, parsed, local){ var i; if (parsed.classes){ for (i = parsed.classes.length; i--; i){ var cn = parsed.classes[i]; if (!Selectors.Filters.byClass(item, cn)) return false; } } if (parsed.attributes){ for (i = parsed.attributes.length; i--; i){ var att = parsed.attributes[i]; if (!Selectors.Filters.byAttribute(item, att.name, att.operator, att.value)) return false; } } if (parsed.pseudos){ for (i = parsed.pseudos.length; i--; i){ var psd = parsed.pseudos[i]; if (!Selectors.Filters.byPseudo(item, psd.parser, psd.argument, local)) return false; } } return true; }, getByTagAndID: function(ctx, tag, id){ if (id){ var item = (ctx.getElementById) ? ctx.getElementById(id, true) : Element.getElementById(ctx, id, true); return (item && Selectors.Filters.byTag(item, tag)) ? [item] : []; } else { return ctx.getElementsByTagName(tag); } }, search: function(self, expression, local){ var splitters = []; var selectors = expression.trim().replace(Selectors.RegExps.splitter, function(m0, m1, m2){ splitters.push(m1); return ':)' + m2; }).split(':)'); var items, filtered, item; for (var i = 0, l = selectors.length; i < l; i++){ var selector = selectors[i]; if (i == 0 && Selectors.RegExps.quick.test(selector)){ items = self.getElementsByTagName(selector); continue; } var splitter = splitters[i - 1]; var tagid = Selectors.Utils.parseTagAndID(selector); var tag = tagid[0], id = tagid[1]; if (i == 0){ items = Selectors.Utils.getByTagAndID(self, tag, id); } else { var uniques = {}, found = []; for (var j = 0, k = items.length; j < k; j++) found = Selectors.Getters[splitter](found, items[j], tag, id, uniques); items = found; } var parsed = Selectors.Utils.parseSelector(selector); if (parsed){ filtered = []; for (var m = 0, n = items.length; m < n; m++){ item = items[m]; if (Selectors.Utils.filter(item, parsed, local)) filtered.push(item); } items = filtered; } } return items; } }; Selectors.Getters = { ' ': function(found, self, tag, id, uniques){ var items = Selectors.Utils.getByTagAndID(self, tag, id); for (var i = 0, l = items.length; i < l; i++){ var item = items[i]; if (Selectors.Utils.chk(item, uniques)) found.push(item); } return found; }, '>': function(found, self, tag, id, uniques){ var children = Selectors.Utils.getByTagAndID(self, tag, id); for (var i = 0, l = children.length; i < l; i++){ var child = children[i]; if (child.parentNode == self && Selectors.Utils.chk(child, uniques)) found.push(child); } return found; }, '+': function(found, self, tag, id, uniques){ while ((self = self.nextSibling)){ if (self.nodeType == 1){ if (Selectors.Utils.chk(self, uniques) && Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self); break; } } return found; }, '~': function(found, self, tag, id, uniques){ while ((self = self.nextSibling)){ if (self.nodeType == 1){ if (!Selectors.Utils.chk(self, uniques)) break; if (Selectors.Filters.byTag(self, tag) && Selectors.Filters.byID(self, id)) found.push(self); } } return found; } }; Selectors.Filters = { byTag: function(self, tag){ return (tag == '*' || (self.tagName && self.tagName.toLowerCase() == tag)); }, byID: function(self, id){ return (!id || (self.id && self.id == id)); }, byClass: function(self, klass){ return (self.className && self.className.contains && self.className.contains(klass, ' ')); }, byPseudo: function(self, parser, argument, local){ return parser.call(self, argument, local); }, byAttribute: function(self, name, operator, value){ var result = Element.prototype.getProperty.call(self, name); if (!result) return (operator == '!='); if (!operator || value == undefined) return true; switch (operator){ case '=': return (result == value); case '*=': return (result.contains(value)); case '^=': return (result.substr(0, value.length) == value); case '$=': return (result.substr(result.length - value.length) == value); case '!=': return (result != value); case '~=': return result.contains(value, ' '); case '|=': return result.contains(value, '-'); } return false; } }; Selectors.Pseudo = new Hash({ // w3c pseudo selectors checked: function(){ return this.checked; }, empty: function(){ return !(this.innerText || this.textContent || '').length; }, not: function(selector){ return !Element.match(this, selector); }, contains: function(text){ return (this.innerText || this.textContent || '').contains(text); }, 'first-child': function(){ return Selectors.Pseudo.index.call(this, 0); }, 'last-child': function(){ var element = this; while ((element = element.nextSibling)){ if (element.nodeType == 1) return false; } return true; }, 'only-child': function(){ var prev = this; while ((prev = prev.previousSibling)){ if (prev.nodeType == 1) return false; } var next = this; while ((next = next.nextSibling)){ if (next.nodeType == 1) return false; } return true; }, 'nth-child': function(argument, local){ argument = (argument == undefined) ? 'n' : argument; var parsed = Selectors.Utils.parseNthArgument(argument); if (parsed.special != 'n') return Selectors.Pseudo[parsed.special].call(this, parsed.a, local); var count = 0; local.positions = local.positions || {}; var uid = $uid(this); if (!local.positions[uid]){ var self = this; while ((self = self.previousSibling)){ if (self.nodeType != 1) continue; count ++; var position = local.positions[$uid(self)]; if (position != undefined){ count = position + count; break; } } local.positions[uid] = count; } return (local.positions[uid] % parsed.a == parsed.b); }, // custom pseudo selectors index: function(index){ var element = this, count = 0; while ((element = element.previousSibling)){ if (element.nodeType == 1 && ++count > index) return false; } return (count == index); }, even: function(argument, local){ return Selectors.Pseudo['nth-child'].call(this, '2n+1', local); }, odd: function(argument, local){ return Selectors.Pseudo['nth-child'].call(this, '2n', local); }, selected: function(){ return this.selected; }, enabled: function(){ return (this.disabled === false); } });/* --- script: Date.js description: Extends the Date native object to include methods useful in managing dates. license: MIT-style license authors: - Aaron Newton - Nicholas Barthelemy - https://svn.nbarthelemy.com/date-js/ - Harald Kirshner - mail [at] digitarald.de; http://digitarald.de - Scott Kyle - scott [at] appden.com; http://appden.com requires: - core:1.2.4/Array - core:1.2.4/String - core:1.2.4/Number - core:1.2.4/Lang - core:1.2.4/Date.English.US - /MooTools.More provides: [Date] ... */ (function(){ var Date = this.Date; if (!Date.now) Date.now = $time; Date.Methods = { ms: 'Milliseconds', year: 'FullYear', min: 'Minutes', mo: 'Month', sec: 'Seconds', hr: 'Hours' }; ['Date', 'Day', 'FullYear', 'Hours', 'Milliseconds', 'Minutes', 'Month', 'Seconds', 'Time', 'TimezoneOffset', 'Week', 'Timezone', 'GMTOffset', 'DayOfYear', 'LastMonth', 'LastDayOfMonth', 'UTCDate', 'UTCDay', 'UTCFullYear', 'AMPM', 'Ordinal', 'UTCHours', 'UTCMilliseconds', 'UTCMinutes', 'UTCMonth', 'UTCSeconds'].each(function(method){ Date.Methods[method.toLowerCase()] = method; }); var pad = function(what, length){ return new Array(length - String(what).length + 1).join('0') + what; }; Date.implement({ set: function(prop, value){ switch ($type(prop)){ case 'object': for (var p in prop) this.set(p, prop[p]); break; case 'string': prop = prop.toLowerCase(); var m = Date.Methods; if (m[prop]) this['set' + m[prop]](value); } return this; }, get: function(prop){ prop = prop.toLowerCase(); var m = Date.Methods; if (m[prop]) return this['get' + m[prop]](); return null; }, clone: function(){ return new Date(this.get('time')); }, increment: function(interval, times){ interval = interval || 'day'; times = $pick(times, 1); switch (interval){ case 'year': return this.increment('month', times * 12); case 'month': var d = this.get('date'); this.set('date', 1).set('mo', this.get('mo') + times); return this.set('date', d.min(this.get('lastdayofmonth'))); case 'week': return this.increment('day', times * 7); case 'day': return this.set('date', this.get('date') + times); } if (!Date.units[interval]) throw new Error(interval + ' is not a supported interval'); return this.set('time', this.get('time') + times * Date.units[interval]()); }, decrement: function(interval, times){ return this.increment(interval, -1 * $pick(times, 1)); }, isLeapYear: function(){ return Date.isLeapYear(this.get('year')); }, clearTime: function(){ return this.set({hr: 0, min: 0, sec: 0, ms: 0}); }, diff: function(date, resolution){ if ($type(date) == 'string') date = Date.parse(date); return ((date - this) / Date.units[resolution || 'day'](3, 3)).toInt(); // non-leap year, 30-day month }, getLastDayOfMonth: function(){ return Date.daysInMonth(this.get('mo'), this.get('year')); }, getDayOfYear: function(){ return (Date.UTC(this.get('year'), this.get('mo'), this.get('date') + 1) - Date.UTC(this.get('year'), 0, 1)) / Date.units.day(); }, getWeek: function(){ return (this.get('dayofyear') / 7).ceil(); }, getOrdinal: function(day){ return Date.getMsg('ordinal', day || this.get('date')); }, getTimezone: function(){ return this.toString() .replace(/^.*? ([A-Z]{3}).[0-9]{4}.*$/, '$1') .replace(/^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, '$1$2$3'); }, getGMTOffset: function(){ var off = this.get('timezoneOffset'); return ((off > 0) ? '-' : '+') + pad((off.abs() / 60).floor(), 2) + pad(off % 60, 2); }, setAMPM: function(ampm){ ampm = ampm.toUpperCase(); var hr = this.get('hr'); if (hr > 11 && ampm == 'AM') return this.decrement('hour', 12); else if (hr < 12 && ampm == 'PM') return this.increment('hour', 12); return this; }, getAMPM: function(){ return (this.get('hr') < 12) ? 'AM' : 'PM'; }, parse: function(str){ this.set('time', Date.parse(str)); return this; }, isValid: function(date) { return !!(date || this).valueOf(); }, format: function(f){ if (!this.isValid()) return 'invalid date'; f = f || '%x %X'; f = formats[f.toLowerCase()] || f; // replace short-hand with actual format var d = this; return f.replace(/%([a-z%])/gi, function($0, $1){ switch ($1){ case 'a': return Date.getMsg('days')[d.get('day')].substr(0, 3); case 'A': return Date.getMsg('days')[d.get('day')]; case 'b': return Date.getMsg('months')[d.get('month')].substr(0, 3); case 'B': return Date.getMsg('months')[d.get('month')]; case 'c': return d.toString(); case 'd': return pad(d.get('date'), 2); case 'H': return pad(d.get('hr'), 2); case 'I': return ((d.get('hr') % 12) || 12); case 'j': return pad(d.get('dayofyear'), 3); case 'm': return pad((d.get('mo') + 1), 2); case 'M': return pad(d.get('min'), 2); case 'o': return d.get('ordinal'); case 'p': return Date.getMsg(d.get('ampm')); case 'S': return pad(d.get('seconds'), 2); case 'U': return pad(d.get('week'), 2); case 'w': return d.get('day'); case 'x': return d.format(Date.getMsg('shortDate')); case 'X': return d.format(Date.getMsg('shortTime')); case 'y': return d.get('year').toString().substr(2); case 'Y': return d.get('year'); case 'T': return d.get('GMTOffset'); case 'Z': return d.get('Timezone'); } return $1; } ); }, toISOString: function(){ return this.format('iso8601'); } }); Date.alias('toISOString', 'toJSON'); Date.alias('diff', 'compare'); Date.alias('format', 'strftime'); var formats = { db: '%Y-%m-%d %H:%M:%S', compact: '%Y%m%dT%H%M%S', iso8601: '%Y-%m-%dT%H:%M:%S%T', rfc822: '%a, %d %b %Y %H:%M:%S %Z', 'short': '%d %b %H:%M', 'long': '%B %d, %Y %H:%M' }; var parsePatterns = []; var nativeParse = Date.parse; var parseWord = function(type, word, num){ var ret = -1; var translated = Date.getMsg(type + 's'); switch ($type(word)){ case 'object': ret = translated[word.get(type)]; break; case 'number': ret = translated[month - 1]; if (!ret) throw new Error('Invalid ' + type + ' index: ' + index); break; case 'string': var match = translated.filter(function(name){ return this.test(name); }, new RegExp('^' + word, 'i')); if (!match.length) throw new Error('Invalid ' + type + ' string'); if (match.length > 1) throw new Error('Ambiguous ' + type); ret = match[0]; } return (num) ? translated.indexOf(ret) : ret; }; Date.extend({ getMsg: function(key, args) { return MooTools.lang.get('Date', key, args); }, units: { ms: $lambda(1), second: $lambda(1000), minute: $lambda(60000), hour: $lambda(3600000), day: $lambda(86400000), week: $lambda(608400000), month: function(month, year){ var d = new Date; return Date.daysInMonth($pick(month, d.get('mo')), $pick(year, d.get('year'))) * 86400000; }, year: function(year){ year = year || new Date().get('year'); return Date.isLeapYear(year) ? 31622400000 : 31536000000; } }, daysInMonth: function(month, year){ return [31, Date.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]; }, isLeapYear: function(year){ return ((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0); }, parse: function(from){ var t = $type(from); if (t == 'number') return new Date(from); if (t != 'string') return from; from = from.clean(); if (!from.length) return null; var parsed; parsePatterns.some(function(pattern){ var bits = pattern.re.exec(from); return (bits) ? (parsed = pattern.handler(bits)) : false; }); return parsed || new Date(nativeParse(from)); }, parseDay: function(day, num){ return parseWord('day', day, num); }, parseMonth: function(month, num){ return parseWord('month', month, num); }, parseUTC: function(value){ var localDate = new Date(value); var utcSeconds = Date.UTC( localDate.get('year'), localDate.get('mo'), localDate.get('date'), localDate.get('hr'), localDate.get('min'), localDate.get('sec') ); return new Date(utcSeconds); }, orderIndex: function(unit){ return Date.getMsg('dateOrder').indexOf(unit) + 1; }, defineFormat: function(name, format){ formats[name] = format; }, defineFormats: function(formats){ for (var name in formats) Date.defineFormat(name, formats[name]); }, parsePatterns: parsePatterns, // this is deprecated defineParser: function(pattern){ parsePatterns.push((pattern.re && pattern.handler) ? pattern : build(pattern)); }, defineParsers: function(){ Array.flatten(arguments).each(Date.defineParser); }, define2DigitYearStart: function(year){ startYear = year % 100; startCentury = year - startYear; } }); var startCentury = 1900; var startYear = 70; var regexOf = function(type){ return new RegExp('(?:' + Date.getMsg(type).map(function(name){ return name.substr(0, 3); }).join('|') + ')[a-z]*'); }; var replacers = function(key){ switch(key){ case 'x': // iso8601 covers yyyy-mm-dd, so just check if month is first return ((Date.orderIndex('month') == 1) ? '%m[.-/]%d' : '%d[.-/]%m') + '([.-/]%y)?'; case 'X': return '%H([.:]%M)?([.:]%S([.:]%s)?)? ?%p? ?%T?'; } return null; }; var keys = { d: /[0-2]?[0-9]|3[01]/, H: /[01]?[0-9]|2[0-3]/, I: /0?[1-9]|1[0-2]/, M: /[0-5]?\d/, s: /\d+/, o: /[a-z]*/, p: /[ap]\.?m\.?/, y: /\d{2}|\d{4}/, Y: /\d{4}/, T: /Z|[+-]\d{2}(?::?\d{2})?/ }; keys.m = keys.I; keys.S = keys.M; var currentLanguage; var recompile = function(language){ currentLanguage = language; keys.a = keys.A = regexOf('days'); keys.b = keys.B = regexOf('months'); parsePatterns.each(function(pattern, i){ if (pattern.format) parsePatterns[i] = build(pattern.format); }); }; var build = function(format){ if (!currentLanguage) return {format: format}; var parsed = []; var re = (format.source || format) // allow format to be regex .replace(/%([a-z])/gi, function($0, $1){ return replacers($1) || $0; } ).replace(/\((?!\?)/g, '(?:') // make all groups non-capturing .replace(/ (?!\?|\*)/g, ',? ') // be forgiving with spaces and commas .replace(/%([a-z%])/gi, function($0, $1){ var p = keys[$1]; if (!p) return $1; parsed.push($1); return '(' + p.source + ')'; } ).replace(/\[a-z\]/gi, '[a-z\\u00c0-\\uffff]'); // handle unicode words return { format: format, re: new RegExp('^' + re + '$', 'i'), handler: function(bits){ bits = bits.slice(1).associate(parsed); var date = new Date().clearTime(); if ('d' in bits) handle.call(date, 'd', 1); if ('m' in bits || 'b' in bits || 'B' in bits) handle.call(date, 'm', 1); for (var key in bits) handle.call(date, key, bits[key]); return date; } }; }; var handle = function(key, value){ if (!value) return this; switch(key){ case 'a': case 'A': return this.set('day', Date.parseDay(value, true)); case 'b': case 'B': return this.set('mo', Date.parseMonth(value, true)); case 'd': return this.set('date', value); case 'H': case 'I': return this.set('hr', value); case 'm': return this.set('mo', value - 1); case 'M': return this.set('min', value); case 'p': return this.set('ampm', value.replace(/\./g, '')); case 'S': return this.set('sec', value); case 's': return this.set('ms', ('0.' + value) * 1000); case 'w': return this.set('day', value); case 'Y': return this.set('year', value); case 'y': value = +value; if (value < 100) value += startCentury + (value < startYear ? 100 : 0); return this.set('year', value); case 'T': if (value == 'Z') value = '+00'; var offset = value.match(/([+-])(\d{2}):?(\d{2})?/); offset = (offset[1] + '1') * (offset[2] * 60 + (+offset[3] || 0)) + this.getTimezoneOffset(); return this.set('time', this - offset * 60000); } return this; }; Date.defineParsers( '%Y([-./]%m([-./]%d((T| )%X)?)?)?', // "1999-12-31", "1999-12-31 11:59pm", "1999-12-31 23:59:59", ISO8601 '%Y%m%d(T%H(%M%S?)?)?', // "19991231", "19991231T1159", compact '%x( %X)?', // "12/31", "12.31.99", "12-31-1999", "12/31/2008 11:59 PM" '%d%o( %b( %Y)?)?( %X)?', // "31st", "31st December", "31 Dec 1999", "31 Dec 1999 11:59pm" '%b( %d%o)?( %Y)?( %X)?', // Same as above with month and day switched '%Y %b( %d%o( %X)?)?', // Same as above with year coming first '%o %b %d %X %T %Y' // "Thu Oct 22 08:11:23 +0000 2009" ); MooTools.lang.addEvent('langChange', function(language){ if (MooTools.lang.get('Date')) recompile(language); }).fireEvent('langChange', MooTools.lang.getCurrentLanguage()); })();/* --- script: Element.Forms.js description: Extends the Element native object to include methods useful in managing inputs. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element - /MooTools.More provides: [Element.Forms] ... */ Element.implement({ tidy: function(){ this.set('value', this.get('value').tidy()); }, getTextInRange: function(start, end){ return this.get('value').substring(start, end); }, getSelectedText: function(){ if (this.setSelectionRange) return this.getTextInRange(this.getSelectionStart(), this.getSelectionEnd()); return document.selection.createRange().text; }, getSelectedRange: function() { if ($defined(this.selectionStart)) return {start: this.selectionStart, end: this.selectionEnd}; var pos = {start: 0, end: 0}; var range = this.getDocument().selection.createRange(); if (!range || range.parentElement() != this) return pos; var dup = range.duplicate(); if (this.type == 'text') { pos.start = 0 - dup.moveStart('character', -100000); pos.end = pos.start + range.text.length; } else { var value = this.get('value'); var offset = value.length; dup.moveToElementText(this); dup.setEndPoint('StartToEnd', range); if(dup.text.length) offset -= value.match(/[\n\r]*$/)[0].length; pos.end = offset - dup.text.length; dup.setEndPoint('StartToStart', range); pos.start = offset - dup.text.length; } return pos; }, getSelectionStart: function(){ return this.getSelectedRange().start; }, getSelectionEnd: function(){ return this.getSelectedRange().end; }, setCaretPosition: function(pos){ if (pos == 'end') pos = this.get('value').length; this.selectRange(pos, pos); return this; }, getCaretPosition: function(){ return this.getSelectedRange().start; }, selectRange: function(start, end){ if (this.setSelectionRange) { this.focus(); this.setSelectionRange(start, end); } else { var value = this.get('value'); var diff = value.substr(start, end - start).replace(/\r/g, '').length; start = value.substr(0, start).replace(/\r/g, '').length; var range = this.createTextRange(); range.collapse(true); range.moveEnd('character', start + diff); range.moveStart('character', start); range.select(); } return this; }, insertAtCursor: function(value, select){ var pos = this.getSelectedRange(); var text = this.get('value'); this.set('value', text.substring(0, pos.start) + value + text.substring(pos.end, text.length)); if ($pick(select, true)) this.selectRange(pos.start, pos.start + value.length); else this.setCaretPosition(pos.start + value.length); return this; }, insertAroundCursor: function(options, select){ options = $extend({ before: '', defaultMiddle: '', after: '' }, options); var value = this.getSelectedText() || options.defaultMiddle; var pos = this.getSelectedRange(); var text = this.get('value'); if (pos.start == pos.end){ this.set('value', text.substring(0, pos.start) + options.before + value + options.after + text.substring(pos.end, text.length)); this.selectRange(pos.start + options.before.length, pos.end + options.before.length + value.length); } else { var current = text.substring(pos.start, pos.end); this.set('value', text.substring(0, pos.start) + options.before + current + options.after + text.substring(pos.end, text.length)); var selStart = pos.start + options.before.length; if ($pick(select, true)) this.selectRange(selStart, selStart + current.length); else this.setCaretPosition(selStart + text.length); } return this; } });/* --- script: Element.Shortcuts.js description: Extends the Element native object to include some shortcut methods. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Element.Style - /MooTools.More provides: [Element.Shortcuts] ... */ Element.implement({ isDisplayed: function(){ return this.getStyle('display') != 'none'; }, isVisible: function(){ var w = this.offsetWidth, h = this.offsetHeight; return (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : this.isDisplayed(); }, toggle: function(){ return this[this.isDisplayed() ? 'hide' : 'show'](); }, hide: function(){ var d; try { //IE fails here if the element is not in the dom d = this.getStyle('display'); } catch(e){} return this.store('originalDisplay', d || '').setStyle('display', 'none'); }, show: function(display){ display = display || this.retrieve('originalDisplay') || 'block'; return this.setStyle('display', (display == 'none') ? 'block' : display); }, swapClass: function(remove, add){ return this.removeClass(remove).addClass(add); } }); /* --- script: Form.Validator.js description: A css-class based form validation system. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Options - core:1.2.4/Events - core:1.2.4/Selectors - core:1.2.4/Element.Event - core:1.2.4/Element.Style - core:1.2.4/JSON - /Lang- /Class.Binds - /Date Element.Forms - /Form.Validator.English - /Element.Shortcuts provides: [Form.Validator, InputValidator, FormValidator.BaseValidators] ... */ if (!window.Form) window.Form = {}; var InputValidator = new Class({ Implements: [Options], options: { errorMsg: 'Validation failed.', test: function(field){return true;} }, initialize: function(className, options){ this.setOptions(options); this.className = className; }, test: function(field, props){ if (document.id(field)) return this.options.test(document.id(field), props||this.getProps(field)); else return false; }, getError: function(field, props){ var err = this.options.errorMsg; if ($type(err) == 'function') err = err(document.id(field), props||this.getProps(field)); return err; }, getProps: function(field){ if (!document.id(field)) return {}; return field.get('validatorProps'); } }); Element.Properties.validatorProps = { set: function(props){ return this.eliminate('validatorProps').store('validatorProps', props); }, get: function(props){ if (props) this.set(props); if (this.retrieve('validatorProps')) return this.retrieve('validatorProps'); if (this.getProperty('validatorProps')){ try { this.store('validatorProps', JSON.decode(this.getProperty('validatorProps'))); }catch(e){ return {}; } } else { var vals = this.get('class').split(' ').filter(function(cls){ return cls.test(':'); }); if (!vals.length){ this.store('validatorProps', {}); } else { props = {}; vals.each(function(cls){ var split = cls.split(':'); if (split[1]) { try { props[split[0]] = JSON.decode(split[1]); } catch(e) {} } }); this.store('validatorProps', props); } } return this.retrieve('validatorProps'); } }; Form.Validator = new Class({ Implements:[Options, Events], Binds: ['onSubmit'], options: {/* onFormValidate: $empty(isValid, form, event), onElementValidate: $empty(isValid, field, className, warn), onElementPass: $empty(field), onElementFail: $empty(field, validatorsFailed) */ fieldSelectors: 'input, select, textarea', ignoreHidden: true, ignoreDisabled: true, useTitles: false, evaluateOnSubmit: true, evaluateFieldsOnBlur: true, evaluateFieldsOnChange: true, serial: true, stopOnFailure: true, warningPrefix: function(){ return Form.Validator.getMsg('warningPrefix') || 'Warning: '; }, errorPrefix: function(){ return Form.Validator.getMsg('errorPrefix') || 'Error: '; } }, initialize: function(form, options){ this.setOptions(options); this.element = document.id(form); this.element.store('validator', this); this.warningPrefix = $lambda(this.options.warningPrefix)(); this.errorPrefix = $lambda(this.options.errorPrefix)(); if (this.options.evaluateOnSubmit) this.element.addEvent('submit', this.onSubmit); if (this.options.evaluateFieldsOnBlur || this.options.evaluateFieldsOnChange) this.watchFields(this.getFields()); }, toElement: function(){ return this.element; }, getFields: function(){ return (this.fields = this.element.getElements(this.options.fieldSelectors)); }, watchFields: function(fields){ fields.each(function(el){ if (this.options.evaluateFieldsOnBlur) el.addEvent('blur', this.validationMonitor.pass([el, false], this)); if (this.options.evaluateFieldsOnChange) el.addEvent('change', this.validationMonitor.pass([el, true], this)); }, this); }, validationMonitor: function(){ $clear(this.timer); this.timer = this.validateField.delay(50, this, arguments); }, onSubmit: function(event){ if (!this.validate(event) && event) event.preventDefault(); else this.reset(); }, reset: function(){ this.getFields().each(this.resetField, this); return this; }, validate: function(event){ var result = this.getFields().map(function(field){ return this.validateField(field, true); }, this).every(function(v){ return v;}); this.fireEvent('formValidate', [result, this.element, event]); if (this.options.stopOnFailure && !result && event) event.preventDefault(); return result; }, validateField: function(field, force){ if (this.paused) return true; field = document.id(field); var passed = !field.hasClass('validation-failed'); var failed, warned; if (this.options.serial && !force){ failed = this.element.getElement('.validation-failed'); warned = this.element.getElement('.warning'); } if (field && (!failed || force || field.hasClass('validation-failed') || (failed && !this.options.serial))){ var validators = field.className.split(' ').some(function(cn){ return this.getValidator(cn); }, this); var validatorsFailed = []; field.className.split(' ').each(function(className){ if (className && !this.test(className, field)) validatorsFailed.include(className); }, this); passed = validatorsFailed.length === 0; if (validators && !field.hasClass('warnOnly')){ if (passed){ field.addClass('validation-passed').removeClass('validation-failed'); this.fireEvent('elementPass', field); } else { field.addClass('validation-failed').removeClass('validation-passed'); this.fireEvent('elementFail', [field, validatorsFailed]); } } if (!warned){ var warnings = field.className.split(' ').some(function(cn){ if (cn.test('^warn-') || field.hasClass('warnOnly')) return this.getValidator(cn.replace(/^warn-/,'')); else return null; }, this); field.removeClass('warning'); var warnResult = field.className.split(' ').map(function(cn){ if (cn.test('^warn-') || field.hasClass('warnOnly')) return this.test(cn.replace(/^warn-/,''), field, true); else return null; }, this); } } return passed; }, test: function(className, field, warn){ field = document.id(field); if((this.options.ignoreHidden && !field.isVisible()) || (this.options.ignoreDisabled && field.get('disabled'))) return true; var validator = this.getValidator(className); if (field.hasClass('ignoreValidation')) return true; warn = $pick(warn, false); if (field.hasClass('warnOnly')) warn = true; var isValid = validator ? validator.test(field) : true; if (validator && field.isVisible()) this.fireEvent('elementValidate', [isValid, field, className, warn]); if (warn) return true; return isValid; }, resetField: function(field){ field = document.id(field); if (field){ field.className.split(' ').each(function(className){ if (className.test('^warn-')) className = className.replace(/^warn-/, ''); field.removeClass('validation-failed'); field.removeClass('warning'); field.removeClass('validation-passed'); }, this); } return this; }, stop: function(){ this.paused = true; return this; }, start: function(){ this.paused = false; return this; }, ignoreField: function(field, warn){ field = document.id(field); if (field){ this.enforceField(field); if (warn) field.addClass('warnOnly'); else field.addClass('ignoreValidation'); } return this; }, enforceField: function(field){ field = document.id(field); if (field) field.removeClass('warnOnly').removeClass('ignoreValidation'); return this; } }); Form.Validator.getMsg = function(key){ return MooTools.lang.get('Form.Validator', key); }; Form.Validator.adders = { validators:{}, add : function(className, options){ this.validators[className] = new InputValidator(className, options); //if this is a class (this method is used by instances of Form.Validator and the Form.Validator namespace) //extend these validators into it //this allows validators to be global and/or per instance if (!this.initialize){ this.implement({ validators: this.validators }); } }, addAllThese : function(validators){ $A(validators).each(function(validator){ this.add(validator[0], validator[1]); }, this); }, getValidator: function(className){ return this.validators[className.split(':')[0]]; } }; $extend(Form.Validator, Form.Validator.adders); Form.Validator.implement(Form.Validator.adders); Form.Validator.add('IsEmpty', { errorMsg: false, test: function(element){ if (element.type == 'select-one' || element.type == 'select') return !(element.selectedIndex >= 0 && element.options[element.selectedIndex].value != ''); else return ((element.get('value') == null) || (element.get('value').length == 0)); } }); Form.Validator.addAllThese([ ['required', { errorMsg: function(){ return Form.Validator.getMsg('required'); }, test: function(element){ return !Form.Validator.getValidator('IsEmpty').test(element); } }], ['minLength', { errorMsg: function(element, props){ if ($type(props.minLength)) return Form.Validator.getMsg('minLength').substitute({minLength:props.minLength,length:element.get('value').length }); else return ''; }, test: function(element, props){ if ($type(props.minLength)) return (element.get('value').length >= $pick(props.minLength, 0)); else return true; } }], ['maxLength', { errorMsg: function(element, props){ //props is {maxLength:10} if ($type(props.maxLength)) return Form.Validator.getMsg('maxLength').substitute({maxLength:props.maxLength,length:element.get('value').length }); else return ''; }, test: function(element, props){ //if the value is <= than the maxLength value, element passes test return (element.get('value').length <= $pick(props.maxLength, 10000)); } }], ['validate-integer', { errorMsg: Form.Validator.getMsg.pass('integer'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^(-?[1-9]\d*|0)$/).test(element.get('value')); } }], ['validate-numeric', { errorMsg: Form.Validator.getMsg.pass('numeric'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^-?(?:0$0(?=\d*\.)|[1-9]|0)\d*(\.\d+)?$/).test(element.get('value')); } }], ['validate-digits', { errorMsg: Form.Validator.getMsg.pass('digits'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^[\d() .:\-\+#]+$/.test(element.get('value'))); } }], ['validate-alpha', { errorMsg: Form.Validator.getMsg.pass('alpha'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^[a-zA-Z]+$/).test(element.get('value')); } }], ['validate-alphanum', { errorMsg: Form.Validator.getMsg.pass('alphanum'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || !(/\W/).test(element.get('value')); } }], ['validate-date', { errorMsg: function(element, props){ if (Date.parse){ var format = props.dateFormat || '%x'; return Form.Validator.getMsg('dateSuchAs').substitute({date: new Date().format(format)}); } else { return Form.Validator.getMsg('dateInFormatMDY'); } }, test: function(element, props){ if (Form.Validator.getValidator('IsEmpty').test(element)) return true; var d; if (Date.parse){ var format = props.dateFormat || '%x'; d = Date.parse(element.get('value')); var formatted = d.format(format); if (formatted != 'invalid date') element.set('value', formatted); return !isNaN(d); } else { var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/; if (!regex.test(element.get('value'))) return false; d = new Date(element.get('value').replace(regex, '$1/$2/$3')); return (parseInt(RegExp.$1, 10) == (1 + d.getMonth())) && (parseInt(RegExp.$2, 10) == d.getDate()) && (parseInt(RegExp.$3, 10) == d.getFullYear()); } } }], ['validate-email', { errorMsg: Form.Validator.getMsg.pass('email'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i).test(element.get('value')); } }], ['validate-url', { errorMsg: Form.Validator.getMsg.pass('url'), test: function(element){ return Form.Validator.getValidator('IsEmpty').test(element) || (/^(https?|ftp|rmtp|mms):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i).test(element.get('value')); } }], ['validate-currency-dollar', { errorMsg: Form.Validator.getMsg.pass('currencyDollar'), test: function(element){ // [$]1[##][,###]+[.##] // [$]1###+[.##] // [$]0.## // [$].## return Form.Validator.getValidator('IsEmpty').test(element) || (/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/).test(element.get('value')); } }], ['validate-one-required', { errorMsg: Form.Validator.getMsg.pass('oneRequired'), test: function(element, props){ var p = document.id(props['validate-one-required']) || element.getParent(); return p.getElements('input').some(function(el){ if (['checkbox', 'radio'].contains(el.get('type'))) return el.get('checked'); return el.get('value'); }); } }] ]); Element.Properties.validator = { set: function(options){ var validator = this.retrieve('validator'); if (validator) validator.setOptions(options); return this.store('validator:options'); }, get: function(options){ if (options || !this.retrieve('validator')){ if (options || !this.retrieve('validator:options')) this.set('validator', options); this.store('validator', new Form.Validator(this, this.retrieve('validator:options'))); } return this.retrieve('validator'); } }; Element.implement({ validate: function(options){ this.set('validator', options); return this.get('validator', options).validate(); } }); //legacy var FormValidator = Form.Validator;/* --- script: Form.Validator.Extras.js description: Additional validators for the Form.Validator class. license: MIT-style license authors: - Aaron Newton requires: - /Form.Validator provides: [Form.Validator.Extras] ... */ Form.Validator.addAllThese([ ['validate-enforce-oncheck', { test: function(element, props){ if (element.checked){ var fv = element.getParent('form').retrieve('validator'); if (!fv) return true; (props.toEnforce || document.id(props.enforceChildrenOf).getElements('input, select, textarea')).map(function(item){ fv.enforceField(item); }); } return true; } }], ['validate-ignore-oncheck', { test: function(element, props){ if (element.checked){ var fv = element.getParent('form').retrieve('validator'); if (!fv) return true; (props.toIgnore || document.id(props.ignoreChildrenOf).getElements('input, select, textarea')).each(function(item){ fv.ignoreField(item); fv.resetField(item); }); } return true; } }], ['validate-nospace', { errorMsg: function(){ return Form.Validator.getMsg('noSpace'); }, test: function(element, props){ return !element.get('value').test(/\s/); } }], ['validate-toggle-oncheck', { test: function(element, props){ var fv = element.getParent('form').retrieve('validator'); if (!fv) return true; var eleArr = props.toToggle || document.id(props.toToggleChildrenOf).getElements('input, select, textarea'); if (!element.checked){ eleArr.each(function(item){ fv.ignoreField(item); fv.resetField(item); }); } else { eleArr.each(function(item){ fv.enforceField(item); }); } return true; } }], ['validate-reqchk-bynode', { errorMsg: function(){ return Form.Validator.getMsg('reqChkByNode'); }, test: function(element, props){ return (document.id(props.nodeId).getElements(props.selector || 'input[type=checkbox], input[type=radio]')).some(function(item){ return item.checked; }); } }], ['validate-required-check', { errorMsg: function(element, props){ return props.useTitle ? element.get('title') : Form.Validator.getMsg('requiredChk'); }, test: function(element, props){ return !!element.checked; } }], ['validate-reqchk-byname', { errorMsg: function(element, props){ return Form.Validator.getMsg('reqChkByName').substitute({label: props.label || element.get('type')}); }, test: function(element, props){ var grpName = props.groupName || element.get('name'); var oneCheckedItem = $$(document.getElementsByName(grpName)).some(function(item, index){ return item.checked; }); var fv = element.getParent('form').retrieve('validator'); if (oneCheckedItem && fv) fv.resetField(element); return oneCheckedItem; } }], ['validate-match', { errorMsg: function(element, props){ return Form.Validator.getMsg('match').substitute({matchName: props.matchName || document.id(props.matchInput).get('name')}); }, test: function(element, props){ var eleVal = element.get('value'); var matchVal = document.id(props.matchInput) && document.id(props.matchInput).get('value'); return eleVal && matchVal ? eleVal == matchVal : true; } }], ['validate-after-date', { errorMsg: function(element, props){ return Form.Validator.getMsg('afterDate').substitute({ label: props.afterLabel || (props.afterElement ? Form.Validator.getMsg('startDate') : Form.Validator.getMsg('currentDate')) }); }, test: function(element, props){ var start = document.id(props.afterElement) ? Date.parse(document.id(props.afterElement).get('value')) : new Date(); var end = Date.parse(element.get('value')); return end && start ? end >= start : true; } }], ['validate-before-date', { errorMsg: function(element, props){ return Form.Validator.getMsg('beforeDate').substitute({ label: props.beforeLabel || (props.beforeElement ? Form.Validator.getMsg('endDate') : Form.Validator.getMsg('currentDate')) }); }, test: function(element, props){ var start = Date.parse(element.get('value')); var end = document.id(props.beforeElement) ? Date.parse(document.id(props.beforeElement).get('value')) : new Date(); return end && start ? end >= start : true; } }], ['validate-custom-required', { errorMsg: function(){ return Form.Validator.getMsg('required'); }, test: function(element, props){ return element.get('value') != props.emptyValue; } }], ['validate-same-month', { errorMsg: function(element, props){ var startMo = document.id(props.sameMonthAs) && document.id(props.sameMonthAs).get('value'); var eleVal = element.get('value'); if (eleVal != '') return Form.Validator.getMsg(startMo ? 'sameMonth' : 'startMonth'); }, test: function(element, props){ var d1 = Date.parse(element.get('value')); var d2 = Date.parse(document.id(props.sameMonthAs) && document.id(props.sameMonthAs).get('value')); return d1 && d2 ? d1.format('%B') == d2.format('%B') : true; } }], ['validate-cc-num', { errorMsg: function(element){ var ccNum = element.get('value').replace(/[^0-9]/g, ''); return Form.Validator.getMsg('creditcard').substitute({length: ccNum.length}); }, test: function(element){ // required is a different test if (Form.Validator.getValidator('IsEmpty').test(element)) { return true; } // Clean number value var ccNum = element.get('value'); ccNum = ccNum.replace(/[^0-9]/g, ''); var valid_type = false; if (ccNum.test(/^4[0-9]{12}([0-9]{3})?$/)) valid_type = 'Visa'; else if (ccNum.test(/^5[1-5]([0-9]{14})$/)) valid_type = 'Master Card'; else if (ccNum.test(/^3[47][0-9]{13}$/)) valid_type = 'American Express'; else if (ccNum.test(/^6011[0-9]{12}$/)) valid_type = 'Discover'; if (valid_type) { var sum = 0; var cur = 0; for(var i=ccNum.length-1; i>=0; --i) { cur = ccNum.charAt(i).toInt(); if (cur == 0) { continue; } if ((ccNum.length-i) % 2 == 0) { cur += cur; } if (cur > 9) { cur = cur.toString().charAt(0).toInt() + cur.toString().charAt(1).toInt(); } sum += cur; } if ((sum % 10) == 0) { return true; } } var chunks = ''; while (ccNum != '') { chunks += ' ' + ccNum.substr(0,4); ccNum = ccNum.substr(4); } element.getParent('form').retrieve('validator').ignoreField(element); element.set('value', chunks.clean()); element.getParent('form').retrieve('validator').enforceField(element); return false; } }] ]);/* --- script: OverText.js description: Shows text over an input that disappears when the user clicks into it. The text remains hidden if the user adds a value. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Options - core:1.2.4/Events - core:1.2.4/Element.Event - /Class.Binds - /Class.Occlude - /Element.Position - /Element.Shortcuts provides: [OverText] ... */ var OverText = new Class({ Implements: [Options, Events, Class.Occlude], Binds: ['reposition', 'assert', 'focus', 'hide'], options: {/* textOverride: null, onFocus: $empty() onTextHide: $empty(textEl, inputEl), onTextShow: $empty(textEl, inputEl), */ element: 'label', positionOptions: { position: 'upperLeft', edge: 'upperLeft', offset: { x: 4, y: 2 } }, poll: false, pollInterval: 250, wrap: false }, property: 'OverText', initialize: function(element, options){ this.element = document.id(element); if (this.occlude()) return this.occluded; this.setOptions(options); this.attach(this.element); OverText.instances.push(this); if (this.options.poll) this.poll(); return this; }, toElement: function(){ return this.element; }, attach: function(){ var val = this.options.textOverride || this.element.get('alt') || this.element.get('title'); if (!val) return; this.text = new Element(this.options.element, { 'class': 'overTxtLabel', styles: { lineHeight: 'normal', position: 'absolute', cursor: 'text' }, html: val, events: { click: this.hide.pass(this.options.element == 'label', this) } }).inject(this.element, 'after'); if (this.options.element == 'label') { if (!this.element.get('id')) this.element.set('id', 'input_' + new Date().getTime()); this.text.set('for', this.element.get('id')); } if (this.options.wrap) { this.textHolder = new Element('div', { styles: { lineHeight: 'normal', position: 'relative' }, 'class':'overTxtWrapper' }).adopt(this.text).inject(this.element, 'before'); } this.element.addEvents({ focus: this.focus, blur: this.assert, change: this.assert }).store('OverTextDiv', this.text); window.addEvent('resize', this.reposition.bind(this)); this.assert(true); this.reposition(); }, wrap: function(){ if (this.options.element == 'label') { if (!this.element.get('id')) this.element.set('id', 'input_' + new Date().getTime()); this.text.set('for', this.element.get('id')); } }, startPolling: function(){ this.pollingPaused = false; return this.poll(); }, poll: function(stop){ //start immediately //pause on focus //resumeon blur if (this.poller && !stop) return this; var test = function(){ if (!this.pollingPaused) this.assert(true); }.bind(this); if (stop) $clear(this.poller); else this.poller = test.periodical(this.options.pollInterval, this); return this; }, stopPolling: function(){ this.pollingPaused = true; return this.poll(true); }, focus: function(){ if (this.text && (!this.text.isDisplayed() || this.element.get('disabled'))) return; this.hide(); }, hide: function(suppressFocus, force){ if (this.text && (this.text.isDisplayed() && (!this.element.get('disabled') || force))){ this.text.hide(); this.fireEvent('textHide', [this.text, this.element]); this.pollingPaused = true; if (!suppressFocus){ try { this.element.fireEvent('focus'); this.element.focus(); } catch(e){} //IE barfs if you call focus on hidden elements } } return this; }, show: function(){ if (this.text && !this.text.isDisplayed()){ this.text.show(); this.reposition(); this.fireEvent('textShow', [this.text, this.element]); this.pollingPaused = false; } return this; }, assert: function(suppressFocus){ this[this.test() ? 'show' : 'hide'](suppressFocus); }, test: function(){ var v = this.element.get('value'); return !v; }, reposition: function(){ this.assert(true); if (!this.element.isVisible()) return this.stopPolling().hide(); if (this.text && this.test()) this.text.position($merge(this.options.positionOptions, {relativeTo: this.element})); return this; } }); OverText.instances = []; $extend(OverText, { each: function(fn) { return OverText.instances.map(function(ot, i){ if (ot.element && ot.text) return fn.apply(OverText, [ot, i]); return null; //the input or the text was destroyed }); }, update: function(){ return OverText.each(function(ot){ return ot.reposition(); }); }, hideAll: function(){ return OverText.each(function(ot){ return ot.hide(true, true); }); }, showAll: function(){ return OverText.each(function(ot) { return ot.show(); }); } }); if (window.Fx && Fx.Reveal) { Fx.Reveal.implement({ hideInputs: Browser.Engine.trident ? 'select, input, textarea, object, embed, .overTxtLabel' : false }); }/* --- script: Fx.Scroll.js description: Effect to smoothly scroll any element, including the window. license: MIT-style license authors: - Valerio Proietti requires: - core:1.2.4/Fx - core:1.2.4/Element.Event - core:1.2.4/Element.Dimensions - /MooTools.More provides: [Fx.Scroll] ... */ Fx.Scroll = new Class({ Extends: Fx, options: { offset: {x: 0, y: 0}, wheelStops: true }, initialize: function(element, options){ this.element = this.subject = document.id(element); this.parent(options); var cancel = this.cancel.bind(this, false); if ($type(this.element) != 'element') this.element = document.id(this.element.getDocument().body); var stopper = this.element; if (this.options.wheelStops){ this.addEvent('start', function(){ stopper.addEvent('mousewheel', cancel); }, true); this.addEvent('complete', function(){ stopper.removeEvent('mousewheel', cancel); }, true); } }, set: function(){ var now = Array.flatten(arguments); if (Browser.Engine.gecko) now = [Math.round(now[0]), Math.round(now[1])]; this.element.scrollTo(now[0], now[1]); }, compute: function(from, to, delta){ return [0, 1].map(function(i){ return Fx.compute(from[i], to[i], delta); }); }, start: function(x, y){ if (!this.check(x, y)) return this; var scrollSize = this.element.getScrollSize(), scroll = this.element.getScroll(), values = {x: x, y: y}; for (var z in values){ var max = scrollSize[z]; if ($chk(values[z])) values[z] = ($type(values[z]) == 'number') ? values[z] : max; else values[z] = scroll[z]; values[z] += this.options.offset[z]; } return this.parent([scroll.x, scroll.y], [values.x, values.y]); }, toTop: function(){ return this.start(false, 0); }, toLeft: function(){ return this.start(0, false); }, toRight: function(){ return this.start('right', false); }, toBottom: function(){ return this.start(false, 'bottom'); }, toElement: function(el){ var position = document.id(el).getPosition(this.element); return this.start(position.x, position.y); }, scrollIntoView: function(el, axes, offset){ axes = axes ? $splat(axes) : ['x','y']; var to = {}; el = document.id(el); var pos = el.getPosition(this.element); var size = el.getSize(); var scroll = this.element.getScroll(); var containerSize = this.element.getSize(); var edge = { x: pos.x + size.x, y: pos.y + size.y }; ['x','y'].each(function(axis) { if (axes.contains(axis)) { if (edge[axis] > scroll[axis] + containerSize[axis]) to[axis] = edge[axis] - containerSize[axis]; if (pos[axis] < scroll[axis]) to[axis] = pos[axis]; } if (to[axis] == null) to[axis] = scroll[axis]; if (offset && offset[axis]) to[axis] = to[axis] + offset[axis]; }, this); if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y); return this; }, scrollToCenter: function(el, axes, offset){ axes = axes ? $splat(axes) : ['x', 'y']; el = $(el); var to = {}, pos = el.getPosition(this.element), size = el.getSize(), scroll = this.element.getScroll(), containerSize = this.element.getSize(), edge = { x: pos.x + size.x, y: pos.y + size.y }; ['x','y'].each(function(axis){ if(axes.contains(axis)){ to[axis] = pos[axis] - (containerSize[axis] - size[axis])/2; } if(to[axis] == null) to[axis] = scroll[axis]; if(offset && offset[axis]) to[axis] = to[axis] + offset[axis]; }, this); if (to.x != scroll.x || to.y != scroll.y) this.start(to.x, to.y); return this; } }); /* --- script: Fx.SmoothScroll.js description: Class for creating a smooth scrolling effect to all internal links on the page. license: MIT-style license authors: - Valerio Proietti requires: - core:1.2.4/Selectors - /Fx.Scroll provides: [Fx.SmoothScroll] ... */ var SmoothScroll = Fx.SmoothScroll = new Class({ Extends: Fx.Scroll, initialize: function(options, context){ context = context || document; this.doc = context.getDocument(); var win = context.getWindow(); this.parent(this.doc, options); this.links = $$(this.options.links || this.doc.links); var location = win.location.href.match(/^[^#]*/)[0] + '#'; this.links.each(function(link){ if (link.href.indexOf(location) != 0) {return;} var anchor = link.href.substr(location.length); if (anchor) this.useLink(link, anchor); }, this); if (!Browser.Engine.webkit419) { this.addEvent('complete', function(){ win.location.hash = this.anchor; }, true); } }, useLink: function(link, anchor){ var el; link.addEvent('click', function(event){ if (el !== false && !el) el = document.id(anchor) || this.doc.getElement('a[name=' + decodeURIComponent(anchor) + ']'); if (el) { event.preventDefault(); this.anchor = anchor; this.toElement(el).chain(function(){ this.fireEvent('scrolledTo', [link, el]); }.bind(this)); link.blur(); } }.bind(this)); } });/* Script: Date.Russian.js Date messages for Russian. License: MIT-style license. Authors: Evstigneev Pavel */ MooTools.lang.set('ru-RU', 'Date', { months: ['ßíâàðü', 'Ôåâðàëü', 'Ìàðò', 'Àïðåëü', 'Ìàé', 'Èþíü', 'Èþëü', 'Àâãóñò', 'Ñåíòÿáðü', 'Îêòÿáðü', 'Íîÿáðü', 'Äåêàáðü'], days: ['Âñ', 'Ïí', 'Âò', 'Ñð', '×ò', 'Ïò', 'Ñá'], //culture's date order: MM/DD/YYYY dateOrder: ['date', 'month', 'year'], AM: 'AM', PM: 'PM', shortDate: '%d.%m.%Y', shortTime: '%H:%M', /* * Russian language pluralization rules, taken from CLDR project, http://unicode.org/cldr/ * * one -> n mod 10 is 1 and n mod 100 is not 11; * few -> n mod 10 in 2..4 and n mod 100 not in 12..14; * many -> n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14; * other -> everything else (example 3.14) */ pluralize: function (n, one, few, many, other) { var modulo10 = n % 10 var modulo100 = n % 100 if (modulo10 == 1 && modulo100 != 11) { return one; } else if ((modulo10 == 2 || modulo10 == 3 || modulo10 == 4) && !(modulo100 == 12 || modulo100 == 13 || modulo100 == 14)) { return few; } else if (modulo10 == 0 || (modulo10 == 5 || modulo10 == 6 || modulo10 == 7 || modulo10 == 8 || modulo10 == 9) || (modulo100 == 11 || modulo100 == 12 || modulo100 == 13 || modulo100 == 14)) { return many; } else { return other; } }, /* Date.Extras */ ordinal: '', lessThanMinuteAgo: 'ìåíüøå ìèíóòû íàçàä', minuteAgo: 'ìèíóòà íàçàä', minutesAgo: function (delta) { return '{delta} ' + this.pluralize(delta, 'ìèíóòà', 'ìèíóòû', 'ìèíóò') + ' íàçàä'}, hourAgo: '÷àñ íàçàä', hoursAgo: function (delta) { return '{delta} ' + this.pluralize(delta, '÷àñ', '÷àñà', '÷àñîâ') + ' íàçàä'}, dayAgo: 'â÷åðà', daysAgo: function (delta) { return '{delta} ' + this.pluralize(delta, 'äåíü', 'äíÿ', 'äíåé') + ' íàçàä'}, lessThanMinuteUntil: 'ìåíüøå ìèíóòû íàçàä', minuteUntil: '÷åðåç ìèíóòó', minutesUntil: function (delta) { return '÷åðåç {delta} ' + this.pluralize(delta, '÷àñ', '÷àñà', '÷àñîâ') + ''}, hourUntil: '÷åðåç ÷àñ', hoursUntil: function (delta) { return '÷åðåç {delta} ' + this.pluralize(delta, '÷àñ', '÷àñà', '÷àñîâ') + ''}, dayUntil: 'çàâòðà', daysUntil: function (delta) { return '÷åðåç {delta} ' + this.pluralize(delta, 'äåíü', 'äíÿ', 'äíåé') + ''} });/* --- script: Form.Validator.Russian.js description: Form.Validator messages in Russian (utf-8 and cp1251). license: MIT-style license authors: - Chernodarov Egor requires: - /Lang - /Form.Validator provides: [Form.Validator.Russian] ... */ MooTools.lang.set('ru-RU', 'Form.Validator', { required:'Ýòî ïîëå îáÿçàòåëüíî ê çàïîëíåíèþ', minLength:'Ïîæàëóéñòà, ââåäèòå õîòÿ áû {minLength} ñèìâîëîâ (Âû ââåëè {length})', maxLength:'Ïîæàëóéñòà, ââåäèòå íå áîëüøå {maxLength} ñèìâîëîâ (Âû ââåëè {length})', integer:'Ïîæàëóéñòà, ââåäèòå â ýòî ïîëå ÷èñëî. Äðîáíûå ÷èñëà (íàïðèìåð 1.25) òóò íå ðàçðåøåíû', numeric:'Ïîæàëóéñòà, ââåäèòå â ýòî ïîëå ÷èñëî (íàïðèìåð, "1" èëè "1.1", èëè "-1", èëè "-1.1")', digits:' ýòîì ïîëå Âû ìîæåòå èñïîëüçîâàòü òîëüêî öèôðû è çíàêè ïóíêòóàöèè (íàïðèìåð, òåëåôîííûé íîìåð ñî çíàêàìè äåôèñà èëè ñ òî÷êàìè)', alpha:' ýòîì ïîëå ìîæíî èñïîëüçîâàòü òîëüêî ëàòèíñêèå áóêâû (a-z). Ïðîáåëû è äðóãèå ñèìâîëû çàïðåùåíû.', alphanum:' ýòîì ïîëå ìîæíî èñïîëüçîâàòü òîëüêî ëàòèíñêèå áóêâû (a-z) è öèôðû (0-9). Ïðîáåëû è äðóãèå ñèìâîëû çàïðåùåíû.', dateSuchAs:'Ïîæàëóéñòà, ââåäèòå êîððåêòíóþ äàòó {date}', dateInFormatMDY:'Ïîæàëóéñòà, ââåäèòå äàòó â ôîðìàòå ÌÌ.ÄÄ.ÃÃÃà (íàïðèìåð "31/12/2010")', email:'Ïîæàëóéñòà, ââåäèòå êîððåêòíûé àäðåñ ýëåêòðîííîé ïî÷òû. Äëÿ ïðèìåðà "lomonosov@yandex.ru"', url:'Ïîæàëóéñòà, ââåäèòå ïðàâèëüíóþ ññûëêó âèäà http://www.lomonosov.ru', currencyDollar:'Ïîæàëóéñòà, ââåäèòå ñóììó â äîëëàðàõ. Íàïðèìåð: $100.00.', oneRequired:'Ïîæàëóéñòà, âûáåðèòå õîòü ÷òî-íèáóäü â îäíîì èç ýòèõ ïîëåé', errorPrefix: 'Îøèáêà: ', warningPrefix: 'Âíèìàíèå: ' });/* --- script: DomReady.js description: Contains the custom event domready. license: MIT-style license. requires: - /Element.Event provides: [DomReady] ... */ Element.Events.domready = { onAdd: function(fn){ if (Browser.loaded) fn.call(this); } }; (function(){ var domready = function(){ if (Browser.loaded) return; Browser.loaded = true; window.fireEvent('domready'); document.fireEvent('domready'); }; window.addEvent('load', domready); if (Browser.Engine.trident){ var temp = document.createElement('div'); (function(){ ($try(function(){ temp.doScroll(); // Technique by Diego Perini return document.id(temp).inject(document.body).set('html', 'temp').dispose(); })) ? domready() : arguments.callee.delay(50); })(); } else if (Browser.Engine.webkit && Browser.Engine.version < 525){ (function(){ (['loaded', 'complete'].contains(document.readyState)) ? domready() : arguments.callee.delay(50); })(); } else { document.addEvent('DOMContentLoaded', domready); } })(); /* Script: Clientcide.js The Clientcide namespace. License: http://www.clientcide.com/wiki/cnet-libraries#license */ var Clientcide = { version: '%build%', assetLocation: "../images/assets", setAssetLocation: function(baseHref) { Clientcide.assetLocation = baseHref; if (Clientcide.preloaded) Clientcide.preLoadCss(); }, preLoadCss: function(){ if (window.StickyWin && StickyWin.ui) StickyWin.ui(); if (window.StickyWin && StickyWin.pointy) StickyWin.pointy(); Clientcide.preloaded = true; return true; }, preloaded: false }; (function(){ if (!window.addEvent) return; var preload = function(){ if (window.dbug) dbug.log('preloading clientcide css'); if (!Clientcide.preloaded) Clientcide.preLoadCss(); }; window.addEvent('domready', preload); window.addEvent('load', preload); })(); setCNETAssetBaseHref = Clientcide.setAssetLocation;/* Script: ToElement.js Defines the toElement method for a class. License: http://www.clientcide.com/wiki/cnet-libraries#license */ Class.ToElement = new Class({ toElement: function(){ return this.element; } }); var ToElement = Class.ToElement;/* Script: StyleWriter.js Provides a simple method for injecting a css style element into the DOM if it's not already present. License: http://www.clientcide.com/wiki/cnet-libraries#license */ var StyleWriter = new Class({ createStyle: function(css, id) { window.addEvent('domready', function(){ try { if (document.id(id) && id) return; var style = new Element('style', {id: id||''}).inject($$('head')[0]); if (Browser.Engine.trident) style.styleSheet.cssText = css; else style.set('text', css); }catch(e){dbug.log('error: %s',e);} }.bind(this)); } });/* Script: StickyWin.js Creates a div within the page with the specified contents at the location relative to the element you specify; basically an in-page popup maker. License: http://www.clientcide.com/wiki/cnet-libraries#license */ var StickyWin = new Class({ Binds: ['destroy', 'hide', 'esc'], Implements: [Options, Events, StyleWriter, Class.ToElement], options: { // onDisplay: $empty, // onClose: $empty, // onDestroy: $empty, closeClassName: 'closeSticky', pinClassName: 'pinSticky', content: '', zIndex: 10000, className: '', // id: ... set above in initialize function /* these are the defaults for Element.position anyway ************************************************ edge: false, //see Element.position position: 'center', //center, corner == upperLeft, upperRight, bottomLeft, bottomRight offset: {x:0,y:0}, relativeTo: document.body, */ width: false, height: false, timeout: -1, allowMultipleByClass: true, allowMultiple: true, showNow: true, useIframeShim: true, iframeShimSelector: '', destroyOnClose: false, closeOnClickOut: false, closeOnEsc: false, getWindowManager: function(){ return StickyWin.WM; } }, css: '.SWclearfix:after {content: "."; display: block; height: 0; clear: both; visibility: hidden;}'+ '.SWclearfix {display: inline-table;} * html .SWclearfix {height: 1%;} .SWclearfix {display: block;}', initialize: function(options){ this.options.inject = this.options.inject || { target: document.body, where: 'bottom' }; this.setOptions(options); this.windowManager = this.options.getWindowManager(); this.id = this.options.id || 'StickyWin_'+new Date().getTime(); this.makeWindow(); if (this.windowManager) this.windowManager.add(this); if (this.options.content) this.setContent(this.options.content); if (this.options.timeout > 0) { this.addEvent('onDisplay', function(){ this.hide.delay(this.options.timeout, this); }.bind(this)); } //add css for clearfix this.createStyle(this.css, 'StickyWinClearFix'); if (this.options.closeOnClickOut || this.options.closeOnEsc) this.attach(); if (this.options.destroyOnClose) this.addEvent('close', this.destroy); if (this.options.showNow) this.show(); }, attach: function(attach){ var method = $pick(attach, true) ? 'addEvents' : 'removeEvents'; var events = {}; if (this.options.closeOnClickOut) events.click = this.esc; if (this.options.closeOnEsc) events.keyup = this.esc; document[method](events); }, esc: function(e) { if (e.key == "esc") this.hide(); if (e.type == "click" && this.element != e.target && !this.element.hasChild(e.target)) this.hide(); }, makeWindow: function(){ this.destroyOthers(); if (!document.id(this.id)) { this.win = new Element('div', { id: this.id }).addClass(this.options.className).addClass('StickyWinInstance').addClass('SWclearfix').setStyles({ display:'none', position:'absolute', zIndex:this.options.zIndex }).inject(this.options.inject.target, this.options.inject.where).store('StickyWin', this); } else this.win = document.id(this.id); this.element = this.win; if (this.options.width && $type(this.options.width.toInt())=="number") this.win.setStyle('width', this.options.width.toInt()); if (this.options.height && $type(this.options.height.toInt())=="number") this.win.setStyle('height', this.options.height.toInt()); return this; }, show: function(suppressEvent){ this.showWin(); if (!suppressEvent) this.fireEvent('display'); if (this.options.useIframeShim) this.showIframeShim(); this.visible = true; return this; }, showWin: function(){ if (this.windowManager) this.windowManager.focus(this); if (!this.positioned) this.position(); this.win.show(); }, hide: function(suppressEvent){ if ($type(suppressEvent) == "event" || !suppressEvent) this.fireEvent('close'); this.hideWin(); if (this.options.useIframeShim) this.hideIframeShim(); this.visible = false; return this; }, hideWin: function(){ this.win.setStyle('display','none'); }, destroyOthers: function() { if (!this.options.allowMultipleByClass || !this.options.allowMultiple) { $$('div.StickyWinInstance').each(function(sw) { if (!this.options.allowMultiple || (!this.options.allowMultipleByClass && sw.hasClass(this.options.className))) sw.retrieve('StickyWin').destroy(); }, this); } }, setContent: function(html) { if (this.win.getChildren().length>0) this.win.empty(); if ($type(html) == "string") this.win.set('html', html); else if (document.id(html)) this.win.adopt(html); this.win.getElements('.'+this.options.closeClassName).each(function(el){ el.addEvent('click', this.hide); }, this); return this; }, position: function(options){ this.positioned = true; this.setOptions(options); this.win.position({ allowNegative: $pick(this.options.allowNegative, this.options.relativeTo != document.body), relativeTo: this.options.relativeTo, position: this.options.position, offset: this.options.offset, edge: this.options.edge }); if (this.shim) this.shim.position(); return this; }, makeIframeShim: function(){ if (!this.shim){ var el = (this.options.iframeShimSelector)?this.win.getElement(this.options.iframeShimSelector):this.win; this.shim = new IframeShim(el, { display: false, name: 'StickyWinShim' }); } }, showIframeShim: function(){ if (this.options.useIframeShim) { this.makeIframeShim(); this.shim.show(); } }, hideIframeShim: function(){ if (this.shim) this.shim.hide(); }, destroy: function(){ if (this.windowManager) this.windowManager.remove(this); if (this.win) this.win.destroy(); if (this.options.useIframeShim && this.shim) this.shim.destroy(); if (document.id('modalOverlay')) document.id('modalOverlay').destroy(); this.fireEvent('destroy'); } }); StickyWin.Stacker = new Class({ Implements: [Options, Events], Binds: ['click'], instances: [], options: { zIndexBase: 9000 }, initialize: function(options) { this.setOptions(options); this.zIndex = this.options.zIndex; }, add: function(sw) { this.instances.include(sw); $(sw).addEvent('mousedown', this.click); }, click: function(e) { this.instances.each(function(sw){ var el = $(sw); if (el == e.target || el.hasChild($(e.target))) this.focus(sw); }, this); }, focus: function(instance){ if (this.focused == instance) return; this.focused = instance; if (instance) this.instances.erase(instance).push(instance); this.instances.each(function(current, i){ $(current).setStyle('z-index', this.options.zIndexBase + i); }, this); this.focused = instance; }, remove: function(sw) { this.instances.erase(sw); $(sw).removeEvent('click', this.click); } }); StickyWin.WM = new StickyWin.Stacker();/* Script: StickyWin.Modal.js This script extends StickyWin and StickyWin.Fx classes to add Mask functionality. License: http://www.clientcide.com/wiki/cnet-libraries#license */ StickyWin.Modal = new Class({ Extends: StickyWin, options: { modalize: true, maskOptions: { style: { 'background-color':'#333', opacity:0.8 } }, hideOnClick: true, getWindowManager: function(){ return StickyWin.ModalWM; } }, initialize: function(options) { this.options.maskTarget = this.options.maskTarget || document.body; this.setOptions(options); this.mask = new Mask(this.options.maskTarget, this.options.maskOptions).addEvent('click', function() { if (this.options.hideOnClick) this.hide(); }.bind(this)); this.parent(options); }, show: function(showModal){ if ($pick(showModal, this.options.modalize)) this.mask.show(); this.parent(); }, hide: function(hideModal){ if ($pick(hideModal, true)) this.mask.hide(); this.parent(); } }); StickyWin.ModalWM = new StickyWin.Stacker({ zIndexBase: 11000 }); if (StickyWin.Fx) StickyWin.Fx.Modal = StickyWin.Modal;/* --- script: Tips.js description: Class for creating nice tips that follow the mouse cursor when hovering an element. license: MIT-style license authors: - Valerio Proietti - Christoph Pojer requires: - core:1.2.4/Options - core:1.2.4/Events - core:1.2.4/Element.Event - core:1.2.4/Element.Style - core:1.2.4/Element.Dimensions - /MooTools.More provides: [Tips] ... */ (function(){ var read = function(option, element){ return (option) ? ($type(option) == 'function' ? option(element) : element.get(option)) : ''; }; this.Tips = new Class({ Implements: [Events, Options], options: { /* onAttach: $empty(element), onDetach: $empty(element), */ onShow: function(){ this.tip.setStyle('display', 'block'); }, onHide: function(){ this.tip.setStyle('display', 'none'); }, title: 'title', text: function(element){ return element.get('rel') || element.get('href'); }, showDelay: 100, hideDelay: 100, className: 'tip-wrap', offset: {x: 16, y: 16}, windowPadding: {x:0, y:0}, fixed: false }, initialize: function(){ var params = Array.link(arguments, {options: Object.type, elements: $defined}); this.setOptions(params.options); if (params.elements) this.attach(params.elements); this.container = new Element('div', {'class': 'tip'}); }, toElement: function(){ if (this.tip) return this.tip; return this.tip = new Element('div', { 'class': this.options.className, styles: { position: 'absolute', top: 0, left: 0 } }).adopt( new Element('div', {'class': 'tip-top'}), this.container, new Element('div', {'class': 'tip-bottom'}) ).inject(document.body); }, attach: function(elements){ $$(elements).each(function(element){ var title = read(this.options.title, element), text = read(this.options.text, element); element.erase('title').store('tip:native', title).retrieve('tip:title', title); element.retrieve('tip:text', text); this.fireEvent('attach', [element]); var events = ['enter', 'leave']; if (!this.options.fixed) events.push('move'); events.each(function(value){ var event = element.retrieve('tip:' + value); if (!event) event = this['element' + value.capitalize()].bindWithEvent(this, element); element.store('tip:' + value, event).addEvent('mouse' + value, event); }, this); }, this); return this; }, detach: function(elements){ $$(elements).each(function(element){ ['enter', 'leave', 'move'].each(function(value){ element.removeEvent('mouse' + value, element.retrieve('tip:' + value)).eliminate('tip:' + value); }); this.fireEvent('detach', [element]); if (this.options.title == 'title'){ // This is necessary to check if we can revert the title var original = element.retrieve('tip:native'); if (original) element.set('title', original); } }, this); return this; }, elementEnter: function(event, element){ this.container.empty(); ['title', 'text'].each(function(value){ var content = element.retrieve('tip:' + value); if (content) this.fill(new Element('div', {'class': 'tip-' + value}).inject(this.container), content); }, this); $clear(this.timer); this.timer = (function(){ this.show(this, element); this.position((this.options.fixed) ? {page: element.getPosition()} : event); }).delay(this.options.showDelay, this); }, elementLeave: function(event, element){ $clear(this.timer); this.timer = this.hide.delay(this.options.hideDelay, this, element); this.fireForParent(event, element); }, fireForParent: function(event, element){ element = element.getParent(); if (!element || element == document.body) return; if (element.retrieve('tip:enter')) element.fireEvent('mouseenter', event); else this.fireForParent(event, element); }, elementMove: function(event, element){ this.position(event); }, position: function(event){ if (!this.tip) document.id(this); var size = window.getSize(), scroll = window.getScroll(), tip = {x: this.tip.offsetWidth, y: this.tip.offsetHeight}, props = {x: 'left', y: 'top'}, obj = {}; for (var z in props){ obj[props[z]] = event.page[z] + this.options.offset[z]; if ((obj[props[z]] + tip[z] - scroll[z]) > size[z] - this.options.windowPadding[z]) obj[props[z]] = event.page[z] - this.options.offset[z] - tip[z]; } this.tip.setStyles(obj); }, fill: function(element, contents){ if(typeof contents == 'string') element.set('html', contents); else element.adopt(contents); }, show: function(element){ if (!this.tip) document.id(this); this.fireEvent('show', [this.tip, element]); }, hide: function(element){ if (!this.tip) document.id(this); this.fireEvent('hide', [this.tip, element]); } }); })();/* --- script: Hash.Extras.js description: Extends the Hash native object to include getFromPath which allows a path notation to child elements. license: MIT-style license authors: - Aaron Newton requires: - core:1.2.4/Hash.base - /MooTools.More provides: [Hash.Extras] ... */ Hash.implement({ getFromPath: function(notation){ var source = this.getClean(); notation.replace(/\[([^\]]+)\]|\.([^.[]+)|[^[.]+/g, function(match){ if (!source) return null; var prop = arguments[2] || arguments[1] || arguments[0]; source = (prop in source) ? source[prop] : null; return match; }); return source; }, cleanValues: function(method){ method = method || $defined; this.each(function(v, k){ if (!method(v)) this.erase(k); }, this); return this; }, run: function(){ var args = arguments; this.each(function(v, k){ if ($type(v) == 'function') v.run(args); }); } });/* --- script: String.Extras.js description: Extends the String native object to include methods useful in managing various kinds of strings (query strings, urls, html, etc). license: MIT-style license authors: - Aaron Newton - Guillermo Rauch requires: - core:1.2.4/String - core:1.2.4/$util - core:1.2.4/Array provides: [String.Extras] ... */ (function(){ var tidymap = { "[\xa0\u2002\u2003\u2009]": " ", "\xb7": "*", "[\u2018\u2019]": "'", "[\u201c\u201d]": '"', "\u2026": "...", "\u2013": "-", "\u2014": "--", "\uFFFD": "»" }; var getRegForTag = function(tag, contents) { tag = tag || ''; var regstr = contents ? "<" + tag + "[^>]*>([\\s\\S]*?)<\/" + tag + ">" : "<\/?" + tag + "([^>]+)?>"; reg = new RegExp(regstr, "gi"); return reg; }; String.implement({ standardize: function(){ var text = this; return text; }, repeat: function(times){ return new Array(times + 1).join(this); }, pad: function(length, str, dir){ if (this.length >= length) return this; var pad = (str == null ? ' ' : '' + str).repeat(length - this.length).substr(0, length - this.length); if (!dir || dir == 'right') return this + pad; if (dir == 'left') return pad + this; return pad.substr(0, (pad.length / 2).floor()) + this + pad.substr(0, (pad.length / 2).ceil()); }, getTags: function(tag, contents){ return this.match(getRegForTag(tag, contents)) || []; }, stripTags: function(tag, contents){ return this.replace(getRegForTag(tag, contents), ''); }, tidy: function(){ var txt = this.toString(); $each(tidymap, function(value, key){ txt = txt.replace(new RegExp(key, 'g'), value); }); return txt; } }); })(); /* Script: StickyWin.ui.js Creates an html holder for in-page popups using a default style. License: http://www.clientcide.com/wiki/cnet-libraries#license */ StickyWin.UI = new Class({ Implements: [Options, Class.ToElement, StyleWriter], options: { width: 'auto', css: "", cssClass: '', buttons: [], cssId: 'defaultStickyWinStyle', cssClassName: 'DefaultStickyWin', closeButton: true /* These options are deprecated: closeTxt: false, onClose: $empty, confirmTxt: false, onConfirm: $empty */ }, initialize: function() { var args = this.getArgs(arguments); this.setOptions(args.options); this.legacy(); var css = this.options.css.substitute({baseHref: this.options.baseHref || Clientcide.assetLocation + '/stickyWinHTML/'}, /\\?\{%([^}]+)%\}/g); if (Browser.Engine.trident4) css = css.replace(/png/g, 'gif'); this.createStyle(css, this.options.cssId); this.build(); if (args.caption || args.body) this.setContent(args.caption, args.body); }, getArgs: function(){ return StickyWin.UI.getArgs.apply(this, arguments); }, legacy: function(){ var opt = this.options; //saving bytes //legacy support if (opt.confirmTxt) opt.buttons.push({text: opt.confirmTxt, onClick: opt.onConfirm || $empty}); if (opt.closeTxt) opt.buttons.push({text: opt.closeTxt, onClick: opt.onClose || $empty}); }, build: function(){ var opt = this.options; var container = new Element('div', { 'class': opt.cssClassName }); if (opt.width) container.setStyle('width', opt.width); this.element = container; this.element.store('StickyWinUI', this); if (opt.cssClass) container.addClass(opt.cssClass); var bodyDiv = new Element('div').addClass('body'); this.body = bodyDiv; var top_ur = new Element('div').addClass('top_ur'); this.top_ur = top_ur; this.top = new Element('div').addClass('top').adopt( new Element('div').addClass('top_ul') ).adopt(top_ur); container.adopt(this.top); //body container.adopt(new Element('div').addClass('middle').adopt(bodyDiv)); //close buttons if (opt.buttons.length > 0){ var closeButtons = new Element('div').addClass('closeButtons'); opt.buttons.each(function(button){ if (button.properties && button.properties.className){ button.properties['class'] = button.properties.className; delete button.properties.className; } var properties = $merge({'class': 'closeSticky'}, button.properties); new Element('a').addEvent('click', button.onClick || $empty) .appendText(button.text).inject(closeButtons).set(properties).addClass('button'); }); container.adopt(new Element('div').addClass('closeBody').adopt(closeButtons)); } //footer container.adopt( new Element('div').addClass('bottom').adopt( new Element('div').addClass('bottom_ll') ).adopt( new Element('div').addClass('bottom_lr') ) ); if (this.options.closeButton) container.adopt(new Element('div').addClass('closeButton').addClass('closeSticky')); return this; }, setCaption: function(caption) { this.caption = caption; if (!this.h1) { this.makeCaption(caption); } else { if (document.id(caption)) this.h1.adopt(caption); else this.h1.set('html', caption); } return this; }, makeCaption: function(caption) { if (!caption) return this.destroyCaption(); var opt = this.options; this.h1 = new Element('h1').addClass('caption'); if (opt.width) this.h1.setStyle('width', (opt.width-40-(opt.closeButton?10:0))); this.setCaption(caption); this.top_ur.adopt(this.h1); return this; }, destroyCaption: function(){ if (this.h1) { this.h1.destroy(); this.h1 = null; } return this; }, setContent: function(){ var args = this.getArgs.apply(this, arguments); var caption = args.caption; var body = args.body; this.setCaption(caption); if (document.id(body)) this.body.empty().adopt(body); else this.body.set('html', body); return this; } }); StickyWin.UI.getArgs = function(){ var input = $type(arguments[0]) == "arguments"?arguments[0]:arguments; if (Browser.Engine.presto && 1 === input.length) input = input[0]; var cap = input[0], bod = input[1]; var args = Array.link(input, {options: Object.type}); if (input.length == 3 || (!args.options && input.length == 2)) { args.caption = cap; args.body = bod; } else if (($type(bod) == 'object' || !bod) && cap && $type(cap) != 'object'){ args.body = cap; } return args; }; StickyWin.ui = function(caption, body, options){ return document.id(new StickyWin.UI(caption, body, options)); }; /* Script: StickyWin.UI.Pointy.js Creates an html holder for in-page popups using a default style - this one including a pointer in the specified direction. License: http://www.clientcide.com/wiki/cnet-libraries#license */ StickyWin.UI.Pointy = new Class({ Extends: StickyWin.UI, options: { theme: 'dark', themes: { dark: { bgColor: '#333', fgColor: '#ddd', imgset: 'dark' }, light: { bgColor: '#ccc', fgColor: '#333', imgset: 'light' } }, css: "div.DefaultPointyTip {vertical-align: auto; position: relative;}"+ "div.DefaultPointyTip * {text-align:left !important}"+ "div.DefaultPointyTip .pointyWrapper div.body{background: {%bgColor%}; color: {%fgColor%}; left: 0px; right: 0px !important;padding: 0px 10px !important;margin-left: 0px !important;font-family: verdana;font-size: 11px;line-height: 13px;position: relative;}"+ "div.DefaultPointyTip .pointyWrapper div.top {position: relative;height: 25px; overflow: visible;}"+ "div.DefaultPointyTip .pointyWrapper div.top_ul{background: url({%baseHref%}{%imgset%}_back.png) top left no-repeat;width: 8px;height: 25px; position: absolute; left: 0px;}"+ "div.DefaultPointyTip .pointyWrapper div.top_ur{background: url({%baseHref%}{%imgset%}_back.png) top right !important;margin: 0 0 0 8px !important;height: 25px;position: relative;left: 0px !important;padding: 0;}"+ "div.DefaultPointyTip .pointyWrapper h1.caption{color: {%fgColor%};left: 0px !important;top: 4px !important;clear: none !important;overflow: hidden;font-weight: 700;font-size: 12px !important;position: relative;float: left;height: 22px !important;margin: 0 !important;padding: 0 !important;}"+ "div.DefaultPointyTip .pointyWrapper div.middle, div.DefaultPointyTip .pointyWrapper div.closeBody{background: {%bgColor%};margin: 0 0px 0 0 !important;position: relative;top: 0 !important;}"+ "div.DefaultPointyTip .pointyWrapper div.bottom {clear: both; width: 100% !important; background: none; height: 6px} "+ "div.DefaultPointyTip .pointyWrapper div.bottom_ll{font-size:1; background: url({%baseHref%}{%imgset%}_back.png) bottom left no-repeat;width: 6px;height: 6px;position: absolute; left: 0px;}"+ "div.DefaultPointyTip .pointyWrapper div.bottom_lr{font-size:1; background: url({%baseHref%}{%imgset%}_back.png) bottom right;height: 6px;margin: 0 0 0 6px !important;position: relative;left: 0 !important;}"+ "div.DefaultPointyTip .pointyWrapper div.noCaption{ height: 6px; overflow: hidden}"+ "div.DefaultPointyTip .pointyWrapper div.closeButton{width:13px; height:13px; background:url({%baseHref%}{%imgset%}_x.png) no-repeat; position: absolute; right: 0px; margin:0px !important; cursor:pointer; z-index: 1; top: 4px;}"+ "div.DefaultPointyTip .pointyWrapper div.pointyDivot {background: url({%divot%}) no-repeat;}", divot: '{%baseHref%}{%imgset%}_divot.png', divotSize: 22, direction: 12, cssId: 'defaultPointyTipStyle', cssClassName: 'DefaultPointyTip' }, initialize: function() { var args = this.getArgs(arguments); this.setOptions(args.options); $extend(this.options, this.options.themes[this.options.theme]); this.options.baseHref = this.options.baseHref || Clientcide.assetLocation + '/PointyTip/'; this.options.divot = this.options.divot.substitute(this.options, /\\?\{%([^}]+)%\}/g); if (Browser.Engine.trident4) this.options.divot = this.options.divot.replace(/png/g, 'gif'); this.options.css = this.options.css.substitute(this.options, /\\?\{%([^}]+)%\}/g); if (args.options && args.options.theme) { while (!this.id) { var id = $random(0, 999999999); if (!StickyWin.UI.Pointy[id]) { StickyWin.UI.Pointy[id] = this; this.id = id; } } this.options.css = this.options.css.replace(/div\.DefaultPointyTip/g, "div#pointy_"+this.id); this.options.cssId = "pointyTipStyle_" + this.id; } if ($type(this.options.direction) == 'string') { var map = { left: 9, right: 3, up: 12, down: 6 }; this.options.direction = map[this.options.direction]; } this.parent(args.caption, args.body, this.options); if (this.id) document.id(this).set('id', "pointy_"+this.id); }, build: function(){ this.parent(); var opt = this.options; this.pointyWrapper = new Element('div', { 'class': 'pointyWrapper' }).inject(document.id(this)); document.id(this).getChildren().each(function(el){ if (el != this.pointyWrapper) this.pointyWrapper.grab(el); }, this); var w = opt.divotSize; var h = w; var left = (opt.width - opt.divotSize)/2; var orient = function(){ switch(opt.direction) { case 12: case 1: case 11: return { height: h/2 }; case 5: case 6: case 7: return { height: h/2, backgroundPosition: '0 -'+h/2+'px' }; case 8: case 9: case 10: return { width: w/2 }; case 2: case 3: case 4: return { width: w/2, backgroundPosition: '100%' }; }; }; this.pointer = new Element('div', { styles: $extend({ width: w, height: h, overflow: 'hidden' }, orient()), 'class': 'pointyDivot pointy_'+opt.direction }).inject(this.pointyWrapper); }, expose: function(){ if (document.id(this).getStyle('display') != 'none' && document.id(document.body).hasChild(document.id(this))) return $empty; document.id(this).setStyles({ visibility: 'hidden', position: 'absolute' }); var dispose; if (!document.body.hasChild(document.id(this))) { document.id(this).inject(document.body); dispose = true; } return (function(){ if (dispose) document.id(this).dispose(); document.id(this).setStyles({ visibility: 'visible', position: 'relative' }); }).bind(this); }, positionPointer: function(options){ if (!this.pointer) return; var opt = options || this.options; var pos; var d = opt.direction; switch (d){ case 12: case 1: case 11: pos = { edge: {x: 'center', y: 'bottom'}, position: { x: d==12?'center':d==1?'right':'left', y: 'top' }, offset: { x: (d==12?0:d==1?-1:1)*opt.divotSize, y: 1 } }; break; case 2: case 3: case 4: pos = { edge: {x: 'left', y: 'center'}, position: { x: 'right', y: d==3?'center':d==2?'top':'bottom' }, offset: { x: -1, y: (d==3?0:d==4?-1:1)*opt.divotSize } }; break; case 5: case 6: case 7: pos = { edge: {x: 'center', y: 'top'}, position: { x: d==6?'center':d==5?'right':'left', y: 'bottom' }, offset: { x: (d==6?0:d==5?-1:1)*opt.divotSize, y: -1 } }; break; case 8: case 9: case 10: pos = { edge: {x: 'right', y: 'center'}, position: { x: 'left', y: d==9?'center':d==10?'top':'bottom' }, offset: { x: 1, y: (d==9?0:d==8?-1:1)*opt.divotSize } }; break; }; var putItBack = this.expose(); this.pointer.position($extend({ relativeTo: this.pointyWrapper }, pos, options)); putItBack(); }, setContent: function(a1, a2){ this.parent(a1, a2); this.top[this.h1?'removeClass':'addClass']('noCaption'); if (Browser.Engine.trident4) document.id(this).getElements('.bottom_ll, .bottom_lr').setStyle('font-size', 1); //IE6 bullshit if (this.options.closeButton) this.body.setStyle('margin-right', 6); this.positionPointer(); return this; }, makeCaption: function(caption){ this.parent(caption); if (this.options.width && this.h1) this.h1.setStyle('width', (this.options.width-(this.options.closeButton?25:15))); } }); StickyWin.UI.pointy = function(caption, body, options){ return document.id(new StickyWin.UI.Pointy(caption, body, options)); }; StickyWin.ui.pointy = StickyWin.UI.pointy;/* Script: StickyWin.PointyTip.js Positions a pointy tip relative to the element you specify. License: http://www.clientcide.com/wiki/cnet-libraries#license */ StickyWin.PointyTip = new Class({ Extends: StickyWin, options: { point: "left", pointyOptions: {} }, initialize: function(){ var args = this.getArgs(arguments); this.setOptions(args.options); var popts = this.options.pointyOptions; var d = popts.direction; if (!d) { var map = { left: 9, right: 3, up: 12, down: 6 }; d = map[this.options.point]; if (!d) d = this.options.point; popts.direction = d; } if (!popts.width) popts.width = this.options.width; this.pointy = new StickyWin.UI.Pointy(args.caption, args.body, popts); this.options.content = null; this.setOptions(args.options, this.getPositionSettings()); this.parent(this.options); this.win.empty().adopt(document.id(this.pointy)); this.attachHandlers(this.win); if (this.options.showNow) this.position(); }, getArgs: function(){ return StickyWin.UI.getArgs.apply(this, arguments); }, getPositionSettings: function(){ var s = this.pointy.options.divotSize; var d = this.options.point; var offset = this.options.offset || {}; switch(d) { case "left": case 8: case 9: case 10: return { edge: { x: 'left', y: d==10?'top':d==8?'bottom':'center' }, position: {x: 'right', y: 'center'}, offset: { x: s + (offset.x || 0), y: offset.y || 0 } }; case "right": case 2: case 3: case 4: return { edge: { x: 'right', y: (d==2?'top':d==4?'bottom':'center') + (offset.y || 0) }, position: {x: 'left', y: 'center'}, offset: { x: -s + (offset.x || 0), y: offset.y || 0 } }; case "up": case 11: case 12: case 1: return { edge: { x: d==11?'left':d==1?'right':'center', y: 'top' }, position: { x: 'center', y: 'bottom' }, offset: { y: s + (offset.y || 0), x: (d==11?-s:d==1?s:0) + (offset.x || 0) } }; case "down": case 5: case 6: case 7: return { edge: { x: (d==7?'left':d==5?'right':'center') + (offset.x || 0), y: 'bottom' }, position: {x: 'center', y: 'top'}, offset: { y: -s + (offset.y || 0), x: (d==7?-s:d==5?s:0) + (offset.x || 0) } }; }; }, setContent: function() { var args = this.getArgs(arguments); this.pointy.setContent(args.caption, args.body); [this.pointy.h1, this.pointy.body].each(this.attachHandlers, this); if (this.visible) this.position(); return this; }, showWin: function(){ this.parent(); this.pointy.positionPointer(); }, position: function(options){ this.parent(options); this.pointy.positionPointer(); }, attachHandlers: function(content) { if (!content) return; content.getElements('.'+this.options.closeClassName).addEvent('click', function(){ this.hide(); }.bind(this)); } });/* Script: Tips.Pointy.js Defines Tips.Pointy, An extension to Tips that adds a pointy style to the tip. License: http://www.clientcide.com/wiki/cnet-libraries#license */ Tips.Pointy = new Class({ Extends: Tips, options: { onShow: function(tip, stickyWin){ stickyWin.show(); }, onHide: function(tip, stickyWin){ stickyWin.hide(); }, pointyTipOptions: { point: 11, width: 150, pointyOptions: { closeButton: false } } }, initialize: function(){ var params = Array.link(arguments, {options: Object.type, elements: $defined}); this.setOptions(params.options); this.tip = new StickyWin.PointyTip($extend(this.options.pointyTipOptions, { showNow: false })); if (this.options.className) document.id(this.tip).addClass(this.options.className); if (params.elements) this.attach(params.elements); }, elementEnter: function(event, element){ var title = '';//element.retrieve('tip:title'); var text = element.retrieve('tip:title');//element.retrieve('tip:text'); if(text.length > 200) { text = text.substr(0, 200) + '...'; } this.tip.setContent(title, text); this.timer = $clear(this.timer); this.timer = this.show.delay(this.options.showDelay, this); this.position(element); }, elementLeave: function(event){ $clear(this.timer); this.timer = this.hide.delay(this.options.hideDelay, this); }, elementMove: function(event){ return; //always fixed }, position: function(element){ this.tip.setOptions({ relativeTo: element }); this.tip.position(); }, show: function(){ this.fireEvent('show', [document.id(this.tip), this.tip]); }, hide: function(){ this.fireEvent('hide', [document.id(this.tip), this.tip]); } });/* --- script: Fx.Morph.js description: Formerly Fx.Styles, effect to transition any number of CSS properties for an element using an object of rules, or CSS based selector rules. license: MIT-style license. requires: - /Fx.CSS provides: [Fx.Morph] ... */ Fx.Morph = new Class({ Extends: Fx.CSS, initialize: function(element, options){ this.element = this.subject = document.id(element); this.parent(options); }, set: function(now){ if (typeof now == 'string') now = this.search(now); for (var p in now) this.render(this.element, p, now[p], this.options.unit); return this; }, compute: function(from, to, delta){ var now = {}; for (var p in from) now[p] = this.parent(from[p], to[p], delta); return now; }, start: function(properties){ if (!this.check(properties)) return this; if (typeof properties == 'string') properties = this.search(properties); var from = {}, to = {}; for (var p in properties){ var parsed = this.prepare(this.element, p, properties[p]); from[p] = parsed.from; to[p] = parsed.to; } return this.parent(from, to); } }); Element.Properties.morph = { set: function(options){ var morph = this.retrieve('morph'); if (morph) morph.cancel(); return this.eliminate('morph').store('morph:options', $extend({link: 'cancel'}, options)); }, get: function(options){ if (options || !this.retrieve('morph')){ if (options || !this.retrieve('morph:options')) this.set('morph', options); this.store('morph', new Fx.Morph(this, this.retrieve('morph:options'))); } return this.retrieve('morph'); } }; Element.implement({ morph: function(props){ this.get('morph').start(props); return this; } }); /* name: TabSwapper.js description: Handles the scripting for a common UI layout; the tabbed box. License: http://www.clientcide.com/wiki/cnet-libraries#license requires: - core: Element.Event, Fx.Tween, Fx.Morph - more: Element.Shortcuts, Element.Dimensions, Element.Measure */ var TabSwapper = new Class({ Implements: [Options, Events], options: { action: 'click', selectedClass: 'active', mouseoverClass: 'over', deselectedClass: '', rearrangeDOM: true, initPanel: 0, smooth: false, smoothSize: false, maxSize: null, effectOptions: { duration:0 }, cookieName: null, cookieDays: 999 // onActive: $empty, // onActiveAfterFx: $empty, // onBackground: $empty }, tabs: [], sections: [], clickers: [], sectionFx: [], initialize: function(options){ this.setOptions(options); var prev = this.setup(); if (prev) return prev; if (this.options.cookieName && this.recall()) this.show(this.recall().toInt()); else this.show(this.options.initPanel); }, setup: function(){ var opt = this.options; var sections = $$(opt.sections); var tabs = $$(opt.tabs); if (tabs[0] && tabs[0].retrieve('tabSwapper')) return tabs[0].retrieve('tabSwapper'); clickers = $$(opt.clickers); tabs.each(function(tab, index){ this.addTab(tab, sections[index], clickers[index], index); }, this); }, addTab: function(tab, section, clicker, index){ tab = document.id(tab); clicker = document.id(clicker); section = document.id(section); //if the tab is already in the interface, just move it if (this.tabs.indexOf(tab) >= 0 && tab.retrieve('tabbered') && this.tabs.indexOf(tab) != index && this.options.rearrangeDOM) { this.moveTab(this.tabs.indexOf(tab), index); return this; } //if the index isn't specified, put the tab at the end if (!$defined(index)) index = this.tabs.length; //if this isn't the first item, and there's a tab //already in the interface at the index 1 less than this //insert this after that one if (index > 0 && this.tabs[index-1] && this.options.rearrangeDOM) { tab.inject(this.tabs[index-1], 'after'); section.inject(this.tabs[index-1].retrieve('section'), 'after'); } this.tabs.splice(index, 0, tab); clicker = clicker || tab; tab.addEvents({ mouseout: function(){ tab.removeClass(this.options.mouseoverClass); }.bind(this), mouseover: function(){ tab.addClass(this.options.mouseoverClass); }.bind(this) }); clicker.addEvent(this.options.action, function(e){ e.preventDefault(); this.show(index); }.bind(this)); tab.store('tabbered', true); tab.store('section', section); tab.store('clicker', clicker); this.hideSection(index); return this; }, removeTab: function(index){ var now = this.tabs[this.now]; if (this.now == index){ if (index > 0) this.show(index - 1); else if (index < this.tabs.length) this.show(index + 1); } this.now = this.tabs.indexOf(now); return this; }, moveTab: function(from, to){ var tab = this.tabs[from]; var clicker = tab.retrieve('clicker'); var section = tab.retrieve('section'); var toTab = this.tabs[to]; var toClicker = toTab.retrieve('clicker'); var toSection = toTab.retrieve('section'); this.tabs.erase(tab).splice(to, 0, tab); tab.inject(toTab, 'before'); clicker.inject(toClicker, 'before'); section.inject(toSection, 'before'); return this; }, show: function(i){ if (!$chk(this.now)) { this.tabs.each(function(tab, idx){ if (i != idx) this.hideSection(idx); }, this); } this.showSection(i).save(i); return this; }, save: function(index){ if (this.options.cookieName) Cookie.write(this.options.cookieName, index, {duration:this.options.cookieDays}); return this; }, recall: function(){ return (this.options.cookieName)?$pick(Cookie.read(this.options.cookieName), false): false; }, hideSection: function(idx) { var tab = this.tabs[idx]; if (!tab) return this; var sect = tab.retrieve('section'); if (!sect) return this; if (sect.getStyle('display') != 'none') { this.lastHeight = sect.getSize().y; sect.setStyle('display', 'none'); tab.swapClass(this.options.selectedClass, this.options.deselectedClass); this.fireEvent('onBackground', [idx, sect, tab]); } return this; }, showSection: function(idx) { var tab = this.tabs[idx]; if (!tab) return this; var sect = tab.retrieve('section'); if (!sect) return this; var smoothOk = this.options.smooth && !Browser.Engine.trident4; if (this.now != idx) { if (!tab.retrieve('tabFx')) tab.store('tabFx', new Fx.Morph(sect, this.options.effectOptions)); var overflow = sect.getStyle('overflow'); var start = { display:'block', overflow: 'hidden' }; if (smoothOk) start.opacity = 0; var effect = false; if (smoothOk) { effect = {opacity: 1}; } else if (sect.getStyle('opacity').toInt() < 1) { sect.setStyle('opacity', 1); if (!this.options.smoothSize) this.fireEvent('onActiveAfterFx', [idx, sect, tab]); } if (this.options.smoothSize) { var size = sect.getDimensions().height; if ($chk(this.options.maxSize) && this.options.maxSize < size) size = this.options.maxSize; if (!effect) effect = {}; effect.height = size; } if ($chk(this.now)) this.hideSection(this.now); if (this.options.smoothSize && this.lastHeight) start.height = this.lastHeight; sect.setStyles(start); if (effect) { tab.retrieve('tabFx').start(effect).chain(function(){ this.fireEvent('onActiveAfterFx', [idx, sect, tab]); sect.setStyles({ height: this.options.maxSize == effect.height ? this.options.maxSize : "auto", overflow: overflow }); sect.getElements('input, textarea').setStyle('opacity', 1); }.bind(this)); } this.now = idx; this.fireEvent('onActive', [idx, sect, tab]); } tab.swapClass(this.options.deselectedClass, this.options.selectedClass); return this; } }); StickyWin.Fx = StickyWin;/* Script: DatePicker.js Allows the user to enter a date in many popuplar date formats or choose from a calendar. License: http://www.clientcide.com/wiki/cnet-libraries#license */ var DatePicker; (function(){ var DPglobal = function() { if (DatePicker.pickers) return; DatePicker.pickers = []; DatePicker.hideAll = function(){ DatePicker.pickers.each(function(picker){ picker.hide(); }); }; }; DatePicker = new Class({ Implements: [Options, Events, StyleWriter], options: { format: "%x", defaultCss: 'div.calendarHolder {height:177px;position: absolute;top: -21px !important;top: -27px;left: -3px;width: 100%;}'+ 'div.calendarHolder table.cal {margin-right: 15px !important;margin-right: 8px;width: 205px;}'+ 'div.calendarHolder td {text-align:center;}'+ 'div.calendarHolder tr.dayRow td {padding: 2px;width: 22px;cursor: pointer;}'+ 'div.calendarHolder table.datePicker * {font-size:11px;line-height:16px;}'+ 'div.calendarHolder table.datePicker {margin: 0;padding:0 5px;float: left;}'+ 'div.calendarHolder table.datePicker table.cal td {cursor:pointer;}'+ 'div.calendarHolder tr.dateNav {font-weight: bold;height:22px;margin-top:8px;}'+ 'div.calendarHolder tr.dayNames {height: 23px;}'+ 'div.calendarHolder tr.dayNames td {color:#666;font-weight:700;border-bottom:1px solid #ddd;}'+ 'div.calendarHolder table.datePicker tr.dayRow td:hover {background:#ccc;}'+ 'div.calendarHolder table.datePicker tr.dayRow td {margin: 1px;}'+ 'div.calendarHolder td.today {color:#bb0904;}'+ 'div.calendarHolder td.otherMonthDate {border:1px solid #fff;color:#ccc;background:#f3f3f3 !important;margin: 0px !important;}'+ 'div.calendarHolder td.selectedDate {border: 1px solid #20397b;background:#dcddef;margin: 0px !important;}'+ 'div.calendarHolder a.leftScroll, div.calendarHolder a.rightScroll {cursor: pointer; color: #000}'+ 'div.datePickerSW div.body {height: 160px !important;height: 149px;}'+ 'div.datePickerSW .clearfix:after {content: ".";display: block;height: 0;clear: both;visibility: hidden;}'+ 'div.datePickerSW .clearfix {display: inline-table;}'+ '* html div.datePickerSW .clearfix {height: 1%;}'+ 'div.datePickerSW .clearfix {display: block;}', calendarId: false, stickyWinOptions: { position: "bottomLeft", offset: {x:10, y:10}, fadeDuration: 400 }, stickyWinUiOptions: {}, updateOnBlur: true, additionalShowLinks: [], showOnInputFocus: true, useDefaultCss: true, hideCalendarOnPick: true, weekStartOffset: 1, showMoreThanOne: true, stickyWinToUse: StickyWin /* onPick: $empty, onShow: $empty, onHide: $empty */ }, initialize: function(input, options){ DPglobal(); //make sure controller is setup if (document.id(input)) this.inputs = $H({start: document.id(input)}); this.today = new Date(); this.setOptions(options); if (this.options.useDefaultCss) this.createStyle(this.options.defaultCss, 'datePickerStyle'); if (!this.inputs) return; this.whens = this.whens || ['start']; if (!this.calendarId) this.calendarId = "popupCalendar" + new Date().getTime(); this.setUpObservers(); this.getCalendar(); this.formValidatorInterface(); DatePicker.pickers.push(this); }, formValidatorInterface: function(){ this.inputs.each(function(input){ var props; if (input.get('validatorProps')) props = input.get('validatorProps'); if (props && props.dateFormat) { dbug.log('using date format specified in validatorProps property of element to play nice with Form.Validator'); this.setOptions({ format: props.dateFormat }); } else { if (!props) props = {}; props.dateFormat = this.options.format; input.set('validatorProps', props); } }, this); }, calWidth: 280, inputDates: {}, selectedDates: {}, setUpObservers: function(){ this.inputs.each(function(input) { if (this.options.showOnInputFocus) input.addEvent('focus', this.show.bind(this)); input.addEvent('blur', function(e){ if (e) { this.selectedDates = this.getDates(null, true); this.fillCalendar(this.selectedDates.start); if (this.options.updateOnBlur) this.updateInput(); } }.bind(this)); }, this); this.options.additionalShowLinks.each(function(lnk){ document.id(lnk).addEvent('click', this.show.bind(this)); }, this); }, getDates: function(dates, getFromInputs){ var d = {}; if (!getFromInputs) dates = dates||this.selectedDates; var getFromInput = function(when){ var input = this.inputs.get(when); if (input) d[when] = this.validDate(input.get('value')); }.bind(this); this.whens.each(function(when) { switch($type(dates)){ case "object": if (dates) d[when] = dates[when]?dates[when]:dates; if (!d[when] && !d[when].format) getFromInput(when); break; default: getFromInput(when); break; } if (!d[when]) d[when] = this.selectedDates[when]||new Date(); }, this); return d; }, updateInput: function(){ var d = {}; $each(this.getDates(), function(value, key){ var input = this.inputs.get(key); if (!input) return; input.set('value', (value)?this.formatDate(value)||"":""); }, this); return this; }, validDate: function(val) { if (!$chk(val)) return null; var date = Date.parse(val.trim()); return isNaN(date)?null:date; }, formatDate: function (date) { return date.format(this.options.format); }, getCalendar: function() { if (!this.calendar) { var cal = new Element("table", { 'id': this.options.calendarId || '', 'border':'0', 'cellpadding':'0', 'cellspacing':'0', 'class':'datePicker' }); var tbody = new Element('tbody').inject(cal); var rows = []; (8).times(function(i){ var row = new Element('tr').inject(tbody); (7).times(function(i){ var td = new Element('td').inject(row).set('html', ' '); }); }); rows = tbody.getElements('tr'); rows[0].addClass('dateNav'); rows[1].addClass('dayNames'); (6).times(function(i){ rows[i+2].addClass('dayRow'); }); this.rows = rows; var dayCells = rows[1].getElements('td'); dayCells.each(function(cell, i){ cell.firstChild.data = Date.getMsg('days')[(i + this.options.weekStartOffset) % 7].substring(0,3); }, this); [6,5,4,3].each(function(i){ rows[0].getElements('td')[i].dispose(); }); this.prevLnk = rows[0].getElement('td').setStyle('text-align', 'right'); this.prevLnk.adopt(new Element('a').set('html', "<").addClass('rightScroll')); this.month = rows[0].getElements('td')[1]; this.month.set('colspan', 5); this.nextLnk = rows[0].getElements('td')[2].setStyle('text-align', 'left'); this.nextLnk.adopt(new Element('a').set('html', '>').addClass('leftScroll')); cal.addEvent('click', this.clickCalendar.bind(this)); this.calendar = cal; this.container = new Element('div').adopt(cal).addClass('calendarHolder'); this.content = StickyWin.ui('', this.container, $merge(this.options.stickyWinUiOptions, { width: this.calWidth })); var opts = $merge(this.options.stickyWinOptions, { content: this.content, className: 'datePickerSW', allowMultipleByClass: true, showNow: false, relativeTo: this.inputs.get('start') }); this.stickyWin = new this.options.stickyWinToUse(opts); this.stickyWin.addEvent('onDisplay', this.positionClose.bind(this)); } return this.calendar; }, positionClose: function(){ if (this.closePositioned) return; var closer = this.content.getElement('div.closeButton'); if (closer) { closer.inject(this.container, 'after').setStyle('z-index', this.stickyWin.win.getStyle('z-index').toInt()+2); (function(){ this.content.setStyle('width', this.calendar.getSize().x + (this.options.time ? 240 : 40)); closer.position({relativeTo: this.stickyWin.win.getElement('.top'), position: 'upperRight', edge: 'upperRight'}); }).delay(3, this); } this.closePositioned = true; }, hide: function(){ this.stickyWin.hide(); this.fireEvent('onHide'); return this; }, hideOthers: function(){ DatePicker.pickers.each(function(picker){ if (picker != this) picker.hide(); }); return this; }, show: function(){ this.selectedDates = {}; var dates = this.getDates(null, true); this.whens.each(function(when){ this.inputDates[when] = dates[when]?dates[when].clone():dates.start?dates.start.clone():this.today; this.selectedDates[when] = !this.inputDates[when] || isNaN(this.inputDates[when]) ? this.today : this.inputDates[when].clone(); this.getCalendar(when); }, this); this.fillCalendar(this.selectedDates.start); if (!this.options.showMoreThanOne) this.hideOthers(); this.stickyWin.show(); this.fireEvent('onShow'); return this; }, handleScroll: function(e){ if (e.target.hasClass('rightScroll')||e.target.hasClass('leftScroll')) { var newRef = e.target.hasClass('rightScroll') ?this.rows[2].getElement('td').refDate - Date.units.day() :this.rows[7].getElements('td')[6].refDate + Date.units.day(); this.fillCalendar(new Date(newRef)); return true; } return false; }, setSelectedDates: function(e, newDate){ this.selectedDates.start = newDate; }, onPick: function(){ this.updateSelectors(); this.inputs.each(function(input) { input.fireEvent("change"); input.fireEvent("blur"); }); this.fireEvent('onPick'); if (this.options.hideCalendarOnPick) this.hide(); }, clickCalendar: function(e) { if (this.handleScroll(e)) return; if (!e.target.firstChild || !e.target.firstChild.data) return; var val = e.target.firstChild.data; if (e.target.refDate) { var newDate = new Date(e.target.refDate); this.setSelectedDates(e, newDate); this.updateInput(); this.onPick(); } }, fillCalendar: function (date) { if ($type(date) == "string") date = new Date(date); var startDate = (date)?new Date(date.getTime()):new Date(); var hours = startDate.get('hours'); startDate.setDate(1); var startDay = startDate.getDay( ); //line added if ( startDay < this.options.weekStartOffset ) startDay += 7; //line added startDate.setTime((startDate.getTime() - (Date.units.day() * (startDay))) + (Date.units.day() * this.options.weekStartOffset)); var monthyr = new Element('span', { html: Date.getMsg('months')[date.getMonth()] + " " + date.getFullYear() }); document.id(this.rows[0].getElements('td')[1]).empty().adopt(monthyr); var atDate = startDate.clone(); this.rows.each(function(row, i){ if (i < 2) return; row.getElements('td').each(function(td){ atDate.set('hours', hours); td.firstChild.data = atDate.getDate(); td.refDate = atDate.getTime(); atDate.setTime(atDate.getTime() + Date.units.day()); }, this); }, this); this.updateSelectors(); }, updateSelectors: function(){ var atDate; var month = new Date(this.rows[5].getElement('td').refDate).getMonth(); this.rows.each(function(row, i){ if (i < 2) return; row.getElements('td').each(function(td){ td.className = ''; atDate = new Date(td.refDate); if (atDate.format("%x") == this.today.format("%x")) td.addClass('today'); this.whens.each(function(when){ var date = this.selectedDates[when]; if (date && atDate.format("%x") == date.format("%x")) { td.addClass('selectedDate'); this.fireEvent('selectedDateMatch', [td, when]); } }, this); this.fireEvent('rowDateEvaluated', [atDate, td]); if (atDate.getMonth() != month) td.addClass('otherMonthDate'); atDate.setTime(atDate.getTime() + Date.units.day()); }, this); }, this); } }); })();/* --- script: Form.Validator.Inline.js description: Extends Form.Validator to add inline messages. license: MIT-style license authors: - Aaron Newton requires: - /Form.Validator provides: [Form.Validator.Inline] ... */ Form.Validator.Inline = new Class({ Extends: Form.Validator, options: { scrollToErrorsOnSubmit: true, scrollFxOptions: { transition: 'quad:out', offset: { y: -20 } } }, initialize: function(form, options){ this.parent(form, options); this.addEvent('onElementValidate', function(isValid, field, className, warn){ var validator = this.getValidator(className); if (!isValid && validator.getError(field)){ if (warn) field.addClass('warning'); var advice = this.makeAdvice(className, field, validator.getError(field), warn); this.insertAdvice(advice, field); this.showAdvice(className, field); } else { this.hideAdvice(className, field); } }); }, makeAdvice: function(className, field, error, warn){ var errorMsg = (warn)?this.warningPrefix:this.errorPrefix; errorMsg += (this.options.useTitles) ? field.title || error:error; var cssClass = (warn) ? 'warning-advice' : 'validation-advice'; var advice = this.getAdvice(className, field); if(advice) { advice = advice.set('html', errorMsg); } else { advice = new Element('div', { html: errorMsg, styles: { display: 'none' }, id: 'advice-' + className + '-' + this.getFieldId(field) }).addClass(cssClass); } field.store('advice-' + className, advice); return advice; }, getFieldId : function(field){ return field.id ? field.id : field.id = 'input_' + field.name; }, showAdvice: function(className, field){ var advice = this.getAdvice(className, field); if (advice && !field.retrieve(this.getPropName(className)) && (advice.getStyle('display') == 'none' || advice.getStyle('visiblity') == 'hidden' || advice.getStyle('opacity') == 0)){ field.store(this.getPropName(className), true); if (advice.reveal) advice.reveal(); else advice.setStyle('display', 'block'); } }, hideAdvice: function(className, field){ var advice = this.getAdvice(className, field); if (advice && field.retrieve(this.getPropName(className))){ field.store(this.getPropName(className), false); //if Fx.Reveal.js is present, transition the advice out if (advice.dissolve) advice.dissolve(); else advice.setStyle('display', 'none'); } }, getPropName: function(className){ return 'advice' + className; }, resetField: function(field){ field = document.id(field); if (!field) return this; this.parent(field); field.className.split(' ').each(function(className){ this.hideAdvice(className, field); }, this); return this; }, getAllAdviceMessages: function(field, force){ var advice = []; if (field.hasClass('ignoreValidation') && !force) return advice; var validators = field.className.split(' ').some(function(cn){ var warner = cn.test('^warn-') || field.hasClass('warnOnly'); if (warner) cn = cn.replace(/^warn-/, ''); var validator = this.getValidator(cn); if (!validator) return; advice.push({ message: validator.getError(field), warnOnly: warner, passed: validator.test(), validator: validator }); }, this); return advice; }, getAdvice: function(className, field){ return field.retrieve('advice-' + className); }, insertAdvice: function(advice, field){ //Check for error position prop var props = field.get('validatorProps'); //Build advice if (!props.msgPos || !document.id(props.msgPos)){ if(field.type.toLowerCase() == 'radio') field.getParent().adopt(advice); else advice.inject(document.id(field), 'after'); } else { document.id(props.msgPos).grab(advice); } }, validateField: function(field, force){ var result = this.parent(field, force); if (this.options.scrollToErrorsOnSubmit && !result){ var failed = document.id(this).getElement('.validation-failed'); var par = document.id(this).getParent(); while (par != document.body && par.getScrollSize().y == par.getSize().y){ par = par.getParent(); } var fx = par.retrieve('fvScroller'); if (!fx && window.Fx && Fx.Scroll){ fx = new Fx.Scroll(par, this.options.scrollFxOptions); par.store('fvScroller', fx); } if (failed){ if (fx) fx.toElement(failed); else par.scrollTo(par.getScroll().x, failed.getPosition(par).y - 20); } } return result; } }); Form.Validator.Tips = new Class({ Extends: Form.Validator.Inline, options: { pointyTipOptions: { point: "left", width: 250 } // tipCaption: '' }, showAdvice: function(className, field){ var advice = this.getAdvice(field); if (advice && !advice.visible){ advice.show(); advice.position(); advice.pointy.positionPointer(); } }, hideAdvice: function(className, field){ var advice = this.getAdvice(field); if (advice && advice.visible) advice.show(); }, getAdvice: function(className, field) { var params = Array.link(arguments, {field: Element.type}); return params.field.retrieve('PointyTip'); }, advices: [], makeAdvice: function(className, field, error, warn){ if (!error && !warn) return; var advice = field.retrieve('PointyTip'); if (!advice){ var cssClass = warn?'warning-advice':'validation-advice'; var msg = new Element('ul', { styles: { margin: 0, padding: 0, listStyle: 'none' } }); var li = this.makeAdviceItem(className, field); if (li) msg.adopt(li); field.store('validationMsgs', msg); advice = new StickyWin.PointyTip(this.options.tipCaption, msg, $merge(this.options.pointyTipOptions, { showNow: false, relativeTo: field, inject: { target: this.element } })); this.advices.push(advice); advice.msgs = {}; field.store('PointyTip', advice); document.id(advice).addClass(cssClass).set('id', 'advice-'+className+'-'+this.getFieldId(field)); } field.store('advice-'+className, advice); this.appendAdvice(className, field, error, warn); advice.pointy.positionPointer(); return advice; }, validateField: function(field, force){ var advice = this.getAdvice(field); var anyVis = this.advices.some(function(a){ return a.visible; }); if (anyVis && this.options.serial) { if (advice && advice.visible) { var passed = this.parent(field, force); if (!field.hasClass('validation-failed')) advice.hide(); } return passed; } var msgs = field.retrieve('validationMsgs'); if (msgs) msgs.getChildren().hide(); if ((field.hasClass('validation-failed') || field.hasClass('warning')) && advice) advice.show(); if (this.options.serial) { var fields = this.element.getElements('.validation-failed, .warning'); if (fields.length) { fields.each(function(f, i) { var adv = this.getAdvice(f); if (adv) adv.hide(); }, this); } } return this.parent(field, force); }, makeAdviceItem: function(className, field, error, warn){ if (!error && !warn) return; var advice = this.getAdvice(field); var errorMsg = this.makeAdviceMsg(field, error, warn); if (advice && advice.msgs[className]) return advice.msgs[className].set('html', errorMsg); return new Element('li', { html: errorMsg, style: { display: 'none' } }); }, makeAdviceMsg: function(field, error, warn){ var errorMsg = (warn)?this.warningPrefix:this.errorPrefix; errorMsg += (this.options.useTitles) ? field.title || error:error; return errorMsg; }, appendAdvice: function(className, field, error, warn) { var advice = this.getAdvice(field); if (advice.msgs[className]) return advice.msgs[className].set('html', this.makeAdviceMsg(field, error, warn)).show(); var li = this.makeAdviceItem(className, field, error, warn); if (!li) return; li.inject(field.retrieve('validationMsgs')).show(); advice.msgs[className] = li; }, insertAdvice: function(advice, field){ //Check for error position prop var props = field.get('validatorProps'); //Build advice if (!props.msgPos || !document.id(props.msgPos)) { switch (field.type.toLowerCase()) { case 'radio': var p = field.getParent().adopt(advice); break; default: document.id(advice).inject(document.id(field), 'after'); }; } else { document.id(props.msgPos).grab(advice); } advice.position(); } }); if (window.FormValidator) FormValidator.Tips = Form.Validator.Tips; /* Author: luistar15, updated by Konstantin Konovalov, (mousewheel, visible items num, loop) License: MIT License Class noobSlide (rev.08-12-08) Arguments: Parameters - see Parameters below Parameters: box: dom element | required items: dom collection | required size: int | item size (px) | default: 240 visible: int | items into viewport | default: 1 mode: string | 'horizontal', 'vertical' | default: 'horizontal' addButtons:{ previous: single dom element OR dom collection| default: null next: single dom element OR dom collection | default: null play: single dom element OR dom collection | default: null playback: single dom element OR dom collection | default: null stop: single dom element OR dom collection | default: null } mouseWheel: boolean | enable mousewheel support, when cursor is over this.box | default: false loop: boolean | enable walking from last to first item | default: true button_event: string | event type | default: 'click' handles: dom collection | default: null handle_event: string | event type| default: 'click' fxOptions: object | Fx.Tween options | default: {duration:500,wait:false} interval: int | for periodical | default: 5000 autoPlay: boolean | default: false onWalk: event | pass arguments: currentItem, currentHandle | default: null startItem: int | default: 0 Properties: box: dom element items: dom collection size: int mode: string buttons: object button_event: string handles: dom collection handle_event: string previousIndex: int nextIndex: int fx: Fx.Tween instance interval: int autoPlay: boolean onWalk: function Methods: previous(manual): walk to previous item manual: bolean | default:false next(manual): walk to next item manual: bolean | default:false play (interval,direction,wait): auto walk items interval: int | required direction: string | "previous" or "next" | required wait: boolean | required stop(): stop auto walk walk(item,manual,noFx): walk to item item: int | required manual: bolean | default:false noFx: boolean | default:false addHandleButtons(handles): handles: dom collection | required addActionButtons(action,buttons): action: string | "previous", "next", "play", "playback", "stop" | required buttons: dom collection | required Requires: mootools 1.2 core */ var noobSlide = new Class({ initialize: function(params) { this.items = params.items; this.loop = params.loop; this.mode = params.mode || 'horizontal'; this.modes = {horizontal:['left','width'], vertical:['top','height']}; this.box = params.box; this.visible = params.visible || 1; this.size = params.size || (this.box.getParent().getSize().x / this.visible).toInt() || 250; this.box.setStyle(this.modes[this.mode][1], (this.size * this.items.length) + 'px'); this.items.each(function(item) { item.setStyle('width', this.size); }, this); this.button_event = params.button_event || 'click'; this.handle_event = params.handle_event || 'click'; this.onWalk = params.onWalk || $empty; this.currentIndex = null; this.previousIndex = null; this.nextIndex = null; this.interval = params.interval || 5000; this.autoPlay = params.autoPlay || false; this._play = null; this.handles = params.handles || null; if(this.handles) { this.addHandleButtons(this.handles); } this.buttons = { previous: [], next: [], play: [], playback: [], stop: [] }; if(params.mouseWheel) { $(this.box).addEvent('mousewheel', function(event) { event = new Event(event); if(event.wheel > 0) { this.previous(); } else if (event.wheel < 0) { this.next(); } return false; }.bind(this)); } if(params.addButtons) { for(var action in params.addButtons) { this.addActionButtons(action, $type(params.addButtons[action])=='array' ? params.addButtons[action] : [params.addButtons[action]]); } } this.fx = new Fx.Tween(this.box, $extend((params.fxOptions || {duration: 500, wait: false}), {property: this.modes[this.mode][0]})); this.walk(params.startItem || 0, true, true); }, addHandleButtons: function(handles) { handles.each(function(item) { item.addEvent(this.handle_event, this.walk.bind(this, [i, true])); }, this); }, addActionButtons: function(action, buttons) { for(var i = 0, l = buttons.length; i < l; i++) { switch(action) { case 'previous': buttons[i].addEvent(this.button_event, this.previous.bind(this, [true])); break; case 'next': buttons[i].addEvent(this.button_event, this.next.bind(this, [true])); break; case 'play': buttons[i].addEvent(this.button_event, this.play.bind(this, [this.interval, 'next', false])); break; case 'playback': buttons[i].addEvent(this.button_event, this.play.bind(this, [this.interval, 'previous', false])); break; case 'stop': buttons[i].addEvent(this.button_event, this.stop.bind(this)); break; } this.buttons[action].push(buttons[i]); } }, previous: function(manual) { this.walk(this.previousIndex, manual); return false; }, next: function(manual) { this.walk(this.nextIndex, manual); return false; }, play: function(interval, direction, wait) { this.stop(); if(!wait) { this[direction](false); } this._play = this[direction].periodical(interval, this, [false]); }, stop: function() { $clear(this._play); }, walk: function(item, manual, noFx) { if(item != this.currentIndex) { this.fx.cancel(); this.currentIndex = item; this.previousIndex = this.currentIndex > 0 ? this.currentIndex - 1 : (this.loop ? this.items.length - this.visible : this.currentIndex); this.nextIndex = this.currentIndex < this.items.length - this.visible ? this.currentIndex + 1 : (this.loop ? 0 : this.currentIndex); this.buttons.previous.each(function(item) { item[this.currentIndex == 0 ? 'addClass' : 'removeClass']('passive'); }, this); this.buttons.next.each(function(item) { item[this.currentIndex == this.nextIndex ? 'addClass' : 'removeClass']('passive'); }, this); if(manual) { this.stop(); } if(noFx) { this.fx.cancel().set(this.size*-this.currentIndex); } else { this.fx.start(this.size*-this.currentIndex); } if(manual && this.autoPlay) { this.play(this.interval, 'next', true); } if(this.onWalk) { this.onWalk((this.items[this.currentIndex] || null), (this.handles && this.handles[this.currentIndex] ? this.handles[this.currentIndex] : null)); } } } }); /* License: MIT-style license. Copyright: Copyright (c) 2009 Konstantin Konovalov (http://clproject.info/). */ var togglePreviewKeydown = function(event) { // esc if([27].contains(event.code)) { document.togglePreview(); } // ctrl + p if(event.control && [80].contains(event.code)) { document.togglePreview(); } } document.togglePreview = function() { $$('link').filter(function(item) { return item.get('rel') == 'stylesheet'; }).each(function(item) { if(item.get('media') == 'print') { item.set({ 'media': 'all', 'kill': true }); } else if(item.get('kill')) { item.set({ 'media': 'print', 'kill': false }); } //Firefox 2 does not apply media change if(Browser.Engine.gecko && Browser.Engine.version <= 18 && item.get('kill')) { var split = '?'; if(item.get('href').indexOf(split) > 0) { split = '&'; } item.set('href', item.get('href') + split + Math.random()); } }); var closePreview = $('closepreview'); var fn = 'addEvent'; if(closePreview) { if(closePreview.getStyle('display') == 'none') { closePreview.setStyle('display', ''); } else { closePreview.setStyle('display', 'none'); fn = 'removeEvent'; } } else { var h1 = new Element('h1', { 'text': 'Âåðñèÿ äëÿ ïå÷àòè' }); var print = new Element('input', { 'type': 'button', 'value': 'Ïå÷àòàòü', 'title': 'ctrl + p', 'events': { 'click': function() { document.togglePreview(); window.print(); } } }).addClass('submit'); var close = new Element('input', { 'type': 'button', 'value': 'Çàêðûòü', 'title': 'Esc', 'events': { 'click': document.togglePreview } }).addClass('submit'); var div = new Element('div', { 'id': 'closepreview' }); div.adopt(h1.adopt(print, close)).inject($(document.body), 'top'); } window.scrollTo(0, 0); document[fn]('keydown', togglePreviewKeydown); } /* License: MIT-style license. Copyright: Copyright (c) 2009 Konstantin Konovalov (http://clproject.info/). */ var Bookmarks = new Class({ initialize: function(items, list) { this.items = $$(items); this.list = $(list); if(!this.item && !this.list) { return; } this.bookmarks = Cookie.read('bookmarks'); this.bookmarks = this.bookmarks ? this.bookmarks.split(',') : new Array(); this.items.each(function(item) { if(this.bookmarks.contains(item.get('id'))) { item.addClass('bookmark'); } item.addEvents({ 'mouseenter': function() { if(item.hasClass('bookmark')) { item.addClass('bookmark-remove'); } else { item.addClass('bookmark-add'); } }, 'mouseout': function() { item.removeClass('bookmark-add').removeClass('bookmark-remove'); }, 'click': function() { if(item.hasClass('bookmark')) { this.remove(item); } else { this.add(item); } item.removeClass('bookmark-add').removeClass('bookmark-remove'); this.bookmarks = this.bookmarks.sort(); Cookie.write('bookmarks', this.bookmarks.join(','), {duration: 30}); this.makelist(); }.bind(this) }) }, this); this.makelist(); }, add: function(item) { item.addClass('bookmark'); this.bookmarks = this.bookmarks.include(item.get('id')); }, remove: function(item) { item.removeClass('bookmark'); this.bookmarks = this.bookmarks.erase(item.get('id')); }, dispose: function() { Cookie.dispose('bookmarks'); this.makelist; }, makelist: function() { var t = ''; this.list.set('html', t); } }); /* --- description: Provide a simple way to create 3D carousel. license: MIT-style copyright: Patrick Allain authors: Patrick Allain requires: - core/1.2.4:: [Class.Extras, Element.Event, Element.Style, Element.Dimension, Fx.Morph] provides: [Moo3DCarousel] ... */ var Moo3DCarousel = new Class({ /** * @see http://mootools.net/docs/core/Class/Class.Extras#Options */ Implements: [Events, Options], /** * Carousel options * Les options du carrousel * * @var Object JSON */ options: { // Le positionnement de l'overlay containerPosition: 'relative', // La marge que l'on dans l'overlay crée margin: 10, // L'offset du centre de l'elipse centerOffset: { x:0 , y:0 }, // La longueur du demi-grand axe xRadius: 300, // La longueur du demi-petit axe yRadius: 50, // La durée de d'une rotation rotateDuration: 500, // Les options pour les transitions fx: { link: 'cancel' }, // Ratio minimale que peut prendre une image ratioMin: 0.4, // Angle offset offsetAngle: 0, // On définit le départ pour la propriété z-index zIndex: 100, // Exposant pour la fonction modulant la position powerExponent: 0.85, // Ajoute l'événent mousewheel mouseWheel: true, // Si on veut faire un autorun autoRun: true, interval: 3000, // Stop le carrousel lorsque l'on le survole stopOver: true, // Sens trigo ou non trigo: true }, /** * The container element * L'élément container * * @var element */ _container: null, /** * The carousel elements * Les éléments constitutifs du Moo3DCarousel * * @var element */ _elements: [], /** * Max size of a images * La taille maximale que peut prendre une image * * @var Object JSON */ _sizeMax: {x:0, y:0}, /** * Index of the current image focused * L'index de l'image mise en avant * * @var int */ _currentIndex: 0, /** * Elipse center * Le centre de l'ellipse * * @var Object JSON */ _center: {x:0, y:0}, /** * The events methods * Les méthodes déclencher lors d'événements * * @var Object */ _evFunct: {}, /** * Timer * * @var timer */ _periodical: null, /** * Autorun * * @var bool */ _autorun: false, /** * Class constructor * Le constructeur de la classe. * * @param element parent * @param Object JSON options */ initialize: function(parent, options) { parent = document.id(parent); this.setOptions(options); // On crée un nouvel élément et on définit sa position puis on l'injecte dans l'élément parent this._container = new Element('div', { 'class': 'Moo3DCarouselOverlay'}) .setStyles({ 'position': this.options.containerPosition, 'z-index': this.options.zIndex }).inject(parent); // On crée notre objet contenant toutes les méthodes déclenchée lors d'un événement this._evFunct = { // Vous pourrez changer le signe en fonction de comment cela vous parait le plus naturel wheel: function(ev) { ev.stop(); this[(ev.wheel == 1) ? 'goNext': 'goPrevious'](); }.bind(this), winResize: function(ev) { this.init(); }.bind(this), mouseEnter: function(ev) { $clear(this._periodical); this.fireEvent('stop'); this._autorun = false; }.bind(this), mouseLeave: function(ev) { $clear(this._periodical); this._periodical = this.goNext.periodical(this.options.interval, this); this.fireEvent('start'); this._autorun = true; }.bind(this) }; // On ajoute l'événement sur l'overlay if ( this.options.mouseWheel ) this._container.addEvent('mousewheel', this._evFunct.wheel ); // On réinitialise lors du redimensionnement de la fenêtre window.addEvent('resize', this._evFunct.winResize ); if (this.options.autoRun) { this._evFunct.mouseLeave(); if ( this.options.stopOver) { // On ajoute les événements dans le cas d'une rotation continue this._container.addEvents({ 'mouseenter' : this._evFunct.mouseEnter, 'mouseleave' : this._evFunct.mouseLeave }); } } }, /** * Add a element in the carousel * Ajoute un élément au carrousel * * @param element elem * @param Object JSON size * @return Moo3DCarousel */ addElement: function(elem, size) { // On récupère l'image et on l'ajoute au tableau elem = document.id(elem); // On injecte l'élément dans l'overlay. elem.inject(this._container); // On ajoute l'élément à la liste des éléments du tableaux this._elements.push(elem); // Dans une premier temps, on récupère l'élément image var imgEl = ( elem.get('tag') == 'img' ) ? elem : elem;//elem.getElement('img'); // On définit la position de l'image en absolu imgEl.setStyle('position', 'absolute'); // On définit l'objet size si celui-ci n'a pas été passez en argument. size = size || {}; // Puis on récupère la taille de l'image. size.x = size.x || imgEl.getProperty('width').toInt() || el.getSize().x; size.y = size.y || imgEl.getProperty('height').toInt() || el.getSize().y; // On stocke cette taille sur l'élément. elem.store("Moo3DCarousel:size", size); // On recalcule la taille maximale this._sizeMax = { x: Math.max(size.x, this._sizeMax.x), y: Math.max(size.y, this._sizeMax.y) }; // On ajoute l'objet permettant de faire des transitions sur l'image elem.store("Moo3DCarousel:fx", new Fx.Morph(imgEl, $extend({duration: this.options.rotateDuration}), this.options.fx) ); // On réinitialise le carrousel afin de prendre en compte le nouvel élément this.init(); return this; }, /** * Retrieve the carousel size * Retourne la taille du carrousel * * @return Object JSON */ getSize: function() { return { x: this._sizeMax.x + 2 * ( this.options.margin + this.options.xRadius), y: this._sizeMax.y + 2 * ( this.options.margin + this.options.yRadius) }; }, /** * Position images without transition * Repositionne les images sans effectuer de transition * * @return Moo3DCarousel */ init: function(index) { this._currentIndex = index || this._currentIndex; // On re-calcule le centre de l'elipse this._center = { x: (this._container.getSize().x / 2) + this.options.centerOffset.x, y: this.options.centerOffset.y + this.options.yRadius }; // On rédéfinit la taille de l'overlay afin que les images ne sorte pas du flux this._container.setStyle('height', this.getSize().y ); var l = this._elements.length; // On replace tous les éléments for ( var i=0; i 0) ? 1 : -1) * Math.PI * Math.pow( Math.abs(teta) / Math.PI , this.options.powerExponent); return teta; }, /** * Fix the style to apply on a element from angle * Calcul le style à appliquer sur un élément du carrousel * en fonction de l'angle sous lequel il est vu * * @param element elem * @param float teta * @return Object JSON */ _getStyles: function(elem, teta) { // On calcule la rotation du carrousel var size = elem.retrieve('Moo3DCarousel:size', elem.getSize() ); // On calcule le coefficient pour le modulant de la taille et de la propriété z-index var sCoeff = (1-this.options.ratioMin) / 2; sCoeff = 1 + sCoeff * (Math.cos(teta)-1) ; // On calcule la taille de l'image modulé par la fonction présenté var out = { width: (size.x * sCoeff).toInt(), height: (size.y * sCoeff).toInt() }; // On ajoute la propriété z-index $extend( out , { 'z-index': (this.options.zIndex + sCoeff * 2 * this._elements.length).toInt() }); // On ajoute la position en décalant horizontalement l'image de la moitié sa largeur $extend( out, { left: (this._center.x + this.options.xRadius * Math.sin(teta + this.options.offsetAngle) - out.width/2).toInt(), top: (this._center.y + this.options.yRadius * Math.cos(teta + this.options.offsetAngle)).toInt() }); return out; }, /** * Focus a element's carousel * Permet de mettre en avant une photo * * @var element|id element * @return Moo3DCarousel */ focus: function(elem) { elem = document.id(elem); var index = this._elements.indexOf(elem); if ( index != -1 ) { this.goTo(index); } return this; }, /** * Focus the previous element * Permet d'accéder à l'élément précédent * * @return Moo3DCarousel */ goPrevious: function() { return this.goTo( this._currentIndex - (this.options.trigo ? -1 : 1) ); }, /** * Focus the next element * Permet d'accéder à l'élément suivant * * @return Moo3DCarousel */ goNext: function() { return this.goTo( this._currentIndex + (this.options.trigo ? -1 : 1) ); }, /** * Focus a element from its index * Permet d'accéder à un élément en fonction de son index * * @param int index * @return Moo3DCarousel */ goTo: function(index) { this.init(); // Déclenche l'événement rotateStart this.fireEvent('rotateStart', this); // Nous refinissons notre l'index de l'image mise en avant this._currentIndex = index % this._elements.length; var l = this._elements.length; // On déplace tous les éléments avec des transitions for ( var i=0; i0)new swfobject.embedSWF(b.nohtml5,b.uid,b.sw,b.sh,"10.0.0",false,f,{allowFullScreen:"true",allowScriptAccess:"always"});else b.stg.innerHTML= b.nohtml5}else alert("uppod:"+f.uid+" uid?")}function ea(){window.onkeydown=function(a){var d=a.which;if(d==undefined)d=a.keyCode;M&&d==27&&r();if((s||M)&&d==32)E()};if(b.cntrlhide==1)b.stg.onmousemove=function(){if(ra){c(o,{visibility:"visible"});ra=false;setTimeout(k,3E3)}};b.stg.onmouseup=function(){t&&(t.active=false);l&&(l.active=false)};b.stg.onmouseover=function(){ja=true};b.stg.onmouseout=function(){ja=false};b.stg.oncontextmenu=function(a){if(!a)a=window.event;a.cancelBubble=true;a.stopPropagation&& a.stopPropagation();if(S)c(S,{display:"block",position:"absolute",top:a.clientY,left:a.clientX});else{S=document.createElement("div");document.body.appendChild(S);var d=document.createElement("div");S.appendChild(d);d.innerHTML="Uppod HTML5 0.0.6";d.onclick=function(){window.open("http://uppod.ru/","_blank")};c(S,{"border-radius":"0px",cursor:"pointer",position:"absolute",top:a.clientY,left:a.clientX,backgroundColor:"#000",color:"#fff",borderStyle:"solid",borderColor:"#000000",borderWidth:"1px", padding:"2px 5px 3px 5px",font:"9px Tahoma",opacity:"1"})}return false};document.onclick=function(){S&&c(S,{display:"none"})}}function da(){T=document.createElement("div");L.c.appendChild(T);T.onclick=E;e=document.createElement(b.m);T.appendChild(e);e.setAttribute("width",b.sw+"px");e.setAttribute("height",b.sh+"px");e.controls=false;e.preload="metadata";e.autoplay=false;c(e,{position:"absolute",top:0,left:0});b.m=="audio"&&c(e,{width:"0px",height:"0px"});setTimeout(Y,33);b.poster!=""&&e.setAttribute("poster", b.poster);b.auto!="none"&&u();y=document.createElement("div");G.c.appendChild(y);c(y,{width:"100%",height:"100%",position:"absolute",top:0,left:0});y.onclick=E;if(b.o>0){ka=document.createElement("canvas");var a=ka.getContext("2d");a.fillStyle="#"+b.bgcolor;a.beginPath();a.moveTo(0,0);a.lineTo(b.o/2,0);a.quadraticCurveTo(0,0,0,b.o/2);a.closePath();a.fill();y.appendChild(ka);la=document.createElement("canvas");a=la.getContext("2d");a.fillStyle="#"+b.bgcolor;a.beginPath();a.moveTo(0,0);a.quadraticCurveTo(b.o/ 2,0,b.o/2,b.o/2);a.lineTo(b.o/2,0);a.closePath();a.fill();y.appendChild(la);ma=document.createElement("canvas");a=ma.getContext("2d");a.fillStyle="#"+b.bgcolor;a.beginPath();a.moveTo(b.o/2,0);a.quadraticCurveTo(b.o/2,b.o/2,0,b.o/2);a.lineTo(b.o/2,b.o/2);a.closePath();a.fill();y.appendChild(ma);na=document.createElement("canvas");a=na.getContext("2d");a.fillStyle="#"+b.bgcolor;a.beginPath();a.moveTo(0,0);a.quadraticCurveTo(0,b.o/2,b.o/2,b.o/2);a.lineTo(0,b.o/2);a.closePath();a.fill();y.appendChild(na); fa()}}function fa(){c(ka,{position:"absolute",top:0,left:0});c(la,{position:"absolute",top:0,left:b.sw-b.o/2});c(ma,{position:"absolute",top:b.sh-b.o/2,left:b.sw-b.o/2});c(na,{position:"absolute",top:b.sh-b.o/2,left:0})}function u(){Z=[];if(b.file!="")if(b.file.indexOf("|")>0)for(var a=b.file.split("|"),d=0;d0){oa=true;c(e,{opacity:1});b.auto=="play"&&!s&&E();playInterval=setInterval(N,100);e.addEventListener("progress",Ea,false);var a=b.volume;e.volume=a;O&&ta(a*O.w)}else setTimeout(Y,33)}function E(){if(oa){ua=true;if(b.auto=="none"){u();b.auto="play"}if(s){e.pause();if(J!=undefined){J.c.style.display="block";P.c.style.display="none"}s=false;b.comment!=undefined&&b.comment!=""&&b.showcomment==1&&alrt&&(alrt.style.display="block")}else{e.play();if(J!=undefined){J.c.style.display= "none";P.c.style.display="block"}s=true;b.cntrlhide==1&&setTimeout(k,3E3);b.comment!=undefined&&b.comment!=""&&b.showcomment==1&&alrt&&(alrt.style.display="none");if(e.currentTime==0){U=true;p();H.c.innerHTML="\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430"}}}}function K(){s&&E();T.removeChild(e);y!=undefined&&G.c.removeChild(y);delete e;delete y;if(l){c(v.canvas,{width:"0"});c(q.canvas,{width:"0"})}da()}function j(a){if(!M||a=="re"){b.iframe!=""&&c(window.parent.document.getElementById(b.iframe), {width:window.parent.innerWidth,height:window.parent.innerHeight,position:"fixed",left:0,top:0});if(a!="re"){M=true;mediaWidth=b.sw;mediaHeight=b.sh;c(G.canvas,{visibility:"hidden"});c(L.canvas,{visibility:"hidden"});c(T,{backgroundColor:"#000",position:"fixed",left:0,top:0})}c(b.stg,{width:b.iframe!=""?window.parent.innerWidth:window.innerWidth,height:b.iframe!=""?window.parent.innerHeight:window.innerHeight,position:"fixed",left:0,top:0});b.debug==0&&c(b.stg,{"z-index":"990"});y!=undefined&&(y.style.display= "none")}else r()}function r(){M=false;b.iframe!=""&&c(window.parent.document.getElementById(b.iframe),{width:mediaWidth,height:mediaHeight,position:"static",left:0,top:0});c(T,{backgroundColor:"transparent",position:"absolute",left:0,top:0});c(b.stg,{width:mediaWidth,height:mediaHeight,position:"static",left:0,top:0});b.debug==0&&c(b.stg,{"z-index":"1"});c(G.canvas,{visibility:"visible"});c(L.canvas,{visibility:"visible"});y!=undefined&&(y.style.display="block")}function k(){if(s&&!ja&&e.currentTime> 0){c(o,{visibility:"hidden"});ra=true}s&&ja&&setInterval(k,3E3)}function m(){va(0)}function w(){if(e.muted){e.muted=false;V.c.style.display="block";Q.c.style.display="none"}else{e.muted=true;Q.c.style.display="block";V.c.style.display="none"}}function N(){if(e!=undefined){played=e.currentTime/e.duration;R!=undefined&&(R.c.innerHTML=wa(e.currentTime));$!=undefined&&($.c.innerHTML=wa(!e.duration||e.duration=="Infinity"?0:e.duration));if(e.ended&&s){m();E()}if(e.ended&&s){m();E()}loaded=0;if(sa){e.buffered? e.buffered.length>0?loaded=e.buffered.end(0)/e.duration:loaded=0:loaded=0;var a=Math.round(loaded*z.w-ia),d=Math.round(played*z.w-ia);a<0&&(a=1);!l.active&&c(v.canvas,{width:""+d+"px"});e.buffered&&c(q.canvas,{width:""+a+"px"});if(U&&!xa)if(e.currentTime>0){g();xa=true}if(e.buffered)if(e.buffered.length>0&&q.canvas.offsetWidth-v.canvas.offsetWidth<=0&&s&&!U){e.pause();U=true;p();setTimeout(F,2E3)}}}if(b.stg.offsetWidth!=b.sw||b.stg.offsetHeight!=b.sh){b.sw=b.stg.offsetWidth;b.sh=b.stg.offsetHeight; if(!M){c(G.canvas,{width:b.sw,height:b.sh});c(L.canvas,{width:b.sw,height:b.sh})}pa&&c(pa.canvas,{width:""+b.sw+"px",height:""+b.cntrloutheight+"px"});alrt&&c(alrt_bg.canvas,{width:""+b.sw+"px"});c(T,{width:""+b.sw+"px",height:""+b.sh+"px"});c(e,{width:""+b.sw+"px",height:""+b.sh+"px"});b.o>0&&fa();c(o,{top:b.sh-(b.cntrlout==1&&!M?0:b.cntrloutheight)+(!M?b.padding:0),left:0});ya()}if(M)if(b.iframe!="")(window.parent.innerWidth!=b.stg.offsetWidth||window.parent.innerHeight!=b.stg.offsetHeight)&&j("re"); else(window.innerWidth!=b.stg.offsetWidth||window.innerHeight!=b.stg.offsetHeight)&&j("re")}function F(){if(U)if(q.canvas.offsetWidth-v.canvas.offsetWidth>z.canvas.offsetWidth/e.duration*b.buffersec||q.canvas.offsetWidth==z.canvas.offsetWidth){e.play();U=false;g()}else{setTimeout(F,2E3);if(b.controls.indexOf("buffer")>-1)H.c.innerHTML=(e.duration?Math.round((q.canvas.offsetWidth-v.canvas.offsetWidth)/(z.canvas.offsetWidth/e.duration*b.buffersec)*100):"0")+"%"}}function p(){b.controls.indexOf("buffer")> -1&&c(H.c,{display:"block"})}function g(){if(b.controls.indexOf("buffer")>-1){c(H.c,{display:"none"});H.c.innerHTML=""}U=false}function Ea(a){if(a.total&&a.loaded&&(e.buffered.length==0||!e.buffered)){a=a.loaded/a.total;if(l){a=Math.round(a*z.w-ia);a<0&&(a=1);c(q.canvas,{width:""+a+"px"})}}}function wa(a){a=Math.round(a);minutes=Math.floor(a/60);minutes=minutes>=10?minutes:minutes;a=Math.floor(a%60);a=a>=10?a:"0"+a;return minutes+":"+a}function Da(){o=document.createElement("div");G.c.appendChild(o); c(o,{position:"absolute",top:b.scrn_h-(b.cntrlout==1?0:b.cntrloutheight)+b.padding,left:b.padding});if(b.cntrlout!=1&&b.cntrlbg==1){b.cntrlbgcolor.indexOf("|")==-1&&(b.cntrlbgcolor=b.cntrlbgcolor+"|"+b.cntrlbgcolor);pa=new ha({w:b.scrn_w,h:b.cntrloutheight,o:b.o/2-b.padding,onotop:1,bgc:b.cntrlbgcolor,bga1:b.cntrlbgalpha1,bga2:b.cntrlbgalpha2});o.appendChild(pa.c)}A=b.controls.split(",");I=0;n=[];x=[];for(var a=0;a-1&&c(H.c, {left:l.offsetLeft})}}function za(a){if(t.active){if(!a)a=window.event;ta(a.clientX-t.offsetLeft-b.stg.offsetLeft-L.c.offsetLeft)}}function ta(a){c(ga.canvas,{width:""+a+"px"});e.volume=Math.max(0,Math.min(1,a/O.w))}function Aa(a){if(l.active){if(!a)a=window.event;a=a.clientX-l.offsetLeft-b.stg.offsetLeft-L.c.offsetLeft;va(a);c(v.canvas,{width:""+(a-ia)+"px"})}}function va(a){if(e.duration){e.currentTime=Math.max(0,Math.min(1,a/z.w))*e.duration;if(sa&&a==0){ia=0;c(q.canvas,{left:0});c(v.canvas,{left:0})}}} function B(a,d,h,C,D){this.c=document.createElement("div");this.s={};D==undefined&&(D=a);for(var X in b.cntrlstyle)this.s[X]=b.cntrlstyle[X];for(X in b["cntrl"+D])this.s[X]=b["cntrl"+D][X];for(X in b["cntrl_"+D])this.s[X]=b["cntrl_"+D][X];if(C=="all")this.s.color=this.s.color_all;if(C=="load")this.s.color=this.s.color_load;if(C=="play")this.s.color=this.s.color_play;this.canvas=document.createElement("canvas");this.canvas.height=h*this.s.scale;this.canvas.width=d*this.s.scale;this.ctx=this.canvas.getContext("2d"); this.s.bg==1&&this.c.appendChild((new ha({w:d*this.s.scale,h:h*this.s.scale,o:h/2*this.s.bg_o*this.s.scale,bgc:this.s.bgcolor,sh:this.s.bg_sh,sh_c:this.s.sh_c,sh_a:this.s.sh_a})).c);if(this.s.color.indexOf("|")>0){C=this.s.color.split("|");D=this.ctx.createLinearGradient(0,0,0,h*this.s.scale);for(this.j=0;this.j0){for(var h=a.bgc.split("|"),C=d.createLinearGradient(0,0,0,a.h),D=0;D0){d.beginPath();d.moveTo(a.onotop==1?0:a.o,0);d.lineTo(a.w-(a.onotop==1?0:a.o),0);a.onotop==1||d.quadraticCurveTo(a.w,0,a.w,a.o);d.lineTo(a.w,a.h-a.o);d.quadraticCurveTo(a.w,a.h,a.w-a.o,a.h);d.lineTo(a.o,a.h);d.quadraticCurveTo(0, a.h,0,a.h-a.o);d.lineTo(0,a.o);a.onotop==1||d.quadraticCurveTo(0,0,a.o,0);!a.brdc&&(a.brdc="cccccc");d.strokeStyle="#"+a.brdc;if(a.brd==0||!a.brd)a.brd=0.1;d.lineWidth=a.brd;d.stroke();d.fill()}else d.fillRect(0,0,a.w,a.h);this.c.appendChild(this.canvas)}function Ca(){this.auto="firstframe";this.bgcolor="ffffff";this.bodycolor="000000";this.brd=0;this.brdcolor="cccccc";this.buffersec=5;this.cntrlbg=1;this.cntrlbgcolor="000000|000000";this.cntrlbgalpha1=0.15;this.cntrlbgalpha2=0.7;this.cntrlendmargin= 7;this.cntrlhide=1;this.cntrlmargin=3;this.cntrlout=0;this.cntrloutheight=35;this.cntrlsize=1;this.cntrlbuffer={center:0};this.cntrl_buffer={};this.cntrlfull={out:0};this.cntrl_full={};this.cntrlstyle={icon:0,color:"ffffff",bg:0,bg_o:1,bg_smallicon:1,bgcolor:"000000",bg_sh:"0",bg_in:"0",bg_gl:"0",gl_a1:0.9,gl_a2:0.1,gl_color:"FFFFFF",sh_blur:6,sh_dist:0,bg_a:1,bg_w:20,bg_h:20,scale:1,eff:0,effE:"Cubic",sh:0,sh_c:"000000",sh_a:0.5,sh_under:1,notip:0,text:0,center:0,marginleft:0,marginright:0,margintop:0, marginbottom:0,alpha:1};this.cntrlplay={};this.cntrl_play={};this.cntrlpause={};this.cntrl_pause={};this.cntrlstop={};this.cntrl_stop={};this.cntrlline={h:4,all_a:0.3,load_a:0.4,play_a:1,click:1,color_play:"ffffff",color_all:"ffffff",color_load:"ffffff"};this.cntrl_line={};this.cntrl_volbarline={};this.cntrlvolbarline={h:4,w:40,all_a:0.4,play_a:1,color_play:"ffffff",color_all:"ffffff"};this.cntrl_volume={};this.cntrlvolume={};this.comment="";this.showcomment=1;this.commentcolor="ffffff";this.commentbgcolor= "000000";this.commentbgcolor_k=false;this.commentbgalpha1=0.5;this.commentbgalpha2=0.1;this.commentalign="left";this.commenttopmargin=0;this.commentmargin=7;this.namefont="Verdana";this.namefontsize=11;this.namefontstyle="normal";this.controls="play,back,time_play,line,time_all,volume,volbarline,full,buffer";this.debug=0;this.file="";this.htmlsize=0;this.iframe="";this.m="video";this.nohtml5="uppod.swf";this.padding=this.o=0;this.poster="";this.screencolor="000000";this.volume=0.8;this.w=500;this.h= 375;this.stg=document.getElementById(f.uid);this.stg==null&&alert("Uppod: UID ("+f.uid+") not found");this.sw=this.stg.offsetWidth;this.sh=this.stg.offsetHeight;this.lang="ru";for(var a in f)this[a]=f[a];if(this.m=="audio"){this.cntrlhide=0;this.controls="play,back,time_play,line,time_all,volume,volbarline,buffer";this.uibg=0}if(this.st){str=Ba(this.st+"?"+Math.random());style=JSON.parse(str,function(d,h){if(typeof h==="string"&&d.indexOf("color")>-1)h=h.replace("#","");return h});for(a in style)this[a]= style[a];if(this.htmlsize==1||!style.w&&!style.h){this.w=this.sw;this.h=this.sh}}}function Ba(){}function Ba(a){if(a){req=new XMLHttpRequest;req.open("GET",a,false);req.send(null);if(req.status==200)return req.responseText}}var b,qa=false,oa=false,s=false,M=false,ra=false,U=false,ja=false,ua=false,sa=false,xa=false,ia=0,S;if(document.getElementById(f.uid))ca();else window.onload=function(){ca()};var G,L,ka,la,na,ma,T,e,Z,y,pa,J,P,W,aa,R,$,V,Q,t,O,ga,ba,l,z,q,v,H,I,A,n,x,o;this.getStatus=function(){return!ua? 0:U?3:s?1:2};this.Play=function(){!s&&oa&&E()};this.Pause=function(){s&&E()};this.Stop=function(){oa&&K()}}function Tween(f){f.dur==undefined&&(f.dur=1E3);f.what=="a"&&(new Fx.Morph(f.mc,{duration:f.dur})).start({opacity:[f.from,f.to]})}function HTR(f){return parseInt(cutHex(f).substring(0,2),16)}function HTG(f){return parseInt(cutHex(f).substring(2,4),16)}function HTB(f){return parseInt(cutHex(f).substring(4,6),16)}function cutHex(f){return f.charAt(0)=="#"?f.substring(1,7):f} function trace(f){alert(f)}if(!this.JSON)this.JSON={}; (function(){function f(j){return j<10?"0"+j:j}function ca(j){fa.lastIndex=0;return fa.test(j)?'"'+j.replace(fa,function(r){var k=E[r];return typeof k==="string"?k:"\\u"+("0000"+r.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+j+'"'}function ea(j,r){var k,m,w,N,F=u,p,g=r[j];if(g&&typeof g==="object"&&typeof g.toJSON==="function")g=g.toJSON(j);if(typeof K==="function")g=K.call(r,j,g);switch(typeof g){case "string":return ca(g);case "number":return isFinite(g)?String(g):"null";case "boolean":case "null":return String(g); case "object":if(!g)return"null";u+=Y;p=[];if(Object.prototype.toString.apply(g)==="[object Array]"){N=g.length;for(k=0;k<\/script>");J=C("__ie_ondomload");if(J){I(J,"onreadystatechange",S)}}catch(q){}}if(h.webkit&&typeof K.readyState!=b){Z=setInterval(function(){if(/loaded|complete/.test(K.readyState)){E()}},10)}if(typeof K.addEventListener!=b){K.addEventListener("DOMContentLoaded",E,null)}R(E)}();function S(){if(J.readyState=="complete"){J.parentNode.removeChild(J);E()}}function E(){if(e){return }if(h.ie&&h.win){var v=a("span");try{var u=K.getElementsByTagName("body")[0].appendChild(v);u.parentNode.removeChild(u)}catch(w){return }}e=true;if(Z){clearInterval(Z);Z=null}var q=o.length;for(var r=0;r0){var r=C(u);if(r){N[q].width=r.getAttribute("width")?r.getAttribute("width"):"0";N[q].height=r.getAttribute("height")?r.getAttribute("height"):"0";if(c(N[q].swfVersion)){if(h.webkit&&h.webkit<312){Y(r)}W(u,true)}else{if(N[q].expressInstall&&!A&&c("6.0.65")&&(h.win||h.mac)){k(N[q])}else{O(r)}}}}else{W(u,true)}}}function Y(t){var q=t.getElementsByTagName(Q)[0];if(q){var w=a("embed"),y=q.attributes;if(y){var v=y.length;for(var u=0;u'}}v.outerHTML='"+AD+"";i[i.length]=AG.id;q=C(AG.id)}else{if(h.webkit&&h.webkit<312){var AC=a("embed");AC.setAttribute("type",P);for(var z in AG){if(AG[z]!=Object.prototype[z]){if(z.toLowerCase()=="data"){AC.setAttribute("src",AG[z])}else{if(z.toLowerCase()=="styleclass"){AC.setAttribute("class",AG[z])}else{if(z.toLowerCase()!="classid"){AC.setAttribute(z,AG[z])}}}}}for(var y in AE){if(AE[y]!=Object.prototype[y]){if(y.toLowerCase()!="movie"){AC.setAttribute(y,AE[y])}}}v.parentNode.replaceChild(AC,v);q=AC}else{var u=a(Q);u.setAttribute("type",P);for(var x in AG){if(AG[x]!=Object.prototype[x]){if(x.toLowerCase()=="styleclass"){u.setAttribute("class",AG[x])}else{if(x.toLowerCase()!="classid"){u.setAttribute(x,AG[x])}}}}for(var w in AE){if(AE[w]!=Object.prototype[w]&&w.toLowerCase()!="movie"){F(u,w,AE[w])}}v.parentNode.replaceChild(u,v);q=u}}}return q}function F(t,q,r){var u=a("param");u.setAttribute("name",q);u.setAttribute("value",r);t.appendChild(u)}function X(r){var q=C(r);if(q&&(q.nodeName=="OBJECT"||q.nodeName=="EMBED")){if(h.ie&&h.win){if(q.readyState==4){B(r)}else{j.attachEvent("onload",function(){B(r)})}}else{q.parentNode.removeChild(q)}}}function B(t){var r=C(t);if(r){for(var q in r){if(typeof r[q]=="function"){r[q]=null}}r.parentNode.removeChild(r)}}function C(t){var q=null;try{q=K.getElementById(t)}catch(r){}return q}function a(q){return K.createElement(q)}function I(t,q,r){t.attachEvent(q,r);d[d.length]=[t,q,r]}function c(t){var r=h.pv,q=t.split(".");q[0]=parseInt(q[0],10);q[1]=parseInt(q[1],10)||0;q[2]=parseInt(q[2],10)||0;return(r[0]>q[0]||(r[0]==q[0]&&r[1]>q[1])||(r[0]==q[0]&&r[1]==q[1]&&r[2]>=q[2]))?true:false}function V(v,r){if(h.ie&&h.mac){return }var u=K.getElementsByTagName("head")[0],t=a("style");t.setAttribute("type","text/css");t.setAttribute("media","screen");if(!(h.ie&&h.win)&&typeof K.createTextNode!=b){t.appendChild(K.createTextNode(v+" {"+r+"}"))}u.appendChild(t);if(h.ie&&h.win&&typeof K.styleSheets!=b&&K.styleSheets.length>0){var q=K.styleSheets[K.styleSheets.length-1];if(typeof q.addRule==Q){q.addRule(v,r)}}}function W(t,q){var r=q?"visible":"hidden";if(e&&C(t)){C(t).style.visibility=r}else{V("#"+t,"visibility:"+r)}}function g(s){var r=/[\\\"<>\.;]/;var q=r.exec(s)!=null;return q?encodeURIComponent(s):s}var D=function(){if(h.ie&&h.win){window.attachEvent("onunload",function(){var w=d.length;for(var v=0;v=0){G=N;o=g[N][0];w=(G||(u.loop?g.length:0))-1;E=((G+1)%g.length)||(u.loop?0:-1);r();a.className="lbLoading";m=new Image();m.onload=k;m.src=o}return false}function k(){a.className="";d.set(0);h.setStyles({backgroundImage:"url("+o+")",display:""});q.setStyle("width",m.width);$$(q,J,e).setStyle("height",m.height);A.set("html",g[G][1]||"");L.set("html",(((g.length>1)&&u.counterText)||"").replace(/{x}/,G+1).replace(/{y}/,g.length));if(w>=0){t.src=g[w][0]}if(E>=0){K.src=g[E][0]}M=h.offsetWidth;s=h.offsetHeight;var P=Math.max(0,y-(s/2)),N=0,O;if(a.offsetHeight!=s){N=i.start({height:s,top:P})}if(a.offsetWidth!=M){N=i.start({width:M,marginLeft:-M/2})}O=function(){H.setStyles({width:M,top:P+s,marginLeft:-M/2,visibility:"hidden",display:""});d.start(1)};if(N){i.chain(O)}else{O()}}function j(){if(w>=0){J.style.display=""}if(E>=0){e.style.display=""}C.set(-c.offsetHeight).start(0);H.style.visibility=""}function r(){m.onload=$empty;m.src=t.src=K.src=o;i.cancel();d.cancel();C.cancel();$$(J,e,h,H).setStyle("display","none")}function D(){if(G>=0){r();G=w=E=-1;a.style.display="none";x.cancel().chain(l).start(0)}return false}Element.implement({slimbox:function(N,O){$$(this).slimbox(N,O);return this}});Elements.implement({slimbox:function(N,Q,P){Q=Q||function(R){return[R.href,R.title]};P=P||function(){return true};var O=this;O.removeEvents("click").addEvent("click",function(){var R=O.filter(P,this);return Slimbox.open(R.map(Q),R.indexOf(this),N)});return O}});return{open:function(P,O,N){u=$extend({loop:false,overlayOpacity:0.8,overlayFadeDuration:400,resizeDuration:400,resizeTransition:false,initialWidth:250,initialHeight:250,imageFadeDuration:400,captionAnimationDuration:400,counterText:"Image {x} of {y}",closeKeys:[27,88,67],previousKeys:[37,80],nextKeys:[39,78]},N||{});x=new Fx.Tween(I,{property:"opacity",duration:u.overlayFadeDuration});i=new Fx.Morph(a,$extend({duration:u.resizeDuration,link:"chain"},u.resizeTransition?{transition:u.resizeTransition}:{}));d=new Fx.Tween(h,{property:"opacity",duration:u.imageFadeDuration,onComplete:j});C=new Fx.Tween(c,{property:"margin-top",duration:u.captionAnimationDuration});if(typeof P=="string"){P=[[P,O]];O=0}y=F.getScrollTop()+(F.getHeight()/2);M=u.initialWidth;s=u.initialHeight;a.setStyles({top:Math.max(0,y-(s/2)),width:M,height:s,marginLeft:-M/2,display:""});v=n||(I.currentStyle&&(I.currentStyle.position!="fixed"));if(v){I.style.position="absolute"}x.set(0).start(u.overlayOpacity);z();l(1);g=P;u.loop=u.loop&&(g.length>1);return b(O)}}})(); /* login form */ var showLoginForm = function(item) { new StickyWin.Modal({ closeOnEsc: true, content: StickyWin.ui('Âõîä íà ïîðòàë', $('signin').get('html')), destroyOnClose: true, id: 'stickySignin', offset: {x: -315, y: 0}, position: 'bottomLeft', relativeTo: $defined(item) ? item : $$('.signin')[0], width: 350 }); $('stickySignin').getElement('input[type=text], textarea').focus(); return false; } window.addEvent('domready', function() { // locale MooTools.lang.setLanguage('ru-RU'); Clientcide.setAssetLocation(AssetsPath); // carousel var carousel = $('carousel'); if(carousel) { var isIndex = document.body.hasClass('index'); var active = 0; $$('#carousel .item').each(function(item, index) { if(item.hasClass('active')) { active = index; } }); carousel = new Moo3DCarousel(carousel, { xRadius: 150, yRadius: 10, rotateDuration: 'normal', ratioMin: 0.25, offsetAngle: 0, powerExponent: 0.85, stopOver: true, trigo: false, interval: 7000, autoRun: isIndex }); $('carousel').setStyle('display', ''); $$('#carousel .item').each(function(item, index) { item.fade(0.5); var caption = item.getElement('div'); caption.fade('hide'); var captionFx = new Fx.Morph(caption); caption.addEvents({ 'mouseenter': function() { captionFx.cancel(); captionFx.start({ 'height': 60, 'margin-top': -60 }); }, 'mouseleave': function() { captionFx.cancel(); captionFx.start({ 'height': 30, 'margin-top': -30 }); } }); carousel.addElement(item, { x: 250, y: 175 }); }); carousel.addEvent('rotateStart', function() { this.getFocused().fade(0.5); this.getFocused().getElement('div').fade('out'); }); carousel.addEvent('rotateEnd', function() { this.getFocused().fade('in'); this.getFocused().getElement('div').fade('in'); }); if(isIndex) { $$('.header-nav li').each(function(item, index) { item.addEvent('mouseenter', function() { carousel.goTo(index); }); }); } carousel.goTo(active); $$('#carousel a.prev').each(function(item) { item.addEvent('click', function() { carousel.goNext(); return false; }); }); $$('#carousel a.next').each(function(item) { item.addEvent('click', function() { carousel.goPrevious(); return false; }); }); } // catalog tabswapper new TabSwapper({ tabs: $$('#catalog .level-1-togglers li'), clickers: $$('#catalog .level-1-togglers a'), sections: $$('#catalog .level-1-panel'), cookieName: 'catalog-level-1' }); // overtext $$('input[alt],textarea[alt]').each(function(item) { new OverText(item); }); // tables $$('table').each(function(table) { if(table.getElement('td.td-toggler')) { table.getElements('tr:nth-child(4n+2)').each(function(tr) { tr.addClass('odd'); tr.getNext('tr').addClass('odd'); }); } else { table.getElements('tr:nth-child(2n+1)').each(function(tr) { tr.addClass('odd'); }); } }); $$('.td-toggler-icon').addEvent('click', function(event) { var td = $(this).getParent('td'); td.toggleClass('active'); var tr = this.getParent('tr').getNext('tr'); tr.toggleClass('off'); tr.toggleClass('active'); return false; }); $$('.td-toggler-icon2').addEvent('click', function(event) { $(this).getParent().toggleClass('active'); return false; }); // noobslide $$('.slider-persons').each(function(item) { new noobSlide({ addButtons: { previous: item.getElement('.prev'), next: item.getElement('.next') }, box: item.getElement('.move'), fxOptions: {duration: 250}, items: item.getElements('figure'), loop: false, visible: 5 }); }); $$('.slider-books').each(function(item) { new noobSlide({ addButtons: { previous: item.getElement('.prev'), next: item.getElement('.next') }, box: item.getElement('.move'), fxOptions: {duration: 250}, items: item.getElements('figure'), loop: false, visible: 4 }); }); // tabswapper $$('.tabs').each(function(item) { var init = 0; item.getElements('td').each(function(td, i) { if(td.hasClass('active')) { init = i; } }); new TabSwapper({ selectedClass: 'active', tabs: item.getElements('#taber td'), clickers: item.getElements('td'), sections: item.getElements('.item'), initPanel: init, smooth: true, smoothSize: true }); }); // tabswapper - library search $$('.tab_tables').each(function(item) { var init = 0; /*item.getElements('ul li').each(function(td, i) { if(li.hasClass('active')) { init = i; } });*/ new TabSwapper({ selectedClass: 'active', tabs: item.getElements('.t_sel li'), /*clickers: item.getElements('li'),*/ sections: item.getElements('.item'), initPanel: init, smooth: true, smoothSize: true }); }); // tabswapper - journal main articles $$('.j_articles').each(function(item) { var init = 0; item.getElements('ul li').each(function(td, i) { if(td.hasClass('active')) { init = i; } }); new TabSwapper({ selectedClass: 'active', tabs: item.getElements('ul li'), rearrangeDOM: false, /*clickers: item.getElements('tr'),*/ action: 'mouseover', sections: item.getElements('article'), initPanel: init, smooth: true, smoothSize: true }); }); // tabswapper - journal lenta $$('.tabs_lenta').each(function(item) { var init = 0; item.getElements('a').each(function(td, i) { if(td.hasClass('active')) { init = i; } }); new TabSwapper({ selectedClass: 'active', tabs: item.getElements('h2 a'), rearrangeDOM: false, clickers: item.getElements('a'), sections: item.getElements('.item'), initPanel: init, smooth: true, smoothSize: true }); }); $$('.toggle').each(function(item) { var init = 0; item.getElements('.toggler').each(function(td, i) { if(td.hasClass('active')) { init = i; } }); new TabSwapper({ selectedClass: 'active', tabs: item.getElements('.toggler'), rearrangeDOM: false, clickers: item.getElements('.toggler'), sections: item.getElements('.table-persons'), initPanel: init, smooth: true, smoothSize: true }); }); $$('.tabs_lib').each(function(item) { var init = 0; item.getElements('span').each(function(td, i) { if(td.hasClass('active')) { init = i; } }); new TabSwapper({ selectedClass: 'active', tabs: item.getElements('h2 span'), rearrangeDOM: false, clickers: item.getElements('a'), sections: item.getElements('.item'), initPanel: init, smooth: true, smoothSize: true }); }); // for genres $$('.tabs_lib h2 a').addEvent('click', function(event) { var genres = $(this).getParent('.body').getChildren('.item2'); genres.toggleClass('active'); return false; }); // book preview (slimbox) $$(".preview_link").filter(function(el) { return el.rel && el.rel.test(/^lightbox/i); }).slimbox({/* Put custom options here */}, null, function(el) { return (this == el) || ((this.rel.length > 8) && (this.rel == el.rel)); }); // print preview $$('a[href$=print]').each(function(item) { item.addEvent('click', function() { document.togglePreview(); return false; }); }); if(document.location.hash.indexOf('#print') > -1) { document.togglePreview(); } // bookmarks new Bookmarks('.ebook div.p', 'bookmarks'); // sendmessage form $$('a[href*=sendmessage], li.send a').each(function(item) { item.addEvent('click', function() { new StickyWin.Modal({ closeOnEsc: true, content: StickyWin.ui('Îòïðàâèòü ñîîáùåíèå', $('sendmessage').innerHTML), destroyOnClose: true, id: 'stickySendmessage', offset: {x: 0, y: -50}, width: 500 }); $('stickySendmessage').getElement('input[type=text], textarea').focus(); return false; }); }); // dates $$('input.date').each(function(item) { new DatePicker(item, { showMoreThanOne: false, stickyWinOptions: { offset: {x: 0, y: 0} }, updateOnBlur: false }); }); // form validator $$('form.validation').each(function(item) { new Form.Validator.Tips(item, { pointyTipOptions: { pointyOptions: { theme: 'light' } } }); }); // submit button disable $$('form').each(function(form) { if(!form.hasClass('validation')) { form.addEvent('submit', function() { form.getElements('input[type=submit], input[type=button]').each(function(submit) { submit.set('disabled', true); }); }); } else { form.getElements('input').each(function(item) { item.set('autocomplete', 'off'); }); } }); // remove / cancel notification var message = 'Âû óâåðåíû?'; $$('a[rel=cancel], a[rel=remove], a[rel=alert]').each(function(item) { item.addEvent('click', function() { if(!confirm(message)) { return false; } }); }); // pointy tips new Tips.Pointy($$('a.input-help[title], img.help[title]'), { pointyTipOptions: { point: 9, pointyOptions: { theme: 'light' }, width: 200 } }); new Tips.Pointy($$('img[title]'), { pointyTipOptions: { point: 3, pointyOptions: { theme: 'light' }, width: 200 } }); $$('a.input-help[title]').each(function(item) { item.addEvent('click', function() { return false; }); }); // target blank for external $$('a[href^=http]').each(function(item) { item.set('target', '_blank'); }); // smooth scroll new Fx.SmoothScroll(); // cms: main data, text, binds $$('section.bind').each(function(section) { var a = section.getElement('h3 a'); var img = section.getElement('h3 img'); var box = section.getElement('.box'); if(!img.hasClass('minus')) { box.setStyle('display', 'none'); } if(a.get('href') == '#') { // toggle a.addEvent('click', function() { if(img.hasClass('minus')) { img.removeClass('minus'); box.setStyle('display', 'none'); } else { img.addClass('minus'); box.setStyle('display', ''); } return false; }); } else { // ajax loading box.addEvent('afterAjax', function() { box.getElements('a[href*=MoveUpObject], a[href*=MoveDownObject], a[href*=DeleteFromList]').each(function(item) { item.addEvent('click', function() { new Request.HTML({ useSpinner: true, update: box, onSuccess: function() { box.fireEvent('afterAjax'); }, onTimeout: function() { alert(123) } }).get(item.get('href')); return false; }); }); box.getElements('form').each(function(item) { new Form.Request(item, box, { requestOptions: { useSpinner: true }, onSend: function() { // alert(123) }, onSuccess: function() { box.fireEvent('afterAjax'); } }); }); $$('.bind input[type=button].setimage').each(function(button) { button.addEvent('click', function() { try { var id = $$('.bind input[name=OBJECT_IMAGE_ID]:checked')[0].value; $('IMAGE_ID').set('value', id); var src = $('OBJECT_IMAGE').get('src'); src = src.replace(/[0-9]+/, id); $('OBJECT_IMAGE').set('src', src); alert('Èçîáðàæåíèå çàìåíåíî, ñîõðàíèòå îñíîâíûå äàííûå ñòàòüè'); } catch(e) { alert('Èçîáðàæåíèå íå âûáðàíî'); } }); }); }); a.addEvent('click', function() { if(img.hasClass('minus')) { img.removeClass('minus'); box.setStyle('display', 'none'); } else { img.addClass('loading'); new Request.HTML({ useSpinner: true, update: box, onSuccess: function() { img.removeClass('loading'); img.addClass('minus'); box.setStyle('display', ''); box.fireEvent('afterAjax'); } }).get(a.get('href')); } return false; }); } }); // library show/hide extra info $$('.collapser').addEvent('click', function(event) { var td = $(this).getParent('td'); td.toggleClass('active'); if(td.hasClass('has-info')) { } else { var tr = this.getParent('tr').getNext('.tr-hided'); tr.toggleClass('off'); tr.toggleClass('active'); } return false; }); // library show/hide filters $$('.lf_collapser').addEvent('click', function(event) { var td = $(this).getParent('.libfilter'); td.toggleClass('active'); return false; }); $$('.lf_collapser').addEvent('click', function(event) { var div = $(this).getParent('.create_task'); div.toggleClass('active'); return false; }); // enable download - library article $$('.dl_switcher input').each(function(item) { item.addEvent('click', function() { $(this).getParent('.dl_switcher').getPrevious('ul').toggleClass('active'); }); }); // ebook font change var links = $$('.font a'); links.each(function(link) { link.addEvent('click', function() { links.each(function(item) { item.getParent().removeClass('active'); }); link.getParent().addClass('active'); $$('.ebook')[0].setStyle('font-size', link.getStyle('font-size')); return false; }); }); // pretty view $$('input[type=checkbox]', 'input[type=radio]').setStyle('border', 'none'); // linker $$('a[rel^=linker]').each(function(item) { var links = item.get('rel').replace('linker|', '').split('|'); var text = ''; item.addEvent('mouseenter', function() { var sticky = new StickyWin.PointyTip(text, { allowMultiple: false, className: 'linker', closeOnClickOut: true, offset: {x: -10, y: -10}, point: 11, pointyOptions: {theme: 'light'}, relativeTo: item }); sticky.win.getElements('a.yeslink, a.nolink').each(function(yeslink) { var li = yeslink.getParent(); if(yeslink.get('rel')==item.get('href')) { li.addClass('active'); } yeslink.addEvent('click', function() { if(yeslink.get('rel')!=item.get('href')) { item.set('href', yeslink.get('rel')); item.toggleClass('selected'); } sticky.hide(); return false; }); }); }); }); }); window.addEvent('keydown', function(event) { // ctrl -> if(event.control && event.key == 'right') { document.location = $$('.pager .next a')[0].get('href'); } // ctrl <- if(event.control && event.key == 'left') { document.location = $$('.pager .prev a')[0].get('href'); } }); window.addEvent('domready', function() { $$(".options").addEvent("mouseenter", function(){ $(this).toggleClass("hovered"); $(this).getNext().toggleClass("optionShow"); window.addEvent("click", function(e){ $$(".optionShow").removeClass('optionShow'); $$(".hovered").removeClass('hovered'); }) }) })