aptechka 0.1.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.
- package/.prettierignore +16 -0
- package/.prettierrc +9 -0
- package/.vscode/extensions.json +4 -0
- package/.vscode/launch.json +11 -0
- package/.vscode/settings.json +18 -0
- package/README.md +0 -0
- package/index.html +32 -0
- package/package.json +272 -0
- package/public/vite.svg +1 -0
- package/src/packages/animation/Animated.ts +189 -0
- package/src/packages/animation/Damped.ts +39 -0
- package/src/packages/animation/Tweened.ts +51 -0
- package/src/packages/animation/index.ts +10 -0
- package/src/packages/attribute/index.ts +59 -0
- package/src/packages/canvas-2d/index.ts +137 -0
- package/src/packages/controls/Controls.ts +15 -0
- package/src/packages/controls/KeyboardControls.ts +63 -0
- package/src/packages/controls/LinearControls.ts +27 -0
- package/src/packages/controls/User.ts +20 -0
- package/src/packages/controls/WheelControls.ts +92 -0
- package/src/packages/controls/index.ts +5 -0
- package/src/packages/css-unit-parser/index.ts +32 -0
- package/src/packages/custom-element/index.ts +19 -0
- package/src/packages/device/Device.ts +113 -0
- package/src/packages/device/Viewport.ts +67 -0
- package/src/packages/device/index.ts +2 -0
- package/src/packages/element-constructor/ElementConstructor.ts +577 -0
- package/src/packages/element-constructor/htmlTags.ts +679 -0
- package/src/packages/element-constructor/index.ts +4 -0
- package/src/packages/element-constructor/specialObjects.ts +8 -0
- package/src/packages/element-constructor/svgTags.ts +588 -0
- package/src/packages/en3/attachments/En3SourceManager.ts +116 -0
- package/src/packages/en3/core/en3.ts +306 -0
- package/src/packages/en3/index.ts +52 -0
- package/src/packages/en3/instances/en3LazyLoader.ts +22 -0
- package/src/packages/en3/libs/MeshoptDecoder.js +138 -0
- package/src/packages/en3/loaders/en3GLTFLoader.ts +54 -0
- package/src/packages/en3/loaders/en3TextureLoader.ts +3 -0
- package/src/packages/en3/objects/En3Clip.ts +53 -0
- package/src/packages/en3/objects/En3ClipHelpers.ts +12 -0
- package/src/packages/en3/objects/En3GLTF.ts +35 -0
- package/src/packages/en3/objects/En3Image.ts +18 -0
- package/src/packages/en3/objects/En3ImageLike.ts +101 -0
- package/src/packages/en3/objects/En3SourceConsumer.ts +5 -0
- package/src/packages/en3/objects/En3Video.ts +88 -0
- package/src/packages/en3/test/En3HTML.ts +55 -0
- package/src/packages/en3/test/En3ModifiedMaterial.ts +221 -0
- package/src/packages/en3/test/En3Raycaster.ts +187 -0
- package/src/packages/en3/utils/coverTexture.ts +29 -0
- package/src/packages/en3/utils/dispose.ts +27 -0
- package/src/packages/en3/utils/traverseMaterials.ts +10 -0
- package/src/packages/en3/utils/traverseMeshes.ts +9 -0
- package/src/packages/image/index.ts +19 -0
- package/src/packages/intersector/index.ts +83 -0
- package/src/packages/ladder/index.ts +112 -0
- package/src/packages/layout-box/index.ts +417 -0
- package/src/packages/loading/index.ts +131 -0
- package/src/packages/measurer/CumulativeOffsetLeft.ts +8 -0
- package/src/packages/measurer/CumulativeOffsetTop.ts +8 -0
- package/src/packages/measurer/Meaurer.ts +38 -0
- package/src/packages/measurer/index.ts +3 -0
- package/src/packages/media/index.ts +38 -0
- package/src/packages/morph/Link.ts +32 -0
- package/src/packages/morph/Morph.ts +246 -0
- package/src/packages/morph/index.ts +10 -0
- package/src/packages/notifier/index.ts +41 -0
- package/src/packages/order/index.ts +14 -0
- package/src/packages/resizer/index.ts +55 -0
- package/src/packages/router/Link.ts +33 -0
- package/src/packages/router/Route.ts +152 -0
- package/src/packages/router/RouteElement.ts +34 -0
- package/src/packages/router/Router.ts +190 -0
- package/src/packages/router/index.ts +13 -0
- package/src/packages/scroll/ScrollElement.ts +618 -0
- package/src/packages/scroll/ScrollUserElement.ts +21 -0
- package/src/packages/scroll/ScrollbarElement.ts +170 -0
- package/src/packages/scroll/index.ts +2 -0
- package/src/packages/scroll-entries/index.ts +74 -0
- package/src/packages/source/SourceClass.ts +77 -0
- package/src/packages/source/SourceElement.ts +177 -0
- package/src/packages/source/SourceManager.ts +61 -0
- package/src/packages/source/SourceSet.ts +52 -0
- package/src/packages/source/index.ts +8 -0
- package/src/packages/store/Composed.ts +33 -0
- package/src/packages/store/Derived.ts +24 -0
- package/src/packages/store/DerivedArray.ts +36 -0
- package/src/packages/store/Resource.ts +38 -0
- package/src/packages/store/Store.ts +144 -0
- package/src/packages/store/StoreRegistry.ts +105 -0
- package/src/packages/store/index.ts +23 -0
- package/src/packages/ticker/index.ts +173 -0
- package/src/packages/utils/array.ts +3 -0
- package/src/packages/utils/attributes.ts +19 -0
- package/src/packages/utils/browser.ts +2 -0
- package/src/packages/utils/canvas.ts +46 -0
- package/src/packages/utils/collisions.ts +12 -0
- package/src/packages/utils/coordinates.ts +40 -0
- package/src/packages/utils/decoding.ts +11 -0
- package/src/packages/utils/dev.ts +5 -0
- package/src/packages/utils/dom.ts +48 -0
- package/src/packages/utils/easings.ts +69 -0
- package/src/packages/utils/file.ts +17 -0
- package/src/packages/utils/function.ts +29 -0
- package/src/packages/utils/index.ts +61 -0
- package/src/packages/utils/layout.ts +22 -0
- package/src/packages/utils/math.ts +74 -0
- package/src/packages/utils/number.ts +26 -0
- package/src/packages/utils/object.ts +108 -0
- package/src/packages/utils/string.ts +49 -0
- package/src/packages/utils/ts-shape.ts +25 -0
- package/src/packages/utils/ts-utility.ts +47 -0
- package/src/packages/video/index.ts +39 -0
- package/src/playground/index.ts +0 -0
- package/tsconfig.json +31 -0
- package/vite.config.ts +65 -0
|
@@ -0,0 +1,577 @@
|
|
|
1
|
+
import { Store } from '$packages/store'
|
|
2
|
+
import { isBrowser, camelToKebab } from '$packages/utils'
|
|
3
|
+
|
|
4
|
+
export type ElementConstructorTagNameMap = HTMLElementTagNameMap & SVGElementTagNameMap
|
|
5
|
+
|
|
6
|
+
export type ElementConstructorTagNames = keyof ElementConstructorTagNameMap
|
|
7
|
+
|
|
8
|
+
export type ElementConstructorStringStoreClass = Store<string | null | undefined> | Store<string>
|
|
9
|
+
|
|
10
|
+
export type ElementConstructorStringArrayStoreClass =
|
|
11
|
+
| Store<Array<string | null | undefined>>
|
|
12
|
+
| Store<Array<string>>
|
|
13
|
+
|
|
14
|
+
export type ElementConstructorClass =
|
|
15
|
+
| string
|
|
16
|
+
| Array<string | ElementConstructorStringStoreClass | ElementConstructorStringArrayStoreClass>
|
|
17
|
+
| ElementConstructorStringStoreClass
|
|
18
|
+
| ElementConstructorStringArrayStoreClass
|
|
19
|
+
| { [key: string]: boolean | Store<boolean> }
|
|
20
|
+
|
|
21
|
+
export type ElementConstructorStyleToken = Exclude<
|
|
22
|
+
Extract<keyof CSSStyleDeclaration, string> | `--${string}`,
|
|
23
|
+
'length' | 'parentRule'
|
|
24
|
+
>
|
|
25
|
+
|
|
26
|
+
export type ElementConstructorStyleValue = string | Store<string | null | undefined> | Store<string>
|
|
27
|
+
|
|
28
|
+
export type ElementConstructorStyle = Partial<{
|
|
29
|
+
[K in ElementConstructorStyleToken]: ElementConstructorStyleValue
|
|
30
|
+
}>
|
|
31
|
+
|
|
32
|
+
export type ElementConstructorJSSWrapper = {
|
|
33
|
+
[key: string]: object | ElementConstructorStyle
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type ElementConstructorJSS =
|
|
37
|
+
| ElementConstructorStyle
|
|
38
|
+
| {
|
|
39
|
+
[key: string]: ElementConstructorJSSWrapper | ElementConstructorStyle
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type ElementConstructorEventMap = HTMLElementEventMap & SVGElementEventMap
|
|
43
|
+
|
|
44
|
+
export type ElementConstructorEventNames = keyof ElementConstructorEventMap
|
|
45
|
+
|
|
46
|
+
export type ElementConstructorEventValue<E extends Event> =
|
|
47
|
+
| {
|
|
48
|
+
callback: (event: E) => void
|
|
49
|
+
options?: AddEventListenerOptions
|
|
50
|
+
}
|
|
51
|
+
| ((event: E) => void)
|
|
52
|
+
|
|
53
|
+
export type ElementConstructorEvents = Partial<{
|
|
54
|
+
[EventName in
|
|
55
|
+
| ElementConstructorEventNames
|
|
56
|
+
| `custom:${string}`]: EventName extends ElementConstructorEventNames
|
|
57
|
+
? ElementConstructorEventValue<HTMLElementEventMap[EventName]>
|
|
58
|
+
: ElementConstructorEventValue<CustomEvent>
|
|
59
|
+
}>
|
|
60
|
+
|
|
61
|
+
export type ElementConstructorNativeAttribute<
|
|
62
|
+
TagName extends ElementConstructorTagNames,
|
|
63
|
+
E = ElementConstructorTagNameMap[TagName]
|
|
64
|
+
> = {
|
|
65
|
+
[K in keyof E]: E[K] extends string ? K : never
|
|
66
|
+
}[keyof E]
|
|
67
|
+
|
|
68
|
+
type ElementConstructorAttributeValue =
|
|
69
|
+
| string
|
|
70
|
+
| undefined
|
|
71
|
+
| null
|
|
72
|
+
| boolean
|
|
73
|
+
| number
|
|
74
|
+
| Store<string>
|
|
75
|
+
| Store<string | undefined | null>
|
|
76
|
+
| Store<boolean>
|
|
77
|
+
| Store<boolean | undefined | null>
|
|
78
|
+
| Store<number>
|
|
79
|
+
| Store<number | undefined | null>
|
|
80
|
+
|
|
81
|
+
export type ElementConstructorNativeAttributes<T extends ElementConstructorTagNames> = Partial<{
|
|
82
|
+
[K in ElementConstructorNativeAttribute<T>]: ElementConstructorAttributeValue
|
|
83
|
+
}>
|
|
84
|
+
|
|
85
|
+
export type ElementConstructorCustomAttributes = {
|
|
86
|
+
[key: string]: ElementConstructorAttributeValue
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export type ElementConstructorAttributes<T extends ElementConstructorTagNames> =
|
|
90
|
+
| ElementConstructorNativeAttributes<T>
|
|
91
|
+
| ElementConstructorCustomAttributes
|
|
92
|
+
|
|
93
|
+
export type ElementConstructorPrimitiveChild = string | number | boolean | null | undefined
|
|
94
|
+
|
|
95
|
+
export type ElementConstructorSimpleChild =
|
|
96
|
+
| ElementConstructorPrimitiveChild
|
|
97
|
+
| ElementConstructor
|
|
98
|
+
| Node
|
|
99
|
+
| Array<ElementConstructorPrimitiveChild>
|
|
100
|
+
| Array<ElementConstructor>
|
|
101
|
+
| Array<Node>
|
|
102
|
+
|
|
103
|
+
export type ElementConstructorStoreChild = Store<any>
|
|
104
|
+
export type ElementConstructorStoreChildren = Store<Array<any>>
|
|
105
|
+
|
|
106
|
+
export type ElementConstructorChildren = Array<
|
|
107
|
+
ElementConstructorSimpleChild | ElementConstructorStoreChild | ElementConstructorStoreChildren
|
|
108
|
+
>
|
|
109
|
+
|
|
110
|
+
export type ElementConstructorParent = Node | ElementConstructor
|
|
111
|
+
|
|
112
|
+
export type ElementConstructorCreatedCallback<TagName extends ElementConstructorTagNames> = (
|
|
113
|
+
element: ElementConstructorTagNameMap[TagName]
|
|
114
|
+
) => void
|
|
115
|
+
|
|
116
|
+
export type ElementConstructorTagObject<TagName extends ElementConstructorTagNames> = {
|
|
117
|
+
class?: ElementConstructorClass
|
|
118
|
+
style?: TagName extends 'style' ? ElementConstructorJSS : ElementConstructorStyle
|
|
119
|
+
events?: ElementConstructorEvents
|
|
120
|
+
attributes?: ElementConstructorAttributes<TagName>
|
|
121
|
+
children?: ElementConstructorChildren
|
|
122
|
+
shadowChildren?: ElementConstructorChildren
|
|
123
|
+
parent?: ElementConstructorParent
|
|
124
|
+
svg?: boolean
|
|
125
|
+
created?: ElementConstructorCreatedCallback<TagName>
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export type ElementConstructorObject =
|
|
129
|
+
| Partial<{
|
|
130
|
+
[T in ElementConstructorTagNames]: ElementConstructorTagObject<T>
|
|
131
|
+
}>
|
|
132
|
+
| {
|
|
133
|
+
[key: `${string}-${string}`]: ElementConstructorTagObject<'div'>
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export type ElementConstructorType = HTMLElement | SVGElement
|
|
137
|
+
|
|
138
|
+
export class ElementConstructor<T extends ElementConstructorTagNames = ElementConstructorTagNames> {
|
|
139
|
+
#rootElements: Array<ElementConstructorType> = []
|
|
140
|
+
|
|
141
|
+
constructor(object: ElementConstructorObject)
|
|
142
|
+
constructor(value: string, object: ElementConstructorTagObject<T>)
|
|
143
|
+
constructor(element: HTMLElement, object: ElementConstructorTagObject<T>)
|
|
144
|
+
constructor(...args: any[]) {
|
|
145
|
+
const p1 = args[0]
|
|
146
|
+
const p2 = args[1]
|
|
147
|
+
|
|
148
|
+
if (isBrowser) {
|
|
149
|
+
if (typeof p1 === 'string') {
|
|
150
|
+
const wrapper = document.createElement('div')
|
|
151
|
+
wrapper.innerHTML = p1
|
|
152
|
+
const element = wrapper.firstElementChild as HTMLElement
|
|
153
|
+
this.#rootElements = [element]
|
|
154
|
+
this.#applyProperties(element, p2)
|
|
155
|
+
} else if (p1 instanceof HTMLElement) {
|
|
156
|
+
this.#rootElements = [p1]
|
|
157
|
+
this.#applyProperties(p1, p2)
|
|
158
|
+
} else {
|
|
159
|
+
this.#rootElements = this.#createElements(p1)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public get rootElements() {
|
|
165
|
+
return this.#rootElements
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#createElements(object: ElementConstructorObject) {
|
|
169
|
+
const elements: Array<ElementConstructorType> = []
|
|
170
|
+
|
|
171
|
+
for (const k in object) {
|
|
172
|
+
const tagName = k as keyof ElementConstructorObject
|
|
173
|
+
const properties = object[tagName] as ElementConstructorTagObject<any>
|
|
174
|
+
const element = this.#createElement(tagName, properties?.svg)
|
|
175
|
+
|
|
176
|
+
if (properties) {
|
|
177
|
+
this.#applyProperties(element, properties)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
elements.push(element)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return elements
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
#createElement(tagName: ElementConstructorTagNames, isSVG = false) {
|
|
187
|
+
let element: HTMLElement | SVGElement = null!
|
|
188
|
+
|
|
189
|
+
if (tagName.includes('-')) {
|
|
190
|
+
element = new (customElements.get(tagName)!)()
|
|
191
|
+
} else if (isSVG) {
|
|
192
|
+
element = document.createElementNS('http://www.w3.org/2000/svg', tagName)
|
|
193
|
+
} else {
|
|
194
|
+
element = document.createElement(tagName)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return element
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
#applyProperties(element: ElementConstructorType, properties?: ElementConstructorTagObject<any>) {
|
|
201
|
+
for (const k in properties) {
|
|
202
|
+
const propertyName = k as keyof ElementConstructorTagObject<any>
|
|
203
|
+
|
|
204
|
+
if (propertyName === 'class') {
|
|
205
|
+
this.#createClassList(element, properties[propertyName])
|
|
206
|
+
} else if (propertyName === 'style') {
|
|
207
|
+
this.#createStyle(element, properties[propertyName])
|
|
208
|
+
} else if (propertyName === 'events') {
|
|
209
|
+
this.#createEvents(element, properties[propertyName])
|
|
210
|
+
} else if (propertyName === 'attributes') {
|
|
211
|
+
this.#createAttributes(element, properties[propertyName])
|
|
212
|
+
} else if (propertyName === 'children') {
|
|
213
|
+
this.#createChildren(element, properties[propertyName])
|
|
214
|
+
} else if (propertyName === 'shadowChildren') {
|
|
215
|
+
this.#createChildren(element.shadowRoot || element, properties[propertyName])
|
|
216
|
+
} else if (propertyName === 'parent') {
|
|
217
|
+
this.#createParent(element, properties[propertyName])
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (properties?.created) {
|
|
222
|
+
properties.created(element)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Class
|
|
227
|
+
|
|
228
|
+
#createClassList(element: ElementConstructorType, classObject?: ElementConstructorClass) {
|
|
229
|
+
if (!classObject) {
|
|
230
|
+
return
|
|
231
|
+
} else if (typeof classObject === 'string') {
|
|
232
|
+
element.classList.add(classObject)
|
|
233
|
+
} else if (Array.isArray(classObject)) {
|
|
234
|
+
classObject.forEach((v) => {
|
|
235
|
+
this.#createClassList(element, v)
|
|
236
|
+
})
|
|
237
|
+
} else if (typeof classObject === 'object') {
|
|
238
|
+
if (classObject instanceof Store) {
|
|
239
|
+
this.#manageStringStoreClass(
|
|
240
|
+
element,
|
|
241
|
+
classObject as
|
|
242
|
+
| ElementConstructorStringStoreClass
|
|
243
|
+
| ElementConstructorStringArrayStoreClass
|
|
244
|
+
)
|
|
245
|
+
} else {
|
|
246
|
+
for (const className in classObject) {
|
|
247
|
+
const isActive = classObject[className]
|
|
248
|
+
|
|
249
|
+
if (isActive instanceof Store) {
|
|
250
|
+
this.#manageBooleanStoreClass(element, className, isActive)
|
|
251
|
+
} else if (isActive) {
|
|
252
|
+
element.classList.add(className)
|
|
253
|
+
} else {
|
|
254
|
+
element.classList.remove(className)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
#manageStringStoreClass(
|
|
262
|
+
element: ElementConstructorType,
|
|
263
|
+
store: ElementConstructorStringStoreClass | ElementConstructorStringArrayStoreClass
|
|
264
|
+
) {
|
|
265
|
+
store.subscribe(({ current, previous }) => {
|
|
266
|
+
if (previous) {
|
|
267
|
+
;[previous].flat().forEach((v) => {
|
|
268
|
+
if (v) {
|
|
269
|
+
element.classList.remove(v)
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (current) {
|
|
275
|
+
;[current].flat().forEach((v) => {
|
|
276
|
+
if (v) {
|
|
277
|
+
element.classList.add(v)
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
}
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
#manageBooleanStoreClass(
|
|
285
|
+
element: ElementConstructorType,
|
|
286
|
+
className: string,
|
|
287
|
+
store: Store<boolean>
|
|
288
|
+
) {
|
|
289
|
+
store.subscribe(({ current }) => {
|
|
290
|
+
if (current) {
|
|
291
|
+
element.classList.add(className)
|
|
292
|
+
} else {
|
|
293
|
+
element.classList.remove(className)
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// Style
|
|
299
|
+
|
|
300
|
+
#createStyle(
|
|
301
|
+
element: ElementConstructorType,
|
|
302
|
+
object?: ElementConstructorStyle | ElementConstructorJSS
|
|
303
|
+
) {
|
|
304
|
+
if (!object) {
|
|
305
|
+
return
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
const isJSS = element.tagName === 'style' || element.tagName === 'STYLE'
|
|
309
|
+
|
|
310
|
+
if (isJSS) {
|
|
311
|
+
this.#createJSSStyle(element, object as ElementConstructorJSS)
|
|
312
|
+
} else {
|
|
313
|
+
this.#createAttributeStyle(element, object as ElementConstructorStyle)
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
#createAttributeStyle(element: ElementConstructorType, object: ElementConstructorStyle) {
|
|
318
|
+
for (const k in object) {
|
|
319
|
+
const token = k as ElementConstructorStyleToken
|
|
320
|
+
const value = object[token]
|
|
321
|
+
|
|
322
|
+
if (value instanceof Store) {
|
|
323
|
+
value.subscribe(({ current }) => {
|
|
324
|
+
this.#setStyleProperty(element, token, current)
|
|
325
|
+
})
|
|
326
|
+
} else {
|
|
327
|
+
this.#setStyleProperty(element, token, value)
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
#createJSSStyle(element: ElementConstructorType, object: ElementConstructorJSS) {
|
|
333
|
+
for (const key in object) {
|
|
334
|
+
const value = (object as any)[key]
|
|
335
|
+
|
|
336
|
+
if (typeof value === 'object' && !(value instanceof Store)) {
|
|
337
|
+
element.appendChild(new Text(`${key} {`))
|
|
338
|
+
this.#createJSSStyle(element, value)
|
|
339
|
+
element.appendChild(new Text(`}`))
|
|
340
|
+
} else {
|
|
341
|
+
if (value instanceof Store) {
|
|
342
|
+
const text = new Text()
|
|
343
|
+
|
|
344
|
+
value.subscribe((e) => {
|
|
345
|
+
if (e.current) {
|
|
346
|
+
text.nodeValue = `${camelToKebab(key)}: ${e.current};`
|
|
347
|
+
} else {
|
|
348
|
+
text.nodeValue = ''
|
|
349
|
+
}
|
|
350
|
+
})
|
|
351
|
+
|
|
352
|
+
element.appendChild(text)
|
|
353
|
+
} else {
|
|
354
|
+
element.appendChild(new Text(`${camelToKebab(key)}: ${value};`))
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
#setStyleProperty(
|
|
361
|
+
element: ElementConstructorType,
|
|
362
|
+
token: ElementConstructorStyleToken,
|
|
363
|
+
value?: string | null | undefined
|
|
364
|
+
) {
|
|
365
|
+
if (token.includes('--')) {
|
|
366
|
+
if (value) {
|
|
367
|
+
element.style.setProperty(token, value)
|
|
368
|
+
} else {
|
|
369
|
+
element.style.removeProperty(token)
|
|
370
|
+
}
|
|
371
|
+
} else {
|
|
372
|
+
if (value) {
|
|
373
|
+
element.style[token as any] = value
|
|
374
|
+
} else {
|
|
375
|
+
element.style[token as any] = ''
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Events
|
|
381
|
+
|
|
382
|
+
#createEvents(element: ElementConstructorType, events?: ElementConstructorEvents) {
|
|
383
|
+
if (!events) {
|
|
384
|
+
return
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
for (const k in events) {
|
|
388
|
+
const eventName = k as keyof ElementConstructorEvents
|
|
389
|
+
const listener = events[eventName]
|
|
390
|
+
|
|
391
|
+
if (typeof listener === 'object') {
|
|
392
|
+
element.addEventListener(eventName, listener.callback as EventListener, listener.options)
|
|
393
|
+
} else if (typeof listener === 'function') {
|
|
394
|
+
element.addEventListener(eventName, listener as EventListener)
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Attributes
|
|
400
|
+
|
|
401
|
+
#createAttributes(
|
|
402
|
+
element: ElementConstructorType,
|
|
403
|
+
attributes?: ElementConstructorAttributes<any>
|
|
404
|
+
) {
|
|
405
|
+
for (const attributeName in attributes) {
|
|
406
|
+
const value = attributes[attributeName]
|
|
407
|
+
|
|
408
|
+
if (value instanceof Store) {
|
|
409
|
+
value.subscribe(({ current }) => {
|
|
410
|
+
this.#setAttribute(element, attributeName, current)
|
|
411
|
+
})
|
|
412
|
+
} else {
|
|
413
|
+
this.#setAttribute(element, attributeName, value)
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
#setAttribute(
|
|
419
|
+
element: ElementConstructorType,
|
|
420
|
+
name: string,
|
|
421
|
+
value: string | boolean | number | null | undefined
|
|
422
|
+
) {
|
|
423
|
+
if (name in element && !(element.constructor as any)?.observedAttributes?.includes(name)) {
|
|
424
|
+
if (value != undefined) {
|
|
425
|
+
;(element as any)[name as any] = value.toString()
|
|
426
|
+
}
|
|
427
|
+
} else {
|
|
428
|
+
if (value != undefined) {
|
|
429
|
+
element.setAttribute(name, value.toString())
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// Children
|
|
435
|
+
|
|
436
|
+
#createChildren(
|
|
437
|
+
root: ElementConstructorType | ShadowRoot,
|
|
438
|
+
children?: ElementConstructorChildren
|
|
439
|
+
) {
|
|
440
|
+
if (!children) {
|
|
441
|
+
return
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
children.forEach((child) => {
|
|
445
|
+
if (child instanceof Store) {
|
|
446
|
+
const storeRootElement = document.createElement('div')
|
|
447
|
+
storeRootElement.style.display = 'contents'
|
|
448
|
+
root.appendChild(storeRootElement)
|
|
449
|
+
|
|
450
|
+
child.subscribe(({ current }) => {
|
|
451
|
+
this.#replaceChildren(
|
|
452
|
+
storeRootElement,
|
|
453
|
+
this.#getChildrenArray(current),
|
|
454
|
+
Array.from(storeRootElement.childNodes)
|
|
455
|
+
)
|
|
456
|
+
})
|
|
457
|
+
} else if (child instanceof ElementConstructor) {
|
|
458
|
+
root.append(...child.rootElements)
|
|
459
|
+
} else {
|
|
460
|
+
if (
|
|
461
|
+
typeof child === 'string' &&
|
|
462
|
+
child.trim().startsWith('<') &&
|
|
463
|
+
child.trim().endsWith('>')
|
|
464
|
+
) {
|
|
465
|
+
const wrapper = document.createElement('div')
|
|
466
|
+
wrapper.innerHTML = child
|
|
467
|
+
root.append(wrapper.firstElementChild!)
|
|
468
|
+
} else {
|
|
469
|
+
const childNodeOrUndefined = this.#getOrCreateNode(child)
|
|
470
|
+
|
|
471
|
+
if (childNodeOrUndefined instanceof Node) {
|
|
472
|
+
root.append(childNodeOrUndefined)
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
#getChildrenArray(children: ElementConstructorSimpleChild) {
|
|
480
|
+
const arr = [children]
|
|
481
|
+
.flat()
|
|
482
|
+
.map((v) => {
|
|
483
|
+
if (v instanceof ElementConstructor) {
|
|
484
|
+
return v.rootElements
|
|
485
|
+
} else {
|
|
486
|
+
return this.#getOrCreateNode(v)
|
|
487
|
+
}
|
|
488
|
+
})
|
|
489
|
+
.flat()
|
|
490
|
+
.filter(Boolean) as Array<Node | ElementConstructorType>
|
|
491
|
+
|
|
492
|
+
return arr
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
#replaceChildren(
|
|
496
|
+
rootElement: HTMLElement,
|
|
497
|
+
newChildren: Array<Node>,
|
|
498
|
+
currentChildren: Array<Node>
|
|
499
|
+
) {
|
|
500
|
+
currentChildren.forEach((currentChild, index) => {
|
|
501
|
+
if (index < newChildren.length) {
|
|
502
|
+
const newChild = newChildren[index]
|
|
503
|
+
|
|
504
|
+
if (!this.#areNodesEqual(currentChild, newChild)) {
|
|
505
|
+
rootElement.replaceChild(newChild, currentChild)
|
|
506
|
+
}
|
|
507
|
+
} else {
|
|
508
|
+
rootElement.removeChild(currentChild)
|
|
509
|
+
}
|
|
510
|
+
})
|
|
511
|
+
|
|
512
|
+
for (let i = currentChildren.length; i < newChildren.length; i++) {
|
|
513
|
+
rootElement.appendChild(newChildren[i])
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
#areNodesEqual(
|
|
518
|
+
currentChild: Node,
|
|
519
|
+
newChild: Exclude<ElementConstructorSimpleChild, ElementConstructor>
|
|
520
|
+
) {
|
|
521
|
+
if (!newChild) {
|
|
522
|
+
return false
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (newChild instanceof Node) {
|
|
526
|
+
return currentChild.isEqualNode(newChild)
|
|
527
|
+
} else {
|
|
528
|
+
return currentChild.textContent === newChild.toString()
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
#getOrCreateNode(child: Exclude<ElementConstructorSimpleChild, ElementConstructor>) {
|
|
533
|
+
if (child instanceof Node) {
|
|
534
|
+
return child
|
|
535
|
+
} else if (child != undefined) {
|
|
536
|
+
return new Text(String(child))
|
|
537
|
+
} else {
|
|
538
|
+
return undefined
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
// Parent
|
|
543
|
+
|
|
544
|
+
#createParent(element: ElementConstructorType, parent?: ElementConstructorParent) {
|
|
545
|
+
if (!parent) {
|
|
546
|
+
return
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
const parentNode = parent instanceof ElementConstructor ? parent.rootElements[0] : parent
|
|
550
|
+
|
|
551
|
+
parentNode.appendChild(element)
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
export function element(object: ElementConstructorObject): ElementConstructor
|
|
556
|
+
export function element<T extends ElementConstructorTagNames = ElementConstructorTagNames>(
|
|
557
|
+
value: string,
|
|
558
|
+
object?: ElementConstructorTagObject<T>
|
|
559
|
+
): ElementConstructor
|
|
560
|
+
export function element(
|
|
561
|
+
element: HTMLElement,
|
|
562
|
+
object: ElementConstructorTagObject<any>
|
|
563
|
+
): ElementConstructor
|
|
564
|
+
export function element(...args: any[]) {
|
|
565
|
+
return new (ElementConstructor as any)(...args)
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export function elementFactory(object: ElementConstructorObject): () => ElementConstructor
|
|
569
|
+
export function elementFactory(
|
|
570
|
+
element: HTMLElement,
|
|
571
|
+
object: ElementConstructorTagObject<any>
|
|
572
|
+
): () => ElementConstructor
|
|
573
|
+
export function elementFactory(...args: any[]) {
|
|
574
|
+
return () => {
|
|
575
|
+
return new (ElementConstructor as any)(...args)
|
|
576
|
+
}
|
|
577
|
+
}
|