Closed
Bug 1384398
Opened 7 years ago
Closed 7 years ago
stylo: serialization of font-family doesn't match Gecko
Categories
(Core :: CSS Parsing and Computation, defect, P2)
Core
CSS Parsing and Computation
Tracking
()
RESOLVED
FIXED
mozilla57
Tracking | Status | |
---|---|---|
firefox-esr52 | --- | unaffected |
firefox55 | --- | wontfix |
firefox56 | --- | wontfix |
firefox57 | --- | fixed |
People
(Reporter: heycam, Assigned: heycam)
References
Details
Attachments
(2 files, 1 obsolete file)
It looks like there are a couple of differences in how font-family values are serialized. Compare the attached test with stylo enabled and disabled:
1. Stylo serializes the space separated font names as a single identifier with backslashed-escaped spaces, but Gecko serializes them as three separate identifiers.
2. Stylo puts a space after the comma, and Gecko doesn't. (Stylo's behaviour seems preferable.)
3. If you open devtools, the two `:root { font-family: ... }` rules are displayed differently. In the style sheet without the following @supports rule, backslashes are not displayed, and in the style sheet with the following @supports rule, backslashes are displayed. That's pretty weird.
Assignee | ||
Comment 2•7 years ago
|
||
Flags: needinfo?(cam)
(In reply to Cameron McCormack (:heycam) from comment #0)
> 2. Stylo puts a space after the comma, and Gecko doesn't. (Stylo's
> behaviour seems preferable.)
Space after comma is speced, if I'm not mistaken.
https://drafts.csswg.org/cssom/#serialize-a-string
Assignee | ||
Comment 4•7 years ago
|
||
(In reply to Cameron McCormack (:heycam) from comment #0)
> 3. If you open devtools, the two `:root { font-family: ... }` rules are
> displayed differently. In the style sheet without the following @supports
> rule, backslashes are not displayed, and in the style sheet with the
> following @supports rule, backslashes are displayed. That's pretty weird.
I can't reproduce this one any more.
Assignee | ||
Comment 5•7 years ago
|
||
(In reply to Cameron McCormack (:heycam) from comment #0)
> 1. Stylo serializes the space separated font names as a single identifier
> with backslashed-escaped spaces, but Gecko serializes them as three separate
> identifiers.
For this I think the issue is that Servo's FamilyName type cannot distinguish between a sequence of identifiers (each of which individually must be escaped individually) and a single identifier.
Assignee | ||
Comment 6•7 years ago
|
||
(In reply to Cameron McCormack (:heycam) from comment #0)
> 2. Stylo puts a space after the comma, and Gecko doesn't. (Stylo's
> behaviour seems preferable.)
This is a regression from bug 280443.
Assignee | ||
Comment 7•7 years ago
|
||
Assignee | ||
Updated•7 years ago
|
Assignee: nobody → cam
Status: NEW → ASSIGNED
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Assignee | ||
Comment 10•7 years ago
|
||
Comment 11•7 years ago
|
||
mozreview-review |
Comment on attachment 8891724 [details]
Bug 1384398 - style: Preserve font-family identifier sequence when serializing.
https://reviewboard.mozilla.org/r/162786/#review168124
::: servo/components/style/properties/gecko.mako.rs:1825
(Diff revision 1)
> FontFamilyType::eFamily_moz_fixed => FontFamily::Generic(Atom::from("-moz-fixed")),
> - FontFamilyType::eFamily_named => FontFamily::FamilyName(FamilyName {
> - name: (&*gecko_font_family_name.mName).into(),
> - quoted: false
> - }),
> + FontFamilyType::eFamily_named => {
> + let name = Atom::from(&*gecko_font_family_name.mName);
> + FontFamily::FamilyName(FamilyName {
> + name: name.clone(),
> + syntax: FamilyNameSyntax::Identifiers(vec![name]),
hmm... So I don't really think this is correct... Why is it? Couldn't it be a sequence of identifiers?
::: servo/components/style/properties/longhand/font.mako.rs:106
(Diff revision 1)
> +
> + #[derive(Debug, PartialEq, Eq, Clone, Hash)]
> + #[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
> + pub enum FamilyNameSyntax {
> + Quoted,
> + Identifiers(Vec<Atom>),
Instead of `Identifiers(Vec<Atom>)`, why not just `SpaceSeparatedIdentifiers`, and given we need to convert the name to a `String` anyway, we can split it during serialisation instead of keeping track of it this way.
Would that work? If not, why not?
::: servo/components/style/properties/longhand/font.mako.rs:251
(Diff revision 1)
> - write!(CssStringWriter::new(dest), "{}", self.name)?;
> + write!(CssStringWriter::new(dest), "{}", self.name)?;
> - dest.write_char('"')
> + dest.write_char('"')
> - } else {
> - serialize_identifier(&*self.name.to_string(), dest)
> - }
> + }
> + FamilyNameSyntax::Identifiers(ref identifiers) => {
And if that works, a comment to mention that it's intentional and what problem it prevents would be quite on point.
Attachment #8891724 -
Flags: review?(emilio+bugs)
Comment 12•7 years ago
|
||
mozreview-review |
Comment on attachment 8891725 [details]
Bug 1384398 - Separate family names in font-family serialization with ", ".
https://reviewboard.mozilla.org/r/162788/#review168126
r=me
Apparently we had tests for this, but not the previous patch, any chance to write one?
Attachment #8891725 -
Flags: review?(emilio+bugs) → review+
Assignee | ||
Comment 13•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8891724 [details]
Bug 1384398 - style: Preserve font-family identifier sequence when serializing.
https://reviewboard.mozilla.org/r/162786/#review168124
> hmm... So I don't really think this is correct... Why is it? Couldn't it be a sequence of identifiers?
The spec says (if I read it correctly) that sequences of identifiers should compute to a single string with all of the identifiers concatened with a single space in between. Gecko doesn't do that currently, and it just stores a single string with a quoted flag. So I figured I'd do the smallest change here and just worry about the specified value. (And yes, ideally we would have a separate specified and computed type for a family name list.)
> Instead of `Identifiers(Vec<Atom>)`, why not just `SpaceSeparatedIdentifiers`, and given we need to convert the name to a `String` anyway, we can split it during serialisation instead of keeping track of it this way.
>
> Would that work? If not, why not?
By this do you mean store a single String that is the serialization of the sequence of identifiers, and so would already take into account any backslash-escaping of individual identifiers?
Comment 14•7 years ago
|
||
mozreview-review-reply |
Comment on attachment 8891724 [details]
Bug 1384398 - style: Preserve font-family identifier sequence when serializing.
https://reviewboard.mozilla.org/r/162786/#review168124
> The spec says (if I read it correctly) that sequences of identifiers should compute to a single string with all of the identifiers concatened with a single space in between. Gecko doesn't do that currently, and it just stores a single string with a quoted flag. So I figured I'd do the smallest change here and just worry about the specified value. (And yes, ideally we would have a separate specified and computed type for a family name list.)
Right, but this effectively makes a value of:
```
Identifiers([foo, bar]),
```
Go to gecko as:
```
{ name: "foo bar", quoted: false }
```
And return as:
```
Identifiers([foo bar])
```
Which at least deserves a comment I think.
> By this do you mean store a single String that is the serialization of the sequence of identifiers, and so would already take into account any backslash-escaping of individual identifiers?
Nope, I mean the raw string as Gecko does, just instead of passing it down to serialize_identifier entirely, which would escape the spaces, do it ourselves splitting... I think it may work because it doesn't matter whether the original had any escaped space or not, I think.
Basically, I was suggesting something like:
```
let name = self.name.to_string(); // We already do this conversion.
let mut first = true;
for ident in name.split(' ') { // This doesn't allocate or anything like that.
if !first {
dest.write_char(' ')?;
}
first = false;
serialize_identifier(ident, dest)?;
}
````
Assignee | ||
Comment 15•7 years ago
|
||
(In reply to Emilio Cobos Álvarez [:emilio] from comment #14)
> > By this do you mean store a single String that is the serialization of the sequence of identifiers, and so would already take into account any backslash-escaping of individual identifiers?
>
> Nope, I mean the raw string as Gecko does, just instead of passing it down
> to serialize_identifier entirely, which would escape the spaces, do it
> ourselves splitting... I think it may work because it doesn't matter whether
> the original had any escaped space or not, I think.
>
> Basically, I was suggesting something like:
>
>
> ```
> let name = self.name.to_string(); // We already do this conversion.
>
> let mut first = true;
> for ident in name.split(' ') { // This doesn't allocate or anything like
> that.
> if !first {
> dest.write_char(' ')?;
> }
> first = false;
> serialize_identifier(ident, dest)?;
> }
> ````
I don't think that would work when you have identifiers with backslash-escaped spaces in them, e.g. if you had
p { font-family: A B\ \ C D; }
then it should represent the family name "A B C D" but it would get incorrectly serialized as "A B C D" (which is equivalent to "A B C D").
If you like I would be happy to store the white space concatenated identifier-serialized identifiers in one Atom, and pass that to Gecko_FontFamilyList_AppendNamed with aQuoted = false. I guess that is closer to what Gecko does itself. Then serialization is just writing that Atom out.
Comment 16•7 years ago
|
||
(In reply to Cameron McCormack (:heycam) from comment #15)
> I don't think that would work when you have identifiers with
> backslash-escaped spaces in them, e.g. if you had
>
> p { font-family: A B\ \ C D; }
>
> then it should represent the family name "A B C D" but it would get
> incorrectly serialized as "A B C D" (which is equivalent to "A B C D").
Hmm... Yeah, that's fair.
> If you like I would be happy to store the white space concatenated
> identifier-serialized identifiers in one Atom, and pass that to
> Gecko_FontFamilyList_AppendNamed with aQuoted = false. I guess that is
> closer to what Gecko does itself. Then serialization is just writing that
> Atom out.
That sounds great :)
Updated•7 years ago
|
Priority: P2 → --
Assignee | ||
Updated•7 years ago
|
Priority: -- → P2
Assignee | ||
Updated•7 years ago
|
Flags: needinfo?(cam)
Assignee | ||
Comment 17•7 years ago
|
||
Reworked patch still needs some work: https://treeherder.mozilla.org/#/jobs?repo=try&revision=24e6d23b7603663552938cfb0d8803dec5faa2bd
Assignee | ||
Comment 18•7 years ago
|
||
Flags: needinfo?(cam)
Comment hidden (mozreview-request) |
Comment hidden (mozreview-request) |
Comment 21•7 years ago
|
||
mozreview-review |
Comment on attachment 8891724 [details]
Bug 1384398 - style: Preserve font-family identifier sequence when serializing.
https://reviewboard.mozilla.org/r/162786/#review170528
::: servo/components/style/properties/longhand/font.mako.rs:260
(Diff revision 2)
> - dest.write_char('"')
> + dest.write_char('"')
> - } else {
> - serialize_identifier(&*self.name.to_string(), dest)
> - }
> + }
> + FamilyNameSyntax::Identifiers(ref serialization) => {
> + dest.write_str(&*serialization)
nit: Maybe add a comment on here to note they're escaped already.
Attachment #8891724 -
Flags: review?(emilio+bugs) → review+
Comment hidden (mozreview-request) |
Assignee | ||
Updated•7 years ago
|
Attachment #8891724 -
Attachment is obsolete: true
Assignee | ||
Comment 23•7 years ago
|
||
Comment 24•7 years ago
|
||
Pushed by cmccormack@mozilla.com:
https://hg.mozilla.org/integration/autoland/rev/df230b4a8eb5
Separate family names in font-family serialization with ", ". r=emilio
Comment 25•7 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
status-firefox57:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla57
Comment 26•7 years ago
|
||
Is it expected that this patch produces a lot of stdout messages about fonts? It is polluting my system logs (linux).
Flags: needinfo?(emilio+bugs)
Flags: needinfo?(cam)
Comment 27•7 years ago
|
||
Yeah, Cameron accidentally left a debugging println! there, but that was removed in https://github.com/servo/servo/pull/17987 which should be in the next nightly.
Sorry for the hassle!
Flags: needinfo?(emilio+bugs)
Flags: needinfo?(cam)
Updated•7 years ago
|
status-firefox55:
--- → wontfix
status-firefox56:
--- → wontfix
status-firefox-esr52:
--- → unaffected
You need to log in
before you can comment on or make changes to this bug.
Description
•