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

Ensure cite is string when merging quote #10678

Merged
merged 3 commits into from
Oct 17, 2018
Merged

Ensure cite is string when merging quote #10678

merged 3 commits into from
Oct 17, 2018

Conversation

ellatrix
Copy link
Member

Description

When merging a paragraph with a quote, the citation is undefined and cast to a string.

screen shot 2018-10-17 at 10 10 03

How has this been tested?

Screenshots

Types of changes

Checklist:

  • My code is tested.
  • My code follows the WordPress code style.
  • My code follows the accessibility standards.
  • My code has proper inline documentation.

@ellatrix ellatrix added the [Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable label Oct 17, 2018
@ellatrix ellatrix added this to the 4.0 milestone Oct 17, 2018
@ellatrix ellatrix requested a review from a team October 17, 2018 08:18
@gziolo gziolo added the [Type] Bug An existing feature does not function as intended label Oct 17, 2018
@@ -50,6 +50,10 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) {
result[ key ] = schema.default;
}

if ( schema.source === 'html' && typeof result[ key ] !== 'string' ) {
Copy link
Member Author

Choose a reason for hiding this comment

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

This is similar to what was done with rich-text source before. It would create() here.

@@ -50,6 +50,10 @@ export function createBlock( name, blockAttributes = {}, innerBlocks = [] ) {
result[ key ] = schema.default;
}

if ( schema.source === 'html' && typeof result[ key ] !== 'string' ) {
result[ key ] = '';
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this change a little bit risky? e.g: some block may be comparing the attribute with undefining to check if the value does not exist and that may stop working now.
Also isn't there a risk a block may want to differentiate an HTML attribute being undefined (e.g: the query element was not found ) with an HTML attribute being empty (element exists but its content is empty )?
In this case, I would be inclined to just add a default value of the empty string in the merge function to reduce the risks.

Copy link
Member Author

Choose a reason for hiding this comment

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

(e.g: the query element was not found )

We currently already pass '' if the query is not found.

Alternative is to add default: '' everywhere.

Copy link
Member Author

Choose a reason for hiding this comment

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

And do you have a use case for the undefined? Note that ! value will still work.

Copy link
Member

@jorgefilipecosta jorgefilipecosta Oct 17, 2018

Choose a reason for hiding this comment

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

If we already pass '' if the query was not found I think everything seems fine. I was not aware of that. Sorry, I thought we passed undefined when the query did not match any selector.

Copy link
Member Author

@ellatrix ellatrix Oct 17, 2018

Choose a reason for hiding this comment

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

if ( ! match ) {
return '';
}

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer default everywhere or accounting for the undefined value in merges much more than to include ad hoc corrections in the factory.

It's also conflicting messaging when we went out of our way in #10338 to explicitly remove tolerances. If we'd kept the tolerances, I'd rather see something where we normalize undefined of type: 'string' to an empty string, but again still nothing targeting one specific source.

What's the issue with providing the default, aside from tedium / verbosity? I see it as no different (and thus extremely confusing in its consistency) from how we don't provide empty arrays for array types, zero's for number types, or an empty string for any other string types (what's the difference here between why we need an empty string here for assumed HTML stringiness and source: 'attribute'?).

At worst, I'd think we should codify this as a source-level default mapping.

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 find it a bit weird that plugin authors will have to provide the default value, and may forget about it. Otherwise we have to set the default in merge functions etc., but since even we forget about it, I think block authors might also forget about it and cause these preventable bugs.

Copy link
Member

Choose a reason for hiding this comment

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

That's all well and good as a goal, but targeting a resolution for something so specific is going to have negative consequences (i.e. bugs) elsewhere in setting people up for mixed expectations for what is and isn't normalized on their behalf.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay, then let's change it. I'm not sure what the right solution is here tbh.

Copy link
Member

Choose a reason for hiding this comment

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

I think it's a reasonable expectation on the part of the block author that if they want to assume an attribute is a string (i.e. in concatenating), they should assure that it is one, via default.

This doesn't mean we have to add the default for every source: 'html' attribute, if we're not actually making such an assumption. I think it's also perfectly reasonable to not define the default if the stringiness is not assumed but instead accounted-for in the implementation.

See: #10756

Copy link
Member

@gziolo gziolo left a comment

Choose a reason for hiding this comment

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

This solves the issue and improves merging blocks with Quote block nicely 👍

@ellatrix ellatrix merged commit 1c2282c into master Oct 17, 2018
@ellatrix ellatrix deleted the fix/quote-merge branch October 17, 2018 09:17
Copy link
Member

@jorgefilipecosta jorgefilipecosta left a comment

Choose a reason for hiding this comment

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

Everything looks good in my tests 👍

@@ -197,11 +197,18 @@ export const settings = {
);
},

merge( attributes, attributesToMerge ) {
merge( attributes, { value, citation } ) {
if ( ! value || value === '<p></p>' ) {
Copy link
Member

@aduth aduth Oct 18, 2018

Choose a reason for hiding this comment

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

This is interesting to me as well that it be required to test for. I understand it's a consequence of the multiline behavior, but (correct me if I'm wrong) it's still effectively an emptiness check, and as such it seems strange we'd need to fork logic for concatenating the value of an "empty" field. And also strange that, if it is a test of emptiness, that it not be something we could use RichText.isEmpty for.

Alternatively, should we account for this from RichText itself, never allowing '<p></p>' to become the value, but instead normalizing to--I assume--the empty string? This feels awfully reminiscent of inconsistencies we had ages ago with the RichText array vs. undefined values.

@ellatrix
Copy link
Member Author

ellatrix commented Oct 18, 2018 via email

@aduth aduth mentioned this pull request Oct 19, 2018
4 tasks
mcsf pushed a commit that referenced this pull request Nov 1, 2018
* Ensure cite is string when merging quote

* Ensure createBlock returns string for html source

* Don't merge empty paragraphs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Rich Text Related to the Rich Text component that allows developers to render a contenteditable [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