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