From e002d7811533e276c9927b237748c4e170f4cb10 Mon Sep 17 00:00:00 2001 From: Anne van Kesteren Date: Fri, 8 Apr 2016 13:08:09 +0200 Subject: [PATCH] Enable an event listener to be invoked just once --- dom.bs | 47 ++++++++++++++++++++++++++++++++++++++--------- dom.html | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/dom.bs b/dom.bs index 082123e45..2af1964f6 100644 --- a/dom.bs +++ b/dom.bs @@ -966,7 +966,7 @@ for historical reasons.
 [Exposed=(Window,Worker)]
 interface EventTarget {
-  void addEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
+  void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
   void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
   boolean dispatchEvent(Event event);
 };
@@ -979,6 +979,10 @@ dictionary EventListenerOptions {
   boolean capture;
   boolean passive;
 };
+
+dictionary AddEventListenerOptions : EventListenerOptions {
+  boolean once;
+};
 

The {{EventTarget}} object represents the target to which an event is dispatched @@ -996,6 +1000,7 @@ when something has occurred.

  • callback (an {{EventListener}})
  • capture (a boolean, initially false)
  • passive (a boolean, initially false) +
  • once (a boolean, initially false)
  • removed (a boolean for bookkeeping purposes, initially false) @@ -1031,6 +1036,9 @@ specified otherwise it returns null. callback will not cancel the event by invoking {{preventDefault()}}. This is used to enable performance optimizations described in [[#observing-event-listeners]]. + When set to true, options's once member indicates that the callback + will only be invoked once after which the event listener will be removed. + The event listener is appended to target's list of event listeners and is not appended if it is a duplicate, i.e., having the same type, callback, capture and passive values. @@ -1048,7 +1056,8 @@ specified otherwise it returns null. {{Event/preventDefault()}} method was not invoked, and false otherwise. -

    To flatten options run these steps: +

    To flatten options, run these +steps:

    1. Let capture and passive be false. @@ -1064,6 +1073,21 @@ specified otherwise it returns null.

    2. Return capture and passive.

    +

    To flatten more options, run these +steps: + +

      +
    1. Let capture and passive be the result of flattening + options. + +

    2. Let once be false. + +

    3. If options is a dictionary and {{AddEventListenerOptions/once}} is + present in options with value true, then set once to true. + +

    4. Return capture, passive, and once. +

    +

    The addEventListener(type, callback, options) method, when invoked, must run these steps: @@ -1080,14 +1104,15 @@ method, when invoked, must run these steps:

  • If callback is null, terminate these steps. -

  • Let capture and passive be the result of flattening - options. +

  • Let capture, passive, and once be the result of + flattening more options. -

  • Append an event listener to the associated list of event listeners with - type set to type, callback set to callback, capture - set to capture, and passive set to passive unless there already is an - event listener in that list with the same type, callback, capture, and - passive. +

  • If context object's associated list of event listener does not contain an + event listener whose type is type, callback is callback, + capture is capture, and passive is passive, then append a new + event listener to it, whose type is type, callback is + callback, capture is capture, passive is passive, + and once is once.

    The @@ -1271,6 +1296,10 @@ an object with event, run these steps:

  • Unset event's in passive listener flag. +

  • If listener's once is true, then set listener's + removed to true and remove it from object's associated list of + event listeners. +

  • If event's stop immediate propagation flag is set, return found. diff --git a/dom.html b/dom.html index 7e700d221..7ef3a0939 100644 --- a/dom.html +++ b/dom.html @@ -687,7 +687,7 @@

    3.6. Interface EventTarget

    [Exposed=(Window,Worker)]
     interface EventTarget {
    -  void addEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
    +  void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options);
       void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options);
       boolean dispatchEvent(Event event);
     };
    @@ -700,6 +700,10 @@ 

    capture; boolean passive; }; + +dictionary AddEventListenerOptions : EventListenerOptions { + boolean once; +};

    The EventTarget object represents the target to which an event is dispatched when something has occurred.

    Each EventTarget object has an associated list of event listeners.

    @@ -710,6 +714,7 @@

    callback (an EventListener)
  • capture (a boolean, initially false)
  • passive (a boolean, initially false) +
  • once (a boolean, initially false)
  • removed (a boolean for bookkeeping purposes, initially false)

    Although callback is an EventListener, as can be seen from the @@ -730,6 +735,7 @@

    event’s eventPhase attribute value is BUBBLING_PHASE. When false (or not present), callback will not be invoked when event’s eventPhase attribute value is CAPTURING_PHASE. Either way, callback will be invoked if event’s eventPhase attribute value is AT_TARGET.

    When set to true, optionspassive member indicates that the callback will not cancel the event by invoking preventDefault(). This is used to enable performance optimizations described in §3.7 Observing event listeners.

    +

    When set to true, options’s once member indicates that the callback will only be invoked once after which the event listener will be removed.

    The event listener is appended to target’s list of event listeners and is not appended if it is a duplicate, i.e., having the same type, callback, capture and passive values.

    target . removeEventListener(type, callback [, options]) @@ -738,7 +744,8 @@

    Dispatches a synthetic event event to target and returns true if either event’s cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise. -

    To flatten options run these steps:

    +

    To flatten options, run these +steps:

    1. Let capture and passive be false.

      @@ -753,6 +760,19 @@

      Return capture and passive.

    +

    To flatten more options, run these +steps:

    +
      +
    1. +

      Let capture and passive be the result of flattening options.

      +
    2. +

      Let once be false.

      +
    3. +

      If options is a dictionary and once is + present in options with value true, then set once to true.

      +
    4. +

      Return capture, passive, and once.

      +

    The addEventListener(type, callback, options) method, when invoked, must run these steps:

    1. @@ -765,9 +785,10 @@

      If callback is null, terminate these steps.

    2. -

      Let capture and passive be the result of flattening options.

      +

      Let capture, passive, and once be the result of flattening more options.

    3. -

      Append an event listener to the associated list of event listeners with type set to type, callback set to callback, capture set to capture, and passive set to passive unless there already is an event listener in that list with the same type, callback, capture, and passive.

      +

      If context object’s associated list of event listener does not contain an event listener whose type is type, callback is callback, capture is capture, and passive is passive, then append a new event listener to it, whose type is type, callback is callback, capture is capture, passive is passive, + and once is once.

    The removeEventListener(type, callback, options) method, when invoked, must, run these steps

      @@ -911,6 +932,8 @@

      Call listener’s callback’s handleEvent(), with event as argument and event’s currentTarget attribute value as callback this value. If this throws any exception, report the exception.

    1. Unset event’s in passive listener flag.

      +
    2. +

      If listener’s once is true, then set listener’s removed to true and remove it from object’s associated list of event listeners.

    3. If event’s stop immediate propagation flag is set, return found.

      @@ -5125,6 +5148,7 @@

      acceptNode(node), in §6.3
    4. add(), in §7.1
    5. addedNodes, in §4.3.3 +
    6. AddEventListenerOptions, in §3.6
    7. addEventListener(type, callback), in §3.6
    8. addEventListener(type, callback, options), in §3.6
    9. add(tokens), in §7.1 @@ -5413,6 +5437,7 @@

      first child, in §2.1
    10. firstElementChild, in §4.2.6
    11. flatten, in §3.6 +
    12. flatten more, in §3.6
    13. following, in §2.1
    14. get an attribute by name, in §4.9
    15. get an attribute by namespace and local name, in §4.9 @@ -5665,6 +5690,7 @@

      observe(target, options), in §4.3.1
    16. offset, in §5.2
    17. oldValue, in §4.3.3 +
    18. once, in §3.6
    19. "open", in §4.8
    20. ordered set parser, in §2.3
    21. ordered set serializer, in §2.3 @@ -6138,7 +6164,7 @@

      I [Exposed=(Window,Worker)] interface EventTarget { - void addEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options); + void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options); void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options); boolean dispatchEvent(Event event); }; @@ -6152,6 +6178,10 @@

      I boolean passive; }; +dictionary AddEventListenerOptions : EventListenerOptions { + boolean once; +}; + [NoInterfaceObject, Exposed=Window] interface NonElementParentNode {