mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
style: Tweak font-family serialization so that it is simpler.
In particular, every time that there's at least more than one identifier, switch to quoted family name, since the reconstruction of the serialization will be lossy anyway. This allows us to avoid copies and all that. What Chrome implements doesn't make much sense in the sense that they always serialize: font-family: "foo"; -> font-family: foo; font-family: foo bar; -> font-family: "foo bar"; font-family: foo\ bar; -> font-family: "foo bar"; This patch makes us match on the second case, but not on the rest, because I think Gecko's behavior is preferable in those cases. Bug: 1434802 Reviewed-by: xidorn MozReview-Commit-ID: JwBECA93lfi
This commit is contained in:
parent
f4c9c598a3
commit
9490786876
1 changed files with 24 additions and 25 deletions
|
@ -7,20 +7,21 @@
|
||||||
use Atom;
|
use Atom;
|
||||||
use app_units::Au;
|
use app_units::Au;
|
||||||
use byteorder::{BigEndian, ByteOrder};
|
use byteorder::{BigEndian, ByteOrder};
|
||||||
use cssparser::{CssStringWriter, Parser, serialize_identifier};
|
use cssparser::{CssStringWriter, Parser};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use gecko_bindings::{bindings, structs};
|
use gecko_bindings::{bindings, structs};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use gecko_bindings::sugar::refptr::RefPtr;
|
use gecko_bindings::sugar::refptr::RefPtr;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use style_traits::{CssWriter, ParseError, ToCss};
|
use style_traits::{CssWriter, ParseError, ToCss};
|
||||||
use values::CSSFloat;
|
use values::{CSSFloat, serialize_atom_identifier};
|
||||||
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
use values::animated::{ToAnimatedValue, ToAnimatedZero};
|
||||||
use values::computed::{Context, NonNegativeLength, ToComputedValue, Integer, Number};
|
use values::computed::{Context, NonNegativeLength, ToComputedValue, Integer, Number};
|
||||||
use values::generics::font::{FontSettings, FeatureTagValue, VariationValue};
|
use values::generics::font::{FontSettings, FeatureTagValue, VariationValue};
|
||||||
|
@ -286,10 +287,8 @@ impl ToCss for FamilyName {
|
||||||
write!(CssStringWriter::new(dest), "{}", self.name)?;
|
write!(CssStringWriter::new(dest), "{}", self.name)?;
|
||||||
dest.write_char('"')
|
dest.write_char('"')
|
||||||
}
|
}
|
||||||
FamilyNameSyntax::Identifiers(ref serialization) => {
|
FamilyNameSyntax::Identifier => {
|
||||||
// Note that `serialization` is already escaped/
|
serialize_atom_identifier(&self.name, dest)
|
||||||
// serialized appropriately.
|
|
||||||
dest.write_str(&*serialization)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -301,13 +300,12 @@ impl ToCss for FamilyName {
|
||||||
/// or unquoted as a sequence of one or more identifiers.
|
/// or unquoted as a sequence of one or more identifiers.
|
||||||
pub enum FamilyNameSyntax {
|
pub enum FamilyNameSyntax {
|
||||||
/// The family name was specified in a quoted form, e.g. "Font Name"
|
/// The family name was specified in a quoted form, e.g. "Font Name"
|
||||||
/// or 'Font Name'.
|
/// or 'Font Name', or as a list of unquoted identifiers.
|
||||||
Quoted,
|
Quoted,
|
||||||
|
|
||||||
/// The family name was specified in an unquoted form as a sequence of
|
/// The family name was specified in an unquoted form as a single
|
||||||
/// identifiers. The `String` is the serialization of the sequence of
|
/// identifier.
|
||||||
/// identifiers.
|
Identifier,
|
||||||
Identifiers(String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq)]
|
||||||
|
@ -367,7 +365,7 @@ impl SingleFontFamily {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parse a font-family value
|
/// Parse a font-family value.
|
||||||
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(value) = input.try(|i| i.expect_string_cloned()) {
|
if let Ok(value) = input.try(|i| i.expect_string_cloned()) {
|
||||||
return Ok(SingleFontFamily::FamilyName(FamilyName {
|
return Ok(SingleFontFamily::FamilyName(FamilyName {
|
||||||
|
@ -405,28 +403,32 @@ impl SingleFontFamily {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut value = first_ident.as_ref().to_owned();
|
let mut syntax = FamilyNameSyntax::Identifier;
|
||||||
let mut serialization = String::new();
|
let mut value = Cow::Borrowed(first_ident.as_ref());
|
||||||
serialize_identifier(&first_ident, &mut serialization).unwrap();
|
|
||||||
|
|
||||||
// These keywords are not allowed by themselves.
|
// These keywords are not allowed by themselves.
|
||||||
// The only way this value can be valid with with another keyword.
|
// The only way this value can be valid with with another keyword.
|
||||||
if css_wide_keyword {
|
if css_wide_keyword {
|
||||||
|
syntax = FamilyNameSyntax::Quoted;
|
||||||
|
|
||||||
let ident = input.expect_ident()?;
|
let ident = input.expect_ident()?;
|
||||||
|
|
||||||
|
let value = value.to_mut();
|
||||||
value.push(' ');
|
value.push(' ');
|
||||||
value.push_str(&ident);
|
value.push_str(&ident);
|
||||||
serialization.push(' ');
|
|
||||||
serialize_identifier(&ident, &mut serialization).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
|
while let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
|
||||||
|
syntax = FamilyNameSyntax::Quoted;
|
||||||
|
|
||||||
|
let value = value.to_mut();
|
||||||
value.push(' ');
|
value.push(' ');
|
||||||
value.push_str(&ident);
|
value.push_str(&ident);
|
||||||
serialization.push(' ');
|
|
||||||
serialize_identifier(&ident, &mut serialization).unwrap();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(SingleFontFamily::FamilyName(FamilyName {
|
Ok(SingleFontFamily::FamilyName(FamilyName {
|
||||||
name: Atom::from(value),
|
name: Atom::from(value),
|
||||||
syntax: FamilyNameSyntax::Identifiers(serialization),
|
syntax,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,7 +463,6 @@ impl SingleFontFamily {
|
||||||
/// Get the corresponding font-family with family name
|
/// Get the corresponding font-family with family name
|
||||||
fn from_font_family_name(family: &structs::FontFamilyName) -> SingleFontFamily {
|
fn from_font_family_name(family: &structs::FontFamilyName) -> SingleFontFamily {
|
||||||
use gecko_bindings::structs::FontFamilyType;
|
use gecko_bindings::structs::FontFamilyType;
|
||||||
use values::serialize_atom_identifier;
|
|
||||||
|
|
||||||
match family.mType {
|
match family.mType {
|
||||||
FontFamilyType::eFamily_sans_serif => SingleFontFamily::Generic(atom!("sans-serif")),
|
FontFamilyType::eFamily_sans_serif => SingleFontFamily::Generic(atom!("sans-serif")),
|
||||||
|
@ -472,11 +473,9 @@ impl SingleFontFamily {
|
||||||
FontFamilyType::eFamily_moz_fixed => SingleFontFamily::Generic(Atom::from("-moz-fixed")),
|
FontFamilyType::eFamily_moz_fixed => SingleFontFamily::Generic(Atom::from("-moz-fixed")),
|
||||||
FontFamilyType::eFamily_named => {
|
FontFamilyType::eFamily_named => {
|
||||||
let name = Atom::from(&*family.mName);
|
let name = Atom::from(&*family.mName);
|
||||||
let mut serialization = String::new();
|
|
||||||
serialize_atom_identifier(&name, &mut serialization).unwrap();
|
|
||||||
SingleFontFamily::FamilyName(FamilyName {
|
SingleFontFamily::FamilyName(FamilyName {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
syntax: FamilyNameSyntax::Identifiers(serialization),
|
syntax: FamilyNameSyntax::Identifier,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
FontFamilyType::eFamily_named_quoted => SingleFontFamily::FamilyName(FamilyName {
|
FontFamilyType::eFamily_named_quoted => SingleFontFamily::FamilyName(FamilyName {
|
||||||
|
@ -622,7 +621,7 @@ impl FontFamilyList {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
/// Iterator of FontFamily
|
/// Iterator of FontFamily
|
||||||
pub struct FontFamilyNameIter<'a> {
|
pub struct FontFamilyNameIter<'a> {
|
||||||
names: &'a structs::nsTArray<structs::FontFamilyName>,
|
names: &'a [structs::FontFamilyName],
|
||||||
cur: usize,
|
cur: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue