diff --git a/packages/core/integration-tests/test/integration/webmanifest-json/file-handler-icon.png b/packages/core/integration-tests/test/integration/webmanifest-json/file-handler-icon.png new file mode 100644 index 00000000000..8a1daa0121d Binary files /dev/null and b/packages/core/integration-tests/test/integration/webmanifest-json/file-handler-icon.png differ diff --git a/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json b/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json index bf9b21d989b..6111282a874 100644 --- a/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json +++ b/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json @@ -16,14 +16,26 @@ ], "shortcuts": [ { - "name": "example-shortcut", - "icons": [ - { - "src": "shortcut-icon.png", - "sizes": "100x100", - "type": "image/png" - } - ] + "name": "example-shortcut", + "icons": [ + { + "src": "shortcut-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] + } + ], + "file_handlers": [ + { + "name": "example-file-handler", + "icons": [ + { + "src": "file-handler-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] } ] } diff --git a/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest b/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest index 7b9bf17e5db..60168aaeada 100644 --- a/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest +++ b/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest @@ -31,5 +31,6 @@ {} ] } - ] + ], + "file_handlers": {} } diff --git a/packages/core/integration-tests/test/integration/webmanifest/file-handler-icon.png b/packages/core/integration-tests/test/integration/webmanifest/file-handler-icon.png new file mode 100644 index 00000000000..8a1daa0121d Binary files /dev/null and b/packages/core/integration-tests/test/integration/webmanifest/file-handler-icon.png differ diff --git a/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest b/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest index bf9b21d989b..6111282a874 100644 --- a/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest +++ b/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest @@ -16,14 +16,26 @@ ], "shortcuts": [ { - "name": "example-shortcut", - "icons": [ - { - "src": "shortcut-icon.png", - "sizes": "100x100", - "type": "image/png" - } - ] + "name": "example-shortcut", + "icons": [ + { + "src": "shortcut-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] + } + ], + "file_handlers": [ + { + "name": "example-file-handler", + "icons": [ + { + "src": "file-handler-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] } ] } diff --git a/packages/core/integration-tests/test/webmanifest.js b/packages/core/integration-tests/test/webmanifest.js index 7b0ce812d4e..9c6cc091297 100644 --- a/packages/core/integration-tests/test/webmanifest.js +++ b/packages/core/integration-tests/test/webmanifest.js @@ -30,6 +30,10 @@ describe('webmanifest', function () { type: 'png', assets: ['shortcut-icon.png'], }, + { + type: 'png', + assets: ['file-handler-icon.png'], + }, ]); const manifest = await outputFS.readFile( @@ -39,6 +43,7 @@ describe('webmanifest', function () { assert(/screenshot\.[0-9a-f]+\.png/.test(manifest)); assert(/icon\.[0-9a-f]+\.png/.test(manifest)); assert(/shortcut-icon\.[0-9a-f]+\.png/.test(manifest)); + assert(/file-handler-icon\.[0-9a-f]+\.png/.test(manifest)); }); it('should support .json', async function () { @@ -67,6 +72,10 @@ describe('webmanifest', function () { type: 'png', assets: ['shortcut-icon.png'], }, + { + type: 'png', + assets: ['file-handler-icon.png'], + }, ]); const manifest = await outputFS.readFile( @@ -76,9 +85,10 @@ describe('webmanifest', function () { assert(/screenshot\.[0-9a-f]+\.png/.test(manifest)); assert(/icon\.[0-9a-f]+\.png/.test(manifest)); assert(/shortcut-icon\.[0-9a-f]+\.png/.test(manifest)); + assert(/file-handler-icon\.[0-9a-f]+\.png/.test(manifest)); }); - it('should throw on malformed icons and screenshots', async function () { + it('should throw on malformed icons, screenshots, shortcuts, and file handlers', async function () { let manifestPath = path.join( __dirname, '/integration/webmanifest-schema/manifest.webmanifest', @@ -167,6 +177,17 @@ describe('webmanifest', function () { line: 31, }, }, + { + end: { + column: 21, + line: 35, + }, + message: 'Expected type array', + start: { + column: 20, + line: 35, + }, + }, ], }, ], diff --git a/packages/transformers/webmanifest/src/WebManifestTransformer.js b/packages/transformers/webmanifest/src/WebManifestTransformer.js index 3288a9c330a..a6307df5efc 100644 --- a/packages/transformers/webmanifest/src/WebManifestTransformer.js +++ b/packages/transformers/webmanifest/src/WebManifestTransformer.js @@ -39,6 +39,15 @@ const MANIFEST_SCHEMA: SchemaEntity = { }, }, }, + file_handlers: { + type: 'array', + items: { + type: 'object', + properties: { + icons: RESOURCES_SCHEMA, + }, + }, + }, }, }; @@ -54,8 +63,7 @@ export default (new Transformer({ 'Invalid webmanifest', ); - for (const key of ['icons', 'screenshots']) { - const list = data[key]; + function addResourceListToAsset(list, parent) { if (list) { invariant(Array.isArray(list)); for (let i = 0; i < list.length; i++) { @@ -63,31 +71,28 @@ export default (new Transformer({ res.src = asset.addURLDependency(res.src, { loc: { filePath: asset.filePath, - ...getJSONSourceLocation(pointers[`/${key}/${i}/src`], 'value'), + ...getJSONSourceLocation( + pointers[`/${parent}/${i}/src`], + 'value', + ), }, }); } } } - if (data.shortcuts) { - invariant(Array.isArray(data.shortcuts)); - for (let i = 0; i < data.shortcuts.length; i++) { - const list = data.shortcuts[i].icons; - if (list) { - invariant(Array.isArray(list)); - for (let j = 0; j < list.length; j++) { - const res = list[j]; - res.src = asset.addURLDependency(res.src, { - loc: { - filePath: asset.filePath, - ...getJSONSourceLocation( - pointers[`/shortcuts/${i}/icons/${j}/src`], - 'value', - ), - }, - }); - } + for (const key of ['icons', 'screenshots']) { + const list = data[key]; + addResourceListToAsset(list, key); + } + + for (const key of ['shortcuts', 'file_handlers']) { + const list = data[key]; + if (list) { + invariant(Array.isArray(list)); + for (let i = 0; i < list.length; i++) { + const iconList = list[i].icons; + addResourceListToAsset(iconList, `${key}/${i}/icons`); } } }