aboutsummaryrefslogtreecommitdiff
path: root/src/components/rich_content/rich_content.jsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/rich_content/rich_content.jsx')
-rw-r--r--src/components/rich_content/rich_content.jsx69
1 files changed, 50 insertions, 19 deletions
diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx
index ffb36f50..ce562f13 100644
--- a/src/components/rich_content/rich_content.jsx
+++ b/src/components/rich_content/rich_content.jsx
@@ -5,6 +5,7 @@ import { convertHtmlToTree } from 'src/services/html_converter/html_tree_convert
import { convertHtmlToLines } from 'src/services/html_converter/html_line_converter.service.js'
import StillImage from 'src/components/still-image/still-image.vue'
import MentionLink from 'src/components/mention_link/mention_link.vue'
+import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
import './rich_content.scss'
@@ -51,6 +52,11 @@ export default Vue.component('RichContent', {
required: false,
type: Boolean,
default: false
+ },
+ hideMentions: {
+ required: false,
+ type: Boolean,
+ default: false
}
},
// NEVER EVER TOUCH DATA INSIDE RENDER
@@ -64,6 +70,7 @@ export default Vue.component('RichContent', {
// unique index for vue "tag" property
let mentionIndex = 0
let tagsIndex = 0
+ let firstMentionReplaced = false
const renderImage = (tag) => {
return <StillImage
@@ -78,7 +85,6 @@ export default Vue.component('RichContent', {
attrs.target = '_blank'
if (!encounteredTextReverse) {
lastTags.push(linkData)
- attrs['data-parser-last'] = true
}
return <a {...{ attrs }}>
{ children.map(processItem) }
@@ -90,7 +96,12 @@ export default Vue.component('RichContent', {
writtenMentions.push(linkData)
if (!encounteredText) {
firstMentions.push(linkData)
- return ''
+ if (!firstMentionReplaced && !this.hideMentions) {
+ firstMentionReplaced = true
+ return <MentionsLine mentions={ firstMentions } />
+ } else {
+ return ''
+ }
} else {
return <MentionLink
url={attrs.href}
@@ -116,7 +127,7 @@ export default Vue.component('RichContent', {
encounteredText = true
}
if (item.includes(':')) {
- unescapedItem = processTextForEmoji(
+ unescapedItem = ['', processTextForEmoji(
unescapedItem,
this.emoji,
({ shortcode, url }) => {
@@ -127,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) {
@@ -143,7 +154,7 @@ export default Vue.component('RichContent', {
if (firstMentions.length > 1 && lastMentions.length > 1) {
break
} else {
- return ''
+ return !this.hideMentions ? <MentionsLine mentions={lastMentions} /> : ''
}
} else {
break
@@ -153,25 +164,19 @@ export default Vue.component('RichContent', {
case 'a': // replace mentions with MentionLink
if (!this.handleLinks) break
if (attrs['class'] && attrs['class'].includes('mention')) {
+ // Handling mentions here
return renderMention(attrs, children, encounteredText)
- } else if (attrs['class'] && attrs['class'].includes('hashtag')) {
+ } else {
+ // Everything else will be handled in reverse pass
encounteredText = true
return item // We'll handle it later
- } else {
- attrs.target = '_blank'
- return <a {...{ attrs }}>
- { children.map(processItem) }
- </a>
}
}
- // Render tag as is
if (children !== undefined) {
- return <Tag {...{ attrs: getAttrs(opener) }}>
- { children.map(processItem) }
- </Tag>
+ return [opener, children.map(processItem), closer]
} else {
- return <Tag/>
+ return item
}
}
}
@@ -188,7 +193,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
@@ -196,17 +201,43 @@ export default Vue.component('RichContent', {
// should only be this
if (attrs['class'] && attrs['class'].includes('hashtag')) {
return renderHashtag(attrs, children, encounteredTextReverse)
+ } else {
+ attrs.target = '_blank'
+ html.includes('freenode') && console.log('PASS1', children)
+ const newChildren = [...children].reverse().map(processItemReverse).reverse()
+ html.includes('freenode') && console.log('PASS1b', newChildren)
+
+ return <a {...{ attrs }}>
+ { newChildren }
+ </a>
}
+ case '':
+ return [...children].reverse().map(processItemReverse).reverse()
+ }
+
+ // 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
+ return <Tag {...{ attrs: getAttrs(opener) }}>
+ { newChildren }
+ </Tag>
+ } else {
+ return <Tag/>
}
}
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 = <span class="RichContent">
- { convertHtmlToTree(html).map(processItem).reverse().map(processItemReverse).reverse() }
+ { pass2 }
</span>
const event = {