@peter.naydenov/cuts 2.1.3 → 2.1.5

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.
Files changed (38) hide show
  1. package/Changelog.md +28 -0
  2. package/README.md +1 -1
  3. package/coverage/lcov-report/index.html +29 -29
  4. package/coverage/lcov-report/src/findInstructions.js.html +27 -27
  5. package/coverage/lcov-report/src/index.html +25 -25
  6. package/coverage/lcov-report/src/main.js.html +129 -51
  7. package/coverage/lcov-report/src/methods/hide.js.html +127 -67
  8. package/coverage/lcov-report/src/methods/index.html +38 -38
  9. package/coverage/lcov-report/src/methods/jump.js.html +27 -12
  10. package/coverage/lcov-report/src/methods/jumpBack.js.html +10 -10
  11. package/coverage/lcov-report/src/methods/jumpsReset.js.html +3 -3
  12. package/coverage/lcov-report/src/methods/listShortcuts.js.html +5 -5
  13. package/coverage/lcov-report/src/methods/setScenes.js.html +16 -16
  14. package/coverage/lcov-report/src/methods/show.js.html +154 -76
  15. package/coverage/lcov-report/src/setInstruction.js.html +23 -11
  16. package/coverage/lcov.info +362 -314
  17. package/dist/cuts.cjs +1 -1
  18. package/dist/cuts.esm.mjs +1 -1
  19. package/dist/cuts.umd.js +1 -1
  20. package/package.json +2 -2
  21. package/src/main.js +28 -9
  22. package/src/methods/hide.js +46 -39
  23. package/src/methods/jump.js +7 -2
  24. package/src/methods/jumpBack.js +2 -2
  25. package/src/methods/jumpsReset.js +1 -1
  26. package/src/methods/setScenes.js +1 -1
  27. package/src/methods/show.js +23 -6
  28. package/src/setInstruction.js +5 -1
  29. package/test/02-cuts.test.js +339 -1
  30. package/types/main.d.ts +42 -6
  31. package/types/main.d.ts.map +1 -1
  32. package/types/methods/hide.d.ts +1 -1
  33. package/types/methods/hide.d.ts.map +1 -1
  34. package/types/methods/jump.d.ts.map +1 -1
  35. package/types/methods/setScenes.d.ts +2 -2
  36. package/types/methods/show.d.ts.map +1 -1
  37. package/types/setInstruction.d.ts.map +1 -1
  38. package/vitest.config.js +1 -1
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">85% </span>
26
+ <span class="strong">88.09% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>34/40</span>
28
+ <span class='fraction'>37/42</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">80% </span>
33
+ <span class="strong">77.77% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>4/5</span>
35
+ <span class='fraction'>7/9</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">53.84% </span>
40
+ <span class="strong">61.53% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>7/13</span>
42
+ <span class='fraction'>8/13</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
47
  <span class="strong">100% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>30/30</span>
49
+ <span class='fraction'>31/31</span>
50
50
  </div>
51
51
 
52
52
 
@@ -238,7 +238,33 @@
238
238
  <a name='L173'></a><a href='#L173'>173</a>
239
239
  <a name='L174'></a><a href='#L174'>174</a>
240
240
  <a name='L175'></a><a href='#L175'>175</a>
241
- <a name='L176'></a><a href='#L176'>176</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
242
268
  <span class="cline-any cline-neutral">&nbsp;</span>
243
269
  <span class="cline-any cline-neutral">&nbsp;</span>
244
270
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -278,15 +304,8 @@
278
304
  <span class="cline-any cline-neutral">&nbsp;</span>
279
305
  <span class="cline-any cline-neutral">&nbsp;</span>
280
306
  <span class="cline-any cline-neutral">&nbsp;</span>
281
- <span class="cline-any cline-yes">14x</span>
282
- <span class="cline-any cline-yes">14x</span>
283
- <span class="cline-any cline-yes">14x</span>
284
- <span class="cline-any cline-yes">4x</span>
285
- <span class="cline-any cline-yes">4x</span>
286
- <span class="cline-any cline-yes">4x</span>
287
307
  <span class="cline-any cline-neutral">&nbsp;</span>
288
308
  <span class="cline-any cline-neutral">&nbsp;</span>
