olum 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/olum.js CHANGED
@@ -1,622 +1,165 @@
1
1
  /**
2
2
  * @name Olum.js
3
- * @version 0.1.0
3
+ * @version 0.2.1
4
4
  * @copyright 2021
5
5
  * @author Eissa Saber
6
6
  * @license MIT
7
7
  */
8
- ((root, factory) => {
8
+ (function (root, factory) {
9
9
  if (typeof module === "object" && module.exports) module.exports = factory();
10
10
  else if (typeof define === "function" && define.amd) define(factory);
11
- else {
12
- const ob = factory();
13
- for(let key in ob) { root[key] = ob[key]; }
14
- }
15
- })(typeof self !== "undefined" ? self : this, () => {
11
+ else root.Olum = factory();
12
+ })(typeof self !== "undefined" ? self : this, function () {
16
13
  "use strict";
17
- /**
18
- * helpers for optimizing the code
19
- */
20
- const global = typeof self !== "undefined" ? self : this;
21
- const isDebugging = false;
22
- const debugStr = "Olum [warn]:";
23
- const quotes = str => "“" + str + "”";
24
- const devtoolHint = `${debugStr} ${quotes("devtool extension")} is not installed!
25
- \nto install it please download ${quotes("devtool.js")} from the official repo
26
- \n@ https://raw.githubusercontent.com/olumjs/olum-devtool/master/devtool.js
27
- \nand save it in the root of your project`;
28
- const isDev = () => !!["localhost", "127.0.0.1"].includes(location.hostname);
29
- const isObj = obj => !!(obj !== null && typeof obj === "object");
30
- const isFullArr = arr => !!(isObj(arr) && Array.isArray(arr) && arr.length);
31
- const isFullObj = obj => !!(isObj(obj) && Array.isArray(Object.keys(obj)) && Object.keys(obj).length);
32
- const isDef = val => !!(val !== undefined && val !== null);
33
- const isTrue = val => !!(val === true);
34
- const toNum = val => parseFloat(val.replace(/\D/g, ""));
35
- const delItem = (arr, item) => (arr.length && arr.indexOf(item) > -1 ? arr.splice(arr.indexOf(item), 1) : null);
36
- const hasProp = (obj, key) => !!obj.hasOwnProperty(key);
37
- const delProp = (obj, key) => (hasProp(obj, key) ? delete obj[key] : null);
38
- const isSame = (a, b) => !!(a === b);
39
- const addProp = (obj, key, val) => {
40
- Object.defineProperty(obj, key, {
41
- value: val,
42
- writable: true,
43
- configurable: true,
44
- });
45
- };
46
- const debugLib = (args, level = "log") => {
47
- level = level == "err" ? "error" : level;
48
- if (isDebugging) Array.isArray(args) ? console[level](...args) : console[level](args);
49
- }
50
- String.prototype.upper = function () {
51
- return this.toUpperCase();
52
- };
53
- String.prototype.lower = function () {
54
- return this.toLowerCase();
55
- };
14
+ /* helpers */
15
+ var global = typeof self !== "undefined" ? self : this;
16
+ var debugStr = "Olum [warn]:";
17
+ var isDebugging = false;
56
18
 
57
- /* Capitalize a string */
58
- String.prototype.cap = function () {
59
- return this.toLowerCase().split(" ").map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
60
- };
61
-
62
- /* For debuging purposes, works in dev mode */
63
- const debug = (args, level = "log") => {
64
- level = level == "err" ? "error" : level;
65
- if (isDev()) Array.isArray(args) ? console[level](...args) : console[level](args);
19
+ function isDef(val) {
20
+ return (val !== undefined && val !== null);
66
21
  }
67
22
 
68
- /**
69
- * A shorthand for selecting nodes from dom
70
- *
71
- * @example $(".header") // returns 1st element
72
- * @example $(".header", true) // returns array
73
- * @example $(elm).get("li") // returns 1st li inside elm
74
- * @example $(elm).get("li", true) // returns array of li inside elm
75
- * @param {String} target can be class, id, tag or Element
76
- * @param {Boolean} level (optional) boolean if omited it returns 1st element otherwise (true) returns array
77
- */
78
- const $ = (target, level, el = document) => {
79
- if (typeof target == "string") {
80
- const elms = [].slice.call(el.querySelectorAll(target));
81
- if (isFullArr(elms)) {
82
- if (level) return elms;
83
- else return elms[0];
84
- } else {
85
- if (level) {
86
- return [];
87
- } else {
88
- return null;
89
- }
90
- }
91
- } else {
92
- if (!Array.isArray(target) && !!target && target instanceof Element) target.get = (t, l) => $(t, l, target);
93
- return target;
94
- }
95
- };
96
-
97
- /**
98
- * A shorthand for addEventListener() - removeEventListener()
99
- */
100
- function on(event, cb, propagation = false) {
101
- return this.addEventListener(event, cb, propagation);
23
+ function isDev() {
24
+ return ["localhost", "127.0.0.1"].indexOf(global.location.hostname) !== -1;
102
25
  }
103
26
 
104
- function off(event, cb, propagation = false) {
105
- return this.removeEventListener(event, cb, propagation);
27
+ function isObj(obj) {
28
+ return (obj !== null && typeof obj === "object");
106
29
  }
107
- Element.prototype.on = on;
108
- Element.prototype.off = off;
109
- Document.prototype.on = on;
110
- Document.prototype.off = off;
111
- global.on = on;
112
- global.off = off;
113
-
114
- /**
115
- * Replace string with values
116
- *
117
- * @example setTemp(`<div>{{name}}</div>`, {name:"olumjs"})
118
- */
119
- const setTemp = (temp, obj, delimit = ["{{", "}}"]) => {
120
- for (let key in obj) {
121
- temp = temp.replace(new RegExp(`\\${delimit[0][0]}\\${delimit[0][1]}${key}\\${delimit[1][0]}\\${delimit[1][1]}`, "g"), obj[key]);
122
- }
123
- return temp;
124
- }
125
-
126
- /**
127
- * Expand/Collapse element height
128
- *
129
- * @example elm.toggle(0.6)
130
- * @Hint CSS must have `height: 0; overflow: hidden;`
131
- */
132
- Element.prototype.toggle = function (time = 0.3) {
133
- this.style.transition = `height ${time}s ease-in-out`;
134
- if (this.clientHeight == 0) {
135
- this.style.height = "auto";
136
- const h = this.clientHeight + "px";
137
- this.style.height = "0";
138
- setTimeout(() => this.style.height = h, 0);
139
- } else this.style.height = "0";
140
- };
141
-
142
- // translations
143
- class Localize {
144
- key = "tolang";
145
-
146
- constructor(dictionary, rtlLangs) {
147
- this.dictionary = dictionary;
148
- this.rtlLangs = rtlLangs;
149
- this.init();
150
- }
151
-
152
- init() {
153
- this.detect();
154
- const _this = this;
155
- String.prototype.trans = function trans() {
156
- const str = this;
157
- const locales = _this.dictionary;
158
- const lang = _this.current();
159
- const langObj = locales[lang];
160
- const err = `"${str}" property is misspelled or missed at "src/locales/${lang}.js"`;
161
- let translatedStr;
162
-
163
- if (typeof locales != "undefined" && typeof langObj != "undefined") {
164
- for (let key in langObj) {
165
- if (str === key) translatedStr = langObj[key];
166
- }
167
- } else {
168
- debug("locales or langObj are not defined! @ String.prototype.trans", "warn");
169
- }
170
-
171
- return translatedStr || err;
172
- };
173
- this.tolang();
174
- };
175
-
176
- detect() {
177
- const container = $("body");
178
- if (container) {
179
- if (this.rtlLangs.includes(this.current())) container.classList.add("RTL");
180
- else container.classList.remove("RTL");
181
- }
182
- }
183
-
184
- current() {
185
- return localStorage.getItem(this.key) || "en";
186
- }
187
-
188
- tolang() {
189
- document.on("click", e => {
190
- if (e.target.hasAttribute(this.key)) {
191
- // disable href in anchor
192
- if (e.target.nodeName === "A") e.target.setAttribute("href", "javascript:void(0)");
193
- // disable icons in links
194
- [...e.target.children].forEach(icon => (icon.style.pointerEvents = "none"));
195
- // update current lang
196
- const lang = e.target.getAttribute(this.key);
197
- localStorage.setItem(this.key, lang);
198
- location.reload();
199
- }
200
- });
201
- }
202
30
 
31
+ function isFullArr(arr) {
32
+ return !!(isObj(arr) && Array.isArray(arr) && arr.length);
203
33
  }
204
-
205
- /**
206
- * @example origin.method(url, { body: {name:"olumjs"},"Content-Type": "application/json" }).then(console.log).catch(console.error)
207
- */
208
- class Origin {
209
- constructor() {
210
- if (!(this instanceof Origin)) console.error(`${debugStr} can't invoke ${quotes("Origin constructor")} without new keyword`);
211
- this.xhr = new XMLHttpRequest();
212
- }
213
34
 
214
- setParams(data) {
215
- if (isFullObj(data)) {
216
- for (let key in data) {
217
- if (key !== "body") this.xhr.setRequestHeader(key, data[key]);
218
- }
219
- if (hasProp(data, "body") && isFullObj(data.body)) {
220
- return JSON.stringify(data.body);
221
- }
222
- return null;
223
- }
224
- }
225
-
226
- onload(resolve, reject) {
227
- return this.xhr.onreadystatechange = () => {
228
- if (this.xhr.readyState === 4) {
229
- if (this.xhr.status === 0 || (this.xhr.status >= 200 && this.xhr.status <= 299)) {
230
- try {
231
- resolve(JSON.parse(this.xhr.responseText));
232
- } catch (err) {
233
- resolve(this.xhr.responseText);
234
- }
235
- } else if (this.xhr.status >= 400 && this.xhr.status <= 599) {
236
- reject(`${debugStr} couldn't reach the server`);
237
- }
238
- }
239
- };
240
- }
241
-
242
- req(method, url, data = {}) {
243
- return new Promise((resolve, reject) => {
244
- this.xhr.open(method, url, true);
245
- const form = this.setParams(data);
246
- this.onload(resolve, reject);
247
- this.xhr.onerror = () => reject(`${debugStr} network error`);
248
- form !== null ? this.xhr.send(form) : this.xhr.send();
249
- });
250
- }
251
-
252
- get = (url, data = {}) => this.req("GET", url, data);
253
- post = (url, data = {}) => this.req("POST", url, data);
254
- delete = (url, data = {}) => this.req("DELETE", url, data);
255
- put = (url, data = {}) => this.req("PUT", url, data);
256
- patch = (url, data = {}) => this.req("PATCH", url, data);
35
+ function isFullObj(obj) {
36
+ return !!(isObj(obj) && Array.isArray(Object.keys(obj)) && Object.keys(obj).length);
257
37
  }
258
38
 
259
- /**
260
- * @example new Olum({
261
- mode: "history",
262
- root: "/",
263
- el: "#app",
264
- prefix: "app",
265
- routes: [{ path: "/", comp: Home }],
39
+ function addProp(obj, key, val) {
40
+ Object.defineProperty(obj, key, {
41
+ value: val,
42
+ writable: true,
43
+ configurable: true,
266
44
  });
267
- */
268
- class Olum {
269
- isFrozen = false;
270
- routes = [];
271
- pushStateAPI = !!global.history.pushState;
272
-
273
- constructor({
274
- mode,
275
- root,
276
- el,
277
- prefix,
278
- err,
279
- routes
280
- }) {
281
- if (!(this instanceof Olum)) console.error(`${debugStr} can't invoke ${quotes("Olum constructor")} without new keyword`);
282
- this.setMode(mode);
283
- this.setRoot(root);
284
- this.setPrefix(prefix);
285
- this.setErr(err);
286
-
287
- if (!this.hasRootElm(el)) {
288
- console.error(`${debugStr} couldn't find a value for ${quotes("el property")} @ router instance. \nmake sure it has the right selector e.g. el:"#app" \nand ${quotes("Root Element")} exists in dom e.g. <div id="app"></div>`);
289
- } else if (!this.hasRoutes(routes)) {
290
- console.error(`${debugStr} couldn't find ${quotes("routes property")} @ router instance or it's empty. \nmake sure that ${quotes("routes property")} has components \ne.g. routes = [{ path: "/", comp: Home }]`);
291
- } else {
292
- this.popStateEvent = new PopStateEvent("popstate");
293
- this.viewLoaded = new CustomEvent("viewLoaded", { detail: {}, bubbles: true, cancelable: true, composed: false });
294
- this.listen();
295
- }
296
- }
297
-
298
- hasRootElm(el) {
299
- const appMarkup = document.querySelector(el);
300
-
301
- if (!!el && !!appMarkup) {
302
- this.rootCompName = el.replace(/\#|\./, "").cap();
303
- this.appMarkup = appMarkup;
304
- return true;
305
- }
306
-
307
- return false;
308
- }
309
-
310
- hasRoutes(routes) {
311
- if (!!routes && isFullArr(routes)) {
312
- routes.forEach(route => this.addRoute(route.path, route.comp));
313
- return true;
314
- }
315
- return false;
316
- }
317
-
318
- setPrefix(prefix) {
319
- if (!!prefix) {
320
- this.prefix = prefix;
321
- } else {
322
- this.prefix = null;
323
- debug(`${debugStr} couldn't find ${quotes("prefix property")} @ router instance. \nfalling back to default component tag e.g. <ComponentName/>`, "warn");
324
- }
325
- }
326
-
327
- setRoot(root) {
328
- if (!!root) {
329
- this.root = root;
330
- } else {
331
- this.root = "/";
332
- debug(`${debugStr} couldn't find ${quotes("root property")} @ router instance. \nfalling back to default value: ${quotes("/")}`, "warn");
333
- }
334
- }
45
+ }
46
+ String.prototype.cap = function () {
47
+ return this.toLowerCase().split(" ").map(function (word) {
48
+ return word.charAt(0).toUpperCase() + word.slice(1);
49
+ }).join(" ");
50
+ };
335
51
 
336
- setErr(err) {
337
- if (!!err) {
338
- this.err = this.resolve(err);
339
- } else {
340
- this.err = null;
341
- debug(`${debugStr} couldn't find ${quotes("err property")} @ router instance. \nfalling back to default 404 page`, "warn");
342
- }
343
- }
52
+ function debug(args, level) {
53
+ if (!isDef(level)) level = "log";
54
+ level = level == "err" ? "error" : level;
55
+ if (isDebugging) Array.isArray(args) ? console[level].apply(console, args) : console[level](args);
56
+ }
344
57
 
345
- setMode(mode) {
346
- if (!!mode) {
347
- if (this.pushStateAPI) this.mode = mode;
348
- else {
349
- this.mode = "hash"; // force hash
350
- debug(`${debugStr} mode is set to ${quotes("hash")} \n${quotes("history")} is not supported!`, "warn");
351
- }
58
+ function Olum(config) {
59
+ if (!(this instanceof Olum)) throw new Error("can't invoke 'Olum' without 'new' keyword");
60
+ var $this = this;
61
+
62
+ // set defaults
63
+ var rootElm = null;
64
+ var rootCompName = null;
65
+ var which = null;
66
+ var prefix = config && config.prefix ? config.prefix : null;
67
+
68
+ this.use = function (arg) {
69
+ if (arg) {
70
+ if (arg.name && typeof arg.name === "function" && arg.name() === "OlumRouter") which = { type: "router", cb: arg };
71
+ else which = { type: "component", cb: arg };
72
+ if (which) init();
73
+ else throw new Error(debugStr + " Root component or router are not defined!");
352
74
  } else {
353
- this.mode = this.pushStateAPI ? "history" : "hash"; // default
354
- debug(`${debugStr} couldn't find ${quotes("mode property")} @ router instance. \nfalling back to available default mode: ${quotes(this.mode)}`, "warn");
75
+ throw new Error(debugStr + " Missing component or router @use()");
355
76
  }
356
77
  }
357
78
 
358
- addRoute(path, comp) {
359
- this.routes.push({
360
- path: this.resolve(path),
361
- cb: () => this.inject(comp),
362
- });
363
- }
364
-
365
- delRoute(path) {
366
- this.routes.forEach(item => {
367
- if (item.path === this.resolve(path)) delItem(this.routes, item);
368
- });
369
- }
370
-
371
- flush() {
372
- this.routes = [];
373
- }
79
+ this.$ = function (selector) {
80
+ if (selector) {
81
+ var delimiter;
82
+ if (selector.indexOf(".") !== -1) delimiter = ".";
83
+ else if (selector.indexOf("#") !== -1) delimiter = "#";
374
84
 
375
- resolve(path) {
376
- const root = this.clear(this.root);
377
- path = this.clear(path);
378
- path = (this.root !== "/") ? ("/" + root + "/" + path) : ("/" + path);
379
- path = path !== "/" ? path.replace(/\/$/g, "") : path;
380
- return path;
381
- }
382
-
383
- clear(str) {
384
- const regex = new RegExp(`^[\#\/]{1,}|\/$`, "g");
385
- str = str.lower().trim().replace(regex, "");
386
- return str;
387
- }
388
-
389
- freeze() {
390
- this.isFrozen = true;
391
- }
392
-
393
- unfreeze(){
394
- this.isFrozen = false;
395
- }
396
-
397
- listen() {
398
- global.on("popstate", () => {
399
- debugLib(["Dispatched Popstate", this.routes]);
400
- let current = this.getRoute();
401
- const root = "/" + this.clear(this.root);
402
-
403
- // todo enhance this part
404
- current = (this.mode === "hash" && this.root !== "/") ? (current = root + current).replace(/\/$/, "") : current;
405
-
406
- const route = this.routes.find(route => {
407
- if (route.path === current) {
408
- return route;
409
- } else if (current === "" || current === "/" || current.includes("index.html")) {
410
- return route.path === root;
411
- }
412
- });
413
-
414
- if (isDef(route)) {
415
- if (!this.isFrozen) route.cb(); // invokes inject(view)
416
- } else {
417
- if (isDef(this.err)) {
418
- const err = this.routes.find(route => route.path === this.err);
419
- if (isDef(err)) {
420
- err.cb();
421
- } else {
422
- console.error(`${debugStr} unmached path of ${quotes("err property")} @ router instance.`);
423
- }
424
- } else {
425
- this.appMarkup.innerHTML = "Not Found!";
426
- }
427
- }
428
-
429
- debugLib({
430
- current,
431
- route
432
- });
433
-
434
- });
435
-
436
- dispatchEvent(this.popStateEvent);
437
- }
438
-
439
- getRoute() {
440
- let fragment = "";
441
- if (this.mode === "history") {
442
- fragment = this.clear(decodeURI(location.pathname));
443
- } else if (this.mode === "hash") {
444
- fragment = this.clear(decodeURI(location.hash));
445
- }
446
- return "/" + fragment;
447
- }
448
-
449
- navigate(path) {
450
- this.unfreeze();
451
- path = this.resolve(path);
452
- if (this.mode === "history") {
453
- global.history.pushState({}, "", path);
454
- debugLib("Pushed to history");
455
- dispatchEvent(this.popStateEvent);
456
- } else if (this.mode === "hash") {
457
- // todo enhance this part
458
- if (this.root === "/") {
459
- location.href = `${location.href.replace(/\#.*/g, "")}#${path}`;
460
- } else {
461
- let root = this.clear(this.root);
462
- root = root.replace(/\//g, `\\/`);
463
- const rootRegex = new RegExp(`\\/${root}`, "g");
464
- let _path = path.replace(rootRegex, "");
465
- _path = "/" + _path.replace(/^\//g, "");
466
- location.href = `${location.href.replace(/\#.*/g, "")}#${_path}`;
85
+ // start devtool
86
+ if (isDev()) {
87
+ rootCompName = selector.replace(/\#|\./, "").cap();
88
+ global.olumDevtool = { rootCompName: rootCompName, selector: selector };
467
89
  }
468
- }
469
-
470
- }
471
-
472
- to() {
473
- const links = $("[to]", true);
474
- if (isFullArr(links)) {
475
- links.forEach(link => {
476
- // disable href in anchor
477
- if (link.nodeName === "A") link.setAttribute("href", "javascript:void(0)");
478
- // disable icons in links
479
- [...link.children].forEach(icon => (icon.style.pointerEvents = "none"));
90
+ // end devtool
480
91
 
481
- // onclick
482
- link.on("click", e => {
483
- const path = e.target.getAttribute("to");
484
- const _path_ = this.resolve(path);
485
- const current = this.getRoute();
486
- if (isSame(_path_, current)) return; // stop routing | preserve history from duplicated routes
487
- this.navigate(path); // navigate to clicked route
488
- });
489
- });
92
+ selector = selector.replace(/\#|\./, "");
93
+ rootElm =
94
+ delimiter === "." ? document.getElementsByClassName(selector)[0] :
95
+ delimiter === "#" ? document.getElementById(selector) :
96
+ document.getElementsByTagName(selector)[0];
97
+ } else {
98
+ throw new Error(debugStr + " Root Element is not found in DOM!");
490
99
  }
100
+ return this;
491
101
  }
492
102
 
493
- active(path_b) {
494
- const links = $("[to]", true);
495
- if (isFullArr(links)) {
496
- links.forEach(link => {
497
- const path_a = this.resolve(link.getAttribute("to"));
498
- if (path_a === path_b) {
499
- link.classList.add("active");
500
- } else {
501
- link.classList.remove("active");
502
- }
503
- });
504
- }
505
- }
103
+ function buildTree(entry) {
104
+ var compsArr = [];
506
105
 
507
- buildTree(entry) {
508
- const compsArr = [];
509
- const recursive = comp => {
510
- if (hasProp(comp, "components") && isFullObj(comp.components)) {
511
- for (let key in comp.components) {
512
- const obj = {};
106
+ function recursive(comp) {
107
+ if (comp.hasOwnProperty("components") && isFullObj(comp.components)) {
108
+ for (var key in comp.components) {
109
+ var obj = {};
513
110
  addProp(obj, "parent", comp.name);
514
111
  addProp(obj, "child", {});
515
112
  addProp(obj.child, "name", key);
516
- const instance = new comp.components[key]();
113
+ var instance = new comp.components[key]();
517
114
  addProp(obj.child, "data", instance.data());
518
115
  compsArr.push(obj);
519
116
 
520
- if (hasProp(obj, "child") && hasProp(obj.child, "data")) {
521
- const nextEntry = obj.child.data;
117
+ if (obj.hasOwnProperty("child") && obj.child.hasOwnProperty("data")) {
118
+ var nextEntry = obj.child.data;
522
119
  recursive(nextEntry);
523
120
  }
524
121
  }
525
122
  }
526
123
  };
527
124
  recursive(entry);
528
- debugLib(["compsArr", compsArr]);
529
-
530
125
  return compsArr;
531
126
  }
532
127
 
533
- inject(View) {
534
- if (!View || typeof View != "function") {
535
- console.error(`${debugStr} ${quotes("View argument")} is missing or it's not a constructor function! @ Olum.inject(View)`);
536
- } else {
537
- const view = new View();
538
- const entry = view.data();
539
- const compsArr = this.buildTree(entry);
540
-
541
- const init = instance => {
542
- // labeling components
543
- const label = instance ? instance.label(entry, compsArr) : {
544
- entry,
545
- compsArr
546
- };
547
- // final component (View)
548
- const viewObj = this.merge(label);
549
- // css
550
- this.buildStyles(viewObj.style);
551
- // html
552
- this.appMarkup.innerHTML = viewObj.template;
553
- // js
554
- setTimeout(() => {
555
- this.active(this.getRoute()); // add active class to current route link tag
556
- this.to(); // enables to attribute e.g. <a to="/">Home</a>
557
- const scriptKeysArr = Object.keys(viewObj.script);
558
- const recursive = (num = 0) => {
559
- viewObj.script[scriptKeysArr[num]]();
560
- if (num === scriptKeysArr.length - 1) {
561
- if (isDef(this.viewLoaded)) {
562
- dispatchEvent(this.viewLoaded);
563
- debugLib("viewLoaded");
564
- }
565
- }
566
- if (num + 1 <= scriptKeysArr.length - 1) recursive(num + 1);
567
- };
568
- recursive();
569
- }, 0);
570
- }
571
-
572
- if (isDev()) {
573
- import("/devtool.js").then(module => {
574
- const Devtool = module.default;
575
- const instance = new Devtool(this.appMarkup, this.rootCompName);
576
- init(instance);
577
- }).catch(() => debug(devtoolHint, "warn"));
578
- } else {
579
- init();
580
- }
581
-
582
- }
583
- }
584
-
585
- buildStyles(css) {
586
- const id = "olum_style_tag";
587
- let styleTag = document.getElementById(id);
128
+ function buildStyles(css) {
129
+ var id = "olum_style_tag";
130
+ var styleTag = document.getElementById(id);
588
131
  if (!styleTag) {
589
132
  styleTag = document.createElement("style");
590
133
  styleTag.id = id;
591
134
  document.head.append(styleTag);
592
135
  }
593
- styleTag.innerHTML = css;
136
+ styleTag.innerHTML = css + "\n [to] * {pointer-events: none;}";
594
137
  }
595
138
 
596
- merge({
597
- entry,
598
- compsArr
599
- }) {
139
+ function merge(tree) {
140
+ var entry = tree.entry;
141
+ var compsArr = tree.compsArr;
142
+
600
143
  // parent (view)
601
- let template = entry.template || "";
602
- let style = entry.style || "";
603
- const script = {};
144
+ var template = entry.template || "";
145
+ var style = entry.style || "";
146
+ var script = {};
604
147
  !!(entry.render) ? (script[0] = entry.render) : null;
605
148
 
606
149
  // children
607
150
  if (isFullArr(compsArr)) {
608
- compsArr.forEach((comp, index) => {
609
- const data = comp.child.data;
610
- const html = data.template || "";
611
- const css = data.style || "";
612
- const js = data.render || null;
613
- const name = this.prefix !== null ? this.prefix + "-" + data.name : data.name;
614
- const regex = new RegExp(`<(${name}\\s{0,})\\/>`, "gi"); // detect components e.g. <App-AddTodo /> or <AddTodo />
151
+ for(var i = 0; i < compsArr.length; i++) {
152
+ var data = compsArr[i].child.data;
153
+ var html = data.template || "";
154
+ var css = data.style || "";
155
+ var js = data.render || null;
156
+ var name = prefix ? prefix + "-" + data.name : data.name;
157
+ var regex = new RegExp("<(" + name + "\\s{0,})\\/>", "gi"); // detect components e.g. <App-AddTodo /> or <AddTodo />
615
158
 
616
159
  template = template.replace(regex, html);
617
160
  style += css;
618
- if (js !== null) script[index + 1] = js;
619
- });
161
+ if (js !== null) script[i + 1] = js;
162
+ }
620
163
  }
621
164
 
622
165
  return {
@@ -625,44 +168,106 @@
625
168
  script,
626
169
  };
627
170
  }
171
+
172
+ function labelView(root, arr) {
173
+ var compAttrRegex = /(olum-component=[\"\']([^\"|\']*)[\"\'])|(olum-component)/gi;
174
+ var openingSelfClosingTagRegex = /<[a-z]+(>|.*?[^?]>)/gi;
175
+ var greaterCharRegex = /\>/gi;
176
+ var compsArr = Array.from(arr);
177
+ var entry = root;
178
+
179
+ // children
180
+ for(var i = 0; i < compsArr.length; i++) {
181
+ var name = compsArr[i].child.data.name || "undefined";
182
+ if (compsArr[i].child && compsArr[i].child.data && compsArr[i].child.data.hasOwnProperty("template")) {
183
+ var data = compsArr[i].child.data;
184
+ // clean
185
+ data.template = data.template.replace(compAttrRegex, "");
186
+ // labeling
187
+ var compWrapper = data.template.match(openingSelfClosingTagRegex);
188
+ if (isFullArr(compWrapper)) {
189
+ data.template = data.template.replace(compWrapper[0], compWrapper[0].replace(greaterCharRegex, " olum-component='"+name+"'>"));
190
+ }
191
+ }
192
+ }
628
193
 
629
- }
194
+ // parent (view)
195
+ if (entry.template) {
196
+ var name = entry.name || "undefined";
197
+ // clean
198
+ entry.template = entry.template.replace(compAttrRegex, "");
199
+ // labeling
200
+ var compWrapper = entry.template.match(openingSelfClosingTagRegex);
201
+ if (isFullArr(compWrapper)) {
202
+ entry.template = entry.template.replace(
203
+ compWrapper[0],
204
+ compWrapper[0].replace(greaterCharRegex, " olum-component='"+name+"' router-view='"+name+"'>")
205
+ );
206
+ }
207
+ }
630
208
 
631
- /**
632
- * @example const event = new Service("eventName");
633
- * window.on(event.event, () => console.log("fired"));
634
- * event.trigger()
635
- */
636
- class Service {
637
- constructor(event) {
638
- if (!(this instanceof Service)) console.error(`${debugStr} can't invoke ${quotes("Service constructor")} without new keyword`);
639
- this.event = event;
640
- this.init();
641
- return this;
209
+ // root (placeholder)
210
+ rootElm.setAttribute("olum-component", rootCompName);
211
+
212
+ return {
213
+ entry,
214
+ compsArr,
215
+ };
642
216
  }
643
217
 
644
- init() {
645
- this.serviceEvent = new CustomEvent(this.event, {
646
- detail: {},
647
- bubbles: true,
648
- cancelable: true,
649
- composed: false,
650
- });
218
+ function useComponent() {
219
+ debug("use component");
220
+ var view = new which.cb();
221
+ var entry = view.data();
222
+ var compsArr = buildTree(entry);
223
+ // labeling components
224
+ var label = isDev() ? labelView(entry, compsArr) : { entry: entry, compsArr: compsArr };
225
+ // final component (View)
226
+ var viewObj = merge(label);
227
+ // css
228
+ buildStyles(viewObj.style);
229
+ // html
230
+ rootElm.innerHTML = viewObj.template;
231
+ // js
232
+ setTimeout(function () {
233
+ for (var key in viewObj.script) {
234
+ viewObj.script[key]();
235
+ }
236
+ }, 0);
237
+ }
238
+
239
+ function useRouter() {
240
+ debug("use OlumRouter");
241
+ var router = which.cb;
242
+ // share core functionalites with router
243
+ // props
244
+ router.__proto__.rootElm = rootElm;
245
+ // methods
246
+ router.__proto__.buildStyles = buildStyles;
247
+ router.__proto__.buildTree = buildTree;
248
+ router.__proto__.labelView = labelView;
249
+ router.__proto__.merge = merge;
250
+
251
+ if (router.isReady) router.listen();
252
+ }
253
+
254
+ function mount() {
255
+ debug({mount:"mount()",rootElm, which});
256
+
257
+ if (which && which.type && which.cb) {
258
+ if (which.type === "router") useRouter();
259
+ else if (which.type === "component") useComponent();
260
+ } else {
261
+ throw new Error(debugStr + " Can't mount, Missing component or router @use()");
262
+ }
651
263
  }
652
264
 
653
- trigger() {
654
- if (isDef(this.serviceEvent)) dispatchEvent(this.serviceEvent);
265
+ function init() {
266
+ if (!rootElm) throw new Error(debugStr + " Root Element is not found in DOM!");
267
+ else mount();
655
268
  }
269
+
656
270
  }
657
271
 
658
- return {
659
- Olum,
660
- Service,
661
- Origin,
662
- $,
663
- debug,
664
- setTemp,
665
- Localize
666
- };
667
-
272
+ return Olum;
668
273
  });
package/dist/olum.min.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * @name Olum.js
3
- * @version 0.1.0
3
+ * @version 0.2.1
4
4
  * @copyright 2021
5
5
  * @author Eissa Saber
6
6
  * @license MIT
7
7
  */
8
- "use strict";var _this2=void 0;function _getRequireWildcardCache(e){if("function"!=typeof WeakMap)return null;var t=new WeakMap,n=new WeakMap;return(_getRequireWildcardCache=function(e){return e?n:t})(e)}function _interopRequireWildcard(e,t){if(!t&&e&&e.__esModule)return e;if(null===e||"object"!==_typeof(e)&&"function"!=typeof e)return{default:e};t=_getRequireWildcardCache(t);if(t&&t.has(e))return t.get(e);var n,r,o={},i=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&((r=i?Object.getOwnPropertyDescriptor(e,n):null)&&(r.get||r.set)?Object.defineProperty(o,n,r):o[n]=e[n]);return o.default=e,t&&t.set(e,o),o}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _defineProperties(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}function _createClass(e,t,n){return t&&_defineProperties(e.prototype,t),n&&_defineProperties(e,n),e}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _toConsumableArray(e){return _arrayWithoutHoles(e)||_iterableToArray(e)||_unsupportedIterableToArray(e)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(e,t){if(e){if("string"==typeof e)return _arrayLikeToArray(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Map"===(n="Object"===n&&e.constructor?e.constructor.name:n)||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?_arrayLikeToArray(e,t):void 0}}function _iterableToArray(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function _arrayWithoutHoles(e){if(Array.isArray(e))return _arrayLikeToArray(e)}function _arrayLikeToArray(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function _typeof(e){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}!function(e,t){if("object"===("undefined"==typeof module?"undefined":_typeof(module))&&module.exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var n,r=t();for(n in r)e[n]=r[n]}}("undefined"!=typeof self?self:void 0,function(){function i(){return!!["localhost","127.0.0.1"].includes(location.hostname)}function t(e){return!(null===e||"object"!==_typeof(e))}function o(e){return!!(t(e)&&Array.isArray(e)&&e.length)}function c(e){return!!(t(e)&&Array.isArray(Object.keys(e))&&Object.keys(e).length)}function s(e){return!(null==e)}function u(e,t){return!!e.hasOwnProperty(t)}function l(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,configurable:!0})}function h(e){var t="err"==(t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"log")?"error":t}var f="undefined"!=typeof self?self:_this2,p="Olum [warn]:",d=function(e){return"“"+e+"”"},y="".concat(p," ").concat(d("devtool extension")," is not installed!\n \nto install it please download ").concat(d("devtool.js")," from the official repo\n \n@ https://raw.githubusercontent.com/olumjs/olum-devtool/master/devtool.js\n \nand save it in the root of your project");String.prototype.upper=function(){return this.toUpperCase()},String.prototype.lower=function(){return this.toLowerCase()},String.prototype.cap=function(){return this.toLowerCase().split(" ").map(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}).join(" ")};function v(e){var t,n="err"==(n=1<arguments.length&&void 0!==arguments[1]?arguments[1]:"log")?"error":n;i()&&(Array.isArray(e)?(t=console)[n].apply(t,_toConsumableArray(e)):console[n](e))}function m(n,e){var t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:document;return"string"!=typeof n?(!Array.isArray(n)&&n&&n instanceof Element&&(n.get=function(e,t){return m(e,t,n)}),n):(t=[].slice.call(t.querySelectorAll(n)),o(t)?e?t:t[0]:e?[]:null)}function e(e,t){return this.addEventListener(e,t,2<arguments.length&&void 0!==arguments[2]&&arguments[2])}function n(e,t){return this.removeEventListener(e,t,2<arguments.length&&void 0!==arguments[2]&&arguments[2])}Element.prototype.on=e,Element.prototype.off=n,Document.prototype.on=e,Document.prototype.off=n,f.on=e,f.off=n;Element.prototype.toggle=function(){var e,t=this;this.style.transition="height ".concat(0<arguments.length&&void 0!==arguments[0]?arguments[0]:.3,"s ease-in-out"),0==this.clientHeight?(this.style.height="auto",e=this.clientHeight+"px",this.style.height="0",setTimeout(function(){return t.style.height=e},0)):this.style.height="0"};var r=function(){function n(e,t){_classCallCheck(this,n),_defineProperty(this,"key","tolang"),this.dictionary=e,this.rtlLangs=t,this.init()}return _createClass(n,[{key:"init",value:function(){this.detect();var i=this;String.prototype.trans=function(){var e,t=i.dictionary,n=i.current(),r=t[n],n='"'.concat(this,'" property is misspelled or missed at "src/locales/').concat(n,'.js"');if(void 0!==t&&void 0!==r)for(var o in r)this===o&&(e=r[o]);else v("locales or langObj are not defined! @ String.prototype.trans","warn");return e||n},this.tolang()}},{key:"detect",value:function(){var e=m("body");e&&(this.rtlLangs.includes(this.current())?e.classList.add("RTL"):e.classList.remove("RTL"))}},{key:"current",value:function(){return localStorage.getItem(this.key)||"en"}},{key:"tolang",value:function(){var t=this;document.on("click",function(e){e.target.hasAttribute(t.key)&&("A"===e.target.nodeName&&e.target.setAttribute("href","javascript:void(0)"),_toConsumableArray(e.target.children).forEach(function(e){return e.style.pointerEvents="none"}),e=e.target.getAttribute(t.key),localStorage.setItem(t.key,e),location.reload())})}}]),n}(),a=function(){function e(){var t=this;_classCallCheck(this,e),_defineProperty(this,"get",function(e){return t.req("GET",e,1<arguments.length&&void 0!==arguments[1]?arguments[1]:{})}),_defineProperty(this,"post",function(e){return t.req("POST",e,1<arguments.length&&void 0!==arguments[1]?arguments[1]:{})}),_defineProperty(this,"delete",function(e){return t.req("DELETE",e,1<arguments.length&&void 0!==arguments[1]?arguments[1]:{})}),_defineProperty(this,"put",function(e){return t.req("PUT",e,1<arguments.length&&void 0!==arguments[1]?arguments[1]:{})}),_defineProperty(this,"patch",function(e){return t.req("PATCH",e,1<arguments.length&&void 0!==arguments[1]?arguments[1]:{})}),this instanceof e||console.error("".concat(p," can't invoke ").concat(d("Origin constructor")," without new keyword")),this.xhr=new XMLHttpRequest}return _createClass(e,[{key:"setParams",value:function(e){if(c(e)){for(var t in e)"body"!==t&&this.xhr.setRequestHeader(t,e[t]);return u(e,"body")&&c(e.body)?JSON.stringify(e.body):null}}},{key:"onload",value:function(t,e){var n=this;return this.xhr.onreadystatechange=function(){if(4===n.xhr.readyState)if(0===n.xhr.status||200<=n.xhr.status&&n.xhr.status<=299)try{t(JSON.parse(n.xhr.responseText))}catch(e){t(n.xhr.responseText)}else 400<=n.xhr.status&&n.xhr.status<=599&&e("".concat(p," couldn't reach the server"))}}},{key:"req",value:function(r,o){var i=this,a=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};return new Promise(function(e,t){i.xhr.open(r,o,!0);var n=i.setParams(a);i.onload(e,t),i.xhr.onerror=function(){return t("".concat(p," network error"))},null!==n?i.xhr.send(n):i.xhr.send()})}}]),e}();return{Olum:function(){function a(e){var t=e.mode,n=e.root,r=e.el,o=e.prefix,i=e.err,e=e.routes;_classCallCheck(this,a),_defineProperty(this,"isFrozen",!1),_defineProperty(this,"routes",[]),_defineProperty(this,"pushStateAPI",!!f.history.pushState),this instanceof a||console.error("".concat(p," can't invoke ").concat(d("Olum constructor")," without new keyword")),this.setMode(t),this.setRoot(n),this.setPrefix(o),this.setErr(i),this.hasRootElm(r)?this.hasRoutes(e)?(this.popStateEvent=new PopStateEvent("popstate"),this.viewLoaded=new CustomEvent("viewLoaded",{detail:{},bubbles:!0,cancelable:!0,composed:!1}),this.listen()):console.error("".concat(p," couldn't find ").concat(d("routes property")," @ router instance or it's empty. \nmake sure that ").concat(d("routes property"),' has components \ne.g. routes = [{ path: "/", comp: Home }]')):console.error("".concat(p," couldn't find a value for ").concat(d("el property"),' @ router instance. \nmake sure it has the right selector e.g. el:"#app" \nand ').concat(d("Root Element"),' exists in dom e.g. <div id="app"></div>'))}return _createClass(a,[{key:"hasRootElm",value:function(e){var t=document.querySelector(e);return!(!e||!t)&&(this.rootCompName=e.replace(/\#|\./,"").cap(),this.appMarkup=t,!0)}},{key:"hasRoutes",value:function(e){var t=this;return!(!e||!o(e))&&(e.forEach(function(e){return t.addRoute(e.path,e.comp)}),!0)}},{key:"setPrefix",value:function(e){e?this.prefix=e:(this.prefix=null,v("".concat(p," couldn't find ").concat(d("prefix property")," @ router instance. \nfalling back to default component tag e.g. <ComponentName/>"),"warn"))}},{key:"setRoot",value:function(e){e?this.root=e:(this.root="/",v("".concat(p," couldn't find ").concat(d("root property")," @ router instance. \nfalling back to default value: ").concat(d("/")),"warn"))}},{key:"setErr",value:function(e){e?this.err=this.resolve(e):(this.err=null,v("".concat(p," couldn't find ").concat(d("err property")," @ router instance. \nfalling back to default 404 page"),"warn"))}},{key:"setMode",value:function(e){e?this.pushStateAPI?this.mode=e:(this.mode="hash",v("".concat(p," mode is set to ").concat(d("hash")," \n").concat(d("history")," is not supported!"),"warn")):(this.mode=this.pushStateAPI?"history":"hash",v("".concat(p," couldn't find ").concat(d("mode property")," @ router instance. \nfalling back to available default mode: ").concat(d(this.mode)),"warn"))}},{key:"addRoute",value:function(e,t){var n=this;this.routes.push({path:this.resolve(e),cb:function(){return n.inject(t)}})}},{key:"delRoute",value:function(n){var r=this;this.routes.forEach(function(e){var t;e.path===r.resolve(n)&&(t=r.routes,e=e,t.length&&-1<t.indexOf(e)&&t.splice(t.indexOf(e),1))})}},{key:"flush",value:function(){this.routes=[]}},{key:"resolve",value:function(e){var t=this.clear(this.root);return e=this.clear(e),e="/"!==(e="/"!==this.root?"/"+t+"/"+e:"/"+e)?e.replace(/\/$/g,""):e}},{key:"clear",value:function(e){var t=new RegExp("^[#/]{1,}|/$","g");return e=e.lower().trim().replace(t,"")}},{key:"freeze",value:function(){this.isFrozen=!0}},{key:"unfreeze",value:function(){this.isFrozen=!1}},{key:"listen",value:function(){var o=this;f.on("popstate",function(){h(["Dispatched Popstate",o.routes]);var e,t=o.getRoute(),n="/"+o.clear(o.root),t="hash"===o.mode&&"/"!==o.root?(t=n+t).replace(/\/$/,""):t,r=o.routes.find(function(e){return e.path===t?e:""===t||"/"===t||t.includes("index.html")?e.path===n:void 0});s(r)?o.isFrozen||r.cb():s(o.err)?(e=o.routes.find(function(e){return e.path===o.err}),s(e)?e.cb():console.error("".concat(p," unmached path of ").concat(d("err property")," @ router instance."))):o.appMarkup.innerHTML="Not Found!",h({current:t,route:r})}),dispatchEvent(this.popStateEvent)}},{key:"getRoute",value:function(){var e="";return"history"===this.mode?e=this.clear(decodeURI(location.pathname)):"hash"===this.mode&&(e=this.clear(decodeURI(location.hash))),"/"+e}},{key:"navigate",value:function(e){var t;this.unfreeze(),e=this.resolve(e),"history"===this.mode?(f.history.pushState({},"",e),h("Pushed to history"),dispatchEvent(this.popStateEvent)):"hash"===this.mode&&("/"===this.root?location.href="".concat(location.href.replace(/\#.*/g,""),"#").concat(e):(t=(t=this.clear(this.root)).replace(/\//g,"\\/"),t=new RegExp("\\/".concat(t),"g"),t="/"+(t=e.replace(t,"")).replace(/^\//g,""),location.href="".concat(location.href.replace(/\#.*/g,""),"#").concat(t)))}},{key:"to",value:function(){var r=this,e=m("[to]",!0);o(e)&&e.forEach(function(e){"A"===e.nodeName&&e.setAttribute("href","javascript:void(0)"),_toConsumableArray(e.children).forEach(function(e){return e.style.pointerEvents="none"}),e.on("click",function(e){var t=e.target.getAttribute("to"),n=r.resolve(t),e=r.getRoute();n!==e&&r.navigate(t)})})}},{key:"active",value:function(t){var n=this,e=m("[to]",!0);o(e)&&e.forEach(function(e){n.resolve(e.getAttribute("to"))===t?e.classList.add("active"):e.classList.remove("active")})}},{key:"buildTree",value:function(e){var o=[];return function e(t){if(u(t,"components")&&c(t.components))for(var n in t.components){var r={};l(r,"parent",t.name),l(r,"child",{}),l(r.child,"name",n);n=new t.components[n];l(r.child,"data",n.data()),o.push(r),u(r,"child")&&u(r.child,"data")&&e(r.child.data)}}(e),h(["compsArr",o]),o}},{key:"inject",value:function(e){var t,n,r,o=this;e&&"function"==typeof e?(t=(new e).data(),n=this.buildTree(t),r=function(e){var e=e?e.label(t,n):{entry:t,compsArr:n},r=o.merge(e);o.buildStyles(r.style),o.appMarkup.innerHTML=r.template,setTimeout(function(){o.active(o.getRoute()),o.to();var n=Object.keys(r.script);(function e(){var t=0<arguments.length&&void 0!==arguments[0]?arguments[0]:0;r.script[n[t]](),t===n.length-1&&s(o.viewLoaded)&&(dispatchEvent(o.viewLoaded),h("viewLoaded")),t+1<=n.length-1&&e(t+1)})()},0)},i()?Promise.resolve().then(function(){return _interopRequireWildcard(require("/devtool.js"))}).then(function(e){e=new e.default(o.appMarkup,o.rootCompName);r(e)}).catch(function(){return v(y,"warn")}):r()):console.error("".concat(p," ").concat(d("View argument")," is missing or it's not a constructor function! @ Olum.inject(View)"))}},{key:"buildStyles",value:function(e){var t="olum_style_tag",n=document.getElementById(t);n||((n=document.createElement("style")).id=t,document.head.append(n)),n.innerHTML=e}},{key:"merge",value:function(e){var i=this,t=e.entry,e=e.compsArr,a=t.template||"",c=t.style||"",s={};return t.render&&(s[0]=t.render),o(e)&&e.forEach(function(e,t){var n=e.child.data,r=n.template||"",o=n.style||"",e=n.render||null,n=null!==i.prefix?i.prefix+"-"+n.name:n.name,n=new RegExp("<(".concat(n,"\\s{0,})\\/>"),"gi");a=a.replace(n,r),c+=o,null!==e&&(s[t+1]=e)}),{template:a,style:c,script:s}}}]),a}(),Service:function(){function t(e){return _classCallCheck(this,t),this instanceof t||console.error("".concat(p," can't invoke ").concat(d("Service constructor")," without new keyword")),this.event=e,this.init(),this}return _createClass(t,[{key:"init",value:function(){this.serviceEvent=new CustomEvent(this.event,{detail:{},bubbles:!0,cancelable:!0,composed:!1})}},{key:"trigger",value:function(){s(this.serviceEvent)&&dispatchEvent(this.serviceEvent)}}]),t}(),Origin:a,$:m,debug:v,setTemp:function(e,t){var n,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:["{{","}}"];for(n in t)e=e.replace(new RegExp("\\".concat(r[0][0],"\\").concat(r[0][1]).concat(n,"\\").concat(r[1][0],"\\").concat(r[1][1]),"g"),t[n]);return e},Localize:r}});
8
+ !function(e,t){"object"==typeof module&&module.exports?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Olum=t()}("undefined"!=typeof self?self:this,function(){"use strict";var n="undefined"!=typeof self?self:this,c="Olum [warn]:",o=!1;function u(){return-1!==["localhost","127.0.0.1"].indexOf(n.location.hostname)}function f(e){return null!==e&&"object"==typeof e}function d(e){return f(e)&&Array.isArray(e)&&e.length}function h(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,configurable:!0})}function y(e,t){t="err"==(t=null==t?"log":t)?"error":t,o&&(Array.isArray(e)?console[t].apply(console,e):console[t](e))}return String.prototype.cap=function(){return this.toLowerCase().split(" ").map(function(e){return e.charAt(0).toUpperCase()+e.slice(1)}).join(" ")},function e(t){if(!(this instanceof e))throw new Error("can't invoke 'Olum' without 'new' keyword");var m=null,p=null,o=null,s=t&&t.prefix?t.prefix:null;function r(e){var a=[];return function e(t){if(t.hasOwnProperty("components")&&f(r=t.components)&&Array.isArray(Object.keys(r))&&Object.keys(r).length)for(var n in t.components){var o={};h(o,"parent",t.name),h(o,"child",{}),h(o.child,"name",n),n=new t.components[n],h(o.child,"data",n.data()),a.push(o),o.hasOwnProperty("child")&&o.child.hasOwnProperty("data")&&e(o.child.data)}var r}(e),a}function a(e){var t="olum_style_tag",n=document.getElementById(t);n||((n=document.createElement("style")).id=t,document.head.append(n)),n.innerHTML=e+"\n [to] * {pointer-events: none;}"}function l(e){var t=e.entry,n=e.compsArr,o=t.template||"",r=t.style||"",a={};if(t.render&&(a[0]=t.render),d(n))for(var l=0;l<n.length;l++){var i=(m=n[l].child.data).template||"",c=m.style||"",u=m.render||null,m=s?s+"-"+m.name:m.name,m=new RegExp("<("+m+"\\s{0,})\\/>","gi"),o=o.replace(m,i);r+=c,null!==u&&(a[l+1]=u)}return{template:o,style:r,script:a}}function i(e,t){for(var n=/(olum-component=[\"\']([^\"|\']*)[\"\'])|(olum-component)/gi,o=/<[a-z]+(>|.*?[^?]>)/gi,r=/\>/gi,a=Array.from(t),e=e,l=0;l<a.length;l++){var i,c,u=a[l].child.data.name||"undefined";a[l].child&&a[l].child.data&&a[l].child.data.hasOwnProperty("template")&&((i=a[l].child.data).template=i.template.replace(n,""),d(c=i.template.match(o))&&(i.template=i.template.replace(c[0],c[0].replace(r," olum-component='"+u+"'>"))))}return e.template&&(u=e.name||"undefined",e.template=e.template.replace(n,""),d(c=e.template.match(o))&&(e.template=e.template.replace(c[0],c[0].replace(r," olum-component='"+u+"' router-view='"+u+"'>")))),m.setAttribute("olum-component",p),{entry:e,compsArr:a}}this.use=function(e){if(!e)throw new Error(c+" Missing component or router @use()");if(!(o=e.name&&"function"==typeof e.name&&"OlumRouter"===e.name()?{type:"router",cb:e}:{type:"component",cb:e}))throw new Error(c+" Root component or router are not defined!");!function(){if(!m)throw new Error(c+" Root Element is not found in DOM!");!function(){if(y({mount:"mount()",rootElm:m,which:o}),!(o&&o.type&&o.cb))throw new Error(c+" Can't mount, Missing component or router @use()");"router"===o.type?function(){y("use OlumRouter");var e=o.cb;e.__proto__.rootElm=m,e.__proto__.buildStyles=a,e.__proto__.buildTree=r,e.__proto__.labelView=i,e.__proto__.merge=l,e.isReady&&e.listen()}():"component"===o.type&&function(){y("use component");var e=(new o.cb).data(),t=r(e),n=l(u()?i(e,t):{entry:e,compsArr:t});a(n.style),m.innerHTML=n.template,setTimeout(function(){for(var e in n.script)n.script[e]()},0)}()}()}()},this.$=function(e){if(!e)throw new Error(c+" Root Element is not found in DOM!");var t;return-1!==e.indexOf(".")?t=".":-1!==e.indexOf("#")&&(t="#"),u()&&(p=e.replace(/\#|\./,"").cap(),n.olumDevtool={rootCompName:p,selector:e}),e=e.replace(/\#|\./,""),m="."===t?document.getElementsByClassName(e)[0]:"#"===t?document.getElementById(e):document.getElementsByTagName(e)[0],this}}});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olum",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "The VanillaJS developer’s platform.",
5
5
  "main": "dist/olum.js",
6
6
  "directories": {