From 172065c9eb9b936ec7833610b53afe92e6a7a98e Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 15 Jun 2021 14:43:44 +0300 Subject: [PATCH] fixed bug with hashtags --- src/components/rich_content/rich_content.jsx | 33 ++++++++++------- .../specs/components/rich_content.spec.js | 36 +++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index 4144d895..c8e1af9c 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -85,7 +85,6 @@ export default Vue.component('RichContent', { attrs.target = '_blank' if (!encounteredTextReverse) { lastTags.push(linkData) - attrs['data-parser-last'] = true } return { children.map(processItem) } @@ -128,7 +127,7 @@ export default Vue.component('RichContent', { encounteredText = true } if (item.includes(':')) { - unescapedItem = processTextForEmoji( + unescapedItem = ['', processTextForEmoji( unescapedItem, this.emoji, ({ shortcode, url }) => { @@ -139,14 +138,14 @@ export default Vue.component('RichContent', { alt={`:${shortcode}:`} /> } - ) + )] } return unescapedItem } // Handle tag nodes if (Array.isArray(item)) { - const [opener, children] = item + const [opener, children, closer] = item const Tag = getTagName(opener) const attrs = getAttrs(opener) switch (Tag) { @@ -176,14 +175,10 @@ export default Vue.component('RichContent', { } } - - // Render tag as is if (children !== undefined) { - return - { children.map(processItem) } - + return [opener, children.map(processItem), closer] } else { - return + return item } } } @@ -200,7 +195,7 @@ export default Vue.component('RichContent', { } else if (Array.isArray(item)) { // Handle tag nodes const [opener, children] = item - const Tag = getTagName(opener) + const Tag = opener === '' ? '' : getTagName(opener) switch (Tag) { case 'a': // replace mentions with MentionLink if (!this.handleLinks) break @@ -209,16 +204,30 @@ export default Vue.component('RichContent', { if (attrs['class'] && attrs['class'].includes('hashtag')) { return renderHashtag(attrs, children, encounteredTextReverse) } + break + case '': + return [...children].reverse().map(processItemReverse).reverse() + } + + // Render tag as is + if (children !== undefined) { + return + { Array.isArray(children) ? [...children].reverse().map(processItemReverse).reverse() : children } + + } else { + return } } return item } + const pass1 = convertHtmlToTree(html).map(processItem) + const pass2 = [...pass1].reverse().map(processItemReverse).reverse() // DO NOT USE SLOTS they cause a re-render feedback loop here. // slots updated -> rerender -> emit -> update up the tree -> rerender -> ... // at least until vue3? const result = - { convertHtmlToTree(html).map(processItem).reverse().map(processItemReverse).reverse() } + { pass2 } const event = { diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js index e364a5b3..82f1ae89 100644 --- a/test/unit/specs/components/rich_content.spec.js +++ b/test/unit/specs/components/rich_content.spec.js @@ -603,4 +603,40 @@ describe('RichContent', () => { expect(wrapper.html()).to.eql(compwrap(expected)) }) + + it('buggy example/hashtags', () => { + const html = [ + '

', + '', + 'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg', + ' ', + '#nou', + ' ', + '#screencap', + '

' + ].join('') + const expected = [ + '

', + '', + 'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg', + ' ', + '#nou', + ' ', + '#screencap', + '

' + ].join('') + + const wrapper = shallowMount(RichContent, { + localVue, + propsData: { + hideMentions: true, + handleLinks: true, + greentext: true, + emoji: [], + html + } + }) + + expect(wrapper.html()).to.eql(compwrap(expected)) + }) })