native-document 1.0.0

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.
Files changed (47) hide show
  1. package/dist/native-document.dev.js +2346 -0
  2. package/dist/native-document.min.js +1 -0
  3. package/elements.js +2 -0
  4. package/index.js +11 -0
  5. package/package.json +16 -0
  6. package/readme.md +495 -0
  7. package/rollup.config.js +29 -0
  8. package/router.js +9 -0
  9. package/src/data/MemoryManager.js +60 -0
  10. package/src/data/Observable.js +162 -0
  11. package/src/data/ObservableChecker.js +24 -0
  12. package/src/data/ObservableItem.js +101 -0
  13. package/src/data/Store.js +74 -0
  14. package/src/elements/content-formatter.js +32 -0
  15. package/src/elements/control/for-each.js +110 -0
  16. package/src/elements/control/show-if.js +86 -0
  17. package/src/elements/control/switch.js +88 -0
  18. package/src/elements/description-list.js +5 -0
  19. package/src/elements/form.js +71 -0
  20. package/src/elements/html5-semantics.js +12 -0
  21. package/src/elements/img.js +45 -0
  22. package/src/elements/index.js +21 -0
  23. package/src/elements/interactive.js +7 -0
  24. package/src/elements/list.js +6 -0
  25. package/src/elements/medias.js +8 -0
  26. package/src/elements/meta-data.js +9 -0
  27. package/src/elements/table.js +14 -0
  28. package/src/errors/ArgTypesError.js +7 -0
  29. package/src/errors/NativeDocumentError.js +8 -0
  30. package/src/errors/RouterError.js +9 -0
  31. package/src/router/Route.js +102 -0
  32. package/src/router/RouteGroupHelper.js +52 -0
  33. package/src/router/Router.js +232 -0
  34. package/src/router/RouterComponent.js +37 -0
  35. package/src/router/link.js +27 -0
  36. package/src/router/modes/HashRouter.js +83 -0
  37. package/src/router/modes/HistoryRouter.js +66 -0
  38. package/src/router/modes/MemoryRouter.js +71 -0
  39. package/src/utils/args-types.js +100 -0
  40. package/src/utils/debug-manager.js +34 -0
  41. package/src/utils/helpers.js +37 -0
  42. package/src/utils/prototypes.js +16 -0
  43. package/src/utils/validator.js +96 -0
  44. package/src/wrappers/AttributesWrapper.js +94 -0
  45. package/src/wrappers/DocumentObserver.js +51 -0
  46. package/src/wrappers/HtmlElementEventsWrapper.js +77 -0
  47. package/src/wrappers/HtmlElementWrapper.js +174 -0
