diff --git a/cypress/component/richtext.cy.ts b/cypress/component/richtext.cy.ts index 519068d7b9..28ae7e6f77 100644 --- a/cypress/component/richtext.cy.ts +++ b/cypress/component/richtext.cy.ts @@ -6,6 +6,19 @@ import NcRichText from '../../src/components/NcRichText/NcRichText.vue' describe('NcRichText', () => { describe('renders with markdown', () => { + describe('normal text', () => { + it('XML-like text (escaped and unescaped)', () => { + mount(NcRichText, { + propsData: { + text: 'text</span>', + useMarkdown: true, + }, + }) + + cy.get('p').should('have.text', 'text') + }) + }) + describe('headings', () => { it('heading (with hash (#) syntax divided with space from text)', () => { const testCases = [ @@ -274,6 +287,17 @@ describe('NcRichText', () => { cy.get('code').should('have.text', 'inline code') }) + + it('inline code (with ignored bold, italic, XML-like syntax))', () => { + mount(NcRichText, { + propsData: { + text: '`inline code **bold text** _italic text_ text</span>`', + useMarkdown: true, + }, + }) + + cy.get('code').should('have.text', 'inline code **bold text** _italic text_ text') + }) }) describe('multiline code', () => { @@ -333,20 +357,20 @@ describe('NcRichText', () => { cy.get('code').should('have.text', 'line 1\nline 2\nline 3\n') }) - it('multiline code (with ignored bold, italic, inline code syntax)', () => { + it('multiline code (with ignored bold, italic, inline code, XML-like syntax)', () => { mount(NcRichText, { propsData: { - text: '```\n**bold text**\n_italic text_\n`inline code`\n```', + text: '```\n**bold text**\n_italic text_\n`inline code`\ntext</span>\n```', useMarkdown: true, }, }) - cy.get('pre').should('have.text', '**bold text**\n_italic text_\n`inline code`\n') + cy.get('pre').should('have.text', '**bold text**\n_italic text_\n`inline code`\ntext\n') }) }) describe('blockquote', () => { - it('blockquote (with greater then (gt >) syntax)', () => { + it('blockquote (with greater then (>) syntax - normal)', () => { mount(NcRichText, { propsData: { text: '> blockquote', @@ -357,6 +381,17 @@ describe('NcRichText', () => { cy.get('blockquote').should('have.text', '\nblockquote\n') }) + it('blockquote (with greater then (>) syntax - escaped)', () => { + mount(NcRichText, { + propsData: { + text: '> blockquote', + useMarkdown: true, + }, + }) + + cy.get('blockquote').should('have.text', '\nblockquote\n') + }) + it('blockquote (with bold, italic text, inline code)', () => { mount(NcRichText, { propsData: { @@ -401,7 +436,7 @@ describe('NcRichText', () => { }, }) - cy.get('blockquote').should('have.text', '\nline 1\n\nline 3\n') + cy.get('blockquote').should('have.text', '\nline 1\nline 3\n') }) it('blockquote (with nested blockquote)', () => { diff --git a/l10n/messages.pot b/l10n/messages.pot index 47ffa24798..53bc1f1b16 100644 --- a/l10n/messages.pot +++ b/l10n/messages.pot @@ -242,5 +242,5 @@ msgstr "" msgid "Undo changes" msgstr "" -msgid "Write message, use \"@\" to mention someone, use \":\" for emoji autocompletion …" +msgid "Write a message …" msgstr "" diff --git a/package-lock.json b/package-lock.json index a88156dca9..66753fe08f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,9 +34,9 @@ "linkify-string": "^4.0.0", "md5": "^2.3.0", "node-polyfill-webpack-plugin": "^2.0.1", + "rehype-external-links": "^3.0.0", "rehype-react": "^7.1.2", "remark-breaks": "^3.0.2", - "remark-external-links": "^9.0.1", "remark-parse": "^10.0.1", "remark-rehype": "^10.1.0", "splitpanes": "^2.4.1", @@ -4403,6 +4403,11 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, "node_modules/@vue/compiler-core": { "version": "3.2.47", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", @@ -12413,6 +12418,26 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element/node_modules/@types/hast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.0.tgz", + "integrity": "sha512-SoytUJRuf68HXYqcXicQIhCrLQjqeYU2anikr4G3p3Iz+OZO5QDQpDj++gv+RenHsnUBwNZ2dumBArF8VLSk2Q==", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/hast-util-whitespace": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", @@ -20455,6 +20480,86 @@ "jsesc": "bin/jsesc" } }, + "node_modules/rehype-external-links": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", + "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-is-element": "^3.0.0", + "is-absolute-url": "^4.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-external-links/node_modules/@types/hast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.0.tgz", + "integrity": "sha512-SoytUJRuf68HXYqcXicQIhCrLQjqeYU2anikr4G3p3Iz+OZO5QDQpDj++gv+RenHsnUBwNZ2dumBArF8VLSk2Q==", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/rehype-external-links/node_modules/@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "node_modules/rehype-external-links/node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/rehype-external-links/node_modules/unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-external-links/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-external-links/node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/rehype-react": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-7.2.0.tgz", @@ -20503,36 +20608,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/remark-external-links": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-9.0.1.tgz", - "integrity": "sha512-EYw+p8Zqy5oT5+W8iSKzInfRLY+zeKWHCf0ut+Q5SwnaSIDGXd2zzvp4SWqyAuVbinNmZ0zjMrDKaExWZnTYqQ==", - "dependencies": { - "@types/hast": "^2.3.2", - "@types/mdast": "^3.0.0", - "extend": "^3.0.0", - "is-absolute-url": "^4.0.0", - "mdast-util-definitions": "^5.0.0", - "space-separated-tokens": "^2.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/remark-external-links/node_modules/is-absolute-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", - "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/remark-parse": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", @@ -30804,6 +30879,11 @@ } } }, + "@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + }, "@vue/compiler-core": { "version": "3.2.47", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.2.47.tgz", @@ -36986,6 +37066,24 @@ "web-namespaces": "^2.0.0" } }, + "hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "requires": { + "@types/hast": "^3.0.0" + }, + "dependencies": { + "@types/hast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.0.tgz", + "integrity": "sha512-SoytUJRuf68HXYqcXicQIhCrLQjqeYU2anikr4G3p3Iz+OZO5QDQpDj++gv+RenHsnUBwNZ2dumBArF8VLSk2Q==", + "requires": { + "@types/unist": "*" + } + } + } + }, "hast-util-whitespace": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", @@ -43023,6 +43121,66 @@ } } }, + "rehype-external-links": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/rehype-external-links/-/rehype-external-links-3.0.0.tgz", + "integrity": "sha512-yp+e5N9V3C6bwBeAC4n796kc86M4gJCdlVhiMTxIrJG5UHDMh+PJANf9heqORJbt1nrCbDwIlAZKjANIaVBbvw==", + "requires": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-is-element": "^3.0.0", + "is-absolute-url": "^4.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0" + }, + "dependencies": { + "@types/hast": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.0.tgz", + "integrity": "sha512-SoytUJRuf68HXYqcXicQIhCrLQjqeYU2anikr4G3p3Iz+OZO5QDQpDj++gv+RenHsnUBwNZ2dumBArF8VLSk2Q==", + "requires": { + "@types/unist": "*" + } + }, + "@types/unist": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz", + "integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w==" + }, + "is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==" + }, + "unist-util-is": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.0.tgz", + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "requires": { + "@types/unist": "^3.0.0" + } + }, + "unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, + "unist-util-visit-parents": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.1.tgz", + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "requires": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + } + } + } + }, "rehype-react": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/rehype-react/-/rehype-react-7.2.0.tgz", @@ -43159,28 +43317,6 @@ "unist-util-visit": "^4.0.0" } }, - "remark-external-links": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/remark-external-links/-/remark-external-links-9.0.1.tgz", - "integrity": "sha512-EYw+p8Zqy5oT5+W8iSKzInfRLY+zeKWHCf0ut+Q5SwnaSIDGXd2zzvp4SWqyAuVbinNmZ0zjMrDKaExWZnTYqQ==", - "requires": { - "@types/hast": "^2.3.2", - "@types/mdast": "^3.0.0", - "extend": "^3.0.0", - "is-absolute-url": "^4.0.0", - "mdast-util-definitions": "^5.0.0", - "space-separated-tokens": "^2.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - }, - "dependencies": { - "is-absolute-url": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", - "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==" - } - } - }, "remark-parse": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", diff --git a/package.json b/package.json index ab997ae24e..a43ffbb552 100644 --- a/package.json +++ b/package.json @@ -65,9 +65,9 @@ "linkify-string": "^4.0.0", "md5": "^2.3.0", "node-polyfill-webpack-plugin": "^2.0.1", + "rehype-external-links": "^3.0.0", "rehype-react": "^7.1.2", "remark-breaks": "^3.0.2", - "remark-external-links": "^9.0.1", "remark-parse": "^10.0.1", "remark-rehype": "^10.1.0", "splitpanes": "^2.4.1", diff --git a/src/components/NcAvatar/NcAvatar.vue b/src/components/NcAvatar/NcAvatar.vue index 69a844131b..83600cc531 100644 --- a/src/components/NcAvatar/NcAvatar.vue +++ b/src/components/NcAvatar/NcAvatar.vue @@ -700,6 +700,7 @@ export default { &--unknown { position: relative; background-color: var(--color-main-background); + white-space: normal; } &:not(&--unknown) { diff --git a/src/components/NcRichContenteditable/NcRichContenteditable.vue b/src/components/NcRichContenteditable/NcRichContenteditable.vue index d14577edd8..ad16c096af 100644 --- a/src/components/NcRichContenteditable/NcRichContenteditable.vue +++ b/src/components/NcRichContenteditable/NcRichContenteditable.vue @@ -27,6 +27,8 @@ This component displays contenteditable div with automated `@` [at] autocompleti ### Examples +Try mentioning user @Test01 or inserting emoji :smile + ```vue +``` -