From 5f51ee4412721601980bc8cf6bf42f5231e4e781 Mon Sep 17 00:00:00 2001 From: tonio Date: Tue, 15 Jun 2010 11:24:44 +0200 Subject: [PATCH] Plugins can now declare separate css and js files. --- INSTALL | 4 +- .../static/css/quarantine.css | 8 + .../amavis_quarantine/templates/index.html | 9 +- .../templates/autoreply.html | 2 +- extensions/stats/templates/content.html | 2 +- extensions/webmail/static/css/webmail.css | 161 + extensions/webmail/templates/compose.html | 38 - extensions/webmail/templates/index.html | 119 +- scripts/extension.py | 13 + static/{stylesheets => css}/SqueezeBox.css | 0 static/{stylesheets => css}/box.css | 0 static/{stylesheets => css}/calendar.css | 0 static/{stylesheets => css}/closebox.png | Bin static/{stylesheets => css}/corner-tl.png | Bin static/{stylesheets => css}/default.css | 0 static/{stylesheets => css}/login.css | 0 static/{stylesheets => css}/logo-icon.png | Bin static/{stylesheets => css}/logo.png | Bin static/{stylesheets => css}/mailng.png | Bin static/{stylesheets => css}/searchbar.css | 0 static/{stylesheets => css}/spinner.gif | Bin static/js/infobox.js | 2 +- static/js/mootools-more.js | 2100 +------- static/js/mootools.js | 4461 +---------------- templates/common/email_listing.html | 4 +- templates/common/viewmail.html | 2 +- templates/layout_simple.html | 6 +- templates/nlayout.html | 8 +- templates/registration/login.html | 8 +- 29 files changed, 374 insertions(+), 6573 deletions(-) create mode 100644 extensions/amavis_quarantine/static/css/quarantine.css create mode 100644 extensions/webmail/static/css/webmail.css rename static/{stylesheets => css}/SqueezeBox.css (100%) rename static/{stylesheets => css}/box.css (100%) rename static/{stylesheets => css}/calendar.css (100%) rename static/{stylesheets => css}/closebox.png (100%) rename static/{stylesheets => css}/corner-tl.png (100%) rename static/{stylesheets => css}/default.css (100%) rename static/{stylesheets => css}/login.css (100%) rename static/{stylesheets => css}/logo-icon.png (100%) rename static/{stylesheets => css}/logo.png (100%) rename static/{stylesheets => css}/mailng.png (100%) rename static/{stylesheets => css}/searchbar.css (100%) rename static/{stylesheets => css}/spinner.gif (100%) diff --git a/INSTALL b/INSTALL index 26db0b628..146ca0ccf 100644 --- a/INSTALL +++ b/INSTALL @@ -269,7 +269,7 @@ Then, edit your /etc/dovecot/dovecot-sql.conf and modify following lines:: driver = mysql connect = host= dbname= user= password= - default_pass_scheme = PLAIN-MD5 + default_pass_scheme = CRYPT password_query = SELECT full_address AS user, password FROM admin_mailbox WHERE full_address = '%u' user_query = SELECT path AS home, uid, gid FROM admin_mailbox WHERE full_address = '%u' @@ -279,7 +279,7 @@ Enable quotas with Dovecot Put the following lines inside your dovecot.conf file:: protocol imap { - mail_plugins = quota quota_imap + mail_plugins = quota imap_quota } Before continuing, you need to know which quota backend must be user diff --git a/extensions/amavis_quarantine/static/css/quarantine.css b/extensions/amavis_quarantine/static/css/quarantine.css new file mode 100644 index 000000000..da2ff19ad --- /dev/null +++ b/extensions/amavis_quarantine/static/css/quarantine.css @@ -0,0 +1,8 @@ +thead tr { + position: relative; + z-index: 1; +} + +tr.table-tr-selected { + background: #ffffcc; +} \ No newline at end of file diff --git a/extensions/amavis_quarantine/templates/index.html b/extensions/amavis_quarantine/templates/index.html index 878e0549e..46c08901d 100644 --- a/extensions/amavis_quarantine/templates/index.html +++ b/extensions/amavis_quarantine/templates/index.html @@ -1,14 +1,7 @@ {% extends "common/email_listing.html" %} {% load i18n %} {% block css %} -thead tr { - position: relative; - z-index: 1; -} - -tr.table-tr-selected { - background: #ffffcc; -} + {% endblock %} {% block js %} mysubmit = function(event, name) { diff --git a/extensions/postfix_autoreply/templates/autoreply.html b/extensions/postfix_autoreply/templates/autoreply.html index 1ee731a23..2293038f0 100644 --- a/extensions/postfix_autoreply/templates/autoreply.html +++ b/extensions/postfix_autoreply/templates/autoreply.html @@ -3,7 +3,7 @@ {% block html_head %} + href="/static/css/calendar.css" /> -
diff --git a/extensions/webmail/templates/index.html b/extensions/webmail/templates/index.html index 30b58912d..2edaa9772 100644 --- a/extensions/webmail/templates/index.html +++ b/extensions/webmail/templates/index.html @@ -1,124 +1,7 @@ {% extends "common/email_listing.html" %} {% load i18n %} {% block css %} -#listing { - position: absolute; - left: 155px; - right: 0px; - top: 130px; - height: expression(document.body.clientHeight - 35 + "px"); - overflow: auto; -} - -html > body #listing { - position: fixed; - bottom: 35px; -} - -#folders { - float: left; - width: 150px; -} - -/*thead tr { - position: relative; - top: expression(offsetParent.scrollTop); /*IE5+ only*/ - z-index: 1; - padding: 0; -}*/ - -/*table#emails > tbody { - position: fixed; - bottom: 35px; - top: 155px; - left: 155px; - right: 0px; - overflow-x: hidden; - overflow-y: auto; -}*/ - -#emails th { - position: relative; -} - -#emails tr { - width: 100%; - /*position: relative;*/ - border-bottom: 1px solid #C8D6E8; -} - -tr.selected { - background: #ffffcc; -} - -.box h3 { - font-size: small; - margin: 2px 0px 2px 0px; - text-align: center; -} - -.box ul { - list-style: none; - padding: 5px 5px; - margin: 0; -} - -.box li { - clear: both; - margin-bottom: 4px; -} - -.box li.selected { - background: #ffffcc; - position: relative; -} - -.box a:link, .box a:visited { - background: transparent; - color: black; - /*font-weight: bold;*/ - text-decoration: none; -} - -.box a:hover { - color: #6AB0C5; - text-decoration: none; -} - -.box img { - float: left; - margin-right: 2px; - border: 0; -} - -th { - /*-moz-box-shadow: 0px -15px 10px -10px rgba(0,0,0,0.6) inset; - -webkit-box-shadow: 0px -15px 10px -10px rgba(0,0,0,0.6) inset;*/ -} - -th.selected { - background: #EEEEEE; -} - -.draggable { - cursor: move; -} - -.dragging { - background: #6AB0C5; -} - -ul.hidden { - display: none; -} - -ul.visible { - background: white; - display: block; - padding-bottom: 0; - padding-left: 10px; -} - + {% endblock %} {% block js %} wm_updatelisting = function(resp) { diff --git a/scripts/extension.py b/scripts/extension.py index 3b98ce22b..3ff4078c6 100755 --- a/scripts/extension.py +++ b/scripts/extension.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- import os, sys +import glob from django.conf import settings def usage(): @@ -16,6 +17,18 @@ def update_extension(name, extdir, state): or "rm %s/%s" % (d, name) os.system(cmd) + staticpath = "%s/%s" % (extdir, "static") + if os.path.isdir(staticpath): + for d in ['css', 'js']: + subpath = "%s/%s" % (staticpath, d) + if not os.path.isdir(subpath): + continue + for f in glob.glob("%s/*.%s" % (subpath, d)): + cmd = state == "on" \ + and "ln -s %s static/%s" % (f, d) \ + or "rm static/%s/%s" % (d, os.path.basename(f)) + os.system(cmd) + if __name__ == "__main__": if len(sys.argv) != 3: usage() diff --git a/static/stylesheets/SqueezeBox.css b/static/css/SqueezeBox.css similarity index 100% rename from static/stylesheets/SqueezeBox.css rename to static/css/SqueezeBox.css diff --git a/static/stylesheets/box.css b/static/css/box.css similarity index 100% rename from static/stylesheets/box.css rename to static/css/box.css diff --git a/static/stylesheets/calendar.css b/static/css/calendar.css similarity index 100% rename from static/stylesheets/calendar.css rename to static/css/calendar.css diff --git a/static/stylesheets/closebox.png b/static/css/closebox.png similarity index 100% rename from static/stylesheets/closebox.png rename to static/css/closebox.png diff --git a/static/stylesheets/corner-tl.png b/static/css/corner-tl.png similarity index 100% rename from static/stylesheets/corner-tl.png rename to static/css/corner-tl.png diff --git a/static/stylesheets/default.css b/static/css/default.css similarity index 100% rename from static/stylesheets/default.css rename to static/css/default.css diff --git a/static/stylesheets/login.css b/static/css/login.css similarity index 100% rename from static/stylesheets/login.css rename to static/css/login.css diff --git a/static/stylesheets/logo-icon.png b/static/css/logo-icon.png similarity index 100% rename from static/stylesheets/logo-icon.png rename to static/css/logo-icon.png diff --git a/static/stylesheets/logo.png b/static/css/logo.png similarity index 100% rename from static/stylesheets/logo.png rename to static/css/logo.png diff --git a/static/stylesheets/mailng.png b/static/css/mailng.png similarity index 100% rename from static/stylesheets/mailng.png rename to static/css/mailng.png diff --git a/static/stylesheets/searchbar.css b/static/css/searchbar.css similarity index 100% rename from static/stylesheets/searchbar.css rename to static/css/searchbar.css diff --git a/static/stylesheets/spinner.gif b/static/css/spinner.gif similarity index 100% rename from static/stylesheets/spinner.gif rename to static/css/spinner.gif diff --git a/static/js/infobox.js b/static/js/infobox.js index a28b76bac..b35054ec2 100644 --- a/static/js/infobox.js +++ b/static/js/infobox.js @@ -31,7 +31,7 @@ var InfoBox = new Class({ }); this.setProfile("gray"); this.spinner = new Element("img", { - "src" : "/static/stylesheets/spinner.gif" + "src" : "/static/css/spinner.gif" }); this.spinner.setStyle("float", "left"); this.spinner.inject(this.box); diff --git a/static/js/mootools-more.js b/static/js/mootools-more.js index 58b45bc8c..bf8611d2e 100644 --- a/static/js/mootools-more.js +++ b/static/js/mootools-more.js @@ -1,2062 +1,40 @@ -//MooTools More, . Copyright (c) 2006-2009 Aaron Newton , Valerio Proietti & the MooTools team , MIT Style License. -/* ---- - -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: Log.js - -description: Provides basic logging functionality for plugins to implement. - -license: MIT-style license - -authors: -- Guillermo Rauch -- Thomas Aylott -- Scott Kyle - -requires: -- core:1.2.4/Class -- /MooTools.More - -provides: [Log] - -... -*/ - -(function(){ - -var global = this; - -var log = function(){ - if (global.console && console.log){ - try { - console.log.apply(console, arguments); - } catch(e) { - console.log(Array.slice(arguments)); - } - } else { - Log.logged.push(arguments); - } - return this; -}; - -var disabled = function(){ - this.logged.push(arguments); - return this; -}; - -this.Log = new Class({ - - logged: [], - - log: disabled, - - resetLog: function(){ - this.logged.empty(); - return this; - }, - - enableLog: function(){ - this.log = log; - this.logged.each(function(args){ - this.log.apply(this, args); - }, this); - return this.resetLog(); - }, - - disableLog: function(){ - this.log = disabled; - return this; - } - -}); - -Log.extend(new Log).enableLog(); - -// legacy -Log.logger = function(){ - return this.log.apply(this, arguments); -}; - -})(); - -/* ---- - -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: 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: Element.Delegation.js - -description: Extends the Element native object to include the delegate method for more efficient event management. - -credits: -- "Event checking based on the work of Daniel Steigerwald. License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz" - -license: MIT-style license - -authors: -- Aaron Newton -- Daniel Steigerwald - -requires: -- core:1.2.4/Element.Event -- core:1.2.4/Selectors -- /MooTools.More - -provides: [Element.Delegation] - -... -*/ - -(function(addEvent, removeEvent){ - - var match = /(.*?):relay\(([^)]+)\)$/, - combinators = /[+>~\s]/, - splitType = function(type){ - var bits = type.match(match); - return !bits ? {event: type} : { - event: bits[1], - selector: bits[2] - }; - }, - check = function(e, selector){ - var t = e.target; - if (combinators.test(selector = selector.trim())){ - var els = this.getElements(selector); - for (var i = els.length; i--; ){ - var el = els[i]; - if (t == el || el.hasChild(t)) return el; - } - } else { - for ( ; t && t != this; t = t.parentNode){ - if (Element.match(t, selector)) return document.id(t); - } - } - return null; - }; - - Element.implement({ - - addEvent: function(type, fn){ - var splitted = splitType(type); - if (splitted.selector){ - var monitors = this.retrieve('$moo:delegateMonitors', {}); - if (!monitors[type]){ - var monitor = function(e){ - var el = check.call(this, e, splitted.selector); - if (el) this.fireEvent(type, [e, el], 0, el); - }.bind(this); - monitors[type] = monitor; - addEvent.call(this, splitted.event, monitor); - } - } - return addEvent.apply(this, arguments); - }, - - removeEvent: function(type, fn){ - var splitted = splitType(type); - if (splitted.selector){ - var events = this.retrieve('events'); - if (!events || !events[type] || (fn && !events[type].keys.contains(fn))) return this; - - if (fn) removeEvent.apply(this, [type, fn]); - else removeEvent.apply(this, type); - - events = this.retrieve('events'); - if (events && events[type] && events[type].keys.length == 0){ - var monitors = this.retrieve('$moo:delegateMonitors', {}); - removeEvent.apply(this, [splitted.event, monitors[type]]); - delete monitors[type]; - } - return this; - } - return removeEvent.apply(this, arguments); - }, - - fireEvent: function(type, args, delay, bind){ - var events = this.retrieve('events'); - if (!events || !events[type]) return this; - events[type].keys.each(function(fn){ - fn.create({bind: bind || this, delay: delay, arguments: args})(); - }, this); - return this; - } - - }); - -})(Element.prototype.addEvent, Element.prototype.removeEvent); - -/* ---- - -script: Fx.Elements.js - -description: Effect to change any number of CSS properties of any number of Elements. - -license: MIT-style license - -authors: -- Valerio Proietti - -requires: -- core:1.2.4/Fx.CSS -- /MooTools.More - -provides: [Fx.Elements] - -... -*/ - -Fx.Elements = new Class({ - - Extends: Fx.CSS, - - initialize: function(elements, options){ - this.elements = this.subject = $$(elements); - this.parent(options); - }, - - compute: function(from, to, delta){ - var now = {}; - for (var i in from){ - var iFrom = from[i], iTo = to[i], iNow = now[i] = {}; - for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta); - } - return now; - }, - - set: function(now){ - for (var i in now){ - var iNow = now[i]; - for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit); - } - return this; - }, - - start: function(obj){ - if (!this.check(obj)) return this; - var from = {}, to = {}; - for (var i in obj){ - var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {}; - for (var p in iProps){ - var parsed = this.prepare(this.elements[i], p, iProps[p]); - iFrom[p] = parsed.from; - iTo[p] = parsed.to; - } - } - return this.parent(from, to); - } - -}); - -/* ---- - -script: Fx.Accordion.js - -description: An Fx.Elements extension which allows you to easily create accordion type controls. - -license: MIT-style license - -authors: -- Valerio Proietti - -requires: -- core:1.2.4/Element.Event -- /Fx.Elements - -provides: [Fx.Accordion] - -... -*/ - -Fx.Accordion = new Class({ - - Extends: Fx.Elements, - - options: {/* - onActive: $empty(toggler, section), - onBackground: $empty(toggler, section), - fixedHeight: false, - fixedWidth: false, - */ - display: 0, - show: false, - height: true, - width: false, - opacity: true, - alwaysHide: false, - trigger: 'click', - initialDisplayFx: true, - returnHeightToAuto: true - }, - - initialize: function(){ - var params = Array.link(arguments, { - 'container': Element.type, //deprecated - 'options': Object.type, - 'togglers': $defined, - 'elements': $defined - }); - this.parent(params.elements, params.options); - this.togglers = $$(params.togglers); - this.previous = -1; - this.internalChain = new Chain(); - if (this.options.alwaysHide) this.options.wait = true; - if ($chk(this.options.show)){ - this.options.display = false; - this.previous = this.options.show; - } - if (this.options.start){ - this.options.display = false; - this.options.show = false; - } - this.effects = {}; - if (this.options.opacity) this.effects.opacity = 'fullOpacity'; - if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth'; - if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight'; - for (var i = 0, l = this.togglers.length; i < l; i++) this.addSection(this.togglers[i], this.elements[i]); - this.elements.each(function(el, i){ - if (this.options.show === i){ - this.fireEvent('active', [this.togglers[i], el]); - } else { - for (var fx in this.effects) el.setStyle(fx, 0); - } - }, this); - if ($chk(this.options.display) || this.options.initialDisplayFx === false) this.display(this.options.display, this.options.initialDisplayFx); - if (this.options.fixedHeight !== false) this.options.returnHeightToAuto = false; - this.addEvent('complete', this.internalChain.callChain.bind(this.internalChain)); - }, - - addSection: function(toggler, element){ - toggler = document.id(toggler); - element = document.id(element); - var test = this.togglers.contains(toggler); - this.togglers.include(toggler); - this.elements.include(element); - var idx = this.togglers.indexOf(toggler); - var displayer = this.display.bind(this, idx); - toggler.store('accordion:display', displayer); - toggler.addEvent(this.options.trigger, displayer); - if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'}); - if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'}); - element.fullOpacity = 1; - if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth; - if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight; - element.setStyle('overflow', 'hidden'); - if (!test){ - for (var fx in this.effects) element.setStyle(fx, 0); - } - return this; - }, - - detach: function(){ - this.togglers.each(function(toggler) { - toggler.removeEvent(this.options.trigger, toggler.retrieve('accordion:display')); - }, this); - }, - - display: function(index, useFx){ - if (!this.check(index, useFx)) return this; - useFx = $pick(useFx, true); - if (this.options.returnHeightToAuto){ - var prev = this.elements[this.previous]; - if (prev && !this.selfHidden){ - for (var fx in this.effects){ - prev.setStyle(fx, prev[this.effects[fx]]); - } - } - } - index = ($type(index) == 'element') ? this.elements.indexOf(index) : index; - if ((this.timer && this.options.wait) || (index === this.previous && !this.options.alwaysHide)) return this; - this.previous = index; - var obj = {}; - this.elements.each(function(el, i){ - obj[i] = {}; - var hide; - if (i != index){ - hide = true; - } else if (this.options.alwaysHide && ((el.offsetHeight > 0 && this.options.height) || el.offsetWidth > 0 && this.options.width)){ - hide = true; - this.selfHidden = true; - } - this.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]); - for (var fx in this.effects) obj[i][fx] = hide ? 0 : el[this.effects[fx]]; - }, this); - this.internalChain.chain(function(){ - if (this.options.returnHeightToAuto && !this.selfHidden){ - var el = this.elements[index]; - if (el) el.setStyle('height', 'auto'); - }; - }.bind(this)); - return useFx ? this.start(obj) : this.set(obj); - } - -}); - -/* - Compatibility with 1.2.0 -*/ -var Accordion = new Class({ - - Extends: Fx.Accordion, - - initialize: function(){ - this.parent.apply(this, arguments); - var params = Array.link(arguments, {'container': Element.type}); - this.container = params.container; - }, - - addSection: function(toggler, element, pos){ - toggler = document.id(toggler); - element = document.id(element); - var test = this.togglers.contains(toggler); - var len = this.togglers.length; - if (len && (!test || pos)){ - pos = $pick(pos, len - 1); - toggler.inject(this.togglers[pos], 'before'); - element.inject(toggler, 'after'); - } else if (this.container && !test){ - toggler.inject(this.container); - element.inject(this.container); - } - return this.parent.apply(this, arguments); - } - -}); - -/* ---- - -script: Fx.Slide.js - -description: Effect to slide an element in and out of view. - -license: MIT-style license - -authors: -- Valerio Proietti - -requires: -- core:1.2.4/Fx Element.Style -- /MooTools.More - -provides: [Fx.Slide] - -... -*/ - -Fx.Slide = new Class({ - - Extends: Fx, - - options: { - mode: 'vertical', - wrapper: false, - hideOverflow: true - }, - - initialize: function(element, options){ - this.addEvent('complete', function(){ - this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0); - if (this.open) this.wrapper.setStyle('height', ''); - if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper); - }, true); - this.element = this.subject = document.id(element); - this.parent(options); - var wrapper = this.element.retrieve('wrapper'); - var styles = this.element.getStyles('margin', 'position', 'overflow'); - if (this.options.hideOverflow) styles = $extend(styles, {overflow: 'hidden'}); - if (this.options.wrapper) wrapper = document.id(this.options.wrapper).setStyles(styles); - this.wrapper = wrapper || new Element('div', { - styles: styles - }).wraps(this.element); - this.element.store('wrapper', this.wrapper).setStyle('margin', 0); - this.now = []; - this.open = true; - }, - - vertical: function(){ - this.margin = 'margin-top'; - this.layout = 'height'; - this.offset = this.element.offsetHeight; - }, - - horizontal: function(){ - this.margin = 'margin-left'; - this.layout = 'width'; - this.offset = this.element.offsetWidth; - }, - - set: function(now){ - this.element.setStyle(this.margin, now[0]); - this.wrapper.setStyle(this.layout, now[1]); - return this; - }, - - compute: function(from, to, delta){ - return [0, 1].map(function(i){ - return Fx.compute(from[i], to[i], delta); - }); - }, - - start: function(how, mode){ - if (!this.check(how, mode)) return this; - this[mode || this.options.mode](); - var margin = this.element.getStyle(this.margin).toInt(); - var layout = this.wrapper.getStyle(this.layout).toInt(); - var caseIn = [[margin, layout], [0, this.offset]]; - var caseOut = [[margin, layout], [-this.offset, 0]]; - var start; - switch (how){ - case 'in': start = caseIn; break; - case 'out': start = caseOut; break; - case 'toggle': start = (layout == 0) ? caseIn : caseOut; - } - return this.parent(start[0], start[1]); - }, - - slideIn: function(mode){ - return this.start('in', mode); - }, - - slideOut: function(mode){ - return this.start('out', mode); - }, - - hide: function(mode){ - this[mode || this.options.mode](); - this.open = false; - return this.set([-this.offset, 0]); - }, - - show: function(mode){ - this[mode || this.options.mode](); - this.open = true; - return this.set([0, this.offset]); - }, - - toggle: function(mode){ - return this.start('toggle', mode); - } - -}); - -Element.Properties.slide = { - - set: function(options){ - var slide = this.retrieve('slide'); - if (slide) slide.cancel(); - return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options)); - }, - - get: function(options){ - if (options || !this.retrieve('slide')){ - if (options || !this.retrieve('slide:options')) this.set('slide', options); - this.store('slide', new Fx.Slide(this, this.retrieve('slide:options'))); - } - return this.retrieve('slide'); - } - -}; - -Element.implement({ - - slide: function(how, mode){ - how = how || 'toggle'; - var slide = this.get('slide'), toggle; - switch (how){ - case 'hide': slide.hide(mode); break; - case 'show': slide.show(mode); break; - case 'toggle': - var flag = this.retrieve('slide:flag', slide.open); - slide[flag ? 'slideOut' : 'slideIn'](mode); - this.store('slide:flag', !flag); - toggle = true; - break; - default: slide.start(how, mode); - } - if (!toggle) this.eliminate('slide:flag'); - return this; - } - -}); - - -/* ---- - -script: Drag.js - -description: The base Drag Class. Can be used to drag and resize Elements using mouse events. - -license: MIT-style license - -authors: -- Valerio Proietti -- Tom Occhinno -- Jan Kassens - -requires: -- core:1.2.4/Events -- core:1.2.4/Options -- core:1.2.4/Element.Event -- core:1.2.4/Element.Style -- /MooTools.More - -provides: [Drag] - -*/ - -var Drag = new Class({ - - Implements: [Events, Options], - - options: {/* - onBeforeStart: $empty(thisElement), - onStart: $empty(thisElement, event), - onSnap: $empty(thisElement) - onDrag: $empty(thisElement, event), - onCancel: $empty(thisElement), - onComplete: $empty(thisElement, event),*/ - snap: 6, - unit: 'px', - grid: false, - style: true, - limit: false, - handle: false, - invert: false, - preventDefault: false, - stopPropagation: false, - modifiers: {x: 'left', y: 'top'} - }, - - initialize: function(){ - var params = Array.link(arguments, {'options': Object.type, 'element': $defined}); - this.element = document.id(params.element); - this.document = this.element.getDocument(); - this.setOptions(params.options || {}); - var htype = $type(this.options.handle); - this.handles = ((htype == 'array' || htype == 'collection') ? $$(this.options.handle) : document.id(this.options.handle)) || this.element; - this.mouse = {'now': {}, 'pos': {}}; - this.value = {'start': {}, 'now': {}}; - - this.selection = (Browser.Engine.trident) ? 'selectstart' : 'mousedown'; - - this.bound = { - start: this.start.bind(this), - check: this.check.bind(this), - drag: this.drag.bind(this), - stop: this.stop.bind(this), - cancel: this.cancel.bind(this), - eventStop: $lambda(false) - }; - this.attach(); - }, - - attach: function(){ - this.handles.addEvent('mousedown', this.bound.start); - return this; - }, - - detach: function(){ - this.handles.removeEvent('mousedown', this.bound.start); - return this; - }, - - start: function(event){ - if (event.rightClick) return; - if (this.options.preventDefault) event.preventDefault(); - if (this.options.stopPropagation) event.stopPropagation(); - this.mouse.start = event.page; - this.fireEvent('beforeStart', this.element); - var limit = this.options.limit; - this.limit = {x: [], y: []}; - for (var z in this.options.modifiers){ - if (!this.options.modifiers[z]) continue; - if (this.options.style) this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt(); - else this.value.now[z] = this.element[this.options.modifiers[z]]; - if (this.options.invert) this.value.now[z] *= -1; - /*this.mouse.pos[z] = event.page[z] - this.value.now[z];*/ - this.mouse.pos[z] = this.value.now[z]; - if (limit && limit[z]){ - for (var i = 2; i--; i){ - if ($chk(limit[z][i])) this.limit[z][i] = $lambda(limit[z][i])(); - } - } - } - if ($type(this.options.grid) == 'number') this.options.grid = {x: this.options.grid, y: this.options.grid}; - this.document.addEvents({mousemove: this.bound.check, mouseup: this.bound.cancel}); - this.document.addEvent(this.selection, this.bound.eventStop); - }, - - check: function(event){ - if (this.options.preventDefault) event.preventDefault(); - var distance = Math.round(Math.sqrt(Math.pow(event.page.x - this.mouse.start.x, 2) + Math.pow(event.page.y - this.mouse.start.y, 2))); - if (distance > this.options.snap){ - this.cancel(); - this.document.addEvents({ - mousemove: this.bound.drag, - mouseup: this.bound.stop - }); - this.fireEvent('start', [this.element, event]).fireEvent('snap', this.element); - } - }, - - drag: function(event){ - if (this.options.preventDefault) event.preventDefault(); - this.mouse.now = event.page; - for (var z in this.options.modifiers){ - if (!this.options.modifiers[z]) continue; - this.value.now[z] = this.mouse.now[z] - this.mouse.pos[z]; - if (this.options.invert) this.value.now[z] *= -1; - if (this.options.limit && this.limit[z]){ - if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){ - this.value.now[z] = this.limit[z][1]; - } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){ - this.value.now[z] = this.limit[z][0]; - } - } - if (this.options.grid[z]) this.value.now[z] -= ((this.value.now[z] - (this.limit[z][0]||0)) % this.options.grid[z]); - if (this.options.style) { - this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit); - } else { - this.element[this.options.modifiers[z]] = this.value.now[z]; - } - } - this.fireEvent('drag', [this.element, event]); - }, - - cancel: function(event){ - this.document.removeEvent('mousemove', this.bound.check); - this.document.removeEvent('mouseup', this.bound.cancel); - if (event){ - this.document.removeEvent(this.selection, this.bound.eventStop); - this.fireEvent('cancel', this.element); - } - }, - - stop: function(event){ - this.document.removeEvent(this.selection, this.bound.eventStop); - this.document.removeEvent('mousemove', this.bound.drag); - this.document.removeEvent('mouseup', this.bound.stop); - if (event) this.fireEvent('complete', [this.element, event]); - } - -}); - -Element.implement({ - - makeResizable: function(options){ - var drag = new Drag(this, $merge({modifiers: {x: 'width', y: 'height'}}, options)); - this.store('resizer', drag); - return drag.addEvent('drag', function(){ - this.fireEvent('resize', drag); - }.bind(this)); - } - -}); - - -/* ---- - -script: Drag.Move.js - -description: A Drag extension that provides support for the constraining of draggables to containers and droppables. - -license: MIT-style license - -authors: -- Valerio Proietti -- Tom Occhinno -- Jan Kassens -- Aaron Newton -- Scott Kyle - -requires: -- core:1.2.4/Element.Dimensions -- /Drag - -provides: [Drag.Move] - -... -*/ - -Drag.Move = new Class({ - - Extends: Drag, - - options: {/* - onEnter: $empty(thisElement, overed), - onLeave: $empty(thisElement, overed), - onDrop: $empty(thisElement, overed, event),*/ - droppables: [], - container: false, - precalculate: false, - includeMargins: true, - checkDroppables: true - }, - - initialize: function(element, options){ - this.parent(element, options); - element = this.element; - - this.droppables = $$(this.options.droppables); - this.container = document.id(this.options.container); - - if (this.container && $type(this.container) != 'element') - this.container = document.id(this.container.getDocument().body); - - var styles = element.getStyles('left', 'top', 'position'); - if (styles.left == 'auto' || styles.top == 'auto') - element.setPosition(element.getPosition(element.getOffsetParent())); - - if (styles.position == 'static') - element.setStyle('position', 'absolute'); - - this.addEvent('start', this.checkDroppables, true); - - this.overed = null; - }, - - start: function(event){ - if (this.container) this.options.limit = this.calculateLimit(); - - if (this.options.precalculate){ - this.positions = this.droppables.map(function(el){ - return el.getCoordinates(); - }); - } - - this.parent(event); - }, - - calculateLimit: function(){ - var offsetParent = this.element.getOffsetParent(), - containerCoordinates = this.container.getCoordinates(offsetParent), - containerBorder = {}, - elementMargin = {}, - elementBorder = {}, - containerMargin = {}, - offsetParentPadding = {}; - - ['top', 'right', 'bottom', 'left'].each(function(pad){ - containerBorder[pad] = this.container.getStyle('border-' + pad).toInt(); - elementBorder[pad] = this.element.getStyle('border-' + pad).toInt(); - elementMargin[pad] = this.element.getStyle('margin-' + pad).toInt(); - containerMargin[pad] = this.container.getStyle('margin-' + pad).toInt(); - offsetParentPadding[pad] = offsetParent.getStyle('padding-' + pad).toInt(); - }, this); - - var width = this.element.offsetWidth + elementMargin.left + elementMargin.right, - height = this.element.offsetHeight + elementMargin.top + elementMargin.bottom, - left = 0, - top = 0, - right = containerCoordinates.right - containerBorder.right - width, - bottom = containerCoordinates.bottom - containerBorder.bottom - height; - - if (this.options.includeMargins){ - left += elementMargin.left; - top += elementMargin.top; - } else { - right += elementMargin.right; - bottom += elementMargin.bottom; - } - - if (this.element.getStyle('position') == 'relative'){ - var coords = this.element.getCoordinates(offsetParent); - coords.left -= this.element.getStyle('left').toInt(); - coords.top -= this.element.getStyle('top').toInt(); - - left += containerBorder.left - coords.left; - top += containerBorder.top - coords.top; - right += elementMargin.left - coords.left; - bottom += elementMargin.top - coords.top; - - if (this.container != offsetParent){ - left += containerMargin.left + offsetParentPadding.left; - top += (Browser.Engine.trident4 ? 0 : containerMargin.top) + offsetParentPadding.top; - } - } else { - left -= elementMargin.left; - top -= elementMargin.top; - - if (this.container == offsetParent){ - right -= containerBorder.left; - bottom -= containerBorder.top; - } else { - left += containerCoordinates.left + containerBorder.left; - top += containerCoordinates.top + containerBorder.top; - } - } - - return { - x: [left, right], - y: [top, bottom] - }; - }, - - checkAgainst: function(el, i){ - el = (this.positions) ? this.positions[i] : el.getCoordinates(); - var now = this.mouse.now; - return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top); - }, - - checkDroppables: function(){ - var overed = this.droppables.filter(this.checkAgainst, this).getLast(); - if (this.overed != overed){ - if (this.overed) this.fireEvent('leave', [this.element, this.overed]); - if (overed) this.fireEvent('enter', [this.element, overed]); - this.overed = overed; - } - }, - - drag: function(event){ - this.parent(event); - if (this.options.checkDroppables && this.droppables.length) this.checkDroppables(); - }, - - stop: function(event){ - this.checkDroppables(); - this.fireEvent('drop', [this.element, this.overed, event]); - this.overed = null; - return this.parent(event); - } - -}); - -Element.implement({ - - makeDraggable: function(options){ - var drag = new Drag.Move(this, options); - this.store('dragger', drag); - return drag; - } - -}); - - -/* ---- - -script: Sortables.js - -description: Class for creating a drag and drop sorting interface for lists of items. - -license: MIT-style license - -authors: -- Tom Occhino - -requires: -- /Drag.Move - -provides: [Slider] - -... -*/ - -var Sortables = new Class({ - - Implements: [Events, Options], - - options: {/* - onSort: $empty(element, clone), - onStart: $empty(element, clone), - onComplete: $empty(element),*/ - snap: 4, - opacity: 1, - clone: false, - revert: false, - handle: false, - constrain: false - }, - - initialize: function(lists, options){ - this.setOptions(options); - this.elements = []; - this.lists = []; - this.idle = true; - - this.addLists($$(document.id(lists) || lists)); - if (!this.options.clone) this.options.revert = false; - if (this.options.revert) this.effect = new Fx.Morph(null, $merge({duration: 250, link: 'cancel'}, this.options.revert)); - }, - - attach: function(){ - this.addLists(this.lists); - return this; - }, - - detach: function(){ - this.lists = this.removeLists(this.lists); - return this; - }, - - addItems: function(){ - Array.flatten(arguments).each(function(element){ - this.elements.push(element); - var start = element.retrieve('sortables:start', this.start.bindWithEvent(this, element)); - (this.options.handle ? element.getElement(this.options.handle) || element : element).addEvent('mousedown', start); - }, this); - return this; - }, - - addLists: function(){ - Array.flatten(arguments).each(function(list){ - this.lists.push(list); - this.addItems(list.getChildren()); - }, this); - return this; - }, - - removeItems: function(){ - return $$(Array.flatten(arguments).map(function(element){ - this.elements.erase(element); - var start = element.retrieve('sortables:start'); - (this.options.handle ? element.getElement(this.options.handle) || element : element).removeEvent('mousedown', start); - - return element; - }, this)); - }, - - removeLists: function(){ - return $$(Array.flatten(arguments).map(function(list){ - this.lists.erase(list); - this.removeItems(list.getChildren()); - - return list; - }, this)); - }, - - getClone: function(event, element){ - if (!this.options.clone) return new Element('div').inject(document.body); - if ($type(this.options.clone) == 'function') return this.options.clone.call(this, event, element, this.list); - var clone = element.clone(true).setStyles({ - margin: '0px', - position: 'absolute', - visibility: 'hidden', - 'width': element.getStyle('width') - }); - //prevent the duplicated radio inputs from unchecking the real one - if (clone.get('html').test('radio')) { - clone.getElements('input[type=radio]').each(function(input, i) { - input.set('name', 'clone_' + i); - }); - } - - return clone.inject(this.list).setPosition(element.getPosition(element.getOffsetParent())); - }, - - getDroppables: function(){ - var droppables = this.list.getChildren(); - if (!this.options.constrain) droppables = this.lists.concat(droppables).erase(this.list); - return droppables.erase(this.clone).erase(this.element); - }, - - insert: function(dragging, element){ - var where = 'inside'; - if (this.lists.contains(element)){ - this.list = element; - this.drag.droppables = this.getDroppables(); - } else { - where = this.element.getAllPrevious().contains(element) ? 'before' : 'after'; - } - this.element.inject(element, where); - this.fireEvent('sort', [this.element, this.clone]); - }, - - start: function(event, element){ - if (!this.idle) return; - this.idle = false; - this.element = element; - this.opacity = element.get('opacity'); - this.list = element.getParent(); - this.clone = this.getClone(event, element); - - this.drag = new Drag.Move(this.clone, { - snap: this.options.snap, - container: this.options.constrain && this.element.getParent(), - droppables: this.getDroppables(), - onSnap: function(){ - event.stop(); - this.clone.setStyle('visibility', 'visible'); - this.element.set('opacity', this.options.opacity || 0); - this.fireEvent('start', [this.element, this.clone]); - }.bind(this), - onEnter: this.insert.bind(this), - onCancel: this.reset.bind(this), - onComplete: this.end.bind(this) - }); - - this.clone.inject(this.element, 'before'); - this.drag.start(event); - }, - - end: function(){ - this.drag.detach(); - this.element.set('opacity', this.opacity); - if (this.effect){ - var dim = this.element.getStyles('width', 'height'); - var pos = this.clone.computePosition(this.element.getPosition(this.clone.offsetParent)); - this.effect.element = this.clone; - this.effect.start({ - top: pos.top, - left: pos.left, - width: dim.width, - height: dim.height, - opacity: 0.25 - }).chain(this.reset.bind(this)); - } else { - this.reset(); - } - }, - - reset: function(){ - this.idle = true; - this.clone.destroy(); - this.fireEvent('complete', this.element); - }, - - serialize: function(){ - var params = Array.link(arguments, {modifier: Function.type, index: $defined}); - var serial = this.lists.map(function(list){ - return list.getChildren().map(params.modifier || function(element){ - return element.get('id'); - }, this); - }, this); - - var index = params.index; - if (this.lists.length == 1) index = 0; - return $chk(index) && index >= 0 && index < this.lists.length ? serial[index] : serial; - } - -}); - - -/* ---- - -script: HtmlTable.js - -description: Builds table elements with methods to add rows. - -license: MIT-style license - -authors: -- Aaron Newton - -requires: -- core:1.2.4/Options -- core:1.2.4/Events -- /Class.Occlude - -provides: [HtmlTable] - -... -*/ - -var HtmlTable = new Class({ - - Implements: [Options, Events, Class.Occlude], - - options: { - properties: { - cellpadding: 0, - cellspacing: 0, - border: 0 - }, - rows: [], - headers: [], - footers: [] - }, - - property: 'HtmlTable', - - initialize: function(){ - var params = Array.link(arguments, {options: Object.type, table: Element.type}); - this.setOptions(params.options); - this.element = params.table || new Element('table', this.options.properties); - if (this.occlude()) return this.occluded; - this.build(); - }, - - build: function(){ - this.element.store('HtmlTable', this); - - this.body = document.id(this.element.tBodies[0]) || new Element('tbody').inject(this.element); - $$(this.body.rows); - - if (this.options.headers.length) this.setHeaders(this.options.headers); - else this.thead = document.id(this.element.tHead); - if (this.thead) this.head = document.id(this.thead.rows[0]); - - if (this.options.footers.length) this.setFooters(this.options.footers); - this.tfoot = document.id(this.element.tFoot); - if (this.tfoot) this.foot = document.id(this.thead.rows[0]); - - this.options.rows.each(function(row){ - this.push(row); - }, this); - - ['adopt', 'inject', 'wraps', 'grab', 'replaces', 'dispose'].each(function(method){ - this[method] = this.element[method].bind(this.element); - }, this); - }, - - toElement: function(){ - return this.element; - }, - - empty: function(){ - this.body.empty(); - return this; - }, - - set: function(what, items) { - var target = (what == 'headers') ? 'tHead' : 'tFoot'; - this[target.toLowerCase()] = (document.id(this.element[target]) || new Element(target.toLowerCase()).inject(this.element, 'top')).empty(); - var data = this.push(items, {}, this[target.toLowerCase()], what == 'headers' ? 'th' : 'td'); - if (what == 'headers') this.head = document.id(this.thead.rows[0]); - else this.foot = document.id(this.thead.rows[0]); - return data; - }, - - setHeaders: function(headers){ - this.set('headers', headers); - return this; - }, - - setFooters: function(footers){ - this.set('footers', footers); - return this; - }, - - push: function(row, rowProperties, target, tag){ - var tds = row.map(function(data){ - var td = new Element(tag || 'td', data.properties), - type = data.content || data || '', - element = document.id(type); - if($type(type) != 'string' && element) td.adopt(element); - else td.set('html', type); - - return td; - }); - - return { - tr: new Element('tr', rowProperties).inject(target || this.body).adopt(tds), - tds: tds - }; - } - -}); - - -/* ---- - -script: HtmlTable.Select.js - -description: Builds a stripy, sortable table with methods to add rows. Rows can be selected with the mouse or keyboard navigation. - -license: MIT-style license - -authors: -- Harald Kirschner -- Aaron Newton - -requires: -- /Keyboard -- /HtmlTable -- /Class.refactor -- /Element.Delegation - -provides: [HtmlTable.Select] - -... -*/ - -HtmlTable = Class.refactor(HtmlTable, { - - options: { - /*onRowFocus: $empty, - onRowUnfocus: $empty,*/ - useKeyboard: true, - classRowSelected: 'table-tr-selected', - classRowHovered: 'table-tr-hovered', - classSelectable: 'table-selectable', - allowMultiSelect: true, - selectable: false - }, - - initialize: function(){ - this.previous.apply(this, arguments); - if (this.occluded) return this.occluded; - this.selectedRows = new Elements(); - this.bound = { - mouseleave: this.mouseleave.bind(this), - focusRow: this.focusRow.bind(this) - }; - if (this.options.selectable) this.enableSelect(); - }, - - enableSelect: function(){ - this.selectEnabled = true; - this.attachSelects(); - this.element.addClass(this.options.classSelectable); - }, - - disableSelect: function(){ - this.selectEnabled = false; - this.attach(false); - this.element.removeClass(this.options.classSelectable); - }, - - attachSelects: function(attach){ - attach = $pick(attach, true); - var method = attach ? 'addEvents' : 'removeEvents'; - this.element[method]({ - mouseleave: this.bound.mouseleave - }); - this.body[method]({ - 'click:relay(tr)': this.bound.focusRow - }); - if (this.options.useKeyboard || this.keyboard){ - if (!this.keyboard) this.keyboard = new Keyboard({ - events: { - down: function(e) { - e.preventDefault(); - this.shiftFocus(1); - }.bind(this), - up: function(e) { - e.preventDefault(); - this.shiftFocus(-1); - }.bind(this), - enter: function(e) { - e.preventDefault(); - if (this.hover) this.focusRow(this.hover); - }.bind(this) - }, - active: true - }); - this.keyboard[attach ? 'activate' : 'deactivate'](); - } - this.updateSelects(); - }, - - mouseleave: function(){ - if (this.hover) this.leaveRow(this.hover); - }, - - focus: function(){ - if (this.keyboard) this.keyboard.activate(); - }, - - blur: function(){ - if (this.keyboard) this.keyboard.deactivate(); - }, - - push: function(){ - var ret = this.previous.apply(this, arguments); - this.updateSelects(); - return ret; - }, - - updateSelects: function(){ - Array.each(this.body.rows, function(row){ - var binders = row.retrieve('binders'); - if ((binders && this.selectEnabled) || (!binders && !this.selectEnabled)) return; - if (!binders){ - binders = { - mouseenter: this.enterRow.bind(this, [row]), - mouseleave: this.leaveRow.bind(this, [row]) - }; - row.store('binders', binders).addEvents(binders); - } else { - row.removeEvents(binders); - } - }, this); - }, - - enterRow: function(row){ - if (this.hover) this.hover = this.leaveRow(this.hover); - this.hover = row.addClass(this.options.classRowHovered); - }, - - shiftFocus: function(offset){ - if (!this.hover) return this.enterRow(this.body.rows[0]); - var to = Array.indexOf(this.body.rows, this.hover) + offset; - if (to < 0) to = 0; - if (to >= this.body.rows.length) to = this.body.rows.length - 1; - if (this.hover == this.body.rows[to]) return this; - this.enterRow(this.body.rows[to]); - }, - - leaveRow: function(row){ - row.removeClass(this.options.classRowHovered); - }, - - focusRow: function(){ - var row = arguments[1] || arguments[0]; //delegation passes the event first - if (!this.body.getChildren().contains(row)) return; - var unfocus = function(row){ - this.selectedRows.erase(row); - row.removeClass(this.options.classRowSelected); - this.fireEvent('rowUnfocus', [row, this.selectedRows]); - }.bind(this); - if (!this.options.allowMultiSelect) this.selectedRows.each(unfocus); - if (!this.selectedRows.contains(row)) { - this.selectedRows.push(row); - row.addClass(this.options.classRowSelected); - this.fireEvent('rowFocus', [row, this.selectedRows]); - } else { - unfocus(row); - } - return false; - }, - - selectAll: function(status){ - status = $pick(status, true); - if (!this.options.allowMultiSelect && status) return; - if (!status) this.selectedRows.removeClass(this.options.classRowSelected).empty(); - else this.selectedRows.combine(this.body.rows).addClass(this.options.classRowSelected); - return this; - }, - - selectNone: function(){ - return this.selectAll(false); - } - -}); - - -/* ---- - -script: Keyboard.js - -description: KeyboardEvents used to intercept events on a class for keyboard and format modifiers in a specific order so as to make alt+shift+c the same as shift+alt+c. - -license: MIT-style license - -authors: -- Perrin Westrich -- Aaron Newton -- Scott Kyle - -requires: -- core:1.2.4/Events -- core:1.2.4/Options -- core:1.2.4/Element.Event -- /Log - -provides: [Keyboard] - -... -*/ - -(function(){ - - var Keyboard = this.Keyboard = new Class({ - - Extends: Events, - - Implements: [Options, Log], - - options: { - /* - onActivate: $empty, - onDeactivate: $empty, - */ - defaultEventType: 'keydown', - active: false, - events: {}, - nonParsedEvents: ['activate', 'deactivate', 'onactivate', 'ondeactivate', 'changed', 'onchanged'] - }, - - initialize: function(options){ - this.setOptions(options); - this.setup(); - }, - setup: function(){ - this.addEvents(this.options.events); - //if this is the root manager, nothing manages it - if (Keyboard.manager && !this.manager) Keyboard.manager.manage(this); - if (this.options.active) this.activate(); - }, - - handle: function(event, type){ - //Keyboard.stop(event) prevents key propagation - if (event.preventKeyboardPropagation) return; - - var bubbles = !!this.manager; - if (bubbles && this.activeKB){ - this.activeKB.handle(event, type); - if (event.preventKeyboardPropagation) return; - } - this.fireEvent(type, event); - - if (!bubbles && this.activeKB) this.activeKB.handle(event, type); - }, - - addEvent: function(type, fn, internal){ - return this.parent(Keyboard.parse(type, this.options.defaultEventType, this.options.nonParsedEvents), fn, internal); - }, - - removeEvent: function(type, fn){ - return this.parent(Keyboard.parse(type, this.options.defaultEventType, this.options.nonParsedEvents), fn); - }, - - toggleActive: function(){ - return this[this.active ? 'deactivate' : 'activate'](); - }, - - activate: function(instance){ - if (instance) { - //if we're stealing focus, store the last keyboard to have it so the relenquish command works - if (instance != this.activeKB) this.previous = this.activeKB; - //if we're enabling a child, assign it so that events are now passed to it - this.activeKB = instance.fireEvent('activate'); - Keyboard.manager.fireEvent('changed'); - } else if (this.manager) { - //else we're enabling ourselves, we must ask our parent to do it for us - this.manager.activate(this); - } - return this; - }, - - deactivate: function(instance){ - if (instance) { - if(instance === this.activeKB) { - this.activeKB = null; - instance.fireEvent('deactivate'); - Keyboard.manager.fireEvent('changed'); - } - } - else if (this.manager) { - this.manager.deactivate(this); - } - return this; - }, - - relenquish: function(){ - if (this.previous) this.activate(this.previous); - }, - - //management logic - manage: function(instance){ - if (instance.manager) instance.manager.drop(instance); - this.instances.push(instance); - instance.manager = this; - if (!this.activeKB) this.activate(instance); - else this._disable(instance); - }, - - _disable: function(instance){ - if (this.activeKB == instance) this.activeKB = null; - }, - - drop: function(instance){ - this._disable(instance); - this.instances.erase(instance); - }, - - instances: [], - - trace: function(){ - Keyboard.trace(this); - }, - - each: function(fn){ - Keyboard.each(this, fn); - } - - }); - - var parsed = {}; - var modifiers = ['shift', 'control', 'alt', 'meta']; - var regex = /^(?:shift|control|ctrl|alt|meta)$/; - - Keyboard.parse = function(type, eventType, ignore){ - if (ignore && ignore.contains(type.toLowerCase())) return type; - - type = type.toLowerCase().replace(/^(keyup|keydown):/, function($0, $1){ - eventType = $1; - return ''; - }); - - if (!parsed[type]){ - var key, mods = {}; - type.split('+').each(function(part){ - if (regex.test(part)) mods[part] = true; - else key = part; - }); - - mods.control = mods.control || mods.ctrl; // allow both control and ctrl - - var keys = []; - modifiers.each(function(mod){ - if (mods[mod]) keys.push(mod); - }); - - if (key) keys.push(key); - parsed[type] = keys.join('+'); - } - - return eventType + ':' + parsed[type]; - }; - - Keyboard.each = function(keyboard, fn){ - var current = keyboard || Keyboard.manager; - while (current){ - fn.run(current); - current = current.activeKB; - } - }; - - Keyboard.stop = function(event){ - event.preventKeyboardPropagation = true; - }; - - Keyboard.manager = new Keyboard({ - active: true - }); - - Keyboard.trace = function(keyboard){ - keyboard = keyboard || Keyboard.manager; - keyboard.enableLog(); - keyboard.log('the following items have focus: '); - Keyboard.each(keyboard, function(current){ - keyboard.log(document.id(current.widget) || current.wiget || current); - }); - }; - - var handler = function(event){ - var keys = []; - modifiers.each(function(mod){ - if (event[mod]) keys.push(mod); - }); - - if (!regex.test(event.key)) keys.push(event.key); - Keyboard.manager.handle(event, event.type + ':' + keys.join('+')); - }; - - document.addEvents({ - 'keyup': handler, - 'keydown': handler - }); - - Event.Keys.extend({ - 'shift': 16, - 'control': 17, - 'alt': 18, - 'capslock': 20, - 'pageup': 33, - 'pagedown': 34, - 'end': 35, - 'home': 36, - 'numlock': 144, - 'scrolllock': 145, - ';': 186, - '=': 187, - ',': 188, - '-': Browser.Engine.Gecko ? 109 : 189, - '.': 190, - '/': 191, - '`': 192, - '[': 219, - '\\': 220, - ']': 221, - "'": 222 - }); - -})(); - - -/* ---- - -script: Scroller.js - -description: Class which scrolls the contents of any Element (including the window) when the mouse reaches the Element's boundaries. - -license: MIT-style license - -authors: -- Valerio Proietti - -requires: -- core:1.2.4/Events -- core:1.2.4/Options -- core:1.2.4/Element.Event -- core:1.2.4/Element.Dimensions - -provides: [Scroller] - -... -*/ - -var Scroller = new Class({ - - Implements: [Events, Options], - - options: { - area: 20, - velocity: 1, - onChange: function(x, y){ - this.element.scrollTo(x, y); - }, - fps: 50 - }, - - initialize: function(element, options){ - this.setOptions(options); - this.element = document.id(element); - this.docBody = document.id(this.element.getDocument().body); - this.listener = ($type(this.element) != 'element') ? this.docBody : this.element; - this.timer = null; - this.bound = { - attach: this.attach.bind(this), - detach: this.detach.bind(this), - getCoords: this.getCoords.bind(this) - }; - }, - - start: function(){ - this.listener.addEvents({ - mouseover: this.bound.attach, - mouseout: this.bound.detach - }); - }, - - stop: function(){ - this.listener.removeEvents({ - mouseover: this.bound.attach, - mouseout: this.bound.detach - }); - this.detach(); - this.timer = $clear(this.timer); - }, - - attach: function(){ - this.listener.addEvent('mousemove', this.bound.getCoords); - }, - - detach: function(){ - this.listener.removeEvent('mousemove', this.bound.getCoords); - this.timer = $clear(this.timer); - }, - - getCoords: function(event){ - this.page = (this.listener.get('tag') == 'body') ? event.client : event.page; - if (!this.timer) this.timer = this.scroll.periodical(Math.round(1000 / this.options.fps), this); - }, - - scroll: function(){ - var size = this.element.getSize(), - scroll = this.element.getScroll(), - pos = this.element != this.docBody ? this.element.getOffsets() : {x: 0, y:0}, - scrollSize = this.element.getScrollSize(), - change = {x: 0, y: 0}; - for (var z in this.page){ - if (this.page[z] < (this.options.area + pos[z]) && scroll[z] != 0) { - change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity; - } else if (this.page[z] + this.options.area > (size[z] + pos[z]) && scroll[z] + size[z] != scrollSize[z]) { - change[z] = (this.page[z] - size[z] + this.options.area - pos[z]) * this.options.velocity; - } - } - if (change.y || change.x) this.fireEvent('change', [scroll.x + change.x, scroll.y + change.y]); - } - -}); - -/* ---- - -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]); - } - -}); - -})(); \ No newline at end of file +MooTools.More={'version':'1.2.4.4','build':'6f6057dc645fdb7547689183b2311063bd653ddf'};(function(){var global=this;var log=function(){if(global.console&&console.log){try{console.log.apply(console,arguments);}catch(e){console.log(Array.slice(arguments));}}else{Log.logged.push(arguments);} +return this;};var disabled=function(){this.logged.push(arguments);return this;};this.Log=new Class({logged:[],log:disabled,resetLog:function(){this.logged.empty();return this;},enableLog:function(){this.log=log;this.logged.each(function(args){this.log.apply(this,args);},this);return this.resetLog();},disableLog:function(){this.log=disabled;return this;}});Log.extend(new Log).enableLog();Log.logger=function(){return this.log.apply(this,arguments);};})();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;};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;}});(function(addEvent,removeEvent){var match=/(.*?):relay\(([^)]+)\)$/,combinators=/[+>~\s]/,splitType=function(type){var bits=type.match(match);return!bits?{event:type}:{event:bits[1],selector:bits[2]};},check=function(e,selector){var t=e.target;if(combinators.test(selector=selector.trim())){var els=this.getElements(selector);for(var i=els.length;i--;){var el=els[i];if(t==el||el.hasChild(t))return el;}}else{for(;t&&t!=this;t=t.parentNode){if(Element.match(t,selector))return document.id(t);}} +return null;};Element.implement({addEvent:function(type,fn){var splitted=splitType(type);if(splitted.selector){var monitors=this.retrieve('$moo:delegateMonitors',{});if(!monitors[type]){var monitor=function(e){var el=check.call(this,e,splitted.selector);if(el)this.fireEvent(type,[e,el],0,el);}.bind(this);monitors[type]=monitor;addEvent.call(this,splitted.event,monitor);}} +return addEvent.apply(this,arguments);},removeEvent:function(type,fn){var splitted=splitType(type);if(splitted.selector){var events=this.retrieve('events');if(!events||!events[type]||(fn&&!events[type].keys.contains(fn)))return this;if(fn)removeEvent.apply(this,[type,fn]);else removeEvent.apply(this,type);events=this.retrieve('events');if(events&&events[type]&&events[type].keys.length==0){var monitors=this.retrieve('$moo:delegateMonitors',{});removeEvent.apply(this,[splitted.event,monitors[type]]);delete monitors[type];} +return this;} +return removeEvent.apply(this,arguments);},fireEvent:function(type,args,delay,bind){var events=this.retrieve('events');if(!events||!events[type])return this;events[type].keys.each(function(fn){fn.create({bind:bind||this,delay:delay,arguments:args})();},this);return this;}});})(Element.prototype.addEvent,Element.prototype.removeEvent);Fx.Elements=new Class({Extends:Fx.CSS,initialize:function(elements,options){this.elements=this.subject=$$(elements);this.parent(options);},compute:function(from,to,delta){var now={};for(var i in from){var iFrom=from[i],iTo=to[i],iNow=now[i]={};for(var p in iFrom)iNow[p]=this.parent(iFrom[p],iTo[p],delta);} +return now;},set:function(now){for(var i in now){var iNow=now[i];for(var p in iNow)this.render(this.elements[i],p,iNow[p],this.options.unit);} +return this;},start:function(obj){if(!this.check(obj))return this;var from={},to={};for(var i in obj){var iProps=obj[i],iFrom=from[i]={},iTo=to[i]={};for(var p in iProps){var parsed=this.prepare(this.elements[i],p,iProps[p]);iFrom[p]=parsed.from;iTo[p]=parsed.to;}} +return this.parent(from,to);}});Fx.Accordion=new Class({Extends:Fx.Elements,options:{display:0,show:false,height:true,width:false,opacity:true,alwaysHide:false,trigger:'click',initialDisplayFx:true,returnHeightToAuto:true},initialize:function(){var params=Array.link(arguments,{'container':Element.type,'options':Object.type,'togglers':$defined,'elements':$defined});this.parent(params.elements,params.options);this.togglers=$$(params.togglers);this.previous=-1;this.internalChain=new Chain();if(this.options.alwaysHide)this.options.wait=true;if($chk(this.options.show)){this.options.display=false;this.previous=this.options.show;} +if(this.options.start){this.options.display=false;this.options.show=false;} +this.effects={};if(this.options.opacity)this.effects.opacity='fullOpacity';if(this.options.width)this.effects.width=this.options.fixedWidth?'fullWidth':'offsetWidth';if(this.options.height)this.effects.height=this.options.fixedHeight?'fullHeight':'scrollHeight';for(var i=0,l=this.togglers.length;i0&&this.options.height)||el.offsetWidth>0&&this.options.width)){hide=true;this.selfHidden=true;} +this.fireEvent(hide?'background':'active',[this.togglers[i],el]);for(var fx in this.effects)obj[i][fx]=hide?0:el[this.effects[fx]];},this);this.internalChain.chain(function(){if(this.options.returnHeightToAuto&&!this.selfHidden){var el=this.elements[index];if(el)el.setStyle('height','auto');};}.bind(this));return useFx?this.start(obj):this.set(obj);}});var Accordion=new Class({Extends:Fx.Accordion,initialize:function(){this.parent.apply(this,arguments);var params=Array.link(arguments,{'container':Element.type});this.container=params.container;},addSection:function(toggler,element,pos){toggler=document.id(toggler);element=document.id(element);var test=this.togglers.contains(toggler);var len=this.togglers.length;if(len&&(!test||pos)){pos=$pick(pos,len-1);toggler.inject(this.togglers[pos],'before');element.inject(toggler,'after');}else if(this.container&&!test){toggler.inject(this.container);element.inject(this.container);} +return this.parent.apply(this,arguments);}});Fx.Slide=new Class({Extends:Fx,options:{mode:'vertical',wrapper:false,hideOverflow:true},initialize:function(element,options){this.addEvent('complete',function(){this.open=(this.wrapper['offset'+this.layout.capitalize()]!=0);if(this.open)this.wrapper.setStyle('height','');if(this.open&&Browser.Engine.webkit419)this.element.dispose().inject(this.wrapper);},true);this.element=this.subject=document.id(element);this.parent(options);var wrapper=this.element.retrieve('wrapper');var styles=this.element.getStyles('margin','position','overflow');if(this.options.hideOverflow)styles=$extend(styles,{overflow:'hidden'});if(this.options.wrapper)wrapper=document.id(this.options.wrapper).setStyles(styles);this.wrapper=wrapper||new Element('div',{styles:styles}).wraps(this.element);this.element.store('wrapper',this.wrapper).setStyle('margin',0);this.now=[];this.open=true;},vertical:function(){this.margin='margin-top';this.layout='height';this.offset=this.element.offsetHeight;},horizontal:function(){this.margin='margin-left';this.layout='width';this.offset=this.element.offsetWidth;},set:function(now){this.element.setStyle(this.margin,now[0]);this.wrapper.setStyle(this.layout,now[1]);return this;},compute:function(from,to,delta){return[0,1].map(function(i){return Fx.compute(from[i],to[i],delta);});},start:function(how,mode){if(!this.check(how,mode))return this;this[mode||this.options.mode]();var margin=this.element.getStyle(this.margin).toInt();var layout=this.wrapper.getStyle(this.layout).toInt();var caseIn=[[margin,layout],[0,this.offset]];var caseOut=[[margin,layout],[-this.offset,0]];var start;switch(how){case'in':start=caseIn;break;case'out':start=caseOut;break;case'toggle':start=(layout==0)?caseIn:caseOut;} +return this.parent(start[0],start[1]);},slideIn:function(mode){return this.start('in',mode);},slideOut:function(mode){return this.start('out',mode);},hide:function(mode){this[mode||this.options.mode]();this.open=false;return this.set([-this.offset,0]);},show:function(mode){this[mode||this.options.mode]();this.open=true;return this.set([0,this.offset]);},toggle:function(mode){return this.start('toggle',mode);}});Element.Properties.slide={set:function(options){var slide=this.retrieve('slide');if(slide)slide.cancel();return this.eliminate('slide').store('slide:options',$extend({link:'cancel'},options));},get:function(options){if(options||!this.retrieve('slide')){if(options||!this.retrieve('slide:options'))this.set('slide',options);this.store('slide',new Fx.Slide(this,this.retrieve('slide:options')));} +return this.retrieve('slide');}};Element.implement({slide:function(how,mode){how=how||'toggle';var slide=this.get('slide'),toggle;switch(how){case'hide':slide.hide(mode);break;case'show':slide.show(mode);break;case'toggle':var flag=this.retrieve('slide:flag',slide.open);slide[flag?'slideOut':'slideIn'](mode);this.store('slide:flag',!flag);toggle=true;break;default:slide.start(how,mode);} +if(!toggle)this.eliminate('slide:flag');return this;}});var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:'px',grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:'left',y:'top'}},initialize:function(){var params=Array.link(arguments,{'options':Object.type,'element':$defined});this.element=document.id(params.element);this.document=this.element.getDocument();this.setOptions(params.options||{});var htype=$type(this.options.handle);this.handles=((htype=='array'||htype=='collection')?$$(this.options.handle):document.id(this.options.handle))||this.element;this.mouse={'now':{},'pos':{}};this.value={'start':{},'now':{}};this.selection=(Browser.Engine.trident)?'selectstart':'mousedown';this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:$lambda(false)};this.attach();},attach:function(){this.handles.addEvent('mousedown',this.bound.start);return this;},detach:function(){this.handles.removeEvent('mousedown',this.bound.start);return this;},start:function(event){if(event.rightClick)return;if(this.options.preventDefault)event.preventDefault();if(this.options.stopPropagation)event.stopPropagation();this.mouse.start=event.page;this.fireEvent('beforeStart',this.element);var limit=this.options.limit;this.limit={x:[],y:[]};for(var z in this.options.modifiers){if(!this.options.modifiers[z])continue;if(this.options.style)this.value.now[z]=this.element.getStyle(this.options.modifiers[z]).toInt();else this.value.now[z]=this.element[this.options.modifiers[z]];if(this.options.invert)this.value.now[z]*=-1;this.mouse.pos[z]=this.value.now[z];if(limit&&limit[z]){for(var i=2;i--;i){if($chk(limit[z][i]))this.limit[z][i]=$lambda(limit[z][i])();}}} +if($type(this.options.grid)=='number')this.options.grid={x:this.options.grid,y:this.options.grid};this.document.addEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});this.document.addEvent(this.selection,this.bound.eventStop);},check:function(event){if(this.options.preventDefault)event.preventDefault();var distance=Math.round(Math.sqrt(Math.pow(event.page.x-this.mouse.start.x,2)+Math.pow(event.page.y-this.mouse.start.y,2)));if(distance>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent('start',[this.element,event]).fireEvent('snap',this.element);}},drag:function(event){if(this.options.preventDefault)event.preventDefault();this.mouse.now=event.page;for(var z in this.options.modifiers){if(!this.options.modifiers[z])continue;this.value.now[z]=this.mouse.now[z]-this.mouse.pos[z];if(this.options.invert)this.value.now[z]*=-1;if(this.options.limit&&this.limit[z]){if($chk(this.limit[z][1])&&(this.value.now[z]>this.limit[z][1])){this.value.now[z]=this.limit[z][1];}else if($chk(this.limit[z][0])&&(this.value.now[z]el.left&&now.xel.top);},checkDroppables:function(){var overed=this.droppables.filter(this.checkAgainst,this).getLast();if(this.overed!=overed){if(this.overed)this.fireEvent('leave',[this.element,this.overed]);if(overed)this.fireEvent('enter',[this.element,overed]);this.overed=overed;}},drag:function(event){this.parent(event);if(this.options.checkDroppables&&this.droppables.length)this.checkDroppables();},stop:function(event){this.checkDroppables();this.fireEvent('drop',[this.element,this.overed,event]);this.overed=null;return this.parent(event);}});Element.implement({makeDraggable:function(options){var drag=new Drag.Move(this,options);this.store('dragger',drag);return drag;}});var Sortables=new Class({Implements:[Events,Options],options:{snap:4,opacity:1,clone:false,revert:false,handle:false,constrain:false},initialize:function(lists,options){this.setOptions(options);this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(lists)||lists));if(!this.options.clone)this.options.revert=false;if(this.options.revert)this.effect=new Fx.Morph(null,$merge({duration:250,link:'cancel'},this.options.revert));},attach:function(){this.addLists(this.lists);return this;},detach:function(){this.lists=this.removeLists(this.lists);return this;},addItems:function(){Array.flatten(arguments).each(function(element){this.elements.push(element);var start=element.retrieve('sortables:start',this.start.bindWithEvent(this,element));(this.options.handle?element.getElement(this.options.handle)||element:element).addEvent('mousedown',start);},this);return this;},addLists:function(){Array.flatten(arguments).each(function(list){this.lists.push(list);this.addItems(list.getChildren());},this);return this;},removeItems:function(){return $$(Array.flatten(arguments).map(function(element){this.elements.erase(element);var start=element.retrieve('sortables:start');(this.options.handle?element.getElement(this.options.handle)||element:element).removeEvent('mousedown',start);return element;},this));},removeLists:function(){return $$(Array.flatten(arguments).map(function(list){this.lists.erase(list);this.removeItems(list.getChildren());return list;},this));},getClone:function(event,element){if(!this.options.clone)return new Element('div').inject(document.body);if($type(this.options.clone)=='function')return this.options.clone.call(this,event,element,this.list);var clone=element.clone(true).setStyles({margin:'0px',position:'absolute',visibility:'hidden','width':element.getStyle('width')});if(clone.get('html').test('radio')){clone.getElements('input[type=radio]').each(function(input,i){input.set('name','clone_'+i);});} +return clone.inject(this.list).setPosition(element.getPosition(element.getOffsetParent()));},getDroppables:function(){var droppables=this.list.getChildren();if(!this.options.constrain)droppables=this.lists.concat(droppables).erase(this.list);return droppables.erase(this.clone).erase(this.element);},insert:function(dragging,element){var where='inside';if(this.lists.contains(element)){this.list=element;this.drag.droppables=this.getDroppables();}else{where=this.element.getAllPrevious().contains(element)?'before':'after';} +this.element.inject(element,where);this.fireEvent('sort',[this.element,this.clone]);},start:function(event,element){if(!this.idle)return;this.idle=false;this.element=element;this.opacity=element.get('opacity');this.list=element.getParent();this.clone=this.getClone(event,element);this.drag=new Drag.Move(this.clone,{snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables(),onSnap:function(){event.stop();this.clone.setStyle('visibility','visible');this.element.set('opacity',this.options.opacity||0);this.fireEvent('start',[this.element,this.clone]);}.bind(this),onEnter:this.insert.bind(this),onCancel:this.reset.bind(this),onComplete:this.end.bind(this)});this.clone.inject(this.element,'before');this.drag.start(event);},end:function(){this.drag.detach();this.element.set('opacity',this.opacity);if(this.effect){var dim=this.element.getStyles('width','height');var pos=this.clone.computePosition(this.element.getPosition(this.clone.offsetParent));this.effect.element=this.clone;this.effect.start({top:pos.top,left:pos.left,width:dim.width,height:dim.height,opacity:0.25}).chain(this.reset.bind(this));}else{this.reset();}},reset:function(){this.idle=true;this.clone.destroy();this.fireEvent('complete',this.element);},serialize:function(){var params=Array.link(arguments,{modifier:Function.type,index:$defined});var serial=this.lists.map(function(list){return list.getChildren().map(params.modifier||function(element){return element.get('id');},this);},this);var index=params.index;if(this.lists.length==1)index=0;return $chk(index)&&index>=0&&index=this.body.rows.length)to=this.body.rows.length-1;if(this.hover==this.body.rows[to])return this;this.enterRow(this.body.rows[to]);},leaveRow:function(row){row.removeClass(this.options.classRowHovered);},focusRow:function(){var row=arguments[1]||arguments[0];if(!this.body.getChildren().contains(row))return;var unfocus=function(row){this.selectedRows.erase(row);row.removeClass(this.options.classRowSelected);this.fireEvent('rowUnfocus',[row,this.selectedRows]);}.bind(this);if(!this.options.allowMultiSelect)this.selectedRows.each(unfocus);if(!this.selectedRows.contains(row)){this.selectedRows.push(row);row.addClass(this.options.classRowSelected);this.fireEvent('rowFocus',[row,this.selectedRows]);}else{unfocus(row);} +return false;},selectAll:function(status){status=$pick(status,true);if(!this.options.allowMultiSelect&&status)return;if(!status)this.selectedRows.removeClass(this.options.classRowSelected).empty();else this.selectedRows.combine(this.body.rows).addClass(this.options.classRowSelected);return this;},selectNone:function(){return this.selectAll(false);}});(function(){var Keyboard=this.Keyboard=new Class({Extends:Events,Implements:[Options,Log],options:{defaultEventType:'keydown',active:false,events:{},nonParsedEvents:['activate','deactivate','onactivate','ondeactivate','changed','onchanged']},initialize:function(options){this.setOptions(options);this.setup();},setup:function(){this.addEvents(this.options.events);if(Keyboard.manager&&!this.manager)Keyboard.manager.manage(this);if(this.options.active)this.activate();},handle:function(event,type){if(event.preventKeyboardPropagation)return;var bubbles=!!this.manager;if(bubbles&&this.activeKB){this.activeKB.handle(event,type);if(event.preventKeyboardPropagation)return;} +this.fireEvent(type,event);if(!bubbles&&this.activeKB)this.activeKB.handle(event,type);},addEvent:function(type,fn,internal){return this.parent(Keyboard.parse(type,this.options.defaultEventType,this.options.nonParsedEvents),fn,internal);},removeEvent:function(type,fn){return this.parent(Keyboard.parse(type,this.options.defaultEventType,this.options.nonParsedEvents),fn);},toggleActive:function(){return this[this.active?'deactivate':'activate']();},activate:function(instance){if(instance){if(instance!=this.activeKB)this.previous=this.activeKB;this.activeKB=instance.fireEvent('activate');Keyboard.manager.fireEvent('changed');}else if(this.manager){this.manager.activate(this);} +return this;},deactivate:function(instance){if(instance){if(instance===this.activeKB){this.activeKB=null;instance.fireEvent('deactivate');Keyboard.manager.fireEvent('changed');}} +else if(this.manager){this.manager.deactivate(this);} +return this;},relenquish:function(){if(this.previous)this.activate(this.previous);},manage:function(instance){if(instance.manager)instance.manager.drop(instance);this.instances.push(instance);instance.manager=this;if(!this.activeKB)this.activate(instance);else this._disable(instance);},_disable:function(instance){if(this.activeKB==instance)this.activeKB=null;},drop:function(instance){this._disable(instance);this.instances.erase(instance);},instances:[],trace:function(){Keyboard.trace(this);},each:function(fn){Keyboard.each(this,fn);}});var parsed={};var modifiers=['shift','control','alt','meta'];var regex=/^(?:shift|control|ctrl|alt|meta)$/;Keyboard.parse=function(type,eventType,ignore){if(ignore&&ignore.contains(type.toLowerCase()))return type;type=type.toLowerCase().replace(/^(keyup|keydown):/,function($0,$1){eventType=$1;return'';});if(!parsed[type]){var key,mods={};type.split('+').each(function(part){if(regex.test(part))mods[part]=true;else key=part;});mods.control=mods.control||mods.ctrl;var keys=[];modifiers.each(function(mod){if(mods[mod])keys.push(mod);});if(key)keys.push(key);parsed[type]=keys.join('+');} +return eventType+':'+parsed[type];};Keyboard.each=function(keyboard,fn){var current=keyboard||Keyboard.manager;while(current){fn.run(current);current=current.activeKB;}};Keyboard.stop=function(event){event.preventKeyboardPropagation=true;};Keyboard.manager=new Keyboard({active:true});Keyboard.trace=function(keyboard){keyboard=keyboard||Keyboard.manager;keyboard.enableLog();keyboard.log('the following items have focus: ');Keyboard.each(keyboard,function(current){keyboard.log(document.id(current.widget)||current.wiget||current);});};var handler=function(event){var keys=[];modifiers.each(function(mod){if(event[mod])keys.push(mod);});if(!regex.test(event.key))keys.push(event.key);Keyboard.manager.handle(event,event.type+':'+keys.join('+'));};document.addEvents({'keyup':handler,'keydown':handler});Event.Keys.extend({'shift':16,'control':17,'alt':18,'capslock':20,'pageup':33,'pagedown':34,'end':35,'home':36,'numlock':144,'scrolllock':145,';':186,'=':187,',':188,'-':Browser.Engine.Gecko?109:189,'.':190,'/':191,'`':192,'[':219,'\\':220,']':221,"'":222});})();var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(x,y){this.element.scrollTo(x,y);},fps:50},initialize:function(element,options){this.setOptions(options);this.element=document.id(element);this.docBody=document.id(this.element.getDocument().body);this.listener=($type(this.element)!='element')?this.docBody:this.element;this.timer=null;this.bound={attach:this.attach.bind(this),detach:this.detach.bind(this),getCoords:this.getCoords.bind(this)};},start:function(){this.listener.addEvents({mouseover:this.bound.attach,mouseout:this.bound.detach});},stop:function(){this.listener.removeEvents({mouseover:this.bound.attach,mouseout:this.bound.detach});this.detach();this.timer=$clear(this.timer);},attach:function(){this.listener.addEvent('mousemove',this.bound.getCoords);},detach:function(){this.listener.removeEvent('mousemove',this.bound.getCoords);this.timer=$clear(this.timer);},getCoords:function(event){this.page=(this.listener.get('tag')=='body')?event.client:event.page;if(!this.timer)this.timer=this.scroll.periodical(Math.round(1000/this.options.fps),this);},scroll:function(){var size=this.element.getSize(),scroll=this.element.getScroll(),pos=this.element!=this.docBody?this.element.getOffsets():{x:0,y:0},scrollSize=this.element.getScrollSize(),change={x:0,y:0};for(var z in this.page){if(this.page[z]<(this.options.area+pos[z])&&scroll[z]!=0){change[z]=(this.page[z]-this.options.area-pos[z])*this.options.velocity;}else if(this.page[z]+this.options.area>(size[z]+pos[z])&&scroll[z]+size[z]!=scrollSize[z]){change[z]=(this.page[z]-size[z]+this.options.area-pos[z])*this.options.velocity;}} +if(change.y||change.x)this.fireEvent('change',[scroll.x+change.x,scroll.y+change.y]);}});(function(){var read=function(option,element){return(option)?($type(option)=='function'?option(element):element.get(option)):'';};this.Tips=new Class({Implements:[Events,Options],options:{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'){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]);}});})(); \ No newline at end of file diff --git a/static/js/mootools.js b/static/js/mootools.js index 009857165..12e0f8650 100644 --- a/static/js/mootools.js +++ b/static/js/mootools.js @@ -1,4329 +1,132 @@ -/* ---- - -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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: 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: JSON.js - -description: JSON encoder and decoder. - -license: MIT-style license. - -See Also: - -requires: -- /Array -- /String -- /Number -- /Function -- /Hash - -provides: [JSON] - -... -*/ - -var JSON = new Hash(this.JSON && { - stringify: JSON.stringify, - parse: JSON.parse -}).extend({ - - $specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'}, - - $replaceChars: function(chr){ - return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16); - }, - - encode: function(obj){ - switch ($type(obj)){ - case 'string': - return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"'; - case 'array': - return '[' + String(obj.map(JSON.encode).clean()) + ']'; - case 'object': case 'hash': - var string = []; - Hash.each(obj, function(value, key){ - var json = JSON.encode(value); - if (json) string.push(JSON.encode(key) + ':' + json); - }); - return '{' + string + '}'; - case 'number': case 'boolean': return String(obj); - case false: return 'null'; - } - return null; - }, - - decode: function(string, secure){ - if ($type(string) != 'string' || !string.length) return null; - if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null; - return eval('(' + string + ')'); - } - -}); - -Native.implement([Hash, Array, String, Number], { - - toJSON: function(){ - return JSON.encode(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: 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: 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: 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; - } - -}); - - -/* ---- - -script: Fx.Transitions.js - -description: Contains a set of advanced transitions to be used with any of the Fx Classes. - -license: MIT-style license. - -credits: -- Easing Equations by Robert Penner, , modified and optimized to be used with MooTools. - -requires: -- /Fx - -provides: [Fx.Transitions] - -... -*/ - -Fx.implement({ - - getTransition: function(){ - var trans = this.options.transition || Fx.Transitions.Sine.easeInOut; - if (typeof trans == 'string'){ - var data = trans.split(':'); - trans = Fx.Transitions; - trans = trans[data[0]] || trans[data[0].capitalize()]; - if (data[1]) trans = trans['ease' + data[1].capitalize() + (data[2] ? data[2].capitalize() : '')]; - } - return trans; - } - -}); - -Fx.Transition = function(transition, params){ - params = $splat(params); - return $extend(transition, { - easeIn: function(pos){ - return transition(pos, params); - }, - easeOut: function(pos){ - return 1 - transition(1 - pos, params); - }, - easeInOut: function(pos){ - return (pos <= 0.5) ? transition(2 * pos, params) / 2 : (2 - transition(2 * (1 - pos), params)) / 2; - } - }); -}; - -Fx.Transitions = new Hash({ - - linear: $arguments(0) - -}); - -Fx.Transitions.extend = function(transitions){ - for (var transition in transitions) Fx.Transitions[transition] = new Fx.Transition(transitions[transition]); -}; - -Fx.Transitions.extend({ - - Pow: function(p, x){ - return Math.pow(p, x[0] || 6); - }, - - Expo: function(p){ - return Math.pow(2, 8 * (p - 1)); - }, - - Circ: function(p){ - return 1 - Math.sin(Math.acos(p)); - }, - - Sine: function(p){ - return 1 - Math.sin((1 - p) * Math.PI / 2); - }, - - Back: function(p, x){ - x = x[0] || 1.618; - return Math.pow(p, 2) * ((x + 1) * p - x); - }, - - Bounce: function(p){ - var value; - for (var a = 0, b = 1; 1; a += b, b /= 2){ - if (p >= (7 - 4 * a) / 11){ - value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2); - break; - } - } - return value; - }, - - Elastic: function(p, x){ - return Math.pow(2, 10 * --p) * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3); - } - -}); - -['Quad', 'Cubic', 'Quart', 'Quint'].each(function(transition, i){ - Fx.Transitions[transition] = new Fx.Transition(function(p){ - return Math.pow(p, [i + 2]); - }); -}); - - -/* ---- - -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, - 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; - 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(); - 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; - } - -}); - -(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: Request.JSON.js - -description: Extends the basic Request Class with additional methods for sending and receiving JSON data. - -license: MIT-style license. - -requires: -- /Request JSON - -provides: [Request.HTML] - -... -*/ - -Request.JSON = new Class({ - - Extends: Request, - - options: { - secure: true - }, - - initialize: function(options){ - this.parent(options); - this.headers.extend({'Accept': 'application/json', 'X-Request': 'JSON'}); - }, - - success: function(text){ - this.response.json = JSON.decode(text, this.options.secure); - this.onSuccess(this.response.json, text); - } - -}); +//MooTools, , My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2009 Valerio Proietti, , MIT Style License. + +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-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]:'';});}});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'});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;}});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);}};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;}});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';} +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;i1);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;}};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,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1};(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'}});})();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(@, @, @)';});(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};}});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;};})();Element.alias('setPosition','position');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;}});Native.implement([Document,Element],{getElements:function(expression,nocash){expression=expression.split(',');var items,local={};for(var i=0,l=expression.length;i1),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':function(found,self,tag,id,uniques){var children=Selectors.Utils.getByTagAndID(self,tag,id);for(var i=0,l=children.length;iindex)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);}});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();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);}})();var JSON=new Hash(this.JSON&&{stringify:JSON.stringify,parse:JSON.parse}).extend({$specialChars:{'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},$replaceChars:function(chr){return JSON.$specialChars[chr]||'\\u00'+Math.floor(chr.charCodeAt()/16).toString(16)+(chr.charCodeAt()%16).toString(16);},encode:function(obj){switch($type(obj)){case'string':return'"'+obj.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case'array':return'['+String(obj.map(JSON.encode).clean())+']';case'object':case'hash':var string=[];Hash.each(obj,function(value,key){var json=JSON.encode(value);if(json)string.push(JSON.encode(key)+':'+json);});return'{'+string+'}';case'number':case'boolean':return String(obj);case false:return'null';} +return null;},decode:function(string,secure){if($type(string)!='string'||!string.length)return null;if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"/g,'')))return null;return eval('('+string+')');}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});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();};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);};var Fx=new Class({Implements:[Chain,Events,Options],options:{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=(7-4*a)/11){value=b*b-Math.pow((11-6*a-11*p)/4,2);break;}} +return value;},Elastic:function(p,x){return Math.pow(2,10*--p)*Math.cos(20*p*Math.PI*(x[0]||1)/3);}});['Quad','Cubic','Quart','Quint'].each(function(transition,i){Fx.Transitions[transition]=new Fx.Transition(function(p){return Math.pow(p,[i+2]);});});var Request=new Class({Implements:[Chain,Events,Options],options:{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,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;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();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;}});(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;}});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 + +{% block css %}{% endblock %} diff --git a/templates/nlayout.html b/templates/nlayout.html index 14a6ad57a..8fbc2acf2 100644 --- a/templates/nlayout.html +++ b/templates/nlayout.html @@ -6,9 +6,9 @@ MailNG - {%block pagetitle %}{% endblock %} - - - + + + @@ -71,7 +71,7 @@