From 162b80183992ffcd5fcf42b00ae638c9afaf1f8e Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 19 Apr 2018 19:00:46 +0300 Subject: [PATCH 1/2] Move part sorting to merge --- .../libs/handlebars/ircmessageparser/merge.js | 18 ++++++++++++++++-- client/js/libs/handlebars/parse.js | 14 +------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/client/js/libs/handlebars/ircmessageparser/merge.js b/client/js/libs/handlebars/ircmessageparser/merge.js index fd1a6877..3051be1d 100644 --- a/client/js/libs/handlebars/ircmessageparser/merge.js +++ b/client/js/libs/handlebars/ircmessageparser/merge.js @@ -13,7 +13,11 @@ function assign(textPart, fragment) { 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. // 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 @@ -28,8 +32,18 @@ function merge(textParts, styleFragments) { // is filled with "text" parts, dummy objects with start/end but no extra // metadata. const allParts = textParts + .sort(sortParts) // Sort all parts identified based on their position in the original text .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 return allParts.map((textPart) => { diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js index bd825047..27bd76cf 100644 --- a/client/js/libs/handlebars/parse.js +++ b/client/js/libs/handlebars/parse.js @@ -2,7 +2,6 @@ const Handlebars = require("handlebars/runtime"); const parseStyle = require("./ircmessageparser/parseStyle"); -const anyIntersection = require("./ircmessageparser/anyIntersection"); const findChannels = require("./ircmessageparser/findChannels"); const findLinks = require("./ircmessageparser/findLinks"); const findEmoji = require("./ircmessageparser/findEmoji"); @@ -85,21 +84,10 @@ module.exports = function parse(text, users) { const emojiParts = findEmoji(cleanText); const nameParts = findNames(cleanText, (users || [])); - // Sort all parts identified based on their position in the original text const parts = channelParts .concat(linkParts) .concat(emojiParts) - .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]); - }, []); + .concat(nameParts); // Merge the styling information with the channels / URLs / nicks / text objects and // generate HTML strings with the resulting fragments From d19c00faab32e9479f9c4f205ec8bbb99cd65454 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Thu, 19 Apr 2018 19:01:20 +0300 Subject: [PATCH 2/2] Build clean text message only once --- client/js/libs/handlebars/ircmessageparser/merge.js | 5 +---- client/js/libs/handlebars/parse.js | 2 +- test/client/js/libs/handlebars/ircmessageparser/merge.js | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/client/js/libs/handlebars/ircmessageparser/merge.js b/client/js/libs/handlebars/ircmessageparser/merge.js index 3051be1d..890df86c 100644 --- a/client/js/libs/handlebars/ircmessageparser/merge.js +++ b/client/js/libs/handlebars/ircmessageparser/merge.js @@ -24,10 +24,7 @@ function sortParts(a, b) { // 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" // fragments will contain duplicate styling attributes. -function merge(textParts, styleFragments) { - // Re-build the overall text (without control codes) from the style fragments - const cleanText = styleFragments.reduce((acc, frag) => acc + frag.text, ""); - +function merge(textParts, styleFragments, cleanText) { // 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 // metadata. diff --git a/client/js/libs/handlebars/parse.js b/client/js/libs/handlebars/parse.js index 27bd76cf..0a08769a 100644 --- a/client/js/libs/handlebars/parse.js +++ b/client/js/libs/handlebars/parse.js @@ -91,7 +91,7 @@ module.exports = function parse(text, users) { // Merge the styling information with the channels / URLs / nicks / text objects and // 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 const fragments = textPart.fragments.map(createFragment).join(""); diff --git a/test/client/js/libs/handlebars/ircmessageparser/merge.js b/test/client/js/libs/handlebars/ircmessageparser/merge.js index bcf79ca5..4125b6cc 100644 --- a/test/client/js/libs/handlebars/ircmessageparser/merge.js +++ b/test/client/js/libs/handlebars/ircmessageparser/merge.js @@ -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); });