sprae 5.3.0 → 6.1.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 +50 -17
- package/readme.md +63 -66
- package/sprae.auto.js +25 -65
- package/sprae.auto.min.js +1 -1
- package/sprae.js +25 -65
- package/sprae.min.js +1 -1
- package/src/core.js +16 -11
- package/src/directives.js +23 -68
- package/test/{dom.js → attrs.js} +9 -325
- package/test/events.js +138 -0
- package/test/test.js +12 -1
- package/todo.md +2 -2
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
|
})
|
|
@@ -74,6 +64,13 @@ test('common: const in on', async () => {
|
|
|
74
64
|
is(state.y, 2)
|
|
75
65
|
})
|
|
76
66
|
|
|
67
|
+
test('common: const in with', async () => {
|
|
68
|
+
let el = h`<div :with="{x(){let x = 1; y=x;}}" @x="x()"></div>`
|
|
69
|
+
let state = sprae(el,{y:0})
|
|
70
|
+
el.dispatchEvent(new CustomEvent('x'))
|
|
71
|
+
is(state.y, 1)
|
|
72
|
+
})
|
|
73
|
+
|
|
77
74
|
test('style', async () => {
|
|
78
75
|
let el = h`<x style="left: 1px" :style="style"></x>`
|
|
79
76
|
let params = sprae(el, {style: "top: 1px"})
|
|
@@ -146,9 +143,8 @@ test('props: multiprop', async () => {
|
|
|
146
143
|
is(el.outerHTML, `<input id="0" name="0" for="0">`)
|
|
147
144
|
})
|
|
148
145
|
|
|
149
|
-
// FIXME: this must work without return
|
|
150
146
|
test('props: calculation', async () => {
|
|
151
|
-
let el = h`<x :x="let a = 5; return Array.from({length: x}, (_,i)=>i).join('')"></x>`
|
|
147
|
+
let el = h`<x :x="(()=>{ let a = 5; return Array.from({length: x}, (_,i)=>i).join('') })()"></x>`
|
|
152
148
|
let state = sprae(el, {x:3});
|
|
153
149
|
is(el.outerHTML, `<x x="012"></x>`)
|
|
154
150
|
state.x = 4
|
|
@@ -570,318 +566,6 @@ test('each: with :with', () => {
|
|
|
570
566
|
is(el.outerHTML, `<ul><li>0</li><li>1</li><li>2</li></ul>`)
|
|
571
567
|
})
|
|
572
568
|
|
|
573
|
-
test('on: base', async () => {
|
|
574
|
-
let el = h`<div :on="{click(e){log.push('click')}, x}"></div>`
|
|
575
|
-
let log = []
|
|
576
|
-
let params = sprae(el, {x(){log.push('x')}, log})
|
|
577
|
-
|
|
578
|
-
is(el.outerHTML, `<div></div>`);
|
|
579
|
-
el.dispatchEvent(new window.Event('click'));
|
|
580
|
-
is(log, ['click'])
|
|
581
|
-
el.dispatchEvent(new window.Event('x'));
|
|
582
|
-
is(log, ['click','x'])
|
|
583
|
-
|
|
584
|
-
params.x = function(){log.push('xx')}
|
|
585
|
-
await tick()
|
|
586
|
-
el.dispatchEvent(new window.Event('x'));
|
|
587
|
-
is(log, ['click','x','xx']);
|
|
588
|
-
|
|
589
|
-
console.log('make null')
|
|
590
|
-
params.x = null;
|
|
591
|
-
await tick()
|
|
592
|
-
el.dispatchEvent(new window.Event('x'));
|
|
593
|
-
is(log, ['click','x','xx']);
|
|
594
|
-
})
|
|
595
|
-
|
|
596
|
-
test('onevt: this context', e => {
|
|
597
|
-
let el = h`<div :onx="function(){log.push(this)}"></div>`
|
|
598
|
-
let state = sprae(el, {log: []})
|
|
599
|
-
el.dispatchEvent(new window.Event('x'));
|
|
600
|
-
is(state.log, [el])
|
|
601
|
-
})
|
|
602
|
-
|
|
603
|
-
test('on: this in chains refers to el', () => {
|
|
604
|
-
let el = h`<div :ona..onb="function(e){x=this; log.push(1); return () => log.push(2)}"></div>`
|
|
605
|
-
let state = sprae(el, {log:[], x:null})
|
|
606
|
-
el.dispatchEvent(new window.Event('a'));
|
|
607
|
-
is(state.log, [1])
|
|
608
|
-
})
|
|
609
|
-
|
|
610
|
-
test('on: multiple events', e => {
|
|
611
|
-
let el = h`<div :onscroll:onclick:onx="e=>log.push(e.type)"></div>`
|
|
612
|
-
let state = sprae(el, {log:[]})
|
|
613
|
-
|
|
614
|
-
el.dispatchEvent(new window.Event('click'));
|
|
615
|
-
is(state.log, ['click'])
|
|
616
|
-
el.dispatchEvent(new window.Event('scroll'));
|
|
617
|
-
is(state.log, ['click','scroll'])
|
|
618
|
-
el.dispatchEvent(new window.Event('x'));
|
|
619
|
-
is(state.log, ['click','scroll','x'])
|
|
620
|
-
})
|
|
621
|
-
|
|
622
|
-
test('on: in-out events', e => {
|
|
623
|
-
// let el = document.createElement('x');
|
|
624
|
-
// el.setAttribute(':onmousedown..onmouseup', 'e=>(log.push(e.type),e=>log.push(e.type))')
|
|
625
|
-
let el = h`<x :onmousedown..onmouseup="(e) => { x=this; log.push(e.type); return e=>log.push(e.type); }"></x>`
|
|
626
|
-
|
|
627
|
-
let state = sprae(el, {log:[],x:null})
|
|
628
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
629
|
-
is(state.x, el);
|
|
630
|
-
is(state.log, ['mousedown'])
|
|
631
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
632
|
-
is(state.log, ['mousedown','mouseup'])
|
|
633
|
-
})
|
|
634
|
-
|
|
635
|
-
test('on: in-out side-effects', e => {
|
|
636
|
-
let log = []
|
|
637
|
-
|
|
638
|
-
// 1. skip in event and do directly out
|
|
639
|
-
let el = h`<x :onin..onout="io"></x>`
|
|
640
|
-
sprae(el, { io(e) {
|
|
641
|
-
log.push(e.type)
|
|
642
|
-
return (e) => (log.push(e.type), [1,2,3])
|
|
643
|
-
} })
|
|
644
|
-
|
|
645
|
-
el.dispatchEvent(new window.Event('out'));
|
|
646
|
-
is(log, [])
|
|
647
|
-
|
|
648
|
-
// 2. Some nonsensical return is fine
|
|
649
|
-
el.dispatchEvent(new window.Event('in'));
|
|
650
|
-
is(log, ['in'])
|
|
651
|
-
el.dispatchEvent(new window.Event('out'));
|
|
652
|
-
is(log, ['in','out'], 'out triggers right')
|
|
653
|
-
el.dispatchEvent(new window.Event('out'));
|
|
654
|
-
is(log, ['in','out'])
|
|
655
|
-
el.dispatchEvent(new window.Event('in'));
|
|
656
|
-
is(log, ['in','out','in'])
|
|
657
|
-
el.dispatchEvent(new window.Event('in'));
|
|
658
|
-
is(log, ['in','out','in', 'in'])
|
|
659
|
-
el.dispatchEvent(new window.Event('out'));
|
|
660
|
-
is(log, ['in','out','in','in','out','out'])
|
|
661
|
-
el.dispatchEvent(new window.Event('out'));
|
|
662
|
-
is(log, ['in','out','in','in','out','out'])
|
|
663
|
-
})
|
|
664
|
-
|
|
665
|
-
test('on: chain of events', e => {
|
|
666
|
-
let el = h`<div :onmousedown..onmousemove..onmouseup="e=>(log.push(e.type),e=>(log.push(e.type),e=>log.push(e.type)))"></div>`
|
|
667
|
-
let state = sprae(el, {log:[]})
|
|
668
|
-
|
|
669
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
670
|
-
is(state.log, ['mousedown'])
|
|
671
|
-
el.dispatchEvent(new window.Event('mousemove'));
|
|
672
|
-
is(state.log, ['mousedown','mousemove'])
|
|
673
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
674
|
-
is(state.log, ['mousedown','mousemove','mouseup'])
|
|
675
|
-
el.dispatchEvent(new window.Event('mouseup'));
|
|
676
|
-
is(state.log, ['mousedown','mousemove','mouseup'])
|
|
677
|
-
el.dispatchEvent(new window.Event('mousedown'));
|
|
678
|
-
is(state.log, ['mousedown','mousemove','mouseup','mousedown'])
|
|
679
|
-
})
|
|
680
|
-
|
|
681
|
-
test('on: parallel chains', e => {
|
|
682
|
-
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>`
|
|
683
|
-
let state = sprae(el, {log:[]})
|
|
684
|
-
|
|
685
|
-
console.log('emit x')
|
|
686
|
-
el.dispatchEvent(new window.Event('x'));
|
|
687
|
-
is(state.log, ['x'])
|
|
688
|
-
console.log('emit x')
|
|
689
|
-
el.dispatchEvent(new window.Event('x'));
|
|
690
|
-
is(state.log, ['x','x'])
|
|
691
|
-
console.log('emit y')
|
|
692
|
-
el.dispatchEvent(new window.Event('y'));
|
|
693
|
-
is(state.log, ['x','x','y','y'])
|
|
694
|
-
console.log('emit y')
|
|
695
|
-
el.dispatchEvent(new window.Event('y'));
|
|
696
|
-
is(state.log, ['x','x','y','y'])
|
|
697
|
-
console.log('emit z')
|
|
698
|
-
el.dispatchEvent(new window.Event('z'));
|
|
699
|
-
console.log('emit y')
|
|
700
|
-
el.dispatchEvent(new window.Event('y'));
|
|
701
|
-
is(state.log, ['x','x','y','y','z','z'])
|
|
702
|
-
el.dispatchEvent(new window.Event('z'));
|
|
703
|
-
is(state.log, ['x','x','y','y','z','z']);
|
|
704
|
-
el.dispatchEvent(new window.Event('x'));
|
|
705
|
-
is(state.log, ['x','x','y','y','z','z','x']);
|
|
706
|
-
})
|
|
707
|
-
|
|
708
|
-
test('on: state changes between chain of events', async e => {
|
|
709
|
-
let el = h`<x :on="{'x..y':fn}"></x>`
|
|
710
|
-
let log = []
|
|
711
|
-
let state = sprae(el, {log, fn: () => (log.push('x1'), ()=>log.push('y1'))})
|
|
712
|
-
console.log('emit x')
|
|
713
|
-
el.dispatchEvent(new window.Event('x'));
|
|
714
|
-
is(log, ['x1'])
|
|
715
|
-
console.log('update fn')
|
|
716
|
-
state.fn = () => (log.push('x2'), () => log.push('y2'))
|
|
717
|
-
await tick()
|
|
718
|
-
is(log, ['x1'])
|
|
719
|
-
// console.log('xx')
|
|
720
|
-
// NOTE: state update registers new chain listener before finishing prev chain
|
|
721
|
-
// el.dispatchEvent(new window.Event('x'));
|
|
722
|
-
// el.dispatchEvent(new window.Event('x'));
|
|
723
|
-
// is(log, [1])
|
|
724
|
-
console.log('emit y, y')
|
|
725
|
-
el.dispatchEvent(new window.Event('y'));
|
|
726
|
-
el.dispatchEvent(new window.Event('y'));
|
|
727
|
-
is(log, ['x1', 'y1'])
|
|
728
|
-
console.log('emit x')
|
|
729
|
-
el.dispatchEvent(new window.Event('x'));
|
|
730
|
-
is(log, ['x1','y1','x2'])
|
|
731
|
-
console.log('emit y, y')
|
|
732
|
-
el.dispatchEvent(new window.Event('y'));
|
|
733
|
-
el.dispatchEvent(new window.Event('y'));
|
|
734
|
-
is(log, ['x1','y1','x2','y2'])
|
|
735
|
-
})
|
|
736
|
-
|
|
737
|
-
test('on: once', e => {
|
|
738
|
-
// NOTE: if callback updates it's still rebound
|
|
739
|
-
let el = h`<x :onx.once="(e=>x&&log.push(this))" ></x>`
|
|
740
|
-
let log = []
|
|
741
|
-
let state = sprae(el, {log, x:1})
|
|
742
|
-
el.dispatchEvent(new window.Event('x'));
|
|
743
|
-
is(log, [el])
|
|
744
|
-
el.dispatchEvent(new window.Event('x'));
|
|
745
|
-
is(log, [el])
|
|
746
|
-
state.x = 2
|
|
747
|
-
el.dispatchEvent(new window.Event('x'));
|
|
748
|
-
el.dispatchEvent(new window.Event('x'));
|
|
749
|
-
is(log, [el])
|
|
750
|
-
})
|
|
751
|
-
|
|
752
|
-
test('on: capture, stop, prevent', e => {
|
|
753
|
-
let el = h`<x :onx.capture="e=>log.push(1)"><y :onx="e=>log.push(2)"></y></x>`
|
|
754
|
-
let state = sprae(el, {log:[]})
|
|
755
|
-
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
756
|
-
is(state.log, [1,2])
|
|
757
|
-
|
|
758
|
-
let el2 = h`<x :onx="e=>log.push(1)"><y :onx.stop="e=>log.push(2)"></y></x>`
|
|
759
|
-
let state2 = sprae(el2, {log:[]})
|
|
760
|
-
el2.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
761
|
-
is(state2.log, [2])
|
|
762
|
-
})
|
|
763
|
-
|
|
764
|
-
test('on: window, self', e => {
|
|
765
|
-
let el = h`<x :onx.self="e=>log.push(1)"><y :onx.window="e=>log.push(2)"></y></x>`
|
|
766
|
-
let state = sprae(el, {log:[]})
|
|
767
|
-
el.firstChild.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
768
|
-
is(state.log, [])
|
|
769
|
-
el.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
770
|
-
is(state.log, [1])
|
|
771
|
-
window.dispatchEvent(new window.Event('x', {bubbles:true}));
|
|
772
|
-
is(state.log, [1,2])
|
|
773
|
-
})
|
|
774
|
-
|
|
775
|
-
test('on: keys', e => {
|
|
776
|
-
let el = h`<x :onkeydown.enter="e=>log.push(1)"></x>`
|
|
777
|
-
let state = {log:[]}
|
|
778
|
-
sprae(el, state)
|
|
779
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
780
|
-
is(state.log,[])
|
|
781
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
782
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
783
|
-
is(state.log,[1])
|
|
784
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
785
|
-
is(state.log,[1,1])
|
|
786
|
-
})
|
|
787
|
-
|
|
788
|
-
test('on: key combinations', e => {
|
|
789
|
-
let el = h`<x :onkeydown.ctrl-enter="e=>log.push(1)"></x>`
|
|
790
|
-
let state = {log:[]}
|
|
791
|
-
sprae(el, state)
|
|
792
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
793
|
-
is(state.log,[])
|
|
794
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
795
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: '' }));
|
|
796
|
-
is(state.log,[])
|
|
797
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
798
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
799
|
-
is(state.log,[1])
|
|
800
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter' }));
|
|
801
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', ctrlKey: true }));
|
|
802
|
-
is(state.log,[1,1])
|
|
803
|
-
let el2 = h`<x :onkeydown.ctrl-alt-enter="e=>log.push(1)"></x>`
|
|
804
|
-
})
|
|
805
|
-
|
|
806
|
-
test('on: keys with prevent', e => {
|
|
807
|
-
let el = h`<y :onkeydown="e=>log.push(e.key)"><x :ref="x" :onkeydown.enter.stop></x></y>`
|
|
808
|
-
let state = sprae(el, {log:[]})
|
|
809
|
-
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
810
|
-
console.log('enter')
|
|
811
|
-
state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
812
|
-
is(state.log,['x'])
|
|
813
|
-
})
|
|
814
|
-
|
|
815
|
-
test('on: debounce', async e => {
|
|
816
|
-
let el = h`<x :onkeydown.debounce-1="e=>log.push(e.key)"></x>`
|
|
817
|
-
let state = sprae(el, {log:[]})
|
|
818
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
819
|
-
is(state.log, [])
|
|
820
|
-
await time(2)
|
|
821
|
-
is(state.log, ['x'])
|
|
822
|
-
})
|
|
823
|
-
|
|
824
|
-
test('on: debounce 0', async e => {
|
|
825
|
-
let el = h`<x :onkeydown.debounce-0="e=>log.push(e.key)"></x>`
|
|
826
|
-
let state = sprae(el, {log:[]})
|
|
827
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
828
|
-
is(state.log, [])
|
|
829
|
-
await time(2)
|
|
830
|
-
is(state.log, ['x'])
|
|
831
|
-
})
|
|
832
|
-
|
|
833
|
-
test('on: throttle', async e => {
|
|
834
|
-
let el = h`<x :onkeydown.throttle-10="e=>log.push(e.key)"></x>`
|
|
835
|
-
let state = sprae(el, {log:[]})
|
|
836
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
837
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
838
|
-
is(state.log, ['x'])
|
|
839
|
-
await time(5)
|
|
840
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
841
|
-
is(state.log, ['x'])
|
|
842
|
-
await time(10)
|
|
843
|
-
is(state.log, ['x', 'x'])
|
|
844
|
-
await time(10)
|
|
845
|
-
is(state.log, ['x', 'x'])
|
|
846
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
847
|
-
is(state.log, ['x', 'x', 'x'])
|
|
848
|
-
})
|
|
849
|
-
|
|
850
|
-
test('on: toggle', async e => {
|
|
851
|
-
let el = h`<x :onx.toggle="e=>(log.push(1),e=>log.push(2))"></x>`
|
|
852
|
-
let state = sprae(el, {log:[]})
|
|
853
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
854
|
-
is(state.log, [1])
|
|
855
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
856
|
-
is(state.log, [1,2])
|
|
857
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
858
|
-
is(state.log, [1,2,1])
|
|
859
|
-
el.dispatchEvent(new window.KeyboardEvent('x'));
|
|
860
|
-
is(state.log, [1,2,1,2])
|
|
861
|
-
})
|
|
862
|
-
|
|
863
|
-
test.skip('on: nexttick', async e => {
|
|
864
|
-
let el = h`<x :onkeydown.nexttick="e=>log.push(e.key)"></x>`
|
|
865
|
-
let state = sprae(el, {log:[]})
|
|
866
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
867
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
868
|
-
is(state.log, [])
|
|
869
|
-
await time()
|
|
870
|
-
is(state.log, ['x', 'x'])
|
|
871
|
-
})
|
|
872
|
-
|
|
873
|
-
test('on: modifiers chain', async e => {
|
|
874
|
-
let el = h`<x :onkeydown.letter..onkeyup.letter="e=>(log.push(e.key),(e)=>log.push(e.key))"></x>`
|
|
875
|
-
let state = sprae(el, {log:[]})
|
|
876
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
|
|
877
|
-
el.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
878
|
-
is(state.log,['x'])
|
|
879
|
-
el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'Enter', bubbles: true }));
|
|
880
|
-
is(state.log,['x'])
|
|
881
|
-
el.dispatchEvent(new window.KeyboardEvent('keyup', { key: 'x', bubbles: true }));
|
|
882
|
-
is(state.log,['x', 'x'])
|
|
883
|
-
})
|
|
884
|
-
|
|
885
569
|
test('with: inline', async () => {
|
|
886
570
|
let el = h`<x :with="{foo:'bar'}"><y :text="foo + baz"></y></x>`
|
|
887
571
|
let state = sprae(el, {baz: 'qux'})
|
|
@@ -929,7 +613,7 @@ test.skip('with: reactive transparency', () => {
|
|
|
929
613
|
is(el.innerHTML, `<y>13</y>`)
|
|
930
614
|
})
|
|
931
615
|
test('with: writes to state', async () => {
|
|
932
|
-
let a = h`<x :with="{a:1}"><y :
|
|
616
|
+
let a = h`<x :with="{a:1}"><y :onx="e=>a++" :text="a"></y></x>`
|
|
933
617
|
sprae(a)
|
|
934
618
|
is(a.innerHTML, `<y>1</y>`)
|
|
935
619
|
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,5 +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
|
-
* [
|
|
54
|
-
* [ ]
|
|
53
|
+
* [x] `<li :each="item in items" :with="{collapsed:true}"><button :onclick='e=>collapsed=false'></li>`
|
|
54
|
+
* [ ] `:with="{likes:[], like(){ /* likes should not be undefined here */ }}"`
|