events.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. import window from "../global/window";
  2. import extend from "./extend";
  3. import DependencyLib from "./inputmask.dependencyLib";
  4. export { on, off, trigger, Evnt as Event };
  5. const document = window.document;
  6. function isValidElement(elem) {
  7. return elem instanceof Element;
  8. }
  9. let Evnt;
  10. if (typeof window.CustomEvent === "function") {
  11. Evnt = window.CustomEvent;
  12. } else if (window.Event && document && document.createEvent) {
  13. Evnt = function (event, params) {
  14. params = params || {
  15. bubbles: false,
  16. cancelable: false,
  17. composed: true,
  18. detail: undefined
  19. };
  20. const evt = document.createEvent("CustomEvent");
  21. evt.initCustomEvent(
  22. event,
  23. params.bubbles,
  24. params.cancelable,
  25. params.detail
  26. );
  27. return evt;
  28. };
  29. Evnt.prototype = window.Event.prototype;
  30. } else if (typeof Event !== "undefined") {
  31. // nodejs
  32. Evnt = Event;
  33. }
  34. function on(events, handler) {
  35. function addEvent(ev, namespace) {
  36. // register domevent
  37. if (elem.addEventListener) {
  38. // all browsers except IE before version 9
  39. elem.addEventListener(ev, handler, false);
  40. } else if (elem.attachEvent) {
  41. // IE before version 9
  42. elem.attachEvent(`on${ev}`, handler);
  43. }
  44. eventRegistry[ev] = eventRegistry[ev] || {};
  45. eventRegistry[ev][namespace] = eventRegistry[ev][namespace] || [];
  46. eventRegistry[ev][namespace].push(handler);
  47. }
  48. if (isValidElement(this[0])) {
  49. var eventRegistry = this[0].eventRegistry,
  50. elem = this[0];
  51. events.split(" ").forEach((event) => {
  52. const [ev, namespace = "global"] = event.split(".");
  53. addEvent(ev, namespace);
  54. });
  55. }
  56. return this;
  57. }
  58. function off(events, handler) {
  59. let eventRegistry, elem;
  60. function removeEvent(ev, namespace, handler) {
  61. if (ev in eventRegistry === true) {
  62. // unbind to dom events
  63. if (elem.removeEventListener) {
  64. // all browsers except IE before version 9
  65. elem.removeEventListener(ev, handler, false);
  66. } else if (elem.detachEvent) {
  67. // IE before version 9
  68. elem.detachEvent(`on${ev}`, handler);
  69. }
  70. if (namespace === "global") {
  71. for (const nmsp in eventRegistry[ev]) {
  72. eventRegistry[ev][nmsp].splice(
  73. eventRegistry[ev][nmsp].indexOf(handler),
  74. 1
  75. );
  76. }
  77. } else {
  78. eventRegistry[ev][namespace].splice(
  79. eventRegistry[ev][namespace].indexOf(handler),
  80. 1
  81. );
  82. }
  83. }
  84. }
  85. function resolveNamespace(ev, namespace) {
  86. let evts = [],
  87. hndx,
  88. hndL;
  89. if (ev.length > 0) {
  90. if (handler === undefined) {
  91. for (
  92. hndx = 0, hndL = eventRegistry[ev][namespace].length;
  93. hndx < hndL;
  94. hndx++
  95. ) {
  96. evts.push({
  97. ev,
  98. namespace: namespace && namespace.length > 0 ? namespace : "global",
  99. handler: eventRegistry[ev][namespace][hndx]
  100. });
  101. }
  102. } else {
  103. evts.push({
  104. ev,
  105. namespace: namespace && namespace.length > 0 ? namespace : "global",
  106. handler
  107. });
  108. }
  109. } else if (namespace.length > 0) {
  110. for (const evNdx in eventRegistry) {
  111. for (const nmsp in eventRegistry[evNdx]) {
  112. if (nmsp === namespace) {
  113. if (handler === undefined) {
  114. for (
  115. hndx = 0, hndL = eventRegistry[evNdx][nmsp].length;
  116. hndx < hndL;
  117. hndx++
  118. ) {
  119. evts.push({
  120. ev: evNdx,
  121. namespace: nmsp,
  122. handler: eventRegistry[evNdx][nmsp][hndx]
  123. });
  124. }
  125. } else {
  126. evts.push({
  127. ev: evNdx,
  128. namespace: nmsp,
  129. handler
  130. });
  131. }
  132. }
  133. }
  134. }
  135. }
  136. return evts;
  137. }
  138. if (isValidElement(this[0]) && events) {
  139. eventRegistry = this[0].eventRegistry;
  140. elem = this[0];
  141. events.split(" ").forEach((event) => {
  142. const [ev, namespace] = event.split(".");
  143. resolveNamespace(ev, namespace).forEach(
  144. ({ ev: ev1, handler: handler1, namespace: namespace1 }) => {
  145. removeEvent(ev1, namespace1, handler1);
  146. }
  147. );
  148. });
  149. }
  150. return this;
  151. }
  152. function trigger(events /* , args... */) {
  153. if (isValidElement(this[0])) {
  154. const eventRegistry = this[0].eventRegistry,
  155. elem = this[0],
  156. _events = typeof events === "string" ? events.split(" ") : [events.type];
  157. for (let endx = 0; endx < _events.length; endx++) {
  158. const nsEvent = _events[endx].split("."),
  159. ev = nsEvent[0],
  160. namespace = nsEvent[1] || "global";
  161. if (document !== undefined && namespace === "global") {
  162. // trigger domevent
  163. var evnt,
  164. params = {
  165. bubbles: true,
  166. cancelable: true,
  167. composed: true,
  168. detail: arguments[1]
  169. };
  170. // The custom event that will be created
  171. if (document.createEvent) {
  172. try {
  173. switch (ev) {
  174. case "input":
  175. params.inputType = "insertText";
  176. evnt = new InputEvent(ev, params);
  177. break;
  178. default:
  179. evnt = new CustomEvent(ev, params);
  180. }
  181. } catch (e) {
  182. evnt = document.createEvent("CustomEvent");
  183. evnt.initCustomEvent(
  184. ev,
  185. params.bubbles,
  186. params.cancelable,
  187. params.detail
  188. );
  189. }
  190. if (events.type) extend(evnt, events);
  191. elem.dispatchEvent(evnt);
  192. } else {
  193. evnt = document.createEventObject();
  194. evnt.eventType = ev;
  195. evnt.detail = arguments[1];
  196. if (events.type) extend(evnt, events);
  197. elem.fireEvent("on" + evnt.eventType, evnt);
  198. }
  199. } else if (eventRegistry[ev] !== undefined) {
  200. arguments[0] = arguments[0].type
  201. ? arguments[0]
  202. : DependencyLib.Event(arguments[0]);
  203. arguments[0].detail = arguments.slice(1);
  204. const registry = eventRegistry[ev],
  205. handlers =
  206. namespace === "global"
  207. ? Object.values(registry).flat()
  208. : registry[namespace];
  209. handlers.forEach((handler) => handler.apply(elem, arguments));
  210. }
  211. }
  212. }
  213. return this;
  214. }