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 df3bafd8591..bf9b21d989b 100644 --- a/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json +++ b/packages/core/integration-tests/test/integration/webmanifest-json/manifest.json @@ -13,5 +13,17 @@ "sizes": "100x100", "type": "image/png" } + ], + "shortcuts": [ + { + "name": "example-shortcut", + "icons": [ + { + "src": "shortcut-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] + } ] } diff --git a/packages/core/integration-tests/test/integration/webmanifest-json/shortcut-icon.png b/packages/core/integration-tests/test/integration/webmanifest-json/shortcut-icon.png new file mode 100644 index 00000000000..8a1daa0121d Binary files /dev/null and b/packages/core/integration-tests/test/integration/webmanifest-json/shortcut-icon.png differ 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 f28b0aedc75..7b9bf17e5db 100644 --- a/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest +++ b/packages/core/integration-tests/test/integration/webmanifest-schema/manifest.webmanifest @@ -12,5 +12,24 @@ }, {} ], - "screenshots": {} + "screenshots": {}, + "shortcuts": [ + { + "icons": {} + }, + { + "icons": [ + { + "src": "icon.png", + "sizes": "100x100", + "type": "image/png" + }, + { + "sizes": "100x100", + "type": "image/png" + }, + {} + ] + } + ] } diff --git a/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest b/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest index df3bafd8591..bf9b21d989b 100644 --- a/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest +++ b/packages/core/integration-tests/test/integration/webmanifest/manifest.webmanifest @@ -13,5 +13,17 @@ "sizes": "100x100", "type": "image/png" } + ], + "shortcuts": [ + { + "name": "example-shortcut", + "icons": [ + { + "src": "shortcut-icon.png", + "sizes": "100x100", + "type": "image/png" + } + ] + } ] } diff --git a/packages/core/integration-tests/test/integration/webmanifest/shortcut-icon.png b/packages/core/integration-tests/test/integration/webmanifest/shortcut-icon.png new file mode 100644 index 00000000000..8a1daa0121d Binary files /dev/null and b/packages/core/integration-tests/test/integration/webmanifest/shortcut-icon.png differ diff --git a/packages/core/integration-tests/test/webmanifest.js b/packages/core/integration-tests/test/webmanifest.js index e63cf3918dd..cfee46756f2 100644 --- a/packages/core/integration-tests/test/webmanifest.js +++ b/packages/core/integration-tests/test/webmanifest.js @@ -26,6 +26,10 @@ describe('webmanifest', function () { type: 'png', assets: ['screenshot.png'], }, + { + type: 'png', + assets: ['shortcut-icon.png'], + }, ]); const manifest = await outputFS.readFile( @@ -34,6 +38,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)); }); it('should support .json', async function () { @@ -58,6 +63,10 @@ describe('webmanifest', function () { type: 'png', assets: ['screenshot.png'], }, + { + type: 'png', + assets: ['shortcut-icon.png'], + }, ]); const manifest = await outputFS.readFile( @@ -66,6 +75,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)); }); it('should throw on malformed icons and screenshots', async function () { @@ -124,6 +134,39 @@ describe('webmanifest', function () { line: 15, }, }, + { + end: { + column: 17, + line: 18, + }, + message: 'Expected type array', + start: { + column: 16, + line: 18, + }, + }, + { + end: { + column: 9, + line: 30, + }, + message: 'Missing property src', + start: { + column: 9, + line: 27, + }, + }, + { + end: { + column: 10, + line: 31, + }, + message: 'Missing property src', + start: { + column: 9, + line: 31, + }, + }, ], }, ], diff --git a/packages/transformers/webmanifest/src/WebManifestTransformer.js b/packages/transformers/webmanifest/src/WebManifestTransformer.js index 138c90f3a76..3288a9c330a 100644 --- a/packages/transformers/webmanifest/src/WebManifestTransformer.js +++ b/packages/transformers/webmanifest/src/WebManifestTransformer.js @@ -30,6 +30,15 @@ const MANIFEST_SCHEMA: SchemaEntity = { properties: { icons: RESOURCES_SCHEMA, screenshots: RESOURCES_SCHEMA, + shortcuts: { + type: 'array', + items: { + type: 'object', + properties: { + icons: RESOURCES_SCHEMA, + }, + }, + }, }, }; @@ -61,6 +70,28 @@ export default (new Transformer({ } } + 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', + ), + }, + }); + } + } + } + } + asset.type = 'webmanifest'; asset.setCode(JSON.stringify(data)); return [asset];