Skip to content
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

Element: Fix serializer handling of multiple distinct contexts #21156

Closed
wants to merge 6 commits into from

Conversation

aduth
Copy link
Member

@aduth aduth commented Mar 25, 2020

Fixes: #20721 (comment)
Previously: #8189, #5897

This pull request seeks to resolve an issue with the implementation of the custom @wordpress/element serializer where the a context consumer is only able to consume the value of the closest context provider, even if it is not of the same context type. As can be observed in the included test case, the result was that two distinct context providers would not interoperate.

Implementation Notes:

As described at #20721 (comment), the underlying problem is that when a provider renders its children, it replaces the current context recursion argument, which prevents multiple provider values from coexisting in the same element tree.

The proposed changes seek to resolve this by changing the context argument to a Map object, where a provider extends the map with its value. At the time the consumer is rendered, it performs a lookup of the provider's value using the components internal type._context.Provider value.

Testing Instructions:

Ensure unit tests pass:

npm run test-unit

@aduth aduth added [Type] Bug An existing feature does not function as intended [Package] Element /packages/element labels Mar 25, 2020
@aduth aduth requested a review from gziolo March 25, 2020 18:46
@aduth aduth mentioned this pull request Mar 25, 2020
6 tasks
@github-actions
Copy link

github-actions bot commented Mar 25, 2020

Size Change: +6.51 kB (0%)

Total Size: 863 kB

Filename Size Change
build/a11y/index.js 999 B +1 B
build/annotations/index.js 3.42 kB -7 B (0%)
build/api-fetch/index.js 3.39 kB +3 B (0%)
build/block-directory/index.js 6.01 kB -5 B (0%)
build/block-editor/index.js 101 kB +34 B (0%)
build/block-library/index.js 110 kB -34 B (0%)
build/block-serialization-default-parser/index.js 1.64 kB -2 B (0%)
build/block-serialization-spec-parser/index.js 3.1 kB -1 B
build/blocks/index.js 57.5 kB +24 B (0%)
build/components/index.js 190 kB -1.12 kB (0%)
build/compose/index.js 6.21 kB +1 B
build/core-data/index.js 10.6 kB -45 B (0%)
build/data/index.js 8.24 kB -15 B (0%)
build/date/index.js 5.36 kB -5 B (0%)
build/deprecated/index.js 772 B +1 B
build/edit-post/index.js 91.1 kB -81 B (0%)
build/edit-site/index.js 6.72 kB -14 B (0%)
build/edit-widgets/index.js 4.43 kB -3 B (0%)
build/editor/index.js 42.8 kB -7 B (0%)
build/element/index.js 12.3 kB +7.82 kB (63%) 🆘
build/format-library/index.js 6.94 kB -4 B (0%)
build/html-entities/index.js 621 B -1 B
build/i18n/index.js 3.49 kB +1 B
build/keyboard-shortcuts/index.js 2.3 kB -4 B (0%)
build/list-reusable-blocks/index.js 2.98 kB -8 B (0%)
build/media-utils/index.js 4.85 kB +5 B (0%)
build/nux/index.js 3 kB -6 B (0%)
build/plugins/index.js 2.54 kB +1 B
build/priority-queue/index.js 780 B -1 B
build/redux-routine/index.js 2.84 kB +5 B (0%)
build/rich-text/index.js 14.4 kB -18 B (0%)
build/server-side-render/index.js 2.54 kB -5 B (0%)
build/shortcode/index.js 1.7 kB -1 B
build/url/index.js 4.02 kB +3 B (0%)
build/viewport/index.js 1.61 kB +2 B (0%)
build/wordcount/index.js 1.17 kB -1 B
ℹ️ View Unchanged
Filename Size Change
build/autop/index.js 2.58 kB 0 B
build/blob/index.js 620 B 0 B
build/block-directory/style-rtl.css 760 B 0 B
build/block-directory/style.css 760 B 0 B
build/block-editor/style-rtl.css 10.9 kB 0 B
build/block-editor/style.css 10.9 kB 0 B
build/block-library/editor-rtl.css 7.22 kB 0 B
build/block-library/editor.css 7.23 kB 0 B
build/block-library/style-rtl.css 7.43 kB 0 B
build/block-library/style.css 7.44 kB 0 B
build/block-library/theme-rtl.css 669 B 0 B
build/block-library/theme.css 671 B 0 B
build/components/style-rtl.css 15.8 kB 0 B
build/components/style.css 15.7 kB 0 B
build/data-controls/index.js 1.04 kB 0 B
build/dom-ready/index.js 568 B 0 B
build/dom/index.js 3.06 kB 0 B
build/edit-post/style-rtl.css 8.43 kB 0 B
build/edit-post/style.css 8.43 kB 0 B
build/edit-site/style-rtl.css 2.91 kB 0 B
build/edit-site/style.css 2.9 kB 0 B
build/edit-widgets/style-rtl.css 2.57 kB 0 B
build/edit-widgets/style.css 2.57 kB 0 B
build/editor/editor-styles-rtl.css 428 B 0 B
build/editor/editor-styles.css 431 B 0 B
build/editor/style-rtl.css 3.38 kB 0 B
build/editor/style.css 3.38 kB 0 B
build/escape-html/index.js 733 B 0 B
build/format-library/style-rtl.css 502 B 0 B
build/format-library/style.css 502 B 0 B
build/hooks/index.js 1.93 kB 0 B
build/is-shallow-equal/index.js 710 B 0 B
build/keycodes/index.js 1.69 kB 0 B
build/list-reusable-blocks/style-rtl.css 226 B 0 B
build/list-reusable-blocks/style.css 226 B 0 B
build/notices/index.js 1.57 kB 0 B
build/nux/style-rtl.css 616 B 0 B
build/nux/style.css 613 B 0 B
build/primitives/index.js 1.5 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/warning/index.js 1.14 kB 0 B

