From 102184d7af3471dde57ef7e2a8d33f02cbd1a94f Mon Sep 17 00:00:00 2001 From: Quoc Huy Nguyen Dinh Date: Wed, 7 May 2025 12:00:07 +1000 Subject: [PATCH] Fix issue rendering user mentions --- src/shared/HtmlReady.js | 25 ++++++++++++++++--------- src/shared/HtmlReady.test.js | 6 +++--- yarn.lock | 13 ++++--------- 3 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/shared/HtmlReady.js b/src/shared/HtmlReady.js index 5cde39a33..60be36be5 100644 --- a/src/shared/HtmlReady.js +++ b/src/shared/HtmlReady.js @@ -285,23 +285,30 @@ function proxifyImages(doc, state) { function linkifyNode(child, state) { try { const tag = child.parentNode.tagName ? child.parentNode.tagName.toLowerCase() : child.parentNode.tagName; - if (tag === 'code') return; - if (tag === 'a') return; + if (tag === 'code' || tag === 'a') return undefined; const { mutate } = state; - if (!child.data) return; + if (!child.data) return undefined; child = EmbeddedPlayerEmbedNode(child, state.links, state.images); const data = XMLSerializer.serializeToString(child); - const content = linkify(data, state.mutate, state.hashtags, state.usertags, state.images, state.links); + const content = linkify(data, mutate, state.hashtags, state.usertags, state.images, state.links); + if (mutate && content !== data) { - const newChild = DOMParser.parseFromString(`${content}`); + const doc = DOMParser.parseFromString(`${content}`, 'text/html'); + const wrapper = doc.documentElement; // This is the + + const fragment = child.ownerDocument.createDocumentFragment(); + for (let i = 0; i < wrapper.childNodes.length; i += 1) { + fragment.appendChild(wrapper.childNodes[i].cloneNode(true)); + } + const parentNode = child.parentNode; - parentNode.appendChild(newChild); + parentNode.insertBefore(fragment, child); parentNode.removeChild(child); - // eslint-disable-next-line consistent-return - return newChild; + + return fragment; } } catch (error) { console.error('linkify_error', error); @@ -332,7 +339,7 @@ function linkify(content, mutate, hashtags, usertags, images, links) { const preceedings = (preceeding1 || '') + (preceeding2 || ''); // include the preceeding matches if they exist - if (!mutate) return `${preceedings}${user}`; + if (!mutate) return match; return valid ? `${preceedings}@${user}` : `${preceedings}@${user}`; } diff --git a/src/shared/HtmlReady.test.js b/src/shared/HtmlReady.test.js index 31176b25a..d67065267 100644 --- a/src/shared/HtmlReady.test.js +++ b/src/shared/HtmlReady.test.js @@ -73,14 +73,14 @@ describe('htmlready', () => { it('should allow more than one link per post', () => { const somanylinks = 'https://foo.com and https://blah.com'; - const htmlified = 'https://foo.com and https://blah.com'; + const htmlified = 'https://foo.com and https://blah.com'; const res = HtmlReady(somanylinks).html; expect(res).toEqual(htmlified); }); it('should link usernames', () => { const textwithmentions = '@username (@a1b2, whatever'; - const htmlified = '@username (@a1b2, whatever'; + const htmlified = '@username (@a1b2, whatever'; const res = HtmlReady(textwithmentions).html; expect(res).toEqual(htmlified); }); @@ -133,7 +133,7 @@ describe('htmlready', () => { const prefix = ''; const suffix = ''; const input = prefix + url + suffix; - const expected = prefix + '' + url + '' + suffix; + const expected = prefix + '' + url + '' + suffix; const result = HtmlReady(input).html; expect(result).toEqual(expected); }); diff --git a/yarn.lock b/yarn.lock index 2d77c771c..7296904a4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3752,15 +3752,10 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001449: - version "1.0.30001617" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001617.tgz" - integrity sha512-mLyjzNI9I+Pix8zwcrpxEbGlfqOkF9kM3ptzmKNw5tizSyYwMe+nGLTqMK9cO+0E+Bh6TsBxNAaHWEM8xwSsmA== - -caniuse-lite@^1.0.30001587: - version "1.0.30001668" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz#98e214455329f54bf7a4d70b49c9794f0fbedbed" - integrity sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw== +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001449, caniuse-lite@^1.0.30001587: + version "1.0.30001717" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001717.tgz" + integrity sha512-auPpttCq6BDEG8ZAuHJIplGw6GODhjw+/11e7IjpnYCxZcW/ONgPs0KVBJ0d1bY3e2+7PRe5RCLyP+PfwVgkYw== caseless@~0.11.0: version "0.11.0" -- GitLab