From c6e37ef4149c49908c269ee538d3c0e5a344f442 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 10:33:11 -0700 Subject: [PATCH 01/13] feat: create filter module to prefix svg filename to IDs within SVGs --- AUTHORS | 1 + README.md | 10 +++- lib/loader.js | 3 ++ lib/options.js | 7 +++ lib/sanitize/filters/unique-svg-ids.js | 69 ++++++++++++++++++++++++++ package.json | 4 +- 6 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 lib/sanitize/filters/unique-svg-ids.js diff --git a/AUTHORS b/AUTHORS index 9b4e565..165d4dc 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ Jerry Hamlet (http://hamletink.com/) +William Brinkert diff --git a/README.md b/README.md index db13226..cec7e88 100644 --- a/README.md +++ b/README.md @@ -17,10 +17,12 @@ other loaders before `svg-react` to alter/update/remove nodes before reaching In addition, the new [filters](#filters) API allows for additional ways to modify the generated SVG Component. This allows `svg-react` to also be used as a pre-loader (with `filters` and `raw=true` params) for modifying SVGs before they -are acted on by the loader version of `svg-react`. +are acted on by the loader version of `svg-react`. ### Notes +> This fork has an added filter which creates unique IDs and mask, fill, and xlink:href +> references to those IDs. > As of version 0.4.0, `svg-react-loader` no longer requires `babel` to > transpile the generated code. Everything is returned as an ES5-7 compatible > module, and the component is just a @@ -93,6 +95,10 @@ the resource will override those given for the loader. blocks, or within `className` properties, with. If indicated without a string, the file's basename will be used as a prefix. +* `uniqueIdPrefix`: When set to `true` will prefix the filename to the IDs and + references within the SVG, solving the problem of ID collision when multiple + SVGs are used on the same page. + * `raw`: If set to `true` will output the parsed object tree repesenting the SVG as a JSON string. Otherwise, returns a string of JavaScript that represents the component's module. @@ -121,6 +127,7 @@ module: { loader: 'svg-react-loader', query: { classIdPrefix: '[name]-[hash:8]__', + uniqueIdPrefix: true, filters: [ function (value) { // ... @@ -204,6 +211,7 @@ Report an Issue * [Bugs](http://github.com/jhamlet/svg-react-loader/issues) * Contact the author: +* For issues with the generation of unique ID prefixes, please contact License diff --git a/lib/loader.js b/lib/loader.js index 1333e5e..fd2262d 100644 --- a/lib/loader.js +++ b/lib/loader.js @@ -33,6 +33,7 @@ module.exports = function svgReactLoader (source) { var raw = params.raw; var xmlnsTest = params.xmlnsTest; var classIdPrefix = params.classIdPrefix || false; + var uniqueIdPrefix = params.uniqueIdPrefix || false; context.cacheable(); @@ -72,6 +73,8 @@ module.exports = function svgReactLoader (source) { lutils.interpolatename(context, classIdPrefix) : classIdPrefix; + options.uniqueIdPrefix = uniqueIdPrefix === true ? displayName + '__' : ''; + if (params.filters) { filters = filters. diff --git a/lib/options.js b/lib/options.js index 0e15cf7..0b5784d 100644 --- a/lib/options.js +++ b/lib/options.js @@ -38,6 +38,13 @@ module.exports = function (opts) { })); } + if (options.uniqueIdPrefix) { + filters. + push(require('./sanitize/filters/unique-svg-ids')({ + prefix: options.uniqueIdPrefix + })); + } + if (options.root) { filters. push(require('./sanitize/filters/custom-root')(options.root)); diff --git a/lib/sanitize/filters/unique-svg-ids.js b/lib/sanitize/filters/unique-svg-ids.js new file mode 100644 index 0000000..69c5ba1 --- /dev/null +++ b/lib/sanitize/filters/unique-svg-ids.js @@ -0,0 +1,69 @@ +var R = require('ramda'); +var css = require('css'); + +var DEFAULTS = { + prefix: 'filename-prefix__', +}; + +module.exports = function configureUniquePrefixId (opts) { + var options = R.merge(DEFAULTS, opts || {}); + var cache = options.cache = {}; + var selectorRegex = /(url\(#)((\w|-)*)(\))/gmi; + + _getMatches = (field, val) => { + var str = val.toString(); + var matches = selectorRegex.exec(str); + // console.log(`-----------\n ${field} id is: ${opts.prefix + matches[2].replace('\"', "")}`); + selectorRegex.lastIndex = 0; + return opts.prefix + matches[2].replace('\"', ""); + + } + + return function createUniquePrefixId (value) { + var hasID = false; + var path = this.path; + // var isStyle = isStyleNode(value); + // var hasChildren = hasChildrenKey(value); + // if(opts.prefix === "Bars__") console.log(`******* bars : ${JSON.stringify(value, null, 2)}`); + if (value.xlinkHref && value.xlinkHref.toString().startsWith("#")){ + var newValue = "#" + opts.prefix + value.xlinkHref.toString().replace("#", ""); + // console.log(`****** new xlink:href: ${newValue}`); + value.xlinkHref = newValue; + this.update(value); + } + if (value.id){ + console.log(`value id: ${JSON.stringify(value.id, null, 2)}`); + var newValue = opts.prefix + value.id; + value.id = newValue; + // console.log(`#######################\n value here: ${JSON.stringify(value, null, 2)}`); + // console.log(`=======================\n before this:`); + // console.log(this); + // console.log(`new id: ${value.id}`); + this.update(value); + // console.log(`+++++++++++++++++++++++\n after this:`); + // console.log(this); + // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); + hasID = true; + } + if (value.fill && value.fill.toString().startsWith("url")){ + // console.log(`value fill: ${JSON.stringify(value.fill, null, 2)}`); + var newValue = "url(#" + _getMatches('fill', value.fill) + ")"; + // console.log(`new fill id: ${newValue}`); + value.fill = newValue; + this.update(value); + // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); + hasID = true; + } + if (value.mask && value.mask.toString().startsWith("url")){ + // console.log(`value mask: ${JSON.stringify(value.mask, null, 2)}`); + var newValue = _getMatches('mask', value.mask); + var newValue = "url(#" + _getMatches('fill', value.mask) + ")"; + // console.log(`new mask id: ${newValue}`); + value.mask = newValue; + this.update(value); + // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); + hasID = true; + } + // if (hasID) console.log(JSON.stringify(opts.prefix, null, 2)); + }; +}; diff --git a/package.json b/package.json index 7f01cdd..9a2e94e 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/jhamlet/svg-react-loader.git" + "url": "git+https://github.com/SilverFox70/svg-react-loader" }, "keywords": [ "webpack", @@ -26,7 +26,7 @@ "bugs": { "url": "https://github.com/jhamlet/svg-react-loader/issues" }, - "homepage": "https://github.com/jhamlet/svg-react-loader#readme", + "homepage": "https://github.com/SilverFox70/svg-react-loader#readme", "dependencies": { "css": "2.2.1", "loader-utils": "1.1.0", From a4490b9797b59f8099a9f0de396557004173daf0 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 10:38:50 -0700 Subject: [PATCH 02/13] update [readme] clarify what uniqueIdPrefix actually does --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index cec7e88..3e37e72 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ are acted on by the loader version of `svg-react`. ### Notes -> This fork has an added filter which creates unique IDs and mask, fill, and xlink:href -> references to those IDs. +> This fork has an added filter which creates 'unique' IDs and mask, fill, and xlink:href +> references to those IDs by prefixing the filename. > As of version 0.4.0, `svg-react-loader` no longer requires `babel` to > transpile the generated code. Everything is returned as an ES5-7 compatible > module, and the component is just a From 43c574a9f3c0bec98307d4b608022912889d9020 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 10:49:29 -0700 Subject: [PATCH 03/13] chore: clean up logs and dead code --- lib/sanitize/filters/unique-svg-ids.js | 34 +++++++------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/lib/sanitize/filters/unique-svg-ids.js b/lib/sanitize/filters/unique-svg-ids.js index 69c5ba1..1a7d2ed 100644 --- a/lib/sanitize/filters/unique-svg-ids.js +++ b/lib/sanitize/filters/unique-svg-ids.js @@ -10,60 +10,44 @@ module.exports = function configureUniquePrefixId (opts) { var cache = options.cache = {}; var selectorRegex = /(url\(#)((\w|-)*)(\))/gmi; + // Find the ID reference in items such as: "url(#a)" and return "a" _getMatches = (field, val) => { var str = val.toString(); var matches = selectorRegex.exec(str); - // console.log(`-----------\n ${field} id is: ${opts.prefix + matches[2].replace('\"', "")}`); selectorRegex.lastIndex = 0; + // clean up and get rid of the quotes return opts.prefix + matches[2].replace('\"', ""); - } return function createUniquePrefixId (value) { - var hasID = false; - var path = this.path; - // var isStyle = isStyleNode(value); - // var hasChildren = hasChildrenKey(value); - // if(opts.prefix === "Bars__") console.log(`******* bars : ${JSON.stringify(value, null, 2)}`); + // Find all the xlink:href props with local references and update if (value.xlinkHref && value.xlinkHref.toString().startsWith("#")){ var newValue = "#" + opts.prefix + value.xlinkHref.toString().replace("#", ""); - // console.log(`****** new xlink:href: ${newValue}`); value.xlinkHref = newValue; this.update(value); } + + // Find all IDs and update with filename prefix if (value.id){ console.log(`value id: ${JSON.stringify(value.id, null, 2)}`); var newValue = opts.prefix + value.id; value.id = newValue; - // console.log(`#######################\n value here: ${JSON.stringify(value, null, 2)}`); - // console.log(`=======================\n before this:`); - // console.log(this); - // console.log(`new id: ${value.id}`); this.update(value); - // console.log(`+++++++++++++++++++++++\n after this:`); - // console.log(this); - // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); - hasID = true; } + + // Find all fill props and update with filename prefix if (value.fill && value.fill.toString().startsWith("url")){ - // console.log(`value fill: ${JSON.stringify(value.fill, null, 2)}`); var newValue = "url(#" + _getMatches('fill', value.fill) + ")"; - // console.log(`new fill id: ${newValue}`); value.fill = newValue; this.update(value); - // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); - hasID = true; } + + // Find all mask props and update with filename prefix if (value.mask && value.mask.toString().startsWith("url")){ - // console.log(`value mask: ${JSON.stringify(value.mask, null, 2)}`); var newValue = _getMatches('mask', value.mask); var newValue = "url(#" + _getMatches('fill', value.mask) + ")"; - // console.log(`new mask id: ${newValue}`); value.mask = newValue; this.update(value); - // console.log(`updated values: ${JSON.stringify(value, null, 2)}`); - hasID = true; } - // if (hasID) console.log(JSON.stringify(opts.prefix, null, 2)); }; }; From 72ab380fa6f7080d5fb386728b28e06d07141f0b Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 11:28:56 -0700 Subject: [PATCH 04/13] chore: remove logging line --- lib/sanitize/filters/unique-svg-ids.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/sanitize/filters/unique-svg-ids.js b/lib/sanitize/filters/unique-svg-ids.js index 1a7d2ed..7974840 100644 --- a/lib/sanitize/filters/unique-svg-ids.js +++ b/lib/sanitize/filters/unique-svg-ids.js @@ -1,6 +1,8 @@ var R = require('ramda'); var css = require('css'); +// This should be changed, because this isn't going to help +// anyone in the case of a failure to get filename for prefix. var DEFAULTS = { prefix: 'filename-prefix__', }; @@ -29,7 +31,6 @@ module.exports = function configureUniquePrefixId (opts) { // Find all IDs and update with filename prefix if (value.id){ - console.log(`value id: ${JSON.stringify(value.id, null, 2)}`); var newValue = opts.prefix + value.id; value.id = newValue; this.update(value); From 1cf6149d7193cae50821763bb60263bcd1491289 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 14:11:13 -0700 Subject: [PATCH 05/13] feat: add simple tests --- .../unit/sanitize/filters/unique-id-prefix.js | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 test/unit/sanitize/filters/unique-id-prefix.js diff --git a/test/unit/sanitize/filters/unique-id-prefix.js b/test/unit/sanitize/filters/unique-id-prefix.js new file mode 100644 index 0000000..090c2ff --- /dev/null +++ b/test/unit/sanitize/filters/unique-id-prefix.js @@ -0,0 +1,56 @@ +/*globals describe, it*/ +require('should'); + +describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { + const traverse = require('traverse'); + const prefixStyleClassnames = + require('../../../../lib/sanitize/filters/unique-svg-ids')({prefix: 'svgFilename__'}); + + it('should work on a simple tree', () => { + const tree = { + id: 'a', + fill: 'url(#a)', + mask: 'url(#a)', + xlinkHref: '#a' + }; + + var result = traverse.map(tree, prefixStyleClassnames); + + result. + should. + eql({ + id: 'svgFilename__a', + fill: 'url(#svgFilename__a)', + mask: 'url(#svgFilename__a)', + xlinkHref: '#svgFilename__a' + }); + }); + + it('should work on a more complex tree', () => { + const tree = { + id: 'a', + id: 'b', + fill: 'url(#a)', + mask: 'url(#a)', + xlinkHref: '#a', + fill: 'url(#b)', + mask: 'url(#b)', + xlinkHref: '#b' + }; + + const result = traverse.map(tree, prefixStyleClassnames); + + result. + should. + eql({ + id: 'svgFilename__a', + fill: 'url(#svgFilename__a)', + mask: 'url(#svgFilename__a)', + xlinkHref: '#svgFilename__a', + id: 'svgFilename__b', + fill: 'url(#svgFilename__b)', + mask: 'url(#svgFilename__b)', + xlinkHref: '#svgFilename__b' + }); + }); +}); From e07b61d98a7c87a3141d1c72ceb2dcb9c064f265 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 14:40:30 -0700 Subject: [PATCH 06/13] chore: minor clean up --- AUTHORS | 1 - .../unit/sanitize/filters/unique-id-prefix.js | 20 +++++++++++-------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/AUTHORS b/AUTHORS index 165d4dc..9b4e565 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,2 +1 @@ Jerry Hamlet (http://hamletink.com/) -William Brinkert diff --git a/test/unit/sanitize/filters/unique-id-prefix.js b/test/unit/sanitize/filters/unique-id-prefix.js index 090c2ff..fddcf1e 100644 --- a/test/unit/sanitize/filters/unique-id-prefix.js +++ b/test/unit/sanitize/filters/unique-id-prefix.js @@ -29,13 +29,15 @@ describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { it('should work on a more complex tree', () => { const tree = { id: 'a', - id: 'b', fill: 'url(#a)', mask: 'url(#a)', xlinkHref: '#a', - fill: 'url(#b)', - mask: 'url(#b)', - xlinkHref: '#b' + props: { + id: 'b', + fill: 'url(#b)', + mask: 'url(#b)', + xlinkHref: '#b' + } }; const result = traverse.map(tree, prefixStyleClassnames); @@ -47,10 +49,12 @@ describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { fill: 'url(#svgFilename__a)', mask: 'url(#svgFilename__a)', xlinkHref: '#svgFilename__a', - id: 'svgFilename__b', - fill: 'url(#svgFilename__b)', - mask: 'url(#svgFilename__b)', - xlinkHref: '#svgFilename__b' + props: { + id: 'svgFilename__b', + fill: 'url(#svgFilename__b)', + mask: 'url(#svgFilename__b)', + xlinkHref: '#svgFilename__b' + } }); }); }); From 2b74ac0e172e2d15d5ae7aa3d3fe1149c5e185da Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 21 Aug 2018 16:40:45 -0700 Subject: [PATCH 07/13] feat: add another test and update variable name in test file --- .../unit/sanitize/filters/unique-id-prefix.js | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/test/unit/sanitize/filters/unique-id-prefix.js b/test/unit/sanitize/filters/unique-id-prefix.js index fddcf1e..b371761 100644 --- a/test/unit/sanitize/filters/unique-id-prefix.js +++ b/test/unit/sanitize/filters/unique-id-prefix.js @@ -1,9 +1,9 @@ /*globals describe, it*/ require('should'); -describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { +describe('svg-react-loader/lib/sanitize/filters/unique-svg-ids', () => { const traverse = require('traverse'); - const prefixStyleClassnames = + const prefixFilename = require('../../../../lib/sanitize/filters/unique-svg-ids')({prefix: 'svgFilename__'}); it('should work on a simple tree', () => { @@ -14,7 +14,7 @@ describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { xlinkHref: '#a' }; - var result = traverse.map(tree, prefixStyleClassnames); + var result = traverse.map(tree, prefixFilename); result. should. @@ -40,7 +40,7 @@ describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { } }; - const result = traverse.map(tree, prefixStyleClassnames); + const result = traverse.map(tree, prefixFilename); result. should. @@ -57,4 +57,24 @@ describe('svg-react-loader/lib/sanitize/filters/prefix-style-class-id', () => { } }); }); + + it('should not update values for fill, mask, or xlink:href if they are not references to IDs', () => { + const tree = { + id: 'c', + fill: '#fafafa', + mask: '#ae4d19', + xlinkHref: 'http://www.w3.org/1999/xlink' + }; + + const result = traverse.map(tree, prefixFilename); + + result. + should. + eql({ + id: 'svgFilename__c', + fill: '#fafafa', + mask: '#ae4d19', + xlinkHref: 'http://www.w3.org/1999/xlink' + }); + }); }); From 6e59f5ee33503c88392608bb3b9931250201b415 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Wed, 22 Aug 2018 09:42:26 -0700 Subject: [PATCH 08/13] docs: update readme --- README.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3e37e72..43b9b31 100644 --- a/README.md +++ b/README.md @@ -19,10 +19,18 @@ modify the generated SVG Component. This allows `svg-react` to also be used as a pre-loader (with `filters` and `raw=true` params) for modifying SVGs before they are acted on by the loader version of `svg-react`. +This fork has an added filter which creates 'unique' IDs and mask, fill, and xlink:href +references to those IDs by prefixing the SVG filename. This solves a common problem +encountered when loading multiple SVGs onto the same page: if the IDs within the different +SVGs are the same, there will be ID collisions which will cause a variety of issues with +the rendering of the SVG components. Although there are plugins available for [SVGO](https://github.com/svg/svgo) +designed to solve this problem, the solution implemented here provides another way to +avoid ID collision issues on SVGs. Although this version is not yet available via NPM, +you may still include it in your project by placing `"svg-react-loader": "git+https://github.com/SilverFox70/svg-react-loader.git"` into your `package.json` file and running `npm install`. In order to get a clean install +you may find it necessary to first delete your `node_modules` folder *before* running npm install again. + ### Notes -> This fork has an added filter which creates 'unique' IDs and mask, fill, and xlink:href -> references to those IDs by prefixing the filename. > As of version 0.4.0, `svg-react-loader` no longer requires `babel` to > transpile the generated code. Everything is returned as an ES5-7 compatible > module, and the component is just a @@ -32,7 +40,10 @@ are acted on by the loader version of `svg-react`. Installation ------------ - +> Please note that this fork is NOT yet available on NPM and therefore +> running the command below will not get you this fork of the project. +> This instruction is being kept for legacy pruposes and will be removed +> or updated when and if this fork becomes available on NPM. ~~~ % npm install --save-dev svg-react-loader ~~~ From 61e55b68e8e3f6767b295506d3a26023c561fab7 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Wed, 22 Aug 2018 09:43:54 -0700 Subject: [PATCH 09/13] docs: update readme to fix typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 43b9b31..2b51b7c 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Installation ------------ > Please note that this fork is NOT yet available on NPM and therefore > running the command below will not get you this fork of the project. -> This instruction is being kept for legacy pruposes and will be removed +> This instruction is being kept for legacy purposes and will be removed > or updated when and if this fork becomes available on NPM. ~~~ % npm install --save-dev svg-react-loader From d1932415216698ecca9841df3957283c46cf9249 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Fri, 19 Oct 2018 10:42:02 -0700 Subject: [PATCH 10/13] docs: update readme and package.jsonfor merge --- README.md | 10 ++-------- package.json | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 2b51b7c..4fd2e59 100644 --- a/README.md +++ b/README.md @@ -19,15 +19,13 @@ modify the generated SVG Component. This allows `svg-react` to also be used as a pre-loader (with `filters` and `raw=true` params) for modifying SVGs before they are acted on by the loader version of `svg-react`. -This fork has an added filter which creates 'unique' IDs and mask, fill, and xlink:href +There is a filter which creates 'unique' IDs and mask, fill, and xlink:href references to those IDs by prefixing the SVG filename. This solves a common problem encountered when loading multiple SVGs onto the same page: if the IDs within the different SVGs are the same, there will be ID collisions which will cause a variety of issues with the rendering of the SVG components. Although there are plugins available for [SVGO](https://github.com/svg/svgo) designed to solve this problem, the solution implemented here provides another way to -avoid ID collision issues on SVGs. Although this version is not yet available via NPM, -you may still include it in your project by placing `"svg-react-loader": "git+https://github.com/SilverFox70/svg-react-loader.git"` into your `package.json` file and running `npm install`. In order to get a clean install -you may find it necessary to first delete your `node_modules` folder *before* running npm install again. +avoid ID collision issues on SVGs. ### Notes @@ -40,10 +38,6 @@ you may find it necessary to first delete your `node_modules` folder *before* ru Installation ------------ -> Please note that this fork is NOT yet available on NPM and therefore -> running the command below will not get you this fork of the project. -> This instruction is being kept for legacy purposes and will be removed -> or updated when and if this fork becomes available on NPM. ~~~ % npm install --save-dev svg-react-loader ~~~ diff --git a/package.json b/package.json index 9a2e94e..4322d31 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/SilverFox70/svg-react-loader" + "url": "git+https://github.com/jhamlet/svg-react-loader.git" }, "keywords": [ "webpack", From b863896f50856c32a90fd896e3c9e1df3852713a Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 23 Oct 2018 15:19:34 -0700 Subject: [PATCH 11/13] update: include simple integration test to assert unique id prefix works --- test/integration/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/test.js b/test/integration/test.js index 0cdf9c8..5f40ea5 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -4,7 +4,7 @@ import React, { Component } from 'react'; import { mount } from 'enzyme'; import SimpleSvg from '../../lib/loader.js?name=SimpleSvg!../samples/simple.svg'; -import StylesSvg from '../../lib/loader.js?classIdPrefix!../samples/styles.svg'; +import StylesSvg from '../../lib/loader.js?classIdPrefix&uniqueIdPrefix=true!../samples/styles.svg'; import TextSvg from '../../lib/loader.js!../samples/text.svg'; import ObjectSvg from '../../lib/loader.js!../samples/object.json'; @@ -61,7 +61,7 @@ describe('svg-react-loader', () => { const expectedProps = { version: "1.1", - id: "Layer_1", + id: "Styles__Layer_1", width: "50px", height: "50px", x: "0px", From 8c1fc941eef97fab78ec288f794153fbcf161a01 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Tue, 23 Oct 2018 16:45:33 -0700 Subject: [PATCH 12/13] feat: handle clipPath, use, and other case of href with SVGs; added integration test for above --- lib/sanitize/filters/unique-svg-ids.js | 14 +++++++++ test/integration/test.js | 39 ++++++++++++++++++++++++++ test/samples/clippath.svg | 19 +++++++++++++ test/samples/use.svg | 6 ++++ 4 files changed, 78 insertions(+) create mode 100644 test/samples/clippath.svg create mode 100644 test/samples/use.svg diff --git a/lib/sanitize/filters/unique-svg-ids.js b/lib/sanitize/filters/unique-svg-ids.js index 7974840..964eb53 100644 --- a/lib/sanitize/filters/unique-svg-ids.js +++ b/lib/sanitize/filters/unique-svg-ids.js @@ -29,6 +29,13 @@ module.exports = function configureUniquePrefixId (opts) { this.update(value); } + // Find all href props and update + if (value.href && value.href.toString().startsWith("#")){ + var newValue = "#" + opts.prefix + value.href.toString().replace("#", ""); + value.href = newValue; + this.update(value); + } + // Find all IDs and update with filename prefix if (value.id){ var newValue = opts.prefix + value.id; @@ -50,5 +57,12 @@ module.exports = function configureUniquePrefixId (opts) { value.mask = newValue; this.update(value); } + + // Find all clipPath props and update with filename prefix + if (value.clipPath && value.clipPath.toString().startsWith("url")){ + var newValue = "url(#" + _getMatches('clipPath', value.clipPath) + ")"; + value.clipPath = newValue; + this.update(value); + } }; }; diff --git a/test/integration/test.js b/test/integration/test.js index 5f40ea5..24f1598 100644 --- a/test/integration/test.js +++ b/test/integration/test.js @@ -7,6 +7,8 @@ import SimpleSvg from '../../lib/loader.js?name=SimpleSvg!../samples/simple.svg' import StylesSvg from '../../lib/loader.js?classIdPrefix&uniqueIdPrefix=true!../samples/styles.svg'; import TextSvg from '../../lib/loader.js!../samples/text.svg'; import ObjectSvg from '../../lib/loader.js!../samples/object.json'; +import ClipPathSvg from '../../lib/loader.js?uniqueIdPrefix=true!../samples/clippath.svg'; +import UseSvg from "../../lib/loader.js?uniqueIdPrefix=true!../samples/use.svg"; require('should'); @@ -142,4 +144,41 @@ describe('svg-react-loader', () => { be. true; }); + + it('clippath.svg', () => { + const wrapper = mount(); + + const expectedClipPathProps = { + id: "Clippath__myClip" + } + + const expectedUseProps = { + clipPath: "url(#Clippath__myClip)", + xlinkHref: "#Clippath__heart", + fill: "red" + } + + getPropsMinusChildren(wrapper.find('clipPath')). + should. + eql(expectedClipPathProps); + + getPropsMinusChildren(wrapper.find('use')). + should. + eql(expectedUseProps); + }); + + it('use.svg', () => { + const wrapper = mount(); + + const expectedProps = { + href: "#Use__myCircle", + x: "20", + fill: "white", + stroke: "blue" + } + + getPropsMinusChildren(wrapper.find('use')). + should. + eql(expectedProps); + }); }); diff --git a/test/samples/clippath.svg b/test/samples/clippath.svg new file mode 100644 index 0000000..eb5999e --- /dev/null +++ b/test/samples/clippath.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/samples/use.svg b/test/samples/use.svg new file mode 100644 index 0000000..a41e800 --- /dev/null +++ b/test/samples/use.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From f7e91c6ff78a63e4ff764ff0194dbe2b5c125077 Mon Sep 17 00:00:00 2001 From: Bill Brinkert Date: Mon, 4 Feb 2019 10:59:47 -0800 Subject: [PATCH 13/13] feat: make uniqueIdPrefix default to true --- lib/options.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/options.js b/lib/options.js index 0b5784d..9623eac 100644 --- a/lib/options.js +++ b/lib/options.js @@ -8,6 +8,7 @@ var DEFAULTS = { 'for': 'htmlFor' }, classIdPrefix: false, + uniqueIdPrefix: true, raw: false, xmlnsTest: /^xmlns(Xlink)?$/ };