[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 Yahoo! Inc. All rights reserved. 4 Licensed under the BSD License. 5 http://yuilibrary.com/license/ 6 */ 7 8 YUI.add('node-base', function (Y, NAME) { 9 10 /** 11 * @module node 12 * @submodule node-base 13 */ 14 15 var methods = [ 16 /** 17 * Determines whether the node has the given className. 18 * @method hasClass 19 * @for Node 20 * @param {String} className the class name to search for 21 * @return {Boolean} Whether or not the node has the specified class 22 */ 23 'hasClass', 24 25 /** 26 * Adds a class name to the node. 27 * @method addClass 28 * @param {String} className the class name to add to the node's class attribute 29 * @chainable 30 */ 31 'addClass', 32 33 /** 34 * Removes a class name from the node. 35 * @method removeClass 36 * @param {String} className the class name to remove from the node's class attribute 37 * @chainable 38 */ 39 'removeClass', 40 41 /** 42 * Replace a class with another class on the 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 47 * @chainable 48 */ 49 'replaceClass', 50 51 /** 52 * If the className exists on the node it is removed, if it doesn't exist it is added. 53 * @method toggleClass 54 * @param {String} className the class name to be toggled 55 * @param {Boolean} force Option to force adding or removing the class. 56 * @chainable 57 */ 58 'toggleClass' 59 ]; 60 61 Y.Node.importMethod(Y.DOM, methods); 62 /** 63 * Determines whether each node has the given className. 64 * @method hasClass 65 * @see Node.hasClass 66 * @for NodeList 67 * @param {String} className the class name to search for 68 * @return {Array} An array of booleans for each node bound to the NodeList. 69 */ 70 71 /** 72 * Adds a class name to each node. 73 * @method addClass 74 * @see Node.addClass 75 * @param {String} className the class name to add to each node's class attribute 76 * @chainable 77 */ 78 79 /** 80 * Removes a class name from each node. 81 * @method removeClass 82 * @see Node.removeClass 83 * @param {String} className the class name to remove from each node's class attribute 84 * @chainable 85 */ 86 87 /** 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 94 * @chainable 95 */ 96 97 /** 98 * For each node, if the className exists on the node it is removed, if it doesn't exist it is added. 99 * @method toggleClass 100 * @see Node.toggleClass 101 * @param {String} className the class name to be toggled 102 * @chainable 103 */ 104 Y.NodeList.importMethod(Y.Node.prototype, methods); 105 /** 106 * @module node 107 * @submodule node-base 108 */ 109 110 var Y_Node = Y.Node, 111 Y_DOM = Y.DOM; 112 113 /** 114 * Returns a new dom node using the provided markup string. 115 * @method create 116 * @static 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 122 * @for Node 123 */ 124 Y_Node.create = function(html, doc) { 125 if (doc && doc._node) { 126 doc = doc._node; 127 } 128 return Y.one(Y_DOM.create(html, doc)); 129 }; 130 131 Y.mix(Y_Node.prototype, { 132 /** 133 * Creates a new Node using the provided markup string. 134 * @method create 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 140 */ 141 create: Y_Node.create, 142 143 /** 144 * Inserts the content before the reference node. 145 * @method insert 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 151 * <dl> 152 * <dt>Y.Node</dt> 153 * <dd>The Node to insert before</dd> 154 * <dt>HTMLElement</dt> 155 * <dd>The element to insert before</dd> 156 * <dt>Int</dt> 157 * <dd>The index of the child element to insert before</dd> 158 * <dt>"replace"</dt> 159 * <dd>Replaces the existing HTML</dd> 160 * <dt>"before"</dt> 161 * <dd>Inserts before the existing HTML</dd> 162 * <dt>"before"</dt> 163 * <dd>Inserts content before the node</dd> 164 * <dt>"after"</dt> 165 * <dd>Inserts content after the node</dd> 166 * </dl> 167 * @chainable 168 */ 169 insert: function(content, where) { 170 this._insert(content, where); 171 return this; 172 }, 173 174 _insert: function(content, where) { 175 var node = this._node, 176 ret = null; 177 178 if (typeof where == 'number') { // allow index 179 where = this._node.childNodes[where]; 180 } else if (where && where._node) { // Node 181 where = where._node; 182 } 183 184 if (content && typeof content != 'string') { // allow Node or NodeList/Array instances 185 content = content._node || content._nodes || content; 186 } 187 ret = Y_DOM.addHTML(node, content, where); 188 189 return ret; 190 }, 191 192 /** 193 * Inserts the content as the firstChild of the node. 194 * @method prepend 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. 198 * @chainable 199 */ 200 prepend: function(content) { 201 return this.insert(content, 0); 202 }, 203 204 /** 205 * Inserts the content as the lastChild of the node. 206 * @method append 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. 210 * @chainable 211 */ 212 append: function(content) { 213 return this.insert(content, null); 214 }, 215 216 /** 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 222 */ 223 appendChild: function(node) { 224 return Y_Node.scrubVal(this._insert(node)); 225 }, 226 227 /** 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 234 */ 235 insertBefore: function(newNode, refNode) { 236 return Y.Node.scrubVal(this._insert(newNode, refNode)); 237 }, 238 239 /** 240 * Appends the node to the given node. 241 * @example 242 * // appendTo returns the node that has been created beforehand 243 * Y.Node.create('<p></p>').appendTo('body').set('text', 'hello world!'); 244 * @method appendTo 245 * @param {Node | HTMLElement | String} node The node to append to. 246 * If `node` is a string it will be considered as a css selector and only the first matching node will be used. 247 * @chainable 248 */ 249 appendTo: function(node) { 250 Y.one(node).append(this); 251 return this; 252 }, 253 254 // This method is deprecated, and is intentionally left undocumented. 255 // Use `setHTML` instead. 256 setContent: function(content) { 257 this._insert(content, 'replace'); 258 return this; 259 }, 260 261 // This method is deprecated, and is intentionally left undocumented. 262 // Use `getHTML` instead. 263 getContent: function() { 264 var node = this; 265 266 if (node._node.nodeType === 11) { // 11 === Node.DOCUMENT_FRAGMENT_NODE 267 // "this", when it is a document fragment, must be cloned because 268 // the nodes contained in the fragment actually disappear once 269 // the fragment is appended anywhere 270 node = node.create("<div/>").append(node.cloneNode(true)); 271 } 272 273 return node.get("innerHTML"); 274 } 275 }); 276 277 /** 278 * Replaces the node's current html content with the content provided. 279 * Note that this passes to innerHTML and is not escaped. 280 * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a> 281 * to escape html content or `set('text')` to add as text. 282 * @method setHTML 283 * @param {String | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert 284 * @chainable 285 */ 286 Y.Node.prototype.setHTML = Y.Node.prototype.setContent; 287 288 /** 289 * Returns the node's current html content (e.g. innerHTML) 290 * @method getHTML 291 * @return {String} The html content 292 */ 293 Y.Node.prototype.getHTML = Y.Node.prototype.getContent; 294 295 Y.NodeList.importMethod(Y.Node.prototype, [ 296 /** 297 * Called on each Node instance 298 * @for NodeList 299 * @method append 300 * @see Node.append 301 */ 302 'append', 303 304 /** 305 * Called on each Node instance 306 * @for NodeList 307 * @method insert 308 * @see Node.insert 309 */ 310 'insert', 311 312 /** 313 * Called on each Node instance 314 * @for NodeList 315 * @method appendChild 316 * @see Node.appendChild 317 */ 318 'appendChild', 319 320 /** 321 * Called on each Node instance 322 * @for NodeList 323 * @method insertBefore 324 * @see Node.insertBefore 325 */ 326 'insertBefore', 327 328 /** 329 * Called on each Node instance 330 * @for NodeList 331 * @method prepend 332 * @see Node.prepend 333 */ 334 'prepend', 335 336 'setContent', 337 338 'getContent', 339 340 /** 341 * Called on each Node instance 342 * Note that this passes to innerHTML and is not escaped. 343 * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a> 344 * to escape html content or `set('text')` to add as text. 345 * @for NodeList 346 * @method setHTML 347 * @see Node.setHTML 348 */ 349 'setHTML', 350 351 /** 352 * Called on each Node instance 353 * @for NodeList 354 * @method getHTML 355 * @see Node.getHTML 356 */ 357 'getHTML' 358 ]); 359 /** 360 * @module node 361 * @submodule node-base 362 */ 363 364 var Y_Node = Y.Node, 365 Y_DOM = Y.DOM; 366 367 /** 368 * Static collection of configuration attributes for special handling 369 * @property ATTRS 370 * @static 371 * @type object 372 */ 373 Y_Node.ATTRS = { 374 /** 375 * Allows for getting and setting the text of an element. 376 * Formatting is preserved and special characters are treated literally. 377 * @config text 378 * @type String 379 */ 380 text: { 381 getter: function() { 382 return Y_DOM.getText(this._node); 383 }, 384 385 setter: function(content) { 386 Y_DOM.setText(this._node, content); 387 return content; 388 } 389 }, 390 391 /** 392 * Allows for getting and setting the text of an element. 393 * Formatting is preserved and special characters are treated literally. 394 * @config for 395 * @type String 396 */ 397 'for': { 398 getter: function() { 399 return Y_DOM.getAttribute(this._node, 'for'); 400 }, 401 402 setter: function(val) { 403 Y_DOM.setAttribute(this._node, 'for', val); 404 return val; 405 } 406 }, 407 408 'options': { 409 getter: function() { 410 return this._node.getElementsByTagName('option'); 411 } 412 }, 413 414 /** 415 * Returns a NodeList instance of all HTMLElement children. 416 * @readOnly 417 * @config children 418 * @type NodeList 419 */ 420 'children': { 421 getter: function() { 422 var node = this._node, 423 children = node.children, 424 childNodes, i, len; 425 426 if (!children) { 427 childNodes = node.childNodes; 428 children = []; 429 430 for (i = 0, len = childNodes.length; i < len; ++i) { 431 if (childNodes[i].tagName) { 432 children[children.length] = childNodes[i]; 433 } 434 } 435 } 436 return Y.all(children); 437 } 438 }, 439 440 value: { 441 getter: function() { 442 return Y_DOM.getValue(this._node); 443 }, 444 445 setter: function(val) { 446 Y_DOM.setValue(this._node, val); 447 return val; 448 } 449 } 450 }; 451 452 Y.Node.importMethod(Y.DOM, [ 453 /** 454 * Allows setting attributes on DOM nodes, normalizing in some cases. 455 * This passes through to the DOM node, allowing for custom attributes. 456 * @method setAttribute 457 * @for Node 458 * @for NodeList 459 * @chainable 460 * @param {string} name The attribute name 461 * @param {string} value The value to set 462 */ 463 'setAttribute', 464 /** 465 * Allows getting attributes on DOM nodes, normalizing in some cases. 466 * This passes through to the DOM node, allowing for custom attributes. 467 * @method getAttribute 468 * @for Node 469 * @for NodeList 470 * @param {string} name The attribute name 471 * @return {string} The attribute value 472 */ 473 'getAttribute' 474 475 ]); 476 /** 477 * @module node 478 * @submodule node-base 479 */ 480 481 var Y_Node = Y.Node; 482 var Y_NodeList = Y.NodeList; 483 /** 484 * List of events that route to DOM events 485 * @static 486 * @property DOM_EVENTS 487 * @for Node 488 */ 489 490 Y_Node.DOM_EVENTS = { 491 abort: 1, 492 beforeunload: 1, 493 blur: 1, 494 change: 1, 495 click: 1, 496 close: 1, 497 command: 1, 498 contextmenu: 1, 499 copy: 1, 500 cut: 1, 501 dblclick: 1, 502 DOMMouseScroll: 1, 503 drag: 1, 504 dragstart: 1, 505 dragenter: 1, 506 dragover: 1, 507 dragleave: 1, 508 dragend: 1, 509 drop: 1, 510 error: 1, 511 focus: 1, 512 key: 1, 513 keydown: 1, 514 keypress: 1, 515 keyup: 1, 516 load: 1, 517 message: 1, 518 mousedown: 1, 519 mouseenter: 1, 520 mouseleave: 1, 521 mousemove: 1, 522 mousemultiwheel: 1, 523 mouseout: 1, 524 mouseover: 1, 525 mouseup: 1, 526 mousewheel: 1, 527 orientationchange: 1, 528 paste: 1, 529 reset: 1, 530 resize: 1, 531 select: 1, 532 selectstart: 1, 533 submit: 1, 534 scroll: 1, 535 textInput: 1, 536 unload: 1, 537 invalid: 1 538 }; 539 540 // Add custom event adaptors to this list. This will make it so 541 // that delegate, key, available, contentready, etc all will 542 // be available through Node.on 543 Y.mix(Y_Node.DOM_EVENTS, Y.Env.evt.plugins); 544 545 Y.augment(Y_Node, Y.EventTarget); 546 547 Y.mix(Y_Node.prototype, { 548 /** 549 * Removes event listeners from the node and (optionally) its subtree 550 * @method purge 551 * @param {Boolean} recurse (optional) Whether or not to remove listeners from the 552 * node's subtree 553 * @param {String} type (optional) Only remove listeners of the specified type 554 * @chainable 555 * 556 */ 557 purge: function(recurse, type) { 558 Y.Event.purgeElement(this._node, recurse, type); 559 return this; 560 } 561 562 }); 563 564 Y.mix(Y.NodeList.prototype, { 565 _prepEvtArgs: function(type, fn, context) { 566 // map to Y.on/after signature (type, fn, nodes, context, arg1, arg2, etc) 567 var args = Y.Array(arguments, 0, true); 568 569 if (args.length < 2) { // type only (event hash) just add nodes 570 args[2] = this._nodes; 571 } else { 572 args.splice(2, 0, this._nodes); 573 } 574 575 args[3] = context || this; // default to NodeList instance as context 576 577 return args; 578 }, 579 580 /** 581 Subscribe a callback function for each `Node` in the collection to execute 582 in response to a DOM event. 583 584 NOTE: Generally, the `on()` method should be avoided on `NodeLists`, in 585 favor of using event delegation from a parent Node. See the Event user 586 guide for details. 587 588 Most DOM events are associated with a preventable default behavior, such as 589 link clicks navigating to a new page. Callbacks are passed a 590 `DOMEventFacade` object as their first argument (usually called `e`) that 591 can be used to prevent this default behavior with `e.preventDefault()`. See 592 the `DOMEventFacade` API for all available properties and methods on the 593 object. 594 595 By default, the `this` object will be the `NodeList` that the subscription 596 came from, <em>not the `Node` that received the event</em>. Use 597 `e.currentTarget` to refer to the `Node`. 598 599 Returning `false` from a callback is supported as an alternative to calling 600 `e.preventDefault(); e.stopPropagation();`. However, it is recommended to 601 use the event methods. 602 603 @example 604 605 Y.all(".sku").on("keydown", function (e) { 606 if (e.keyCode === 13) { 607 e.preventDefault(); 608 609 // Use e.currentTarget to refer to the individual Node 610 var item = Y.MyApp.searchInventory( e.currentTarget.get('value') ); 611 // etc ... 612 } 613 }); 614 615 @method on 616 @param {String} type The name of the event 617 @param {Function} fn The callback to execute in response to the event 618 @param {Object} [context] Override `this` object in callback 619 @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 620 @return {EventHandle} A subscription handle capable of detaching that 621 subscription 622 @for NodeList 623 **/ 624 on: function(type, fn, context) { 625 return Y.on.apply(Y, this._prepEvtArgs.apply(this, arguments)); 626 }, 627 628 /** 629 * Applies an one-time event listener to each Node bound to the NodeList. 630 * @method once 631 * @param {String} type The event being listened for 632 * @param {Function} fn The handler to call when the event fires 633 * @param {Object} context The context to call the handler with. 634 * Default is the NodeList instance. 635 * @return {EventHandle} A subscription handle capable of detaching that 636 * subscription 637 * @for NodeList 638 */ 639 once: function(type, fn, context) { 640 return Y.once.apply(Y, this._prepEvtArgs.apply(this, arguments)); 641 }, 642 643 /** 644 * Applies an event listener to each Node bound to the NodeList. 645 * The handler is called only after all on() handlers are called 646 * and the event is not prevented. 647 * @method after 648 * @param {String} type The event being listened for 649 * @param {Function} fn The handler to call when the event fires 650 * @param {Object} context The context to call the handler with. 651 * Default is the NodeList instance. 652 * @return {EventHandle} A subscription handle capable of detaching that 653 * subscription 654 * @for NodeList 655 */ 656 after: function(type, fn, context) { 657 return Y.after.apply(Y, this._prepEvtArgs.apply(this, arguments)); 658 }, 659 660 /** 661 * Applies an one-time event listener to each Node bound to the NodeList 662 * that will be called only after all on() handlers are called and the 663 * event is not prevented. 664 * 665 * @method onceAfter 666 * @param {String} type The event being listened for 667 * @param {Function} fn The handler to call when the event fires 668 * @param {Object} context The context to call the handler with. 669 * Default is the NodeList instance. 670 * @return {EventHandle} A subscription handle capable of detaching that 671 * subscription 672 * @for NodeList 673 */ 674 onceAfter: function(type, fn, context) { 675 return Y.onceAfter.apply(Y, this._prepEvtArgs.apply(this, arguments)); 676 } 677 }); 678 679 Y_NodeList.importMethod(Y.Node.prototype, [ 680 /** 681 * Called on each Node instance 682 * @method detach 683 * @see Node.detach 684 * @for NodeList 685 */ 686 'detach', 687 688 /** Called on each Node instance 689 * @method detachAll 690 * @see Node.detachAll 691 * @for NodeList 692 */ 693 'detachAll' 694 ]); 695 696 /** 697 Subscribe a callback function to execute in response to a DOM event or custom 698 event. 699 700 Most DOM events are associated with a preventable default behavior such as 701 link clicks navigating to a new page. Callbacks are passed a `DOMEventFacade` 702 object as their first argument (usually called `e`) that can be used to 703 prevent this default behavior with `e.preventDefault()`. See the 704 `DOMEventFacade` API for all available properties and methods on the object. 705 706 If the event name passed as the first parameter is not a whitelisted DOM event, 707 it will be treated as a custom event subscriptions, allowing 708 `node.fire('customEventName')` later in the code. Refer to the Event user guide 709 for the full DOM event whitelist. 710 711 By default, the `this` object in the callback will refer to the subscribed 712 `Node`. 713 714 Returning `false` from a callback is supported as an alternative to calling 715 `e.preventDefault(); e.stopPropagation();`. However, it is recommended to use 716 the event methods. 717 718 @example 719 720 Y.one("#my-form").on("submit", function (e) { 721 e.preventDefault(); 722 723 // proceed with ajax form submission instead... 724 }); 725 726 @method on 727 @param {String} type The name of the event 728 @param {Function} fn The callback to execute in response to the event 729 @param {Object} [context] Override `this` object in callback 730 @param {Any} [arg*] 0..n additional arguments to supply to the subscriber 731 @return {EventHandle} A subscription handle capable of detaching that 732 subscription 733 @for Node 734 **/ 735 736 Y.mix(Y.Node.ATTRS, { 737 offsetHeight: { 738 setter: function(h) { 739 Y.DOM.setHeight(this._node, h); 740 return h; 741 }, 742 743 getter: function() { 744 return this._node.offsetHeight; 745 } 746 }, 747 748 offsetWidth: { 749 setter: function(w) { 750 Y.DOM.setWidth(this._node, w); 751 return w; 752 }, 753 754 getter: function() { 755 return this._node.offsetWidth; 756 } 757 } 758 }); 759 760 Y.mix(Y.Node.prototype, { 761 sizeTo: function(w, h) { 762 var node; 763 if (arguments.length < 2) { 764 node = Y.one(w); 765 w = node.get('offsetWidth'); 766 h = node.get('offsetHeight'); 767 } 768 769 this.setAttrs({ 770 offsetWidth: w, 771 offsetHeight: h 772 }); 773 } 774 }); 775 776 if (!Y.config.doc.documentElement.hasAttribute) { // IE < 8 777 Y.Node.prototype.hasAttribute = function(attr) { 778 if (attr === 'value') { 779 if (this.get('value') !== "") { // IE < 8 fails to populate specified when set in HTML 780 return true; 781 } 782 } 783 return !!(this._node.attributes[attr] && 784 this._node.attributes[attr].specified); 785 }; 786 } 787 788 // IE throws an error when calling focus() on an element that's invisible, not 789 // displayed, or disabled. 790 Y.Node.prototype.focus = function () { 791 try { 792 this._node.focus(); 793 } catch (e) { 794 Y.log('error focusing node: ' + e.toString(), 'error', 'node'); 795 } 796 797 return this; 798 }; 799 800 // IE throws error when setting input.type = 'hidden', 801 // input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden' 802 Y.Node.ATTRS.type = { 803 setter: function(val) { 804 if (val === 'hidden') { 805 try { 806 this._node.type = 'hidden'; 807 } catch(e) { 808 this._node.style.display = 'none'; 809 this._inputType = 'hidden'; 810 } 811 } else { 812 try { // IE errors when changing the type from "hidden' 813 this._node.type = val; 814 } catch (e) { 815 Y.log('error setting type: ' + val, 'info', 'node'); 816 } 817 } 818 return val; 819 }, 820 821 getter: function() { 822 return this._inputType || this._node.type; 823 }, 824 825 _bypassProxy: true // don't update DOM when using with Attribute 826 }; 827 828 if (Y.config.doc.createElement('form').elements.nodeType) { 829 // IE: elements collection is also FORM node which trips up scrubVal. 830 Y.Node.ATTRS.elements = { 831 getter: function() { 832 return this.all('input, textarea, button, select'); 833 } 834 }; 835 } 836 /** 837 * Provides methods for managing custom Node data. 838 * 839 * @module node 840 * @main node 841 * @submodule node-data 842 */ 843 844 Y.mix(Y.Node.prototype, { 845 _initData: function() { 846 if (! ('_data' in this)) { 847 this._data = {}; 848 } 849 }, 850 851 /** 852 * @method getData 853 * @for Node 854 * @description Retrieves arbitrary data stored on a Node instance. 855 * If no data is associated with the Node, it will attempt to retrieve 856 * a value from the corresponding HTML data attribute. (e.g. node.getData('foo') 857 * will check node.getAttribute('data-foo')). 858 * @param {string} name Optional name of the data field to retrieve. 859 * If no name is given, all data is returned. 860 * @return {any | Object} Whatever is stored at the given field, 861 * or an object hash of all fields. 862 */ 863 getData: function(name) { 864 this._initData(); 865 var data = this._data, 866 ret = data; 867 868 if (arguments.length) { // single field 869 if (name in data) { 870 ret = data[name]; 871 } else { // initialize from HTML attribute 872 ret = this._getDataAttribute(name); 873 } 874 } else if (typeof data == 'object' && data !== null) { // all fields 875 ret = {}; 876 Y.Object.each(data, function(v, n) { 877 ret[n] = v; 878 }); 879 880 ret = this._getDataAttributes(ret); 881 } 882 883 return ret; 884 885 }, 886 887 _getDataAttributes: function(ret) { 888 ret = ret || {}; 889 var i = 0, 890 attrs = this._node.attributes, 891 len = attrs.length, 892 prefix = this.DATA_PREFIX, 893 prefixLength = prefix.length, 894 name; 895 896 while (i < len) { 897 name = attrs[i].name; 898 if (name.indexOf(prefix) === 0) { 899 name = name.substr(prefixLength); 900 if (!(name in ret)) { // only merge if not already stored 901 ret[name] = this._getDataAttribute(name); 902 } 903 } 904 905 i += 1; 906 } 907 908 return ret; 909 }, 910 911 _getDataAttribute: function(name) { 912 name = this.DATA_PREFIX + name; 913 914 var node = this._node, 915 attrs = node.attributes, 916 data = attrs && attrs[name] && attrs[name].value; 917 918 return data; 919 }, 920 921 /** 922 * @method setData 923 * @for Node 924 * @description Stores arbitrary data on a Node instance. 925 * This is not stored with the DOM node. 926 * @param {string} name The name of the field to set. If no val 927 * is given, name is treated as the data and overrides any existing data. 928 * @param {any} val The value to be assigned to the field. 929 * @chainable 930 */ 931 setData: function(name, val) { 932 this._initData(); 933 if (arguments.length > 1) { 934 this._data[name] = val; 935 } else { 936 this._data = name; 937 } 938 939 return this; 940 }, 941 942 /** 943 * @method clearData 944 * @for Node 945 * @description Clears internally stored data. 946 * @param {string} name The name of the field to clear. If no name 947 * is given, all data is cleared. 948 * @chainable 949 */ 950 clearData: function(name) { 951 if ('_data' in this) { 952 if (typeof name != 'undefined') { 953 delete this._data[name]; 954 } else { 955 delete this._data; 956 } 957 } 958 959 return this; 960 } 961 }); 962 963 Y.mix(Y.NodeList.prototype, { 964 /** 965 * @method getData 966 * @for NodeList 967 * @description Retrieves arbitrary data stored on each Node instance 968 * bound to the NodeList. 969 * @see Node 970 * @param {string} name Optional name of the data field to retrieve. 971 * If no name is given, all data is returned. 972 * @return {Array} An array containing all of the data for each Node instance. 973 * or an object hash of all fields. 974 */ 975 getData: function(name) { 976 var args = (arguments.length) ? [name] : []; 977 return this._invoke('getData', args, true); 978 }, 979 980 /** 981 * @method setData 982 * @for NodeList 983 * @description Stores arbitrary data on each Node instance bound to the 984 * NodeList. This is not stored with the DOM node. 985 * @param {string} name The name of the field to set. If no name 986 * is given, name is treated as the data and overrides any existing data. 987 * @param {any} val The value to be assigned to the field. 988 * @chainable 989 */ 990 setData: function(name, val) { 991 var args = (arguments.length > 1) ? [name, val] : [name]; 992 return this._invoke('setData', args); 993 }, 994 995 /** 996 * @method clearData 997 * @for NodeList 998 * @description Clears data on all Node instances bound to the NodeList. 999 * @param {string} name The name of the field to clear. If no name 1000 * is given, all data is cleared. 1001 * @chainable 1002 */ 1003 clearData: function(name) { 1004 var args = (arguments.length) ? [name] : []; 1005 return this._invoke('clearData', [name]); 1006 } 1007 }); 1008 1009 1010 }, '3.17.2', {"requires": ["event-base", "node-core", "dom-base", "dom-style"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |