@@ -34,6 +34,7 @@ interface SelectionRectangle {
3434export class TextSelectDirective implements OnInit , OnDestroy {
3535
3636 hasSelection = false ;
37+ selectedText = '' ;
3738
3839 private componentRef : ComponentRef < any > = null ;
3940
@@ -87,17 +88,22 @@ export class TextSelectDirective implements OnInit, OnDestroy {
8788 private processSelection ( ) : void {
8889 // setting up a zero-delay timeout to wait for the selection to be cleared
8990 // this solves the issue of the previous selection not being cleared before the mouseup event
90- setTimeout ( ( ) => {
91+ // setTimeout(() => {
9192 const selection = document . getSelection ( ) ;
9293 const stringSelection = selection . toString ( ) . trim ( ) ;
94+ const previousSelection = this . selectedText ;
9395 if ( this . hasSelection ) {
9496 this . zone . runGuarded ( ( ) => {
9597 this . hasSelection = false ;
98+ this . selectedText = '' ;
99+ this . componentRef . destroy ( ) ;
100+ this . componentRef = null ;
96101 } ) ;
97- this . componentRef . destroy ( ) ;
98- this . componentRef = null ;
99102 }
100- if ( ! selection . rangeCount || ! stringSelection ) {
103+
104+ // check if there is a selection and if it is different from the previous one
105+ // (to handle a bug in browsers that fires the mouseup event again if clicking on the selection)
106+ if ( ! selection . rangeCount || ! stringSelection || previousSelection === stringSelection ) {
101107 return ;
102108 }
103109 let range = selection . getRangeAt ( 0 ) ;
@@ -108,27 +114,29 @@ export class TextSelectDirective implements OnInit, OnDestroy {
108114 if ( stringSelection ) {
109115 this . zone . runGuarded ( ( ) => {
110116 this . hasSelection = true ;
111- } ) ;
112- }
113- if ( this . componentRef === null ) {
114- const componentFactory =
115- this . componentFactoryResolver . resolveComponentFactory ( TextSelectionTooltipComponent ) ;
116- this . componentRef = componentFactory . create ( this . injector ) ;
117+ if ( this . componentRef === null ) {
118+ const componentFactory =
119+ this . componentFactoryResolver . resolveComponentFactory ( TextSelectionTooltipComponent ) ;
120+ this . componentRef = componentFactory . create ( this . injector ) ;
117121
118- this . appRef . attachView ( this . componentRef . hostView ) ;
122+ this . appRef . attachView ( this . componentRef . hostView ) ;
119123
120- const domElem =
121- ( this . componentRef . hostView as EmbeddedViewRef < any > )
122- . rootNodes [ 0 ] as HTMLElement ;
124+ const domElem =
125+ ( this . componentRef . hostView as EmbeddedViewRef < any > )
126+ . rootNodes [ 0 ] as HTMLElement ;
123127
124- document . body . appendChild ( domElem ) ;
128+ document . body . appendChild ( domElem ) ;
125129
126- this . componentRef . instance . left = localRectangle . left + localRectangle . width / 2 ;
127- this . componentRef . instance . top = localRectangle . top ;
128- this . componentRef . instance . text = stringSelection ;
130+ this . componentRef . instance . left = localRectangle . left + localRectangle . width / 2 ;
131+ this . componentRef . instance . top = localRectangle . top ;
132+ this . componentRef . instance . text = stringSelection ;
133+
134+ this . selectedText = stringSelection ;
135+ }
136+ } ) ;
129137 }
130138 }
131- } ) ;
139+ // });
132140 }
133141
134142 // Convert the given viewport-relative rectangle to a host-relative rectangle.
0 commit comments