diff options
Diffstat (limited to 'live')
-rw-r--r-- | live/img/close_red.png | bin | 0 -> 587 bytes | |||
-rw-r--r-- | live/img/info-win-b-l.png | bin | 0 -> 844 bytes | |||
-rw-r--r-- | live/img/info-win-b-r.png | bin | 0 -> 466 bytes | |||
-rw-r--r-- | live/img/info-win-m-l.png | bin | 0 -> 180 bytes | |||
-rw-r--r-- | live/img/info-win-m-r.png | bin | 0 -> 176 bytes | |||
-rw-r--r-- | live/img/info-win-t-l.png | bin | 0 -> 1131 bytes | |||
-rw-r--r-- | live/img/info-win-t-r.png | bin | 0 -> 716 bytes | |||
-rw-r--r-- | live/img/tip-hint-bl.png | bin | 0 -> 528 bytes | |||
-rw-r--r-- | live/img/tip-hint-br.png | bin | 0 -> 336 bytes | |||
-rw-r--r-- | live/img/tip-hint-ml.png | bin | 0 -> 110 bytes | |||
-rw-r--r-- | live/img/tip-hint-mr.png | bin | 0 -> 112 bytes | |||
-rw-r--r-- | live/img/tip-hint-tl.png | bin | 0 -> 470 bytes | |||
-rw-r--r-- | live/img/tip-hint-tr.png | bin | 0 -> 346 bytes | |||
-rw-r--r-- | live/js/live/hinttips.js | 34 | ||||
-rw-r--r-- | live/js/live/infowin.js | 296 | ||||
-rw-r--r-- | live/js/mootools/mootools.v1.11.js | 1101 |
16 files changed, 1431 insertions, 0 deletions
diff --git a/live/img/close_red.png b/live/img/close_red.png Binary files differnew file mode 100644 index 0000000..05e02b2 --- /dev/null +++ b/live/img/close_red.png diff --git a/live/img/info-win-b-l.png b/live/img/info-win-b-l.png Binary files differnew file mode 100644 index 0000000..5fccc68 --- /dev/null +++ b/live/img/info-win-b-l.png diff --git a/live/img/info-win-b-r.png b/live/img/info-win-b-r.png Binary files differnew file mode 100644 index 0000000..29a09e9 --- /dev/null +++ b/live/img/info-win-b-r.png diff --git a/live/img/info-win-m-l.png b/live/img/info-win-m-l.png Binary files differnew file mode 100644 index 0000000..9fb5356 --- /dev/null +++ b/live/img/info-win-m-l.png diff --git a/live/img/info-win-m-r.png b/live/img/info-win-m-r.png Binary files differnew file mode 100644 index 0000000..f097081 --- /dev/null +++ b/live/img/info-win-m-r.png diff --git a/live/img/info-win-t-l.png b/live/img/info-win-t-l.png Binary files differnew file mode 100644 index 0000000..f916543 --- /dev/null +++ b/live/img/info-win-t-l.png diff --git a/live/img/info-win-t-r.png b/live/img/info-win-t-r.png Binary files differnew file mode 100644 index 0000000..854bde2 --- /dev/null +++ b/live/img/info-win-t-r.png diff --git a/live/img/tip-hint-bl.png b/live/img/tip-hint-bl.png Binary files differnew file mode 100644 index 0000000..790a602 --- /dev/null +++ b/live/img/tip-hint-bl.png diff --git a/live/img/tip-hint-br.png b/live/img/tip-hint-br.png Binary files differnew file mode 100644 index 0000000..61eafcf --- /dev/null +++ b/live/img/tip-hint-br.png diff --git a/live/img/tip-hint-ml.png b/live/img/tip-hint-ml.png Binary files differnew file mode 100644 index 0000000..b730b57 --- /dev/null +++ b/live/img/tip-hint-ml.png diff --git a/live/img/tip-hint-mr.png b/live/img/tip-hint-mr.png Binary files differnew file mode 100644 index 0000000..bf2465c --- /dev/null +++ b/live/img/tip-hint-mr.png diff --git a/live/img/tip-hint-tl.png b/live/img/tip-hint-tl.png Binary files differnew file mode 100644 index 0000000..467ecec --- /dev/null +++ b/live/img/tip-hint-tl.png diff --git a/live/img/tip-hint-tr.png b/live/img/tip-hint-tr.png Binary files differnew file mode 100644 index 0000000..a4c9b3f --- /dev/null +++ b/live/img/tip-hint-tr.png diff --git a/live/js/live/hinttips.js b/live/js/live/hinttips.js new file mode 100644 index 0000000..5cf899a --- /dev/null +++ b/live/js/live/hinttips.js @@ -0,0 +1,34 @@ +/* + * Extension of mootools Tips class for rounded corner + * tooltips of variable size up to some maximum. + */ + +var HintTips = Tips.extend({ + initialize: function(elements, options){ + this.parent(elements, options); + this.toolTip.empty(); + /* top border of tip */ + var hd = new Element('div', {'class': this.options.className + '-tip-top'}).inject(this.toolTip); + hd = new Element('div', {'class': this.options.className + '-tip-c'}).inject(hd); + + /* body of tip: some helper divs and content */ + this.wrapper = new Element('div', {'class': this.options.className + '-tip-bdy'}).inject(this.toolTip); + this.wrapper = new Element('div', {'class': this.options.className + '-tip-c'}).inject(this.wrapper); + this.wrapper = new Element('div', {'class': this.options.className + '-tip-s'}).inject(this.wrapper); + + /* bottom border of tip */ + var bt = new Element('div', {'class': this.options.className + '-tip-bot'}).inject(this.toolTip); + bt = new Element('div', {'class': this.options.className + '-tip-c'}).inject(bt); + } + }); + +window.addEvent('domready', function(){ + var tips = new HintTips($$('*[title]'), { + maxTitleChars: 100, + className: 'hint' + }); + }); + +window.addEvent('mousedown', function(){ + $$('.hint-tip').setStyle('visibility', 'hidden'); + });
\ No newline at end of file diff --git a/live/js/live/infowin.js b/live/js/live/infowin.js new file mode 100644 index 0000000..c142700 --- /dev/null +++ b/live/js/live/infowin.js @@ -0,0 +1,296 @@ +/* + * Extension of mootools to display a popup window with + * some html code. + */ + +/* +Class: InfoWin + Create an information window as overlay to current page. + +Arguments: + +Options: + +Note: + A window consists of a frame-element. This is the overall + containing element used to control the display and size of the + window. It is accesable through the 'winFrame' property. + + The InfoWin class provides the followin properties to fill the + window with content: + - titleBox: the element meant to place the title of the window into. + - buttonBox: here the default window buttons are created. You might + clear this and create your own kind of window controls. + - winBody: this is where your window contents goes. + */ +var InfoWin = new Class({ + options: { + timeout: 0, + onShow: Class.empty, + onHide: Class.empty, + className: 'info', + wm: false, // overide default window manager. + draggable: true, + resizable: true, + buttonimg: 'transparent.png', + bodyselect: 'div.epg_content', + titleselect: 'div.caption', + offsets: {'x': -16, 'y': -16} + }, + + initialize: function(id, options){ + this.setOptions(options); + this.wm = this.options.wm || InfoWin.$wm; + this.winFrame = $(id + '-win-id'); + if (!$defined(this.winFrame)){ + this.build(id); + this.wm.register(this); + } + }, + + // internal: build new window element. + // + // build sets up a frame for a new InfoWin. The parent element + // of the window frame has the id '<id>-win-id'. The function + // must return true if the body of the InfoWin has been filled + // with the user data, false otherwise. + build: function(id){ + this.winFrame = new Element('div', { + 'id': id + '-win-id', + 'class': this.options.className + '-win', + 'styles': { + 'position': 'absolute', + 'top': '0', + 'left': '0' + } + }); + + // header of window: upper shadows, corners title and controls + var top = new Element('div', { + 'class': this.options.className + '-win-top' + }).inject(this.winFrame); + if (this.options.draggable) this.winFrame.makeDraggable({'handle': top}); + top = new Element('div', { + 'class': this.options.className + '-win-c' + }).inject(top); + this.titleBox = new Element('div', { + 'class': this.options.className + '-win-t' + }).inject(top); + + this.buttonBox = new Element('div', { + 'class': this.options.className + '-win-b' + }).inject(top); + var cls = new Element('div', { + 'class': 'close' + }).inject(this.buttonBox); + var self = this; + cls.addEvent('click', function(event){ + var event = new Event(event); + event.stop(); + return self.hide(); + }); + cls = new Element('img', { + 'src': this.options.buttonimg, + 'alt': 'close', + 'width': '16px', + 'height': '16px' + }).inject(cls); + + // body of window: user content. + var bdy = new Element('div', { + 'class': this.options.className + '-win-body' + }).inject(this.winFrame); + bdy = new Element('div', { + 'class': this.options.className + '-win-c' + }).inject(bdy); + this.winBody = new Element('div', { + 'class': this.options.className + '-win-s' + }).inject(bdy); + + // bottom border of window: lower shadows and corners, optional + // resize handle. + var bot = new Element('div', { + 'class': this.options.className + '-win-bot' + }).inject(this.winFrame); + bot = new Element('div', { + 'class': this.options.className + '-win-c' + }).inject(bot); + + if (this.options.resizable) { + this.winFrame.makeResizable({'handle': bot}); + } + + if (!this.fillTitle(id)) { + // todo: add generic title + } + return this.fillBody(id); + }, + + show: function(event){ + if (this.options.timeout) + this.timer = this.hide.delay(this.options.timeout, this); + this.position(event); + this.fireEvent('onShow', [this.winFrame]); + this.wm.raise(this); + return false; + }, + + hide: function(){ + this.fireEvent('onHide', [this.winFrame]); + this.wm.bury(this); + return false; + }, + + fillBody: function(id){ + var bodyElems = $$('#'+ id + ' ' + this.options.bodyselect); + if ($defined(bodyElems) && bodyElems.length > 0) { + this.winBody.empty().adopt(bodyElems); + return true; + } + return false; + }, + + fillTitle: function(id){ + var titleElems = $$('#' + id + ' ' + this.options.titleselect); + if ($defined(titleElems) && titleElems.length > 0) { + this.titleBox.empty().adopt(titleElems); + return true; + } + return false; + }, + + position: function(event){ + var prop = {'x': 'left', 'y': 'top'}; + for (var z in prop) { + var pos = event.page[z] + this.options.offsets[z]; + this.winFrame.setStyle(prop[z], pos); + } + } + }); + +InfoWin.implement(new Events, new Options); + +InfoWin.Manager = new Class({ + options: { + zIndex: 100, + closedContainer: 'infowin-closed', + openedContainer: 'infowin-opened', + onRegister: Class.empty, + onRaise: Class.empty, + onBury: Class.empty + }, + + initialize: function(options){ + this.setOptions(options); + // initialize properties this.closedWins and this.openedWins: + ['closed', 'opened'].each(function(kind){ + var wins = kind + 'Wins'; + var opts = this.options[kind + 'Container']; + this[wins] = $(opts); + if (!$defined(this[wins])){ + this[wins] = new Element('div', { + 'id': opts, + 'styles' : { + 'display' : (kind == 'closed') ? 'none' : 'block' + } + }); + this[wins].inject(document.body); + } + }, this); + }, + + register: function(infoWin){ + var self = this; + this.fireEvent('onRegister', [infoWin]); + infoWin.winFrame.addEvent('click', function(){ + self.raise(infoWin); + }); + infoWin.winFrame.inject(this.closedWins); + }, + + raise: function(infoWin){ + this.fireEvent('onRaise', [infoWin]); + infoWin.winFrame.remove(); + infoWin.winFrame.inject(this.openedWins); + }, + + bury: function(infoWin){ + this.fireEvent('onBury', [infoWin]); + infoWin.winFrame.remove(); + infoWin.winFrame.inject(this.closedWins); + } + }); + +InfoWin.Manager.implement(new Events, new Options); + +InfoWin.$wm = null; +window.addEvent('domready', function(){ + InfoWin.$wm = new InfoWin.Manager(); + }); + + +InfoWin.Ajax = InfoWin.extend({ + options: { + loadingMsg: 'loading', + errorMsg: 'an error occured!', + onError: Class.empty + }, + + initialize: function(id, url, options){ + this.parent(id, options); + if ($defined(this.ajaxResponse)) { + var self = this; + this.addEvent('onError', function(){ + self.hide.delay(1000, self); + }); + var ajax = new Ajax(url, { + update: this.ajaxResponse, + onComplete: function(text, xmldoc){ + self.fillTitle(id); + self.fillBody(id); + }, + onFailure: function(transport){ + self.titleBox.setHTML(self.options.errorMsg); + self.fireEvent('onError', [id, url]); + } + }).request('async=1'); + } + }, + + // this function gets called when no previous instance for 'id' + // created a dom subtree for an infowin. + build: function(id){ + if (!this.parent(id)) { + this.titleBox.setHTML(this.options.loadingMsg); + this.ajaxResponse = new Element('div', { + 'styles' : { + 'display': 'none' + } + }).inject(this.winFrame); + } + } + }); + +InfoWin.Ajax.implement(new Events, new Options); + + +window.addEvent('domready', function(){ + $$('a[href^="epginfo.html?epgid"]').each(function(el){ + var href = el.href; + var epgid = $pick(href, ""); + if (epgid != "") { + var extractId = /epgid=(\w+)/; + var found = extractId.exec(epgid); + if ($defined(found) && found.length > 1) { + epgid = found[1]; + el.addEvent('click', function(event){ + var event = new Event(event); + new InfoWin.Ajax(epgid, href).show(event); + event.stop(); + return false; + }); + } + } + }); + }); + diff --git a/live/js/mootools/mootools.v1.11.js b/live/js/mootools/mootools.v1.11.js index 9c8be88..ac754b9 100644 --- a/live/js/mootools/mootools.v1.11.js +++ b/live/js/mootools/mootools.v1.11.js @@ -3017,6 +3017,325 @@ Function.extend({ /* +Script: Element.Filters.js + add Filters capability to <Elements>. + +License: + MIT-style license. +*/ + +/* +Class: Elements + A collection of methods to be used with <$$> elements collections. +*/ + +Elements.extend({ + + /* + Property: filterByTag + Filters the collection by a specified tag name. + Returns a new Elements collection, while the original remains untouched. + */ + + filterByTag: function(tag){ + return new Elements(this.filter(function(el){ + return (Element.getTag(el) == tag); + })); + }, + + /* + Property: filterByClass + Filters the collection by a specified class name. + Returns a new Elements collection, while the original remains untouched. + */ + + filterByClass: function(className, nocash){ + var elements = this.filter(function(el){ + return (el.className && el.className.contains(className, ' ')); + }); + return (nocash) ? elements : new Elements(elements); + }, + + /* + Property: filterById + Filters the collection by a specified ID. + Returns a new Elements collection, while the original remains untouched. + */ + + filterById: function(id, nocash){ + var elements = this.filter(function(el){ + return (el.id == id); + }); + return (nocash) ? elements : new Elements(elements); + }, + + /* + Property: filterByAttribute + Filters the collection by a specified attribute. + Returns a new Elements collection, while the original remains untouched. + + Arguments: + name - the attribute name. + operator - optional, the attribute operator. + value - optional, the attribute value, only valid if the operator is specified. + */ + + filterByAttribute: function(name, operator, value, nocash){ + var elements = this.filter(function(el){ + var current = Element.getProperty(el, name); + if (!current) return false; + if (!operator) return true; + switch(operator){ + case '=': return (current == value); + case '*=': return (current.contains(value)); + case '^=': return (current.substr(0, value.length) == value); + case '$=': return (current.substr(current.length - value.length) == value); + case '!=': return (current != value); + case '~=': return current.contains(value, ' '); + } + return false; + }); + return (nocash) ? elements : new Elements(elements); + } + +}); + +/* +Script: Element.Selectors.js + Css Query related functions and <Element> extensions + +License: + MIT-style license. +*/ + +/* Section: Utility Functions */ + +/* +Function: $E + Selects a single (i.e. the first found) Element based on the selector passed in and an optional filter element. + Returns as <Element>. + +Arguments: + selector - string; the css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Example: + >$E('a', 'myElement') //find the first anchor tag inside the DOM element with id 'myElement' + +Returns: + a DOM element - the first element that matches the selector +*/ + +function $E(selector, filter){ + return ($(filter) || document).getElement(selector); +}; + +/* +Function: $ES + Returns a collection of Elements that match the selector passed in limited to the scope of the optional filter. + See Also: <Element.getElements> for an alternate syntax. + Returns as <Elements>. + +Returns: + an array of dom elements that match the selector within the filter + +Arguments: + selector - string; css selector to match + filter - optional; a DOM element to limit the scope of the selector match; defaults to document. + +Examples: + >$ES("a") //gets all the anchor tags; synonymous with $$("a") + >$ES('a','myElement') //get all the anchor tags within $('myElement') +*/ + +function $ES(selector, filter){ + return ($(filter) || document).getElementsBySelector(selector); +}; + +$$.shared = { + + 'regexp': /^(\w*|\*)(?:#([\w-]+)|\.([\w-]+))?(?:\[(\w+)(?:([!*^$]?=)["']?([^"'\]]*)["']?)?])?$/, + + 'xpath': { + + getParam: function(items, context, param, i){ + var temp = [context.namespaceURI ? 'xhtml:' : '', param[1]]; + if (param[2]) temp.push('[@id="', param[2], '"]'); + if (param[3]) temp.push('[contains(concat(" ", @class, " "), " ', param[3], ' ")]'); + if (param[4]){ + if (param[5] && param[6]){ + switch(param[5]){ + case '*=': temp.push('[contains(@', param[4], ', "', param[6], '")]'); break; + case '^=': temp.push('[starts-with(@', param[4], ', "', param[6], '")]'); break; + case '$=': temp.push('[substring(@', param[4], ', string-length(@', param[4], ') - ', param[6].length, ' + 1) = "', param[6], '"]'); break; + case '=': temp.push('[@', param[4], '="', param[6], '"]'); break; + case '!=': temp.push('[@', param[4], '!="', param[6], '"]'); + } + } else { + temp.push('[@', param[4], ']'); + } + } + items.push(temp.join('')); + return items; + }, + + getItems: function(items, context, nocash){ + var elements = []; + var xpath = document.evaluate('.//' + items.join('//'), context, $$.shared.resolver, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); + for (var i = 0, j = xpath.snapshotLength; i < j; i++) elements.push(xpath.snapshotItem(i)); + return (nocash) ? elements : new Elements(elements.map($)); + } + + }, + + 'normal': { + + getParam: function(items, context, param, i){ + if (i == 0){ + if (param[2]){ + var el = context.getElementById(param[2]); + if (!el || ((param[1] != '*') && (Element.getTag(el) != param[1]))) return false; + items = [el]; + } else { + items = $A(context.getElementsByTagName(param[1])); + } + } else { + items = $$.shared.getElementsByTagName(items, param[1]); + if (param[2]) items = Elements.filterById(items, param[2], true); + } + if (param[3]) items = Elements.filterByClass(items, param[3], true); + if (param[4]) items = Elements.filterByAttribute(items, param[4], param[5], param[6], true); + return items; + }, + + getItems: function(items, context, nocash){ + return (nocash) ? items : $$.unique(items); + } + + }, + + resolver: function(prefix){ + return (prefix == 'xhtml') ? 'http://www.w3.org/1999/xhtml' : false; + }, + + getElementsByTagName: function(context, tagName){ + var found = []; + for (var i = 0, j = context.length; i < j; i++) found.extend(context[i].getElementsByTagName(tagName)); + return found; + } + +}; + +$$.shared.method = (window.xpath) ? 'xpath' : 'normal'; + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.Methods.Dom = { + + /* + Property: getElements + Gets all the elements within an element that match the given (single) selector. + Returns as <Elements>. + + Arguments: + selector - string; the css selector to match + + Examples: + >$('myElement').getElements('a'); // get all anchors within myElement + >$('myElement').getElements('input[name=dialog]') //get all input tags with name 'dialog' + >$('myElement').getElements('input[name$=log]') //get all input tags with names ending with 'log' + + Notes: + Supports these operators in attribute selectors: + + - = : is equal to + - ^= : starts-with + - $= : ends-with + - != : is not equal to + + Xpath is used automatically for compliant browsers. + */ + + getElements: function(selector, nocash){ + var items = []; + selector = selector.trim().split(' '); + for (var i = 0, j = selector.length; i < j; i++){ + var sel = selector[i]; + var param = sel.match($$.shared.regexp); + if (!param) break; + param[1] = param[1] || '*'; + var temp = $$.shared[$$.shared.method].getParam(items, this, param, i); + if (!temp) break; + items = temp; + } + return $$.shared[$$.shared.method].getItems(items, this, nocash); + }, + + /* + Property: getElement + Same as <Element.getElements>, but returns only the first. Alternate syntax for <$E>, where filter is the Element. + Returns as <Element>. + + Arguments: + selector - string; css selector + */ + + getElement: function(selector){ + return $(this.getElements(selector, true)[0] || false); + }, + + /* + Property: getElementsBySelector + Same as <Element.getElements>, but allows for comma separated selectors, as in css. Alternate syntax for <$$>, where filter is the Element. + Returns as <Elements>. + + Arguments: + selector - string; css selector + */ + + getElementsBySelector: function(selector, nocash){ + var elements = []; + selector = selector.split(','); + for (var i = 0, j = selector.length; i < j; i++) elements = elements.concat(this.getElements(selector[i], true)); + return (nocash) ? elements : $$.unique(elements); + } + +}; + +Element.extend({ + + /* + Property: getElementById + Targets an element with the specified id found inside the Element. Does not overwrite document.getElementById. + + Arguments: + id - string; the id of the element to find. + */ + + getElementById: function(id){ + var el = document.getElementById(id); + if (!el) return false; + for (var parent = el.parentNode; parent != this; parent = parent.parentNode){ + if (!parent) return false; + } + return el; + }/*compatibility*/, + + getElementsByClassName: function(className){ + return this.getElements('.' + className); + } + + /*end compatibility*/ + +}); + +document.extend(Element.Methods.Dom); +Element.extend(Element.Methods.Dom); + +/* Script: Element.Form.js Contains Element prototypes to deal with Forms and their elements. @@ -3092,6 +3411,161 @@ Element.extend({ }); /* +Script: Element.Dimensions.js + Contains Element prototypes to deal with Element size and position in space. + +Note: + The functions in this script require n XHTML doctype. + +License: + MIT-style license. +*/ + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: scrollTo + Scrolls the element to the specified coordinated (if the element has an overflow) + + Arguments: + x - the x coordinate + y - the y coordinate + + Example: + >$('myElement').scrollTo(0, 100) + */ + + scrollTo: function(x, y){ + this.scrollLeft = x; + this.scrollTop = y; + }, + + /* + Property: getSize + Return an Object representing the size/scroll values of the element. + + Example: + (start code) + $('myElement').getSize(); + (end) + + Returns: + (start code) + { + 'scroll': {'x': 100, 'y': 100}, + 'size': {'x': 200, 'y': 400}, + 'scrollSize': {'x': 300, 'y': 500} + } + (end) + */ + + getSize: function(){ + return { + 'scroll': {'x': this.scrollLeft, 'y': this.scrollTop}, + 'size': {'x': this.offsetWidth, 'y': this.offsetHeight}, + 'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight} + }; + }, + + /* + Property: getPosition + Returns the real offsets of the element. + + Arguments: + overflown - optional, an array of nested scrolling containers for scroll offset calculation, use this if your element is inside any element containing scrollbars + + Example: + >$('element').getPosition(); + + Returns: + >{x: 100, y:500}; + */ + + getPosition: function(overflown){ + overflown = overflown || []; + var el = this, left = 0, top = 0; + do { + left += el.offsetLeft || 0; + top += el.offsetTop || 0; + el = el.offsetParent; + } while (el); + overflown.each(function(element){ + left -= element.scrollLeft || 0; + top -= element.scrollTop || 0; + }); + return {'x': left, 'y': top}; + }, + + /* + Property: getTop + Returns the distance from the top of the window to the Element. + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + */ + + getTop: function(overflown){ + return this.getPosition(overflown).y; + }, + + /* + Property: getLeft + Returns the distance from the left of the window to the Element. + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + */ + + getLeft: function(overflown){ + return this.getPosition(overflown).x; + }, + + /* + Property: getCoordinates + Returns an object with width, height, left, right, top, and bottom, representing the values of the Element + + Arguments: + overflown - optional, an array of nested scrolling containers, see Element::getPosition + + Example: + (start code) + var myValues = $('myElement').getCoordinates(); + (end) + + Returns: + (start code) + { + width: 200, + height: 300, + left: 100, + top: 50, + right: 300, + bottom: 350 + } + (end) + */ + + getCoordinates: function(overflown){ + var position = this.getPosition(overflown); + var obj = { + 'width': this.offsetWidth, + 'height': this.offsetHeight, + 'left': position.x, + 'top': position.y + }; + obj.right = obj.left + obj.width; + obj.bottom = obj.top + obj.height; + return obj; + } + +}); + +/* Script: Window.DomReady.js Contains the custom event domready, for window. @@ -3272,6 +3746,633 @@ window.extend({ }); /* +Script: Fx.Base.js + Contains <Fx.Base>, the foundamentals of the MooTools Effects. + +License: + MIT-style license. +*/ + +var Fx = {}; + +/* +Class: Fx.Base + Base class for the Effects. + +Options: + transition - the equation to use for the effect see <Fx.Transitions>; default is <Fx.Transitions.Sine.easeInOut> + duration - the duration of the effect in ms; 500 is the default. + unit - the unit is 'px' by default (other values include things like 'em' for fonts or '%'). + wait - boolean: to wait or not to wait for a current transition to end before running another of the same instance. defaults to true. + fps - the frames per second for the transition; default is 50 + +Events: + onStart - the function to execute as the effect begins; nothing (<Class.empty>) by default. + onComplete - the function to execute after the effect has processed; nothing (<Class.empty>) by default. + onCancel - the function to execute when you manually stop the effect. +*/ + +Fx.Base = new Class({ + + options: { + onStart: Class.empty, + onComplete: Class.empty, + onCancel: Class.empty, + transition: function(p){ + return -(Math.cos(Math.PI * p) - 1) / 2; + }, + duration: 500, + unit: 'px', + wait: true, + fps: 50 + }, + + initialize: function(options){ + this.element = this.element || null; + this.setOptions(options); + if (this.options.initialize) this.options.initialize.call(this); + }, + + step: function(){ + var time = $time(); + if (time < this.time + this.options.duration){ + this.delta = this.options.transition((time - this.time) / this.options.duration); + this.setNow(); + this.increase(); + } else { + this.stop(true); + this.set(this.to); + this.fireEvent('onComplete', this.element, 10); + this.callChain(); + } + }, + + /* + Property: set + Immediately sets the value with no transition. + + Arguments: + to - the point to jump to + + Example: + >var myFx = new Fx.Style('myElement', 'opacity').set(0); //will make it immediately transparent + */ + + set: function(to){ + this.now = to; + this.increase(); + return this; + }, + + setNow: function(){ + this.now = this.compute(this.from, this.to); + }, + + compute: function(from, to){ + return (to - from) * this.delta + from; + }, + + /* + Property: start + Executes an effect from one position to the other. + + Arguments: + from - integer: staring value + to - integer: the ending value + + Examples: + >var myFx = new Fx.Style('myElement', 'opacity').start(0,1); //display a transition from transparent to opaque. + */ + + start: function(from, to){ + if (!this.options.wait) this.stop(); + else if (this.timer) return this; + this.from = from; + this.to = to; + this.change = this.to - this.from; + this.time = $time(); + this.timer = this.step.periodical(Math.round(1000 / this.options.fps), this); + this.fireEvent('onStart', this.element); + return this; + }, + + /* + Property: stop + Stops the transition. + */ + + stop: function(end){ + if (!this.timer) return this; + this.timer = $clear(this.timer); + if (!end) this.fireEvent('onCancel', this.element); + return this; + }/*compatibility*/, + + custom: function(from, to){ + return this.start(from, to); + }, + + clearTimer: function(end){ + return this.stop(end); + } + + /*end compatibility*/ + +}); + +Fx.Base.implement(new Chain, new Events, new Options); + +/* +Script: Fx.CSS.js + Css parsing class for effects. Required by <Fx.Style>, <Fx.Styles>, <Fx.Elements>. No documentation needed, as its used internally. + +License: + MIT-style license. +*/ + +Fx.CSS = { + + select: function(property, to){ + if (property.test(/color/i)) return this.Color; + var type = $type(to); + if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi; + return this.Single; + }, + + parse: function(el, property, fromTo){ + if (!fromTo.push) fromTo = [fromTo]; + var from = fromTo[0], to = fromTo[1]; + if (!$chk(to)){ + to = from; + from = el.getStyle(property); + } + var css = this.select(property, to); + return {'from': css.parse(from), 'to': css.parse(to), 'css': css}; + } + +}; + +Fx.CSS.Single = { + + parse: function(value){ + return parseFloat(value); + }, + + getNow: function(from, to, fx){ + return fx.compute(from, to); + }, + + getValue: function(value, unit, property){ + if (unit == 'px' && property != 'opacity') value = Math.round(value); + return value + unit; + } + +}; + +Fx.CSS.Multi = { + + parse: function(value){ + return value.push ? value : value.split(' ').map(function(v){ + return parseFloat(v); + }); + }, + + getNow: function(from, to, fx){ + var now = []; + for (var i = 0; i < from.length; i++) now[i] = fx.compute(from[i], to[i]); + return now; + }, + + getValue: function(value, unit, property){ + if (unit == 'px' && property != 'opacity') value = value.map(Math.round); + return value.join(unit + ' ') + unit; + } + +}; + +Fx.CSS.Color = { + + parse: function(value){ + return value.push ? value : value.hexToRgb(true); + }, + + getNow: function(from, to, fx){ + var now = []; + for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i])); + return now; + }, + + getValue: function(value){ + return 'rgb(' + value.join(',') + ')'; + } + +}; + +/* +Script: Fx.Styles.js + Contains <Fx.Styles> + +License: + MIT-style license. +*/ + +/* +Class: Fx.Styles + Allows you to animate multiple css properties at once; + Colors must be in hex format. + Inherits methods, properties, options and events from <Fx.Base>. + +Arguments: + el - the $(element) to apply the styles transition to + options - the fx options (see: <Fx.Base>) + +Example: + (start code) + var myEffects = new Fx.Styles('myElement', {duration: 1000, transition: Fx.Transitions.linear}); + + //height from 10 to 100 and width from 900 to 300 + myEffects.start({ + 'height': [10, 100], + 'width': [900, 300] + }); + + //or height from current height to 100 and width from current width to 300 + myEffects.start({ + 'height': 100, + 'width': 300 + }); + (end) +*/ + +Fx.Styles = Fx.Base.extend({ + + initialize: function(el, options){ + this.element = $(el); + this.parent(options); + }, + + setNow: function(){ + for (var p in this.from) this.now[p] = this.css[p].getNow(this.from[p], this.to[p], this); + }, + + set: function(to){ + var parsed = {}; + this.css = {}; + for (var p in to){ + this.css[p] = Fx.CSS.select(p, to[p]); + parsed[p] = this.css[p].parse(to[p]); + } + return this.parent(parsed); + }, + + /* + Property: start + Executes a transition for any number of css properties in tandem. + + Arguments: + obj - an object containing keys that specify css properties to alter and values that specify either the from/to values (as an array) or just the end value (an integer). + + Example: + see <Fx.Styles> + */ + + start: function(obj){ + if (this.timer && this.options.wait) return this; + this.now = {}; + this.css = {}; + var from = {}, to = {}; + for (var p in obj){ + var parsed = Fx.CSS.parse(this.element, p, obj[p]); + from[p] = parsed.from; + to[p] = parsed.to; + this.css[p] = parsed.css; + } + return this.parent(from, to); + }, + + increase: function(){ + for (var p in this.now) this.element.setStyle(p, this.css[p].getValue(this.now[p], this.options.unit, p)); + } + +}); + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: effects + Applies an <Fx.Styles> to the Element; This a shortcut for <Fx.Styles>. + + Example: + >var myEffects = $(myElement).effects({duration: 1000, transition: Fx.Transitions.Sine.easeInOut}); + >myEffects.start({'height': [10, 100], 'width': [900, 300]}); + */ + + effects: function(options){ + return new Fx.Styles(this, options); + } + +}); + +/* +Script: Drag.Base.js + Contains <Drag.Base>, <Element.makeResizable> + +License: + MIT-style license. +*/ + +var Drag = {}; + +/* +Class: Drag.Base + Modify two css properties of an element based on the position of the mouse. + +Note: + Drag.Base requires an XHTML doctype. + +Arguments: + el - the $(element) to apply the transformations to. + options - optional. The options object. + +Options: + handle - the $(element) to act as the handle for the draggable element. defaults to the $(element) itself. + modifiers - an object. see Modifiers Below. + limit - an object, see Limit below. + grid - optional, distance in px for snap-to-grid dragging + snap - optional, the distance you have to drag before the element starts to respond to the drag. defaults to false + + modifiers: + x - string, the style you want to modify when the mouse moves in an horizontal direction. defaults to 'left' + y - string, the style you want to modify when the mouse moves in a vertical direction. defaults to 'top' + + limit: + x - array with start and end limit relative to modifiers.x + y - array with start and end limit relative to modifiers.y + +Events: + onStart - optional, function to execute when the user starts to drag (on mousedown); + onComplete - optional, function to execute when the user completes the drag. + onDrag - optional, function to execute at every step of the drag +*/ + +Drag.Base = new Class({ + + options: { + handle: false, + unit: 'px', + onStart: Class.empty, + onBeforeStart: Class.empty, + onComplete: Class.empty, + onSnap: Class.empty, + onDrag: Class.empty, + limit: false, + modifiers: {x: 'left', y: 'top'}, + grid: false, + snap: 6 + }, + + initialize: function(el, options){ + this.setOptions(options); + this.element = $(el); + this.handle = $(this.options.handle) || this.element; + this.mouse = {'now': {}, 'pos': {}}; + this.value = {'start': {}, 'now': {}}; + this.bound = { + 'start': this.start.bindWithEvent(this), + 'check': this.check.bindWithEvent(this), + 'drag': this.drag.bindWithEvent(this), + 'stop': this.stop.bind(this) + }; + this.attach(); + if (this.options.initialize) this.options.initialize.call(this); + }, + + attach: function(){ + this.handle.addEvent('mousedown', this.bound.start); + return this; + }, + + detach: function(){ + this.handle.removeEvent('mousedown', this.bound.start); + return this; + }, + + start: function(event){ + this.fireEvent('onBeforeStart', this.element); + this.mouse.start = event.page; + var limit = this.options.limit; + this.limit = {'x': [], 'y': []}; + for (var z in this.options.modifiers){ + if (!this.options.modifiers[z]) continue; + this.value.now[z] = this.element.getStyle(this.options.modifiers[z]).toInt(); + this.mouse.pos[z] = event.page[z] - this.value.now[z]; + if (limit && limit[z]){ + for (var i = 0; i < 2; i++){ + if ($chk(limit[z][i])) this.limit[z][i] = ($type(limit[z][i]) == 'function') ? limit[z][i]() : limit[z][i]; + } + } + } + if ($type(this.options.grid) == 'number') this.options.grid = {'x': this.options.grid, 'y': this.options.grid}; + document.addListener('mousemove', this.bound.check); + document.addListener('mouseup', this.bound.stop); + this.fireEvent('onStart', this.element); + event.stop(); + }, + + check: function(event){ + 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){ + document.removeListener('mousemove', this.bound.check); + document.addListener('mousemove', this.bound.drag); + this.drag(event); + this.fireEvent('onSnap', this.element); + } + event.stop(); + }, + + drag: function(event){ + this.out = false; + 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.limit[z]){ + if ($chk(this.limit[z][1]) && (this.value.now[z] > this.limit[z][1])){ + this.value.now[z] = this.limit[z][1]; + this.out = true; + } else if ($chk(this.limit[z][0]) && (this.value.now[z] < this.limit[z][0])){ + this.value.now[z] = this.limit[z][0]; + this.out = true; + } + } + if (this.options.grid[z]) this.value.now[z] -= (this.value.now[z] % this.options.grid[z]); + this.element.setStyle(this.options.modifiers[z], this.value.now[z] + this.options.unit); + } + this.fireEvent('onDrag', this.element); + event.stop(); + }, + + stop: function(){ + document.removeListener('mousemove', this.bound.check); + document.removeListener('mousemove', this.bound.drag); + document.removeListener('mouseup', this.bound.stop); + this.fireEvent('onComplete', this.element); + } + +}); + +Drag.Base.implement(new Events, new Options); + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: makeResizable + Makes an element resizable (by dragging) with the supplied options. + + Arguments: + options - see <Drag.Base> for acceptable options. + */ + + makeResizable: function(options){ + return new Drag.Base(this, $merge({modifiers: {x: 'width', y: 'height'}}, options)); + } + +}); + +/* +Script: Drag.Move.js + Contains <Drag.Move>, <Element.makeDraggable> + +License: + MIT-style license. +*/ + +/* +Class: Drag.Move + Extends <Drag.Base>, has additional functionality for dragging an element, support snapping and droppables. + Drag.move supports either position absolute or relative. If no position is found, absolute will be set. + Inherits methods, properties, options and events from <Drag.Base>. + +Note: + Drag.Move requires an XHTML doctype. + +Arguments: + el - the $(element) to apply the drag to. + options - optional. see Options below. + +Options: + all the drag.Base options, plus: + container - an element, will fill automatically limiting options based on the $(element) size and position. defaults to false (no limiting) + droppables - an array of elements you can drop your draggable to. + overflown - an array of nested scrolling containers, see Element::getPosition +*/ + +Drag.Move = Drag.Base.extend({ + + options: { + droppables: [], + container: false, + overflown: [] + }, + + initialize: function(el, options){ + this.setOptions(options); + this.element = $(el); + this.droppables = $$(this.options.droppables); + this.container = $(this.options.container); + this.position = {'element': this.element.getStyle('position'), 'container': false}; + if (this.container) this.position.container = this.container.getStyle('position'); + if (!['relative', 'absolute', 'fixed'].contains(this.position.element)) this.position.element = 'absolute'; + var top = this.element.getStyle('top').toInt(); + var left = this.element.getStyle('left').toInt(); + if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){ + top = $chk(top) ? top : this.element.getTop(this.options.overflown); + left = $chk(left) ? left : this.element.getLeft(this.options.overflown); + } else { + top = $chk(top) ? top : 0; + left = $chk(left) ? left : 0; + } + this.element.setStyles({'top': top, 'left': left, 'position': this.position.element}); + this.parent(this.element); + }, + + start: function(event){ + this.overed = null; + if (this.container){ + var cont = this.container.getCoordinates(); + var el = this.element.getCoordinates(); + if (this.position.element == 'absolute' && !['relative', 'absolute', 'fixed'].contains(this.position.container)){ + this.options.limit = { + 'x': [cont.left, cont.right - el.width], + 'y': [cont.top, cont.bottom - el.height] + }; + } else { + this.options.limit = { + 'y': [0, cont.height - el.height], + 'x': [0, cont.width - el.width] + }; + } + } + this.parent(event); + }, + + drag: function(event){ + this.parent(event); + var overed = this.out ? false : this.droppables.filter(this.checkAgainst, this).getLast(); + if (this.overed != overed){ + if (this.overed) this.overed.fireEvent('leave', [this.element, this]); + this.overed = overed ? overed.fireEvent('over', [this.element, this]) : null; + } + return this; + }, + + checkAgainst: function(el){ + el = el.getCoordinates(this.options.overflown); + var now = this.mouse.now; + return (now.x > el.left && now.x < el.right && now.y < el.bottom && now.y > el.top); + }, + + stop: function(){ + if (this.overed && !this.out) this.overed.fireEvent('drop', [this.element, this]); + else this.element.fireEvent('emptydrop', this); + this.parent(); + return this; + } + +}); + +/* +Class: Element + Custom class to allow all of its methods to be used with any DOM element via the dollar function <$>. +*/ + +Element.extend({ + + /* + Property: makeDraggable + Makes an element draggable with the supplied options. + + Arguments: + options - see <Drag.Move> and <Drag.Base> for acceptable options. + */ + + makeDraggable: function(options){ + return new Drag.Move(this, options); + } + +}); + +/* Script: XHR.js Contains the basic XMLHttpRequest Class Wrapper. |