From e010e7bca423a06fa9f78098643dcc70a069af93 Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 10:52:40 +0800 Subject: [PATCH 1/6] feat: Add control to the heading and list action buttons in the example default editor. --- demos/src/Examples/Default/React/index.jsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/demos/src/Examples/Default/React/index.jsx b/demos/src/Examples/Default/React/index.jsx index fddcfd2d30f..51513a983d2 100644 --- a/demos/src/Examples/Default/React/index.jsx +++ b/demos/src/Examples/Default/React/index.jsx @@ -84,48 +84,56 @@ const MenuBar = () => { From cd28cfcce42f45ac326234cfce962baad7cc7375 Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 11:43:45 +0800 Subject: [PATCH 2/6] feat: Add test cases to the example default editor to ensure that bullet list, ordered list, and heading are allowed to convert between each other. --- .../src/Examples/Default/React/index.spec.js | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/demos/src/Examples/Default/React/index.spec.js b/demos/src/Examples/Default/React/index.spec.js index 005560deeee..1166c22a2ae 100644 --- a/demos/src/Examples/Default/React/index.spec.js +++ b/demos/src/Examples/Default/React/index.spec.js @@ -10,6 +10,28 @@ context('/src/Examples/Default/React/', () => { }) }) + it('Heading, bulletList, and orderedList should be allowed to convert between each other.', () => { + cy.get('.tiptap h1').should('exist') + cy.get('.tiptap ul').should('not.exist') + cy.get('.tiptap ol').should('not.exist') + cy.get('button').contains('Bullet list').should('not.be.disabled') + cy.get('button').contains('Ordered list').should('not.be.disabled') + + cy.get('button').contains('Bullet list').click() + cy.get('.tiptap h1').should('not.exist') + cy.get('.tiptap ul').should('exist') + cy.get('.tiptap ol').should('not.exist') + cy.get('button').contains('H1').should('not.be.disabled') + cy.get('button').contains('Ordered list').should('not.be.disabled') + + cy.get('button').contains('Ordered list').click() + cy.get('.tiptap h1').should('not.exist') + cy.get('.tiptap ul').should('not.exist') + cy.get('.tiptap ol').should('exist') + cy.get('button').contains('H1').should('not.be.disabled') + cy.get('button').contains('Bullet list').should('not.be.disabled') + }) + it('should apply the paragraph style when the keyboard shortcut is pressed', () => { cy.get('.tiptap h1').should('exist') cy.get('.tiptap p').should('not.exist') From cc6df2cb2577c87150be949cf0ee726a03ad161c Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 11:44:22 +0800 Subject: [PATCH 3/6] fix: `shouldDispatch` should remain `true` in `can().chain().commands().run()` because the state required by later commands may depend on the commands executed earlier. --- packages/core/src/CommandManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/CommandManager.ts b/packages/core/src/CommandManager.ts index 21ad3844e3b..79d6f862dac 100644 --- a/packages/core/src/CommandManager.ts +++ b/packages/core/src/CommandManager.ts @@ -101,7 +101,7 @@ export class CommandManager { public createCan(startTr?: Transaction): CanCommands { const { rawCommands, state } = this - const dispatch = false + const dispatch = true const tr = startTr || state.tr const props = this.buildProps(tr, dispatch) const formattedCommands = Object.fromEntries( From c3d12d4f081135350f475058eb2848715a47898c Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 11:45:34 +0800 Subject: [PATCH 4/6] fix: If `defaultType.isTextBlock` is `false`, skip `tr.setNodeMarkType`, otherwise `clearNodes` will throw an exception during execution. --- packages/core/src/commands/clearNodes.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/src/commands/clearNodes.ts b/packages/core/src/commands/clearNodes.ts index 1e124063efa..63605a33630 100644 --- a/packages/core/src/commands/clearNodes.ts +++ b/packages/core/src/commands/clearNodes.ts @@ -42,7 +42,9 @@ export const clearNodes: RawCommands['clearNodes'] = () => ({ state, tr, dispatc if (node.type.isTextblock) { const { defaultType } = $mappedFrom.parent.contentMatchAt($mappedFrom.index()) - tr.setNodeMarkup(nodeRange.start, defaultType) + if (defaultType && defaultType.isTextblock) { + tr.setNodeMarkup(nodeRange.start, defaultType) + } } if (targetLiftDepth || targetLiftDepth === 0) { From adb6a8100c2bbaaeaac2f05880137c71b030cd39 Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 14:33:27 +0800 Subject: [PATCH 5/6] fix: Fix the issue in the test case, otherwise Cypress will detect two buttons, which will throw an exception and cause the test to fail. --- demos/src/Examples/Transition/Vue/index.spec.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/demos/src/Examples/Transition/Vue/index.spec.js b/demos/src/Examples/Transition/Vue/index.spec.js index 4185db85a80..1e0020f93bf 100644 --- a/demos/src/Examples/Transition/Vue/index.spec.js +++ b/demos/src/Examples/Transition/Vue/index.spec.js @@ -1,3 +1,5 @@ +/// + context('/src/Examples/Transition/Vue/', () => { beforeEach(() => { cy.visit('/src/Examples/Transition/Vue/') @@ -22,7 +24,7 @@ context('/src/Examples/Transition/Vue/', () => { cy.get('.tiptap').should('exist') cy.get('.tiptap').should('be.visible') - cy.get('button').click() + cy.get('button').contains('Hide editor').click() cy.get('.tiptap').should('not.exist') }) From 6b08af8d8819e22696a85f55025f789a17fe638b Mon Sep 17 00:00:00 2001 From: guanriyue Date: Mon, 21 Oct 2024 15:07:18 +0800 Subject: [PATCH 6/6] fix: In `can.chain`, `dispatch` should be guaranteed to be a function --- tests/cypress/integration/core/can.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cypress/integration/core/can.spec.ts b/tests/cypress/integration/core/can.spec.ts index 380892f44ca..78fefeb2de2 100644 --- a/tests/cypress/integration/core/can.spec.ts +++ b/tests/cypress/integration/core/can.spec.ts @@ -168,7 +168,7 @@ describe('can', () => { expect(canSetMarkToBold).to.eq(true) }) - it('builds and passes down an undefined dispatch for nested "can" chain', () => { + it('builds and passes down a function dispatch for nested "can" chain', () => { const editor = new Editor({ extensions: [Document, Paragraph, Text, History], }) @@ -191,8 +191,8 @@ describe('can', () => { .run() // eslint-disable-next-line no-unused-expressions - expect(capturedOuterDispatch).to.be.undefined + expect(capturedOuterDispatch).to.be.not.undefined // eslint-disable-next-line no-unused-expressions - expect(capturedInnerDispatch).to.be.undefined + expect(capturedInnerDispatch).to.be.not.undefined }) })