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/LICENSE +21 -0
- package/README.md +354 -0
- package/cdn/index.js +5 -0
- package/index.d.ts +291 -0
- package/index.js +1180 -0
- package/merger/for.js +218 -0
- package/merger/if.js +125 -0
- package/merger/key.js +101 -0
- package/merger/switch.js +127 -0
- package/normal/For.js +30 -0
- package/normal/If.js +29 -0
- package/normal/Key.js +27 -0
- package/normal/Switch.js +29 -0
- package/normal/component.js +211 -0
- package/normal/template.js +24 -0
- package/package.json +27 -0
- package/pawaComponent.js +68 -0
- package/pawaElement.js +455 -0
- package/power.js +468 -0
- package/reactive.js +174 -0
- package/resumer.js +21 -0
- package/server.js +21 -0
- package/utils.js +328 -0
package/index.js
ADDED
|
@@ -0,0 +1,1180 @@
|
|
|
1
|
+
import { track, trigger, createEffect } from './reactive.js'
|
|
2
|
+
import { PawaElement, PawaComment } from './pawaElement.js';
|
|
3
|
+
import {
|
|
4
|
+
If,
|
|
5
|
+
event,
|
|
6
|
+
unMountElement,
|
|
7
|
+
mountElement,
|
|
8
|
+
For,
|
|
9
|
+
States,
|
|
10
|
+
ref,
|
|
11
|
+
documentEvent,
|
|
12
|
+
Switch,
|
|
13
|
+
exitTransition,
|
|
14
|
+
After,
|
|
15
|
+
Every,
|
|
16
|
+
Key
|
|
17
|
+
} from './power.js'
|
|
18
|
+
import { propsValidator, sanitizeTemplate, setPawaDevError, splitAndAdd, pawaWayRemover, checkKeywordsExistence } from './utils.js';
|
|
19
|
+
import PawaComponent from './pawaComponent.js';
|
|
20
|
+
import { getServerInstance, isServer } from './server.js'
|
|
21
|
+
import { templates } from './normal/template.js'
|
|
22
|
+
import { normal_component } from './normal/component.js';
|
|
23
|
+
import { resumer } from './resumer.js';
|
|
24
|
+
let ERROR_CALLER
|
|
25
|
+
export const setErrorCALLER = (callback) => {
|
|
26
|
+
ERROR_CALLER = callback
|
|
27
|
+
}
|
|
28
|
+
// in progress
|
|
29
|
+
const errorCaller = (message) => {
|
|
30
|
+
|
|
31
|
+
}
|
|
32
|
+
const client = !isServer()
|
|
33
|
+
const serverInstance = getServerInstance()
|
|
34
|
+
if (client) {
|
|
35
|
+
window.__pawaDev = {
|
|
36
|
+
tool: false,
|
|
37
|
+
errors: [],
|
|
38
|
+
totalEffect: 0,
|
|
39
|
+
errorState: null,
|
|
40
|
+
components: new Set(),
|
|
41
|
+
renderCount: 0,
|
|
42
|
+
reactiveUpdates: 0,
|
|
43
|
+
totalComponent: 0,
|
|
44
|
+
performance: {
|
|
45
|
+
renderTime: [],
|
|
46
|
+
effectTime: [],
|
|
47
|
+
componentTime: [],
|
|
48
|
+
start: 0,
|
|
49
|
+
end: 0
|
|
50
|
+
},
|
|
51
|
+
setError: ({ el, msg, directives, stack, template, warn } = {}) => {
|
|
52
|
+
if (__pawaDev.tool !== true) return
|
|
53
|
+
if (__pawaDev.errorState) {
|
|
54
|
+
__pawaDev.errorState.value = true
|
|
55
|
+
}
|
|
56
|
+
__pawaDev.errors.push({
|
|
57
|
+
el,
|
|
58
|
+
msg,
|
|
59
|
+
directives,
|
|
60
|
+
stack,
|
|
61
|
+
timestamp: Date.now(),
|
|
62
|
+
template: template ? template : ''
|
|
63
|
+
})
|
|
64
|
+
if (warn) {
|
|
65
|
+
console.warn(msg, stack, template)
|
|
66
|
+
}
|
|
67
|
+
console.error(msg, stack)
|
|
68
|
+
},
|
|
69
|
+
logRender: (component, time) => {
|
|
70
|
+
__pawaDev.renderCount++
|
|
71
|
+
__pawaDev.performance.renderTime.push({
|
|
72
|
+
component,
|
|
73
|
+
time,
|
|
74
|
+
timestamp: Date.now()
|
|
75
|
+
})
|
|
76
|
+
},
|
|
77
|
+
logEffect: (effect, time) => {
|
|
78
|
+
__pawaDev.totalEffect++
|
|
79
|
+
__pawaDev.performance.effectTime.push({
|
|
80
|
+
effect,
|
|
81
|
+
time,
|
|
82
|
+
timestamp: Date.now()
|
|
83
|
+
})
|
|
84
|
+
},
|
|
85
|
+
logComponent: (name, time) => {
|
|
86
|
+
__pawaDev.components.add(name)
|
|
87
|
+
__pawaDev.performance.componentTime.push({
|
|
88
|
+
name,
|
|
89
|
+
time,
|
|
90
|
+
timestamp: Date.now()
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const compoBeforeCall = new Set()
|
|
97
|
+
const compoAfterCall = new Set()
|
|
98
|
+
const renderBeforePawa = new Set()
|
|
99
|
+
const renderAfterPawa = new Set()
|
|
100
|
+
const renderBeforeChild = new Set()
|
|
101
|
+
const startsWithSet = new Set()
|
|
102
|
+
const fullNamePlugin = new Set()
|
|
103
|
+
const externalPlugin = {}
|
|
104
|
+
const externalPluginMap = new Map()
|
|
105
|
+
let pawaAttributes = new Set()
|
|
106
|
+
let primaryDirective = new Set()
|
|
107
|
+
|
|
108
|
+
const mapsPlugins = {
|
|
109
|
+
compoAfterCall,
|
|
110
|
+
compoBeforeCall,
|
|
111
|
+
renderAfterPawa,
|
|
112
|
+
renderBeforePawa,
|
|
113
|
+
renderBeforeChild,
|
|
114
|
+
startsWithSet,
|
|
115
|
+
fullNamePlugin,
|
|
116
|
+
externalPlugin,
|
|
117
|
+
externalPluginMap,
|
|
118
|
+
primaryDirective
|
|
119
|
+
}
|
|
120
|
+
export const pluginsMap = () => mapsPlugins
|
|
121
|
+
export const escapePawaAttribute = new Set()
|
|
122
|
+
export const dependentPawaAttribute = new Set()
|
|
123
|
+
|
|
124
|
+
export const removePlugin = (...pluginName) => {
|
|
125
|
+
pluginName.forEach(n => {
|
|
126
|
+
if (pawaAttributes.has(n)) {
|
|
127
|
+
pawaAttributes.delete(n)
|
|
128
|
+
delete externalPlugin[n]
|
|
129
|
+
if (externalPluginMap.has(n)) {
|
|
130
|
+
const extArray = externalPluginMap.get(n)
|
|
131
|
+
extArray.forEach(ex => {
|
|
132
|
+
dependentPawaAttribute.delete(ex)
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
})
|
|
138
|
+
}
|
|
139
|
+
const applyMode = (mode, callback) => {
|
|
140
|
+
if (mode === null || mode === undefined) {
|
|
141
|
+
callback()
|
|
142
|
+
} else if (mode === 'client' && client) {
|
|
143
|
+
callback()
|
|
144
|
+
} else if (mode === 'server' && !client) {
|
|
145
|
+
callback()
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* @typedef {{startsWith:string,mode:null |'client'|'server',dependency:Array<string>,fullName:string,plugin:(el:HTMLElement | PawaElement,attr:object)=>void}} AttriPlugin
|
|
150
|
+
*/
|
|
151
|
+
/**
|
|
152
|
+
* @typedef {{
|
|
153
|
+
* attribute?:{register:Array<AttriPlugin>},
|
|
154
|
+
* component?:{
|
|
155
|
+
* beforeCall?:(stateContext:PawaComponent,app:object)=>void,
|
|
156
|
+
* afterCall?:(stateContext:PawaComponent,el:HTMLElement)=>void
|
|
157
|
+
* },
|
|
158
|
+
* renderSystem?:{
|
|
159
|
+
* beforePawa?:(el:HTMLElement,context:object)=>void,
|
|
160
|
+
* afterPawa?:(el:PawaElement)=>void,
|
|
161
|
+
* beforeChildRender?:(el:PawaElement)=>void
|
|
162
|
+
* }
|
|
163
|
+
* }} PluginObject
|
|
164
|
+
*/
|
|
165
|
+
/**
|
|
166
|
+
* @param {Array<()=>PluginObject>} func
|
|
167
|
+
*/
|
|
168
|
+
export const PluginSystem = (...func) => {
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
func.forEach(fn => {
|
|
172
|
+
/**
|
|
173
|
+
* @type {PluginObject}
|
|
174
|
+
*/
|
|
175
|
+
if (typeof fn !== 'function') {
|
|
176
|
+
console.warn('plugin must be a function that returns the plugin objects')
|
|
177
|
+
return
|
|
178
|
+
}
|
|
179
|
+
const getPlugin = fn()
|
|
180
|
+
// attributes plugin or extension
|
|
181
|
+
|
|
182
|
+
if (getPlugin?.attribute) {
|
|
183
|
+
getPlugin.attribute.register.forEach(attrPlugins => {
|
|
184
|
+
if (attrPlugins.fullName && attrPlugins.startsWith) {
|
|
185
|
+
console.warn('Either Plugins FullName or startsWith. you are not required to use two of does plugin registers at this same entry.')
|
|
186
|
+
return
|
|
187
|
+
}
|
|
188
|
+
const extPluginArray = []
|
|
189
|
+
if (attrPlugins?.dependency && attrPlugins?.dependency.length > 0) {
|
|
190
|
+
attrPlugins.dependency.forEach(dp => {
|
|
191
|
+
if (dependentPawaAttribute.has(dp)) {
|
|
192
|
+
__pawaDev.setError({ msg: `${dp} is already used - from pawa plugin it might cause some issues`, warn: true })
|
|
193
|
+
}
|
|
194
|
+
dependentPawaAttribute.add(dp)
|
|
195
|
+
extPluginArray.push(dp)
|
|
196
|
+
})
|
|
197
|
+
}
|
|
198
|
+
if (attrPlugins?.fullName) {
|
|
199
|
+
if (pawaAttributes.has(attrPlugins.fullName)) {
|
|
200
|
+
console.warn(`attribute plugin already exist ${attrPlugins.fullName}`)
|
|
201
|
+
return
|
|
202
|
+
}
|
|
203
|
+
// console.log(attrPlugins)
|
|
204
|
+
applyMode(attrPlugins?.mode, () => {
|
|
205
|
+
pawaAttributes.add(attrPlugins.fullName)
|
|
206
|
+
fullNamePlugin.add(attrPlugins.fullName)
|
|
207
|
+
externalPlugin[attrPlugins.fullName] = attrPlugins?.plugin
|
|
208
|
+
if (extPluginArray.length > 0) externalPluginMap.set(attrPlugins.fullName, extPluginArray)
|
|
209
|
+
})
|
|
210
|
+
} else if (attrPlugins?.startsWith) {
|
|
211
|
+
if (pawaAttributes.has(attrPlugins.startsWith)) {
|
|
212
|
+
console.warn(`attribute plugin already exist ${attrPlugins.startsWith}`)
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
applyMode(attrPlugins?.mode, () => {
|
|
216
|
+
pawaAttributes.add(attrPlugins.startsWith)
|
|
217
|
+
startsWithSet.add(attrPlugins.startsWith)
|
|
218
|
+
externalPlugin[attrPlugins.startsWith] = attrPlugins?.plugin
|
|
219
|
+
if (extPluginArray.length > 0) externalPluginMap.set(attrPlugins.startsWith, extPluginArray)
|
|
220
|
+
})
|
|
221
|
+
}
|
|
222
|
+
})
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
}
|
|
227
|
+
if (getPlugin?.component) {
|
|
228
|
+
if (getPlugin.component?.beforeCall && typeof getPlugin.component?.beforeCall === 'function') {
|
|
229
|
+
compoBeforeCall.add(getPlugin.component.beforeCall)
|
|
230
|
+
}
|
|
231
|
+
if (getPlugin.component?.afterCall && typeof getPlugin.component?.afterCall === 'function') {
|
|
232
|
+
compoAfterCall.add(getPlugin.component.afterCall)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
if (getPlugin?.renderSystem) {
|
|
236
|
+
if (getPlugin.renderSystem?.beforePawa && typeof getPlugin.renderSystem?.beforePawa === 'function') {
|
|
237
|
+
renderBeforePawa.add(getPlugin.renderSystem?.beforePawa)
|
|
238
|
+
}
|
|
239
|
+
if (getPlugin.renderSystem?.afterPawa && typeof getPlugin.renderSystem?.afterPawa === 'function') {
|
|
240
|
+
renderAfterPawa.add(getPlugin.renderSystem?.afterPawa)
|
|
241
|
+
}
|
|
242
|
+
if (getPlugin.renderSystem?.beforeChildRender && typeof getPlugin.renderSystem?.beforeChildRender === 'function') {
|
|
243
|
+
renderBeforePawa.add(getPlugin.renderSystem?.beforeChildRender)
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
})
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
export const keepContext = (context) => {
|
|
250
|
+
if (!client) return
|
|
251
|
+
stateContext = context
|
|
252
|
+
formerStateContext = stateContext
|
|
253
|
+
|
|
254
|
+
}
|
|
255
|
+
export const components = new Map()
|
|
256
|
+
/**
|
|
257
|
+
* @type {PawaComponent}
|
|
258
|
+
*/
|
|
259
|
+
let stateContext = {
|
|
260
|
+
_hasRun: false,
|
|
261
|
+
_formerContext: null,
|
|
262
|
+
_insert: {},
|
|
263
|
+
_resume: false,
|
|
264
|
+
_hook: {
|
|
265
|
+
effect: [],
|
|
266
|
+
isMount: [],
|
|
267
|
+
isUnMount: []
|
|
268
|
+
},
|
|
269
|
+
_stateMap: new Map,
|
|
270
|
+
component: null,
|
|
271
|
+
_transportContext: {},
|
|
272
|
+
_reactiveProps: {},
|
|
273
|
+
_template: '',
|
|
274
|
+
_static: [],
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export const getCurrentContext = () => {
|
|
278
|
+
return stateContext
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
let formerStateContext = null
|
|
282
|
+
let pawaContext = {}
|
|
283
|
+
|
|
284
|
+
export const setPawaAttributes = (...attr) => {
|
|
285
|
+
attr.forEach((att) => {
|
|
286
|
+
if (pawaAttributes.has(att)) {
|
|
287
|
+
throw Error(`${att} already exits`)
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
pawaAttributes.add(att)
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
const setPrimaryAttibute = (...name) => {
|
|
294
|
+
name.forEach(att => {
|
|
295
|
+
primaryDirective.add(att)
|
|
296
|
+
})
|
|
297
|
+
}
|
|
298
|
+
export const getPrimaryDirective=()=>primaryDirective
|
|
299
|
+
setPrimaryAttibute('if', 'else-if', 'for', 'else','switch','case','default','case','key')
|
|
300
|
+
setPawaAttributes('if', 'else-if', 'for', 'else', 'mount',
|
|
301
|
+
'unmount', 'forKey', 'state-', 'on-', 'out-','key')
|
|
302
|
+
export const getDependentAttribute = () => dependentPawaAttribute
|
|
303
|
+
export const getPawaAttributes = () => {
|
|
304
|
+
return pawaAttributes
|
|
305
|
+
}
|
|
306
|
+
export const setError = ({ error }) => {
|
|
307
|
+
if (!client) return
|
|
308
|
+
if (!stateContext) {
|
|
309
|
+
console.warn('must be used inside of a component')
|
|
310
|
+
return
|
|
311
|
+
}
|
|
312
|
+
if (!stateContext._hasRun) {
|
|
313
|
+
if (!stateContext?._error) {
|
|
314
|
+
stateContext._error = []
|
|
315
|
+
}
|
|
316
|
+
stateContext?._error.push(error)
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
*
|
|
322
|
+
* @param {...()=>string|null} component
|
|
323
|
+
* Function registrar for pawajs component
|
|
324
|
+
*/
|
|
325
|
+
export const RegisterComponent = (...args) => {
|
|
326
|
+
// Handle new signature from plugin: RegisterComponent('Name1', Func1, 'Name2', Func2, ...)
|
|
327
|
+
|
|
328
|
+
if (typeof args[0] === 'string') {
|
|
329
|
+
for (let i = 0; i < args.length; i += 2) {
|
|
330
|
+
const name = args[i];
|
|
331
|
+
const component = args[i + 1];
|
|
332
|
+
if (typeof name === 'string' && typeof component === 'function') {
|
|
333
|
+
// if (components.has(name.toUpperCase())) continue;
|
|
334
|
+
components.set(name.toUpperCase(), component);
|
|
335
|
+
} else {
|
|
336
|
+
console.warn('Mismatched arguments for RegisterComponent. Expected pairs of (string, function).');
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
// Handle old signature for dev mode: RegisterComponent(ComponentFunc1, ComponentFunc2, ...)
|
|
343
|
+
args.forEach((component) => {
|
|
344
|
+
if (typeof component === 'function' && component.name) {
|
|
345
|
+
// if (components.has(component.name.toUpperCase())) return;
|
|
346
|
+
components.set(component.name.toUpperCase(), component);
|
|
347
|
+
} else {
|
|
348
|
+
console.warn('Component registration failed: Component must be a named function. This might happen in production builds without the pawajs Vite plugin.');
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
*
|
|
355
|
+
* @param {()=>()=>any} callback
|
|
356
|
+
* A function that runs based on the deps and the returns are for unMounted hook
|
|
357
|
+
* ( from Array,Number,null deps) while deps(object) are for the main reactive effect
|
|
358
|
+
* @param {Array|null|object|number} deps
|
|
359
|
+
* Array - for state dependency.
|
|
360
|
+
*
|
|
361
|
+
* object- for any state used inside of the callback but under the use of element or component.
|
|
362
|
+
*
|
|
363
|
+
* Number - before mount hook.
|
|
364
|
+
*
|
|
365
|
+
* null- for Mount hook
|
|
366
|
+
* @returns {void}
|
|
367
|
+
*/
|
|
368
|
+
export const runEffect = (callback, deps) => {
|
|
369
|
+
if (client) {
|
|
370
|
+
if (stateContext._hasRun) {
|
|
371
|
+
return
|
|
372
|
+
}
|
|
373
|
+
if (stateContext) {
|
|
374
|
+
if (!stateContext._hook) {
|
|
375
|
+
stateContext._hook = {}
|
|
376
|
+
}
|
|
377
|
+
if (!stateContext._hook.isMount) {
|
|
378
|
+
stateContext._hook.isMount = []
|
|
379
|
+
}
|
|
380
|
+
if (!stateContext._hook.beforeMount) {
|
|
381
|
+
stateContext._hook.beforeMount = []
|
|
382
|
+
}
|
|
383
|
+
if (!stateContext._hook.reactiveEffect) {
|
|
384
|
+
stateContext._hook.reactiveEffect = []
|
|
385
|
+
}
|
|
386
|
+
if (!stateContext._hook.effect) {
|
|
387
|
+
stateContext._hook.effect = []
|
|
388
|
+
}
|
|
389
|
+
if (deps === undefined || deps === null) {
|
|
390
|
+
stateContext._hook.isMount.push(callback)
|
|
391
|
+
} else if (typeof deps === 'object' && !Array.isArray(deps)) {
|
|
392
|
+
stateContext._hook.reactiveEffect.push({ deps: deps, effect: callback })
|
|
393
|
+
} else if (Array.isArray(deps)) {
|
|
394
|
+
stateContext._hook.effect.push({
|
|
395
|
+
deps: deps,
|
|
396
|
+
effect: callback
|
|
397
|
+
})
|
|
398
|
+
} else if (typeof deps === 'number') {
|
|
399
|
+
stateContext._hook.beforeMount.push(callback)
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
*
|
|
407
|
+
* @param {object} props
|
|
408
|
+
* @returns {object}
|
|
409
|
+
*/
|
|
410
|
+
export const useValidateComponent = (component, object) => {
|
|
411
|
+
if (typeof component === 'function') {
|
|
412
|
+
if (component.name) {
|
|
413
|
+
component.validateProps = object
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* @returns {{id:string,setValue:()=>void}}
|
|
419
|
+
*/
|
|
420
|
+
export const setContext = () => {
|
|
421
|
+
if (client) {
|
|
422
|
+
|
|
423
|
+
const id = crypto.randomUUID()
|
|
424
|
+
const setValue = (val = {}) => {
|
|
425
|
+
if (stateContext._hasRun) {
|
|
426
|
+
return
|
|
427
|
+
}
|
|
428
|
+
if (!stateContext) {
|
|
429
|
+
console.warn('set Context value must be inside of a component')
|
|
430
|
+
return null
|
|
431
|
+
}
|
|
432
|
+
if (!stateContext._transportContext) {
|
|
433
|
+
stateContext._transportContext = {}
|
|
434
|
+
}
|
|
435
|
+
if (stateContext._transportContext[id]) {
|
|
436
|
+
delete stateContext._transportContext[id]
|
|
437
|
+
}
|
|
438
|
+
stateContext._transportContext[id] = val
|
|
439
|
+
}
|
|
440
|
+
return {
|
|
441
|
+
id,
|
|
442
|
+
setValue
|
|
443
|
+
}
|
|
444
|
+
} else {
|
|
445
|
+
return serverInstance.setContext?.()
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Get parent Context
|
|
452
|
+
* @param {object} context
|
|
453
|
+
* @return {object}
|
|
454
|
+
*/
|
|
455
|
+
export const useContext = (context) => {
|
|
456
|
+
if (client) {
|
|
457
|
+
if (!stateContext) {
|
|
458
|
+
console.warn('getContext must be called inside of a component')
|
|
459
|
+
return
|
|
460
|
+
}
|
|
461
|
+
if (stateContext?._transportContext[context.id]) {
|
|
462
|
+
const contexts = stateContext._transportContext[context.id]
|
|
463
|
+
return contexts
|
|
464
|
+
} else {
|
|
465
|
+
console.warn('this component not in the context tree')
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
} else {
|
|
469
|
+
return serverInstance.useContext?.(context)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Get Current component context from the html
|
|
475
|
+
* @returns {object}
|
|
476
|
+
*/
|
|
477
|
+
export const useInnerContext = () => {
|
|
478
|
+
if (client) {
|
|
479
|
+
if (!stateContext) {
|
|
480
|
+
console.warn('must be used inside component')
|
|
481
|
+
return
|
|
482
|
+
}
|
|
483
|
+
return stateContext._elementContext
|
|
484
|
+
} else {
|
|
485
|
+
return serverInstance.useInnerContext?.()
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
export const accessChild = () => {
|
|
489
|
+
if (client) {
|
|
490
|
+
return
|
|
491
|
+
} else {
|
|
492
|
+
return serverInstance.accessChild?.()
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
/**@returns {()=>void} - let's component serialized useInsert data on server*/
|
|
496
|
+
export const useServer = () => {
|
|
497
|
+
if (client) {
|
|
498
|
+
return
|
|
499
|
+
} else {
|
|
500
|
+
return serverInstance.useServer?.()
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
export const useAsync = () => {
|
|
504
|
+
if (client) {
|
|
505
|
+
if (stateContext._hasRun) return { $async: () => {} }
|
|
506
|
+
const storeContext = stateContext
|
|
507
|
+
return {
|
|
508
|
+
$async: (callback) => {
|
|
509
|
+
if (storeContext._hasRun) {
|
|
510
|
+
storeContext._hasRun = false
|
|
511
|
+
keepContext(storeContext)
|
|
512
|
+
}
|
|
513
|
+
const res = callback()
|
|
514
|
+
storeContext._hasRun = true
|
|
515
|
+
stateContext = null
|
|
516
|
+
return res
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
} else {
|
|
520
|
+
return {
|
|
521
|
+
$async: (callback) => {
|
|
522
|
+
return callback()
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
export const isResume = () => {
|
|
528
|
+
if (client) {
|
|
529
|
+
return stateContext._resume
|
|
530
|
+
} else {
|
|
531
|
+
return false
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Insert into the html context in component
|
|
536
|
+
* @param {object} obj
|
|
537
|
+
* @returns void
|
|
538
|
+
*/
|
|
539
|
+
export const useInsert = (obj = {}) => {
|
|
540
|
+
if (client) {
|
|
541
|
+
if (stateContext._hasRun) {
|
|
542
|
+
return
|
|
543
|
+
}
|
|
544
|
+
if (!stateContext._insert) {
|
|
545
|
+
stateContext._insert = {}
|
|
546
|
+
}
|
|
547
|
+
Object.assign(stateContext._insert, obj)
|
|
548
|
+
} else {
|
|
549
|
+
// console.log(serverInstance.useInsert)
|
|
550
|
+
const res = serverInstance.useInsert(obj)
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const createDeepProxy = (target, callback) => {
|
|
554
|
+
return new Proxy(target, {
|
|
555
|
+
get(target, property) {
|
|
556
|
+
const value = target[property];
|
|
557
|
+
track(target, property);
|
|
558
|
+
if (typeof value === "object" && value !== null) {
|
|
559
|
+
return createDeepProxy(value, callback);
|
|
560
|
+
}
|
|
561
|
+
return value;
|
|
562
|
+
},
|
|
563
|
+
set(target, property, value) {
|
|
564
|
+
target[property] = value;
|
|
565
|
+
trigger(target, property);
|
|
566
|
+
callback(target, property);
|
|
567
|
+
return true;
|
|
568
|
+
},
|
|
569
|
+
});
|
|
570
|
+
};
|
|
571
|
+
const globalEffectMap = new Map();
|
|
572
|
+
/**
|
|
573
|
+
* @param {PawaComponent} context
|
|
574
|
+
*/
|
|
575
|
+
export const setStateContext = (context) => {
|
|
576
|
+
const map = new Map()
|
|
577
|
+
// const formerMap=formerStateContext
|
|
578
|
+
formerStateContext = stateContext
|
|
579
|
+
stateContext = context
|
|
580
|
+
if (stateContext._hasRun) {
|
|
581
|
+
return
|
|
582
|
+
}
|
|
583
|
+
stateContext._transportContext = {}
|
|
584
|
+
stateContext._static = []
|
|
585
|
+
stateContext._formerContext = formerStateContext
|
|
586
|
+
stateContext._reactiveProps = {}
|
|
587
|
+
stateContext._template = ''
|
|
588
|
+
stateContext._resume = false
|
|
589
|
+
stateContext._hook={
|
|
590
|
+
beforeMount:[],
|
|
591
|
+
reactiveEffect:[],
|
|
592
|
+
effect:[],
|
|
593
|
+
isMount:[],
|
|
594
|
+
isUnMount:[],
|
|
595
|
+
}
|
|
596
|
+
Object.assign(stateContext._transportContext, formerStateContext._transportContext)
|
|
597
|
+
formerStateContext = stateContext
|
|
598
|
+
return stateContext
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
const promiseCallback = (func, main) => {
|
|
602
|
+
const promise = func()
|
|
603
|
+
promise.then(res => {
|
|
604
|
+
main.value = res
|
|
605
|
+
main.failed = false
|
|
606
|
+
main.async = false
|
|
607
|
+
}).catch(error => {
|
|
608
|
+
main.async = false
|
|
609
|
+
main.failed = true
|
|
610
|
+
})
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* @param {FunctionConstructor|number|string|null} initialValue
|
|
615
|
+
* Any Function(can be return Promise or string or number) or string,number, null.
|
|
616
|
+
* @param {string|null}section
|
|
617
|
+
* A string for identifing or creating the localStorage(string) or compute value (array)
|
|
618
|
+
* @returns {{value:any,id:string,async?:boolean,failed?:boolean,retry?:()=>void}}
|
|
619
|
+
* notice the async, failed and retry works when Promised is pas into initialValue Function.
|
|
620
|
+
*
|
|
621
|
+
* id is not meant to be touched its pawajs way of tracking state
|
|
622
|
+
*/
|
|
623
|
+
export const $state = (initialValue, section = null) => {
|
|
624
|
+
if (!client) {
|
|
625
|
+
return serverInstance.$state?.(initialValue)
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const id = crypto.randomUUID()
|
|
629
|
+
const states = {
|
|
630
|
+
value: null,
|
|
631
|
+
id: id
|
|
632
|
+
}
|
|
633
|
+
let promise
|
|
634
|
+
if (initialValue instanceof Function) {
|
|
635
|
+
const result = initialValue()
|
|
636
|
+
if (result instanceof Promise) {
|
|
637
|
+
promise = result
|
|
638
|
+
states.async = true
|
|
639
|
+
states.failed = false
|
|
640
|
+
} else {
|
|
641
|
+
states.value = result
|
|
642
|
+
}
|
|
643
|
+
} else {
|
|
644
|
+
states.value = initialValue
|
|
645
|
+
}
|
|
646
|
+
if (typeof section === 'string') {
|
|
647
|
+
|
|
648
|
+
try {
|
|
649
|
+
if (localStorage.getItem(section)) {
|
|
650
|
+
const stored = JSON.parse(sanitizeTemplate(localStorage.getItem(section)))
|
|
651
|
+
states.value = stored.value
|
|
652
|
+
|
|
653
|
+
} else {
|
|
654
|
+
localStorage.setItem(section, JSON.stringify(states))
|
|
655
|
+
}
|
|
656
|
+
} catch (e) {
|
|
657
|
+
console.warn('error while trying to use localStorage')
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
let timeOut
|
|
661
|
+
const main = createDeepProxy(states, (target, property) => {
|
|
662
|
+
if (typeof section === 'string') {
|
|
663
|
+
if (timeOut) {
|
|
664
|
+
clearTimeout(timeOut)
|
|
665
|
+
}
|
|
666
|
+
timeOut = setTimeout(() => {
|
|
667
|
+
localStorage.setItem(section, JSON.stringify(states))
|
|
668
|
+
}, 50)
|
|
669
|
+
}
|
|
670
|
+
globalEffectMap.forEach((effect) => {
|
|
671
|
+
|
|
672
|
+
if (effect.deps?.has(target.id)) {
|
|
673
|
+
if (effect.cleanup) {
|
|
674
|
+
effect.cleanup();
|
|
675
|
+
}
|
|
676
|
+
effect.cleanup = effect.callback();
|
|
677
|
+
} else if (effect.deps.size === 0) {
|
|
678
|
+
effect.cleanup = effect.callback();
|
|
679
|
+
}
|
|
680
|
+
});
|
|
681
|
+
});
|
|
682
|
+
if (Array.isArray(section)) {
|
|
683
|
+
if (stateContext._hasRun === false && typeof initialValue === 'function') {
|
|
684
|
+
const cleanup=stateWatch(()=>{
|
|
685
|
+
main.value=initialValue()
|
|
686
|
+
},section)
|
|
687
|
+
stateContext._hook.isUnMount.push(cleanup)
|
|
688
|
+
}else{
|
|
689
|
+
console.error('state compute must be inside a component and initialValue must be a function')
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
if (promise instanceof Promise) {
|
|
693
|
+
|
|
694
|
+
promise.then(res => {
|
|
695
|
+
main.value = res
|
|
696
|
+
main.failed = false
|
|
697
|
+
main.async = false
|
|
698
|
+
}).catch(error => {
|
|
699
|
+
main.async = false
|
|
700
|
+
main.failed = true
|
|
701
|
+
})
|
|
702
|
+
|
|
703
|
+
const asyncObject = {
|
|
704
|
+
retry: () => {
|
|
705
|
+
promiseCallback(initialValue, main)
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
Object.assign(main, asyncObject)
|
|
709
|
+
return main
|
|
710
|
+
} else {
|
|
711
|
+
return main
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const watchCallbacks = new Map();
|
|
717
|
+
const stateWatch = (callback, dependencies) => {
|
|
718
|
+
if (!callback) {
|
|
719
|
+
console.warn('stateWatch: Callback function is required');
|
|
720
|
+
return;
|
|
721
|
+
}
|
|
722
|
+
const dep = new Set()
|
|
723
|
+
if (dependencies) {
|
|
724
|
+
dependencies.forEach(d => {
|
|
725
|
+
dep.add(d.id)
|
|
726
|
+
})
|
|
727
|
+
}
|
|
728
|
+
const effect = {
|
|
729
|
+
callback: () => {
|
|
730
|
+
if (!watchCallbacks.has(callback)) {
|
|
731
|
+
watchCallbacks.set(callback, true);
|
|
732
|
+
Promise.resolve().then(() => {
|
|
733
|
+
if (effect.cleanup) {
|
|
734
|
+
effect.cleanup();
|
|
735
|
+
}
|
|
736
|
+
const result = callback();
|
|
737
|
+
// Handle cleanup function returned from callback
|
|
738
|
+
if (typeof result === 'function') {
|
|
739
|
+
effect.cleanup = result;
|
|
740
|
+
}
|
|
741
|
+
watchCallbacks.delete(callback);
|
|
742
|
+
});
|
|
743
|
+
}
|
|
744
|
+
},
|
|
745
|
+
deps: dep,
|
|
746
|
+
cleanup: null,
|
|
747
|
+
};
|
|
748
|
+
|
|
749
|
+
// Initial run with cleanup handling
|
|
750
|
+
const result = callback();
|
|
751
|
+
if (typeof result === 'function') {
|
|
752
|
+
effect.cleanup = result;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
globalEffectMap.set(callback, effect);
|
|
756
|
+
|
|
757
|
+
return () => {
|
|
758
|
+
if (effect.cleanup) {
|
|
759
|
+
effect.cleanup();
|
|
760
|
+
}
|
|
761
|
+
globalEffectMap.delete(callback);
|
|
762
|
+
watchCallbacks.delete(callback);
|
|
763
|
+
};
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
export const restoreContext = (state_context) => {
|
|
767
|
+
stateContext = state_context._formerContext
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
*
|
|
771
|
+
* @param {PawaElement|HTMLElement} el
|
|
772
|
+
* @returns null
|
|
773
|
+
*/
|
|
774
|
+
const component = (el, resume = false, attr, notRender, stopResume) => {
|
|
775
|
+
if (el._running) {
|
|
776
|
+
return
|
|
777
|
+
}
|
|
778
|
+
el._running = true
|
|
779
|
+
|
|
780
|
+
if (!resume) {
|
|
781
|
+
normal_component(el, stateContext, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch)
|
|
782
|
+
} else {
|
|
783
|
+
stopResume.stop = true
|
|
784
|
+
let name
|
|
785
|
+
let comment
|
|
786
|
+
let endComment
|
|
787
|
+
const children = []
|
|
788
|
+
let serialized
|
|
789
|
+
let id
|
|
790
|
+
const getComment = (node) => {
|
|
791
|
+
if (node.previousSibling.nodeType === 8) {
|
|
792
|
+
const c = node.previousSibling.data.split('+')
|
|
793
|
+
if (c[1] === attr.value) {
|
|
794
|
+
comment = node.previousSibling
|
|
795
|
+
name = c[2]
|
|
796
|
+
serialized = c[3]
|
|
797
|
+
id = c[1]
|
|
798
|
+
} else {
|
|
799
|
+
getComment(node.previousSibling)
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
} else {
|
|
803
|
+
getComment(node.previousSibling)
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
const getEndComment = (comment) => {
|
|
807
|
+
const isComment = comment.nextSibling
|
|
808
|
+
if (comment.nextSibling.nodeType === 8) {
|
|
809
|
+
if (isComment.data.split('+')[1] === id) {
|
|
810
|
+
endComment = isComment
|
|
811
|
+
} else {
|
|
812
|
+
getEndComment(isComment)
|
|
813
|
+
}
|
|
814
|
+
} else if (isComment.nodeType === 1) {
|
|
815
|
+
children.push(isComment)
|
|
816
|
+
getEndComment(isComment)
|
|
817
|
+
} else {
|
|
818
|
+
getEndComment(isComment)
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
getComment(el)
|
|
822
|
+
getEndComment(comment)
|
|
823
|
+
el.removeAttribute(attr.name)
|
|
824
|
+
const numberComponentChildren = notRender.index + children.length - 1
|
|
825
|
+
notRender.notRender = numberComponentChildren
|
|
826
|
+
resumer.resume_component?.(el, attr, setStateContext, mapsPlugins, formerStateContext, pawaContext, stateWatch, { comment, endComment, name, serialized, id, children })
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* @param {PawaElement | HTMLElement} el
|
|
832
|
+
*/
|
|
833
|
+
const mainAttribute = (el, exp) => {
|
|
834
|
+
const attrMap = new Map();
|
|
835
|
+
if (el._running) return
|
|
836
|
+
// Store original attribute value
|
|
837
|
+
if (el._hasForOrIf()) {
|
|
838
|
+
return
|
|
839
|
+
}
|
|
840
|
+
if (el._componentName) {
|
|
841
|
+
return
|
|
842
|
+
}
|
|
843
|
+
attrMap.set(exp.name, exp.value);
|
|
844
|
+
el._preRenderAvoid.push(exp.name)
|
|
845
|
+
const removeAttribute = new Set()
|
|
846
|
+
removeAttribute.add('disabled')
|
|
847
|
+
el._mainAttribute[exp.name] = exp.value
|
|
848
|
+
el._checkStatic()
|
|
849
|
+
let enter=false
|
|
850
|
+
const evaluate = () => {
|
|
851
|
+
|
|
852
|
+
try {
|
|
853
|
+
// Always use original value from map for evaluation
|
|
854
|
+
let value = attrMap.get(exp.name);
|
|
855
|
+
let isBoolean
|
|
856
|
+
const regex = /@{([^}]*)}/g;
|
|
857
|
+
const keys = Object.keys(el._context);
|
|
858
|
+
const resolvePath = (path, obj) => {
|
|
859
|
+
return path.split('.').reduce((acc, key) => acc?.[key], obj);
|
|
860
|
+
};
|
|
861
|
+
const values = keys.map((key) => resolvePath(key, el._context));
|
|
862
|
+
|
|
863
|
+
value = value.replace(regex, (match, expression) => {
|
|
864
|
+
if (checkKeywordsExistence(el._staticContext, expression)) {
|
|
865
|
+
return ''
|
|
866
|
+
} else {
|
|
867
|
+
const func = new Function(...keys, `return ${expression}`);
|
|
868
|
+
isBoolean = func(...values)
|
|
869
|
+
if (typeof isBoolean !== 'boolean') {
|
|
870
|
+
return isBoolean
|
|
871
|
+
}else{
|
|
872
|
+
return ''
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
if (removeAttribute.has(exp.name)) {
|
|
878
|
+
if (isBoolean) {
|
|
879
|
+
el.setAttribute(exp.name, '');
|
|
880
|
+
} else {
|
|
881
|
+
el.removeAttribute(exp.name)
|
|
882
|
+
}
|
|
883
|
+
} else {
|
|
884
|
+
if (exp.name === 'class' && !enter) {
|
|
885
|
+
requestAnimationFrame(()=>{
|
|
886
|
+
el.setAttribute(exp.name, value);
|
|
887
|
+
})
|
|
888
|
+
enter=true
|
|
889
|
+
}else{
|
|
890
|
+
el.setAttribute(exp.name, value);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
} catch (error) {
|
|
894
|
+
console.warn(`failed at attribute ${exp.name}`, el)
|
|
895
|
+
setPawaDevError({
|
|
896
|
+
message: `error at attribute ${error.message}`,
|
|
897
|
+
error: error,
|
|
898
|
+
template: el._template
|
|
899
|
+
})
|
|
900
|
+
}
|
|
901
|
+
};
|
|
902
|
+
createEffect(() => {
|
|
903
|
+
evaluate();
|
|
904
|
+
});
|
|
905
|
+
};
|
|
906
|
+
|
|
907
|
+
const textContentHandler = (el, isName) => {
|
|
908
|
+
if (el._hasForOrIf()) {
|
|
909
|
+
return
|
|
910
|
+
}
|
|
911
|
+
if (el._running) {
|
|
912
|
+
return
|
|
913
|
+
}
|
|
914
|
+
const nodesMap = new Map();
|
|
915
|
+
|
|
916
|
+
// Get all text nodes and store their original content
|
|
917
|
+
const textNodes = Array.from(el.childNodes).filter(node => node.nodeType === Node.TEXT_NODE);
|
|
918
|
+
textNodes.forEach(node => {
|
|
919
|
+
nodesMap.set(node, node.nodeValue);
|
|
920
|
+
});
|
|
921
|
+
el._checkStatic()
|
|
922
|
+
const evaluate = () => {
|
|
923
|
+
try {
|
|
924
|
+
textNodes.forEach(textNode => {
|
|
925
|
+
// Always use original content from map for evaluation
|
|
926
|
+
let value = nodesMap.get(textNode);
|
|
927
|
+
const regex = /@{([^}]*)}/g;
|
|
928
|
+
|
|
929
|
+
const keys = Object.keys(el._context);
|
|
930
|
+
const resolvePath = (path, obj) => {
|
|
931
|
+
return path.split('.').reduce((acc, key) => acc?.[key], obj);
|
|
932
|
+
};
|
|
933
|
+
const values = keys.map((key) => resolvePath(key, el._context));
|
|
934
|
+
|
|
935
|
+
value = value.replace(regex, (match, expression) => {
|
|
936
|
+
if (checkKeywordsExistence(el._staticContext, expression)) {
|
|
937
|
+
return ''
|
|
938
|
+
} else {
|
|
939
|
+
|
|
940
|
+
el._textContent[expression] = value
|
|
941
|
+
const func = new Function(...keys, `return ${expression}`);
|
|
942
|
+
return String(func(...values));
|
|
943
|
+
}
|
|
944
|
+
});
|
|
945
|
+
textNode.nodeValue = value;
|
|
946
|
+
|
|
947
|
+
});
|
|
948
|
+
} catch (error) {
|
|
949
|
+
// console.warn(`error at ${el} textcontent`)
|
|
950
|
+
setPawaDevError({
|
|
951
|
+
message: `error at TextContent ${error.message}`,
|
|
952
|
+
error: error,
|
|
953
|
+
template: el._template
|
|
954
|
+
})
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
createEffect(() => {
|
|
959
|
+
evaluate();
|
|
960
|
+
}, el);
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
const template = (el, resume = false, notRender, attr) => {
|
|
964
|
+
if (el._running) {
|
|
965
|
+
return
|
|
966
|
+
}
|
|
967
|
+
el._running = true
|
|
968
|
+
templates(el)
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
const directives = {
|
|
972
|
+
if: If,
|
|
973
|
+
for: For,
|
|
974
|
+
else:(el)=>{el._running =true},
|
|
975
|
+
case:(el)=>{el._running =true},
|
|
976
|
+
default:(el)=>{el._running =true},
|
|
977
|
+
'else-if':(el)=>{el._running =true},
|
|
978
|
+
mount: mountElement,
|
|
979
|
+
unmount: unMountElement,
|
|
980
|
+
ref: ref,
|
|
981
|
+
switch:Switch,
|
|
982
|
+
key:Key,
|
|
983
|
+
'is-exit':exitTransition,
|
|
984
|
+
}
|
|
985
|
+
export const useRef = () => {
|
|
986
|
+
return { value: null }
|
|
987
|
+
}
|
|
988
|
+
export const render = (el, contexts = {}, notRender, isName) => {
|
|
989
|
+
const stopResume = { stop: false }
|
|
990
|
+
if (el.tagName === 'SCRIPT') {
|
|
991
|
+
return false
|
|
992
|
+
}
|
|
993
|
+
if (el.tagName === 'TITLE') {
|
|
994
|
+
document.title=el.textContent
|
|
995
|
+
el.remove()
|
|
996
|
+
return
|
|
997
|
+
}
|
|
998
|
+
const context = {
|
|
999
|
+
...contexts
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
for (const fn of renderBeforePawa) {
|
|
1003
|
+
try {
|
|
1004
|
+
fn(el, context)
|
|
1005
|
+
} catch (error) {
|
|
1006
|
+
__pawaDev.setError({ el: el, msg: error.message })
|
|
1007
|
+
console.error(error.message)
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
PawaElement.Element(el, context)
|
|
1011
|
+
el._staticContext = stateContext._static
|
|
1012
|
+
for (const fn of renderAfterPawa) {
|
|
1013
|
+
try {
|
|
1014
|
+
fn(el)
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
__pawaDev.setError({ el: el, msg: error.message })
|
|
1017
|
+
console.error(error.message)
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (Array.from(el.childNodes).some(node =>
|
|
1022
|
+
node.nodeType === Node.TEXT_NODE && node.nodeValue.includes('@{')
|
|
1023
|
+
) && !el._avoidPawaRender) {
|
|
1024
|
+
textContentHandler(el, isName)
|
|
1025
|
+
}
|
|
1026
|
+
let startAttribute = false
|
|
1027
|
+
const startObject = {}
|
|
1028
|
+
//get startsWith plugin
|
|
1029
|
+
if (!el._avoidPawaRender) {
|
|
1030
|
+
|
|
1031
|
+
startsWithSet.forEach(starts => {
|
|
1032
|
+
|
|
1033
|
+
el._attributes.forEach(attr => {
|
|
1034
|
+
if (attr.name.startsWith('on:')) {
|
|
1035
|
+
startAttribute = true
|
|
1036
|
+
startObject[attr.name] = starts
|
|
1037
|
+
}
|
|
1038
|
+
})
|
|
1039
|
+
})
|
|
1040
|
+
const number = { notRender: null }
|
|
1041
|
+
el._attributes.forEach(attr => {
|
|
1042
|
+
|
|
1043
|
+
if (stopResume.stop || el._hasRun) return
|
|
1044
|
+
if (directives[attr.name]) {
|
|
1045
|
+
directives[attr.name](el, attr, stateContext)
|
|
1046
|
+
} else if (attr.name.startsWith('on-')) {
|
|
1047
|
+
event(el, attr, stateContext)
|
|
1048
|
+
} else if (attr.value.includes('@{') && !attr.name.startsWith('resume-attr')) {
|
|
1049
|
+
mainAttribute(el, attr, isName)
|
|
1050
|
+
} else if (attr.name.startsWith('state-')) {
|
|
1051
|
+
States(el, attr, getCurrentContext())
|
|
1052
|
+
} else if (attr.name.startsWith('out-')) {
|
|
1053
|
+
documentEvent(el, attr)
|
|
1054
|
+
} else if (attr.name.startsWith('after-[') && attr.name.endsWith(']')) {
|
|
1055
|
+
After(el, attr)
|
|
1056
|
+
}
|
|
1057
|
+
else if (attr.name.startsWith('every-[') && attr.name.endsWith(']')) {
|
|
1058
|
+
Every(el, attr)
|
|
1059
|
+
}
|
|
1060
|
+
else if (attr.name.startsWith('c-c-')) {
|
|
1061
|
+
stopResume.stop = true
|
|
1062
|
+
|
|
1063
|
+
component(el, true, attr, notRender, stopResume)
|
|
1064
|
+
} else if (attr.name.startsWith('c-at-')) {
|
|
1065
|
+
resumer.resume_attribute?.(el, attr, notRender)
|
|
1066
|
+
} else if (attr.name.startsWith('c-$-')) {
|
|
1067
|
+
resumer.resume_state?.(el, attr, notRender)
|
|
1068
|
+
} else if (attr.name.startsWith('c-t')) {
|
|
1069
|
+
resumer.resume_text(el, attr, isName)
|
|
1070
|
+
} else if (attr.name.startsWith('c-if-')) {
|
|
1071
|
+
// console.log('resume -if',el,el._attributes)
|
|
1072
|
+
directives['if'](el, attr, stateContext, true, notRender, stopResume)
|
|
1073
|
+
} else if (attr.name === 'c-for') {
|
|
1074
|
+
directives['for'](el, attr, stateContext, true, notRender, stopResume)
|
|
1075
|
+
} else if (attr.name.startsWith('c-sw-')) {
|
|
1076
|
+
directives['switch'](el, attr, stateContext, true, notRender, stopResume)
|
|
1077
|
+
} else if (attr.name === 'c-for') {
|
|
1078
|
+
directives['for'](el, attr, stateContext, true, notRender, stopResume)
|
|
1079
|
+
} else if (fullNamePlugin.has(attr.name)) {
|
|
1080
|
+
if (externalPlugin[attr.name]) {
|
|
1081
|
+
const plugin = externalPlugin[attr.name]
|
|
1082
|
+
try {
|
|
1083
|
+
if (typeof plugin !== 'function') {
|
|
1084
|
+
console.warn(`${attr.name} plugin must be a function`)
|
|
1085
|
+
return
|
|
1086
|
+
}
|
|
1087
|
+
plugin(el, attr, stateContext, notRender, stopResume)
|
|
1088
|
+
} catch (error) {
|
|
1089
|
+
console.warn(error.message, error.stack)
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
} else if (startAttribute) {
|
|
1093
|
+
const name = startObject[attr.name]
|
|
1094
|
+
if (externalPlugin[name]) {
|
|
1095
|
+
const plugin = externalPlugin[name]
|
|
1096
|
+
try {
|
|
1097
|
+
if (typeof plugin !== 'function') {
|
|
1098
|
+
console.warn(`${name} plugin must be a function`)
|
|
1099
|
+
return
|
|
1100
|
+
}
|
|
1101
|
+
plugin(el, attr, stateContext, notRender, stopResume)
|
|
1102
|
+
} catch (error) {
|
|
1103
|
+
console.warn(error.message, error.stack)
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
|
|
1108
|
+
|
|
1109
|
+
})
|
|
1110
|
+
}
|
|
1111
|
+
if (stopResume.stop) return
|
|
1112
|
+
if (el._componentName && !el._avoidPawaRender) {
|
|
1113
|
+
component(el)
|
|
1114
|
+
return
|
|
1115
|
+
}
|
|
1116
|
+
if (el._elementType === 'template' && !el._avoidPawaRender) {
|
|
1117
|
+
template(el)
|
|
1118
|
+
return
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
if (el._out === false || el._running === false || el._componentOrTemplate !== true) {
|
|
1122
|
+
|
|
1123
|
+
if (el._running) {
|
|
1124
|
+
return true
|
|
1125
|
+
}
|
|
1126
|
+
for (const fn of renderBeforeChild) {
|
|
1127
|
+
try {
|
|
1128
|
+
fn(el)
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
__pawaDev.setError({ el: el, msg: error.message })
|
|
1131
|
+
console.error(error.message)
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
const number = { notRender: null, index: null }
|
|
1135
|
+
Array.from(el.children).forEach((child, index) => {
|
|
1136
|
+
number.index = index
|
|
1137
|
+
if (number.notRender && index <= number.notRender) return
|
|
1138
|
+
render(child, context, number, isName)
|
|
1139
|
+
})
|
|
1140
|
+
el._callMount()
|
|
1141
|
+
if (el.hasAttribute('p:c')) {
|
|
1142
|
+
el.removeAttribute('p:c')
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
export const pawaStartApp = (app, context = {}) => {
|
|
1148
|
+
render(app, context)
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
/**
|
|
1152
|
+
* Tagged template function for syntax highlighting and future tooling support.
|
|
1153
|
+
* Usage: return html`<div>...</div>`
|
|
1154
|
+
*/
|
|
1155
|
+
export const html = (strings, ...values) => {
|
|
1156
|
+
if (strings.length === 1) return strings[0];
|
|
1157
|
+
let result = "";
|
|
1158
|
+
for (let i = 0; i < strings.length; i++) {
|
|
1159
|
+
result += strings[i];
|
|
1160
|
+
if (i < values.length) {
|
|
1161
|
+
result += values[i];
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
return result;
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
const Pawa = {
|
|
1168
|
+
useInsert,
|
|
1169
|
+
useContext,
|
|
1170
|
+
useValidateComponent,
|
|
1171
|
+
setPawaAttributes,
|
|
1172
|
+
setContext,
|
|
1173
|
+
$state,
|
|
1174
|
+
pawaStartApp,
|
|
1175
|
+
RegisterComponent,
|
|
1176
|
+
runEffect,
|
|
1177
|
+
html
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
export default Pawa
|