diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 7e229dbbce20..3f540b216269 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2316,6 +2316,39 @@ class MethodDefiner(PropertyDefiner): }) break + if (not static and + maplikeOrSetlikeOrIterable and + maplikeOrSetlikeOrIterable.isIterable() and + maplikeOrSetlikeOrIterable.isValueIterator()): + # Add our keys/values/entries + self.regular.append({ + "name": "keys", + "methodInfo": False, + "selfHostedName": "ArrayKeys", + "length": 0, + "flags": "JSPROP_ENUMERATE", + "condition": PropertyDefiner.getControllingCondition(m, + descriptor) + }) + self.regular.append({ + "name": "values", + "methodInfo": False, + "selfHostedName": "ArrayValues", + "length": 0, + "flags": "JSPROP_ENUMERATE", + "condition": PropertyDefiner.getControllingCondition(m, + descriptor) + }) + self.regular.append({ + "name": "entries", + "methodInfo": False, + "selfHostedName": "ArrayEntries", + "length": 0, + "flags": "JSPROP_ENUMERATE", + "condition": PropertyDefiner.getControllingCondition(m, + descriptor) + }) + if not static: stringifier = descriptor.operations['Stringifier'] if (stringifier and diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index de31511bcd51..d98be67cccb2 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -3632,6 +3632,11 @@ class IDLIterable(IDLMaplikeOrSetlikeOrIterableBase): we generate our functions as if they were part of the interface specification during parsing. """ + # We only need to add entries/keys/values here if we're a pair iterator. + # Value iterators just copy these from %ArrayPrototype% instead. + if not self.isPairIterator(): + return + # object entries() self.addMethod("entries", members, False, self.iteratorType, affectsNothing=True, newObject=True) diff --git a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py index 5b2e1a13534f..e3b38c41a928 100644 --- a/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py +++ b/dom/bindings/parser/tests/test_interface_maplikesetlikeiterable.py @@ -78,7 +78,7 @@ def WebIDLTest(parser, harness): # __iterable to it for the iterable<> case. iterableMembers.append(("__iterable", WebIDL.IDLIterable)) - valueIterableMembers = list(iterableMembers) + valueIterableMembers = [("__iterable", WebIDL.IDLIterable)] valueIterableMembers.append(("__indexedgetter", WebIDL.IDLMethod)) valueIterableMembers.append(("length", WebIDL.IDLAttribute)) diff --git a/dom/bindings/test/test_iterable.html b/dom/bindings/test/test_iterable.html index e512ec33e1f6..d60b5a0b020c 100644 --- a/dom/bindings/test/test_iterable.html +++ b/dom/bindings/test/test_iterable.html @@ -52,6 +52,12 @@ testExistence("IterableSingle: ", itr, base_properties); is(itr[Symbol.iterator], Array.prototype[Symbol.iterator], "IterableSingle: Should be using %ArrayIterator% for @@iterator"); + is(itr.keys, Array.prototype.keys, + "IterableSingle: Should be using %ArrayIterator% for 'keys'"); + is(itr.entries, Array.prototype.entries, + "IterableSingle: Should be using %ArrayIterator% for 'entries'"); + is(itr.values, itr[Symbol.iterator], + "IterableSingle: Should be using @@iterator for 'values'"); var keys = [...itr.keys()]; var values = [...itr.values()]; var entries = [...itr.entries()]; @@ -85,7 +91,7 @@ is(entry.value, undefined, "IterableDouble: Entry iterator value should be undefined"); is(entry.done, true, "IterableSingle: Entry iterator done should be true"); is(Object.prototype.toString.call(Object.getPrototypeOf(key_itr)), - "[object TestInterfaceIterableSingleIteratorPrototype]", + "[object Array Iterator]", "iterator prototype should have the right brand"); // Simple dual type iterable creation and functionality test