289
- <span class="cline-any cline-yes">14x</span>
290
309
  <span class="cline-any cline-neutral">&nbsp;</span>
291
310
  <span class="cline-any cline-neutral">&nbsp;</span>
292
311
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -294,9 +313,6 @@
294
313
  <span class="cline-any cline-neutral">&nbsp;</span>
295
314
  <span class="cline-any cline-neutral">&nbsp;</span>
296
315
  <span class="cline-any cline-neutral">&nbsp;</span>
297
- <span class="cline-any cline-yes">14x</span>
298
- <span class="cline-any cline-yes">14x</span>
299
- <span class="cline-any cline-yes">14x</span>
300
316
  <span class="cline-any cline-neutral">&nbsp;</span>
301
317
  <span class="cline-any cline-neutral">&nbsp;</span>
302
318
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -307,21 +323,22 @@
307
323
  <span class="cline-any cline-neutral">&nbsp;</span>
308
324
  <span class="cline-any cline-neutral">&nbsp;</span>
309
325
  <span class="cline-any cline-neutral">&nbsp;</span>
310
- <span class="cline-any cline-yes">14x</span>
311
- <span class="cline-any cline-yes">14x</span>
312
- <span class="cline-any cline-yes">14x</span>
313
- <span class="cline-any cline-yes">14x</span>
314
- <span class="cline-any cline-yes">14x</span>
315
- <span class="cline-any cline-yes">14x</span>
316
- <span class="cline-any cline-yes">14x</span>
317
326
  <span class="cline-any cline-neutral">&nbsp;</span>
318
327
  <span class="cline-any cline-neutral">&nbsp;</span>
319
328
  <span class="cline-any cline-neutral">&nbsp;</span>
329
+ <span class="cline-any cline-yes">35x</span>
330
+ <span class="cline-any cline-yes">35x</span>
331
+ <span class="cline-any cline-yes">35x</span>
332
+ <span class="cline-any cline-yes">6x</span>
333
+ <span class="cline-any cline-yes">6x</span>
334
+ <span class="cline-any cline-yes">3x</span>
320
335
  <span class="cline-any cline-neutral">&nbsp;</span>
321
336
  <span class="cline-any cline-neutral">&nbsp;</span>
322
337
  <span class="cline-any cline-neutral">&nbsp;</span>
338
+ <span class="cline-any cline-yes">3x</span>
323
339
  <span class="cline-any cline-neutral">&nbsp;</span>
324
340
  <span class="cline-any cline-neutral">&nbsp;</span>
341
+ <span class="cline-any cline-yes">35x</span>
325
342
  <span class="cline-any cline-neutral">&nbsp;</span>
326
343
  <span class="cline-any cline-neutral">&nbsp;</span>
327
344
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -329,8 +346,43 @@
329
346
  <span class="cline-any cline-neutral">&nbsp;</span>
330
347
  <span class="cline-any cline-neutral">&nbsp;</span>
331
348
  <span class="cline-any cline-neutral">&nbsp;</span>
349
+ <span class="cline-any cline-yes">35x</span>
350
+ <span class="cline-any cline-yes">35x</span>
351
+ <span class="cline-any cline-yes">35x</span>
332
352
  <span class="cline-any cline-neutral">&nbsp;</span>
