fixed bug with hashtags
This commit is contained in:
parent
7309f8ce1a
commit
4aac0125e5
|
@ -85,7 +85,6 @@ export default Vue.component('RichContent', {
|
||||||
attrs.target = '_blank'
|
attrs.target = '_blank'
|
||||||
if (!encounteredTextReverse) {
|
if (!encounteredTextReverse) {
|
||||||
lastTags.push(linkData)
|
lastTags.push(linkData)
|
||||||
attrs['data-parser-last'] = true
|
|
||||||
}
|
}
|
||||||
return <a {...{ attrs }}>
|
return <a {...{ attrs }}>
|
||||||
{ children.map(processItem) }
|
{ children.map(processItem) }
|
||||||
|
@ -128,7 +127,7 @@ export default Vue.component('RichContent', {
|
||||||
encounteredText = true
|
encounteredText = true
|
||||||
}
|
}
|
||||||
if (item.includes(':')) {
|
if (item.includes(':')) {
|
||||||
unescapedItem = processTextForEmoji(
|
unescapedItem = ['', processTextForEmoji(
|
||||||
unescapedItem,
|
unescapedItem,
|
||||||
this.emoji,
|
this.emoji,
|
||||||
({ shortcode, url }) => {
|
({ shortcode, url }) => {
|
||||||
|
@ -139,14 +138,14 @@ export default Vue.component('RichContent', {
|
||||||
alt={`:${shortcode}:`}
|
alt={`:${shortcode}:`}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
)
|
)]
|
||||||
}
|
}
|
||||||
return unescapedItem
|
return unescapedItem
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle tag nodes
|
// Handle tag nodes
|
||||||
if (Array.isArray(item)) {
|
if (Array.isArray(item)) {
|
||||||
const [opener, children] = item
|
const [opener, children, closer] = item
|
||||||
const Tag = getTagName(opener)
|
const Tag = getTagName(opener)
|
||||||
const attrs = getAttrs(opener)
|
const attrs = getAttrs(opener)
|
||||||
switch (Tag) {
|
switch (Tag) {
|
||||||
|
@ -176,14 +175,10 @@ export default Vue.component('RichContent', {
|
||||||
</a>
|
</a>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render tag as is
|
|
||||||
if (children !== undefined) {
|
if (children !== undefined) {
|
||||||
return <Tag {...{ attrs: getAttrs(opener) }}>
|
return [opener, children.map(processItem), closer]
|
||||||
{ children.map(processItem) }
|
|
||||||
</Tag>
|
|
||||||
} else {
|
} else {
|
||||||
return <Tag/>
|
return item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,7 +195,7 @@ export default Vue.component('RichContent', {
|
||||||
} else if (Array.isArray(item)) {
|
} else if (Array.isArray(item)) {
|
||||||
// Handle tag nodes
|
// Handle tag nodes
|
||||||
const [opener, children] = item
|
const [opener, children] = item
|
||||||
const Tag = getTagName(opener)
|
const Tag = opener === '' ? '' : getTagName(opener)
|
||||||
switch (Tag) {
|
switch (Tag) {
|
||||||
case 'a': // replace mentions with MentionLink
|
case 'a': // replace mentions with MentionLink
|
||||||
if (!this.handleLinks) break
|
if (!this.handleLinks) break
|
||||||
|
@ -209,16 +204,30 @@ export default Vue.component('RichContent', {
|
||||||
if (attrs['class'] && attrs['class'].includes('hashtag')) {
|
if (attrs['class'] && attrs['class'].includes('hashtag')) {
|
||||||
return renderHashtag(attrs, children, encounteredTextReverse)
|
return renderHashtag(attrs, children, encounteredTextReverse)
|
||||||
}
|
}
|
||||||
|
break
|
||||||
|
case '':
|
||||||
|
return [...children].reverse().map(processItemReverse).reverse()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render tag as is
|
||||||
|
if (children !== undefined) {
|
||||||
|
return <Tag {...{ attrs: getAttrs(opener) }}>
|
||||||
|
{ Array.isArray(children) ? [...children].reverse().map(processItemReverse).reverse() : children }
|
||||||
|
</Tag>
|
||||||
|
} else {
|
||||||
|
return <Tag/>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return item
|
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.
|
// DO NOT USE SLOTS they cause a re-render feedback loop here.
|
||||||
// slots updated -> rerender -> emit -> update up the tree -> rerender -> ...
|
// slots updated -> rerender -> emit -> update up the tree -> rerender -> ...
|
||||||
// at least until vue3?
|
// at least until vue3?
|
||||||
const result = <span class="RichContent">
|
const result = <span class="RichContent">
|
||||||
{ convertHtmlToTree(html).map(processItem).reverse().map(processItemReverse).reverse() }
|
{ pass2 }
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
const event = {
|
const event = {
|
||||||
|
|
|
@ -603,4 +603,40 @@ describe('RichContent', () => {
|
||||||
|
|
||||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('buggy example/hashtags', () => {
|
||||||
|
const html = [
|
||||||
|
'<p>',
|
||||||
|
'<a href="http://macrochan.org/images/N/H/NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg">',
|
||||||
|
'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg</a>',
|
||||||
|
' <a class="hashtag" data-tag="nou" href="https://shitposter.club/tag/nou">',
|
||||||
|
'#nou</a>',
|
||||||
|
' <a class="hashtag" data-tag="screencap" href="https://shitposter.club/tag/screencap">',
|
||||||
|
'#screencap</a>',
|
||||||
|
' </p>'
|
||||||
|
].join('')
|
||||||
|
const expected = [
|
||||||
|
'<p>',
|
||||||
|
'<a href="http://macrochan.org/images/N/H/NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg" target="_blank">',
|
||||||
|
'NHCMDUXJPPZ6M3Z2CQ6D2EBRSWGE7MZY.jpg</a>',
|
||||||
|
' <a class="hashtag" data-tag="nou" href="https://shitposter.club/tag/nou" target="_blank">',
|
||||||
|
'#nou</a>',
|
||||||
|
' <a class="hashtag" data-tag="screencap" href="https://shitposter.club/tag/screencap" target="_blank">',
|
||||||
|
'#screencap</a>',
|
||||||
|
' </p>'
|
||||||
|
].join('')
|
||||||
|
|
||||||
|
const wrapper = shallowMount(RichContent, {
|
||||||
|
localVue,
|
||||||
|
propsData: {
|
||||||
|
hideMentions: true,
|
||||||
|
handleLinks: true,
|
||||||
|
greentext: true,
|
||||||
|
emoji: [],
|
||||||
|
html
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue