From 2e3ad112488e59fd07704c4a31f13f990c2b2014 Mon Sep 17 00:00:00 2001 From: Vjacheslav Trushkin Date: Mon, 2 Jan 2023 00:13:11 +0200 Subject: [PATCH] fix(utils): replacing ids in svg after replacing same ids --- packages/utils/package.json | 2 +- packages/utils/src/svg/id.ts | 7 ++++- packages/utils/tests/replace-ids-test.ts | 33 +++++++++++++++++++++--- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/packages/utils/package.json b/packages/utils/package.json index f346f5a..990950d 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -3,7 +3,7 @@ "type": "module", "description": "Common functions for working with Iconify icon sets used by various packages.", "author": "Vjacheslav Trushkin", - "version": "2.0.8", + "version": "2.0.9", "license": "MIT", "bugs": "https://github.com/iconify/iconify/issues", "homepage": "https://iconify.design/", diff --git a/packages/utils/src/svg/id.ts b/packages/utils/src/svg/id.ts index 26ce358..31c7468 100644 --- a/packages/utils/src/svg/id.ts +++ b/packages/utils/src/svg/id.ts @@ -49,6 +49,10 @@ export function replaceIDs( return body; } + // Random text to make sure there are no conflicts between old and new ids + const suffix = + 'suffix' + ((Math.random() * 0x1000000) | Date.now()).toString(16); + // Replace with unique ids ids.forEach((id) => { const newID = @@ -62,9 +66,10 @@ export function replaceIDs( // Allowed characters before id: [#;"] // Allowed characters after id: [)"], .[a-z] new RegExp('([#;"])(' + escapedID + ')([")]|\\.[a-z])', 'g'), - '$1' + newID + '$3' + '$1' + newID + suffix + '$3' ); }); + body = body.replace(new RegExp(suffix, 'g'), ''); return body; } diff --git a/packages/utils/tests/replace-ids-test.ts b/packages/utils/tests/replace-ids-test.ts index 0e44e5e..0ec2b0d 100644 --- a/packages/utils/tests/replace-ids-test.ts +++ b/packages/utils/tests/replace-ids-test.ts @@ -25,9 +25,12 @@ describe('Testing replaceIDs', () => { // Using callback let counter = 0; - expect( - replaceIDs(body, () => 'callbackID' + (counter++).toString()) - ).toBe( + const replaced = replaceIDs( + body, + () => 'callbackID' + (counter++).toString() + ); + + expect(replaced).toBe( body .replace(/ssvg-id-1st-place-medala/g, 'callbackID0') .replace(/ssvg-id-1st-place-medalb/g, 'callbackID7') @@ -46,6 +49,30 @@ describe('Testing replaceIDs', () => { .replace(/ssvg-id-1st-place-medalo/g, 'callbackID9') .replace(/ssvg-id-1st-place-medalp/g, 'callbackID6') ); + + // Replacing it again to test double replacement with overlapping numbers + counter = 10; + expect( + replaceIDs(replaced, () => 'callbackID' + (counter++).toString()) + ).toBe( + body + .replace(/ssvg-id-1st-place-medala/g, 'callbackID10') + .replace(/ssvg-id-1st-place-medalb/g, 'callbackID17') + .replace(/ssvg-id-1st-place-medalc/g, 'callbackID20') + .replace(/ssvg-id-1st-place-medald/g, 'callbackID11') + .replace(/ssvg-id-1st-place-medale/g, 'callbackID21') + .replace(/ssvg-id-1st-place-medalf/g, 'callbackID12') + .replace(/ssvg-id-1st-place-medalg/g, 'callbackID22') + .replace(/ssvg-id-1st-place-medalh/g, 'callbackID13') + .replace(/ssvg-id-1st-place-medali/g, 'callbackID23') + .replace(/ssvg-id-1st-place-medalj/g, 'callbackID14') + .replace(/ssvg-id-1st-place-medalk/g, 'callbackID18') + .replace(/ssvg-id-1st-place-medall/g, 'callbackID24') + .replace(/ssvg-id-1st-place-medalm/g, 'callbackID15') + .replace(/ssvg-id-1st-place-medaln/g, 'callbackID25') + .replace(/ssvg-id-1st-place-medalo/g, 'callbackID19') + .replace(/ssvg-id-1st-place-medalp/g, 'callbackID16') + ); }); test('Matching parts', () => {