pawajs 1.4.10 → 1.4.11

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/CHANGELOG.md CHANGED
@@ -2,4 +2,5 @@ CHANGELOG.md
2
2
  + version 1.3.0 - v1.4.0 on experiment
3
3
  + version 1.4.0 for-key bug fixing
4
4
  + version 1.4.4 added onSuspense and fix out- (document event)
5
- + version 1.4.7 solving resuming issue when wrapping with template
5
+ + version 1.4.7 - 1.4.10 solving resuming issue when wrapping with template
6
+ + version 1.4.11 - added more event modifiers
package/index.js CHANGED
@@ -261,7 +261,7 @@ export const PluginSystem = (...func) => {
261
261
  if (attrPlugins?.fullName) {
262
262
  if (pawaAttributes.has(attrPlugins.fullName)) {
263
263
  console.warn(`attribute plugin already exist ${attrPlugins.fullName}`)
264
- return
264
+ // return
265
265
  }
266
266
 
267
267
  applyMode(attrPlugins?.mode, () => {
@@ -273,7 +273,7 @@ export const PluginSystem = (...func) => {
273
273
  } else if (attrPlugins?.startsWith) {
274
274
  if (pawaAttributes.has(attrPlugins.startsWith)) {
275
275
  console.warn(`attribute plugin already exist ${attrPlugins.startsWith}`)
276
- return
276
+ // return
277
277
  }
278
278
  applyMode(attrPlugins?.mode, () => {
279
279
  pawaAttributes.add(attrPlugins.startsWith)
@@ -284,8 +284,6 @@ export const PluginSystem = (...func) => {
284
284
  }
285
285
  })
286
286
 
287
-
288
-
289
287
  }
290
288
  if (getPlugin?.component) {
291
289
  if (getPlugin.component?.beforeCall && typeof getPlugin.component?.beforeCall === 'function') {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "pawajs",
3
- "version": "1.4.10",
3
+ "version": "1.4.11",
4
4
  "type":"module",
5
- "description": "pawajs library (html runtime) for easily building web ui, enhancing html element, micro frontend etc ",
5
+ "description": "pawajs library (reactive web runtime) for easily building web ui, enhancing html element, micro frontend etc ",
6
6
  "main": "index.js",
7
7
  "scripts": {
8
8
  "test": "echo \"Error: no test specified\" && exit 1"
package/power.js CHANGED
@@ -138,8 +138,11 @@ export const event = (el, attr, stateContext) => {
138
138
  if (el._running || checkKeywordsExistence(el._staticContext,attr.value)) {
139
139
  return
140
140
  }
141
- const splitName = attr.name.split('-')
142
- const eventType = splitName[1]
141
+ const directive = attr.name.substring(3); // from 'on-click.prevent' to 'click.prevent'
142
+ const parts = directive.split('.');
143
+ const eventType = parts[0];
144
+ const modifiers = new Set(parts.slice(1));
145
+
143
146
  el.removeAttribute(attr.name)
144
147
  const context = el._context
145
148
  const keys = Object.keys(context);
@@ -155,7 +158,64 @@ export const event = (el, attr, stateContext) => {
155
158
  __pawaDev.setError({el:e.target,msg:error.message,stack:error.stack,directives:'on-event'})
156
159
  }
157
160
  `)
158
- el.addEventListener(eventType, (e) => {
161
+
162
+ const handler = (e) => {
163
+ // Early return modifiers
164
+ if (modifiers.has('self') && e.target !== el) return;
165
+ if (modifiers.has('left') && 'button' in e && e.button !== 0) return;
166
+ if (modifiers.has('middle') && 'button' in e && e.button !== 1) return;
167
+ if (modifiers.has('right') && 'button' in e && e.button !== 2) return;
168
+ if (modifiers.has('ctrl') && !e.ctrlKey) return;
169
+ if (modifiers.has('alt') && !e.altKey) return;
170
+ if (modifiers.has('shift') && !e.shiftKey) return;
171
+ if (modifiers.has('meta') && !e.metaKey) return;
172
+ if (modifiers.has('exact')) {
173
+ if (e.ctrlKey && !modifiers.has('ctrl')) return;
174
+ if (e.altKey && !modifiers.has('alt')) return;
175
+ if (e.shiftKey && !modifiers.has('shift')) return;
176
+ if (e.metaKey && !modifiers.has('meta')) return;
177
+ }
178
+
179
+ // Key modifiers
180
+ if (eventType.startsWith('key')) {
181
+ const keyAlias = {
182
+ 'enter': 'Enter',
183
+ 'tab': 'Tab',
184
+ 'delete': ['Backspace', 'Delete'],
185
+ 'esc': 'Escape',
186
+ 'space': ' ',
187
+ 'up': 'ArrowUp',
188
+ 'down': 'ArrowDown',
189
+ 'left': 'ArrowLeft',
190
+ 'right': 'ArrowRight'
191
+ };
192
+
193
+ let shouldRun = false;
194
+ let hasKeyModifier = false;
195
+ for (const mod of modifiers) {
196
+ if (keyAlias[mod]) {
197
+ hasKeyModifier = true;
198
+ const expectedKey = keyAlias[mod];
199
+ if (Array.isArray(expectedKey)) {
200
+ if (expectedKey.includes(e.key)) {
201
+ shouldRun = true;
202
+ break;
203
+ }
204
+ } else if (e.key === expectedKey) {
205
+ shouldRun = true;
206
+ break;
207
+ }
208
+ }
209
+ }
210
+ if (hasKeyModifier && !shouldRun) {
211
+ return;
212
+ }
213
+ }
214
+
215
+ // Action modifiers
216
+ if (modifiers.has('prevent')) e.preventDefault();
217
+ if (modifiers.has('stop')) e.stopPropagation();
218
+
159
219
  try {
160
220
  func(e, ...values)
161
221
  } catch (error) {
@@ -165,8 +225,15 @@ export const event = (el, attr, stateContext) => {
165
225
  template: el._template
166
226
  })
167
227
  }
168
- })
228
+ };
169
229
 
230
+ const options = {
231
+ capture: modifiers.has('capture'),
232
+ once: modifiers.has('once'),
233
+ passive: modifiers.has('passive')
234
+ };
235
+
236
+ el.addEventListener(eventType, handler, options)
170
237
  }
171
238
 
172
239
  export const mountElement = (el, attr) => {
@@ -335,10 +402,14 @@ export const documentEvent = (el, attr) => {
335
402
  if (el._running || checkKeywordsExistence(el._staticContext,attr.value)) {
336
403
  return
337
404
  }
338
- if (attr.name.split('-')[2]) {
339
- return
340
- }
341
- const eventName = attr.name.split('-')[1]
405
+ const directive = attr.name.substring(4); // from 'out-click.prevent' to 'click.prevent'
406
+ const parts = directive.split('.');
407
+ const eventType = parts[0];
408
+ const modifiers = new Set(parts.slice(1));
409
+
410
+ if (!eventType) return;
411
+
412
+ el.removeAttribute(attr.name)
342
413
  const keys = Object.keys(el._context);
343
414
  const resolvePath = (path, obj) => {
344
415
  return path.split('.').reduce((acc, key) => acc?.[key], obj);
@@ -348,27 +419,85 @@ export const documentEvent = (el, attr) => {
348
419
  ${attr.value}
349
420
  }catch(error){
350
421
  console.error(error.message,error.stack)
351
- __pawaDev({msg:error.message,stack:error.stack,directives:'out-event'})
422
+ __pawaDev.setError({msg:error.message,stack:error.stack,directives:'out-event'})
352
423
  }`)
353
424
  const values = keys.map((key) => resolvePath(key, el._context));
354
- const functions = (e) => {
425
+ const handler = (e) => {
426
+ // Modifier checks
427
+ if (modifiers.has('left') && 'button' in e && e.button !== 0) return;
428
+ if (modifiers.has('middle') && 'button' in e && e.button !== 1) return;
429
+ if (modifiers.has('right') && 'button' in e && e.button !== 2) return;
430
+ if (modifiers.has('ctrl') && !e.ctrlKey) return;
431
+ if (modifiers.has('alt') && !e.altKey) return;
432
+ if (modifiers.has('shift') && !e.shiftKey) return;
433
+ if (modifiers.has('meta') && !e.metaKey) return;
434
+ if (modifiers.has('exact')) {
435
+ if (e.ctrlKey && !modifiers.has('ctrl')) return;
436
+ if (e.altKey && !modifiers.has('alt')) return;
437
+ if (e.shiftKey && !modifiers.has('shift')) return;
438
+ if (e.metaKey && !modifiers.has('meta')) return;
439
+ }
440
+
441
+ // Key modifiers
442
+ if (eventType.startsWith('key')) {
443
+ const keyAlias = {
444
+ 'enter': 'Enter',
445
+ 'tab': 'Tab',
446
+ 'delete': ['Backspace', 'Delete'],
447
+ 'esc': 'Escape',
448
+ 'space': ' ',
449
+ 'up': 'ArrowUp',
450
+ 'down': 'ArrowDown',
451
+ 'left': 'ArrowLeft',
452
+ 'right': 'ArrowRight'
453
+ };
454
+
455
+ let shouldRun = false;
456
+ let hasKeyModifier = false;
457
+ for (const mod of modifiers) {
458
+ if (keyAlias[mod]) {
459
+ hasKeyModifier = true;
460
+ const expectedKey = keyAlias[mod];
461
+ if (Array.isArray(expectedKey)) {
462
+ if (expectedKey.includes(e.key)) {
463
+ shouldRun = true;
464
+ break;
465
+ }
466
+ } else if (e.key === expectedKey) {
467
+ shouldRun = true;
468
+ break;
469
+ }
470
+ }
471
+ }
472
+ if (hasKeyModifier && !shouldRun) {
473
+ return;
474
+ }
475
+ }
476
+
477
+ // Action modifiers
478
+ if (modifiers.has('prevent')) e.preventDefault();
479
+ if (modifiers.has('stop')) e.stopPropagation();
480
+
355
481
  try {
356
482
  const $element=el
357
483
  func(e,$element, ...values)
358
484
  } catch (error) {
359
485
  setPawaDevError({
360
- message: `Error from out-${eventName} directive ${error.message}`,
486
+ message: `Error from out-${eventType} directive ${error.message}`,
361
487
  error: error,
362
488
  template: el._template
363
489
  })
364
490
  }
365
491
  }
366
- el.removeAttribute(attr.name)
367
- el._MountFunctions.push( ()=> {
368
- document.addEventListener(eventName, functions)
369
- })
370
492
 
371
- const unMount = () => document.removeEventListener(eventName, functions);
493
+ const options = {
494
+ capture: modifiers.has('capture'),
495
+ once: modifiers.has('once'),
496
+ passive: modifiers.has('passive')
497
+ };
498
+ const target = modifiers.has('window') ? window : document;
499
+ el._MountFunctions.push(() => target.addEventListener(eventType, handler, options))
500
+ const unMount = () => target.removeEventListener(eventType, handler, options);
372
501
  el._setUnMount(unMount)
373
502
 
374
503
  }