@lexriver/dome 2.0.2 → 2.0.4

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 (43) hide show
  1. package/out/index.cjs +994 -0
  2. package/out/index.mjs +2164 -0
  3. package/out/src/AnimatedArray.d.ts +29 -0
  4. package/out/src/AnimatedTable.d.mts +2 -1
  5. package/out/src/AnimatedTable.d.ts +39 -0
  6. package/out/src/AnimatedTable.mjs +2 -1
  7. package/out/src/AnimatedText.d.mts +1 -1
  8. package/out/src/AnimatedText.d.ts +13 -0
  9. package/out/src/AnimatedText.mjs +1 -1
  10. package/out/src/Animation.d.ts +4 -0
  11. package/out/src/Dome.d.ts +9 -0
  12. package/out/src/Dome.mjs +1 -1
  13. package/out/src/DomeComponent.d.ts +25 -0
  14. package/out/src/DomeManipulator.d.ts +52 -0
  15. package/out/src/DomeRouter.d.ts +32 -0
  16. package/out/src/LongestCommonSubsequence.d.ts +15 -0
  17. package/out/src/index.d.mts +5 -1
  18. package/out/src/index.d.ts +15 -0
  19. package/out/src/index.mjs +5 -1
  20. package/package.json +21 -3
  21. package/out/src/DomeRouter.console-test.d.mts +0 -1
  22. package/out/src/DomeRouter.console-test.mjs +0 -44
  23. package/out/src/concurrent-updates.test.d.mts +0 -1
  24. package/out/src/concurrent-updates.test.mjs +0 -203
  25. package/out/src/temp-test.d.mts +0 -1
  26. package/out/src/temp-test.mjs +0 -20
  27. package/out/vitest.config.d.ts +0 -2
  28. package/out/vitest.config.js +0 -9
  29. package/src/AnimatedArray.mts +0 -74
  30. package/src/AnimatedTable.mts +0 -120
  31. package/src/AnimatedText.mts +0 -30
  32. package/src/Animation.mts +0 -4
  33. package/src/Dome.mts +0 -346
  34. package/src/DomeComponent.mts +0 -84
  35. package/src/DomeManipulator.mts +0 -391
  36. package/src/DomeRouter.console-test.mts +0 -52
  37. package/src/DomeRouter.mts +0 -287
  38. package/src/LongestCommonSubsequence.mts +0 -201
  39. package/src/concurrent-updates.test.mts +0 -252
  40. package/src/index.mts +0 -12
  41. package/src/temp-test.mts +0 -23
  42. package/tsconfig.json +0 -59
  43. package/vitest.config.ts +0 -10
