diff options
author | Luca Casonato <lucacasonato@yahoo.com> | 2021-04-19 01:00:13 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-19 01:00:13 +0200 |
commit | 0552eaf569ef910b0d132b6e60758f17a4519d91 (patch) | |
tree | 6fe6ff3755487475bcef60f3ddb7c8d42432494b /op_crates/webidl/00_webidl.js | |
parent | 0c5ecec8f60d4f1586e56b4e6e36ca973c555830 (diff) |
chore: align `Headers` to spec (#10199)
This commit aligns `Headers` to spec. It also removes the now unused
03_dom_iterable.js file. We now pass all relevant `Headers` WPT. We do
not implement any sort of header filtering, as we are a server side
runtime.
This is likely not the most efficient implementation of `Headers` yet.
It is however spec compliant. Once all the APIs in the `HTTP` hot loop
are correct we can start optimizing them. It is likely that this commit
reduces bench throughput temporarily.
Diffstat (limited to 'op_crates/webidl/00_webidl.js')
-rw-r--r-- | op_crates/webidl/00_webidl.js | 92 |
1 files changed, 74 insertions, 18 deletions
diff --git a/op_crates/webidl/00_webidl.js b/op_crates/webidl/00_webidl.js index 508abe44d..63946c9a1 100644 --- a/op_crates/webidl/00_webidl.js +++ b/op_crates/webidl/00_webidl.js @@ -764,12 +764,16 @@ opts, ); } + const keys = Reflect.ownKeys(V); const result = {}; - for (const key of V) { - const typedKey = keyConverter(key, opts); - const value = V[key]; - const typedValue = valueConverter(value, opts); - result[typedKey] = typedValue; + for (const key of keys) { + const desc = Object.getOwnPropertyDescriptor(V, key); + if (desc !== undefined && desc.enumerable === true) { + const typedKey = keyConverter(key, opts); + const value = V[key]; + const typedValue = valueConverter(value, opts); + result[typedKey] = typedValue; + } } return result; }; @@ -802,29 +806,81 @@ throw new TypeError("Illegal constructor"); } + function define(target, source) { + for (const key of Reflect.ownKeys(source)) { + const descriptor = Reflect.getOwnPropertyDescriptor(source, key); + if (descriptor && !Reflect.defineProperty(target, key, descriptor)) { + throw new TypeError(`Cannot redefine property: ${String(key)}`); + } + } + } + + const _iteratorInternal = Symbol("iterator internal"); + + const globalIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf( + [][Symbol.iterator](), + )); + function mixinPairIterable(name, prototype, dataSymbol, keyKey, valueKey) { + const iteratorPrototype = Object.create(globalIteratorPrototype, { + [Symbol.toStringTag]: { configurable: true, value: `${name} Iterator` }, + }); + define(iteratorPrototype, { + next() { + const internal = this && this[_iteratorInternal]; + if (!internal) { + throw new TypeError( + `next() called on a value that is not a ${name} iterator object`, + ); + } + const { target, kind, index } = internal; + const values = target[dataSymbol]; + const len = values.length; + if (index >= len) { + return { value: undefined, done: true }; + } + const pair = values[index]; + internal.index = index + 1; + let result; + switch (kind) { + case "key": + result = pair[keyKey]; + break; + case "value": + result = pair[valueKey]; + break; + case "key+value": + result = [pair[keyKey], pair[valueKey]]; + break; + } + return { value: result, done: false }; + }, + }); + function createDefaultIterator(target, kind) { + const iterator = Object.create(iteratorPrototype); + Object.defineProperty(iterator, _iteratorInternal, { + value: { target, kind, index: 0 }, + configurable: true, + }); + return iterator; + } + const methods = { - *entries() { + entries() { assertBranded(this, prototype); - for (const entry of this[dataSymbol]) { - yield [entry[keyKey], entry[valueKey]]; - } + return createDefaultIterator(this, "key+value"); }, [Symbol.iterator]() { assertBranded(this, prototype); - return this.entries(); + return createDefaultIterator(this, "key+value"); }, - *keys() { + keys() { assertBranded(this, prototype); - for (const entry of this[dataSymbol]) { - yield entry[keyKey]; - } + return createDefaultIterator(this, "key"); }, - *values() { + values() { assertBranded(this, prototype); - for (const entry of this[dataSymbol]) { - yield entry[valueKey]; - } + return createDefaultIterator(this, "value"); }, forEach(idlCallback, thisArg) { assertBranded(this, prototype); |