-
Notifications
You must be signed in to change notification settings - Fork 4.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
Core Data: Remove dependencies on the block editor package #67687
Conversation
Size Change: +120 B (+0.01%) Total Size: 1.83 MB
ℹ️ View Unchanged
|
CI is fine with the refactoring. I would appreciate feedback if that direction is promising enough to take it to the finish line. |
@@ -106,7 +113,7 @@ export default function useEntityBlockEditor( kind, name, { id: _id } = {} ) { | |||
selection, | |||
content: ( { blocks: blocksForSerialization = [] } ) => | |||
__unstableSerializeAndClean( blocksForSerialization ), | |||
...updateFootnotesFromMeta( newBlocks, meta ), | |||
...onEditEntityRecord( newBlocks, meta ), |
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.
Could this be implemented with a filter? useEntityBlockEditor
could run all edits
through a filter before passing them to editEntityRecord
:
const edits = applyFilters( 'editor.editEntityRecord', { selection, content, blocks, meta } );
There is prior art with the editor.preSavePost
filter in the editor
package.
Then footnotes could act as a "feature plugin" that adds footnote functionality to various places with hooks.
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.
Sure, that works for me. I wanted to propose something with a real code to get the discussion going 😄
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'm not sure if using a filter just because of a dependency issue is the right solution. I think "core-data" knowing of "blocks" and "footnotes" is ok, it's actually the right thing to do (core-data knows about the WP entities and their content/structure). What we could get rid of is the dependency towards "block-editor" package which only exists because of the InnerBlocks.Content
if I'm not wrong.
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 we could get rid of is the dependency towards "block-editor" package which only exists because of the InnerBlocks.Content if I'm not wrong.
There are other dependencies involved, which are probably less unwanted:
import {
getSaveElement,
__unstableGetBlockProps as getBlockProps,
} from '@wordpress/blocks';
import { RichTextData } from '@wordpress/rich-text';
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 alternative is to reimplement InnerBlock.Content
and the rest using some primitives mirroring:
gutenberg/packages/block-editor/src/components/inner-blocks/index.js
Lines 306 to 312 in c20ad9f
useInnerBlocksProps.save = getInnerBlocksProps; | |
// Expose default appender placeholders as components. | |
ForwardedInnerBlocks.DefaultBlockAppender = DefaultBlockAppender; | |
ForwardedInnerBlocks.ButtonBlockAppender = ButtonBlockAppender; | |
ForwardedInnerBlocks.Content = () => useInnerBlocksProps.save().children; |
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 we could get rid of is the dependency towards "block-editor" package which only exists because of the
InnerBlocks.Content
if I'm not wrong.
Yes, it's right that core-data
knows about blocks, footnotes and rich text, the only problem is that it depends on block-editor
to do that. It should depend only on blocks
and rich-text
packages.
And eliminating block-editor
looks doable. The only function that core-data
uses from block-editor
is getRichTextValues
. That function is implemented using:
- some helpers from
blocks
andrich-text
- the
RichText.Content
andInnerBlocks.Content
components
In turn, RichText.Content
and InnerBlocks.Content
are very simple components implemented again using helpers from blocks
and rich-text
.
The code also relies on the identity of the RichText.Content
and InnerBlocks.Content
. These must be globally unique functions, because they are used like:
// create JSX element somewhere
const el = <InnerBlocks.Content />;
// inspect the element type somewhere else:
if ( el.type === InnerBlocks.Content ) { /* ... */ }
What we could do is:
- Move
getRichTextValues
fromblock-editor
toblocks
. It's easy because i) it's private API; ii) is used only at one place, incore-data
; iii) depends only on code fromelement
,blocks
andrich-text
, which are already dependencies ofblocks
. - Move the
RichText.Content
andInnerBlocks.Content
components also fromblock-editor
toblocks
. Also easy, they also depend only onblocks
andrich-text
code. - The
RichText
andInnerBlocks
components inblock-editor
will import and use theContent
components like this:import { RichTextContent, InnerBlocksContent } from '@wordpress/blocks'; RichText.Content = RichTextContent; InnerBlocks.Content = InnerBlocksContent;
That's all. The block-editor
dependency is eliminated and everything works as before. Also all the three functions/components naturally belong to blocks
because they are part of the save
pipeline. And parsing and serializing blocks is one of the main things the blocks
package does.
The RichText
and InnerBlocks
components in block-editor
have a lot of "edit" logic that belongs to block-editor
and should stay there. But the .Content
sub-components which contain the "save" logic can be imported. And anyone who checks the InnerBlocks.Content
value (from block-editor
) or the InnerBlocksContent
value (from block
) will see the same function. That's important for a lot of the serializing logic (renderToString
etc.) which uses code like
switch ( el.type ) {
case InnerBlocks.Content:
/* ... */
break;
case RichText.Content:
/* ... */
break;
}
How does that sound? @ellatrix should be much more familiar with this code than me, are there any gotchas I'm missing?
@jsnajdr outlined the path forward in #67687 (comment) that seems the most reasonable taking into account that there is a shared agreement that |
What?
Fixes #64604.
The same concern has been raised in the original PR
@wordpress/core-data
should not depend on@wordpress/block-editor
as they are independent packages that should be combined together to build any editor.Why?
How?
Testing Instructions
Testing Instructions for Keyboard
Screenshots or screencast