Merge branch 'disjointed-popovers' into shigusegubu

* disjointed-popovers:
  limit width of popover to slightly lesser than screen width
  don't hide on clicks in popover's content
  use user popovers in notifications as well
  properly center user popovers
  user popovers WIP
  fix tests
  fix popovers in modals
  recalculate position on scrolls
  remove duplicate buttons on post buttons
  fix animations, replace ugly old mentionlink tooltips with new usercard ones
  fix popovers so that all of them have shadows
  turns out it is needed still + some code cleanup
  vPadding is no longer needed
  hide popovers on scroll
  more fixes to chat popovers
  popup offsets should be fixed now
  experimental disjointed popups
shigusegubu
Henry Jameson 2 years ago
commit 197cc3d458
  1. 3
      src/App.js
  2. 2
      src/App.scss
  3. 1
      src/App.vue
  4. 2
      src/components/chat_message/chat_message.vue
  5. 4
      src/components/extra_buttons/extra_buttons.vue
  6. 8
      src/components/mention_link/mention_link.js
  7. 7
      src/components/mention_link/mention_link.scss
  8. 133
      src/components/mention_link/mention_link.vue
  9. 4
      src/components/notification/notification.js
  10. 39
      src/components/notification/notification.vue
  11. 161
      src/components/popover/popover.js
  12. 45
      src/components/popover/popover.vue
  13. 5
      src/components/react_button/react_button.vue
  14. 2
      src/components/settings_modal/tabs/general_tab.vue
  15. 4
      src/components/status/status.js
  16. 38
      src/components/status/status.vue
  17. 2
      src/components/status_popover/status_popover.vue
  18. 2
      src/i18n/en.json
  19. 23
      test/unit/specs/components/rich_content.spec.js

