* A base class which objects requiring attributes and custom event support can * extend. Base also handles the chaining of initializer and destructor methods across * the hierarchy as part of object construction and destruction. Additionally, attributes configured * through the static ATTRS property for each class * in the hierarchy will be initialized by Base. *
* **NOTE:** Prior to version 3.11.0, ATTRS would get added a class at a time. That is, * Base would loop through each class in the hierarchy, and add the class' ATTRS, and * then call it's initializer, and move on to the subclass' ATTRS and initializer. As of * 3.11.0, ATTRS from all classes in the hierarchy are added in one `addAttrs` call before * any initializers are called. This fixes subtle edge-case issues with subclass ATTRS overriding * superclass `setter`, `getter` or `valueFn` definitions and being unable to get/set attributes * defined by the subclass. This order of operation change may impact `setter`, `getter` or `valueFn` * code which expects a superclass' initializer to have run. This is expected to be rare, but to support * it, Base supports a `_preAddAttrs()`, method hook (same signature as `addAttrs`). Components can * implement this method on their prototype for edge cases which do require finer control over * the order in which attributes are added (see widget-htmlparser). *
* The static NAME property of each class extending * from Base will be used as the identifier for the class, and is used by Base to prefix * all events fired by instances of that class. *
* The config object can also contain the following non-attribute properties, providing a convenient * way to configure events listeners and plugins for the instance, as part of the constructor call: *
* The string to be used to identify instances of * this class, for example in prefixing events. *
* Classes extending Base, should define their own * static NAME property, which should be camelCase by * convention (e.g. MyClass.NAME = "myClass";). *