Comparing version 15.3.0 to 16.0.0
@@ -19,3 +19,3 @@ "use strict"; | ||
const configurable = !utils.getExtAttr(this.idl.extAttrs, "Unforgeable"); | ||
const configurable = !utils.getExtAttr(this.idl.extAttrs, "LegacyUnforgeable"); | ||
const shouldReflect = | ||
@@ -27,2 +27,6 @@ this.idl.extAttrs.some(attr => attr.name.startsWith("Reflect")) && this.ctx.processReflect !== null; | ||
const async = this.idl.idlType.generic === "Promise"; | ||
const promiseHandlingBefore = async ? `try {` : ``; | ||
const promiseHandlingAfter = async ? `} catch (e) { return Promise.reject(e); }` : ``; | ||
let brandCheck = ` | ||
@@ -53,4 +57,12 @@ if (!exports.is(esValue)) { | ||
if (utils.getExtAttr(this.idl.extAttrs, "LenientThis")) { | ||
brandCheck = ""; | ||
const replaceable = utils.getExtAttr(this.idl.extAttrs, "Replaceable"); | ||
const legacyLenientSetter = utils.getExtAttr(this.idl.extAttrs, "LegacyLenientSetter"); | ||
const legacyLenientThis = utils.getExtAttr(this.idl.extAttrs, "LegacyLenientThis"); | ||
if (legacyLenientThis) { | ||
brandCheck = ` | ||
if (!exports.is(esValue)) { | ||
return; | ||
} | ||
`; | ||
} | ||
@@ -70,8 +82,14 @@ | ||
addMethod(this.idl.name, [], ` | ||
${promiseHandlingBefore} | ||
const esValue = this !== null && this !== undefined ? this : globalObject; | ||
${brandCheck} | ||
${getterBody} | ||
${promiseHandlingAfter} | ||
`, "get", { configurable }); | ||
if (!this.idl.readonly) { | ||
if (async) { | ||
throw new Error(`Illegal promise-typed attribute "${this.idl.name}" in interface "${this.interface.idl.name}"`); | ||
} | ||
let idlConversion; | ||
@@ -101,19 +119,43 @@ if (typeof this.idl.idlType.idlType === "string" && !this.idl.idlType.nullable && | ||
`, "set", { configurable }); | ||
} else if (utils.getExtAttr(this.idl.extAttrs, "PutForwards")) { | ||
addMethod(this.idl.name, ["V"], ` | ||
const esValue = this !== null && this !== undefined ? this : globalObject; | ||
${brandCheck} | ||
this.${this.idl.name}.${utils.getExtAttr(this.idl.extAttrs, "PutForwards").rhs.value} = V; | ||
`, "set", { configurable }); | ||
} else if (utils.getExtAttr(this.idl.extAttrs, "Replaceable")) { | ||
addMethod(this.idl.name, ["V"], ` | ||
const esValue = this !== null && this !== undefined ? this : globalObject; | ||
${brandCheck} | ||
Object.defineProperty(esValue, "${this.idl.name}", { | ||
configurable: true, | ||
enumerable: true, | ||
value: V, | ||
writable: true | ||
}); | ||
`, "set", { configurable }); | ||
} else { | ||
const putForwards = utils.getExtAttr(this.idl.extAttrs, "PutForwards"); | ||
setterBody = ""; | ||
if (replaceable) { | ||
if (legacyLenientThis) { | ||
brandCheck = ""; | ||
} | ||
setterBody = ` | ||
Object.defineProperty(esValue, "${this.idl.name}", { | ||
configurable: true, | ||
enumerable: true, | ||
value: V, | ||
writable: true | ||
}); | ||
`; | ||
} else if (putForwards) { | ||
setterBody = ` | ||
const Q = esValue["${this.idl.name}"]; | ||
if (!utils.isObject(Q)) { | ||
throw new TypeError("Property '${this.idl.name}' is not an object"); | ||
} | ||
`; | ||
// WebIDL calls the `Set` abstract operation with a `Throw` value of `false`: | ||
setterBody += `Reflect.set(Q, "${putForwards.rhs.value}", V);`; | ||
} | ||
if (setterBody) { | ||
addMethod(this.idl.name, ["V"], ` | ||
const esValue = this !== null && this !== undefined ? this : globalObject; | ||
${brandCheck} | ||
${setterBody} | ||
`, "set", { configurable }); | ||
} else if (legacyLenientSetter) { | ||
addMethod(this.idl.name, ["V"], legacyLenientThis ? "" : ` | ||
const esValue = this !== null && this !== undefined ? this : globalObject; | ||
${brandCheck} | ||
`, "set", { configurable }); | ||
} | ||
} | ||
@@ -120,0 +162,0 @@ |
@@ -36,3 +36,3 @@ "use strict"; | ||
const conv = Types.generateTypeConversion( | ||
this.ctx, "value", typeConversion, argAttrs, this.name, `context + " has member ${field.name} that"`); | ||
this.ctx, "value", typeConversion, argAttrs, this.name, `context + " has member '${field.name}' that"`); | ||
this.requires.merge(conv.requires); | ||
@@ -39,0 +39,0 @@ |
@@ -23,4 +23,4 @@ "use strict"; | ||
const string = \`\${value}\`; | ||
if (!enumerationValues.has(value)) { | ||
throw new TypeError(\`\${context} '\${value}' is not a valid enumeration value for ${this.name}\`); | ||
if (!enumerationValues.has(string)) { | ||
throw new TypeError(\`\${context} '\${string}' is not a valid enumeration value for ${this.name}\`); | ||
} | ||
@@ -27,0 +27,0 @@ return string; |
@@ -95,9 +95,4 @@ "use strict"; | ||
// TODO: put back in next major version. | ||
// if (!exposed && !utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) { | ||
// throw new Error(`Interface ${this.name} has neither [Exposed] nor [NoInterfaceObject]`); | ||
// } | ||
// For now: | ||
if (!exposed) { | ||
this.exposed = new Set(["Window"]); | ||
if (!exposed && !utils.getExtAttr(this.idl.extAttrs, "LegacyNoInterfaceObject")) { | ||
throw new Error(`Interface ${this.name} has neither [Exposed] nor [LegacyNoInterfaceObject]`); | ||
} | ||
@@ -107,4 +102,4 @@ | ||
if (legacyWindowAlias) { | ||
if (utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) { | ||
throw new Error(`Interface ${this.name} has [LegacyWindowAlias] and [NoInterfaceObject]`); | ||
if (utils.getExtAttr(this.idl.extAttrs, "LegacyNoInterfaceObject")) { | ||
throw new Error(`Interface ${this.name} has [LegacyWindowAlias] and [LegacyNoInterfaceObject]`); | ||
} | ||
@@ -565,3 +560,3 @@ | ||
const hasNamedDeleter = this.namedDeleter !== null; | ||
const overrideBuiltins = Boolean(utils.getExtAttr(this.idl.extAttrs, "OverrideBuiltins")); | ||
const overrideBuiltins = Boolean(utils.getExtAttr(this.idl.extAttrs, "LegacyOverrideBuiltins")); | ||
@@ -1005,3 +1000,3 @@ const supportsPropertyIndex = (O, index, indexedValue) => { | ||
if ((m.type === "attribute" || m.type === "operation") && m.special !== "static" && | ||
utils.getExtAttr(m.extAttrs, "Unforgeable")) { | ||
utils.getExtAttr(m.extAttrs, "LegacyUnforgeable")) { | ||
unforgeable.add(m.name); | ||
@@ -1216,3 +1211,3 @@ } | ||
exports.new = globalObject => { | ||
const wrapper = makeWrapper(globalObject); | ||
${this.isLegacyPlatformObj ? "let" : "const"} wrapper = makeWrapper(globalObject); | ||
@@ -1371,10 +1366,2 @@ exports._internalSetup(wrapper, globalObject); | ||
// Inheritance is taken care of by "extends" clause in class declaration. | ||
if (utils.getExtAttr(this.idl.extAttrs, "LegacyArrayClass")) { | ||
if (this.idl.inheritance) { | ||
throw new Error(`Interface ${this.name} has [LegacyArrayClass] but inherits from ${this.idl.inheritance}`); | ||
} | ||
this.str += ` | ||
Object.setPrototypeOf(${this.name}.prototype, Array.prototype); | ||
`; | ||
} | ||
@@ -1506,3 +1493,3 @@ const protoProps = new Map(); | ||
exports.install = (globalObject, globalNames = ["Window"]) => { | ||
exports.install = (globalObject, globalNames) => { | ||
if (!globalNames.some(globalName => exposed.has(globalName))) { | ||
@@ -1536,3 +1523,3 @@ return; | ||
if (!utils.getExtAttr(this.idl.extAttrs, "NoInterfaceObject")) { | ||
if (!utils.getExtAttr(this.idl.extAttrs, "LegacyNoInterfaceObject")) { | ||
this.str += ` | ||
@@ -1539,0 +1526,0 @@ Object.defineProperty(globalObject, interfaceName, { |
@@ -22,3 +22,5 @@ "use strict"; | ||
if (utils.isOnInstance(overload, this.interface.idl) !== firstOverloadOnInstance) { | ||
throw new Error(`[Unforgeable] is not applied uniformly to operation "${this.name}" on ${this.interface.name}`); | ||
throw new Error( | ||
`[LegacyUnforgeable] is not applied uniformly to operation "${this.name}" on ${this.interface.name}` | ||
); | ||
} | ||
@@ -29,2 +31,18 @@ } | ||
isAsync() { | ||
// As of the time of this writing, the current spec does not disallow such overloads, but the intention is to do so: | ||
// https://github.com/heycam/webidl/pull/776 | ||
const firstAsync = this.idls[0].idlType.generic === "Promise"; | ||
for (const overload of this.idls.slice(1)) { | ||
const isAsync = overload.idlType.generic === "Promise"; | ||
if (isAsync !== firstAsync) { | ||
throw new Error( | ||
`Overloading between Promise and non-Promise return types is not allowed: operation ` + | ||
`"${this.name}" on ${this.interface.name}` | ||
); | ||
} | ||
} | ||
return firstAsync; | ||
} | ||
fixUpArgsExtAttrs() { | ||
@@ -53,2 +71,5 @@ for (const idl of this.idls) { | ||
const onInstance = this.isOnInstance(); | ||
const async = this.isAsync(); | ||
const promiseHandlingBefore = async ? `try {` : ``; | ||
const promiseHandlingAfter = async ? `} catch (e) { return Promise.reject(e); }` : ``; | ||
@@ -104,6 +125,8 @@ const type = this.static ? "static operation" : "regular operation"; | ||
str = promiseHandlingBefore + str + promiseHandlingAfter; | ||
if (this.static) { | ||
this.interface.addStaticMethod(this.name, argNames, str); | ||
} else { | ||
const forgeable = !utils.getExtAttr(this.idls[0].extAttrs, "Unforgeable"); | ||
const forgeable = !utils.getExtAttr(this.idls[0].extAttrs, "LegacyUnforgeable"); | ||
this.interface.addMethod( | ||
@@ -110,0 +133,0 @@ onInstance ? "instance" : "prototype", |
@@ -359,3 +359,3 @@ "use strict"; | ||
const clamp = utils.getExtAttr(extAttrs, "Clamp"); | ||
const treatNullAs = utils.getExtAttr(extAttrs, "TreatNullAs"); | ||
const nullToEmptyString = utils.getExtAttr(extAttrs, "LegacyNullToEmptyString"); | ||
@@ -369,3 +369,3 @@ let optString = `context: ${errPrefix},`; | ||
} | ||
if (treatNullAs && treatNullAs.rhs.value === "EmptyString") { | ||
if (nullToEmptyString) { | ||
optString += "treatNullAsEmptyString: true,"; | ||
@@ -372,0 +372,0 @@ } |
@@ -41,3 +41,4 @@ "use strict"; | ||
function isOnInstance(memberIDL, interfaceIDL) { | ||
return memberIDL.special !== "static" && (getExtAttr(memberIDL.extAttrs, "Unforgeable") || isGlobal(interfaceIDL)); | ||
return memberIDL.special !== "static" && (getExtAttr(memberIDL.extAttrs, "LegacyUnforgeable") || | ||
isGlobal(interfaceIDL)); | ||
} | ||
@@ -44,0 +45,0 @@ |
{ | ||
"name": "webidl2js", | ||
"version": "15.3.0", | ||
"version": "16.0.0", | ||
"description": "Auto-generates class structures for WebIDL specifications", | ||
@@ -5,0 +5,0 @@ "main": "lib/transformer.js", |
@@ -273,4 +273,2 @@ # JavaScript bindings generator for Web IDL | ||
Temporarily, until the next major release, `globalNames` defaults to `["Window"]`. | ||
#### `create(globalObject, constructorArgs, privateData)` | ||
@@ -314,3 +312,3 @@ | ||
The second argument `globalNames` is the same as for [the `install()` export for interfaces](#installglobalobject-globalnames). (However, it does not have a default.) | ||
The second argument `globalNames` is the same as for [the `install()` export for interfaces](#installglobalobject-globalnames). | ||
@@ -475,13 +473,14 @@ ### For dictionaries | ||
- `[EnforceRange]` | ||
- `[Exposed]` (temporarily defaulting to `[Exposed=Window]`) | ||
- `[LegacyArrayClass]` | ||
- `[Exposed]` | ||
- `[LegacyLenientThis]` | ||
- `[LegacyLenientSetter]` | ||
- `[LegacyNoInterfaceObject]` | ||
- `[LegacyNullToEmptyString]` | ||
- `[LegacyOverrideBuiltins]` | ||
- `[LegacyUnenumerableNamedProperties]` | ||
- `[LegacyUnforgeable]` | ||
- `[LegacyWindowAlias]` | ||
- `[NoInterfaceObject]` | ||
- `[OverrideBuiltins]` | ||
- `[PutForwards]` | ||
- `[Replaceable]` | ||
- `[SameObject]` (automatic caching) | ||
- `[TreatNullAs]` | ||
- `[Unforgeable]` | ||
- `[Unscopable]` | ||
@@ -501,7 +500,6 @@ | ||
- `[Global]`'s various consequences, including the named properties object and `[[SetPrototypeOf]]` | ||
- `[LenientSetter]` | ||
- `[LenientThis]` | ||
- `[NamedConstructor]` | ||
- `[LegacyFactoryFunction]` | ||
- `[LegacyNamespace]` | ||
- `[LegacyTreatNonObjectAsNull]` | ||
- `[SecureContext]` | ||
- `[TreatNonObjectAsNull]` | ||
@@ -508,0 +506,0 @@ ## Nonstandard extended attributes |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
162836
3745
513