@@ -0,0 +1,162 @@
1
+ import ObservableItem from './ObservableItem';
2
+ import Validator from "../utils/validator";
3
+ import MemoryManager from "./MemoryManager";
4
+ import NativeDocumentError from "../errors/NativeDocumentError";
5
+ import {throttle} from "../utils/helpers.js";
6
+
7
+ /**
8
+ *
9
+ * @param {*} value
10
+ * @returns {ObservableItem}
11
+ * @constructor
12
+ */
13
+ export function Observable(value) {
14
+ return new ObservableItem(value);
15
+ }
16
+
17
+
18
+ Observable.computed = function(callback, dependencies = []) {
19
+ const initialValue = callback();
20
+ const observable = new ObservableItem(initialValue);
21
+
22
+ const updatedValue = throttle(() => observable.set(callback()), 10, { debounce: true });
23
+
24
+ dependencies.forEach(dependency => dependency.subscribe(updatedValue));
25
+
26
+ return observable;
27
+ };
28
+
29
+ /**
30
+ *
31
+ * @param {ObservableItem} observable
32
+ */
33
+ Observable.cleanup = function(observable) {
34
+ observable.cleanup();
35
+ };
36
+
37
+ /**
38
+ * Get the value of an observable or an object of observables.
39
+ * @param {ObservableItem|Object<ObservableItem>} object
40
+ * @returns {{}|*|null}
41
+ */
42
+ Observable.value = function(data) {
43
+ if(Validator.isObservable(data)) {
44
+ return data.val();
45
+ }
46
+ if(Validator.isProxy(data)) {
47
+ return data.$val();
48
+ }
49
+ if(Validator.isArray(data)) {
50
+ const result = [];
51
+ data.forEach(item => {
52
+ result.push(Observable.value(item));
53
+ });
54
+ return result;
55
+ }
56
+ return data;
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param {Object} value
62
+ * @returns {Proxy}
63
+ */
64
+ Observable.init = function(value) {
65
+ const data = {};
66
+ for(const key in value) {
67
+ const itemValue = value[key];
68
+ if(Validator.isJson(itemValue)) {
69
+ console.log(itemValue)
70
+ data[key] = Observable.init(itemValue);
71
+ continue;
72
+ }
73
+ data[key] = Observable(itemValue);
74
+ }
75
+
76
+ const $val = function() {
77
+ const result = {};
78
+ for(const key in data) {
79
+ const dataItem = data[key];
80
+ if(Validator.isObservable(dataItem)) {
81
+ result[key] = dataItem.val();
82
+ } else if(Validator.isProxy(dataItem)) {
83
+ result[key] = dataItem.$val();
84
+ } else {
85
+ result[key] = dataItem;
86
+ }
87
+ }
88
+ return result;
89
+ };
90
+
91
+ return new Proxy(data, {
92
+ get(target, property) {
93
+ if(property === '__isProxy__') {
94
+ return true;
95
+ }
96
+ if(property === '$val') {
97
+ return $val;
98
+ }
99
+ if(target[property] !== undefined) {
100
+ return target[property];
101
+ }
102
+ return undefined;
103
+ },
104
+ set(target, prop, newValue) {
105
+ if(target[prop] !== undefined) {
106
+ target[prop].set(newValue);
107
+ }
108
+ }
109
+ })
110
+ };
111
+
112
+ Observable.object = Observable.init;
113
+ /**
114
+ *
115
+ * @param {Array} target
116
+ * @returns {ObservableItem}
117
+ */
118
+ Observable.array = function(target) {
119
+ if(!Array.isArray(target)) {
120
+ throw new NativeDocumentError('Observable.array : target must be an array');
121
+ }
122
+ const observer = Observable(target);
123
+
124
+ const methods = ['push', 'pop', 'shift', 'unshift', 'reverse', 'sort', 'splice'];
125
+
126
+ methods.forEach((method) => {
127
+ observer[method] = function(...values) {
128
+ const target = observer.val();
129
+ const result = target[method].apply(target, arguments);
130
+ observer.trigger();
131
+ return result;
132
+ };
133
+ });
134
+
135
+ const overrideMethods = ['map', 'filter', 'reduce', 'some', 'every', 'find'];
136
+ overrideMethods.forEach((method) => {
137
+ observer[method] = function(callback) {
138
+ return observer.val()[method](callback);
139
+ };
140
+ })
141
+
142
+ return observer;
143
+ };
144
+
145
+ /**
146
+ * Enable auto cleanup of observables.
147
+ * @param {Boolean} enable
148
+ * @param {{interval:Boolean, threshold:number}} options
149
+ */
150
+ Observable.autoCleanup = function(enable = false, options = {}) {
151
+ if(!enable) {
152
+ return;
153
+ }
154
+ const { interval = 60000, threshold = 100 } = options;
155
+
156
+ window.addEventListener('beforeunload', () => {
157
+ MemoryManager.cleanup();
158
+ });
159
+
160
+ setInterval(() => MemoryManager.cleanObservables(threshold), interval);
161
+ }
162
+
@@ -0,0 +1,24 @@
1
+ /**
2
+ *
3
+ * @param {ObservableItem} $observable
4
+ * @param {Function} $checker
5
+ * @class ObservableChecker
6
+ */
7
+ export default function ObservableChecker($observable, $checker) {
8
+ this.observable = $observable;
9
+ this.checker = $checker;
10
+
11
+ this.subscribe = function(callback) {
12
+ return $observable.subscribe((value) => {
13
+ callback && callback($checker(value));
14
+ });
15
+ };
16
+
17
+ this.val = function() {
18
+ return $checker && $checker($observable.val());
19
+ };
20
+
21
+ this.cleanup = function() {
22
+ return $observable.cleanup();
23
+ }
24
+ }
@@ -0,0 +1,101 @@
1
+ import DebugManager from "../utils/debug-manager";
2
+ import MemoryManager from "./MemoryManager";
3
+ import NativeDocumentError from "../errors/NativeDocumentError";
4
+ import ObservableChecker from "./ObservableChecker";
5
+
6
+ /**
7
+ *
8
+ * @param {*} value
9
+ * @class ObservableItem
10
+ */
11
+ export default function ObservableItem(value) {
12
+ if (value === undefined) {
13
+ throw new NativeDocumentError('ObservableItem requires an initial value');
14
+ }
15
+ if(value instanceof ObservableItem) {
16
+ throw new NativeDocumentError('ObservableItem cannot be an Observable');
17
+ }
18
+
19
+ const $initialValue = (typeof value === 'object') ? JSON.parse(JSON.stringify(value)) : value;
20
+
21
+ let $previousValue = value;
22
+ let $currentValue = value;
23
+ let $isCleanedUp = false;
24
+
25
+ const $listeners = [];
26
+
27
+ const $memoryId = MemoryManager.register(this, $listeners);
28
+
29
+ this.trigger = () => {
30
+ $listeners.forEach(listener => {
31
+ try {
32
+ listener($currentValue, $previousValue);
33
+ } catch (error) {
34
+ DebugManager.error('Listener Undefined', 'Error in observable listener:', error);
35
+ this.unsubscribe(listener);
36
+ }
37
+ });
38
+
39
+ };
40
+
41
+ this.originalValue = () => $initialValue;
42
+
43
+ /**
44
+ * @param {*} data
45
+ */
46
+ this.set = (data) => {
47
+ const newValue = (typeof data === 'function') ? data($currentValue) : data;
48
+ if($currentValue === newValue) {
49
+ return;
50
+ }
51
+ $previousValue = $currentValue;
52
+ $currentValue = newValue;
53
+ this.trigger();
54
+ };
55
+
56
+ this.val = () => $currentValue;
57
+
58
+ this.cleanup = function() {
59
+ $listeners.splice(0);
60
+ $isCleanedUp = true;
61
+ };
62
+
63
+ /**
64
+ *
65
+ * @param {Function} callback
66
+ * @returns {(function(): void)}
67
+ */
68
+ this.subscribe = (callback) => {
69
+ if ($isCleanedUp) {
70
+ DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
71
+ return () => {};
72
+ }
73
+ if (typeof callback !== 'function') {
74
+ throw new NativeDocumentError('Callback must be a function');
75
+ }
76
+
77
+ $listeners.push(callback);
78
+ return () => this.unsubscribe(callback);
79
+ };
80
+
81
+ /**
82
+ * Unsubscribe from an observable.
83
+ * @param {Function} callback
84
+ */
85
+ this.unsubscribe = (callback) => {
86
+ const index = $listeners.indexOf(callback);
87
+ if (index > -1) {
88
+ $listeners.splice(index, 1);
89
+ }
90
+ };
91
+
92
+ /**
93
+ * Create an Observable checker instance
94
+ * @param callback
95
+ * @returns {ObservableChecker}
96
+ */
97
+ this.check = function(callback) {
98
+ return new ObservableChecker(this, callback)
99
+ };
100
+
101
+ }
@@ -0,0 +1,74 @@
1
+ import {Observable} from "./Observable";
2
+
3
+ export const Store = (function() {
4
+
5
+ const $stores = new Map();
6
+
7
+ return {
8
+ /**
9
+ * Create a new state follower and return it.
10
+ * @param {string} name
11
+ * @returns {ObservableItem}
12
+ */
13
+ use(name) {
14
+ const {observer: originalObserver, followers } = $stores.get(name);
15
+ const observerFollower = Observable(originalObserver.val());
16
+ const unSubscriber = originalObserver.subscribe(value => observerFollower.set(value));
17
+ const updaterUnsubscriber = observerFollower.subscribe(value => originalObserver.set(value));
18
+ observerFollower.destroy = () => {
19
+ unSubscriber();
20
+ updaterUnsubscriber();
21
+ observerFollower.cleanup();
22
+ };
23
+ followers.add(observerFollower);
24
+
25
+ return observerFollower;
26
+ },
27
+ /**
28
+ * @param {string} name
29
+ * @returns {ObservableItem}
30
+ */
31
+ follow(name) {
32
+ return this.use(name);
33
+ },
34
+ /**
35
+ * Create a new state and return the observer.
36
+ * @param {string} name
37
+ * @param {*} value
38
+ * @returns {ObservableItem}
39
+ */
40
+ create(name, value) {
41
+ const observer = Observable(value);
42
+ $stores.set(name, { observer, followers: new Set()});
43
+ return observer;
44
+ },
45
+ /**
46
+ * Get the observer for a state.
47
+ * @param {string} name
48
+ * @returns {null|ObservableItem}
49
+ */
50
+ get(name) {
51
+ const item = $stores.get(name);
52
+ return item ? item.observer : null;
53
+ },
54
+ /**
55
+ *
56
+ * @param {string} name
57
+ * @returns {{observer: ObservableItem, followers: Set}}
58
+ */
59
+ getWithFollowers(name) {
60
+ return $stores.get(name);
61
+ },
62
+ /**
63
+ * Delete a state.
64
+ * @param {string} name
65
+ */
66
+ delete(name) {
67
+ const item = $stores.get(name);
68
+ if(!item) return;
69
+ item.observer.cleanup();
70
+ item.followers.forEach(follower => follower.destroy());
71
+ item.observer.clear();
72
+ }
73
+ };
74
+ }());
@@ -0,0 +1,32 @@
1
+ import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
+
3
+ export const Div = HtmlElementWrapper('div');
4
+ export const Span = HtmlElementWrapper('span');
5
+ export const Label = HtmlElementWrapper('span');
6
+ export const P = HtmlElementWrapper('p');
7
+ export const Paragraph = P;
8
+ export const Strong = HtmlElementWrapper('strong');
9
+ export const H1 = HtmlElementWrapper('h1');
10
+ export const H2 = HtmlElementWrapper('h2');
11
+ export const H3 = HtmlElementWrapper('h3');
12
+ export const H4 = HtmlElementWrapper('h4');
13
+ export const H5 = HtmlElementWrapper('h5');
14
+ export const H6 = HtmlElementWrapper('h6');
15
+
16
+ export const Br = HtmlElementWrapper('br');
17
+
18
+ export const Link = HtmlElementWrapper('a');
19
+ export const Pre = HtmlElementWrapper('pre');
20
+ export const Code = HtmlElementWrapper('code');
21
+ export const Blockquote = HtmlElementWrapper('blockquote');
22
+ export const Hr = HtmlElementWrapper('hr');
23
+ export const Em = HtmlElementWrapper('em');
24
+ export const Small = HtmlElementWrapper('small');
25
+ export const Mark = HtmlElementWrapper('mark');
26
+ export const Del = HtmlElementWrapper('del');
27
+ export const Ins = HtmlElementWrapper('ins');
28
+ export const Sub = HtmlElementWrapper('sub');
29
+ export const Sup = HtmlElementWrapper('sup');
30
+ export const Abbr = HtmlElementWrapper('abbr');
31
+ export const Cite = HtmlElementWrapper('cite');
32
+ export const Quote = HtmlElementWrapper('q');
@@ -0,0 +1,110 @@
1
+ import ObservableItem from "../../data/ObservableItem";
2
+ import {Observable} from "../../data/Observable";
3
+ import {createTextNode} from "../../wrappers/HtmlElementWrapper";
4
+ import Validator from "../../utils/validator";
5
+ import {throttle} from "../../utils/helpers.js";
6
+
7
+
8
+ /**
9
+ *
10
+ * @param {*} item
11
+ * @param {string|null} defaultKey
12
+ * @param {?Function} key
13
+ * @returns {*}
14
+ */
15
+ const getKey = (item, defaultKey, key) => {
16
+ if(Validator.isFunction(key)) return key(item, defaultKey);
17
+ if(Validator.isObservable(item)) {
18
+ const val = item.val();
19
+ return (val && key) ? val[key] : defaultKey;
20
+ }
21
+ return item[key] ?? defaultKey;
22
+ }
23
+
24
+ /**
25
+ *
26
+ * @param {Map} cache
27
+ * @param {Set} keyIds
28
+ */
29
+ const cleanBlockByCache = (cache, keyIds) => {
30
+ for(const [key, {child}] of cache.entries()) {
31
+ if(keyIds.has(key)) {
32
+ continue;
33
+ }
34
+ child.remove();
35
+ }
36
+ }
37
+
38
+ /**
39
+ *
40
+ * @param {Array|Object|ObservableItem} data
41
+ * @param {Function} callback
42
+ * @param {?Function} key
43
+ * @returns {DocumentFragment}
44
+ */
45
+ export function ForEach(data, callback, key) {
46
+ const element = document.createDocumentFragment();
47
+ const blockStart = document.createComment('Foreach start');
48
+ const blockEnd = document.createComment('Foreach end');
49
+
50
+ element.appendChild(blockStart);
51
+ element.appendChild(blockEnd);
52
+
53
+ let cache = new Map();
54
+
55
+ const handleContentItem = (item, indexKey) => {
56
+ const keyId = getKey(item, indexKey, key);
57
+
58
+ if(cache.has(keyId)) {
59
+ cache.get(keyId).indexObserver.set(indexKey);
60
+ }
61
+ else {
62
+ const indexObserver = Observable(indexKey);
63
+ let child = callback(item, indexObserver);
64
+ if(Validator.isStringOrObservable(child)) {
65
+ child = createTextNode(child);
66
+ }
67
+ cache.set(keyId, { child, indexObserver});
68
+ }
69
+ return keyId;
70
+ }
71
+ const keyIds = new Set();
72
+
73
+ const buildContent = () => {
74
+ const items = (Validator.isObservable(data)) ? data.val() : data;
75
+ const parent = blockEnd.parentNode;
76
+ if(!parent) {
77
+ return;
78
+ }
79
+ keyIds.clear();
80
+ if(Array.isArray(items)) {
81
+ items.forEach((item, index) => keyIds.add(handleContentItem(item, index)));
82
+ } else {
83
+ for(const indexKey in items) {
84
+ keyIds.add(handleContentItem(items[indexKey], indexKey));
85
+ }
86
+ }
87
+
88
+ cleanBlockByCache(cache, keyIds);
89
+ let nextElementSibling = blockEnd;
90
+ for(const item of [...keyIds].reverse()) {
91
+ const { child } = cache.get(item);
92
+ if(child) {
93
+ if(nextElementSibling && nextElementSibling.previousSibling === child) {
94
+ nextElementSibling = child;
95
+ continue;
96
+ }
97
+ parent.insertBefore(child, nextElementSibling);
98
+ nextElementSibling = child;
99
+ }
100
+ }
101
+ };
102
+
103
+ buildContent();
104
+ if(Validator.isObservable(data)) {
105
+ data.subscribe(throttle((newValue, oldValue) => {
106
+ buildContent(newValue, oldValue);
107
+ }, 50, { debounce: true }))
108
+ }
109
+ return element;
110
+ }
@@ -0,0 +1,86 @@
1
+ import { Observable } from "../../data/Observable";
2
+ import {createTextNode} from "../../wrappers/HtmlElementWrapper";
3
+ import Validator from "../../utils/validator";
4
+ import DebugManager from "../../utils/debug-manager.js";
5
+
6
+ /**
7
+ * Show the element if the condition is true
8
+ *
9
+ * @param {ObservableItem|ObservableChecker} condition
10
+ * @param {*} child
11
+ * @param {string|null} comment
12
+ * @returns {DocumentFragment}
13
+ */
14
+ export const ShowIf = function(condition, child, comment) {
15
+ if(!(Validator.isObservable(condition))) {
16
+ return DebugManager.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
17
+ }
18
+ const element = document.createDocumentFragment();
19
+ const positionKeeperStart = document.createComment('Show if : '+(comment || ''));
20
+ const positionKeeperEnd = document.createComment('Show if : '+(comment || ''));
21
+
22
+ element.appendChild(positionKeeperStart);
23
+ element.appendChild(positionKeeperEnd);
24
+
25
+ let childElement = null;
26
+ const getChildElement = () => {
27
+ if(childElement) {
28
+ return childElement;
29
+ }
30
+ if(typeof child === 'function') {
31
+ childElement = child();
32
+ }
33
+ else {
34
+ childElement = child;
35
+ }
36
+ if(Validator.isStringOrObservable(childElement)) {
37
+ childElement = createTextNode(childElement);
38
+ }
39
+ return childElement;
40
+ };
41
+
42
+ const currentValue = condition.val();
43
+
44
+ if(currentValue) {
45
+ element.appendChild(getChildElement());
46
+ }
47
+ condition.subscribe(value => {
48
+ const parent = positionKeeperEnd.parentNode;
49
+ if(value && parent) {
50
+ parent.insertBefore(getChildElement(), positionKeeperEnd);
51
+ } else {
52
+ if(Validator.isElement(childElement)){
53
+ childElement.remove();
54
+ }
55
+ }
56
+ });
57
+
58
+ return element;
59
+ }
60
+
61
+ /**
62
+ * Hide the element if the condition is true
63
+ * @param {ObservableItem|ObservableChecker} condition
64
+ * @param child
65
+ * @param comment
66
+ * @returns {DocumentFragment}
67
+ */
68
+ export const HideIf = function(condition, child, comment) {
69
+
70
+ const hideCondition = Observable(!condition.val());
71
+ condition.subscribe(value => hideCondition.set(!value));
72
+
73
+ return ShowIf(hideCondition, child, comment);
74
+ }
75
+
76
+ /**
77
+ * Hide the element if the condition is false
78
+ *
79
+ * @param {ObservableItem|ObservableChecker} condition
80
+ * @param {*} child
81
+ * @param {string|null} comment
82
+ * @returns {DocumentFragment}
83
+ */
84
+ export const HideIfNot = function(condition, child, comment) {
85
+ return ShowIf(condition, child, comment);
86
+ }
@@ -0,0 +1,88 @@
1
+ import NativeDocumentError from "../../errors/NativeDocumentError";
2
+ import {createTextNode} from "../../wrappers/HtmlElementWrapper";
3
+ import Validator from "../../utils/validator";
4
+
5
+ /**
6
+ *
7
+ * @param {ObservableItem|ObservableChecker} condition
8
+ * @param {*} onTrue
9
+ * @param {*} onFalse
10
+ * @returns {DocumentFragment}
11
+ */
12
+ export const Switch = function (condition, onTrue, onFalse) {
13
+
14
+ if(!Validator.isObservable(condition)) {
15
+ throw new NativeDocumentError("Toggle : condition must be an Observable");
16
+ }
17
+
18
+ const commentStart = document.createComment('Toggle Start');
19
+ const commentEnd = document.createComment('Toggle End');
20
+
21
+ const element = document.createDocumentFragment();
22
+ element.appendChild(commentStart);
23
+ element.appendChild(commentEnd);
24
+
25
+ const elements = {
26
+ onTrueNode: (Validator.isFunction(onTrue)) ? null : onTrue,
27
+ onFalseNode: (Validator.isFunction(onFalse)) ? null : onFalse,
28
+ };
29
+
30
+ if(Validator.isStringOrObservable(elements.onTrueNode)) {
31
+ elements.onTrueNode = createTextNode(elements.onTrueNode);
32
+ }
33
+ if(Validator.isStringOrObservable(elements.onFalseNode)) {
34
+ elements.onFalseNode = createTextNode(elements.onFalseNode);
35
+ }
36
+
37
+ const handle = (value) => {
38
+ const parent = commentEnd.parentNode;
39
+ if(!parent) {
40
+ return;
41
+ }
42
+ if(value) {
43
+ if(!elements.onTrueNode && Validator.isFunction(onTrue)) {
44
+ elements.onTrueNode = onTrue();
45
+ }
46
+ elements.onFalseNode && elements.onFalseNode.remove();
47
+ parent.insertBefore(elements.onTrueNode, commentEnd);
48
+ } else {
49
+ if(!elements.onFalseNode && Validator.isFunction(onFalse)) {
50
+ elements.onFalseNode = onFalse();
51
+ }
52
+ elements.onTrueNode && elements.onTrueNode.remove();
53
+ parent.insertBefore(elements.onFalseNode, commentEnd);
54
+ }
55
+ };
56
+
57
+ condition.subscribe(handle);
58
+ handle(condition.val());
59
+
60
+ return element;
61
+ }
62
+
63
+ /**
64
+ *
65
+ * @param condition
66
+ * @returns {{show: Function, otherwise: (((*) => {}):DocumentFragment)}
67
+ */
68
+ export const When = function(condition) {
69
+ let $onTrue = null;
70
+ let $onFalse = null;
71
+
72
+ return {
73
+ show(onTrue) {
74
+ if(!Validator.isElement(onTrue) && !Validator.isFunction(onTrue)) {
75
+ throw new NativeDocumentError("When : onTrue must be a valid Element");
76
+ }
77
+ $onTrue = onTrue;
78
+ return this;
79
+ },
80
+ otherwise(onFalse) {
81
+ if(!Validator.isElement(onFalse) && !Validator.isFunction(onFalse)) {
82
+ throw new NativeDocumentError("When : onFalse must be a valid Element");
83
+ }
84
+ $onFalse = onFalse;
85
+ return Switch(condition, $onTrue, $onFalse);
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,5 @@
1
+ import HtmlElementWrapper from "../wrappers/HtmlElementWrapper";
2
+
3
+ export const Dl = HtmlElementWrapper('dl');
4
+ export const Dt = HtmlElementWrapper('dt');
5
+ export const Dd = HtmlElementWrapper('dd');