diff --git a/build/build-cdt-lib.js b/build/build-cdt-lib.js index cac2eaf2fdc3..a465a461c58f 100644 --- a/build/build-cdt-lib.js +++ b/build/build-cdt-lib.js @@ -34,44 +34,16 @@ const modifications = [ 'const Common = require(\'../Common.js\');', 'const Platform = require(\'../Platform.js\');', '%sourceFilePrinted%', - 'module.exports = TextSourceMap;', + 'module.exports = SourceMap;', + 'SourceMap.parseSourceMap = parseSourceMap;', ].join('\n'), rawCodeToReplace: { - /* Original: - - let url = Common.ParsedURL.ParsedURL.completeURL(this.#baseURL, href) || href; - const source = sourceMap.sourcesContent && sourceMap.sourcesContent[i]; - if (url === this.#compiledURLInternal && source) { - url = Common.ParsedURL.ParsedURL.concatenate(url, '? [sm]'); - } - if (this.#sourceInfos.has(url)) { - continue; - } - this.#sourceInfos.set(url, new TextSourceMap.SourceInfo(source || null, null)); - sourcesList.push(url); - ---- - If a source file is the same as the compiled url and there is a sourcesContent, - then `entry.sourceURL` (what is returned from .mappings) will have `? [sm]` appended. - This is useful in DevTools - to show that a sources panel tab not a real network resource - - but for us it is not wanted. The sizing function uses `entry.sourceURL` to index the byte - counts, and is further used in the details to specify a file within a source map. - */ - [`url = Common.ParsedURL.ParsedURL.concatenate(url, '? [sm]');`]: '', // Use normal console.warn so we don't need to import CDT's logger. 'Common.Console.Console.instance().warn': 'console.warn', - // Similar to the reason for removing `url += Common.UIString('? [sm]')`. // The entries in `.mappings` should not have their url property modified. + // The sizing function uses `entry.sourceURL` to index the byte + // counts, and is further used in the details to specify a file within a source map. 'Common.ParsedURL.ParsedURL.completeURL(this.#baseURL, href)': `''`, - // Replace i18n function with a very simple templating function. - 'i18n.i18n.getLocalizedString.bind(undefined, str_)': ( - /** @param {string} template @param {object} vars */ - function(template, vars) { - let result = template; - for (const [key, value] of Object.entries(vars)) { - result = result.replace(new RegExp('{' + key + '}'), value); - } - return result; - }).toString(), // Add some types. // eslint-disable-next-line max-len 'mappings(): SourceMapEntry[] {': '/** @return {Array<{lineNumber: number, columnNumber: number, sourceURL?: string, sourceLineNumber: number, sourceColumnNumber: number, name?: string, lastColumnNumber?: number}>} */\nmappings(): SourceMapEntry[] {', @@ -79,20 +51,14 @@ const modifications = [ classesToRemove: [], methodsToRemove: [ // Not needed. + 'compatibleForURL', 'load', - // Not needed. - 'sourceContentProvider', + 'reverseMapTextRanges', ], variablesToRemove: [ 'Common', - 'CompilerSourceMappingContentProvider_js_1', - 'i18n', - 'i18nString', - 'PageResourceLoader_js_1', 'Platform', - 'str_', 'TextUtils', - 'UIStrings', ], }, { @@ -233,15 +199,24 @@ function doModification(modification) { sourceFilePrinted += printer.printNode(ts.EmitHint.Unspecified, node, sourceFile) + '\n'; }); + const content = modification.template.replace('%sourceFilePrinted%', () => sourceFilePrinted); + writeGeneratedFile(modification.output, content); +} + +/** + * @param {string} outputPath + * @param {string} contents + */ +function writeGeneratedFile(outputPath, contents) { const modifiedFile = [ '// @ts-nocheck\n', '// generated by yarn build-cdt-lib\n', '/* eslint-disable */\n', '"use strict";\n', - modification.template.replace('%sourceFilePrinted%', () => sourceFilePrinted), + contents, ].join(''); - fs.writeFileSync(modification.output, modifiedFile); + fs.writeFileSync(outputPath, modifiedFile); } modifications.forEach(doModification); diff --git a/build/build-cdt-strings.js b/build/build-cdt-strings.js index dd8d68521abb..58e78f83612b 100644 --- a/build/build-cdt-strings.js +++ b/build/build-cdt-strings.js @@ -19,6 +19,17 @@ function doReplacement(text, searchValue, replaceValue) { return newValue; } +/** + * @param {string} text + * @param {[string|RegExp, string][]} replacements + */ +function doReplacements(text, replacements) { + for (const replacement of replacements) { + text = doReplacement(text, replacement[0], replacement[1]); + } + return text; +} + /** * @param {string} text * @param {string} startPattern @@ -31,11 +42,8 @@ function extract(text, startPattern, endPattern, replacements = []) { const endIndex = text.indexOf(endPattern, startIndex); if (endIndex === -1) throw new Error(`could not find: ${endPattern}`); - let subText = text.substring(startIndex, endIndex + endPattern.length); - for (const replacement of replacements) { - subText = doReplacement(subText, replacement[0], replacement[1]); - } - return subText; + const subText = text.substring(startIndex, endIndex + endPattern.length); + return doReplacements(subText, replacements); } /** @@ -59,39 +67,21 @@ ${extraCode}`.trimStart(); // core/lib/deprecations-strings.js { // eslint-disable-next-line max-len - const inFile = `${LH_ROOT}/node_modules/chrome-devtools-frontend/front_end/models/issues_manager/DeprecationIssue.ts`; - const outFile = `${LH_ROOT}/core/lib/deprecations-strings.js`; - - const input = fs.readFileSync(inFile, 'utf-8'); - - const uiStringsDeclare = extract(input, 'const UIStrings', '};', [ - // Some patterns are supported in DevTools UIStrings, but not ours. - [/\\\\/g, ''], - [`\\'plan-b\\'`, 'plan-b'], - ]); - const getDescriptionDeclare = - extract(input, 'getDescription(): MarkdownIssueDescription', '});\n }', [ - ['getDescription(): MarkdownIssueDescription', 'function getDescription(issueDetails)'], - ['this.#issueDetails', 'issueDetails'], - [`let messageFunction = (): string => '';`, `let message;`], - [/messageFunction/g, 'message'], - [/i18nLazyString/g, 'str_'], - ['resolveLazyDescription', ''], - ['links,', 'links, message,'], - [/Protocol\.Audits\.DeprecationIssueType\.(\w+)/g, `'$1'`], - ]); - - const extraCode = ` -/** - * @param {LH.Crdp.Audits.DeprecationIssueDetails} issueDetails - */ -${getDescriptionDeclare} - -export { - getDescription as getIssueDetailDescription, - UIStrings, -};`; - fs.writeFileSync(outFile, createStringsModule(uiStringsDeclare, extraCode)); + const uiStringsFile = `${LH_ROOT}/node_modules/chrome-devtools-frontend/front_end/generated/Deprecation.ts`; + const generatedDeprecationSourceText = [ + '// auto-generated by build/build-cdt-strings.js\n', + '/* eslint-disable */\n', + doReplacements(fs.readFileSync(uiStringsFile, 'utf-8'), [ + [': Partial>', ''], + ['export interface DeprecationDescriptor {', ''], + [' milestone?: number;', ''], + [' chromeStatusFeature?: number;\n}', ''], + // Some patterns are supported in DevTools UIStrings, but not ours. + [/\\\\/g, ''], + [`{imageOrientation: 'from-image'}`, `\\\\{imageOrientation: 'from-image'\\\\}`], + ]), + ].join(''); + fs.writeFileSync(`${LH_ROOT}/core/lib/deprecations-strings.js`, generatedDeprecationSourceText); } // core/lib/bf-cache-strings.js diff --git a/core/audits/deprecations.js b/core/audits/deprecations.js index 81e1f637e367..df2c9038d16c 100644 --- a/core/audits/deprecations.js +++ b/core/audits/deprecations.js @@ -11,7 +11,7 @@ import {Audit} from './audit.js'; import {JSBundles} from '../computed/js-bundles.js'; import * as i18n from '../lib/i18n/i18n.js'; -import {getIssueDetailDescription} from '../lib/deprecations-strings.js'; +import {getIssueDetailDescription} from '../lib/deprecation-description.js'; /* eslint-disable max-len */ const UIStrings = { diff --git a/core/lib/bf-cache-strings.js b/core/lib/bf-cache-strings.js index 89dd98226632..76d262ec690d 100644 --- a/core/lib/bf-cache-strings.js +++ b/core/lib/bf-cache-strings.js @@ -5,514 +5,527 @@ import * as i18n from '../lib/i18n/i18n.js'; const UIStrings = { /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ notMainFrame: 'Navigation happened in a frame other than the main frame.', /** - * @description Description text for not restored reason BackForwardCacheDisabled. - */ + * @description Description text for not restored reason BackForwardCacheDisabled. + */ backForwardCacheDisabled: 'Back/forward cache is disabled by flags. Visit chrome://flags/#back-forward-cache to enable it locally on this device.', /** - * @description Description text for not restored reason RelatedActiveContentsExist. - * Note: "window.open()" is the name of a JavaScript method and should not be translated. - */ + * @description Description text for not restored reason RelatedActiveContentsExist. + * Note: "window.open()" is the name of a JavaScript method and should not be translated. + */ relatedActiveContentsExist: 'The page was opened using \'`window.open()`\' and another tab has a reference to it, or the page opened a window.', /** - * @description Description text for not restored reason HTTPStatusNotOK. - */ + * @description Description text for not restored reason HTTPStatusNotOK. + */ HTTPStatusNotOK: 'Only pages with a status code of 2XX can be cached.', /** - * @description Description text for not restored reason SchemeNotHTTPOrHTTPS. - */ + * @description Description text for not restored reason SchemeNotHTTPOrHTTPS. + */ schemeNotHTTPOrHTTPS: 'Only pages whose URL scheme is HTTP / HTTPS can be cached.', /** - * @description Description text for not restored reason Loading. - */ + * @description Description text for not restored reason Loading. + */ loading: 'The page did not finish loading before navigating away.', /** - * @description Description text for not restored reason WasGrantedMediaAccess. - */ + * @description Description text for not restored reason WasGrantedMediaAccess. + */ wasGrantedMediaAccess: 'Pages that have granted access to record video or audio are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason HTTPMethodNotGET. - */ + * @description Description text for not restored reason HTTPMethodNotGET. + */ HTTPMethodNotGET: 'Only pages loaded via a GET request are eligible for back/forward cache.', /** - * @description Description text for not restored reason SubframeIsNavigating. - */ + * @description Description text for not restored reason SubframeIsNavigating. + */ subframeIsNavigating: 'An iframe on the page started a navigation that did not complete.', /** - * @description Description text for not restored reason Timeout. - */ + * @description Description text for not restored reason Timeout. + */ timeout: 'The page exceeded the maximum time in back/forward cache and was expired.', /** - * @description Description text for not restored reason CacheLimit. - */ + * @description Description text for not restored reason CacheLimit. + */ cacheLimit: 'The page was evicted from the cache to allow another page to be cached.', /** - * @description Description text for not restored reason JavaScriptExecution. - */ + * @description Description text for not restored reason JavaScriptExecution. + */ JavaScriptExecution: 'Chrome detected an attempt to execute JavaScript while in the cache.', /** - * @description Description text for not restored reason RendererProcessKilled. - */ + * @description Description text for not restored reason RendererProcessKilled. + */ rendererProcessKilled: 'The renderer process for the page in back/forward cache was killed.', /** - * @description Description text for not restored reason RendererProcessCrashed. - */ + * @description Description text for not restored reason RendererProcessCrashed. + */ rendererProcessCrashed: 'The renderer process for the page in back/forward cache crashed.', /** - * @description Description text for not restored reason GrantedMediaStreamAccess. - */ + * @description Description text for not restored reason GrantedMediaStreamAccess. + */ grantedMediaStreamAccess: 'Pages that have granted media stream access are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason CacheFlushed. - */ + * @description Description text for not restored reason CacheFlushed. + */ cacheFlushed: 'The cache was intentionally cleared.', /** - * @description Description text for not restored reason ServiceWorkerVersionActivation. - */ + * @description Description text for not restored reason ServiceWorkerVersionActivation. + */ serviceWorkerVersionActivation: 'The page was evicted from back/forward cache due to a service worker activation.', /** - * @description Description text for not restored reason SessionRestored. - */ + * @description Description text for not restored reason SessionRestored. + */ sessionRestored: 'Chrome restarted and cleared the back/forward cache entries.', /** - * @description Description text for not restored reason ServiceWorkerPostMessage. - * Note: "MessageEvent" should not be translated. - */ + * @description Description text for not restored reason ServiceWorkerPostMessage. + * Note: "MessageEvent" should not be translated. + */ serviceWorkerPostMessage: 'A service worker attempted to send the page in back/forward cache a `MessageEvent`.', /** - * @description Description text for not restored reason EnteredBackForwardCacheBeforeServiceWorkerHostAdded. - */ + * @description Description text for not restored reason EnteredBackForwardCacheBeforeServiceWorkerHostAdded. + */ enteredBackForwardCacheBeforeServiceWorkerHostAdded: 'A service worker was activated while the page was in back/forward cache.', /** - * @description Description text for not restored reason ServiceWorkerClaim. - */ + * @description Description text for not restored reason ServiceWorkerClaim. + */ serviceWorkerClaim: 'The page was claimed by a service worker while it is in back/forward cache.', /** - * @description Description text for not restored reason HaveInnerContents. - */ + * @description Description text for not restored reason HaveInnerContents. + */ haveInnerContents: 'Pages that use portals are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason TimeoutPuttingInCache. - */ + * @description Description text for not restored reason TimeoutPuttingInCache. + */ timeoutPuttingInCache: 'The page timed out entering back/forward cache (likely due to long-running pagehide handlers).', /** - * @description Description text for not restored reason BackForwardCacheDisabledByLowMemory. - */ + * @description Description text for not restored reason BackForwardCacheDisabledByLowMemory. + */ backForwardCacheDisabledByLowMemory: 'Back/forward cache is disabled due to insufficient memory.', /** - * @description Description text for not restored reason BackForwardcCacheDisabledByCommandLine. - */ + * @description Description text for not restored reason BackForwardcCacheDisabledByCommandLine. + */ backForwardCacheDisabledByCommandLine: 'Back/forward cache is disabled by the command line.', /** - * @description Description text for not restored reason NetworkRequestDatapipeDrainedAsBytesConsumer. - */ + * @description Description text for not restored reason NetworkRequestDatapipeDrainedAsBytesConsumer. + */ networkRequestDatapipeDrainedAsBytesConsumer: 'Pages that have inflight fetch() or XHR are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason NetworkRequestRedirected. - */ + * @description Description text for not restored reason NetworkRequestRedirected. + */ networkRequestRedirected: 'The page was evicted from back/forward cache because an active network request involved a redirect.', /** - * @description Description text for not restored reason NetworkRequestTimeout. - */ + * @description Description text for not restored reason NetworkRequestTimeout. + */ networkRequestTimeout: 'The page was evicted from the cache because a network connection was open too long. Chrome limits the amount of time that a page may receive data while cached.', /** - * @description Description text for not restored reason NetworkExceedsBufferLimit. - */ + * @description Description text for not restored reason NetworkExceedsBufferLimit. + */ networkExceedsBufferLimit: 'The page was evicted from the cache because an active network connection received too much data. Chrome limits the amount of data that a page may receive while cached.', /** - * @description Description text for not restored reason NavigationCancelledWhileRestoring. - */ + * @description Description text for not restored reason NavigationCancelledWhileRestoring. + */ navigationCancelledWhileRestoring: 'Navigation was cancelled before the page could be restored from back/forward cache.', /** - * @description Description text for not restored reason BackForwardCacheDisabledForPrerender. - */ + * @description Description text for not restored reason BackForwardCacheDisabledForPrerender. + */ backForwardCacheDisabledForPrerender: 'Back/forward cache is disabled for prerenderer.', /** - * @description Description text for not restored reason userAgentOverrideDiffers. - */ + * @description Description text for not restored reason userAgentOverrideDiffers. + */ userAgentOverrideDiffers: 'Browser has changed the user agent override header.', /** - * @description Description text for not restored reason ForegroundCacheLimit. - */ + * @description Description text for not restored reason ForegroundCacheLimit. + */ foregroundCacheLimit: 'The page was evicted from the cache to allow another page to be cached.', /** - * @description Description text for not restored reason BackForwardCacheDisabledForDelegate. - */ + * @description Description text for not restored reason BackForwardCacheDisabledForDelegate. + */ backForwardCacheDisabledForDelegate: 'Back/forward cache is not supported by delegate.', /** - * @description Description text for not restored reason UnloadHandlerExistsInMainFrame. - */ + * @description Description text for not restored reason UnloadHandlerExistsInMainFrame. + */ unloadHandlerExistsInMainFrame: 'The page has an unload handler in the main frame.', /** - * @description Description text for not restored reason UnloadHandlerExistsInSubFrame. - */ + * @description Description text for not restored reason UnloadHandlerExistsInSubFrame. + */ unloadHandlerExistsInSubFrame: 'The page has an unload handler in a sub frame.', /** - * @description Description text for not restored reason ServiceWorkerUnregistration. - */ + * @description Description text for not restored reason ServiceWorkerUnregistration. + */ serviceWorkerUnregistration: 'ServiceWorker was unregistered while a page was in back/forward cache.', /** - * @description Description text for not restored reason NoResponseHead. - */ + * @description Description text for not restored reason NoResponseHead. + */ noResponseHead: 'Pages that do not have a valid response head cannot enter back/forward cache.', /** - * @description Description text for not restored reason CacheControlNoStore. - */ + * @description Description text for not restored reason CacheControlNoStore. + */ cacheControlNoStore: 'Pages with cache-control:no-store header cannot enter back/forward cache.', /** - * @description Description text for not restored reason IneligibleAPI. - */ + * @description Description text for not restored reason IneligibleAPI. + */ ineligibleAPI: 'Ineligible APIs were used.', /** - * @description Description text for not restored reason InternalError. - */ + * @description Description text for not restored reason InternalError. + */ internalError: 'Internal error.', /** - * @description Description text for not restored reason WebSocket. - */ + * @description Description text for not restored reason WebSocket. + */ webSocket: 'Pages with WebSocket cannot enter back/forward cache.', /** - * @description Description text for not restored reason WebTransport. - */ + * @description Description text for not restored reason WebTransport. + */ webTransport: 'Pages with WebTransport cannot enter back/forward cache.', /** - * @description Description text for not restored reason WebRTC. - */ + * @description Description text for not restored reason WebRTC. + */ webRTC: 'Pages with WebRTC cannot enter back/forward cache.', /** - * @description Description text for not restored reason MainResourceHasCacheControlNoStore. - */ + * @description Description text for not restored reason MainResourceHasCacheControlNoStore. + */ mainResourceHasCacheControlNoStore: 'Pages whose main resource has cache-control:no-store cannot enter back/forward cache.', /** - * @description Description text for not restored reason MainResourceHasCacheControlNoCache. - */ + * @description Description text for not restored reason MainResourceHasCacheControlNoCache. + */ mainResourceHasCacheControlNoCache: 'Pages whose main resource has cache-control:no-cache cannot enter back/forward cache.', /** - * @description Description text for not restored reason SubresourceHasCacheControlNoStore. - */ + * @description Description text for not restored reason SubresourceHasCacheControlNoStore. + */ subresourceHasCacheControlNoStore: 'Pages whose subresource has cache-control:no-store cannot enter back/forward cache.', /** - * @description Description text for not restored reason SubresourceHasCacheControlNoCache. - */ + * @description Description text for not restored reason SubresourceHasCacheControlNoCache. + */ subresourceHasCacheControlNoCache: 'Pages whose subresource has cache-control:no-cache cannot enter back/forward cache.', /** - * @description Description text for not restored reason ContainsPlugins. - */ + * @description Description text for not restored reason ContainsPlugins. + */ containsPlugins: 'Pages containing plugins are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason DocumentLoaded. - */ + * @description Description text for not restored reason DocumentLoaded. + */ documentLoaded: 'The document did not finish loading before navigating away.', /** - * @description Description text for not restored reason DedicatedWorkerOrWorklet. - */ + * @description Description text for not restored reason DedicatedWorkerOrWorklet. + */ dedicatedWorkerOrWorklet: 'Pages that use a dedicated worker or worklet are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason OutstandingNetworkRequestOthers. - */ + * @description Description text for not restored reason OutstandingNetworkRequestOthers. + */ outstandingNetworkRequestOthers: 'Pages with an in-flight network request are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason OutstandingIndexedDBTransaction. - */ + * @description Description text for not restored reason OutstandingIndexedDBTransaction. + */ outstandingIndexedDBTransaction: 'Page with ongoing indexed DB transactions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedNotificationsPermission. - */ + * @description Description text for not restored reason RequestedNotificationsPermission. + */ requestedNotificationsPermission: 'Pages that have requested notifications permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedMIDIPermission. - */ + * @description Description text for not restored reason RequestedMIDIPermission. + */ requestedMIDIPermission: 'Pages that have requested MIDI permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedAudioCapturePermission. - */ + * @description Description text for not restored reason RequestedAudioCapturePermission. + */ requestedAudioCapturePermission: 'Pages that have requested audio capture permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedVideoCapturePermission. - */ + * @description Description text for not restored reason RequestedVideoCapturePermission. + */ requestedVideoCapturePermission: 'Pages that have requested video capture permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedBackForwardCacheBlockedSensors. - */ + * @description Description text for not restored reason RequestedBackForwardCacheBlockedSensors. + */ requestedBackForwardCacheBlockedSensors: 'Pages that have requested sensor permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason RequestedBackgroundWorkPermission. - */ + * @description Description text for not restored reason RequestedBackgroundWorkPermission. + */ requestedBackgroundWorkPermission: 'Pages that have requested background sync or fetch permissions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason BroadcastChannel. - */ + * @description Description text for not restored reason BroadcastChannel. + */ broadcastChannel: 'The page cannot be cached because it has a BroadcastChannel instance with registered listeners.', /** - * @description Description text for not restored reason IndexedDBConnection. - */ + * @description Description text for not restored reason IndexedDBConnection. + */ indexedDBConnection: 'Pages that have an open IndexedDB connection are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebXR. - */ + * @description Description text for not restored reason WebXR. + */ webXR: 'Pages that use WebXR are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason SharedWorker. - */ + * @description Description text for not restored reason SharedWorker. + */ sharedWorker: 'Pages that use SharedWorker are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebLocks. - */ + * @description Description text for not restored reason WebLocks. + */ webLocks: 'Pages that use WebLocks are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebHID. - */ + * @description Description text for not restored reason WebHID. + */ webHID: 'Pages that use WebHID are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebShare. - */ + * @description Description text for not restored reason WebShare. + */ webShare: 'Pages that use WebShare are not currently eligible for back/forwad cache.', /** - * @description Description text for not restored reason RequestedStorageAccessGrant. - */ + * @description Description text for not restored reason RequestedStorageAccessGrant. + */ requestedStorageAccessGrant: 'Pages that have requested storage access are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebNfc. - */ + * @description Description text for not restored reason WebNfc. + */ webNfc: 'Pages that use WebNfc are not currently eligible for back/forwad cache.', /** - * @description Description text for not restored reason OutstandingNetworkRequestFetch. - */ + * @description Description text for not restored reason OutstandingNetworkRequestFetch. + */ outstandingNetworkRequestFetch: 'Pages with an in-flight fetch network request are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason OutstandingNetworkRequestXHR. - */ + * @description Description text for not restored reason OutstandingNetworkRequestXHR. + */ outstandingNetworkRequestXHR: 'Pages with an in-flight XHR network request are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason AppBanner. - */ + * @description Description text for not restored reason AppBanner. + */ appBanner: 'Pages that requested an AppBanner are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason Printing. - */ + * @description Description text for not restored reason Printing. + */ printing: 'Pages that show Printing UI are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebDatabase. - */ + * @description Description text for not restored reason WebDatabase. + */ webDatabase: 'Pages that use WebDatabase are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason PictureInPicture. - */ + * @description Description text for not restored reason PictureInPicture. + */ pictureInPicture: 'Pages that use Picture-in-Picture are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason Portal. - */ + * @description Description text for not restored reason Portal. + */ portal: 'Pages that use portals are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason SpeechRecognizer. - */ + * @description Description text for not restored reason SpeechRecognizer. + */ speechRecognizer: 'Pages that use SpeechRecognizer are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason IdleManager. - */ + * @description Description text for not restored reason IdleManager. + */ idleManager: 'Pages that use IdleManager are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason PaymentManager. - */ + * @description Description text for not restored reason PaymentManager. + */ paymentManager: 'Pages that use PaymentManager are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason SpeechSynthesis. - */ + * @description Description text for not restored reason SpeechSynthesis. + */ speechSynthesis: 'Pages that use SpeechSynthesis are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason KeyboardLock. - */ + * @description Description text for not restored reason KeyboardLock. + */ keyboardLock: 'Pages that use Keyboard lock are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason WebOTPService. - */ + * @description Description text for not restored reason WebOTPService. + */ webOTPService: 'Pages that use WebOTPService are not currently eligible for bfcache.', /** - * @description Description text for not restored reason OutstandingNetworkRequestDirectSocket. - */ + * @description Description text for not restored reason OutstandingNetworkRequestDirectSocket. + */ outstandingNetworkRequestDirectSocket: 'Pages with an in-flight network request are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason InjectedJavascript. - */ + * @description Description text for not restored reason InjectedJavascript. + */ injectedJavascript: - 'Pages that JavaScript is injected into by extensions are not currently eligible for back/forward cache.', + 'Pages that `JavaScript` is injected into by extensions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason InjectedStyleSheet. - */ + * @description Description text for not restored reason InjectedStyleSheet. + */ injectedStyleSheet: - 'Pages that StyleSheet is injected into by extensions are not currently eligible for back/forward cache.', + 'Pages that a `StyleSheet` is injected into by extensions are not currently eligible for back/forward cache.', /** - * @description Description text for not restored reason ContentSecurityHandler. - */ + * @description Description text for not restored reason ContentSecurityHandler. + */ contentSecurityHandler: 'Pages that use SecurityHandler are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentWebAuthenticationAPI: 'Pages that use WebAuthetication API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentFileChooser: 'Pages that use FileChooser API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentSerial: 'Pages that use Serial API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentFileSystemAccess: 'Pages that use File System Access API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentMediaDevicesDispatcherHost: 'Pages that use Media Device Dispatcher are not eligible for back/forward cache.', /** - * @description Description text for not restored reason NotMainFrame. - */ + * @description Description text for not restored reason NotMainFrame. + */ contentWebBluetooth: 'Pages that use WebBluetooth API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason ContentWebUSB. - */ + * @description Description text for not restored reason ContentWebUSB. + */ contentWebUSB: 'Pages that use WebUSB API are not eligible for back/forward cache.', /** - * @description Description text for not restored reason ContentMediaSession. - */ + * @description Description text for not restored reason ContentMediaSession. + */ contentMediaSession: 'Pages that use MediaSession API and set a playback state are not eligible for back/forward cache.', /** - * @description Description text for not restored reason ContentMediaSessionService. - */ + * @description Description text for not restored reason ContentMediaSessionService. + */ contentMediaSessionService: 'Pages that use MediaSession API and set action handlers are not eligible for back/forward cache.', /** - * @description Description text for not restored reason ContentMediaPlay. - */ + * @description Description text for not restored reason ContentMediaPlay. + */ contentMediaPlay: 'A media player was playing upon navigating away.', /** - * @description Description text for not restored reason ContentScreenReader. - */ + * @description Description text for not restored reason ContentScreenReader. + */ contentScreenReader: 'Back/forward cache is disabled due to screen reader.', /** - * @description Description text for not restored reason EmbedderPopupBlockerTabHelper. - */ + * @description Description text for not restored reason EmbedderPopupBlockerTabHelper. + */ embedderPopupBlockerTabHelper: 'Popup blocker was present upon navigating away.', /** - * @description Description text for not restored reason EmbedderSafeBrowsingTriggeredPopupBlocker. - */ + * @description Description text for not restored reason EmbedderSafeBrowsingTriggeredPopupBlocker. + */ embedderSafeBrowsingTriggeredPopupBlocker: 'Safe Browsing considered this page to be abusive and blocked popup.', /** - * @description Description text for not restored reason EmbedderSafeBrowsingThreatDetails. - */ + * @description Description text for not restored reason EmbedderSafeBrowsingThreatDetails. + */ embedderSafeBrowsingThreatDetails: 'Safe Browsing details were shown upon navigating away.', /** - * @description Description text for not restored reason EmbedderAppBannerManager. - */ + * @description Description text for not restored reason EmbedderAppBannerManager. + */ embedderAppBannerManager: 'App Banner was present upon navigating away.', /** - * @description Description text for not restored reason EmbedderDomDistillerViewerSource. - */ + * @description Description text for not restored reason EmbedderDomDistillerViewerSource. + */ embedderDomDistillerViewerSource: 'DOM Distiller Viewer was present upon navigating away.', /** - * @description Description text for not restored reason EmbedderDomDistillerSelfDeletingRequestDelegate. - */ + * @description Description text for not restored reason EmbedderDomDistillerSelfDeletingRequestDelegate. + */ embedderDomDistillerSelfDeletingRequestDelegate: 'DOM distillation was in progress upon navigating away.', /** - * @description Description text for not restored reason EmbedderOomInterventionTabHelper. - */ + * @description Description text for not restored reason EmbedderOomInterventionTabHelper. + */ embedderOomInterventionTabHelper: 'Out-Of-Memory Intervention bar was present upon navigating away.', /** - * @description Description text for not restored reason EmbedderOfflinePage. - */ + * @description Description text for not restored reason EmbedderOfflinePage. + */ embedderOfflinePage: 'The offline page was shown upon navigating away.', /** - * @description Description text for not restored reason EmbedderChromePasswordManagerClientBindCredentialManager. - */ + * @description Description text for not restored reason EmbedderChromePasswordManagerClientBindCredentialManager. + */ embedderChromePasswordManagerClientBindCredentialManager: 'Chrome Password Manager was present upon navigating away.', /** - * @description Description text for not restored reason EmbedderPermissionRequestManager. - */ + * @description Description text for not restored reason EmbedderPermissionRequestManager. + */ embedderPermissionRequestManager: 'There were permission requests upon navigating away.', /** - * @description Description text for not restored reason EmbedderModalDialog. - */ + * @description Description text for not restored reason EmbedderModalDialog. + */ embedderModalDialog: 'Modal dialog such as form resubmission or http password dialog was shown for the page upon navigating away.', /** - * @description Description text for not restored reason EmbedderExtensions. - */ + * @description Description text for not restored reason EmbedderExtensions. + */ embedderExtensions: 'Back/forward cache is disabled due to extensions.', /** - * @description Description text for not restored reason EmbedderExtensionMessaging. - */ + * @description Description text for not restored reason EmbedderExtensionMessaging. + */ embedderExtensionMessaging: 'Back/forward cache is disabled due to extensions using messaging API.', /** - * @description Description text for not restored reason EmbedderExtensionMessagingForOpenPort. - */ + * @description Description text for not restored reason EmbedderExtensionMessagingForOpenPort. + */ embedderExtensionMessagingForOpenPort: 'Extensions with long-lived connection should close the connection before entering back/forward cache.', /** - * @description Description text for not restored reason EmbedderExtensionSentMessageToCachedFrame. - */ + * @description Description text for not restored reason EmbedderExtensionSentMessageToCachedFrame. + */ embedderExtensionSentMessageToCachedFrame: 'Extensions with long-lived connection attempted to send messages to frames in back/forward cache.', /** - * @description Description text for not restored reason ErrorDocument. - */ + * @description Description text for not restored reason ErrorDocument. + */ errorDocument: 'Back/forward cache is disabled due to a document error.', /** - * @description Description text for not restored reason FencedFramesEmbedder. - */ + * @description Description text for not restored reason FencedFramesEmbedder. + */ fencedFramesEmbedder: 'Pages using FencedFrames cannot be stored in bfcache.', /** - * @description Description text for not restored reason KeepaliveRequest. - */ + * @description Description text for not restored reason KeepaliveRequest. + */ keepaliveRequest: 'Back/forward cache is disabled due to a keepalive request.', + /** + * @description Empty string to roll protocol. + */ + authorizationHeader: 'Back/forward cache is disabled due to a keepalive request.', + /** + * @description Description text for not restored reason IndexedDBEvent. + */ + indexedDBEvent: 'Back/forward cache is disabled due to an IndexedDB event.', + /** + * @description Description text for not restored reason CookieDisabled. + */ + cookieDisabled: + 'Back/forward cache is disabled because cookies are disabled on a page that uses `Cache-Control: no-store`.', }; const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings); @@ -653,6 +666,9 @@ const NotRestoredReasonDescription = { 'ErrorDocument': {name: str_(UIStrings.errorDocument)}, 'FencedFramesEmbedder': {name: str_(UIStrings.fencedFramesEmbedder)}, 'KeepaliveRequest': {name: str_(UIStrings.keepaliveRequest)}, + 'AuthorizationHeader': {name: str_(UIStrings.authorizationHeader)}, + 'IndexedDBEvent': {name: str_(UIStrings.indexedDBEvent)}, + 'CookieDisabled': {name: str_(UIStrings.cookieDisabled)}, }; export { diff --git a/core/lib/cdt/generated/SourceMap.js b/core/lib/cdt/generated/SourceMap.js index 29df45d97b07..ef966850ef99 100644 --- a/core/lib/cdt/generated/SourceMap.js +++ b/core/lib/cdt/generated/SourceMap.js @@ -8,7 +8,7 @@ const Platform = require('../Platform.js'); // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. Object.defineProperty(exports, "__esModule", { value: true }); -exports.TextSourceMap = exports.SourceMapEntry = exports.Offset = exports.Section = exports.SourceMapV3 = void 0; +exports.SourceMap = exports.SourceMapEntry = exports.parseSourceMap = void 0; /* * Copyright (C) 2012 Google Inc. All rights reserved. * @@ -41,42 +41,24 @@ exports.TextSourceMap = exports.SourceMapEntry = exports.Offset = exports.Sectio ; ; ; -; -; -; -; -; -; -class SourceMapV3 { - version; - file; - sources; - sections; - mappings; - sourceRoot; - names; - sourcesContent; - // eslint-disable-next-line @typescript-eslint/naming-convention - x_google_ignoreList; - constructor() { +/** + * Parses the {@link content} as JSON, ignoring BOM markers in the beginning, and + * also handling the CORB bypass prefix correctly. + * + * @param content the string representation of a sourcemap. + * @returns the {@link SourceMapV3} representation of the {@link content}. + */ +function parseSourceMap(content) { + if (content.startsWith(')]}')) { + content = content.substring(content.indexOf('\n')); } -} -exports.SourceMapV3 = SourceMapV3; -class Section { - map; - offset; - url; - constructor() { + if (content.charCodeAt(0) === 0xFEFF) { + // Strip BOM at the beginning before parsing the JSON. + content = content.slice(1); } + return JSON.parse(content); } -exports.Section = Section; -class Offset { - line; - column; - constructor() { - } -} -exports.Offset = Offset; +exports.parseSourceMap = parseSourceMap; class SourceMapEntry { lineNumber; columnNumber; @@ -106,8 +88,7 @@ for (let i = 0; i < base64Digits.length; ++i) { base64Map.set(base64Digits.charAt(i), i); } const sourceMapToSourceList = new WeakMap(); -class TextSourceMap { - #initiator; +class SourceMap { #json; #compiledURLInternal; #sourceMappingURL; @@ -118,17 +99,15 @@ class TextSourceMap { * Implements Source Map V3 model. See https://github.com/google/closure-compiler/wiki/Source-Maps * for format description. */ - constructor(compiledURL, sourceMappingURL, payload, initiator) { - this.#initiator = initiator; + constructor(compiledURL, sourceMappingURL, payload) { this.#json = payload; this.#compiledURLInternal = compiledURL; this.#sourceMappingURL = sourceMappingURL; this.#baseURL = (sourceMappingURL.startsWith('data:') ? compiledURL : sourceMappingURL); this.#mappingsInternal = null; this.#sourceInfos = new Map(); - if (this.#json.sections) { - const sectionWithURL = Boolean(this.#json.sections.find(section => Boolean(section.url))); - if (sectionWithURL) { + if ('sections' in this.#json) { + if (this.#json.sections.find(section => 'url' in section)) { console.warn(`SourceMap "${sourceMappingURL}" contains unsupported "URL" field in one of its sections.`); } } @@ -266,6 +245,8 @@ class TextSourceMap { if (this.#mappingsInternal === null) { this.#mappingsInternal = []; this.eachSection(this.parseMap.bind(this)); + // As per spec, mappings are not necessarily sorted. + this.mappings().sort(SourceMapEntry.compare); this.#computeReverseMappings(this.#mappingsInternal); this.#json = null; } @@ -303,42 +284,43 @@ class TextSourceMap { if (!this.#json) { return; } - if (!this.#json.sections) { - callback(this.#json, 0, 0); - return; + if ('sections' in this.#json) { + for (const section of this.#json.sections) { + if ('map' in section) { + callback(section.map, section.offset.line, section.offset.column); + } + } } - for (const section of this.#json.sections) { - callback(section.map, section.offset.line, section.offset.column); + else { + callback(this.#json, 0, 0); } } parseSources(sourceMap) { const sourcesList = []; - const sourceRoot = sourceMap.sourceRoot || Platform.DevToolsPath.EmptyUrlString; + const sourceRoot = sourceMap.sourceRoot ?? ''; const ignoreList = new Set(sourceMap.x_google_ignoreList); for (let i = 0; i < sourceMap.sources.length; ++i) { let href = sourceMap.sources[i]; // The source map v3 proposal says to prepend the sourceRoot to the source URL // and if the resulting URL is not absolute, then resolve the source URL against - // the source map URL. Appending the sourceRoot (if one exists) is not likely to + // the source map URL. Prepending the sourceRoot (if one exists) is not likely to // be meaningful or useful if the source URL is already absolute though. In this // case, use the source URL as is without prepending the sourceRoot. if (Common.ParsedURL.ParsedURL.isRelativeURL(href)) { if (sourceRoot && !sourceRoot.endsWith('/') && href && !href.startsWith('/')) { - href = Common.ParsedURL.ParsedURL.concatenate(sourceRoot, '/', href); + href = sourceRoot.concat('/', href); } else { - href = Common.ParsedURL.ParsedURL.concatenate(sourceRoot, href); + href = sourceRoot.concat(href); } } - let url = '' || href; + const url = '' || href; const source = sourceMap.sourcesContent && sourceMap.sourcesContent[i]; - if (url === this.#compiledURLInternal && source) { - } sourcesList.push(url); if (!this.#sourceInfos.has(url)) { const content = source ?? null; const ignoreListHint = ignoreList.has(i); - this.#sourceInfos.set(url, new TextSourceMap.SourceInfo(content, ignoreListHint)); + this.#sourceInfos.set(url, { content, ignoreListHint, reverseMappings: null }); } } sourceMapToSourceList.set(sourceMap, sourcesList); @@ -355,8 +337,8 @@ class TextSourceMap { // only reach this point when we are certain // we have the list available. const sources = sourceMapToSourceList.get(map); - const names = map.names || []; - const stringCharIterator = new TextSourceMap.StringCharIterator(map.mappings); + const names = map.names ?? []; + const stringCharIterator = new SourceMap.StringCharIterator(map.mappings); let sourceURL = sources && sources[sourceIndex]; while (true) { if (stringCharIterator.peek() === ',') { @@ -393,8 +375,6 @@ class TextSourceMap { nameIndex += this.decodeVLQ(stringCharIterator); this.mappings().push(new SourceMapEntry(lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber, names[nameIndex])); } - // As per spec, mappings are not necessarily sorted. - this.mappings().sort(SourceMapEntry.compare); } isSeparator(char) { return char === ',' || char === ';'; @@ -403,38 +383,17 @@ class TextSourceMap { // Read unsigned value. let result = 0; let shift = 0; - let digit = TextSourceMap._VLQ_CONTINUATION_MASK; - while (digit & TextSourceMap._VLQ_CONTINUATION_MASK) { + let digit = SourceMap._VLQ_CONTINUATION_MASK; + while (digit & SourceMap._VLQ_CONTINUATION_MASK) { digit = base64Map.get(stringCharIterator.next()) || 0; - result += (digit & TextSourceMap._VLQ_BASE_MASK) << shift; - shift += TextSourceMap._VLQ_BASE_SHIFT; + result += (digit & SourceMap._VLQ_BASE_MASK) << shift; + shift += SourceMap._VLQ_BASE_SHIFT; } // Fix the sign. const negative = result & 1; result >>= 1; return negative ? -result : result; } - reverseMapTextRange(url, textRange) { - function comparator(position, mappingIndex) { - if (position.lineNumber !== mappings[mappingIndex].sourceLineNumber) { - return position.lineNumber - mappings[mappingIndex].sourceLineNumber; - } - return position.columnNumber - mappings[mappingIndex].sourceColumnNumber; - } - const reverseMappings = this.reversedMappings(url); - const mappings = this.mappings(); - if (!reverseMappings.length) { - return null; - } - const startIndex = Platform.ArrayUtilities.lowerBound(reverseMappings, { lineNumber: textRange.startLine, columnNumber: textRange.startColumn }, comparator); - const endIndex = Platform.ArrayUtilities.upperBound(reverseMappings, { lineNumber: textRange.endLine, columnNumber: textRange.endColumn }, comparator); - if (endIndex >= reverseMappings.length) { - return null; - } - const startMapping = mappings[reverseMappings[startIndex]]; - const endMapping = mappings[reverseMappings[endIndex]]; - return new TextUtils.TextRange.TextRange(startMapping.lineNumber, startMapping.columnNumber, endMapping.lineNumber, endMapping.columnNumber); - } mapsOrigin() { const mappings = this.mappings(); if (mappings.length > 0) { @@ -482,17 +441,17 @@ class TextSourceMap { return ranges; } } -exports.TextSourceMap = TextSourceMap; -(function (TextSourceMap) { +exports.SourceMap = SourceMap; +(function (SourceMap) { // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration // eslint-disable-next-line @typescript-eslint/naming-convention - TextSourceMap._VLQ_BASE_SHIFT = 5; + SourceMap._VLQ_BASE_SHIFT = 5; // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration // eslint-disable-next-line @typescript-eslint/naming-convention - TextSourceMap._VLQ_BASE_MASK = (1 << 5) - 1; + SourceMap._VLQ_BASE_MASK = (1 << 5) - 1; // TODO(crbug.com/1172300) Ignored during the jsdoc to ts migration // eslint-disable-next-line @typescript-eslint/naming-convention - TextSourceMap._VLQ_CONTINUATION_MASK = 1 << 5; + SourceMap._VLQ_CONTINUATION_MASK = 1 << 5; class StringCharIterator { string; position; @@ -510,18 +469,9 @@ exports.TextSourceMap = TextSourceMap; return this.position < this.string.length; } } - TextSourceMap.StringCharIterator = StringCharIterator; - class SourceInfo { - content; - ignoreListHint; - reverseMappings = null; - constructor(content, ignoreListHint) { - this.content = content; - this.ignoreListHint = ignoreListHint; - } - } - TextSourceMap.SourceInfo = SourceInfo; -})(TextSourceMap = exports.TextSourceMap || (exports.TextSourceMap = {})); + SourceMap.StringCharIterator = StringCharIterator; +})(SourceMap = exports.SourceMap || (exports.SourceMap = {})); -module.exports = TextSourceMap; \ No newline at end of file +module.exports = SourceMap; +SourceMap.parseSourceMap = parseSourceMap; \ No newline at end of file diff --git a/core/lib/deprecation-description.js b/core/lib/deprecation-description.js new file mode 100644 index 000000000000..c7910a1473bd --- /dev/null +++ b/core/lib/deprecation-description.js @@ -0,0 +1,71 @@ +/** + * @license Copyright 2023 The Lighthouse Authors. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. + */ + +import * as i18n from '../lib/i18n/i18n.js'; +import {DEPRECATIONS_METADATA, UIStrings as DeprecationUIStrings} from './deprecations-strings.js'; + +const UIStrings = { + // Store strings used across messages in this block. + /** + * @description This links to the chrome feature status page when one exists. + */ + feature: 'Check the feature status page for more details.', + /** + * @description This links to the chromium dash schedule when a milestone is set. + * @example {100} milestone + */ + milestone: 'This change will go into effect with milestone {milestone}.', + /** + * @description Title of issue raised when a deprecated feature is used + */ + title: 'Deprecated Feature Used', +}; + +const str_ = i18n.createIcuMessageFn(import.meta.url, UIStrings); +const deprecationsStr_ = i18n.createIcuMessageFn(import.meta.url, DeprecationUIStrings); + +/** + * @param {LH.Crdp.Audits.DeprecationIssueDetails} issueDetails + */ +function getIssueDetailDescription(issueDetails) { + let message; + const type = /** @type {keyof DEPRECATIONS_METADATA} */ (issueDetails.type); + const maybeEnglishMessage = DeprecationUIStrings[type]; + if (maybeEnglishMessage) { + message = deprecationsStr_(maybeEnglishMessage); + } + + const links = []; + /** @type {{chromeStatusFeature?: number, milestone?: number}|undefined} */ + const deprecationMeta = DEPRECATIONS_METADATA[type]; + const feature = deprecationMeta?.chromeStatusFeature ?? 0; + if (feature !== 0) { + links.push({ + link: `https://chromestatus.com/feature/${feature}`, + linkTitle: str_(UIStrings.feature), + }); + } + const milestone = deprecationMeta?.milestone ?? 0; + if (milestone !== 0) { + links.push({ + link: 'https://chromiumdash.appspot.com/schedule', + linkTitle: str_(UIStrings.milestone, {milestone}), + }); + } + return ({ + substitutions: new Map([ + ['PLACEHOLDER_title', str_(UIStrings.title)], + ['PLACEHOLDER_message', message], + ]), + links, + message, + }); +} + +export { + getIssueDetailDescription, + UIStrings, +}; diff --git a/core/lib/deprecations-strings.js b/core/lib/deprecations-strings.js index e147d3cbe08c..20420cb9a580 100644 --- a/core/lib/deprecations-strings.js +++ b/core/lib/deprecations-strings.js @@ -1,654 +1,385 @@ // auto-generated by build/build-cdt-strings.js /* eslint-disable */ +// Copyright 2023 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. -import * as i18n from '../lib/i18n/i18n.js'; +// This file is auto-generated, do not edit manually. +// Re-generate with: npm run generate-protocol-resources -const UIStrings = { - // Store strings used across messages in this block. +export const UIStrings = { /** - * @description This links to the chrome feature status page when one exists. + * @description We show this warning when 1) an 'authorization' header is attached to the request by scripts, 2) there is no 'authorization' in the 'access-control-allow-headers' header in the response, and 3) there is a wildcard symbol ('*') in the 'access-control-allow-header' header in the response. This is allowed now, but we're planning to reject such responses and require responses to have an 'access-control-allow-headers' containing 'authorization'. */ - feature: 'Check the feature status page for more details.', + AuthorizationCoveredByWildcard: "Authorization will not be covered by the wildcard symbol (*) in CORS `Access-Control-Allow-Headers` handling.", /** - * @description This links to the chromium dash schedule when a milestone is set. - * @example {100} milestone + * @description This warning occurs when a page attempts to request a resource whose URL contained both a newline character (`\n` or `\r`), and a less-than character (`<`). These resources are blocked. */ - milestone: 'This change will go into effect with milestone {milestone}.', + CanRequestURLHTTPContainingNewline: "Resource requests whose URLs contained both removed whitespace `(n|r|t)` characters and less-than characters (`<`) are blocked. Please remove newlines and encode less-than characters from places like element attribute values in order to load these resources.", /** - * @description Title of issue raised when a deprecated feature is used + * @description This warning occurs when the website attempts to invoke the deprecated `chrome.loadTimes().connectionInfo` API. */ - title: 'Deprecated Feature Used', - - /** - * @description We show this warning when 1) an "authorization" header is - * attached to the request by scripts, 2) there is no "authorization" in - * the "access-control-allow-headers" header in the response, and 3) there - * is a wildcard symbol ("*") in the "access-control-allow-header" header - * in the response. This is allowed now, but we're planning to reject such - * responses and require responses to have an "access-control-allow-headers" - * containing "authorization". - */ - authorizationCoveredByWildcard: - 'Authorization will not be covered by the wildcard symbol (*) in CORS `Access-Control-Allow-Headers` handling.', + ChromeLoadTimesConnectionInfo: "`chrome.loadTimes()` is deprecated, instead use standardized API: Navigation Timing 2.", /** - * @description This warning occurs when a page attempts to request a resource - * whose URL contained both a newline character (`\n` or `\r`), and a - * less-than character (`<`). These resources are blocked. + * @description This warning occurs when the website attempts to invoke the deprecated `chrome.loadTimes().firstPaintAfterLoadTime` API. */ - canRequestURLHTTPContainingNewline: - 'Resource requests whose URLs contained both removed whitespace `(n|r|t)` characters and less-than characters (`<`) are blocked. Please remove newlines and encode less-than characters from places like element attribute values in order to load these resources.', + ChromeLoadTimesFirstPaintAfterLoadTime: "`chrome.loadTimes()` is deprecated, instead use standardized API: Paint Timing.", /** - * @description This warning occurs when the website attempts to invoke the - * deprecated `chrome.loadTimes().connectionInfo` API. + * @description This warning occurs when the website attempts to invoke the deprecated `chrome.loadTimes().wasAlternateProtocolAvailable` API. */ - chromeLoadTimesConnectionInfo: - '`chrome.loadTimes()` is deprecated, instead use standardized API: Navigation Timing 2.', + ChromeLoadTimesWasAlternateProtocolAvailable: "`chrome.loadTimes()` is deprecated, instead use standardized API: `nextHopProtocol` in Navigation Timing 2.", /** - * @description This warning occurs when the website attempts to invoke the - * deprecated `chrome.loadTimes().firstPaintAfterLoadTime` API. + * @description This warning occurs when the browser attempts to store a cookie containing a banned character. Rather than the cookie string being truncated at the banned character, the entire cookie will be rejected now. */ - chromeLoadTimesFirstPaintAfterLoadTime: - '`chrome.loadTimes()` is deprecated, instead use standardized API: Paint Timing.', + CookieWithTruncatingChar: "Cookies containing a `(0|r|n)` character will be rejected instead of truncated.", /** - * @description This warning occurs when the website attempts to invoke the - * deprecated `chrome.loadTimes().wasAlternateProtocolAvailable` API. + * @description This warning occurs when a frame accesses another frame's data after having set `document.domain` without having set the `Origin-Agent-Cluster` http header. This is a companion warning to `documentDomainSettingWithoutOriginAgentClusterHeader`, where that warning occurs when `document.domain` is set, and this warning occurs when an access has been made, based on that previous `document.domain` setting. */ - chromeLoadTimesWasAlternateProtocolAvailable: - '`chrome.loadTimes()` is deprecated, instead use standardized API: `nextHopProtocol` in Navigation Timing 2.', + CrossOriginAccessBasedOnDocumentDomain: "Relaxing the same-origin policy by setting `document.domain` is deprecated, and will be disabled by default. This deprecation warning is for a cross-origin access that was enabled by setting `document.domain`.", /** - * @description This warning occurs when the browser attempts to store a - * cookie containing a banned character. Rather than the cookie string - * being truncated at the banned character, the entire cookie will be - * rejected now. + * @description Issue text shown when the web page uses a deprecated web API. The window.alert is the deprecated web API function. */ - cookieWithTruncatingChar: 'Cookies containing a `(0|r|n)` character will be rejected instead of truncated.', + CrossOriginWindowAlert: "Triggering window.alert from cross origin iframes has been deprecated and will be removed in the future.", /** - * @description This warning occurs when a frame accesses another frame's - * data after having set `document.domain` without having set the - * `Origin-Agent-Cluster` http header. This is a companion warning to - * `documentDomainSettingWithoutOriginAgentClusterHeader`, where that - * warning occurs when `document.domain` is set, and this warning - * occurs when an access has been made, based on that previous - * `document.domain` setting. + * @description Issue text shown when the web page uses a deprecated web API. The window.confirm is the deprecated web API function. */ - crossOriginAccessBasedOnDocumentDomain: - 'Relaxing the same-origin policy by setting `document.domain` is deprecated, and will be disabled by default. This deprecation warning is for a cross-origin access that was enabled by setting `document.domain`.', + CrossOriginWindowConfirm: "Triggering window.confirm from cross origin iframes has been deprecated and will be removed in the future.", /** - * @description Issue text shown when the web page uses a deprecated web API. The placeholder is - * the deprecated web API function. - * @example {window.alert} PH1 + * @description Warning displayed to developers when they hide the Cast button on a video element using the deprecated CSS selector instead of using the disableRemotePlayback attribute on the element. */ - crossOriginWindowApi: 'Triggering {PH1} from cross origin iframes has been deprecated and will be removed in the future.', + CSSSelectorInternalMediaControlsOverlayCastButton: "The `disableRemotePlayback` attribute should be used in order to disable the default Cast integration instead of using `-internal-media-controls-overlay-cast-button` selector.", /** - * @description Warning displayed to developers when they hide the Cast button - * on a video element using the deprecated CSS selector instead of using the - * disableRemotePlayback attribute on the element. + * @description Warning displayed to developers when a data: URL is assigned to SVG to let them know that the support is deprecated. */ - cssSelectorInternalMediaControlsOverlayCastButton: - 'The `disableRemotePlayback` attribute should be used in order to disable the default Cast integration instead of using `-internal-media-controls-overlay-cast-button` selector.', + DataUrlInSvgUse: "Support for data: URLs in SVG element is deprecated and it will be removed in the future.", /** - * @description This message is shown when the example deprecated feature is used + * @description This warning occurs when a script modifies `document.domain` without having set on `Origin-Agent-Cluster` http header. In other words, when a script relies on the default behaviour of `Origin-Agent-Cluster` when setting document.domain. */ - deprecationExample: 'This is an example of a translated deprecation issue message.', + DocumentDomainSettingWithoutOriginAgentClusterHeader: "Relaxing the same-origin policy by setting `document.domain` is deprecated, and will be disabled by default. To continue using this feature, please opt-out of origin-keyed agent clusters by sending an `Origin-Agent-Cluster: ?0` header along with the HTTP response for the document and frames. See https://developer.chrome.com/blog/immutable-document-domain/ for more details.", /** - * @description This warning occurs when a script modifies `document.domain` - * without having set on `Origin-Agent-Cluster` http header. In other - * words, when a script relies on the default behaviour of - * `Origin-Agent-Cluster` when setting document.domain. + * @description Warning displayed to developers when non-standard Mutation Events are used. These are deprecated and will be removed. */ - documentDomainSettingWithoutOriginAgentClusterHeader: - 'Relaxing the same-origin policy by setting `document.domain` is deprecated, and will be disabled by default. To continue using this feature, please opt-out of origin-keyed agent clusters by sending an `Origin-Agent-Cluster: ?0` header along with the HTTP response for the document and frames. See https://developer.chrome.com/blog/immutable-document-domain/ for more details.', - /** - * @description Warning displayed to developers when the non-standard `Event.path` API is used to notify them that this API is deprecated. - */ - eventPath: '`Event.path` is deprecated and will be removed. Please use `Event.composedPath()` instead.', + DOMMutationEvents: "DOM Mutation Events, including `DOMSubtreeModified`, `DOMNodeInserted`, `DOMNodeRemoved`, `DOMNodeRemovedFromDocument`, `DOMNodeInsertedIntoDocument`, and `DOMCharacterDataModified` are deprecated (https://w3c.github.io/uievents/#legacy-event-types) and will be removed. Please use `MutationObserver` instead.", /** * @description This message is shown when the deprecated Expect-CT header is present. */ - expectCTHeader: 'The `Expect-CT` header is deprecated and will be removed. Chrome requires Certificate Transparency for all publicly trusted certificates issued after April 30, 2018.', + ExpectCTHeader: "The `Expect-CT` header is deprecated and will be removed. Chrome requires Certificate Transparency for all publicly trusted certificates issued after April 30, 2018.", /** * @description Warning displayed to developers when the Geolocation API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is no longer supported. */ - geolocationInsecureOrigin: - '`getCurrentPosition()` and `watchPosition()` no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.', + GeolocationInsecureOrigin: "`getCurrentPosition()` and `watchPosition()` no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.", /** * @description Warning displayed to developers when the Geolocation API is used from an insecure origin (one that isn't localhost or doesn't use HTTPS) to notify them that this use is deprecated. */ - geolocationInsecureOriginDeprecatedNotRemoved: - '`getCurrentPosition()` and `watchPosition()` are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.', + GeolocationInsecureOriginDeprecatedNotRemoved: "`getCurrentPosition()` and `watchPosition()` are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.", /** - * @description This warning occurs when the `getUserMedia()` API is invoked - * on an insecure (e.g., HTTP) site. This is only permitted on secure sites - * (e.g., HTTPS). + * @description This warning occurs when the `getUserMedia()` API is invoked on an insecure (e.g., HTTP) site. This is only permitted on secure sites (e.g., HTTPS). */ - getUserMediaInsecureOrigin: - '`getUserMedia()` no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.', + GetUserMediaInsecureOrigin: "`getUserMedia()` no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details.", /** * @description A deprecation warning shown to developers in the DevTools Issues tab when code tries to use the deprecated hostCandidate field, guiding developers to use the the equivalent information in the .address and .port fields instead. */ - hostCandidateAttributeGetter: - '`RTCPeerConnectionIceErrorEvent.hostCandidate` is deprecated. Please use `RTCPeerConnectionIceErrorEvent.address` or `RTCPeerConnectionIceErrorEvent.port` instead.', - /** - * @description A deprecation warning shown in the DevTools Issues tab, - * when a service worker reads one of the fields from an event named - * "canmakepayment". - */ - identityInCanMakePaymentEvent: 'The merchant origin and arbitrary data from the `canmakepayment` service worker event are deprecated and will be removed: `topOrigin`, `paymentRequestOrigin`, `methodData`, `modifiers`.', - /** - * @description This warning occurs when an insecure context (e.g., HTTP) - * requests a private resource (not on open internet). This is done to - * mitigate the potential for CSRF and other attacks. - */ - insecurePrivateNetworkSubresourceRequest: - 'The website requested a subresource from a network that it could only access because of its users\' privileged network position. These requests expose non-public devices and servers to the internet, increasing the risk of a cross-site request forgery (CSRF) attack, and/or information leakage. To mitigate these risks, Chrome deprecates requests to non-public subresources when initiated from non-secure contexts, and will start blocking them.', - /** - * @description This warning occurs when a stylesheet loaded from a local - * file directive does not end in the file type `.css`. - */ - localCSSFileExtensionRejected: - 'CSS cannot be loaded from `file:` URLs unless they end in a `.css` file extension.', - /** - * @description This is a deprecation warning to developers that occurs when - * the script attempts to use the Media Source Extensions API in a way that - * is no longer supported by the specification for the API. The usage - * that is problematic is when the script calls the `SourceBuffer.abort()` - * method at a time when there is still processing happening in response to a - * previous `SourceBuffer.remove()` call for the same SourceBuffer object. - * More precisely, we show this warning to developers when script calls the - * SourceBuffer abort() method while the asynchronous processing of a remove() - * call on that SourceBuffer is not yet complete. Early versions of the Media - * Source Extensions specification allowed such aborts, but standardization of - * the specification resulted in disallowing the aborts. The script should - * instead wait for the asynchronous remove() operation to complete, which is - * observable by listening for the associated 'updateend' event from the - * SourceBuffer. A note is also included in the warning, describing when - * abort() is meaningful and allowed by the specification for purposes other - * than interrupting a remove() operation's asynchronous steps. Those - * supported purposes include using abort() to interrupt processing that may - * still be happening in response to a previous appendBuffer() call on that - * SourceBuffer, or using abort() to clear the internal of any unprocessed - * data remaining from previous appendBuffer() calls. - * See https://www.w3.org/TR/media-source-2/#dom-sourcebuffer-abort for the - * currently specified behavior, which would throw an exception once the - * deprecated removal abort is no longer supported. - * See https://github.com/w3c/media-source/issues/19 for the discussion that - * led to the specification change. - */ - mediaSourceAbortRemove: - 'Using `SourceBuffer.abort()` to abort `remove()`\'s asynchronous range removal is deprecated due to specification change. Support will be removed in the future. You should listen to the `updateend` event instead. `abort()` is intended to only abort an asynchronous media append or reset parser state.', - /** - * @description This is a deprecation warning to developers that occurs when - * the script attempts to use the Media Source Extensions API in a way that is - * no longer supported by the specification for the API. The usage that is - * problematic is when the script sets the duration attribute of a MediaSource - * object too low. The duration attribute of a MediaSource must be longer than - * the actual duration of any media (audio or video) already in the - * MediaSource. When set too low, the MediaSource must remove audio and video - * content that is beyond the time indicated by the new duration. Content - * removal that is caused by setting the duration attribute too low is no - * longer allowed by the specification. The message describes the minimum - * allowable duration value as the "highest presentation timestamp of any - * buffered coded frames" as a more precise way of describing the duration of - * content already in the MediaSource: "coded frames" are the specification's - * way of describing compressed audio frames or compressed video frames, and - * they each have a "presentation timestamp" that describes precisely when - * that frame's playback occurs in the overall media presentation. Early - * versions of the Media Source Extensions specification allowed this to - * happen, but standardization of the specification resulted in disallowing - * this behavior. The underlying issue leading to this specification change - * was that setting the duration attribute should be synchronous, but setting - * it lower than the timestamp of something currently buffered would cause - * confusing removal of media between that new duration and the previous, - * larger, duration. The script should instead explicitly remove that range of - * media first, before lowering the duration. - * See https://www.w3.org/TR/media-source-2/#dom-mediasource-duration and - * https://www.w3.org/TR/media-source-2/#dom-mediasource-duration for the - * currently specified behavior, which would throw an exception once support - * is removed for deprecated implicit asynchronous range removal when duration - * is truncated. - * See both https://github.com/w3c/media-source/issues/20 and - * https://github.com/w3c/media-source/issues/26 for the discussion that led - * to the specification change. - */ - mediaSourceDurationTruncatingBuffered: - 'Setting `MediaSource.duration` below the highest presentation timestamp of any buffered coded frames is deprecated due to specification change. Support for implicit removal of truncated buffered media will be removed in the future. You should instead perform explicit `remove(newDuration, oldDuration)` on all `sourceBuffers`, where `newDuration < oldDuration`.', - /** - * @description This warning occurs when the browser requests Web MIDI access - * as sysex (system exclusive messages) can be allowed via prompt even if - * the browser did not specifically request it. - */ - noSysexWebMIDIWithoutPermission: - 'Web MIDI will ask a permission to use even if the sysex is not specified in the `MIDIOptions`.', + HostCandidateAttributeGetter: "`RTCPeerConnectionIceErrorEvent.hostCandidate` is deprecated. Please use `RTCPeerConnectionIceErrorEvent.address` or `RTCPeerConnectionIceErrorEvent.port` instead.", + /** + * @description A deprecation warning shown in the DevTools Issues tab, when a service worker reads one of the fields from an event named 'canmakepayment'. + */ + IdentityInCanMakePaymentEvent: "The merchant origin and arbitrary data from the `canmakepayment` service worker event are deprecated and will be removed: `topOrigin`, `paymentRequestOrigin`, `methodData`, `modifiers`.", + /** + * @description This warning occurs when an insecure context (e.g., HTTP) requests a private resource (not on open internet). This is done to mitigate the potential for CSRF and other attacks. + */ + InsecurePrivateNetworkSubresourceRequest: "The website requested a subresource from a network that it could only access because of its users' privileged network position. These requests expose non-public devices and servers to the internet, increasing the risk of a cross-site request forgery (CSRF) attack, and/or information leakage. To mitigate these risks, Chrome deprecates requests to non-public subresources when initiated from non-secure contexts, and will start blocking them.", + /** + * @description This is a deprecated warning to developers that a field in a structure has been renamed. + */ + InterestGroupDailyUpdateUrl: "The `dailyUpdateUrl` field of `InterestGroups` passed to `joinAdInterestGroup()` has been renamed to `updateUrl`, to more accurately reflect its behavior.", + /** + * @description This warning occurs when a stylesheet loaded from a local file directive does not end in the file type `.css`. + */ + LocalCSSFileExtensionRejected: "CSS cannot be loaded from `file:` URLs unless they end in a `.css` file extension.", + /** + * @description This is a deprecation warning to developers that occurs when the script attempts to use the Media Source Extensions API in a way that is no longer supported by the specification for the API. The usage that is problematic is when the script calls the `SourceBuffer.abort()` method at a time when there is still processing happening in response to a previous `SourceBuffer.remove()` call for the same SourceBuffer object. More precisely, we show this warning to developers when script calls the SourceBuffer abort() method while the asynchronous processing of a remove() call on that SourceBuffer is not yet complete. Early versions of the Media Source Extensions specification allowed such aborts, but standardization of the specification resulted in disallowing the aborts. The script should instead wait for the asynchronous remove() operation to complete, which is observable by listening for the associated 'updateend' event from the SourceBuffer. A note is also included in the warning, describing when abort() is meaningful and allowed by the specification for purposes other than interrupting a remove() operation's asynchronous steps. Those supported purposes include using abort() to interrupt processing that may still be happening in response to a previous appendBuffer() call on that SourceBuffer, or using abort() to clear the internal of any unprocessed data remaining from previous appendBuffer() calls. See https://www.w3.org/TR/media-source-2/#dom-sourcebuffer-abort for the currently specified behavior, which would throw an exception once the deprecated removal abort is no longer supported. See https://github.com/w3c/media-source/issues/19 for the discussion that led to the specification change. + */ + MediaSourceAbortRemove: "Using `SourceBuffer.abort()` to abort `remove()`'s asynchronous range removal is deprecated due to specification change. Support will be removed in the future. You should listen to the `updateend` event instead. `abort()` is intended to only abort an asynchronous media append or reset parser state.", + /** + * @description This is a deprecation warning to developers that occurs when the script attempts to use the Media Source Extensions API in a way that is no longer supported by the specification for the API. The usage that is problematic is when the script sets the duration attribute of a MediaSource object too low. The duration attribute of a MediaSource must be longer than the actual duration of any media (audio or video) already in the MediaSource. When set too low, the MediaSource must remove audio and video content that is beyond the time indicated by the new duration. Content removal that is caused by setting the duration attribute too low is no longer allowed by the specification. The message describes the minimum allowable duration value as the 'highest presentation timestamp of any buffered coded frames' as a more precise way of describing the duration of content already in the MediaSource: 'coded frames' are the specification's way of describing compressed audio frames or compressed video frames, and they each have a 'presentation timestamp' that describes precisely when that frame's playback occurs in the overall media presentation. Early versions of the Media Source Extensions specification allowed this to happen, but standardization of the specification resulted in disallowing this behavior. The underlying issue leading to this specification change was that setting the duration attribute should be synchronous, but setting it lower than the timestamp of something currently buffered would cause confusing removal of media between that new duration and the previous, larger, duration. The script should instead explicitly remove that range of media first, before lowering the duration. See https://www.w3.org/TR/media-source-2/#dom-mediasource-duration and https://www.w3.org/TR/media-source-2/#dom-mediasource-duration for the currently specified behavior, which would throw an exception once support is removed for deprecated implicit asynchronous range removal when duration is truncated. See both https://github.com/w3c/media-source/issues/20 and https://github.com/w3c/media-source/issues/26 for the discussion that led to the specification change. + */ + MediaSourceDurationTruncatingBuffered: "Setting `MediaSource.duration` below the highest presentation timestamp of any buffered coded frames is deprecated due to specification change. Support for implicit removal of truncated buffered media will be removed in the future. You should instead perform explicit `remove(newDuration, oldDuration)` on all `sourceBuffers`, where `newDuration < oldDuration`.", + /** + * @description This warning is displayed when a site contains a `