pawajs 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/merger/for.js ADDED
@@ -0,0 +1,218 @@
1
+ import { createEffect } from '../reactive.js';
2
+ import { render, $state, keepContext, restoreContext } from '../index.js';
3
+ import { PawaComment, PawaElement } from '../pawaElement.js';
4
+ import { processNode, pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
5
+
6
+ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes, resume,
7
+ { comment, endComment, unique, elementArray, insertIndex,keyOrders }) => {
8
+ let firstEnter
9
+ let func
10
+ let once=false
11
+ let promised
12
+ const keyOrder= keyOrders || new Map()
13
+ const evaluate = () => {
14
+ if (endComment.parentElement === null) {
15
+ el._deleteEffects()
16
+ }
17
+ try {
18
+ const keys = Object.keys(el._context);
19
+ const resolvePath = (path, obj) => {
20
+ return path.split('.').reduce((acc, key) => acc?.[key], obj);
21
+ };
22
+ const values = keys.map((key) => resolvePath(key, el._context));
23
+
24
+ let array
25
+ if (!func) {
26
+
27
+ const funcs = new Function(...keys, `
28
+ return ${arrayName}
29
+ `)
30
+ func = funcs
31
+ }
32
+ let update
33
+ array = func(...values)
34
+ if (!firstEnter) {
35
+ const div = document.createElement('div')
36
+ array.forEach((item, index) => {
37
+ const context = el._context
38
+ const itemContext = {
39
+ [arrayItem]: item,
40
+ [indexes]: index,
41
+ ...context
42
+ }
43
+ const newElement = el._attrElement('for')
44
+ newElement.setAttribute('data-for-index', index)
45
+ processNode(newElement, itemContext)
46
+ div.appendChild(newElement)
47
+ })
48
+ const removeElement = []
49
+
50
+ const newElementsMap = new Map()
51
+ Array.from(div.children).forEach(child => {
52
+ const key = child.getAttribute('for-key')
53
+ if (key) newElementsMap.set(key, child)
54
+ })
55
+
56
+ elementArray.forEach((keyComment) => {
57
+ let lookLike=null
58
+ // console.log(keyComment.nextSibling,keyComment.nextSibling._exitAnimation,'next sib');
59
+ lookLike = newElementsMap.get(keyComment._forKey) || null
60
+ if (lookLike !== null) {
61
+ keyComment._index = lookLike.getAttribute('data-for-index')
62
+ }
63
+ if (!el.getAttribute('for-key')) {
64
+ return
65
+ }
66
+ if(lookLike) return
67
+ if (lookLike === null) {
68
+ elementArray.delete(keyComment)
69
+
70
+ insertIndex.delete(Number(keyComment._forKey))
71
+ keyOrder.delete(keyComment._index)
72
+ const promise = new Promise(async(resolve) => {
73
+ await pawaWayRemover(keyComment,keyComment._endComment)
74
+ keyComment._deleteKey()
75
+ resolve(true)
76
+ })
77
+ removeElement.push(promise)
78
+ }
79
+ })
80
+ //insertIndex.clear()
81
+ //find if update needed
82
+ if (div.children.length > elementArray.size || elementArray.size > div.children.length) {
83
+ update=true
84
+ }else{
85
+ let indexKey=0
86
+ keyOrder.forEach((value,key)=>{
87
+ if(update)return;
88
+ if(div.children[indexKey].getAttribute('data-for-index') !== key){
89
+ update=true
90
+ }
91
+ })
92
+ }
93
+ const next = () => Promise.all(removeElement).then(async (res) => {
94
+ if (res) {
95
+ if (update) {
96
+ const keyMap = new Map()
97
+ elementArray.forEach(child => {
98
+ keyMap.set(child._forKey, child)
99
+ })
100
+ Array.from(div.children).forEach((child, index) => {
101
+ const key = child.getAttribute('for-key')
102
+ const context = el._context
103
+ const itemContext = {
104
+ [arrayItem]: array[index],
105
+ [indexes]: index,
106
+ ...context
107
+ }
108
+
109
+ if (keyMap.get(key)) {
110
+ let oldElement = keyMap.get(key)
111
+ const fragment = oldElement._resetForKeyElement()
112
+
113
+ oldElement.remove()
114
+
115
+ endComment.parentElement.insertBefore(oldElement._endComment, endComment)
116
+ endComment.parentElement.insertBefore(oldElement, oldElement._endComment)
117
+ Array.from(fragment.childNodes).forEach((com) => {
118
+ endComment.parentElement.insertBefore(com, oldElement._endComment)
119
+ })
120
+ } else {
121
+ const keyComment = document.createComment(`key=${child.getAttribute('for-key') || index}`)
122
+ const endKeyComment = document.createComment('end key')
123
+ PawaComment.Element(keyComment)
124
+ keyComment._endComment = endKeyComment
125
+ keyComment._setKey(child.getAttribute('for-key') || index)
126
+ child.setAttribute('for-unique', unique)
127
+ child.setAttribute('data-for-index', index)
128
+ keyComment._index = index
129
+ processNode(child, itemContext)
130
+
131
+ endComment.parentElement.insertBefore(endKeyComment, endComment)
132
+ endKeyComment.parentElement.insertBefore(keyComment, endKeyComment)
133
+ endKeyComment.parentElement.insertBefore(child, endKeyComment)
134
+ insertIndex.set(index, child.getAttribute('for-key') || 'key')
135
+ if (stateContext._hasRun) {
136
+ stateContext._hasRun = false
137
+ keepContext(stateContext)
138
+ }
139
+ elementArray.add(keyComment)
140
+ render(child, itemContext)
141
+ stateContext._hasRun = true
142
+ }
143
+ })
144
+ }
145
+ }
146
+ })
147
+
148
+ if (promised instanceof Promise) {
149
+ promised = promised.then(()=>{
150
+ return next()
151
+ })
152
+ } else {
153
+ promised = next()
154
+ }
155
+
156
+ }
157
+ if (firstEnter && !resume) {
158
+ array.forEach((item, index) => {
159
+ const context = el._context
160
+ const itemContext = {
161
+ [arrayItem]: item,
162
+ [indexes]: index,
163
+ ...context
164
+ }
165
+ const newElement = el._attrElement('for')
166
+ const keyComment = document.createComment(`key=${newElement.getAttribute('for-key') || index}`)
167
+ const endKeyComment = document.createComment('end key')
168
+ PawaComment.Element(keyComment)
169
+ keyComment._endComment = endKeyComment
170
+ newElement.setAttribute('for-unique', unique)
171
+ newElement.setAttribute('data-for-index', index)
172
+ processNode(newElement, itemContext)
173
+ keyOrder.set(index,{comment:keyComment})
174
+ keyComment._index = index
175
+ keyComment._setKey(newElement.getAttribute('for-key') || index)
176
+ endComment.parentElement.insertBefore(endKeyComment, endComment)
177
+ endKeyComment.parentElement.insertBefore(keyComment, endKeyComment)
178
+ endKeyComment.parentElement.insertBefore(newElement, endKeyComment)
179
+ insertIndex.set(index, newElement.getAttribute('for-key') || 'key')
180
+ // if(newElement.getAttribute('for-key)){
181
+ // keyMap
182
+ // }
183
+ if (stateContext._hasRun) {
184
+ stateContext._hasRun = false
185
+ keepContext(stateContext)
186
+ }
187
+ render(newElement, itemContext)
188
+ stateContext._hasRun = true
189
+ elementArray.add(keyComment)
190
+ })
191
+
192
+ } else {
193
+ if(!resume)return
194
+ if(once)return
195
+ elementArray.forEach((keyComment) => {
196
+ if(keyComment.nextElementSibling === null) return
197
+ const context = el._context
198
+ const itemContext = {
199
+ [arrayItem]: array[keyComment._index],
200
+ [indexes]: keyComment._index,
201
+ ...context
202
+ }
203
+ render(keyComment.nextElementSibling, itemContext,{notRender:false,index:null})
204
+
205
+ })
206
+ once=true
207
+ }
208
+ firstEnter = false
209
+ } catch (error) {
210
+ setPawaDevError({
211
+ message: `Error from For directive ${error.message}`,
212
+ error: error,
213
+ template: el._template
214
+ })
215
+ }
216
+ }
217
+ return evaluate
218
+ }
package/merger/if.js ADDED
@@ -0,0 +1,125 @@
1
+ import { render, $state, keepContext,restoreContext} from '../index.js';
2
+ import { pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
3
+
4
+ export const merger_if=(el,attr,stateContext,resume=false,{comment,endComment,children,chained,chainMap})=>{
5
+ let func
6
+ let removePromise=null
7
+ let promised=false
8
+ let firstEnter = false
9
+ const parent = endComment.parentElement
10
+ let latestChain
11
+ let oldChain
12
+ if (resume) {
13
+ oldChain={id:attr.value}
14
+ }
15
+ const evaluate = () => {
16
+ if (endComment.parentElement === null) {
17
+ el._deleteEffects()
18
+ }
19
+ try {
20
+
21
+ if (!func) {
22
+ func =new Map()
23
+ chained.forEach((item)=>{
24
+ if(item.condition === 'else')return
25
+ let funcs=safeEval(el._context,item.exp,item.element)
26
+ func.set(item.exp,funcs)
27
+ })
28
+ }
29
+ const values = getEvalValues(el._context)
30
+ let current
31
+ chained.forEach(element => {
32
+ if (current || element.condition === 'else') return
33
+ current=func.get(element.exp)(...values)
34
+ if (current) {
35
+ latestChain={
36
+ id:element.exp,
37
+ condition:element.condition
38
+ }
39
+ }else{
40
+ latestChain={
41
+ id:'else',
42
+ condition:'else'
43
+ }
44
+ }
45
+ });
46
+ if (!firstEnter) {
47
+ for (const fn of el._terminateEffects) {
48
+ comment._terminateEffects.add(fn)
49
+ }
50
+ }
51
+ const setElement=(newElement,exp)=>{
52
+ newElement.removeAttribute(exp)
53
+ if (stateContext._hasRun) {
54
+ stateContext._hasRun = false
55
+ keepContext(stateContext)
56
+ }
57
+ comment.data=`condition ${exp}`
58
+ parent.insertBefore(newElement, endComment)
59
+ render(newElement, el._context)
60
+ stateContext._hasRun = true
61
+ }
62
+ if (comment.nextSibling !== endComment && oldChain.id !== latestChain.id) {
63
+ removePromise=pawaWayRemover(comment,endComment)
64
+ }
65
+ if (comment.nextSibling === endComment) {
66
+
67
+ Promise.resolve(removePromise).then(()=>{
68
+ if (comment.nextSibling === endComment) {
69
+ const getRightElement=chainMap.get(latestChain.id)
70
+ if (getRightElement) {
71
+ const ele=getRightElement.element.cloneNode(true)
72
+ setElement(ele,latestChain.condition)
73
+ }
74
+ }
75
+ promised=false
76
+ })
77
+ promised=true
78
+
79
+ }
80
+ if(firstEnter){
81
+ if(oldChain.id === latestChain.id)return
82
+ const getRightElement=chainMap.get(latestChain.id)
83
+ if (getRightElement) {
84
+ Promise.resolve(removePromise).then(()=>{
85
+ if (comment.nextSibling === endComment && oldChain.id === latestChain.id) {
86
+ const getRightElements=chainMap.get(latestChain.id)
87
+ if (getRightElements) {
88
+ const ele=getRightElement.element.cloneNode(true)
89
+ setElement(ele,latestChain.condition)
90
+ }
91
+ }
92
+ promised=false
93
+ })
94
+ }else{
95
+ removePromise=pawaWayRemover(comment,endComment)
96
+ }
97
+ }
98
+
99
+ if(firstEnter === false && resume && current){
100
+ el.removeAttribute(attr.name)
101
+ if (stateContext._hasRun) {
102
+ stateContext._hasRun = false
103
+ keepContext(stateContext)
104
+ }
105
+ const number={notRender:null,index:null}
106
+ children.forEach((value, index) => {
107
+ number.index=index
108
+ if(number.notRender && index >= number.notRender) return
109
+ render(value,el._context,number)
110
+ })
111
+ stateContext._hasRun=true
112
+ }
113
+ oldChain=latestChain
114
+ firstEnter=true
115
+ } catch (error) {
116
+ console.log(error.message,error.stack)
117
+ setPawaDevError({
118
+ message: `Error from IF directive ${error.message}`,
119
+ error: error,
120
+ template: el._template
121
+ })
122
+ }
123
+ }
124
+ return evaluate
125
+ }
package/merger/key.js ADDED
@@ -0,0 +1,101 @@
1
+ import { render, $state, keepContext,restoreContext} from '../index.js';
2
+ import { pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
3
+
4
+ export const merger_key=(el,attr,stateContext,resume=false,{comment,endComment,children,old})=>{
5
+ let func
6
+ let removePromise=null
7
+ let promised=false
8
+ let firstEnter = false
9
+ const parent = endComment.parentElement
10
+ let latestState
11
+ let oldsate
12
+ let once=false
13
+ if (resume) {
14
+ oldsate=old
15
+ }
16
+ const evaluate = () => {
17
+ if (endComment.parentElement === null) {
18
+ el._deleteEffects()
19
+ }
20
+ try {
21
+ let value=attr.value
22
+ let keyValue
23
+ if (!func) {
24
+ func=safeEval(el._context,attr.value,el)
25
+ }
26
+ const values = getEvalValues(el._context)
27
+ let current
28
+
29
+ if (!firstEnter) {
30
+ for (const fn of el._terminateEffects) {
31
+ comment._terminateEffects.add(fn)
32
+ }
33
+ }
34
+ const setElement=(newElement,exp)=>{
35
+ if (stateContext._hasRun) {
36
+ stateContext._hasRun = false
37
+ keepContext(stateContext)
38
+ }
39
+ comment.data=`key ${latestState}`
40
+ endComment.data=`/ key ${latestState}`
41
+ parent.insertBefore(newElement, endComment)
42
+ render(newElement, el._context)
43
+ stateContext._hasRun = true
44
+ }
45
+ latestState=func(...values)
46
+ if( resume && !once && latestState === oldsate){
47
+ if (stateContext._hasRun) {
48
+ stateContext._hasRun = false
49
+ keepContext(stateContext)
50
+ }
51
+ const number={notRender:null,index:null}
52
+ children.forEach((value, index) => {
53
+ number.index=index
54
+ if(number.notRender && index >= number.notRender) return
55
+ render(value,el._context,number)
56
+ })
57
+ stateContext._hasRun=true
58
+ once=true
59
+ }
60
+ // if(oldsate === latestState && firstEnter)return
61
+ if (comment.nextSibling !== endComment && oldsate !== latestState) {
62
+ removePromise=pawaWayRemover(comment,endComment)
63
+ }
64
+ if (oldsate !== latestState && firstEnter) {
65
+ Promise.resolve(removePromise).then(()=>{
66
+ if (comment.nextSibling === endComment && oldsate !== latestState) {
67
+ const newElement=el.cloneNode(true)
68
+ newElement.removeAttribute('key')
69
+ oldsate=latestState
70
+ setElement(newElement,latestState)
71
+ }
72
+ promised=false
73
+ })
74
+ promised=true
75
+
76
+ }
77
+ if(!firstEnter && !resume){
78
+ if(oldsate === latestState)return
79
+ if (comment.nextSibling === endComment && oldsate !== latestState) {
80
+ const newElement=el.cloneNode(true)
81
+ newElement.removeAttribute('key')
82
+ oldsate=latestState
83
+ setElement(newElement,latestState)
84
+ }
85
+
86
+ // promised=false
87
+ }
88
+
89
+
90
+ firstEnter=true
91
+ } catch (error) {
92
+ console.log(error.message,error.stack)
93
+ setPawaDevError({
94
+ message: `Error from IF directive ${error.message}`,
95
+ error: error,
96
+ template: el._template
97
+ })
98
+ }
99
+ }
100
+ return evaluate
101
+ }
@@ -0,0 +1,127 @@
1
+ import { render, $state, keepContext,restoreContext} from '../index.js';
2
+ import { pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
3
+
4
+ export const merger_switch=(el,attr,stateContext,resume=false,{comment,endComment,children,chained,chainMap,caseValue})=>{
5
+ let func
6
+ let removePromise=null
7
+ let promised=false
8
+ let firstEnter = false
9
+ const parent = endComment.parentElement
10
+ let latestChain
11
+ let oldChain
12
+ let switchFunc
13
+ if (resume) {
14
+ oldChain={id:caseValue.value}
15
+ }
16
+ const evaluate = () => {
17
+ if (endComment.parentElement === null) {
18
+ el._deleteEffects()
19
+ }
20
+ try {
21
+
22
+ if (!func) {
23
+ func =new Map()
24
+ chained.forEach((item)=>{
25
+ if(item.condition === 'default')return
26
+ let funcs=safeEval(el._context,item.exp,item.element)
27
+ func.set(item.exp,funcs)
28
+ })
29
+ switchFunc=safeEval(el._context,attr.value,el)
30
+ }
31
+ const values = getEvalValues(el._context)
32
+ let current
33
+ chained.forEach(element => {
34
+ if (current || element.condition === 'default') return
35
+ current=switchFunc(...values) === func.get(element.exp)(...values)
36
+ if (current) {
37
+ latestChain={
38
+ id:element.exp,
39
+ condition:element.condition
40
+ }
41
+ }else{
42
+ latestChain={
43
+ id:'default',
44
+ condition:'default'
45
+ }
46
+ }
47
+ });
48
+ if (!firstEnter) {
49
+ for (const fn of el._terminateEffects) {
50
+ comment._terminateEffects.add(fn)
51
+ }
52
+ }
53
+ const setElement=(newElement,exp)=>{
54
+ newElement.removeAttribute(exp)
55
+ if (stateContext._hasRun) {
56
+ stateContext._hasRun = false
57
+ keepContext(stateContext)
58
+ }
59
+ comment.data=`condition ${exp}`
60
+ parent.insertBefore(newElement, endComment)
61
+ render(newElement, el._context)
62
+ stateContext._hasRun = true
63
+ }
64
+ if (comment.nextSibling !== endComment && oldChain.id !== latestChain.id) {
65
+ removePromise=pawaWayRemover(comment,endComment)
66
+ }
67
+ if (comment.nextSibling === endComment) {
68
+
69
+ Promise.resolve(removePromise).then(()=>{
70
+ if (comment.nextSibling === endComment) {
71
+ const getRightElement=chainMap.get(latestChain.id)
72
+ if (getRightElement) {
73
+ const ele=getRightElement.element.cloneNode(true)
74
+ setElement(ele,latestChain.condition)
75
+ }
76
+ }
77
+ promised=false
78
+ })
79
+ promised=true
80
+
81
+ }
82
+ if(firstEnter){
83
+ if(oldChain.id === latestChain.id)return
84
+ const getRightElement=chainMap.get(latestChain.id)
85
+ if (getRightElement) {
86
+ Promise.resolve(removePromise).then(()=>{
87
+ if (comment.nextSibling === endComment) {
88
+ const getRightElement=chainMap.get(latestChain.id)
89
+ if (getRightElement) {
90
+ const ele=getRightElement.element.cloneNode(true)
91
+ setElement(ele,latestChain.condition)
92
+ }
93
+ }
94
+ promised=false
95
+ })
96
+ }else{
97
+ removePromise=pawaWayRemover(comment,endComment)
98
+ }
99
+ }
100
+
101
+ if(firstEnter === false && resume && current){
102
+ el.removeAttribute(attr.name)
103
+ if (stateContext._hasRun) {
104
+ stateContext._hasRun = false
105
+ keepContext(stateContext)
106
+ }
107
+ const number={notRender:null,index:null}
108
+ children.forEach((value, index) => {
109
+ number.index=index
110
+ if(number.notRender && index >= number.notRender) return
111
+ render(value,el._context,number)
112
+ })
113
+ stateContext._hasRun=true
114
+ }
115
+ oldChain=latestChain
116
+ firstEnter=true
117
+ } catch (error) {
118
+ console.log(error.message,error.stack)
119
+ setPawaDevError({
120
+ message: `Error from IF directive ${error.message}`,
121
+ error: error,
122
+ template: el._template
123
+ })
124
+ }
125
+ }
126
+ return evaluate
127
+ }
package/normal/For.js ADDED
@@ -0,0 +1,30 @@
1
+ import { createEffect } from '../reactive.js';
2
+ import { pawaWayRemover} from '../utils.js';
3
+ import { merger_for } from '../merger/for.js';
4
+ export const normal_For = (el, attr, stateContext, endComment) => {
5
+ const exp = new WeakMap()
6
+ const value = attr.value
7
+ const split = value.split(' in ')
8
+ const arrayName = split[1]
9
+ const arrayItems = split[0].split(',')
10
+ const arrayItem = arrayItems[0]
11
+ const indexes = arrayItems[1]
12
+ const comment = document.createComment(`${attr.value}`)
13
+ endComment.parentElement.insertBefore(comment, endComment)
14
+ el._underControl = comment
15
+ const unique = crypto.randomUUID()
16
+ const insertIndex = new Map()
17
+ const elementArray = new Set()
18
+ el._deCompositionElement = true
19
+ el._isKill = true
20
+ el._kill = () => {
21
+ pawaWayRemover(comment, endComment)
22
+ comment.remove(), endComment.remove();
23
+ }
24
+ const evaluate = merger_for(el, stateContext, attr, arrayName, arrayItem, indexes, false,
25
+ { comment, endComment, unique, elementArray, insertIndex })
26
+ createEffect(() => {
27
+ evaluate()
28
+ })
29
+
30
+ }
package/normal/If.js ADDED
@@ -0,0 +1,29 @@
1
+ import { createEffect } from '../reactive.js';
2
+ import { render, $state, keepContext,restoreContext} from '../index.js';
3
+ import { PawaComment, PawaElement } from '../pawaElement.js';
4
+ import { processNode, pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
5
+ import { merger_if } from '../merger/if.js';
6
+ export const normal_If=(el, attr, stateContext,endComment,chainMap,chained)=>{
7
+
8
+ const comment = document.createComment(`condition`)
9
+ el._out = true
10
+ const parent = endComment.parentElement
11
+ el._deCompositionElement = true
12
+ el._isKill = true
13
+ el._kill = () => {
14
+ pawaWayRemover(comment, endComment)
15
+ comment.remove(), endComment.remove();
16
+ }
17
+ PawaComment.Element(comment)
18
+ comment._setCoveringElement(el)
19
+ parent.insertBefore(comment, endComment)
20
+ el._underControl = comment
21
+ const context = el._context
22
+ let firstEnter = false
23
+ comment._controlComponent = true
24
+ const evaluate=merger_if(el,attr,stateContext,false,
25
+ {comment,endComment,chained,chainMap})
26
+ createEffect(() => {
27
+ evaluate()
28
+ }, el)
29
+ }
package/normal/Key.js ADDED
@@ -0,0 +1,27 @@
1
+ import { createEffect } from '../reactive.js';
2
+ import { render, $state, keepContext,restoreContext} from '../index.js';
3
+ import { PawaComment, PawaElement } from '../pawaElement.js';
4
+ import { processNode, pawaWayRemover, safeEval, getEvalValues, setPawaDevError, checkKeywordsExistence } from '../utils.js';
5
+ import { merger_key } from '../merger/key.js';
6
+ export const normal_key=(el, attr, stateContext,endComment,chainMap,chained)=>{
7
+
8
+ const comment = document.createComment(`condition`)
9
+ el._out = true
10
+ const parent = endComment.parentElement
11
+ el._deCompositionElement = true
12
+ el._isKill = true
13
+ el._kill = () => {
14
+ pawaWayRemover(comment, endComment)
15
+ comment.remove(), endComment.remove();
16
+ }
17
+ PawaComment.Element(comment)
18
+ comment._setCoveringElement(el)
19
+ parent.insertBefore(comment, endComment)
20
+ el._underControl = comment
21
+ comment._controlComponent = true
22
+ const evaluate=merger_key(el,attr,stateContext,false,
23
+ {comment,endComment})
24
+ createEffect(() => {
25
+ evaluate()
26
+ }, el)
27
+ }