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

Templates : HTML comments cause the Site Editor to crash. #47212

Closed
scruffian opened this issue Jan 17, 2023 · 4 comments · Fixed by #48129
Closed

Templates : HTML comments cause the Site Editor to crash. #47212

scruffian opened this issue Jan 17, 2023 · 4 comments · Fixed by #48129
Assignees
Labels
[Package] Blocks /packages/blocks [Type] Bug An existing feature does not function as intended

Comments

@scruffian
Copy link
Contributor

What problem does this address?

When testing #38984, the modified template causes the Site Editor to crash.

To replicate:

  1. Add an empty HTML comment to a template file in a block theme:
  2. Open the template in the Site Editor
  3. The Site Editor displays this error:

Screenshot 2023-01-17 at 16 39 29

What is your proposed solution?

We should allow HTMLs comment in template files!

@scruffian scruffian added [Package] Blocks /packages/blocks [Type] Bug An existing feature does not function as intended labels Jan 17, 2023
@mcsf
Copy link
Contributor

mcsf commented Jan 17, 2023

Here is what's happening:

  • Any HTML comment that isn't a Gutenberg block boundary is parsed by the parser as "freeform" content, in the same way that a stray piece of HTML would be if found outside of any blocks.
  • The Post and Site editors are configured to delegate the handling of freeform content to the Classic block.
  • The Classic block is an adaptor for an underlying TinyMCE instance.
  • TinyMCE is only loaded in the Post environment, so when the Classic block tries to invoke functions in the nonexisting wp.tinymce, we get a TypeError.

A few ideas on how to solve this at different layers. Most of these suggestions are mutually compatible:

  • I'd rather not touch the block parser itself. It's doing exactly as it was designed: returning nodes for any non-block piece of HTML it finds.
  • In the Site Editor, silently discard freeform nodes in the Site Editor if they only contain an HTML comment. If there's a freeform node with any actual HTML content, that should probably be surfaced up to the user.
  • or: In the Classic block, silently render nothing if given just an HTML comment (not sure how I feel about this one).
  • In the Classic block, explicitly test for the presence of TinyMCE, and show a dedicated notice if it isn't. This is a much nicer failure mode than the generic block error view.
  • In the Site Editor, consider setting the HTML Block as the handler of freeform content, instead of the Classic block.
  • I didn't look into this, but look at the initialisation logic in the block library (registerCoreBlocks), because we shouldn't be setting Classic block if the environment isn't complete.

@dmsnell
Copy link
Member

dmsnell commented Jan 17, 2023

thanks @mcsf for jumping in and investigating!

silently discard freeform nodes in the Site Editor if they only contain an HTML comment

sounds great to me! or build a small criterion for discarding them, since we could have the same kind of issues we've seen with extra newlines.

/**
 * Checks if given HTML is likely empty.
 *
 * Naive criteria for whether HTML represents meaningful content:
 *  - contains non-whitespace #text content, e.g. "this bare text implies HTML structure"
 *  - there exist _any_ tags/elements, e.g. "<div class=placeholder></div>"
 *
 * Specifically, these things are not considered meaningful content:
 *  - HTML comments
 *  - CDATA sections
 *  - "blank" #text nodes, e.g. newlines, medium mathematical space, non-breaking space
 */
const htmlLikelyEmpty = html => {
	const div = document.createElement( 'div' );
	div.innerHTML = html;

	// If we have text content then it's probably supposed to render.
	if ( div.innerText.trim() ) {
		return false;
	}

	for ( const { nodeType } of div.childNodes ) {
		// If we have any HTML elements we probably need to render
		// even if the text content is empty.
		if ( Node.ELEMENT_NODE === nodeType ) {
			return false;
		}
	}

	return true;
}

@ndiego ndiego moved this to ❓ Triage in WordPress 6.2 Editor Tasks Jan 19, 2023
@ndiego ndiego moved this from ❓ Triage to 📥 Todo in WordPress 6.2 Editor Tasks Jan 30, 2023
@kevin940726
Copy link
Member

This also happens if we just add an arbitrary HTML in the template file. For instance, add a <p>Hello World</p>.

In the Site Editor, consider setting the HTML Block as the handler of freeform content, instead of the Classic block.

I think this might be a better option as it's less destructive, and users can still keep their content no matter if it's accidentally added or not.

Comments-only freeform block can still be handled by not rendering anything in the visual editor, but available in the code editor. In the end, comments are code, not visible to the users, ...I think 😆 .

@oandregal
Copy link
Member

There's a follow-up for this issue that is tracked at #48408

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Blocks /packages/blocks [Type] Bug An existing feature does not function as intended
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

7 participants