Skip to content

Commit

Permalink
Merge pull request #4222 from nextcloud/fix/menu-bubble-at-in-user-name
Browse files Browse the repository at this point in the history
Fix: Leftovers of `name` prop migration + fix `@` in user ids (richEditor)
  • Loading branch information
susnux committed Jun 27, 2023
2 parents d7ef68f + cb532ca commit 1dcaadf
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 21 deletions.
9 changes: 6 additions & 3 deletions CHANGELOG.md
Expand Up @@ -6,10 +6,13 @@ All notable changes to this project will be documented in this file.
[Full Changelog](https://github.com/nextcloud/nextcloud-vue/compare/v7.11.2...v8.0.0-beta.1)

### :boom: Breaking changes
- The deprecated `NcPopoverMenu` component was removed [\#4088](https://github.com/nextcloud/nextcloud-vue/pull/4088) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `NcPopoverMenu` component was removed [\#4081](https://github.com/nextcloud/nextcloud-vue/pull/4081) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `NcAppNavigationCounter` component was removed [\#4096](https://github.com/nextcloud/nextcloud-vue/pull/4096) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `title` property was removed and the `name` propery is now required for `NcActions*`, `NcAppNavigationItem` and `NcBreadcrumb*` [\#4052](https://github.com/nextcloud/nextcloud-vue/pull/4052) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `excludeClickOutsideClasses` property was removed from `clickOutsideOptions` [\#4052](https://github.com/nextcloud/nextcloud-vue/pull/4052) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `excludeClickOutsideClasses` property was removed from `clickOutsideOptions` [\#4088](https://github.com/nextcloud/nextcloud-vue/pull/4088) ([raimund-schluessler](https://github.com/raimund-schluessler))
- The deprecated `title` property was removed, every occurrence of `title` was renamed to `name` [\#4106](https://github.com/nextcloud/nextcloud-vue/pull/4106) ([raimund-schluessler](https://github.com/raimund-schluessler)),[\#4052](https://github.com/nextcloud/nextcloud-vue/pull/4052) ([raimund-schluessler](https://github.com/raimund-schluessler))
- `label` property was renamed to `name` for `NcMentionBubble`
- `name` propery is now required for `NcActions*`, `NcAppNavigationItem` and `NcBreadcrumb*`
- See linked pull request for full migration guide

### :rocket: Enhancements
- feat\(NcNoteCard\): Add new 'info' version to display informational messaged [\#4063](https://github.com/nextcloud/nextcloud-vue/pull/4063) ([moan0s](https://github.com/moan0s))
Expand Down
10 changes: 5 additions & 5 deletions src/components/NcRichContenteditable/NcAutoCompleteResult.vue
Expand Up @@ -32,10 +32,10 @@
</div>
</div>

<!-- Label and subline -->
<!-- Title and subline -->
<span class="autocomplete-result__content">
<span class="autocomplete-result__label">
{{ label }}
<span class="autocomplete-result__title" :title="title">
{{ title }}
</span>
<span v-if="subline" class="autocomplete-result__subline">
{{ subline }}
Expand All @@ -51,7 +51,7 @@ export default {
name: 'NcAutoCompleteResult',
props: {
label: {
title: {
type: String,
required: true,
},
Expand Down Expand Up @@ -180,7 +180,7 @@ $autocomplete-padding: 10px;
padding-left: $autocomplete-padding;
}
&__label,
&__title,
&__subline {
white-space: nowrap;
overflow: hidden;
Expand Down
22 changes: 11 additions & 11 deletions src/components/NcRichContenteditable/NcRichContenteditable.vue
Expand Up @@ -64,14 +64,14 @@ export default {
Test01: {
icon: 'icon-user',
id: 'Test01',
label: 'Test01',
title: 'Test01',
source: 'users',
primary: true,
},
Test02: {
icon: 'icon-user',
id: 'Test02',
label: 'Test02',
title: 'Test02',
source: 'users',
status: {
clearAt: null,
Expand All @@ -81,10 +81,10 @@ export default {
},
subline: 'Visiting London',
},
'Test 03': {
'Test@User': {
icon: 'icon-user',
id: 'Test 03',
label: 'Test 03',
id: 'Test@User',
title: 'Test 03',
source: 'users',
status: {
clearAt: null,
Expand All @@ -97,7 +97,7 @@ export default {
'Test Offline': {
icon: 'icon-user',
id: 'Test Offline',
label: 'Test Offline',
title: 'Test Offline',
source: 'users',
status: {
clearAt: null,
Expand All @@ -110,7 +110,7 @@ export default {
'Test DND': {
icon: 'icon-user',
id: 'Test DND',
label: 'Test DND',
title: 'Test DND',
source: 'users',
status: {
clearAt: null,
Expand Down Expand Up @@ -279,8 +279,8 @@ export default {
// Allow spaces in the middle of mentions
allowSpaces: true,
fillAttr: 'id',
// Search against id and label (display name)
lookup: result => `${result.id} ${result.label}`,
// Search against id and title (display name)
lookup: result => `${result.id} ${result.title}`,
// Where to inject the menu popup
menuContainer: this.menuContainer,
// Popup mention autocompletion templates
Expand Down Expand Up @@ -348,7 +348,7 @@ export default {
// Where to inject the menu popup
menuContainer: this.menuContainer,
// Popup mention autocompletion templates
menuItemTemplate: item => `<img class="tribute-container-link__item__icon" src="${item.original.icon_url}"> <span class="tribute-container-link__item__label">${item.original.title}</span>`,
menuItemTemplate: item => `<img class="tribute-container-link__item__icon" src="${item.original.icon_url}"> <span class="tribute-container-link__item__title">${item.original.title}</span>`,
// Hide if no results
noMatchTemplate: () => t('No link provider found'),
selectTemplate: this.getLink,
Expand Down Expand Up @@ -815,7 +815,7 @@ export default {
&__item {
display: flex;
align-items: center;
&__label {
&__title {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
Expand Down
4 changes: 2 additions & 2 deletions src/mixins/richEditor/index.js
Expand Up @@ -66,8 +66,8 @@ export default {
return Linkify(part)
}

// Extracting the id, nuking the " and @
const id = part.replace(/@|&quot;/gi, '')
// Extracting the id, nuking the leading @ and all "
const id = part.slice(1).replace(/&quot;/gi, '')
// Compiling template and prepend with the space we removed during the split
return ' ' + this.genSelectTemplate(id)
})
Expand Down
94 changes: 94 additions & 0 deletions tests/unit/mixins/richEditor.spec.js
@@ -0,0 +1,94 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import { shallowMount } from '@vue/test-utils'
import richEditor from '../../../src/mixins/richEditor/index.js'

const TestEditor = {
mixins: [richEditor],
render: (h) => h('div'),
}

describe('richEditor.js', () => {
'use strict'

describe('renderContent', () => {
it('sanitizes the input', () => {
const editor = shallowMount(TestEditor, { propsData: { userData: {} } })
const input = 'Some <table>html</table>'
const output = editor.vm.renderContent(input)

expect(output).toEqual('Some &lt;table&gt;html&lt;/table&gt;')
})

it('converts newline to hard line breaks', () => {
const editor = shallowMount(TestEditor, { propsData: { userData: {} } })
const input = 'hard\nbreak'
const output = editor.vm.renderContent(input)

expect(output).toEqual('hard<br>break')
})

it('no duplicated ampersand (from Linkify)', () => {
const editor = shallowMount(TestEditor, { propsData: { userData: {} } })
const input = 'hello &'
const output = editor.vm.renderContent(input)

expect(output).toEqual('hello &amp;')
})

it('keeps mentions without user data', () => {
const editor = shallowMount(TestEditor, { propsData: { userData: {} } })
const input = 'hello @foobar'
const output = editor.vm.renderContent(input)

expect(output).toEqual('hello @foobar')
})

it('keeps mentions with user data', () => {
const editor = shallowMount(TestEditor, {
propsData: {
userData: {
jdoe: {
id: 'jdoe',
title: 'J. Doe',
source: 'users',
icon: 'icon-user',
},
},
},
})
const input = 'hello @jdoe'
const output = editor.vm.renderContent(input)

expect(output).toMatch(/^hello <span.+role="heading" title="J. Doe"/)
})

it('keep mentions with special characters', () => {
const editor = shallowMount(TestEditor, { propsData: { userData: {} } })
const input = 'hello @foo@bar - hello @"bar @ foo"'
const output = editor.vm.renderContent(input)

expect(output).toEqual('hello @foo@bar - hello @"bar @ foo"')
})
})
})

0 comments on commit 1dcaadf

Please sign in to comment.