Skip to content

Commit 3662d56

Browse files
committed
feat(mirror): ignore OS limitations when mirroring to mobile
1 parent 05a5410 commit 3662d56

File tree

2 files changed

+140
-2
lines changed

2 files changed

+140
-2
lines changed

scripts/build/mirror.test.ts

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,69 @@ import { BrowserName } from '../../types/types.js';
77
import bcd from '../../index.js';
88
import { InternalSupportBlock } from '../../types/index.js';
99

10-
import mirrorSupport from './mirror.js';
10+
import mirrorSupport, { isOSLimitation } from './mirror.js';
1111

1212
describe('mirror', () => {
13+
describe('isOSLimitation', () => {
14+
it('returns false for undefined notes', () => {
15+
assert.equal(isOSLimitation(undefined), false);
16+
});
17+
18+
it('returns true for OS limitation notes', () => {
19+
assert.equal(
20+
isOSLimitation('Supported on ChromeOS, macOS, and Windows only.'),
21+
true,
22+
);
23+
assert.equal(
24+
isOSLimitation('Supported on Linux and Windows only.'),
25+
true,
26+
);
27+
assert.equal(isOSLimitation('Supported on macOS only.'), true);
28+
assert.equal(isOSLimitation('Not supported on Windows.'), true);
29+
assert.equal(isOSLimitation('Not yet supported on macOS.'), true);
30+
});
31+
32+
it('returns false for non-OS-limitation notes', () => {
33+
assert.equal(
34+
isOSLimitation('This feature requires a flag to be enabled.'),
35+
false,
36+
);
37+
assert.equal(
38+
isOSLimitation('Before version 70, this method always returned true.'),
39+
false,
40+
);
41+
assert.equal(
42+
isOSLimitation('Firefox 73 added support for this thing.'),
43+
false,
44+
);
45+
});
46+
47+
it('handles array of notes (returns true only if all match)', () => {
48+
assert.equal(
49+
isOSLimitation([
50+
'Supported on ChromeOS, macOS, and Windows only.',
51+
'Not yet supported on Linux.',
52+
]),
53+
true,
54+
);
55+
assert.equal(
56+
isOSLimitation([
57+
'Supported on ChromeOS, macOS, and Windows only.',
58+
'This feature requires a flag.',
59+
]),
60+
false,
61+
);
62+
assert.equal(
63+
isOSLimitation(['This is a note.', 'This is another note.']),
64+
false,
65+
);
66+
});
67+
68+
it('returns false for empty string', () => {
69+
assert.equal(isOSLimitation(''), false);
70+
});
71+
});
72+
1373
describe('default export', () => {
1474
describe('version numbers match expected values', () => {
1575
const mappings: {
@@ -189,6 +249,38 @@ describe('mirror', () => {
189249
notes: 'This feature is only supported in ChromeOS, macOS and Linux.',
190250
});
191251
});
252+
253+
it('OS-specific partial_implementation and notes are not mirrored', () => {
254+
const support = {
255+
chrome: {
256+
version_added: '134',
257+
partial_implementation: true,
258+
notes: 'Supported on ChromeOS, macOS, and Windows only.',
259+
},
260+
};
261+
262+
const mirrored = mirrorSupport('chrome_android', support);
263+
assert.deepEqual(mirrored, {
264+
version_added: '134',
265+
});
266+
});
267+
268+
it('Non-OS-specific partial_implementation and notes are still mirrored', () => {
269+
const support = {
270+
chrome: {
271+
version_added: '70',
272+
partial_implementation: true,
273+
notes: 'This feature is incomplete and may not work as expected.',
274+
},
275+
};
276+
277+
const mirrored = mirrorSupport('chrome_android', support);
278+
assert.deepEqual(mirrored, {
279+
version_added: '70',
280+
partial_implementation: true,
281+
notes: 'This feature is incomplete and may not work as expected.',
282+
});
283+
});
192284
});
193285

194286
describe('Validations', () => {

scripts/build/mirror.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,41 @@ const { browsers } = bcd;
1616
type Notes = string | [string, string, ...string[]] | null;
1717

1818
/**
19+
* Check if a support statement has OS-specific limitation notes
20+
* @param notes The notes field from a support statement
21+
* @returns True if the notes indicate OS-specific limitations
1922
*/
23+
export const isOSLimitation = (
24+
notes: string | string[] | undefined,
25+
): boolean => {
26+
if (notes === undefined) {
27+
return false;
28+
} else if (Array.isArray(notes)) {
29+
return notes.every(isOSLimitation);
30+
}
31+
32+
const words = notes
33+
.split(/\s+/)
34+
.map((word) => word.toLowerCase().replace(/[,.;:!?]$/g, '')); // Remove trailing punctuation
35+
36+
if (words.length === 0) {
37+
return false;
38+
}
39+
40+
const os = ['chromeos', 'linux', 'macos', 'windows'];
41+
const expectedWords = ['supported', 'on', 'only', 'not', 'yet', 'and'];
42+
43+
let hasOSKeyword = false;
44+
for (const word of words) {
45+
if (os.includes(word)) {
46+
hasOSKeyword = true;
47+
} else if (!expectedWords.includes(word)) {
48+
return false;
49+
}
50+
}
51+
52+
return hasOSKeyword;
53+
};
2054

2155
const matchingSafariVersions = new Map([
2256
['1', '1'],
@@ -215,6 +249,17 @@ export const bumpSupport = (
215249

216250
const newData: SimpleSupportStatement = copyStatement(sourceData);
217251

252+
if (
253+
browsers[sourceBrowser].type === 'desktop' &&
254+
browsers[destination].type === 'mobile' &&
255+
sourceData.partial_implementation &&
256+
isOSLimitation(sourceData.notes)
257+
) {
258+
// Ignore partial flag due to OS limitation.
259+
delete newData.partial_implementation;
260+
delete newData.notes;
261+
}
262+
218263
if (!browsers[destination].accepts_flags && newData.flags) {
219264
// Remove flag data if the target browser doesn't accept flags
220265
return { version_added: false };
@@ -254,7 +299,8 @@ export const bumpSupport = (
254299
return { version_added: false };
255300
}
256301

257-
if (sourceData.notes) {
302+
// Only process notes if they weren't already removed (e.g., for OS-specific limitations)
303+
if (sourceData.notes && newData.notes !== undefined) {
258304
const sourceBrowserName =
259305
sourceBrowser === 'chrome'
260306
? '(Google )?Chrome'

0 commit comments

Comments
 (0)