diff --git a/cypress/e2e/nodes/Preview.spec.js b/cypress/e2e/nodes/Preview.spec.js index ab90ca0769..74d3c41d89 100644 --- a/cypress/e2e/nodes/Preview.spec.js +++ b/cypress/e2e/nodes/Preview.spec.js @@ -28,7 +28,7 @@ import { createCustomEditor } from './../../support/components.js' import testData from '../../fixtures/Preview.md' import { loadMarkdown, runCommands, expectMarkdown } from './helpers.js' -describe.only('Preview extension', { retries: 0 }, () => { +describe('Preview extension', { retries: 0 }, () => { const editor = createCustomEditor({ content: '', @@ -71,23 +71,34 @@ describe.only('Preview extension', { retries: 0 }, () => { expect(editor.can().setPreview()).to.be.false }) - it('can run on a paragraph with a link', () => { + it('convert a paragraph with a link', () => { prepareEditor('[link text](https://nextcloud.com)\n') - expect(editor.can().setPreview()).to.be.true + editor.commands.setPreview() + expectPreview() }) - it('can run the second a paragraph with a link', () => { + it('convert the second a paragraph with a link', () => { prepareEditor('hello\n\n[link text](https://nextcloud.com)\n') editor.commands.setTextSelection(10) - expect(editor.can().setPreview()).to.be.true + editor.commands.setPreview() + expectPreview() + }) + + it('convert a paragraph with a link and a space', () => { + prepareEditor('[link text](https://nextcloud.com)\n') + editor.commands.insertContentAt( + editor.state.doc.content.size - 1, + ' ', + { updateSelection: false }, + ) + editor.commands.setPreview() + expectPreview() }) it('results in a preview node with the href and text with link mark', () => { prepareEditor('[link text](https://nextcloud.com)\n') editor.commands.setPreview() - expect(getParentNode().type.name).to.equal('preview') - expect(getParentNode().attrs.href).to.equal('https://nextcloud.com') - expect(getMark().attrs.href).to.equal('https://nextcloud.com') + expectPreview() }) it('cannot run twice', () => { @@ -131,6 +142,15 @@ describe.only('Preview extension', { retries: 0 }, () => { }) + /** + * Expect a preview in the editor. + */ + function expectPreview() { + expect(getParentNode().type.name).to.equal('preview') + expect(getParentNode().attrs.href).to.equal('https://nextcloud.com') + expect(getMark().attrs.href).to.equal('https://nextcloud.com') + } + /** * */ diff --git a/cypress/fixtures/Preview.md b/cypress/fixtures/Preview.md index f912504604..93233867a6 100644 --- a/cypress/fixtures/Preview.md +++ b/cypress/fixtures/Preview.md @@ -14,10 +14,10 @@ empty [link text](https://nextcloud.com) -## Preserves a link preview +## Preserves a link preview - TODO [link text](https://nextcloud.com (Preview)) --- -[link text](https://nextcloud.com (Preview)) +[link text](https://nextcloud.com "Preview") diff --git a/src/nodes/Preview.js b/src/nodes/Preview.js index 98eaef15c3..412705f34c 100644 --- a/src/nodes/Preview.js +++ b/src/nodes/Preview.js @@ -93,13 +93,12 @@ export default Node.create({ }, /** - * Turn a preview back into a paragraph - * that contains a single link. + * Turn a preview back into a paragraph with a link. * */ unsetPreview: () => ({ state, chain }) => { console.info(this.attributes) - return isPreview(this.name, this.attributes, state) + return isActive(this.name, this.attributes, state) && chain() .setNode('paragraph') .run() @@ -110,9 +109,11 @@ export default Node.create({ }) /** + * Attributes for a preview from link in the current selection * - * @param root0 - * @param root0.selection + * @param {object} state the edior state + * @param {object} state.selection current selection + * @return {object} */ function previewAttributesFromSelection({ selection }) { const { $from } = selection @@ -121,24 +122,26 @@ function previewAttributesFromSelection({ selection }) { } /** - * - * @param typeOrName - * @param attributes - * @param state + * Is the active node one of typeOrName with the given attributes + * @param {object|string} typeOrName type or name of the preview node type + * @param {object} attributes attributes of the node + * @param {object} state current editor state + * @return {boolean} */ -function isPreview(typeOrName, attributes, state) { +function isActive(typeOrName, attributes, state) { const type = getNodeType(typeOrName, state.schema) return isNodeActive(state, type, attributes) } /** - * - * @param root0 - * @param root0.selection + * Is it possible to convert the currently selected node into a preview? + * @param {object} state current editor state + * @param {object} state.selection current selection + * @return {boolean} */ function previewPossible({ selection }) { const { $from } = selection - if (childCount($from.parent) > 1) { + if (hasOtherContent($from.parent)) { return false } const href = extractHref($from.nodeAfter) @@ -149,18 +152,21 @@ function previewPossible({ selection }) { } /** - * - * @param node + * Does the node contain more content than the first child + * @param {object} node node to inspect + * @return {boolean} */ -function extractHref(node) { - const link = node.marks.find(mark => mark.type.name === 'link') - return link?.attrs.href +function hasOtherContent(node) { + return node.childCount > 2 + || (node.childCount === 2 && node.lastChild.textContent.trim()) } /** - * - * @param node + * Get the link href of the given node + * @param {object} node to inspect + * @return {string} The href of the link mark of the node */ -function childCount(node) { - return node.content.content.length +function extractHref(node) { + const link = node.marks.find(mark => mark.type.name === 'link') + return link?.attrs.href }