@@ -1,9 +0,0 @@
1
- import { defineConfig } from 'vitest/config';
2
- export default defineConfig({
3
- test: {
4
- exclude: [
5
- './out/**',
6
- './node_modules/**'
7
- ]
8
- }
9
- });
@@ -1,74 +0,0 @@
1
- import { Animation } from './Animation.mjs'
2
- import { DomeManipulator } from "./DomeManipulator.mjs"
3
- import { LongestCommonSubsequence } from "./LongestCommonSubsequence.mjs"
4
-
5
- interface KeyToElementPair{
6
- key:string
7
- element:HTMLElement
8
- }
9
-
10
- export class AnimatedArray<T>{
11
- arrayOfKeyToElement:KeyToElementPair[] = []
12
-
13
- constructor(protected params:{
14
- parentElement?:HTMLElement,
15
- array?:T[],
16
- getKey:(o:T)=>string,
17
- getHtmlElement:(o:T)=>HTMLElement,
18
- animationShow?:Animation
19
- animationHide?:Animation
20
- //renderEmptyList?:()=>HTMLElement
21
- emptyList?:HTMLElement
22
- }){
23
- if(params.array && params.parentElement){
24
- this.update(params.array)
25
- }
26
- }
27
-
28
- get size():number{
29
- return this.arrayOfKeyToElement.length
30
- }
31
-
32
- update(array:T[], parentElement?:HTMLElement|Element){
33
- parentElement = parentElement || this.params.parentElement
34
- if(!parentElement){
35
- console.warn('AnimatedArray unable to update, no parentElement')
36
- return
37
- }
38
-
39
- if(array.length == 0 && this.params.emptyList){
40
- DomeManipulator.replaceAllChildrenAsync(parentElement, this.params.emptyList)
41
- return
42
- }
43
-
44
- if(array.length > 0 && this.params.emptyList){
45
- DomeManipulator.removeElementAsync(this.params.emptyList, this.params.animationHide)
46
- }
47
-
48
- //let arrayOfKeyToElement:KeyToElementPair[] = []
49
- let newArrayOfKeys = array.map((item:T) => this.params.getKey(item))
50
- let oldArrayOfKeys = this.arrayOfKeyToElement.map(x => x.key)
51
- LongestCommonSubsequence.getPatchOrdered({
52
- oldArray: oldArrayOfKeys,
53
- newArray: newArrayOfKeys,
54
- onAdd:(index:number, key:string) => {
55
- if(!parentElement) throw new Error('no parent element') //TODO: remove this
56
- let itemIndex = newArrayOfKeys.indexOf(key)
57
- if(itemIndex == -1) throw new Error('no itemIndex') //TODO: remove this
58
- let item = array[itemIndex]
59
- let element = this.params.getHtmlElement(item)
60
- this.arrayOfKeyToElement.splice(index,0,{key, element})
61
- DomeManipulator.insertByIndexAsync(element, index, parentElement, this.params.animationShow)
62
- //this.insertNewElementWithAnimation(element, index, parentElement)
63
-
64
- },
65
- onRemove: (index:number, key:string) => {
66
- DomeManipulator.removeElementAsync(this.arrayOfKeyToElement[index].element, this.params.animationHide)
67
- this.arrayOfKeyToElement.splice(index,1)
68
- }
69
- })
70
-
71
- }
72
-
73
-
74
- }
@@ -1,120 +0,0 @@
1
- import { ObservableVariable } from '@lexriver/observable'
2
- import { Animation } from './Animation.mjs'
3
- import { DomeManipulator } from "./DomeManipulator.mjs"
4
- import { AnimatedArray, DomeComponent } from "./index.mjs"
5
-
6
- interface Attrs<T>{
7
- isLoadingO?:ObservableVariable<boolean>
8
- itemsO:ObservableVariable<T[]>
9
- animationShowRow:Animation
10
- animationHideRow:Animation
11
- animationHideTable?:Animation
12
- animationShowTable?:Animation
13
- animationHideEmptyList?:Animation
14
- animationShowEmptyList?:Animation
15
- animationShowLoading?:Animation
16
- animationHideLoading?:Animation
17
- getKey:(item:T)=>string
18
- rootElement?:HTMLElement
19
- tableElement?:HTMLElement
20
- tableBody?:HTMLElement
21
- renderTableHead?:(items:T[])=>HTMLElement
22
- renderTableRow:(item:T)=>HTMLElement
23
- renderTableFooter?:(items:T[]) => HTMLElement
24
- renderEmptyList:()=>HTMLElement
25
- renderLoading?:()=>HTMLElement
26
- }
27
-
28
- export class AnimatedTable<T> extends DomeComponent<Attrs<T>>{
29
- // rootElement
30
- // table
31
- // thead
32
- // tbody
33
- // tfooter
34
- // emptyList
35
- refRoot:HTMLElement = this.attrs.rootElement || document.createElement('div')
36
- refTable:HTMLElement = this.attrs.tableElement || document.createElement('table')
37
- refTableHead:Element = this.attrs.renderTableHead ? this.attrs.renderTableHead(this.attrs.itemsO.get()) : document.createElement('thead')
38
- refTableBody:HTMLElement = this.attrs.tableBody || document.createElement('tbody')
39
- refTableFooter:Element = this.attrs.renderTableFooter ? this.attrs.renderTableFooter(this.attrs.itemsO.get()) : document.createElement('tfoot')
40
- refEmptyList:Element = this.attrs.renderEmptyList ? this.attrs.renderEmptyList() : document.createElement('div')
41
- refLoading:Element = this.attrs.renderLoading ? this.attrs.renderLoading() : document.createElement('div')
42
-
43
- animatedArray = new AnimatedArray<T>({
44
- animationHide: this.attrs.animationHideRow,
45
- animationShow: this.attrs.animationShowRow,
46
- array: [],
47
- getKey: this.attrs.getKey,
48
- getHtmlElement: this.attrs.renderTableRow
49
- })
50
-
51
- render(){
52
- // refRoot
53
- // refTable
54
- // refTableHead
55
- // refTableBody
56
- // refTableFooter
57
- // refEmptyListEl
58
- // refLoading
59
-
60
- this.refRoot.appendChild(this.refTable)
61
- this.refRoot.appendChild(this.refEmptyList)
62
- this.refRoot.appendChild(this.refLoading)
63
- if(this.refTableHead) this.refTable.appendChild(this.refTableHead)
64
- if(this.refTableBody) this.refTable.appendChild(this.refTableBody)
65
- if(this.refTableFooter) this.refTable.appendChild(this.refTableFooter)
66
- console.log('AnimatedTable render()', 'refRoot=', this.refRoot)
67
- return this.refRoot
68
- }
69
-
70
- afterRender(){
71
- this.updateAsync()
72
- //this.animatedArray.update(this.attrs.items, this.el)
73
- }
74
-
75
- async updateAsync(){
76
- try {
77
- if(this.attrs.renderLoading){
78
- this.refLoading = await DomeManipulator.replaceAsync(this.refLoading, this.attrs.renderLoading())
79
- }
80
- if(this.attrs.isLoadingO && this.attrs.isLoadingO.get()){
81
- // show loading
82
- await DomeManipulator.unhideElementAsync(this.refLoading, this.attrs.animationShowLoading)
83
- } else {
84
- // hide loading
85
- await DomeManipulator.hideElementAsync(this.refLoading, this.attrs.animationHideLoading)
86
- }
87
-
88
- const items = this.attrs.itemsO.get()
89
- const currentCount = items.length
90
-
91
- if(currentCount == 0){
92
- // render empty list
93
- await DomeManipulator.hideElementAsync(this.refTable, this.attrs.animationHideTable)
94
- if(this.attrs.renderEmptyList){
95
- this.refEmptyList = await DomeManipulator.replaceAsync(this.refEmptyList, this.attrs.renderEmptyList())
96
- }
97
- await DomeManipulator.unhideElementAsync(this.refEmptyList, this.attrs.animationShowEmptyList)
98
-
99
- } else {
100
-
101
- // render list with items
102
- await DomeManipulator.hideElementAsync(this.refEmptyList, this.attrs.animationHideEmptyList)
103
- if(this.attrs.renderTableHead){
104
- this.refTableHead = await DomeManipulator.replaceAsync(this.refTableHead, this.attrs.renderTableHead(items))
105
- }
106
- if(this.attrs.renderTableFooter){
107
- this.refTableFooter = await DomeManipulator.replaceAsync(this.refTableFooter, this.attrs.renderTableFooter(items))
108
- }
109
- await DomeManipulator.unhideElementAsync(this.refTable, this.attrs.animationShowTable)
110
-
111
- this.animatedArray.update(items, this.refTableBody)
112
- }
113
- } catch(x){
114
- console.error('AnimatedTable update failed', x)
115
- }
116
-
117
-
118
-
119
- }
120
- }
@@ -1,30 +0,0 @@
1
- import { ObservableVariable } from "@lexriver/observable";
2
- import { CssClass, DomeManipulator } from "./DomeManipulator.mjs";
3
- import { DomeComponent } from "./index.mjs";
4
-
5
- interface Attrs{
6
- textO:ObservableVariable<string>
7
- tag?:string
8
- class?:CssClass
9
- }
10
-
11
- export class AnimatedText extends DomeComponent<Attrs>{
12
- render(){
13
- //const result = this.attrs.tag ? document.createElement(this.attrs.tag) : document.createElement('span')
14
- const result = document.createElement(this.attrs.tag || 'span')
15
- //console.log('AnimatedText', 'this.attrs.class=',this.attrs.class)
16
- if(this.attrs.class){
17
- DomeManipulator.setCssClasses(result, this.attrs.class)
18
- }
19
- result.append(this.attrs.textO.get())
20
- return result
21
- }
22
- async updateAsync(){
23
- if(!this.rootElement) return
24
- try {
25
- this.rootElement = await DomeManipulator.replaceAsync(this.rootElement, this.render(), this.attrs.onHideAnimation, this.attrs.onShowAnimation)
26
- } catch(x){
27
- console.error('AnimatedText update failed', x)
28
- }
29
- }
30
- }
package/src/Animation.mts DELETED
@@ -1,4 +0,0 @@
1
- export interface Animation{
2
- cssClassName:string
3
- timeMs:number
4
- }
package/src/Dome.mts DELETED
@@ -1,346 +0,0 @@
1
- // inspiration: https://github.com/vadimdemedes/dom-chef/blob/master/index.js
2
- const svgTagNames = require('svg-tag-names')
3
- import { DataTypes } from '@lexriver/data-types'
4
- import { ObservableVariable, checkIfObservable } from '@lexriver/observable'
5
- import { DomeComponent } from './DomeComponent.mjs'
6
- import { DomeManipulator } from './DomeManipulator.mjs'
7
-
8
- const filename = '[Dome]: '
9
-
10
-
11
- interface OnEventObject{
12
- eventName:string
13
- eventParams:Object
14
- eventReaction:(eventParams:Object)=>void
15
- }
16
-
17
-
18
-
19
- //const mountFunctionByNode = new Map<Node, (ref:any)=>void>()
20
-
21
- // https://github.com/jonschlinkert/arr-flatten/blob/master/index.js
22
- function flattenArray(arr:any[], res:any[] = []){
23
- var i = 0, cur;
24
- var len = arr.length;
25
- for (; i < len; i++) {
26
- cur = arr[i];
27
- Array.isArray(cur) ? flattenArray(cur, res) : res.push(cur);
28
- }
29
- return res;
30
- }
31
-
32
-
33
- function checkIfNonDimensionalCssName(name:string){
34
- // Copied from Preact
35
- const IS_NON_DIMENSIONAL = /acit|ex(?:s|g|n|p|$)|rph|ows|mnc|ntw|ine[ch]|zoo|^ord/i
36
- return IS_NON_DIMENSIONAL.test(name)
37
- }
38
-
39
-
40
- const excludeSvgTags = [
41
- 'a',
42
- 'audio',
43
- 'canvas',
44
- 'iframe',
45
- 'script',
46
- 'video'
47
- ]
48
-
49
- const svgTags = svgTagNames.filter(name => !excludeSvgTags.includes(name))
50
-
51
- const isSVG = tagName => svgTags.includes(tagName)
52
-
53
- const setCSSProps = (el, style:{[key:string]:string|number}) => {
54
- if(DataTypes.isString(style)){
55
- el.style = style
56
-
57
- } else if(DataTypes.isObjectWithKeys(style)){
58
- Object.keys(style).forEach(name => {
59
- let value = style[name]
60
-
61
- if (typeof value === 'number' && !checkIfNonDimensionalCssName(name)) {
62
- value = `${value}px`
63
- }
64
-
65
- el.style[name] = value
66
- })
67
- }
68
- }
69
-
70
- const createElement = (tagName) => {
71
- if (isSVG(tagName)) {
72
- return document.createElementNS('http://www.w3.org/2000/svg', tagName)
73
- }
74
-
75
- if (tagName === DocumentFragment) {
76
- return document.createDocumentFragment()
77
- }
78
-
79
- return document.createElement(tagName)
80
- }
81
-
82
-
83
- // function subscribeToEventByParam(x:OnEventObject, el:HTMLElement){
84
- // if(
85
- // !x.eventName ||
86
- // Data.isString(x.eventName) == false ||
87
- // !x.eventReaction ||
88
- // Data.isFunction(x.eventReaction) == false
89
- // ){
90
- // console.error('x=', x, 'el=', el)
91
- // throw new Error(`Please provide object of type {eventName:string, eventParams:Object, eventReaction:(eventParams, htmlElement)=>void}`)
92
- // }
93
- // //DomeEventDispatcher.subscribeToEvent(el, x.eventName, x.eventParams || {}, x.eventReaction)
94
- // DomeEventDispatcher.subscribeToEvent({
95
- // eventName: x.eventName,
96
- // eventParamsFilter: x.eventParams || {},
97
- // action: x.eventReaction,
98
- // unsubscribeWhen: () => DomeManipulator.isInDom(el) == false
99
- // })
100
-
101
-
102
- // }
103
-
104
- const build = (tagName, attrs, children:DocumentFragment) => {
105
- if(!tagName) {
106
- console.trace()
107
- throw new Error('tagName='+tagName)
108
- }
109
- // if(children && typeof children !== 'object'){
110
- // //console.log('tagName=', tagName, 'attrs=',attrs, 'children=', children)
111
- // console.log('tagName=', tagName, 'children=', children, 'typeof children=', typeof children)
112
- // }
113
- if(tagName == DocumentFragment){
114
- //console.warn(filename, 'isDocumentFragment!')
115
- const el = createElement(tagName)
116
- el.appendChild(children)
117
- return el
118
- }
119
-
120
- //console.log(filename, 'instaceof=', tagName instanceof DomeComponent)
121
- //console.log(filename, 'has render=', tagName.render)
122
- //console.log(filename, 'instanceof Object=', tagName instanceof Object)
123
-
124
- if(tagName.prototype && tagName.prototype['__DomeComponent']){
125
- // we have a DomeComponent
126
- //console.warn('DomeComponent!')
127
- try {
128
- const instance = new tagName(attrs, children) as DomeComponent<any>
129
- //console.log('instance=', instance)
130
- if(instance['render'] && DataTypes.isFunction(instance['render'])){
131
-
132
-
133
- //#region make ref points to instance, not element
134
- if(attrs.ref && DataTypes.isFunction(attrs.ref)){
135
- attrs.ref(instance)
136
- }
137
- //#endregion
138
-
139
- instance['init']()
140
-
141
- instance.rootElement = instance['render']()
142
-
143
- //#region subscribe to observable attribute
144
- for(let attribute of Object.values(attrs)){
145
- if(checkIfObservable(attribute)){
146
- attribute.eventOnChange.subscribe(() => {
147
- //this.update()
148
- instance.scheduleUpdate()
149
- })
150
- }
151
- }
152
- //#endregion
153
-
154
-
155
- //requestAnimationFrame(() => {
156
- instance['afterRender']()
157
- //})
158
-
159
- return instance.rootElement
160
- }
161
- } catch(error){
162
- console.error('error while creating DomeComponent class', error)
163
- }
164
- return;
165
-
166
- }
167
- if(DataTypes.isFunction(tagName)){
168
- // call functional component
169
- return tagName(attrs, children)
170
-
171
- } else if(DataTypes.isString(tagName)){
172
- const el = createElement(tagName)
173
- //console.log('lex-dome', 'creating element', el)
174
-
175
- Object.keys(attrs).forEach(name => {
176
- const value = attrs[name]
177
-
178
- if (name === 'class' || name === 'className' || name === 'cssClasses') {
179
- //DomeManipulator.setCssClasses(el, value)
180
- assignDynamicCssClasses(name, value, el)
181
-
182
-
183
-
184
- } else if (name === 'style') {
185
- setCSSProps(el, value)
186
-
187
- } else if(['disabled', 'autocomplete', 'selected', 'checked'].indexOf(name) >= 0){
188
- if(attrs[name]){
189
- DomeManipulator.setAttribute(el, name, name)
190
- }
191
-
192
- } else if(name === 'onCreate' || name === 'ref'){
193
- if(DataTypes.isFunction(value) == false) throw new Error(`Please provide function <${tagName} ${name}={ref => myRef=ref} />`)
194
- value(el)
195
-
196
- // } else if(name === 'onEvent'){ //TODO: remove this!?
197
- // // <div onEvent={{eventName:'myCumstomEvent', eventParams:{any:'params',can:'be',here:true}, eventReaction:()=>{}}}>some text for div</div>
198
- // //#region is Object
199
- // if(Data.isObjectWithKeys(value)){
200
- // subscribeToEventByParam(value as OnEventObject, el)
201
- // return
202
- // }
203
- // //#endregion
204
-
205
- // //#region is Array
206
- // if(Data.isArray(value)){
207
- // for(let x of value){
208
- // subscribeToEventByParam(x as OnEventObject, el)
209
- // }
210
- // }
211
- // //#endregion
212
-
213
- } else if(name == 'visibleIf'){ //TODO: remove this!?
214
- if(checkIfObservable(value) == false) {
215
- console.error('value=', value)
216
- throw new Error('Please provide Observable<boolean> as argument for visibleIf')
217
- }
218
- let obs = value as ObservableVariable<boolean>
219
- obs.eventOnChange.subscribe((isVisible) => {
220
- if(isVisible){
221
- DomeManipulator.unhideElementAsync(el)
222
- } else {
223
- DomeManipulator.hideElementAsync(el)
224
- }
225
- })
226
-
227
- setTimeout(() => { //TODO: hack to trigger event on mount to DOM
228
- obs.eventOnChange.triggerAsync(obs.get())
229
- }, 1)
230
-
231
- } else if (name.indexOf('on') === 0 && value) {
232
- const eventName = name.slice(2).toLowerCase()
233
- if(DataTypes.isFunction(value) == false) {
234
- console.error('unable to subscribe for event', eventName, 'listener is not a function', 'element=', el, 'listener=', value)
235
- return
236
- }
237
- //console.log('adding event listener for', el, 'eventName=', eventName, 'value=', value)
238
- el.addEventListener(eventName, value)
239
-
240
- } else if (name === 'innerHtml') {
241
- el.innerHTML = value
242
-
243
- } else if (name !== 'key' && value !== false) {
244
- DomeManipulator.setAttribute(el, name, value === true ? '' : value)
245
- }
246
- })
247
-
248
- if (!attrs.innerHtml) {
249
- el.appendChild(children)
250
- }
251
-
252
- return el
253
-
254
- } else throw new Error("not implemented")
255
- }
256
-
257
-
258
-
259
- /**
260
- *
261
- * @param value
262
- * @param name
263
- * @param element
264
- */
265
- function assignDynamicCssClasses(name: string, value: {[key:string]:boolean|ObservableVariable<boolean>}, element: any) {
266
- if (DataTypes.isObjectWithKeys(value) == false){
267
- DomeManipulator.setCssClasses(element, value)
268
- return
269
- //throw new Error(`Please provide object for ${name}, ex: {class1:true, class2:myVarO}`)
270
- }
271
- let resultArray: string[] = []
272
- for (let [k, v] of Object.entries(value)) {
273
- if(v === undefined){
274
- //skip
275
-
276
- } else if (DataTypes.isBoolean(v)) {
277
- if(v){
278
- resultArray.push(k)
279
- }
280
-
281
- } else if (checkIfObservable(v)) {
282
- let o = v as ObservableVariable<boolean>
283
- o.eventOnChange.subscribe((showThiCssClass) => {
284
- if(!DomeManipulator.isInDom(element)) return {unsubscribe:true} //TODO: test it
285
- // reassign whole attribute
286
- DomeManipulator.setCssClasses(element, value)
287
- })
288
- if (o.get()) {
289
- resultArray.push(k)
290
- }
291
- } else {
292
- console.error(`Please provide classNames as a keys and boolean or Observable<boolean> for values., ex: {class1:true, class2:myVarO}`, 'name=', name, 'value=', value, 'typeof value =', typeof value)
293
- throw new Error('Wrong value for `class` attribute')
294
- }
295
- }
296
- DomeManipulator.setCssClasses(element, resultArray) // yes, array of classes is ok here
297
- }
298
-
299
- export function h(tagName, attrs, ...childrenArgs) {
300
- // eslint-disable-next-line prefer-rest-params
301
- //const childrenArgs = [].slice.apply(arguments, [2])
302
- const children = document.createDocumentFragment()
303
- //const childArray:any[] = []
304
-
305
- // console.log(filename, 'childrenArgs=', childrenArgs)
306
- // console.log(filename, 'childrenO=', childrenO)
307
- // if(tagName === 'hoho'){
308
- // console.warn(filename, tagName, attrs, ...childrenArgs)
309
- // }
310
-
311
- flattenArray(childrenArgs).forEach(child => {
312
- //(childrenArgs).forEach(child => {
313
- // if(tagName === 'hoho'){
314
- // console.warn(filename, 'child=', child)
315
- // }
316
- if (child instanceof Node) {
317
- children.appendChild(child)
318
- //childArray.push(child)
319
-
320
- // const mountFunction = mountFunctionByNode.get(child)
321
- // if(mountFunction){
322
- // mountFunction(child)
323
- // mountFunctionByNode.delete(child)// delete after execution
324
- // }
325
-
326
- } else if (typeof child !== 'boolean' && typeof child !== 'undefined' && child !== null) {
327
- //console.log('[Dome] child=', child)
328
- //console.warn(filename, 'text? child=', child)
329
- children.appendChild(document.createTextNode(child))
330
- //childArray.push(document.createTextNode(child))
331
- }
332
- })
333
-
334
- //return build(tagName, attrs || {}, children)
335
- return build(tagName, attrs || {}, children)
336
- }
337
-
338
- // Improve TypeScript support for DocumentFragment
339
- // https://github.com/Microsoft/TypeScript/issues/20469
340
- export const React = {
341
- createElement: h,
342
- Fragment: typeof DocumentFragment === 'function' ? DocumentFragment : () => {}
343
- }
344
-
345
- export default React
346
-
@@ -1,84 +0,0 @@
1
- import { debounce } from 'ts-debounce'
2
- import { Animation } from './Animation.mjs'
3
- import { DomeManipulator } from "./DomeManipulator.mjs"
4
-
5
-
6
- interface InternalAttrs{
7
- ref?:(ref)=>void
8
- onShowAnimation?:Animation
9
- onHideAnimation?:Animation
10
- }
11
- export abstract class DomeComponent<Attrs>{
12
- public rootElement!:Element|HTMLElement
13
- private updateInProgress = false
14
- private updateRequested = false
15
- constructor(
16
- public attrs:Attrs & InternalAttrs,
17
- public children:any
18
- ){
19
- //this.init()
20
-
21
- }
22
- //abstract render(attrs:Attrs, children:any):HTMLElement
23
- protected init():void{}
24
- protected abstract render():HTMLElement
25
- protected afterRender():void{
26
- //console.log('afterRender(), el=', this.el)
27
- }
28
- // protected onMount(){
29
-
30
- // }
31
-
32
- async updateAsync(){
33
- //console.log('DomeComponent: calling native update() method!') //TODO: remove this
34
- if(!this.rootElement) {
35
- console.error('DomeComponent: unable to update, no rootElement', 'this=', this)
36
- return
37
- }
38
- if(!this.rootElement.parentNode){
39
- console.error('DomeComponent: unable to update, no parent for rootElement, not mounted?', 'this=', this)
40
- return
41
- }
42
-
43
- //console.time('browser')
44
- const newEl = this.render()
45
- //console.log('DomeComponent: update() newEl=', newEl) //TODO: remove this
46
- //DomeManipulator.unhideElement(this.el) // if was null before
47
- await DomeManipulator.replaceAsync(this.rootElement, newEl, this.attrs.onHideAnimation, this.attrs.onShowAnimation)
48
- this.rootElement = newEl
49
- //console.timeEnd('browser')
50
- this.afterUpdate()
51
-
52
- }
53
- private async runScheduledUpdateAsync() {
54
- if(this.updateInProgress){
55
- this.updateRequested = true
56
- return
57
- }
58
-
59
- this.updateInProgress = true
60
- try {
61
- do {
62
- this.updateRequested = false
63
- try {
64
- await this.updateAsync()
65
- } catch(error) {
66
- console.error('DomeComponent: scheduled update failed', error)
67
- }
68
- } while(this.updateRequested)
69
- } finally {
70
- this.updateInProgress = false
71
- }
72
- }
73
-
74
- scheduleUpdate = debounce(() => this.runScheduledUpdateAsync(), 5)
75
-
76
- protected afterUpdate(){
77
-
78
- }
79
- }
80
- DomeComponent.prototype['__DomeComponent'] = true
81
-
82
- // export interface DomeComponent<Attrs>{
83
- // render:(attrs:Attrs)=>HTMLElement
84
- // }