pawa-ssr 1.3.21 → 1.3.23
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/package.json +1 -1
- package/power.js +389 -277
package/package.json
CHANGED
package/power.js
CHANGED
|
@@ -1,298 +1,410 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import {render} from "./index.js";
|
|
2
|
+
import { convertToNumber,evaluateExpr, processNode, reArrangeAttri, pawaGenerateId } from "./utils.js";
|
|
3
|
+
import {parseHTML} from "linkedom"
|
|
4
|
+
export const If = async(el, attr,stream) => {
|
|
5
|
+
if (el._running) return;
|
|
6
|
+
el._running = true;
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this._error=[]
|
|
35
|
-
this._lazy=false
|
|
36
|
-
this._running=false
|
|
37
|
-
this._hasForOrIf=this.hasForOrIf
|
|
38
|
-
this._createError=this.createError
|
|
39
|
-
this._setError=this.setError
|
|
40
|
-
this._hydrateProps={}
|
|
41
|
-
this._resumeAttr=''
|
|
42
|
-
this._evaluateExpr=this.evaluateExpr
|
|
43
|
-
this._reArrangeAttri=this.reArrange
|
|
44
|
-
this._replaceResumeAttr=this.replaceResumeAttr
|
|
45
|
-
this._setResumeAttr=this.setResumeAttr
|
|
46
|
-
if(this._avoidPawaRender){
|
|
47
|
-
element.removeAttribute('s-pawa-avoid')
|
|
48
|
-
Array.from(element.children).forEach((child) => {
|
|
49
|
-
if (child.nodeType === 1) {
|
|
50
|
-
child.setAttribute('s-pawa-avoid','')
|
|
8
|
+
const nextSiblings = el.nextElementSibling || null;
|
|
9
|
+
const chained=[{
|
|
10
|
+
exp:el.getAttribute('if'),
|
|
11
|
+
condition:'if',
|
|
12
|
+
element:el
|
|
13
|
+
}]
|
|
14
|
+
const chainMap=new Map()
|
|
15
|
+
chainMap.set(el.getAttribute('if'),{condition:'if',element:el})
|
|
16
|
+
const getChained = (sibling) => {
|
|
17
|
+
while (sibling) {
|
|
18
|
+
const next = sibling.nextElementSibling;
|
|
19
|
+
const isElseIf = sibling.hasAttribute('else-if');
|
|
20
|
+
const isElse = sibling.hasAttribute('else');
|
|
21
|
+
|
|
22
|
+
if (isElseIf) {
|
|
23
|
+
const exp = sibling.getAttribute('else-if');
|
|
24
|
+
chained.push({ exp, condition: 'else-if', element: sibling });
|
|
25
|
+
chainMap.set(exp, { condition: 'else-if', element: sibling });
|
|
26
|
+
sibling.remove();
|
|
27
|
+
} else if (isElse) {
|
|
28
|
+
chained.push({ exp: 'false', condition: 'else', element: sibling });
|
|
29
|
+
chainMap.set('else', { condition: 'else', element: sibling });
|
|
30
|
+
sibling.remove();
|
|
31
|
+
} else {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
sibling = next;
|
|
51
35
|
}
|
|
52
|
-
})
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* @typedef{object}
|
|
56
|
-
* @property{any}
|
|
57
|
-
* Object of Html Attributes for Rest Attributes
|
|
58
|
-
*/
|
|
59
|
-
this._restProps={}
|
|
60
|
-
this._componentChildren=null
|
|
61
|
-
this.getComponent()
|
|
62
|
-
this.setProps()
|
|
63
|
-
this.pawaAttribute()
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
*
|
|
67
|
-
* @param {HTMLElement} el
|
|
68
|
-
* @param {object} context
|
|
69
|
-
* @returns {PawaElement}
|
|
70
|
-
*/
|
|
71
|
-
static Element(el,context){
|
|
72
|
-
const pawa=new PawaElement(el,context)
|
|
73
|
-
Object.assign(el,pawa)
|
|
74
|
-
return el
|
|
75
36
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
37
|
+
getChained(nextSiblings)
|
|
38
|
+
let func=new Map()
|
|
39
|
+
let current
|
|
40
|
+
let latestChain
|
|
41
|
+
chained.forEach((item)=>{
|
|
42
|
+
if(item.condition === 'else' || current)return
|
|
43
|
+
const result = el._evaluateExpr(item.exp, el._context,`at condition directives check - ${item.exp} at ${item.element.toString()}`);
|
|
44
|
+
current=result
|
|
45
|
+
if (current) {
|
|
46
|
+
latestChain={
|
|
47
|
+
id:item.exp,
|
|
48
|
+
condition:item.condition
|
|
49
|
+
}
|
|
50
|
+
}else{
|
|
51
|
+
latestChain={
|
|
52
|
+
id:'else',
|
|
53
|
+
condition:'else'
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
})
|
|
58
|
+
const document=el.ownerDocument
|
|
59
|
+
const id=pawaGenerateId(10)
|
|
60
|
+
const comment=document.createComment(`condition(${latestChain.id})@-$@-$@${id}`)
|
|
61
|
+
const endComment=document.createComment(`end condition(${latestChain.id})@-$@-$@${id}`)
|
|
62
|
+
el.replaceWith(endComment);
|
|
63
|
+
let stringHtml=''
|
|
64
|
+
const template=document.createElement('template')
|
|
65
|
+
const store=document.createElement('template')
|
|
66
|
+
chained.forEach((item) => {
|
|
67
|
+
const clone = item.element.cloneNode(true);
|
|
68
|
+
clone._avoidPawaRender = true;
|
|
69
|
+
Array.from(clone.attributes).forEach(at => {
|
|
70
|
+
if (at.name.startsWith('c-') || at.name === 'p:c') {
|
|
71
|
+
clone.removeAttribute(at.name);
|
|
84
72
|
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return this._resumeAttr+='c-t'
|
|
96
|
-
}
|
|
73
|
+
});
|
|
74
|
+
store.appendChild(clone);
|
|
75
|
+
template.appendChild(item.element);
|
|
76
|
+
});
|
|
77
|
+
const getRightElement=chainMap.get(latestChain.id)
|
|
78
|
+
if (getRightElement) {
|
|
79
|
+
const copyElement=getRightElement.element.cloneNode(true)
|
|
80
|
+
copyElement.attributes.forEach((att)=>{
|
|
81
|
+
if(att.name.startsWith('c-')){
|
|
82
|
+
copyElement.removeAttribute(att.name)
|
|
97
83
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
84
|
+
})
|
|
85
|
+
const dataComment=document.createComment(stringHtml)
|
|
86
|
+
let newElement = el.cloneNode(true);
|
|
87
|
+
if (attr.value === latestChain.id) {
|
|
88
|
+
el._replaceResumeAttr('if',`c-if-${id}`,latestChain.id)
|
|
89
|
+
newElement = el.cloneNode(true);
|
|
90
|
+
}else{
|
|
91
|
+
el._replaceResumeAttr('if',`c-if-${id}`,latestChain.id,copyElement)
|
|
92
|
+
newElement = copyElement;
|
|
93
|
+
}
|
|
94
|
+
newElement.removeAttribute(latestChain.condition)
|
|
95
|
+
newElement.setAttribute('pawa-same',true)
|
|
96
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
97
|
+
stream(`<!--${comment.data}-->`)
|
|
98
|
+
store.setAttribute('p:store-if',id)
|
|
99
|
+
store.setAttribute('p:store','')
|
|
100
|
+
comment.parentElement.insertBefore(store,endComment)
|
|
101
|
+
stream(store.outerHTML)
|
|
102
|
+
comment.parentElement.insertBefore(newElement,endComment)
|
|
103
|
+
await render(newElement, el._context,stream);
|
|
104
|
+
stream(`<!--${endComment.data}-->`)
|
|
105
|
+
} else {
|
|
106
|
+
|
|
107
|
+
template.setAttribute('pawa-render',true)
|
|
108
|
+
endComment.replaceWith(template);
|
|
109
|
+
stream(`${template.outerHTML}`)
|
|
110
|
+
// await render(template, el._context,stream);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
export const Switch = async(el, attr,stream) => {
|
|
114
|
+
if (el._running) return;
|
|
115
|
+
el._running = true;
|
|
116
|
+
|
|
117
|
+
const nextSiblings = el.nextElementSibling || null;
|
|
118
|
+
const cases =el.getAttribute('case')
|
|
119
|
+
const chained=[{
|
|
120
|
+
exp:el.getAttribute('case'),
|
|
121
|
+
condition:'case',
|
|
122
|
+
element:el
|
|
123
|
+
}]
|
|
124
|
+
const chainMap=new Map()
|
|
125
|
+
chainMap.set(el.getAttribute('case'),{condition:'case',element:el})
|
|
126
|
+
const getChained = (sibling) => {
|
|
127
|
+
while (sibling) {
|
|
128
|
+
const next = sibling.nextElementSibling;
|
|
129
|
+
const isCase = sibling.hasAttribute('case') && !sibling.hasAttribute('switch');
|
|
130
|
+
const isDefault = sibling.hasAttribute('s-default');
|
|
131
|
+
|
|
132
|
+
if (isCase) {
|
|
133
|
+
const exp = sibling.getAttribute('case');
|
|
134
|
+
chained.push({ exp, condition: 'case', element: sibling });
|
|
135
|
+
chainMap.set(exp, { condition: 'case', element: sibling });
|
|
136
|
+
sibling.remove();
|
|
137
|
+
} else if (isDefault) {
|
|
138
|
+
chained.push({ exp: 'false', condition: 'default', element: sibling });
|
|
139
|
+
chainMap.set('default', { condition: 'default', element: sibling });
|
|
140
|
+
sibling.remove();
|
|
141
|
+
} else {
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
sibling = next;
|
|
115
145
|
}
|
|
116
|
-
setTextResume()
|
|
117
|
-
}
|
|
118
|
-
this._el.setAttribute('p:c',this._resumeAttr)
|
|
119
146
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
147
|
+
getChained(nextSiblings)
|
|
148
|
+
let func=new Map()
|
|
149
|
+
let current
|
|
150
|
+
let latestChain
|
|
151
|
+
const switchFunc=el._evaluateExpr(attr.value,el._context,`at switch directive ${attr.value}`)
|
|
152
|
+
chained.forEach((item)=>{
|
|
153
|
+
if(item.condition === 'default' || current)return
|
|
154
|
+
const result = switchFunc === el._evaluateExpr(item.exp, el._context,`at condition directives check case - ${item.exp} ${item.element.toString()}`);
|
|
155
|
+
current=result
|
|
156
|
+
if (current || item.condition === 'default') {
|
|
157
|
+
latestChain={
|
|
158
|
+
id:item.exp,
|
|
159
|
+
condition:item.condition
|
|
160
|
+
}
|
|
161
|
+
}else{
|
|
162
|
+
latestChain={
|
|
163
|
+
id:'default',
|
|
164
|
+
condition:'default'
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
})
|
|
169
|
+
const document=el.ownerDocument
|
|
170
|
+
const id=pawaGenerateId(10)
|
|
171
|
+
const comment=document.createComment(`switch case (${latestChain.id})@-$@-$@${id}`)
|
|
172
|
+
const endComment=document.createComment(`end switch(${latestChain.id})@-$@-$@${id}`)
|
|
173
|
+
el.replaceWith(endComment);
|
|
174
|
+
let stringHtml=''
|
|
175
|
+
const template=document.createElement('template')
|
|
176
|
+
const store=document.createElement('template')
|
|
177
|
+
// let index=0
|
|
178
|
+
chained.forEach((item) => {
|
|
179
|
+
const clone = item.element.cloneNode(true);
|
|
180
|
+
clone._avoidPawaRender = true;
|
|
181
|
+
Array.from(clone.attributes).forEach(at => {
|
|
182
|
+
if (at.name.startsWith('c-') || at.name === 'p:c') {
|
|
183
|
+
clone.removeAttribute(at.name);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
store.appendChild(clone);
|
|
187
|
+
template.appendChild(item.element);
|
|
188
|
+
});
|
|
189
|
+
el.removeAttribute('switch')
|
|
190
|
+
const getRightElement=chainMap.get(latestChain.id)
|
|
191
|
+
if (getRightElement && (current || latestChain.condition === 'default')) {
|
|
192
|
+
const copyElement=getRightElement.element.cloneNode(true)
|
|
193
|
+
|
|
194
|
+
copyElement.attributes.forEach((att)=>{
|
|
195
|
+
if(att.name.startsWith('c-')){
|
|
196
|
+
copyElement.removeAttribute(att.name)
|
|
197
|
+
}
|
|
198
|
+
})
|
|
199
|
+
let newElement = el.cloneNode(true);
|
|
200
|
+
if (cases === latestChain.id) {
|
|
201
|
+
el._replaceResumeAttr(latestChain.condition,`c-sw-${id}`,latestChain.id)
|
|
202
|
+
newElement = el.cloneNode(true);
|
|
129
203
|
}else{
|
|
130
|
-
|
|
131
|
-
|
|
204
|
+
el._replaceResumeAttr(latestChain.condition === 's-default'?'s-default':latestChain.condition ,`c-sw-${id}`,latestChain.id,copyElement)
|
|
205
|
+
newElement = copyElement;
|
|
132
206
|
}
|
|
207
|
+
newElement.removeAttribute(latestChain.condition)
|
|
208
|
+
newElement.setAttribute('pawa-same',true)
|
|
209
|
+
store.setAttribute('p:store-switch',id)
|
|
210
|
+
store.setAttribute('p:store','')
|
|
211
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
212
|
+
stream(`<!--${comment.data}-->`)
|
|
213
|
+
comment.parentElement.insertBefore(store,endComment)
|
|
214
|
+
stream(store.outerHTML)
|
|
215
|
+
comment.parentElement.insertBefore(newElement,endComment)
|
|
216
|
+
await render(newElement, el._context,stream);
|
|
217
|
+
stream(`<!--${endComment.data}-->`)
|
|
218
|
+
} else {
|
|
219
|
+
// If no case matches and no default, we just leave the comments
|
|
220
|
+
template.setAttribute('pawa-render',true)
|
|
221
|
+
endComment.parentElement.insertBefore(comment, endComment);
|
|
222
|
+
stream(`${template.outerHTML}`)
|
|
223
|
+
// stream(`<!--${comment.data}-->`)
|
|
224
|
+
comment.parentElement.insertBefore(template, endComment);
|
|
225
|
+
// await render(template, el._context,stream);
|
|
226
|
+
// No element rendered
|
|
227
|
+
// stream(`<!--${endComment.data}-->`)
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
export const For=async(el,attr,stream)=>{
|
|
232
|
+
if(el._running){
|
|
233
|
+
return
|
|
133
234
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
235
|
+
el._running=true
|
|
236
|
+
try {
|
|
237
|
+
const value=attr.value
|
|
238
|
+
const document=el.ownerDocument
|
|
239
|
+
const dirId=pawaGenerateId(10)
|
|
240
|
+
const comment=document.createComment(`for(${value})@-$@-$@${dirId}`)
|
|
241
|
+
const endComment=document.createComment(`endfor(${value})@-$@-$@${dirId}`)
|
|
242
|
+
el.replaceWith(endComment)
|
|
243
|
+
const hasKey=el.getAttribute('for-key')
|
|
244
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
245
|
+
// More robust split using regex to find the last occurrence of ' in ' or handle simple cases
|
|
246
|
+
const match = value.match(/^(.*?) in (.*)$/);
|
|
247
|
+
if (!match) throw new Error(`Invalid for loop syntax: ${value}`);
|
|
248
|
+
const [_, itemPart, arrayName] = match;
|
|
249
|
+
const arrayItems=itemPart.split(',')
|
|
250
|
+
const arrayItem=arrayItems[0].trim()
|
|
251
|
+
const indexes=arrayItems[1]
|
|
252
|
+
const array=el._evaluateExpr(arrayName,el._context,`at for directives check - ${attr.value}`)
|
|
253
|
+
const copyElement=el.cloneNode(true)
|
|
254
|
+
const store=[]
|
|
255
|
+
Array.from(copyElement.attributes).forEach(at=>{
|
|
256
|
+
if (at.name.startsWith('c-')) {
|
|
257
|
+
store.push(at)
|
|
258
|
+
copyElement.removeAttribute(at.name)
|
|
259
|
+
}
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
const template=document.createElement('template')
|
|
263
|
+
const storeClone = copyElement.cloneNode(true)
|
|
264
|
+
storeClone._avoidPawaRender = true
|
|
265
|
+
template.appendChild(storeClone)
|
|
266
|
+
store.forEach(at=>{
|
|
267
|
+
copyElement.setAttribute(at.name,at.value)
|
|
268
|
+
})
|
|
269
|
+
const componentAttr={}
|
|
270
|
+
if(Array.isArray(array)){
|
|
271
|
+
if (array.length > 0) {
|
|
272
|
+
stream(`<!--${comment.data}-->`)
|
|
273
|
+
template.setAttribute('p:store-for',dirId)
|
|
274
|
+
template.setAttribute('p:store','')
|
|
275
|
+
endComment.parentElement.insertBefore(template,endComment)
|
|
276
|
+
stream(template.outerHTML)
|
|
277
|
+
el.attributes.forEach(attri =>{
|
|
278
|
+
if(attri.name.startsWith('c-')){
|
|
279
|
+
componentAttr[attri.name]=attri.value
|
|
145
280
|
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
hasForOrIf(){
|
|
150
|
-
if (this._el.getAttribute('if') || this._el.getAttribute('for-each') || this._el.getAttribute('else') || this._el.getAttribute('else-if')) {
|
|
151
|
-
return true
|
|
152
|
-
}else{
|
|
153
|
-
return false
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
getComponent(){
|
|
158
|
-
if (components.has(splitAndAdd(this._el.tagName.toUpperCase())) && !this._client || this._lazy) {
|
|
159
|
-
this._componentName=splitAndAdd(this._el.tagName.toUpperCase())
|
|
160
|
-
const fakeCompo=()=>true
|
|
161
|
-
this._component=new PawaComponent(components.get(splitAndAdd(this._el.tagName.toUpperCase())),fakeCompo)
|
|
162
|
-
Array.from(this._el.children).forEach(slot =>{
|
|
281
|
+
})
|
|
282
|
+
el._replaceResumeAttr('for-each',`c-for`,dirId)
|
|
283
|
+
el.removeAttribute('for-each')
|
|
163
284
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
if(this._el.hasAttribute('only-client')){
|
|
172
|
-
this._el.removeAttribute('only-client')
|
|
285
|
+
// Fix: Use for...of to ensure await works correctly in SSR
|
|
286
|
+
for (const [index, item] of array.entries()) {
|
|
287
|
+
const context=el._context
|
|
288
|
+
const itemContext = {
|
|
289
|
+
[arrayItem]: item,
|
|
290
|
+
[indexes]: index,
|
|
291
|
+
...context
|
|
173
292
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
createError({message,stack}){
|
|
182
|
-
this._error.push({message,stack})
|
|
183
|
-
}
|
|
184
|
-
//set Component props
|
|
185
|
-
setProps(){
|
|
186
|
-
if (this._componentName) {
|
|
187
|
-
const allServerAttr=getPawaAttributes()
|
|
188
|
-
this._el.attributes.forEach(attr=>{
|
|
189
|
-
if(!allServerAttr.has(attr.name)){
|
|
190
|
-
if ( !attr.name.startsWith(':')) {
|
|
191
|
-
if( attr.name.startsWith('c-') || attr.name.startsWith('p:c') || attr.name.startsWith('state-')) return
|
|
192
|
-
let name=''
|
|
193
|
-
if (attr.name.startsWith('-')) {
|
|
194
|
-
name=attr.name.slice(1)
|
|
195
|
-
}else{
|
|
196
|
-
name=attr.name
|
|
197
|
-
}
|
|
198
|
-
let hydatename
|
|
199
|
-
if(name === 'class'){
|
|
200
|
-
hydatename=':'+'className'
|
|
201
|
-
}else if(name === 'default'){
|
|
202
|
-
hydatename=':'+'defaultValue'
|
|
203
|
-
}else{
|
|
204
|
-
hydatename=':'+name
|
|
205
|
-
}
|
|
206
|
-
this._hydrateProps[hydatename]=attr.value
|
|
207
|
-
const setProps=()=>{
|
|
208
|
-
let value=attr.value
|
|
209
|
-
if (value.includes('@{')) {
|
|
210
|
-
const regex = /@{([^}]*)}/g;
|
|
211
|
-
value = value.replace(regex, (match, expression) => {
|
|
212
|
-
|
|
213
|
-
const res = this.evaluateExpr(expression,this._context,`evaluating props with template operators at ${attr.name} - ${attr.value} : ${this._template}`)
|
|
214
|
-
return res
|
|
215
|
-
|
|
216
|
-
});
|
|
217
|
-
return value
|
|
218
|
-
}else if( attr.name.startsWith('on-') || attr.name.startsWith('out-') || attr.name === 'ref'){
|
|
219
|
-
const res=this.evaluateExpr(`(e)=>{
|
|
220
|
-
${attr.value}
|
|
221
|
-
}`, this._context,`evaluating props with template operators at ${attr.name} - ${attr.value} : ${this._template}`)
|
|
222
|
-
return res
|
|
223
|
-
}
|
|
224
|
-
return attr.value
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
this._restProps[name]={name:name,value:attr.value}
|
|
228
|
-
name=name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
229
|
-
if (this._props[name] || name ==='class' && this._props?.className || name ==='default' && this._props.defaultValue) return
|
|
230
|
-
if (name === 'class') {
|
|
231
|
-
this._props['className']=setProps
|
|
232
|
-
}else if(name === 'default'){
|
|
233
|
-
this._props['defaultValue']=setProps
|
|
234
|
-
}else{
|
|
235
|
-
this._props[name]=setProps
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
} else if(attr.name.startsWith(':')) {
|
|
239
|
-
this._hydrateProps[attr.name.slice(1)]=attr.value
|
|
240
|
-
if(attr.value === '') attr.value=true;
|
|
241
|
-
try {
|
|
242
|
-
const func = this.evaluateExpr(`()=>{
|
|
243
|
-
const prop= ${replaceTemplateOperators(attr.value)};
|
|
244
|
-
if(prop === '')return prop
|
|
245
|
-
return prop
|
|
246
|
-
}
|
|
247
|
-
`,this._context,`setting props at ${attr.name} - ${attr.value} : ${this._template}`)
|
|
248
|
-
let name=attr.name.slice(1)
|
|
249
|
-
if(name.includes('-')){
|
|
250
|
-
name=name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
251
|
-
}
|
|
252
|
-
this._props[name]=func
|
|
253
|
-
} catch (error) {
|
|
254
|
-
console.log(error.message,error.stack)
|
|
255
|
-
__pawaDev.setError({
|
|
256
|
-
el:this._el,
|
|
257
|
-
msg:`errors while setting props at runtime ${error.message}`,
|
|
258
|
-
directives:'setting props',
|
|
259
|
-
stack:error.stack,
|
|
260
|
-
template:el?._template,
|
|
261
|
-
})
|
|
262
|
-
}
|
|
293
|
+
itemContext[arrayItem]=item
|
|
294
|
+
const newElement=el.cloneNode(true)
|
|
295
|
+
if(index !== 0){
|
|
296
|
+
newElement.removeAttribute('c-for')
|
|
297
|
+
for (const [key,value] of Object.entries(componentAttr)) {
|
|
298
|
+
if(newElement.hasAttribute(key)){ //removing element with resuming attri from second -- for element
|
|
299
|
+
newElement.removeAttribute(key)
|
|
263
300
|
}
|
|
264
301
|
}
|
|
265
|
-
}
|
|
302
|
+
}
|
|
303
|
+
newElement.setAttribute('pawa-same',true)
|
|
304
|
+
processNode(newElement,itemContext)
|
|
305
|
+
|
|
306
|
+
const key=newElement.getAttribute('for-key')
|
|
307
|
+
const keyComment=document.createComment(`forKey@-$@-$@${dirId}@-$@-$@${key || index}`)
|
|
308
|
+
const endKeyComment=document.createComment(`endForKey@-$@-$@${dirId}@-$@-$@${key || index}`)
|
|
309
|
+
endComment.parentElement.insertBefore(endKeyComment,endComment)
|
|
310
|
+
endKeyComment.parentElement.insertBefore(keyComment,endKeyComment)
|
|
311
|
+
stream(`<!--${keyComment.data}-->`)
|
|
312
|
+
endKeyComment.parentElement.insertBefore(newElement,endKeyComment)
|
|
313
|
+
await render(newElement,itemContext,stream)
|
|
314
|
+
stream(`<!--${endKeyComment.data}-->`)
|
|
266
315
|
}
|
|
316
|
+
stream(`<!--${endComment.data}-->`)
|
|
317
|
+
}else{
|
|
318
|
+
template.setAttribute('pawa-render',true)
|
|
319
|
+
stream(`<template pawa-render="true">${el.outerHTML}</template>`)
|
|
320
|
+
template.appendChild(el)
|
|
321
|
+
comment.replaceWith(template)
|
|
322
|
+
endComment.remove()
|
|
267
323
|
}
|
|
268
|
-
evaluateExpr(expr, context = {},error){
|
|
269
|
-
try {
|
|
270
|
-
const keys = Object.keys(context);
|
|
271
|
-
// Create a cache key based on the expression and the available context keys
|
|
272
|
-
// We sort keys to ensure consistent cache hits regardless of key order
|
|
273
|
-
const cacheKey = expr + '|||' + keys.sort().join(',');
|
|
274
|
-
|
|
275
|
-
let func = expressionCache.get(cacheKey);
|
|
276
|
-
if (!func) {
|
|
277
|
-
func = new Function(...keys, `
|
|
278
|
-
const require=null
|
|
279
|
-
return ${expr}`);
|
|
280
|
-
expressionCache.set(cacheKey, func);
|
|
281
324
|
}
|
|
325
|
+
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error(error.message,error.stack)
|
|
328
|
+
__pawaDev.setError({
|
|
329
|
+
el:el,
|
|
330
|
+
msg:`error from for-each ${attr.value}`+ error.message + error.stack,
|
|
331
|
+
directives:'for-each',
|
|
332
|
+
stack:error.stack,
|
|
333
|
+
template:el?._template,
|
|
334
|
+
})
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
282
338
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
console.error(`Evaluation failed for: ${expr}`,error,err.message,err.stack);
|
|
287
|
-
__pawaDev.setError({
|
|
288
|
-
el:this._el,
|
|
289
|
-
msg:`${error} ${err.message}`,
|
|
290
|
-
directives:'expression',
|
|
291
|
-
stack:err.stack,
|
|
292
|
-
template:this._el?._template,
|
|
293
|
-
})
|
|
294
|
-
return null;
|
|
339
|
+
export const State=async(el,attr)=>{
|
|
340
|
+
if (el._running) {
|
|
341
|
+
return
|
|
295
342
|
}
|
|
296
|
-
|
|
343
|
+
try {
|
|
344
|
+
|
|
345
|
+
const name=attr.name.split('-')[1]
|
|
346
|
+
el._replaceResumeAttr(attr.name,`c-$-${name}`,attr.value)
|
|
347
|
+
el.removeAttribute(attr.name)
|
|
348
|
+
const result=el._evaluateExpr(attr.value,el._context,`at state directive ${attr.name}=${attr.value}`)
|
|
349
|
+
// el.setAttribute(`resume-state-${name}`,attr.value)
|
|
350
|
+
el._context[name]={value:result}
|
|
351
|
+
} catch (error) {
|
|
352
|
+
console.log(error.message,error.stack)
|
|
353
|
+
__pawaDev.setError({
|
|
354
|
+
el:el,
|
|
355
|
+
msg:`error from state ${attr.name} : ${attr.value}`+ error.message + error.stack,
|
|
356
|
+
directives:el.tagName,
|
|
357
|
+
stack:error.stack,
|
|
358
|
+
template:el?._template,
|
|
359
|
+
})
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export const Key=async(el,attr,stream)=>{
|
|
365
|
+
if(el._running){
|
|
366
|
+
return
|
|
367
|
+
}
|
|
368
|
+
el._running=true
|
|
369
|
+
try {
|
|
370
|
+
const value=attr.value
|
|
371
|
+
const document=el.ownerDocument
|
|
372
|
+
const dirId=pawaGenerateId(10)
|
|
373
|
+
const comment=document.createComment(`key`)
|
|
374
|
+
const endComment=document.createComment(`key`)
|
|
375
|
+
const clone=el.cloneNode(true)
|
|
376
|
+
clone._avoidPawaRender = true
|
|
377
|
+
const template=document.createElement('template')
|
|
378
|
+
template.setAttribute('p:store-key',dirId)
|
|
379
|
+
template.setAttribute('p:store','')
|
|
380
|
+
Array.from(clone.attributes).forEach(at => {
|
|
381
|
+
if (at.name.startsWith('c-') || at.name === 'p:c') {
|
|
382
|
+
clone.removeAttribute(at.name);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
template.appendChild(clone)
|
|
386
|
+
el.replaceWith(endComment)
|
|
387
|
+
endComment.parentElement.insertBefore(comment,endComment)
|
|
388
|
+
const func=el._evaluateExpr(attr.value,el._context,`error at Key - ${attr.name} = ${attr.value}`)
|
|
389
|
+
endComment.parentElement.insertBefore(template,endComment)
|
|
390
|
+
comment.data=`key(${func})@-$@-$@${dirId}`
|
|
391
|
+
endComment.data=`key(${func})@-$@-$@${dirId}`
|
|
392
|
+
stream(`<!--${comment.data}-->`)
|
|
393
|
+
stream(template.outerHTML)
|
|
394
|
+
el._replaceResumeAttr('key',`c-key-${dirId}`,typeof func === 'string'?`'${func}'`:func)
|
|
395
|
+
el.removeAttribute(attr.name)
|
|
396
|
+
const newElement=el.cloneNode(true)
|
|
397
|
+
endComment.parentElement.insertBefore(newElement,endComment)
|
|
398
|
+
await render(newElement,el._context,stream)
|
|
399
|
+
stream(`<!--${endComment.data}-->`)
|
|
400
|
+
}catch(error){
|
|
401
|
+
console.error(error.message,error.stack)
|
|
402
|
+
__pawaDev.setError({
|
|
403
|
+
el:el,
|
|
404
|
+
msg:`error from Key at ${attr.value}`+ error.message + error.stack,
|
|
405
|
+
directives:el.tagName,
|
|
406
|
+
stack:error.stack,
|
|
407
|
+
template:el?._template,
|
|
408
|
+
})
|
|
297
409
|
}
|
|
298
|
-
|
|
410
|
+
}
|