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

Trailing whitespaces are trimmed from the end of inline <strong> element when page is being parsed by Vue #11122

Open
kfirba opened this issue Feb 18, 2020 · 19 comments

Comments

@kfirba
Copy link

kfirba commented Feb 18, 2020

Version

2.6.10

Reproduction link

https://jsfiddle.net/kfirba2/us5h04f7/5/

Steps to reproduce

  1. Have a wrapper for Vue
  2. Inside that wrapper, insert an inline element such as <strong> and leave trailing whitespace at the end of it:
<div id="#app">
  This is <strong>BOLD </strong>text
</div>
  1. After the page is parsed with Vue (and Vue has generated a Virtual DOM for the page), the words "BOLD" and "text" will be glued together (the whitespace after the word "BOLD" and before the enclosing tag of <strong> is removed.

What is expected?

It is expected that the whitespace will remain in its place and not trimmed.

What is actually happening?

The trailing whitespace is trimmed.

@despreston
Copy link
Contributor

despreston commented Feb 19, 2020

I think #11065 pr will fix this.

@kfirba
Copy link
Author

kfirba commented Feb 19, 2020

@despreston I’m not sure it’s going to solve it. The PR focuses on the template compiler if I’m not mistaken. The issue here is the DOM that Vue mounts on and parses into virtual DOM on the fly

@Justineo
Copy link
Member

Justineo commented Feb 20, 2020

Hi. What's your use case of using

<strong>BOLD </strong>text

instead of this?

<strong>BOLD</strong> text

@kfirba
Copy link
Author

kfirba commented Feb 20, 2020

@Justineo Hey,

You are absolutely right that it is not natural, however, our website is Vue powered and some of the website's content is UGC. Users are using some sort of a WYSIWYG and never write HTML. Because of that reason, we, nor them, have any good control of the generated HTML. We tried solving that in some ways but it looks like we couldn't achieve a satisfiable solution.

@Justineo
Copy link
Member

I assume you won't need Vue to parse and compile the UGC code. You can try put a v-pre directive on the wrapper element around your UGC so that Vue will skip that part.

@kfirba
Copy link
Author

kfirba commented Feb 20, 2020

@Justineo I wasn't aware of the v-pre directive so thanks for that.

However, it is not entirely true. The way we have it working is that the user (who is not always a "random" user, but may be an editor) has a WYSIWYG where he can also "inject" custom elements which are Vue elements, such as Lead Forms. So the UGC content has Vue elements within it For example:

<div id="#app">
  <p>Text Text Text....</p>
  <lead-form></lead-form>
  <p>...</p>
  <another-element></another-element>
  ...
</div>

@kfirba
Copy link
Author

kfirba commented Feb 24, 2020

@Justineo Hey, is there anything new with that?

@s-gbz
Copy link

s-gbz commented Mar 6, 2020

Correct me if I'm wrong, but isn't skipping whitespaces default behaviour in HTML?
You usually have to insert whitespaces manualy as &nbsp;.

@Garito
Copy link

Garito commented Mar 6, 2020

Sometimes you will need something like since webpack (if I recall correctly) removes all spaces

@kfirba
Copy link
Author

kfirba commented Mar 7, 2020

@s-gbz only subsequent spaces. Multiple spaces are “collapsed” into 1 space visually. In the source code you will find all of the spaces.

This is obviously a bug. Webpack has nothing do to with it as we are talking about Vue mounting on an existing DOM which has never gone any compilation/transpiration step (rendered with PHP)

@abrahamguo
Copy link

Is this something I can look into? @kfirba I agree, this seems like a bug.

@abrahamguo
Copy link

After investigating this issue, I can see that it is caused by this function:

function trimEndingWhitespace (el) {
	// remove trailing whitespace node
	if (!inPre) {
		var lastNode;
		while (
			(lastNode = el.children[el.children.length - 1]) &&
			lastNode.type === 3 &&
			lastNode.text === ' '
		) {
			el.children.pop();
		}
	}
}

which removes ending whitespace. Does anyone know the reasoning behind this function?

@kfirba
Copy link
Author

kfirba commented Apr 2, 2020

@abrahamguo anything new regarding this issue?

@abrahamguo
Copy link

Nope. I found the code for it in the core but I need the advice of people more knowledgeable than me to advise the purpose of this code. Otherwise, you could maybe dig through the history to find why this code was added.

@galaxy-s10
Copy link

@s-gbz only subsequent spaces. Multiple spaces are “collapsed” into 1 space visually. In the source code you will find all of the spaces.

This is obviously a bug. Webpack has nothing do to with it as we are talking about Vue mounting on an existing DOM which has never gone any compilation/transpiration step (rendered with PHP)

Is this something I can look into? @kfirba I agree, this seems like a bug.

Version

2.6.10

Reproduction link

https://jsfiddle.net/kfirba2/us5h04f7/5/

Steps to reproduce

  1. Have a wrapper for Vue
  2. Inside that wrapper, insert an inline element such as <strong> and leave trailing whitespace at the end of it:
<div id="#app">
  This is <strong>BOLD </strong>text
</div>
  1. After the page is parsed with Vue (and Vue has generated a Virtual DOM for the page), the words "BOLD" and "text" will be glued together (the whitespace after the word "BOLD" and before the enclosing tag of <strong> is removed.

What is expected?

It is expected that the whitespace will remain in its place and not trimmed.

What is actually happening?

The trailing whitespace is trimmed.

我认为#11065 pr将解决此问题。

我认为#11065 pr将解决此问题。

cccccccccc

@galaxy-s10
Copy link

Version

2.6.10

Reproduction link

https://jsfiddle.net/kfirba2/us5h04f7/5/

Steps to reproduce

  1. Have a wrapper for Vue
  2. Inside that wrapper, insert an inline element such as <strong> and leave trailing whitespace at the end of it:
<div id="#app">
  This is <strong>BOLD </strong>text
</div>
  1. After the page is parsed with Vue (and Vue has generated a Virtual DOM for the page), the words "BOLD" and "text" will be glued together (the whitespace after the word "BOLD" and before the enclosing tag of <strong> is removed.

What is expected?

It is expected that the whitespace will remain in its place and not trimmed.

What is actually happening?

The trailing whitespace is trimmed.

test

@galaxy-s10
Copy link

@despreston I’m not sure it’s going to solve it. The PR focuses on the template compiler if I’m not mistaken. The issue here is the DOM that Vue mounts on and parses into virtual DOM on the fly

test

@weblogjacob
Copy link

What is the status of this ticket? I have exactly the same problem with some UGC.

<p>This is a<em> </em>paragraph</p>

will be compiled to

<p>This is a<em></em>paragraph</p>

Not the result I am hoping for. The v-pre directive does nothing and the whitespace compiler option does not have any effect.

@kirya-dev
Copy link

Going 2021 years... Without changes?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants