From 1b24ae1c7fc7611213bb9d7a0fbbd66726835752 Mon Sep 17 00:00:00 2001 From: Eric Peterson Date: Fri, 28 May 2021 17:45:16 +0200 Subject: [PATCH] Account for displaying SVGs in the frontend. Signed-off-by: Eric Peterson --- .../reader/transformers/addBaseUrl.test.ts | 41 ++++++++++++++++++- .../src/reader/transformers/addBaseUrl.ts | 23 +++++++++-- 2 files changed, 60 insertions(+), 4 deletions(-) diff --git a/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts b/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts index afed2eff73..2b17d04144 100644 --- a/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts +++ b/plugins/techdocs/src/reader/transformers/addBaseUrl.test.ts @@ -47,8 +47,17 @@ const mockEntityId = { namespace: '', name: '', }; - describe('addBaseUrl', () => { + const originalFetch = global.fetch; + + beforeEach(() => { + global.fetch = jest.fn(); + }); + + afterEach(() => { + global.fetch = originalFetch; + }); + it('contains relative paths', () => { createTestShadowDom(fixture, { preTransformers: [ @@ -86,4 +95,34 @@ describe('addBaseUrl', () => { '', ); }); + + it('transforms svg img src to data uri', async () => { + const svgContent = ''; + const expectedSrc = `data:image/svg+xml;base64,${Buffer.from( + svgContent, + ).toString('base64')}`; + + (global.fetch as jest.Mock).mockReturnValue({ + text: jest.fn().mockResolvedValue(svgContent), + }); + + const root = createTestShadowDom('', { + preTransformers: [ + addBaseUrl({ + techdocsStorageApi, + entityId: mockEntityId, + path: '', + }), + ], + postTransformers: [], + }); + + await new Promise(done => { + process.nextTick(() => { + const actualSrc = root.getElementById('x')?.getAttribute('src'); + expect(expectedSrc).toEqual(actualSrc); + done(); + }); + }); + }); }); diff --git a/plugins/techdocs/src/reader/transformers/addBaseUrl.ts b/plugins/techdocs/src/reader/transformers/addBaseUrl.ts index 9bb5418bc2..98db162b46 100644 --- a/plugins/techdocs/src/reader/transformers/addBaseUrl.ts +++ b/plugins/techdocs/src/reader/transformers/addBaseUrl.ts @@ -38,10 +38,27 @@ export const addBaseUrl = ({ .forEach(async (elem: T) => { const elemAttribute = elem.getAttribute(attributeName); if (!elemAttribute) return; - elem.setAttribute( - attributeName, - await techdocsStorageApi.getBaseUrl(elemAttribute, entityId, path), + + // Special handling for SVG images. + const newValue = await techdocsStorageApi.getBaseUrl( + elemAttribute, + entityId, + path, ); + if (attributeName === 'src' && elemAttribute.endsWith('.svg')) { + try { + const svg = await fetch(newValue); + const svgContent = await svg.text(); + elem.setAttribute( + attributeName, + `data:image/svg+xml;base64,${btoa(svgContent)}`, + ); + } catch (e) { + elem.setAttribute('alt', `Error: ${elemAttribute}`); + } + } else { + elem.setAttribute(attributeName, newValue); + } }); };