pawajs 2.0.7 → 2.0.9

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/cdn/index.html ADDED
@@ -0,0 +1,25 @@
1
+ <!DOCTYPE html>
2
+ <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
3
+ <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
4
+ <!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
5
+ <!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
6
+ <html>
7
+ <head>
8
+ <meta charset="utf-8">
9
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
10
+ <title>pawajs</title>
11
+ <meta name="description" content="">
12
+ <meta name="viewport" content="width=device-width, initial-scale=1">
13
+ <link rel="stylesheet" href="">
14
+ </head>
15
+ <body>
16
+ <!--[if lt IE 7]>
17
+ <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
18
+ <![endif]-->
19
+ <div id="app">
20
+ <counter></counter>
21
+ </div>
22
+
23
+ <script src="./index.js" type="module"></script>
24
+ </body>
25
+ </html>
package/cdn/index.js CHANGED
@@ -1,5 +1,22 @@
1
- import Pawa from '../index.js'
1
+ import { $state, html, useInsert, RegisterComponent, pawaStartApp } from "../index.js"
2
2
 
3
- // this is for cdn file
4
-
5
- window.$pawa=Pawa
3
+ export const Counter=()=>{
4
+ const count=$state(0)
5
+ useInsert({count})
6
+ return html`
7
+ <div>
8
+ <h1>Counter APPs</h1>
9
+ <h2>@{count.value}</h2>
10
+ <span if="count.value > 0">positive</span>
11
+ <span else-if="count.value < 0">negative</span>
12
+ <span else>It zero</span>
13
+ <button on-click=count.value++>Increment</button>
14
+ <button on-click=count.value-->Decrement</button>
15
+ </div>
16
+ `
17
+ }
18
+ __pawaDev.tool=true
19
+ RegisterComponent(Counter)
20
+ const app=document.getElementById('app')
21
+ pawaStartApp(app)
22
+ window.hmr=true
package/index.js CHANGED
@@ -890,7 +890,7 @@ export const restoreContext = (state_context) => {
890
890
  }
891
891
  export const HmrComponentMap=new Map()
892
892
  const renderedComponentsRusumed=new Set()
