Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- import $ from 'jQuery';
- import cloneDeep from 'lodash/cloneDeep.js';
- import merge from 'lodash/merge.js';
- // -----------------------------------------
- // Functions
- /**
- * Gets native el
- *
- * @param {element} $el
- * @returns {arr|undefined}
- */
- // { title: '$el', type: 'jQueryElement' }
- const getNativeEl = ($el) => {
- const nativeEl = [];
- // Lets get the basic native el elements
- if ($el !== undefined && $el !== null) {
- for (let i = 0; i < $el.length; i += 1) {
- nativeEl.push($el[i]);
- }
- }
- if (nativeEl.length) {
- return nativeEl;
- }
- return undefined;
- };
- /**
- * Gets native el from object
- *
- * @param {object} $els
- * @returns {object}
- */
- // { title: '$els', type: 'array', items: 'jQueryElement' }
- const getNativeEls = ($els) => {
- const nativeEls = {};
- const keys = Object.keys($els);
- // Lets get the basic native els elements
- for (let c = 0; c < keys.length; c += 1) {
- nativeEls[keys[c]] = getNativeEl($els[keys[c]]);
- }
- return nativeEls;
- };
- // --------------------------------
- // Class
- class Component {
- // Constructor
- // { title: '$el' },
- // { title: 'data', properties: {
- // comps: { properties: {} },
- // state: { properties: {} }
- // } }
- constructor($el, data = {}) {
- $el = $el instanceof $ ? $el : $($el);
- const $els = data.els || {};
- const nativeEls = getNativeEls($els);
- const nativeEl = getNativeEl($el);
- // Cache elements
- this._$el = $el;
- this._$els = $els;
- this._el = nativeEl;
- this._els = nativeEls || {};
- // Set basics
- this._state = data.state || {};
- this._comps = data.comps || this._comps || {};
- this._render = data.render || this._render || false;
- this._tmpl = data.tmpl && this._getTmplFn(data.tmpl);
- }
- // State...
- // TODO: Should we check diffs in state?
- // { title: 'state', properties: {} }
- set state(state) { this._state = merge(this._state || {}, cloneDeep(state)); }
- get state() { return this._state; }
- // Template...
- // { title: 'tmpl', type: 'string|fn' }
- set tmpl(tmpl) { this._tmpl = this._getTmplFn(tmpl); }
- get tmpl() { return this._tmpl; }
- // Render
- render() {
- if (this._render === false) {
- return this;
- }
- // Get the right template
- const renderedTmpl = this._renderedTmpl;
- const tmpl = this._tmpl(this._state);
- // Maybe there aren't changes
- if (tmpl === renderedTmpl || !this._el) {
- return this;
- }
- // Lets iterate per element
- const el = this._el;
- for (let i = 0; i < el.length; i += 1) {
- el[i].innerHTML = tmpl;
- }
- // Cache the template
- this._renderedTmpl = tmpl;
- this.hasRendered = true;
- // TODO: What about nested components?
- return this;
- }
- /**
- * Destroys nested components
- */
- destroyComps() {
- const compsKeys = Object.keys(this._comps);
- for (let i = 0; i < compsKeys.length; i += 1) {
- if (!this._comps[compsKeys[i]] || !this._comps[compsKeys[i]].destroy) {
- continue;
- }
- this._comps[compsKeys[i]].destroy();
- this._comps[compsKeys[i]] = null;
- }
- }
- /**
- * Destroy component
- */
- destroy() {
- // Lets destroy components underneath
- this.destroyComps();
- if (this._render && this._el !== undefined && this._el !== null) {
- // Lets remove the html!
- for (let i = 0; i < this._el.length; i += 1) {
- this._el[i].innerHTML = '';
- }
- }
- return this;
- }
- // -------------------------------------------------------
- /**
- * Gets template function
- *
- * @param {string|function} tmpl
- * @returns {function}
- */
- _getTmplFn(tmpl) {
- let tmplFn;
- if (typeof tmpl === 'string') {
- tmplFn = () => typeof tmpl === 'string' ? tmpl : '';
- } else if (typeof tmpl === 'function') {
- tmplFn = tmpl;
- } else {
- throw new Error('Template needs to be a string or a function');
- }
- return tmplFn;
- }
- }
- export { Component };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement