Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Leftovers of name prop migration + fix @ in user ids (richEditor) #4222

Merged
merged 1 commit into from Jun 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was intentional, because we agreed to use the term title only if if relates to the HTML attribute title, which it does not here.
Is there a deeper problem with renaming the prop here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the problem was that the property of the menububble was renamed from label to title, but the menububble and the autocompleteresult share the same data.

Also I think that in this case title is the more logical name for this property usage.

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"')
})
})
})