Created
August 26, 2020 09:24
-
-
Save av/dabdff40d6c620edec5cf12c5213a31a to your computer and use it in GitHub Desktop.
Root Component class from an unreleased UI framework
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var HIDE_CLASS = 'ui-hidden'; | |
| var DISABLED_CLASS = 'ui-disabled'; | |
| var FOCUSABLE_GRABBER = ':tabbable:visible:first'; | |
| ui.component = ui.define({ | |
| id: null, | |
| cls: null, | |
| locator: null, | |
| hidden: false, | |
| disabled: false, | |
| parent: null, | |
| components: null, | |
| renderTo: null, | |
| el: null, | |
| bodyEl: null, | |
| bodySelector: null, | |
| rendered: false, | |
| destroyed: false, | |
| _componentMap: null, | |
| grabbers: null, | |
| elements: null, | |
| template: '<div id="{{id}}" class="ui-component {{cls}}"></div>', | |
| bodyTemplate: null, | |
| lazyRender: false, | |
| _previousDisplayState: null, | |
| type: 'component', | |
| EVENTS: { | |
| 'render': function (/*cmp*/) {}, | |
| 'afterrender': function (/*cmp*/) {}, | |
| 'show': function (/*cmp*/) {}, | |
| 'hide': function (/*cmp*/) {}, | |
| 'enable': function (/*cmp*/) {}, | |
| 'disable': function (/*cmp*/) {} | |
| }, | |
| constructor: function (config) { | |
| var components = config && config.components ? config.components : this.components; | |
| config && this._applyConfig(config); | |
| this.components = {}; | |
| this._componentMap = []; | |
| if (components) { | |
| each(components, function (component) { | |
| if (component.config) { | |
| this.addComponent(component.type, component.config); | |
| } else { | |
| this.addComponent(component); | |
| } | |
| }, this); | |
| } | |
| this._template = new ui.Template(this.template); | |
| merge(config, this, true); | |
| ui.manager.register(this); | |
| }, | |
| getTemplateParams: function() { | |
| return { | |
| id: this.id || '', | |
| cls: this.cls || '' | |
| }; | |
| }, | |
| getTemplatePartials: function() { | |
| return {}; | |
| }, | |
| _bindUIEvents: function() { | |
| }, | |
| addComponent: function (type, config) { | |
| var child; | |
| isObject(type) && (child = type); | |
| isString(type) && (child = ui.manager.get(type)); | |
| !child && (child = new type(config)); | |
| child.setParent(this); | |
| if (this.rendered) { | |
| child.render(); | |
| } | |
| return child; | |
| }, | |
| removeComponent: function (component) { | |
| delete this.components[component.locator]; | |
| removeElement(this._componentMap, component.locator); | |
| component.setParent(null); | |
| }, | |
| destroyComponents: function() { | |
| this.eachComponent(function (locator, component) { | |
| component.destroy(); | |
| }); | |
| }, | |
| eachComponent: function(callback, scope) { | |
| each(this._componentMap, function (locator, index) { | |
| return callback.call(scope || this, locator, this.components[locator], index); | |
| }, this); | |
| }, | |
| focus: function() { | |
| var target = grab(FOCUSABLE_GRABBER, this.bodyEl); | |
| }, | |
| _applyConfig: function(config) { | |
| if (config.listeners) { | |
| each(config.listeners, function (key, value) { | |
| if (key !== 'scope') { | |
| this.addListener(key, value, config.listeners.scope || this); | |
| } | |
| }, this); | |
| } | |
| merge(config, this); | |
| delete this.listeners; | |
| delete this.components; | |
| }, | |
| setParent: function(parent) { | |
| this.parent = parent; | |
| this.parent.registerChild(this); | |
| }, | |
| registerChild: function(child) { | |
| this.components[child.locator] = child; | |
| this._componentMap.push(child.locator); | |
| }, | |
| render: function() { | |
| if (this.rendered !== true) { | |
| this._beforeRender(); | |
| this._renderElement(); | |
| this._renderComponents(); | |
| this.rendered = true; | |
| } | |
| if (this.hidden) { | |
| this._doHide(); | |
| } | |
| this._afterRender(); | |
| this.fireEvent('afterrender', this); | |
| this._bindUIEvents(); | |
| }, | |
| show: function() { | |
| if (this.hidden) { | |
| if (!this.rendered && this.parent && this.parent.rendered) { | |
| this.render(); | |
| } | |
| this._doShow(); | |
| this.hidden = false; | |
| this.fireEvent('show', this); | |
| } | |
| }, | |
| hide: function() { | |
| if (!this.hidden) { | |
| this._doHide(); | |
| this.hidden = true; | |
| this.fireEvent('hide', this); | |
| } | |
| }, | |
| _doShow: function() { | |
| if (this.rendered) { | |
| this.el.classList.remove(HIDE_CLASS); | |
| } | |
| }, | |
| _doHide: function() { | |
| if (this.rendered) { | |
| this.el.classList.add(HIDE_CLASS); | |
| } | |
| }, | |
| setVisibility: function(visible) { | |
| this[visible ? 'show' : 'hide'](); | |
| }, | |
| enable: function() { | |
| if (this.disabled) { | |
| this.disabled = false; | |
| if (this.rendered) { | |
| this.el.classList.remove(DISABLED_CLASS); | |
| } | |
| this.fireEvent('enable', this); | |
| } | |
| }, | |
| disable: function() { | |
| if (!this.disabled) { | |
| this.disabled = true; | |
| if (this.rendered) { | |
| this.el.classList.add(DISABLED_CLASS); | |
| } | |
| this.fireEvent('disable', this); | |
| } | |
| }, | |
| _beforeRender: function() { | |
| }, | |
| _renderElement: function() { | |
| this.el = this._template.render(this.getTemplateParams(), this.getTemplatePartials()); | |
| this.bodyEl = this.el; | |
| if (this.bodySelector) { | |
| this.bodyEl = grab(this.bodySelector, this.el); | |
| } | |
| var container = this.parent ? | |
| (this.renderTo ? grab(this.renderTo, this.parent.el) : this.parent.bodyEl) : | |
| (this.renderTo ? grab(this.renderTo) : document.body); | |
| container && container.appendChild(this.el) || document.body.appendChild(this.el); | |
| }, | |
| _renderComponents: function() { | |
| this.eachComponent(function (locator, component) { | |
| if (!component.hidden || !this.lazyRender) { | |
| component.render(); | |
| } | |
| }, this); | |
| }, | |
| _afterRender: function() { | |
| this._processGrabbers(); | |
| }, | |
| _processGrabbers: function() { | |
| if (this.grabbers) { | |
| this.elements = {}; | |
| this._resolveElements(this.grabbers); | |
| } | |
| }, | |
| _resolveElements: function(grabbers) { | |
| each(grabbers, function (grabber, name) { | |
| if (!own(this.elements, name)) { | |
| this.elements[name] = grab(grabber, this.el); | |
| } | |
| }, this) | |
| }, | |
| destroy: function () { | |
| if (!this.destroyed) { | |
| if (this.parent) { | |
| this.parent.removeComponents(this); | |
| } | |
| this._removeEl(); | |
| this.destroyComponents(); | |
| this.purgeListeners(); | |
| this.destroyed = true; | |
| this.el = null; | |
| this.bodyEl = null; | |
| this.elements = null; | |
| this.component = null; | |
| this._componentMap = null; | |
| ui.manager.unregister(this); | |
| } | |
| }, | |
| _removeEl: function () { | |
| if (this.rendered) { | |
| this.el.parentNode.removeChild(this.el); | |
| } | |
| this.el = null; | |
| this.elements = null; | |
| this.rendered = false; | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment