@potok-web-framework/core 0.1.0 → 0.2.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/dist/block.d.ts +17 -0
- package/dist/bootstrap-app.d.ts +8 -0
- package/dist/client-only.d.ts +3 -0
- package/dist/client.mjs +133 -0
- package/dist/constants-BOAOReQ3.mjs +26 -0
- package/dist/constants.d.ts +2 -0
- package/dist/context.d.ts +12 -0
- package/dist/detect-child.d.ts +6 -0
- package/dist/error-boundary.d.ts +5 -0
- package/dist/exports/client.d.ts +1 -0
- package/dist/exports/hmr.d.ts +1 -0
- package/dist/exports/index.d.ts +14 -0
- package/dist/exports/jsx-runtime.d.ts +4 -0
- package/dist/exports/server.d.ts +1 -0
- package/dist/fragment-BahmURhz.mjs +17 -0
- package/dist/fragment.d.ts +4 -0
- package/dist/hmr/hmr-dev.d.ts +9 -0
- package/dist/hmr/register-component.d.ts +2 -0
- package/dist/hmr/registered-component.d.ts +23 -0
- package/dist/hmr/registry.d.ts +12 -0
- package/dist/hmr/types.d.ts +4 -0
- package/dist/hmr/utils.d.ts +3 -0
- package/dist/hmr.mjs +42 -0
- package/dist/html-element-Cm0RtMkT.mjs +42 -0
- package/dist/html-element.d.ts +6 -0
- package/dist/index.mjs +199 -0
- package/dist/jsx-runtime.mjs +10 -0
- package/dist/jsx-types.d.ts +11 -0
- package/dist/lazy.d.ts +7 -0
- package/dist/lib-context-reader.d.ts +5 -0
- package/dist/lib-scripts.d.ts +2 -0
- package/dist/lifecycle-4vjEuXGy.mjs +57 -0
- package/dist/lifecycle.d.ts +8 -0
- package/dist/list.d.ts +9 -0
- package/dist/portal-CbcYOHLv.mjs +44 -0
- package/dist/portal.d.ts +10 -0
- package/dist/prop-types.d.ts +939 -0
- package/dist/ref.d.ts +6 -0
- package/dist/render-to-dom.d.ts +8 -0
- package/dist/render-to-string.d.ts +2 -0
- package/dist/server-node.d.ts +10 -0
- package/dist/server.mjs +1192 -0
- package/dist/show.d.ts +6 -0
- package/dist/signals.d.ts +32 -0
- package/dist/store.d.ts +26 -0
- package/dist/text.d.ts +5 -0
- package/dist/types.d.ts +39 -0
- package/dist/utils-CAe_kbSH.mjs +345 -0
- package/dist/utils.d.ts +11 -0
- package/package.json +7 -2
- package/CHANGELOG.md +0 -7
- package/bun.lock +0 -25
- package/src/block.ts +0 -102
- package/src/bootstrap-app.ts +0 -115
- package/src/client-only.ts +0 -17
- package/src/constants.ts +0 -27
- package/src/context.ts +0 -85
- package/src/detect-child.ts +0 -21
- package/src/error-boundary.ts +0 -51
- package/src/exports/client.ts +0 -1
- package/src/exports/hmr.ts +0 -1
- package/src/exports/index.ts +0 -21
- package/src/exports/jsx-runtime.ts +0 -4
- package/src/exports/server.ts +0 -1
- package/src/fragment.ts +0 -28
- package/src/global.dev.d.ts +0 -12
- package/src/hmr/hmr-dev.ts +0 -10
- package/src/hmr/register-component.ts +0 -109
- package/src/hmr/registered-component.ts +0 -59
- package/src/hmr/registry.ts +0 -78
- package/src/hmr/types.ts +0 -6
- package/src/hmr/utils.ts +0 -20
- package/src/html-element.ts +0 -95
- package/src/jsx-types.ts +0 -13
- package/src/lazy.ts +0 -44
- package/src/lib-context-reader.ts +0 -33
- package/src/lib-scripts.ts +0 -8
- package/src/lifecycle.ts +0 -44
- package/src/list.ts +0 -175
- package/src/portal.ts +0 -101
- package/src/prop-types.ts +0 -1165
- package/src/ref.ts +0 -11
- package/src/render-to-dom.ts +0 -325
- package/src/render-to-string.ts +0 -65
- package/src/server-node.ts +0 -98
- package/src/show.ts +0 -46
- package/src/signals.ts +0 -323
- package/src/store.ts +0 -68
- package/src/text.ts +0 -35
- package/src/types.ts +0 -69
- package/src/utils.ts +0 -118
- package/tests/signals.test.ts +0 -403
- package/tsconfig.json +0 -17
- package/vite.config.ts +0 -21
package/src/ref.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { createSignal } from './signals'
|
|
2
|
-
|
|
3
|
-
export type LibHTMLElementReference<Element extends HTMLElement> = {
|
|
4
|
-
element: Element | null
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
export function createElementReference<Element extends HTMLElement>() {
|
|
8
|
-
return createSignal({
|
|
9
|
-
element: null as Element | null,
|
|
10
|
-
})
|
|
11
|
-
}
|
package/src/render-to-dom.ts
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import { HTML_ELEMENT_STYLE_PX_PROPERTIES } from './constants'
|
|
2
|
-
import type { LibHTMLElementEventMap } from './prop-types'
|
|
3
|
-
import { createEffect, createSignal, deepTrack, untrack } from './signals'
|
|
4
|
-
import type { LibContext, LibNode, PotokElement, WithChildren } from './types'
|
|
5
|
-
import { objectKeys } from './utils'
|
|
6
|
-
|
|
7
|
-
type RenderToDOMOptions = {
|
|
8
|
-
app: () => PotokElement
|
|
9
|
-
needToHydrate?: boolean
|
|
10
|
-
root?: Element
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function renderToDOM(options: RenderToDOMOptions) {
|
|
14
|
-
const rootNode = options.root ?? document
|
|
15
|
-
const libNodeToDOMNodeMap = new Map<LibNode, Node>()
|
|
16
|
-
|
|
17
|
-
const signal = createSignal({
|
|
18
|
-
portals: {} as Record<string, WithChildren<{}>['children']>,
|
|
19
|
-
listeners: {} as LibContext['listeners'],
|
|
20
|
-
isHydrating: options.needToHydrate ?? false,
|
|
21
|
-
})
|
|
22
|
-
|
|
23
|
-
function addDocumentListener(eventType: keyof LibHTMLElementEventMap) {
|
|
24
|
-
const normalizedEventType = eventType.replace(/^on([A-Z])/, (_, letter) =>
|
|
25
|
-
letter.toLowerCase(),
|
|
26
|
-
) as keyof DocumentEventMap
|
|
27
|
-
|
|
28
|
-
document.addEventListener(normalizedEventType, (event) => {
|
|
29
|
-
let isBubbleCancelled = false
|
|
30
|
-
let node = event.target as HTMLElement | null
|
|
31
|
-
|
|
32
|
-
let originalStopPropagation = event.stopPropagation.bind(event)
|
|
33
|
-
let originalStopImmediatePropagation =
|
|
34
|
-
event.stopImmediatePropagation.bind(event)
|
|
35
|
-
|
|
36
|
-
event.stopPropagation = () => {
|
|
37
|
-
isBubbleCancelled = true
|
|
38
|
-
originalStopPropagation()
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
event.stopImmediatePropagation = () => {
|
|
42
|
-
isBubbleCancelled = true
|
|
43
|
-
originalStopImmediatePropagation()
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
while (node) {
|
|
47
|
-
const eventListeningNodes = signal.listeners[eventType]
|
|
48
|
-
|
|
49
|
-
const handler = eventListeningNodes?.get(node)
|
|
50
|
-
|
|
51
|
-
if (handler) {
|
|
52
|
-
Object.defineProperty(event, 'currentTarget', {
|
|
53
|
-
configurable: true,
|
|
54
|
-
enumerable: true,
|
|
55
|
-
get: () => node,
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
handler(event as any)
|
|
59
|
-
|
|
60
|
-
if (isBubbleCancelled) {
|
|
61
|
-
break
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
node = node.parentElement
|
|
66
|
-
}
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const listenedEventTypes = new Set<keyof LibHTMLElementEventMap>()
|
|
71
|
-
|
|
72
|
-
createEffect(() => {
|
|
73
|
-
deepTrack(signal.listeners, 1)
|
|
74
|
-
|
|
75
|
-
untrack(() => {
|
|
76
|
-
objectKeys(signal.listeners).forEach((eventType) => {
|
|
77
|
-
if (listenedEventTypes.has(eventType)) {
|
|
78
|
-
return
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
addDocumentListener(eventType)
|
|
82
|
-
|
|
83
|
-
listenedEventTypes.add(eventType)
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
}, true)
|
|
87
|
-
|
|
88
|
-
const insertDomNode = (
|
|
89
|
-
parentDomNode: Node,
|
|
90
|
-
domNode: Node,
|
|
91
|
-
afterDomNode: Node | null,
|
|
92
|
-
) =>
|
|
93
|
-
parentDomNode.insertBefore(
|
|
94
|
-
domNode,
|
|
95
|
-
afterDomNode ? afterDomNode.nextSibling : parentDomNode.firstChild,
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
const isHTMLElementNode = (node: Node): node is HTMLElement =>
|
|
99
|
-
node instanceof HTMLElement
|
|
100
|
-
|
|
101
|
-
if (!options.needToHydrate) {
|
|
102
|
-
while (rootNode.firstChild) {
|
|
103
|
-
rootNode.removeChild(rootNode.firstChild)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
options.app()({
|
|
108
|
-
parentBlock: null,
|
|
109
|
-
index: 0,
|
|
110
|
-
portals: signal.portals,
|
|
111
|
-
contexts: {},
|
|
112
|
-
listeners: signal.listeners,
|
|
113
|
-
isServer: false,
|
|
114
|
-
promises: [],
|
|
115
|
-
get isHydrating() {
|
|
116
|
-
return signal.isHydrating
|
|
117
|
-
},
|
|
118
|
-
insertNode(parent, node, after) {
|
|
119
|
-
if (signal.isHydrating) {
|
|
120
|
-
if (parent === null) {
|
|
121
|
-
libNodeToDOMNodeMap.set(node, document.querySelector('html')!)
|
|
122
|
-
} else {
|
|
123
|
-
const parentNode = libNodeToDOMNodeMap.get(parent)
|
|
124
|
-
|
|
125
|
-
if (!parentNode) {
|
|
126
|
-
throw new Error('Ошибка гидрации')
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
let childNode: Node | null = null
|
|
130
|
-
|
|
131
|
-
if (after) {
|
|
132
|
-
const node = libNodeToDOMNodeMap.get(after)
|
|
133
|
-
|
|
134
|
-
if (!node) {
|
|
135
|
-
throw new Error('Ошибка гидрации')
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
childNode = node.nextSibling
|
|
139
|
-
} else {
|
|
140
|
-
childNode = parentNode.firstChild
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
while (true) {
|
|
144
|
-
if (!childNode) {
|
|
145
|
-
throw new Error('Ошибка гидрации')
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
(node.type === 'text' &&
|
|
150
|
-
String(node.props.text) === childNode.textContent) ||
|
|
151
|
-
(node.type === 'html-element' &&
|
|
152
|
-
isHTMLElementNode(childNode) &&
|
|
153
|
-
node.props.tag === childNode.tagName.toLowerCase())
|
|
154
|
-
) {
|
|
155
|
-
libNodeToDOMNodeMap.set(node, childNode)
|
|
156
|
-
|
|
157
|
-
break
|
|
158
|
-
} else {
|
|
159
|
-
const oldChildNode = childNode
|
|
160
|
-
childNode = childNode.nextSibling
|
|
161
|
-
oldChildNode.parentElement?.removeChild(oldChildNode)
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
if (parent && !libNodeToDOMNodeMap.has(parent)) {
|
|
170
|
-
libNodeToDOMNodeMap.set(
|
|
171
|
-
parent,
|
|
172
|
-
document.createElement(parent.props.tag),
|
|
173
|
-
)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const parentDomNode = parent ? libNodeToDOMNodeMap.get(parent)! : rootNode
|
|
177
|
-
|
|
178
|
-
const afterDomNode = (after && libNodeToDOMNodeMap.get(after)) ?? null
|
|
179
|
-
|
|
180
|
-
if (node.type === 'text') {
|
|
181
|
-
const domNode = document.createTextNode(String(node.props.text))
|
|
182
|
-
libNodeToDOMNodeMap.set(node, domNode)
|
|
183
|
-
|
|
184
|
-
this.updateTextNode(node)
|
|
185
|
-
|
|
186
|
-
insertDomNode(parentDomNode, domNode, afterDomNode)
|
|
187
|
-
} else if (node.type === 'html-element') {
|
|
188
|
-
if (!libNodeToDOMNodeMap.has(node)) {
|
|
189
|
-
libNodeToDOMNodeMap.set(node, document.createElement(node.props.tag))
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
for (const [key, descriptor] of Object.entries(
|
|
193
|
-
Object.getOwnPropertyDescriptors(node.props),
|
|
194
|
-
)) {
|
|
195
|
-
if (['tag', 'children', 'ref'].includes(key)) {
|
|
196
|
-
continue
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
let value = descriptor.get?.() ?? descriptor.value
|
|
200
|
-
this.updateHtmlElementNodeProp(node, key, value)
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const domNode = libNodeToDOMNodeMap.get(node)! as HTMLElement
|
|
204
|
-
|
|
205
|
-
insertDomNode(parentDomNode, domNode, afterDomNode)
|
|
206
|
-
|
|
207
|
-
if (node.props.ref) {
|
|
208
|
-
node.props.ref.element = domNode
|
|
209
|
-
}
|
|
210
|
-
} else {
|
|
211
|
-
let _: never = node
|
|
212
|
-
throw new Error('Неверный тип ноды')
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
updateTextNode(node) {
|
|
216
|
-
const value = node.props.text
|
|
217
|
-
const domNode = libNodeToDOMNodeMap.get(node)
|
|
218
|
-
|
|
219
|
-
if (!domNode) {
|
|
220
|
-
return
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
domNode.textContent = String(value)
|
|
224
|
-
},
|
|
225
|
-
updateHtmlElementNodeProp(node, key, value) {
|
|
226
|
-
const domNode = libNodeToDOMNodeMap.get(node)
|
|
227
|
-
|
|
228
|
-
if (!domNode) {
|
|
229
|
-
return
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const element = domNode as HTMLElement
|
|
233
|
-
|
|
234
|
-
const isEventTypeKey = (
|
|
235
|
-
key: string,
|
|
236
|
-
): key is keyof LibHTMLElementEventMap => key.startsWith('on')
|
|
237
|
-
|
|
238
|
-
if (isEventTypeKey(key)) {
|
|
239
|
-
if (value) {
|
|
240
|
-
this.listeners[key] ??= new Map()
|
|
241
|
-
|
|
242
|
-
this.listeners[key].set(
|
|
243
|
-
element,
|
|
244
|
-
value as LibHTMLElementEventMap[keyof LibHTMLElementEventMap],
|
|
245
|
-
)
|
|
246
|
-
} else {
|
|
247
|
-
this.listeners[key]?.delete(element)
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
return
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
if (key.startsWith('aria')) {
|
|
254
|
-
const name = key.toLowerCase().replace('aria', 'aria-')
|
|
255
|
-
|
|
256
|
-
if (value) {
|
|
257
|
-
element.setAttribute(name, value as string)
|
|
258
|
-
} else {
|
|
259
|
-
element.removeAttribute(name)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
return
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
if (key === 'className') {
|
|
266
|
-
if (value) {
|
|
267
|
-
element.className = value as string
|
|
268
|
-
} else {
|
|
269
|
-
element.removeAttribute('class')
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
return
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (key === 'style') {
|
|
276
|
-
if (value) {
|
|
277
|
-
Object.keys(value).forEach((key) => {
|
|
278
|
-
const keyValue = value[key as keyof typeof value]
|
|
279
|
-
if (keyValue !== undefined) {
|
|
280
|
-
const normalizedValue = String(
|
|
281
|
-
HTML_ELEMENT_STYLE_PX_PROPERTIES.has(key) &&
|
|
282
|
-
typeof keyValue === 'number'
|
|
283
|
-
? `${keyValue}px`
|
|
284
|
-
: keyValue,
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
element.style.setProperty(key, normalizedValue)
|
|
288
|
-
} else {
|
|
289
|
-
element.style.removeProperty(key)
|
|
290
|
-
}
|
|
291
|
-
})
|
|
292
|
-
} else {
|
|
293
|
-
element.removeAttribute('style')
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
return
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (value !== undefined && value !== null) {
|
|
300
|
-
element.setAttribute(key, String(value))
|
|
301
|
-
} else {
|
|
302
|
-
element.removeAttribute(key)
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
removeNode(node) {
|
|
306
|
-
const domNode = libNodeToDOMNodeMap.get(node)
|
|
307
|
-
|
|
308
|
-
if (!domNode) {
|
|
309
|
-
return
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
libNodeToDOMNodeMap.delete(node)
|
|
313
|
-
|
|
314
|
-
if (isHTMLElementNode(domNode)) {
|
|
315
|
-
domNode.remove()
|
|
316
|
-
} else {
|
|
317
|
-
domNode.parentElement?.removeChild(domNode)
|
|
318
|
-
}
|
|
319
|
-
},
|
|
320
|
-
})
|
|
321
|
-
|
|
322
|
-
if (options.needToHydrate) {
|
|
323
|
-
signal.isHydrating = false
|
|
324
|
-
}
|
|
325
|
-
}
|
package/src/render-to-string.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { ServerNode } from './server-node'
|
|
2
|
-
import { createSignal } from './signals'
|
|
3
|
-
import type { LibNode, LibContext, PotokElement } from './types'
|
|
4
|
-
|
|
5
|
-
export async function renderToString(creator: PotokElement) {
|
|
6
|
-
const signal = createSignal({
|
|
7
|
-
portals: {} as Record<string, PotokElement[]>,
|
|
8
|
-
listeners: {} as LibContext['listeners'],
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
let libNodeToServerNodeMap = new Map<LibNode, ServerNode>()
|
|
12
|
-
let rootNode: ServerNode | undefined
|
|
13
|
-
|
|
14
|
-
let promises: Promise<void>[] = []
|
|
15
|
-
|
|
16
|
-
creator({
|
|
17
|
-
parentBlock: null,
|
|
18
|
-
index: 0,
|
|
19
|
-
portals: signal.portals,
|
|
20
|
-
contexts: {},
|
|
21
|
-
listeners: signal.listeners,
|
|
22
|
-
isServer: true,
|
|
23
|
-
promises,
|
|
24
|
-
isHydrating: false,
|
|
25
|
-
insertNode(parent, libNode, after) {
|
|
26
|
-
if (parent && !libNodeToServerNodeMap.has(parent)) {
|
|
27
|
-
libNodeToServerNodeMap.set(parent, new ServerNode(parent))
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!libNodeToServerNodeMap.has(libNode)) {
|
|
31
|
-
libNodeToServerNodeMap.set(libNode, new ServerNode(libNode))
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const serverNode = libNodeToServerNodeMap.get(libNode)!
|
|
35
|
-
|
|
36
|
-
libNodeToServerNodeMap.set(libNode, serverNode)
|
|
37
|
-
|
|
38
|
-
if (parent === null) {
|
|
39
|
-
rootNode = serverNode
|
|
40
|
-
} else {
|
|
41
|
-
const afterServerNode =
|
|
42
|
-
after && libNodeToServerNodeMap.has(after)
|
|
43
|
-
? libNodeToServerNodeMap.get(after)!
|
|
44
|
-
: null
|
|
45
|
-
|
|
46
|
-
libNodeToServerNodeMap
|
|
47
|
-
.get(parent)
|
|
48
|
-
?.addChild(serverNode, afterServerNode)
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
updateTextNode() {},
|
|
52
|
-
updateHtmlElementNodeProp() {},
|
|
53
|
-
removeNode(node) {
|
|
54
|
-
libNodeToServerNodeMap.get(node)?.remove()
|
|
55
|
-
},
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
await Promise.all(promises)
|
|
59
|
-
|
|
60
|
-
if (!rootNode) {
|
|
61
|
-
throw new Error('Корневая нода не найдена')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return rootNode.stringify()
|
|
65
|
-
}
|
package/src/server-node.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import type { LibNode } from './types'
|
|
2
|
-
|
|
3
|
-
export class ServerNode {
|
|
4
|
-
libNode: LibNode
|
|
5
|
-
parent: ServerNode | null = null
|
|
6
|
-
children: ServerNode[] = []
|
|
7
|
-
|
|
8
|
-
constructor(libNode: LibNode) {
|
|
9
|
-
this.libNode = libNode
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
addChild(node: ServerNode, after: ServerNode | null) {
|
|
13
|
-
if (after) {
|
|
14
|
-
const afterIndex = this.children.indexOf(after)
|
|
15
|
-
this.children.splice(afterIndex + 1, 0, node)
|
|
16
|
-
} else {
|
|
17
|
-
this.children.push(node)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
node.parent = this
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
remove() {
|
|
24
|
-
if (this.parent) {
|
|
25
|
-
this.parent.children.splice(this.parent.children.indexOf(this), 1)
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
stringify(): string {
|
|
30
|
-
if (this.libNode.type === 'text') {
|
|
31
|
-
const parentTagName =
|
|
32
|
-
this.libNode.context.parentBlock?.nearestParentElement?.props.tag
|
|
33
|
-
if (parentTagName && ['title', 'script'].includes(parentTagName)) {
|
|
34
|
-
return String(this.libNode.props.text)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return `<!-- -->${this.libNode.props.text}`
|
|
38
|
-
} else if (this.libNode.type === 'html-element') {
|
|
39
|
-
let result = `<${this.libNode.props.tag}`
|
|
40
|
-
|
|
41
|
-
for (const [key, descriptor] of Object.entries(
|
|
42
|
-
Object.getOwnPropertyDescriptors(this.libNode.props)
|
|
43
|
-
)) {
|
|
44
|
-
if (['tag', 'children', 'ref'].includes(key)) {
|
|
45
|
-
continue
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (key.startsWith('on')) {
|
|
49
|
-
continue
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
let value = descriptor.get?.() ?? descriptor.value
|
|
53
|
-
|
|
54
|
-
if (!value) {
|
|
55
|
-
continue
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (key === 'style') {
|
|
59
|
-
let styleStr = ''
|
|
60
|
-
Object.entries(value as CSSStyleDeclaration).forEach(
|
|
61
|
-
([key, value]) => {
|
|
62
|
-
styleStr += `${key
|
|
63
|
-
.replace(/([A-Z])/g, '-$1')
|
|
64
|
-
.toLowerCase()}:${value};`
|
|
65
|
-
}
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
result += ` style="${styleStr}"`
|
|
69
|
-
continue
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (key.startsWith('aria')) {
|
|
73
|
-
result += ` ${key.toLowerCase().replace('aria', 'aria-')}="${value}"`
|
|
74
|
-
continue
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (key === 'className') {
|
|
78
|
-
result += ` class="${value}"`
|
|
79
|
-
continue
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
result += ` ${key}="${value}"`
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
result += '>'
|
|
86
|
-
|
|
87
|
-
this.children.forEach((child) => {
|
|
88
|
-
result += child.stringify()
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
result += `</${this.libNode.props.tag}>`
|
|
92
|
-
|
|
93
|
-
return result
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
throw new Error('Not implemented')
|
|
97
|
-
}
|
|
98
|
-
}
|
package/src/show.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { LibBlock } from './block'
|
|
2
|
-
import { createEffect, untrack } from './signals'
|
|
3
|
-
import type { LibContext, PotokElement, WithChildren } from './types'
|
|
4
|
-
import { mergeContext, normalizeChildren } from './utils'
|
|
5
|
-
|
|
6
|
-
type ShowProps = WithChildren<{
|
|
7
|
-
when: boolean
|
|
8
|
-
}>
|
|
9
|
-
|
|
10
|
-
class ShowClass<Props extends ShowProps> extends LibBlock {
|
|
11
|
-
constructor(
|
|
12
|
-
readonly props: Props,
|
|
13
|
-
readonly context: LibContext,
|
|
14
|
-
) {
|
|
15
|
-
super()
|
|
16
|
-
|
|
17
|
-
const normalizedChildren = normalizeChildren(props.children)
|
|
18
|
-
|
|
19
|
-
this.addEffect(
|
|
20
|
-
createEffect(() => {
|
|
21
|
-
if (props.when) {
|
|
22
|
-
untrack(() => {
|
|
23
|
-
normalizedChildren.forEach((childCreator, index) => {
|
|
24
|
-
this.children.push(
|
|
25
|
-
childCreator(
|
|
26
|
-
mergeContext(context, {
|
|
27
|
-
parentBlock: this,
|
|
28
|
-
index,
|
|
29
|
-
}),
|
|
30
|
-
),
|
|
31
|
-
)
|
|
32
|
-
})
|
|
33
|
-
})
|
|
34
|
-
} else {
|
|
35
|
-
this.unmountChildren()
|
|
36
|
-
}
|
|
37
|
-
}, true),
|
|
38
|
-
)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function Show(props: ShowProps): PotokElement {
|
|
43
|
-
return function (context: LibContext) {
|
|
44
|
-
return new ShowClass(props, context)
|
|
45
|
-
}
|
|
46
|
-
}
|