|
1 | 1 | import { |
2 | | - ApplicationRef, ComponentFactoryResolver, |
| 2 | + ApplicationRef, |
| 3 | + ComponentFactoryResolver, |
3 | 4 | ComponentRef, |
4 | 5 | Directive, |
5 | 6 | ElementRef, |
6 | 7 | EmbeddedViewRef, |
7 | 8 | Injector, |
| 9 | + Input, |
8 | 10 | NgZone, |
9 | 11 | OnDestroy, |
10 | 12 | OnInit |
@@ -33,6 +35,9 @@ interface SelectionRectangle { |
33 | 35 | }) |
34 | 36 | export class TextSelectDirective implements OnInit, OnDestroy { |
35 | 37 |
|
| 38 | + @Input() |
| 39 | + showTTSControls = true; |
| 40 | + |
36 | 41 | hasSelection = false; |
37 | 42 | selectedText = ''; |
38 | 43 |
|
@@ -89,55 +94,57 @@ export class TextSelectDirective implements OnInit, OnDestroy { |
89 | 94 | // setting up a zero-delay timeout to wait for the selection to be cleared |
90 | 95 | // this solves the issue of the previous selection not being cleared before the mouseup event |
91 | 96 | // setTimeout(() => { |
92 | | - const selection = document.getSelection(); |
93 | | - const stringSelection = selection.toString().trim(); |
94 | | - const previousSelection = this.selectedText; |
95 | | - if (this.hasSelection) { |
| 97 | + const selection = document.getSelection(); |
| 98 | + const stringSelection = selection.toString().trim(); |
| 99 | + const previousSelection = this.selectedText; |
| 100 | + if (this.hasSelection) { |
| 101 | + this.zone.runGuarded(() => { |
| 102 | + this.hasSelection = false; |
| 103 | + this.selectedText = ''; |
| 104 | + this.componentRef.destroy(); |
| 105 | + this.componentRef = null; |
| 106 | + }); |
| 107 | + } |
| 108 | + |
| 109 | + // check if there is a selection and if it is different from the previous one |
| 110 | + // (to handle a bug in browsers that fires the mouseup event again if clicking on the selection) |
| 111 | + if (!selection.rangeCount || !stringSelection || previousSelection === stringSelection) { |
| 112 | + return; |
| 113 | + } |
| 114 | + let range = selection.getRangeAt(0); |
| 115 | + let rangeContainer = this.getRangeContainer(range); |
| 116 | + if (this.elementRef.nativeElement.contains(rangeContainer)) { |
| 117 | + let viewportRectangle = range.getBoundingClientRect(); |
| 118 | + let bodyRelativeRectangle = this.rectangleRelativeToBody(viewportRectangle, rangeContainer); |
| 119 | + if (stringSelection) { |
96 | 120 | this.zone.runGuarded(() => { |
97 | | - this.hasSelection = false; |
98 | | - this.selectedText = ''; |
99 | | - this.componentRef.destroy(); |
100 | | - this.componentRef = null; |
101 | | - }); |
102 | | - } |
| 121 | + this.hasSelection = true; |
| 122 | + if (this.componentRef === null) { |
| 123 | + const componentFactory = |
| 124 | + this.componentFactoryResolver.resolveComponentFactory(TextSelectionTooltipComponent); |
| 125 | + this.componentRef = componentFactory.create(this.injector); |
103 | 126 |
|
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) { |
107 | | - return; |
108 | | - } |
109 | | - let range = selection.getRangeAt(0); |
110 | | - let rangeContainer = this.getRangeContainer(range); |
111 | | - if (this.elementRef.nativeElement.contains(rangeContainer)) { |
112 | | - let viewportRectangle = range.getBoundingClientRect(); |
113 | | - let bodyRelativeRectangle = this.rectangleRelativeToBody(viewportRectangle, rangeContainer); |
114 | | - if (stringSelection) { |
115 | | - this.zone.runGuarded(() => { |
116 | | - this.hasSelection = true; |
117 | | - if (this.componentRef === null) { |
118 | | - const componentFactory = |
119 | | - this.componentFactoryResolver.resolveComponentFactory(TextSelectionTooltipComponent); |
120 | | - this.componentRef = componentFactory.create(this.injector); |
121 | | - |
122 | | - this.appRef.attachView(this.componentRef.hostView); |
123 | | - |
124 | | - const domElem = |
125 | | - (this.componentRef.hostView as EmbeddedViewRef<any>) |
126 | | - .rootNodes[0] as HTMLElement; |
127 | | - |
128 | | - document.body.appendChild(domElem); |
129 | | - |
130 | | - this.componentRef.instance.elementRectangleLeft = bodyRelativeRectangle.left; |
131 | | - this.componentRef.instance.elementRectangleTop = bodyRelativeRectangle.top; |
132 | | - this.componentRef.instance.elementRectangleWidth = bodyRelativeRectangle.width; |
133 | | - this.componentRef.instance.elementRectangleHeight = bodyRelativeRectangle.height; |
134 | | - this.componentRef.instance.text = stringSelection; |
135 | | - |
136 | | - this.selectedText = stringSelection; |
137 | | - } |
138 | | - }); |
139 | | - } |
| 127 | + this.appRef.attachView(this.componentRef.hostView); |
| 128 | + |
| 129 | + const domElem = |
| 130 | + (this.componentRef.hostView as EmbeddedViewRef<any>) |
| 131 | + .rootNodes[0] as HTMLElement; |
| 132 | + |
| 133 | + document.body.appendChild(domElem); |
| 134 | + |
| 135 | + this.componentRef.instance.elementRectangleLeft = bodyRelativeRectangle.left; |
| 136 | + this.componentRef.instance.elementRectangleTop = bodyRelativeRectangle.top; |
| 137 | + this.componentRef.instance.elementRectangleWidth = bodyRelativeRectangle.width; |
| 138 | + this.componentRef.instance.elementRectangleHeight = bodyRelativeRectangle.height; |
| 139 | + this.componentRef.instance.text = stringSelection; |
| 140 | + |
| 141 | + this.componentRef.instance.showTTSControls = this.showTTSControls; |
| 142 | + |
| 143 | + this.selectedText = stringSelection; |
| 144 | + } |
| 145 | + }); |
140 | 146 | } |
| 147 | + } |
141 | 148 | // }); |
142 | 149 | } |
143 | 150 |
|
|
0 commit comments