@@ -14,6 +14,7 @@ import {
14
14
start ,
15
15
accumulate ,
16
16
onceStateChangesTo ,
17
+ readContext ,
17
18
} from "./index" ;
18
19
19
20
test ( "node version " + process . version , ( ) => { } ) ;
@@ -707,32 +708,205 @@ describe("Wrapping AbortController as a state machine", () => {
707
708
708
709
describe ( "Button click" , ( ) => {
709
710
function ButtonClickListener ( button : HTMLButtonElement ) {
710
- function * initial ( ) {
711
- yield on ( "click" , clicked ) ;
711
+ function * Initial ( ) {
712
+ yield on ( "click" , Clicked ) ;
712
713
yield listenTo ( button , "click" ) ;
713
714
}
714
- function * clicked ( ) { }
715
+ function * Clicked ( ) { }
715
716
716
- return initial ;
717
+ return Initial ;
717
718
}
718
719
719
720
it ( "listens when button clicks" , ( ) => {
720
721
const button = document . createElement ( 'button' ) ;
721
722
const machine = start ( ButtonClickListener . bind ( null , button ) ) ;
722
723
723
- expect ( machine . current ) . toEqual ( "initial " ) ;
724
+ expect ( machine . current ) . toEqual ( "Initial " ) ;
724
725
expect ( machine . changeCount ) . toEqual ( 0 ) ;
725
726
726
727
button . click ( ) ;
727
- expect ( machine . current ) . toEqual ( "clicked " ) ;
728
+ expect ( machine . current ) . toEqual ( "Clicked " ) ;
728
729
expect ( machine . changeCount ) . toEqual ( 1 ) ;
729
730
730
731
button . click ( ) ;
731
- expect ( machine . current ) . toEqual ( "clicked " ) ;
732
+ expect ( machine . current ) . toEqual ( "Clicked " ) ;
732
733
expect ( machine . changeCount ) . toEqual ( 1 ) ;
733
734
} ) ;
734
735
} ) ;
735
736
737
+ describe ( "FIXME: Key shortcut click highlighting too many event listeners bug" , ( ) => {
738
+ function KeyShortcutListener ( el : HTMLElement ) {
739
+ function * Open ( ) {
740
+ yield on ( "keydown" , OpenCheckingKey ) ;
741
+ yield listenTo ( el , "keydown" ) ;
742
+ }
743
+ function * OpenCheckingKey ( ) {
744
+ const event : KeyboardEvent = yield readContext ( "event" ) ;
745
+ yield cond ( event . key === 'Escape' , Closed ) ;
746
+ // yield revert();
747
+ yield always ( Open ) ;
748
+ }
749
+ function * Closed ( ) {
750
+ yield on ( "keydown" , ClosedCheckingKey ) ;
751
+ yield listenTo ( el , "keydown" ) ;
752
+ }
753
+ function * ClosedCheckingKey ( ) {
754
+ const event : KeyboardEvent = yield readContext ( "event" ) ;
755
+ yield cond ( event . key === 'Enter' , Open ) ;
756
+ // yield revert();
757
+ yield always ( Closed ) ;
758
+ }
759
+
760
+ return Closed ;
761
+ }
762
+
763
+ it ( "listens when keys are pressed" , ( ) => {
764
+ // FIXME: there’s lots of event listeners being created!
765
+ const input = document . createElement ( 'input' ) ;
766
+ const machine = start ( KeyShortcutListener . bind ( null , input ) ) ;
767
+
768
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
769
+ expect ( machine . changeCount ) . toEqual ( 0 ) ;
770
+
771
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ) ;
772
+ expect ( machine . current ) . toEqual ( "Open" ) ;
773
+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
774
+
775
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ) ;
776
+ expect ( machine . current ) . toEqual ( "Open" ) ;
777
+ expect ( machine . changeCount ) . toEqual ( 6 ) ;
778
+
779
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'a' } ) ) ;
780
+ expect ( machine . current ) . toEqual ( "Open" ) ;
781
+ expect ( machine . changeCount ) . toEqual ( 14 ) ;
782
+
783
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Escape' } ) ) ;
784
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
785
+ expect ( machine . changeCount ) . toEqual ( 30 ) ;
786
+
787
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'a' } ) ) ;
788
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
789
+ expect ( machine . changeCount ) . toEqual ( 62 ) ;
790
+
791
+ machine . abort ( ) ;
792
+ } ) ;
793
+ } ) ;
794
+
795
+ describe ( "Key shortcut cond reading event" , ( ) => {
796
+ function KeyShortcutListener ( el : HTMLElement ) {
797
+ function * Open ( ) {
798
+ yield listenTo ( el , "keydown" ) ;
799
+ yield on (
800
+ "keydown" ,
801
+ cond ( ( readContext ) => {
802
+ const event = readContext ( "event" ) as KeyboardEvent ;
803
+ return event . key === "Escape" ;
804
+ } , Closed )
805
+ ) ;
806
+ }
807
+ function * Closed ( ) {
808
+ yield listenTo ( el , "keydown" ) ;
809
+ yield on (
810
+ "keydown" ,
811
+ cond ( ( readContext ) => {
812
+ const event = readContext ( "event" ) as KeyboardEvent ;
813
+ return event . key === "Enter" ;
814
+ } , Open )
815
+ ) ;
816
+ }
817
+
818
+ return Closed ;
819
+ }
820
+
821
+ it ( "listens when keys are pressed" , ( ) => {
822
+ const input = document . createElement ( 'input' ) ;
823
+ const machine = start ( KeyShortcutListener . bind ( null , input ) ) ;
824
+
825
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
826
+ expect ( machine . changeCount ) . toEqual ( 0 ) ;
827
+
828
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ) ;
829
+ expect ( machine . current ) . toEqual ( "Open" ) ;
830
+ expect ( machine . changeCount ) . toEqual ( 1 ) ;
831
+
832
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Enter' } ) ) ;
833
+ expect ( machine . current ) . toEqual ( "Open" ) ;
834
+ expect ( machine . changeCount ) . toEqual ( 1 ) ;
835
+
836
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'a' } ) ) ;
837
+ expect ( machine . current ) . toEqual ( "Open" ) ;
838
+ expect ( machine . changeCount ) . toEqual ( 1 ) ;
839
+
840
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Escape' } ) ) ;
841
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
842
+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
843
+
844
+ input . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'a' } ) ) ;
845
+ expect ( machine . current ) . toEqual ( "Closed" ) ;
846
+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
847
+
848
+ machine . abort ( ) ;
849
+ } ) ;
850
+ } ) ;
851
+
852
+ describe ( "Element focus" , ( ) => {
853
+ function * ButtonFocusListener ( el : HTMLElement ) {
854
+ yield listenTo ( el . ownerDocument , "focusin" ) ;
855
+ yield on ( "focusin" , compound ( CheckingActive ) ) ;
856
+
857
+ function * Inactive ( ) { }
858
+ function * Active ( ) { }
859
+ function * CheckingActive ( ) {
860
+ yield cond ( el . ownerDocument . activeElement === el , Active ) ;
861
+ yield always ( Inactive ) ;
862
+ }
863
+
864
+ return CheckingActive ;
865
+ }
866
+
867
+ it ( "listens when element receives and loses focus" , ( ) => {
868
+ const button = document . body . appendChild ( document . createElement ( 'button' ) ) ;
869
+ const input = document . body . appendChild ( document . createElement ( 'input' ) ) ;
870
+
871
+ const machine = start ( ButtonFocusListener . bind ( null , button ) ) ;
872
+
873
+ expect ( machine . current ) . toEqual ( "Inactive" ) ;
874
+ expect ( machine . changeCount ) . toEqual ( 0 ) ;
875
+
876
+ button . focus ( ) ;
877
+ expect ( machine . current ) . toEqual ( "Active" ) ;
878
+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
879
+
880
+ button . focus ( ) ;
881
+ expect ( machine . current ) . toEqual ( "Active" ) ;
882
+ expect ( machine . changeCount ) . toEqual ( 2 ) ;
883
+
884
+ input . focus ( ) ;
885
+ expect ( machine . current ) . toEqual ( "Inactive" ) ;
886
+ expect ( machine . changeCount ) . toEqual ( 4 ) ;
887
+
888
+ button . focus ( ) ;
889
+ expect ( machine . current ) . toEqual ( "Active" ) ;
890
+ expect ( machine . changeCount ) . toEqual ( 6 ) ;
891
+
892
+ machine . abort ( ) ;
893
+ button . remove ( ) ;
894
+ input . remove ( ) ;
895
+ } ) ;
896
+
897
+ it ( "is initially Active if element is already focused when starting" , ( ) => {
898
+ const button = document . body . appendChild ( document . createElement ( 'button' ) ) ;
899
+
900
+ button . focus ( ) ;
901
+ const machine = start ( ButtonFocusListener . bind ( null , button ) ) ;
902
+
903
+ expect ( machine . current ) . toEqual ( "Active" ) ;
904
+ expect ( machine . changeCount ) . toEqual ( 0 ) ;
905
+
906
+ button . remove ( ) ;
907
+ } )
908
+ } ) ;
909
+
736
910
describe ( "accumulate()" , ( ) => {
737
911
const messagesKey = Symbol ( "messages" ) ;
738
912
0 commit comments