2
YUI 3.10.3 (build 2fb5187)
3
Copyright 2013 Yahoo! Inc. All rights reserved.
4
Licensed under the BSD License.
5
http://yuilibrary.com/license/
8
YUI.add('node-base', function (Y, NAME) {
12
* @submodule node-base
17
* Determines whether each node has the given className.
20
* @param {String} className the class name to search for
21
* @return {Boolean} Whether or not the element has the specified class
26
* Adds a class name to each node.
28
* @param {String} className the class name to add to the node's class attribute
34
* Removes a class name from each node.
36
* @param {String} className the class name to remove from the node's class attribute
42
* Replace a class with another class for each node.
43
* If no oldClassName is present, the newClassName is simply added.
44
* @method replaceClass
45
* @param {String} oldClassName the class name to be replaced
46
* @param {String} newClassName the class name that will be replacing the old class name
52
* If the className exists on the node it is removed, if it doesn't exist it is added.
54
* @param {String} className the class name to be toggled
55
* @param {Boolean} force Option to force adding or removing the class.
61
Y.Node.importMethod(Y.DOM, methods);
63
* Determines whether each node has the given className.
67
* @param {String} className the class name to search for
68
* @return {Array} An array of booleans for each node bound to the NodeList.
72
* Adds a class name to each node.
75
* @param {String} className the class name to add to the node's class attribute
80
* Removes a class name from each node.
82
* @see Node.removeClass
83
* @param {String} className the class name to remove from the node's class attribute
88
* Replace a class with another class for each node.
89
* If no oldClassName is present, the newClassName is simply added.
90
* @method replaceClass
91
* @see Node.replaceClass
92
* @param {String} oldClassName the class name to be replaced
93
* @param {String} newClassName the class name that will be replacing the old class name
98
* If the className exists on the node it is removed, if it doesn't exist it is added.
100
* @see Node.toggleClass
101
* @param {String} className the class name to be toggled
104
Y.NodeList.importMethod(Y.Node.prototype, methods);
107
* @submodule node-base
114
* Returns a new dom node using the provided markup string.
117
* @param {String} html The markup used to create the element
118
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
119
* to escape html content.
120
* @param {HTMLDocument} doc An optional document context
121
* @return {Node} A Node instance bound to a DOM node or fragment
124
Y_Node.create = function(html, doc) {
125
if (doc && doc._node) {
128
return Y.one(Y_DOM.create(html, doc));
131
Y.mix(Y_Node.prototype, {
133
* Creates a new Node using the provided markup string.
135
* @param {String} html The markup used to create the element.
136
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
137
* to escape html content.
138
* @param {HTMLDocument} doc An optional document context
139
* @return {Node} A Node instance bound to a DOM node or fragment
141
create: Y_Node.create,
144
* Inserts the content before the reference node.
146
* @param {String | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
147
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
148
* to escape html content.
149
* @param {Int | Node | HTMLElement | String} where The position to insert at.
150
* Possible "where" arguments
153
* <dd>The Node to insert before</dd>
154
* <dt>HTMLElement</dt>
155
* <dd>The element to insert before</dd>
157
* <dd>The index of the child element to insert before</dd>
159
* <dd>Replaces the existing HTML</dd>
161
* <dd>Inserts before the existing HTML</dd>
163
* <dd>Inserts content before the node</dd>
165
* <dd>Inserts content after the node</dd>
169
insert: function(content, where) {
170
this._insert(content, where);
174
_insert: function(content, where) {
175
var node = this._node,
178
if (typeof where == 'number') { // allow index
179
where = this._node.childNodes[where];
180
} else if (where && where._node) { // Node
184
if (content && typeof content != 'string') { // allow Node or NodeList/Array instances
185
content = content._node || content._nodes || content;
187
ret = Y_DOM.addHTML(node, content, where);
193
* Inserts the content as the firstChild of the node.
195
* @param {String | Node | HTMLElement} content The content to insert
196
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
197
* to escape html content.
200
prepend: function(content) {
201
return this.insert(content, 0);
205
* Inserts the content as the lastChild of the node.
207
* @param {String | Node | HTMLElement} content The content to insert
208
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
209
* to escape html content.
212
append: function(content) {
213
return this.insert(content, null);
217
* @method appendChild
218
* @param {String | HTMLElement | Node} node Node to be appended
219
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
220
* to escape html content.
221
* @return {Node} The appended node
223
appendChild: function(node) {
224
return Y_Node.scrubVal(this._insert(node));
228
* @method insertBefore
229
* @param {String | HTMLElement | Node} newNode Node to be appended
230
* @param {HTMLElement | Node} refNode Node to be inserted before
231
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
232
* to escape html content.
233
* @return {Node} The inserted node
235
insertBefore: function(newNode, refNode) {
236
return Y.Node.scrubVal(this._insert(newNode, refNode));
240
* Appends the node to the given node.
242
* @param {Node | HTMLElement} node The node to append to
245
appendTo: function(node) {
246
Y.one(node).append(this);
251
* Replaces the node's current content with the content.
252
* Note that this passes to innerHTML and is not escaped.
253
* Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
254
* to escape html content or `set('text')` to add as text.
256
* @deprecated Use setHTML
257
* @param {String | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
260
setContent: function(content) {
261
this._insert(content, 'replace');
266
* Returns the node's current content (e.g. innerHTML)
268
* @deprecated Use getHTML
269
* @return {String} The current content
271
getContent: function(content) {
272
return this.get('innerHTML');
277
* Replaces the node's current html content with the content provided.
278
* Note that this passes to innerHTML and is not escaped.
279
* Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
281
* @param {String | HTML | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
284
Y.Node.prototype.setHTML = Y.Node.prototype.setContent;
287
* Returns the node's current html content (e.g. innerHTML)
289
* @return {String} The html content
291
Y.Node.prototype.getHTML = Y.Node.prototype.getContent;
293
Y.NodeList.importMethod(Y.Node.prototype, [
295
* Called on each Node instance
303
* Called on each Node instance
311
* Called on each Node instance
313
* @method appendChild
314
* @see Node.appendChild
319
* Called on each Node instance
321
* @method insertBefore
322
* @see Node.insertBefore
327
* Called on each Node instance
335
* Called on each Node instance
336
* Note that this passes to innerHTML and is not escaped.
337
* Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
340
* @deprecated Use setHTML
345
* Called on each Node instance
348
* @deprecated Use getHTML
353
* Called on each Node instance
354
* Note that this passes to innerHTML and is not escaped.
355
* Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
363
* Called on each Node instance
372
* @submodule node-base
379
* Static collection of configuration attributes for special handling
386
* Allows for getting and setting the text of an element.
387
* Formatting is preserved and special characters are treated literally.
393
return Y_DOM.getText(this._node);
396
setter: function(content) {
397
Y_DOM.setText(this._node, content);
403
* Allows for getting and setting the text of an element.
404
* Formatting is preserved and special characters are treated literally.
410
return Y_DOM.getAttribute(this._node, 'for');
413
setter: function(val) {
414
Y_DOM.setAttribute(this._node, 'for', val);
421
return this._node.getElementsByTagName('option');
426
* Returns a NodeList instance of all HTMLElement children.
433
var node = this._node,
434
children = node.children,
438
childNodes = node.childNodes;
441
for (i = 0, len = childNodes.length; i < len; ++i) {
442
if (childNodes[i].tagName) {
443
children[children.length] = childNodes[i];
447
return Y.all(children);
453
return Y_DOM.getValue(this._node);
456
setter: function(val) {
457
Y_DOM.setValue(this._node, val);
463
Y.Node.importMethod(Y.DOM, [
465
* Allows setting attributes on DOM nodes, normalizing in some cases.
466
* This passes through to the DOM node, allowing for custom attributes.
467
* @method setAttribute
471
* @param {string} name The attribute name
472
* @param {string} value The value to set
476
* Allows getting attributes on DOM nodes, normalizing in some cases.
477
* This passes through to the DOM node, allowing for custom attributes.
478
* @method getAttribute
481
* @param {string} name The attribute name
482
* @return {string} The attribute value
489
* @submodule node-base
493
var Y_NodeList = Y.NodeList;
495
* List of events that route to DOM events
497
* @property DOM_EVENTS
501
Y_Node.DOM_EVENTS = {
536
orientationchange: 1,
547
// Add custom event adaptors to this list. This will make it so
548
// that delegate, key, available, contentready, etc all will
549
// be available through Node.on
550
Y.mix(Y_Node.DOM_EVENTS, Y.Env.evt.plugins);
552
Y.augment(Y_Node, Y.EventTarget);
554
Y.mix(Y_Node.prototype, {
556
* Removes event listeners from the node and (optionally) its subtree
558
* @param {Boolean} recurse (optional) Whether or not to remove listeners from the
560
* @param {String} type (optional) Only remove listeners of the specified type
564
purge: function(recurse, type) {
565
Y.Event.purgeElement(this._node, recurse, type);
571
Y.mix(Y.NodeList.prototype, {
572
_prepEvtArgs: function(type, fn, context) {
573
// map to Y.on/after signature (type, fn, nodes, context, arg1, arg2, etc)
574
var args = Y.Array(arguments, 0, true);
576
if (args.length < 2) { // type only (event hash) just add nodes
577
args[2] = this._nodes;
579
args.splice(2, 0, this._nodes);
582
args[3] = context || this; // default to NodeList instance as context
588
Subscribe a callback function for each `Node` in the collection to execute
589
in response to a DOM event.
591
NOTE: Generally, the `on()` method should be avoided on `NodeLists`, in
592
favor of using event delegation from a parent Node. See the Event user
595
Most DOM events are associated with a preventable default behavior, such as
596
link clicks navigating to a new page. Callbacks are passed a
597
`DOMEventFacade` object as their first argument (usually called `e`) that
598
can be used to prevent this default behavior with `e.preventDefault()`. See
599
the `DOMEventFacade` API for all available properties and methods on the
602
By default, the `this` object will be the `NodeList` that the subscription
603
came from, <em>not the `Node` that received the event</em>. Use
604
`e.currentTarget` to refer to the `Node`.
606
Returning `false` from a callback is supported as an alternative to calling
607
`e.preventDefault(); e.stopPropagation();`. However, it is recommended to
608
use the event methods.
612
Y.all(".sku").on("keydown", function (e) {
613
if (e.keyCode === 13) {
616
// Use e.currentTarget to refer to the individual Node
617
var item = Y.MyApp.searchInventory( e.currentTarget.get('value') );
623
@param {String} type The name of the event
624
@param {Function} fn The callback to execute in response to the event
625
@param {Object} [context] Override `this` object in callback
626
@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
627
@return {EventHandle} A subscription handle capable of detaching that
631
on: function(type, fn, context) {
632
return Y.on.apply(Y, this._prepEvtArgs.apply(this, arguments));
636
* Applies an one-time event listener to each Node bound to the NodeList.
638
* @param {String} type The event being listened for
639
* @param {Function} fn The handler to call when the event fires
640
* @param {Object} context The context to call the handler with.
641
* Default is the NodeList instance.
642
* @return {EventHandle} A subscription handle capable of detaching that
646
once: function(type, fn, context) {
647
return Y.once.apply(Y, this._prepEvtArgs.apply(this, arguments));
651
* Applies an event listener to each Node bound to the NodeList.
652
* The handler is called only after all on() handlers are called
653
* and the event is not prevented.
655
* @param {String} type The event being listened for
656
* @param {Function} fn The handler to call when the event fires
657
* @param {Object} context The context to call the handler with.
658
* Default is the NodeList instance.
659
* @return {EventHandle} A subscription handle capable of detaching that
663
after: function(type, fn, context) {
664
return Y.after.apply(Y, this._prepEvtArgs.apply(this, arguments));
668
* Applies an one-time event listener to each Node bound to the NodeList
669
* that will be called only after all on() handlers are called and the
670
* event is not prevented.
673
* @param {String} type The event being listened for
674
* @param {Function} fn The handler to call when the event fires
675
* @param {Object} context The context to call the handler with.
676
* Default is the NodeList instance.
677
* @return {EventHandle} A subscription handle capable of detaching that
681
onceAfter: function(type, fn, context) {
682
return Y.onceAfter.apply(Y, this._prepEvtArgs.apply(this, arguments));
686
Y_NodeList.importMethod(Y.Node.prototype, [
688
* Called on each Node instance
695
/** Called on each Node instance
697
* @see Node.detachAll
704
Subscribe a callback function to execute in response to a DOM event or custom
707
Most DOM events are associated with a preventable default behavior such as
708
link clicks navigating to a new page. Callbacks are passed a `DOMEventFacade`
709
object as their first argument (usually called `e`) that can be used to
710
prevent this default behavior with `e.preventDefault()`. See the
711
`DOMEventFacade` API for all available properties and methods on the object.
713
If the event name passed as the first parameter is not a whitelisted DOM event,
714
it will be treated as a custom event subscriptions, allowing
715
`node.fire('customEventName')` later in the code. Refer to the Event user guide
716
for the full DOM event whitelist.
718
By default, the `this` object in the callback will refer to the subscribed
721
Returning `false` from a callback is supported as an alternative to calling
722
`e.preventDefault(); e.stopPropagation();`. However, it is recommended to use
727
Y.one("#my-form").on("submit", function (e) {
730
// proceed with ajax form submission instead...
734
@param {String} type The name of the event
735
@param {Function} fn The callback to execute in response to the event
736
@param {Object} [context] Override `this` object in callback
737
@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
738
@return {EventHandle} A subscription handle capable of detaching that
743
Y.mix(Y.Node.ATTRS, {
745
setter: function(h) {
746
Y.DOM.setHeight(this._node, h);
751
return this._node.offsetHeight;
756
setter: function(w) {
757
Y.DOM.setWidth(this._node, w);
762
return this._node.offsetWidth;
767
Y.mix(Y.Node.prototype, {
768
sizeTo: function(w, h) {
770
if (arguments.length < 2) {
772
w = node.get('offsetWidth');
773
h = node.get('offsetHeight');
784
* @submodule node-base
789
Y.mix(Y_Node.prototype, {
791
* Makes the node visible.
792
* If the "transition" module is loaded, show optionally
793
* animates the showing of the node using either the default
794
* transition effect ('fadeIn'), or the given named effect.
797
* @param {String} name A named Transition effect to use as the show effect.
798
* @param {Object} config Options to use with the transition.
799
* @param {Function} callback An optional function to run after the transition completes.
802
show: function(callback) {
803
callback = arguments[arguments.length - 1];
804
this.toggleView(true, callback);
809
* The implementation for showing nodes.
810
* Default is to remove the hidden attribute and reset the CSS style.display property.
816
this.removeAttribute('hidden');
818
// For back-compat we need to leave this in for browsers that
819
// do not visually hide a node via the hidden attribute
820
// and for users that check visibility based on style display.
821
this.setStyle('display', '');
825
_isHidden: function() {
826
return Y.DOM.getAttribute(this._node, 'hidden') === 'true';
830
* Displays or hides the node.
831
* If the "transition" module is loaded, toggleView optionally
832
* animates the toggling of the node using given named effect.
835
* @param {String} [name] An optional string value to use as transition effect.
836
* @param {Boolean} [on] An optional boolean value to force the node to be shown or hidden
837
* @param {Function} [callback] An optional function to run after the transition completes.
840
toggleView: function(on, callback) {
841
this._toggleView.apply(this, arguments);
845
_toggleView: function(on, callback) {
846
callback = arguments[arguments.length - 1];
848
// base on current state if not forcing
849
if (typeof on != 'boolean') {
850
on = (this._isHidden()) ? 1 : 0;
859
if (typeof callback == 'function') {
868
* If the "transition" module is loaded, hide optionally
869
* animates the hiding of the node using either the default
870
* transition effect ('fadeOut'), or the given named effect.
872
* @param {String} name A named Transition effect to use as the show effect.
873
* @param {Object} config Options to use with the transition.
874
* @param {Function} callback An optional function to run after the transition completes.
877
hide: function(callback) {
878
callback = arguments[arguments.length - 1];
879
this.toggleView(false, callback);
884
* The implementation for hiding nodes.
885
* Default is to set the hidden attribute to true and set the CSS style.display to 'none'.
891
this.setAttribute('hidden', true);
893
// For back-compat we need to leave this in for browsers that
894
// do not visually hide a node via the hidden attribute
895
// and for users that check visibility based on style display.
896
this.setStyle('display', 'none');
900
Y.NodeList.importMethod(Y.Node.prototype, [
902
* Makes each node visible.
903
* If the "transition" module is loaded, show optionally
904
* animates the showing of the node using either the default
905
* transition effect ('fadeIn'), or the given named effect.
907
* @param {String} name A named Transition effect to use as the show effect.
908
* @param {Object} config Options to use with the transition.
909
* @param {Function} callback An optional function to run after the transition completes.
917
* If the "transition" module is loaded, hide optionally
918
* animates the hiding of the node using either the default
919
* transition effect ('fadeOut'), or the given named effect.
921
* @param {String} name A named Transition effect to use as the show effect.
922
* @param {Object} config Options to use with the transition.
923
* @param {Function} callback An optional function to run after the transition completes.
929
* Displays or hides each node.
930
* If the "transition" module is loaded, toggleView optionally
931
* animates the toggling of the nodes using given named effect.
933
* @param {String} [name] An optional string value to use as transition effect.
934
* @param {Boolean} [on] An optional boolean value to force the nodes to be shown or hidden
935
* @param {Function} [callback] An optional function to run after the transition completes.
941
if (!Y.config.doc.documentElement.hasAttribute) { // IE < 8
942
Y.Node.prototype.hasAttribute = function(attr) {
943
if (attr === 'value') {
944
if (this.get('value') !== "") { // IE < 8 fails to populate specified when set in HTML
948
return !!(this._node.attributes[attr] &&
949
this._node.attributes[attr].specified);
953
// IE throws an error when calling focus() on an element that's invisible, not
954
// displayed, or disabled.
955
Y.Node.prototype.focus = function () {
964
// IE throws error when setting input.type = 'hidden',
965
// input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden'
966
Y.Node.ATTRS.type = {
967
setter: function(val) {
968
if (val === 'hidden') {
970
this._node.type = 'hidden';
972
this.setStyle('display', 'none');
973
this._inputType = 'hidden';
976
try { // IE errors when changing the type from "hidden'
977
this._node.type = val;
985
return this._inputType || this._node.type;
988
_bypassProxy: true // don't update DOM when using with Attribute
991
if (Y.config.doc.createElement('form').elements.nodeType) {
992
// IE: elements collection is also FORM node which trips up scrubVal.
993
Y.Node.ATTRS.elements = {
995
return this.all('input, textarea, button, select');
1001
* Provides methods for managing custom Node data.
1005
* @submodule node-data
1008
Y.mix(Y.Node.prototype, {
1009
_initData: function() {
1010
if (! ('_data' in this)) {
1018
* @description Retrieves arbitrary data stored on a Node instance.
1019
* If no data is associated with the Node, it will attempt to retrieve
1020
* a value from the corresponding HTML data attribute. (e.g. node.getData('foo')
1021
* will check node.getAttribute('data-foo')).
1022
* @param {string} name Optional name of the data field to retrieve.
1023
* If no name is given, all data is returned.
1024
* @return {any | Object} Whatever is stored at the given field,
1025
* or an object hash of all fields.
1027
getData: function(name) {
1029
var data = this._data,
1032
if (arguments.length) { // single field
1035
} else { // initialize from HTML attribute
1036
ret = this._getDataAttribute(name);
1038
} else if (typeof data == 'object' && data !== null) { // all fields
1040
Y.Object.each(data, function(v, n) {
1044
ret = this._getDataAttributes(ret);
1051
_getDataAttributes: function(ret) {
1054
attrs = this._node.attributes,
1056
prefix = this.DATA_PREFIX,
1057
prefixLength = prefix.length,
1061
name = attrs[i].name;
1062
if (name.indexOf(prefix) === 0) {
1063
name = name.substr(prefixLength);
1064
if (!(name in ret)) { // only merge if not already stored
1065
ret[name] = this._getDataAttribute(name);
1075
_getDataAttribute: function(name) {
1076
name = this.DATA_PREFIX + name;
1078
var node = this._node,
1079
attrs = node.attributes,
1080
data = attrs && attrs[name] && attrs[name].value;
1088
* @description Stores arbitrary data on a Node instance.
1089
* This is not stored with the DOM node.
1090
* @param {string} name The name of the field to set. If no val
1091
* is given, name is treated as the data and overrides any existing data.
1092
* @param {any} val The value to be assigned to the field.
1095
setData: function(name, val) {
1097
if (arguments.length > 1) {
1098
this._data[name] = val;
1109
* @description Clears internally stored data.
1110
* @param {string} name The name of the field to clear. If no name
1111
* is given, all data is cleared.
1114
clearData: function(name) {
1115
if ('_data' in this) {
1116
if (typeof name != 'undefined') {
1117
delete this._data[name];
1127
Y.mix(Y.NodeList.prototype, {
1131
* @description Retrieves arbitrary data stored on each Node instance
1132
* bound to the NodeList.
1134
* @param {string} name Optional name of the data field to retrieve.
1135
* If no name is given, all data is returned.
1136
* @return {Array} An array containing all of the data for each Node instance.
1137
* or an object hash of all fields.
1139
getData: function(name) {
1140
var args = (arguments.length) ? [name] : [];
1141
return this._invoke('getData', args, true);
1147
* @description Stores arbitrary data on each Node instance bound to the
1148
* NodeList. This is not stored with the DOM node.
1149
* @param {string} name The name of the field to set. If no name
1150
* is given, name is treated as the data and overrides any existing data.
1151
* @param {any} val The value to be assigned to the field.
1154
setData: function(name, val) {
1155
var args = (arguments.length > 1) ? [name, val] : [name];
1156
return this._invoke('setData', args);
1162
* @description Clears data on all Node instances bound to the NodeList.
1163
* @param {string} name The name of the field to clear. If no name
1164
* is given, all data is cleared.
1167
clearData: function(name) {
1168
var args = (arguments.length) ? [name] : [];
1169
return this._invoke('clearData', [name]);
1174
}, '3.10.3', {"requires": ["event-base", "node-core", "dom-base"]});