Merge pull request #2408 from thelounge/xpaw/parser-merger
Minor optimization in style parser
This commit is contained in:
commit
9558a1af58
@ -13,23 +13,34 @@ function assign(textPart, fragment) {
|
|||||||
return Object.assign({}, fragment, {start, end, text});
|
return Object.assign({}, fragment, {start, end, text});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Merge the style fragments withing the text parts, taking into account
|
function sortParts(a, b) {
|
||||||
|
return a.start - b.start || b.end - a.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Merge the style fragments within the text parts, taking into account
|
||||||
// boundaries and text sections that have not matched to links or channels.
|
// boundaries and text sections that have not matched to links or channels.
|
||||||
// For example, given a string "foobar" where "foo" and "bar" have been
|
// For example, given a string "foobar" where "foo" and "bar" have been
|
||||||
// identified as parts (channels, links, etc.) and "fo", "ob" and "ar" have 3
|
// identified as parts (channels, links, etc.) and "fo", "ob" and "ar" have 3
|
||||||
// different styles, the first resulting part will contain fragments "fo" and
|
// different styles, the first resulting part will contain fragments "fo" and
|
||||||
// "o", and the second resulting part will contain "b" and "ar". "o" and "b"
|
// "o", and the second resulting part will contain "b" and "ar". "o" and "b"
|
||||||
// fragments will contain duplicate styling attributes.
|
// fragments will contain duplicate styling attributes.
|
||||||
function merge(textParts, styleFragments) {
|
function merge(textParts, styleFragments, cleanText) {
|
||||||
// Re-build the overall text (without control codes) from the style fragments
|
|
||||||
const cleanText = styleFragments.reduce((acc, frag) => acc + frag.text, "");
|
|
||||||
|
|
||||||
// Every section of the original text that has not been captured in a "part"
|
// Every section of the original text that has not been captured in a "part"
|
||||||
// is filled with "text" parts, dummy objects with start/end but no extra
|
// is filled with "text" parts, dummy objects with start/end but no extra
|
||||||
// metadata.
|
// metadata.
|
||||||
const allParts = textParts
|
const allParts = textParts
|
||||||
|
.sort(sortParts) // Sort all parts identified based on their position in the original text
|
||||||
.concat(fill(textParts, cleanText))
|
.concat(fill(textParts, cleanText))
|
||||||
.sort((a, b) => a.start - b.start);
|
.sort(sortParts) // Sort them again after filling in unstyled text
|
||||||
|
.reduce((prev, curr) => {
|
||||||
|
const intersection = prev.some((p) => anyIntersection(p, curr));
|
||||||
|
|
||||||
|
if (intersection) {
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return prev.concat([curr]);
|
||||||
|
}, []);
|
||||||
|
|
||||||
// Distribute the style fragments within the text parts
|
// Distribute the style fragments within the text parts
|
||||||
return allParts.map((textPart) => {
|
return allParts.map((textPart) => {
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
const Handlebars = require("handlebars/runtime");
|
const Handlebars = require("handlebars/runtime");
|
||||||
const parseStyle = require("./ircmessageparser/parseStyle");
|
const parseStyle = require("./ircmessageparser/parseStyle");
|
||||||
const anyIntersection = require("./ircmessageparser/anyIntersection");
|
|
||||||
const findChannels = require("./ircmessageparser/findChannels");
|
const findChannels = require("./ircmessageparser/findChannels");
|
||||||
const findLinks = require("./ircmessageparser/findLinks");
|
const findLinks = require("./ircmessageparser/findLinks");
|
||||||
const findEmoji = require("./ircmessageparser/findEmoji");
|
const findEmoji = require("./ircmessageparser/findEmoji");
|
||||||
@ -85,25 +84,14 @@ module.exports = function parse(text, users) {
|
|||||||
const emojiParts = findEmoji(cleanText);
|
const emojiParts = findEmoji(cleanText);
|
||||||
const nameParts = findNames(cleanText, (users || []));
|
const nameParts = findNames(cleanText, (users || []));
|
||||||
|
|
||||||
// Sort all parts identified based on their position in the original text
|
|
||||||
const parts = channelParts
|
const parts = channelParts
|
||||||
.concat(linkParts)
|
.concat(linkParts)
|
||||||
.concat(emojiParts)
|
.concat(emojiParts)
|
||||||
.concat(nameParts)
|
.concat(nameParts);
|
||||||
.sort((a, b) => a.start - b.start || b.end - a.end)
|
|
||||||
.reduce((prev, curr) => {
|
|
||||||
const intersection = prev.some((p) => anyIntersection(p, curr));
|
|
||||||
|
|
||||||
if (intersection) {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
return prev.concat([curr]);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Merge the styling information with the channels / URLs / nicks / text objects and
|
// Merge the styling information with the channels / URLs / nicks / text objects and
|
||||||
// generate HTML strings with the resulting fragments
|
// generate HTML strings with the resulting fragments
|
||||||
return merge(parts, styleFragments).map((textPart) => {
|
return merge(parts, styleFragments, cleanText).map((textPart) => {
|
||||||
// Create HTML strings with styling information
|
// Create HTML strings with styling information
|
||||||
const fragments = textPart.fragments.map(createFragment).join("");
|
const fragments = textPart.fragments.map(createFragment).join("");
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ describe("merge", () => {
|
|||||||
}],
|
}],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const actual = merge(textParts, styleFragments);
|
const actual = merge(textParts, styleFragments, styleFragments.map((fragment) => fragment.text).join(""));
|
||||||
|
|
||||||
expect(actual).to.deep.equal(expected);
|
expect(actual).to.deep.equal(expected);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user