893
- export const globalRerender=(el,formercontext)=>{
893
+ export const globalRerender=(el,formercontext,context={})=>{
894
894
  if(!window?.hmr)return
895
895
  let element
896
896
  if (typeof el === 'string') {
@@ -899,7 +899,7 @@ export const globalRerender=(el,formercontext)=>{
899
899
  element=dom.firstElementChild
900
900
  }else element=el
901
901
  formerStateContext=formercontext
902
- normal_component(element,formercontext,setStateContext,mapsPlugins,formercontext,pawaContext,stateWatch)
902
+ normal_component(element,formercontext,setStateContext,mapsPlugins,formercontext,pawaContext,stateWatch,context)
903
903
  }
904
904
  /**
905
905
  *
@@ -2,11 +2,36 @@ import {propsValidator, setPawaDevError, pawaWayRemover, checkKeywordsExistence,
2
2
  import {PawaElement,PawaComment} from '../pawaElement.js';
3
3
  import {keepContext,render, HmrComponentMap } from '../index.js'
4
4
  import {createEffect} from '../reactive.js'
5
- export const normal_component=(el,stateContext,setStateContext,mapsPlugin,formerStateContext,pawaContext,stateWatch)=>{
5
+ function isPawaState(obj) {
6
+ return (
7
+ obj !== null &&
8
+ typeof obj === 'object' &&
9
+ Object.prototype.hasOwnProperty.call(obj, 'value') &&
10
+ typeof obj.id === 'string'
11
+ )
12
+ }
13
+ function restorePawaStateFromContext(oldCtx, newCtx) {
14
+ if (!oldCtx || !newCtx) return
15
+
16
+ for (const key of Object.keys(oldCtx)) {
17
+ const oldVal = oldCtx[key]
18
+ const newVal = newCtx[key]
19
+ if (isPawaState(oldVal) && isPawaState(newVal)) {
20
+ const newOne=newVal.value
21
+ const oldOne=oldVal.value
22
+ if (typeof newOne === typeof oldOne) {
23
+ newVal.value = oldVal.value
24
+ }else if (newVal === null) {
25
+ newVal.value = oldVal.value
26
+ }
27
+ }
28
+ }
29
+ }
30
+ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,formerStateContext,pawaContext,stateWatch,hmrPreserverContext)=>{
6
31
  // Checks if the content is an SVG fragment (graphic elements) without a root <svg> tag.
7
32
  // We exclude 'svg' from the match because a root <svg> tag can be parsed safely inside a <div>.
8
33
  const isSvgFragment = (str) => /^\s*<(path|circle|rect|line|polyline|polygon|ellipse|g|defs|symbol|use|image|text|animate|mask|pattern|clipPath|linearGradient|radialGradient|filter)/i.test(str);
9
-
34
+ const hmr=window?.hmr || false
10
35
  const compoBeforeCall=mapsPlugin.compoBeforeCall
11
36
  const compoAfterCall=mapsPlugin.compoAfterCall
12
37
  const endComment = document.createComment(`end ${el.tagName}`)
@@ -261,6 +286,12 @@ export const normal_component=(el,stateContext,setStateContext,mapsPlugin,former
261
286
  stateContexts?._error?.forEach((error) => {
262
287
  throw Error(error)
263
288
  })
289
+ if (hmr) {
290
+ if (hmrPreserverContext) {
291
+ restorePawaStateFromContext(context, hmrPreserverContext)
292
+ }
293
+
294
+ }
264
295
  render(child, context)
265
296
  }
266
297
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pawajs",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "type":"module",
5
5
  "description": "pawajs library (reactive web runtime) for easily building web ui, enhancing html element, micro frontend, spa etc ",
6
6
  "main": "index.js",
package/pawaElement.js CHANGED
@@ -10,7 +10,6 @@ import { lazyComponentElement } from './index.js';
10
10
  export class PawaElement {
11
11
 
12
12
  #context
13
- #el
14
13
  /**
15
14
  *
16
15
  * @param {HTMLElement} element
@@ -18,24 +17,10 @@ export class PawaElement {
18
17
  */
19
18
  constructor(element,context) {
20
19
  this.#context=context
21
- this.#el=element
22
- // ── Bind every method that touches private fields ──
23
- this.getChildrenTree = this.getChildrenTree.bind(this)
24
- this.checkLazy = this.checkLazy.bind(this)
25
- this.safeEval = this.safeEval.bind(this)
26
- this.setPawaAttr = this.setPawaAttr.bind(this)
27
- this.findPawaAttribute = this.findPawaAttribute.bind(this)
28
- this.getNewElementByRemovingAttr = this.getNewElementByRemovingAttr.bind(this)
29
- this.remove = this.remove.bind(this)
30
- this.unMount = this.unMount.bind(this)
31
- this.elementType = this.elementType.bind(this)
32
- this.setProps = this.setProps.bind(this)
33
- this.clearContext = this.clearContext.bind(this)
34
- // ───────────────────────────────────────────
35
20
  const div=element.cloneNode(true)
36
21
  Object.assign(this, {
37
22
  _resetEffects: new Set(), _context: context, _avoidPawaRender: element.hasAttribute('pawa-avoid'),
38
- _out: false, _stateContext: null, _terminateEffects: new Set(), _deleteEffects: this.terminateEffects,
23
+ _el: element, _out: false, _stateContext: null, _terminateEffects: new Set(), _deleteEffects: this.terminateEffects,
39
24
  _slots: document.createDocumentFragment(), _mainAttribute: {}, _preRenderAvoid: [], _running: false,
40
25
  _hasForOrIf: this.hasForOrIf, _elementContent: element.textContent, _textContent: {}, _attributes: [],
41
26
  _template: div.outerHTML, _exitAnimation: null, _component: null, _unMountFunctions: [], _MountFunctions: [],_beforeUnMountFunctions:[],
@@ -63,13 +48,13 @@ export class PawaElement {
63
48
  Object.assign(element,pawa)
64
49
  }
65
50
  getChildrenTree(){
66
- return Array.from(this.#el.children)
51
+ return Array.from(this._el.children)
67
52
  }
68
53
  checkLazy(){
69
- if (lazyComponents.has(splitAndAdd(this.#el.tagName))) {
70
- if(components.has(splitAndAdd(this.#el.tagName))) return
54
+ if (lazyComponents.has(splitAndAdd(this._el.tagName))) {
55
+ if(components.has(splitAndAdd(this._el.tagName))) return
71
56
  this._lazy=true
72
- triggerLazyLoad(splitAndAdd(this.#el.tagName))
57
+ triggerLazyLoad(splitAndAdd(this._el.tagName))
73
58
 
74
59
  }
75
60
  }
@@ -91,9 +76,9 @@ export class PawaElement {
91
76
 
92
77
  }catch(error){
93
78
  throw new Error(`Error evaluating expression: ${expression}\n${error.message}`);
94
- let element=this.#el || null
79
+
95
80
  __pawaDev.setError({
96
- el:element,
81
+ el:this?._el,
97
82
  msg:`from ${expression}`,
98
83
  directives:directive,
99
84
  stack:error.stack,
@@ -108,24 +93,24 @@ export class PawaElement {
108
93
  })
109
94
  }
110
95
  setPawaAttr(){
111
- const isResume=this.#el.hasAttribute('p:c')
112
- if (this.#el.hasAttribute('p-async')) return
96
+ const isResume=this._el.hasAttribute('p:c')
97
+ if (this._el.hasAttribute('p-async')) return
113
98
  if(isResume){
114
- const pawaAttr=this.#el.getAttribute('p:c')
99
+ const pawaAttr=this._el.getAttribute('p:c')
115
100
  const array=pawaAttr.split(';')
116
101
  array.forEach(value =>{
117
- if(!this.#el.hasAttribute(value.toLowerCase())) {
102
+ if(!this._el.hasAttribute(value.toLowerCase())) {
118
103
  return
119
104
  }
120
- this._attributes.push({name:value,value:this.#el.getAttribute(value.toLowerCase())})
121
- // console.log(this.#el,this._attributes);
105
+ this._attributes.push({name:value,value:this._el.getAttribute(value.toLowerCase())})
106
+ // console.log(this._el,this._attributes);
122
107
  })
123
108
  }else{
124
- this._attributes=Array.from(this.#el.attributes)
109
+ this._attributes=Array.from(this._el.attributes)
125
110
  }
126
111
  }
127
112
  findPawaAttribute(){
128
- Array.from(this.#el.attributes).forEach((attr) => {
113
+ Array.from(this._el.attributes).forEach((attr) => {
129
114
  const pawaAttribute=getPawaAttributes()
130
115
  const dependentAttribute=getDependentAttribute()
131
116
  if (pawaAttribute.has(attr.name) && !dependentAttribute.has(attr.name)) {
@@ -158,7 +143,7 @@ export class PawaElement {
158
143
  }
159
144
 
160
145
  getNewElementByRemovingAttr(attrName){
161
- const element=this.#el.cloneNode(true)
146
+ const element=this._el.cloneNode(true)
162
147
  element.removeAttribute(attrName)
163
148
  return element
164
149
  }
@@ -202,7 +187,7 @@ export class PawaElement {
202
187
  const animate=this._exitAnimation().then(async () => {
203
188
  await this._callUnmount()
204
189
  this._out = true
205
- this.#el.remove()
190
+ this._el.remove()
206
191
  if (callback) {
207
192
  callback()
208
193
  }
@@ -214,7 +199,7 @@ export class PawaElement {
214
199
  } else {
215
200
  this._callUnmount()
216
201
  this._out=true
217
- this.#el.remove()
202
+ this._el.remove()
218
203
  if (callback) {
219
204
  callback()
220
205
  }
@@ -238,9 +223,9 @@ export class PawaElement {
238
223
  func()
239
224
  })
240
225
  this._deleteEffects()
241
- Array.from(this.#el.childNodes).forEach(child => {
226
+ Array.from(this._el.childNodes).forEach(child => {
242
227
  if (child.nodeType === 1) {
243
- if (child?._template) {
228
+ if (child?._el) {
244
229
  child._out = true
245
230
  child._deleteEffects()
246
231
  child._callUnmount()
@@ -269,21 +254,21 @@ export class PawaElement {
269
254
  if (this._avoidPawaRender) {
270
255
  return
271
256
  }
272
- const tag = this.#el.tagName
257
+ const tag = this._el.tagName
273
258
  try {
274
- if (components.has(splitAndAdd(tag)) || this._lazy && !this.#el.hasAttribute('data-prevent:c')) {
259
+ if (components.has(splitAndAdd(tag)) || this._lazy && !this._el.hasAttribute('data-prevent:c')) {
275
260
  this._elementType='component'
276
261
  this._componentOrTemplate=true
277
262
  this._deCompositionElement=true
278
263
  this._componentName=splitAndAdd(tag)
279
264
  const forLazy=()=>true
280
265
  this._component=new PawaComponent(components.get(splitAndAdd(tag)) || forLazy)
281
- Array.from(this.#el.children).forEach(slot =>{
266
+ Array.from(this._el.children).forEach(slot =>{
282
267
  if (slot.tagName === 'TEMPLATE' && slot.getAttribute('prop') && !slot.hasAttribute('js')) {
283
268
  this._slots.appendChild(slot)
284
269
  }
285
270
  })
286
- this._componentChildren=this.#el.innerHTML
271
+ this._componentChildren=this._el.innerHTML
287
272
 
288
273
  } else if(tag ==='TEMPLATE'){
289
274
  this._elementType='template'
@@ -312,9 +297,9 @@ export class PawaElement {
312
297
  return
313
298
  }
314
299
  if (this._componentName) {
315
- const hasPC=this.#el.hasAttribute('p:c')
300
+ const hasPC=this._el.hasAttribute('p:c')
316
301
  if (hasPC) {
317
- Array.from(this.#el.attributes).forEach(attr => {
302
+ Array.from(this._el.attributes).forEach(attr => {
318
303
  if (attr.name.startsWith('c-') || attr.name === 'by') return
319
304
  this._attributes.push({name:attr.name,value:attr.value})
320
305
  });