diff --git a/lint/linter/test-versions.test.ts b/lint/linter/test-versions.test.ts index 6130fa69853f58..53b8909a999b5b 100644 --- a/lint/linter/test-versions.test.ts +++ b/lint/linter/test-versions.test.ts @@ -51,16 +51,6 @@ describe('test-versions', () => { }; }); - it('should log error when a required browser is not defined', () => { - support.chrome = undefined; - test.check(logger, { - data: { support }, - path: { category: 'api' }, - }); - assert.equal(logger.messages.length, 1); - assert.ok(logger.messages[0].message.includes('must be defined')); - }); - it('should log error when a browser is set to mirror but does not have an upstream browser', () => { support.chrome = 'mirror'; test.check(logger, { diff --git a/lint/linter/test-versions.ts b/lint/linter/test-versions.ts index 275ffe7b092601..c14da5781d04eb 100644 --- a/lint/linter/test-versions.ts +++ b/lint/linter/test-versions.ts @@ -26,33 +26,6 @@ const browserTips: Record = { 'Blink editions of Opera Android and Opera desktop were the Chrome version number minus 13, up until Opera Android 43 when they began skipping Chrome versions. Please double-check browsers/opera_android.json to make sure you are using the correct versions.', }; -const realValuesTargetBrowsers = [ - 'chrome', - 'chrome_android', - 'edge', - 'firefox', - 'firefox_android', - 'opera', - 'opera_android', - 'safari', - 'safari_ios', - 'samsunginternet_android', - 'webview_android', -]; - -const realValuesRequired: Record = { - api: realValuesTargetBrowsers, - css: realValuesTargetBrowsers, - html: realValuesTargetBrowsers, - http: realValuesTargetBrowsers, - svg: realValuesTargetBrowsers, - javascript: [...realValuesTargetBrowsers, 'nodejs', 'deno'], - mathml: realValuesTargetBrowsers, - webassembly: realValuesTargetBrowsers, - webdriver: realValuesTargetBrowsers, - webextensions: [], -}; - /** * Test to see if the browser allows for the specified version * @param browser The browser to check @@ -70,11 +43,6 @@ const isValidVersion = ( return !!browsers[browser].preview_name; } return Object.hasOwn(browsers[browser].releases, version.replace('≤', '')); - } else if ( - realValuesRequired[category].includes(browser) && - version !== false - ) { - return false; } return true; }; @@ -140,10 +108,6 @@ const checkVersions = ( supportData[browser]; if (!supportStatement) { - if (realValuesRequired[category].includes(browser)) { - logger.error(chalk`{red {bold ${browser}} must be defined}`); - } - continue; } @@ -170,7 +134,7 @@ const checkVersions = ( logger.error( chalk`{bold ${property}: "${version}"} is {bold NOT} a valid version number for {bold ${browser}}\n Valid {bold ${browser}} versions are: ${Object.keys( browsers[browser].releases, - ).join(', ')}`, + ).join(', ')}, false`, { tip: browserTips[browser] }, ); } diff --git a/schemas/compat-data-schema.md b/schemas/compat-data-schema.md index d87fdc7cdffe58..b9ab0c768f31fa 100644 --- a/schemas/compat-data-schema.md +++ b/schemas/compat-data-schema.md @@ -100,7 +100,7 @@ Here is an example of a `__compat` statement, with all of the properties and the // Supported since Chrome 57 on "version_added": "57", }, - "chrome_android": "mirror", // Mirrors from Chrome Desktop, so "57" + "chrome_android": "mirror", // Mirrors from the upstream browser -- in this case, it is Chrome Desktop, so the data becomes "57" "edge": { // Supported since Edge 12, with a note about a difference in behavior "version_added": "12", @@ -112,8 +112,8 @@ Here is an example of a `__compat` statement, with all of the properties and the "version_removed": "80", }, "firefox_android": { - // Supported in Firefox Android, we just don't know what version it was added in - "version_added": true, + // Support is known to be in at least Firefox Android 50, but it could have been added earlier + "version_added": "≤50", }, "ie": { // Supported since IE 10, but has a caveat that impacts compatibility @@ -126,10 +126,7 @@ Here is an example of a `__compat` statement, with all of the properties and the // Not supported at all in Opera "version_added": false, }, - "opera_android": { - // We don't know if Opera Android supports this or not - "version_added": null, - }, + "opera_android": "mirror", "safari": [ // A support statement can be an array of multiple statements to better describe the compatibility story { @@ -148,6 +145,7 @@ Here is an example of a `__compat` statement, with all of the properties and the "safari_ios": "mirror", "samsunginternet_android": "mirror", "webview_android": "mirror", + // If a browser is not defined, it means we don't have support information for that browser (or for web extensions, the browser has no support at all) }, "status": { // Standards track, deprecation and experimental status @@ -295,14 +293,6 @@ This is the only mandatory property and it contains a string with the version nu } ``` -- Supported, but version unknown: - -```json -{ - "version_added": true -} -``` - - No support: ```json @@ -311,25 +301,10 @@ This is the only mandatory property and it contains a string with the version nu } ``` -- Support unknown (default value, if browser omitted): - -```json -{ - "version_added": null -} -``` - -Note: many data categories no longer allow for `version_added` to be set to `true` or `null`, as we are working to [improve the quality of the compatibility data](https://github.com/mdn/browser-compat-data/issues/3555). - #### `version_removed` Contains a string with the version number the sub-feature was removed in. It may also be `true`, meaning that it is unknown in which version support was removed. If the feature has not been removed from the browser, this property is omitted, rather than being set to `false`. -Default values: - -- If `version_added` is set to `true`, `false`, or a string, `version_removed` defaults to `false`. -- If `version_added` is set to `null`, the default value of `version_removed` is also `null`. - Examples: - Removed in version 10 (added in 4 and supported up until 9): @@ -341,17 +316,6 @@ Examples: } ``` -- Removed in some version after 4: - -```json -{ - "version_added": "4", - "version_removed": true -} -``` - -Note: many data categories no longer allow for `version_removed` to be set to `true`, as we are working to [improve the quality of the compatibility data](https://github.com/mdn/browser-compat-data/issues/3555). - #### `version_last` > [!NOTE] @@ -436,7 +400,7 @@ Example for one flag required: ```json { - "version_added": true, + "version_added": "40", "flags": [ { "type": "preference", @@ -451,7 +415,7 @@ Example for two flags required: ```json { - "version_added": true, + "version_added": "40", "flags": [ { "type": "preference", diff --git a/schemas/compat-data.schema.json b/schemas/compat-data.schema.json index b244ea90c482c2..e8e8c73169f35e 100644 --- a/schemas/compat-data.schema.json +++ b/schemas/compat-data.schema.json @@ -6,43 +6,28 @@ "type": "object", "properties": { "version_added": { - "description": "A string (indicating which browser version added this feature), the value true (indicating support added in an unknown version), the value false (indicating the feature is not supported), or the value null (indicating support is unknown).", + "description": "A string (indicating which browser version added this feature), or the value false (indicating the feature is not supported).", "anyOf": [ { "type": "string", "pattern": "^(≤?(\\d+)(\\.\\d+)*|preview)$" }, { - "type": "boolean", - "nullable": true + "const": false } ], "tsType": "VersionValue" }, "version_removed": { - "description": "A string, indicating which browser version removed this feature, or the value true, indicating that the feature was removed in an unknown version.", - "anyOf": [ - { - "type": "string", - "pattern": "^(≤?(\\d+)(\\.\\d+)*|preview)$" - }, - { - "const": true - } - ], + "description": "A string, indicating which browser version removed this feature.", + "type": "string", + "pattern": "^(≤?(\\d+)(\\.\\d+)*|preview)$", "tsType": "VersionValue" }, "version_last": { - "description": "A string, indicating the last browser version that supported this feature, or the value true, indicating that the feature was removed in an unknown version. This is automatically generated.", - "anyOf": [ - { - "type": "string", - "pattern": "^(≤?(\\d+)(\\.\\d+)*|preview)$" - }, - { - "const": true - } - ], + "description": "A string, indicating the last browser version that supported this feature. This is automatically generated.", + "type": "string", + "pattern": "^(≤?(\\d+)(\\.\\d+)*|preview)$", "tsType": "VersionValue" }, "prefix": { diff --git a/scripts/statistics.test.ts b/scripts/statistics.test.ts index cdf792306669ab..dc21e78b68e3df 100644 --- a/scripts/statistics.test.ts +++ b/scripts/statistics.test.ts @@ -20,8 +20,8 @@ describe('getStats', () => { __compat: { support: { chrome: { version_added: '≤1' }, - firefox: { version_added: '1' }, - safari: { version_added: null }, + firefox: { version_added: '4' }, + safari: { version_added: '10' }, }, }, }, @@ -31,7 +31,7 @@ describe('getStats', () => { __compat: { support: { chrome: { version_added: '1' }, - firefox: { version_added: null }, + firefox: { version_added: '≤30' }, safari: { version_added: '1' }, }, }, @@ -43,24 +43,24 @@ describe('getStats', () => { it('should return stats for all browsers when allBrowsers is true', () => { const stats = getStats('api', true, bcd); assert.deepEqual(stats, { - total: { all: 3, true: 0, null: 1, range: 0, real: 2 }, - chrome: { all: 1, true: 0, null: 0, range: 0, real: 1 }, - firefox: { all: 1, true: 0, null: 1, range: 0, real: 0 }, - safari: { all: 1, true: 0, null: 0, range: 0, real: 1 }, + total: { all: 3, range: 1, real: 2 }, + chrome: { all: 1, range: 0, real: 1 }, + firefox: { all: 1, range: 1, real: 0 }, + safari: { all: 1, range: 0, real: 1 }, }); }); it('should return stats for webextensions browsers when folder is "webextensions"', () => { const stats = getStats('webextensions', false, bcd); assert.deepEqual(stats, { - total: { all: 7, true: 0, null: 5, range: 1, real: 1 }, - chrome: { all: 1, true: 0, null: 0, range: 1, real: 0 }, - edge: { all: 1, true: 0, null: 1, range: 0, real: 0 }, - firefox: { all: 1, true: 0, null: 0, range: 0, real: 1 }, - opera: { all: 1, true: 0, null: 1, range: 0, real: 0 }, - safari: { all: 1, true: 0, null: 1, range: 0, real: 0 }, - firefox_android: { all: 1, true: 0, null: 1, range: 0, real: 0 }, - safari_ios: { all: 1, true: 0, null: 1, range: 0, real: 0 }, + total: { all: 7, range: 1, real: 6 }, + chrome: { all: 1, range: 1, real: 0 }, + edge: { all: 1, range: 0, real: 1 }, + firefox: { all: 1, range: 0, real: 1 }, + opera: { all: 1, range: 0, real: 1 }, + safari: { all: 1, range: 0, real: 1 }, + firefox_android: { all: 1, range: 0, real: 1 }, + safari_ios: { all: 1, range: 0, real: 1 }, }); }); diff --git a/scripts/statistics.ts b/scripts/statistics.ts index effb89ea4fd5e0..f984eb8e0a8f21 100644 --- a/scripts/statistics.ts +++ b/scripts/statistics.ts @@ -19,8 +19,6 @@ import { getRefDate } from './release/utils.js'; interface VersionStatsEntry { all: number; - true: number; - null: number; range: number; real: number; } @@ -81,16 +79,7 @@ const processData = ( browsers.forEach((browser) => { stats[browser].all++; stats.total.all++; - if (!data.support[browser]) { - stats[browser].null++; - stats.total.null++; - } else if (checkSupport(data.support[browser], null)) { - stats[browser].null++; - stats.total.null++; - } else if (checkSupport(data.support[browser], true)) { - stats[browser].true++; - stats.total.true++; - } else if (checkSupport(data.support[browser], '≤')) { + if (checkSupport(data.support[browser], '≤')) { stats[browser].range++; stats.total.range++; } else { @@ -149,10 +138,10 @@ const getStats = ( ] as BrowserName[]); const stats: VersionStats = { - total: { all: 0, true: 0, null: 0, range: 0, real: 0 }, + total: { all: 0, range: 0, real: 0 }, }; browsers.forEach((browser) => { - stats[browser] = { all: 0, true: 0, null: 0, range: 0, real: 0 }; + stats[browser] = { all: 0, range: 0, real: 0 }; }); if (folder) { @@ -226,20 +215,17 @@ const printStats = ( }}: \n`, ); - const header = ['browser', 'real', 'ranged', '`true`', '`null`']; + const header = ['browser', 'real', 'ranged']; + const align = ['l', 'r', 'r']; const rows = Object.keys(stats).map((entry) => [ entry, getStat(stats[entry], 'real', counts), getStat(stats[entry], 'range', counts), - getStat(stats[entry], 'true', counts), - getStat(stats[entry], 'null', counts), ].map(String), ); - const table = markdownTable([header, ...rows], { - align: ['l', ...header.slice(1).map(() => 'r')], - }); + const table = markdownTable([header, ...rows], { align }); console.log(table); }; diff --git a/scripts/traverse.ts b/scripts/traverse.ts index 0d4062d5ac39e9..f2f06a20db2af9 100644 --- a/scripts/traverse.ts +++ b/scripts/traverse.ts @@ -183,7 +183,7 @@ const main = ( browsers: BrowserName[] = Object.keys(bcd.browsers).filter( (b) => bcd.browsers[b].type !== 'server', ) as BrowserName[], - values = ['null', 'true'], + values = [], depth = 100, tag = '', status = {} as StatusFilters, @@ -245,13 +245,6 @@ if (esMain(import.meta)) { nargs: 1, default: '', }) - .option('non-real', { - alias: 'n', - describe: - 'Filter to features with non-real values. Alias for "-f true -f null"', - type: 'boolean', - nargs: 0, - }) .option('depth', { alias: 'd', describe: @@ -288,12 +281,8 @@ if (esMain(import.meta)) { default: undefined, }) .example( - 'npm run traverse -- --browser=safari -n', - 'Find all features containing non-real Safari entries', - ) - .example( - 'npm run traverse -- -b webview_android -f true', - 'Find all features marked as true for WebView', + 'npm run traverse -- -b webview_android -f ≤37', + 'Find all features marked as ≤37 for WebView', ) .example( 'npm run traverse -- -b firefox -f 10', @@ -330,12 +319,10 @@ if (esMain(import.meta)) { }, ); - const filter = [...argv.filter, ...(argv.nonReal ? ['true', 'null'] : [])]; - const features = main( argv.folder, argv.browser, - filter, + argv.filter, argv.depth, argv.tag, argv.status,