Closed
Bug 1382786
Opened 9 years ago
Closed 9 years ago
stylo: implement restrictions on which properties apply to ::first-letter, ::first-line, ::placeholder
Categories
(Core :: CSS Parsing and Computation, enhancement)
Tracking
()
RESOLVED
FIXED
mozilla56
| Tracking | Status | |
|---|---|---|
| firefox56 | --- | fixed |
People
(Reporter: bzbarsky, Assigned: bzbarsky)
References
Details
Attachments
(2 files, 3 obsolete files)
Per CSS spec, only certain properties apply to first-line, first-letter, placeholder pseudo-elements.
The way Gecko implements this is as follows:
1) Style contexts with those pseudos are forced into separate branches of the ruletree via "restriction rules". This is needed to make caching in the ruletree work ok; stylo doesn't need this part.
2) When determining the specified style, once the walk through the ruletree is done and we've mapped everything into the ruledata, if we're resolving one of those pseudos we go through and reset all the specified values to "not specified" for properties that don't have the relevant "allowed for this pseudo" bits set.
We need to do something like this for servo. A quick experiment:
<style>
input::placeholder { border-top-color: red; background: green; }
</style>
<script>
var d = document.createElement("input");
var s = getComputedStyle(d, "::placeholder");
alert(s.borderTopColor);
alert(s.backgroundColor);
</script>
shows we already do this for ::placeholder. But we need to do it for ::first-letter and ::first-line too. Testcase:
<style>
div::first-line { border-top-color: red; }
div::first-letter { display: table }
</style>
<script>
var d = document.createElement("div");
var s = getComputedStyle(d, "::first-line");
alert(s.borderTopColor);
s = getComputedStyle(d, "::first-letter");
alert(s.display);
</script>
which should alert "rgb(0, 0, 0)" and "inline".
| Assignee | ||
Comment 1•9 years ago
|
||
> shows we already do this for ::placeholder
Nope. It just looks like that because of !important rules in ua.css. Here's a failing testcase for ::placeholder:
Summary: stylo: implement restrictions on which properties apply to ::first-letter, ::first-line → stylo: implement restrictions on which properties apply to ::first-letter, ::first-line, ::placeholder
| Assignee | ||
Comment 2•9 years ago
|
||
<style>
input::placeholder { float: right; }
</style>
<script>
var d = document.createElement("input");
var s = getComputedStyle(d, "::placeholder");
alert(s.cssFloat);
</script>
this should alert "none" but servo alerts "right".
Comment 3•9 years ago
|
||
So this is the kind of thing that Gecko implements with the different rule implementations in the rule tree, right?
I think in Servo it'd be nice to follow the pattern we have for `:visited` styles, and filter on the cascade() function instead, but happy to hear other options.
I think it should be somewhat easier now than it was not long ago, I added information of which pseudo we're cascading to StyleBuilder. And it should be just one branch in the "no pseudo" case.
| Assignee | ||
Comment 4•9 years ago
|
||
> So this is the kind of thing that Gecko implements with the different rule implementations in the rule tree
No, it's actually not, except for the restriction rule bits to force not-sharing of cached data between rulenodes that have had this thing applied to them and once that haven't. When we last talked about this, I'd mis-remembered what the restriction rules were for.
Assignee: nobody → bzbarsky
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Assignee | ||
Comment 10•9 years ago
|
||
I'm really glad I wrote part 5, by the way: it turned out when I was done, that I had in fact managed to get some of the flags wrong for Stylo. But at this point Gecko and Stylo both pass the new tests, which is a good sign. ;)
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
Comment 13•9 years ago
|
||
| mozreview-review | ||
Comment on attachment 8888596 [details]
Add property flags for which properties apply to certain pseudo-elements.
https://reviewboard.mozilla.org/r/159588/#review165074
Attachment #8888596 -
Flags: review?(emilio+bugs) → review+
Comment 14•9 years ago
|
||
| mozreview-review | ||
Comment on attachment 8888597 [details]
Flag properties that apply to ::first-letter/::first-line/::placeholder.
https://reviewboard.mozilla.org/r/159590/#review165076
::: servo/components/style/properties/longhand/background.mako.rs:42
(Diff revision 1)
> + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
> )}
> % endfor
>
> <%helpers:vector_longhand name="background-repeat" animation_value_type="discrete"
> - spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat">
> + spec="https://drafts.csswg.org/css-backgrounds/#the-background-repeat"
nit: trailing whitespace.
::: servo/components/style/properties/longhand/box.mako.rs:15
(Diff revision 1)
> gecko_name="Display") %>
>
> // TODO(SimonSapin): don't parse `inline-table`, since we don't support it
> +//
> +// We allow "display" to apply to placeholders because we need to make the
> +// placeholder pseudo-element an inline-block in the UA stylesheet in Gecko.
Oh, I was assuming we wouldn't check this for rules in UA sheets. But this is fine too I guess.
::: servo/components/style/properties/longhand/box.mako.rs:1635
(Diff revision 1)
> // http://dev.w3.org/csswg/css-ui
> // FIXME support logical values `block` and `inline` (https://drafts.csswg.org/css-logical-props/#resize)
> +//
> +// This is APPLIES_TO_PLACEHOLDER so we can override, in the UA sheet, the
> +// 'resize' property we'd inherit from textarea otherwise. Basically, just
> +// makes the UA rules easier to write.
Ditto, let me know if that'd be more preferrable or not.
::: servo/components/style/properties/longhand/inherited_text.mako.rs:732
(Diff revision 1)
> "-webkit-text-fill-color", "Color",
> "computed_value::T::currentcolor()",
> products="gecko", animation_value_type="IntermediateColor",
> need_clone=True, ignored_when_colors_disabled=True,
> + flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER",
> +
nit: Trailing whitespace (though I guess this line can go away entirely)
::: servo/components/style/properties/longhand/padding.mako.rs:10
(Diff revision 1)
> <%namespace name="helpers" file="/helpers.mako.rs" />
> <% from data import ALL_SIDES, maybe_moz_logical_alias %>
> <% data.new_style_struct("Padding", inherited=False) %>
>
> +// APPLIES_TO_PLACEHOLDER so we can set it in UA stylesheets. But we use a
> +// !important value there, so pages can't set it.
nit: Trailing whitespace.
Attachment #8888597 -
Flags: review?(emilio+bugs) → review+
Comment 15•9 years ago
|
||
| mozreview-review | ||
Comment on attachment 8888598 [details]
Filter out non-applying properties when cascading style for ::first-letter/::first-line/::placeholder.
https://reviewboard.mozilla.org/r/159592/#review165082
::: servo/components/style/properties/properties.mako.rs:2783
(Diff revision 1)
> };
> let node_importance = node.importance();
> +
> + let required_flag = match pseudo {
> + #[cfg(feature = "gecko")]
> + Some(&PseudoElement::FirstLetter) => Some(APPLIES_TO_FIRST_LETTER),
nit: Not sure if this'd be more elegant with an explicit method in `PseudoElement`. Also, perhaps a slightly more descriptive name would be something like `property_restrictions`? It'd look something like:
```
let property_restrictions = pseudo.and_then(|p| p.property_restrictions());
```
::: servo/components/style/properties/properties.mako.rs:2796
(Diff revision 1)
> declarations
> .iter()
> // Yield declarations later in source order (with more precedence) first.
> .rev()
> .filter_map(move |&(ref declaration, declaration_importance)| {
> + if let Some(required_flag) = required_flag {
If you think it's better to just skip UA rules as I suggested, you can avoid looking at `cascade_level` here.
::: servo/components/style/properties/properties.mako.rs:2797
(Diff revision 1)
> .iter()
> // Yield declarations later in source order (with more precedence) first.
> .rev()
> .filter_map(move |&(ref declaration, declaration_importance)| {
> + if let Some(required_flag) = required_flag {
> + // Only allow longhands if they have the flag set
nit: Not sure the comment is supper-helpful...
Attachment #8888598 -
Flags: review?(emilio+bugs) → review+
Comment 16•9 years ago
|
||
| mozreview-review | ||
Comment on attachment 8888599 [details]
Bug 1382786 part 4. Update test expectations.
https://reviewboard.mozilla.org/r/159594/#review165084
Attachment #8888599 -
Flags: review?(emilio+bugs) → review+
Comment 17•9 years ago
|
||
| mozreview-review | ||
Comment on attachment 8888600 [details]
Bug 1382786 part 5. Add some tests for which properties are properties are allowed on ::first-letter, ::first-line, and ::placeholder.
https://reviewboard.mozilla.org/r/159596/#review165086
::: layout/style/test/test_first_line_restrictions.html:39
(Diff revision 2)
> + if (info.prerequisites) {
> + for (let name in info.prerequisites) {
> + prereqs += `${name}: ${info.prerequisites[name]}; `;
> + }
> + }
> + $("s").textContent = `
I bet this is how you found bug 1382927 ;)
Attachment #8888600 -
Flags: review?(emilio+bugs) → review+
Comment 18•9 years ago
|
||
| mozreview-review-reply | ||
Comment on attachment 8888598 [details]
Filter out non-applying properties when cascading style for ::first-letter/::first-line/::placeholder.
https://reviewboard.mozilla.org/r/159592/#review165082
> If you think it's better to just skip UA rules as I suggested, you can avoid looking at `cascade_level` here.
Err, I meant you can avoid looking at the flags after looking at cascade_level.
| Assignee | ||
Comment 19•9 years ago
|
||
| mozreview-review-reply | ||
Comment on attachment 8888597 [details]
Flag properties that apply to ::first-letter/::first-line/::placeholder.
https://reviewboard.mozilla.org/r/159590/#review165076
> Oh, I was assuming we wouldn't check this for rules in UA sheets. But this is fine too I guess.
Hmm. I basically duplicated Gecko behavior (albeit with more overhead, because Gecko does this only once all the stuff is cascaded, and with less checks in the inner hot loop, but I couldn't figure out how to do that here).
We could think about allowing this in UA sheets in general, but that's pretty dangerous: it's too easy to create styles that will assert or crash. For now I'd prefer keeping the Gecko behavior.
| Assignee | ||
Comment 20•9 years ago
|
||
> I bet this is how you found bug 1382927 ;)
Yes, it is. I was running the tests in Stylo and Gecko and as I was adding stuff to property_database to make them green, and noticed that the Stylo version took a lot longer to run. ;)
| Assignee | ||
Comment 21•9 years ago
|
||
| mozreview-review-reply | ||
Comment on attachment 8888598 [details]
Filter out non-applying properties when cascading style for ::first-letter/::first-line/::placeholder.
https://reviewboard.mozilla.org/r/159592/#review165082
> nit: Not sure if this'd be more elegant with an explicit method in `PseudoElement`. Also, perhaps a slightly more descriptive name would be something like `property_restrictions`? It'd look something like:
>
> ```
> let property_restrictions = pseudo.and_then(|p| p.property_restrictions());
> ```
Good idea.
> nit: Not sure the comment is supper-helpful...
I'll rephase it to be clearer. The point is that custom properties are always allowed.
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Comment hidden (mozreview-request) |
| Assignee | ||
Updated•9 years ago
|
Attachment #8888596 -
Attachment is obsolete: true
| Assignee | ||
Updated•9 years ago
|
Attachment #8888597 -
Attachment is obsolete: true
| Assignee | ||
Updated•9 years ago
|
Attachment #8888598 -
Attachment is obsolete: true
Comment 28•9 years ago
|
||
Pushed by bzbarsky@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/fb19f23bb69a
part 4. Update test expectations. r=emilio
https://hg.mozilla.org/integration/autoland/rev/cc9fbf7eabe7
part 5. Add some tests for which properties are properties are allowed on ::first-letter, ::first-line, and ::placeholder. r=emilio
Comment 29•9 years ago
|
||
Pushed by bzbarsky@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/6f9ddd2f1395
followup. Mark some more tests as passing.
Comment 30•9 years ago
|
||
| bugherder | ||
https://hg.mozilla.org/mozilla-central/rev/fb19f23bb69a
https://hg.mozilla.org/mozilla-central/rev/cc9fbf7eabe7
https://hg.mozilla.org/mozilla-central/rev/6f9ddd2f1395
Status: NEW → RESOLVED
Closed: 9 years ago
status-firefox56:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla56
Comment 31•8 years ago
|
||
Is there any specific reason why shape-outside was decided to be a property ::first-letter could have? I can't see any note in https://drafts.csswg.org/css-pseudo-4/#first-letter-styling or https://drafts.csswg.org/css-shapes/#shape-outside-property about shape-outside and ::first-letter.
Comment 32•8 years ago
|
||
(In reply to Chris Nardi from comment #31)
> Is there any specific reason why shape-outside was decided to be a property
> ::first-letter could have? I can't see any note in
> https://drafts.csswg.org/css-pseudo-4/#first-letter-styling or
> https://drafts.csswg.org/css-shapes/#shape-outside-property about
> shape-outside and ::first-letter.
I guess per the spec you mention it shouldn't, since https://drafts.csswg.org/css-pseudo-4/#first-letter-styling doesn't mention it explicitly, but says:
> any other properties defined to apply to ::first-letter by their respective specifications
And shape-outside is not defined to apply to ::first-letter explicitly.
If you think it should or what not please do file a different bug for it, this bug was only implementing in the new style system what the old style system was doing, effectively (bug 469227 implemented the latest mechanism, and such).
Comment 33•8 years ago
|
||
I have no opinion on the matter; I was just trying to match up Chrome's implementation of what properties could apply to ::first-letter to the spec and was using Stylo as a guide.
Comment 34•8 years ago
|
||
(In reply to Chris Nardi from comment #33)
> I have no opinion on the matter; I was just trying to match up Chrome's
> implementation of what properties could apply to ::first-letter to the spec
> and was using Stylo as a guide.
Ah, awesome, thanks!
Comment 35•8 years ago
|
||
Also, let me know if there's anything I can help with :)
Comment 36•8 years ago
|
||
Thank you, I'll be sure to ask if I have any other questions. :)
You need to log in
before you can comment on or make changes to this bug.
Description
•