333
- <span class="cline-any cline-yes">14x</span>
353
+ <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-neutral">&nbsp;</span>
355
+ <span class="cline-any cline-neutral">&nbsp;</span>
356
+ <span class="cline-any cline-neutral">&nbsp;</span>
357
+ <span class="cline-any cline-neutral">&nbsp;</span>
358
+ <span class="cline-any cline-neutral">&nbsp;</span>
359
+ <span class="cline-any cline-neutral">&nbsp;</span>
360
+ <span class="cline-any cline-neutral">&nbsp;</span>
361
+ <span class="cline-any cline-neutral">&nbsp;</span>
362
+ <span class="cline-any cline-yes">35x</span>
363
+ <span class="cline-any cline-yes">35x</span>
364
+ <span class="cline-any cline-yes">35x</span>
365
+ <span class="cline-any cline-yes">35x</span>
366
+ <span class="cline-any cline-yes">35x</span>
367
+ <span class="cline-any cline-yes">35x</span>
368
+ <span class="cline-any cline-yes">35x</span>
369
+ <span class="cline-any cline-neutral">&nbsp;</span>
370
+ <span class="cline-any cline-neutral">&nbsp;</span>
371
+ <span class="cline-any cline-neutral">&nbsp;</span>
372
+ <span class="cline-any cline-neutral">&nbsp;</span>
373
+ <span class="cline-any cline-neutral">&nbsp;</span>
374
+ <span class="cline-any cline-neutral">&nbsp;</span>
375
+ <span class="cline-any cline-neutral">&nbsp;</span>
376
+ <span class="cline-any cline-neutral">&nbsp;</span>
377
+ <span class="cline-any cline-neutral">&nbsp;</span>
378
+ <span class="cline-any cline-neutral">&nbsp;</span>
379
+ <span class="cline-any cline-neutral">&nbsp;</span>
380
+ <span class="cline-any cline-neutral">&nbsp;</span>
381
+ <span class="cline-any cline-neutral">&nbsp;</span>
382
+ <span class="cline-any cline-neutral">&nbsp;</span>
383
+ <span class="cline-any cline-neutral">&nbsp;</span>
384
+ <span class="cline-any cline-neutral">&nbsp;</span>
385
+ <span class="cline-any cline-yes">35x</span>
334
386
  <span class="cline-any cline-yes">2x</span>
335
387
  <span class="cline-any cline-yes">1x</span>
336
388
  <span class="cline-any cline-yes">2x</span>
@@ -342,28 +394,28 @@
342
394
  <span class="cline-any cline-neutral">&nbsp;</span>
343
395
  <span class="cline-any cline-neutral">&nbsp;</span>
344
396
  <span class="cline-any cline-neutral">&nbsp;</span>
345
- <span class="cline-any cline-yes">14x</span>
397
+ <span class="cline-any cline-yes">35x</span>
346
398
  <span class="cline-any cline-neutral">&nbsp;</span>
347
399
  <span class="cline-any cline-neutral">&nbsp;</span>
348
400
  <span class="cline-any cline-neutral">&nbsp;</span>
349
401
  <span class="cline-any cline-neutral">&nbsp;</span>
350
402
  <span class="cline-any cline-neutral">&nbsp;</span>
351
403
  <span class="cline-any cline-neutral">&nbsp;</span>
352
- <span class="cline-any cline-yes">14x</span>
404
+ <span class="cline-any cline-yes">35x</span>
353
405
  <span class="cline-any cline-neutral">&nbsp;</span>
354
406
  <span class="cline-any cline-neutral">&nbsp;</span>
355
407
  <span class="cline-any cline-neutral">&nbsp;</span>
356
408
  <span class="cline-any cline-neutral">&nbsp;</span>
357
409
  <span class="cline-any cline-neutral">&nbsp;</span>
358
410
  <span class="cline-any cline-neutral">&nbsp;</span>
359
- <span class="cline-any cline-yes">14x</span>
411
+ <span class="cline-any cline-yes">35x</span>
360
412
  <span class="cline-any cline-neutral">&nbsp;</span>
361
413
  <span class="cline-any cline-neutral">&nbsp;</span>
362
414
  <span class="cline-any cline-neutral">&nbsp;</span>
363
415
  <span class="cline-any cline-neutral">&nbsp;</span>
364
416
  <span class="cline-any cline-neutral">&nbsp;</span>
365
417
  <span class="cline-any cline-neutral">&nbsp;</span>
366
- <span class="cline-any cline-yes">14x</span>
418
+ <span class="cline-any cline-yes">35x</span>
367
419
  <span class="cline-any cline-neutral">&nbsp;</span>
368
420
  <span class="cline-any cline-neutral">&nbsp;</span>
369
421
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -372,7 +424,7 @@
372
424
  <span class="cline-any cline-neutral">&nbsp;</span>
373
425
  <span class="cline-any cline-neutral">&nbsp;</span>
374
426
  <span class="cline-any cline-neutral">&nbsp;</span>
375
- <span class="cline-any cline-yes">14x</span>
427
+ <span class="cline-any cline-yes">35x</span>
376
428
  <span class="cline-any cline-neutral">&nbsp;</span>
377
429
  <span class="cline-any cline-neutral">&nbsp;</span>
