Skip to content

Commit

Permalink
fix: disable text selection in safari
Browse files Browse the repository at this point in the history
  • Loading branch information
mattlewis92 committed Apr 19, 2020
1 parent 0e959d0 commit d044523
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -960,6 +960,33 @@ describe('draggable directive', () => {
.true;
});

it('should make all elements on the page unable to select text while dragging', () => {
const tmp = document.createElement('div');
tmp.innerHTML = 'foo';
document.body.appendChild(tmp);
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
const draggableElement =
fixture.componentInstance.draggableElement.nativeElement;
triggerDomEvent('mousedown', draggableElement, {
clientX: 5,
clientY: 10,
button: 0,
});
expect(getComputedStyle(tmp).userSelect).to.equal('none');
triggerDomEvent('mousemove', draggableElement, {
clientX: 7,
clientY: 10,
button: 0,
});
expect(getComputedStyle(tmp).userSelect).to.equal('none');
triggerDomEvent('mouseup', draggableElement, {
clientX: 7,
clientY: 8,
button: 0,
});
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
});

it('should cancel the drag', () => {
const draggableElement =
fixture.componentInstance.draggableElement.nativeElement;
Expand Down Expand Up @@ -1006,13 +1033,19 @@ describe('draggable directive', () => {
button: 0,
});
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 10 });
expect(getComputedStyle(document.body.children[0]).userSelect).to.equal(
'none'
);
triggerDomEvent('mousemove', draggableElement, { clientX: 7, clientY: 8 });
fixture.destroy();
expect(fixture.componentInstance.dragEnd).to.have.been.calledWith({
x: 2,
y: -2,
dragCancelled: false,
});
expect(getComputedStyle(document.body.children[0]).userSelect).to.equal(
'auto'
);
});

it('should use the contents of the ghost element template as the inner html of the ghost element', () => {
Expand Down Expand Up @@ -1079,35 +1112,25 @@ describe('draggable directive', () => {
});
});

it('should prevent text from being selected while dragging', () => {
it('should allow elements to be selected if clicking but not dragging the element', () => {
const tmp = document.createElement('div');
tmp.innerHTML = 'foo';
document.body.appendChild(tmp);
const preventDefault = sinon.spy();
triggerDomEvent('selectstart', tmp, {
preventDefault,
});
expect(preventDefault).not.to.have.been.called;
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
const draggableElement =
fixture.componentInstance.draggableElement.nativeElement;
triggerDomEvent('mousedown', draggableElement, {
clientX: 5,
clientY: 10,
button: 0,
});
triggerDomEvent('selectstart', tmp, {
preventDefault,
});
expect(preventDefault).to.have.been.calledOnce;
expect(getComputedStyle(tmp).userSelect).to.equal('none');
triggerDomEvent('mouseup', draggableElement, {
clientX: 5,
clientY: 10,
button: 0,
});
triggerDomEvent('selectstart', tmp, {
preventDefault,
});
expect(preventDefault).to.have.been.calledOnce;
expect(getComputedStyle(tmp).userSelect).to.equal('auto');
});

it('should allow for draggable elements to be inside other draggable elements', () => {
Expand Down
37 changes: 22 additions & 15 deletions projects/angular-draggable-droppable/src/lib/draggable.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,24 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
pointerDownEvent.event.stopPropagation();
}

// hack to prevent text getting selected in safari while dragging
const globalDragStyle: HTMLStyleElement = this.renderer.createElement(
'style'
);
this.renderer.setAttribute(globalDragStyle, 'type', 'text/css');
this.renderer.appendChild(
globalDragStyle,
this.renderer.createText(`
body * {
-moz-user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
user-select: none;
}
`)
);
this.document.head.appendChild(globalDragStyle);

const startScrollPosition = this.getScrollPosition();

const scrollContainerScroll$ = new Observable((observer) => {
Expand Down Expand Up @@ -392,10 +410,6 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
margin: '0',
willChange: 'transform',
pointerEvents: 'none',
userSelect: 'none',
touchAction: 'none',
'-webkit-user-drag': 'none',
'-webkit-tap-highlight-color': 'transparant',
});

if (this.ghostElementTemplate) {
Expand Down Expand Up @@ -459,17 +473,10 @@ export class DraggableDirective implements OnInit, OnChanges, OnDestroy {
currentDrag$.complete();
});

const selectionStart$ = new Observable<Event>((observer) => {
return this.renderer.listen('document', 'selectstart', (e) =>
observer.next(e)
);
});

// hack to prevent text getting selected in safari while dragging
selectionStart$
.pipe(takeUntil(merge(dragComplete$, dragEnded$)))
.subscribe((event) => {
event.preventDefault();
merge(dragComplete$, dragEnded$)
.pipe(take(1))
.subscribe(() => {
this.document.head.removeChild(globalDragStyle);
});

return pointerMove;
Expand Down

0 comments on commit d044523

Please sign in to comment.