Advertisement
Guest User

Untitled

a guest
Sep 19th, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.25 KB | None | 0 0
  1. 'use strict';
  2.  
  3. import $ from 'jQuery';
  4. import cloneDeep from 'lodash/cloneDeep.js';
  5. import merge from 'lodash/merge.js';
  6.  
  7. // -----------------------------------------
  8. // Functions
  9.  
  10. /**
  11. * Gets native el
  12. *
  13. * @param {element} $el
  14. * @returns {arr|undefined}
  15. */
  16. // { title: '$el', type: 'jQueryElement' }
  17. const getNativeEl = ($el) => {
  18. const nativeEl = [];
  19.  
  20. // Lets get the basic native el elements
  21. if ($el !== undefined && $el !== null) {
  22. for (let i = 0; i < $el.length; i += 1) {
  23. nativeEl.push($el[i]);
  24. }
  25. }
  26.  
  27. if (nativeEl.length) {
  28. return nativeEl;
  29. }
  30.  
  31. return undefined;
  32. };
  33.  
  34. /**
  35. * Gets native el from object
  36. *
  37. * @param {object} $els
  38. * @returns {object}
  39. */
  40. // { title: '$els', type: 'array', items: 'jQueryElement' }
  41. const getNativeEls = ($els) => {
  42. const nativeEls = {};
  43. const keys = Object.keys($els);
  44.  
  45. // Lets get the basic native els elements
  46. for (let c = 0; c < keys.length; c += 1) {
  47. nativeEls[keys[c]] = getNativeEl($els[keys[c]]);
  48. }
  49.  
  50. return nativeEls;
  51. };
  52.  
  53. // --------------------------------
  54. // Class
  55.  
  56. class Component {
  57. // Constructor
  58. // { title: '$el' },
  59. // { title: 'data', properties: {
  60. // comps: { properties: {} },
  61. // state: { properties: {} }
  62. // } }
  63. constructor($el, data = {}) {
  64. $el = $el instanceof $ ? $el : $($el);
  65.  
  66. const $els = data.els || {};
  67. const nativeEls = getNativeEls($els);
  68. const nativeEl = getNativeEl($el);
  69.  
  70. // Cache elements
  71. this._$el = $el;
  72. this._$els = $els;
  73. this._el = nativeEl;
  74. this._els = nativeEls || {};
  75.  
  76. // Set basics
  77. this._state = data.state || {};
  78. this._comps = data.comps || this._comps || {};
  79. this._render = data.render || this._render || false;
  80. this._tmpl = data.tmpl && this._getTmplFn(data.tmpl);
  81. }
  82.  
  83. // State...
  84. // TODO: Should we check diffs in state?
  85. // { title: 'state', properties: {} }
  86. set state(state) { this._state = merge(this._state || {}, cloneDeep(state)); }
  87. get state() { return this._state; }
  88.  
  89. // Template...
  90. // { title: 'tmpl', type: 'string|fn' }
  91. set tmpl(tmpl) { this._tmpl = this._getTmplFn(tmpl); }
  92. get tmpl() { return this._tmpl; }
  93.  
  94. // Render
  95. render() {
  96. if (this._render === false) {
  97. return this;
  98. }
  99.  
  100. // Get the right template
  101. const renderedTmpl = this._renderedTmpl;
  102. const tmpl = this._tmpl(this._state);
  103.  
  104. // Maybe there aren't changes
  105. if (tmpl === renderedTmpl || !this._el) {
  106. return this;
  107. }
  108.  
  109. // Lets iterate per element
  110. const el = this._el;
  111. for (let i = 0; i < el.length; i += 1) {
  112. el[i].innerHTML = tmpl;
  113. }
  114.  
  115. // Cache the template
  116. this._renderedTmpl = tmpl;
  117. this.hasRendered = true;
  118.  
  119. // TODO: What about nested components?
  120.  
  121. return this;
  122. }
  123.  
  124. /**
  125. * Destroys nested components
  126. */
  127. destroyComps() {
  128. const compsKeys = Object.keys(this._comps);
  129. for (let i = 0; i < compsKeys.length; i += 1) {
  130. if (!this._comps[compsKeys[i]] || !this._comps[compsKeys[i]].destroy) {
  131. continue;
  132. }
  133.  
  134. this._comps[compsKeys[i]].destroy();
  135. this._comps[compsKeys[i]] = null;
  136. }
  137. }
  138.  
  139. /**
  140. * Destroy component
  141. */
  142. destroy() {
  143. // Lets destroy components underneath
  144. this.destroyComps();
  145.  
  146. if (this._render && this._el !== undefined && this._el !== null) {
  147. // Lets remove the html!
  148. for (let i = 0; i < this._el.length; i += 1) {
  149. this._el[i].innerHTML = '';
  150. }
  151. }
  152.  
  153. return this;
  154. }
  155.  
  156. // -------------------------------------------------------
  157.  
  158. /**
  159. * Gets template function
  160. *
  161. * @param {string|function} tmpl
  162. * @returns {function}
  163. */
  164. _getTmplFn(tmpl) {
  165. let tmplFn;
  166.  
  167. if (typeof tmpl === 'string') {
  168. tmplFn = () => typeof tmpl === 'string' ? tmpl : '';
  169. } else if (typeof tmpl === 'function') {
  170. tmplFn = tmpl;
  171. } else {
  172. throw new Error('Template needs to be a string or a function');
  173. }
  174.  
  175. return tmplFn;
  176. }
  177. }
  178. export { Component };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement