-
Notifications
You must be signed in to change notification settings - Fork 4.7k
RichText: Add a format prop to allow HTML string values to be used in RichText components #6034
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
Changes from 1 commit
cf196aa
d85b718
a3f4726
0bec108
dd9e099
2963b65
665c59e
db26521
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,7 @@ import { pickAriaProps } from './aria'; | |
| import patterns from './patterns'; | ||
| import { EVENTS } from './constants'; | ||
| import { withBlockEditContext } from '../block-edit/context'; | ||
| import { domToElement, domToString, elementToString } from './format'; | ||
| import { domToString, elementToString } from './format'; | ||
|
|
||
| const { BACKSPACE, DELETE, ENTER } = keycodes; | ||
|
|
||
|
|
@@ -476,8 +476,8 @@ export class RichText extends Component { | |
| const afterNodes = childNodes.slice( index + 1 ); | ||
|
|
||
| const { format } = this.props; | ||
| const before = format === 'string' ? domToString( beforeNodes ) : domToElement( beforeNodes ); | ||
| const after = format === 'string' ? domToString( afterNodes ) : domToElement( afterNodes ); | ||
| const before = domToFormat( beforeNodes, format ); | ||
| const after = domToFormat( afterNodes, format ); | ||
|
|
||
| this.restoreContentAndSplit( before, after ); | ||
| } else { | ||
|
|
@@ -571,9 +571,8 @@ export class RichText extends Component { | |
| const afterFragment = afterRange.extractContents(); | ||
|
|
||
| const { format } = this.props; | ||
| const before = format === 'string' ? domToString( beforeFragment.childNodes ) : domToElement( beforeFragment.childNodes ); | ||
| const filteredAfterFragment = filterEmptyNodes( afterFragment.childNodes ); | ||
| const after = format === 'string' ? domToString( filteredAfterFragment ) : domToElement( filteredAfterFragment ); | ||
| const before = domToFormat( beforeFragment.childNodes, format ); | ||
| const after = domToFormat( filterEmptyNodes( afterFragment.childNodes ), format ); | ||
|
|
||
| this.restoreContentAndSplit( before, after, blocks ); | ||
| } else { | ||
|
|
@@ -625,8 +624,8 @@ export class RichText extends Component { | |
|
|
||
| const { format } = this.props; | ||
| this.restoreContentAndSplit( | ||
| format === 'string' ? domToString( before ) : domToElement( before ), | ||
| format === 'string' ? domToString( after ) : domToElement( after ) | ||
| domToFormat( before, format ), | ||
| domToFormat( after, format ) | ||
| ); | ||
| } | ||
|
|
||
|
|
@@ -698,7 +697,7 @@ export class RichText extends Component { | |
| default: | ||
| return this.editor.dom.isEmpty( this.editor.getBody() ) ? | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aside: Is the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not an optimization, it's to ensure the paragraph block is considered empty consistently. If we remove it we can end up with content like
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get the sense this has been discussed before, but if we have control over the elements we're producing, why are we keeping the empty string ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't tell honestly :) maybe @iseulde can tell more here.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do we have control over that? This one is getting the nodes from a contenteditable field which can contain all sorts combination. I've seen |
||
| [] : | ||
| domToElement( this.editor.getBody().childNodes || [] ); | ||
| domToFormat( this.editor.getBody().childNodes || [], 'element' ); | ||
|
||
| } | ||
| } | ||
|
|
||
|
|
||
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.
In
domToElement, we're always stripping any TinyMCE internal element and attributes, but here we're not, even though there might be cases where we receive some in the case of splitting.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.
Not sure how to address this in an optimal way. Don't we have tools in TinyMCE to do this for us instead of adding custom logic? Is it a requirement since we're not using this when getting the whole content of the editor but only when splitting?
Uh oh!
There was an error while loading. Please reload this page.
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.
( new tinymce.dom.Serializer( {} ) ).serialize( el )? (Likely with some reuse of a serializer instance)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.
Thanks Andrew but unfortunately it's not working in my testing, we more likely have to specify the same rules used by TinyMCE internally
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.
Well, the content will end up getting passed to the store, so I guess so. On consecutive edits we may pass
getContentagain, but this doesn't necessarily happen. Say you split a paragraph in two and the first part contains some elements with internal attributes. This will be passed on eventually to (block)setAttributes.Not sure immediately how to fix either but I guess @aduth goes in the right direction. Maybe parse and serialise if you want to work on the string? I'll have a look if we can work on the fragment.
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.
Did a little test here: 39d9966
Splitting is currently entirely broken with the HTML format. The diff fixes it and should also get rid of internal stuff.
Uh oh!
There was an error while loading. Please reload this page.
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.
After the splitting fix, but without serialising, you'd get this:
when splitting the first paragraph of the demo content.
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.
(The splitting is broken because
element.outerHTMLdoesn't work on text nodes that are passed.)