diff options
Diffstat (limited to 'app/assets/javascripts/lib/utils/highlight.js')
-rw-r--r-- | app/assets/javascripts/lib/utils/highlight.js | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/highlight.js b/app/assets/javascripts/lib/utils/highlight.js new file mode 100644 index 00000000000..4f7eff2cca1 --- /dev/null +++ b/app/assets/javascripts/lib/utils/highlight.js @@ -0,0 +1,44 @@ +import fuzzaldrinPlus from 'fuzzaldrin-plus'; +import _ from 'underscore'; +import sanitize from 'sanitize-html'; + +/** + * Wraps substring matches with HTML `<span>` elements. + * Inputs are sanitized before highlighting, so this + * filter is safe to use with `v-html` (as long as `matchPrefix` + * and `matchSuffix` are not being dynamically generated). + * + * Note that this function can't be used inside `v-html` as a filter + * (Vue filters cannot be used inside `v-html`). + * + * @param {String} string The string to highlight + * @param {String} match The substring match to highlight in the string + * @param {String} matchPrefix The string to insert at the beginning of a match + * @param {String} matchSuffix The string to insert at the end of a match + */ +export default function highlight(string, match = '', matchPrefix = '<b>', matchSuffix = '</b>') { + if (_.isUndefined(string) || _.isNull(string)) { + return ''; + } + + if (_.isUndefined(match) || _.isNull(match) || match === '') { + return string; + } + + const sanitizedValue = sanitize(string.toString(), { allowedTags: [] }); + + // occurences is an array of character indices that should be + // highlighted in the original string, i.e. [3, 4, 5, 7] + const occurences = fuzzaldrinPlus.match(sanitizedValue, match.toString()); + + return sanitizedValue + .split('') + .map((character, i) => { + if (_.contains(occurences, i)) { + return `${matchPrefix}${character}${matchSuffix}`; + } + + return character; + }) + .join(''); +} |