diff --git a/api/GPUAdapter.json b/api/GPUAdapter.json index 076f29b45e66f4..f56e55213a4d36 100644 --- a/api/GPUAdapter.json +++ b/api/GPUAdapter.json @@ -128,9 +128,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "127" - }, + "chrome_android": "mirror", "edge": "mirror", "firefox": { "version_added": "141", @@ -452,9 +450,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "133" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/api/GPUCommandEncoder.json b/api/GPUCommandEncoder.json index cf0e98c5a8e5c8..2c1d336c4ffecc 100644 --- a/api/GPUCommandEncoder.json +++ b/api/GPUCommandEncoder.json @@ -127,9 +127,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "121" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -226,9 +224,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "140" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -268,9 +264,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "125" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -309,9 +303,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "123" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -351,9 +343,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "121" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -508,9 +498,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "137" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/api/GPUDevice.json b/api/GPUDevice.json index 5cc8a90bbfd43e..0dced8188ca013 100644 --- a/api/GPUDevice.json +++ b/api/GPUDevice.json @@ -167,9 +167,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "138" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -208,9 +206,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "140" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -249,9 +245,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "137" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -801,9 +795,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "135" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -901,9 +893,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "121" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -1059,9 +1049,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "130" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -1362,9 +1350,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "130" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -1984,9 +1970,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "121" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/api/GPUQuerySet.json b/api/GPUQuerySet.json index 2acf454b5187c9..3ab300baef4819 100644 --- a/api/GPUQuerySet.json +++ b/api/GPUQuerySet.json @@ -301,9 +301,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "121" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/api/GPUSupportedFeatures.json b/api/GPUSupportedFeatures.json index 5a7dc06b04605e..b5b2c3ff4cc05a 100644 --- a/api/GPUSupportedFeatures.json +++ b/api/GPUSupportedFeatures.json @@ -862,9 +862,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "142" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, @@ -904,9 +902,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "142" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/api/GPUTexture.json b/api/GPUTexture.json index 9205a57dee9670..646d4b7783f9c7 100644 --- a/api/GPUTexture.json +++ b/api/GPUTexture.json @@ -169,9 +169,7 @@ "partial_implementation": true, "notes": "Supported on ChromeOS, macOS, and Windows only." }, - "chrome_android": { - "version_added": "132" - }, + "chrome_android": "mirror", "deno": { "version_added": false }, diff --git a/scripts/build/mirror.test.ts b/scripts/build/mirror.test.ts index 6a6a5a33269aba..eb09fb953fbe2f 100644 --- a/scripts/build/mirror.test.ts +++ b/scripts/build/mirror.test.ts @@ -7,9 +7,39 @@ import { BrowserName } from '../../types/types.js'; import bcd from '../../index.js'; import { InternalSupportBlock } from '../../types/index.js'; -import mirrorSupport from './mirror.js'; +import mirrorSupport, { isOSLimitation } from './mirror.js'; describe('mirror', () => { + describe('isOSLimitation', () => { + it('returns true for OS limitation notes', () => { + assert.equal( + isOSLimitation('Supported on ChromeOS, macOS, and Windows only.'), + true, + ); + assert.equal(isOSLimitation('Supported on macOS only.'), true); + assert.equal(isOSLimitation('Not supported on Windows.'), true); + }); + + it('returns false for non-OS-limitation notes', () => { + assert.equal( + isOSLimitation('This feature requires a flag to be enabled.'), + false, + ); + assert.equal( + isOSLimitation('Before version 70, this method always returned true.'), + false, + ); + assert.equal( + isOSLimitation('Firefox 73 added support for this thing.'), + false, + ); + }); + + it('returns false for empty string', () => { + assert.equal(isOSLimitation(''), false); + }); + }); + describe('default export', () => { describe('version numbers match expected values', () => { const mappings: { @@ -189,6 +219,38 @@ describe('mirror', () => { notes: 'This feature is only supported in ChromeOS, macOS and Linux.', }); }); + + it('OS-specific partial_implementation and notes are not mirrored', () => { + const support = { + chrome: { + version_added: '134', + partial_implementation: true, + notes: 'Supported on ChromeOS, macOS, and Windows only.', + }, + }; + + const mirrored = mirrorSupport('chrome_android', support); + assert.deepEqual(mirrored, { + version_added: '134', + }); + }); + + it('Non-OS-specific partial_implementation and notes are still mirrored', () => { + const support = { + chrome: { + version_added: '70', + partial_implementation: true, + notes: 'This feature is incomplete and may not work as expected.', + }, + }; + + const mirrored = mirrorSupport('chrome_android', support); + assert.deepEqual(mirrored, { + version_added: '70', + partial_implementation: true, + notes: 'This feature is incomplete and may not work as expected.', + }); + }); }); describe('Validations', () => { diff --git a/scripts/build/mirror.ts b/scripts/build/mirror.ts index dd8408c36e038e..3224e53ffc18b3 100644 --- a/scripts/build/mirror.ts +++ b/scripts/build/mirror.ts @@ -15,8 +15,38 @@ const { browsers } = bcd; type Notes = string | [string, string, ...string[]] | null; +const OS_NOTES = [ + 'Available on macOS and Windows only.', + 'Available only on macOS.', + 'ChromeOS only', + 'ChromeOS and Windows', + 'Fully supported on Windows and Linux, no support on ChromeOS.', + 'Linux support is not enabled by default.', + 'Not supported on macOS.', + 'Not supported on Windows.', + 'Only on macOS and Windows.', + 'Only on Windows.', + 'Only supported on ChromeOS', + 'Only supported on macOS.', + 'Only supported on Windows.', + 'Only works on macOS.', + 'Supported on ChromeOS, macOS, and Windows only.', + 'Supported on ChromeOS and macOS only.', + 'Supported on macOS only.', + 'Supported on macOS Catalina 10.15.1+, Windows, and ChromeOS. Not yet supported on Linux.', + 'Supported on Windows only, in all contexts except for service workers.', + 'Supported only on macOS 10.12 (Sierra) and later.', + 'This cursor is only supported on macOS and Linux.', +].map((s) => s.toLowerCase()); + /** + * Check if a note indicates OS-specific limitations. + * @param notes A single notes string from a support statement + * @returns True if the notes indicate OS-specific limitations */ +export const isOSLimitation = (notes: string): boolean => { + return OS_NOTES.includes(notes.toLowerCase()); +}; const matchingSafariVersions = new Map([ ['1', '1'], @@ -215,6 +245,30 @@ export const bumpSupport = ( const newData: SimpleSupportStatement = copyStatement(sourceData); + if ( + browsers[sourceBrowser].type === 'desktop' && + browsers[destination].type === 'mobile' && + sourceData.partial_implementation + ) { + const notes = Array.isArray(sourceData.notes) + ? sourceData.notes + : sourceData.notes + ? [sourceData.notes] + : []; + const [firstNote, secondNote, ...otherNotes] = notes.filter( + (notes) => !isOSLimitation(notes), + ); + if (!firstNote) { + // Ignore OS limitation. + delete newData.partial_implementation; + delete newData.notes; + } else if (!secondNote) { + newData.notes = firstNote; + } else { + newData.notes = [firstNote, secondNote, ...otherNotes]; + } + } + if (!browsers[destination].accepts_flags && newData.flags) { // Remove flag data if the target browser doesn't accept flags return { version_added: false }; @@ -254,7 +308,8 @@ export const bumpSupport = ( return { version_added: false }; } - if (sourceData.notes) { + // Only process notes if they weren't already removed (e.g., for OS-specific limitations) + if (sourceData.notes && newData.notes !== undefined) { const sourceBrowserName = sourceBrowser === 'chrome' ? '(Google )?Chrome'