a2538f9359bfc04faea85be7f5480b9723cf5316ea6affb0eaf1c050e14dcfa417800d04a56d811fb6553380ea22c5051ef76512a8f7e69e7205f7385d6bf9 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import * as dom from '../../../base/browser/dom.js';
  6. import * as platform from '../../../base/common/platform.js';
  7. import { EventType, Gesture } from '../../../base/browser/touch.js';
  8. import { Disposable } from '../../../base/common/lifecycle.js';
  9. import { MouseHandler } from './mouseHandler.js';
  10. import { EditorMouseEvent, EditorPointerEventFactory } from '../editorDom.js';
  11. import { BrowserFeatures } from '../../../base/browser/canIUse.js';
  12. import { TextAreaSyntethicEvents } from './textAreaInput.js';
  13. /**
  14. * Currently only tested on iOS 13/ iPadOS.
  15. */
  16. export class PointerEventHandler extends MouseHandler {
  17. constructor(context, viewController, viewHelper) {
  18. super(context, viewController, viewHelper);
  19. this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode));
  20. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e)));
  21. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e)));
  22. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false)));
  23. this._lastPointerType = 'mouse';
  24. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, 'pointerdown', (e) => {
  25. const pointerType = e.pointerType;
  26. if (pointerType === 'mouse') {
  27. this._lastPointerType = 'mouse';
  28. return;
  29. }
  30. else if (pointerType === 'touch') {
  31. this._lastPointerType = 'touch';
  32. }
  33. else {
  34. this._lastPointerType = 'pen';
  35. }
  36. }));
  37. // PonterEvents
  38. const pointerEvents = new EditorPointerEventFactory(this.viewHelper.viewDomNode);
  39. this._register(pointerEvents.onPointerMove(this.viewHelper.viewDomNode, (e) => this._onMouseMove(e)));
  40. this._register(pointerEvents.onPointerUp(this.viewHelper.viewDomNode, (e) => this._onMouseUp(e)));
  41. this._register(pointerEvents.onPointerLeave(this.viewHelper.viewDomNode, (e) => this._onMouseLeave(e)));
  42. this._register(pointerEvents.onPointerDown(this.viewHelper.viewDomNode, (e, pointerId) => this._onMouseDown(e, pointerId)));
  43. }
  44. onTap(event) {
  45. if (!event.initialTarget || !this.viewHelper.linesContentDomNode.contains(event.initialTarget)) {
  46. return;
  47. }
  48. event.preventDefault();
  49. this.viewHelper.focusTextArea();
  50. const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false);
  51. if (target.position) {
  52. // this.viewController.moveTo(target.position);
  53. this.viewController.dispatchMouse({
  54. position: target.position,
  55. mouseColumn: target.position.column,
  56. startedOnLineNumbers: false,
  57. mouseDownCount: event.tapCount,
  58. inSelectionMode: false,
  59. altKey: false,
  60. ctrlKey: false,
  61. metaKey: false,
  62. shiftKey: false,
  63. leftButton: false,
  64. middleButton: false,
  65. onInjectedText: target.type === 6 /* MouseTargetType.CONTENT_TEXT */ && target.detail.injectedText !== null
  66. });
  67. }
  68. }
  69. onChange(e) {
  70. if (this._lastPointerType === 'touch') {
  71. this._context.viewModel.viewLayout.deltaScrollNow(-e.translationX, -e.translationY);
  72. }
  73. }
  74. _onMouseDown(e, pointerId) {
  75. if (e.browserEvent.pointerType === 'touch') {
  76. return;
  77. }
  78. super._onMouseDown(e, pointerId);
  79. }
  80. }
  81. class TouchHandler extends MouseHandler {
  82. constructor(context, viewController, viewHelper) {
  83. super(context, viewController, viewHelper);
  84. this._register(Gesture.addTarget(this.viewHelper.linesContentDomNode));
  85. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Tap, (e) => this.onTap(e)));
  86. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Change, (e) => this.onChange(e)));
  87. this._register(dom.addDisposableListener(this.viewHelper.linesContentDomNode, EventType.Contextmenu, (e) => this._onContextMenu(new EditorMouseEvent(e, false, this.viewHelper.viewDomNode), false)));
  88. }
  89. onTap(event) {
  90. event.preventDefault();
  91. this.viewHelper.focusTextArea();
  92. const target = this._createMouseTarget(new EditorMouseEvent(event, false, this.viewHelper.viewDomNode), false);
  93. if (target.position) {
  94. // Send the tap event also to the <textarea> (for input purposes)
  95. const event = document.createEvent('CustomEvent');
  96. event.initEvent(TextAreaSyntethicEvents.Tap, false, true);
  97. this.viewHelper.dispatchTextAreaEvent(event);
  98. this.viewController.moveTo(target.position);
  99. }
  100. }
  101. onChange(e) {
  102. this._context.viewModel.viewLayout.deltaScrollNow(-e.translationX, -e.translationY);
  103. }
  104. }
  105. export class PointerHandler extends Disposable {
  106. constructor(context, viewController, viewHelper) {
  107. super();
  108. if ((platform.isIOS && BrowserFeatures.pointerEvents)) {
  109. this.handler = this._register(new PointerEventHandler(context, viewController, viewHelper));
  110. }
  111. else if (window.TouchEvent) {
  112. this.handler = this._register(new TouchHandler(context, viewController, viewHelper));
  113. }
  114. else {
  115. this.handler = this._register(new MouseHandler(context, viewController, viewHelper));
  116. }
  117. }
  118. getTargetAtClientPoint(clientX, clientY) {
  119. return this.handler.getTargetAtClientPoint(clientX, clientY);
  120. }
  121. }