gesture-controller.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. class GestureController {
  5. constructor() {
  6. this.gestureId = 0;
  7. this.requestedStart = new Map();
  8. this.disabledGestures = new Map();
  9. this.disabledScroll = new Set();
  10. }
  11. /**
  12. * Creates a gesture delegate based on the GestureConfig passed
  13. */
  14. createGesture(config) {
  15. var _a;
  16. return new GestureDelegate(this, this.newID(), config.name, (_a = config.priority) !== null && _a !== void 0 ? _a : 0, !!config.disableScroll);
  17. }
  18. /**
  19. * Creates a blocker that will block any other gesture events from firing. Set in the ion-gesture component.
  20. */
  21. createBlocker(opts = {}) {
  22. return new BlockerDelegate(this, this.newID(), opts.disable, !!opts.disableScroll);
  23. }
  24. start(gestureName, id, priority) {
  25. if (!this.canStart(gestureName)) {
  26. this.requestedStart.delete(id);
  27. return false;
  28. }
  29. this.requestedStart.set(id, priority);
  30. return true;
  31. }
  32. capture(gestureName, id, priority) {
  33. if (!this.start(gestureName, id, priority)) {
  34. return false;
  35. }
  36. const requestedStart = this.requestedStart;
  37. let maxPriority = -10000;
  38. requestedStart.forEach((value) => {
  39. maxPriority = Math.max(maxPriority, value);
  40. });
  41. if (maxPriority === priority) {
  42. this.capturedId = id;
  43. requestedStart.clear();
  44. const event = new CustomEvent('ionGestureCaptured', { detail: { gestureName } });
  45. document.dispatchEvent(event);
  46. return true;
  47. }
  48. requestedStart.delete(id);
  49. return false;
  50. }
  51. release(id) {
  52. this.requestedStart.delete(id);
  53. if (this.capturedId === id) {
  54. this.capturedId = undefined;
  55. }
  56. }
  57. disableGesture(gestureName, id) {
  58. let set = this.disabledGestures.get(gestureName);
  59. if (set === undefined) {
  60. set = new Set();
  61. this.disabledGestures.set(gestureName, set);
  62. }
  63. set.add(id);
  64. }
  65. enableGesture(gestureName, id) {
  66. const set = this.disabledGestures.get(gestureName);
  67. if (set !== undefined) {
  68. set.delete(id);
  69. }
  70. }
  71. disableScroll(id) {
  72. this.disabledScroll.add(id);
  73. if (this.disabledScroll.size === 1) {
  74. document.body.classList.add(BACKDROP_NO_SCROLL);
  75. }
  76. }
  77. enableScroll(id) {
  78. this.disabledScroll.delete(id);
  79. if (this.disabledScroll.size === 0) {
  80. document.body.classList.remove(BACKDROP_NO_SCROLL);
  81. }
  82. }
  83. canStart(gestureName) {
  84. if (this.capturedId !== undefined) {
  85. // a gesture already captured
  86. return false;
  87. }
  88. if (this.isDisabled(gestureName)) {
  89. return false;
  90. }
  91. return true;
  92. }
  93. isCaptured() {
  94. return this.capturedId !== undefined;
  95. }
  96. isScrollDisabled() {
  97. return this.disabledScroll.size > 0;
  98. }
  99. isDisabled(gestureName) {
  100. const disabled = this.disabledGestures.get(gestureName);
  101. if (disabled && disabled.size > 0) {
  102. return true;
  103. }
  104. return false;
  105. }
  106. newID() {
  107. this.gestureId++;
  108. return this.gestureId;
  109. }
  110. }
  111. class GestureDelegate {
  112. constructor(ctrl, id, name, priority, disableScroll) {
  113. this.id = id;
  114. this.name = name;
  115. this.disableScroll = disableScroll;
  116. this.priority = priority * 1000000 + id;
  117. this.ctrl = ctrl;
  118. }
  119. canStart() {
  120. if (!this.ctrl) {
  121. return false;
  122. }
  123. return this.ctrl.canStart(this.name);
  124. }
  125. start() {
  126. if (!this.ctrl) {
  127. return false;
  128. }
  129. return this.ctrl.start(this.name, this.id, this.priority);
  130. }
  131. capture() {
  132. if (!this.ctrl) {
  133. return false;
  134. }
  135. const captured = this.ctrl.capture(this.name, this.id, this.priority);
  136. if (captured && this.disableScroll) {
  137. this.ctrl.disableScroll(this.id);
  138. }
  139. return captured;
  140. }
  141. release() {
  142. if (this.ctrl) {
  143. this.ctrl.release(this.id);
  144. if (this.disableScroll) {
  145. this.ctrl.enableScroll(this.id);
  146. }
  147. }
  148. }
  149. destroy() {
  150. this.release();
  151. this.ctrl = undefined;
  152. }
  153. }
  154. class BlockerDelegate {
  155. constructor(ctrl, id, disable, disableScroll) {
  156. this.id = id;
  157. this.disable = disable;
  158. this.disableScroll = disableScroll;
  159. this.ctrl = ctrl;
  160. }
  161. block() {
  162. if (!this.ctrl) {
  163. return;
  164. }
  165. if (this.disable) {
  166. for (const gesture of this.disable) {
  167. this.ctrl.disableGesture(gesture, this.id);
  168. }
  169. }
  170. if (this.disableScroll) {
  171. this.ctrl.disableScroll(this.id);
  172. }
  173. }
  174. unblock() {
  175. if (!this.ctrl) {
  176. return;
  177. }
  178. if (this.disable) {
  179. for (const gesture of this.disable) {
  180. this.ctrl.enableGesture(gesture, this.id);
  181. }
  182. }
  183. if (this.disableScroll) {
  184. this.ctrl.enableScroll(this.id);
  185. }
  186. }
  187. destroy() {
  188. this.unblock();
  189. this.ctrl = undefined;
  190. }
  191. }
  192. const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
  193. const GESTURE_CONTROLLER = new GestureController();
  194. export { BACKDROP_NO_SCROLL as B, GESTURE_CONTROLLER as G };