Skip to content

Commit 67d3a5e

Browse files
committed
fix: don't highlight text when dragging elements
Fixes #28
1 parent bd25b99 commit 67d3a5e

File tree

2 files changed

+45
-6
lines changed

2 files changed

+45
-6
lines changed

src/draggable.directive.ts

+27-6
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
OnDestroy,
1010
OnChanges,
1111
NgZone,
12-
SimpleChanges
12+
SimpleChanges,
13+
Inject
1314
} from '@angular/core';
1415
import { Subject, Observable, merge } from 'rxjs';
1516
import {
@@ -23,6 +24,7 @@ import {
2324
filter
2425
} from 'rxjs/operators';
2526
import { DraggableHelper } from './draggable-helper.provider';
27+
import { DOCUMENT } from '@angular/common';
2628

2729
export interface Coordinates {
2830
x: number;
@@ -150,12 +152,35 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
150152
public element: ElementRef<HTMLElement>,
151153
private renderer: Renderer2,
152154
private draggableHelper: DraggableHelper,
153-
private zone: NgZone
155+
private zone: NgZone,
156+
@Inject(DOCUMENT) private document: any
154157
) {}
155158

156159
ngOnInit(): void {
157160
this.checkEventListeners();
158161

162+
// hack to prevent text getting selected in safari while dragging
163+
this.pointerDown.subscribe(() => {
164+
const style: HTMLStyleElement = this.renderer.createElement('style');
165+
this.renderer.setAttribute(style, 'type', 'text/css');
166+
this.renderer.appendChild(
167+
style,
168+
this.renderer.createText(`
169+
body * {
170+
-moz-user-select: none;
171+
-ms-user-select: none;
172+
-webkit-user-select: none;
173+
user-select: none;
174+
}
175+
`)
176+
);
177+
this.document.head.appendChild(style);
178+
179+
this.pointerUp.pipe(take(1)).subscribe(() => {
180+
this.document.head.removeChild(style);
181+
});
182+
});
183+
159184
const pointerDrag: Observable<any> = this.pointerDown.pipe(
160185
filter(() => this.canDrag()),
161186
mergeMap((pointerDownEvent: PointerEvent) => {
@@ -167,8 +192,6 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
167192

168193
const pointerMove: Observable<Coordinates> = this.pointerMove.pipe(
169194
map((pointerMoveEvent: PointerEvent) => {
170-
pointerMoveEvent.event.preventDefault();
171-
172195
return {
173196
currentDrag,
174197
x: pointerMoveEvent.clientX - pointerDownEvent.clientX,
@@ -220,8 +243,6 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
220243
);
221244

222245
dragStart$.subscribe(() => {
223-
pointerDownEvent.event.preventDefault();
224-
225246
this.zone.run(() => {
226247
this.dragStart.next({ x: 0, y: 0 });
227248
});

test/draggable.directive.spec.ts

+18
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ describe('draggable directive', () => {
5858
afterEach(() => {
5959
fixture.destroy();
6060
document.body.innerHTML = '';
61+
Array.from(document.head.getElementsByTagName('style')).forEach(style => {
62+
document.head.removeChild(style);
63+
});
6164
});
6265

6366
it('should make the element draggable', () => {
@@ -618,4 +621,19 @@ describe('draggable directive', () => {
618621
expect((ghostElement as HTMLElement).hasAttribute('mwldraggable')).to.be
619622
.true;
620623
});
624+
625+
it('should make all elements on the page unable to select text while dragging', () => {
626+
const tmp = document.createElement('div');
627+
tmp.innerHTML = 'foo';
628+
document.body.appendChild(tmp);
629+
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
630+
const draggableElement: HTMLElement =
631+
fixture.componentInstance.draggable.element.nativeElement;
632+
triggerDomEvent('mousedown', draggableElement, { clientX: 5, clientY: 10 });
633+
expect(getComputedStyle(tmp).userSelect).to.equal('none');
634+
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
635+
expect(getComputedStyle(tmp).userSelect).to.equal('none');
636+
triggerDomEvent('mouseup', draggableElement, { clientX: 7, clientY: 8 });
637+
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
638+
});
621639
});

0 commit comments

Comments
 (0)