pawajs 1.4.37 → 1.4.39
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/index.d.ts +27 -0
- package/index.js +54 -24
- package/merger/for.js +9 -19
- package/normal/component.js +45 -7
- package/package.json +1 -1
- package/pawaElement.js +31 -14
- package/power.js +22 -19
- package/reactive.js +9 -2
- package/server.js +1 -0
package/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export interface PawaElement extends HTMLElement {
|
|
|
10
10
|
_terminateEffects: Set<Function>;
|
|
11
11
|
_deleteEffects: () => void;
|
|
12
12
|
_slots: DocumentFragment;
|
|
13
|
+
_stateContext: any;
|
|
13
14
|
_mainAttribute: Record<string, any>;
|
|
14
15
|
_preRenderAvoid: string[];
|
|
15
16
|
_lazy: boolean;
|
|
@@ -74,6 +75,7 @@ export interface PawaElement extends HTMLElement {
|
|
|
74
75
|
mount(): void;
|
|
75
76
|
elementType(): void;
|
|
76
77
|
setProps(): void;
|
|
78
|
+
safeEval(context: any, expr: string, error?: string, element?: boolean): any;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export interface PawaComment extends Comment {
|
|
@@ -157,6 +159,9 @@ export function pluginsMap(): {
|
|
|
157
159
|
fullNamePlugin: Set<string>;
|
|
158
160
|
externalPlugin: Record<string, Function>;
|
|
159
161
|
externalPluginMap: Map<string, string[]>;
|
|
162
|
+
primaryDirective: Set<string>;
|
|
163
|
+
pawaAttributes: Set<string>;
|
|
164
|
+
allowAsProp: Set<string>;
|
|
160
165
|
};
|
|
161
166
|
|
|
162
167
|
export const escapePawaAttribute: Set<string>;
|
|
@@ -178,6 +183,19 @@ export function keepContext(context: any): void;
|
|
|
178
183
|
|
|
179
184
|
export const components: Map<string, Function>;
|
|
180
185
|
|
|
186
|
+
export const lazyComponents: Map<string, any>;
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Internal registry for tracking elements awaiting lazy component loading.
|
|
190
|
+
*/
|
|
191
|
+
export const lazyComponentElement: Map<string, { element: PawaElement; func: Function }[]>;
|
|
192
|
+
|
|
193
|
+
export function addLazyComponentElement(element: PawaElement, func: Function): void;
|
|
194
|
+
|
|
195
|
+
export function createIntersectionObserver(element: HTMLElement, observeBy?: HTMLElement): IntersectionObserver;
|
|
196
|
+
|
|
197
|
+
export const HmrComponentMap: Map<string, any>;
|
|
198
|
+
|
|
181
199
|
export function getCurrentContext(): any;
|
|
182
200
|
|
|
183
201
|
export function setPawaAttributes(...attr: string[]): void;
|
|
@@ -278,6 +296,12 @@ export function useAsync(): { $async: <T>(callback: () => T) => T ,onSuspense:(h
|
|
|
278
296
|
*/
|
|
279
297
|
export function isResume(): boolean;
|
|
280
298
|
|
|
299
|
+
/**
|
|
300
|
+
* Forwards props to the child component.
|
|
301
|
+
* @param {Record<string, any>} [props] - Props to forward.
|
|
302
|
+
*/
|
|
303
|
+
export function forwardProps(props?: Record<string, any>): void;
|
|
304
|
+
|
|
281
305
|
/**
|
|
282
306
|
* Exposes variables to the template scope.
|
|
283
307
|
* @param {Record<string, any>} [obj] - Variables to expose.
|
|
@@ -335,7 +359,10 @@ declare const Pawa: {
|
|
|
335
359
|
setContext: typeof setContext;
|
|
336
360
|
$state: typeof $state;
|
|
337
361
|
pawaStartApp: typeof pawaStartApp;
|
|
362
|
+
useAsync: typeof useAsync;
|
|
363
|
+
useInnerContext: typeof useInnerContext;
|
|
338
364
|
RegisterComponent: typeof RegisterComponent;
|
|
365
|
+
forwardProps: typeof forwardProps;
|
|
339
366
|
runEffect: typeof runEffect;
|
|
340
367
|
html: typeof html;
|
|
341
368
|
};
|
package/index.js
CHANGED
|
@@ -75,6 +75,7 @@ const startsWithSet = new Set()
|
|
|
75
75
|
const fullNamePlugin = new Set()
|
|
76
76
|
const externalPlugin = {}
|
|
77
77
|
const externalPluginMap = new Map()
|
|
78
|
+
const allowAsProp= new Set()
|
|
78
79
|
let pawaAttributes = new Set()
|
|
79
80
|
let primaryDirective = new Set()
|
|
80
81
|
|
|
@@ -90,6 +91,7 @@ const mapsPlugins = {
|
|
|
90
91
|
externalPluginMap,
|
|
91
92
|
primaryDirective,
|
|
92
93
|
pawaAttributes,
|
|
94
|
+
allowAsProp
|
|
93
95
|
}
|
|
94
96
|
export const pluginsMap = () => mapsPlugins
|
|
95
97
|
export const escapePawaAttribute = new Set()
|
|
@@ -120,7 +122,8 @@ const applyMode = (mode, callback) => {
|
|
|
120
122
|
}
|
|
121
123
|
}
|
|
122
124
|
/**
|
|
123
|
-
* @typedef {{startsWith:string,mode:null |'client'|'server',dependency:Array<string>,
|
|
125
|
+
* @typedef {{startsWith:string,mode:null |'client'|'server',dependency:Array<string>,
|
|
126
|
+
* allowAsProp:boolean,fullName:string,plugin:(el:HTMLElement | PawaElement,attr:object)=>void}} AttriPlugin
|
|
124
127
|
*/
|
|
125
128
|
/**
|
|
126
129
|
* @typedef {{
|
|
@@ -155,8 +158,12 @@ func.forEach(fn => {
|
|
|
155
158
|
dependentPawaAttribute.add(dp); extPluginArray.push(dp)
|
|
156
159
|
})
|
|
157
160
|
}
|
|
161
|
+
|
|
158
162
|
const name = attrPlugins.fullName || attrPlugins.startsWith, set = attrPlugins.fullName ? fullNamePlugin : startsWithSet
|
|
159
163
|
if (pawaAttributes.has(name)) { console.warn(`attribute plugin already exist ${name}`); return }
|
|
164
|
+
if (attrPlugins?.allowAsProp) {
|
|
165
|
+
allowAsProp.add(name)
|
|
166
|
+
}
|
|
160
167
|
applyMode(attrPlugins?.mode, () => {
|
|
161
168
|
pawaAttributes.add(name); set.add(name); externalPlugin[name] = attrPlugins.plugin
|
|
162
169
|
if (extPluginArray.length) externalPluginMap.set(name, extPluginArray)
|
|
@@ -227,9 +234,9 @@ const setPrimaryAttibute = (...name) => {
|
|
|
227
234
|
|
|
228
235
|
export const getPrimaryDirectives=()=>primaryDirective
|
|
229
236
|
|
|
230
|
-
setPrimaryAttibute('if', 'else-if', 'for-each', 'else','switch','case','default','
|
|
237
|
+
setPrimaryAttibute('if', 'else-if', 'for-each', 'else','switch','case','s-default','key')
|
|
231
238
|
setPawaAttributes('if', 'else-if', 'for-each', 'else', 'mount',
|
|
232
|
-
'unmount', 'forKey', 'state-', 'on-', 'out-','key','switch','case','default')
|
|
239
|
+
'unmount', 'forKey', 'state-', 'on-', 'out-','key','switch','case','s-default')
|
|
233
240
|
export const getDependentAttribute = () => dependentPawaAttribute
|
|
234
241
|
export const getPawaAttributes = () => {
|
|
235
242
|
return pawaAttributes
|
|
@@ -237,10 +244,11 @@ export const getPawaAttributes = () => {
|
|
|
237
244
|
let laziler
|
|
238
245
|
export const lazyComponentElement=new Map()
|
|
239
246
|
export const addLazyComponentElement=(element,func)=>{
|
|
240
|
-
|
|
241
|
-
|
|
247
|
+
const tagName=splitAndAdd(element.tagName)
|
|
248
|
+
if (lazyComponentElement.has(tagName)) {
|
|
249
|
+
lazyComponentElement.get(tagName).push({element:element,func})
|
|
242
250
|
}else{
|
|
243
|
-
lazyComponentElement.set(
|
|
251
|
+
lazyComponentElement.set(tagName, [{element:element,func}])
|
|
244
252
|
}
|
|
245
253
|
}
|
|
246
254
|
/**
|
|
@@ -279,7 +287,7 @@ export const createIntersectionObserver = (element, observeBy) => {
|
|
|
279
287
|
const observer = new IntersectionObserver(entries => {
|
|
280
288
|
entries.forEach(entry => {
|
|
281
289
|
if (entry.isIntersecting) {
|
|
282
|
-
const tagName = element.tagName;
|
|
290
|
+
const tagName = splitAndAdd(element.tagName);
|
|
283
291
|
const lazyData = lazyComponents.get(tagName);
|
|
284
292
|
|
|
285
293
|
if (!lazyData) return;
|
|
@@ -306,6 +314,7 @@ export const createIntersectionObserver = (element, observeBy) => {
|
|
|
306
314
|
el._stateContext._hasRun = true;
|
|
307
315
|
}
|
|
308
316
|
}
|
|
317
|
+
lazyComponentElement.delete(tagName)
|
|
309
318
|
observer.disconnect();
|
|
310
319
|
}).catch(err => console.error(`Lazy load failed for ${tagName}:`, err));
|
|
311
320
|
}
|
|
@@ -406,13 +415,13 @@ RegisterComponent.lazy=async(...args)=>{
|
|
|
406
415
|
}
|
|
407
416
|
},{
|
|
408
417
|
_terminateEffects:terminateEffect
|
|
409
|
-
})
|
|
418
|
+
},)
|
|
410
419
|
if (terminateEffect.size > 0) {
|
|
411
420
|
window.addEventListener('beforeunload',()=>{
|
|
412
421
|
terminateEffect.forEach(fn =>{
|
|
413
422
|
fn()
|
|
414
423
|
})
|
|
415
|
-
})
|
|
424
|
+
},deps?.update)
|
|
416
425
|
}
|
|
417
426
|
}
|
|
418
427
|
} else if (Array.isArray(deps)) {
|
|
@@ -587,6 +596,14 @@ export const isResume = () => {
|
|
|
587
596
|
return false
|
|
588
597
|
}
|
|
589
598
|
}
|
|
599
|
+
export const forwardProps=(props={})=>{
|
|
600
|
+
if (client) {
|
|
601
|
+
if (isResume())return
|
|
602
|
+
stateContext._restProps=Object.entries(props).length > 0 ? props : {bPAr:''}
|
|
603
|
+
}else{
|
|
604
|
+
return serverInstance.forwardProps?.(props)
|
|
605
|
+
}
|
|
606
|
+
}
|
|
590
607
|
/**
|
|
591
608
|
* Insert into the html context in component
|
|
592
609
|
* @param {object} obj
|
|
@@ -655,6 +672,7 @@ export const setStateContext = (context) => {
|
|
|
655
672
|
stateContext._serializedData={}
|
|
656
673
|
stateContext._formerContext = formerStateContext
|
|
657
674
|
stateContext._reactiveProps = {}
|
|
675
|
+
stateContext._restProps={}
|
|
658
676
|
stateContext._template = ''
|
|
659
677
|
stateContext._resume = false
|
|
660
678
|
stateContext._suspense=''
|
|
@@ -840,13 +858,14 @@ export const restoreContext = (state_context) => {
|
|
|
840
858
|
stateContext = state_context._formerContext
|
|
841
859
|
}
|
|
842
860
|
export const HmrComponentMap=new Map()
|
|
861
|
+
const renderedComponentsRusumed=new Set()
|
|
843
862
|
/**
|
|
844
863
|
*
|
|
845
864
|
* @param {PawaElement|HTMLElement} el
|
|
846
865
|
* @returns null
|
|
847
866
|
*/
|
|
848
867
|
const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
849
|
-
if (el._running) {
|
|
868
|
+
if (el._running || (resume && renderedComponentsRusumed.has(attr.value))) {
|
|
850
869
|
return
|
|
851
870
|
}
|
|
852
871
|
el._running = true
|
|
@@ -854,6 +873,7 @@ const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
|
854
873
|
if (!resume) {
|
|
855
874
|
if (el._lazy) {
|
|
856
875
|
// pas the normal component to lazy handler
|
|
876
|
+
el.style.opacity=0
|
|
857
877
|
addLazyComponentElement(el,()=>normal_component(el, stateContext, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch))
|
|
858
878
|
return
|
|
859
879
|
}else{
|
|
@@ -861,7 +881,7 @@ const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
|
861
881
|
}
|
|
862
882
|
} else {
|
|
863
883
|
stopResume.stop = true
|
|
864
|
-
let name
|
|
884
|
+
let name=''
|
|
865
885
|
let comment
|
|
866
886
|
let endComment
|
|
867
887
|
const children = []
|
|
@@ -917,12 +937,14 @@ const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
|
917
937
|
numberComponentChildren = notRender.index + children.length -1
|
|
918
938
|
}
|
|
919
939
|
notRender.notRender = numberComponentChildren
|
|
920
|
-
|
|
940
|
+
renderedComponentsRusumed.add(attr.value)
|
|
941
|
+
|
|
942
|
+
if (lazyComponents.has(name.toUpperCase())) {
|
|
921
943
|
const trackElement=document.createElement(name)
|
|
922
944
|
trackElement._stateContext=el._stateContext
|
|
923
945
|
addLazyComponentElement(trackElement,()=>resumer.resume_component?.(el, attr, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch, { comment, endComment, name, serialized, id, children }))
|
|
924
|
-
if (
|
|
925
|
-
|
|
946
|
+
if (lazyComponentElement.has(name.toUpperCase())) {
|
|
947
|
+
createIntersectionObserver(trackElement,el)
|
|
926
948
|
}
|
|
927
949
|
}else{
|
|
928
950
|
resumer.resume_component?.(el, attr, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch, { comment, endComment, name, serialized, id, children })
|
|
@@ -992,7 +1014,9 @@ const mainAttribute = (el, exp) => {
|
|
|
992
1014
|
el.value = value;
|
|
993
1015
|
el.setAttribute(exp.name, value);
|
|
994
1016
|
} else {
|
|
995
|
-
if (exp.name === 'class' &&
|
|
1017
|
+
if ((exp.name === 'class' || exp.name === 'style') && enter) {
|
|
1018
|
+
console.log('entered',enter);
|
|
1019
|
+
|
|
996
1020
|
requestAnimationFrame(()=>{
|
|
997
1021
|
el.setAttribute(exp.name, value);
|
|
998
1022
|
})
|
|
@@ -1132,11 +1156,7 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1132
1156
|
}
|
|
1133
1157
|
}
|
|
1134
1158
|
|
|
1135
|
-
|
|
1136
|
-
node.nodeType === Node.TEXT_NODE && node.nodeValue.includes('@{')
|
|
1137
|
-
) && !el._avoidPawaRender) {
|
|
1138
|
-
textContentHandler(el, isName)
|
|
1139
|
-
}
|
|
1159
|
+
|
|
1140
1160
|
let startAttribute = false
|
|
1141
1161
|
const startObject = {}
|
|
1142
1162
|
//get startsWith plugin
|
|
@@ -1152,27 +1172,31 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1152
1172
|
})
|
|
1153
1173
|
})
|
|
1154
1174
|
const number = { notRender: null }
|
|
1175
|
+
const isAcomponent=el._componentName?true:false
|
|
1176
|
+
|
|
1155
1177
|
el._attributes.forEach(attr => {
|
|
1156
1178
|
|
|
1157
1179
|
if (stopResume.stop || el._hasRun) return
|
|
1158
1180
|
if (directives[attr.name]) {
|
|
1159
1181
|
directives[attr.name](el, attr, stateContext)
|
|
1160
|
-
} else if (attr.name.startsWith('on-')) {
|
|
1182
|
+
} else if (attr.name.startsWith('on-') && !isAcomponent) {
|
|
1161
1183
|
event(el, attr, stateContext)
|
|
1162
1184
|
} else if (attr.value.includes('@{') && !attr.name.startsWith('c-at-')) {
|
|
1163
1185
|
mainAttribute(el, attr, isName)
|
|
1164
1186
|
} else if (attr.name.startsWith('state-')) {
|
|
1165
1187
|
States(el, attr, getCurrentContext())
|
|
1166
|
-
} else if (attr.name.startsWith('out-')) {
|
|
1188
|
+
} else if (attr.name.startsWith('out-') && !isAcomponent) {
|
|
1167
1189
|
documentEvent(el, attr)
|
|
1168
|
-
} else if (attr.name.startsWith('after-[') && attr.name.endsWith(']')) {
|
|
1190
|
+
} else if (attr.name.startsWith('after-[') && attr.name.endsWith(']') && !isAcomponent) {
|
|
1169
1191
|
After(el, attr)
|
|
1170
1192
|
}
|
|
1171
|
-
else if (attr.name.startsWith('every-[') && attr.name.endsWith(']')) {
|
|
1193
|
+
else if (attr.name.startsWith('every-[') && attr.name.endsWith(']') && !isAcomponent) {
|
|
1172
1194
|
Every(el, attr)
|
|
1173
1195
|
}
|
|
1174
1196
|
else if (attr.name.startsWith('c-c-')) {
|
|
1175
1197
|
stopResume.stop = true
|
|
1198
|
+
|
|
1199
|
+
|
|
1176
1200
|
component(el, true, attr, notRender, stopResume)// component continuity
|
|
1177
1201
|
} else if (attr.name.startsWith('c-at-')) {
|
|
1178
1202
|
resumer.resume_attribute?.(el, attr, notRender) //attribute continuity
|
|
@@ -1221,7 +1245,13 @@ export const render = (el, contexts = {}, notRender, isName) => {
|
|
|
1221
1245
|
|
|
1222
1246
|
})
|
|
1223
1247
|
}
|
|
1248
|
+
|
|
1224
1249
|
if (stopResume.stop) return
|
|
1250
|
+
if (Array.from(el.childNodes).some(node =>
|
|
1251
|
+
node.nodeType === Node.TEXT_NODE && node.nodeValue.includes('@{')
|
|
1252
|
+
) && !el._avoidPawaRender) {
|
|
1253
|
+
textContentHandler(el, isName)
|
|
1254
|
+
}
|
|
1225
1255
|
if (el._componentName && !el._avoidPawaRender) {
|
|
1226
1256
|
component(el)
|
|
1227
1257
|
return
|
package/merger/for.js
CHANGED
|
@@ -11,6 +11,8 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
11
11
|
let func
|
|
12
12
|
let context=el._context
|
|
13
13
|
const keyOrder=keyOrders || new Map()
|
|
14
|
+
let noKey
|
|
15
|
+
let array
|
|
14
16
|
const evaluate = () => {
|
|
15
17
|
if (endComment.parentElement === null) {
|
|
16
18
|
el._deleteEffects()
|
|
@@ -19,7 +21,7 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
19
21
|
if (!func) {
|
|
20
22
|
func=el.safeEval(context, arrayName, 'for-each');
|
|
21
23
|
}
|
|
22
|
-
|
|
24
|
+
array = func(...getEvalValues(context))
|
|
23
25
|
let update;
|
|
24
26
|
if (!firstEnter) {
|
|
25
27
|
const div = document.createElement('div')
|
|
@@ -50,9 +52,12 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
50
52
|
keyComment._index = lookLike.getAttribute('data-for-index')
|
|
51
53
|
}
|
|
52
54
|
if (!el.getAttribute('for-key')) {
|
|
55
|
+
noKey=true
|
|
56
|
+
lookLike=true
|
|
53
57
|
return
|
|
54
58
|
}
|
|
55
59
|
if(lookLike) return
|
|
60
|
+
|
|
56
61
|
if (lookLike === null) {
|
|
57
62
|
elementArray.delete(keyComment)
|
|
58
63
|
|
|
@@ -79,7 +84,7 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
79
84
|
let indexKey=0
|
|
80
85
|
keyOrder.forEach((value,key)=>{
|
|
81
86
|
if(update)return;
|
|
82
|
-
if(div.children[indexKey]?.getAttribute('data-for-index') !== key){
|
|
87
|
+
if(div.children[indexKey]?.getAttribute('data-for-index') && indexKey !== key){
|
|
83
88
|
update=true
|
|
84
89
|
}
|
|
85
90
|
indexKey++
|
|
@@ -87,7 +92,7 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
87
92
|
}
|
|
88
93
|
const next = () => Promise.all(removeElement).then(async (res) => {
|
|
89
94
|
if (res) {
|
|
90
|
-
if (update) {
|
|
95
|
+
if (update && !noKey) {
|
|
91
96
|
const keyMap = new Map()
|
|
92
97
|
elementArray.forEach(child => {
|
|
93
98
|
keyMap.set(child._forKey, child)
|
|
@@ -182,22 +187,7 @@ export const merger_for = (el, stateContext, attr, arrayName, arrayItem, indexes
|
|
|
182
187
|
stateContext._hasRun = true
|
|
183
188
|
elementArray.add(keyComment)
|
|
184
189
|
})
|
|
185
|
-
|
|
186
|
-
} else {
|
|
187
|
-
if(!resume)return
|
|
188
|
-
if(once)return
|
|
189
|
-
const number={notRender:null,index:null}
|
|
190
|
-
elementArray.forEach((keyComment) => {
|
|
191
|
-
if(keyComment.nextElementSibling === null) return
|
|
192
|
-
const itemContext = {
|
|
193
|
-
[arrayItem]: array[keyComment._index],
|
|
194
|
-
[indexes]: keyComment._index,
|
|
195
|
-
...context
|
|
196
|
-
}
|
|
197
|
-
render(keyComment.nextElementSibling, itemContext,{notRender:false,index:null})
|
|
198
|
-
})
|
|
199
|
-
once=true
|
|
200
|
-
}
|
|
190
|
+
}
|
|
201
191
|
firstEnter = false
|
|
202
192
|
} catch (error) {
|
|
203
193
|
setPawaDevError({
|
package/normal/component.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {propsValidator, setPawaDevError, pawaWayRemover, checkKeywordsExistence, sanitizeTemplate } from '../utils.js';
|
|
1
|
+
import {propsValidator, setPawaDevError, pawaWayRemover, checkKeywordsExistence, sanitizeTemplate, splitAndAdd } from '../utils.js';
|
|
2
2
|
import {PawaElement,PawaComment} from '../pawaElement.js';
|
|
3
3
|
import {keepContext,render, HmrComponentMap } from '../index.js'
|
|
4
4
|
import {createEffect} from '../reactive.js'
|
|
@@ -61,7 +61,7 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
|
|
|
61
61
|
console.error(error.message)
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
|
-
|
|
64
|
+
let div =el._compoToSvg?document.createElementNS('http://www.w3.org/2000/svg', 'svg'): document.createElement('div')
|
|
65
65
|
el._componentTerminate=() => {
|
|
66
66
|
comment._terminateByComponent(endComment)
|
|
67
67
|
}
|
|
@@ -151,16 +151,54 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
|
|
|
151
151
|
if (component?._insert) {
|
|
152
152
|
Object.assign(el._context,component._insert)
|
|
153
153
|
}
|
|
154
|
+
const restProps={}
|
|
155
|
+
if (Object.entries(stateContexts._restProps).length > 0) {
|
|
156
|
+
const props=el._restProps
|
|
157
|
+
if (stateContexts._restProps['className'] && props['class']) {
|
|
158
|
+
restProps['class']={...props['class']}
|
|
159
|
+
}
|
|
160
|
+
if (stateContexts._restProps['defaultValue'] && props['default']) {
|
|
161
|
+
restProps['default']={...props['default']}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
for (const key in props) {
|
|
165
|
+
let name=key
|
|
166
|
+
name=name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
167
|
+
if (stateContexts._restProps[name]) {
|
|
168
|
+
restProps[key]={...props[key]}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}else{
|
|
172
|
+
Object.assign(restProps,el._restProps)
|
|
173
|
+
}
|
|
154
174
|
const context=el._context
|
|
155
|
-
|
|
175
|
+
const getAsChild=()=>{
|
|
176
|
+
const asChild=div.firstElementChild
|
|
177
|
+
if (splitAndAdd(asChild?.tagName|| '') === 'ASCHILD') {
|
|
178
|
+
const getChildren=asChild.firstElementChild
|
|
179
|
+
Array.from(asChild.attributes).forEach(attr=>{
|
|
180
|
+
if (getChildren.hasAttribute(attr.name)) {
|
|
181
|
+
let attrName=getChildren.getAttribute(attr.name)
|
|
182
|
+
attrName=attr.value +' '+attrName
|
|
183
|
+
getChildren.setAttribute(attr.name, attrName)
|
|
184
|
+
}else{
|
|
185
|
+
getChildren.setAttribute(attr.name, attr.value)
|
|
186
|
+
}
|
|
187
|
+
})
|
|
188
|
+
asChild.remove()
|
|
189
|
+
div.appendChild(getChildren)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const propsSetter=()=>{
|
|
193
|
+
getAsChild()
|
|
156
194
|
const findElement=div.querySelector('[--]') || div.querySelector('[rest]')
|
|
157
195
|
if (findElement) {
|
|
158
196
|
findElement.removeAttribute('--')
|
|
159
197
|
findElement.removeAttribute('rest')
|
|
160
198
|
}
|
|
161
|
-
if(Object.entries(
|
|
199
|
+
if(Object.entries(restProps).length > 0){
|
|
162
200
|
if (findElement) {
|
|
163
|
-
for (const [key,value] of Object.entries(
|
|
201
|
+
for (const [key,value] of Object.entries(restProps)) {
|
|
164
202
|
findElement.setAttribute(value.name,value.value)
|
|
165
203
|
}
|
|
166
204
|
}
|
|
@@ -183,7 +221,7 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
|
|
|
183
221
|
bfm._sent=true
|
|
184
222
|
const result= bfm(comment)
|
|
185
223
|
if (typeof result === 'function') {
|
|
186
|
-
el.
|
|
224
|
+
el._beforeUnMountFunctions.push(result)
|
|
187
225
|
}
|
|
188
226
|
})
|
|
189
227
|
|
|
@@ -230,7 +268,7 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
|
|
|
230
268
|
if (hook.deps?.component) {
|
|
231
269
|
createEffect(() => {
|
|
232
270
|
return effect()
|
|
233
|
-
},el)
|
|
271
|
+
},el,hook.deps?.update)
|
|
234
272
|
} else {
|
|
235
273
|
createEffect(() => {
|
|
236
274
|
return effect()
|
package/package.json
CHANGED
package/pawaElement.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {components,lazyComponents ,escapePawaAttribute,getPawaAttributes,getDependentAttribute,getPrimaryDirectives } from './index.js';
|
|
1
|
+
import {components,lazyComponents ,escapePawaAttribute,getPawaAttributes,getDependentAttribute,getPrimaryDirectives, pluginsMap } from './index.js';
|
|
2
2
|
import {splitAndAdd,replaceTemplateOperators,setPawaDevError,getEvalValues, checkKeywordsExistence} from './utils.js';
|
|
3
3
|
import PawaComponent from './pawaComponent.js';
|
|
4
4
|
import { createIntersectionObserver } from './index.js';
|
|
@@ -23,12 +23,12 @@ export class PawaElement {
|
|
|
23
23
|
_el: element, _out: false, _stateContext: null, _terminateEffects: new Set(), _deleteEffects: this.terminateEffects,
|
|
24
24
|
_slots: document.createDocumentFragment(), _mainAttribute: {}, _preRenderAvoid: [], _running: false,
|
|
25
25
|
_hasForOrIf: this.hasForOrIf, _elementContent: element.textContent, _textContent: {}, _attributes: [],
|
|
26
|
-
_template: div.outerHTML, _exitAnimation: null, _component: null, _unMountFunctions: [], _MountFunctions: [],
|
|
26
|
+
_template: div.outerHTML, _exitAnimation: null, _component: null, _unMountFunctions: [], _MountFunctions: [],_beforeUnMountFunctions:[],
|
|
27
27
|
_elementType: '', _getNode: this.getNode, _componentOrTemplate: false, _props: {}, _isView: null,
|
|
28
|
-
_isElementComponent: false, _pawaAttribute: {}, _setUnMount: this.setUnMounts, _componentName: '',
|
|
28
|
+
_isElementComponent: false, _pawaAttribute: {}, _setUnMount: this.setUnMounts, _componentName: '',_compoToSvg: false,_asChild: false,
|
|
29
29
|
_attrElement: this.getNewElementByRemovingAttr, _attr: {}, _staticContext: [], _checkStatic: this.reCheckStaticContext,
|
|
30
30
|
_callMount: this.mount, _callUnmount: this.unMount, _remove: this.remove, _componentChildren: undefined,
|
|
31
|
-
_pawaElementComponent: null, _componentTerminate: null, _cacheSetUp: false, _effectsCarrier: null,
|
|
31
|
+
_pawaElementComponent: null, _componentTerminate: null, _cacheSetUp: false, _effectsCarrier: null,_beforeUnMount:this.beforeUnMount,
|
|
32
32
|
_pawaElementComponentName: '', _reCallEffect: this.reCallEffect, _ElementEffects: new Map(),
|
|
33
33
|
_deCompositionElement: false, _restProps: {}, _kill: null, _isKill: false, _scriptFetching: element.hasAttribute('script'),
|
|
34
34
|
_scriptDone: false, _underControl: null, safeEval: this.safeEval, _reactiveProps: {},
|
|
@@ -97,8 +97,11 @@ export class PawaElement {
|
|
|
97
97
|
const pawaAttr=this._el.getAttribute('p:c')
|
|
98
98
|
const array=pawaAttr.split(';')
|
|
99
99
|
array.forEach(value =>{
|
|
100
|
-
if(!this._el.hasAttribute(value))
|
|
101
|
-
|
|
100
|
+
if(!this._el.hasAttribute(value.toLowerCase())) {
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
this._attributes.push({name:value,value:this._el.getAttribute(value.toLowerCase())})
|
|
104
|
+
// console.log(this._el,this._attributes);
|
|
102
105
|
})
|
|
103
106
|
}else{
|
|
104
107
|
this._attributes=Array.from(this._el.attributes)
|
|
@@ -172,10 +175,8 @@ export class PawaElement {
|
|
|
172
175
|
}
|
|
173
176
|
}
|
|
174
177
|
async remove(callback){
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
return
|
|
178
|
-
}
|
|
178
|
+
|
|
179
|
+
await this._beforeUnMount()
|
|
179
180
|
if (typeof this._exitAnimation === 'function') {
|
|
180
181
|
|
|
181
182
|
try {
|
|
@@ -200,6 +201,15 @@ export class PawaElement {
|
|
|
200
201
|
}
|
|
201
202
|
return true
|
|
202
203
|
}
|
|
204
|
+
if (typeof this._kill === 'function' && this._isKill && this._deCompositionElement) {
|
|
205
|
+
this._kill()
|
|
206
|
+
return
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async beforeUnMount(){
|
|
210
|
+
this._beforeUnMountFunctions.forEach(func => {
|
|
211
|
+
func()
|
|
212
|
+
});
|
|
203
213
|
}
|
|
204
214
|
async unMount(){
|
|
205
215
|
if (this._component && this._pawaElementComponentName === '') {
|
|
@@ -291,10 +301,17 @@ export class PawaElement {
|
|
|
291
301
|
});
|
|
292
302
|
}
|
|
293
303
|
const pawaAttribute=getPawaAttributes()
|
|
304
|
+
const {allowAsProp}=pluginsMap()
|
|
294
305
|
const dependAttribute=getDependentAttribute()
|
|
295
306
|
this._attributes.forEach((attr) => {
|
|
296
|
-
|
|
297
|
-
|
|
307
|
+
if (attr.name === 'svg') {
|
|
308
|
+
this._compoToSvg = true
|
|
309
|
+
return
|
|
310
|
+
}else if(attr.name === 'aschild' || attr.name === 'as-child'){
|
|
311
|
+
this._asChild = true
|
|
312
|
+
return
|
|
313
|
+
}
|
|
314
|
+
if (!attr.name.startsWith(':') && (!pawaAttribute.has(attr.name) && !dependAttribute.has(attr.name) )) {
|
|
298
315
|
let name=''
|
|
299
316
|
if (attr.name.startsWith('-')) {
|
|
300
317
|
name=attr.name.slice(1)
|
|
@@ -316,7 +333,7 @@ export class PawaElement {
|
|
|
316
333
|
}
|
|
317
334
|
});
|
|
318
335
|
return value
|
|
319
|
-
}else if( attr.name.startsWith('on-') || attr.name.startsWith('out-')){
|
|
336
|
+
}else if( attr.name.startsWith('on-') || attr.name.startsWith('out-') || attr.name === 'ref'){
|
|
320
337
|
const res=this.safeEval(context,`(e)=>{
|
|
321
338
|
${attr.value}
|
|
322
339
|
}`, 'props',true)
|
|
@@ -335,7 +352,7 @@ export class PawaElement {
|
|
|
335
352
|
this._props[name]=setProps
|
|
336
353
|
}
|
|
337
354
|
|
|
338
|
-
this._restProps[name]={name:name,value:attr.value}
|
|
355
|
+
this._restProps[attr.name]={name:attr.name,value:attr.value}
|
|
339
356
|
}else if(!pawaAttribute.has(attr.name) && attr.name.startsWith(':')){
|
|
340
357
|
|
|
341
358
|
const propsName=attr.name.slice(1)
|
package/power.js
CHANGED
|
@@ -388,7 +388,7 @@ export const For = (el, attr, stateContext,resume=false,notRender,stopResume) =>
|
|
|
388
388
|
|
|
389
389
|
export const ref = (el, attr) => {
|
|
390
390
|
el._checkStatic()
|
|
391
|
-
if (el._running || checkKeywordsExistence(el._staticContext,attr.value)) {
|
|
391
|
+
if (el._running || checkKeywordsExistence(el._staticContext,attr.value) || el._componentName) {
|
|
392
392
|
return
|
|
393
393
|
}
|
|
394
394
|
try {
|
|
@@ -519,26 +519,29 @@ export const documentEvent = (el, attr) => {
|
|
|
519
519
|
const unMount = () => target.removeEventListener(eventType, handler, options);
|
|
520
520
|
el._setUnMount(unMount)
|
|
521
521
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
522
|
+
|
|
523
|
+
export const exitTransition = (el, attr) => {
|
|
524
|
+
if (el._running || el._componentName) {
|
|
525
|
+
return
|
|
526
|
+
}
|
|
527
|
+
const maxWait = 5000 // 5 seconds max
|
|
528
|
+
const promise = (resolve, startTime = Date.now()) => {
|
|
529
|
+
setTimeout(() => {
|
|
530
|
+
const animations = el.getAnimations({ subtree: false })
|
|
531
|
+
if (animations.length === 0 ) {
|
|
532
|
+
resolve()
|
|
533
|
+
return
|
|
534
|
+
}
|
|
535
|
+
Promise.all(animations.map(a => a.finished))
|
|
536
|
+
.then(() => promise(resolve, startTime))
|
|
537
|
+
.catch(() => promise(resolve, startTime))
|
|
538
|
+
}, 50)
|
|
525
539
|
}
|
|
526
|
-
el._exitAnimation=()=>{
|
|
527
|
-
return new Promise(
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
if (animations.length === 0) {
|
|
531
|
-
resolve()
|
|
532
|
-
return
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
Promise.all(animations.map(a=>a.finished)).then(resolve).catch(resolve)
|
|
536
|
-
})
|
|
537
|
-
})
|
|
538
|
-
}
|
|
539
|
-
el.removeAttribute(attr.name)
|
|
540
|
+
el._exitAnimation = () => {
|
|
541
|
+
return new Promise(promise)
|
|
542
|
+
}
|
|
543
|
+
el.removeAttribute(attr.name)
|
|
540
544
|
}
|
|
541
|
-
|
|
542
545
|
const createTimedExecutable = (el, attr, useInterval) => {
|
|
543
546
|
if (el._running) return;
|
|
544
547
|
const getTime = attr.name.match(/\[(.*?)\]/)[1];
|
package/reactive.js
CHANGED
|
@@ -27,6 +27,10 @@ function scheduleRenderWithTimeBudget() {
|
|
|
27
27
|
|
|
28
28
|
for (const fn of scheduled) {
|
|
29
29
|
const cleanUp = fn();
|
|
30
|
+
if (fn?._sideEffect) {
|
|
31
|
+
const cleared=fn?._sideEffect?.()
|
|
32
|
+
if(typeof cleared === 'function')cleared()
|
|
33
|
+
}
|
|
30
34
|
if (typeof cleanUp === 'function') cleanUp();
|
|
31
35
|
processed.push(fn);
|
|
32
36
|
if (performance.now() - start > FRAME_BUDGET) {
|
|
@@ -75,7 +79,7 @@ export const queueEffect = (effect,depsMap) => {
|
|
|
75
79
|
};
|
|
76
80
|
|
|
77
81
|
// Add parent tracking to effects
|
|
78
|
-
export const createEffect = (fn, el) => {
|
|
82
|
+
export const createEffect = (fn, el,update=null) => {
|
|
79
83
|
const effect = () => {
|
|
80
84
|
activeEffect = effect;
|
|
81
85
|
effect.el = el;
|
|
@@ -86,6 +90,8 @@ export const queueEffect = (effect,depsMap) => {
|
|
|
86
90
|
return cleanUp
|
|
87
91
|
}
|
|
88
92
|
};
|
|
93
|
+
update?.()
|
|
94
|
+
effect._sideEffect=update
|
|
89
95
|
effect._id=crypto.randomUUID()
|
|
90
96
|
effect._done=false
|
|
91
97
|
effect._dep=null
|
|
@@ -117,7 +123,7 @@ if (el) {
|
|
|
117
123
|
// console.log(el,effect._dep);
|
|
118
124
|
}
|
|
119
125
|
|
|
120
|
-
el
|
|
126
|
+
el?._terminateEffects.add(deletes)
|
|
121
127
|
|
|
122
128
|
}
|
|
123
129
|
return effect;
|
|
@@ -131,6 +137,7 @@ export const track = (target, key) => {
|
|
|
131
137
|
|
|
132
138
|
let depsMap = targetMap.get(target);
|
|
133
139
|
if (!depsMap) {
|
|
140
|
+
|
|
134
141
|
targetMap.set(target, (depsMap = new Map()));
|
|
135
142
|
}
|
|
136
143
|
let dep = depsMap.get(key);
|