2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3 Code licensed under the BSD License:
4 http://developer.yahoo.net/yui/license.txt
8 YUI.add('compat', function(Y) {
11 var COMPAT_ARG = '~yui|2|compat~';
14 if (window.YAHOO != YUI) {
16 // get any existing YAHOO obj props
17 var o = (window.YAHOO) ? YUI.merge(window.YAHOO) : null;
19 // Make the YUI global the YAHOO global
22 // augment old YAHOO props
29 Y.namespace("util", "widget", "example");
31 // case/location change
32 Y.env = (Y.env) ? Y.mix(Y.env, Y.Env) : Y.Env;
33 Y.lang = (Y.lang) ? Y.mix(Y.lang, Y.Lang) : Y.Lang;
40 getVersion: function(name) {
41 return this.Env.modules[name] || null;
47 // add old lang properties
50 augmentObject: function(r, s) {
51 var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
52 return Y.mix(r, s, (wl), wl);
55 augmentProto: function(r, s) {
56 var a = arguments, wl = (a.length > 2) ? Y.Array(a, 2, true) : null;
57 return Y.mix(r, s, (wl), wl, 1);
60 // extend: Y.bind(Y.extend, Y),
62 // merge: Y.bind(Y.merge, Y)
66 L.augment = L.augmentProto;
68 L.hasOwnProperty = function(o, k) {
69 return (o.hasOwnProperty(k));
72 Y.augmentProto = L.augmentProto;
74 // add register function
76 register: function(name, mainClass, data) {
77 var mods = Y.Env.modules;
79 mods[name] = { versions:[], builds:[] };
81 var m=mods[name],v=data.version,b=data.build,ls=Y.Env.listeners;
87 m.mainClass = mainClass;
88 // fire the module load listeners
89 for (var i=0;i<ls.length;i=i+1) {
92 // label the main class
94 mainClass.VERSION = v;
101 // add old load listeners
102 if ("undefined" !== typeof YAHOO_config) {
103 var l=YAHOO_config.listener,ls=Y.Env.listeners,unique=true,i;
105 // if YAHOO is loaded multiple times we need to check to see if
106 // this is a new config object. If it is, add the new component
107 // load listener to the stack
108 for (i=0;i<ls.length;i=i+1) {
120 // add old registration for yahoo
121 Y.register("yahoo", Y, {version: "3.0.0", build: "1549"});
132 * @deprecated use Y.Env.UA.webkit
134 isSafari: Y.UA.webkit,
142 * @deprecated use Y.Env.UA.webkit
147 * Normalized keycodes for webkit/safari
148 * @property webkitKeymap
159 63276: 33, // page up
160 63277: 34, // page down
161 25: 9 // SHIFT-TAB (Safari provides a different key code in
162 // this case, even though the shiftKey modifier is set)
170 * @deprecated use Y.Env.UA.ie
176 * @method _getScrollLeft
180 _getScrollLeft: function() {
181 return this._getScroll()[1];
186 * @method _getScrollTop
190 _getScrollTop: function() {
191 return this._getScroll()[0];
195 * Returns the scrollTop and scrollLeft. Used to calculate the
196 * pageX and pageY in Internet Explorer
201 _getScroll: function() {
202 var d = Y.config.doc, dd = d.documentElement, db = d.body;
203 if (dd && (dd.scrollTop || dd.scrollLeft)) {
204 return [dd.scrollTop, dd.scrollLeft];
206 return [db.scrollTop, db.scrollLeft];
213 * Returns the event's pageX
215 * @param {Event} ev the event
216 * @return {int} the event's pageX
219 getPageX: function(ev) {
225 x += this._getScrollLeft();
233 * Returns the charcode for an event
234 * @method getCharCode
235 * @param {Event} ev the event
236 * @return {int} the event's charCode
239 getCharCode: function(ev) {
240 var code = ev.keyCode || ev.charCode || 0;
242 // webkit normalization
243 if (Y.UA.webkit && (code in Y.Event.webkitKeymap)) {
244 code = Y.Event.webkitKeymap[code];
250 * Returns the event's pageY
252 * @param {Event} ev the event
253 * @return {int} the event's pageY
256 getPageY: function(ev) {
262 y += this._getScrollTop();
271 * Returns the pageX and pageY properties as an indexed array.
273 * @param {Event} ev the event
274 * @return {[x, y]} the pageX and pageY properties of the event
277 getXY: function(ev) {
278 return [this.getPageX(ev), this.getPageY(ev)];
282 * Returns the event's related target
283 * @method getRelatedTarget
284 * @param {Event} ev the event
285 * @return {HTMLElement} the event's relatedTarget
288 getRelatedTarget: function(ev) {
289 var t = ev.relatedTarget;
291 if (ev.type == "mouseout") {
293 } else if (ev.type == "mouseover") {
298 return this.resolveTextNode(t);
302 * Returns the time of the event. If the time is not included, the
303 * event is modified using the current time.
305 * @param {Event} ev the event
306 * @return {Date} the time of the event
309 getTime: function(ev) {
311 var t = new Date().getTime();
324 * Convenience method for stopPropagation + preventDefault
326 * @param {Event} ev the event
329 stopEvent: function(ev) {
330 this.stopPropagation(ev);
331 this.preventDefault(ev);
335 * Stops event propagation
336 * @method stopPropagation
337 * @param {Event} ev the event
340 stopPropagation: function(ev) {
341 if (ev.stopPropagation) {
342 ev.stopPropagation();
344 ev.cancelBubble = true;
349 * Prevents the default behavior of the event
350 * @method preventDefault
351 * @param {Event} ev the event
354 preventDefault: function(ev) {
355 if (ev.preventDefault) {
358 ev.returnValue = false;
363 * Returns the event's target element. Safari sometimes provides
364 * a text node, and this is automatically resolved to the text
365 * node's parent so that it behaves like other browsers.
367 * @param {Event} ev the event
368 * @param {boolean} resolveTextNode when set to true the target's
369 * parent will be returned if the target is a
370 * text node. @deprecated, the text node is
371 * now resolved automatically
372 * @return {HTMLElement} the event's target
375 getTarget: function(ev, resolveTextNode) {
376 var t = ev.target || ev.srcElement;
377 return this.resolveTextNode(t);
381 * In some cases, some browsers will return a text node inside
382 * the actual element that was targeted. This normalizes the
383 * return value for getTarget and getRelatedTarget.
384 * @method resolveTextNode
385 * @param {HTMLElement} node node to resolve
386 * @return {HTMLElement} the normized node
389 resolveTextNode: function(node) {
390 if (node && 3 == node.nodeType) {
391 return node.parentNode;
398 * We cache elements bound by id because when the unload event
399 * fires, we can no longer use document.getElementById
403 * @deprecated Elements are not cached any longer
405 getEl: function(id) {
413 * Calls Y.Event.attach with the correct argument order
414 * @method removeListener
416 Y.Event.removeListener = function(el, type, fn, data, override) {
418 var context, a=[type, fn, el];
423 context = (override === true) ? data : override;
432 return Y.Event.detach.apply(Y.Event, a);
436 * Calls Y.Event.detach with the correct argument order
437 * @method addListener
439 Y.Event.addListener = function(el, type, fn, data, override) {
442 // var a = Y.Array(arguments, 0, true), el = a.shift();
443 // a.splice(2, 0, el);
444 // return Y.Event.attach.apply(Y.Event, a);
445 var context, a=[type, fn, el];
450 context = (override === true) ? data : override;
459 return Y.Event.attach.apply(Y.Event, a);
462 Y.Event.on = Y.Event.addListener;
464 var newOnavail = Y.Event.onAvailable;
466 Y.Event.onAvailable = function(id, fn, p_obj, p_override) {
467 return newOnavail(id, fn, p_obj, p_override, false, true);
470 Y.Event.onContentReady = function(id, fn, p_obj, p_override) {
471 return newOnavail(id, fn, p_obj, p_override, true, true);
474 Y.Event.onDOMReady = function(fn) {
475 var a = Y.Array(arguments, 0, true);
476 a.unshift('event:ready');
477 return Y.on.apply(Y, a);
480 Y.util.Event = Y.Event;
482 var CE = function(type, oScope, silent, signature) {
487 silent: silent || false
488 // signature: signature || CE.LIST
491 CE.superclass.constructor.call(this, type, o);
493 this.signature = signature || CE.LIST;
496 Y.extend(CE, Y.CustomEvent, {
501 * Subscriber listener sigature constant. The LIST type returns three
502 * parameters: the event type, the array of args passed to fire, and
503 * the optional custom object
504 * @property YAHOO.util.CustomEvent.LIST
511 * Subscriber listener sigature constant. The FLAT type returns two
512 * parameters: the first argument passed to fire and the optional
514 * @property YAHOO.util.CustomEvent.FLAT
520 Y.util.CustomEvent = CE;
522 var EP = function() {
523 //console.log('Compat CustomEvent constructor executed: ' + this._yuid);
525 var sub = this.subscribe;
526 Y.EventTarget.apply(this, arguments);
527 this.subscribe = sub;
528 this.__yuiepinit = function() {};
532 Y.extend(EP, Y.EventTarget, {
534 createEvent: function(type, o) {
536 o.signature = o.signature || CE.FLAT;
537 return this.publish(type, o);
540 subscribe: function(type, fn, obj, override) {
541 var ce = this._yuievt.events[type] || this.createEvent(type),
542 a = Y.Array(arguments);
544 if (override && true !== override) {
549 Y.EventTarget.prototype.subscribe.apply(this, a);
552 fireEvent: function(type) {
553 return this.fire.apply(this, arguments);
556 hasEvent: function(type) {
557 return this.getEvent(type);
561 Y.util.EventProvider = EP;
566 Y.register("event", Y, {version: "3.0.0", build: "1549"});
569 var propertyCache = {};
571 HYPHEN: /(-[a-z])/i, // to normalize get/setStyle
572 ROOT_TAG: /^body|html$/i, // body for quirks mode, html for standards,
573 OP_SCROLL:/^(?:inline|table-row)$/i
576 var hyphenToCamel = function(property) {
577 if ( !patterns.HYPHEN.test(property) ) {
578 return property; // no hyphens
581 if (propertyCache[property]) { // already converted
582 return propertyCache[property];
585 var converted = property;
587 while( patterns.HYPHEN.exec(converted) ) {
588 converted = converted.replace(RegExp.$1,
589 RegExp.$1.substr(1).toUpperCase());
592 propertyCache[property] = converted;
594 //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
600 if (el.nodeType || el.item) { // Node, or NodeList
604 if (typeof el === 'string') { // id
605 return document.getElementById(el);
608 if ('length' in el) { // array-like
610 for (var i = 0, len = el.length; i < len; ++i) {
611 c[c.length] = Dom.get(el[i]);
617 return el; // some other object, just pass it back
623 isAncestor: function(haystack, needle) {
624 return YUI.DOM.contains(Dom.get(haystack), Dom.get(needle));
627 inDocument: function(el) {
628 return Dom.isAncestor(Y.config.doc.documentElement, el);
631 batch: function(el, method, o, override, args) {
632 el = (el && (el.tagName || el.item)) ? el : Dom.get(el); // skip get() when possible
634 if (!el || !method) {
638 args = Y.Array(args);
640 var scope = (override) ? o : window;
642 var apply = function(el) {
644 var tmp = slice.call(args);
646 return method.apply(scope, tmp);
648 return method.call(scope, el, o);
652 if (el.tagName || el.length === undefined) { // element or not array-like
658 for (var i = 0, len = el.length; i < len; ++i) {
659 collection[collection.length] = apply(el[i]);
665 // 2.x returns false if already present
666 _addClass: function(el, className) {
667 if ( YUI.DOM.hasClass(el, className) ) {
671 YUI.DOM.addClass(el, className);
675 // 2.x returns false if not present
676 _removeClass: function(el, className) {
677 if ( !YUI.DOM.hasClass(el, className) ) {
681 YUI.DOM.removeClass(el, className);
685 // 2.x returns false if no newClass or same as oldClass
686 _replaceClass: function(el, oldClass, newClass) {
687 if (!newClass || oldClass === newClass) {
691 YUI.DOM.replaceClass(el, oldClass, newClass);
695 getElementsByClassName: function(className, tag, root) {
697 root = (root) ? Dom.get(root) : Y.config.doc;
700 nodes = Y.Selector.query(tag + '.' + className, root);
705 getElementsBy: function(method, tag, root) {
707 root = (root) ? Dom.get(root) : null || document;
711 nodes = YUI.DOM.byTag(tag, root, method);
716 getViewportWidth: YUI.DOM.winWidth,
717 getViewportHeight: YUI.DOM.winHeight,
718 getDocumentWidth: YUI.DOM.docWidth,
719 getDocumentHeight: YUI.DOM.docHeight,
720 getDocumentScrollTop: YUI.DOM.docScrollY,
721 getDocumentScrollLeft: YUI.DOM.docScrollX,
722 getDocumentHeight: YUI.DOM.docHeight,
724 _guid: function(el, prefix) {
725 prefix = prefix || 'yui-gen';
726 Dom._id_counter = Dom._id_counter || 0;
728 if (el && el.id) { // do not override existing ID
732 var id = prefix + Dom._id_counter++;
741 _region: function(el) {
742 if ( (el.parentNode === null || el.offsetParent === null ||
743 YUI.DOM.getStyle(el, 'display') == 'none') && el != el.ownerDocument.body) {
747 return YUI.DOM.region(el);
751 _ancestorByClass: function(element, className) {
752 return YUI.DOM.ancestor(element, function(el) {
753 return YUI.DOM.hasClass(el, className);
757 _ancestorByTag: function(element, tag) {
758 tag = tag.toUpperCase();
759 return YUI.DOM.ancestor(element, function(el) {
760 return el.tagName.toUpperCase() === tag;
765 var slice = [].slice;
767 var wrap = function(fn, name) {
768 Dom[name] = function() {
769 var args = slice.call(arguments);
770 args[0] = Dom.get(args[0]);
771 return fn.apply(Dom, args);
776 getAncestorBy: YUI.DOM.ancestor,
777 getAncestorByClassName: Dom._ancestorByClass,
778 getAncestorByTagName: Dom._ancestorByTag,
779 getPreviousSiblingBy: YUI.DOM.previous,
780 getPreviousSibling: YUI.DOM.previous,
781 getNextSiblingBy: YUI.DOM.next,
782 getNextSibling: YUI.DOM.next,
783 getFirstChildBy: YUI.DOM.firstChild,
784 getFirstChild: YUI.DOM.firstChild,
785 getLastChildBy: YUI.DOM.lastChild,
786 getLastChild: YUI.DOM.lastChild,
787 getChildrenBy: YUI.DOM.children,
788 getChildren: YUI.DOM.children,
789 insertBefore: function(newNode, refNode) {
790 YUI.DOM.insertBefore(Dom.get(newNode), Dom.get(refNode));
792 insertAfter: function(newNode, refNode) {
793 YUI.DOM.insertAfter(Dom.get(newNode), Dom.get(refNode));
797 Y.each(wrapped, wrap);
800 getStyle: YUI.DOM.getStyle,
801 setStyle: YUI.DOM.setStyle,
802 getXY: YUI.DOM.getXY,
803 setXY: YUI.DOM.setXY,
808 getRegion: Dom._region,
809 hasClass: YUI.DOM.hasClass,
810 addClass: Dom._addClass,
811 removeClass: Dom._removeClass,
812 replaceClass: Dom._replaceClass,
813 generateId: Dom._guid
816 Y.each(batched, function(v, n) {
817 Dom[n] = function(el) {
818 var args = slice.call(arguments, 1);
819 return Dom.batch(el, v, null, null, args);
825 YAHOO.util.Region = function(t, r, b, l) {
834 YAHOO.util.Region.prototype.contains = function(region) {
835 return ( region.left >= this.left &&
836 region.right <= this.right &&
837 region.top >= this.top &&
838 region.bottom <= this.bottom );
842 YAHOO.util.Region.prototype.getArea = function() {
843 return ( (this.bottom - this.top) * (this.right - this.left) );
846 YAHOO.util.Region.prototype.intersect = function(region) {
847 var t = Math.max( this.top, region.top );
848 var r = Math.min( this.right, region.right );
849 var b = Math.min( this.bottom, region.bottom );
850 var l = Math.max( this.left, region.left );
852 if (b >= t && r >= l) {
853 return new YAHOO.util.Region(t, r, b, l);
859 YAHOO.util.Region.prototype.union = function(region) {
860 var t = Math.min( this.top, region.top );
861 var r = Math.max( this.right, region.right );
862 var b = Math.max( this.bottom, region.bottom );
863 var l = Math.min( this.left, region.left );
865 return new YAHOO.util.Region(t, r, b, l);
868 YAHOO.util.Region.prototype.toString = function() {
869 return ( "Region {" +
871 ", right: " + this.right +
872 ", bottom: " + this.bottom +
873 ", left: " + this.left +
877 YAHOO.util.Region.getRegion = function(el) {
878 return YUI.DOM.region(el);
881 YAHOO.util.Point = function(x, y) {
882 if (YAHOO.lang.isArray(x)) { // accept input from Dom.getXY, Event.getXY, etc.
883 y = x[1]; // dont blow away x yet
887 this.x = this.right = this.left = this[0] = x;
888 this.y = this.top = this.bottom = this[1] = y;
891 YAHOO.util.Point.prototype = new YAHOO.util.Region();
895 }, '3.0.0' ,{requires:['dom','event']});
896 YUI._setup(); YUI.use('dom', 'event', 'compat');