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/pawaElement.js ADDED
@@ -0,0 +1,455 @@
1
+ import {components,escapePawaAttribute,getPawaAttributes,getDependentAttribute,} from './index.js';
2
+ import {splitAndAdd,replaceTemplateOperators,setPawaDevError,getEvalValues,safeEval} from './utils.js';
3
+ import PawaComponent from './pawaComponent.js';
4
+ import { getPrimaryDirective } from './index.js';
5
+
6
+
7
+ export class PawaElement {
8
+
9
+ /**
10
+ *
11
+ * @param {HTMLElement} element
12
+ * @param {object} context
13
+ */
14
+ constructor(element,context) {
15
+ /**
16
+ * @type{PawaElement|HTMLElement}
17
+ */
18
+ const div=document.createElement('div')
19
+ div.appendChild(element.cloneNode(true))
20
+ this._resetEffects=new Set()
21
+ this._context=context;
22
+ this._avoidPawaRender=element.hasAttribute('pawa-avoid');
23
+ this._el=element
24
+ this._out=false;
25
+ this._terminateEffects=new Set()
26
+ this._deleteEffects=this.terminateEffects
27
+ /**
28
+ * @type{HTMLAllCollection}
29
+ */
30
+ this._slots=document.createDocumentFragment()
31
+ this._mainAttribute={}
32
+ this._preRenderAvoid=[]
33
+ this._running=false
34
+ this._hasForOrIf=this.hasForOrIf
35
+ this._elementContent=element.textContent
36
+ this._textContent={}
37
+ this._attributes=[]
38
+ this._template=div.innerHTML;
39
+ this._exitAnimation=null;
40
+ this._component=null
41
+ this._unMountFunctions=[];
42
+ this._MountFunctions=[];
43
+ this._elementType=''
44
+ this._getNode=this.getNode
45
+ this._componentOrTemplate=false
46
+ this._props={}
47
+ this._isView=null
48
+ this._isElementComponent=false
49
+ this._pawaAttribute={}
50
+ this._setUnMount=this.setUnMounts
51
+ this._componentName=''
52
+ this._attrElement=this.getNewElementByRemovingAttr
53
+ this._attr={}
54
+ this._staticContext=[],
55
+ this._checkStatic=this.reCheckStaticContext
56
+ this._callMount=this.mount
57
+ this._callUnMOunt=this.unMount
58
+ this._remove=this.remove
59
+ this._componentChildren
60
+ this._pawaElementComponent=null
61
+ this._componentTerminate=null
62
+ this._cacheSetUp=false
63
+ this._effectsCarrier=null
64
+ this._pawaElementComponentName=''
65
+ this._reCallEffect=this.reCallEffect
66
+ this._ElementEffects=new Map()
67
+ this._deCompositionElement=false
68
+ this._restProps={}
69
+ this._kill=null
70
+ this._isKill=false
71
+ this._scriptFetching=element.hasAttribute('script')
72
+ this._scriptDone=false
73
+ this._underControl=null
74
+ /**
75
+ * @type{object}
76
+ */
77
+ this._reactiveProps={}
78
+ if (this._lazy) {
79
+
80
+ this._componentOrTemplate=true
81
+ }
82
+
83
+ if(this._avoidPawaRender){
84
+ element.removeAttribute('pawa-avoid')
85
+ Array.from(element.children).forEach((child) => {
86
+ if (child.nodeType === 1) {
87
+ child.setAttribute('pawa-avoid','')
88
+ }
89
+ })
90
+ }
91
+ this.setPawaAttr()
92
+ this.elementType()
93
+ this.setProps()
94
+ this.setAttri()
95
+ this.findPawaAttribute()
96
+ }
97
+
98
+ static Element(element,context){
99
+ const pawa=new PawaElement(element,context)
100
+ Object.assign(element,pawa)
101
+ }
102
+ getChildrenTree(){
103
+ return Array.from(this._el.children)
104
+ }
105
+ reCallEffect(){
106
+ this._resetEffects.forEach((call)=>{
107
+ call()
108
+ })
109
+ }
110
+ findPawaAttribute(){
111
+ Array.from(this._el.attributes).forEach((attr) => {
112
+ const pawaAttribute=getPawaAttributes()
113
+ const dependentAttribute=getDependentAttribute()
114
+ if (pawaAttribute.has(attr.name) && !dependentAttribute.has(attr.name)) {
115
+ if (!escapePawaAttribute.has(attr.name)) {
116
+ this._pawaAttribute[attr.name]=attr.value
117
+ }
118
+ } else {
119
+ pawaAttribute.forEach((value) => {
120
+ if (attr.name.startsWith(value) && !dependentAttribute.has(value)) {
121
+ this._pawaAttribute[attr.name]=attr.value
122
+ }
123
+ })
124
+ }
125
+ })
126
+
127
+ }
128
+ setUnMounts(func){
129
+ this._unMountFunctions.push(func)
130
+ }
131
+ getNode(){
132
+ const nodeDiv=document.createElement('div')
133
+ nodeDiv.innerHTML=this._template
134
+ const node=nodeDiv.firstElementChild
135
+ return node
136
+ }
137
+ terminateEffects(){
138
+ this._terminateEffects.forEach((eff) => {
139
+ eff()
140
+ })
141
+ }
142
+
143
+ getNewElementByRemovingAttr(attrName){
144
+ const element=this._el.cloneNode(true)
145
+ element.removeAttribute(attrName)
146
+ return element
147
+ }
148
+
149
+ setAttri(){
150
+ this._attributes.forEach((attr) => {
151
+ this._attr[attr.name]=attr.value
152
+ })
153
+ }
154
+ hasForOrIf(){
155
+ const primary=getPrimaryDirective()
156
+ let truth=false
157
+ primary.forEach((att)=>{
158
+ if(truth) return
159
+ if(this._attributes.includes(att)){
160
+ truth=true
161
+ return
162
+ }
163
+ truth=false
164
+ })
165
+ }
166
+ reCheckStaticContext(){
167
+ const context=this._context
168
+ if (this._staticContext.length > 0) {
169
+ for (const [key,value] of Object.entries(context)) {
170
+ if (this._staticContext.includes(key)) {
171
+ this._staticContext=this._staticContext.filter(value =>value !== key)
172
+ }
173
+ }
174
+ }
175
+ }
176
+ async remove(callback){
177
+ if (typeof this._kill === 'function' && this._isKill && this._deCompositionElement) {
178
+ this._kill()
179
+ return
180
+ }
181
+ if (typeof this._exitAnimation === 'function') {
182
+
183
+ try {
184
+ const animate=this._exitAnimation().then(() => {
185
+ this._callUnMOunt()
186
+ this._out = true
187
+ this._el.remove()
188
+ if (callback) {
189
+ callback()
190
+ }
191
+ })
192
+ return animate
193
+ } catch (error) {
194
+ console.error(error);
195
+
196
+ }
197
+ } else {
198
+ this._callUnMOunt()
199
+ this._out=true
200
+ this._el.remove()
201
+ if (callback) {
202
+ console.log(callback)
203
+ callback?.()
204
+ }
205
+ return true
206
+ }
207
+ }
208
+ async unMount(){
209
+ if (this._component && this._pawaElementComponentName === '') {
210
+ this._componentTerminate()
211
+ } else {
212
+ this._unMountFunctions.forEach(func => {
213
+ func()
214
+ })
215
+ this._deleteEffects()
216
+ Array.from(this._el.childNodes).forEach(child => {
217
+ if (child.nodeType === 1) {
218
+ if (child?._el) {
219
+ child._out = true
220
+ child._deleteEffects()
221
+ child._callUnMOunt()
222
+ }
223
+ } else if (child.nodeType === 8) {
224
+ if (child?._controlComponent) {
225
+ // console.log(child);
226
+ child._remove()
227
+
228
+ }
229
+ }
230
+
231
+ })
232
+ }
233
+ }
234
+ mount(){
235
+ try {
236
+ this._MountFunctions.forEach((func) => {
237
+ func()
238
+ })
239
+ } catch (e) {
240
+ throw e
241
+ }
242
+ }
243
+ elementType(){
244
+ if (this._avoidPawaRender) {
245
+ return
246
+ }
247
+ const tag = this._el.tagName
248
+ try {
249
+ if (components.has(splitAndAdd(tag))) {
250
+ this._elementType='component'
251
+ this._componentOrTemplate=true
252
+ this._deCompositionElement=true
253
+ this._componentName=splitAndAdd(tag)
254
+ this._component=new PawaComponent(components.get(splitAndAdd(tag)))
255
+ Array.from(this._el.children).forEach(slot =>{
256
+ if (slot.tagName === 'TEMPLATE' && slot.getAttribute('prop') && !slot.hasAttribute('js')) {
257
+ this._slots.appendChild(slot)
258
+ }
259
+ })
260
+ this._componentChildren=this._el.innerHTML
261
+
262
+ } else if(tag ==='TEMPLATE'){
263
+ this._elementType='template'
264
+ this._deCompositionElement=true
265
+ this._componentOrTemplate=true
266
+ } else {
267
+ this._elementType='element'
268
+ this._componentOrTemplate=false
269
+ }
270
+ } catch (error) {
271
+ console.warn('from element tag identitfier be sure if its the right component',error)
272
+ throw new Error(error);
273
+
274
+ }
275
+ }
276
+ setProps(){
277
+ if (this._avoidPawaRender) {
278
+ return
279
+ }
280
+ if (!this._context) {
281
+ return
282
+ }
283
+ if (this._componentName) {
284
+ const pawaAttribute=getPawaAttributes()
285
+ const dependAttribute=getDependentAttribute()
286
+ this._attributes.forEach((attr) => {
287
+ if (!attr.name.startsWith(':') && !pawaAttribute.has(attr.name) && !dependAttribute.has(attr.name)) {
288
+ let name=''
289
+ if (attr.name.startsWith('-')) {
290
+ name=attr.name.slice(1)
291
+ } else {
292
+ name=attr.name
293
+ }
294
+ this._restProps[name]={name:name,value:attr.value}
295
+ }else if(!pawaAttribute.has(attr.name) && attr.name.startsWith(':')){
296
+
297
+ const propsName=attr.name.slice(1)
298
+ try {
299
+ const keys = Object.keys(this._context);
300
+ const resolvePath = (path, obj) => {
301
+ return path.split('.').reduce((acc, key) => acc?.[key], obj);
302
+ };
303
+ const values = keys.map((key) => resolvePath(key, this._context));
304
+ if(attr.value === '') attr.value=true;
305
+ const value=new Function(...keys,`
306
+ return ()=>{
307
+ try{
308
+ const prop= ${replaceTemplateOperators(attr.value)};
309
+ if(prop === '')return prop
310
+ return prop
311
+ }catch(error){
312
+ console.error(error.message,error.stack)
313
+ }
314
+ }
315
+ `)(...values)
316
+ this._props[propsName]=value
317
+ } catch (error) {
318
+ setPawaDevError({
319
+ message:`error from ${this._componentName} prop :${propsName} ${error.message}`,
320
+ error:error,
321
+ template:this._template
322
+ })
323
+ }
324
+ }
325
+ })
326
+ }
327
+ }
328
+ }
329
+
330
+
331
+ export class PawaComment {
332
+ constructor(element) {
333
+
334
+ this._index=null;
335
+ this._el=element
336
+ this._setCoveringElement=this.setCoveringElement
337
+ this._data={}
338
+ this._terminateEffects=new Set()
339
+ this._run
340
+ this._coveringElement=null
341
+ this._setData=this.setData
342
+ this._removeSiblings=this.removeSiblings
343
+ this._controlComponent=false
344
+ this._componentTerminate=null
345
+ this._componentElement=null
346
+ this._setComponentOut=this. pp
347
+ this._deleteEffects=this.terminateEffects
348
+ this._remove=this.remove
349
+ this._terminateByComponent=this.terminate
350
+ this._forKey=null
351
+ this._forIndex=null
352
+ this._setKey=this.setForKey
353
+ this._endComment=null
354
+ this._keyRemover=this.keyRemoveElement
355
+ this._resetForKeyElement=this.forKeyResetElement
356
+ this._deleteKey=this.deleteKey
357
+ }
358
+ static Element(element){
359
+ const pawa=new PawaComment(element)
360
+ Object.assign(element,pawa)
361
+ return element
362
+ }
363
+ forKeyResetElement(){
364
+ const fragment=document.createDocumentFragment()
365
+ while (this._el.nextSibling !== this._endComment) {
366
+ fragment.appendChild(this._el.nextSibling)
367
+ }
368
+ this._endComment.remove()
369
+
370
+ return fragment
371
+ }
372
+ async keyRemoveElement(callback,firstElement=true){
373
+ const comment=this._el
374
+ if (!comment?.nextSibling) {
375
+ return
376
+ }
377
+ if (comment.nextSibling === this._endComment) {
378
+
379
+ return
380
+ } else {
381
+ if (comment?.nextSibling?.nodeType === 8) {
382
+ if(comment.nextSibling?._controlComponent){
383
+ comment.nextSibling._remove()
384
+ }else{
385
+ comment.nextSibling.remove()
386
+ }
387
+
388
+ } else if (comment.nextSibling.nodeType === 1) {
389
+ if (firstElement) {
390
+ console.log(callback)
391
+ await comment.nextSibling._remove(callback)
392
+ } else{
393
+ await comment.nextSibling._remove()
394
+ }
395
+ firstElement=false
396
+ }
397
+ }
398
+ await this._el._keyRemover(comment,firstElement)
399
+ }
400
+ deleteKey(){
401
+ this._el.remove()
402
+ this._endComment.remove()
403
+ }
404
+ setForKey(arg=String){
405
+ this._forKey=arg
406
+ }
407
+ terminateEffects() {
408
+ this._terminateEffects.forEach((eff) => {
409
+ eff()
410
+ })
411
+ }
412
+ setCoveringElement(el){
413
+ this._coveringElement=el
414
+ }
415
+ setData(obj){
416
+ Object.assign(this._data,obj)
417
+ }
418
+ terminate(endComment){
419
+ this._remove()
420
+ this._removeSiblings(endComment)
421
+ this._el.remove()
422
+ endComment.remove()
423
+ }
424
+ remove(){
425
+ const comment=this._el
426
+ if (comment._controlComponent) {
427
+
428
+ comment?._componentElement?._unMountFunctions.forEach(unMount =>{
429
+ unMount()
430
+ })
431
+ comment?._componentElement?._deleteEffects()
432
+ // console.log('delete');
433
+
434
+ comment._deleteEffects()
435
+ comment.remove()
436
+ } else {
437
+ comment.remove()
438
+ }
439
+
440
+ }
441
+ removeSiblings(endComment){
442
+ const comment=this._el
443
+ while (comment.nextSibling) {
444
+ if (comment.nextSibling === endComment) {
445
+ return
446
+ } else {
447
+ if (comment.nextSibling.nodeType === 8) {
448
+ comment._remove()
449
+ } else if (comment.nextSibling.nodeType === 1) {
450
+ comment.nextSibling._remove()
451
+ }
452
+ }
453
+ }
454
+ }
455
+ }