378
430
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -380,17 +432,17 @@
380
432
  <span class="cline-any cline-neutral">&nbsp;</span>
381
433
  <span class="cline-any cline-neutral">&nbsp;</span>
382
434
  <span class="cline-any cline-neutral">&nbsp;</span>
383
- <span class="cline-any cline-yes">14x</span>
435
+ <span class="cline-any cline-yes">35x</span>
384
436
  <span class="cline-any cline-neutral">&nbsp;</span>
385
437
  <span class="cline-any cline-neutral">&nbsp;</span>
386
438
  <span class="cline-any cline-neutral">&nbsp;</span>
387
439
  <span class="cline-any cline-neutral">&nbsp;</span>
388
440
  <span class="cline-any cline-neutral">&nbsp;</span>
389
441
  <span class="cline-any cline-neutral">&nbsp;</span>
442
+ <span class="cline-any cline-yes">41x</span>
390
443
  <span class="cline-any cline-neutral">&nbsp;</span>
391
444
  <span class="cline-any cline-neutral">&nbsp;</span>
392
445
  <span class="cline-any cline-neutral">&nbsp;</span>
393
- <span class="cline-any cline-yes">18x</span>
394
446
  <span class="cline-any cline-neutral">&nbsp;</span>
395
447
  <span class="cline-any cline-neutral">&nbsp;</span>
396
448
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -404,8 +456,8 @@
404
456
  <span class="cline-any cline-neutral">&nbsp;</span>
405
457
  <span class="cline-any cline-neutral">&nbsp;</span>
406
458
  <span class="cline-any cline-neutral">&nbsp;</span>
407
- <span class="cline-any cline-yes">14x</span>
408
- <span class="cline-any cline-yes">14x</span>
459
+ <span class="cline-any cline-yes">35x</span>
460
+ <span class="cline-any cline-yes">35x</span>
409
461
  <span class="cline-any cline-neutral">&nbsp;</span>
410
462
  <span class="cline-any cline-neutral">&nbsp;</span>
411
463
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -451,14 +503,40 @@ import jumpBack from './methods/jumpBack.js'
451
503
  import jumpsReset from './methods/jumpsReset.js'
452
504
  &nbsp;
453
505
  &nbsp;
