From 13b6f3ab1118c5c4459d728c164d6b8ac45477b5 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Wed, 15 Jul 2020 19:20:13 +0800 Subject: [PATCH 1/7] first step! --- src/tmp.ts | 264 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 264 insertions(+) create mode 100644 src/tmp.ts diff --git a/src/tmp.ts b/src/tmp.ts new file mode 100644 index 000000000..0abb4968d --- /dev/null +++ b/src/tmp.ts @@ -0,0 +1,264 @@ +import * as fs from "fs"; +import * as path from "path"; +import fetch from "node-fetch"; +// import { JSDOM } from "jsdom"; + + + +interface IDLSource { + url: string; + title: string; + deprecated?: boolean; + local?: boolean; +} + +// const idlSelector = [ +// "pre.idl:not(.extract):not(.example)", // bikeshed and ReSpec +// "pre.code code.idl-code", // Web Cryptography +// "pre:not(.extract) code.idl", // HTML +// "#permission-registry + pre.highlight" // Permissions +// ].join(","); + +// const cssPropSelector = [ +// ".propdef dfn", // CSS Fonts, SVG +// ".propdef-title", // SVG Paint Servers +// "dfn.css[data-dfn-type=property]" +// ].join(","); + + +async function fetchIDLs() { + const idlSources = (require("../inputfiles/idlSources.json") as IDLSource[]); + await Promise.all(idlSources.map(async source => { + if (source.local) { + return; + } + await fetchIDL(source); + // fs.writeFileSync(path.join(__dirname, `../inputfiles/idl/${source.title}.widl`), idl + '\n'); + // if (comments) { + // fs.writeFileSync(path.join(__dirname, `../inputfiles/idl/${source.title}.commentmap.json`), comments + '\n'); + // } + })).then( + ()=>{ + console.log(); + console.log(deprecatedSet); + } + ); +} + +const tmpLocalFolder = path.join(__dirname, "localIdlSource"); +const deprecatedSet = new Set(); +// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] +async function fetchIDL(source: IDLSource) { + + if (!fs.existsSync(tmpLocalFolder)) { + fs.mkdirSync(tmpLocalFolder); + } + + if (source.url.endsWith(".idl")) { + return; + } + + const localFile = path.join(tmpLocalFolder, source.title); + let webPageContent: string; + if (fs.existsSync(localFile)) { + webPageContent = fs.readFileSync(localFile, { encoding: "utf-8" }); + } + else { + const response = await fetch(source.url); + webPageContent = await response.text(); + fs.writeFileSync(localFile, webPageContent); + } + if(webPageContent.toLowerCase().includes("deprecated")){ + deprecatedSet.add(source.url); + } + // const dom = JSDOM.fragment( + // ""// webPageContent + // ); + +} + +// function extractIDL(dom: DocumentFragment) { +// const elements = Array.from(dom.querySelectorAll(idlSelector)) +// .filter(el => { +// if (el.parentElement && el.parentElement.classList.contains("example")) { +// return false; +// } +// const previous = el.previousElementSibling; +// if (!previous) { +// return true; +// } +// return !previous.classList.contains("atrisk") && !previous.textContent!.includes("IDL Index"); +// }); +// return elements.map(element => trimCommonIndentation(element.textContent!).trim()).join('\n\n'); +// } + +// function extractCSSDefinitions(dom: DocumentFragment) { +// const properties = Array.from(dom.querySelectorAll(cssPropSelector)) +// .map(element => element.textContent!.trim()); + +// if (!properties.length) { +// return ""; +// } + +// return `partial interface CSSStyleDeclaration {${ +// properties.map(property => `\n [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString ${ +// hyphenToCamelCase(property) +// };`).join("") +// }\n};`; +// } + +// function hyphenToCamelCase(name: string) { +// const camel = name +// .replace(/^-(\w)/, (_, c) => c) +// .replace(/-(\w)/g, (_, c) => c.toUpperCase()); +// return camel === "float" ? "_float" : camel; +// } + +// function processComments(dom: DocumentFragment) { +// const elements = [...dom.querySelectorAll("dl.domintro")]; +// if (!elements.length) { +// return undefined; +// } + +// const result: Record = {}; +// for (const element of elements) { +// for (const { dt, dd } of generateDescriptionPairs(element)) { +// elements.push(...importNestedList(dd)); +// const comment = dd +// .map(desc => { +// desc.normalize(); +// convertChildPre(desc); +// return innerText(desc).replace(/’/g, "'"); +// }) +// .filter(text => text) +// .join("\n\n"); +// for (const key of dt.map(term => getKey(term.innerHTML))) { +// if (!key) { +// continue; +// } +// const retargeted = retargetCommentKey(key, dom); +// // prefer the first description +// if (!result[retargeted]) { +// result[retargeted] = comment; +// } +// } +// } +// } +// if (!Object.keys(result).length) { +// return undefined; +// } +// return JSON.stringify(result, undefined, 4); +// } + +// function convertChildPre(e: Element) { +// for (const pre of e.querySelectorAll("pre")) { +// const code = pre.querySelector(":scope > code") as HTMLElement; +// if (!code) { +// continue; +// } +// const text = innerText(code, { +// getComputedStyle(_: Element) { +// return { whiteSpace: "pre" } as CSSStyleDeclaration; +// } +// }); +// pre.textContent = "```\n" + text + "\n```"; +// } +// } + +// function getKey(s: string) { +// const keyRegexp = /#dom-([a-zA-Z0-9-_]+)/i; +// const match = s.match(keyRegexp); +// if (match) { +// return match[1]; +// } +// return undefined; +// } + +// function* generateDescriptionPairs(domIntro: Element) { +// const dt: HTMLElement[] = []; +// const dd: HTMLElement[] = []; +// let element = domIntro.firstElementChild; +// while (element) { +// switch (element.localName) { +// case "dt": +// if (dd.length) { +// yield { dt: [...dt], dd: [...dd] }; +// dt.length = dd.length = 0; +// } +// dt.push(element as HTMLElement) +// break; +// case "dd": +// dd.push(element as HTMLElement) +// break; +// default: +// debugger; +// } +// element = element.nextElementSibling; +// } +// if (dd.length) { +// yield { dt: [...dt], dd: [...dd] }; +// } +// } + +// function* importNestedList(elements: Element[]) { +// for (const element of elements) { +// for (const dl of element.getElementsByTagName("dl")) { +// dl.remove(); +// yield dl; +// } +// } +// } + +// /** +// * Specifications tends to keep existing keys even after a member relocation +// * so that external links can be stable and won't broken. +// */ +// function retargetCommentKey(key: string, dom: DocumentFragment) { +// const [parent, member] = key.split(/-/g); +// if (!member) { +// return parent; +// } +// const dfn = dom.getElementById(`dom-${key}`); +// if (!dfn || !dfn.dataset.dfnFor) { +// // The optional third word is for overloads and can be safely ignored. +// return `${parent}-${member}`; +// } +// return `${dfn.dataset.dfnFor.toLowerCase()}-${member}`; +// } + +// /** +// * Remove common indentation: +// *
+//  *       typedef Type = "type";
+//  *
+//  *       dictionary Dictionary {
+//  *         "member"
+//  *       };
+//  *     
+// * Here the textContent has 6 common preceding whitespaces that can be unindented. +// */ +// function trimCommonIndentation(text: string) { +// const lines = text.split("\n"); +// if (!lines[0].trim()) { +// lines.shift(); +// } +// if (!lines[lines.length - 1].trim()) { +// lines.pop(); +// } +// const commonIndentation = Math.min(...lines.filter(line => line.trim()).map(getIndentation)); +// return lines.map(line => line.slice(commonIndentation)).join("\n"); +// } + +// /** Count preceding whitespaces */ +// function getIndentation(line: string) { +// let count = 0; +// for (const ch of line) { +// if (ch !== " ") { +// break; +// } +// count++; +// } +// return count; +// } + +fetchIDLs(); \ No newline at end of file From be34ecee0a50b72c407c587bd72a28e92c707153 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Thu, 16 Jul 2020 19:17:12 +0800 Subject: [PATCH 2/7] beta version. --- README.md | 9 +- inputfiles/deprecatedMessage.json | 32 ++++ manualAnalytics/README.md | 6 + .../idlSourceAppearDeprecateText.ts | 62 ++++++++ manualAnalytics/mdnDeprecatedApis.ts | 139 ++++++++++++++++++ package.json | 1 + src/emitter.ts | 2 +- src/helpers.ts | 6 +- src/index.ts | 15 ++ tsconfig.json | 3 +- 10 files changed, 266 insertions(+), 9 deletions(-) create mode 100644 inputfiles/deprecatedMessage.json create mode 100644 manualAnalytics/README.md create mode 100644 manualAnalytics/idlSourceAppearDeprecateText.ts create mode 100644 manualAnalytics/mdnDeprecatedApis.ts diff --git a/README.md b/README.md index 6933606c2..b0461c934 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 sprecate file rather than merge in comment.json is mdn/apiDescriptions.json would also possiably be deprecated. \ No newline at end of file diff --git a/inputfiles/deprecatedMessage.json b/inputfiles/deprecatedMessage.json new file mode 100644 index 000000000..fe1aa72fb --- /dev/null +++ b/inputfiles/deprecatedMessage.json @@ -0,0 +1,32 @@ +{ + "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.", + "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.", + "MouseScrollEvent": "Do not use this interface for wheel events.\n\nLike MouseWheelEvent, this interface is non-standard and deprecated. It was used in Gecko-based browsers only. Instead use the standard WheelEvent.\n", + "SVGExternalResourcesRequired": " This interface was removed in the SVG 2 specification.", + "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.", + "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.", + "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.", + "SVGAltGlyphDefElement": " This interface was removed in the SVG 2 specification.", + "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.", + "IDBDatabaseException": " This interface was removed from the specification and was replaced by usage of DOMException.", + "FileError": " This interface is obsolete per the latest specification. Use the new DOM4 DOMError interface instead.", + "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.", + "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.", + "SVGAltGlyphItemElement": " This interface was removed in the SVG 2 specification.", + "SVGGlyphElement": " This interface was removed in the SVG 2 specification.", + "SVGRenderingIntent": " This interface was removed in the SVG 2 specification.", + "BlobBuilder": " The BlobBuilder interface has been deprecated in favor of the newly introduced Blob constructor.", + "MouseWheelEvent": "Do not use this interface for wheel events.\n\nLike MouseScrollEvent, this interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard WheelEvent.\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.", + "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).", + "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.", + "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", + "DOMLocator": " This is not implemented in Mozilla", + "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", + "SVGMatrix": " SVG 2 replaced the SVGMatrix interface by the more general DOMMatrix and DOMMatrixReadOnly interfaces.", + "DOMConfiguration": " This interface has never been supported in Gecko, and has been removed from the DOM specification.", + "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.", + "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).", + "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.", + "PerformanceNavigation": "This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\n" +} \ No newline at end of file diff --git a/manualAnalytics/README.md b/manualAnalytics/README.md new file mode 100644 index 000000000..25a113a04 --- /dev/null +++ b/manualAnalytics/README.md @@ -0,0 +1,6 @@ +# READ ME! +All files in this folder aimes to be used by USER rather than CODE. + +Users could have a quick view of some data. +mdnDeprecatedApis.ts -- all api names marked as deprecated in `https://developer.mozilla.org/en-US/docs/Web/API` +idlSourceAppearDeprecateText.ts -- check web pages in `inputfiles/idlSources.json`, to see whether there is text "deprecate". diff --git a/manualAnalytics/idlSourceAppearDeprecateText.ts b/manualAnalytics/idlSourceAppearDeprecateText.ts new file mode 100644 index 000000000..cfd005364 --- /dev/null +++ b/manualAnalytics/idlSourceAppearDeprecateText.ts @@ -0,0 +1,62 @@ +import * as fs from "fs"; +import * as path from "path"; +import fetch from "node-fetch"; +// import { JSDOM } from "jsdom"; + +interface IDLSource { + url: string; + title: string; + deprecated?: boolean; + local?: boolean; +} + +async function fetchIDLs() { + const idlSources = (require("../inputfiles/idlSources.json") as IDLSource[]); + await Promise.all(idlSources.map(async source => { + if (source.local) { + return; + } + await fetchIDL(source); + })).then( + ()=>{ + console.log(); + console.log(deprecatedSet); + } + ); +} + +const tmpLocalFolder = path.join(__dirname, "localIdlSource"); +const deprecatedSet = new Set(); + +// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] + +async function fetchIDL(source: IDLSource) { + + if (!fs.existsSync(tmpLocalFolder)) { + fs.mkdirSync(tmpLocalFolder); + } + + if (source.url.endsWith(".idl")) { + return; + } + + const localFile = path.join(tmpLocalFolder, source.title); + let webPageContent: string; + if (fs.existsSync(localFile)) { + webPageContent = fs.readFileSync(localFile, { encoding: "utf-8" }); + } + else { + const response = await fetch(source.url); + webPageContent = await response.text(); + fs.writeFileSync(localFile, webPageContent); + } + if(webPageContent.toLowerCase().includes("deprecated")){ + deprecatedSet.add(source.url); + } + // const dom = JSDOM.fragment( + // ""// webPageContent + // ); + +} + +fetchIDLs(); \ No newline at end of file diff --git a/manualAnalytics/mdnDeprecatedApis.ts b/manualAnalytics/mdnDeprecatedApis.ts new file mode 100644 index 000000000..09156cca5 --- /dev/null +++ b/manualAnalytics/mdnDeprecatedApis.ts @@ -0,0 +1,139 @@ +import * as fs from "fs"; +import fetch from "node-fetch"; +import { JSDOM } from "jsdom"; +import path from "path"; + +const outputFolder = __dirname + +const mdnDeprecatedApisFile = path.join(outputFolder, "mdnDeprecatedApis.json"); +const mdnObsoleteApisFile = path.join(outputFolder, "mdnObsoleteApis.json"); +const mdnDeprecatedApisReasonFile = path.join(outputFolder, "mdnDeprecatedApisReason.json"); +const mdnObsoleteApisReasonFile = path.join(outputFolder, "mdnObsoleteApisReason.json"); + +const mdnApiWeb = "https://developer.mozilla.org/en-US/docs/Web/API" + +async function fetchInterfaceDescriptions() { + const fragment = await fetchDom(mdnApiWeb); + const InterfacesSelector = '#wikiArticle > div:nth-child(8)'; + + const interfacesFragment = fragment.querySelector(InterfacesSelector); + + if (!interfacesFragment) { + // This is not that right, but is better than nothing. + throw new Error("css selector for interfaces has been changed!"); + } + + const deprecatedIconSelector = '.icon-thumbs-down-alt'; + const deprecatedAPIs = []; + + for (const deprecatedIconElem of interfacesFragment.querySelectorAll(deprecatedIconSelector)) { + const deprecatedAPI = deprecatedIconElem?.parentElement?.parentElement?.previousSibling?.textContent; + if (!deprecatedAPI) { + console.dir(deprecatedIconElem); + throw new Error("some element could not "); + } + deprecatedAPIs.push(deprecatedAPI); + } + + const obsoleteIconSelector = '.icon-trash'; + const obsoleteAPIs = []; + for (const obsoleteIconElem of interfacesFragment.querySelectorAll(obsoleteIconSelector)) { + const obsoleteAPI = obsoleteIconElem?.parentElement?.parentElement?.previousSibling?.textContent; + if (!obsoleteAPI) { + console.dir(obsoleteIconElem); + throw new Error("some element could not "); + } + obsoleteAPIs.push(obsoleteAPI); + } + + fs.writeFileSync(mdnDeprecatedApisFile, JSON.stringify(deprecatedAPIs)); + fs.writeFileSync(mdnObsoleteApisFile, JSON.stringify(obsoleteAPIs)); +} + +async function fetchDeprecatedApiReasons() { + await fetchInterfaceDescriptions(); + + const deprecatedAPIArray: string[] = require(mdnDeprecatedApisFile); + const obsoleteAPIArray: string[] = require(mdnObsoleteApisFile); + + // const maekDeprecatedJsdocApiArray = [...deprecatedAPIArray, ...obsoleteAPIArray]; + + // const deprecatedAPIArray: string[] = JSON.parse(s); + // use Promise.all to acclete. + const mdnDeprecatedApisReason: Record = {}; + const mdnObsoleteApisReason: Record = {}; + + Promise.all(deprecatedAPIArray.map(async apiName => { + const fragment = await fetchDom(`${mdnApiWeb}/${apiName}`); + + let isSearchedArea = true; + const searchArea = Array.from(fragment.querySelector("#wikiArticle")?.children!).filter(item => { + if (item.tagName === "H2") { + isSearchedArea = false; + } + return isSearchedArea; + }); + const reason1 = searchArea.find(e => e.className.split(' ').includes("warning"))?.textContent; + const reason2 = searchArea.find(e => e.className.split(' ').includes("note"))?.textContent; + + // const reason1 = fragment.querySelector("#wikiArticle > .warning")?.textContent; + // const reason2 = fragment.querySelector("#wikiArticle > .note")?.textContent; + + if (reason1 && reason2) { + throw new Error("not consider situation! api name is " + apiName); + } + if (!reason1 && !reason2) { + return Promise.resolve(); + } + const reason = reason1 ?? reason2; + if (!reason) { + throw new Error("impossiable"); + } + mdnDeprecatedApisReason[apiName] = reason.substring(reason.indexOf(':') + 1).replace("\n", ""); + })).then(() => { + fs.writeFileSync(mdnDeprecatedApisReasonFile, JSON.stringify(mdnDeprecatedApisReason)); + }) + + Promise.all(obsoleteAPIArray.map(async apiName => { + const fragment = await fetchDom(`${mdnApiWeb}/${apiName}`); + + let isSearchedArea = true; + const searchArea = Array.from(fragment.querySelector("#wikiArticle")?.children!).filter(item => { + if (item.tagName === "H2") { + isSearchedArea = false; + } + return isSearchedArea; + }); + const reason1 = searchArea.find(e => e.className.split(' ').includes("warning"))?.textContent; + const reason2 = searchArea.find(e => e.className.split(' ').includes("note"))?.textContent; + + // const reason1 = fragment.querySelector("#wikiArticle > .warning")?.textContent; + // const reason2 = fragment.querySelector("#wikiArticle > .note")?.textContent; + + if (reason1 && reason2 && apiName !== "IDBEnvironment") { + throw new Error("not consider situation! api name is " + apiName); + } + if (!reason1 && !reason2) { + return Promise.resolve(); + } + const reason = reason1 ?? reason2; + if (!reason) { + throw new Error("impossiable"); + } + mdnObsoleteApisReason[apiName] = reason.substring(reason.indexOf(':') + 1).replace("\n", ""); + })).then(() => { + fs.writeFileSync(mdnObsoleteApisReasonFile, JSON.stringify(mdnObsoleteApisReason)); + }) +} + +async function fetchDom(url: string) { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`Failed to fetch ${url}`); + } + const responseString = await response.text(); + + return JSDOM.fragment(responseString); +} + +fetchDeprecatedApiReasons(); \ No newline at end of file diff --git a/package.json b/package.json index 9a0757996..a238f0db3 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "node-fetch": "^2.6.0", "print-diff": "^0.1.1", "styleless-innertext": "^1.1.2", + "ts-node": "^8.10.2", "typescript": "next", "webidl2": "^23.12.1" } diff --git a/src/emitter.ts b/src/emitter.ts index 6c6080b8f..5fda3d92a 100644 --- a/src/emitter.ts +++ b/src/emitter.ts @@ -640,7 +640,7 @@ export function emitWebIdl(webidl: Browser.WebIdl, flavor: Flavor) { 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 568ffbf4a..56ac87faf 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 2af14aacd..c1751053d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -72,6 +72,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")); @@ -110,6 +111,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 tmp = target.comment ?? ""; + const tmp2 = "\n * @deprecated " + transformVerbosity(key, value); + target.comment = tmp + tmp2; + } + } + return idl; + } + function transformVerbosity(name: string, description: string): string { for (const regTemplate of removeVerboseIntroductions) { const [{ source: template }, replace] = regTemplate; @@ -177,6 +191,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"]) { diff --git a/tsconfig.json b/tsconfig.json index 1d92daf0d..d5751939e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,7 @@ "noUnusedParameters": true }, "include": [ - "./src" + "./src", + "./manualAnalytics" ] } From ef60cfd849452bc3e076b7cd10aed9613b027359 Mon Sep 17 00:00:00 2001 From: ShuiRuTian <158983297@qq.com> Date: Thu, 16 Jul 2020 22:17:01 +0800 Subject: [PATCH 3/7] less file, optimise code. --- inputfiles/deprecatedMessage.json | 57 ++++++++++++------------ manualAnalytics/mdnDeprecatedApis.ts | 65 +++++++--------------------- manualAnalytics/tsconfig.json | 12 +++++ tsconfig.json | 3 +- 4 files changed, 58 insertions(+), 79 deletions(-) create mode 100644 manualAnalytics/tsconfig.json diff --git a/inputfiles/deprecatedMessage.json b/inputfiles/deprecatedMessage.json index fe1aa72fb..caa43d292 100644 --- a/inputfiles/deprecatedMessage.json +++ b/inputfiles/deprecatedMessage.json @@ -1,32 +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.", - "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.", - "MouseScrollEvent": "Do not use this interface for wheel events.\n\nLike MouseWheelEvent, this interface is non-standard and deprecated. It was used in Gecko-based browsers only. Instead use the standard WheelEvent.\n", - "SVGExternalResourcesRequired": " This interface was removed in the SVG 2 specification.", - "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.", - "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.", - "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.", - "SVGAltGlyphDefElement": " This interface was removed in the SVG 2 specification.", - "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.", - "IDBDatabaseException": " This interface was removed from the specification and was replaced by usage of DOMException.", - "FileError": " This interface is obsolete per the latest specification. Use the new DOM4 DOMError interface instead.", - "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.", - "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.", - "SVGAltGlyphItemElement": " This interface was removed in the SVG 2 specification.", - "SVGGlyphElement": " This interface was removed in the SVG 2 specification.", - "SVGRenderingIntent": " This interface was removed in the SVG 2 specification.", - "BlobBuilder": " The BlobBuilder interface has been deprecated in favor of the newly introduced Blob constructor.", - "MouseWheelEvent": "Do not use this interface for wheel events.\n\nLike MouseScrollEvent, this interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard WheelEvent.\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.", - "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).", - "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.", - "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", - "DOMLocator": " This is not implemented in Mozilla", + "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", - "SVGMatrix": " SVG 2 replaced the SVGMatrix interface by the more general DOMMatrix and DOMMatrixReadOnly interfaces.", - "DOMConfiguration": " This interface has never been supported in Gecko, and has been removed from the DOM specification.", - "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.", - "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).", - "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.", - "PerformanceNavigation": "This interface is deprecated in the Navigation Timing Level 2 specification. Please use the PerformanceNavigationTiming interface instead.\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/manualAnalytics/mdnDeprecatedApis.ts b/manualAnalytics/mdnDeprecatedApis.ts index 09156cca5..fde984e87 100644 --- a/manualAnalytics/mdnDeprecatedApis.ts +++ b/manualAnalytics/mdnDeprecatedApis.ts @@ -5,10 +5,8 @@ import path from "path"; const outputFolder = __dirname -const mdnDeprecatedApisFile = path.join(outputFolder, "mdnDeprecatedApis.json"); -const mdnObsoleteApisFile = path.join(outputFolder, "mdnObsoleteApis.json"); -const mdnDeprecatedApisReasonFile = path.join(outputFolder, "mdnDeprecatedApisReason.json"); -const mdnObsoleteApisReasonFile = path.join(outputFolder, "mdnObsoleteApisReason.json"); +const mdnDeprecatedObsoleteApisFile = path.join(outputFolder, "mdnDeprecatedObsoleteApis.json"); +const mdnDeprecatedObsoleteApisReasonFile = path.join(outputFolder, "mdnDeprecatedObsoleteApisReason.json"); const mdnApiWeb = "https://developer.mozilla.org/en-US/docs/Web/API" @@ -46,57 +44,28 @@ async function fetchInterfaceDescriptions() { obsoleteAPIs.push(obsoleteAPI); } - fs.writeFileSync(mdnDeprecatedApisFile, JSON.stringify(deprecatedAPIs)); - fs.writeFileSync(mdnObsoleteApisFile, JSON.stringify(obsoleteAPIs)); + fs.writeFileSync(mdnDeprecatedObsoleteApisFile, JSON.stringify({ deprecatedAPIs, obsoleteAPIs })); } async function fetchDeprecatedApiReasons() { await fetchInterfaceDescriptions(); + const data = require(mdnDeprecatedObsoleteApisFile); + const deprecatedAPIArray: string[] = data.deprecatedAPIs; + const obsoleteAPIArray: string[] = data.obsoleteAPIs; - const deprecatedAPIArray: string[] = require(mdnDeprecatedApisFile); - const obsoleteAPIArray: string[] = require(mdnObsoleteApisFile); - - // const maekDeprecatedJsdocApiArray = [...deprecatedAPIArray, ...obsoleteAPIArray]; - - // const deprecatedAPIArray: string[] = JSON.parse(s); - // use Promise.all to acclete. const mdnDeprecatedApisReason: Record = {}; const mdnObsoleteApisReason: Record = {}; - Promise.all(deprecatedAPIArray.map(async apiName => { - const fragment = await fetchDom(`${mdnApiWeb}/${apiName}`); - - let isSearchedArea = true; - const searchArea = Array.from(fragment.querySelector("#wikiArticle")?.children!).filter(item => { - if (item.tagName === "H2") { - isSearchedArea = false; - } - return isSearchedArea; - }); - const reason1 = searchArea.find(e => e.className.split(' ').includes("warning"))?.textContent; - const reason2 = searchArea.find(e => e.className.split(' ').includes("note"))?.textContent; - - // const reason1 = fragment.querySelector("#wikiArticle > .warning")?.textContent; - // const reason2 = fragment.querySelector("#wikiArticle > .note")?.textContent; - - if (reason1 && reason2) { - throw new Error("not consider situation! api name is " + apiName); - } - if (!reason1 && !reason2) { - return Promise.resolve(); - } - const reason = reason1 ?? reason2; - if (!reason) { - throw new Error("impossiable"); - } - mdnDeprecatedApisReason[apiName] = reason.substring(reason.indexOf(':') + 1).replace("\n", ""); - })).then(() => { - fs.writeFileSync(mdnDeprecatedApisReasonFile, JSON.stringify(mdnDeprecatedApisReason)); - }) + const dPromise = getReasonPromise(deprecatedAPIArray, (apiname, reason) => { mdnDeprecatedApisReason[apiname] = reason; }); + const oPromise = getReasonPromise(obsoleteAPIArray, (apiname, reason) => { mdnObsoleteApisReason[apiname] = reason; }); + Promise.all([dPromise, oPromise]).then(() => { + fs.writeFileSync(mdnDeprecatedObsoleteApisReasonFile, JSON.stringify({ mdnDeprecatedApisReason, mdnObsoleteApisReason })); + }); +} - Promise.all(obsoleteAPIArray.map(async apiName => { +async function getReasonPromise(apiNameArray: string[], cb: (apiName: string, reason: string) => void) { + return Promise.all(apiNameArray.map(async apiName => { const fragment = await fetchDom(`${mdnApiWeb}/${apiName}`); - let isSearchedArea = true; const searchArea = Array.from(fragment.querySelector("#wikiArticle")?.children!).filter(item => { if (item.tagName === "H2") { @@ -120,10 +89,8 @@ async function fetchDeprecatedApiReasons() { if (!reason) { throw new Error("impossiable"); } - mdnObsoleteApisReason[apiName] = reason.substring(reason.indexOf(':') + 1).replace("\n", ""); - })).then(() => { - fs.writeFileSync(mdnObsoleteApisReasonFile, JSON.stringify(mdnObsoleteApisReason)); - }) + cb(apiName, reason.substring(reason.indexOf(':') + 1).replace(/\n/g, "").trim() + '\n') + })) } async function fetchDom(url: string) { diff --git a/manualAnalytics/tsconfig.json b/manualAnalytics/tsconfig.json new file mode 100644 index 000000000..191ffcfe8 --- /dev/null +++ b/manualAnalytics/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "outDir": "./out", + "strict": true, + "esModuleInterop": true, + "sourceMap": true, + "noUnusedLocals": true, + "noUnusedParameters": true + } +} diff --git a/tsconfig.json b/tsconfig.json index d5751939e..1d92daf0d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,7 +10,6 @@ "noUnusedParameters": true }, "include": [ - "./src", - "./manualAnalytics" + "./src" ] } From 48b4411209a83631d79b6c2a4b0210c9907ac60b Mon Sep 17 00:00:00 2001 From: ShuiRuTian <158983297@qq.com> Date: Thu, 16 Jul 2020 22:21:27 +0800 Subject: [PATCH 4/7] Update baseline. --- baselines/dom.generated.d.ts | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/baselines/dom.generated.d.ts b/baselines/dom.generated.d.ts index 81e514517..5f7143469 100644 --- a/baselines/dom.generated.d.ts +++ b/baselines/dom.generated.d.ts @@ -2328,7 +2328,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; @@ -10527,7 +10529,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; @@ -11514,7 +11517,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; @@ -11604,7 +11609,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; @@ -14776,7 +14783,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; @@ -14900,7 +14909,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; From a21833ab013aba4c7eb03e9ae82562da915a0edf Mon Sep 17 00:00:00 2001 From: ShuiRuTian <158983297@qq.com> Date: Thu, 16 Jul 2020 22:46:30 +0800 Subject: [PATCH 5/7] clean code. --- .gitignore | 3 +- .vscode/launch.template.json | 26 ++ manualAnalytics/README.md | 3 +- .../idlSourceAppearDeprecateText.ts | 10 +- manualAnalytics/mdnDeprecatedApis.ts | 8 +- src/tmp.ts | 264 ------------------ 6 files changed, 38 insertions(+), 276 deletions(-) create mode 100644 .vscode/launch.template.json delete mode 100644 src/tmp.ts 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/.vscode/launch.template.json b/.vscode/launch.template.json new file mode 100644 index 000000000..826536d86 --- /dev/null +++ b/.vscode/launch.template.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Current TS File", + "type": "node", + "request": "launch", + "args": [ + "${relativeFile}" + ], + "runtimeArgs": [ + "--nolazy", + "-r", + "ts-node/register" + ], + "sourceMaps": true, + "cwd": "${workspaceRoot}", + "protocol": "inspector", + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "env": { + "TS_NODE_PROJECT": "${workspaceFolder}/tsconfig.json" + } + } + ] +} \ No newline at end of file diff --git a/manualAnalytics/README.md b/manualAnalytics/README.md index 25a113a04..092853ca0 100644 --- a/manualAnalytics/README.md +++ b/manualAnalytics/README.md @@ -2,5 +2,6 @@ All files in this folder aimes to be used by USER rather than CODE. Users could have a quick view of some data. + mdnDeprecatedApis.ts -- all api names marked as deprecated in `https://developer.mozilla.org/en-US/docs/Web/API` -idlSourceAppearDeprecateText.ts -- check web pages in `inputfiles/idlSources.json`, to see whether there is text "deprecate". +idlSourceAppearDeprecateText.ts -- check web pages in `inputfiles/idlSources.json`, to see whether there is text "deprecate" in the whole page. diff --git a/manualAnalytics/idlSourceAppearDeprecateText.ts b/manualAnalytics/idlSourceAppearDeprecateText.ts index cfd005364..fa7e3c030 100644 --- a/manualAnalytics/idlSourceAppearDeprecateText.ts +++ b/manualAnalytics/idlSourceAppearDeprecateText.ts @@ -18,18 +18,16 @@ async function fetchIDLs() { } await fetchIDL(source); })).then( - ()=>{ - console.log(); - console.log(deprecatedSet); + () => { + fs.writeFileSync(path.join(__dirname, 'idlSourcePossiable.json'), JSON.stringify(Array.from(deprecatedSet))); } ); } +// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] const tmpLocalFolder = path.join(__dirname, "localIdlSource"); const deprecatedSet = new Set(); -// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] - async function fetchIDL(source: IDLSource) { if (!fs.existsSync(tmpLocalFolder)) { @@ -50,7 +48,7 @@ async function fetchIDL(source: IDLSource) { webPageContent = await response.text(); fs.writeFileSync(localFile, webPageContent); } - if(webPageContent.toLowerCase().includes("deprecated")){ + if (webPageContent.toLowerCase().includes("deprecated")) { deprecatedSet.add(source.url); } // const dom = JSDOM.fragment( diff --git a/manualAnalytics/mdnDeprecatedApis.ts b/manualAnalytics/mdnDeprecatedApis.ts index fde984e87..498e12140 100644 --- a/manualAnalytics/mdnDeprecatedApis.ts +++ b/manualAnalytics/mdnDeprecatedApis.ts @@ -10,7 +10,7 @@ const mdnDeprecatedObsoleteApisReasonFile = path.join(outputFolder, "mdnDeprecat const mdnApiWeb = "https://developer.mozilla.org/en-US/docs/Web/API" -async function fetchInterfaceDescriptions() { +async function getDeprecatedObsoleteApiNames() { const fragment = await fetchDom(mdnApiWeb); const InterfacesSelector = '#wikiArticle > div:nth-child(8)'; @@ -47,8 +47,8 @@ async function fetchInterfaceDescriptions() { fs.writeFileSync(mdnDeprecatedObsoleteApisFile, JSON.stringify({ deprecatedAPIs, obsoleteAPIs })); } -async function fetchDeprecatedApiReasons() { - await fetchInterfaceDescriptions(); +async function getDeprecatedObsoleteApiReasons() { + await getDeprecatedObsoleteApiNames(); const data = require(mdnDeprecatedObsoleteApisFile); const deprecatedAPIArray: string[] = data.deprecatedAPIs; const obsoleteAPIArray: string[] = data.obsoleteAPIs; @@ -103,4 +103,4 @@ async function fetchDom(url: string) { return JSDOM.fragment(responseString); } -fetchDeprecatedApiReasons(); \ No newline at end of file +getDeprecatedObsoleteApiReasons(); \ No newline at end of file diff --git a/src/tmp.ts b/src/tmp.ts deleted file mode 100644 index 0abb4968d..000000000 --- a/src/tmp.ts +++ /dev/null @@ -1,264 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import fetch from "node-fetch"; -// import { JSDOM } from "jsdom"; - - - -interface IDLSource { - url: string; - title: string; - deprecated?: boolean; - local?: boolean; -} - -// const idlSelector = [ -// "pre.idl:not(.extract):not(.example)", // bikeshed and ReSpec -// "pre.code code.idl-code", // Web Cryptography -// "pre:not(.extract) code.idl", // HTML -// "#permission-registry + pre.highlight" // Permissions -// ].join(","); - -// const cssPropSelector = [ -// ".propdef dfn", // CSS Fonts, SVG -// ".propdef-title", // SVG Paint Servers -// "dfn.css[data-dfn-type=property]" -// ].join(","); - - -async function fetchIDLs() { - const idlSources = (require("../inputfiles/idlSources.json") as IDLSource[]); - await Promise.all(idlSources.map(async source => { - if (source.local) { - return; - } - await fetchIDL(source); - // fs.writeFileSync(path.join(__dirname, `../inputfiles/idl/${source.title}.widl`), idl + '\n'); - // if (comments) { - // fs.writeFileSync(path.join(__dirname, `../inputfiles/idl/${source.title}.commentmap.json`), comments + '\n'); - // } - })).then( - ()=>{ - console.log(); - console.log(deprecatedSet); - } - ); -} - -const tmpLocalFolder = path.join(__dirname, "localIdlSource"); -const deprecatedSet = new Set(); -// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] -async function fetchIDL(source: IDLSource) { - - if (!fs.existsSync(tmpLocalFolder)) { - fs.mkdirSync(tmpLocalFolder); - } - - if (source.url.endsWith(".idl")) { - return; - } - - const localFile = path.join(tmpLocalFolder, source.title); - let webPageContent: string; - if (fs.existsSync(localFile)) { - webPageContent = fs.readFileSync(localFile, { encoding: "utf-8" }); - } - else { - const response = await fetch(source.url); - webPageContent = await response.text(); - fs.writeFileSync(localFile, webPageContent); - } - if(webPageContent.toLowerCase().includes("deprecated")){ - deprecatedSet.add(source.url); - } - // const dom = JSDOM.fragment( - // ""// webPageContent - // ); - -} - -// function extractIDL(dom: DocumentFragment) { -// const elements = Array.from(dom.querySelectorAll(idlSelector)) -// .filter(el => { -// if (el.parentElement && el.parentElement.classList.contains("example")) { -// return false; -// } -// const previous = el.previousElementSibling; -// if (!previous) { -// return true; -// } -// return !previous.classList.contains("atrisk") && !previous.textContent!.includes("IDL Index"); -// }); -// return elements.map(element => trimCommonIndentation(element.textContent!).trim()).join('\n\n'); -// } - -// function extractCSSDefinitions(dom: DocumentFragment) { -// const properties = Array.from(dom.querySelectorAll(cssPropSelector)) -// .map(element => element.textContent!.trim()); - -// if (!properties.length) { -// return ""; -// } - -// return `partial interface CSSStyleDeclaration {${ -// properties.map(property => `\n [CEReactions] attribute [LegacyNullToEmptyString] CSSOMString ${ -// hyphenToCamelCase(property) -// };`).join("") -// }\n};`; -// } - -// function hyphenToCamelCase(name: string) { -// const camel = name -// .replace(/^-(\w)/, (_, c) => c) -// .replace(/-(\w)/g, (_, c) => c.toUpperCase()); -// return camel === "float" ? "_float" : camel; -// } - -// function processComments(dom: DocumentFragment) { -// const elements = [...dom.querySelectorAll("dl.domintro")]; -// if (!elements.length) { -// return undefined; -// } - -// const result: Record = {}; -// for (const element of elements) { -// for (const { dt, dd } of generateDescriptionPairs(element)) { -// elements.push(...importNestedList(dd)); -// const comment = dd -// .map(desc => { -// desc.normalize(); -// convertChildPre(desc); -// return innerText(desc).replace(/’/g, "'"); -// }) -// .filter(text => text) -// .join("\n\n"); -// for (const key of dt.map(term => getKey(term.innerHTML))) { -// if (!key) { -// continue; -// } -// const retargeted = retargetCommentKey(key, dom); -// // prefer the first description -// if (!result[retargeted]) { -// result[retargeted] = comment; -// } -// } -// } -// } -// if (!Object.keys(result).length) { -// return undefined; -// } -// return JSON.stringify(result, undefined, 4); -// } - -// function convertChildPre(e: Element) { -// for (const pre of e.querySelectorAll("pre")) { -// const code = pre.querySelector(":scope > code") as HTMLElement; -// if (!code) { -// continue; -// } -// const text = innerText(code, { -// getComputedStyle(_: Element) { -// return { whiteSpace: "pre" } as CSSStyleDeclaration; -// } -// }); -// pre.textContent = "```\n" + text + "\n```"; -// } -// } - -// function getKey(s: string) { -// const keyRegexp = /#dom-([a-zA-Z0-9-_]+)/i; -// const match = s.match(keyRegexp); -// if (match) { -// return match[1]; -// } -// return undefined; -// } - -// function* generateDescriptionPairs(domIntro: Element) { -// const dt: HTMLElement[] = []; -// const dd: HTMLElement[] = []; -// let element = domIntro.firstElementChild; -// while (element) { -// switch (element.localName) { -// case "dt": -// if (dd.length) { -// yield { dt: [...dt], dd: [...dd] }; -// dt.length = dd.length = 0; -// } -// dt.push(element as HTMLElement) -// break; -// case "dd": -// dd.push(element as HTMLElement) -// break; -// default: -// debugger; -// } -// element = element.nextElementSibling; -// } -// if (dd.length) { -// yield { dt: [...dt], dd: [...dd] }; -// } -// } - -// function* importNestedList(elements: Element[]) { -// for (const element of elements) { -// for (const dl of element.getElementsByTagName("dl")) { -// dl.remove(); -// yield dl; -// } -// } -// } - -// /** -// * Specifications tends to keep existing keys even after a member relocation -// * so that external links can be stable and won't broken. -// */ -// function retargetCommentKey(key: string, dom: DocumentFragment) { -// const [parent, member] = key.split(/-/g); -// if (!member) { -// return parent; -// } -// const dfn = dom.getElementById(`dom-${key}`); -// if (!dfn || !dfn.dataset.dfnFor) { -// // The optional third word is for overloads and can be safely ignored. -// return `${parent}-${member}`; -// } -// return `${dfn.dataset.dfnFor.toLowerCase()}-${member}`; -// } - -// /** -// * Remove common indentation: -// *
-//  *       typedef Type = "type";
-//  *
-//  *       dictionary Dictionary {
-//  *         "member"
-//  *       };
-//  *     
-// * Here the textContent has 6 common preceding whitespaces that can be unindented. -// */ -// function trimCommonIndentation(text: string) { -// const lines = text.split("\n"); -// if (!lines[0].trim()) { -// lines.shift(); -// } -// if (!lines[lines.length - 1].trim()) { -// lines.pop(); -// } -// const commonIndentation = Math.min(...lines.filter(line => line.trim()).map(getIndentation)); -// return lines.map(line => line.slice(commonIndentation)).join("\n"); -// } - -// /** Count preceding whitespaces */ -// function getIndentation(line: string) { -// let count = 0; -// for (const ch of line) { -// if (ch !== " ") { -// break; -// } -// count++; -// } -// return count; -// } - -fetchIDLs(); \ No newline at end of file From 0240e4c9a926018dc1edb3ddfacbe8b5b5be1339 Mon Sep 17 00:00:00 2001 From: Song <158983297@qq.com> Date: Mon, 3 Aug 2020 10:59:26 +0800 Subject: [PATCH 6/7] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b0461c934..aec487453 100644 --- a/README.md +++ b/README.md @@ -103,4 +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 sprecate file rather than merge in comment.json is mdn/apiDescriptions.json would also possiably be deprecated. \ No newline at end of file +- `deprecatedMessage.json`: the reason why one type is deprecated. The reason why it is a sprecated file rather than merge in comment.json is mdn/apiDescriptions.json would also possiably be deprecated. From a394ee1ceab1a79823f4f053d34f3101056d3a70 Mon Sep 17 00:00:00 2001 From: ShuiRuTian <158983297@qq.com> Date: Thu, 10 Sep 2020 23:44:36 +0800 Subject: [PATCH 7/7] fix as suggest. --- README.md | 2 +- manualAnalytics/README.md | 7 -- .../idlSourceAppearDeprecateText.ts | 60 ---------- manualAnalytics/mdnDeprecatedApis.ts | 106 ------------------ manualAnalytics/tsconfig.json | 12 -- package.json | 1 - src/index.ts | 6 +- 7 files changed, 4 insertions(+), 190 deletions(-) delete mode 100644 manualAnalytics/README.md delete mode 100644 manualAnalytics/idlSourceAppearDeprecateText.ts delete mode 100644 manualAnalytics/mdnDeprecatedApis.ts delete mode 100644 manualAnalytics/tsconfig.json diff --git a/README.md b/README.md index b0461c934..c9a0da2bc 100644 --- a/README.md +++ b/README.md @@ -103,4 +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 sprecate file rather than merge in comment.json is mdn/apiDescriptions.json would also possiably be deprecated. \ No newline at end of file +- `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/manualAnalytics/README.md b/manualAnalytics/README.md deleted file mode 100644 index 092853ca0..000000000 --- a/manualAnalytics/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# READ ME! -All files in this folder aimes to be used by USER rather than CODE. - -Users could have a quick view of some data. - -mdnDeprecatedApis.ts -- all api names marked as deprecated in `https://developer.mozilla.org/en-US/docs/Web/API` -idlSourceAppearDeprecateText.ts -- check web pages in `inputfiles/idlSources.json`, to see whether there is text "deprecate" in the whole page. diff --git a/manualAnalytics/idlSourceAppearDeprecateText.ts b/manualAnalytics/idlSourceAppearDeprecateText.ts deleted file mode 100644 index fa7e3c030..000000000 --- a/manualAnalytics/idlSourceAppearDeprecateText.ts +++ /dev/null @@ -1,60 +0,0 @@ -import * as fs from "fs"; -import * as path from "path"; -import fetch from "node-fetch"; -// import { JSDOM } from "jsdom"; - -interface IDLSource { - url: string; - title: string; - deprecated?: boolean; - local?: boolean; -} - -async function fetchIDLs() { - const idlSources = (require("../inputfiles/idlSources.json") as IDLSource[]); - await Promise.all(idlSources.map(async source => { - if (source.local) { - return; - } - await fetchIDL(source); - })).then( - () => { - fs.writeFileSync(path.join(__dirname, 'idlSourcePossiable.json'), JSON.stringify(Array.from(deprecatedSet))); - } - ); -} -// ['https://www.w3.org/TR/css-color-3/', 'https://www.w3.org/TR/credential-management-1/', 'https://www.w3.org/TR/css-text-decor-3/', 'https://w3c.github.io/media-playback-quality/', 'https://www.w3.org/TR/css-text-3/', 'https://drafts.csswg.org/css-images-3/', 'https://www.w3.org/TR/secure-contexts/', 'https://www.w3.org/TR/SVG2/types.html', 'https://html.spec.whatwg.org/multipage/obsolete.html', 'https://notifications.spec.whatwg.org/', 'https://www.w3.org/TR/SVG2/text.html', 'https://fetch.spec.whatwg.org/', 'https://html.spec.whatwg.org/multipage/webappapis.html', 'https://dom.spec.whatwg.org/', 'https://drafts.fxtf.org/css-masking-1/', 'https://www.w3.org/TR/filter-effects-1/', 'https://drafts.csswg.org/cssom/', 'https://w3c.github.io/webrtc-pc/', 'https://webaudio.github.io/web-audio-api/', 'https://heycam.github.io/webidl/', 'https://www.w3.org/TR/SVG2/pservers.html', 'https://www.w3.org/TR/uievents/'] - -const tmpLocalFolder = path.join(__dirname, "localIdlSource"); -const deprecatedSet = new Set(); - -async function fetchIDL(source: IDLSource) { - - if (!fs.existsSync(tmpLocalFolder)) { - fs.mkdirSync(tmpLocalFolder); - } - - if (source.url.endsWith(".idl")) { - return; - } - - const localFile = path.join(tmpLocalFolder, source.title); - let webPageContent: string; - if (fs.existsSync(localFile)) { - webPageContent = fs.readFileSync(localFile, { encoding: "utf-8" }); - } - else { - const response = await fetch(source.url); - webPageContent = await response.text(); - fs.writeFileSync(localFile, webPageContent); - } - if (webPageContent.toLowerCase().includes("deprecated")) { - deprecatedSet.add(source.url); - } - // const dom = JSDOM.fragment( - // ""// webPageContent - // ); - -} - -fetchIDLs(); \ No newline at end of file diff --git a/manualAnalytics/mdnDeprecatedApis.ts b/manualAnalytics/mdnDeprecatedApis.ts deleted file mode 100644 index 498e12140..000000000 --- a/manualAnalytics/mdnDeprecatedApis.ts +++ /dev/null @@ -1,106 +0,0 @@ -import * as fs from "fs"; -import fetch from "node-fetch"; -import { JSDOM } from "jsdom"; -import path from "path"; - -const outputFolder = __dirname - -const mdnDeprecatedObsoleteApisFile = path.join(outputFolder, "mdnDeprecatedObsoleteApis.json"); -const mdnDeprecatedObsoleteApisReasonFile = path.join(outputFolder, "mdnDeprecatedObsoleteApisReason.json"); - -const mdnApiWeb = "https://developer.mozilla.org/en-US/docs/Web/API" - -async function getDeprecatedObsoleteApiNames() { - const fragment = await fetchDom(mdnApiWeb); - const InterfacesSelector = '#wikiArticle > div:nth-child(8)'; - - const interfacesFragment = fragment.querySelector(InterfacesSelector); - - if (!interfacesFragment) { - // This is not that right, but is better than nothing. - throw new Error("css selector for interfaces has been changed!"); - } - - const deprecatedIconSelector = '.icon-thumbs-down-alt'; - const deprecatedAPIs = []; - - for (const deprecatedIconElem of interfacesFragment.querySelectorAll(deprecatedIconSelector)) { - const deprecatedAPI = deprecatedIconElem?.parentElement?.parentElement?.previousSibling?.textContent; - if (!deprecatedAPI) { - console.dir(deprecatedIconElem); - throw new Error("some element could not "); - } - deprecatedAPIs.push(deprecatedAPI); - } - - const obsoleteIconSelector = '.icon-trash'; - const obsoleteAPIs = []; - for (const obsoleteIconElem of interfacesFragment.querySelectorAll(obsoleteIconSelector)) { - const obsoleteAPI = obsoleteIconElem?.parentElement?.parentElement?.previousSibling?.textContent; - if (!obsoleteAPI) { - console.dir(obsoleteIconElem); - throw new Error("some element could not "); - } - obsoleteAPIs.push(obsoleteAPI); - } - - fs.writeFileSync(mdnDeprecatedObsoleteApisFile, JSON.stringify({ deprecatedAPIs, obsoleteAPIs })); -} - -async function getDeprecatedObsoleteApiReasons() { - await getDeprecatedObsoleteApiNames(); - const data = require(mdnDeprecatedObsoleteApisFile); - const deprecatedAPIArray: string[] = data.deprecatedAPIs; - const obsoleteAPIArray: string[] = data.obsoleteAPIs; - - const mdnDeprecatedApisReason: Record = {}; - const mdnObsoleteApisReason: Record = {}; - - const dPromise = getReasonPromise(deprecatedAPIArray, (apiname, reason) => { mdnDeprecatedApisReason[apiname] = reason; }); - const oPromise = getReasonPromise(obsoleteAPIArray, (apiname, reason) => { mdnObsoleteApisReason[apiname] = reason; }); - Promise.all([dPromise, oPromise]).then(() => { - fs.writeFileSync(mdnDeprecatedObsoleteApisReasonFile, JSON.stringify({ mdnDeprecatedApisReason, mdnObsoleteApisReason })); - }); -} - -async function getReasonPromise(apiNameArray: string[], cb: (apiName: string, reason: string) => void) { - return Promise.all(apiNameArray.map(async apiName => { - const fragment = await fetchDom(`${mdnApiWeb}/${apiName}`); - let isSearchedArea = true; - const searchArea = Array.from(fragment.querySelector("#wikiArticle")?.children!).filter(item => { - if (item.tagName === "H2") { - isSearchedArea = false; - } - return isSearchedArea; - }); - const reason1 = searchArea.find(e => e.className.split(' ').includes("warning"))?.textContent; - const reason2 = searchArea.find(e => e.className.split(' ').includes("note"))?.textContent; - - // const reason1 = fragment.querySelector("#wikiArticle > .warning")?.textContent; - // const reason2 = fragment.querySelector("#wikiArticle > .note")?.textContent; - - if (reason1 && reason2 && apiName !== "IDBEnvironment") { - throw new Error("not consider situation! api name is " + apiName); - } - if (!reason1 && !reason2) { - return Promise.resolve(); - } - const reason = reason1 ?? reason2; - if (!reason) { - throw new Error("impossiable"); - } - cb(apiName, reason.substring(reason.indexOf(':') + 1).replace(/\n/g, "").trim() + '\n') - })) -} - -async function fetchDom(url: string) { - const response = await fetch(url); - if (!response.ok) { - throw new Error(`Failed to fetch ${url}`); - } - const responseString = await response.text(); - - return JSDOM.fragment(responseString); -} - -getDeprecatedObsoleteApiReasons(); \ No newline at end of file diff --git a/manualAnalytics/tsconfig.json b/manualAnalytics/tsconfig.json deleted file mode 100644 index 191ffcfe8..000000000 --- a/manualAnalytics/tsconfig.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "compilerOptions": { - "target": "es2017", - "module": "commonjs", - "outDir": "./out", - "strict": true, - "esModuleInterop": true, - "sourceMap": true, - "noUnusedLocals": true, - "noUnusedParameters": true - } -} diff --git a/package.json b/package.json index a238f0db3..9a0757996 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,6 @@ "node-fetch": "^2.6.0", "print-diff": "^0.1.1", "styleless-innertext": "^1.1.2", - "ts-node": "^8.10.2", "typescript": "next", "webidl2": "^23.12.1" } diff --git a/src/index.ts b/src/index.ts index c1751053d..55a570237 100644 --- a/src/index.ts +++ b/src/index.ts @@ -116,9 +116,9 @@ function emitDom() { for (const [key, value] of Object.entries(descriptions)) { const target = idl.interfaces!.interface[key] || namespaces[key]; if (target) { - const tmp = target.comment ?? ""; - const tmp2 = "\n * @deprecated " + transformVerbosity(key, value); - target.comment = tmp + tmp2; + const comment = target.comment ?? ""; + const deprecated = "\n * @deprecated " + transformVerbosity(key, value); + target.comment = comment + deprecated; } } return idl;