pointer.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import '../../utils/dataTransfer/Clipboard.js';
  2. import { getTreeDiff } from '../../utils/misc/getTreeDiff.js';
  3. import { assertPointerEvents, hasPointerEvents } from '../../utils/pointer/cssPointerEvents.js';
  4. import { isDifferentPointerPosition } from './shared.js';
  5. import { getMouseEventButton } from './buttons.js';
  6. function _define_property(obj, key, value) {
  7. if (key in obj) {
  8. Object.defineProperty(obj, key, {
  9. value: value,
  10. enumerable: true,
  11. configurable: true,
  12. writable: true
  13. });
  14. } else {
  15. obj[key] = value;
  16. }
  17. return obj;
  18. }
  19. class Pointer {
  20. init(instance) {
  21. const target = this.getTarget(instance);
  22. const [, enter] = getTreeDiff(null, target);
  23. const init = this.getEventInit();
  24. assertPointerEvents(instance, target);
  25. instance.dispatchUIEvent(target, 'pointerover', init);
  26. enter.forEach((el)=>instance.dispatchUIEvent(el, 'pointerenter', init));
  27. return this;
  28. }
  29. move(instance, position) {
  30. const prevPosition = this.position;
  31. const prevTarget = this.getTarget(instance);
  32. this.position = position;
  33. if (!isDifferentPointerPosition(prevPosition, position)) {
  34. return;
  35. }
  36. const nextTarget = this.getTarget(instance);
  37. const init = this.getEventInit(-1);
  38. const [leave, enter] = getTreeDiff(prevTarget, nextTarget);
  39. return {
  40. leave: ()=>{
  41. if (hasPointerEvents(instance, prevTarget)) {
  42. if (prevTarget !== nextTarget) {
  43. instance.dispatchUIEvent(prevTarget, 'pointerout', init);
  44. leave.forEach((el)=>instance.dispatchUIEvent(el, 'pointerleave', init));
  45. }
  46. }
  47. },
  48. enter: ()=>{
  49. assertPointerEvents(instance, nextTarget);
  50. if (prevTarget !== nextTarget) {
  51. instance.dispatchUIEvent(nextTarget, 'pointerover', init);
  52. enter.forEach((el)=>instance.dispatchUIEvent(el, 'pointerenter', init));
  53. }
  54. },
  55. move: ()=>{
  56. instance.dispatchUIEvent(nextTarget, 'pointermove', init);
  57. }
  58. };
  59. }
  60. down(instance, button = 0) {
  61. if (this.isDown) {
  62. return;
  63. }
  64. const target = this.getTarget(instance);
  65. assertPointerEvents(instance, target);
  66. this.isDown = true;
  67. this.isPrevented = !instance.dispatchUIEvent(target, 'pointerdown', this.getEventInit(button));
  68. }
  69. up(instance, button = 0) {
  70. if (!this.isDown) {
  71. return;
  72. }
  73. const target = this.getTarget(instance);
  74. assertPointerEvents(instance, target);
  75. this.isPrevented = false;
  76. this.isDown = false;
  77. instance.dispatchUIEvent(target, 'pointerup', this.getEventInit(button));
  78. }
  79. release(instance) {
  80. const target = this.getTarget(instance);
  81. const [leave] = getTreeDiff(target, null);
  82. const init = this.getEventInit();
  83. // Currently there is no PointerEventsCheckLevel that would
  84. // make this check not use the *asserted* cached value from `up`.
  85. /* istanbul ignore else */ if (hasPointerEvents(instance, target)) {
  86. instance.dispatchUIEvent(target, 'pointerout', init);
  87. leave.forEach((el)=>instance.dispatchUIEvent(el, 'pointerleave', init));
  88. }
  89. this.isCancelled = true;
  90. }
  91. getTarget(instance) {
  92. var _this_position_target;
  93. return (_this_position_target = this.position.target) !== null && _this_position_target !== undefined ? _this_position_target : instance.config.document.body;
  94. }
  95. getEventInit(/**
  96. * The `button` that caused the event.
  97. *
  98. * This should be `-1` if the event is not caused by a button or touch/pen contact,
  99. * e.g. a moving pointer.
  100. */ button) {
  101. return {
  102. ...this.position.coords,
  103. pointerId: this.pointerId,
  104. pointerType: this.pointerType,
  105. isPrimary: this.isPrimary,
  106. button: getMouseEventButton(button),
  107. buttons: this.buttons.getButtons()
  108. };
  109. }
  110. constructor({ pointerId, pointerType, isPrimary }, buttons){
  111. _define_property(this, "pointerId", undefined);
  112. _define_property(this, "pointerType", undefined);
  113. _define_property(this, "isPrimary", undefined);
  114. _define_property(this, "buttons", undefined);
  115. _define_property(this, "isMultitouch", false);
  116. _define_property(this, "isCancelled", false);
  117. _define_property(this, "isDown", false);
  118. _define_property(this, "isPrevented", false);
  119. _define_property(this, "position", {});
  120. this.pointerId = pointerId;
  121. this.pointerType = pointerType;
  122. this.isPrimary = isPrimary;
  123. this.isMultitouch = !isPrimary;
  124. this.buttons = buttons;
  125. }
  126. }
  127. export { Pointer };