-
Notifications
You must be signed in to change notification settings - Fork 24.8k
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
[Shadow CSS] Host context fix #21256
Conversation
Fix an error when use two or more :host-context selector. Now all host-context generate all posible combinations in the css result. Close issue angular#19199
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
I signed it! |
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for the commit author(s). If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. |
509700b
to
99c6318
Compare
I signed it! |
1 similar comment
I signed it! |
CLAs look good, thanks! |
Fix an error when use two or more :host-context selector. Now all host-context generate all posible combinations in the css result. Close issue angular#19199
What does |
Hi vicb, The code that you propouse is similar but not equivalent. When use When use Also, in some cases is not possible use
// mixins.scss
@mixin device-type-mobile {
:host-context(.mobile) & { @content; }
}
@mixin device-os-ios {
:host-context(.ios) & { @content; }
}
// usage.scss
.wrapper {
background: green;
@include device-type-mobile {
background: red;
@include device-os-ios {
background: blue;
}
}
}
// generated.css (Forced break lines and commented)
// No mixin applied.
.wrapper[_ngcontent-c5] {
background: green;
}
// One mixin applied
.mobile[_nghost-c5] .wrapper[_ngcontent-c5],
.mobile [_nghost-c5] .wrapper[_ngcontent-c5] {
background: red;
}
// Two mixin applied
// Order .ios > .mobile
.ios[_nghost-c5] .mobile[_ngcontent-c5] .wrapper[_ngcontent-c5],
.ios .mobile [_nghost-c5] .wrapper[_ngcontent-c5],
// Order .mobile > .ios
.mobile[_nghost-c5] .ios[_ngcontent-c5] .wrapper[_ngcontent-c5],
.mobile .ios [_nghost-c5] .wrapper[_ngcontent-c5],
// Same level .mobile = .ios
.ios.mobile[_nghost-c5] .wrapper[_ngcontent-c5],
.ios.mobile [_nghost-c5] .wrapper[_ngcontent-c5] {
background: blue;
} Thank you for review the code. |
Do you have a link to a spec that would explain this behavior ? |
In this link the explain of the :host-context say:
Not specify the behaviour when use two host-context, but if we apply the previous description to two host context, we have two selectors that "looks for a CSS class in any ancestor". :host-context(.one) {} // .one [host] {}
:host-context(.two) {} // .two [host] {}
:host-context(.one .two) {} // .one .two [host] {}
:host-context(.two .one ) {} // .two .one [host] {}
:host-context(.one):host-context(.two) {} // .one .two [host], .two .one [host] {}
// .one should be ancestor and .two also
// NOTE: Now, before the fix, this return an invalid css (.one -shadowcsscontext(.two) [host])
:host-context(.one) {
color: red;
:host-context(.two) {
color: blue;
}
}
/* Is not necessary that stay at the same level, for example
.one [host] {color: red},
.one .two [host], .two .one[host] {color: blue}
*/ I generate the two orders because the two host-context should by ancestors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First of all, thank you @alx1417 for this PR. I am sorry it has taken so long to review it.
I don't believe the test nor the implementation are correct here.
Can you consider my suggested test? If you agree the test is correct, then the implementation needs to change since it fails this test.
Further, if you are going to update the implementation, then I think the changes should be in the _colonHostContextPartReplacer()
method, rather than the _convertColonRule()
which is shared with handling :host()
selectors. And we should also look at the array manipulation being used as I think this could be a bit more performant.
expect(s(':host-context(.one) :host-context(.two) {}', 'contenta', 'a-host')) | ||
.toEqual( | ||
'.one[a-host] .two[contenta], .one .two [a-host], .two[a-host] .one[contenta], .two .one [a-host], .one.two[a-host], .one.two [a-host] {}'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just rebasing and tidying up this PR. I think this test is not actually correct.
First, I don't think that there should be a space between the :host-context()
selectors in the string passed to s()
. Having :host-context(...) :host-context(...)
doesn't make sense to me. I am not even sure how we should interpret this.
Second, I think that contenta
should not appear in the final selection at all.
This is what I would expect:
expect(s(':host-context(.one) :host-context(.two) {}', 'contenta', 'a-host')) | |
.toEqual( | |
'.one[a-host] .two[contenta], .one .two [a-host], .two[a-host] .one[contenta], .two .one [a-host], .one.two[a-host], .one.two [a-host] {}'); | |
}); | |
expect(s(':host-context(.one):host-context(.two) {}', 'contenta', 'a-host') | |
.replace(/ \{\}$/, '') | |
.split(/\,\s+/) | |
.sort()) | |
.toEqual([ | |
'.one .two[a-host]', // `one` is an ancestor and `two` is on the host | |
'.one .two [a-host]', // `one` and `two` are both ancestors (in that order) | |
'.one.two [a-host]', // `one` and `two` are both on the same ancestor | |
'.one.two[a-host]', // `one` and `two` both on the host | |
'.two .one [a-host]', // `two` and `one` are both ancestors (in that order) | |
'.two .one[a-host]', // `two` is an ancestor and `one` is on the host | |
]); |
Closing in favour of #40494. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
When you use more than one :host-context selector in the same css rule, the compiled css generate a invalid css code "-shadowcsscontext".
Example:
Issue Number: #19199
What is the new behavior?
You can use two or more :host-context selector in the same css rule and generate all css combinations.
Example:
Does this PR introduce a breaking change?
Other information