[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/base-core/ -> base-core.js (source)

   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"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1