Source: libs/EventPromise.js

  1. 'use strict';
  2. /**
  3. *
  4. * @file Binds asynchronous events to Promise objects.
  5. *
  6. * @version 0.4.1
  7. */
  8. /**
  9. * @class Creates promises from standard JavaScript events for
  10. * inline asynchronous execution. This class binds itself to the global object
  11. * prototype and is therefore available to all derived objects in the current
  12. * execution context.
  13. *
  14. * <p><b><i>This global class requires ECMAScript 2017 support.</i></b></p>
  15. * @mixin
  16. * @mixes Object.prototype
  17. */
  18. class EventPromise {
  19. /**
  20. * Registers an event listener on a target object and returns a Promise.
  21. *
  22. * @param {String} eventType The type of event to register. This can match
  23. * any event type dispatched by the target object.
  24. * @param {Boolean} useCapture=false As in standard events, this parameter
  25. * specifies if the event is dispatched in the capture phase (true), or in the
  26. * bubble phase (false).
  27. *
  28. * @return A standard Promise object that will receive either a resolution
  29. * when the event fires or a rejection if the event could not be registered.
  30. *
  31. * @example
  32. * //all objects in the current execution context will inherit the
  33. * //onEventPromise handler automatically
  34. * window.onEventPromise("click").then(
  35. * function(resolve, reject) {
  36. * alert ("Clicked on window");
  37. * }
  38. * )
  39. *
  40. * @example
  41. * //the returned Promise also works with async functions as expected
  42. * async function doOnClick() {
  43. * event = await window.onEventPromise("click");
  44. * alert ("Clicked on window");
  45. * }
  46. * doOnClick();
  47. *
  48. */
  49. static onEventPromise(eventType, useCapture) {
  50. if (typeof(useCapture) != "boolean") {
  51. useCapture = false; //W3C default
  52. }
  53. var promise = new Promise((resolve, reject) => {
  54. try {
  55. let listener = (event) => {
  56. this.removeEventListener(eventType, listener);
  57. setTimeout (resolve, 1, event); //prevents multiple sequential promises (if set) for the same event type (e.g. MouseEvent)
  58. }
  59. this.addEventListener(eventType, listener, useCapture);
  60. } catch (err) {
  61. setTimeout (resolve, 1, err);
  62. }
  63. });
  64. return (promise);
  65. }
  66. }
  67. //register function with global object inheritance tree
  68. Object.prototype.onEventPromise = EventPromise.onEventPromise;
  69. //make the property non-enumerable to prevent including it during enumeration (for..in loops, etc.)
  70. Object.defineProperty(Object.prototype, 'onEventPromise', {enumerable: false});