[Gd-chatter] r10947 - in trunk/documentation/topic/cms: css js
housel at gwydiondylan.org
housel at gwydiondylan.org
Wed Nov 8 07:00:17 CET 2006
Author: housel
Date: Wed Nov 8 07:00:14 2006
New Revision: 10947
Modified:
trunk/documentation/topic/cms/css/tree.css
trunk/documentation/topic/cms/js/event.js
trunk/documentation/topic/cms/js/treeview.js
trunk/documentation/topic/cms/js/yahoo.js
Log:
Bug: 7249
Update the treeview control from version 0.11.4 of the Yahoo! User
Interface Library.
Modified: trunk/documentation/topic/cms/css/tree.css
==============================================================================
--- trunk/documentation/topic/cms/css/tree.css (original)
+++ trunk/documentation/topic/cms/css/tree.css Wed Nov 8 07:00:14 2006
@@ -1,4 +1,9 @@
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+/*
+Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.com/yui/license.txt
+Version: 0.11.3
+*/
/* first or middle sibling, no children */
.ygtvtn {
Modified: trunk/documentation/topic/cms/js/event.js
==============================================================================
--- trunk/documentation/topic/cms/js/event.js (original)
+++ trunk/documentation/topic/cms/js/event.js Wed Nov 8 07:00:14 2006
@@ -1,62 +1,97 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.10.0
-*/
+/*
+Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+Version: 0.11.4
+*/
/**
* The CustomEvent class lets you define events for your application
* that can be subscribed to by one or more independent component.
*
- * @param {String} type The type of event, which is passed to the callback
- * when the event fires
- * @param {Object} oScope The context the event will fire from. "this" will
- * refer to this object in the callback. Default value:
- * the window object. The listener can override this.
+ * @param {String} type The type of event, which is passed to the callback
+ * when the event fires
+ * @param {Object} oScope The context the event will fire from. "this" will
+ * refer to this object in the callback. Default value:
+ * the window object. The listener can override this.
+ * @param {boolean} silent pass true to prevent the event from writing to
+ * the log system
+ * @namespace YAHOO.util
+ * @class CustomEvent
* @constructor
*/
-YAHOO.util.CustomEvent = function(type, oScope) {
+YAHOO.util.CustomEvent = function(type, oScope, silent) {
+
/**
* The type of event, returned to subscribers when the event fires
+ * @property type
* @type string
*/
this.type = type;
/**
- * The scope the the event will fire from by default. Defaults to the window
+ * The scope the the event will fire from by default. Defaults to the window
* obj
+ * @property scope
* @type object
*/
this.scope = oScope || window;
/**
+ * By default all custom events are logged in the debug build, set silent
+ * to true to disable logging for this event.
+ * @property silent
+ * @type boolean
+ */
+ this.silent = silent;
+
+ /**
* The subscribers to this event
+ * @property subscribers
* @type Subscriber[]
*/
this.subscribers = [];
- // Register with the event utility for automatic cleanup. Made optional
- // so that CustomEvent can be used independently of pe.event
- if (YAHOO.util.Event) {
- YAHOO.util.Event.regCE(this);
+ if (!this.silent) {
}
+
+ // Only add subscribe events for events that are not generated by CustomEvent
+ //if (oScope && (oScope.constructor != this.constructor)) {
+
+ /*
+ * Custom events provide a custom event that fires whenever there is
+ * a new subscriber to the event. This provides an opportunity to
+ * handle the case where there is a non-repeating event that has
+ * already fired has a new subscriber.
+ *
+ * type CustomEvent
+ */
+ //this.subscribeEvent =
+ //new YAHOO.util.CustomEvent("subscribe", this, true);
+
+ //}
};
YAHOO.util.CustomEvent.prototype = {
/**
* Subscribes the caller to this event
+ * @method subscribe
* @param {Function} fn The function to execute
* @param {Object} obj An object to be passed along when the event fires
* @param {boolean} bOverride If true, the obj passed in becomes the execution
* scope of the listener
*/
subscribe: function(fn, obj, bOverride) {
+ //if (this.subscribeEvent) {
+ //this.subscribeEvent.fire(fn, obj, bOverride);
+ //}
+
this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, bOverride) );
},
/**
* Unsubscribes the caller from this event
+ * @method unsubscribe
* @param {Function} fn The function to execute
* @param {Object} obj An object to be passed along when the event fires
* @return {boolean} True if the subscriber was found and detached.
@@ -83,29 +118,47 @@
* - All of the arguments fire() was executed with as an array
* - The custom object (if any) that was passed into the subscribe() method
* </pre>
- *
+ * @method fire
* @param {Array} an arbitrary set of parameters to pass to the handler
*/
fire: function() {
- for (var i=0, len=this.subscribers.length; i<len; ++i) {
+ var len=this.subscribers.length;
+ if (!len && this.silent) {
+ return;
+ }
+
+ var args = [];
+
+ for (var i=0; i<arguments.length; ++i) {
+ args.push(arguments[i]);
+ }
+
+ if (!this.silent) {
+ }
+
+ for (i=0; i<len; ++i) {
var s = this.subscribers[i];
if (s) {
+ if (!this.silent) {
+ }
var scope = (s.override) ? s.obj : this.scope;
- s.fn.call(scope, this.type, arguments, s.obj);
+ s.fn.call(scope, this.type, args, s.obj);
}
}
},
/**
* Removes all listeners
+ * @method unsubscribeAll
*/
unsubscribeAll: function() {
for (var i=0, len=this.subscribers.length; i<len; ++i) {
- this._delete(i);
+ this._delete(len - 1 - i);
}
},
/**
+ * @method _delete
* @private
*/
_delete: function(index) {
@@ -115,23 +168,36 @@
delete s.obj;
}
- delete this.subscribers[index];
+ // delete this.subscribers[index];
+ this.subscribers.splice(index, 1);
+ },
+
+ /**
+ * @method toString
+ */
+ toString: function() {
+ return "CustomEvent: " + "'" + this.type + "', " +
+ "scope: " + this.scope;
+
}
};
/////////////////////////////////////////////////////////////////////
/**
- * @class Stores the subscriber information to be used when the event fires.
+ * Stores the subscriber information to be used when the event fires.
* @param {Function} fn The function to execute
* @param {Object} obj An object to be passed along when the event fires
* @param {boolean} bOverride If true, the obj passed in becomes the execution
* scope of the listener
+ * @class Subscriber
* @constructor
*/
YAHOO.util.Subscriber = function(fn, obj, bOverride) {
+
/**
* The callback that will be execute when the event fires
+ * @property fn
* @type function
*/
this.fn = fn;
@@ -139,6 +205,7 @@
/**
* An optional custom object that will passed to the callback when
* the event fires
+ * @property obj
* @type object
*/
this.obj = obj || null;
@@ -148,6 +215,7 @@
* event is created (usually the object which contains the event).
* By setting override to true, the execution scope becomes the custom
* object passed in by the subscriber
+ * @property override
* @type boolean
*/
this.override = (bOverride);
@@ -157,32 +225,39 @@
* Returns true if the fn and obj match this objects properties.
* Used by the unsubscribe method to match the right subscriber.
*
+ * @method contains
* @param {Function} fn the function to execute
* @param {Object} obj an object to be passed along when the event fires
- * @return {boolean} true if the supplied arguments match this
+ * @return {boolean} true if the supplied arguments match this
* subscriber's signature.
*/
YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
return (this.fn == fn && this.obj == obj);
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+/**
+ * @method toString
+ */
+YAHOO.util.Subscriber.prototype.toString = function() {
+ return "Subscriber { obj: " + (this.obj || "") +
+ ", override: " + (this.override || "no") + " }";
+};
-// Only load this library once. If it is loaded a second time, existing
-// events cannot be detached.
+// The first instance of Event will win if it is loaded more than once.
if (!YAHOO.util.Event) {
/**
- * @class
* The event utility provides functions to add and remove event listeners,
* event cleansing. It also tries to automatically remove listeners it
* registers during the unload event.
- * @constructor
+ * @namespace YAHOO.util
+ * @class Event
*/
YAHOO.util.Event = function() {
/**
* True after the onload event has fired
+ * @property loadComplete
* @type boolean
* @private
*/
@@ -190,6 +265,7 @@
/**
* Cache of wrapped listeners
+ * @property listeners
* @type array
* @private
*/
@@ -197,6 +273,7 @@
/**
* Listeners that will be attached during the onload event
+ * @property delayedListeners
* @type array
* @private
*/
@@ -205,28 +282,23 @@
/**
* User-defined unload function that will be fired before all events
* are detached
+ * @property unloadListeners
* @type array
* @private
*/
var unloadListeners = [];
/**
- * Cache of the custom events that have been defined. Used for
- * automatic cleanup
- * @type array
- * @private
- */
- var customEvents = [];
-
- /**
* Cache of DOM0 event handlers to work around issues with DOM2 events
* in Safari
+ * @property legacyEvents
* @private
*/
var legacyEvents = [];
/**
* Listener stack for DOM0 events
+ * @property legacyHandlers
* @private
*/
var legacyHandlers = [];
@@ -235,24 +307,28 @@
* The number of times to poll after window.onload. This number is
* increased if additional late-bound handlers are requested after
* the page load.
+ * @property retryCount
* @private
*/
var retryCount = 0;
/**
* onAvailable listeners
+ * @property onAvailStack
* @private
*/
var onAvailStack = [];
/**
* Lookup table for legacy events
+ * @property legacyMap
* @private
*/
var legacyMap = [];
/**
* Counter for auto id generation
+ * @property counter
* @private
*/
var counter = 0;
@@ -262,46 +338,53 @@
/**
* The number of times we should look for elements that are not
* in the DOM at the time the event is requested after the document
- * has been loaded. The default is 200 at 50 ms, so it will poll
+ * has been loaded. The default is 200 at amp;50 ms, so it will poll
* for 10 seconds or until all outstanding handlers are bound
* (whichever comes first).
+ * @property POLL_RETRYS
* @type int
*/
POLL_RETRYS: 200,
/**
* The poll interval in milliseconds
+ * @property POLL_INTERVAL
* @type int
*/
POLL_INTERVAL: 50,
/**
* Element to bind, int constant
+ * @property EL
* @type int
*/
EL: 0,
/**
* Type of event, int constant
+ * @property TYPE
* @type int
*/
TYPE: 1,
/**
* Function to execute, int constant
+ * @property FN
* @type int
*/
FN: 2,
/**
* Function wrapped for scope correction and cleanup, int constant
+ * @property WFN
* @type int
*/
WFN: 3,
/**
- * Object passed in by the user that will be returned as a
+ * Object passed in by the user that will be returned as a
* parameter to the callback, int constant
+ * @property SCOPE
* @type int
*/
SCOPE: 3,
@@ -309,29 +392,33 @@
/**
* Adjusted scope, either the element we are registering the event
* on or the custom object passed in by the listener, int constant
+ * @property ADJ_SCOPE
* @type int
*/
ADJ_SCOPE: 4,
/**
* Safari detection is necessary to work around the preventDefault
- * bug that makes it so you can't cancel a href click from the
+ * bug that makes it so you can't cancel a href click from the
* handler. There is not a capabilities check we can use here.
+ * @property isSafari
* @private
*/
isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),
/**
- * IE detection needed to properly calculate pageX and pageY.
- * capabilities checking didn't seem to work because another
- * browser that does not provide the properties have the values
+ * IE detection needed to properly calculate pageX and pageY.
+ * capabilities checking didn't seem to work because another
+ * browser that does not provide the properties have the values
* calculated in a different manner than IE.
+ * @property isIE
* @private
*/
- isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) &&
+ isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) &&
navigator.userAgent.match(/msie/gi)),
/**
+ * @method addDelayedListener
* @private
*/
addDelayedListener: function(el, sType, fn, oScope, bOverride) {
@@ -349,6 +436,7 @@
},
/**
+ * @method startTimeout
* @private
*/
startTimeout: function(interval) {
@@ -365,18 +453,21 @@
* initial page load it will poll for a fixed time for the element.
* The number of times it will poll and the frequency are
* configurable. By default it will poll for 10 seconds.
- * @param {string} p_id the id of the element to look for.
+ *
+ * @method onAvailable
+ *
+ * @param {string} p_id the id of the element to look for.
* @param {function} p_fn what to execute when the element is found.
- * @param {object} p_obj an optional object to be passed back as
- * a parameter to p_fn.
- * @param {boolean} p_override If set to true, p_fn will execute
- * in the scope of p_obj
+ * @param {object} p_obj an optional object to be passed back as
+ * a parameter to p_fn.
+ * @param {boolean} p_override If set to true, p_fn will execute
+ * in the scope of p_obj
*
*/
onAvailable: function(p_id, p_fn, p_obj, p_override) {
- onAvailStack.push( { id: p_id,
- fn: p_fn,
- obj: p_obj,
+ onAvailStack.push( { id: p_id,
+ fn: p_fn,
+ obj: p_obj,
override: p_override } );
retryCount = this.POLL_RETRYS;
@@ -387,16 +478,18 @@
/**
* Appends an event handler
*
- * @param {Object} el The html element to assign the
+ * @method addListener
+ *
+ * @param {Object} el The html element to assign the
* event to
* @param {String} sType The type of event to append
* @param {Function} fn The method the event invokes
- * @param {Object} oScope An arbitrary object that will be
+ * @param {Object} oScope An arbitrary object that will be
* passed as a parameter to the handler
* @param {boolean} bOverride If true, the obj passed in becomes
* the execution scope of the listener
* @return {boolean} True if the action was successful or defered,
- * false if one or more of the elements
+ * false if one or more of the elements
* could not have the event bound to it.
*/
addListener: function(el, sType, fn, oScope, bOverride) {
@@ -409,45 +502,45 @@
if ( this._isValidCollection(el)) {
var ok = true;
for (var i=0,len=el.length; i<len; ++i) {
- ok = ( this.on(el[i],
- sType,
- fn,
- oScope,
+ ok = ( this.on(el[i],
+ sType,
+ fn,
+ oScope,
bOverride) && ok );
}
return ok;
} else if (typeof el == "string") {
var oEl = this.getEl(el);
- // If the el argument is a string, we assume it is
+ // If the el argument is a string, we assume it is
// actually the id of the element. If the page is loaded
- // we convert el to the actual element, otherwise we
+ // we convert el to the actual element, otherwise we
// defer attaching the event until onload event fires
- // check to see if we need to delay hooking up the event
+ // check to see if we need to delay hooking up the event
// until after the page loads.
if (loadComplete && oEl) {
el = oEl;
} else {
// defer adding the event until onload fires
- this.addDelayedListener(el,
- sType,
- fn,
- oScope,
+ this.addDelayedListener(el,
+ sType,
+ fn,
+ oScope,
bOverride);
return true;
}
}
- // Element should be an html element or an array if we get
+ // Element should be an html element or an array if we get
// here.
if (!el) {
return false;
}
- // we need to make sure we fire registered unload events
- // prior to automatically unhooking them. So we hang on to
+ // we need to make sure we fire registered unload events
+ // prior to automatically unhooking them. So we hang on to
// these instead of attaching them to the window and fire the
// handles explicitly during our one unload event.
if ("unload" == sType && oScope !== this) {
@@ -456,7 +549,6 @@
return true;
}
-
// if the user chooses to override the scope, we use the custom
// object passed in, otherwise the executing scope will be the
// HTML element that the event is registered on
@@ -465,7 +557,7 @@
// wrap the function so we can return the oScope object when
// the event fires;
var wrappedFn = function(e) {
- return fn.call(scope, YAHOO.util.Event.getEvent(e),
+ return fn.call(scope, YAHOO.util.Event.getEvent(e),
oScope);
};
@@ -476,18 +568,22 @@
if (this.useLegacyEvent(el, sType)) {
var legacyIndex = this.getLegacyIndex(el, sType);
- if (legacyIndex == -1) {
+
+ // Add a new dom0 wrapper if one is not detected for this
+ // element
+ if ( legacyIndex == -1 ||
+ el != legacyEvents[legacyIndex][0] ) {
legacyIndex = legacyEvents.length;
legacyMap[el.id + sType] = legacyIndex;
- // cache the signature for the DOM0 event, and
+ // cache the signature for the DOM0 event, and
// include the existing handler for the event, if any
- legacyEvents[legacyIndex] =
+ legacyEvents[legacyIndex] =
[el, sType, el["on" + sType]];
legacyHandlers[legacyIndex] = [];
- el["on" + sType] =
+ el["on" + sType] =
function(e) {
YAHOO.util.Event.fireLegacyEvent(
YAHOO.util.Event.getEvent(e), legacyIndex);
@@ -496,29 +592,25 @@
// add a reference to the wrapped listener to our custom
// stack of events
- legacyHandlers[legacyIndex].push(index);
+ //legacyHandlers[legacyIndex].push(index);
+ legacyHandlers[legacyIndex].push(li);
// DOM2 Event model
} else if (el.addEventListener) {
el.addEventListener(sType, wrappedFn, false);
- // Internet Explorer abstraction
+ // IE
} else if (el.attachEvent) {
el.attachEvent("on" + sType, wrappedFn);
}
return true;
-
- },
- /**
- * Shorthand for YAHOO.util.Event.addListener
- * @type function
- */
- // on: this.addListener,
+ },
/**
* When using legacy events, the handler is routed to this object
* so we can fire our custom listener stack.
+ * @method fireLegacyEvent
* @private
*/
fireLegacyEvent: function(e, legacyIndex) {
@@ -526,18 +618,11 @@
var le = legacyHandlers[legacyIndex];
for (var i=0,len=le.length; i<len; ++i) {
- var index = le[i];
- if (index) {
- var li = listeners[index];
- if ( li && li[this.WFN] ) {
- var scope = li[this.ADJ_SCOPE];
- var ret = li[this.WFN].call(scope, e);
- ok = (ok && ret);
- } else {
- // This listener was removed, so delete it from
- // the array
- delete le[i];
- }
+ var li = le[i];
+ if ( li && li[this.WFN] ) {
+ var scope = li[this.ADJ_SCOPE];
+ var ret = li[this.WFN].call(scope, e);
+ ok = (ok && ret);
}
}
@@ -545,37 +630,27 @@
},
/**
- * Returns the legacy event index that matches the supplied
+ * Returns the legacy event index that matches the supplied
* signature
+ * @method getLegacyIndex
* @private
*/
getLegacyIndex: function(el, sType) {
- /*
- for (var i=0,len=legacyEvents.length; i<len; ++i) {
- var le = legacyEvents[i];
- if (le && le[0] === el && le[1] === sType) {
- return i;
- }
- }
- return -1;
- */
-
var key = this.generateId(el) + sType;
- if (typeof legacyMap[key] == "undefined") {
+ if (typeof legacyMap[key] == "undefined") {
return -1;
} else {
return legacyMap[key];
}
-
},
/**
* Logic that determines when we should automatically use legacy
* events instead of DOM2 events.
+ * @method useLegacyEvent
* @private
*/
useLegacyEvent: function(el, sType) {
-
if (!el.addEventListener && !el.attachEvent) {
return true;
} else if (this.isSafari) {
@@ -583,18 +658,19 @@
return true;
}
}
-
return false;
},
-
+
/**
* Removes an event handler
*
- * @param {Object} el the html element or the id of the element to
+ * @method removeListener
+ *
+ * @param {Object} el the html element or the id of the element to
* assign the event to.
* @param {String} sType the type of event to remove
* @param {Function} fn the method the event invokes
- * @return {boolean} true if the unbind was successful, false
+ * @return {boolean} true if the unbind was successful, false
* otherwise
*/
removeListener: function(el, sType, fn, index) {
@@ -603,13 +679,15 @@
return false;
}
+ var i, len;
+
// The el argument can be a string
if (typeof el == "string") {
el = this.getEl(el);
// The el argument can be an array of elements or element ids.
} else if ( this._isValidCollection(el)) {
var ok = true;
- for (var i=0,len=el.length; i<len; ++i) {
+ for (i=0,len=el.length; i<len; ++i) {
ok = ( this.removeListener(el[i], sType, fn) && ok );
}
return ok;
@@ -619,11 +697,11 @@
for (i=0, len=unloadListeners.length; i<len; i++) {
var li = unloadListeners[i];
- if (li &&
- li[0] == el &&
- li[1] == sType &&
+ if (li &&
+ li[0] == el &&
+ li[1] == sType &&
li[2] == fn) {
- delete unloadListeners[i];
+ unloadListeners.splice(i, 1);
return true;
}
}
@@ -632,7 +710,9 @@
}
var cacheItem = null;
-
+
+ //var index = arguments[3];
+
if ("undefined" == typeof index) {
index = this._getCacheIndex(el, sType, fn);
}
@@ -645,8 +725,22 @@
return false;
}
+ if (this.useLegacyEvent(el, sType)) {
+ var legacyIndex = this.getLegacyIndex(el, sType);
+ var llist = legacyHandlers[legacyIndex];
+ if (llist) {
+ for (i=0, len=llist.length; i<len; ++i) {
+ li = llist[i];
+ if (li &&
+ li[this.EL] == el &&
+ li[this.TYPE] == sType &&
+ li[this.FN] == fn) {
+ llist.splice(i, 1);
+ }
+ }
+ }
- if (el.removeEventListener) {
+ } else if (el.removeEventListener) {
el.removeEventListener(sType, cacheItem[this.WFN], false);
} else if (el.detachEvent) {
el.detachEvent("on" + sType, cacheItem[this.WFN]);
@@ -655,7 +749,7 @@
// removed the wrapped handler
delete listeners[index][this.WFN];
delete listeners[index][this.FN];
- delete listeners[index];
+ listeners.splice(index, 1);
return true;
@@ -663,24 +757,39 @@
/**
* Returns the event's target element
+ * @method getTarget
* @param {Event} ev the event
* @param {boolean} resolveTextNode when set to true the target's
- * parent will be returned if the target is a
- * text node
+ * parent will be returned if the target is a
+ * text node. @deprecated, the text node is
+ * now resolved automatically
* @return {HTMLElement} the event's target
*/
getTarget: function(ev, resolveTextNode) {
var t = ev.target || ev.srcElement;
+ return this.resolveTextNode(t);
+ },
- if (resolveTextNode && t && "#text" == t.nodeName) {
- return t.parentNode;
+ /**
+ * In some cases, some browsers will return a text node inside
+ * the actual element that was targeted. This normalizes the
+ * return value for getTarget and getRelatedTarget.
+ * @method resolveTextNode
+ * @param {HTMLElement} node to resolve
+ * @return the normized node
+ */
+ resolveTextNode: function(node) {
+ if (node && node.nodeName &&
+ "#TEXT" == node.nodeName.toUpperCase()) {
+ return node.parentNode;
} else {
- return t;
+ return node;
}
},
/**
* Returns the event's pageX
+ * @method getPageX
* @param {Event} ev the event
* @return {int} the event's pageX
*/
@@ -699,6 +808,7 @@
/**
* Returns the event's pageY
+ * @method getPageY
* @param {Event} ev the event
* @return {int} the event's pageY
*/
@@ -717,6 +827,7 @@
/**
* Returns the pageX and pageY properties as an indexed array.
+ * @method getXY
* @type int[]
*/
getXY: function(ev) {
@@ -724,7 +835,8 @@
},
/**
- * Returns the event's related target
+ * Returns the event's related target
+ * @method getRelatedTarget
* @param {Event} ev the event
* @return {HTMLElement} the event's relatedTarget
*/
@@ -738,12 +850,13 @@
}
}
- return t;
+ return this.resolveTextNode(t);
},
/**
* Returns the time of the event. If the time is not included, the
* event is modified using the current time.
+ * @method getTime
* @param {Event} ev the event
* @return {Date} the time of the event
*/
@@ -752,8 +865,8 @@
var t = new Date().getTime();
try {
ev.time = t;
- } catch(e) {
- // can't set the time property
+ } catch(e) {
+ // can't set the time property
return t;
}
}
@@ -763,6 +876,7 @@
/**
* Convenience method for stopPropagation + preventDefault
+ * @method stopEvent
* @param {Event} ev the event
*/
stopEvent: function(ev) {
@@ -772,6 +886,7 @@
/**
* Stops event propagation
+ * @method stopPropagation
* @param {Event} ev the event
*/
stopPropagation: function(ev) {
@@ -784,6 +899,7 @@
/**
* Prevents the default behavior of the event
+ * @method preventDefault
* @param {Event} ev the event
*/
preventDefault: function(ev) {
@@ -793,15 +909,16 @@
ev.returnValue = false;
}
},
-
+
/**
* Finds the event in the window object, the caller's arguments, or
* in the arguments of another method in the callstack. This is
* executed automatically for events registered through the event
* manager, so the implementer should not normally need to execute
* this function at all.
+ * @method getEvent
* @param {Event} the event parameter from the handler
- * @return {Event} the event
+ * @return {Event} the event
*/
getEvent: function(e) {
var ev = e || window.event;
@@ -822,6 +939,7 @@
/**
* Returns the charcode for an event
+ * @method getCharCode
* @param {Event} ev the event
* @return {int} the event's charCode
*/
@@ -830,15 +948,17 @@
},
/**
- * @private
* Locating the saved event handler data by function ref
+ *
+ * @method _getCacheIndex
+ * @private
*/
_getCacheIndex: function(el, sType, fn) {
for (var i=0,len=listeners.length; i<len; ++i) {
var li = listeners[i];
- if ( li &&
- li[this.FN] == fn &&
- li[this.EL] == el &&
+ if ( li &&
+ li[this.FN] == fn &&
+ li[this.EL] == el &&
li[this.TYPE] == sType ) {
return i;
}
@@ -848,8 +968,9 @@
},
/**
- * Generates an unique ID for the element if it does not already
+ * Generates an unique ID for the element if it does not already
* have one.
+ * @method generateId
* @param el the element
* @return {string} the id of the element
*/
@@ -857,7 +978,8 @@
var id = el.id;
if (!id) {
- id = "yuievtautoid-" + (counter++);
+ id = "yuievtautoid-" + counter;
+ ++counter;
el.id = id;
}
@@ -866,10 +988,11 @@
/**
* We want to be able to use getElementsByTagName as a collection
- * to attach a group of events to. Unfortunately, different
+ * to attach a group of events to. Unfortunately, different
* browsers return different types of collections. This function
- * tests to determine if the object is array-like. It will also
+ * tests to determine if the object is array-like. It will also
* fail if the object is an array, but is empty.
+ * @method _isValidCollection
* @param o the object to test
* @return {boolean} true if the object is array-like and populated
* @private
@@ -887,13 +1010,15 @@
/**
* @private
+ * @property elCache
* DOM element cache
*/
elCache: {},
/**
- * We cache elements bound by id because when the unload event
+ * We cache elements bound by id because when the unload event
* fires, we can no longer use document.getElementById
+ * @method getEl
* @private
*/
getEl: function(id) {
@@ -908,27 +1033,21 @@
clearCache: function() { },
/**
- * Called by CustomEvent instances to provide a handle to the
- * event * that can be removed later on. Should be package
- * protected.
- * @private
- */
- regCE: function(ce) {
- customEvents.push(ce);
- },
-
- /**
- * @private
* hook up any deferred listeners
+ * @method _load
+ * @private
*/
_load: function(e) {
loadComplete = true;
+ var EU = YAHOO.util.Event;
+ EU._simpleRemove(window, "load", EU._load);
},
/**
- * Polling function that runs before the onload event fires,
- * attempting * to attach to DOM Nodes as soon as they are
+ * Polling function that runs before the onload event fires,
+ * attempting to attach to DOM Nodes as soon as they are
* available
+ * @method _tryPreloadAttach
* @private
*/
_tryPreloadAttach: function() {
@@ -939,10 +1058,9 @@
this.locked = true;
-
- // keep trying until after the page is loaded. We need to
- // check the page load state prior to trying to bind the
- // elements so that we can be certain all elements have been
+ // keep trying until after the page is loaded. We need to
+ // check the page load state prior to trying to bind the
+ // elements so that we can be certain all elements have been
// tested appropriately
var tryAgain = !loadComplete;
if (!tryAgain) {
@@ -954,7 +1072,7 @@
for (var i=0,len=delayedListeners.length; i<len; ++i) {
var d = delayedListeners[i];
- // There may be a race condition here, so we need to
+ // There may be a race condition here, so we need to
// verify the array element is usable.
if (d) {
@@ -963,7 +1081,7 @@
var el = this.getEl(d[this.EL]);
if (el) {
- this.on(el, d[this.TYPE], d[this.FN],
+ this.on(el, d[this.TYPE], d[this.FN],
d[this.SCOPE], d[this.ADJ_SCOPE]);
delete delayedListeners[i];
} else {
@@ -975,7 +1093,7 @@
delayedListeners = stillDelayed;
// onAvailable
- notAvail = [];
+ var notAvail = [];
for (i=0,len=onAvailStack.length; i<len ; ++i) {
var item = onAvailStack[i];
if (item) {
@@ -991,7 +1109,7 @@
}
}
- retryCount = (stillDelayed.length === 0 &&
+ retryCount = (stillDelayed.length === 0 &&
notAvail.length === 0) ? 0 : retryCount - 1;
if (tryAgain) {
@@ -1000,37 +1118,111 @@
this.locked = false;
+ return true;
+
+ },
+
+ /**
+ * Removes all listeners attached to the given element via addListener.
+ * Optionally, the node's children can also be purged.
+ * Optionally, you can specify a specific type of event to remove.
+ * @method purgeElement
+ * @param {HTMLElement} el the element to purge
+ * @param {boolean} recurse recursively purge this element's children
+ * as well. Use with caution.
+ * @param {string} sType optional type of listener to purge. If
+ * left out, all listeners will be removed
+ */
+ purgeElement: function(el, recurse, sType) {
+ var elListeners = this.getListeners(el, sType);
+ if (elListeners) {
+ for (var i=0,len=elListeners.length; i<len ; ++i) {
+ var l = elListeners[i];
+ // can't use the index on the changing collection
+ //this.removeListener(el, l.type, l.fn, l.index);
+ this.removeListener(el, l.type, l.fn);
+ }
+ }
+
+ if (recurse && el && el.childNodes) {
+ for (i=0,len=el.childNodes.length; i<len ; ++i) {
+ this.purgeElement(el.childNodes[i], recurse, sType);
+ }
+ }
+ },
+
+ /**
+ * Returns all listeners attached to the given element via addListener.
+ * Optionally, you can specify a specific type of event to return.
+ * @method getListeners
+ * @param el {HTMLElement} the element to inspect
+ * @param sType {string} optional type of listener to return. If
+ * left out, all listeners will be returned
+ * @return {Object} the listener. Contains the following fields:
+ * type: (string) the type of event
+ * fn: (function) the callback supplied to addListener
+ * obj: (object) the custom object supplied to addListener
+ * adjust: (boolean) whether or not to adjust the default scope
+ * index: (int) its position in the Event util listener cache
+ */
+ getListeners: function(el, sType) {
+ var elListeners = [];
+ if (listeners && listeners.length > 0) {
+ for (var i=0,len=listeners.length; i<len ; ++i) {
+ var l = listeners[i];
+ if ( l && l[this.EL] === el &&
+ (!sType || sType === l[this.TYPE]) ) {
+ elListeners.push({
+ type: l[this.TYPE],
+ fn: l[this.FN],
+ obj: l[this.SCOPE],
+ adjust: l[this.ADJ_SCOPE],
+ index: i
+ });
+ }
+ }
+ }
+
+ return (elListeners.length) ? elListeners : null;
},
/**
- * Removes all listeners registered by pe.event. Called
+ * Removes all listeners registered by pe.event. Called
* automatically during the unload event.
+ * @method _unload
* @private
*/
- _unload: function(e, me) {
+ _unload: function(e) {
+
+ var EU = YAHOO.util.Event;
+
for (var i=0,len=unloadListeners.length; i<len; ++i) {
var l = unloadListeners[i];
if (l) {
- var scope = (l[this.ADJ_SCOPE]) ? l[this.SCOPE]: window;
- l[this.FN].call(scope, this.getEvent(e), l[this.SCOPE] );
+ var scope = (l[EU.ADJ_SCOPE]) ? l[EU.SCOPE]: window;
+ l[EU.FN].call(scope, EU.getEvent(e), l[EU.SCOPE] );
+ delete unloadListeners[i];
+ l=null;
}
}
if (listeners && listeners.length > 0) {
- for (i=0,len=listeners.length; i<len ; ++i) {
- l = listeners[i];
+ //for (i=0,len=listeners.length; i<len ; ++i) {
+ var j = listeners.length;
+ while (j) {
+ var index = j-1;
+ l = listeners[index];
if (l) {
- this.removeListener(l[this.EL], l[this.TYPE],
- l[this.FN], i);
+ EU.removeListener(l[EU.EL], l[EU.TYPE],
+ l[EU.FN], index);
}
- }
- this.clearCache();
- }
+ l=null;
+
+ j = j - 1;
+ }
- for (i=0,len=customEvents.length; i<len; ++i) {
- customEvents[i].unsubscribeAll();
- delete customEvents[i];
+ EU.clearCache();
}
for (i=0,len=legacyEvents.length; i<len; ++i) {
@@ -1039,10 +1231,14 @@
// delete the array item
delete legacyEvents[i];
}
+
+ EU._simpleRemove(window, "unload", EU._unload);
+
},
/**
* Returns scrollLeft
+ * @method _getScrollLeft
* @private
*/
_getScrollLeft: function() {
@@ -1051,6 +1247,7 @@
/**
* Returns scrollTop
+ * @method _getScrollTop
* @private
*/
_getScrollTop: function() {
@@ -1058,39 +1255,72 @@
},
/**
- * Returns the scrollTop and scrollLeft. Used to calculate the
+ * Returns the scrollTop and scrollLeft. Used to calculate the
* pageX and pageY in Internet Explorer
+ * @method _getScroll
* @private
*/
_getScroll: function() {
- var dd = document.documentElement; db = document.body;
- if (dd && dd.scrollTop) {
+ var dd = document.documentElement, db = document.body;
+ if (dd && (dd.scrollTop || dd.scrollLeft)) {
return [dd.scrollTop, dd.scrollLeft];
} else if (db) {
return [db.scrollTop, db.scrollLeft];
} else {
return [0, 0];
}
+ },
+
+ /**
+ * Adds a DOM event directly without the caching, cleanup, scope adj, etc
+ *
+ * @param el the elment to bind the handler to
+ * @param {string} sType the type of event handler
+ * @param {function} fn the callback to invoke
+ * @param {boolen} capture or bubble phase
+ * @private
+ */
+ _simpleAdd: function (el, sType, fn, capture) {
+ if (el.addEventListener) {
+ el.addEventListener(sType, fn, (capture));
+ } else if (el.attachEvent) {
+ el.attachEvent("on" + sType, fn);
+ }
+ },
+
+ /**
+ * Basic remove listener
+ *
+ * @param el the elment to bind the handler to
+ * @param {string} sType the type of event handler
+ * @param {function} fn the callback to invoke
+ * @param {boolen} capture or bubble phase
+ * @private
+ */
+ _simpleRemove: function (el, sType, fn, capture) {
+ if (el.removeEventListener) {
+ el.removeEventListener(sType, fn, (capture));
+ } else if (el.detachEvent) {
+ el.detachEvent("on" + sType, fn);
+ }
}
};
+
} ();
/**
- * @private
+ * YAHOO.util.Event.on is an alias for addListener
+ * @method on
+ * @see addListener
*/
YAHOO.util.Event.on = YAHOO.util.Event.addListener;
if (document && document.body) {
YAHOO.util.Event._load();
} else {
- YAHOO.util.Event.on(window, "load", YAHOO.util.Event._load,
- YAHOO.util.Event, true);
+ YAHOO.util.Event._simpleAdd(window, "load", YAHOO.util.Event._load);
}
-
- YAHOO.util.Event.on(window, "unload", YAHOO.util.Event._unload,
- YAHOO.util.Event, true);
-
+ YAHOO.util.Event._simpleAdd(window, "unload", YAHOO.util.Event._unload);
YAHOO.util.Event._tryPreloadAttach();
-
}
Modified: trunk/documentation/topic/cms/js/treeview.js
==============================================================================
--- trunk/documentation/topic/cms/js/treeview.js (original)
+++ trunk/documentation/topic/cms/js/treeview.js Wed Nov 8 07:00:14 2006
@@ -1,24 +1,21 @@
/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.10.0
+Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 0.11.3
*/
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
-
/**
* Contains the tree view state data and the root node. This is an
* ordered tree; child nodes will be displayed in the order created, and
* there currently is no way to change this.
*
* @constructor
- * @todo graft (appendBefore, appendAfter)
- * @param {string} id The id of the element that the tree will be inserted
- * into.
+ * @param {string|HTMLElement} id The id of the element, or the element
+ * itself that the tree will be inserted into.
*/
YAHOO.widget.TreeView = function(id) {
- if (id) { this.init(id); }
+ if (id) { this.init(id); }
};
/**
@@ -36,6 +33,12 @@
*/
id: null,
+ /**
+ * The host element for this tree
+ * @private
+ */
+ _el: null,
+
/**
* Flat collection of all nodes in this tree
*
@@ -85,7 +88,8 @@
/**
* Sets up the animation for expanding children
*
- * @param {string} the type of animation (acceptable constants in YAHOO.widget.TVAnim)
+ * @param {string} the type of animation (acceptable values defined in
+ * YAHOO.widget.TVAnim)
*/
setExpandAnim: function(type) {
if (YAHOO.widget.TVAnim.isValid(type)) {
@@ -96,7 +100,8 @@
/**
* Sets up the animation for collapsing children
*
- * @param {string} the type of animation (acceptable constants in YAHOO.widget.TVAnim)
+ * @param {string} the type of animation (acceptable values defined in
+ * YAHOO.widget.TVAnim)
*/
setCollapseAnim: function(type) {
if (YAHOO.widget.TVAnim.isValid(type)) {
@@ -173,16 +178,22 @@
/**
* Initializes the tree
*
- * @parm {string} id the id of the element that will hold the tree
+ * @parm {string|HTMLElement} id the id of the element that will hold the tree
* @private
*/
init: function(id) {
this.id = id;
+
+ if ("string" !== typeof id) {
+ this._el = id;
+ this.id = this.generateId(id);
+ }
+
this._nodes = [];
// store a global reference
- YAHOO.widget.TreeView.trees[id] = this;
+ YAHOO.widget.TreeView.trees[this.id] = this;
// Set up the root node
this.root = new YAHOO.widget.RootNode(this);
@@ -195,11 +206,22 @@
*/
draw: function() {
var html = this.root.getHtml();
- document.getElementById(this.id).innerHTML = html;
+ this.getEl().innerHTML = html;
this.firstDraw = false;
},
/**
+ * Returns the tree's host element
+ * @return {HTMLElement} the host element
+ */
+ getEl: function() {
+ if (! this._el) {
+ this._el = document.getElementById(this.id);
+ }
+ return this._el;
+ },
+
+ /**
* Nodes register themselves with the tree instance when they are created.
*
* @param node {Node} the node to register
@@ -267,8 +289,7 @@
/**
* Returns a node that has a matching property and value in the data
- * object that was passed into its constructor. Provides a flexible
- * way for the implementer to get a particular node.
+ * object that was passed into its constructor.
*
* @param {object} property the property to search (usually a string)
* @param {object} value the value we want to find (usuall an int or string)
@@ -286,8 +307,28 @@
},
/**
- * Removes the node and its children, and optionally refreshes the branch
- * of the tree that was affected.
+ * Returns a collection of nodes that have a matching property
+ * and value in the data object that was passed into its constructor.
+ *
+ * @param {object} property the property to search (usually a string)
+ * @param {object} value the value we want to find (usuall an int or string)
+ * @return {Array} the matching collection of nodes, null if no match
+ */
+ getNodesByProperty: function(property, value) {
+ var values = [];
+ for (var i in this._nodes) {
+ var n = this._nodes[i];
+ if (n.data && value == n.data[property]) {
+ values.push(n);
+ }
+ }
+
+ return (values.length) ? values : null;
+ },
+
+ /**
+ * Removes the node and its children, and optionally refreshes the
+ * branch of the tree that was affected.
* @param {Node} The node to remove
* @param {boolean} autoRefresh automatically refreshes branch if true
* @return {boolean} False is there was a problem, true otherwise.
@@ -324,12 +365,14 @@
* @param {Node} node the node to purge
*/
removeChildren: function(node) {
- for (var i=0, len=node.children.length;i<len;++i) {
- this._deleteNode(node.children[i]);
+ while (node.children.length) {
+ this._deleteNode(node.children[0]);
}
node.childrenRendered = false;
node.dynamicLoadComplete = false;
+ // node.collapse();
+ node.expand();
node.collapse();
},
@@ -338,15 +381,26 @@
* @private
*/
_deleteNode: function(node) {
- var p = node.parent;
-
// Remove all the child nodes first
this.removeChildren(node);
+ // Remove the node from the tree
+ this.popNode(node);
+ },
+
+ /**
+ * Removes the node from the tree, preserving the child collection
+ * to make it possible to insert the branch into another part of the
+ * tree, or another tree.
+ * @param {Node} the node to remove
+ */
+ popNode: function(node) {
+ var p = node.parent;
+
// Update the parent's collection of children
var a = [];
- for (i=0, len=p.children.length;i<len;++i) {
+ for (var i=0, len=p.children.length;i<len;++i) {
if (p.children[i] != node) {
a[a.length] = p.children[i];
}
@@ -357,29 +411,54 @@
// reset the childrenRendered flag for the parent
p.childrenRendered = false;
- // Update the sibling relationship
- if (node.previousSibling) {
- node.previousSibling.nextSibling = node.nextSibling;
- }
+ // Update the sibling relationship
+ if (node.previousSibling) {
+ node.previousSibling.nextSibling = node.nextSibling;
+ }
- if (node.nextSibling) {
- node.nextSibling.previousSibling = node.previousSibling;
+ if (node.nextSibling) {
+ node.nextSibling.previousSibling = node.previousSibling;
}
+ node.parent = null;
+ node.previousSibling = null;
+ node.nextSibling = null;
+ node.tree = null;
+
// Update the tree's node collection
delete this._nodes[node.index];
},
/**
+ * toString
+ * @return {string} string representation of the tree
+ */
+ toString: function() {
+ return "TreeView " + this.id;
+ },
+
+ /**
+ * private
+ */
+ generateId: function(el) {
+ var id = el.id;
+
+ if (!id) {
+ id = "yui-tv-auto-id-" + YAHOO.widget.TreeView.counter;
+ YAHOO.widget.TreeView.counter++;
+ }
+
+ return id;
+ },
+
+ /**
* Abstract method that is executed when a node is expanded
- *
* @param node {Node} the node that was expanded
*/
onExpand: function(node) { },
/**
* Abstract method that is executed when a node is collapsed
- *
* @param node {Node} the node that was collapsed.
*/
onCollapse: function(node) { }
@@ -395,6 +474,11 @@
YAHOO.widget.TreeView.trees = [];
/**
+ * @private
+ */
+YAHOO.widget.TreeView.counter = 0;
+
+/**
* Global method for getting a tree by its id. Used in the generated
* tree html.
*
@@ -402,8 +486,8 @@
* @return {TreeView} the tree instance requested, null if not found.
*/
YAHOO.widget.TreeView.getTree = function(treeId) {
- var t = YAHOO.widget.TreeView.trees[treeId];
- return (t) ? t : null;
+ var t = YAHOO.widget.TreeView.trees[treeId];
+ return (t) ? t : null;
};
/**
@@ -415,8 +499,8 @@
* @return {Node} the node instance requested, null if not found
*/
YAHOO.widget.TreeView.getNode = function(treeId, nodeIndex) {
- var t = YAHOO.widget.TreeView.getTree(treeId);
- return (t) ? t.getNodeByIndex(nodeIndex) : null;
+ var t = YAHOO.widget.TreeView.getTree(treeId);
+ return (t) ? t.getNodeByIndex(nodeIndex) : null;
};
/**
@@ -428,57 +512,43 @@
* @param {boolean} capture if true event is capture phase, bubble otherwise
*/
YAHOO.widget.TreeView.addHandler = function (el, sType, fn, capture) {
- capture = (capture) ? true : false;
- if (el.addEventListener) {
- el.addEventListener(sType, fn, capture);
- } else if (el.attachEvent) {
- el.attachEvent("on" + sType, fn);
- } else {
- el["on" + sType] = fn;
- }
+ capture = (capture) ? true : false;
+ if (el.addEventListener) {
+ el.addEventListener(sType, fn, capture);
+ } else if (el.attachEvent) {
+ el.attachEvent("on" + sType, fn);
+ } else {
+ el["on" + sType] = fn;
+ }
};
/**
* Attempts to preload the images defined in the styles used to draw the tree by
* rendering off-screen elements that use the styles.
*/
-YAHOO.widget.TreeView.preload = function() {
+YAHOO.widget.TreeView.preload = function(prefix) {
+ prefix = prefix || "ygtv";
+ var styles = ["tn","tm","tmh","tp","tph","ln","lm","lmh","lp","lph","loading"];
- var styles = [
- "ygtvtn",
- "ygtvtm",
- "ygtvtmh",
- "ygtvtp",
- "ygtvtph",
- "ygtvln",
- "ygtvlm",
- "ygtvlmh",
- "ygtvlp",
- "ygtvlph",
- "ygtvloading"
- ];
-
- var sb = [];
-
- for (var i = 0; i < styles.length; ++i) {
- sb[sb.length] = '<span class="' + styles[i] + '"> </span>';
- }
+ var sb = [];
+
+ for (var i = 0; i < styles.length; ++i) {
+ sb[sb.length] = '<span class="' + prefix + styles[i] + '"> </span>';
+ }
- var f = document.createElement("div");
- var s = f.style;
- s.position = "absolute";
- s.top = "-1000px";
- s.left = "-1000px";
- f.innerHTML = sb.join("");
+ var f = document.createElement("DIV");
+ var s = f.style;
+ s.position = "absolute";
+ s.top = "-1000px";
+ s.left = "-1000px";
+ f.innerHTML = sb.join("");
- document.body.appendChild(f);
+ document.body.appendChild(f);
};
YAHOO.widget.TreeView.addHandler(window,
"load", YAHOO.widget.TreeView.preload);
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
-
/**
* The base class for all tree nodes. The node's presentation and behavior in
* response to mouse events is handled in Node subclasses.
@@ -490,7 +560,7 @@
* @constructor
*/
YAHOO.widget.Node = function(oData, oParent, expanded) {
- if (oParent) { this.init(oData, oParent, expanded); }
+ if (oData) { this.init(oData, oParent, expanded); }
};
YAHOO.widget.Node.prototype = {
@@ -668,44 +738,162 @@
* @param expanded {boolean} the initial expanded/collapsed state
*/
init: function(oData, oParent, expanded) {
- this.data = oData;
- this.children = [];
- this.index = YAHOO.widget.TreeView.nodeCount;
+ this.data = oData;
+ this.children = [];
+ this.index = YAHOO.widget.TreeView.nodeCount;
++YAHOO.widget.TreeView.nodeCount;
- this.expanded = expanded;
+ this.expanded = expanded;
// oParent should never be null except when we create the root node.
if (oParent) {
- this.tree = oParent.tree;
- this.parent = oParent;
- this.href = "javascript:" + this.getToggleLink();
- this.depth = oParent.depth + 1;
- this.multiExpand = oParent.multiExpand;
-
oParent.appendChild(this);
}
},
/**
+ * Certain properties for the node cannot be set until the parent
+ * is known. This is called after the node is inserted into a tree.
+ * the parent is also applied to this node's children in order to
+ * make it possible to move a branch from one tree to another.
+ * @param {Node} parentNode this node's parent node
+ * @return {boolean} true if the application was successful
+ */
+ applyParent: function(parentNode) {
+ if (!parentNode) {
+ return false;
+ }
+
+ this.tree = parentNode.tree;
+ this.parent = parentNode;
+ this.depth = parentNode.depth + 1;
+
+ if (! this.href) {
+ this.href = "javascript:" + this.getToggleLink();
+ }
+
+ if (! this.multiExpand) {
+ this.multiExpand = parentNode.multiExpand;
+ }
+
+ this.tree.regNode(this);
+ parentNode.childrenRendered = false;
+
+ // cascade update existing children
+ for (var i=0, len=this.children.length;i<len;++i) {
+ this.children[i].applyParent(this);
+ }
+
+ return true;
+ },
+
+ /**
* Appends a node to the child collection.
*
- * @param node {Node} the new node
+ * @param childNode {Node} the new node
* @return {Node} the child node
* @private
- * @TODO insertBefore, insertAfter
*/
- appendChild: function(node) {
+ appendChild: function(childNode) {
if (this.hasChildren()) {
var sib = this.children[this.children.length - 1];
- sib.nextSibling = node;
- node.previousSibling = sib;
+ sib.nextSibling = childNode;
+ childNode.previousSibling = sib;
}
+ this.children[this.children.length] = childNode;
+ childNode.applyParent(this);
- this.tree.regNode(node);
- this.children[this.children.length] = node;
- this.childrenRendered = false;
- return node;
+ return childNode;
+ },
+ /**
+ * Appends this node to the supplied node's child collection
+ * @param parentNode {Node} the node to append to.
+ * @return {Node} The appended node
+ */
+ appendTo: function(parentNode) {
+ return parentNode.appendChild(this);
+ },
+
+ /**
+ * Inserts this node before this supplied node
+ *
+ * @param node {Node} the node to insert this node before
+ * @return {Node} the inserted node
+ */
+ insertBefore: function(node) {
+ var p = node.parent;
+ if (p) {
+
+ if (this.tree) {
+ this.tree.popNode(this);
+ }
+
+ var refIndex = node.isChildOf(p);
+ p.children.splice(refIndex, 0, this);
+ if (node.previousSibling) {
+ node.previousSibling.nextSibling = this;
+ }
+ this.previousSibling = node.previousSibling;
+ this.nextSibling = node;
+ node.previousSibling = this;
+
+ this.applyParent(p);
+ }
+
+ return this;
+ },
+
+ /**
+ * Inserts this node after the supplied node
+ *
+ * @param node {Node} the node to insert after
+ * @return {Node} the inserted node
+ */
+ insertAfter: function(node) {
+ var p = node.parent;
+ if (p) {
+
+ if (this.tree) {
+ this.tree.popNode(this);
+ }
+
+ var refIndex = node.isChildOf(p);
+
+ if (!node.nextSibling) {
+ return this.appendTo(p);
+ }
+
+ p.children.splice(refIndex + 1, 0, this);
+
+ node.nextSibling.previousSibling = this;
+ this.previousSibling = node;
+ this.nextSibling = node.nextSibling;
+ node.nextSibling = this;
+
+ this.applyParent(p);
+ }
+
+ return this;
+ },
+
+ /**
+ * Returns true if the Node is a child of supplied Node
+ *
+ * @param parentNode {Node} the Node to check
+ * @return {boolean} The node index if this Node is a child of
+ * supplied Node, else -1.
+ * @private
+ */
+ isChildOf: function(parentNode) {
+ if (parentNode && parentNode.children) {
+ for (var i=0, len=parentNode.children.length; i<len ; ++i) {
+ if (parentNode.children[i] === this) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
},
/**
@@ -1238,12 +1426,18 @@
el.className = this.getStyle();
}
}
+ },
+
+ /**
+ * toString
+ * @return {string} string representation of the node
+ */
+ toString: function() {
+ return "Node (" + this.index + ")";
}
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
-
/**
* A custom YAHOO.widget.Node that handles the unique nature of
* the virtual, presentationless root node.
@@ -1265,6 +1459,7 @@
*/
this.tree = oTree;
};
+
YAHOO.widget.RootNode.prototype = new YAHOO.widget.Node();
// overrides YAHOO.widget.Node
@@ -1272,8 +1467,13 @@
return "";
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+YAHOO.widget.RootNode.prototype.toString = function() {
+ return "RootNode";
+};
+YAHOO.widget.RootNode.prototype.loadComplete = function() {
+ this.tree.draw();
+};
/**
* The default node presentation. The first parameter should be
* either a string that will be used as the node's label, or an object
@@ -1290,12 +1490,16 @@
* @param expanded {boolean} the initial expanded/collapsed state
*/
YAHOO.widget.TextNode = function(oData, oParent, expanded) {
- this.type = "TextNode";
+ // this.type = "TextNode";
- if (oParent) {
- this.init(oData, oParent, expanded);
- this.setUpLabel(oData);
- }
+ if (oData) {
+ this.init(oData, oParent, expanded);
+ this.setUpLabel(oData);
+ }
+
+ /**
+ * @private
+ */
};
YAHOO.widget.TextNode.prototype = new YAHOO.widget.Node();
@@ -1330,26 +1534,26 @@
* @param oData string containing the label, or an object with a label property
*/
YAHOO.widget.TextNode.prototype.setUpLabel = function(oData) {
- if (typeof oData == "string") {
- oData = { label: oData };
- }
- this.label = oData.label;
-
- // update the link
- if (oData.href) {
- this.href = oData.href;
- }
+ if (typeof oData == "string") {
+ oData = { label: oData };
+ }
+ this.label = oData.label;
+
+ // update the link
+ if (oData.href) {
+ this.href = oData.href;
+ }
- // set the target
- if (oData.target) {
- this.target = oData.target;
- }
+ // set the target
+ if (oData.target) {
+ this.target = oData.target;
+ }
if (oData.style) {
this.labelStyle = oData.style;
}
- this.labelElId = "ygtvlabelel" + this.index;
+ this.labelElId = "ygtvlabelel" + this.index;
};
/**
@@ -1358,38 +1562,38 @@
* @return {object} the element
*/
YAHOO.widget.TextNode.prototype.getLabelEl = function() {
- return document.getElementById(this.labelElId);
+ return document.getElementById(this.labelElId);
};
// overrides YAHOO.widget.Node
YAHOO.widget.TextNode.prototype.getNodeHtml = function() {
- var sb = [];
+ var sb = [];
- sb[sb.length] = '<table border="0" cellpadding="0" cellspacing="0">';
- sb[sb.length] = '<tr>';
-
- for (i=0;i<this.depth;++i) {
- // sb[sb.length] = '<td class="ygtvdepthcell"> </td>';
- sb[sb.length] = '<td class="' + this.getDepthStyle(i) + '"> </td>';
- }
+ sb[sb.length] = '<table border="0" cellpadding="0" cellspacing="0">';
+ sb[sb.length] = '<tr>';
+
+ for (i=0;i<this.depth;++i) {
+ // sb[sb.length] = '<td class="ygtvdepthcell"> </td>';
+ sb[sb.length] = '<td class="' + this.getDepthStyle(i) + '"> </td>';
+ }
- var getNode = 'YAHOO.widget.TreeView.getNode(\'' +
- this.tree.id + '\',' + this.index + ')';
+ var getNode = 'YAHOO.widget.TreeView.getNode(\'' +
+ this.tree.id + '\',' + this.index + ')';
- sb[sb.length] = '<td';
- // sb[sb.length] = ' onselectstart="return false"';
- sb[sb.length] = ' id="' + this.getToggleElId() + '"';
- sb[sb.length] = ' class="' + this.getStyle() + '"';
- if (this.hasChildren(true)) {
- sb[sb.length] = ' onmouseover="this.className=';
- sb[sb.length] = getNode + '.getHoverStyle()"';
- sb[sb.length] = ' onmouseout="this.className=';
- sb[sb.length] = getNode + '.getStyle()"';
- }
- sb[sb.length] = ' onclick="javascript:' + this.getToggleLink() + '">';
+ sb[sb.length] = '<td';
+ // sb[sb.length] = ' onselectstart="return false"';
+ sb[sb.length] = ' id="' + this.getToggleElId() + '"';
+ sb[sb.length] = ' class="' + this.getStyle() + '"';
+ if (this.hasChildren(true)) {
+ sb[sb.length] = ' onmouseover="this.className=';
+ sb[sb.length] = getNode + '.getHoverStyle()"';
+ sb[sb.length] = ' onmouseout="this.className=';
+ sb[sb.length] = getNode + '.getStyle()"';
+ }
+ sb[sb.length] = ' onclick="javascript:' + this.getToggleLink() + '">';
/*
- sb[sb.length] = '<img id="' + this.getSpacerId() + '"';
+ sb[sb.length] = '<img id="' + this.getSpacerId() + '"';
sb[sb.length] = ' alt=""';
sb[sb.length] = ' tabindex=0';
sb[sb.length] = ' src="' + this.spacerPath + '"';
@@ -1399,32 +1603,32 @@
sb[sb.length] = ' />';
*/
- sb[sb.length] = ' ';
+ sb[sb.length] = ' ';
- sb[sb.length] = '</td>';
- sb[sb.length] = '<td>';
- sb[sb.length] = '<a';
- sb[sb.length] = ' id="' + this.labelElId + '"';
- sb[sb.length] = ' class="' + this.labelStyle + '"';
- sb[sb.length] = ' href="' + this.href + '"';
- sb[sb.length] = ' target="' + this.target + '"';
- sb[sb.length] = ' onclick="return ' + getNode + '.onLabelClick(' + getNode +')"';
- if (this.hasChildren(true)) {
- sb[sb.length] = ' onmouseover="document.getElementById(\'';
- sb[sb.length] = this.getToggleElId() + '\').className=';
- sb[sb.length] = getNode + '.getHoverStyle()"';
- sb[sb.length] = ' onmouseout="document.getElementById(\'';
- sb[sb.length] = this.getToggleElId() + '\').className=';
- sb[sb.length] = getNode + '.getStyle()"';
- }
- sb[sb.length] = ' >';
- sb[sb.length] = this.label;
- sb[sb.length] = '</a>';
- sb[sb.length] = '</td>';
- sb[sb.length] = '</tr>';
- sb[sb.length] = '</table>';
+ sb[sb.length] = '</td>';
+ sb[sb.length] = '<td>';
+ sb[sb.length] = '<a';
+ sb[sb.length] = ' id="' + this.labelElId + '"';
+ sb[sb.length] = ' class="' + this.labelStyle + '"';
+ sb[sb.length] = ' href="' + this.href + '"';
+ sb[sb.length] = ' target="' + this.target + '"';
+ sb[sb.length] = ' onclick="return ' + getNode + '.onLabelClick(' + getNode +')"';
+ if (this.hasChildren(true)) {
+ sb[sb.length] = ' onmouseover="document.getElementById(\'';
+ sb[sb.length] = this.getToggleElId() + '\').className=';
+ sb[sb.length] = getNode + '.getHoverStyle()"';
+ sb[sb.length] = ' onmouseout="document.getElementById(\'';
+ sb[sb.length] = this.getToggleElId() + '\').className=';
+ sb[sb.length] = getNode + '.getStyle()"';
+ }
+ sb[sb.length] = ' >';
+ sb[sb.length] = this.label;
+ sb[sb.length] = '</a>';
+ sb[sb.length] = '</td>';
+ sb[sb.length] = '</tr>';
+ sb[sb.length] = '</table>';
- return sb.join("");
+ return sb.join("");
};
/**
@@ -1436,7 +1640,10 @@
YAHOO.widget.TextNode.prototype.onLabelClick = function(me) {
//return true;
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+
+YAHOO.widget.TextNode.prototype.toString = function() {
+ return "TextNode (" + this.index + ") " + this.label;
+};
/**
* A menu-specific implementation that differs from TextNode in that only
@@ -1445,7 +1652,7 @@
* @constructor
*/
YAHOO.widget.MenuNode = function(oData, oParent, expanded) {
- if (oParent) {
+ if (oData) {
this.init(oData, oParent, expanded);
this.setUpLabel(oData);
}
@@ -1456,11 +1663,17 @@
*/
this.multiExpand = false;
+ /**
+ * @private
+ */
+
};
YAHOO.widget.MenuNode.prototype = new YAHOO.widget.TextNode();
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+YAHOO.widget.MenuNode.prototype.toString = function() {
+ return "MenuNode (" + this.index + ") " + this.label;
+};
/**
* This implementation takes either a string or object for the
@@ -1479,7 +1692,7 @@
* have an icon
*/
YAHOO.widget.HTMLNode = function(oData, oParent, expanded, hasIcon) {
- if (oParent) {
+ if (oData) {
this.init(oData, oParent, expanded);
this.initContent(oData, hasIcon);
}
@@ -1488,8 +1701,8 @@
YAHOO.widget.HTMLNode.prototype = new YAHOO.widget.Node();
/**
- * The CSS class for the label href. Defaults to ygtvlabel, but can be
- * overridden to provide a custom presentation for a specific node.
+ * The CSS class for the html content container. Defaults to ygtvhtml, but
+ * can be overridden to provide a custom presentation for a specific node.
*
* @type string
*/
@@ -1524,6 +1737,10 @@
this.html = oData.html;
this.contentElId = "ygtvcontentel" + this.index;
this.hasIcon = hasIcon;
+
+ /**
+ * @private
+ */
};
/**
@@ -1543,7 +1760,7 @@
sb[sb.length] = '<tr>';
for (i=0;i<this.depth;++i) {
- sb[sb.length] = '<td class="' + this.getDepthStyle(i) + '"> </td>';
+ sb[sb.length] = '<td class="' + this.getDepthStyle(i) + '"> </td>';
}
if (this.hasIcon) {
@@ -1559,7 +1776,7 @@
sb[sb.length] = 'YAHOO.widget.TreeView.getNode(\'';
sb[sb.length] = this.tree.id + '\',' + this.index + ').getStyle()"';
}
- sb[sb.length] = '> </td>';
+ sb[sb.length] = '> </td>';
}
sb[sb.length] = '<td';
@@ -1574,7 +1791,9 @@
return sb.join("");
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+YAHOO.widget.HTMLNode.prototype.toString = function() {
+ return "HTMLNode (" + this.index + ")";
+};
/**
* A static factory class for tree view expand/collapse animations
@@ -1625,8 +1844,6 @@
};
} ();
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
-
/**
* A 1/2 second fade-in animation.
*
@@ -1635,22 +1852,22 @@
* @param callback {function} function to invoke when the animation is finished
*/
YAHOO.widget.TVFadeIn = function(el, callback) {
- /**
- * The element to animate
+ /**
+ * The element to animate
* @type HTMLElement
- */
- this.el = el;
+ */
+ this.el = el;
- /**
- * the callback to invoke when the animation is complete
- *
- * @type function
- */
- this.callback = callback;
+ /**
+ * the callback to invoke when the animation is complete
+ *
+ * @type function
+ */
+ this.callback = callback;
- /**
- * @private
- */
+ /**
+ * @private
+ */
};
/**
@@ -1682,11 +1899,13 @@
*/
onComplete: function() {
this.callback();
+ },
+
+ toString: function() {
+ return "TVFadeIn";
}
};
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
-
/**
* A 1/2 second fade out animation.
*
@@ -1695,22 +1914,22 @@
* @param callback {Function} function to invoke when the animation is finished
*/
YAHOO.widget.TVFadeOut = function(el, callback) {
- /**
- * The element to animate
+ /**
+ * The element to animate
* @type HTMLElement
- */
- this.el = el;
+ */
+ this.el = el;
- /**
- * the callback to invoke when the animation is complete
- *
- * @type function
- */
- this.callback = callback;
+ /**
+ * the callback to invoke when the animation is complete
+ *
+ * @type function
+ */
+ this.callback = callback;
- /**
- * @private
- */
+ /**
+ * @private
+ */
};
/**
@@ -1739,6 +1958,10 @@
// s.opacity = 1;
s.filter = "alpha(opacity=100)";
this.callback();
+ },
+
+ toString: function() {
+ return "TVFadeOut";
}
};
Modified: trunk/documentation/topic/cms/js/yahoo.js
==============================================================================
--- trunk/documentation/topic/cms/js/yahoo.js (original)
+++ trunk/documentation/topic/cms/js/yahoo.js Wed Nov 8 07:00:14 2006
@@ -1,17 +1,26 @@
-/*
-Copyright (c) 2006, Yahoo! Inc. All rights reserved.
-Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 0.10.0
-*/
+/*
+Copyright (c) 2006, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+Version: 0.11.4
+*/
-/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */
+/**
+ * The YAHOO object is the single global object used by YUI Library. It
+ * contains utility function for setting up namespaces, inheritance, and
+ * logging. YAHOO.util, YAHOO.widget, and YAHOO.example are namespaces
+ * created automatically for and used by the library.
+ * @module YAHOO
+ */
/**
- * The Yahoo global namespace
- * @constructor
+ * The YAHOO global namespace object
+ * @class YAHOO
+ * @static
*/
-var YAHOO = window.YAHOO || {};
+if (typeof YAHOO == "undefined") {
+ YAHOO = {};
+}
/**
* Returns the namespace specified and creates it if it doesn't exist
@@ -22,40 +31,77 @@
* Either of the above would create YAHOO.property, then
* YAHOO.property.package
*
- * @param {String} sNameSpace String representation of the desired
- * namespace
- * @return {Object} A reference to the namespace object
+ * Be careful when naming packages. Reserved words may work in some browsers
+ * and not others. For instance, the following will fail in Safari:
+ *
+ * YAHOO.namespace("really.long.nested.namespace");
+ *
+ * This fails because "long" is a future reserved word in ECMAScript
+ * @method namespace
+ * @static
+ * @param {String} ns The name of the namespace
+ * @return {Object} A reference to the namespace object
*/
-YAHOO.namespace = function( sNameSpace ) {
+YAHOO.namespace = function(ns) {
- if (!sNameSpace || !sNameSpace.length) {
+ if (!ns || !ns.length) {
return null;
}
- var levels = sNameSpace.split(".");
-
- var currentNS = YAHOO;
+ var levels = ns.split(".");
+ var nsobj = YAHOO;
// YAHOO is implied, so it is ignored if it is included
for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) {
- currentNS[levels[i]] = currentNS[levels[i]] || {};
- currentNS = currentNS[levels[i]];
+ nsobj[levels[i]] = nsobj[levels[i]] || {};
+ nsobj = nsobj[levels[i]];
}
- return currentNS;
+ return nsobj;
};
/**
- * Global log method.
+ * Uses YAHOO.widget.Logger to output a log message, if the widget is available.
+ *
+ * @method log
+ * @static
+ * @param {string} sMsg The message to log.
+ * @param {string} sCategory The log category for the message. Default
+ * categories are "info", "warn", "error", time".
+ * Custom categories can be used as well. (opt)
+ * @param {string} sSource The source of the the message (opt)
+ * @return {boolean} True if the log operation was successful.
*/
-YAHOO.log = function(sMsg,sCategory) {
- if(YAHOO.widget.Logger) {
- YAHOO.widget.Logger.log(null, sMsg, sCategory);
+YAHOO.log = function(sMsg, sCategory, sSource) {
+ var l = YAHOO.widget.Logger;
+ if(l && l.log) {
+ return l.log(sMsg, sCategory, sSource);
} else {
return false;
}
};
+/**
+ * Utility to set up the prototype, constructor and superclass properties to
+ * support an inheritance strategy that can chain constructors and methods.
+ *
+ * @method extend
+ * @static
+ * @param {function} subclass the object to modify
+ * @param {function} superclass the object to inherit
+ */
+YAHOO.extend = function(subclass, superclass) {
+ var f = function() {};
+ f.prototype = superclass.prototype;
+ subclass.prototype = new f();
+ subclass.prototype.constructor = subclass;
+ subclass.superclass = superclass.prototype;
+ if (superclass.prototype.constructor == Object.prototype.constructor) {
+ superclass.prototype.constructor = superclass;
+ }
+};
+
YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");
+
More information about the chatter
mailing list