diff --git a/.gitignore b/.gitignore index c9ba02b34..9b2dda73d 100644 --- a/.gitignore +++ b/.gitignore @@ -281,6 +281,7 @@ __pycache__/ generated/ lib/ inputfiles/browser.webidl.json -.vscode +.vscode/* +!.vscode/launch.template.json package-lock.json yarn.lock diff --git a/README.md b/README.md index 6933606c2..c9a0da2bc 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,9 @@ The common steps to send a pull request are: ### What are the TypeScript team's heuristics for PRs to the DOM APIs -Changes to this repo can have pretty drastic ecosystem effects, because these types are included by default in TypeScript. +Changes to this repo can have pretty drastic ecosystem effects, because these types are included by default in TypeScript. Due to this, we tend to be quite conservative with our approach to introducing changes. -To give you a sense of whether we will accept changes, you can use these heuristics to know up-front if we'll be open to merging. +To give you a sense of whether we will accept changes, you can use these heuristics to know up-front if we'll be open to merging. #### Fixes @@ -71,9 +71,9 @@ To give you a sense of whether we will accept changes, you can use these heurist > For example, adding a new spec or subsection via a new or updated IDL file - Does the new objects or fields show up in [mdn/browser-compat-data](https://github.com/mdn/browser-compat-data)? If not, it's likely too soon. -- Is the IDL source from WHATWG? +- Is the IDL source from WHATWG? - Are the additions available in at least two of Firefox, Safari and Chromium? -- Is the IDL source from W3C? +- Is the IDL source from W3C? - What stage of the [W3C process](https://en.wikipedia.org/wiki/World_Wide_Web_Consortium#Specification_maturation) is the proposal for these changes: We aim for Proposed recommendation, but can accept Candidate recommendation for stable looking proposals. - If it's at Working draft the additions available in all three of Firefox, Safari and Chromium - Could any types added at the global scope have naming conflicts? @@ -103,3 +103,4 @@ To give you a sense of whether we will accept changes, you can use these heurist - `overridingTypes.json`: types that are defined in the spec file but has a better or more up-to-date definitions in the json files. - `removedTypes.json`: types that are defined in the spec file but should be removed. - `comments.json`: comment strings to be embedded in the generated .js files. +- `deprecatedMessage.json`: the reason why one type is deprecated. The reason why it is a separate file rather than merge in comment.json is mdn/apiDescriptions.json would also possibly be deprecated. \ No newline at end of file diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 07b47aaac..7e03be384 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -2330,7 +2330,9 @@ declare var AudioParamMap: { new(): AudioParamMap; }; -/** The Web Audio API events that occur when a ScriptProcessorNode input buffer is ready to be processed. */ +/** The Web Audio API events that occur when a ScriptProcessorNode input buffer is ready to be processed. + * @deprecated As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and is soon to be replaced by AudioWorklet. + */ interface AudioProcessingEvent extends Event { readonly inputBuffer: AudioBuffer; readonly outputBuffer: AudioBuffer; @@ -10562,7 +10564,8 @@ declare var MouseEvent: { new(type: string, eventInitDict?: MouseEventInit): MouseEvent; }; -/** Provides event properties that are specific to modifications to the Document Object Model (DOM) hierarchy and nodes. */ +/** Provides event properties that are specific to modifications to the Document Object Model (DOM) hierarchy and nodes. + * @deprecated DOM4 [DOM] provides a new mechanism using a MutationObserver interface which addresses the use cases that mutation events solve, but in a more performant manner. Thus, this specification describes mutation events for reference and completeness of legacy behavior, but deprecates the use of the MutationEvent interface. */ interface MutationEvent extends Event { readonly attrChange: number; readonly attrName: string; @@ -11548,7 +11551,9 @@ declare var PerformanceMeasure: { new(): PerformanceMeasure; }; -/** The legacy PerformanceNavigation interface represents information about how the navigation to the current document was done. */ +/** The legacy PerformanceNavigation interface represents information about how the navigation to the current document was done. + * @deprecated This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead. + */ interface PerformanceNavigation { readonly redirectCount: number; readonly type: number; @@ -11638,7 +11643,9 @@ declare var PerformanceResourceTiming: { new(): PerformanceResourceTiming; }; -/** A legacy interface kept for backwards compatibility and contains properties that offer performance timing information for various events which occur during the loading and use of the current page. You get a PerformanceTiming object describing your page using the window.performance.timing property. */ +/** A legacy interface kept for backwards compatibility and contains properties that offer performance timing information for various events which occur during the loading and use of the current page. You get a PerformanceTiming object describing your page using the window.performance.timing property. + * @deprecated This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead. + */ interface PerformanceTiming { readonly connectEnd: number; readonly connectStart: number; @@ -14820,7 +14827,9 @@ interface ScriptProcessorNodeEventMap { "audioprocess": AudioProcessingEvent; } -/** Allows the generation, processing, or analyzing of audio using JavaScript. */ +/** Allows the generation, processing, or analyzing of audio using JavaScript. + * @deprecated As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and was replaced by AudioWorklet (see AudioWorkletNode). + */ interface ScriptProcessorNode extends AudioNode { /** @deprecated */ readonly bufferSize: number; @@ -14944,7 +14953,9 @@ declare var ServiceWorkerContainer: { new(): ServiceWorkerContainer; }; -/** This ServiceWorker API interface contains information about an event sent to a ServiceWorkerContainer target. This extends the default message event to allow setting a ServiceWorker object as the source of a message. The event object is accessed via the handler function of a message event, when fired by a message received from a service worker. */ +/** This ServiceWorker API interface contains information about an event sent to a ServiceWorkerContainer target. This extends the default message event to allow setting a ServiceWorker object as the source of a message. The event object is accessed via the handler function of a message event, when fired by a message received from a service worker. + * @deprecated In modern browsers, this interface has been deprecated. Service worker messages will now use the MessageEvent interface, for consistency with other web messaging features. + */ interface ServiceWorkerMessageEvent extends Event { readonly data: any; readonly lastEventId: string; diff --git a/inputfiles/deprecatedMessage.json b/inputfiles/deprecatedMessage.json new file mode 100644 index 000000000..caa43d292 --- /dev/null +++ b/inputfiles/deprecatedMessage.json @@ -0,0 +1,33 @@ +{ + "MutationEvent": "DOM4 [DOM] provides a new mechanism using a MutationObserver interface which addresses the use cases that mutation events solve, but in a more performant manner. Thus, this specification describes mutation events for reference and completeness of legacy behavior, but deprecates the use of the MutationEvent interface.", + "SVGAltGlyphItemElement": "This interface was removed in the SVG 2 specification.\n", + "PerformanceTiming": "This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\n", + "MouseScrollEvent": "Do not use this interface for wheel events.Like MouseWheelEvent, this interface is non-standard and deprecated. It was used in Gecko-based browsers only. Instead use the standard WheelEvent.\n", + "SVGAltGlyphDefElement": "This interface was removed in the SVG 2 specification.\n", + "SVGExternalResourcesRequired": "This interface was removed in the SVG 2 specification.\n", + "SVGMatrix": "SVG 2 replaced the SVGMatrix interface by the more general DOMMatrix and DOMMatrixReadOnly interfaces.\n", + "RTCSessionDescriptionCallback": "Because this function type is part of the legacy WebRTC API, you should avoid using it (and the callback-based forms of createOffer() and createAnswer() that make use of it).\n", + "ServiceWorkerMessageEvent": "In modern browsers, this interface has been deprecated. Service worker messages will now use the MessageEvent interface, for consistency with other web messaging features.\n", + "SVGRenderingIntent": "This interface was removed in the SVG 2 specification.\n", + "PerformanceNavigation": "This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\n", + "AudioProcessingEvent": "As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and is soon to be replaced by AudioWorklet.\n", + "ScriptProcessorNode": "As of the August 29 2014 Web Audio API spec publication, this feature has been marked as deprecated, and was replaced by AudioWorklet (see AudioWorkletNode).\n", + "SVGGlyphElement": "This interface was removed in the SVG 2 specification.\n", + "MouseWheelEvent": "Do not use this interface for wheel events.Like MouseScrollEvent, this interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard WheelEvent.\n", + "IDBDatabaseException": "This interface was removed from the specification and was replaced by usage of DOMException.\n", + "NameList": "Although this interface was previously implemented in Gecko, there was no way to actually create one. NameList has been removed, effective with Gecko 10.0\n", + "IDBDatabaseSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "IDBEnvironment": "The indexedDB property that was previously defined in this mixin is instead now WindowOrWorkerGlobalScope.indexedDB (that is, defined as a member of the WindowOrWorkerGlobalScope mixin).\n", + "IDBFactorySync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "IDBVersionChangeRequest": "The latest specification does not include this interface anymore as the IDBDatabase.setVersion() method has been removed. See the compatibility table for version details.The new way to do it is to use the IDBOpenDBRequest interface which has now the onblocked handler and the newly needed onupgradeneeded one.\n", + "IDBIndexSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "IDBTransactionSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "IDBEnvironmentSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "DOMLocator": "This is not implemented in Mozilla\n", + "LocalMediaStream": "This interface is no longer available in any mainstream browser. Do not use LocalMediaStream; you need to update any code that does use it as soon as possible or your content or application will stop working. See Stopping a video stream in MediaStreamTrack to learn how. All other functionality is found in MediaStream.\n", + "IDBObjectStoreSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "BlobBuilder": "The BlobBuilder interface has been deprecated in favor of the newly introduced Blob constructor.\n", + "IDBCursorSync": "The synchronous version of the IndexedDB API was originally intended for use only with Web Workers, and was eventually removed from the spec because its need was questionable. It may however be reintroduced in the future if there is enough demand from web developers.\n", + "DOMConfiguration": "This interface has never been supported in Gecko, and has been removed from the DOM specification.\n", + "FileError": "This interface is obsolete per the latest specification. Use the new DOM4 DOMError interface instead.\n" +} \ No newline at end of file diff --git a/src/emitter.ts b/src/emitter.ts index 66a97ba2d..e3e7bfd9a 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -653,7 +653,7 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor, iterator: boo if (entity.comment) { entity.comment.split('\n').forEach(print); } - if (entity.deprecated) { + if (entity.deprecated && !entity.comment?.includes('@deprecated')) { print(`/** @deprecated */`); } } diff --git a/src/helpers.ts b/src/helpers.ts index e12f7a300..02671a220 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -70,11 +70,11 @@ export function merge(target: T, src: T, shallow?: boolean): T { if (Array.isArray(targetProp) !== Array.isArray(srcProp)) { throw new Error("Mismatch on property: " + k + JSON.stringify(srcProp)); } - if (shallow && typeof (target[k] as any).name === "string" && typeof (src[k] as any).name === "string") { - target[k] = src[k]; + if (shallow && typeof (targetProp as any).name === "string" && typeof (srcProp as any).name === "string") { + target[k] = srcProp; } else { - target[k] = merge(target[k], src[k], shallow); + target[k] = merge(targetProp, srcProp, shallow); } } } diff --git a/src/index.ts b/src/index.ts index 3e8ff8984..0ca747531 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,6 +66,7 @@ function emitDom() { const overriddenItems = require(path.join(inputFolder, "overridingTypes.json")); const addedItems = require(path.join(inputFolder, "addedTypes.json")); const comments = require(path.join(inputFolder, "comments.json")); + const deprecatedInfo = require(path.join(inputFolder, "deprecatedMessage.json")); const documentationFromMDN = require(path.join(inputFolder, 'mdn', 'apiDescriptions.json')); const removedItems = require(path.join(inputFolder, "removedTypes.json")); const idlSources: any[] = require(path.join(inputFolder, "idlSources.json")); @@ -111,6 +112,19 @@ function emitDom() { return idl; } + function mergeDeprecatedMessage(idl: Browser.WebIdl, descriptions: Record) { + const namespaces = arrayToMap(idl.namespaces!, i => i.name, i => i); + for (const [key, value] of Object.entries(descriptions)) { + const target = idl.interfaces!.interface[key] || namespaces[key]; + if (target) { + const comment = target.comment ?? ""; + const deprecated = "\n * @deprecated " + transformVerbosity(key, value); + target.comment = comment + deprecated; + } + } + return idl; + } + function transformVerbosity(name: string, description: string): string { for (const regTemplate of removeVerboseIntroductions) { const [{ source: template }, replace] = regTemplate; @@ -178,6 +192,7 @@ function emitDom() { webidl = merge(webidl, addedItems); webidl = merge(webidl, overriddenItems); webidl = merge(webidl, comments); + webidl = mergeDeprecatedMessage(webidl, deprecatedInfo); for (const name in webidl.interfaces!.interface) { const i = webidl.interfaces!.interface[name]; if (i["override-exposed"]) {