[ 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('base-core', function (Y, NAME) { 9 10 /** 11 * The base module provides the Base class, which objects requiring attribute and custom event support can extend. 12 * The module also provides two ways to reuse code - It augments Base with the Plugin.Host interface which provides 13 * plugin support and also provides the BaseCore.build method which provides a way to build custom classes using extensions. 14 * 15 * @module base 16 */ 17 18 /** 19 * <p>The base-core module provides the BaseCore class, the lightest version of Base, 20 * which provides Base's basic lifecycle management and ATTRS construction support, 21 * but doesn't fire init/destroy or attribute change events.</p> 22 * 23 * <p>It mixes in AttributeCore, which is the lightest version of Attribute</p> 24 * 25 * @module base 26 * @submodule base-core 27 */ 28 var O = Y.Object, 29 L = Y.Lang, 30 DOT = ".", 31 INITIALIZED = "initialized", 32 DESTROYED = "destroyed", 33 INITIALIZER = "initializer", 34 VALUE = "value", 35 OBJECT_CONSTRUCTOR = Object.prototype.constructor, 36 DEEP = "deep", 37 SHALLOW = "shallow", 38 DESTRUCTOR = "destructor", 39 40 AttributeCore = Y.AttributeCore, 41 42 _wlmix = function(r, s, wlhash) { 43 var p; 44 for (p in s) { 45 if(wlhash[p]) { 46 r[p] = s[p]; 47 } 48 } 49 return r; 50 }; 51 52 /** 53 * The BaseCore class, is the lightest version of Base, and provides Base's 54 * basic lifecycle management and ATTRS construction support, but doesn't 55 * fire init/destroy or attribute change events. 56 * 57 * BaseCore also handles the chaining of initializer and destructor methods across 58 * the hierarchy as part of object construction and destruction. Additionally, attributes 59 * configured through the static <a href="#property_BaseCore.ATTRS">ATTRS</a> 60 * property for each class in the hierarchy will be initialized by BaseCore. 61 * 62 * Classes which require attribute support, but don't intend to use/expose attribute 63 * change events can extend BaseCore instead of Base for optimal kweight and 64 * runtime performance. 65 * 66 * **3.11.0 BACK COMPAT NOTE FOR COMPONENT DEVELOPERS** 67 * 68 * Prior to version 3.11.0, ATTRS would get added a class at a time. That is: 69 * 70 * <pre> 71 * for each (class in the hierarchy) { 72 * Call the class Extension constructors. 73 * 74 * Add the class ATTRS. 75 * 76 * Call the class initializer 77 * Call the class Extension initializers. 78 * } 79 * </pre> 80 * 81 * As of 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call 82 * before **any** initializers are called. That is, the flow becomes: 83 * 84 * <pre> 85 * for each (class in the hierarchy) { 86 * Call the class Extension constructors. 87 * } 88 * 89 * Add ATTRS for all classes 90 * 91 * for each (class in the hierarchy) { 92 * Call the class initializer. 93 * Call the class Extension initializers. 94 * } 95 * </pre> 96 * 97 * Adding all ATTRS at once fixes subtle edge-case issues with subclass ATTRS overriding 98 * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes 99 * defined by the subclass. It also leaves us with a cleaner order of operation flow moving 100 * forward. 101 * 102 * However, it may require component developers to upgrade their components, for the following 103 * scenarios: 104 * 105 * 1. It impacts components which may have `setter`, `getter` or `valueFn` code which 106 * expects a superclass' initializer to have run. 107 * 108 * This is expected to be rare, but to support it, Base now supports a `_preAddAttrs()`, method 109 * hook (same signature as `addAttrs`). Components can implement this method on their prototype 110 * for edge cases which do require finer control over the order in which attributes are added 111 * (see widget-htmlparser for example). 112 * 113 * 2. Extension developers may need to move code from Extension constructors to `initializer`s 114 * 115 * Older extensions, which were written before `initializer` support was added, had a lot of 116 * initialization code in their constructors. For example, code which acccessed superclass 117 * attributes. With the new flow this code would not be able to see attributes. The recommendation 118 * is to move this initialization code to an `initializer` on the Extension, which was the 119 * recommendation for anything created after `initializer` support for Extensions was added. 120 * 121 * @class BaseCore 122 * @constructor 123 * @uses AttributeCore 124 * @param {Object} cfg Object with configuration property name/value pairs. 125 * The object can be used to provide initial values for the objects published 126 * attributes. 127 */ 128 function BaseCore(cfg) { 129 if (!this._BaseInvoked) { 130 this._BaseInvoked = true; 131 132 Y.log('constructor called', 'life', 'base'); 133 this._initBase(cfg); 134 } 135 else { Y.log('Based constructor called more than once. Ignoring duplicate calls', 'life', 'base'); } 136 } 137 138 /** 139 * The list of properties which can be configured for each attribute 140 * (e.g. setter, getter, writeOnce, readOnly etc.) 141 * 142 * @property _ATTR_CFG 143 * @type Array 144 * @static 145 * @private 146 */ 147 BaseCore._ATTR_CFG = AttributeCore._ATTR_CFG.concat("cloneDefaultValue"); 148 149 /** 150 * The array of non-attribute configuration properties supported by this class. 151 * 152 * For example `BaseCore` defines a "plugins" configuration property which 153 * should not be set up as an attribute. This property is primarily required so 154 * that when <a href="#property__allowAdHocAttrs">`_allowAdHocAttrs`</a> is enabled by a class, 155 * non-attribute configuration properties don't get added as ad-hoc attributes. 156 * 157 * @property _NON_ATTRS_CFG 158 * @type Array 159 * @static 160 * @private 161 */ 162 BaseCore._NON_ATTRS_CFG = ["plugins"]; 163 164 /** 165 * This property controls whether or not instances of this class should 166 * allow users to add ad-hoc attributes through the constructor configuration 167 * hash. 168 * 169 * AdHoc attributes are attributes which are not defined by the class, and are 170 * not handled by the MyClass._NON_ATTRS_CFG 171 * 172 * @property _allowAdHocAttrs 173 * @type boolean 174 * @default undefined (false) 175 * @protected 176 */ 177 178 /** 179 * The string to be used to identify instances of this class. 180 * 181 * Classes extending BaseCore, should define their own 182 * static NAME property, which should be camelCase by 183 * convention (e.g. MyClass.NAME = "myClass";). 184 * 185 * @property NAME 186 * @type String 187 * @static 188 */ 189 BaseCore.NAME = "baseCore"; 190 191 /** 192 * The default set of attributes which will be available for instances of this class, and 193 * their configuration. In addition to the configuration properties listed by 194 * AttributeCore's <a href="AttributeCore.html#method_addAttr">addAttr</a> method, 195 * the attribute can also be configured with a "cloneDefaultValue" property, which 196 * defines how the statically defined value field should be protected 197 * ("shallow", "deep" and false are supported values). 198 * 199 * By default if the value is an object literal or an array it will be "shallow" 200 * cloned, to protect the default value. 201 * 202 * @property ATTRS 203 * @type Object 204 * @static 205 */ 206 BaseCore.ATTRS = { 207 /** 208 * Flag indicating whether or not this object 209 * has been through the init lifecycle phase. 210 * 211 * @attribute initialized 212 * @readonly 213 * @default false 214 * @type boolean 215 */ 216 initialized: { 217 readOnly:true, 218 value:false 219 }, 220 221 /** 222 * Flag indicating whether or not this object 223 * has been through the destroy lifecycle phase. 224 * 225 * @attribute destroyed 226 * @readonly 227 * @default false 228 * @type boolean 229 */ 230 destroyed: { 231 readOnly:true, 232 value:false 233 } 234 }; 235 236 /** 237 Provides a way to safely modify a `Y.BaseCore` subclass' static `ATTRS` 238 after the class has been defined or created. 239 240 BaseCore-based classes cache information about the class hierarchy in order 241 to efficiently create instances. This cache includes includes the aggregated 242 `ATTRS` configs. If the static `ATTRS` configs need to be modified after the 243 class has been defined or create, then use this method which will make sure 244 to clear any cached data before making any modifications. 245 246 @method modifyAttrs 247 @param {Function} [ctor] The constructor function whose `ATTRS` should be 248 modified. If a `ctor` function is not specified, then `this` is assumed 249 to be the constructor which hosts the `ATTRS`. 250 @param {Object} configs The collection of `ATTRS` configs to mix with the 251 existing attribute configurations. 252 @static 253 @since 3.10.0 254 **/ 255 BaseCore.modifyAttrs = function (ctor, configs) { 256 // When called without a constructor, assume `this` is the constructor. 257 if (typeof ctor !== 'function') { 258 configs = ctor; 259 ctor = this; 260 } 261 262 var attrs, attr, name; 263 264 // Eagerly create the `ATTRS` object if it doesn't already exist. 265 attrs = ctor.ATTRS || (ctor.ATTRS = {}); 266 267 if (configs) { 268 // Clear cache because it has ATTRS aggregation data which is about 269 // to be modified. 270 ctor._CACHED_CLASS_DATA = null; 271 272 for (name in configs) { 273 if (configs.hasOwnProperty(name)) { 274 attr = attrs[name] || (attrs[name] = {}); 275 Y.mix(attr, configs[name], true); 276 } 277 } 278 } 279 }; 280 281 BaseCore.prototype = { 282 283 /** 284 * Internal construction logic for BaseCore. 285 * 286 * @method _initBase 287 * @param {Object} config The constructor configuration object 288 * @private 289 */ 290 _initBase : function(config) { 291 Y.log('init called', 'life', 'base'); 292 293 Y.stamp(this); 294 295 this._initAttribute(config); 296 297 // If Plugin.Host has been augmented [ through base-pluginhost ], setup it's 298 // initial state, but don't initialize Plugins yet. That's done after initialization. 299 var PluginHost = Y.Plugin && Y.Plugin.Host; 300 if (this._initPlugins && PluginHost) { 301 PluginHost.call(this); 302 } 303 304 if (this._lazyAddAttrs !== false) { this._lazyAddAttrs = true; } 305 306 /** 307 * The string used to identify the class of this object. 308 * 309 * @deprecated Use this.constructor.NAME 310 * @property name 311 * @type String 312 */ 313 this.name = this.constructor.NAME; 314 315 this.init.apply(this, arguments); 316 }, 317 318 /** 319 * Initializes AttributeCore 320 * 321 * @method _initAttribute 322 * @private 323 */ 324 _initAttribute: function() { 325 AttributeCore.call(this); 326 }, 327 328 /** 329 * Init lifecycle method, invoked during construction. Sets up attributes 330 * and invokes initializers for the class hierarchy. 331 * 332 * @method init 333 * @chainable 334 * @param {Object} cfg Object with configuration property name/value pairs 335 * @return {BaseCore} A reference to this object 336 */ 337 init: function(cfg) { 338 Y.log('init called', 'life', 'base'); 339 340 this._baseInit(cfg); 341 342 return this; 343 }, 344 345 /** 346 * Internal initialization implementation for BaseCore 347 * 348 * @method _baseInit 349 * @private 350 */ 351 _baseInit: function(cfg) { 352 this._initHierarchy(cfg); 353 354 if (this._initPlugins) { 355 // Need to initPlugins manually, to handle constructor parsing, static Plug parsing 356 this._initPlugins(cfg); 357 } 358 this._set(INITIALIZED, true); 359 }, 360 361 /** 362 * Destroy lifecycle method. Invokes destructors for the class hierarchy. 363 * 364 * @method destroy 365 * @return {BaseCore} A reference to this object 366 * @chainable 367 */ 368 destroy: function() { 369 this._baseDestroy(); 370 return this; 371 }, 372 373 /** 374 * Internal destroy implementation for BaseCore 375 * 376 * @method _baseDestroy 377 * @private 378 */ 379 _baseDestroy : function() { 380 if (this._destroyPlugins) { 381 this._destroyPlugins(); 382 } 383 this._destroyHierarchy(); 384 this._set(DESTROYED, true); 385 }, 386 387 /** 388 * Returns the class hierarchy for this object, with BaseCore being the last class in the array. 389 * 390 * @method _getClasses 391 * @protected 392 * @return {Function[]} An array of classes (constructor functions), making up the class hierarchy for this object. 393 * This value is cached the first time the method, or _getAttrCfgs, is invoked. Subsequent invocations return the 394 * cached value. 395 */ 396 _getClasses : function() { 397 if (!this._classes) { 398 this._initHierarchyData(); 399 } 400 return this._classes; 401 }, 402 403 /** 404 * Returns an aggregated set of attribute configurations, by traversing 405 * the class hierarchy. 406 * 407 * @method _getAttrCfgs 408 * @protected 409 * @return {Object} The hash of attribute configurations, aggregated across classes in the hierarchy 410 * This value is cached the first time the method, or _getClasses, is invoked. Subsequent invocations return 411 * the cached value. 412 */ 413 _getAttrCfgs : function() { 414 if (!this._attrs) { 415 this._initHierarchyData(); 416 } 417 return this._attrs; 418 }, 419 420 /** 421 * A helper method used to isolate the attrs config for this instance to pass to `addAttrs`, 422 * from the static cached ATTRS for the class. 423 * 424 * @method _getInstanceAttrCfgs 425 * @private 426 * 427 * @param {Object} allCfgs The set of all attribute configurations for this instance. 428 * Attributes will be removed from this set, if they belong to the filtered class, so 429 * that by the time all classes are processed, allCfgs will be empty. 430 * 431 * @return {Object} The set of attributes to be added for this instance, suitable 432 * for passing through to `addAttrs`. 433 */ 434 _getInstanceAttrCfgs : function(allCfgs) { 435 436 var cfgs = {}, 437 cfg, 438 val, 439 subAttr, 440 subAttrs, 441 subAttrPath, 442 attr, 443 attrCfg, 444 allSubAttrs = allCfgs._subAttrs, 445 attrCfgProperties = this._attrCfgHash(); 446 447 for (attr in allCfgs) { 448 449 if (allCfgs.hasOwnProperty(attr) && attr !== "_subAttrs") { 450 451 attrCfg = allCfgs[attr]; 452 453 // Need to isolate from allCfgs, because we're going to set values etc. 454 cfg = cfgs[attr] = _wlmix({}, attrCfg, attrCfgProperties); 455 456 val = cfg.value; 457 458 if (val && (typeof val === "object")) { 459 this._cloneDefaultValue(attr, cfg); 460 } 461 462 if (allSubAttrs && allSubAttrs.hasOwnProperty(attr)) { 463 subAttrs = allCfgs._subAttrs[attr]; 464 465 for (subAttrPath in subAttrs) { 466 subAttr = subAttrs[subAttrPath]; 467 468 if (subAttr.path) { 469 O.setValue(cfg.value, subAttr.path, subAttr.value); 470 } 471 } 472 } 473 } 474 } 475 476 return cfgs; 477 }, 478 479 /** 480 * @method _filterAdHocAttrs 481 * @private 482 * 483 * @param {Object} allAttrs The set of all attribute configurations for this instance. 484 * Attributes will be removed from this set, if they belong to the filtered class, so 485 * that by the time all classes are processed, allCfgs will be empty. 486 * @param {Object} userVals The config object passed in by the user, from which adhoc attrs are to be filtered. 487 * @return {Object} The set of adhoc attributes passed in, in the form 488 * of an object with attribute name/configuration pairs. 489 */ 490 _filterAdHocAttrs : function(allAttrs, userVals) { 491 var adHocs, 492 nonAttrs = this._nonAttrs, 493 attr; 494 495 if (userVals) { 496 adHocs = {}; 497 for (attr in userVals) { 498 if (!allAttrs[attr] && !nonAttrs[attr] && userVals.hasOwnProperty(attr)) { 499 adHocs[attr] = { 500 value:userVals[attr] 501 }; 502 } 503 } 504 } 505 506 return adHocs; 507 }, 508 509 /** 510 * A helper method used by _getClasses and _getAttrCfgs, which determines both 511 * the array of classes and aggregate set of attribute configurations 512 * across the class hierarchy for the instance. 513 * 514 * @method _initHierarchyData 515 * @private 516 */ 517 _initHierarchyData : function() { 518 519 var ctor = this.constructor, 520 cachedClassData = ctor._CACHED_CLASS_DATA, 521 c, 522 i, 523 l, 524 attrCfg, 525 attrCfgHash, 526 needsAttrCfgHash = !ctor._ATTR_CFG_HASH, 527 nonAttrsCfg, 528 nonAttrs = {}, 529 classes = [], 530 attrs = []; 531 532 // Start with `this` instance's constructor. 533 c = ctor; 534 535 if (!cachedClassData) { 536 537 while (c) { 538 // Add to classes 539 classes[classes.length] = c; 540 541 // Add to attributes 542 if (c.ATTRS) { 543 attrs[attrs.length] = c.ATTRS; 544 } 545 546 // Aggregate ATTR cfg whitelist. 547 if (needsAttrCfgHash) { 548 attrCfg = c._ATTR_CFG; 549 attrCfgHash = attrCfgHash || {}; 550 551 if (attrCfg) { 552 for (i = 0, l = attrCfg.length; i < l; i += 1) { 553 attrCfgHash[attrCfg[i]] = true; 554 } 555 } 556 } 557 558 // Commenting out the if. We always aggregate, since we don't 559 // know if we'll be needing this on the instance or not. 560 // if (this._allowAdHocAttrs) { 561 nonAttrsCfg = c._NON_ATTRS_CFG; 562 if (nonAttrsCfg) { 563 for (i = 0, l = nonAttrsCfg.length; i < l; i++) { 564 nonAttrs[nonAttrsCfg[i]] = true; 565 } 566 } 567 //} 568 569 c = c.superclass ? c.superclass.constructor : null; 570 } 571 572 // Cache computed `_ATTR_CFG_HASH` on the constructor. 573 if (needsAttrCfgHash) { 574 ctor._ATTR_CFG_HASH = attrCfgHash; 575 } 576 577 cachedClassData = ctor._CACHED_CLASS_DATA = { 578 classes : classes, 579 nonAttrs : nonAttrs, 580 attrs : this._aggregateAttrs(attrs) 581 }; 582 583 } 584 585 this._classes = cachedClassData.classes; 586 this._attrs = cachedClassData.attrs; 587 this._nonAttrs = cachedClassData.nonAttrs; 588 }, 589 590 /** 591 * Utility method to define the attribute hash used to filter/whitelist property mixes for 592 * this class for iteration performance reasons. 593 * 594 * @method _attrCfgHash 595 * @private 596 */ 597 _attrCfgHash: function() { 598 return this.constructor._ATTR_CFG_HASH; 599 }, 600 601 /** 602 * This method assumes that the value has already been checked to be an object. 603 * Since it's on a critical path, we don't want to re-do the check. 604 * 605 * @method _cloneDefaultValue 606 * @param {Object} cfg 607 * @private 608 */ 609 _cloneDefaultValue : function(attr, cfg) { 610 611 var val = cfg.value, 612 clone = cfg.cloneDefaultValue; 613 614 if (clone === DEEP || clone === true) { 615 Y.log('Cloning default value for attribute:' + attr, 'info', 'base'); 616 cfg.value = Y.clone(val); 617 } else if (clone === SHALLOW) { 618 Y.log('Merging default value for attribute:' + attr, 'info', 'base'); 619 cfg.value = Y.merge(val); 620 } else if ((clone === undefined && (OBJECT_CONSTRUCTOR === val.constructor || L.isArray(val)))) { 621 cfg.value = Y.clone(val); 622 } 623 // else if (clone === false), don't clone the static default value. 624 // It's intended to be used by reference. 625 }, 626 627 /** 628 * A helper method, used by _initHierarchyData to aggregate 629 * attribute configuration across the instances class hierarchy. 630 * 631 * The method will protect the attribute configuration value to protect the statically defined 632 * default value in ATTRS if required (if the value is an object literal, array or the 633 * attribute configuration has cloneDefaultValue set to shallow or deep). 634 * 635 * @method _aggregateAttrs 636 * @private 637 * @param {Array} allAttrs An array of ATTRS definitions across classes in the hierarchy 638 * (subclass first, Base last) 639 * @return {Object} The aggregate set of ATTRS definitions for the instance 640 */ 641 _aggregateAttrs : function(allAttrs) { 642 643 var attr, 644 attrs, 645 subAttrsHash, 646 cfg, 647 path, 648 i, 649 cfgPropsHash = this._attrCfgHash(), 650 aggAttr, 651 aggAttrs = {}; 652 653 if (allAttrs) { 654 for (i = allAttrs.length-1; i >= 0; --i) { 655 656 attrs = allAttrs[i]; 657 658 for (attr in attrs) { 659 if (attrs.hasOwnProperty(attr)) { 660 661 // PERF TODO: Do we need to merge here, since we're merging later in getInstanceAttrCfgs 662 // Should we move this down to only merge if we hit the path or valueFn ifs below? 663 cfg = _wlmix({}, attrs[attr], cfgPropsHash); 664 665 path = null; 666 if (attr.indexOf(DOT) !== -1) { 667 path = attr.split(DOT); 668 attr = path.shift(); 669 } 670 671 aggAttr = aggAttrs[attr]; 672 673 if (path && aggAttr && aggAttr.value) { 674 675 subAttrsHash = aggAttrs._subAttrs; 676 677 if (!subAttrsHash) { 678 subAttrsHash = aggAttrs._subAttrs = {}; 679 } 680 681 if (!subAttrsHash[attr]) { 682 subAttrsHash[attr] = {}; 683 } 684 685 subAttrsHash[attr][path.join(DOT)] = { 686 value: cfg.value, 687 path : path 688 }; 689 690 } else if (!path) { 691 692 if (!aggAttr) { 693 aggAttrs[attr] = cfg; 694 } else { 695 if (aggAttr.valueFn && VALUE in cfg) { 696 aggAttr.valueFn = null; 697 } 698 699 // Mix into existing config. 700 _wlmix(aggAttr, cfg, cfgPropsHash); 701 } 702 } 703 } 704 } 705 } 706 } 707 708 return aggAttrs; 709 }, 710 711 /** 712 * Initializes the class hierarchy for the instance, which includes 713 * initializing attributes for each class defined in the class's 714 * static <a href="#property_BaseCore.ATTRS">ATTRS</a> property and 715 * invoking the initializer method on the prototype of each class in the hierarchy. 716 * 717 * @method _initHierarchy 718 * @param {Object} userVals Object with configuration property name/value pairs 719 * @private 720 */ 721 _initHierarchy : function(userVals) { 722 723 var lazy = this._lazyAddAttrs, 724 constr, 725 constrProto, 726 i, 727 l, 728 ci, 729 ei, 730 el, 731 ext, 732 extProto, 733 exts, 734 instanceAttrs, 735 initializers = [], 736 classes = this._getClasses(), 737 attrCfgs = this._getAttrCfgs(), 738 cl = classes.length - 1; 739 740 // Constructors 741 for (ci = cl; ci >= 0; ci--) { 742 743 constr = classes[ci]; 744 constrProto = constr.prototype; 745 exts = constr._yuibuild && constr._yuibuild.exts; 746 747 // Using INITIALIZER in hasOwnProperty check, for performance reasons (helps IE6 avoid GC thresholds when 748 // referencing string literals). Not using it in apply, again, for performance "." is faster. 749 750 if (constrProto.hasOwnProperty(INITIALIZER)) { 751 // Store initializer while we're here and looping 752 initializers[initializers.length] = constrProto.initializer; 753 } 754 755 if (exts) { 756 for (ei = 0, el = exts.length; ei < el; ei++) { 757 758 ext = exts[ei]; 759 760 // Ext Constructor 761 ext.apply(this, arguments); 762 763 extProto = ext.prototype; 764 if (extProto.hasOwnProperty(INITIALIZER)) { 765 // Store initializer while we're here and looping 766 initializers[initializers.length] = extProto.initializer; 767 } 768 } 769 } 770 } 771 772 // ATTRS 773 instanceAttrs = this._getInstanceAttrCfgs(attrCfgs); 774 775 if (this._preAddAttrs) { 776 this._preAddAttrs(instanceAttrs, userVals, lazy); 777 } 778 779 if (this._allowAdHocAttrs) { 780 this.addAttrs(this._filterAdHocAttrs(attrCfgs, userVals), userVals, lazy); 781 } 782 783 this.addAttrs(instanceAttrs, userVals, lazy); 784 785 // Initializers 786 for (i = 0, l = initializers.length; i < l; i++) { 787 initializers[i].apply(this, arguments); 788 } 789 }, 790 791 /** 792 * Destroys the class hierarchy for this instance by invoking 793 * the destructor method on the prototype of each class in the hierarchy. 794 * 795 * @method _destroyHierarchy 796 * @private 797 */ 798 _destroyHierarchy : function() { 799 var constr, 800 constrProto, 801 ci, cl, ei, el, exts, extProto, 802 classes = this._getClasses(); 803 804 for (ci = 0, cl = classes.length; ci < cl; ci++) { 805 constr = classes[ci]; 806 constrProto = constr.prototype; 807 exts = constr._yuibuild && constr._yuibuild.exts; 808 809 if (exts) { 810 for (ei = 0, el = exts.length; ei < el; ei++) { 811 extProto = exts[ei].prototype; 812 if (extProto.hasOwnProperty(DESTRUCTOR)) { 813 extProto.destructor.apply(this, arguments); 814 } 815 } 816 } 817 818 if (constrProto.hasOwnProperty(DESTRUCTOR)) { 819 constrProto.destructor.apply(this, arguments); 820 } 821 } 822 }, 823 824 /** 825 * Default toString implementation. Provides the constructor NAME 826 * and the instance guid, if set. 827 * 828 * @method toString 829 * @return {String} String representation for this object 830 */ 831 toString: function() { 832 return this.name + "[" + Y.stamp(this, true) + "]"; 833 } 834 }; 835 836 // Straightup augment, no wrapper functions 837 Y.mix(BaseCore, AttributeCore, false, null, 1); 838 839 // Fix constructor 840 BaseCore.prototype.constructor = BaseCore; 841 842 Y.BaseCore = BaseCore; 843 844 845 }, '3.17.2', {"requires": ["attribute-core"]});
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 |