@@ -38,9 +38,9 @@ function getCaretCharacterOffsetWithin(element) {
3838
3939function updateSelection ( ) {
4040 var sel = window . getSelection ( ) ;
41- // if(window.getSelection().baseNode.parentNode.id != "document_code_ui_1-focal_text") return;
42-
43- if ( sel . rangeCount > 0 ) {
41+ // if(window.getSelection().baseNode.parentNode.id != "document_code_ui_1-focal_text") return;
42+
43+ if ( sel . rangeCount > 0 ) {
4444 var range = sel . getRangeAt ( 0 ) ;
4545 var el = document . getElementById ( "document_code_ui_1-focal_text" )
4646
@@ -63,16 +63,46 @@ function updateSelection() {
6363 }
6464
6565 var tag_position_value = startOffset . toString ( ) + '-' + endOffset . toString ( ) ;
66- console . log ( "tag_position" + tag_position_value )
66+ // console.log("tag_position" + tag_position_value)
6767 Shiny . setInputValue ( 'document_code_ui_1-tag_position' , tag_position_value ) ;
68- }
68+ }
6969}
7070
71- // Function to send calculated positions to Shiny
71+ // Attach selection listeners to the focal text element
7272$ ( document ) . ready ( function ( ) {
73- document . addEventListener ( 'mouseup' , updateSelection ) ;
74- document . addEventListener ( 'keyup' , updateSelection ) ;
75- document . addEventListener ( 'touchend' , updateSelection ) ;
73+ function attachSelectionListeners ( el ) {
74+ if ( ! el ) return ;
75+
76+ // If element is contenteditable, ensure it can receive keyboard focus
77+ if ( el . isContentEditable && ! el . hasAttribute ( 'tabindex' ) ) {
78+ el . setAttribute ( 'tabindex' , '0' ) ;
79+ }
80+
81+ // Element-level events
82+ el . addEventListener ( 'mouseup' , updateSelection , false ) ;
83+ el . addEventListener ( 'touchend' , updateSelection , false ) ;
84+ // el.addEventListener('input', updateSelection, false); // catches edits in contenteditable
85+ el . addEventListener ( 'keyup' , updateSelection , false ) ;
86+
87+ // Document-level selectionchange: only act when selection is inside the target element
88+ document . addEventListener ( 'selectionchange' , function ( ) {
89+ var sel = window . getSelection ( ) ;
90+ if ( ! sel || sel . rangeCount === 0 ) return ;
91+ var node = sel . anchorNode ;
92+ // climb from text nodes to element nodes
93+ while ( node && node . nodeType !== 1 ) {
94+ node = node . parentNode ;
95+ }
96+ if ( node && el . contains ( node ) ) {
97+ updateSelection ( ) ;
98+ }
99+ } , false ) ;
100+ }
101+
102+ var el = document . getElementById ( 'document_code_ui_1-focal_text' ) ;
103+ if ( el ) {
104+ attachSelectionListeners ( el ) ;
105+ }
76106} )
77107
78108// Obtain information from iframe and send to Shiny
@@ -178,7 +208,6 @@ function findScrollElement(targetId) {
178208
179209 if ( matchingElements . length > 0 ) {
180210 return matchingElements ;
181- return matchingElements ;
182211 } else {
183212 console . log ( "No matching segment found." ) ;
184213 return null ;
0 commit comments