Skip to content

Commit

Permalink
fix: Remove extra type when highlighting the query in the text (#1863)
Browse files Browse the repository at this point in the history
* fix: Remove extra type when highlighting the query in the text

closes #1758

This PR improves text replacement with highlighting and fixes multiple word replacement

* refactor funcions

* refactor order
  • Loading branch information
leiyre committed Nov 14, 2022
1 parent 011fdf2 commit 341c581
Showing 1 changed file with 39 additions and 51 deletions.
90 changes: 39 additions & 51 deletions frontend/plugins/highlight-search.js
Expand Up @@ -16,72 +16,60 @@
*/

export default (context, inject) => {
const htmlText = function (text) {
return text
.toString()
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
const highlightKeywords = function (text, keywords) {
const sortedKeywords = sortByLength([...keywords]);
const pattern = sortedKeywords.map((keyword) => createPattern(keyword));
const regExp = createRegExp(pattern.join("|"));
return replaceText(regExp, text);
};

function htmlHighlightText(text) {
return `<span class="highlight-text">${htmlText(text)}</span>`;
const keywordsSpans = function (text, keywords) {
return (keywords || []).flatMap((keyword) => {
const regex = createRegExp(createPattern(keyword));
return [...text.matchAll(regex)].map((match) => {
return {
start: match.index,
end: match.index + match[0].length,
};
});
});
};

function sortByLength(keywords) {
return (keywords || []).sort((a, b) => b.length - a.length);
}

const regexFromTerm = function (term) {
let q = term.replace(/[-[\]{}()*+?.,\\/^$|#\s]/g, "");
return new RegExp(q, "gi");
};
function createPattern(value) {
return `([^a-zA-ZÀ-ÿ\u00f1\u00d1]|^)${escapeRegExp(value)}`;
}

const escapeRegExp = function (text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};

const highlightSearch = function (query, text) {
const escapedText = htmlText(text);
if (!query) {
return text;
}

return escapedText.replace(
regexFromTerm(query),
(match) => `<span class="highlight-text">${match}</span>`
);
};
function createRegExp(pattern) {
return new RegExp(pattern, "gmi");
}

const highlightKeywords = function (text, keywords) {
const sortedKeywords = ([...keywords] || []).sort(
(a, b) => b.length - a.length
function replaceText(regex, text) {
return htmlText(text).replace(regex, (matched) =>
htmlHighlightText(matched)
);
text = htmlText(text);
sortedKeywords.forEach((keyword) => {
const regex = new RegExp(
`([^a-zA-ZÀ-ÿ\u00f1\u00d1]|^)${escapeRegExp(keyword)}`,
"gmi"
);
text = text.replace(regex, (match) => htmlHighlightText(match));
});
}

return text;
};
function htmlHighlightText(text) {
return `<span class="highlight-text">${htmlText(text)}</span>`;
}

const keywordsSpans = function (text, keywords) {
return (keywords || []).flatMap((keyword) => {
const regex = new RegExp(
`([^a-zA-ZÀ-ÿ\u00f1\u00d1]|^)${escapeRegExp(keyword)}`,
"gmi"
);
return [...text.matchAll(regex)].map((match) => {
return {
start: match.index,
end: match.index + match[0].length,
};
});
});
const htmlText = function (text) {
return text
.toString()
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
};

inject("highlightSearch", highlightSearch);
inject("highlightKeywords", highlightKeywords);
inject("keywordsSpans", keywordsSpans);
inject("htmlText", htmlText);
Expand Down

0 comments on commit 341c581

Please sign in to comment.