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..fb9738a91daa60 100644 --- a/schemas/compat-data.schema.json +++ b/schemas/compat-data.schema.json @@ -13,36 +13,21 @@ "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 - } - ], + "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 - } - ], + "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,