@kizmann/pico-js 1.0.13 → 2.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 (125) hide show
  1. package/README.md +27 -7
  2. package/dist/pico-js.browser.js +2 -0
  3. package/dist/pico-js.browser.js.map +1 -0
  4. package/dist/pico-js.esm.js +2 -0
  5. package/dist/pico-js.esm.js.map +1 -0
  6. package/package.json +20 -7
  7. package/src/dom/DomAttribute.js +374 -0
  8. package/src/dom/DomBuilder.js +152 -0
  9. package/src/dom/DomEvent.js +253 -0
  10. package/src/dom/DomFinder.js +669 -0
  11. package/src/dom/DomForm.js +57 -0
  12. package/src/dom/DomGlobal.js +193 -0
  13. package/src/dom/DomInview.js +332 -0
  14. package/src/dom/DomMeta.js +66 -0
  15. package/src/dom/DomObserver.js +57 -0
  16. package/src/dom/DomRectangle.js +657 -0
  17. package/src/format/FormatFile.js +54 -0
  18. package/src/format/FormatOption.js +108 -0
  19. package/src/format/FormatParam.js +107 -0
  20. package/src/format/FormatParser.js +156 -0
  21. package/src/format/FormatUrl.js +75 -0
  22. package/src/index.browser.js +10 -0
  23. package/src/index.esm.js +138 -0
  24. package/src/now/NowDefault.js +533 -0
  25. package/src/now/NowFormat.js +196 -0
  26. package/src/now/NowGrid.js +251 -0
  27. package/src/now/NowHuman.js +118 -0
  28. package/src/now/NowMatch.js +175 -0
  29. package/src/now/NowRange.js +70 -0
  30. package/src/now/NowWalker.js +544 -0
  31. package/src/tool/scope.js +103 -0
  32. package/src/utils/Array.js +986 -0
  33. package/src/utils/Cookie.js +184 -0
  34. package/src/utils/Data.js +200 -0
  35. package/src/utils/Dom.js +208 -0
  36. package/src/utils/Event.js +140 -0
  37. package/src/utils/Format.js +62 -0
  38. package/src/utils/Hash.js +164 -0
  39. package/src/utils/Locale.js +229 -0
  40. package/src/utils/Mixed.js +887 -0
  41. package/src/utils/Now.js +234 -0
  42. package/src/utils/Number.js +238 -0
  43. package/src/utils/Object.js +655 -0
  44. package/src/utils/Route.js +67 -0
  45. package/src/utils/Runner.js +327 -0
  46. package/src/utils/String.js +618 -0
  47. package/src/{library/element.js → wip/Element.js} +90 -16
  48. package/src/{library/map.js → wip/Map.js} +256 -40
  49. package/types/dom/DomAttribute.d.ts +137 -0
  50. package/types/dom/DomBuilder.d.ts +67 -0
  51. package/types/dom/DomEvent.d.ts +103 -0
  52. package/types/dom/DomFinder.d.ts +321 -0
  53. package/types/dom/DomForm.d.ts +21 -0
  54. package/types/dom/DomGlobal.d.ts +79 -0
  55. package/types/dom/DomInview.d.ts +114 -0
  56. package/types/dom/DomMeta.d.ts +29 -0
  57. package/types/dom/DomObserver.d.ts +21 -0
  58. package/types/dom/DomRectangle.d.ts +270 -0
  59. package/types/format/FormatFile.d.ts +18 -0
  60. package/types/format/FormatOption.d.ts +40 -0
  61. package/types/format/FormatParam.d.ts +39 -0
  62. package/types/format/FormatParser.d.ts +46 -0
  63. package/types/format/FormatUrl.d.ts +17 -0
  64. package/types/index.browser.d.ts +1 -0
  65. package/types/index.esm.d.ts +52 -0
  66. package/types/now/NowDefault.d.ts +183 -0
  67. package/types/now/NowFormat.d.ts +70 -0
  68. package/types/now/NowGrid.d.ts +107 -0
  69. package/types/now/NowHuman.d.ts +37 -0
  70. package/types/now/NowMatch.d.ts +108 -0
  71. package/types/now/NowRange.d.ts +21 -0
  72. package/types/now/NowWalker.d.ts +301 -0
  73. package/types/tool/scope.d.ts +24 -0
  74. package/types/utils/Array.d.ts +480 -0
  75. package/types/utils/Cookie.d.ts +60 -0
  76. package/types/utils/Data.d.ts +91 -0
  77. package/types/utils/Dom.d.ts +138 -0
  78. package/types/utils/Event.d.ts +58 -0
  79. package/types/utils/Format.d.ts +37 -0
  80. package/types/utils/Hash.d.ts +81 -0
  81. package/types/utils/Locale.d.ts +115 -0
  82. package/types/utils/Mixed.d.ts +469 -0
  83. package/types/utils/Now.d.ts +125 -0
  84. package/types/utils/Number.d.ts +127 -0
  85. package/types/utils/Object.d.ts +255 -0
  86. package/types/utils/Route.d.ts +37 -0
  87. package/types/utils/Runner.d.ts +139 -0
  88. package/types/utils/String.d.ts +330 -0
  89. package/types/wip/Element.d.ts +119 -0
  90. package/types/wip/Map.d.ts +254 -0
  91. package/dist/.ignore.js +0 -0
  92. package/dist/pico-js.js +0 -2
  93. package/dist/pico-js.js.map +0 -1
  94. package/src/element/default.js +0 -46
  95. package/src/element/example.js +0 -58
  96. package/src/index.js +0 -90
  97. package/src/library/cookie.js +0 -123
  98. package/src/library/data.js +0 -111
  99. package/src/library/event.js +0 -91
  100. package/src/library/locale.js +0 -84
  101. package/src/library/queue.js +0 -64
  102. package/src/library/route.js +0 -28
  103. package/src/utility/any.js +0 -369
  104. package/src/utility/array.js +0 -410
  105. package/src/utility/dom.js +0 -1425
  106. package/src/utility/now.js +0 -544
  107. package/src/utility/number.js +0 -128
  108. package/src/utility/object.js +0 -429
  109. package/src/utility/string.js +0 -328
  110. package/types/index.d.ts +0 -77
  111. package/types/library/cookie.d.ts +0 -10
  112. package/types/library/data.d.ts +0 -15
  113. package/types/library/element.d.ts +0 -22
  114. package/types/library/event.d.ts +0 -13
  115. package/types/library/locale.d.ts +0 -14
  116. package/types/library/map.d.ts +0 -43
  117. package/types/library/queue.d.ts +0 -18
  118. package/types/library/route.d.ts +0 -11
  119. package/types/utility/any.d.ts +0 -35
  120. package/types/utility/array.d.ts +0 -46
  121. package/types/utility/dom.d.ts +0 -101
  122. package/types/utility/now.d.ts +0 -79
  123. package/types/utility/number.d.ts +0 -17
  124. package/types/utility/object.d.ts +0 -29
  125. package/types/utility/string.d.ts +0 -26
