diff options
| author | Henry Jameson <me@hjkos.com> | 2021-08-12 02:49:37 +0300 |
|---|---|---|
| committer | Henry Jameson <me@hjkos.com> | 2021-08-12 02:56:40 +0300 |
| commit | 2cfff1b8b9c642e9284483d6658312d9a3763417 (patch) | |
| tree | 32c707645da9c8de6c5f2d53e40a1afaf844f508 /src/components/rich_content | |
| parent | a0eaac2216e7f279e10c6b688b9fa81f7a4fad2d (diff) | |
remove new options for style and separate line, now groups all chained
mentions on a mentionsline regardless of placement. fixes spacing
Diffstat (limited to 'src/components/rich_content')
| -rw-r--r-- | src/components/rich_content/rich_content.jsx | 128 |
1 files changed, 29 insertions, 99 deletions
diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index cd73f2e5..4b7d4d37 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -56,25 +56,21 @@ export default Vue.component('RichContent', { required: false, type: Boolean, default: false - }, - hideMentions: { - required: false, - type: Boolean, - default: false } }, // NEVER EVER TOUCH DATA INSIDE RENDER render (h) { // Pre-process HTML - const { newHtml: html, lastMentions } = preProcessPerLine(this.html, this.greentext, this.handleLinks) - const firstMentions = [] // Mentions that appear in the beginning of post body + const { newHtml: html } = preProcessPerLine(this.html, this.greentext, this.handleLinks) + let currentMentions = null // Current chain of mentions, we group all mentions together + // to collapse too many mentions in a row + const lastTags = [] // Tags that appear at the end of post body const writtenMentions = [] // All mentions that appear in post body const writtenTags = [] // All tags that appear in post body // unique index for vue "tag" property let mentionIndex = 0 let tagsIndex = 0 - let firstMentionReplaced = false const renderImage = (tag) => { return <StillImage @@ -98,41 +94,32 @@ export default Vue.component('RichContent', { const renderMention = (attrs, children) => { const linkData = getLinkData(attrs, children, mentionIndex++) linkData.notifying = this.attentions.some(a => a.statusnet_profile_url === linkData.url) - if (!linkData.notifying) { - encounteredText = true - } writtenMentions.push(linkData) - if (!encounteredText) { - firstMentions.push(linkData) - if (!firstMentionReplaced && !this.hideMentions) { - firstMentionReplaced = true - return <MentionsLine mentions={ firstMentions } /> - } else { - return '' - } + if (currentMentions === null) { + currentMentions = [] + } + currentMentions.push(linkData) + if (currentMentions.length === 1) { + return <MentionsLine mentions={ currentMentions } /> } else { - return <MentionLink - url={attrs.href} - content={flattenDeep(children).join('')} - /> + return '' } } - // We stop treating mentions as "first" ones when we encounter - // non-whitespace text - let encounteredText = false // Processor to use with html_tree_converter const processItem = (item, index, array, what) => { // Handle text nodes - just add emoji if (typeof item === 'string') { const emptyText = item.trim() === '' - if (emptyText) { - return encounteredText ? item : item.trim() + if (item.includes('\n')) { + currentMentions = null } - if (!encounteredText) { - item = item.trimStart() - encounteredText = true + if (emptyText) { + // don't include spaces when processing mentions - we'll include them + // in MentionsLine + return currentMentions !== null ? item.trim() : item } + currentMentions = null if (item.includes(':')) { item = ['', processTextForEmoji( item, @@ -156,28 +143,25 @@ export default Vue.component('RichContent', { const Tag = getTagName(opener) const attrs = getAttrs(opener) switch (Tag) { - case 'span': // Replace last mentions class with mentionsline - if (attrs['class'] && attrs['class'].includes('lastMentions')) { - if (firstMentions.length > 1 && lastMentions.length > 1) { - break - } else { - return !this.hideMentions ? <MentionsLine mentions={lastMentions} /> : '' - } - } else { - break - } + case 'br': + currentMentions = null + break case 'img': // replace images with StillImage return 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, encounteredText) + return renderMention(attrs, children) } else { // Everything else will be handled in reverse pass - encounteredText = true + currentMentions = null return item // We'll handle it later } + case 'span': + if (attrs['class'].includes('h-card')) { + return ['', children.map(processItem), ''] + } } if (children !== undefined) { @@ -246,8 +230,6 @@ export default Vue.component('RichContent', { </span> const event = { - firstMentions, - lastMentions, lastTags, writtenMentions, writtenTags @@ -284,15 +266,12 @@ export const preProcessPerLine = (html, greentext, handleLinks) => { const lastMentions = [] const greentextHandle = new Set(['p', 'div']) - let nonEmptyIndex = -1 const lines = convertHtmlToLines(html) - const linesNum = lines.filter(c => c.text).length 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 - nonEmptyIndex += 1 // Greentext stuff if ( @@ -316,42 +295,19 @@ export const preProcessPerLine = (html, greentext, handleLinks) => { // Converting that line part into tree const tree = convertHtmlToTree(string) - // If line has loose text, i.e. text outside a mention or a tag - // we won't touch mentions. - let hasLooseText = false - let mentionsNum = 0 const process = (item) => { if (Array.isArray(item)) { const [opener, children, closer] = item const tag = getTagName(opener) - // If we have a link we probably have mentions - if (tag === 'a') { - if (!handleLinks) return [opener, children, closer] - const attrs = getAttrs(opener) - if (attrs['class'] && attrs['class'].includes('mention')) { - // Got mentions - mentionsNum++ - return [opener, children, closer] - } else { - // Not a mention? Means we have loose text or whatever - hasLooseText = true - return [opener, children, closer] - } - } else if (tag === 'span' || tag === 'p') { + if (tag === 'span' || tag === 'p') { // For span and p we need to go deeper return [opener, [...children].map(process), closer] } else { - // Everything else equals to a loose text - hasLooseText = true return [opener, children, closer] } } if (typeof item === 'string') { - if (item.trim() !== '') { - // only meaningful strings are loose text - hasLooseText = true - } return item } } @@ -359,33 +315,7 @@ export const preProcessPerLine = (html, greentext, handleLinks) => { // We now processed our tree, now we need to mark line as lastMentions const result = [...tree].map(process) - if ( - handleLinks && // Do we handle links at all? - mentionsNum > 1 && // Does it have more than one mention? - !hasLooseText && // Don't do anything if it has something besides mentions - nonEmptyIndex === 0 && // Only check last (first since list is reversed) line - nonEmptyIndex !== linesNum - 1 // Don't do anything if there's only one line - ) { - let mentionIndex = 0 - const process = (item) => { - if (Array.isArray(item)) { - const [opener, children] = item - const tag = getTagName(opener) - if (tag === 'a') { - const attrs = getAttrs(opener) - lastMentions.push(getLinkData(attrs, children, mentionIndex++)) - } else if (children) { - children.forEach(process) - } - } - } - result.forEach(process) - // we DO need mentions here so that we conditionally remove them if don't - // have first mentions - return ['<span class="lastMentions">', flattenDeep(result).join(''), '</span>'].join('') - } else { - return flattenDeep(result).join('') - } + return flattenDeep(result).join('') }).reverse().join('') return { newHtml, lastMentions } |
