From 1809c4b436abd921a532ce45596adebc7c73fc84 Mon Sep 17 00:00:00 2001 From: Tom Najdek Date: Thu, 24 Aug 2017 19:40:17 +0100 Subject: [PATCH] Better approach to handling pseudo-html tags in rendered titles #51 --- package-lock.json | 3 +-- package.json | 1 + src/js/utils.js | 35 +++++++++++++++++++++++++---------- test/utils.spec.js | 11 +++++++++++ 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index a8f398b..19684c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -905,8 +905,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-arraybuffer": { "version": "0.1.5", diff --git a/package.json b/package.json index 157be8b..94822fa 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ ], "dependencies": { "babel-regenerator-runtime": "^6.5.0", + "balanced-match": "^1.0.0", "clipboard": "^1.5.10", "core-js": "^2.4.0", "es6-symbol": "^3.0.2", diff --git a/src/js/utils.js b/src/js/utils.js index b05b53a..ba913d0 100644 --- a/src/js/utils.js +++ b/src/js/utils.js @@ -1,4 +1,5 @@ import _ from 'lodash'; +import balanced from 'balanced-match'; var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']; @@ -236,20 +237,34 @@ export function sanitizeURL(url) { } } -const formatMapping = [ - [new RegExp(/<b>([\s\S]*)<\/b>/), '$1'], - [new RegExp(/<i>([\s\S]*)<\/i>/), '$1'], - [new RegExp(/<sc>([\s\S]*)<\/sc>/), '$1'], - [new RegExp(/<sub>([\s\S]*)<\/sub>/), '$1'], - [new RegExp(/<sup>([\s\S]*)<\/sup>/), '$1'] +const mappings = [ + [['<b>', '<\/b>'], ['', '']], + [['<i>', '<\/i>'], ['', '']], + [['<sc>', '<\/sc>'], ['', '']], + [['<sub>', '<\/sub>'], ['', '']], + [['<sup>', '<\/sup>'], ['', '']] ]; +function recursiveBalancedMatch(mapping, value) { + let matches = balanced(...mapping[0], value); + if(matches) { + return [ + recursiveBalancedMatch(mapping, matches.pre), + mapping[1][0], + recursiveBalancedMatch(mapping, matches.body), + mapping[1][1], + recursiveBalancedMatch(mapping, matches.post) + ].join(''); + } else { + return value; + } +} + export function escapeFormattedValue(value) { let escaped = _.escape(value); - formatMapping.forEach(replacePair => { - escaped = escaped.replace(...replacePair); - }); + return mappings.reduce((value, mapping) => { + return recursiveBalancedMatch(mapping, value); + }, escaped); - return escaped; } diff --git a/test/utils.spec.js b/test/utils.spec.js index 4a251c1..e363631 100644 --- a/test/utils.spec.js +++ b/test/utils.spec.js @@ -36,5 +36,16 @@ describe('utils', function() { it('should render supported tags while escaping other', () => { expect(escapeFormattedValue('Lorem dolot')).toEqual('Lorem <script>ipsum</script> dolot'); }); + + it('should render nested tags', () => { + expect(escapeFormattedValue('Lorem some ipsum dolot')).toEqual('Lorem some ipsum dolot'); + expect(escapeFormattedValue('Lorem some ipsum dolot')).toEqual('Lorem some ipsum dolot'); + expect(escapeFormattedValue('some and ipsum and dolot')).toEqual('some and ipsum and dolot'); + }); + + it('should render multiple tags', () => { + expect(escapeFormattedValue('Lorem some and ipsum and dolot')).toEqual('Lorem some and ipsum and dolot'); + expect(escapeFormattedValue('Lorem some and ipsum and dolot')).toEqual('Lorem some and ipsum and dolot'); + }); }); });