@@ -684,17 +684,61 @@ function serializeJavascriptValueToJSONString (value) {
684
684
// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
685
685
const esIteratorPrototype = Object . getPrototypeOf ( Object . getPrototypeOf ( [ ] [ Symbol . iterator ] ( ) ) )
686
686
687
- // https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
688
- function makeIterator ( iterator , name ) {
687
+ /**
688
+ * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
689
+ * @param {() => unknown[] } iterator
690
+ * @param {string } name name of the instance
691
+ * @param {'key'|'value'|'key+value' } kind
692
+ */
693
+ function makeIterator ( iterator , name , kind ) {
694
+ const object = {
695
+ index : 0 ,
696
+ kind,
697
+ target : iterator
698
+ }
699
+
689
700
const i = {
690
701
next ( ) {
702
+ // 1. Let interface be the interface for which the iterator prototype object exists.
703
+
704
+ // 2. Let thisValue be the this value.
705
+
706
+ // 3. Let object be ? ToObject(thisValue).
707
+
708
+ // 4. If object is a platform object, then perform a security
709
+ // check, passing:
710
+
711
+ // 5. If object is not a default iterator object for interface,
712
+ // then throw a TypeError.
691
713
if ( Object . getPrototypeOf ( this ) !== i ) {
692
714
throw new TypeError (
693
715
`'next' called on an object that does not implement interface ${ name } Iterator.`
694
716
)
695
717
}
696
718
697
- return iterator . next ( )
719
+ // 6. Let index be object’s index.
720
+ // 7. Let kind be object’s kind.
721
+ // 8. Let values be object’s target's value pairs to iterate over.
722
+ const { index, kind, target } = object
723
+ const values = target ( )
724
+
725
+ // 9. Let len be the length of values.
726
+ const len = values . length
727
+
728
+ // 10. If index is greater than or equal to len, then return
729
+ // CreateIterResultObject(undefined, true).
730
+ if ( index >= len ) {
731
+ return { value : undefined , done : true }
732
+ }
733
+
734
+ // 11. Let pair be the entry in values at index index.
735
+ const pair = values [ index ]
736
+
737
+ // 12. Set object’s index to index + 1.
738
+ object . index = index + 1
739
+
740
+ // 13. Return the iterator result for pair and kind.
741
+ return iteratorResult ( pair , kind )
698
742
} ,
699
743
// The class string of an iterator prototype object for a given interface is the
700
744
// result of concatenating the identifier of the interface and the string " Iterator".
@@ -708,6 +752,48 @@ function makeIterator (iterator, name) {
708
752
return Object . setPrototypeOf ( { } , i )
709
753
}
710
754
755
+ // https://webidl.spec.whatwg.org/#iterator-result
756
+ function iteratorResult ( pair , kind ) {
757
+ let result
758
+
759
+ // 1. Let result be a value determined by the value of kind:
760
+ switch ( kind ) {
761
+ case 'key' : {
762
+ // 1. Let idlKey be pair’s key.
763
+ // 2. Let key be the result of converting idlKey to an
764
+ // ECMAScript value.
765
+ // 3. result is key.
766
+ result = pair [ 0 ]
767
+ break
768
+ }
769
+ case 'value' : {
770
+ // 1. Let idlValue be pair’s value.
771
+ // 2. Let value be the result of converting idlValue to
772
+ // an ECMAScript value.
773
+ // 3. result is value.
774
+ result = pair [ 1 ]
775
+ break
776
+ }
777
+ case 'key+value' : {
778
+ // 1. Let idlKey be pair’s key.
779
+ // 2. Let idlValue be pair’s value.
780
+ // 3. Let key be the result of converting idlKey to an
781
+ // ECMAScript value.
782
+ // 4. Let value be the result of converting idlValue to
783
+ // an ECMAScript value.
784
+ // 5. Let array be ! ArrayCreate(2).
785
+ // 6. Call ! CreateDataProperty(array, "0", key).
786
+ // 7. Call ! CreateDataProperty(array, "1", value).
787
+ // 8. result is array.
788
+ result = pair
789
+ break
790
+ }
791
+ }
792
+
793
+ // 2. Return CreateIterResultObject(result, false).
794
+ return { value : result , done : false }
795
+ }
796
+
711
797
/**
712
798
* @see https://fetch.spec.whatwg.org/#body-fully-read
713
799
*/
0 commit comments