compressed-size-action

Provider: SecondProvider,
} = createContext();

const result = renderElement(
Copy link
Member

Choose a reason for hiding this comment

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

I see that e2e tests fail for blocks that have nesting. I'm wondering if there should be another unit tests that replicate how InnerBlocks works, if I follow it properly it would be something like:

<FirstProvider value="First">
 	<FirstConsumer>
 		{ ( first ) => (
 			<SecondProvider value="Second">
 				<SecondConsumer>
 					{ ( second ) => `First: { first }, Second: ${ second }` }
 				</SecondConsumer>
			</SecondProvider>
 		) }
	</FirstConsumer>
</FirstProvider>

Although, I don't see any reason why it would make any difference.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm not really sure what's going on with the end-to-end tests, to be honest. I've not been able to reproduce those same failures in my local environment.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added a test case for this in 90dacf0 for good measure. It passes, as expected. Still struggling with the end-to-end tests in Travis.

Copy link
Member

Choose a reason for hiding this comment

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

I've just realized that we use one shared context for InnerBlocks so the following might be closer to the use case that fails on Travis:

<Provider value="outer">
 	<Consumer>
 		{ ( outter ) => (
 			< Provider value="inner">
 				<Consumer>
 					{ ( inner ) => `Outer: { outer }, Inner: ${ inner }` }
 				</Consumer>
			</Provider>
 		) }
	</Consumer>
</Provider>

I don't think it's much different from a similar existing test though. I can't think of any reason why it fails on Travis :(

Copy link
Member

Choose a reason for hiding this comment

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

Oh no :(

@aduth aduth force-pushed the fix/serialize-multi-context branch from 7704924 to 6313fad Compare March 26, 2020 13:00
@@ -36,6 +36,7 @@ import {
kebabCase,
isPlainObject,
} from 'lodash';
import CoreJSMap from 'core-js-pure/features/map';
Copy link
Member

Choose a reason for hiding this comment

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

Any reason why we use this?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's meant to be temporary, an experiment to see if it would fix the previously-observed issue to use a very predictable implementation.

Base automatically changed from master to trunk March 1, 2021 15:43
@annezazu annezazu closed this Jul 27, 2022
@gziolo gziolo deleted the fix/serialize-multi-context branch July 28, 2022 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Element /packages/element [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants