Merge branch 'better-still-emoji' into shigusegubu
* better-still-emoji: fix tests, add performance test (skipped, doesn't assert anything), tweak max mentions count made the code responsible for showing unwritten mentions actually work remove new options for style and separate line, now groups all chained mentions on a mentionsline regardless of placement. fixes spacing
This commit is contained in:
commit
f96ffe3699
16 changed files with 132 additions and 646 deletions
|
@ -41,7 +41,7 @@ const MentionLink = {
|
|||
},
|
||||
computed: {
|
||||
user () {
|
||||
return this.url && this.$store.getters.findUserByUrl(this.url)
|
||||
return this.url && this.$store && this.$store.getters.findUserByUrl(this.url)
|
||||
},
|
||||
isYou () {
|
||||
// FIXME why user !== currentUser???
|
||||
|
@ -65,9 +65,6 @@ const MentionLink = {
|
|||
highlightClass () {
|
||||
if (this.highlight) return highlightClass(this.user)
|
||||
},
|
||||
oldStyle () {
|
||||
return !this.mergedConfig.mentionsNewStyle
|
||||
},
|
||||
style () {
|
||||
if (this.highlight) {
|
||||
const {
|
||||
|
@ -83,8 +80,7 @@ const MentionLink = {
|
|||
return [
|
||||
{
|
||||
'-you': this.isYou,
|
||||
'-highlighted': this.highlight,
|
||||
'-oldStyle': this.oldStyle
|
||||
'-highlighted': this.highlight
|
||||
},
|
||||
this.highlightType
|
||||
]
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.original {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
.full {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
|
@ -41,8 +37,6 @@
|
|||
}
|
||||
|
||||
.new {
|
||||
margin-right: 0.25em;
|
||||
|
||||
&.-you {
|
||||
& .shortName,
|
||||
& .full {
|
||||
|
@ -61,41 +55,6 @@
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
&:not(.-oldStyle) {
|
||||
.short {
|
||||
padding-left: 0.25em;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
line-height: 1.5;
|
||||
font-size: inherit;
|
||||
|
||||
.at {
|
||||
color: var(--faint);
|
||||
opacity: 0.8;
|
||||
padding-right: 0.25em;
|
||||
vertical-align: -20%;
|
||||
}
|
||||
}
|
||||
|
||||
.you {
|
||||
padding-right: 0.25em;
|
||||
}
|
||||
|
||||
.userName {
|
||||
display: inline-block;
|
||||
color: var(--link);
|
||||
line-height: inherit;
|
||||
margin-left: 0;
|
||||
padding-left: 0.125em;
|
||||
padding-right: 0.25em;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
border-top-right-radius: var(--btnRadius);
|
||||
border-bottom-right-radius: var(--btnRadius);
|
||||
}
|
||||
}
|
||||
|
||||
&.-striped {
|
||||
& .userName,
|
||||
& .full {
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
:class="classnames"
|
||||
>
|
||||
<button
|
||||
class="short"
|
||||
:class="[{ '-sublime': !highlight }, oldStyle ? 'button-unstyled' : 'button-default']"
|
||||
class="short button-unstyled"
|
||||
@click.prevent="onClick"
|
||||
>
|
||||
<!-- eslint-disable vue/no-v-html -->
|
||||
|
|
|
@ -14,11 +14,8 @@ const MentionsLine = {
|
|||
MentionLink
|
||||
},
|
||||
computed: {
|
||||
oldStyle () {
|
||||
return !this.mergedConfig.mentionsNewStyle
|
||||
},
|
||||
limit () {
|
||||
return 6
|
||||
return 5
|
||||
},
|
||||
mentionsComputed () {
|
||||
return this.mentions.slice(0, this.limit)
|
||||
|
@ -29,16 +26,6 @@ const MentionsLine = {
|
|||
manyMentions () {
|
||||
return this.extraMentions.length > 0
|
||||
},
|
||||
buttonClasses () {
|
||||
return [
|
||||
this.oldStyle
|
||||
? 'button-unstyled'
|
||||
: 'button-default -sublime',
|
||||
this.oldStyle
|
||||
? '-oldStyle'
|
||||
: '-newStyle'
|
||||
]
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -1,17 +1,10 @@
|
|||
.MentionsLine {
|
||||
.showMoreLess {
|
||||
white-space: normal;
|
||||
color: var(--link);
|
||||
}
|
||||
|
||||
&.-newStyle {
|
||||
line-height: 1.5;
|
||||
font-size: inherit;
|
||||
display: inline-block;
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&.-oldStyle {
|
||||
color: var(--link);
|
||||
}
|
||||
.mention-link:not(:last-child) {
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,15 +25,13 @@
|
|||
/>
|
||||
</span><button
|
||||
v-if="!expanded"
|
||||
class="showMoreLess"
|
||||
:class="buttonClasses"
|
||||
class="button-unstyled showMoreLess"
|
||||
@click="toggleShowMore"
|
||||
>
|
||||
{{ $t('status.plus_more', { number: extraMentions.length }) }}
|
||||
</button><button
|
||||
v-if="expanded"
|
||||
class="showMoreLess"
|
||||
:class="buttonClasses"
|
||||
class="button-unstyled showMoreLess"
|
||||
@click="toggleShowMore"
|
||||
>
|
||||
{{ $t('general.show_less') }}
|
||||
|
|
|
@ -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 (item.includes('\n')) {
|
||||
currentMentions = null
|
||||
}
|
||||
if (emptyText) {
|
||||
return encounteredText ? item : item.trim()
|
||||
}
|
||||
if (!encounteredText) {
|
||||
item = item.trimStart()
|
||||
encounteredText = true
|
||||
// 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 (this.handleLinks && attrs['class'] && 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 }
|
||||
|
|
|
@ -83,16 +83,6 @@
|
|||
{{ $t('settings.emoji_reactions_on_timeline') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="mentionsOwnLine">
|
||||
{{ $t('settings.mentions_new_place') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<li>
|
||||
<BooleanSetting path="mentionsNewStyle">
|
||||
{{ $t('settings.mentions_new_style') }}
|
||||
</BooleanSetting>
|
||||
</li>
|
||||
<h3>{{ $t('settings.attachments') }}</h3>
|
||||
<li>
|
||||
<BooleanSetting path="useContainFit">
|
||||
|
|
|
@ -176,18 +176,18 @@ const Status = {
|
|||
userId: attn.id
|
||||
}))
|
||||
},
|
||||
alsoMentions () {
|
||||
if (!this.headTailLinks) return []
|
||||
const set = new Set(this.headTailLinks.writtenMentions.map(m => m.url))
|
||||
return this.headTailLinks.writtenMentions.filter(mention => {
|
||||
return !set.has(mention.url)
|
||||
})
|
||||
},
|
||||
mentionsLine () {
|
||||
return this.mentionsOwnLine ? this.mentions : this.alsoMentions
|
||||
},
|
||||
mentionsOwnLine () {
|
||||
return this.mergedConfig.mentionsOwnLine
|
||||
const writtenMentions = this.headTailLinks ? this.headTailLinks.writtenMentions : []
|
||||
const set = new Set(writtenMentions.map(_ => _.url))
|
||||
return this.status.attentions.filter(attn => {
|
||||
return attn.screen_name !== this.replyToName &&
|
||||
attn.screen_name !== this.status.user.screen_name &&
|
||||
!set.has(attn.url)
|
||||
}).map(attn => ({
|
||||
url: attn.statusnet_profile_url,
|
||||
content: attn.screen_name,
|
||||
userId: attn.id
|
||||
}))
|
||||
},
|
||||
hasMentionsLine () {
|
||||
return this.mentionsLine.length > 0
|
||||
|
|
|
@ -306,7 +306,6 @@
|
|||
:no-heading="noHeading"
|
||||
:highlight="highlight"
|
||||
:focused="isFocused"
|
||||
:hide-mentions="mentionsOwnLine && (isReply || true)"
|
||||
@mediaplay="addMediaPlaying($event)"
|
||||
@mediapause="removeMediaPlaying($event)"
|
||||
@parseReady="setHeadTailLinks"
|
||||
|
|
|
@ -26,8 +26,7 @@ const StatusContent = {
|
|||
'focused',
|
||||
'noHeading',
|
||||
'fullContent',
|
||||
'singleLine',
|
||||
'hideMentions'
|
||||
'singleLine'
|
||||
],
|
||||
data () {
|
||||
return {
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
:html="status.raw_html"
|
||||
:emoji="status.emojis"
|
||||
:handle-links="true"
|
||||
:hide-mentions="hideMentions"
|
||||
:greentext="mergedConfig.greentext"
|
||||
:attentions="status.attentions"
|
||||
@parseReady="onParseReady"
|
||||
|
|
|
@ -31,8 +31,7 @@ const StatusContent = {
|
|||
'focused',
|
||||
'noHeading',
|
||||
'fullContent',
|
||||
'singleLine',
|
||||
'hideMentions'
|
||||
'singleLine'
|
||||
],
|
||||
computed: {
|
||||
hideAttachments () {
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
:status="status"
|
||||
:compact="compact"
|
||||
:single-line="singleLine"
|
||||
:hide-mentions="hideMentions"
|
||||
@parseReady="$emit('parseReady', $event)"
|
||||
>
|
||||
<div v-if="status.poll && status.poll.options">
|
||||
|
|
|
@ -57,8 +57,6 @@ export const defaultState = {
|
|||
interfaceLanguage: browserLocale,
|
||||
hideScopeNotice: false,
|
||||
useStreamingApi: false,
|
||||
mentionsOwnLine: false,
|
||||
mentionsNewStyle: false,
|
||||
sidebarRight: undefined, // instance default
|
||||
scopeCopy: undefined, // instance default
|
||||
subjectLineBehavior: undefined, // instance default
|
||||
|
|
|
@ -8,11 +8,13 @@ const makeMention = (who) => {
|
|||
attentions.push({ statusnet_profile_url: `https://fake.tld/@${who}` })
|
||||
return `<span class="h-card"><a class="u-url mention" href="https://fake.tld/@${who}">@<span>${who}</span></a></span>`
|
||||
}
|
||||
const stubMention = (who) => `<span class="h-card"><mentionlink-stub url="https://fake.tld/@${who}" content="@<span>${who}</span>"></mentionlink-stub></span>`
|
||||
const lastMentions = (...data) => `<span class="lastMentions">${data.join('')}</span>`
|
||||
const p = (...data) => `<p>${data.join('')}</p>`
|
||||
const compwrap = (...data) => `<span class="RichContent">${data.join('')}</span>`
|
||||
const removedMentionSpan = '<span class="h-card"></span>'
|
||||
const mentionsLine = (times) => [
|
||||
'<mentionsline-stub mentions="',
|
||||
new Array(times).fill('[object Object]').join(','),
|
||||
'"></mentionsline-stub>'
|
||||
].join('')
|
||||
|
||||
describe('RichContent', () => {
|
||||
it('renders simple post without exploding', () => {
|
||||
|
@ -21,7 +23,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -45,7 +46,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -56,20 +56,15 @@ describe('RichContent', () => {
|
|||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('removes mentions from the beginning of post', () => {
|
||||
it('replaces mention with mentionsline', () => {
|
||||
const html = p(
|
||||
makeMention('John'),
|
||||
' how are you doing thoday?'
|
||||
)
|
||||
const expected = p(
|
||||
removedMentionSpan,
|
||||
'how are you doing thoday?'
|
||||
' how are you doing today?'
|
||||
)
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -77,70 +72,13 @@ describe('RichContent', () => {
|
|||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
expect(wrapper.html()).to.eql(compwrap(p(
|
||||
mentionsLine(1),
|
||||
' how are you doing today?'
|
||||
)))
|
||||
})
|
||||
|
||||
it('replaces first mention with mentionsline if hideMentions=false', () => {
|
||||
const html = p(
|
||||
makeMention('John'),
|
||||
' how are you doing thoday?'
|
||||
)
|
||||
const expected = p(
|
||||
'<span class="h-card">',
|
||||
'<mentionsline-stub mentions="',
|
||||
'[object Object]',
|
||||
'"></mentionsline-stub>',
|
||||
'</span>',
|
||||
'how are you doing thoday?'
|
||||
)
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: false,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('removes mentions from the end of the hellpost (<p>)', () => {
|
||||
const html = [
|
||||
p('How are you doing today, fine gentlemen?'),
|
||||
p(
|
||||
makeMention('John'),
|
||||
makeMention('Josh'),
|
||||
makeMention('Jeremy')
|
||||
)
|
||||
].join('')
|
||||
const expected = [
|
||||
p(
|
||||
'How are you doing today, fine gentlemen?'
|
||||
),
|
||||
// TODO fix this extra line somehow?
|
||||
p()
|
||||
].join('')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('replaces mentions at the end of the hellpost if hideMentions=false (<p>)', () => {
|
||||
it('replaces mentions at the end of the hellpost', () => {
|
||||
const html = [
|
||||
p('How are you doing today, fine gentlemen?'),
|
||||
p(
|
||||
|
@ -167,189 +105,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: false,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('removes mentions from the end of the hellpost (<br>)', () => {
|
||||
const html = [
|
||||
'How are you doing today, fine gentlemen?',
|
||||
[
|
||||
makeMention('John'),
|
||||
makeMention('Josh'),
|
||||
makeMention('Jeremy')
|
||||
].join('')
|
||||
].join('<br>')
|
||||
const expected = [
|
||||
'How are you doing today, fine gentlemen?',
|
||||
// TODO fix this extra line somehow?
|
||||
'<br>'
|
||||
].join('')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('removes mentions from the end of the hellpost (\\n)', () => {
|
||||
const html = [
|
||||
'How are you doing today, fine gentlemen?',
|
||||
[
|
||||
makeMention('John'),
|
||||
makeMention('Josh'),
|
||||
makeMention('Jeremy')
|
||||
].join('')
|
||||
].join('\n')
|
||||
const expected = [
|
||||
'How are you doing today, fine gentlemen?',
|
||||
// TODO fix this extra line somehow?
|
||||
''
|
||||
].join('\n')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('Does not remove mentions in the middle or at the end of text string', () => {
|
||||
const html = [
|
||||
[
|
||||
makeMention('Jack'),
|
||||
'let\'s meet up with ',
|
||||
makeMention('Janet')
|
||||
].join(''),
|
||||
[
|
||||
'cc: ',
|
||||
makeMention('John'),
|
||||
makeMention('Josh'),
|
||||
makeMention('Jeremy')
|
||||
].join('')
|
||||
].join('\n')
|
||||
const expected = [
|
||||
[
|
||||
removedMentionSpan,
|
||||
'let\'s meet up with ',
|
||||
stubMention('Janet')
|
||||
].join(''),
|
||||
[
|
||||
'cc: ',
|
||||
stubMention('John'),
|
||||
stubMention('Josh'),
|
||||
stubMention('Jeremy')
|
||||
].join('')
|
||||
].join('\n')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('removes mentions from the end if there\'s only one first mention', () => {
|
||||
const html = [
|
||||
p(
|
||||
makeMention('Todd'),
|
||||
'so anyway you are wrong'
|
||||
),
|
||||
p(
|
||||
makeMention('Tom'),
|
||||
makeMention('Trace'),
|
||||
makeMention('Theodor')
|
||||
)
|
||||
].join('')
|
||||
const expected = [
|
||||
p(
|
||||
removedMentionSpan,
|
||||
'so anyway you are wrong'
|
||||
),
|
||||
// TODO fix this extra line somehow?
|
||||
p()
|
||||
].join('')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('does not remove mentions from the end if there\'s more than one first mention', () => {
|
||||
const html = [
|
||||
p(
|
||||
makeMention('Zacharie'),
|
||||
makeMention('Zinaide'),
|
||||
'you guys have cool names, and so do these guys: '
|
||||
),
|
||||
p(
|
||||
makeMention('Watson'),
|
||||
makeMention('Wallace'),
|
||||
makeMention('Wakamoto')
|
||||
)
|
||||
].join('')
|
||||
const expected = [
|
||||
p(
|
||||
removedMentionSpan,
|
||||
removedMentionSpan,
|
||||
'you guys have cool names, and so do these guys: '
|
||||
),
|
||||
p(
|
||||
lastMentions(
|
||||
stubMention('Watson'),
|
||||
stubMention('Wallace'),
|
||||
stubMention('Wakamoto')
|
||||
)
|
||||
)
|
||||
].join('')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -378,7 +133,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: false,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -403,7 +157,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: false,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -424,7 +177,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: false,
|
||||
greentext: false,
|
||||
emoji: [],
|
||||
|
@ -446,7 +198,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: false,
|
||||
greentext: false,
|
||||
emoji: [{ url: 'about:blank', shortcode: 'spurdo' }],
|
||||
|
@ -464,7 +215,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: false,
|
||||
greentext: false,
|
||||
emoji: [],
|
||||
|
@ -484,7 +234,7 @@ describe('RichContent', () => {
|
|||
].join('\n')
|
||||
const expected = [
|
||||
'<span class="greentext">>quote</span>',
|
||||
stubMention('lol'),
|
||||
mentionsLine(1),
|
||||
'<span class="greentext">>quote</span>',
|
||||
'<span class="greentext">>quote</span>'
|
||||
].join('\n')
|
||||
|
@ -517,11 +267,7 @@ describe('RichContent', () => {
|
|||
const expected = [
|
||||
'Bruh',
|
||||
'Bruh',
|
||||
[
|
||||
stubMention('foo'),
|
||||
stubMention('bar'),
|
||||
stubMention('baz')
|
||||
].join(''),
|
||||
mentionsLine(3),
|
||||
'Bruh'
|
||||
].join('<br>')
|
||||
|
||||
|
@ -529,119 +275,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('Don\'t remove last mention if it\'s the only one', () => {
|
||||
const html = [
|
||||
'Bruh',
|
||||
'Bruh',
|
||||
makeMention('foo'),
|
||||
makeMention('bar'),
|
||||
makeMention('baz')
|
||||
].join('<br>')
|
||||
const expected = [
|
||||
'Bruh',
|
||||
'Bruh',
|
||||
stubMention('foo'),
|
||||
stubMention('bar'),
|
||||
stubMention('baz')
|
||||
].join('<br>')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('Don\'t remove last mentions if there are more than one first mention - remove first instead', () => {
|
||||
const html = [
|
||||
[
|
||||
makeMention('foo'),
|
||||
makeMention('bar')
|
||||
].join(' '),
|
||||
'Bruh',
|
||||
'Bruh',
|
||||
[
|
||||
makeMention('foo'),
|
||||
makeMention('bar'),
|
||||
makeMention('baz')
|
||||
].join(' ')
|
||||
].join('\n')
|
||||
|
||||
const expected = [
|
||||
[
|
||||
removedMentionSpan,
|
||||
removedMentionSpan,
|
||||
'Bruh' // Due to trim we remove extra newline
|
||||
].join(''),
|
||||
'Bruh',
|
||||
lastMentions([
|
||||
stubMention('foo'),
|
||||
stubMention('bar'),
|
||||
stubMention('baz')
|
||||
].join(' '))
|
||||
].join('\n')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('Remove last mentions if there\'s just one first mention - remove all', () => {
|
||||
const html = [
|
||||
[
|
||||
makeMention('foo')
|
||||
].join(' '),
|
||||
'Bruh',
|
||||
'Bruh',
|
||||
[
|
||||
makeMention('foo'),
|
||||
makeMention('bar'),
|
||||
makeMention('baz')
|
||||
].join(' ')
|
||||
].join('\n')
|
||||
|
||||
const expected = [
|
||||
[
|
||||
removedMentionSpan,
|
||||
'Bruh' // Due to trim we remove extra newline
|
||||
].join(''),
|
||||
'Bruh\n' // Can't remove this one yet
|
||||
].join('\n')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -678,7 +311,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: true,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -690,54 +322,6 @@ describe('RichContent', () => {
|
|||
})
|
||||
|
||||
it('rich contents of a mention are handled properly', () => {
|
||||
const html = [
|
||||
p(
|
||||
'Testing'
|
||||
),
|
||||
p(
|
||||
'<a href="lol" class="mention">',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'</a>'
|
||||
)
|
||||
].join('')
|
||||
const expected = [
|
||||
p(
|
||||
'Testing'
|
||||
),
|
||||
p(
|
||||
'<mentionlink-stub url="lol" content="',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'">',
|
||||
'</mentionlink-stub>'
|
||||
)
|
||||
].join('')
|
||||
|
||||
const wrapper = shallowMount(RichContent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: false,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
html
|
||||
}
|
||||
})
|
||||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it('rich contents of a mention in beginning are handled properly', () => {
|
||||
attentions.push({ statusnet_profile_url: 'lol' })
|
||||
const html = [
|
||||
p(
|
||||
|
@ -757,16 +341,19 @@ describe('RichContent', () => {
|
|||
const expected = [
|
||||
p(
|
||||
'<span class="MentionsLine">',
|
||||
'<mentionlink-stub content="',
|
||||
'<span class="MentionLink mention-link">',
|
||||
'<a href="lol" target="_blank" class="original">',
|
||||
'<span>',
|
||||
'https://</span>',
|
||||
'<span>',
|
||||
'lol.tld/</span>',
|
||||
'<span>',
|
||||
'</span>',
|
||||
'" url="lol" class="mention-link">',
|
||||
'</mentionlink-stub>',
|
||||
'<!---->', // v-if placeholder
|
||||
'</a>',
|
||||
' ',
|
||||
'<!---->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
|
||||
'</span>',
|
||||
'<!---->', // v-if placeholder, mentionsline's extra mentions and stuff
|
||||
'</span>'
|
||||
),
|
||||
p(
|
||||
|
@ -776,12 +363,8 @@ describe('RichContent', () => {
|
|||
|
||||
const wrapper = mount(RichContent, {
|
||||
localVue,
|
||||
stubs: {
|
||||
MentionLink: true
|
||||
},
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: false,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -826,7 +409,6 @@ describe('RichContent', () => {
|
|||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
hideMentions: false,
|
||||
handleLinks: true,
|
||||
greentext: true,
|
||||
emoji: [],
|
||||
|
@ -836,4 +418,63 @@ describe('RichContent', () => {
|
|||
|
||||
expect(wrapper.html()).to.eql(compwrap(expected))
|
||||
})
|
||||
|
||||
it.skip('[INFORMATIVE] Performance testing, 10 000 simple posts', () => {
|
||||
const amount = 20
|
||||
|
||||
const onePost = p(
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
makeMention('Lain'),
|
||||
' i just landed in l a where are you'
|
||||
)
|
||||
|
||||
const TestComponent = {
|
||||
template: `
|
||||
<div v-if="!vhtml">
|
||||
${new Array(amount).fill(`<RichContent html="${onePost}" :greentext="true" :handleLinks="handeLinks" :emoji="[]" :attentions="attentions"/>`)}
|
||||
</div>
|
||||
<div v-else="vhtml">
|
||||
${new Array(amount).fill(`<div v-html="${onePost}"/>`)}
|
||||
</div>
|
||||
`,
|
||||
props: ['handleLinks', 'attentions', 'vhtml']
|
||||
}
|
||||
console.log(1)
|
||||
|
||||
const ptest = (handleLinks, vhtml) => {
|
||||
const t0 = performance.now()
|
||||
|
||||
const wrapper = mount(TestComponent, {
|
||||
localVue,
|
||||
propsData: {
|
||||
attentions,
|
||||
handleLinks,
|
||||
vhtml
|
||||
}
|
||||
})
|
||||
|
||||
const t1 = performance.now()
|
||||
|
||||
wrapper.destroy()
|
||||
|
||||
const t2 = performance.now()
|
||||
|
||||
return `Mount: ${t1 - t0}ms, destroy: ${t2 - t1}ms, avg ${(t1 - t0) / amount}ms - ${(t2 - t1) / amount}ms per item`
|
||||
}
|
||||
|
||||
console.log(`${amount} items with links handling:`)
|
||||
console.log(ptest(true))
|
||||
console.log(`${amount} items without links handling:`)
|
||||
console.log(ptest(false))
|
||||
console.log(`${amount} items plain v-html:`)
|
||||
console.log(ptest(false, true))
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Reference in a new issue