@ -4,7 +4,6 @@ import InstanceSpecificPanel from './components/instance_specific_panel/instance
import FeaturesPanel from './components/features_panel/features_panel.vue'
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
import ShoutPanel from './components/shout_panel/shout_panel.vue'
import SettingsModal from './components/settings_modal/settings_modal.vue'
import MediaModal from './components/media_modal/media_modal.vue'
import SideDrawer from './components/side_drawer/side_drawer.vue'
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
@ -32,7 +31,7 @@ export default {
MobilePostStatusButton,
MobileNav,
DesktopNav,
SettingsModal,
SettingsModal: defineAsyncComponent(() => import('./components/settings_modal/settings_modal.vue')),
UserReportingModal,
PostStatusModal,
GlobalNoticeList

@ -829,7 +829,7 @@ option {
// Vue transitions
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.2s;
transition: opacity 0.3s;
}
.fade-enter-from,

@ -55,6 +55,7 @@
<SettingsModal />
<div id="modal" />
<GlobalNoticeList />
<div id="popovers" />
</div>
</template>

@ -44,7 +44,7 @@
<Popover
trigger="click"
placement="top"
:bound-to-selector="isCurrentUser ? '' : '.scrollable-message-list'"
bound-to-selector=".chat-view-inner"
:bound-to="{ x: 'container' }"
:margin="popoverMarginStyle"
@show="menuOpened = true"

@ -119,12 +119,12 @@
</div>
</template>
<template v-slot:trigger>
<button class="button-unstyled popover-trigger">
<span class="button-unstyled popover-trigger">
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="ellipsis-h"
/>
</button>
</span>
</template>
</Popover>
</template>

@ -2,6 +2,7 @@ import generateProfileLink from 'src/services/user_profile_link_generator/user_p
import { mapGetters, mapState } from 'vuex'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import UserAvatar from '../user_avatar/user_avatar.vue'
import { defineAsyncComponent } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAt
@ -14,7 +15,9 @@ library.add(
const MentionLink = {
name: 'MentionLink',
components: {
UserAvatar
UserAvatar,
Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
UserCard: defineAsyncComponent(() => import('../user_card/user_card.vue'))
},
props: {
url: {
@ -36,6 +39,7 @@ const MentionLink = {
},
methods: {
onClick () {
if (this.shouldShowTooltip) return
const link = generateProfileLink(
this.userId || this.user.id,
this.userScreenName || this.user.screen_name
@ -110,7 +114,7 @@ const MentionLink = {
}
},
shouldShowTooltip () {
return this.mergedConfig.mentionLinkShowTooltip && this.mergedConfig.mentionLinkDisplay === 'short' && this.isRemote
return this.mergedConfig.mentionLinkShowTooltip
},
shouldShowAvatar () {
return this.mergedConfig.mentionLinkShowAvatar

@ -101,7 +101,6 @@
}
&:hover .new .full {
opacity: 1;
pointer-events: initial;
}
@ -113,3 +112,9 @@
color: var(--faint, $fallback--faint);
}
}
.mention-link-popover {
max-width: 70ch;
max-height: 20rem;
overflow: hidden;
}

@ -9,66 +9,85 @@
class="original"
target="_blank"
v-html="content"
/><!-- eslint-enable vue/no-v-html --><span
v-if="user"
class="new"
:style="style"
:class="classnames"
/><!-- eslint-enable vue/no-v-html -->
<Popover
trigger="click"
:bound-to="{ x: 'container'}"
bound-to-selector=".column"
popover-class="popover-default mention-popover"
:disabled="!shouldShowTooltip"
>
<a
class="short button-unstyled"
:class="{ '-with-tooltip': shouldShowTooltip }"
:href="url"
@click.prevent="onClick"
>
<!-- eslint-disable vue/no-v-html -->
<UserAvatar
v-if="shouldShowAvatar"
class="mention-avatar"
:user="user"
/><span
class="shortName"
><FAIcon
v-if="useAtIcon"
size="sm"
icon="at"
class="at"
/>{{ !useAtIcon ? '@' : '' }}<span
class="userName"
v-html="userName"
/><span
v-if="shouldShowFullUserName"
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
</span>
<span
v-if="isYou && shouldShowYous"
:class="{ '-you': shouldBoldenYou }"
> {{ ' ' + $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html -->
</a><span
v-if="shouldShowTooltip"
class="full popover-default"
:class="[highlightType]"
>
<template v-slot:trigger>
<span
class="userNameFull"
v-if="user"
class="new"
:style="style"
:class="classnames"
>
<!-- eslint-disable vue/no-v-html -->
@<span
class="userName"
v-html="userName"
/><span
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
<!-- eslint-enable vue/no-v-html -->
</span>
</span>
</span>
<a
class="short button-unstyled"
:class="{ '-with-tooltip': shouldShowTooltip }"
:href="url"
@click.prevent="onClick"
>
<!-- eslint-disable vue/no-v-html -->
<UserAvatar
v-if="shouldShowAvatar"
class="mention-avatar"
:user="user"
/><span
class="shortName"
><FAIcon
v-if="useAtIcon"
size="sm"
icon="at"
class="at"
/>{{ !useAtIcon ? '@' : '' }}<span
class="userName"
v-html="userName"
/><span
v-if="shouldShowFullUserName"
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
</span>
<span
v-if="isYou && shouldShowYous"
:class="{ '-you': shouldBoldenYou }"
> {{ ' ' + $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html -->
</a><span
v-if="shouldShowTooltip"
class="full"
>
<span
class="userNameFull"
>
<!-- eslint-disable vue/no-v-html -->
@<span
class="userName"
v-html="userName"
/><span
class="serverName"
:class="{ '-faded': shouldFadeDomain }"
v-html="'@' + serverName"
/>
<!-- eslint-enable vue/no-v-html -->
</span>
</span>
</span></template>
<template v-slot:content>
<UserCard
class="mention-link-popover"
:user-id="user.id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</span>
</template>

@ -5,6 +5,7 @@ import UserAvatar from '../user_avatar/user_avatar.vue'
import UserCard from '../user_card/user_card.vue'
import Timeago from '../timeago/timeago.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
import Popover from '../popover/popover.vue'
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
@ -46,7 +47,8 @@ const Notification = {
UserCard,
Timeago,
Status,
RichContent
RichContent,
Popover
},
methods: {
toggleUserExpanded () {

@ -34,21 +34,36 @@
<a
class="avatar-container"
:href="$router.resolve(userProfileLink).href"
@click.stop.prevent.capture="toggleUserExpanded"
@click.prevent
>
<UserAvatar
:compact="true"
:better-shadow="betterShadow"
:user="notification.from_profile"
/>
<Popover
trigger="click"
popover-class="popover-default user-popover"
:overlay-centers="true"
overlay-centers-selector=".user-info-avatar-link .Avatar"
>
<template v-slot:trigger>
<UserAvatar
class="post-avatar"
:bot="botIndicator"
:compact="true"
:better-shadow="betterShadow"
:user="notification.from_profile"
/>
</template>
<template v-slot:content>
<UserCard
class="mention-link-popover"
:user-id="getUser(notification).id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</a>
<div class="notification-right">
<UserCard
v-if="userExpanded"
:user-id="getUser(notification).id"
:rounded="true"
:bordered="true"
/>
<span class="notification-details">
<div class="name-and-action">
<!-- eslint-disable vue/no-v-html -->

@ -31,13 +31,24 @@ const Popover = {
// If true, subtract padding when calculating position for the popover,
// use it when popover offset looks to be different on top vs bottom.
removePadding: Boolean
removePadding: Boolean,
// self-explanatory (i hope)
disabled: Boolean,
// Instead of putting popover next to anchor, overlay popover's center on top of anchor's center
overlayCenters: Boolean,
// What selector (witin popover!) to use for determining center of popover
overlayCentersSelector: String
},
data () {
return {
hidden: true,
styles: { opacity: 0 },
oldSize: { width: 0, height: 0 }
styles: {},
oldSize: { width: 0, height: 0 },
// used to avoid blinking if hovered onto popover
graceTimeout: null
}
},
methods: {
@ -47,9 +58,7 @@ const Popover = {
},
updateStyles () {
if (this.hidden) {
this.styles = {
opacity: 0
}
this.styles = {}
return
}
@ -57,14 +66,26 @@ const Popover = {
// its children are what are inside the slot. Expect only one v-slot:trigger.
const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el
// SVGs don't have offsetWidth/Height, use fallback
const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth
const anchorHeight = anchorEl.offsetHeight || anchorEl.clientHeight
const screenBox = anchorEl.getBoundingClientRect()
// Screen position of the origin point for popover
const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top }
const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth
const anchorScreenBox = anchorEl.getBoundingClientRect()
const anchorStyle = getComputedStyle(anchorEl)
const topPadding = parseFloat(anchorStyle.paddingTop)
const bottomPadding = parseFloat(anchorStyle.paddingBottom)
// Screen position of the origin point for popover = center of the anchor
const origin = {
x: anchorScreenBox.left + anchorWidth * 0.5,
y: anchorScreenBox.top + anchorHeight * 0.5
}
const content = this.$refs.content
const overlayCenter = this.overlayCentersSelector
? this.$refs.content.querySelector(this.overlayCentersSelector)
: null
// Minor optimization, don't call a slow reflow call if we don't have to
const parentBounds = this.boundTo &&
const parentScreenBox = this.boundTo &&
(this.boundTo.x === 'container' || this.boundTo.y === 'container') &&
this.containerBoundingClientRect()
@ -73,64 +94,85 @@ const Popover = {
// What are the screen bounds for the popover? Viewport vs container
// when using viewport, using default margin values to dodge the navbar
const xBounds = this.boundTo && this.boundTo.x === 'container' ? {
min: parentBounds.left + (margin.left || 0),
max: parentBounds.right - (margin.right || 0)
min: parentScreenBox.left + (margin.left || 0),
max: parentScreenBox.right - (margin.right || 0)
} : {
min: 0 + (margin.left || 10),
max: window.innerWidth - (margin.right || 10)
}
const yBounds = this.boundTo && this.boundTo.y === 'container' ? {
min: parentBounds.top + (margin.top || 0),
max: parentBounds.bottom - (margin.bottom || 0)
min: parentScreenBox.top + (margin.top || 0),
max: parentScreenBox.bottom - (margin.bottom || 0)
} : {
min: 0 + (margin.top || 50),
max: window.innerHeight - (margin.bottom || 5)
}
let horizOffset = 0
let vertOffset = 0
if (overlayCenter) {
const box = content.getBoundingClientRect()
const overlayCenterScreenBox = overlayCenter.getBoundingClientRect()
const leftInnerOffset = overlayCenterScreenBox.left - box.left
const topInnerOffset = overlayCenterScreenBox.top - box.top
horizOffset = -leftInnerOffset - overlayCenter.offsetWidth * 0.5
vertOffset = -topInnerOffset - overlayCenter.offsetWidth * 0.5
} else {
horizOffset = content.offsetWidth * -0.5
vertOffset = content.offsetWidth * -0.5
}
const leftBorder = origin.x + horizOffset
const rightBorder = origin.x - horizOffset
// If overflowing from left, move it so that it doesn't
if ((origin.x - content.offsetWidth * 0.5) < xBounds.min) {
horizOffset += -(origin.x - content.offsetWidth * 0.5) + xBounds.min
if (leftBorder < xBounds.min) {
horizOffset += xBounds.min - leftBorder
}
// If overflowing from right, move it so that it doesn't
if ((origin.x + horizOffset + content.offsetWidth * 0.5) > xBounds.max) {
horizOffset -= (origin.x + horizOffset + content.offsetWidth * 0.5) - xBounds.max
if (rightBorder > xBounds.max) {
horizOffset -= rightBorder - xBounds.max
}
// Default to whatever user wished with placement prop
let usingTop = this.placement !== 'bottom'
let translateX = 0
let translateY = 0
// Handle special cases, first force to displaying on top if there's not space on bottom,
// regardless of what placement value was. Then check if there's not space on top, and
// force to bottom, again regardless of what placement value was.
if (origin.y + content.offsetHeight > yBounds.max) usingTop = true
if (origin.y - content.offsetHeight < yBounds.min) usingTop = false
if (overlayCenter) {
translateX = origin.x + horizOffset
translateY = origin.y + vertOffset
} else {
// Default to whatever user wished with placement prop
let usingTop = this.placement !== 'bottom'
let vPadding = 0
if (this.removePadding && usingTop) {
const anchorStyle = getComputedStyle(anchorEl)
vPadding = parseFloat(anchorStyle.paddingTop) + parseFloat(anchorStyle.paddingBottom)
}
// Handle special cases, first force to displaying on top if there's not space on bottom,
// regardless of what placement value was. Then check if there's not space on top, and
// force to bottom, again regardless of what placement value was.
const topBoundary = origin.y - anchorHeight * 0.5 + (this.removePadding ? topPadding : 0)
const bottomBoundary = origin.y + anchorHeight * 0.5 - (this.removePadding ? bottomPadding : 0)
if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true
if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false
const yOffset = (this.offset && this.offset.y) || 0
const translateY = usingTop
? -anchorHeight + vPadding - yOffset - content.offsetHeight
: yOffset
const yOffset = (this.offset && this.offset.y) || 0
translateY = usingTop
? topBoundary - yOffset - content.offsetHeight
: bottomBoundary + yOffset
const xOffset = (this.offset && this.offset.x) || 0
const translateX = anchorWidth * 0.5 - content.offsetWidth * 0.5 + horizOffset + xOffset
const xOffset = (this.offset && this.offset.x) || 0
translateX = origin.x + horizOffset + xOffset
}
// Note, separate translateX and translateY avoids blurry text on chromium,
// single translate or translate3d resulted in blurry text.
this.styles = {
opacity: 1,
transform: `translateX(${Math.round(translateX)}px) translateY(${Math.round(translateY)}px)`
left: `${Math.round(translateX)}px`,
top: `${Math.round(translateY)}px`
}
if (parentScreenBox) {
this.styles.maxWidth = `${Math.round(parentScreenBox.width)}px`
}
},
showPopover () {
if (this.disabled) return
const wasHidden = this.hidden
this.hidden = false
this.$nextTick(() => {
@ -141,13 +183,30 @@ const Popover = {
hidePopover () {
if (!this.hidden) this.$emit('close')
this.hidden = true
this.styles = { opacity: 0 }
},
onMouseenter (e) {
if (this.trigger === 'hover') this.showPopover()
if (this.trigger === 'hover') {
clearTimeout(this.graceTimeout)
this.graceTimeout = null
this.showPopover()
}
},
onMouseleave (e) {
if (this.trigger === 'hover') this.hidePopover()
if (this.trigger === 'hover') {
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
}
},
onMouseenterContent (e) {
if (this.trigger === 'hover') {
clearTimeout(this.graceTimeout)
this.graceTimeout = null
this.showPopover()
}
},
onMouseleaveContent (e) {
if (this.trigger === 'hover') {
this.graceTimeout = setTimeout(() => this.hidePopover(), 1)
}
},
onClick (e) {
if (this.trigger === 'click') {
@ -160,8 +219,12 @@ const Popover = {
},
onClickOutside (e) {
if (this.hidden) return
if (this.$refs.content.contains(e.target)) return
if (this.$el.contains(e.target)) return
this.hidePopover()
},
onScroll (e) {
this.updateStyles()
}
},
updated () {
@ -175,11 +238,17 @@ const Popover = {
this.oldSize = { width: content.offsetWidth, height: content.offsetHeight }
}
},
created () {
mounted () {
let scrollable = this.$refs.trigger.closest('.column.-scrollable')
if (!scrollable) scrollable = window
document.addEventListener('click', this.onClickOutside)
scrollable.addEventListener('scroll', this.onScroll)
},
unmounted () {
beforeUnmount () {
let scrollable = this.$refs.trigger.closest('.column.-scrollable')
if (!scrollable) scrollable = window
document.removeEventListener('click', this.onClickOutside)
scrollable.removeEventListener('scroll', this.onScroll)
this.hidePopover()
}
}

@ -1,5 +1,5 @@
<template>
<div
<span
@mouseenter="onMouseenter"
@mouseleave="onMouseleave"
>
@ -11,20 +11,26 @@
>
<slot name="trigger" />
</button>
<div
v-if="!hidden"
ref="content"
:style="styles"
class="popover"
:class="popoverClass || 'popover-default'"
>
<slot
name="content"
class="popover-inner"
:close="hidePopover"
/>
</div>
</div>
<teleport to="#popovers">
<transition name="fade">
<div
v-if="!hidden"
ref="content"
:style="styles"
class="popover"
:class="popoverClass || 'popover-default'"
@mouseenter="onMouseenterContent"
@mouseleave="onMouseleaveContent"
>
<slot
name="content"
class="popover-inner"
:close="hidePopover"
/>
</div>
</transition>
</teleport>
</span>
</template>
<script src="./popover.js" />
@ -37,14 +43,15 @@
}
.popover {
z-index: 500;
position: absolute;
z-index: 90000;
position: fixed;
min-width: 0;
max-width: 90vw;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
box-shadow: var(--popupShadow);
}
.popover-default {
transition: opacity 0.3s;
&:after {
content: '';
position: absolute;

@ -6,6 +6,7 @@
:offset="{ y: 5 }"
:bound-to="{ x: 'container' }"
remove-padding
popover-class="ReactButton popover-default"
@show="focusInput"
>
<template v-slot:content="{close}">
@ -40,7 +41,7 @@
</div>
</template>
<template v-slot:trigger>
<button
<span
class="button-unstyled popover-trigger"
:title="$t('tool_tip.add_reaction')"
>
@ -48,7 +49,7 @@
class="fa-scale-110 fa-old-padding"
:icon="['far', 'smile-beam']"
/>
</button>
</span>
</template>
</Popover>
</template>

@ -269,7 +269,7 @@
path="mentionLinkShowTooltip"
expert="1"
>
{{ $t('settings.mention_link_show_tooltip') }}
{{ $t('settings.mention_link_use_tooltip') }}
</BooleanSetting>
</li>
</ul>

@ -11,6 +11,7 @@ import Timeago from '../timeago/timeago.vue'
import StatusContent from '../status_content/status_content.vue'
import RichContent from 'src/components/rich_content/rich_content.jsx'
import StatusPopover from '../status_popover/status_popover.vue'
import Popover from '../popover/popover.vue'
import UserListPopover from '../user_list_popover/user_list_popover.vue'
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
@ -115,7 +116,8 @@ const Status = {
StatusContent,
RichContent,
MentionLink,
MentionsLine
MentionsLine,
Popover
},
props: [
'statusoid',

@ -122,17 +122,33 @@
v-if="!noHeading"
class="left-side"
>
<a
:href="$router.resolve(userProfileLink).href"
@click.stop.prevent.capture="toggleUserExpanded"
>
<UserAvatar
class="post-avatar"
:bot="botIndicator"
:compact="compact"
:better-shadow="betterShadow"
:user="status.user"
/>
<a :href="$router.resolve(userProfileLink).href" @click.prevent>
<Popover
trigger="click"
popover-class="popover-default user-popover"
:overlay-centers="true"
overlay-centers-selector=".user-info-avatar-link .Avatar"
>
<template v-slot:trigger>
<UserAvatar
class="post-avatar"
:bot="botIndicator"
:compact="compact"
:better-shadow="betterShadow"
:user="status.user"
/>
</template>
<template v-slot:content>
<UserCard
class="mention-link-popover"
:user-id="status.user.id"
:hide-bio="true"
:bordered="false"
:allow-zooming-avatar="true"
:rounded="true"
/>
</template>
</Popover>
</a>
</div>
<div class="right-side">

@ -52,8 +52,6 @@
border-width: 1px;
border-radius: $fallback--tooltipRadius;
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.5);
box-shadow: var(--popupShadow);
/* TODO cleanup this */
.Status.Status {

@ -523,7 +523,7 @@
"mention_link_display_short": "always as short names (e.g. {'@'}foo)",
"mention_link_display_full_for_remote": "as full names only for remote users (e.g. {'@'}foo{'@'}example.org)",
"mention_link_display_full": "always as full names (e.g. {'@'}foo{'@'}example.org)",
"mention_link_show_tooltip": "Show full user names as tooltip for remote users",
"mention_link_use_tooltip": "Show user card when clicking mention links",
"mention_link_show_avatar": "Show user avatar beside the link",
"mention_link_fade_domain": "Fade domains (e.g. {'@'}example.org in {'@'}foo{'@'}example.org)",
"mention_link_bolden_you": "Highlight mention of you when you are mentioned",

@ -4,7 +4,15 @@ import RichContent from 'src/components/rich_content/rich_content.jsx'
const attentions = []
const global = {
mocks: {
'$store': null
'$store': {
state: {},
getters: {
mergedConfig: () => ({
mentionLinkShowTooltip: true
}),
findUserByUrl: () => null
}
}
},
stubs: {
FAIcon: true
@ -131,8 +139,7 @@ describe('RichContent', () => {
].join(''),
[
makeMention('John'),
makeMention('Josh'),
makeMention('Jeremy')
makeMention('Josh'), makeMention('Jeremy')
].join('')
].join('\n')
@ -359,9 +366,9 @@ describe('RichContent', () => {
'</span>',
'</a>',
'<!-- eslint-enable vue/no-v-html -->',
'<!--v-if-->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
'<!---->', // vue placeholder
'</span>',
'<!--v-if-->', // v-if placeholder, mentionsline's extra mentions and stuff
'<!--v-if-->', // vue placeholder, mentionsline's extra mentions and stuff
'</span>'
),
p(
@ -422,7 +429,7 @@ describe('RichContent', () => {
'</span>',
'</a>',
'<!-- eslint-enable vue/no-v-html -->',
'<!--v-if-->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
'<!---->', // vue placeholder, mentionlink's "new" (i.e. rich) display
'</span>',
'<span class="MentionLink mention-link">',
'<!-- eslint-disable vue/no-v-html -->',
@ -435,9 +442,9 @@ describe('RichContent', () => {
'</span>',
'</a>',
'<!-- eslint-enable vue/no-v-html -->',
'<!--v-if-->', // v-if placeholder, mentionlink's "new" (i.e. rich) display
'<!---->', // vue placeholder, mentionlink's "new" (i.e. rich) display
'</span>',
'<!--v-if-->', // v-if placeholder, mentionsline's extra mentions and stuff
'<!--v-if-->', // vue placeholder, mentionsline's extra mentions and stuff
'</span>',
' ',
'</span>',

Loading…
Cancel
Save