tungsten 0.1.60 → 0.1.62

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 (79) hide show
  1. package/dist/Components.d.ts +14 -0
  2. package/dist/Components.d.ts.map +1 -1
  3. package/dist/Components.js +95 -0
  4. package/dist/FunctionComponentStandIn.d.ts +5 -0
  5. package/dist/FunctionComponentStandIn.d.ts.map +1 -1
  6. package/dist/FunctionComponentStandIn.js +13 -0
  7. package/dist/Instance/Instance.d.ts.map +1 -1
  8. package/dist/RenderedContentNode.d.ts +5 -0
  9. package/dist/RenderedContentNode.d.ts.map +1 -1
  10. package/dist/Servers/DevServer.d.ts.map +1 -1
  11. package/dist/Servers/DevServer.js +14 -14
  12. package/dist/Servers/ProdServer.d.ts.map +1 -1
  13. package/dist/Store/makeStore.d.ts.map +1 -1
  14. package/dist/TungstenApp.d.ts +11 -0
  15. package/dist/TungstenApp.d.ts.map +1 -0
  16. package/dist/TungstenApp.js +46 -0
  17. package/dist/babelPlugins/BabelTransformBindDirect.d.ts.map +1 -1
  18. package/dist/babelPlugins/BabelTransformBindVar.d.ts.map +1 -1
  19. package/dist/babelPlugins/BabelTransformCjsToEsm.d.ts.map +1 -1
  20. package/dist/babelPlugins/BabelTransformCjsToFunction.d.ts.map +1 -1
  21. package/dist/babelPlugins/BabelTransformCjsToFunction2.d.ts.map +1 -1
  22. package/dist/babelPlugins/BabelTransformComponentState.d.ts.map +1 -1
  23. package/dist/babelPlugins/BabelTransformComponentStyles.d.ts.map +1 -1
  24. package/dist/babelPlugins/BabelTransformCssImports.d.ts +2 -1
  25. package/dist/babelPlugins/BabelTransformCssImports.d.ts.map +1 -1
  26. package/dist/babelPlugins/BabelTransformCssImports.js +44 -17
  27. package/dist/babelPlugins/BabelTransformDependencyImportsOld.d.ts.map +1 -1
  28. package/dist/babelPlugins/BabelTransformDeproxyState.d.ts.map +1 -1
  29. package/dist/babelPlugins/BabelTransformPackageImports.d.ts.map +1 -1
  30. package/dist/babelPlugins/BabelTransformPackageImports.js +57 -30
  31. package/dist/babelPlugins/BabelTransformReactive.d.ts.map +1 -1
  32. package/dist/babelPlugins/BabelTransformReactiveSvelteStyle.d.ts.map +1 -1
  33. package/dist/babelPlugins/BabelTransformUniqueComponents.d.ts.map +1 -1
  34. package/dist/babelPlugins/transformPackageImports/BabelTransformDependencyImportsCjs.d.ts.map +1 -1
  35. package/dist/babelPlugins/transformPackageImports/BabelTransformDependencyImportsCjs.js +1 -3
  36. package/dist/babelPlugins/transformPackageImports/BabelTransformDependencyImportsEsm.d.ts.map +1 -1
  37. package/dist/babelPlugins/transformPackageImports/getWebLocationOfPackageFile.d.ts +2 -0
  38. package/dist/babelPlugins/transformPackageImports/getWebLocationOfPackageFile.d.ts.map +1 -0
  39. package/dist/babelPlugins/transformPackageImports/getWebLocationOfPackageFile.js +24 -0
  40. package/dist/bin/index.js +0 -0
  41. package/dist/browserStorage.d.ts.map +1 -1
  42. package/dist/build/babel.user.common.config.d.ts.map +1 -1
  43. package/dist/build/babel.user.common.config.js +1 -61
  44. package/dist/build/compileJavascript.d.ts.map +1 -1
  45. package/dist/build/compileJavascript.js +2 -1
  46. package/dist/build/makeBabelUserDevConfig.d.ts.map +1 -1
  47. package/dist/build/makeBabelUserDevConfig.js +7 -14
  48. package/dist/build/makeBabelUserProdConfig.d.ts.map +1 -1
  49. package/dist/build/makeBabelUserProdConfig.js +1 -3
  50. package/dist/componentProxyHandlers.d.ts.map +1 -1
  51. package/dist/components/Link.d.ts.map +1 -1
  52. package/dist/components/Link.js +1 -1
  53. package/dist/components/Stylesheet.d.ts +0 -1
  54. package/dist/components/Stylesheet.d.ts.map +1 -1
  55. package/dist/components/Stylesheet.js +0 -19
  56. package/dist/createRoutes.d.ts +3 -0
  57. package/dist/createRoutes.d.ts.map +1 -0
  58. package/dist/createRoutes.js +3 -0
  59. package/dist/hasDomain.d.ts.map +1 -1
  60. package/dist/hydrate/hydrate.d.ts.map +1 -1
  61. package/dist/hydrate/hydrate.js +9 -42
  62. package/dist/indexInner.d.ts +5 -3
  63. package/dist/indexInner.d.ts.map +1 -1
  64. package/dist/indexInner.js +5 -3
  65. package/dist/jsxRuntime.d.ts +1 -1
  66. package/dist/jsxRuntime.d.ts.map +1 -1
  67. package/dist/jsxRuntime.js +9 -5
  68. package/dist/makeServerRpc.d.ts.map +1 -1
  69. package/dist/nbsp.d.ts +3 -0
  70. package/dist/nbsp.d.ts.map +1 -0
  71. package/dist/nbsp.js +8 -0
  72. package/dist/routing/MatchedRoute.d.ts +5 -0
  73. package/dist/routing/MatchedRoute.d.ts.map +1 -1
  74. package/dist/update/integrateUpdateVdom.d.ts.map +1 -1
  75. package/dist/update/integrateUpdateVdom.js +10 -12
  76. package/dist/update/integrateUpdateVdomPrebuild.d.ts +2 -0
  77. package/dist/update/integrateUpdateVdomPrebuild.d.ts.map +1 -0
  78. package/dist/update/integrateUpdateVdomPrebuild.js +1453 -0
  79. package/package.json +149 -144
