diff --git a/index.bs b/index.bs
index f39d69e4..a2dbbdde 100644
--- a/index.bs
+++ b/index.bs
@@ -469,12 +469,14 @@ underscore.
ArgumentNameKeyword :
"async"
+ "async_disposer"
"attribute"
"callback"
"const"
"constructor"
"deleter"
"dictionary"
+ "disposer"
"enum"
"getter"
"includes"
@@ -886,6 +888,8 @@ The qualified name of an [=interface=] |interface| is defined as foll
ReadWriteMaplike
ReadWriteSetlike
InheritAttribute
+ Disposer
+ AsyncDisposer
@@ -1000,10 +1004,10 @@ or [=partial interface mixins=] can be found in [[#using-mixins-and-partials]].
An [=interface mixin=] is a specification of a set of interface mixin members
(matching MixinMembers),
-which are the [=constants=], [=regular operations=], [=regular attributes=], and [=stringifiers=]
+which are the [=constants=], [=regular operations=], [=regular attributes=], [=stringifiers=], [=disposers=], and [=async_disposers=]
that appear between the braces in the [=interface mixin=] declaration.
-These [=constants=], [=regular operations=], [=regular attributes=], and [=stringifiers=]
+These [=constants=], [=regular operations=], [=regular attributes=], [=stringifiers=], [=disposers=], and [=async_disposers=]
describe the behaviors that can be implemented by an object,
as if they were specified on the [=interface=] that [=includes=] them.
@@ -1144,6 +1148,8 @@ No [=extended attributes=] defined in this specification are applicable to [=inc
Const
RegularOperation
Stringifier
+ Disposer
+ AsyncDisposer
OptionalReadOnly AttributeRest
@@ -1356,6 +1362,22 @@ and summarized in the following informative table:
● |
|
+
+
+ [=Disposers=] |
+ ● |
+ |
+ ● |
+ |
+
+
+
+ [=AsyncDisposers=] |
+ ● |
+ |
+ ● |
+ |
+
[=Special Operations=] |
● |
@@ -1849,7 +1871,7 @@ are applicable only to regular attributes:
An operation is an [=interface member=], [=callback interface
member=] or [=namespace member=]
(matching static RegularOperation,
-stringifier,
+stringifier, disposer, async-disposer,
RegularOperation or
SpecialOperation)
that defines a behavior that can be invoked on objects implementing the interface.
@@ -1888,7 +1910,7 @@ If the operation has a
[=special keyword=]
used in its declaration (that is, any keyword matching
Special, or
-the stringifier keyword),
+the stringifier, disposer, or async_disposer keywords),
then it declares a special operation. A single operation can declare
both a regular operation and a special operation;
see [[#idl-special-operations]] for details on special operations.
@@ -2507,6 +2529,41 @@ See [[#interface-object]] for details on how a [=constructor operation=] is to b
+Disposers
+
+When an [=interface=] has a disposer, it indicates that objects
+that implement the interface have an implementation of the {{%Symbol.dispose%}} operation.
+Disposers can be specified using a disposer keyword, which creates a
+{{%Symbol.dispose%}} operation.
+
+
+ interface interface_identifier {
+ disposer;
+ };
+
+
+Prose accompanying the interface must define the disposal behavior
+of the interface.
+
+On a given [=interface=], there must exist at most one disposer.
+
+Async Disposers
+
+When an [=interface=] has an async_disposer, it indicates that objects
+that implement the interface have an implementation of the {{%Symbol.asyncDispose%}} operation.
+Async Disposers can be specified using an async_disposer keyword, which creates a
+{{%Symbol.asyncDispose%}} operation.
+
+
+ interface interface_identifier {
+ async_disposer;
+ };
+
+
+Prose accompanying the interface must define the async disposal behavior
+of the interface.
+
+On a given [=interface=], there must exist at most one async disposer.
Stringifiers
@@ -7119,6 +7176,8 @@ and comprise the following:
* [=attribute setters=]
* the function objects that correspond to operations
* the function objects that correspond to stringifiers
+* the function objects that correspond to disposers
+* the function objects that correspond to async disposers
Each [=realm=]
must have its own unique set of each of
@@ -10154,8 +10213,9 @@ There also must not be more than
one [=stringifier=]
or more than one [=iterable declaration=],
[=asynchronously iterable declaration=],
-[=maplike declaration=] or
-[=setlike declaration=]
+[=maplike declaration=],
+[=setlike declaration=],
+[=disposer=], or [=async_disposer=]
across those interfaces.
Note: This is because all of the [=members=] of the interface
@@ -11966,8 +12026,10 @@ with the [{{LegacyNoInterfaceObject}}] [=extended attribute=].
Additionally, [=interface prototype objects=] get properties declaratively from:
* [[#js-stringifier]],
-* [[#js-maplike]], and
-* [[#js-setlike]].
+* [[#js-maplike]],
+* [[#js-setlike]],
+* [[#js-disposer]], and
+* [[#js-async-disposer]].
Issue: Define those properties imperatively instead.
@@ -12613,6 +12675,76 @@ A [=regular operation=] that does not [=have default method steps=] must not be
+Disposers
+
+If the [=interface=] has an [=exposed=] [=disposer=], then there must
+exist a property with the following characteristics:
+
+* The name of the property is {{%Symbol.dispose%}}.
+* If the [=disposer=] is [=unforgeable=] on the interface
+ or if the interface was declared with the [{{Global}}] [=extended attribute=],
+ then the property exists on every object that [=implements=] the interface.
+ Otherwise, the property exists on the [=interface prototype object=].
+* The property as attributes
+ { \[[Writable]]: |B|, \[[Enumerable]]: true, \[[Configurable]]: |B| },
+ where |B| is false if the disposer is [=unforgeable=] on the interface,
+ and true otherwise.
+*
+
+ The value of the property is a [=built-in function object=], which behaves as follows:
+
+ 1. Let |thisValue| be the
this value.
+ 1. Let |O| be [=?=]
ToObject(|thisValue|).
+ 1. If |O| [=is a platform object=],
+ then [=perform a security check=], passing:
+ * the platform object |O|,
+ * the [=identifier=] of the [=disposer=], and
+ * the type "
method
".
+ 1. If |O| does not [=implement=] the [=interface=]
+ on which the disposer was declared, then [=JavaScript/throw=] a
{{TypeError}}.
+ 1. Performing the [=disposal behavior=] of the interface.
+
+* The value of the [=function object=]'s length
+ property is the Number value 0.
+* The value of the [=function object=]'s name
+ property is the Symbol value {{%Symbol.dispose%}}.
+
+Async Disposers
+
+If the [=interface=] has an [=exposed=] [=async_disposer=], then there must
+exist a property with the following characteristics:
+
+* The name of the property is {{%Symbol.asyncDispose%}}.
+* If the [=async_disposer=] is [=unforgeable=] on the interface
+ or if the interface was declared with the [{{Global}}] [=extended attribute=],
+ then the property exists on every object that [=implements=] the interface.
+ Otherwise, the property exists on the [=interface prototype object=].
+* The property as attributes
+ { \[[Writable]]: |B|, \[[Enumerable]]: true, \[[Configurable]]: |B| },
+ where |B| is false if the async disposer is [=unforgeable=] on the interface,
+ and true otherwise.
+*
+
+ The value of the property is a [=built-in function object=], which behaves as follows:
+
+ 1. Let |thisValue| be the
this value.
+ 1. Let |O| be [=?=]
ToObject(|thisValue|).
+ 1. If |O| [=is a platform object=],
+ then [=perform a security check=], passing:
+ * the platform object |O|,
+ * the [=identifier=] of the [=disposer=], and
+ * the type "
method
".
+ 1. If |O| does not [=implement=] the [=interface=]
+ on which the disposer was declared, then [=JavaScript/throw=] a
{{TypeError}}.
+ 1. Let |V| be an uninitialized variable.
+ 1. Set |V| to the result of performing the [=async disposal behavior=] of the interface.
+ 1. Return the result of [=converted to a JavaScript value|converting=] |V| to a Promise value.
+
+* The value of the [=function object=]'s length
+ property is the Number value 0.
+* The value of the [=function object=]'s name
+ property is the Symbol value {{%Symbol.asyncDispose%}}.
+
Stringifiers
If the [=interface=] has an [=exposed=] [=stringifier=],
@@ -13911,8 +14043,10 @@ which has a [{{Global}}] [=extended attribute=]
get properties declaratively from:
* [[#js-stringifier]],
-* [[#js-maplike]], and
-* [[#js-setlike]].
+* [[#js-maplike]],
+* [[#js-setlike]],
+* [[#js-disposer]], and
+* [[#js-async-disposer]].
Issue: Define those properties imperatively instead.