Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

⚛️ Hydrate the blocks with Directives Hydration (using wp-block and wp-inner-blocks) #66

Merged
merged 20 commits into from
Sep 13, 2022

Conversation

DAreRodz
Copy link
Collaborator

@DAreRodz DAreRodz commented Sep 7, 2022

Tracking issue: #64

This PR uses the toVdom() function from preact-markup to hydrate blocks inside a single vDOM tree.

It uses <wp-block> and <wp-inner-blocks> tags to detect both block components and children.

  • Fix preact hooks
  • Get block props from data-wp-block-props
  • Get attributes from data-wp-block-attributes
  • Handle sourced attributes defined in data-wp-block-sourced-attributes

I'm planning to implement these directives in a different PR, to test how it could be done with the preact option hooks API.

  • Expose attributes defined in data-wp-block-provides-block-context
  • Consume attributes defined in data-wp-block-uses-block-context

@DAreRodz DAreRodz self-assigned this Sep 7, 2022
@DAreRodz DAreRodz changed the title Generate the vDOM tree from the DOM and hydrate blocks Hydrate the blocks with full vDOM (using wp-block and wp-inner-blocks) Sep 7, 2022
@DAreRodz
Copy link
Collaborator Author

DAreRodz commented Sep 8, 2022

For context, using components from different entry points was failing because each entry point had its own instance of preact/hooks, which needs to be a singleton to work correctly. This is fixed in 99635c4 by specifying runtimeChunk (props to @luisherranz). 🎉

@DAreRodz DAreRodz marked this pull request as ready for review September 13, 2022 07:57
@DAreRodz
Copy link
Collaborator Author

I consider this PR ready to review. There is a problem with hydration, though, that it is not working correctly (elements are being regenerated). We should investigate that.

cc: @luisherranz

Copy link
Member

@luisherranz luisherranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, David!

I think it's ready to merge, and we can continue in other PRs. I've asked a few questions, though.

Also, I'm not sure yet if it'd be better to use the visitor pattern or Preact options. I'm inclined to think Preact options are safer.

package.json Outdated Show resolved Hide resolved
src/blocks/interactive-child/register-view.js Outdated Show resolved Hide resolved
src/blocks/interactive-parent/register-view.js Outdated Show resolved Hide resolved
webpack.config.js Outdated Show resolved Hide resolved
visitor.map = components;

const dom = document.querySelector('.wp-site-blocks');
const vdom = toVdom(dom, visitor, createElement, {}).props.children;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need .props.children here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because you run hydrate on the parent element (wp-site-blocks), but you pass the vdom of the content (wp-site-blocks works as a wrapper).

We can change this with a better approach in the future. 🙂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. I'm using createRootFragment for that 🙂

src/gutenberg-packages/to-vdom.js Outdated Show resolved Hide resolved
return text;
}
if (n.nodeType !== 1) return null;
let nodeName = String(n.nodeName).toLowerCase();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is there a possibility that a node name is not in lowercase?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the node is an Element, it always return the uppercase name (e.g. DIV for <div>). 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I was using node.localName 🙂

src/gutenberg-packages/to-vdom.js Outdated Show resolved Hide resolved
src/gutenberg-packages/to-vdom.js Outdated Show resolved Hide resolved
src/gutenberg-packages/to-vdom.js Outdated Show resolved Hide resolved
Comment on lines +122 to +126
// The block content comes between two line breaks that seem to be included during block
// serialization, corresponding to those between the block markup and the block content.
//
// They need to be removed here; otherwise, the preact hydration fails.
return sprintf($block_wrapper, substr($block_content, 1, -1));
Copy link
Collaborator Author

@DAreRodz DAreRodz Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left a note here explaining the fix for the Preact hydration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be fixed in Gutenberg itself.

@DAreRodz DAreRodz merged commit 7f5d00e into main-full-vdom-hydration Sep 13, 2022
@DAreRodz DAreRodz deleted the full-vdom/hydrate-vdom-from-dom branch September 13, 2022 15:50
@luisherranz luisherranz changed the title Hydrate the blocks with full vDOM (using wp-block and wp-inner-blocks) ⚛️ Hydrate the blocks with full vDOM (using wp-block and wp-inner-blocks) Sep 13, 2022
@luisherranz luisherranz changed the title ⚛️ Hydrate the blocks with full vDOM (using wp-block and wp-inner-blocks) ⚛️ Hydrate the blocks with Directives Hydration (using wp-block and wp-inner-blocks) Jan 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants