Skip to content

Commit

Permalink
Better approach to handling pseudo-html tags in rendered titles #51
Browse files Browse the repository at this point in the history
  • Loading branch information
tnajdek committed Aug 24, 2017
1 parent 32f9928 commit 1809c4b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 12 deletions.
3 changes: 1 addition & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -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",
Expand Down
35 changes: 25 additions & 10 deletions 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'];


Expand Down Expand Up @@ -236,20 +237,34 @@ export function sanitizeURL(url) {
}
}

const formatMapping = [
[new RegExp(/&lt;b&gt;([\s\S]*)&lt;\/b&gt;/), '<b>$1</b>'],
[new RegExp(/&lt;i&gt;([\s\S]*)&lt;\/i&gt;/), '<i>$1</i>'],
[new RegExp(/&lt;sc&gt;([\s\S]*)&lt;\/sc&gt;/), '<span class="small-caps">$1</span>'],
[new RegExp(/&lt;sub&gt;([\s\S]*)&lt;\/sub&gt;/), '<sub>$1</sub>'],
[new RegExp(/&lt;sup&gt;([\s\S]*)&lt;\/sup&gt;/), '<sup>$1</sup>']
const mappings = [
[['&lt;b&gt;', '&lt;\/b&gt;'], ['<b>', '</b>']],
[['&lt;i&gt;', '&lt;\/i&gt;'], ['<i>', '</i>']],
[['&lt;sc&gt;', '&lt;\/sc&gt;'], ['<span class="small-caps">', '</span>']],
[['&lt;sub&gt;', '&lt;\/sub&gt;'], ['<sub>', '</sub>']],
[['&lt;sup&gt;', '&lt;\/sup&gt;'], ['<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;
}
11 changes: 11 additions & 0 deletions test/utils.spec.js
Expand Up @@ -36,5 +36,16 @@ describe('utils', function() {
it('should render supported tags while escaping other', () => {
expect(escapeFormattedValue('Lorem <script><i>ipsum</i></script> dolot')).toEqual('Lorem &lt;script&gt;<i>ipsum</i>&lt;/script&gt; dolot');
});

it('should render nested tags', () => {
expect(escapeFormattedValue('Lorem <sc>some <i>ipsum</i></sc> dolot')).toEqual('Lorem <span class="small-caps">some <i>ipsum</i></span> dolot');
expect(escapeFormattedValue('Lorem <i>some<i> ipsum</i></i> dolot')).toEqual('Lorem <i>some<i> ipsum</i></i> dolot');
expect(escapeFormattedValue('<i>some and <b>ip<i>s</i>um</b> and <sup>dolot</sup></i>')).toEqual('<i>some and <b>ip<i>s</i>um</b> and <sup>dolot</sup></i>');
});

it('should render multiple tags', () => {
expect(escapeFormattedValue('Lorem <i>some</i> and <b>ipsum</b> and <sup>dolot</sup>')).toEqual('Lorem <i>some</i> and <b>ipsum</b> and <sup>dolot</sup>');
expect(escapeFormattedValue('Lorem <i>some</i> and <i>ipsum</i> and <i>dolot</i>')).toEqual('Lorem <i>some</i> and <i>ipsum</i> and <i>dolot</i>');
});
});
});

0 comments on commit 1809c4b

Please sign in to comment.