UI for Zipcoin Blue

tap-click.js 7.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. import { Injectable } from '@angular/core';
  2. import { Activator } from './activator';
  3. import { App } from '../components/app/app';
  4. import { Config } from '../config/config';
  5. import { DomController } from '../platform/dom-controller';
  6. import { GestureController } from '../gestures/gesture-controller';
  7. import { Platform } from '../platform/platform';
  8. import { hasPointerMoved, pointerCoord } from '../util/dom';
  9. import { POINTER_EVENT_TYPE_TOUCH } from '../gestures/pointer-events';
  10. import { RippleActivator } from './ripple';
  11. import { UIEventManager } from '../gestures/ui-event-manager';
  12. /**
  13. * @hidden
  14. */
  15. export class TapClick {
  16. constructor(config, plt, dom, app, gestureCtrl) {
  17. this.plt = plt;
  18. this.app = app;
  19. this.gestureCtrl = gestureCtrl;
  20. this.disableClick = 0;
  21. this.events = new UIEventManager(plt);
  22. let activator = config.get('activator');
  23. if (activator === 'ripple') {
  24. this.activator = new RippleActivator(app, config, dom);
  25. }
  26. else if (activator === 'highlight') {
  27. this.activator = new Activator(app, config, dom);
  28. }
  29. this.usePolyfill = config.getBoolean('tapPolyfill');
  30. (void 0) /* console.debug */;
  31. const doc = plt.doc();
  32. this.events.listen(doc, 'click', this.click.bind(this), { passive: false, capture: true });
  33. this.pointerEvents = this.events.pointerEvents({
  34. element: doc,
  35. pointerDown: this.pointerStart.bind(this),
  36. pointerMove: this.pointerMove.bind(this),
  37. pointerUp: this.pointerEnd.bind(this),
  38. passive: true
  39. });
  40. this.pointerEvents.mouseWait = DISABLE_NATIVE_CLICK_AMOUNT;
  41. }
  42. pointerStart(ev) {
  43. if (this.startCoord) {
  44. return false;
  45. }
  46. if (!this.app.isEnabled()) {
  47. return false;
  48. }
  49. this.lastTouchEnd = 0;
  50. this.dispatchClick = true;
  51. if (this.plt.doc() === ev.target) {
  52. this.startCoord = pointerCoord(ev);
  53. return true;
  54. }
  55. this.activatableEle = getActivatableTarget(ev.target);
  56. if (!this.activatableEle) {
  57. this.startCoord = null;
  58. return false;
  59. }
  60. this.startCoord = pointerCoord(ev);
  61. this.activator && this.activator.downAction(ev, this.activatableEle, this.startCoord);
  62. return true;
  63. }
  64. pointerMove(ev) {
  65. if (this.startCoord && this.shouldCancelEvent(ev)) {
  66. this.pointerCancel(ev);
  67. }
  68. }
  69. pointerEnd(ev, pointerEventType) {
  70. if (!this.dispatchClick)
  71. return;
  72. (void 0) /* runInDev */;
  73. if (!this.startCoord) {
  74. return;
  75. }
  76. if (this.activator && ev.target !== this.plt.doc()) {
  77. let activatableEle = getActivatableTarget(ev.target) || this.activatableEle;
  78. if (activatableEle) {
  79. this.activator.upAction(ev, activatableEle, this.startCoord);
  80. }
  81. }
  82. if (this.usePolyfill && pointerEventType === POINTER_EVENT_TYPE_TOUCH && this.app.isEnabled()) {
  83. this.handleTapPolyfill(ev);
  84. }
  85. this.startCoord = null;
  86. this.activatableEle = null;
  87. }
  88. pointerCancel(ev) {
  89. (void 0) /* console.debug */;
  90. this.startCoord = null;
  91. this.activatableEle = null;
  92. this.dispatchClick = false;
  93. this.activator && this.activator.clearState(false);
  94. this.pointerEvents.stop();
  95. }
  96. shouldCancelEvent(ev) {
  97. return (this.app.isScrolling() ||
  98. this.gestureCtrl.isCaptured() ||
  99. hasPointerMoved(POINTER_TOLERANCE, this.startCoord, pointerCoord(ev)));
  100. }
  101. click(ev) {
  102. if (this.shouldCancelClick(ev)) {
  103. ev.preventDefault();
  104. ev.stopPropagation();
  105. return;
  106. }
  107. if (this.activator && this.plt.doc() !== ev.target) {
  108. // cool, a click is gonna happen, let's tell the activator
  109. // so the element can get the given "active" style
  110. const activatableEle = getActivatableTarget(ev.target);
  111. if (activatableEle) {
  112. this.activator.clickAction(ev, activatableEle, this.startCoord);
  113. }
  114. }
  115. (void 0) /* runInDev */;
  116. }
  117. shouldCancelClick(ev) {
  118. if (this.usePolyfill) {
  119. if (!ev.isIonicTap && this.isDisabledNativeClick()) {
  120. (void 0) /* console.debug */;
  121. return true;
  122. }
  123. }
  124. else if (!this.dispatchClick) {
  125. (void 0) /* console.debug */;
  126. return true;
  127. }
  128. if (!this.app.isEnabled()) {
  129. (void 0) /* console.debug */;
  130. return true;
  131. }
  132. if (this.gestureCtrl.isCaptured()) {
  133. (void 0) /* console.debug */;
  134. return true;
  135. }
  136. return false;
  137. }
  138. profileClickDelay(ev) {
  139. if (this.lastTouchEnd) {
  140. let diff = Date.now() - this.lastTouchEnd;
  141. if (diff < 100) {
  142. (void 0) /* console.debug */;
  143. }
  144. else {
  145. console.warn(`SLOW click dispatched. Delay(ms):`, diff, ev);
  146. }
  147. this.lastTouchEnd = null;
  148. }
  149. else {
  150. (void 0) /* console.debug */;
  151. }
  152. }
  153. handleTapPolyfill(ev) {
  154. (void 0) /* assert */;
  155. // only dispatch mouse click events from a touchend event
  156. // when tapPolyfill config is true, and the startCoordand endCoord
  157. // are not too far off from each other
  158. let endCoord = pointerCoord(ev);
  159. if (hasPointerMoved(POINTER_TOLERANCE, this.startCoord, endCoord)) {
  160. (void 0) /* console.debug */;
  161. return;
  162. }
  163. // prevent native mouse click events for XX amount of time
  164. this.disableClick = Date.now() + DISABLE_NATIVE_CLICK_AMOUNT;
  165. if (this.app.isScrolling()) {
  166. // do not fire off a click event while the app was scrolling
  167. (void 0) /* console.debug */;
  168. }
  169. else {
  170. // dispatch a mouse click event
  171. (void 0) /* console.debug */;
  172. let clickEvent = this.plt.doc().createEvent('MouseEvents');
  173. clickEvent.initMouseEvent('click', true, true, this.plt.win(), 1, 0, 0, endCoord.x, endCoord.y, false, false, false, false, 0, null);
  174. clickEvent.isIonicTap = true;
  175. ev.target.dispatchEvent(clickEvent);
  176. }
  177. }
  178. isDisabledNativeClick() {
  179. return this.disableClick > Date.now();
  180. }
  181. }
  182. TapClick.decorators = [
  183. { type: Injectable },
  184. ];
  185. /** @nocollapse */
  186. TapClick.ctorParameters = () => [
  187. { type: Config, },
  188. { type: Platform, },
  189. { type: DomController, },
  190. { type: App, },
  191. { type: GestureController, },
  192. ];
  193. function getActivatableTarget(ele) {
  194. let targetEle = ele;
  195. for (let x = 0; x < 10; x++) {
  196. if (!targetEle)
  197. break;
  198. if (isActivatable(targetEle)) {
  199. return targetEle;
  200. }
  201. targetEle = targetEle.parentElement;
  202. }
  203. return null;
  204. }
  205. /**
  206. * @hidden
  207. */
  208. export function isActivatable(ele) {
  209. if (ACTIVATABLE_ELEMENTS.indexOf(ele.tagName) > -1) {
  210. return true;
  211. }
  212. for (let i = 0, l = ACTIVATABLE_ATTRIBUTES.length; i < l; i++) {
  213. if (ele.hasAttribute && ele.hasAttribute(ACTIVATABLE_ATTRIBUTES[i])) {
  214. return true;
  215. }
  216. }
  217. return false;
  218. }
  219. const ACTIVATABLE_ELEMENTS = ['A', 'BUTTON'];
  220. const ACTIVATABLE_ATTRIBUTES = ['tappable', 'ion-button'];
  221. const POINTER_TOLERANCE = 100;
  222. const DISABLE_NATIVE_CLICK_AMOUNT = 2500;
  223. /**
  224. * @hidden
  225. */
  226. export function setupTapClick(config, plt, dom, app, gestureCtrl) {
  227. return function () {
  228. return new TapClick(config, plt, dom, app, gestureCtrl);
  229. };
  230. }
  231. //# sourceMappingURL=tap-click.js.map