-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Try avoiding parse to get content of Editable #523
Conversation
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.
I like the idea. 👍 Seems everywhere we're using html-to-react
we have access to a DOM node anyways, so a nice optimization to skip the step of converting the string to a DOM.
@@ -0,0 +1,29 @@ | |||
import { createElement } from 'react'; |
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.
Since we'll need this in blocks/api/query.js
as well, we'll probably want to place the file somewhere more generic. Kinda ties to #408, as it seems in addition to component components, we'll need common utilities as well.
That, or we could just commit to individually publishing npm modules for the utilities we create.
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.
That, or we could just commit to individually publishing npm modules for the utilities we create.
If we don't depend on html-to-react anyway, I was thinking of just creating a separate package that has some options to handle nodes (like we need to ignore internal mce stuff).
If this works well, I'll go ahead and create a package for it. |
blocks/components/editable/index.js
Outdated
htmlToReactParser.parse( before ), | ||
htmlToReactParser.parse( after ) | ||
map( before, nodeToReact ), | ||
hasAfter ? map( childNodes.slice( splitIndex ), nodeToReact ) : '' |
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.
I think the fallback value shouldn't be a string here?
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.
null?
@aduth What do you have in mind for https://github.com/WordPress/gutenberg/blob/master/blocks/api/query.js? |
It's not obvious because we use export function children( selector ) {
return ( node ) => {
let match = node;
if ( selector ) {
match = node.querySelector( selector );
}
return nodeToReact( match );
};
} |
For me this seems to be working well now. |
return node.nodeValue; | ||
} | ||
|
||
if ( node.getAttribute( 'data-mce-bogus' ) === 'all' ) { |
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.
What's the plan for handling this and the below key.startsWith( 'data-mce-' )
when we make the utility more generic?
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.
Yeah, that's the next thing :)
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.
So right now you can pass the createElement callback, which means that you can filter stuff, there is no dependency on React, and you can use it with other React-like libraries.
const props = reduce( node.attributes, ( result, { name, value } ) => { | ||
let key = camelCaseAttrMap[ name.replace( /[-:]/, '' ) ] || name; | ||
|
||
if ( key.startsWith( 'data-mce-' ) ) { |
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.
We don't use babel-polyfill
, so we don't have access to ES2015 base type prototype methods like Array#includes
or String#startsWith
. This will error in IE11. We may consider incorporating the polyfill. It's not small though. But this is a common enough problem that it's probably worth considering since it's easy for a developer to overlook. That or some custom lint behaviors.
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.
Oh, didn't realise this.
match = node.querySelector( selector ); | ||
} | ||
|
||
if ( match ) { |
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.
Why can't we just return nodeToReact( match );
?
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.
Don't we need the childNodes here?
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.
Don't we need the childNodes here?
Yeah, you're right.
Just to clarify; I believe |
Maybe an option could be created for nodeListToReact( element, {
mapNode: ( node ) => {
switch ( node.getAttribute( 'data-mce-bogus' ) ) {
case 'all': return null;
case null: return node;
default: return node.childNodes;
}
},
mapAttribute: ( value, key ) => startsWith( 'data-mce-', key ) ? null : value
} ); |
You don't like the current solution? :) |
Oh, I think I missed the transition to passing in |
Yeah, it's also nice that it's very flexible, you can use it with other React-like libraries. |
60c5c68
to
c1e4aca
Compare
I added style support in the package, and this seems to be working well. Any concerns, thoughts? Mergeable? |
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.
Needs a rebase, but otherwise looks good 👍
This is just an experiment. Creating this branch to see what others think.
The current behaviour is DOM => HTML => DOM => VDOM (React). This change proposes DOM => VDOM (React) which would eliminate HTML => DOM parsing every time
getContent
is called.WIP