sprae 5.2.0 → 6.0.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/examples/todomvc.html +14 -15
- package/package.json +2 -2
- package/r&d.md +58 -17
- package/readme.md +77 -87
- package/sprae.auto.js +31 -70
- package/sprae.auto.min.js +1 -1
- package/sprae.js +31 -70
- package/sprae.min.js +1 -1
- package/src/core.js +16 -11
- package/src/directives.js +32 -65
- package/test/{dom.js → attrs.js} +9 -325
- package/test/events.js +138 -0
- package/test/test.js +12 -1
- package/todo.md +2 -1
package/test/{dom.js → attrs.js}
RENAMED
|
@@ -6,16 +6,6 @@ import sprae from '../src/index.js'
|
|
|
6
6
|
import h from 'hyperf'
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
Object.defineProperty(DocumentFragment.prototype, 'outerHTML', {
|
|
10
|
-
get() {
|
|
11
|
-
let s = ''
|
|
12
|
-
this.childNodes.forEach(n => {
|
|
13
|
-
s += n.nodeType === 3 ? n.textContent : n.outerHTML != null ? n.outerHTML : ''
|
|
14
|
-
})
|
|
15
|
-
return s
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
9
|
test.skip('autoinit', async () => {
|
|
20
10
|
is(window.x.innerHTML, '1')
|
|
21
11
|
})
|
|
@@ -447,10 +437,10 @@ test('each: loop within condition', async () => {
|
|
|
447
437
|
|
|
448
438
|
const params = sprae(el, { a: 1 })
|
|
449
439
|
|
|
450
|
-
is(el.innerHTML, '<x><y>
|
|
440
|
+
is(el.innerHTML, '<x><y>0</y></x>')
|
|
451
441
|
params.a = 2
|
|
452
442
|
await tick()
|
|
453
|
-
is(el.innerHTML, '<x><y
|
|
443
|
+
is(el.innerHTML, '<x><y>0</y><y>-1</y></x>')
|
|
454
444
|
params.a = 0
|
|
455
445
|
await tick()
|
|
456
446
|
is(el.innerHTML, '')
|
|
@@ -481,7 +471,7 @@ test('each: next items have own "this", not single one', async () => {
|
|
|
481
471
|
let el = h`<div><x :each="x in 3" :data-x="x" :x="log.push(x, this.dataset.x)"></x></div>`
|
|
482
472
|
let log = []
|
|
483
473
|
let state = sprae(el, {log})
|
|
484
|
-
is(state.log, [1,'1',2,'2'
|
|
474
|
+
is(state.log, [0,'0',1,'1',2,'2'])
|
|
485
475
|
})
|
|
486
476
|
|
|
487
477
|
test('each: unkeyed', async () => {
|
|
@@ -520,7 +510,7 @@ test('each: keyed', async () => {
|
|
|
520
510
|
test('each: wrapped source', async () => {
|
|
521
511
|
let el = h`<div><x :each="i in (x || 2)" :text="i"></x></div>`
|
|
522
512
|
sprae(el, {x:0})
|
|
523
|
-
is(el.innerHTML, `<x>
|
|
513
|
+
is(el.innerHTML, `<x>0</x><x>1</x>`)
|
|
524
514
|
})
|
|
525
515
|
|
|
526
516
|
test('each: unmounted elements remove listeners', async () => {
|
|
@@ -564,316 +554,10 @@ test('each: key-based caching is in-sync with direct elements', () => {
|
|
|
564
554
|
is(el.outerHTML, el2.outerHTML)
|
|
565
555
|
})
|
|
566
556
|
|
|
567
|
-
test('
|
|
568
|
-
let el = h`<
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
is(el.outerHTML, `<div></div>`);
|
|
573
|
-
el.dispatchEvent(new window.Event('click'));
|
|
574
|
-
is(log, ['click'])
|
|
575
|
-
el.dispatchEvent(new window.Event('x'));
|
|
576
|
-
is(log, ['click','x'])
|
|
577
|
-
|
|
578
|
-
params.x = function(){log.push('xx')}
|
|
579
|
-
await tick()
|
|
580
|
-
el.dispatchEvent(new window.Event('x'));
|
|
581
|
-
is(log, ['click','x','xx']);
|
|
582
|
-
|
|
583
|
-
console.log('make null')
|
|
584
|
-
params.x = null;
|
|
585
|
-
await tick()
|
|
586
|
-
el.dispatchEvent(new window.Event('x'));
|
|
587
|
-
is(log, ['click','x','xx']);
|
|
588
|
-
})
|
|
589
|
-
|
|
590
|
-
test('onevt: this context', e => {
|
|
591
|
-
let el = h`<div :onx="function(){log.push(this)}"></div>`
|
|
592
|
-
let state = sprae(el, {log: []})
|
|
593
|
-
el.dispatchEvent(new window.Event('x'));
|
|
594
|
-
is(state.log, [el])
|
|
595
|
-
})
|
|
596
|
-
|
|
597
|
-
test('on: this in chains refers to el', () => {
|
|
598
|
-
let el = h`<div :ona..onb="function(e){x=this; log.push(1); return () => log.push(2)}"></div>`
|
|
599
|
-
let state = sprae(el, {log:[], x:null})
|
|
600
|
-
el.dispatchEvent(new window.Event('a'));
|
|
601
|
-
is(state.log, [1])
|
|
602
|
-
})
|
|
603
|
-
|
|
604
|
-
test('on: multiple events', e => {
|
|
605
|
-
let el = h`<div :onscroll:onclick:onx="e=>log.push(e.type)"></div>`
|
|
606
|
-
let state = sprae(el, {log:[]})
|
|
607
|
-
|
|
608
|
-
el.dispatchEvent(new window.Event('click'));
|
|
609
|
-
is(state.log, ['click'])
|
|
610
|
-
el.dispatchEvent(new window.Event('scroll'));
|
|
611
|
-
is(state.log, ['click','scroll'])
|
|
612
|
-
el.dispatchEvent(new window.Event('x'));
|
|
613
|
-
is(state.log, ['click','scroll','x'])
|
|
614
|
-
})
|
|
615
|
-
|
|
616
|
-
test('on: in-out events', e => {
|
|
617
|
-
// let el = document.createElement('x');
|
|
618
|
-
// el.setAttribute(':onmousedown..onmouseup', 'e=>(log.push(e.type),e=>log.push(e.type))')
|
|
619
|
-
let el = h`<x :onmousedown..onmouseup="(e) => { x=this; log.push(e.type); return e=>log.push(e.type); }"></x>`
|
|
620
|
-
|
|
621
|
-
let state = sprae(el, {log:[],x:null})
|
|
622
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
623
|
-
is(state.x, el);
|
|
624
|
-
is(state.log, ['mousedown'])
|
|
625
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
626
|
-
is(state.log, ['mousedown','mouseup'])
|
|
627
|
-
})
|
|
628
|
-
|
|
629
|
-
test('on: in-out side-effects', e => {
|
|
630
|
-
let log = []
|
|
631
|
-
|
|
632
|
-
// 1. skip in event and do directly out
|
|
633
|
-
let el = h`<x :onin..onout="io"></x>`
|
|
634
|
-
sprae(el, { io(e) {
|
|
635
|
-
log.push(e.type)
|
|
636
|
-
return (e) => (log.push(e.type), [1,2,3])
|
|
637
|
-
} })
|
|
638
|
-
|
|
639
|
-
el.dispatchEvent(new window.Event('out'));
|
|
640
|
-
is(log, [])
|
|
641
|
-
|
|
642
|
-
// 2. Some nonsensical return is fine
|
|
643
|
-
el.dispatchEvent(new window.Event('in'));
|
|
644
|
-
is(log, ['in'])
|
|
645
|
-
el.dispatchEvent(new window.Event('out'));
|
|
646
|
-
is(log, ['in','out'], 'out triggers right')
|
|
647
|
-
el.dispatchEvent(new window.Event('out'));
|
|
648
|
-
is(log, ['in','out'])
|
|
649
|
-
el.dispatchEvent(new window.Event('in'));
|
|
650
|
-
is(log, ['in','out','in'])
|
|
651
|
-
el.dispatchEvent(new window.Event('in'));
|
|
652
|
-
is(log, ['in','out','in', 'in'])
|
|
653
|
-
el.dispatchEvent(new window.Event('out'));
|
|
654
|
-
is(log, ['in','out','in','in','out','out'])
|
|
655
|
-
el.dispatchEvent(new window.Event('out'));
|
|
656
|
-
is(log, ['in','out','in','in','out','out'])
|
|
657
|
-
})
|
|
658
|
-
|
|
659
|
-
test('on: chain of events', e => {
|
|
660
|
-
let el = h`<div :onmousedown..onmousemove..onmouseup="e=>(log.push(e.type),e=>(log.push(e.type),e=>log.push(e.type)))"></div>`
|
|
661
|
-
let state = sprae(el, {log:[]})
|
|
662
|
-
|
|
663
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
664
|
-
is(state.log, ['mousedown'])
|
|
665
|
-
el.dispatchEvent(new window.Event('mousemove'));
|
|
666
|
-
is(state.log, ['mousedown','mousemove'])
|
|
667
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
668
|
-
is(state.log, ['mousedown','mousemove','mouseup'])
|
|
669
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
670
|
-
is(state.log, ['mousedown','mousemove','mouseup'])
|
|
671
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
672
|
-
is(state.log, ['mousedown','mousemove','mouseup','mousedown'])
|
|
673
|
-
})
|
|
674
|
-
|
|
675
|
-
test('on: parallel chains', e => {
|
|
676
|
-
let el = h`<div :onx..ony..onz="e=>('x',log.push(e.type),e=>('y',log.push(e.type),e=>('z',log.push(e.type))))"></div>`
|
|
677
|
-
let state = sprae(el, {log:[]})
|
|
678
|
-
|
|
679
|
-
console.log('emit x')
|
|
680
|
-
el.dispatchEvent(new window.Event('x'));
|
|
681
|
-
is(state.log, ['x'])
|
|
682
|
-
console.log('emit x')
|
|
683
|
-
el.dispatchEvent(new window.Event('x'));
|
|
684
|
-
is(state.log, ['x','x'])
|
|
685
|
-
console.log('emit y')
|
|
686
|
-
el.dispatchEvent(new window.Event('y'));
|
|
687
|
-
is(state.log, ['x','x','y','y'])
|
|
688
|
-
console.log('emit y')
|
|
689
|
-
el.dispatchEvent(new window.Event('y'));
|
|
690
|
-
is(state.log, ['x','x','y','y'])
|
|
691
|
-
console.log('emit z')
|
|
692
|
-
el.dispatchEvent(new window.Event('z'));
|
|
693
|
-
console.log('emit y')
|
|
694
|
-
el.dispatchEvent(new window.Event('y'));
|
|
695
|
-
is(state.log, ['x','x','y','y','z','z'])
|
|
696
|
-
el.dispatchEvent(new window.Event('z'));
|
|
697
|
-
is(state.log, ['x','x','y','y','z','z']);
|
|
698
|
-
el.dispatchEvent(new window.Event('x'));
|
|
699
|
-
is(state.log, ['x','x','y','y','z','z','x']);
|
|
700
|
-
})
|
|
701
|
-
|
|
702
|
-
test('on: state changes between chain of events', async e => {
|
|
703
|
-
let el = h`<x :on="{'x..y':fn}"></x>`
|
|
704
|
-
let log = []
|
|
705
|
-
let state = sprae(el, {log, fn: () => (log.push('x1'), ()=>log.push('y1'))})
|
|
706
|
-
console.log('emit x')
|
|
707
|
-
el.dispatchEvent(new window.Event('x'));
|
|
708
|
-
is(log, ['x1'])
|
|
709
|
-
console.log('update fn')
|
|
710
|
-
state.fn = () => (log.push('x2'), () => log.push('y2'))
|
|
711
|
-
await tick()
|
|
712
|
-
is(log, ['x1'])
|
|
713
|
-
// console.log('xx')
|
|
714
|
-
// NOTE: state update registers new chain listener before finishing prev chain
|
|
715
|
-
// el.dispatchEvent(new window.Event('x'));
|
|
716
|
-
// el.dispatchEvent(new window.Event('x'));
|
|
717
|
-
// is(log, [1])
|
|
718
|
-
console.log('emit y, y')
|
|
719
|
-
el.dispatchEvent(new window.Event('y'));
|
|
720
|
-
el.dispatchEvent(new window.Event('y'));
|
|
721
|
-
is(log, ['x1', 'y1'])
|
|
722
|
-
console.log('emit x')
|
|
723
|
-
el.dispatchEvent(new window.Event('x'));
|
|
724
|
-
is(log, ['x1','y1','x2'])
|
|
725
|
-
console.log('emit y, y')
|
|
726
|
-
el.dispatchEvent(new window.Event('y'));
|
|
727
|
-
el.dispatchEvent(new window.Event('y'));
|
|
728
|
-
is(log, ['x1','y1','x2','y2'])
|
|
729
|
-
})
|
|
730
|
-
|
|
731
|
-
test('on: once', e => {
|
|
732
|
-
// NOTE: if callback updates it's still rebound
|
|
733
|
-
let el = h`<x :onx.once="(e=>x&&log.push(this))" ></x>`
|
|
734
|
-
let log = []
|
|
735
|
-
let state = sprae(el, {log, x:1})
|
|
736
|
-
el.dispatchEvent(new window.Event('x'));
|
|
737
|
-
is(log, [el])
|
|
738
|
-
el.dispatchEvent(new window.Event('x'));
|
|
739
|
-
is(log, [el])
|
|
740
|
-
state.x = 2
|
|
741
|
-
el.dispatchEvent(new window.Event('x'));
|
|
742
|
-
el.dispatchEvent(new window.Event('x'));
|
|
743
|
-
is(log, [el])
|
|
744
|
-
})
|
|
745
|
-
|
|
746
|
-
test('on: capture, stop, prevent', e => {
|
|
747
|
-
let el = h`<x :onx.capture="e=>log.push(1)"><y :onx="e=>log.push(2)"></y></x>`
|
|
748
|
-
let state = sprae(el, {log:[]})
|
|
749
|
-
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
750
|
-
is(state.log, [1,2])
|
|
751
|
-
|
|
752
|
-
let el2 = h`<x :onx="e=>log.push(1)"><y :onx.stop="e=>log.push(2)"></y></x>`
|
|
753
|
-
let state2 = sprae(el2, {log:[]})
|
|
754
|
-
el2.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
755
|
-
is(state2.log, [2])
|
|
756
|
-
})
|
|
757
|
-
|
|
758
|
-
test('on: window, self', e => {
|
|
759
|
-
let el = h`<x :onx.self="e=>log.push(1)"><y :onx.window="e=>log.push(2)"></y></x>`
|
|
760
|
-
let state = sprae(el, {log:[]})
|
|
761
|
-
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
762
|
-
is(state.log, [])
|
|
763
|
-
el.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
764
|
-
is(state.log, [1])
|
|
765
|
-
window.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
766
|
-
is(state.log, [1,2])
|
|
767
|
-
})
|
|
768
|
-
|
|
769
|
-
test('on: keys', e => {
|
|
770
|
-
let el = h`<x :onkeydown.enter="e=>log.push(1)"></x>`
|
|
771
|
-
let state = {log:[]}
|
|
772
|
-
sprae(el, state)
|
|
773
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
774
|
-
is(state.log,[])
|
|
775
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
776
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
777
|
-
is(state.log,[1])
|
|
778
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
779
|
-
is(state.log,[1,1])
|
|
780
|
-
})
|
|
781
|
-
|
|
782
|
-
test('on: key combinations', e => {
|
|
783
|
-
let el = h`<x :onkeydown.ctrl-enter="e=>log.push(1)"></x>`
|
|
784
|
-
let state = {log:[]}
|
|
785
|
-
sprae(el, state)
|
|
786
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
787
|
-
is(state.log,[])
|
|
788
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
789
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
790
|
-
is(state.log,[])
|
|
791
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
792
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
793
|
-
is(state.log,[1])
|
|
794
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
795
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
796
|
-
is(state.log,[1,1])
|
|
797
|
-
let el2 = h`<x :onkeydown.ctrl-alt-enter="e=>log.push(1)"></x>`
|
|
798
|
-
})
|
|
799
|
-
|
|
800
|
-
test('on: keys with prevent', e => {
|
|
801
|
-
let el = h`<y :onkeydown="e=>log.push(e.key)"><x :ref="x" :onkeydown.enter.stop></x></y>`
|
|
802
|
-
let state = sprae(el, {log:[]})
|
|
803
|
-
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
804
|
-
console.log('enter')
|
|
805
|
-
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
806
|
-
is(state.log,['x'])
|
|
807
|
-
})
|
|
808
|
-
|
|
809
|
-
test('on: debounce', async e => {
|
|
810
|
-
let el = h`<x :onkeydown.debounce-1="e=>log.push(e.key)"></x>`
|
|
811
|
-
let state = sprae(el, {log:[]})
|
|
812
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
813
|
-
is(state.log, [])
|
|
814
|
-
await time(2)
|
|
815
|
-
is(state.log, ['x'])
|
|
816
|
-
})
|
|
817
|
-
|
|
818
|
-
test('on: debounce 0', async e => {
|
|
819
|
-
let el = h`<x :onkeydown.debounce-0="e=>log.push(e.key)"></x>`
|
|
820
|
-
let state = sprae(el, {log:[]})
|
|
821
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
822
|
-
is(state.log, [])
|
|
823
|
-
await time(2)
|
|
824
|
-
is(state.log, ['x'])
|
|
825
|
-
})
|
|
826
|
-
|
|
827
|
-
test('on: throttle', async e => {
|
|
828
|
-
let el = h`<x :onkeydown.throttle-10="e=>log.push(e.key)"></x>`
|
|
829
|
-
let state = sprae(el, {log:[]})
|
|
830
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
831
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
832
|
-
is(state.log, ['x'])
|
|
833
|
-
await time(5)
|
|
834
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
835
|
-
is(state.log, ['x'])
|
|
836
|
-
await time(10)
|
|
837
|
-
is(state.log, ['x', 'x'])
|
|
838
|
-
await time(10)
|
|
839
|
-
is(state.log, ['x', 'x'])
|
|
840
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
841
|
-
is(state.log, ['x', 'x', 'x'])
|
|
842
|
-
})
|
|
843
|
-
|
|
844
|
-
test('on: toggle', async e => {
|
|
845
|
-
let el = h`<x :onx.toggle="e=>(log.push(1),e=>log.push(2))"></x>`
|
|
846
|
-
let state = sprae(el, {log:[]})
|
|
847
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
848
|
-
is(state.log, [1])
|
|
849
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
850
|
-
is(state.log, [1,2])
|
|
851
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
852
|
-
is(state.log, [1,2,1])
|
|
853
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
854
|
-
is(state.log, [1,2,1,2])
|
|
855
|
-
})
|
|
856
|
-
|
|
857
|
-
test.skip('on: nexttick', async e => {
|
|
858
|
-
let el = h`<x :onkeydown.nexttick="e=>log.push(e.key)"></x>`
|
|
859
|
-
let state = sprae(el, {log:[]})
|
|
860
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
861
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
862
|
-
is(state.log, [])
|
|
863
|
-
await time()
|
|
864
|
-
is(state.log, ['x', 'x'])
|
|
865
|
-
})
|
|
866
|
-
|
|
867
|
-
test('on: modifiers chain', async e => {
|
|
868
|
-
let el = h`<x :onkeydown.letter..onkeyup.letter="e=>(log.push(e.key),(e)=>log.push(e.key))"></x>`
|
|
869
|
-
let state = sprae(el, {log:[]})
|
|
870
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
871
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
872
|
-
is(state.log,['x'])
|
|
873
|
-
el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'Enter', bubbles: true }));
|
|
874
|
-
is(state.log,['x'])
|
|
875
|
-
el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'x', bubbles: true }));
|
|
876
|
-
is(state.log,['x', 'x'])
|
|
557
|
+
test('each: with :with', () => {
|
|
558
|
+
let el = h`<ul><li :each="i in 3" :with="{x:i}" :text="x"></li></ul>`
|
|
559
|
+
sprae(el)
|
|
560
|
+
is(el.outerHTML, `<ul><li>0</li><li>1</li><li>2</li></ul>`)
|
|
877
561
|
})
|
|
878
562
|
|
|
879
563
|
test('with: inline', async () => {
|
|
@@ -923,7 +607,7 @@ test.skip('with: reactive transparency', () => {
|
|
|
923
607
|
is(el.innerHTML, `<y>13</y>`)
|
|
924
608
|
})
|
|
925
609
|
test('with: writes to state', async () => {
|
|
926
|
-
let a = h`<x :with="{a:1}"><y :
|
|
610
|
+
let a = h`<x :with="{a:1}"><y :onx="e=>a++" :text="a"></y></x>`
|
|
927
611
|
sprae(a)
|
|
928
612
|
is(a.innerHTML, `<y>1</y>`)
|
|
929
613
|
a.firstChild.dispatchEvent(new window.Event('x'))
|
package/test/events.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// import { signal } from 'usignal/sync'
|
|
2
|
+
import test, {is, any, throws} from 'tst'
|
|
3
|
+
import {tick, time} from 'wait-please'
|
|
4
|
+
import sprae from '../src/index.js'
|
|
5
|
+
import h from 'hyperf'
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
test('events: this context', e => {
|
|
9
|
+
let el = h`<div @x="log.push(this)"></div>`
|
|
10
|
+
let state = sprae(el, {log: []})
|
|
11
|
+
el.dispatchEvent(new window.Event('x'));
|
|
12
|
+
is(state.log, [el])
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
test('events: multiple events', e => {
|
|
16
|
+
let el = h`<div @scroll@click@x="log.push(event.type)"></div>`
|
|
17
|
+
let state = sprae(el, {log:[]})
|
|
18
|
+
|
|
19
|
+
el.dispatchEvent(new window.Event('click'));
|
|
20
|
+
is(state.log, ['click'])
|
|
21
|
+
el.dispatchEvent(new window.Event('scroll'));
|
|
22
|
+
is(state.log, ['click','scroll'])
|
|
23
|
+
el.dispatchEvent(new window.Event('x'));
|
|
24
|
+
is(state.log, ['click','scroll','x'])
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
test('events: once', e => {
|
|
28
|
+
// NOTE: if callback updates it's still rebound
|
|
29
|
+
let el = h`<x @x.once="(x&&log.push(this))" ></x>`
|
|
30
|
+
let log = []
|
|
31
|
+
let state = sprae(el, {log, x:1})
|
|
32
|
+
el.dispatchEvent(new window.Event('x'));
|
|
33
|
+
is(log, [el])
|
|
34
|
+
el.dispatchEvent(new window.Event('x'));
|
|
35
|
+
is(log, [el])
|
|
36
|
+
state.x = 2
|
|
37
|
+
el.dispatchEvent(new window.Event('x'));
|
|
38
|
+
el.dispatchEvent(new window.Event('x'));
|
|
39
|
+
is(log, [el])
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test('events: capture, stop, prevent', e => {
|
|
43
|
+
let el = h`<x @x.capture="log.push(1)"><y @x="log.push(2)"></y></x>`
|
|
44
|
+
let state = sprae(el, {log:[]})
|
|
45
|
+
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
46
|
+
is(state.log, [1,2])
|
|
47
|
+
|
|
48
|
+
let el2 = h`<x @x="log.push(1)"><y @x.stop="log.push(2)"></y></x>`
|
|
49
|
+
let state2 = sprae(el2, {log:[]})
|
|
50
|
+
el2.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
51
|
+
is(state2.log, [2])
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
test('events: window, self', e => {
|
|
55
|
+
let el = h`<x @x.self="log.push(1)"><y @x.window="log.push(2)"></y></x>`
|
|
56
|
+
let state = sprae(el, {log:[]})
|
|
57
|
+
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
58
|
+
is(state.log, [])
|
|
59
|
+
el.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
60
|
+
is(state.log, [1])
|
|
61
|
+
window.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
62
|
+
is(state.log, [1,2])
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test('events: keys', e => {
|
|
66
|
+
let el = h`<x @keydown.enter="log.push(1)"></x>`
|
|
67
|
+
let state = {log:[]}
|
|
68
|
+
sprae(el, state)
|
|
69
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
70
|
+
is(state.log,[])
|
|
71
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
72
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
73
|
+
is(state.log,[1])
|
|
74
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
75
|
+
is(state.log,[1,1])
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
test('events: key combinations', e => {
|
|
79
|
+
let el = h`<x @keydown.ctrl-enter="log.push(1)"></x>`
|
|
80
|
+
let state = {log:[]}
|
|
81
|
+
sprae(el, state)
|
|
82
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
83
|
+
is(state.log,[])
|
|
84
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
85
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
86
|
+
is(state.log,[])
|
|
87
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
88
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
89
|
+
is(state.log,[1])
|
|
90
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
91
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
92
|
+
is(state.log,[1,1])
|
|
93
|
+
let el2 = h`<x @keydown.ctrl-alt-enter="log.push(1)"></x>`
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
test('events: keys with prevent', e => {
|
|
97
|
+
let el = h`<y @keydown="log.push(event.key)"><x :ref="x" @keydown.enter.stop></x></y>`
|
|
98
|
+
let state = sprae(el, {log:[]})
|
|
99
|
+
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
100
|
+
console.log('enter')
|
|
101
|
+
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
102
|
+
is(state.log,['x'])
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
test('events: debounce', async e => {
|
|
106
|
+
let el = h`<x @keydown.debounce-1="log.push(event.key)"></x>`
|
|
107
|
+
let state = sprae(el, {log:[]})
|
|
108
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
109
|
+
is(state.log, [])
|
|
110
|
+
await time(2)
|
|
111
|
+
is(state.log, ['x'])
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
test('events: debounce 0', async e => {
|
|
115
|
+
let el = h`<x @keydown.debounce-0="log.push(event.key)"></x>`
|
|
116
|
+
let state = sprae(el, {log:[]})
|
|
117
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
118
|
+
is(state.log, [])
|
|
119
|
+
await time(2)
|
|
120
|
+
is(state.log, ['x'])
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
test('events: throttle', async e => {
|
|
124
|
+
let el = h`<x @keydown.throttle-10="log.push(event.key)"></x>`
|
|
125
|
+
let state = sprae(el, {log:[]})
|
|
126
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
127
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
128
|
+
is(state.log, ['x'])
|
|
129
|
+
await time(5)
|
|
130
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
131
|
+
is(state.log, ['x'])
|
|
132
|
+
await time(10)
|
|
133
|
+
is(state.log, ['x', 'x'])
|
|
134
|
+
await time(10)
|
|
135
|
+
is(state.log, ['x', 'x'])
|
|
136
|
+
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
137
|
+
is(state.log, ['x', 'x', 'x'])
|
|
138
|
+
})
|
package/test/test.js
CHANGED
|
@@ -1,2 +1,13 @@
|
|
|
1
1
|
import './state.js'
|
|
2
|
-
import './
|
|
2
|
+
import './attrs.js'
|
|
3
|
+
import './events.js'
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(DocumentFragment.prototype, 'outerHTML', {
|
|
6
|
+
get() {
|
|
7
|
+
let s = ''
|
|
8
|
+
this.childNodes.forEach(n => {
|
|
9
|
+
s += n.nodeType === 3 ? n.textContent : n.outerHTML != null ? n.outerHTML : ''
|
|
10
|
+
})
|
|
11
|
+
return s
|
|
12
|
+
}
|
|
13
|
+
})
|
package/todo.md
CHANGED
|
@@ -50,4 +50,5 @@
|
|
|
50
50
|
* [x] Autorun
|
|
51
51
|
* [x] There's some bug with prostogreen not triggering effect. (caused by special array.length case)
|
|
52
52
|
* [x] Getters must become evaluable
|
|
53
|
-
* [ ] `:with="{likes:[], like(){ /* likes should not be undefined here */ }}"`
|
|
53
|
+
* [ ] `:with="{likes:[], like(){ /* likes should not be undefined here */ }}"`
|
|
54
|
+
* [ ] `<li :each="item in items" :with="{collapsed:true}"><button :onclick='e=>collapsed=false'></li>`
|