@@ -0,0 +1,184 @@
1
+ import { For, Arr, Now, Mix } from "#src/index.esm.js";
2
+
3
+ export const COOKIE_REGEX = {
4
+ entry: /(?<=^|;)\s*(?<key>.*?)\s*=\s*(?<value>[^;$]+)/g
5
+ };
6
+
7
+ export class PicoCookie
8
+ {
9
+ static $cookie = null;
10
+
11
+ /**
12
+ * Read raw document.cookie
13
+ *
14
+ * @example Cookie.global() // => "a=b; c=d"
15
+ *
16
+ * @returns {string} Cookie string
17
+ */
18
+ static global()
19
+ {
20
+ if ( globalThis.document == null ) {
21
+ return '';
22
+ }
23
+
24
+ return globalThis.document.cookie || '';
25
+ }
26
+
27
+ /**
28
+ * Parse cookies into object
29
+ *
30
+ * @example Cookie.parse() // => {a:"b"}
31
+ * @example Cookie.parse(true) // force parse
32
+ *
33
+ * @param {boolean} [fresh] Force refresh
34
+ * @returns {Record<string, any>} Cookie map
35
+ */
36
+ static parse(fresh = false)
37
+ {
38
+ if ( !fresh && this.$cookie ) {
39
+ return this.$cookie;
40
+ }
41
+
42
+ this.$cookie = {};
43
+
44
+ let matches = this.global().matchAll(...[
45
+ COOKIE_REGEX.entry
46
+ ]);
47
+
48
+ if ( matches == null ) {
49
+ return this.$cookie;
50
+ }
51
+
52
+ let fn = (value) => {
53
+ return value.replaceAll('{:}', ';');
54
+ }
55
+
56
+ Arr.each(Array.from(matches), ({ groups }) => {
57
+ this.$cookie[groups.key] = fn(groups.value);
58
+ });
59
+
60
+ return this.$cookie;
61
+ }
62
+
63
+ /**
64
+ * Get cookie value by key
65
+ *
66
+ * @example Cookie.get("foo") // => "bar"
67
+ * @example Cookie.get("x", null, "bool") // => true
68
+ *
69
+ * @param {string} key Cookie key
70
+ * @param {any} [fallback] Fallback value
71
+ * @param {string} [decode] Decode mode
72
+ * @returns {any} Cookie value
73
+ */
74
+ static get(key, fallback = null, decode = 'string')
75
+ {
76
+ if ( !this.$cookie ) {
77
+ this.parse();
78
+ }
79
+
80
+ if ( this.$cookie[key] == null ) {
81
+ return fallback;
82
+ }
83
+
84
+ if ( /^bool(ean)?$/.test(decode) ) {
85
+ return Mix.bool(this.$cookie[key]);
86
+ }
87
+
88
+ if ( /^num(ber)?$/.test(decode) ) {
89
+ return Mix.bool(this.$cookie[key]);
90
+ }
91
+
92
+ if ( /^int(eger)?$/.test(decode) ) {
93
+ return Mix.bool(this.$cookie[key]);
94
+ }
95
+
96
+ if ( /^obj(ext)?$/.test(decode) ) {
97
+ return For.parseOptions(this.$cookie[key]);
98
+ }
99
+
100
+ return Mix.str(this.$cookie[key]);
101
+ }
102
+
103
+ /**
104
+ * Set cookie value with options
105
+ *
106
+ * @example Cookie.set("a", "b") // => Cookie
107
+ * @example Cookie.set("a", {x:1}) // => Cookie
108
+ *
109
+ * @param {string} key Cookie key
110
+ * @param {any} value Cookie value
111
+ * @param {any} [expire] Expire date spec
112
+ * @param {any} [options] Cookie options
113
+ * @returns {typeof PicoCookie} Cookie class
114
+ */
115
+ static set(key, value, expire = null, options = {})
116
+ {
117
+ if ( !this.$cookie ) {
118
+ this.parse();
119
+ }
120
+
121
+ if ( !(expire instanceof Now) ) {
122
+ expire = Now.make(expire || '+7 days');
123
+ }
124
+
125
+ options = {
126
+ expires: expire.toUTC(), path: '/', ...options
127
+ };
128
+
129
+ if ( Mix.isRef(value) ) {
130
+ value = For.castOptions(value, false);
131
+ }
132
+
133
+ if ( value != null ) {
134
+ this.$cookie[key] = value;
135
+ }
136
+
137
+ let plain = key + '=' + value.replaceAll(...[
138
+ ';', '{:}'
139
+ ]);
140
+
141
+ Arr.each(options, (value, key) => {
142
+ plain += `;${key}=${value}`;
143
+ });
144
+
145
+ globalThis.document.cookie = plain;
146
+
147
+ return this;
148
+ }
149
+
150
+ /**
151
+ * Remove cookie by key
152
+ *
153
+ * @example Cookie.forget("a") // => Cookie
154
+ *
155
+ * @param {string} key Cookie key
156
+ * @param {any} [options] Cookie options
157
+ * @returns {typeof PicoCookie} Cookie class
158
+ */
159
+ static forget(key, options = {})
160
+ {
161
+ let expires = 'Thu, 01 Jan 1970 00:00:01 GMT';
162
+
163
+ options = {
164
+ expires, path: '/', ...options
165
+ };
166
+
167
+ if ( this.$cookie[key] ) {
168
+ delete this.$cookie[key];
169
+ }
170
+
171
+ let plain = `${key}=null`;
172
+
173
+ Arr.each(options, (value, key) => {
174
+ plain += `;${key}=${value}`;
175
+ });
176
+
177
+ globalThis.document.cookie = plain;
178
+
179
+ return this;
180
+ }
181
+
182
+ }
183
+
184
+ export default PicoCookie;
@@ -0,0 +1,200 @@
1
+ import { Arr, Num, Event, Mix, Obj } from "#src/index.esm.js";
2
+
3
+ export class PicoData
4
+ {
5
+ /**
6
+ * In-memory data store
7
+ *
8
+ * @type {Record<string, any>}
9
+ */
10
+ static $data = {};
11
+
12
+ /**
13
+ * Check if store key exists
14
+ *
15
+ * @example Data.has(["x"]) // => true|false
16
+ *
17
+ * @param {any} input Store key input
18
+ * @returns {boolean} True if exists
19
+ */
20
+ static has(input)
21
+ {
22
+ return Obj.has(this.$data, ...[
23
+ Arr.first(input)
24
+ ]);
25
+ }
26
+
27
+ /**
28
+ * Set store key and fire event
29
+ *
30
+ * @example Data.set(["x"], 1)
31
+ * @example Data.set(["x"], {a:1})
32
+ *
33
+ * @param {any} input Store key input
34
+ * @param {any} value Value to set
35
+ * @returns {void} No return value
36
+ */
37
+ static set(input, value)
38
+ {
39
+ let [stored, key] = [
40
+ null, Arr.first(input)
41
+ ];
42
+
43
+ if ( Obj.has(this.$data, key) ) {
44
+ stored = Obj.get(this.$data, key);
45
+ }
46
+
47
+ if ( Mix.isEqual(stored, value) ) {
48
+ return;
49
+ }
50
+
51
+ Obj.set(...[
52
+ this.$data, key, value
53
+ ]);
54
+
55
+ Event.fire('store:' + key, value, key);
56
+ }
57
+
58
+ /**
59
+ * Remove store key
60
+ *
61
+ * @example Data.unset(["x"])
62
+ *
63
+ * @param {any} input Store key input
64
+ * @returns {void} No return value
65
+ */
66
+ static unset(input)
67
+ {
68
+ Obj.unset(this.$data, [
69
+ ...Arr.first(input)
70
+ ]);
71
+ }
72
+
73
+ /**
74
+ * Get stored value (cloned)
75
+ *
76
+ * @example Data.get(["x"], null) // => value
77
+ * @example Data.get(["x"], 1, true) // set+get
78
+ *
79
+ * @param {any} input Store key input
80
+ * @param {any} [fallback] Fallback value
81
+ * @param {boolean} [forceSet] Set if missing
82
+ * @returns {any} Stored value
83
+ */
84
+ static get(input, fallback = null, forceSet = false)
85
+ {
86
+ let key = Arr.first(input);
87
+
88
+ if ( !Obj.has(this.$data, key) && !forceSet ) {
89
+ return fallback;
90
+ }
91
+
92
+ if ( Obj.has(this.$data, key) && forceSet ) {
93
+ Obj.set(this.$data, key, fallback);
94
+ }
95
+
96
+ let value = Obj.get(this.$data, key, fallback);
97
+
98
+ if ( !Mix.isObj(value) ) {
99
+ return value;
100
+ }
101
+
102
+ return Obj.clone(value);
103
+ }
104
+
105
+ /**
106
+ * Find item by id in array store
107
+ *
108
+ * @example Data.find(["list"], {id:1})
109
+ *
110
+ * @param {any} input Store key input
111
+ * @param {any} value Search value
112
+ * @param {any} [fallback] Fallback value
113
+ * @returns {any} Found item
114
+ */
115
+ static find(input, value, fallback = null)
116
+ {
117
+ let key = Arr.first(input);
118
+
119
+ if ( Obj.has(this.$data, key) === false ) {
120
+ return fallback;
121
+ }
122
+
123
+ if ( Obj.has(value, 'id') === false ) {
124
+ return fallback;
125
+ }
126
+
127
+ let index = Arr.findIndex(this.get(key), {
128
+ id: value.id
129
+ });
130
+
131
+ if ( index === - 1 ) {
132
+ return fallback;
133
+ }
134
+
135
+ return this.get(key + '.' + index);
136
+ }
137
+
138
+ /**
139
+ * Replace item by id in array store
140
+ *
141
+ * @example Data.replace(["list"], {id:1})
142
+ *
143
+ * @param {any} input Store key input
144
+ * @param {any} value Item to replace
145
+ * @returns {void} No return value
146
+ */
147
+ static replace(input, value)
148
+ {
149
+ let key = Arr.first(input);
150
+
151
+ if ( Obj.has(this.$data, key) === false ) {
152
+ return;
153
+ }
154
+
155
+ if ( Obj.has(value, 'id') === false ) {
156
+ return;
157
+ }
158
+
159
+ let index = Arr.findIndex(this.get(key), {
160
+ id: Num.int(value.id)
161
+ });
162
+
163
+ if ( index === - 1 ) {
164
+ return;
165
+ }
166
+
167
+ this.set(key + '.' + index, value);
168
+ }
169
+
170
+ /**
171
+ * Add items to array store
172
+ *
173
+ * @example Data.add(["list"], 1, 2)
174
+ *
175
+ * @param {any} input Store key input
176
+ * @param {...any} args Items to add
177
+ * @returns {void} No return value
178
+ */
179
+ static add(input, ...args)
180
+ {
181
+ this.set(input, Arr.concat(this.get(input, []), args));
182
+ }
183
+
184
+ /**
185
+ * Remove items from array store
186
+ *
187
+ * @example Data.remove(["list"], 1)
188
+ *
189
+ * @param {any} input Store key input
190
+ * @param {...any} args Items to remove
191
+ * @returns {void} No return value
192
+ */
193
+ static remove(input, ...args)
194
+ {
195
+ this.set(input, Arr.diff(this.get(input, []), args));
196
+ }
197
+
198
+ }
199
+
200
+ export default PicoData;
@@ -0,0 +1,208 @@
1
+ import { Arr, Mix, Dom } from "#src/index.esm.js";
2
+ import { PicoDomFinderPlugin } from "#src/dom/DomFinder.js";
3
+ import { PicoDomFormPlugin } from "#src/dom/DomForm.js";
4
+ import { PicoDomEventPlugin } from "#src/dom/DomEvent.js";
5
+ import { PicoDomBuilderPlugin } from "#src/dom/DomBuilder.js";
6
+ import { PicoDomGlobalPlugin } from "#src/dom/DomGlobal.js";
7
+ import { PicoDomRectanglePlugin } from "#src/dom/DomRectangle.js";
8
+ import { PicoDomAttributePlugin } from "#src/dom/DomAttribute.js";
9
+ import { PicoDomInviewPlugin } from "#src/dom/DomInview.js";
10
+ import { PicoDomMetaPlugin } from "#src/dom/DomMeta.js";
11
+ import { PicoDomObserverPlugin } from "#src/dom/DomObserver.js";
12
+
13
+ export const PicoDomPlugins = [
14
+ PicoDomFinderPlugin,
15
+ PicoDomGlobalPlugin,
16
+ PicoDomFormPlugin,
17
+ PicoDomEventPlugin,
18
+ PicoDomBuilderPlugin,
19
+ PicoDomRectanglePlugin,
20
+ PicoDomAttributePlugin,
21
+ PicoDomInviewPlugin,
22
+ PicoDomMetaPlugin,
23
+ PicoDomObserverPlugin,
24
+ ];
25
+
26
+ /**
27
+ * @class PicoDom
28
+ *
29
+ * @typedef {import('#src/dom/DomFinder.js').PicoDomFinderInstance} PicoDomFinderInstance
30
+ * @typedef {import('#src/dom/DomGlobal.js').PicoDomGlobalStatic} PicoDomGlobalStatic
31
+ * @typedef {import('#src/dom/DomGlobal.js').PicoDomGlobalInstance} PicoDomGlobalInstance
32
+ * @typedef {import('#src/dom/DomEvent.js').PicoDomEventStatic} PicoDomEventStatic
33
+ * @typedef {import('#src/dom/DomEvent.js').PicoDomEventInstance} PicoDomEventInstance
34
+ * @typedef {import('#src/dom/DomBuilder.js').PicoDomBuilderStatic} PicoDomBuilderStatic
35
+ * @typedef {import('#src/dom/DomBuilder.js').PicoDomBuilderInstance} PicoDomBuilderInstance
36
+ * @typedef {import('#src/dom/DomRectangle.js').PicoDomRectangleStatic} PicoDomRectangleStatic
37
+ * @typedef {import('#src/dom/DomRectangle.js').PicoDomRectangleInstance} PicoDomRectangleInstance
38
+ * @typedef {import('#src/dom/DomAttribute.js').PicoDomAttributeStatic} PicoDomAttributeStatic
39
+ * @typedef {import('#src/dom/DomAttribute.js').PicoDomAttributeInstance} PicoDomAttributeInstance
40
+ * @typedef {import('#src/dom/DomInview.js').PicoDomInviewStatic} PicoDomInviewStatic
41
+ * @typedef {import('#src/dom/DomInview.js').PicoDomInviewInstance} PicoDomInviewInstance
42
+ * @typedef {import('#src/dom/DomMeta.js').PicoDomMetaStatic} PicoDomMetaStatic
43
+ * @typedef {import('#src/dom/DomMeta.js').PicoDomMetaInstance} PicoDomMetaInstance
44
+ * @typedef {import('#src/dom/DomObserver.js').PicoDomObserverStatic} PicoDomObserverStatic
45
+ * @typedef {import('#src/dom/DomObserver.js').PicoDomObserverInstance} PicoDomObserverInstance
46
+ *
47
+ * @mixes PicoDomFinderStatic
48
+ * @mixes PicoDomGlobalStatic
49
+ * @mixes PicoDomFormStatic
50
+ * @mixes PicoDomEventStatic
51
+ * @mixes PicoDomBuilderStatic
52
+ * @mixes PicoDomRectangleStatic
53
+ * @mixes PicoDomAttributeStatic
54
+ * @mixes PicoDomInviewStatic
55
+ * @mixes PicoDomMetaStatic
56
+ * @mixes PicoDomObserverStatic
57
+ *
58
+ * @extends PicoDomFinderInstance
59
+ * @extends PicoDomGlobalInstance
60
+ * @extends PicoDomFormInstance
61
+ * @extends PicoDomEventInstance
62
+ * @extends PicoDomBuilderInstance
63
+ * @extends PicoDomRectangleInstance
64
+ * @extends PicoDomAttributeInstance
65
+ * @extends PicoDomInviewInstance
66
+ * @extends PicoDomMetaInstance
67
+ * @extends PicoDomObserverInstance
68
+ */
69
+ export class PicoDom {
70
+
71
+ /**
72
+ * Init hooks for constructor
73
+ *
74
+ * @type {Array<function>}
75
+ */
76
+ static init = [];
77
+
78
+ /**
79
+ * First selected element
80
+ *
81
+ * @type {HTMLElement}
82
+ */
83
+ el = null;
84
+
85
+ /**
86
+ * All selected elements
87
+ *
88
+ * @type {Array<HTMLElement>}
89
+ */
90
+ els = [];
91
+
92
+ /**
93
+ * Create Dom wrapper from input
94
+ *
95
+ * @example new Dom("body").get(0) // => HTMLElement
96
+ *
97
+ * @param {any} el Element or selector
98
+ * @param {...any} args Plugin args
99
+ */
100
+ constructor(el, ...args)
101
+ {
102
+ Arr.each(Dom.init, (fn) => {
103
+ el = fn.call(this, el, ...args);
104
+ });
105
+
106
+ if ( el instanceof Dom ) {
107
+ el = el.el;
108
+ }
109
+
110
+ if ( ! Mix.isArr(el) ) {
111
+ el = [el];
112
+ }
113
+
114
+ (this.el = el[0], this.els = el);
115
+ }
116
+
117
+ /**
118
+ * Create new Dom wrapper
119
+ *
120
+ * @example Dom.find("body") // => Dom
121
+ *
122
+ * @param {any} el Element or selector
123
+ * @param {...any} args Plugin args
124
+ * @returns {PicoDom} Dom wrapper
125
+ */
126
+ static find(el, ...args)
127
+ {
128
+ return new Dom(el, ...args);
129
+ }
130
+
131
+ /**
132
+ * Extend Dom with a plugin
133
+ *
134
+ * @example Dom.extend(fn)
135
+ *
136
+ * @param {function} plugin Plugin function
137
+ * @returns {void} No return value
138
+ */
139
+ static extend(plugin)
140
+ {
141
+ plugin.call({}, this);
142
+ }
143
+
144
+ /**
145
+ * Get window or empty object
146
+ *
147
+ * @example Dom.win().innerWidth // => number|undefined
148
+ *
149
+ * @returns {any} Window or {}
150
+ */
151
+ static win()
152
+ {
153
+ if ( globalThis.window == null ) {
154
+ return {};
155
+ }
156
+
157
+ return window;
158
+ }
159
+
160
+ /**
161
+ * Get document or empty object
162
+ *
163
+ * @example Dom.doc().body // => HTMLElement|undefined
164
+ *
165
+ * @returns {any} Document or {}
166
+ */
167
+ static doc()
168
+ {
169
+ if ( globalThis.document == null ) {
170
+ return {};
171
+ }
172
+
173
+ return document;
174
+ }
175
+
176
+ /**
177
+ * Get document.body or empty
178
+ *
179
+ * @example Dom.body().nodeType // => 1|undefined
180
+ *
181
+ * @returns {any} Body or {}
182
+ */
183
+ static body()
184
+ {
185
+ if ( ! this.doc().body ) {
186
+ return {};
187
+ }
188
+
189
+ return this.doc().body;
190
+ }
191
+
192
+ }
193
+
194
+ /**
195
+ * @returns {typeof PicoDom}
196
+ */
197
+ export function PicoDomBuilder() {
198
+
199
+ let cls = PicoDom;
200
+
201
+ for ( const plugin of PicoDomPlugins ) {
202
+ cls = plugin.call(cls, cls);
203
+ }
204
+
205
+ return cls;
206
+ }
207
+
208
+ export default PicoDomBuilder;