454
- function main ( cfg= {logLevel:0} ) {
506
+ /**
507
+ * Cuts
508
+ * @param {CutsConfig} [cfg] - configuration object
509
+ */
510
+ &nbsp;
511
+ /**
512
+ * @typedef {Object} CutsConfig
513
+ * @property {0|1} [logLevel=1] - Logging level. `1` emits '@app-error' events; `0` silences them silently.
514
+ */
515
+ &nbsp;
516
+ /**
517
+ * @typedef {'Key'|'Click'|'Form'|'Hover'|'Scroll'} pluginNames
518
+ * @description List of available shortcut plugins.
519
+ */
520
+ &nbsp;
521
+ /**
522
+ * @typedef {Object} CutsState
523
+ * @property {string|null} scene - current scene name
524
+ * @property {Array.&lt;string&gt;|null} parents - current parent scene names
525
+ * @property {boolean} opened - whether the scene manager is opened
526
+ */
527
+ &nbsp;
528
+ function main ( cfg = {} ) {
455
529
  const
456
530
  shortcutMngr = shortcuts ({ errorEventName: '@app-error' })
457
- , logLevel = cfg.logLevel || 1
531
+ , logLevel = ( cfg.logLevel ?? 1 )
458
532
  , log = createLog ({ level:logLevel }, (arg) =&gt; {
459
- const { type } = arg;
460
- <span class="missing-if-branch" title="else path not taken" >E</span>if ( type === 'error' ) {
461
- shortcutMngr.emit ( '@app-error', arg )
533
+ const { type, logLevel:configuredLevel } = arg;
534
+ if ( configuredLevel === 0 ) return // Silent mode: no @app-error events
535
+ <span class="missing-if-branch" title="else path not taken" >E</span>if ( type === 'error' ) {
536
+ // Use the raw emitter (not shortcutMngr.emit) so '@app-error'
537
+ // handlers keep receiving the log entry as their sole argument -
538
+ // shortcutMngr.emit now prepends a { dependencies, type } context object.
539
+ shortcutMngr.getDependencies().emit ( '@app-error', arg )
462
540
  }
463
541
  })
464
542
  , state = {
@@ -557,17 +635,15 @@ function main ( cfg= {logLevel:0} ) {
557
635
  */
558
636
  API.disablePlugin = <span class="fstat-no" title="function not covered" >( </span>pluginName ) =&gt; <span class="cstat-no" title="statement not covered" >shortcutMngr.disablePlugin ( pluginName )</span>
559
637
 
560
- /**
561
- * Get the current state of the application
562
- * @function getState
563
- * @returns {Object} with properties:
564
- * - scene: current scene name
565
- * - parents: current parent scene names
566
- * - opened: boolean indicating if the application is opened
567
- */
638
+ /**
639
+ * Get the current state of the application
640
+ * @function getState
641
+ * @returns {CutsState} current scene, parents, and opened flag
642
+ */
568
643
  API.getState = () =&gt; ({
569
644
  scene : state.currentScene
570
- , parents : state.currentParents
645
+ // Copy - never leak the live array, or callers mutating it corrupt internal state.
646
+ , parents : state.currentParents ? [ ...state.currentParents ] : <span class="branch-1 cbranch-no" title="branch not covered" >state.currentParents</span>
571
647
  , opened : state.opened
572
648
  })
573
649
  &nbsp;
@@ -579,7 +655,9 @@ function main ( cfg= {logLevel:0} ) {
579
655
  * @param {...*} args - Extra data to pass to the listeners
580
656
  * @returns void
581
657
  */
582
- API.emit = <span class="fstat-no" title="function not covered" >( </span>event, ...args ) =&gt; <span class="cstat-no" title="statement not covered" >shortcutMngr.emit ( event, ...args )</span>
658
+ // Use the raw emitter (not shortcutMngr.emit) so listeners keep receiving exactly the
659
+ // args passed here - shortcutMngr.emit prepends a { dependencies, type } context object.
660
+ API.emit = ( event, ...args ) =&gt; shortcutMngr.getDependencies().emit ( event, ...args )
583
661
  return API
584
662
  } // main func.
585
663
  &nbsp;
@@ -595,7 +673,7 @@ export default main
595
673
  <div class='footer quiet pad2 space-top1 center small'>
596
674
  Code coverage generated by
597
675
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
598
- at 2026-04-09T15:47:31.753Z
676
+ at 2026-07-09T15:42:10.120Z
599
677
  </div>
600
678
  <script src="../prettify.js"></script>
601
679
  <script>
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">4% </span>
26
+ <span class="strong">91.42% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>1/25</span>
28
+ <span class='fraction'>32/35</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">0% </span>
33
+ <span class="strong">84.61% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>0/11</span>
35
+ <span class='fraction'>11/13</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">20% </span>
40
+ <span class="strong">80% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>1/5</span>
42
+ <span class='fraction'>4/5</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">4.16% </span>
47
+ <span class="strong">93.93% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>1/24</span>
49
+ <span class='fraction'>31/33</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line low'></div>
64
+ <div class='status-line high'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -116,7 +116,27 @@
116
116
  <a name='L51'></a><a href='#L51'>51</a>
117
117
  <a name='L52'></a><a href='#L52'>52</a>
118
118
  <a name='L53'></a><a href='#L53'>53</a>
119
- <a name='L54'></a><a href='#L54'>54</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral">&nbsp;</span>
120
140
  <span class="cline-any cline-neutral">&nbsp;</span>
121
141
  <span class="cline-any cline-neutral">&nbsp;</span>
122
142
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -127,42 +147,62 @@
127
147
  <span class="cline-any cline-neutral">&nbsp;</span>
128
148
  <span class="cline-any cline-neutral">&nbsp;</span>
129
149
  <span class="cline-any cline-neutral">&nbsp;</span>
130
- <span class="cline-any cline-yes">14x</span>
150
+ <span class="cline-any cline-yes">35x</span>
131
151
  <span class="cline-any cline-neutral">&nbsp;</span>
152
+ <span class="cline-any cline-yes">7x</span>
153
+ <span class="cline-any cline-yes">7x</span>
154
+ <span class="cline-any cline-yes">7x</span>
155
+ <span class="cline-any cline-yes">7x</span>
156
+ <span class="cline-any cline-yes">7x</span>
157
+ <span class="cline-any cline-neutral">&nbsp;</span>
158
+ <span class="cline-any cline-neutral">&nbsp;</span>
159
+ <span class="cline-any cline-yes">7x</span>
160
+ <span class="cline-any cline-yes">1x</span>
161
+ <span class="cline-any cline-yes">1x</span>
162
+ <span class="cline-any cline-yes">1x</span>
163
+ <span class="cline-any cline-yes">1x</span>
132
164
  <span class="cline-any cline-no">&nbsp;</span>
133
- <span class="cline-any cline-no">&nbsp;</span>
134
- <span class="cline-any cline-no">&nbsp;</span>
135
- <span class="cline-any cline-no">&nbsp;</span>
165
+ <span class="cline-any cline-neutral">&nbsp;</span>
166
+ <span class="cline-any cline-neutral">&nbsp;</span>
136
167
  <span class="cline-any cline-no">&nbsp;</span>
137
168
  <span class="cline-any cline-neutral">&nbsp;</span>
138
169
  <span class="cline-any cline-neutral">&nbsp;</span>
170
+ <span class="cline-any cline-yes">6x</span>
139
171
  <span class="cline-any cline-neutral">&nbsp;</span>
140
- <span class="cline-any cline-no">&nbsp;</span>
141
- <span class="cline-any cline-no">&nbsp;</span>
172
+ <span class="cline-any cline-yes">7x</span>
173
+ <span class="cline-any cline-yes">7x</span>
142
174
  <span class="cline-any cline-neutral">&nbsp;</span>
143
- <span class="cline-any cline-no">&nbsp;</span>
175
+ <span class="cline-any cline-yes">1x</span>
176
+ <span class="cline-any cline-yes">1x</span>
144
177
  <span class="cline-any cline-neutral">&nbsp;</span>
145
- <span class="cline-any cline-no">&nbsp;</span>
146
- <span class="cline-any cline-no">&nbsp;</span>
147
- <span class="cline-any cline-no">&nbsp;</span>
148
- <span class="cline-any cline-no">&nbsp;</span>
149
- <span class="cline-any cline-no">&nbsp;</span>
150
178
  <span class="cline-any cline-neutral">&nbsp;</span>
151
179
  <span class="cline-any cline-neutral">&nbsp;</span>
152
- <span class="cline-any cline-no">&nbsp;</span>
153
- <span class="cline-any cline-no">&nbsp;</span>
154
- <span class="cline-any cline-no">&nbsp;</span>
155
- <span class="cline-any cline-no">&nbsp;</span>
156
- <span class="cline-any cline-no">&nbsp;</span>
180
+ <span class="cline-any cline-yes">6x</span>
157
181
  <span class="cline-any cline-neutral">&nbsp;</span>
158
182
  <span class="cline-any cline-neutral">&nbsp;</span>
159
- <span class="cline-any cline-no">&nbsp;</span>
160
- <span class="cline-any cline-no">&nbsp;</span>
161
- <span class="cline-any cline-no">&nbsp;</span>
162
- <span class="cline-any cline-no">&nbsp;</span>
163
183
  <span class="cline-any cline-neutral">&nbsp;</span>
164
- <span class="cline-any cline-no">&nbsp;</span>
184
+ <span class="cline-any cline-yes">6x</span>
185
+ <span class="cline-any cline-neutral">&nbsp;</span>
186
+ <span class="cline-any cline-neutral">&nbsp;</span>
187
+ <span class="cline-any cline-yes">6x</span>
188
+ <span class="cline-any cline-yes">6x</span>
189
+ <span class="cline-any cline-neutral">&nbsp;</span>
190
+ <span class="cline-any cline-yes">6x</span>
191
+ <span class="cline-any cline-yes">7x</span>
192
+ <span class="cline-any cline-yes">3x</span>
193
+ <span class="cline-any cline-yes">3x</span>
194
+ <span class="cline-any cline-neutral">&nbsp;</span>
195
+ <span class="cline-any cline-neutral">&nbsp;</span>
196
+ <span class="cline-any cline-yes">6x</span>
197
+ <span class="cline-any cline-yes">7x</span>
198
+ <span class="cline-any cline-neutral">&nbsp;</span>
199
+ <span class="cline-any cline-yes">7x</span>
200
+ <span class="cline-any cline-yes">7x</span>
201
+ <span class="cline-any cline-yes">6x</span>
202
+ <span class="cline-any cline-yes">6x</span>
203
+ <span class="cline-any cline-neutral">&nbsp;</span>
165
204
  <span class="cline-any cline-neutral">&nbsp;</span>
205
+ <span class="cline-any cline-yes">7x</span>
166
206
  <span class="cline-any cline-neutral">&nbsp;</span>
167
207
  <span class="cline-any cline-neutral">&nbsp;</span>
168
208
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -177,51 +217,71 @@ function hide ( dependencies, state ) {
177
217
  /**
178
218
  * @function hide
179
219
  * @description Hide the current scene and returns to the parent one
180
- * @param {number|string} endSteps - number of steps to end or '*' to end all scenes to the root
181
- * @returns {Promise} - promise that resolves when the process 'end' is completed
220
+ * @param {number|string} [endSteps=1] - number of steps to end; omit or `1` for current scene only; `'*'` to end all scenes to root
221
+ * @returns {Promise&lt;void&gt;} - promise that resolves when the process 'end' is completed
182
222
  */
183
- return function <span class="fstat-no" title="function not covered" >hide </span>( endSteps=<span class="branch-0 cbranch-no" title="branch not covered" >1 </span>) {
223
+ return function hide ( endSteps=1 ) {
184
224
  const
185
- { askForPromise, shortcutMngr, setInstruction } = <span class="cstat-no" title="statement not covered" >dependencies</span>
186
- , { currentScene, currentParents, scenes } = <span class="cstat-no" title="statement not covered" >state</span>
187
- , hideTask = <span class="cstat-no" title="statement not covered" >askForPromise ()</span>
188
- , instructions = <span class="cstat-no" title="statement not covered" >[]</span>
189
- , hasParents = <span class="cstat-no" title="statement not covered" >currentParents.length &gt; 0</span>
225
+ { askForPromise, shortcutMngr, setInstruction } = dependencies
226
+ , { currentScene, scenes } = state
227
+ , hideTask = askForPromise ()
228
+ , unloadTask = askForPromise ()
229
+ , hasBeforeHide = typeof scenes[currentScene].beforeHide === 'function'
190
230
  ;
191
- let el;
192
-
193
- <span class="cstat-no" title="statement not covered" > shortcutMngr.pause () </span> // Stop all shortcuts
194
- <span class="cstat-no" title="statement not covered" > instructions.push ( setInstruction ( scenes[currentScene].hide )) </span> // Set instruction to hide current scene
195
231
  &nbsp;
196
- <span class="cstat-no" title="statement not covered" > if ( !hasParents ) <span class="cstat-no" title="statement not covered" >state.currentScene = null</span></span>
197
-
198
- <span class="cstat-no" title="statement not covered" > if ( hasParents &amp;&amp; endSteps === '*' ) {</span>
199
- <span class="cstat-no" title="statement not covered" > [...currentParents].reverse().forEach ( <span class="fstat-no" title="function not covered" >name </span>=&gt; {</span>
200
- <span class="cstat-no" title="statement not covered" > el = state.currentParents.at ( -1 )</span>
201
- <span class="cstat-no" title="statement not covered" > state.currentScene = el</span>
202
- <span class="cstat-no" title="statement not covered" > instructions.push ( setInstruction ( scenes[name].hide)) </span>
203
- })
204
- }
205
- <span class="cstat-no" title="statement not covered" > if ( hasParents &amp;&amp; ![ '*', 1].includes(endSteps) ) {</span>
206
- <span class="cstat-no" title="statement not covered" > currentParents.slice ( `-${endSteps-1}` ).reverse().map ( <span class="fstat-no" title="function not covered" >name </span>=&gt; {</span>
207
- <span class="cstat-no" title="statement not covered" > el = state.currentParents.at ( -1 )</span>
208
- <span class="cstat-no" title="statement not covered" > state.currentScene = el</span>
209
- <span class="cstat-no" title="statement not covered" > instructions.push ( setInstruction (scenes[name].hide))</span>
210
- })
232
+ if ( hasBeforeHide ) { // Execute 'beforeHide' function if exists - same guard 'show' honors when navigating away
233
+ const closingFn = scenes[currentScene].beforeHide;
234
+ try {
235
+ const result = closingFn ({ done:unloadTask.done, dependencies: shortcutMngr.getDependencies() });
236
+ <span class="missing-if-branch" title="if path not taken" >I</span>if ( result != null &amp;&amp; <span class="branch-1 cbranch-no" title="branch not covered" >typeof result.then === 'function' </span>) {
237
+ <span class="cstat-no" title="statement not covered" > result.then ( unloadTask.done ).catch ( <span class="fstat-no" title="function not covered" >()</span> =&gt; <span class="cstat-no" title="statement not covered" >unloadTask.done ( false ) </span>);</span>
238
+ }
239
+ } catch ( err ) {
240
+ <span class="cstat-no" title="statement not covered" > unloadTask.done ( false );</span>
241
+ }
211
242
  }
212
- <span class="cstat-no" title="statement not covered" > endSteps = askForPromise.sequence ( instructions )</span>
213
- <span class="cstat-no" title="statement not covered" > endSteps.onComplete ( <span class="fstat-no" title="function not covered" >()</span> =&gt; {</span>
214
- <span class="cstat-no" title="statement not covered" > shortcutMngr.changeContext ( state.currentScene ) </span> // If state.currentScene is null, then all shortcuts are switched off and currentContext is null
215
- <span class="cstat-no" title="statement not covered" > hideTask.done () </span>
216
- })
217
- <span class="cstat-no" title="statement not covered" > return hideTask.promise</span>
243
+ else unloadTask.done ( true )
244
+ &nbsp;
245
+ unloadTask.onComplete ( continueHiding =&gt; {
246
+ if ( !continueHiding ) {
247
+ // 'beforeHide' returned false - cancel, nothing was torn down or changed
248
+ hideTask.done ()
249
+ return hideTask.promise
250
+ }
251
+ &nbsp;
252
+ const
253
+ instructions = []
254
+ // Work on a copy of the recorded ancestor chain - it's the source of truth for what to
255
+ // climb back to, including for wildcard-overlay scenes ('*' itself is never stored here,
256
+ // only the real scene name that was current when the overlay was shown).
257
+ , remaining = [ ...state.currentParents ]
258
+ ;
259
+ &nbsp;
260
+ shortcutMngr.pause () // Stop all shortcuts
261
+ instructions.push ( setInstruction ( scenes[currentScene].hide )) // Hiding the current scene is always at least 1 step
262
+ &nbsp;
263
+ const ancestorsToHide = ( endSteps === '*' ) ? remaining.length : Math.min ( endSteps - 1, remaining.length )
264
+ for ( let i = 0; i &lt; ancestorsToHide; i++ ) {
265
+ const name = remaining.pop ()
266
+ instructions.push ( setInstruction ( scenes[name].hide ))
267
+ }
268
+ &nbsp;
269
+ state.currentScene = remaining.length &gt; 0 ? remaining.pop () : null
270
+ state.currentParents = remaining
271
+ &nbsp;
272
+ const goingTask = askForPromise.sequence ( instructions );
273
+ goingTask.onComplete ( () =&gt; {
274
+ shortcutMngr.changeContext ( state.currentScene ) // If state.currentScene is null, then all shortcuts are switched off and currentContext is null
275
+ hideTask.done ()
276
+ })
277
+ }) // unloadTask onComplete
278
+ return hideTask.promise
218
279
  }} // hide func.
219
280
  &nbsp;
220
281
  &nbsp;
221
282
  &nbsp;
222
283
  export default hide
223
284
  &nbsp;
224
- &nbsp;
225
285
  &nbsp;</pre></td></tr></table></pre>
226
286
 
227
287
  <div class='push'></div><!-- for sticky footer -->
@@ -229,7 +289,7 @@ export default hide
229
289
  <div class='footer quiet pad2 space-top1 center small'>
230
290
  Code coverage generated by
231
291
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
232
- at 2026-04-09T15:47:31.753Z
292
+ at 2026-07-09T15:42:10.120Z
233
293
  </div>
234
294
  <script src="../../prettify.js"></script>
235
295
  <script>