@@ -0,0 +1,1453 @@
1
+ // ////////////////////////////////////////////
2
+ // // Variant of integrateUpdateVdom.ts
3
+ // //
4
+ // // To avoid unstyled view flashes, when creating content we want to build full html trees
5
+ // // and insert them whole, not build them up bit by bit
6
+ // ////////////////////////////////////////////
7
+ export {};
8
+ // import type { ExtendableHTMLElement } from '../ExtendableHTMLElement.js'
9
+ // import type { BindVariable } from '../components/bindable/BindVariable.js'
10
+ // //import type { BindFilterFunction } from '../BindFilterFunction.js'
11
+ // import type {
12
+ // FilterCheckedFunc, FilterFuncNumber, FilterFuncString, HTMLBindableElementNumber,
13
+ // HTMLBindableElementString, HTMLCheckedBindableElement
14
+ // } from '../../types/jsx/html.js'
15
+ // import { IsHTMLElement } from '../DomNodes.js'
16
+ // import { DomRegion } from '../DomRegion.js'
17
+ // import { DomPointer } from '../DomPointer.js'
18
+ // import {
19
+ // ContentNode, ContentNodeComponentIsClassComponent, ContentNodeHtml, ContentNodeIsNonRendered,
20
+ // ContentNodeIsLiteral, ContentNodeIsHtml, ContentNodeIsComponent, ContentNodeIsArray,
21
+ // ContentNodeComponentAny, ContentNodeFunctionComponentAny, ContentNodeClassComponentAny,
22
+ // ContentNodeIsElement, ContentNodeElementHasValidKey, NodeValue,
23
+ // ContentNodeComponent,
24
+ // ContentNodeLiteral
25
+ // } from '../ContentNode.js'
26
+ // import { Instance } from '../Instance/Instance.js'
27
+ // import { HtmlEvent, HtmlEventName, StringIsHtmlEvent, htmlEvents } from '../htmlEvents.js'
28
+ // import { out, warn } from '../appOutput.js'
29
+ // import { getStyledContentFromFunctionComponent } from '../getStyledContentFromFunctionComponent.js'
30
+ // import { FunctionElement } from '../FunctionComponentStandIn.js'
31
+ // import { TungstenElement } from '../TungstenElement.js'
32
+ // import { jssToCss } from '../style/jssToCss.js'
33
+ // import { AnyComponent } from '../AnyComponent.js'
34
+ // import { htmlEventHandlerKey } from '../htmlEventHandlerKey.js'
35
+ // import { todo } from '../todo.js'
36
+ // import { $ContentNull, $contentNull } from '../symbols.js'
37
+ // import { throwError } from '../throwError.js'
38
+ // import {
39
+ // $number, $string, RenderedContentNode, RenderedContentNodeIsArray, RenderedContentNodeIsLiteral,
40
+ // makeRenderedContentNodeNonRendered, makeRenderedContentNodeHtml, makeRenderedContentNodeLiteral,
41
+ // RenderedContentNodeHtml, RenderedContentNodeIsNonRendered, WideRenderedContentNodeIsArray,
42
+ // WideRenderedContentNodeIsLiteral, WideRenderedContentNodeIsHtml, WideRenderedContentNodeIsComponent,
43
+ // RenderedContentNodeLiteral, RenderedContentNodeComponent, RenderedContentNodeClassComponent,
44
+ // RenderedContentNodeFunctionComponent, RenderedContentNodeSingleIsHead, RenderedContentNodeSingleIsComponent,
45
+ // RenderedContentNodeSingleIsHtml, RenderedContentNodeArray, RenderedContentNodeIsElement,
46
+ // RenderedContentNodeSingleIsLiteral, RenderedContentNodeNonRendered,
47
+ // $nonRendered, type $NonRendered
48
+ // } from '../RenderedContentNode.js'
49
+ // import { UpdateResult } from './UpdateResult.js'
50
+ // import { hasValidKey } from '../hasValidKey.js'
51
+ // import { $key, $props, $routeData, $routeParams, $type } from '../contentNodeSymbols.js'
52
+ // import { printComponentNamesInSource } from '../render/printComponentNameInSource.js'
53
+ // import { bindableHtmlElementsNumber, bindableHtmlElementsString } from '../components/bindable/bindableHtmlElements.js'
54
+ // import { ExtendedChangeEvent } from '../../types/jsx/html.events.js'
55
+ // import { checkedValueToBoolean } from '../checkedValueToBoolean.js'
56
+ // import { setCurrentComponent } from 'tungsten/hooks/setCurrentComponent.js'
57
+ // import { clearCurrentComponent } from 'tungsten/hooks/clearCurrentComponent.js'
58
+ // type TungstenHtmlDomElement = TungstenHTMLElement | Text | $NonRendered
59
+ // type TungstenHtmlDomElementNode = TungstenHtmlDomElement| TungstenHtmlDomElement[]
60
+ // type TungstenHtmlDomElements = TungstenHtmlDomElementNode | TungstenHtmlDomElementNode[]
61
+ // export type TungstenHTMLElement = HTMLElement & {
62
+ // __tungsten_click_handler: (this: HTMLElement, ev: MouseEvent) => any //// !! Why are we declaring just this event here?
63
+ // [key: string]: unknown // this could be refined to allow only the keys we use - event handler refs
64
+ // }
65
+ // function debug(...texts: unknown[]) { // eslint-disable-line @typescript-eslint/no-unused-vars
66
+ // //console.log(...texts)
67
+ // //console.log(getStackTrace().split('\n')[2])
68
+ // }
69
+ // const timing = true as boolean // eslint-disable-line no-type-assertion/no-type-assertion
70
+ // // need to be adapted to work for func components?
71
+ // export async function integrateElementUpdateVdom(
72
+ // element: AnyComponent, newContent: ContentNode
73
+ // ): Promise<UpdateResult> {
74
+ // let startTime = 0
75
+ // if (timing) startTime = (new Date).getMilliseconds()
76
+ // debug(`integrateElementUpdateVdom`, element)
77
+ // debug(`integrateElementUpdateVdom`, newContent)
78
+ // //console.log('***** integrateElementUpdateVdom', element.constructor.name, '*****')
79
+ // //console.log(newContent, element.__currentContent)
80
+ // // if (element.constructor.name === 'ViewpointComponent') return {
81
+ // // renderedContent: makeRenderedContentNodeNonRendered(),
82
+ // // nodesLength: 0
83
+ // // }
84
+ // //console.log('update element', element.constructor.name)
85
+ // const instance = element.__instance
86
+ // // get the content tree that was previous rendered
87
+ // if (element.__currentContent === $contentNull) {
88
+ // throwError(
89
+ // 'integrateElementContent()',
90
+ // '__currentContent is $contentNull (element that is updating is missing info for current content)'
91
+ // )
92
+ // }
93
+ // const currentContent: RenderedContentNode = element.__currentContent
94
+ // debug(`${element.constructor.name} currentContent`, currentContent)
95
+ // debug('firstElement', element.__domRegion?.firstElement)
96
+ // debug('lastElement', element.__domRegion?.lastElement)
97
+ // debug('currentContent', currentContent)
98
+ // debug('newContent', newContent)
99
+ // // get the information of where in the dom it was rendered
100
+ // if (element.__domRegion === undefined) throwError('integrateUpdate()', '__domRegion in element was undefined')
101
+ // const domRegion: DomRegion = element.__domRegion
102
+ // debug('element domRegion', domRegion)
103
+ // //console.log('element domRegion', domRegion)
104
+ // debug(`get position of first element for '${element.constructor.name}'`)
105
+ // debug('dom region', domRegion)
106
+ // const previousPositionOfFirstElement = domRegion.positionOfFirst()
107
+ // //const previousPositionOfLastElement = domRegion.positionOfLast()
108
+ // //const previousNodesLength = (previousPositionOfFirstElement >= 0) ? 1 + previousPositionOfLastElement - previousPositionOfFirstElement : 0
109
+ // //console.log('previousPositionOfFirstElement', previousPositionOfFirstElement)
110
+ // //console.log('previousPositionOfLastElement', previousPositionOfLastElement)
111
+ // const domPointer = new DomPointer(domRegion.parent, previousPositionOfFirstElement)
112
+ // // bump index by one to jump over start comment
113
+ // domPointer.increment()
114
+ // //console.log('dom pointer', domPointer)
115
+ // //console.log('pointed element', domPointer.get())
116
+ // // const renderedTree = await applyUpdate({
117
+ // // tungstenElement: element,
118
+ // // instance,
119
+ // // newNode: newContent,
120
+ // // oldNode: currentContent,
121
+ // // domRegion,
122
+ // // domPointer,
123
+ // // parentNode: null // we only care about select elements for option elements, not components
124
+ // // })
125
+ // const renderedTree = await applyUpdate({
126
+ // tungstenElement: element,
127
+ // instance,
128
+ // newNode: newContent,
129
+ // oldNode: currentContent,
130
+ // domRegion,
131
+ // domPointer,
132
+ // parentNode: null // we only care about select elements for option elements, not components
133
+ // })
134
+ // debug('renderedTree', renderedTree)
135
+ // element.__currentContent = renderedTree
136
+ // debug(`for el '${element.constructor.name}'`, element)
137
+ // //console.log('update element dom region?', domPointer.parent, domPointer.index)
138
+ // // bump index by one to jump over end comment
139
+ // domPointer.increment()
140
+ // // domPointer
141
+ // //const domIndexStart = domPointer.index
142
+ // //const domIndexCount = domPointer.index - domIndexStart
143
+ // element.__domRegion.updateByIndexes(previousPositionOfFirstElement, domPointer.index -1)
144
+ // debug(`${element.constructor.name} element.__domRegion`, element.__domRegion)
145
+ // debug('firstElement', element.__domRegion?.firstElement)
146
+ // debug('lastElement', element.__domRegion?.lastElement)
147
+ // //console.log(`${element.constructor.name} element.__domRegion`, element.__domRegion)
148
+ // //console.log('firstElement', element.__domRegion?.firstElement)
149
+ // //console.log('lastElement', element.__domRegion?.lastElement)
150
+ // //console.log('Current Content after update for element', element.constructor.name, 'is', element.__currentContent)
151
+ // const newPositionOfFirstElement = domRegion.positionOfFirst()
152
+ // const newPositionOfLastElement = domRegion.positionOfLast()
153
+ // const newNodesLength
154
+ // = (newPositionOfFirstElement >= 0) ? 1 + newPositionOfLastElement - newPositionOfFirstElement : 0
155
+ // //console.log('finished updating element. ', element.constructor.name, ' El positions:', newPositionOfFirstElement, newPositionOfLastElement)
156
+ // if (timing) out(`Updated ${element.constructor.name} in ${(new Date).getMilliseconds() - startTime}ms`)
157
+ // // newNodesLength previousNodesLength
158
+ // return { renderedContent: renderedTree, nodesLength: newNodesLength }
159
+ // }
160
+ // type KeyedOldChildren = Record<string | number, [index: number, node: RenderedContentNode]>
161
+ // function getKeyedOldChildren(array: RenderedContentNodeArray): KeyedOldChildren {
162
+ // const keyedChildren: KeyedOldChildren = {}
163
+ // let i = 0
164
+ // for (const child of array) {
165
+ // if (RenderedContentNodeIsElement(child) && child[$key] !== undefined && child[$key] !== null) {
166
+ // keyedChildren[child[$key]] = [i, child]
167
+ // }
168
+ // i++
169
+ // }
170
+ // return keyedChildren
171
+ // }
172
+ // type ApplyUpdateArgs = {
173
+ // tungstenElement: AnyComponent
174
+ // instance: Instance
175
+ // newNode: ContentNode
176
+ // oldNode: RenderedContentNode | $ContentNull
177
+ // domRegion: DomRegion// | null,
178
+ // domPointer: DomPointer
179
+ // parentNode: ContentNode
180
+ // }
181
+ // async function applyUpdate(
182
+ // { tungstenElement, instance, newNode, oldNode, domRegion, domPointer, parentNode }: ApplyUpdateArgs
183
+ // ) : Promise<RenderedContentNode> {
184
+ // //console.log('applyUpdate')
185
+ // //console.log('newNode', newNode)
186
+ // //console.log('oldNode', oldNode)
187
+ // //console.log('parentNode', parentNode)
188
+ // //console.log('domPointer.index', domPointer.index)
189
+ // debug('existing node', oldNode)
190
+ // if (ContentNodeIsNonRendered(newNode)) {
191
+ // console.log('DD delete node because current node is non rendered')
192
+ // debug('DD delete node because current node is non rendered')
193
+ // deleteNodeIfRendered(oldNode)
194
+ // return makeRenderedContentNodeNonRendered()
195
+ // } else if (ContentNodeIsArray(newNode)) {
196
+ // //newNode
197
+ // debug('*** Content node is array')
198
+ // if (WideRenderedContentNodeIsArray(oldNode)) {
199
+ // debug('*** old node is array')
200
+ // //oldNode
201
+ // //console.log('array update', newNode)
202
+ // //console.log('old array', oldNode)
203
+ // const keyedOldChildren = getKeyedOldChildren(oldNode)
204
+ // const tempOldChildren: (RenderedContentNode | undefined)[] = [...oldNode]
205
+ // if (Object.keys(keyedOldChildren).length > 0) {
206
+ // //console.log('handling a keyed array')
207
+ // // Keyed arrays a bitch
208
+ // // here is a load of code to deal with it
209
+ // // We make a list of keyed entries from the old array
210
+ // // New keyed items updated old items with matching keys, and then are moved to the correct spot
211
+ // // Unkeyed items are compared to the item in the same place in the old array, and are then moved to the correct
212
+ // // spot incase keyed items have changed the sequencing
213
+ // // Each time an old item is updated, it is removed from a temp list of old nodes
214
+ // // Any other nodes will have been shifting to the bottom by the inserting/moving approach
215
+ // // and these are deleted at the end
216
+ // // I hate you React, uggghhhh
217
+ // // 1 // 1 Key is 1, Key 1 exists, Positions equal, Update old key 1
218
+ // // 3 // 2 Key is 3, Old Key 3 exists, Positions not equal, update (first, because could be async), move
219
+ // // 4 // 3 Key is 4, Old Key 4 exists, Positions not equal, update (first, because could be async), move
220
+ // // 5 // 4 Key is 5, Old Key 5 exists, Positions not equal, update (first, because could be async), move
221
+ // // un // 5 Replace
222
+ // // un Trim
223
+ // // 1 // 1 Key is 1, Key 1 exists, Positions equal, Update old key 1 (1,2,3,un,4,5,un)
224
+ // // 3 // 2 Key is 3, Old Key 3 exists, Positions not equal, update (first, because could be async), move (1,3,2,un,4,5,un)
225
+ // // un // 3 No Key, Compare to 3rd item: Diff, create and insert (1,3,un',2,un,4,5,un)
226
+ // // 4 // un Key is 4, Old Key 4 exists, update, move (1,3,un',4,2,un,5,un)
227
+ // // 5 // 4 Key is 5, Old Key 5 exists, Positions not equal, update (first, because could be async), move (1,3,un',4,5,2,un,un)
228
+ // // un // 5 No Key, Compare to 6th item: Diff, create and insert (1,3,un',4,5,un',2,un,un)
229
+ // // un // un No Key, Might Match, Update, Move
230
+ // // Trim excess (1,3,un',4,5,un',2,un,un) Unused Keys: 2
231
+ // //const usedKeys: Record<string | number, true> = {}
232
+ // //const usedOldChildren
233
+ // // // check for keys
234
+ // // const keyed = checkForKeys(newNode, oldNode)
235
+ // // // extract children with keys into a keyed objected
236
+ // // const newChildren = getKeyedAndUnkeyedChildren(newNode)
237
+ // // const oldChildren = getKeyedAndUnkeyedRrenderedChildren(oldNode)
238
+ // // update
239
+ // const renderedNodes: RenderedContentNode = []
240
+ // // do we need to start with keyed entries, then do non keyed?
241
+ // let i = 0
242
+ // for (const childNode of newNode) {
243
+ // //console.log('child node', childNode, ' of ', newNode)
244
+ // let renderedContent
245
+ // let keyedOldChild
246
+ // if (
247
+ // ContentNodeIsElement(childNode)
248
+ // && ContentNodeElementHasValidKey(childNode)
249
+ // && (keyedOldChild = keyedOldChildren[childNode[$key]]) !== undefined
250
+ // ) {
251
+ // //console.log('update a keyed item', childNode)
252
+ // const [oldChildIndex, oldChild] = keyedOldChild
253
+ // // create a throwaway DomPointer because we are going to manage our DomPointer differently
254
+ // const tempDomPointer = new DomPointer(domPointer.parent, domPointer.index)
255
+ // // update
256
+ // renderedContent = await applyUpdate({
257
+ // tungstenElement,
258
+ // instance,
259
+ // newNode: childNode,
260
+ // oldNode: oldChild,
261
+ // domRegion,
262
+ // domPointer: tempDomPointer,
263
+ // parentNode
264
+ // })
265
+ // // move
266
+ // //console.log('moving the keyed item', childNode[$key])
267
+ // moveRenderedContent(renderedContent, domPointer)
268
+ // // delete oldChild from temp list
269
+ // delete tempOldChildren[oldChildIndex]
270
+ // } else {
271
+ // //console.log('update an unkeyed item in a keyed array', childNode)
272
+ // // create a throwaway DomPointer because we are going to manage our DomPointer differently
273
+ // const tempDomPointer = new DomPointer(domPointer.parent, domPointer.index)
274
+ // const oldChild = oldNode[i]
275
+ // if (
276
+ // oldChild !== undefined
277
+ // && ( !RenderedContentNodeIsElement(oldChild) || !hasValidKey(oldChild) )
278
+ // ) {
279
+ // //console.log('update/replace a non keyed item', _nki)
280
+ // //throwError('b', 'b')
281
+ // // update/replace as required
282
+ // renderedContent = await applyUpdate({
283
+ // tungstenElement,
284
+ // instance,
285
+ // newNode: childNode,
286
+ // oldNode: oldChild,
287
+ // domRegion,
288
+ // domPointer: tempDomPointer,
289
+ // parentNode
290
+ // })
291
+ // // move -- we need to move it, because we may have removed or inserted elements
292
+ // // pushing the original out of place
293
+ // //console.log('moving the non keyed item', _nki)
294
+ // moveRenderedContent(renderedContent, domPointer)
295
+ // // remove replaced node from list
296
+ // delete tempOldChildren[i]
297
+ // } else {
298
+ // //console.log('create a non keyed item', newNode)
299
+ // //console.log('dp', domPointer)
300
+ // //throwError('c', 'c')
301
+ // // create
302
+ // renderedContent = await createRenderedContentNode({
303
+ // tungstenElement,
304
+ // instance,
305
+ // newNode: childNode,
306
+ // domPointer,
307
+ // parentNode
308
+ // })
309
+ // }
310
+ // }
311
+ // renderedNodes.push(renderedContent)
312
+ // i++
313
+ // }
314
+ // //console.log('to trim', [...tempOldChildren])
315
+ // // trim
316
+ // for (const oldChild of tempOldChildren) {
317
+ // if (oldChild) {
318
+ // console.log('deleting old child', oldChild)
319
+ // deleteNodeIfRendered(oldChild)
320
+ // }
321
+ // }
322
+ // return renderedNodes
323
+ // } else {
324
+ // const renderedNodes: RenderedContentNode[] = []
325
+ // let i = 0
326
+ // for (const child of newNode) {
327
+ // const oldChild = oldNode[i]
328
+ // if (oldChild !== undefined) {
329
+ // renderedNodes.push(await applyUpdate({
330
+ // tungstenElement,
331
+ // instance,
332
+ // newNode: child,
333
+ // oldNode: oldChild,
334
+ // domRegion,
335
+ // domPointer,
336
+ // parentNode
337
+ // }))
338
+ // } else {
339
+ // renderedNodes.push(await createRenderedContentNode({
340
+ // tungstenElement,
341
+ // instance,
342
+ // newNode: child,
343
+ // domPointer,
344
+ // parentNode
345
+ // }))
346
+ // }
347
+ // i++
348
+ // }
349
+ // while (i < oldNode.length) {
350
+ // console.log('deleting old child 2', oldNode[i])
351
+ // deleteNodeIfRendered(oldNode[i]!)
352
+ // i++
353
+ // }
354
+ // return renderedNodes
355
+ // }
356
+ // } else {
357
+ // console.log('DD delete node because current node is array and existing node is not', oldNode)
358
+ // debug('DD delete node because current node is array and existing node is not')
359
+ // deleteNodeIfRendered(oldNode)
360
+ // // insert
361
+ // // domRegion ???
362
+ // // domPointer ???
363
+ // // return Promise.all(newNode.map(
364
+ // // (x: ContentNode) => createNode({
365
+ // // tungstenElement,
366
+ // // instance,
367
+ // // newNode: x,
368
+ // // domPointer
369
+ // // })
370
+ // // ))
371
+ // const renderedNodes: RenderedContentNode = []
372
+ // for (const childNode of newNode) {
373
+ // renderedNodes.push(await createRenderedContentNode({
374
+ // tungstenElement,
375
+ // instance,
376
+ // newNode: childNode,
377
+ // domPointer,
378
+ // parentNode
379
+ // }))
380
+ // }
381
+ // return renderedNodes
382
+ // }
383
+ // } else if (ContentNodeIsLiteral(newNode)) {
384
+ // //let domNode: Text
385
+ // if (WideRenderedContentNodeIsLiteral(oldNode)) {
386
+ // //console.log('setting dom text content to ', newNode.toString())
387
+ // oldNode.domNode.textContent = newNode.toString()
388
+ // domPointer.increment()
389
+ // debug(`!!!!dom pointer index is`, domPointer.index, 'after updating literal node')
390
+ // return makeRenderedContentNodeLiteral(newNode, oldNode.domNode)
391
+ // } else {
392
+ // // insert text node
393
+ // debug(`!!!!dom pointer index is before creating literal`)
394
+ // const { text, textNode } = createLiteral(newNode)
395
+ // console.log('DD delete node because current node is literal and existing node is not', oldNode)
396
+ // debug('DD delete node because current node is literal and existing node is not')
397
+ // deleteNodeIfRendered(oldNode)
398
+ // debug('dom parent', domPointer.parent)
399
+ // debug('dom index', domPointer.index)
400
+ // if (domPointer.parent.childNodes.length === domPointer.index) {
401
+ // domPointer.parent.appendChild(textNode)
402
+ // } else {
403
+ // domPointer.parent.insertBefore(textNode, domPointer.parent.childNodes[domPointer.index]!)
404
+ // }
405
+ // domPointer.increment()
406
+ // //domPointer.increment()
407
+ // // return (typeof value === 'string')
408
+ // // ? {
409
+ // // [$type]: $string,
410
+ // // value,
411
+ // // domNode: textNode
412
+ // // } : {
413
+ // // [$type]: $number,
414
+ // // value,
415
+ // // domNode: textNode
416
+ // // }
417
+ // return {
418
+ // [$type]: $string, // should we keep the number version? // or switch to $text
419
+ // value: text,
420
+ // domNode: textNode
421
+ // }
422
+ // //domNode = createTextElement(newNode.toString(), domPointer)
423
+ // //return makeRenderedContentNodeLiteral(newNode, domNode)
424
+ // }
425
+ // } else if (ContentNodeIsHtml(newNode)) {
426
+ // //newNode
427
+ // //console.log('comparing html el', newNode, 'to', oldNode)
428
+ // //console.log('applying an html node', newNode)
429
+ // processHtmlNode(newNode, parentNode)
430
+ // debug('old node is html', WideRenderedContentNodeIsHtml(oldNode))
431
+ // if (WideRenderedContentNodeIsHtml(oldNode)) {
432
+ // debug('node types', newNode[$type].toLocaleLowerCase(), oldNode[$type].toLocaleLowerCase(), newNode[$type].toLocaleLowerCase() === oldNode[$type].toLocaleLowerCase())
433
+ // }
434
+ // if (
435
+ // WideRenderedContentNodeIsHtml(oldNode)
436
+ // && newNode[$type].toLocaleLowerCase() === oldNode[$type].toLocaleLowerCase()
437
+ // ) {
438
+ // //newNode[$props].it = it
439
+ // //console.log('updating html node', newNode[$type])
440
+ // //console.log('old node', oldNode[$type])
441
+ // debug('updating html node', newNode[$type])
442
+ // // !!!! update
443
+ // const domNode = oldNode.domNode
444
+ // updateAttributes(newNode, oldNode, domNode)
445
+ // domPointer.increment()
446
+ // debug(`!!!!dom pointer index is`, domPointer.index, 'after updating html node')
447
+ // // !!! handle children
448
+ // const newChildren = newNode[$props].children
449
+ // //console.log(newNode[$type], 'children', newChildren)
450
+ // const oldChildren = oldNode.renderedChildren
451
+ // //console.log('oldChildren', oldChildren)
452
+ // const renderedChildren = await applyUpdate({
453
+ // tungstenElement: tungstenElement,
454
+ // instance,
455
+ // newNode: newChildren,
456
+ // oldNode: oldChildren,
457
+ // domRegion: new DomRegion(domNode),
458
+ // domPointer: new DomPointer(domNode, 0),
459
+ // parentNode: newNode
460
+ // })
461
+ // return makeRenderedContentNodeHtml(newNode, domNode, renderedChildren)
462
+ // } else {
463
+ // // insert html node
464
+ // const htmlTree = await createHtmlTree({
465
+ // tungstenElement,
466
+ // contentNode: newNode,
467
+ // instance,
468
+ // //domPointer,
469
+ // parentNode
470
+ // })
471
+ // //console.log('deleting node and creating html', newNode[$type], oldNode)
472
+ // debug('deleting node and creating html node', newNode[$type], oldNode)
473
+ // deleteNodeIfRendered(oldNode)
474
+ // const renderedNode = insertHtmlTree({
475
+ // contentNode: newNode,
476
+ // tree: htmlTree,
477
+ // domRegion,
478
+ // domPointer
479
+ // })
480
+ // //children
481
+ // // const renderedHtmlElement: RenderedContentNode = await createRenderedContentNode({
482
+ // // tungstenElement: tungstenElement,
483
+ // // instance,
484
+ // // newNode: newNode,
485
+ // // domPointer: new DomPointer(htmlEl, htmlEl.childNodes.length),
486
+ // // parentNode: parentNode
487
+ // // })
488
+ // return renderedNode
489
+ // }
490
+ // } else if (ContentNodeIsComponent(newNode)) {
491
+ // //console.log('Comp A', WideRenderedContentNodeIsComponent(oldNode))
492
+ // if (
493
+ // WideRenderedContentNodeIsComponent(oldNode)
494
+ // && newNode[$type] === oldNode[$type]
495
+ // && (
496
+ // (oldNode[$key] !== undefined && newNode[$key] !== undefined) // if either is keyed and the keys don't match, replace
497
+ // || (oldNode[$key] === newNode[$key])
498
+ // )
499
+ // ) {
500
+ // //console.log('updating tu el', newNode, oldNode[$key], newNode[$key])
501
+ // // update
502
+ // const { content, complete } = await oldNode.element.__updateAndReturnContent()
503
+ // return await applyUpdate({
504
+ // tungstenElement: oldNode.element,
505
+ // instance,
506
+ // newNode: content,
507
+ // oldNode,
508
+ // domRegion,
509
+ // domPointer,
510
+ // parentNode: null // don't care about this except for <select> parent for <option>
511
+ // })
512
+ // complete()
513
+ // // return updateComponent({
514
+ // // newNode,
515
+ // // parent: tungstenElement,
516
+ // // instance,
517
+ // // oldNode,
518
+ // // domPointer
519
+ // // })
520
+ // } else {
521
+ // const htmlTree
522
+ // = await createTungstenComponent({ parent: tungstenElement, instance, node: newNode })
523
+ // //console.log('deleting and replacing node', oldNode)
524
+ // console.log('deleting node and creating component', newNode[$type].constructor.name, oldNode)
525
+ // debug('deleting node and creating component', newNode[$type].constructor.name, oldNode)
526
+ // deleteNodeIfRendered(oldNode)
527
+ // // insert new
528
+ // //console.log('Creating tung comp in applyUpdate')
529
+ // // const renderedElement
530
+ // // = await createTungstenComponent({ parent: tungstenElement, instance, node: newNode, domPointer })
531
+ // // apply tree
532
+ // const renderedNode = insertHtmlTree(newNode, htmlTree, domRegion, domPointer)
533
+ // debug('renderedNode', renderedNode)
534
+ // return renderedNode
535
+ // }
536
+ // }
537
+ // // should never be reached
538
+ // const n: never = newNode // eslint-disable-line @typescript-eslint/no-unused-vars
539
+ // return makeRenderedContentNodeNonRendered()
540
+ // }
541
+ // type UpdateComponentArgs = {
542
+ // newNode: ContentNodeComponent
543
+ // parent: AnyComponent
544
+ // instance: Instance
545
+ // oldNode: ContentNodeComponent
546
+ // domPointer: DomPointer
547
+ // }
548
+ // async function updateComponent({ newNode, parent, instance, oldNode, domPointer }: UpdateComponentArgs) {
549
+ // if (ContentNodeComponentIsClassComponent(newNode)) {
550
+ // debug('updating component', newNode[$type].name)
551
+ // return await updateClassComponent({
552
+ // parent,
553
+ // instance,
554
+ // newNode,
555
+ // oldNode: oldNode as RenderedContentNodeClassComponent, // eslint-disable-line no-type-assertion/no-type-assertion -- oldNode is proven to be class comp, because type is the same as newNode
556
+ // domPointer,
557
+ // })
558
+ // } else {
559
+ // debug('updating function component', newNode[$type].name)
560
+ // return await updateFunctionComponent({
561
+ // parent,
562
+ // instance,
563
+ // newNode,
564
+ // oldNode: oldNode as RenderedContentNodeFunctionComponent, // eslint-disable-line no-type-assertion/no-type-assertion -- oldNode is proven to be function comp, because type is the same as newNode
565
+ // domPointer,
566
+ // })
567
+ // }
568
+ // }
569
+ // function moveRenderedContent(renderedContent: RenderedContentNode, domPointer: DomPointer): void {
570
+ // //console.log('moving, index', domPointer.index, renderedContent)
571
+ // if (RenderedContentNodeIsArray(renderedContent)) {
572
+ // for (const renderedContentChild of renderedContent) {
573
+ // moveRenderedContent(renderedContentChild, domPointer)
574
+ // }
575
+ // } else if (RenderedContentNodeSingleIsLiteral(renderedContent)) {
576
+ // moveDomNode(renderedContent.domNode, domPointer)
577
+ // } else if (RenderedContentNodeSingleIsHtml(renderedContent)) {
578
+ // moveDomNode(renderedContent.domNode, domPointer)
579
+ // } else if (RenderedContentNodeSingleIsComponent(renderedContent)) {
580
+ // //console.log('moving a rendered component')
581
+ // if (renderedContent.element.__currentContent !== $contentNull) {
582
+ // domPointer.increment() // starting comment
583
+ // moveRenderedContent(renderedContent.element.__currentContent, domPointer)
584
+ // domPointer.increment() // ending comment
585
+ // }
586
+ // } else if (RenderedContentNodeSingleIsHead(renderedContent)) {
587
+ // throwError('moveRenderedContent()', 'Should not try to update the position of the html head')
588
+ // //moveDomNode(renderedContent.domNode, domPointer)
589
+ // } else {
590
+ // renderedContent
591
+ // const n: RenderedContentNodeNonRendered = renderedContent // eslint-disable-line @typescript-eslint/no-unused-vars
592
+ // }
593
+ // //console.log('moving done, index', domPointer.index, renderedContent)
594
+ // }
595
+ // function moveDomNode(domNode: HTMLElement | Text, domPointer: DomPointer) {
596
+ // //console.log('moving domNode', domNode)
597
+ // if (domPointer.positionOf(domNode) !== domPointer.index) {
598
+ // //console.log('document.activeElement', document.activeElement, domNode == document.activeElement, domNode === document.activeElement)
599
+ // const hasFocus = domNode === document.activeElement
600
+ // const activeElement = document.activeElement
601
+ // if (domPointer.index >= domPointer.parent.childNodes.length) {
602
+ // //console.log('appending', domNode)
603
+ // domPointer.parent.appendChild(domNode)
604
+ // } else {
605
+ // //console.log('inserting at', domPointer.index, domNode)
606
+ // domPointer.parent.insertBefore(domNode, domPointer.parent.childNodes[domPointer.index]!)
607
+ // }
608
+ // //console.log('had focus', hasFocus)
609
+ // if (hasFocus) domNode.focus()
610
+ // //console.log('post document.activeElement', document.activeElement)
611
+ // if ( activeElement) (activeElement as Element & { focus: () => void } ).focus() // eslint-disable-line no-type-assertion/no-type-assertion -- activeElement was a focused dom node, so it should have a focus method??
612
+ // }
613
+ // domPointer.increment()
614
+ // }
615
+ // function deleteNodeIfRendered(node: $ContentNull | RenderedContentNode) {
616
+ // console.log('-deleteNodeIfRendered', node)
617
+ // debug('-deleteNodeIfRendered', node)
618
+ // if (node !== $contentNull && !RenderedContentNodeIsNonRendered(node)) {
619
+ // //node
620
+ // if (RenderedContentNodeIsArray(node)) {
621
+ // debug('delete array of rendered nodes')
622
+ // for (const child of node) {
623
+ // deleteNodeIfRendered(child)
624
+ // }
625
+ // } else if (RenderedContentNodeIsLiteral(node)) {
626
+ // node.domNode.remove()
627
+ // // find text node
628
+ // // and delete it?
629
+ // } else if (RenderedContentNodeSingleIsHead(node)) {
630
+ // throwError('deleteNodeIfRendered', 'has been asked to remove the head node, this should not occur')
631
+ // } else if (RenderedContentNodeSingleIsHtml(node)) {
632
+ // debug('delete node html', node)
633
+ // //node
634
+ // node.domNode.remove()
635
+ // } else if (RenderedContentNodeSingleIsComponent(node)) {
636
+ // //console.log('***delete component', node.element.__currentContent)
637
+ // debug('***delete component', node.element.__currentContent)
638
+ // //console.log('***delete component', node.element.__currentContent)
639
+ // //node
640
+ // node.element.__delete()
641
+ // deleteNodeIfRendered(node.element.__currentContent)
642
+ // //console.log('deleting opening comment', node.openingComment)
643
+ // node.openingComment.remove()
644
+ // //console.log('deleting closing comment', node.closingComment)
645
+ // node.closingComment.remove()
646
+ // //console.log(`indicate to ${node.element.constructor.name} that it has been deleted`)
647
+ // node.element.__deleted()
648
+ // //todo('remove rendered component')
649
+ // }
650
+ // }
651
+ // }
652
+ // type CreateNodeArgs = {
653
+ // tungstenElement: AnyComponent,
654
+ // instance: Instance
655
+ // newNode: ContentNode
656
+ // domPointer: DomPointer
657
+ // parentNode: ContentNode
658
+ // }
659
+ // async function createRenderedContentNode({ tungstenElement, instance, newNode, domPointer, parentNode }: CreateNodeArgs)
660
+ // : Promise<RenderedContentNode> {
661
+ // debug('-createNode')
662
+ // //console.log('createNode', newNode)
663
+ // debug('domPointer', domPointer.parent, domPointer.index)
664
+ // if (ContentNodeIsNonRendered(newNode)) {
665
+ // debug('node is NonRendered')
666
+ // return makeRenderedContentNodeNonRendered()
667
+ // } else if (ContentNodeIsArray(newNode)) {
668
+ // debug('node is array')
669
+ // const renderedNodes: RenderedContentNode = []
670
+ // for (const childNode of newNode) {
671
+ // renderedNodes.push(await createRenderedContentNode({
672
+ // tungstenElement,
673
+ // instance,
674
+ // newNode: childNode,
675
+ // domPointer,
676
+ // parentNode
677
+ // }))
678
+ // }
679
+ // return renderedNodes
680
+ // } else if (ContentNodeIsLiteral(newNode)) {
681
+ // return createLiteral(newNode, domPointer)
682
+ // } else if (ContentNodeIsHtml(newNode)) {
683
+ // return await createHtmlElement(tungstenElement, instance, newNode, domPointer, parentNode)
684
+ // } else if (ContentNodeIsComponent(newNode)) {
685
+ // //console.log('Creating tung comp in createNode')
686
+ // return await createTungstenComponent( { parent: tungstenElement, instance, node: newNode })
687
+ // }
688
+ // const n: never = newNode // eslint-disable-line @typescript-eslint/no-unused-vars
689
+ // return makeRenderedContentNodeNonRendered()
690
+ // }
691
+ // type CreateHtmlTreeArgs = {
692
+ // tungstenElement: AnyComponent,
693
+ // contentNode: ContentNode
694
+ // instance: Instance
695
+ // //domPointer: DomPointer
696
+ // parentNode: ContentNode
697
+ // }
698
+ // async function createHtmlTree({ tungstenElement, contentNode, instance, parentNode }: CreateHtmlTreeArgs)
699
+ // : Promise<TungstenHtmlDomElements> {
700
+ // debug('-createNode')
701
+ // //console.log('createNode', contentNode)
702
+ // //debug('domPointer', domPointer.parent, domPointer.index)
703
+ // if (ContentNodeIsNonRendered(contentNode)) {
704
+ // debug('node is NonRendered')
705
+ // return $nonRendered
706
+ // } else if (ContentNodeIsArray(contentNode)) {
707
+ // debug('node is array')
708
+ // const nodeArray: TungstenHtmlDomElements[] = []
709
+ // for (const childNode of contentNode) {
710
+ // nodeArray.push(await createHtmlTree({
711
+ // tungstenElement,
712
+ // contentNode: childNode,
713
+ // instance,
714
+ // //domPointer,
715
+ // parentNode
716
+ // }))
717
+ // }
718
+ // return nodeArray
719
+ // } else if (ContentNodeIsLiteral(contentNode)) {
720
+ // return createLiteral(contentNode)
721
+ // } else if (ContentNodeIsHtml(contentNode)) {
722
+ // const htmlEl = await createHtmlElement(instance, contentNode, parentNode)
723
+ // completeHtmlTree(contentNode, parentNode, htmlEl, instance)
724
+ // return makeRenderedContentNodeHtml(contentNode, htmlEl, renderedChildren)
725
+ // } else if (ContentNodeIsComponent(contentNode)) {
726
+ // //console.log('Creating tung comp in createNode')
727
+ // return createTungstenComponent( { parent: tungstenElement, instance, node: contentNode })
728
+ // }
729
+ // const n: never = contentNode // eslint-disable-line @typescript-eslint/no-unused-vars
730
+ // return makeRenderedContentNodeNonRendered()
731
+ // }
732
+ // async function completeHtmlTree(
733
+ // tungstenElement: AnyComponent,
734
+ // contentNode: ContentNodeHtml, parentContentNode: ContentNode,
735
+ // domNode: TungstenHTMLElement, instance: Instance
736
+ // ): Promise<RenderedContentNodeHtml> {
737
+ // const { children } = contentNode[$props]
738
+ // let renderedChildren: RenderedContentNode
739
+ // // if (Array.isArray(children)) {
740
+ // // } else {
741
+ // if (ContentNodeIsNonRendered(children)) {
742
+ // debug('node is NonRendered')
743
+ // renderedChildren = $nonRendered
744
+ // } else if (ContentNodeIsArray(children)) {
745
+ // debug('node is array')
746
+ // const nodeArray: RenderedContentNode[] = []
747
+ // for (const childNode of children) {
748
+ // if (ContentNodeIsNonRendered(childNode)) {
749
+ // } else if (ContentNodeIsArray(children)) {
750
+ // } else if (ContentNodeIsLiteral(children)) {
751
+ // } else if (ContentNodeIsHtml(children)) {
752
+ // } else if (ContentNodeIsComponent(children)) {
753
+ // }
754
+ // nodeArray.push(await completeHtmlTree(
755
+ // tungstenElement,
756
+ // childNode,
757
+ // contentNode,
758
+ // parentDomNode,
759
+ // instance,
760
+ // ))
761
+ // }
762
+ // renderedChildren = nodeArray
763
+ // } else if (ContentNodeIsLiteral(children)) {
764
+ // const { text, textNode } = createLiteral(children)
765
+ // domNode.append(textNode)
766
+ // renderedChildren = makeRenderedContentNodeLiteral(text, textNode)
767
+ // } else if (ContentNodeIsHtml(children)) {
768
+ // const htmlEl = await createHtmlElement(instance, children, parentContentNode)
769
+ // domNode.append(htmlEl)
770
+ // const renderedNode = await completeHtmlTree(tungstenElement, children, parentContentNode, htmlEl, instance)
771
+ // renderedChildren = renderedNode
772
+ // return makeRenderedContentNodeHtml(children, htmlEl, renderedChildren)
773
+ // } else if (ContentNodeIsComponent(children)) {
774
+ // const htmlTree = await createTungstenComponent( { parent: tungstenElement, instance, node: children })
775
+ // const renderedNode = await completeHtmlTree(tungstenElement, htmlTree, parentContentNode, htmlEl, instance)
776
+ // //return createTungstenComponent( { parent: tungstenElement, instance, node: children })
777
+ // renderedChildren = renderedNode
778
+ // }
779
+ // const n: never = children // eslint-disable-line @typescript-eslint/no-unused-vars
780
+ // //}
781
+ // return {
782
+ // [$type]: contentNode[$type],
783
+ // [$props]: contentNode[$props],
784
+ // domNode,
785
+ // renderedChildren
786
+ // }
787
+ // }
788
+ // type InsertTreeArgs = {
789
+ // contentNode: ContentNode,
790
+ // tree: TungstenHtmlDomElements,
791
+ // domRegion: DomRegion,
792
+ // domPointer: DomPointer
793
+ // }
794
+ // function insertHtmlTree({contentNode, tree, domRegion, domPointer}: InsertTreeArgs): RenderedContentNode {
795
+ // if (Array.isArray(tree)) {
796
+ // } else {
797
+ // if (tree !== $nonRendered) {
798
+ // debug('dom parent', domPointer.parent)
799
+ // debug('dom parent children length', domPointer.parent.childNodes.length)
800
+ // debug('domPointer.index', domPointer.index)
801
+ // if (domPointer.index >= domPointer.parent.childNodes.length) {
802
+ // domPointer.parent.appendChild(tree)
803
+ // } else {
804
+ // debug('new html el', tree)
805
+ // debug('insert before', domPointer.parent.childNodes[domPointer.index])
806
+ // domPointer.parent.insertBefore(tree, domPointer.parent.childNodes[domPointer.index]!)
807
+ // debug('created el', domPointer.get())
808
+ // }
809
+ // domPointer.increment()
810
+ // //!!!! node.domElement = el
811
+ // //if (IsHTMLElement(domPointer.parent)) debug('***', newNode[$type], 'html created', htmlEl)
812
+ // if (tree.nodeType == 1) {
813
+ // const textNode = tree as Text
814
+ // return {
815
+ // [$type]: $string,
816
+ // value: String(contentNode as ContentNodeLiteral),
817
+ // domNode: textNode
818
+ // }
819
+ // } else {
820
+ // const htmlNode = tree as TungstenHTMLElement
821
+ // return {
822
+ // [$type]: htmlNode.tagName,
823
+ // [$props]: contentNode[$props],
824
+ // domNode: htmlNode
825
+ // }
826
+ // }
827
+ // } else {
828
+ // return $nonRendered
829
+ // }
830
+ // }
831
+ // }
832
+ // type CreateCommentArgs = {
833
+ // text: string
834
+ // domPointer: DomPointer
835
+ // }
836
+ // function createComment({ text, domPointer }: CreateCommentArgs): Comment {
837
+ // debug('-createComment')
838
+ // //console.log('createComment', text)
839
+ // const comment = document.createComment(text)
840
+ // if (domPointer.index >= domPointer.parent.childNodes.length) {
841
+ // domPointer.parent.appendChild(comment)
842
+ // } else {
843
+ // domPointer.parent.insertBefore(comment, domPointer.parent.childNodes[domPointer.index]!)
844
+ // }
845
+ // domPointer.increment()
846
+ // return comment
847
+ // }
848
+ // export function processHtmlNode(node: ContentNodeHtml, parentNode: ContentNode) {
849
+ // // insert value attr content into the textarea content
850
+ // debug('processHtmlNode', node)
851
+ // //console.log('processHtmlNode', node)
852
+ // const props = node[$props]
853
+ // // set a button without specified type to button, so buttons don't submit forms unless instructed to
854
+ // if (node[$type] === 'button' && !props.type) props.type = 'button'
855
+ // if (props.bind !== undefined) {
856
+ // const eventName = 'onInput'
857
+ // //// we have event handler code here as well as in addAttributes -- should this be moved to updateAttributes??
858
+ // if (node[$type] in bindableHtmlElementsString) {
859
+ // type Element = HTMLBindableElementString
860
+ // debug('binding')
861
+ // const [bindObject, bindKey] = (props.bind as BindVariable<any>)
862
+ // props.value = bindObject[bindKey] ?? '' // nullish coalesce to avoid putting undef/null into elements
863
+ // let handler: (event: ExtendedChangeEvent<any>) => void | Promise<void>
864
+ // if ('filter' in props) {
865
+ // const filterFunc = props.filter as FilterFuncString<any, any>
866
+ // handler = async (event: ExtendedChangeEvent<any>) => {
867
+ // bindObject[bindKey] = await filterFunc((event.target as Element).value, event)
868
+ // }
869
+ // } else {
870
+ // handler = (event: ExtendedChangeEvent<any>) => {
871
+ // bindObject[bindKey] = (event.target as Element).value
872
+ // }
873
+ // }
874
+ // if (eventName in props) {
875
+ // props[eventName] = async (event: ExtendedChangeEvent<any>) => {
876
+ // await handler(event)
877
+ // props[eventName]
878
+ // }
879
+ // } else {
880
+ // props[eventName] = handler
881
+ // }
882
+ // // should we be saving the handler like we do in hydrate?
883
+ // //props[eventName] = handler
884
+ // delete props.bind
885
+ // delete props.filter
886
+ // } else if (node[$type] in bindableHtmlElementsNumber) {
887
+ // type Element = HTMLBindableElementNumber
888
+ // debug('binding')
889
+ // const [bindObject, bindKey] = (props.bind as BindVariable<any>)
890
+ // props.value = bindObject[bindKey] ?? '' // nullish coalesce to avoid putting undef/null into elements
891
+ // let handler: (event: ExtendedChangeEvent<any>) => void | Promise<void>
892
+ // if ('filter' in props) {
893
+ // const filterFunc = props.filter as FilterFuncNumber<any, any>
894
+ // handler = async (event: ExtendedChangeEvent<any>) => {
895
+ // bindObject[bindKey] = await filterFunc((event.target as Element).value, event)
896
+ // }
897
+ // } else {
898
+ // handler = (event: ExtendedChangeEvent<any>) => {
899
+ // bindObject[bindKey] = (event.target as Element).value
900
+ // }
901
+ // }
902
+ // if (eventName in props) {
903
+ // props[eventName] = async (event: ExtendedChangeEvent<any>) => {
904
+ // await handler(event)
905
+ // props[eventName]
906
+ // }
907
+ // } else {
908
+ // props[eventName] = handler
909
+ // }
910
+ // //props[eventName] = handler
911
+ // delete props.bind
912
+ // delete props.filter
913
+ // }
914
+ // }
915
+ // if (props.bindChecked !== undefined) {
916
+ // const eventName = 'onChange'
917
+ // debug('bindChecked')
918
+ // const [bindObject, bindKey] = (props.bindChecked as BindVariable<any>)
919
+ // props.checked = checkedValueToBoolean(bindObject[bindKey])
920
+ // let handler: (event: ExtendedChangeEvent<any>) => void | Promise<void>
921
+ // if ('filterChecked' in props) {
922
+ // const filterFunc = props.filterChecked as FilterCheckedFunc<any, any>
923
+ // handler = async (event: ExtendedChangeEvent<any>) => {
924
+ // bindObject[bindKey] = await filterFunc((event.target as HTMLCheckedBindableElement).checked, event)
925
+ // }
926
+ // } else {
927
+ // handler = (event: ExtendedChangeEvent<any>) => {
928
+ // bindObject[bindKey] = (event.target as HTMLCheckedBindableElement).checked
929
+ // }
930
+ // }
931
+ // if (eventName in props) {
932
+ // props[eventName] = async (event: ExtendedChangeEvent<any>) => {
933
+ // await handler(event)
934
+ // props[eventName]
935
+ // }
936
+ // } else {
937
+ // props[eventName] = handler
938
+ // }
939
+ // delete props.bindChecked
940
+ // delete props.filterChecked
941
+ // }
942
+ // if (props.bindRadio !== undefined) {
943
+ // const eventName = 'onChange'
944
+ // debug('bindRadio')
945
+ // const [bindObject, bindKey] = (props.bindRadio as BindVariable<any>)
946
+ // props.checked = bindObject[bindKey] === props.value
947
+ // type EventHandler = (event: ExtendedChangeEvent<any>) => void
948
+ // const handler: EventHandler = (event: ExtendedChangeEvent<any>) => {
949
+ // //console.log('bound radio changed 3', (event.target as HTMLCheckedBindableElement).value)
950
+ // bindObject[bindKey] = (event.target as HTMLCheckedBindableElement).value
951
+ // }
952
+ // if (eventName in props) {
953
+ // props[eventName] = async (event: ExtendedChangeEvent<any>) => {
954
+ // await handler(event)
955
+ // ;(props[eventName] as EventHandler)(event)
956
+ // }
957
+ // } else {
958
+ // props[eventName] = handler
959
+ // }
960
+ // delete props.bindRadio
961
+ // }
962
+ // if (node[$type] === 'textarea') {
963
+ // if ('children' in props) {
964
+ // if ('value' in props) {
965
+ // warn('textarea element has both value attribute and children, value attribute will be used.')
966
+ // //delete props.children
967
+ // props.children = props.value
968
+ // }
969
+ // }
970
+ // }
971
+ // // This code relies on the select node being the immediate parent.
972
+ // // This may not be the case (there could be a wrapping component), and could be improved
973
+ // if (node[$type] === 'option') {
974
+ // if (ContentNodeIsHtml(parentNode) && parentNode[$type] === 'select') {
975
+ // if (parentNode[$props].value !== undefined) {
976
+ // if (props.value === parentNode[$props].value) {
977
+ // props.selected = 'selected'
978
+ // }
979
+ // }
980
+ // }
981
+ // }
982
+ // //console.log('processed:', node)
983
+ // debug('post processHtmlNode', node)
984
+ // }
985
+ // function createLiteral(value: string | number): { text: string, textNode: Text } {
986
+ // const text = String(value)
987
+ // return {
988
+ // text,
989
+ // textNode: document.createTextNode(text)
990
+ // }
991
+ // // debug('-createLiteral:', value)
992
+ // // //const textNode = createTextElement(String(value), domPointer)
993
+ // // debug('dom parent', domPointer.parent)
994
+ // // debug('dom index', domPointer.index)
995
+ // // const textNode = document.createTextNode(text)
996
+ // // if (domPointer.parent.childNodes.length === domPointer.index) {
997
+ // // domPointer.parent.appendChild(textNode)
998
+ // // } else {
999
+ // // domPointer.parent.insertBefore(textNode, domPointer.parent.childNodes[domPointer.index]!)
1000
+ // // }
1001
+ // // domPointer.increment()
1002
+ // // //domPointer.increment()
1003
+ // // return (typeof value === 'string')
1004
+ // // ? {
1005
+ // // [$type]: $string,
1006
+ // // value,
1007
+ // // domNode: textNode
1008
+ // // } : {
1009
+ // // [$type]: $number,
1010
+ // // value,
1011
+ // // domNode: textNode
1012
+ // // }
1013
+ // }
1014
+ // // function createTextElement(text: string, domPointer: DomPointer) {
1015
+ // // }
1016
+ // async function createHtmlElement(
1017
+ // //tungstenElement: AnyComponent,
1018
+ // instance: Instance,
1019
+ // node: ContentNodeHtml,
1020
+ // //domPointer: DomPointer,
1021
+ // parentNode: ContentNode
1022
+ // ) : Promise<TungstenHTMLElement> {
1023
+ // //console.log('Create HTML El', node)
1024
+ // //console.log('Process HTML El')
1025
+ // processHtmlNode(node, parentNode)
1026
+ // debug('-createHtmlElement', node)
1027
+ // const htmlEl = document.createElement(node[$type])
1028
+ // addAttributes(node, htmlEl as ExtendableHTMLElement)
1029
+ // if (node[$type] === 'head') {
1030
+ // for (const el of instance.persistentHeadChildren) {
1031
+ // htmlEl.appendChild(el.cloneNode(true))
1032
+ // }
1033
+ // }
1034
+ // //console.log('creating hmtl node', node[$type])
1035
+ // //console.log('has ref?', 'ref' in node[$props])
1036
+ // if ('ref' in node[$props]) {
1037
+ // node[$props].ref.current = htmlEl
1038
+ // }
1039
+ // // debug('dom parent', domPointer.parent)
1040
+ // // debug('dom parent children length', domPointer.parent.childNodes.length)
1041
+ // // debug('domPointer.index', domPointer.index)
1042
+ // // if (domPointer.index >= domPointer.parent.childNodes.length) {
1043
+ // // domPointer.parent.appendChild(htmlEl)
1044
+ // // } else {
1045
+ // // debug('new html el', htmlEl)
1046
+ // // debug('insert before', domPointer.parent.childNodes[domPointer.index])
1047
+ // // domPointer.parent.insertBefore(htmlEl, domPointer.parent.childNodes[domPointer.index]!)
1048
+ // // debug('created el', domPointer.get())
1049
+ // // }
1050
+ // // domPointer.increment()
1051
+ // // //!!!! node.domElement = el
1052
+ // // if (IsHTMLElement(domPointer.parent)) debug('***', node[$type], 'html created', htmlEl)
1053
+ // // children
1054
+ // // const renderedChildren: RenderedContentNode = await createNode({
1055
+ // // tungstenElement: tungstenElement,
1056
+ // // instance,
1057
+ // // newNode: node[$props].children,
1058
+ // // //domPointer: new DomPointer(htmlEl, htmlEl.childNodes.length),
1059
+ // // parentNode: node
1060
+ // // })
1061
+ // return htmlEl as TungstenHTMLElement
1062
+ // // return {
1063
+ // // ...node,
1064
+ // // domNode: htmlEl as TungstenHTMLElement, // eslint-disable-line no-type-assertion/no-type-assertion -- as TungstenHTMLElement allows us to attach additional props later (for storing event handler funcs)
1065
+ // // renderedChildren
1066
+ // // }
1067
+ // }
1068
+ // function removeAttribute(htmlElement: HTMLElement, attr: string) {
1069
+ // if (attr === 'checked') (htmlElement as HTMLInputElement).checked = false
1070
+ // else htmlElement.removeAttribute(attr)
1071
+ // }
1072
+ // type Attributes = Record<string, unknown>
1073
+ // function addAttributes(node: ContentNodeHtml, domNode: ExtendableHTMLElement): Attributes {
1074
+ // //console.log('-addAttributes', node)
1075
+ // const attributes = processAttributes(node)
1076
+ // debug('attributes', attributes)
1077
+ // for (const key in attributes) {
1078
+ // //console.log('attr', key)
1079
+ // if ( StringIsHtmlEvent(key) ) {
1080
+ // debug('add', htmlEvents[key])
1081
+ // const eventName = htmlEvents[key]
1082
+ // todo('addAttributes() warning - ensure type safety of event names')
1083
+ // todo('addAttributes() warning - ensure type safety of event listener') // we need to set all possible event listeners to take only EventListener funcs
1084
+ // const handler = attributes[key] as EventListener
1085
+ // // // if its a button without type="submit", prevent default to stop it from submitting forms
1086
+ // // const handler = (key === 'onClick' && node[$type] === 'button' && node[$props].type !== 'submit')
1087
+ // // ? (event: Event) => { event.preventDefault(); return (attributes[key] as EventListener)(event) }
1088
+ // // : attributes[key] as EventListener
1089
+ // domNode.addEventListener(eventName, handler)
1090
+ // domNode[htmlEventHandlerKey(eventName)] = handler
1091
+ // } else {
1092
+ // //if (! (key in ignoreAttributes)) {
1093
+ // //console.log('add attr', key, attributes[key])
1094
+ // if (typeof attributes[key] === 'boolean') {
1095
+ // //console.log('bool attr', attributes[key])
1096
+ // if (attributes[key]) domNode.setAttribute(key, '')
1097
+ // } else if (attributes[key] !== undefined && attributes[key] !== null) {
1098
+ // //console.log('string attr', String(attributes[key]))
1099
+ // domNode.setAttribute(key, String(attributes[key]))
1100
+ // }
1101
+ // //}
1102
+ // }
1103
+ // }
1104
+ // domNode.__tungsten_oldAttributes = attributes
1105
+ // return attributes
1106
+ // }
1107
+ // const clickEvents: [HtmlEvent, HtmlEventName][] = [['onClick', 'click']]
1108
+ // function updateAttributes(
1109
+ // node: ContentNodeHtml, oldNode: ContentNodeHtml, domNodeHTMLElement: HTMLElement
1110
+ // ) : Attributes {
1111
+ // //console.log('-updateAttributes node', node)
1112
+ // //console.log('domNodeHTMLElement', domNodeHTMLElement)
1113
+ // const domNode = domNodeHTMLElement as TungstenHTMLElement
1114
+ // //console.log('-updateAttributes', node)
1115
+ // debug('-updateAttributes', node)
1116
+ // const newAttributes = processAttributes(node)
1117
+ // // are re-process the old node attribs here to we can see what we applied last time.
1118
+ // // would be better to save this and then grab it later
1119
+ // //const oldAttributes = processAttributes(oldNode)
1120
+ // const oldAttributes = domNode.__tungsten_oldAttributes as undefined | Attributes
1121
+ // //console.log('newAttributes', newAttributes)
1122
+ // //console.log('oldAttributes', oldAttributes)
1123
+ // debug('attributes', newAttributes)
1124
+ // debug('oldAttributes', oldAttributes)
1125
+ // for (const attr in oldAttributes) {
1126
+ // if (!(attr in newAttributes)) {
1127
+ // debug('remove attr', attr)
1128
+ // removeAttribute(domNode, attr)
1129
+ // }
1130
+ // }
1131
+ // // for (const attr of domNode.attributes) {
1132
+ // // if ( ! (attr.name in newAttributes) ) {
1133
+ // // debug('remove attr', attr.name)
1134
+ // // removeAttribute(domNode, attr.name)
1135
+ // // }
1136
+ // // }
1137
+ // //if (attributes.onClick !== undefined)
1138
+ // for ( const [event, eventName] of clickEvents ) {
1139
+ // if ( newAttributes[event] === undefined ) {
1140
+ // debug('remove event', eventName)
1141
+ // //!!
1142
+ // domNode.removeEventListener(eventName, domNode[htmlEventHandlerKey(eventName)] as EventListener)
1143
+ // }
1144
+ // }
1145
+ // for (const key in newAttributes) {
1146
+ // switch (key) {
1147
+ // case 'onClick': {
1148
+ // debug('add onclick')
1149
+ // const clickHandlerKey = htmlEventHandlerKey('click')
1150
+ // debug('domNode.' + clickHandlerKey, domNode[clickHandlerKey])
1151
+ // if (domNode[clickHandlerKey]) {
1152
+ // domNode.removeEventListener('click', domNode[clickHandlerKey] as EventListener)
1153
+ // }
1154
+ // // if its a button without type="submit", prevent default to stop it from submitting forms
1155
+ // const handler = newAttributes[key] as EventListener
1156
+ // // const handler = (key === 'onClick' && node[$type] === 'button' && node[$props].type !== 'submit')
1157
+ // // ? (event: Event) => { event.preventDefault(); return (attributes[key] as EventListener)(event) }
1158
+ // // : attributes[key] as EventListener
1159
+ // todo(`Ensure type safety on event listener`)
1160
+ // domNode.addEventListener('click', handler)
1161
+ // domNode[clickHandlerKey] = handler
1162
+ // debug('added event handler', domNode[clickHandlerKey])
1163
+ // break
1164
+ // }
1165
+ // default: {
1166
+ // //console.log('add/set attr', domNode, key, attributes[key], String(attributes[key]))
1167
+ // //if (domNode.tagName === 'input' || domNode.tagName === 'INPUT') continue
1168
+ // // try to set value directly for inputs that aren't updating with the below code
1169
+ // if (key === 'value') {
1170
+ // domNode.value = String(newAttributes[key])
1171
+ // } else {
1172
+ // if (typeof newAttributes[key] === 'boolean') {
1173
+ // if (newAttributes[key]) domNode.setAttribute(key, '')
1174
+ // else removeAttribute(domNode, key)
1175
+ // } else if (newAttributes[key] === undefined || newAttributes[key] === null) {
1176
+ // removeAttribute(domNode, key)
1177
+ // } else {
1178
+ // domNode.setAttribute(key, String(newAttributes[key]))
1179
+ // }
1180
+ // }
1181
+ // }
1182
+ // }
1183
+ // }
1184
+ // domNode.__tungsten_oldAttributes = newAttributes
1185
+ // return newAttributes
1186
+ // }
1187
+ // // const ignoreAttributes = {
1188
+ // // 'ref': true,
1189
+ // // //'key': true
1190
+ // // }
1191
+ // function processAttributes(node: ContentNodeHtml): Attributes {
1192
+ // const { [$props]: props } = node
1193
+ // debug('-processAttributes')
1194
+ // debug('props', props)
1195
+ // const attributes = { ...props }
1196
+ // delete attributes.ref
1197
+ // delete attributes.class
1198
+ // if (attributes.className !== undefined) attributes.class = attributes.className
1199
+ // delete attributes.className
1200
+ // // process the bind attr to a value attr
1201
+ // if (attributes.bind) {
1202
+ // const bind = attributes.bind as BindVariable<Record<string, unknown>>
1203
+ // // this will overwrite any existing value attr
1204
+ // attributes.value = (bind[0][bind[1]] ?? '') as NodeValue // !!! unsafe, assuming bind variable is a suitable value
1205
+ // // setup on onChange event handler
1206
+ // // this will overwrite any other onChange
1207
+ // if (node[$type] in bindableHtmlElementsString) {
1208
+ // type Element = HTMLBindableElementString
1209
+ // let handler
1210
+ // if ('filter' in attributes) {
1211
+ // const filterFunc = attributes.filter as FilterFuncString<any, any>
1212
+ // handler = async (event: Event) => {
1213
+ // bind[0][bind[1]] = await filterFunc((event.target as Element).value, event)
1214
+ // }
1215
+ // } else {
1216
+ // handler = (event: Event) => {
1217
+ // bind[0][bind[1]] = (event.target as Element).value
1218
+ // }
1219
+ // }
1220
+ // attributes.onChange = handler
1221
+ // } else if (node[$type] in bindableHtmlElementsNumber) {
1222
+ // type Element = HTMLBindableElementNumber
1223
+ // let handler
1224
+ // if ('filter' in attributes) {
1225
+ // const filterFunc = attributes.filter as FilterFuncNumber<any, any>
1226
+ // handler = async (event: Event) => {
1227
+ // bind[0][bind[1]] = await filterFunc((event.target as Element).value, event)
1228
+ // }
1229
+ // } else {
1230
+ // handler = (event: Event) => {
1231
+ // bind[0][bind[1]] = (event.target as Element).value
1232
+ // }
1233
+ // }
1234
+ // attributes.onChange = handler
1235
+ // }
1236
+ // delete attributes.bind
1237
+ // delete attributes.filter
1238
+ // }
1239
+ // if (attributes.children !== undefined) {
1240
+ // delete attributes.children
1241
+ // }
1242
+ // if (attributes.style !== undefined) {
1243
+ // attributes.style = jssToCss(attributes.style)
1244
+ // }
1245
+ // if (attributes.css !== undefined) {
1246
+ // if (attributes.style !== undefined) {
1247
+ // attributes.style = ((attributes.style as string) + ' ' + (attributes.css as string)).trim()
1248
+ // } else {
1249
+ // attributes.style = attributes.css
1250
+ // }
1251
+ // }
1252
+ // return attributes
1253
+ // }
1254
+ // type CreateTungstenComponentArgs = {
1255
+ // parent: TungstenElement
1256
+ // instance: Instance,
1257
+ // node: ContentNodeComponentAny,
1258
+ // //domRegion: DomRegion,
1259
+ // //domPointer: DomPointer
1260
+ // }
1261
+ // export async function createTungstenComponent({ parent, instance, node }: CreateTungstenComponentArgs)
1262
+ // : Promise<TungstenHtmlDomElements> {
1263
+ // debug('-createTungstenComponent')
1264
+ // //debug('domPointer', domPointer.parent, domPointer.index)
1265
+ // if (ContentNodeComponentIsClassComponent(node)) {
1266
+ // return createTungstenClassComponent(parent, instance, node)
1267
+ // } else {
1268
+ // return createTungstenFunctionComponent(parent, instance, node)
1269
+ // }
1270
+ // // need to set a domRegion
1271
+ // // element.__domRegion = domRegion
1272
+ // }
1273
+ // let cc = 0 // debugging aid
1274
+ // async function createTungstenClassComponent(
1275
+ // parent: TungstenElement,
1276
+ // instance: Instance,
1277
+ // node: ContentNodeClassComponentAny,
1278
+ // //domPointer: DomPointer
1279
+ // ) : Promise<TungstenHtmlDomElements> {
1280
+ // //console.log('creating tung class comp', node[$type].name)
1281
+ // //console.log('domPointer', domPointer)
1282
+ // //console.log('DP parent children', domPointer.parent.childNodes)
1283
+ // //console.log('current', domPointer.get())
1284
+ // const c = cc++
1285
+ // // const domStartIndex = domPointer.index
1286
+ // // debug(`[${c}]`, '!!&& dom start index', domStartIndex)
1287
+ // // debug(`[${c}]`, 'class component')
1288
+ // const element = new node[$type]({
1289
+ // props: node[$props],
1290
+ // routeParams: node[$routeParams],
1291
+ // routeData: node[$routeData],
1292
+ // instance,
1293
+ // parentElement: parent
1294
+ // })
1295
+ // await element.__init()
1296
+ // const content = await element.__initialContent()
1297
+ // //const content = await element.__styledContent()
1298
+ // //console.log('new comp content', content)
1299
+ // //console.log(`[${c}]`, 'content', content)
1300
+ // const htmlTree = await createHtmlTree({
1301
+ // tungstenElement: element,
1302
+ // instance,
1303
+ // newNode: content,
1304
+ // //domPointer,
1305
+ // parentNode: null
1306
+ // })
1307
+ // return htmlTree
1308
+ // //const compName = node[$type].name // should take into account other factors // maybe in render too
1309
+ // // const openingComment = createComment({ text: printComponentNamesInSource ? compName : '', domPointer })
1310
+ // // const renderedContent: RenderedContentNode = await createRenderedContentNode({
1311
+ // // tungstenElement: element,
1312
+ // // instance,
1313
+ // // newNode: content,
1314
+ // // domPointer,
1315
+ // // parentNode: null
1316
+ // // })
1317
+ // // const closingComment = createComment({ text: printComponentNamesInSource ? ('/' + compName) : '', domPointer })
1318
+ // // //console.log('created class comp closing comment', node[$type].name)
1319
+ // // //const renderedContent: RenderedContentNode = await integrateNode({ node: content, domRegion: null, domPointer, parent: element, instance })
1320
+ // // const domLength = domPointer.index - domStartIndex
1321
+ // // debug(`[${c}]`, '&& for node', node)
1322
+ // // debug(`[${c}]`, '&& dom start index', domStartIndex)
1323
+ // // debug(`[${c}]`, '&& dom end index', domLength)
1324
+ // // //console.log('domPointer.parent', domPointer.parent)
1325
+ // // //console.log('domStartIndex', domStartIndex)
1326
+ // // //console.log('domLength', domLength)
1327
+ // // //console.log('new dom region when creating class comp', node[$type].name, domPointer.parent)
1328
+ // // //console.log('new dom region', domStartIndex, domLength)
1329
+ // // element.__domRegion = new DomRegion(domPointer.parent, domStartIndex, domLength)
1330
+ // // debug(`[${c}]`, '&& dom region first element', element.__domRegion.firstElement)
1331
+ // // debug(`[${c}]`, '&& dom region last element', element.__domRegion.lastElement)
1332
+ // // //console.log('created dom region', element.__domRegion)
1333
+ // // element.__currentContent = renderedContent
1334
+ // // element.__didMount()
1335
+ // // return {
1336
+ // // ...node,
1337
+ // // element,
1338
+ // // openingComment,
1339
+ // // closingComment
1340
+ // // }
1341
+ // }
1342
+ // let xx = 0
1343
+ // async function createTungstenFunctionComponent(
1344
+ // parent: TungstenElement,
1345
+ // instance: Instance,
1346
+ // node: ContentNodeFunctionComponentAny,
1347
+ // //domPointer: DomPointer
1348
+ // ) : Promise<TungstenHtmlDomElements> {
1349
+ // //console.log('creating tung func comp', node[$type].name)
1350
+ // //console.log('create Tung Func C')
1351
+ // const x = xx++
1352
+ // // const domStartIndex = domPointer.index
1353
+ // // debug(`[${x}]`, 'create function component', node)
1354
+ // // debug(`[${x}]`, 'domPointer.parent', domPointer.parent)
1355
+ // // debug(`[${x}]`, 'dom index', domPointer.index)
1356
+ // const element = new FunctionElement(
1357
+ // node[$type], node[$props], node[$routeParams], node[$routeData], instance, parent
1358
+ // )
1359
+ // setCurrentComponent(element)
1360
+ // const content = await getStyledContentFromFunctionComponent(element)
1361
+ // debug('new func comp content', content)
1362
+ // //const content = await getStyledContentFromFunctionComponent(node.type, node.props)
1363
+ // clearCurrentComponent()
1364
+ // debug('content', content)
1365
+ // const htmlTree = await createHtmlTree({
1366
+ // tungstenElement: element,
1367
+ // instance,
1368
+ // newNode: content,
1369
+ // //domPointer,
1370
+ // parentNode: null
1371
+ // })
1372
+ // return htmlTree
1373
+ // // const compName = node[$type].name // should take into account other factors // maybe in render too
1374
+ // // const openingComment = createComment({ text: printComponentNamesInSource ? compName : '', domPointer })
1375
+ // // const renderedContent: RenderedContentNode = await createRenderedContentNode({
1376
+ // // tungstenElement: element,
1377
+ // // instance,
1378
+ // // newNode: content,
1379
+ // // domPointer,
1380
+ // // parentNode: null
1381
+ // // })
1382
+ // // const closingComment = createComment({ text: printComponentNamesInSource ? ('/' + compName) : '', domPointer })
1383
+ // // //const renderedContent: RenderedContentNode = await integrateNode({ node: content, domRegion: null, domPointer, parent: element, instance })
1384
+ // // const domLength = domPointer.index - domStartIndex
1385
+ // // debug(`[${x}]`, '&& Continuing create FC', node)
1386
+ // // debug(`[${x}]`, '&& domPointer.parent', domPointer.parent)
1387
+ // // debug(`[${x}]`, '&& dom start index', domStartIndex)
1388
+ // // debug(`[${x}]`, '&& dom length', domLength)
1389
+ // // debug(`[${x}]`, '&& dom pointer children', domPointer.parent.childNodes)
1390
+ // // //console.log('new dom region when creating func comp', node[$type].name, domPointer.parent)
1391
+ // // element.__domRegion = new DomRegion(domPointer.parent, domStartIndex, domLength)
1392
+ // // //console.log('&& dom region first element', element.__domRegion.firstElement)
1393
+ // // //console.log('&& dom region last element', element.__domRegion.lastElement)
1394
+ // // element.__currentContent = renderedContent
1395
+ // // return {
1396
+ // // ...node,
1397
+ // // element,
1398
+ // // openingComment,
1399
+ // // closingComment
1400
+ // // }
1401
+ // }
1402
+ // type UpdateClassComponentArgs = {
1403
+ // parent: AnyComponent
1404
+ // instance: Instance
1405
+ // newNode: ContentNodeClassComponentAny
1406
+ // oldNode: RenderedContentNodeClassComponent
1407
+ // //element: TungstenBaseComponent
1408
+ // domPointer: DomPointer
1409
+ // }
1410
+ // async function updateClassComponent({ newNode, oldNode, domPointer }: UpdateClassComponentArgs)
1411
+ // : Promise<RenderedContentNodeClassComponent> {
1412
+ // //console.log('-updateClassComponent', newNode)
1413
+ // const element = oldNode.element
1414
+ // element.props = newNode[$props]
1415
+ // debug('update class component', newNode)
1416
+ // //console.log('update class component', newNode)
1417
+ // //console.log('old element', element)
1418
+ // //console.log('domPointer before updating comp', domPointer)
1419
+ // //console.log('domPointer children', [...domPointer.parent.childNodes])
1420
+ // //throwError('','')
1421
+ // const updateResult = await element.__update()
1422
+ // domPointer.increment(updateResult.nodesLength) // bump the dom pointer index forward by the number of nodes within that element's content
1423
+ // element.__didUpdate()
1424
+ // return {
1425
+ // ...newNode,
1426
+ // element,
1427
+ // openingComment: oldNode.openingComment,
1428
+ // closingComment: oldNode.closingComment
1429
+ // }
1430
+ // }
1431
+ // type UpdateFunctionComponentArgs = {
1432
+ // parent: AnyComponent
1433
+ // instance: Instance
1434
+ // newNode: ContentNodeFunctionComponentAny
1435
+ // oldNode: RenderedContentNodeFunctionComponent
1436
+ // //element: FunctionComponentStandInAny
1437
+ // domPointer: DomPointer
1438
+ // }
1439
+ // async function updateFunctionComponent({ newNode, oldNode, domPointer }: UpdateFunctionComponentArgs)
1440
+ // : Promise<RenderedContentNodeFunctionComponent> {
1441
+ // // this func does not seem to be updating the dom pointer index
1442
+ // //console.log('updateFunctionComponent')
1443
+ // const standIn = oldNode.element
1444
+ // standIn.props = newNode[$props]
1445
+ // const updateResult = await standIn.update()
1446
+ // domPointer.increment(updateResult.nodesLength) // bump the dom pointer index forward by the number of nodes within that element's content
1447
+ // return {
1448
+ // ...newNode,
1449
+ // element: standIn,
1450
+ // openingComment: oldNode.openingComment,
1451
+ // closingComment: oldNode.closingComment
1452
+ // }
1453
+ // }