From e98a2af39e01e42a6dc24aa148eb67e98cb1dbef Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Wed, 18 Aug 2021 20:54:04 +0300
Subject: hopefully final fix for spacings

---
 src/components/rich_content/rich_content.jsx | 37 +++++++++++++++++-----------
 1 file changed, 23 insertions(+), 14 deletions(-)

(limited to 'src/components/rich_content/rich_content.jsx')

diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
index 8ab007e3..d98947df 100644
--- a/src/components/rich_content/rich_content.jsx
+++ b/src/components/rich_content/rich_content.jsx
@@ -61,6 +61,8 @@ export default Vue.component('RichContent', {
     // Pre-process HTML
     const { newHtml: html } = preProcessPerLine(this.html, this.greentext)
     let currentMentions = null // Current chain of mentions, we group all mentions together
+    // This is used to recover spacing removed when parsing mentions
+    let lastSpacing = ''
 
     const lastTags = [] // Tags that appear at the end of post body
     const writtenMentions = [] // All mentions that appear in post body
@@ -119,14 +121,9 @@ export default Vue.component('RichContent', {
         if (emptyText) {
           // don't include spaces when processing mentions - we'll include them
           // in MentionsLine
+          lastSpacing = item
           return currentMentions !== null ? item.trim() : item
         }
-        // We add space with mentionsLine, otherwise non-text elements will
-        // stick to them.
-        if (currentMentions !== null) {
-          // single whitespace trim
-          item = item[0].match(/\s/) ? item.slice(1) : item
-        }
 
         currentMentions = null
         if (item.includes(':')) {
@@ -151,21 +148,32 @@ export default Vue.component('RichContent', {
         const [opener, children, closer] = item
         const Tag = getTagName(opener)
         const attrs = getAttrs(opener)
+        const previouslyMentions = currentMentions !== null
+        /* During grouping of mentions we trim all the empty text elements
+         * This padding is added to recover last space removed in case
+         * we have a tag right next to mentions
+         */
+        const mentionsLinePadding =
+              // Padding is only needed if we just finished parsing mentions
+              previouslyMentions &&
+              // Don't add padding if content is string and has padding already
+              !(children && typeof children[0] === 'string' && children[0].match(/^\s/))
+                ? lastSpacing
+                : ''
         switch (Tag) {
           case 'br':
             currentMentions = null
             break
           case 'img': // replace images with StillImage
-            return renderImage(opener)
+            return ['', [mentionsLinePadding, renderImage(opener)], '']
           case 'a': // replace mentions with MentionLink
             if (!this.handleLinks) break
             if (attrs['class'] && attrs['class'].includes('mention')) {
               // Handling mentions here
               return renderMention(attrs, children)
             } else {
-              // Everything else will be handled in reverse pass
               currentMentions = null
-              return item // We'll handle it later
+              break
             }
           case 'span':
             if (this.handleLinks && attrs['class'] && attrs['class'].includes('h-card')) {
@@ -174,9 +182,13 @@ export default Vue.component('RichContent', {
         }
 
         if (children !== undefined) {
-          return [opener, children.map(processItem), closer]
+          return [
+            opener,
+            [mentionsLinePadding].concat(children.map(processItem)),
+            closer
+          ]
         } else {
-          return item
+          return ['', [mentionsLinePadding, item], '']
         }
       }
     }
@@ -215,7 +227,6 @@ export default Vue.component('RichContent', {
 
         // Render tag as is
         if (children !== undefined) {
-          html.includes('freenode') && console.log('PASS2', children)
           const newChildren = Array.isArray(children)
             ? [...children].reverse().map(processItemReverse).reverse()
             : children
@@ -283,8 +294,6 @@ export const preProcessPerLine = (html, greentext) => {
 
   const lines = convertHtmlToLines(html)
   const newHtml = lines.reverse().map((item, index, array) => {
-    // Going over each line in reverse to detect last mentions,
-    // keeping non-text stuff as-is
     if (!item.text) return item
     const string = item.text
 
-- 
cgit v1.2.3-70-g09d2

