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

(fix) Fix the href not getting removed (#1943) #1965

Closed
wants to merge 21 commits into from

Conversation

cristianbote
Copy link
Member

@cristianbote cristianbote commented Oct 2, 2019

This fixes #1943

Adds +4B 🙁
Shaves -1B 😁
Adds +15B 😢
Adds +12B 😢

@cristianbote
Copy link
Member Author

Look into this and basically href property exists on dom. So, it's set to empty string when null value is passed along.

https://github.com/preactjs/preact/pull/1965/files#diff-642a704212e8abfc3d854f17a1aaacbeR101

@coveralls
Copy link

coveralls commented Oct 2, 2019

Coverage Status

Coverage increased (+0.1%) to 99.769% when pulling 75b2f0d on fix/skip-setter-for-href into 013dc38 on master.

Copy link
Member

@JoviDeCroock JoviDeCroock left a comment

Choose a reason for hiding this comment

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

Great work, thanks for digging in!

@marvinhagemeister
Copy link
Member

Is href the only attribute where that error pops up?

@cristianbote
Copy link
Member Author

@marvinhagemeister Well that's kinda the issue here. Basically anything that name in dom will end up with empty string, whenever it's gonna be removed from props.

I did tried that before and everything passed. But, is that the proper behaviour? Would it break custom elements 💯 support? 🤔

Copy link
Member

@developit developit left a comment

Choose a reason for hiding this comment

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

I think this might be possible to fix elsewhere. Specifically, this line makes it so that diffing props where a key has an undefined value with props where that key doesn't exist will not call setProperty(), because oldProps[key] === newProps[key]:

if ((!hydrate || typeof newProps[i]=='function') && i!=='value' && i!=='checked' && oldProps[i]!==newProps[i]) {

I believe it may be possible to circumvent this by changing the comparison in the oldProps diff to consider undefined values of new props to be a "removal":

	for (i in oldProps) {
-		if (!(i in newProps)) {
+		if (newProps[i] === undefined) {
			setProperty(dom, i, null, oldProps[i], isSvg);
		}
	}

Also it looks like the 8.x version of DOM property diffing actually always removed any corresponding attribute for null values. I don't know that we should adopt that approach again, but it seems it may have been to work around this issue.

if ((value==null || value===false) && name!='spellcheck') node.removeAttribute(name);

src/diff/props.js Outdated Show resolved Hide resolved
Copy link
Member

@marvinhagemeister marvinhagemeister left a comment

Choose a reason for hiding this comment

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

Just checked the spec regarding the failing test with <table border=""/>. We can safely remove that attribute as border will only have an effect when the value is 1 👍 So we just need to update our test :)

@cristianbote
Copy link
Member Author

This is breaking the uncontrolled input behaviour, which is true. Looking to fix that.

marvinhagemeister and others added 8 commits October 8, 2019 23:49
The way MobX works is that every observed component returns false
from shouldComponentUpdate unless props have changed. They than
trigger the child renders themselves via direct forceUpdate calls.

Our issue was that we only set the force flag sort-of globally
during a render and would ignore any children that have been
enqueued via forceUpdate in the same render cycle. With these
changes we ensure that the force flag is always the one from
the current component.
* Append portal node to container instead of prepend

This fixes the issue described in #1806. Expected test outcomes were
generated by taking the test code and running it with React instead of
Preact.

* Add additional test for portals testing ordering
@cristianbote
Copy link
Member Author

I think this is ready. The added size is bothering me but oh well. Let me know what you think

Copy link
Member

@JoviDeCroock JoviDeCroock left a comment

Choose a reason for hiding this comment

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

LGTM 👍 great work Cristian

src/diff/props.js Outdated Show resolved Hide resolved
dom[name] = value==null ? '' : value;
if (value==null) {
// This condition here guards against modifying a unonctrolled input's value
if (name!=='value' && name!=='checked') {
Copy link
Member

Choose a reason for hiding this comment

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

ooooh crap I hadn't thought of this implication. There are a bunch more names here that would have to be disabled, I think this might be a sign that we need to try different overall solutions...

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, you're right. I'm gonna start looking at it from other angles

cristianbote and others added 2 commits October 20, 2019 22:09
Co-Authored-By: Jason Miller <developit@users.noreply.github.com>
@cristianbote
Copy link
Member Author

I'm gonna close this one since I'm pursuing another option here. Will open a different one.

@ForsakenHarmony ForsakenHarmony deleted the fix/skip-setter-for-href branch May 21, 2021 22:26
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

Successfully merging this pull request may close these issues.

Undefined props not handled correctly.
7 participants