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 popper's behavior when it doesn't have any parents (#136) #137

Merged
merged 6 commits into from Jan 9, 2017

Conversation

adevnadia
Copy link

Solves this: #136

will be 'false positive'. Because getOffsetParent(element) returns html node, and scrollParent would be the body node.
Hence the additional check for nodeNames.
*/
} else if (!(getOffsetParent(element).nodeName === 'HTML' && scrollParent.nodeName === 'BODY') && getOffsetParent(element).contains(scrollParent)) {
Copy link
Member

Choose a reason for hiding this comment

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

getOffsetParent should be cached here instead of get called twice.

@FezVrasta
Copy link
Member

May you add a test for this case?

rect.right += scrollLeft;
} else {
const offsetParent = getOffsetParent(element);
if (!(offsetParent.nodeName === 'HTML' && scrollParent.nodeName === 'BODY') && offsetParent.contains(scrollParent)) {
Copy link
Member

@FezVrasta FezVrasta Jan 8, 2017

Choose a reason for hiding this comment

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

Sorry if I'm being picky, I hope you don't mind.

!(offsetParent.nodeName === 'HTML' && scrollParent.nodeName === 'BODY') is quite confusing to read, I was thinking that we could split it into multiple variables to make it easier to understand what's happening here.

Below you find my attempt, I'm not sure if it's correct though...

const offsetParent = getOffsetParent(element);
const offsetParentIsHTML = offsetParent.nodeName === 'HTML';
const scrollParentIsBody = scrollParent.nodeName === 'BODY';
const isScrollParentBodyChildOfHTML = offsetParentIsHTML && scrollParentIsBody;
if (!isScrollParentBodyChildOfHTML && offsetParent.contains(scrollParent)) {

Copy link
Author

Choose a reason for hiding this comment

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

Don't mind of course. isBodyChildOfHTML doesn't make a lot of sense though, since body is always a child of html. But I see your point, I'll make it more readable.

@adevnadia
Copy link
Author

adevnadia commented Jan 8, 2017

About test: I was planning to work on unit tests for the rest of the functions on the next weekend (can't do that sooner), so it will be covered in there. Writing functional tests is a nightmare, maybe need to do something about them as well...

This fix doesn't break anything, all the existing tests are green locally.

@FezVrasta
Copy link
Member

I was thinking about a simple functional test like the others we already have, unit tests make sense to me to check stuff that doesn't interact with DOM (IMHO) so I wouldn't bother trying to write an unit test for this case.

@FezVrasta
Copy link
Member

By the way, SauceLabs is in maintenance until Monday so we have time before we are able to merge this PR.

@adevnadia
Copy link
Author

I would strongly disagree with the 'simple, like others we have' :D There has to be a better way to do this...

Done, renamed and tested.

// When a popper doesn't have any positioned or scrollable parents, `offsetParent.contains(scrollParent)`
// will return a "false positive". This is happening because `getOffsetParent` returns `html` node,
// and `scrollParent` is the `body` node. Hence the additional check.
const isParentScrolledOrPositioned = !(offsetParentIsHTML && scrollParentIsBody);
Copy link
Member

Choose a reason for hiding this comment

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

I don't get why this is called isParentScrolledOrPositioned? We don't check if the parent is scrolled nor if it's positioned...

Copy link
Author

Choose a reason for hiding this comment

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

Because:
getOffsetParent(element) - returns a positioned parent or HTML if there is none.
scrollParent = getScrollParent(parent) - returns a scrollable parent or BODY if there is none.
Which means that if we want to know if our popper isn't inside some container that is positioned or scrollable, we need offsetParent to be HTML and scrollParent to be BODY.

isScrolledParentBodyAndOffsetParentHtml doesn't seem like a good idea.

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, but isParentScrolled means that we are checking that the parent element has a scrollTop or scrollLeft value different from 0.

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, you're right... Can you change it to something that you think is better?

@FezVrasta
Copy link
Member

@nadiam84 any idea to make the tests simpler is more than welcome 🙂

// When a popper doesn't have any positioned or scrollable parents, `offsetParent.contains(scrollParent)`
// will return a "false positive". This is happening because `getOffsetParent` returns `html` node,
// and `scrollParent` is the `body` node. Hence the additional check.
else if (getOffsetParent(element).contains(scrollParent) && scrollParent.nodeName !== 'BODY') {
Copy link
Member

@FezVrasta FezVrasta Jan 8, 2017

Choose a reason for hiding this comment

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

@nadiam84 does it make sense? I avoided to check that offsetParent is html because we already know that scrollParent is child of offsetParent.

So, if body is bothoffsetParent and scrollParent , it will return false because body doesn't contains itself.
If offsetParent contains scrollParent AND scrollParent is body, then offsetParent must be html

Also, doing so we don't have to invent a name for the variable! 😜

Copy link
Author

Choose a reason for hiding this comment

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

body doesn't contains itself Actually it does ;) But all's good I think, it's the same situation. And tests are green :)

@FezVrasta FezVrasta merged commit fe50dd4 into floating-ui:master Jan 9, 2017
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.

None yet

2 participants