-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
add insertContent logic to setContent #4895
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
97cf1f2
add demos for setContent, let setContent use same logic as insertCont…
bdbch 3783c24
Merge branch 'main' into bdbch/refactor-set-content
bdbch fa560f0
Merge branch 'main' into bdbch/refactor-set-content
nperez0111 1ed48ba
fix: insertContentAt now supports an empty fragment
nperez0111 751f06a
test: add some more tests of what the behavior should be
nperez0111 49f41e1
test: one more test
nperez0111 6da6344
feat: keep backwards compatibility with previous versions
nperez0111 be8ad4d
Merge branch 'develop' into bdbch/refactor-set-content
bdbch beb8f05
chore: fix lint
nperez0111 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import './styles.scss' | ||
|
||
import { Color } from '@tiptap/extension-color' | ||
import ListItem from '@tiptap/extension-list-item' | ||
import Mentions from '@tiptap/extension-mention' | ||
import TextStyle from '@tiptap/extension-text-style' | ||
import { EditorProvider } from '@tiptap/react' | ||
import StarterKit from '@tiptap/starter-kit' | ||
import React from 'react' | ||
|
||
const extensions = [ | ||
Color.configure({ types: [TextStyle.name, ListItem.name] }), | ||
TextStyle.configure({ types: [ListItem.name] }), | ||
StarterKit.configure({ | ||
bulletList: { | ||
keepMarks: true, | ||
}, | ||
orderedList: { | ||
keepMarks: true, | ||
}, | ||
}), | ||
Mentions, | ||
] | ||
|
||
const content = '' | ||
|
||
export default () => { | ||
return ( | ||
<EditorProvider extensions={extensions} content={content}></EditorProvider> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
context('/src/Commands/SetContent/React/', () => { | ||
before(() => { | ||
cy.visit('/src/Commands/SetContent/React/') | ||
}) | ||
|
||
beforeEach(() => { | ||
cy.get('.tiptap').type('{selectall}{backspace}') | ||
}) | ||
|
||
it('should insert raw text content', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('Hello World.') | ||
cy.get('.tiptap').should('contain.html', '<p>Hello World.</p>') | ||
}) | ||
}) | ||
|
||
it('should emit updates', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
let updateCount = 0 | ||
const callback = () => { | ||
updateCount += 1 | ||
} | ||
|
||
editor.on('update', callback) | ||
// emit an update | ||
editor.commands.setContent('Hello World.', true) | ||
expect(updateCount).to.equal(1) | ||
|
||
updateCount = 0 | ||
// do not emit an update | ||
editor.commands.setContent('Hello World again.', false) | ||
expect(updateCount).to.equal(0) | ||
editor.off('update', callback) | ||
}) | ||
}) | ||
|
||
it('should insert more complex html content', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<h1>Welcome to Tiptap</h1><p>This is a paragraph.</p><ul><li><p>List Item A</p></li><li><p>List Item B</p><ul><li><p>Subchild</p></li></ul></li></ul>') | ||
cy.get('.tiptap').should('contain.html', '<h1>Welcome to Tiptap</h1><p>This is a paragraph.</p><ul><li><p>List Item A</p></li><li><p>List Item B</p><ul><li><p>Subchild</p></li></ul></li></ul>') | ||
}) | ||
}) | ||
|
||
it('should remove newlines and tabs', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>Hello\n\tworld\n\t\thow\n\t\t\tnice.</p>') | ||
cy.get('.tiptap').should('contain.html', '<p>Hello world how nice.</p>') | ||
}) | ||
}) | ||
|
||
it('should keep newlines and tabs when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>Hello\n\tworld\n\t\thow\n\t\t\tnice.</p>', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '<p>Hello\n\tworld\n\t\thow\n\t\t\tnice.</p>') | ||
}) | ||
}) | ||
|
||
it('should overwrite existing content', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>Initial Content</p>') | ||
cy.get('.tiptap').should('contain.html', '<p>Initial Content</p>') | ||
}) | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>Overwritten Content</p>') | ||
cy.get('.tiptap').should('contain.html', '<p>Overwritten Content</p>') | ||
}) | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('Content without tags') | ||
cy.get('.tiptap').should('contain.html', '<p>Content without tags</p>') | ||
}) | ||
}) | ||
|
||
it('should insert mentions', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p><span data-type="mention" data-id="1" data-label="John Doe">@John Doe</span></p>') | ||
cy.get('.tiptap').should('contain.html', '<span data-type="mention" data-id="1" data-label="John Doe" contenteditable="false">@John Doe</span>') | ||
}) | ||
}) | ||
|
||
it('should remove newlines and tabs between html fragments', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<h1>Tiptap</h1>\n\t<p><strong>Hello World</strong></p>') | ||
cy.get('.tiptap').should('contain.html', '<h1>Tiptap</h1><p><strong>Hello World</strong></p>') | ||
}) | ||
}) | ||
|
||
// TODO I'm not certain about this behavior and what it should do... | ||
// This exists in insertContentAt as well | ||
it('should keep newlines and tabs between html fragments when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<h1>Tiptap</h1>\n\t<p><strong>Hello World</strong></p>', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '<h1>Tiptap</h1><p>\n\t</p><p><strong>Hello World</strong></p>') | ||
}) | ||
}) | ||
|
||
it('should allow inserting nothing', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('') | ||
cy.get('.tiptap').should('contain.html', '') | ||
}) | ||
}) | ||
|
||
it('should allow inserting nothing when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '') | ||
}) | ||
}) | ||
|
||
it('should allow inserting a partial HTML tag', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>foo') | ||
cy.get('.tiptap').should('contain.html', '<p>foo</p>') | ||
}) | ||
}) | ||
|
||
it('should allow inserting a partial HTML tag when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<p>foo', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '<p>foo</p>') | ||
}) | ||
}) | ||
|
||
it('will remove an incomplete HTML tag', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('foo<p') | ||
cy.get('.tiptap').should('contain.html', '<p>foo</p>') | ||
}) | ||
}) | ||
|
||
// TODO I'm not certain about this behavior and what it should do... | ||
// This exists in insertContentAt as well | ||
it('should allow inserting an incomplete HTML tag when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('foo<p', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '<p>foo<p</p>') | ||
}) | ||
}) | ||
|
||
it('should allow inserting a list', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<ul><li>ABC</li><li>123</li></ul>') | ||
cy.get('.tiptap').should('contain.html', '<ul><li><p>ABC</p></li><li><p>123</p></li></ul>') | ||
}) | ||
}) | ||
|
||
it('should allow inserting a list when preserveWhitespace = full', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('<ul><li>ABC</li><li>123</li></ul>', false, { preserveWhitespace: 'full' }) | ||
cy.get('.tiptap').should('contain.html', '<ul><li><p>ABC</p></li><li><p>123</p></li></ul>') | ||
}) | ||
}) | ||
|
||
it('should remove newlines and tabs when parseOptions.preserveWhitespace=false', () => { | ||
cy.get('.tiptap').then(([{ editor }]) => { | ||
editor.commands.setContent('\n<h1>Tiptap</h1><p><strong>Hello\n World</strong>\n</p>\n', false, { preserveWhitespace: false }) | ||
cy.get('.tiptap').should('contain.html', '<h1>Tiptap</h1><p><strong>Hello World</strong></p>') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* Basic editor styles */ | ||
.tiptap { | ||
> * + * { | ||
margin-top: 0.75em; | ||
} | ||
|
||
ul, | ||
ol { | ||
padding: 0 1rem; | ||
} | ||
|
||
h1, | ||
h2, | ||
h3, | ||
h4, | ||
h5, | ||
h6 { | ||
line-height: 1.1; | ||
} | ||
|
||
code { | ||
background-color: rgba(#616161, 0.1); | ||
color: #616161; | ||
} | ||
|
||
pre { | ||
background: #0D0D0D; | ||
color: #FFF; | ||
font-family: 'JetBrainsMono', monospace; | ||
padding: 0.75rem 1rem; | ||
border-radius: 0.5rem; | ||
|
||
code { | ||
color: inherit; | ||
padding: 0; | ||
background: none; | ||
font-size: 0.8rem; | ||
} | ||
} | ||
|
||
img { | ||
max-width: 100%; | ||
height: auto; | ||
} | ||
|
||
blockquote { | ||
padding-left: 1rem; | ||
border-left: 2px solid rgba(#0D0D0D, 0.1); | ||
} | ||
|
||
hr { | ||
border: none; | ||
border-top: 2px solid rgba(#0D0D0D, 0.1); | ||
margin: 2rem 0; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was removed because
commands.clearContent
relies onsetContent
to be able to reset the document to the initial schema. This was early exiting and causing a no-op makingclearContent
not actually clear anything.This is very old code that wasn't very well documented but after some testing, I'm confident in this not "leading to strange errors".
insertContentAt
is much more robust than when this was written.I tested inserting empty content into a node and a block and it essentially resulted in a no-op.