@@ -524,19 +524,15 @@ function _single_tap(el, e) {
524
524
525
525
/** Get the rest of the textitems in the current active/hovered word's
526
526
* sentence or paragraph, or null if no selection. */
527
- let get_textitems_spans = function ( e ) {
527
+ let get_textitems_spans = function ( span_attribute ) {
528
528
let elements = $ ( 'span.kwordmarked, span.newmultiterm, span.wordhover' ) ;
529
529
elements . sort ( ( a , b ) => _get_order ( $ ( a ) ) - _get_order ( $ ( b ) ) ) ;
530
530
if ( elements . length == 0 )
531
531
return elements ;
532
532
533
533
const w = elements [ 0 ] ;
534
- let attr_name = 'sentence-id' ;
535
- if ( e && e . shiftKey ) {
536
- attr_name = 'paragraph-id' ;
537
- }
538
- const attr_value = $ ( w ) . data ( attr_name ) ;
539
- return $ ( `span.textitem[data-${ attr_name } ="${ attr_value } "]` ) . toArray ( ) ;
534
+ const attr_value = $ ( w ) . data ( span_attribute ) ;
535
+ return $ ( `span.textitem[data-${ span_attribute } ="${ attr_value } "]` ) . toArray ( ) ;
540
536
} ;
541
537
542
538
let handle_bookmark = function ( ) {
@@ -547,8 +543,8 @@ let handle_bookmark = function() {
547
543
548
544
/** Copy the text of the textitemspans to the clipboard, and add a
549
545
* color flash. */
550
- let handle_copy = function ( e ) {
551
- tis = get_textitems_spans ( e ) ;
546
+ let handle_copy = function ( span_attribute ) {
547
+ tis = get_textitems_spans ( span_attribute ) ;
552
548
copy_text_to_clipboard ( tis ) ;
553
549
}
554
550
@@ -680,8 +676,8 @@ let show_translation_for_text = function(text) {
680
676
681
677
682
678
/** Show the translation using the next dictionary. */
683
- function show_sentence_translation ( e ) {
684
- const tis = get_textitems_spans ( e ) ;
679
+ function handle_translate ( span_attribute ) {
680
+ const tis = get_textitems_spans ( span_attribute ) ;
685
681
const sentence = tis . map ( s => $ ( s ) . text ( ) ) . join ( '' ) ;
686
682
show_translation_for_text ( sentence ) ;
687
683
}
@@ -779,75 +775,107 @@ function add_page_after() {
779
775
}
780
776
781
777
782
- function handle_keydown ( e ) {
783
- if ( $ ( 'span.word' ) . length == 0 ) {
784
- return ; // Nothing to do.
785
- }
778
+ function getKeyString ( event ) {
779
+ const keys = [ ] ;
780
+
781
+ // Check for modifier keys
782
+ if ( event . ctrlKey ) keys . push ( 'ctrl' ) ;
783
+ if ( event . shiftKey ) keys . push ( 'shift' ) ;
784
+ if ( event . altKey ) keys . push ( 'alt' ) ;
785
+ if ( event . metaKey ) keys . push ( 'meta' ) ;
786
+
787
+ // Map special keys to names if needed
788
+ const keyMap = {
789
+ ' ' : 'space'
790
+ } ;
791
+
792
+ const key = keyMap [ event . key ] || event . key . toLowerCase ( ) ;
793
+
794
+ // If it's a normal key (not a modifier), add it to the keys array
795
+ if ( ! [ 'shift' , 'ctrl' , 'alt' , 'meta' ] . includes ( key ) ) {
796
+ keys . push ( key ) ;
797
+ }
798
+
799
+ const ret = keys . join ( '+' ) ;
800
+ console . log ( `Got keydown = ${ ret } ` ) ;
801
+ return ret ;
802
+ }
786
803
787
- // Map of key codes (e.which) to lambdas:
788
- let map = { } ;
789
-
790
- const kESC = 27 ;
791
- const kRETURN = 13 ;
792
- const kLEFT = 37 ;
793
- const kRIGHT = 39 ;
794
- const kUP = 38 ;
795
- const kDOWN = 40 ;
796
- const kB = 66 ; // B)ookmark
797
- const kC = 67 ; // C)opy
798
- const kT = 84 ; // T)ranslate
799
- const kM = 77 ; // The(M)e
800
- const kH = 72 ; // Toggle H)ighlight
801
- const kF = 70 ; // Toggle F)ocus mode
802
- const k1 = 49 ;
803
- const k2 = 50 ;
804
- const k3 = 51 ;
805
- const k4 = 52 ;
806
- const k5 = 53 ;
807
- const kI = 73 ;
808
- const kW = 87 ;
809
-
810
- map [ kESC ] = ( ) => start_hover_mode ( ) ;
811
- map [ kRETURN ] = ( ) => start_hover_mode ( ) ;
812
804
805
+ function get_right_increment ( ) {
813
806
// read/index.js has some data rendered at the top of the page.
814
807
const lang_is_rtl = $ ( '#lang_is_rtl' ) ;
815
- let left_increment = - 1 ;
816
- let right_increment = 1 ;
817
- if ( lang_is_rtl == null )
808
+ if ( lang_is_rtl == null ) {
818
809
console . log ( "ERROR: missing lang control." ) ;
819
- else {
820
- const is_rtl = ( lang_is_rtl . val ( ) . toLowerCase ( ) == "true" ) ;
821
- if ( is_rtl ) {
822
- left_increment = 1 ;
823
- right_increment = - 1 ;
824
- }
810
+ return 1 ; // fallback.
811
+ }
812
+ const is_rtl = ( lang_is_rtl . val ( ) . toLowerCase ( ) == "true" ) ;
813
+ return is_rtl ? - 1 : 1 ;
814
+ }
815
+
816
+
817
+ function handle_keydown ( e ) {
818
+ if ( $ ( 'span.word' ) . length == 0 ) {
819
+ return ; // Nothing to do.
825
820
}
826
821
827
- map [ kLEFT ] = ( ) => move_cursor ( left_increment ) ;
828
- map [ kRIGHT ] = ( ) => move_cursor ( right_increment ) ;
829
- map [ kUP ] = ( ) => increment_status_for_selected_elements ( e , + 1 ) ;
830
- map [ kDOWN ] = ( ) => increment_status_for_selected_elements ( e , - 1 ) ;
831
- map [ kB ] = ( ) => handle_bookmark ( ) ;
832
- map [ kC ] = ( ) => handle_copy ( e ) ;
833
- map [ kT ] = ( ) => show_sentence_translation ( e ) ;
834
- map [ kM ] = ( ) => next_theme ( ) ;
835
- map [ kH ] = ( ) => toggle_highlight ( ) ;
836
- map [ kF ] = ( ) => toggleFocus ( ) ;
837
- map [ k1 ] = ( ) => update_status_for_marked_elements ( 1 ) ;
838
- map [ k2 ] = ( ) => update_status_for_marked_elements ( 2 ) ;
839
- map [ k3 ] = ( ) => update_status_for_marked_elements ( 3 ) ;
840
- map [ k4 ] = ( ) => update_status_for_marked_elements ( 4 ) ;
841
- map [ k5 ] = ( ) => update_status_for_marked_elements ( 5 ) ;
842
- map [ kI ] = ( ) => update_status_for_marked_elements ( 98 ) ;
843
- map [ kW ] = ( ) => update_status_for_marked_elements ( 99 ) ;
844
-
845
- if ( e . which in map ) {
846
- let a = map [ e . which ] ;
847
- a ( ) ;
822
+ // User hotkeys, to be read from UserSettings.
823
+ const user_keys = {
824
+ 'HotkeyStartHover' : 'escape' ,
825
+ 'HotkeyPrevWord' : 'arrowleft' ,
826
+ 'HotkeyNextWord' : 'arrowright' ,
827
+ 'HotkeyStatusUp' : 'arrowup' ,
828
+ 'HotkeyStatusDown' : 'arrowdown' ,
829
+ 'HotkeyBookmark' : 'b' ,
830
+ 'HotkeyCopySentence' : 'c' ,
831
+ 'HotkeyCopyPara' : 'shift+c' ,
832
+ 'HotkeyTranslateSentence' : 't' ,
833
+ 'HotkeyTranslatePara' : 'shift+t' ,
834
+ 'HotkeyNextTheme' : 'm' ,
835
+ 'HotkeyToggleHighlight' : 'h' ,
836
+ 'HotkeyToggleFocus' : 'f' ,
837
+ 'HotkeyStatus1' : '1' ,
838
+ 'HotkeyStatus2' : '2' ,
839
+ 'HotkeyStatus3' : '3' ,
840
+ 'HotkeyStatus4' : '4' ,
841
+ 'HotkeyStatus5' : '5' ,
842
+ 'HotkeyStatusIgnore' : 'i' ,
843
+ 'HotkeyStatusWellKnown' : 'w' ,
844
+ } ;
845
+
846
+ // Map of shortcuts to lambdas:
847
+ let map = {
848
+ [ user_keys [ 'HotkeyStartHover' ] ] : ( ) => start_hover_mode ( ) ,
849
+ [ user_keys [ 'HotkeyPrevWord' ] ] : ( ) => move_cursor ( - 1 * get_right_increment ( ) ) ,
850
+ [ user_keys [ 'HotkeyNextWord' ] ] : ( ) => move_cursor ( get_right_increment ( ) ) ,
851
+ [ user_keys [ 'HotkeyStatusUp' ] ] : ( ) => increment_status_for_selected_elements ( + 1 ) ,
852
+ [ user_keys [ 'HotkeyStatusDown' ] ] : ( ) => increment_status_for_selected_elements ( - 1 ) ,
853
+ [ user_keys [ 'HotkeyBookmark' ] ] : ( ) => handle_bookmark ( ) ,
854
+ [ user_keys [ 'HotkeyCopySentence' ] ] : ( ) => handle_copy ( 'sentence-id' ) ,
855
+ [ user_keys [ 'HotkeyCopyPara' ] ] : ( ) => handle_copy ( 'paragraph-id' ) ,
856
+ [ user_keys [ 'HotkeyTranslateSentence' ] ] : ( ) => handle_translate ( 'sentence-id' ) ,
857
+ [ user_keys [ 'HotkeyTranslatePara' ] ] : ( ) => handle_translate ( 'paragraph-id' ) ,
858
+ [ user_keys [ 'HotkeyNextTheme' ] ] : ( ) => next_theme ( ) ,
859
+ [ user_keys [ 'HotkeyToggleHighlight' ] ] : ( ) => toggle_highlight ( ) ,
860
+ [ user_keys [ 'HotkeyToggleFocus' ] ] : ( ) => toggleFocus ( ) ,
861
+ [ user_keys [ 'HotkeyStatus1' ] ] : ( ) => update_status_for_marked_elements ( 1 ) ,
862
+ [ user_keys [ 'HotkeyStatus2' ] ] : ( ) => update_status_for_marked_elements ( 2 ) ,
863
+ [ user_keys [ 'HotkeyStatus3' ] ] : ( ) => update_status_for_marked_elements ( 3 ) ,
864
+ [ user_keys [ 'HotkeyStatus4' ] ] : ( ) => update_status_for_marked_elements ( 4 ) ,
865
+ [ user_keys [ 'HotkeyStatus5' ] ] : ( ) => update_status_for_marked_elements ( 5 ) ,
866
+ [ user_keys [ 'HotkeyStatusIgnore' ] ] : ( ) => update_status_for_marked_elements ( 98 ) ,
867
+ [ user_keys [ 'HotkeyStatusWellKnown' ] ] : ( ) => update_status_for_marked_elements ( 99 ) ,
868
+ }
869
+
870
+ const ks = getKeyString ( e ) ;
871
+ if ( ks in map ) {
872
+ // Override any existing event - e.g., if "up" arrow is in the map,
873
+ // don't scroll screen.
874
+ e . preventDefault ( ) ;
875
+ map [ ks ] ( ) ;
848
876
}
849
877
else {
850
- // console.log('unhandled key ' + e.which );
878
+ // console.log('unhandled key ' + ks );
851
879
}
852
880
}
853
881
@@ -944,12 +972,7 @@ function post_bulk_update(updates) {
944
972
/**
945
973
* Change status using arrow keys for selected or hovered elements.
946
974
*/
947
- function increment_status_for_selected_elements ( e , shiftBy ) {
948
- // Don't scroll screen. If screen scrolling happens, then pressing
949
- // "up" will both scroll up *and* change the status the selected term,
950
- // which is odd.
951
- e . preventDefault ( ) ;
952
-
975
+ function increment_status_for_selected_elements ( shiftBy ) {
953
976
const elements = Array . from ( document . querySelectorAll ( 'span.kwordmarked, span.wordhover' ) ) ;
954
977
if ( elements . length == 0 )
955
978
return ;
0 commit comments