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