1 | /** |
||
2 | * [Siteapp] - multi-purpose frontend application |
||
3 | * |
||
4 | * Siteapp Module Abstract |
||
5 | * |
||
6 | * @package [Siteapp] |
||
7 | * @subpackage [Siteapp] module |
||
8 | * @author Björn Bartels <[email protected]> |
||
9 | * @link https://gitlab.bjoernbartels.earth/groups/themes |
||
10 | * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0 |
||
11 | * @copyright copyright (c) 2016 Björn Bartels <[email protected]> |
||
12 | * |
||
13 | * @namespace Siteapp |
||
14 | * @module Siteapp.Module |
||
15 | * @abstract |
||
16 | */ |
||
17 | /** global: Siteapp */ |
||
18 | /** global: Siteapp_Module_DEFAULTS */ |
||
19 | /** global: ModuleManager */ |
||
20 | |||
21 | import {Exception} from '../sys/siteapp.exception'; |
||
22 | |||
23 | class ModuleException extends Exception { |
||
24 | |||
25 | get name () { |
||
26 | return "SiteappModuleException"; |
||
27 | } |
||
28 | |||
29 | }; |
||
30 | |||
31 | const Siteapp_Module_DEFAULTS = { |
||
0 ignored issues
–
show
Unused Code
introduced
by
![]() |
|||
32 | |||
33 | }; |
||
34 | |||
35 | /** |
||
36 | * Module module abstract. |
||
37 | * @module Siteapp.Module |
||
38 | */ |
||
39 | const Module = class Module { |
||
40 | |||
41 | /** |
||
42 | * Sets-up the module basics. |
||
43 | * ! (to override by extending class) |
||
44 | * |
||
45 | * - set 'this.$element' here, if needed |
||
46 | * |
||
47 | * @function |
||
48 | */ |
||
49 | _setup (element, options) { |
||
0 ignored issues
–
show
|
|||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Initializes the module. |
||
54 | * ! (to override by extending class) |
||
55 | * |
||
56 | * - call '[Siteapp].{ModuleManager}.initialze(this)' here, if needed |
||
57 | * |
||
58 | * @function |
||
59 | */ |
||
60 | _init () { |
||
61 | //console.//log ('module init:', this.manager.functionName(this)); |
||
62 | } |
||
63 | |||
64 | /** |
||
65 | * Sets-up events and event handling the module. |
||
66 | * ! (to override by extending class) |
||
67 | * |
||
68 | * @function |
||
69 | */ |
||
70 | _events () { |
||
71 | } |
||
72 | |||
73 | /** |
||
74 | * Destroys the module. |
||
75 | * ! (to override by extending class) |
||
76 | * |
||
77 | * @function |
||
78 | */ |
||
79 | _destroy () { |
||
80 | //console.//log ('module destroy:', this.manager.functionName(this)); |
||
81 | } |
||
82 | |||
83 | /** |
||
84 | * Reinitializes the module. |
||
85 | * ! (to override by extending class) |
||
86 | * |
||
87 | * @function |
||
88 | */ |
||
89 | reflow() { |
||
90 | //console.//log ('module reflow:', this.manager.functionName(this)); |
||
91 | } |
||
92 | |||
93 | // ... and add your own propertiesfrom here... |
||
94 | |||
95 | // |
||
96 | // ... |
||
97 | // |
||
98 | |||
99 | |||
100 | |||
101 | // HERE BE DRAGONS !!! |
||
102 | // only modify/override the following properties and methods if you know what you are doing |
||
103 | |||
104 | |||
105 | /** |
||
106 | * Create a new instance of a module. |
||
107 | * |
||
108 | * @class |
||
109 | * @name Module |
||
110 | * @param {jQuery} element - jQuery object to apply the module to. |
||
111 | * @param {Object} options - Overrides to the default module settings. |
||
112 | */ |
||
113 | constructor(element, options, app) { |
||
114 | |||
115 | this._setup(element, options); |
||
116 | if ( element && (!this.$element || !this.$element.jquery) ) { |
||
117 | // make sure, we have a jQuery object here |
||
118 | this.$element = $(element); |
||
119 | } |
||
120 | |||
121 | this.options = $.extend({}, Siteapp_Module_DEFAULTS, (this.$element ? this.$element.data() : {}), options); |
||
122 | |||
123 | if (app instanceof Siteapp) { |
||
124 | this.application = app; |
||
125 | } |
||
126 | |||
127 | var moduleName = Siteapp.sys.hyphenate( Siteapp.sys.functionName(this) ); |
||
128 | if (!this.uuid) { |
||
129 | this.uuid = moduleName+'-'+Siteapp.sys.genUUID(6); |
||
130 | } |
||
131 | |||
132 | var attrName = moduleName; |
||
133 | if (this.manager.options.namespacedModuleTriggers) { |
||
134 | attrName = this.application.appName+'-'+moduleName; |
||
135 | } |
||
136 | |||
137 | if(!this.$element.attr(`data-${attrName}`)){ this.$element.attr(`data-${attrName}`, this.uuid); } |
||
138 | |||
139 | if(!this.$element.data(this.application.appName+'Plugin')){ this.$element.data(this.application.appName+'Plugin', this); } |
||
140 | /** |
||
141 | * Fires when the module has initialized. |
||
142 | * @event Module#init |
||
143 | */ |
||
144 | this.$element.trigger(`init.${moduleName}`); |
||
145 | } |
||
146 | |||
147 | /** |
||
148 | * Destroys the module. |
||
149 | * |
||
150 | * @function |
||
151 | */ |
||
152 | destroy() { |
||
153 | this._destroy(); |
||
154 | var moduleName = Siteapp.sys.functionName(this); |
||
155 | var attrName = moduleName; |
||
156 | if (this.manager.options.namespacedModuleTriggers) { |
||
157 | attrName = this.application.appName+'-'+moduleName; |
||
158 | } |
||
159 | |||
160 | this.$element.removeAttr(`data-${attrName}`).removeData(this.application.appName+'Plugin') |
||
161 | /** |
||
162 | * Fires when the module has been destroyed. |
||
163 | * @event Module#destroyed |
||
164 | */ |
||
165 | .trigger(`destroyed.${attrName}`); |
||
166 | for(var prop in this){ |
||
167 | this[prop] = null; //clean up script to prep for garbage collection. |
||
168 | } |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * Hide the main module element. |
||
173 | * |
||
174 | * @function |
||
175 | */ |
||
176 | hide() { |
||
177 | this.$element.hide(); |
||
178 | } |
||
179 | |||
180 | /** |
||
181 | * Show the main module element. |
||
182 | * |
||
183 | * @function |
||
184 | */ |
||
185 | show() { |
||
186 | this.$element.show(); |
||
187 | } |
||
188 | |||
189 | /** |
||
190 | * generate trigger markup attribute |
||
191 | * |
||
192 | * @function |
||
193 | * @private |
||
194 | */ |
||
195 | get _triggerAttribute() { |
||
196 | |||
197 | var attr = [ |
||
198 | 'data-', |
||
199 | (this.manager.namespacedModuleTriggers ? this.application.appName+'-' : ''), |
||
200 | Siteapp.sys.hyphenate(Siteapp.sys.functionName(this)).toLowerCase(), |
||
201 | '' |
||
202 | ]; |
||
203 | |||
204 | return attr.join(''); |
||
205 | } |
||
206 | |||
207 | /** |
||
208 | * generate trigger markup data-... options |
||
209 | * |
||
210 | * @function |
||
211 | * @private |
||
212 | */ |
||
213 | get _triggerDataOptions() { |
||
214 | |||
215 | var dataAttrs = []; |
||
216 | $.each(this.options, (key, val) => { |
||
217 | if ( (val === null) || ( (val instanceof Object) && !(val instanceof Array) ) ) { |
||
218 | //if ( (val === null) || ( (typeof val == 'object') && !(typeof val.join == 'undefined') ) ) { |
||
219 | dataAttrs.push(''); |
||
220 | } else { |
||
221 | dataAttrs.push(' data-'+Siteapp.sys.hyphenate(key)+'='+ JSON.stringify(val) +''); |
||
222 | } |
||
223 | }); |
||
224 | |||
225 | return dataAttrs.join(''); |
||
226 | } |
||
227 | |||
228 | /** |
||
229 | * generate trigger markup tag |
||
230 | * |
||
231 | * @function |
||
232 | * @private |
||
233 | */ |
||
234 | get _triggerTag() { |
||
235 | if (!this._tagName) { |
||
236 | this._tagName = 'div'; |
||
237 | } |
||
238 | var html = [ |
||
239 | '<'+this._tagName+' ', |
||
240 | this._triggerAttribute, |
||
241 | this._triggerDataOptions, |
||
242 | '>', |
||
243 | '<!-- modulecontent -->', |
||
244 | '</'+this._tagName+'>' |
||
245 | ]; |
||
246 | |||
247 | return html.join(''); |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * set trigger markup tagname |
||
252 | * |
||
253 | * @function |
||
254 | * @private |
||
255 | */ |
||
256 | set _triggerTag( tag ) { |
||
257 | if ( (typeof tag == 'string') && (tag != '') ) { |
||
258 | this._tagName = tag.toLowerCase(); |
||
259 | } |
||
260 | } |
||
261 | |||
262 | /** |
||
263 | * Retrieves module markup, generates |
||
264 | * |
||
265 | * @function |
||
266 | */ |
||
267 | get markup() { |
||
268 | var html = this._triggerTag; |
||
269 | if (this.$element) { |
||
270 | html = html.replace( '<!-- modulecontent -->', (this.$element.html() || '') ); |
||
271 | } |
||
272 | return (html); |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Return initial markup |
||
277 | * |
||
278 | * @function |
||
279 | */ |
||
280 | toString() { |
||
281 | return (this.markup); |
||
282 | } |
||
283 | |||
284 | /** |
||
285 | * return initial markup elements |
||
286 | * |
||
287 | * @function |
||
288 | */ |
||
289 | toElement() { |
||
290 | if (this.$element) { |
||
291 | return this.$element; |
||
292 | } |
||
293 | return $(this.toString()); |
||
294 | } |
||
295 | |||
296 | /** |
||
297 | * Retrieve attached module manager. |
||
298 | */ |
||
299 | get manager () { |
||
300 | return this._manager; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * Attach application object. |
||
305 | */ |
||
306 | set manager ( _manager ) { |
||
307 | if (_manager instanceof ModuleManager) { |
||
308 | this._manager = _manager; |
||
309 | } else { |
||
310 | throw new ModuleException('Invalid module manager object to attach, must be an instance of Siteapp.ModuleManager'); |
||
311 | } |
||
312 | } |
||
313 | |||
314 | /** |
||
315 | * Retrieve attached application. |
||
316 | */ |
||
317 | get application () { |
||
318 | return this._app; |
||
319 | } |
||
320 | |||
321 | /** |
||
322 | * Attach application object. |
||
323 | */ |
||
324 | set application ( app ) { |
||
325 | if (app instanceof Siteapp) { |
||
326 | this._app = app; |
||
327 | } else { |
||
328 | throw new ModuleException('Invalid application object to attach, must be an instance of Siteapp'); |
||
329 | } |
||
330 | } |
||
331 | } |
||
332 | |||
333 | // |
||
334 | // now, after extending, the module gets registered: |
||
335 | // [Siteapp].[ModuleManager].register({Moduleclass}, 'Moduletriggername'); |
||
336 | // |
||
337 | |||
338 | export default Module; |