@@ -18,6 +18,11 @@ import {
1818
1919import "./style.css" ;
2020
21+ const isMobileDevice = ( ) : boolean => {
22+ if ( typeof window === "undefined" || typeof navigator === "undefined" ) return false ;
23+ return / M o b i | A n d r o i d | i P h o n e | i P a d | i P o d | W i n d o w s P h o n e | I E M o b i l e | O p e r a M i n i / i. test ( navigator . userAgent || "" ) ;
24+ } ;
25+
2126const toLuminance = ( color : Color , y : number = 0.6 ) => {
2227 // This is mostly used to adapt to light/dark mode
2328
@@ -539,34 +544,45 @@ export class AnnotatedText extends React.Component<TextData & TextMethods> {
539544 }
540545
541546 componentDidMount ( ) {
542- document . addEventListener ( 'selectionchange' , this . _boundSelectionChange ) ;
547+ if ( ! isMobileDevice ( ) ) return ;
548+ document . addEventListener ( "selectionchange" , this . _boundSelectionChange ) ;
543549 }
544550
545551 componentWillUnmount ( ) {
546- document . removeEventListener ( 'selectionchange' , this . _boundSelectionChange ) ;
552+ if ( ! isMobileDevice ( ) ) return ;
553+ document . removeEventListener ( "selectionchange" , this . _boundSelectionChange ) ;
547554 }
548555
549556 private isNodeInside = ( node : Node | null ) => {
550557 const container = this . containerRef . current ;
551- return ! ! container && ! ! node && ( node === container || container . contains ( node as Node ) ) ;
558+ return (
559+ ! ! container &&
560+ ! ! node &&
561+ ( node === container || container . contains ( node as Node ) )
562+ ) ;
552563 } ;
553564
554565 handleSelectionChange = ( ) => {
555566 if ( this . _ignoreSelectionChange ) return ;
556- const sel = typeof window !== ' undefined' ? window . getSelection ?.( ) : null ;
567+ const sel = typeof window !== " undefined" ? window . getSelection ?.( ) : null ;
557568 if ( ! sel || sel . isCollapsed ) return ;
558- if ( ! this . isNodeInside ( sel . anchorNode ) && ! this . isNodeInside ( sel . focusNode ) ) return ;
569+ if ( ! this . isNodeInside ( sel . anchorNode ) && ! this . isNodeInside ( sel . focusNode ) )
570+ return ;
559571 // Wait a tick so the browser finalizes the selection on mobile
560572 setTimeout ( ( ) => {
561573 const spans = getDocumentSelectedRanges ( ) ;
562574 if ( spans && spans . length > 0 ) {
563575 this . _ignoreSelectionChange = true ;
564576 this . props . onMouseSelect ?.( spans , makeModKeys ( { } as any ) ) ;
565- try { window . getSelection ( ) ?. removeAllRanges ( ) ; } catch { }
566- setTimeout ( ( ) => { this . _ignoreSelectionChange = false ; } , 0 ) ;
577+ try {
578+ window . getSelection ( ) ?. removeAllRanges ( ) ;
579+ } catch { }
580+ setTimeout ( ( ) => {
581+ this . _ignoreSelectionChange = false ;
582+ } , 0 ) ;
567583 }
568584 } , 0 ) ;
569- }
585+ } ;
570586
571587 handleKeyUp = ( event : React . KeyboardEvent ) => {
572588 // if (event.metaKey || event.key === 'Meta' || event.shiftKey || event.key === 'Shift') {
@@ -590,18 +606,35 @@ export class AnnotatedText extends React.Component<TextData & TextMethods> {
590606 }
591607 } ;
592608
593- handleMouseUp = (
609+ handleTouchUp = (
594610 event : React . MouseEvent < HTMLElement > | React . TouchEvent < HTMLElement >
595611 ) => {
596612 const spans = getDocumentSelectedRanges ( ) ;
597613 this . _ignoreSelectionChange = true ; // prevent our own clear from retriggering
598- try { window . getSelection ( ) ?. removeAllRanges ( ) ; } catch { }
614+ try {
615+ window . getSelection ( ) ?. removeAllRanges ( ) ;
616+ } catch { }
599617 if ( spans . length > 0 ) {
600618 this . props . onMouseSelect ?.( spans , makeModKeys ( event as any ) ) ;
601619 } else {
602620 this . props . onMouseSelect ?.( [ ] , makeModKeys ( event as any ) ) ;
603621 }
604- setTimeout ( ( ) => { this . _ignoreSelectionChange = false ; } , 0 ) ;
622+ setTimeout ( ( ) => {
623+ this . _ignoreSelectionChange = false ;
624+ } , 0 ) ;
625+ } ;
626+
627+ handleMouseUp = ( event : React . MouseEvent < HTMLElement > ) => {
628+ if ( event . type === "mouseup" ) {
629+ const spans = getDocumentSelectedRanges ( ) ;
630+ window . getSelection ( ) . removeAllRanges ( ) ;
631+ if ( spans . length > 0 ) {
632+ //this.props.onMouseSelect([...this.props.mouse_selection, ...spans]);
633+ this . props . onMouseSelect ?.( spans , makeModKeys ( event ) ) ;
634+ } else {
635+ this . props . onMouseSelect ?.( [ ] , makeModKeys ( event ) ) ;
636+ }
637+ }
605638 } ;
606639
607640 handleClickSpan = ( event , span_id ) => {
@@ -669,7 +702,10 @@ export class AnnotatedText extends React.Component<TextData & TextMethods> {
669702 className = "metanno-text-view"
670703 ref = { this . containerRef }
671704 onMouseUp = { this . handleMouseUp }
672- onTouchEnd = { ( e ) => { e . persist ?.( ) ; setTimeout ( ( ) => this . handleMouseUp ( e as any ) , 0 ) ; } }
705+ onTouchEnd = { ( e ) => {
706+ e . persist ?.( ) ;
707+ setTimeout ( ( ) => this . handleTouchUp ( e as any ) , 0 ) ;
708+ } }
673709 onTouchCancel = { ( e ) => this . props . onMouseSelect ?.( [ ] , makeModKeys ( e ) ) }
674710 onKeyDown = { this . handleKeyDown }
675711 onKeyUp = { this . handleKeyUp }
0 commit comments