diff --git a/layout/style/res/Mozilla_Bullet.bf b/layout/style/res/Mozilla_Bullet.bf
new file mode 100644
index 0000000000000..de8a7e2c29fe7
--- /dev/null
+++ b/layout/style/res/Mozilla_Bullet.bf
@@ -0,0 +1,139 @@
+
+
+2.2
+
+Mozilla Bullet
+Bullet
+Regular
+false
+false
+Mozilla Bullet
+Mozilla Bullet
+Version 1.0
+
+
+
+
+400
+1024
+
+Mozilla
+Mats Palmgren
+
+
+
+
+ 84.0000000000
+ 66.0000000000
+ 62.0000000000
+ 4.0000000000
+ 0.0000000000
+ 0.0000000000
+ 130.5577907913
+ 34.0000000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/style/res/Mozilla_Bullet.ttf b/layout/style/res/Mozilla_Bullet.ttf
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/layout/style/res/Mozilla_Bullet.woff2 b/layout/style/res/Mozilla_Bullet.woff2
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/layout/style/res/html.css b/layout/style/res/html.css
index 7c731c9a9f18b..0827645addb61 100644
--- a/layout/style/res/html.css
+++ b/layout/style/res/html.css
@@ -5,6 +5,11 @@
@namespace url(http://www.w3.org/1999/xhtml); /* set default namespace to HTML */
@namespace xul url(http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul);
+@font-face {
+ font-family: -moz-bullet-font;
+ src: url("data:font/woff2;base64,d09GMgABAAAAAARYAAwAAAAACqAAAAQFAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cBmAAgwIRCAqKDIcYATYCJAMsCxgABCAFg2AHIBtDCFGUrM0MyM/DGJyndUclpZwnU8QPQ6wsFOHO+/yHNvV9IEqSQgsVJW2p+uZkohKbVExPEz/JUW7zk6rzYH9723UJ/4DzBII8CSzwgFMOOE4KW2rjAmh4qQWSiid60f7Y9FsXScfUpeluagFqTTQYyoQaQSubXil0lHRsBehAI9KofG/6ogF9/Hl6lBd920LmeTxj8JXBfFWKwYAY3QsAAXD17ZAB4M6Ocv/nsZlkaTl0gLipewIQEMB2d9lKDAT1ZjP/F7jmWsQ3wn8AZvZFgIIC7ESh4AP1iFb4nPnfWyJgcQArpUWqW9W96j71kHr/L9a/dNRbj+8/ujXLWCMMFYVYiXoEaZQ4YOC/E7Dkz3JEjaokxAP6i3hIUjv9fwYyE6I3yIozKkaGN63fP36aeLJmxlRZwZiFziPrMVvOlnCF98SQJfGO/Xllv/FnWAcEjrMqaMCPwVmktCDO5zzxcXqeKS+QFxYnvJLFVzKZAFcKnlZRwHEPVM3mXxNt2gdZEpkKaIAG9gbgDTU5SOYDcmX7Rr61evEA1U+1/3SMb6FFtUqh55nYleE95j2zPNxzdlnGoR5xu/PxQKzb7bFaFLvl79Z54Lx9OH+g0/PPYlcsNo/nwP2V2vsHUHsV4KqEsd+e2r6Fu2v7abkfvsb65b41uwvRvqewH25kTntqolbYsEr5DAqrX97a0jrBLjFRExVHR2dH1Za6unyZfCVZHqQP0BtYjuUYlg9J6SurcrTEiOr26m5xcuTW4Sp3ljkUYWJ9+/iVmzbzPpcuXnGeqU3U7IKjz/qeKSSCltyhuSoxkqqTZX+DXt/OMmAikC8SzVD0jg3dbhIE0eUqc04UFFrxCSXzFxgHclzRMPe0ocOjiKRoSZISE0OtpkBjECdxkkRM1KiaJV0ed0V5umBP1wyUPL2ZBGLSDh5itIHahHRF0CY5nZMGib6T3cOmDvcTSZKuPiFJFpPRGNTIOq7jl5OjDiGIoo6qEE0QtfQJ3VYUD2RZvbm5uWWCWOgR4HXAk5GxLEO0izhLdvPTfpTV3xeOnOfT96uR53CdPrPq+P9HZvzO4QCMmDr7lTcNZorT6iMOYgI+IxClMzeCspeoLt5ABGSpta6gRZmQSnzk9e9jmOAYKC7RsyGMYaB6MpbNKMiRq2U6vI0yPZuTMiODFytMrGEBi7pjGgkAMoaNLGOFSoYceaZMx1+XTC/UNpmRzY1nmwT7AIcK+fK5lYNjz893lwMTuXlD2AKl8Md+24AxitRaLH/MUMqd9z862owy/bZTuZUqs1iRQop0KdLgZwPc9JS0lprnkef1gitBCRhjgV+vjGK8BfIV8CrlVghj1vIyZfyC/AJvqbsQYAEA/v+IAQA=");
+}
+
/* bidi */
:-moz-has-dir-attr {
diff --git a/servo/components/style/properties/cascade.rs b/servo/components/style/properties/cascade.rs
index 781f1a31f4288..f8fa6aa9880dc 100644
--- a/servo/components/style/properties/cascade.rs
+++ b/servo/components/style/properties/cascade.rs
@@ -794,6 +794,34 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_PADDING);
}
+ if self
+ .author_specified
+ .contains(LonghandId::FontFamily)
+ {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY);
+ }
+
+ if self
+ .author_specified
+ .contains(LonghandId::LetterSpacing)
+ {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING);
+ }
+
+ if self
+ .author_specified
+ .contains(LonghandId::WordSpacing)
+ {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING);
+ }
+
+ if self
+ .author_specified
+ .contains(LonghandId::FontSynthesis)
+ {
+ builder.add_flags(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS);
+ }
+
#[cfg(feature = "servo")]
{
if let Some(font) = builder.get_font_if_mutated() {
diff --git a/servo/components/style/properties/computed_value_flags.rs b/servo/components/style/properties/computed_value_flags.rs
index cc7d9c94fb90a..b3e5fe4f7f9bb 100644
--- a/servo/components/style/properties/computed_value_flags.rs
+++ b/servo/components/style/properties/computed_value_flags.rs
@@ -12,7 +12,7 @@ bitflags! {
/// If we ever want to add some flags that shouldn't inherit for them,
/// we might want to add a function to handle this.
#[repr(C)]
- pub struct ComputedValueFlags: u16 {
+ pub struct ComputedValueFlags: u32 {
/// Whether the style or any of the ancestors has a text-decoration-line
/// property that should get propagated to descendants.
///
@@ -89,6 +89,18 @@ bitflags! {
/// FIXME(emilio): Try to merge this with BORDER_BACKGROUND, see
/// https://github.com/w3c/csswg-drafts/issues/4777
const HAS_AUTHOR_SPECIFIED_PADDING = 1 << 15;
+
+ /// Whether there are author-specified rules for `font-family`.
+ const HAS_AUTHOR_SPECIFIED_FONT_FAMILY = 1 << 16;
+
+ /// Whether there are author-specified rules for `font-synthesis`.
+ const HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS = 1 << 17;
+
+ /// Whether there are author-specified rules for `letter-spacing`.
+ const HAS_AUTHOR_SPECIFIED_LETTER_SPACING = 1 << 18;
+
+ /// Whether there are author-specified rules for `word-spacing`.
+ const HAS_AUTHOR_SPECIFIED_WORD_SPACING = 1 << 19;
}
}
diff --git a/servo/components/style/style_adjuster.rs b/servo/components/style/style_adjuster.rs
index b29afe72691af..2d6a7a5b7b8c9 100644
--- a/servo/components/style/style_adjuster.rs
+++ b/servo/components/style/style_adjuster.rs
@@ -817,6 +817,52 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
}
}
+ /// A legacy ::marker (i.e. no 'content') without an author-specified 'font-family'
+ /// and 'list-style-type:disc|circle|square|disclosure-closed|disclosure-open'
+ /// is assigned 'font-family:-moz-bullet-font'. (This is for
- etc.)
+ /// We don't want synthesized italic/bold for this font, so turn that off too.
+ /// Likewise for 'letter/word-spacing' -- unless the author specified it then reset
+ /// them to their initial value because traditionally we never added such spacing
+ /// between a legacy bullet and the list item's content, so we keep that behavior
+ /// for web-compat reasons.
+ /// We intentionally don't check 'list-style-image' below since we want it to use
+ /// the same font as its fallback ('list-style-type') in case it fails to load.
+ #[cfg(feature = "gecko")]
+ fn adjust_for_marker_pseudo(&mut self) {
+ use crate::values::computed::font::{FamilyName, FontFamily, FontFamilyList, FontFamilyNameSyntax, FontSynthesis, SingleFontFamily};
+ use crate::values::computed::text::{LetterSpacing, WordSpacing};
+
+ let is_legacy_marker = self.style.pseudo.map_or(false, |p| p.is_marker()) &&
+ self.style.get_counters().ineffective_content_property() &&
+ self.style.get_list().clone_list_style_type().is_bullet();
+ if !is_legacy_marker {
+ return;
+ }
+ if !self.style.flags.get().contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_FAMILY) {
+ let moz_bullet_font_family = FontFamily {
+ families: FontFamilyList::new(Box::new([SingleFontFamily::FamilyName(FamilyName {
+ name: atom!("-moz-bullet-font"),
+ syntax: FontFamilyNameSyntax::Identifiers,
+ })])),
+ is_system_font: false,
+ };
+ self.style.mutate_font().set_font_family(moz_bullet_font_family);
+
+ // FIXME(mats): We can remove this if support for font-synthesis is added to @font-face rules.
+ // Then we can add it to the @font-face rule in html.css instead.
+ // https://github.com/w3c/csswg-drafts/issues/6081
+ if !self.style.flags.get().contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_FONT_SYNTHESIS) {
+ self.style.mutate_font().set_font_synthesis(FontSynthesis::none());
+ }
+ }
+ if !self.style.flags.get().contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_LETTER_SPACING) {
+ self.style.mutate_inherited_text().set_letter_spacing(LetterSpacing::normal());
+ }
+ if !self.style.flags.get().contains(ComputedValueFlags::HAS_AUTHOR_SPECIFIED_WORD_SPACING) {
+ self.style.mutate_inherited_text().set_word_spacing(WordSpacing::normal());
+ }
+ }
+
/// Adjusts the style to account for various fixups that don't fit naturally
/// into the cascade.
///
@@ -882,6 +928,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
{
self.adjust_for_appearance(element);
self.adjust_for_inert();
+ self.adjust_for_marker_pseudo();
}
self.set_bits();
}
diff --git a/servo/components/style/values/computed/text.rs b/servo/components/style/values/computed/text.rs
index b42dfb488a3d6..629626b06b338 100644
--- a/servo/components/style/values/computed/text.rs
+++ b/servo/components/style/values/computed/text.rs
@@ -110,6 +110,14 @@ impl ToComputedValue for specified::WordSpacing {
/// A computed value for the `line-height` property.
pub type LineHeight = GenericLineHeight;
+impl WordSpacing {
+ /// Return the `normal` computed value, which is just zero.
+ #[inline]
+ pub fn normal() -> Self {
+ LengthPercentage::zero()
+ }
+}
+
#[derive(Clone, Debug, MallocSizeOf, PartialEq, ToResolvedValue)]
#[repr(C)]
/// text-overflow.
diff --git a/servo/components/style/values/generics/mod.rs b/servo/components/style/values/generics/mod.rs
index b1536bb7f339d..7f05e22b6c610 100644
--- a/servo/components/style/values/generics/mod.rs
+++ b/servo/components/style/values/generics/mod.rs
@@ -95,6 +95,21 @@ impl CounterStyle {
pub fn decimal() -> Self {
CounterStyle::Name(CustomIdent(atom!("decimal")))
}
+
+ /// Is this a bullet? (i.e. `list-style-type: disc|circle|square|disclosure-closed|disclosure-open`)
+ #[inline]
+ pub fn is_bullet(&self) -> bool {
+ match self {
+ CounterStyle::Name(CustomIdent(ref name)) => {
+ name == &atom!("disc") ||
+ name == &atom!("circle") ||
+ name == &atom!("square") ||
+ name == &atom!("disclosure-closed") ||
+ name == &atom!("disclosure-open")
+ }
+ _ => false,
+ }
+ }
}
impl Parse for CounterStyle {
diff --git a/servo/components/style/values/specified/font.rs b/servo/components/style/values/specified/font.rs
index 8408e3b443745..14bd719070055 100644
--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -1972,6 +1972,14 @@ impl FontSynthesis {
style: true,
}
}
+ #[inline]
+ /// Get the 'none' value of font-synthesis
+ pub fn none() -> Self {
+ FontSynthesis {
+ weight: false,
+ style: false,
+ }
+ }
}
impl Parse for FontSynthesis {
diff --git a/servo/components/style/values/specified/list.rs b/servo/components/style/values/specified/list.rs
index 5d31c0b34d24b..14004e65cc831 100644
--- a/servo/components/style/values/specified/list.rs
+++ b/servo/components/style/values/specified/list.rs
@@ -67,6 +67,15 @@ impl ListStyleType {
_ => unreachable!("Unknown counter style keyword value"),
})))
}
+
+ /// Is this a bullet? (i.e. `list-style-type: disc|circle|square|disclosure-closed|disclosure-open`)
+ #[inline]
+ pub fn is_bullet(&self) -> bool {
+ match self {
+ ListStyleType::CounterStyle(ref style) => style.is_bullet(),
+ _ => false,
+ }
+ }
}
#[cfg(feature = "gecko")]
diff --git a/xpcom/ds/StaticAtoms.py b/xpcom/ds/StaticAtoms.py
index 8f90cac896207..2f5be143517ba 100644
--- a/xpcom/ds/StaticAtoms.py
+++ b/xpcom/ds/StaticAtoms.py
@@ -48,6 +48,7 @@
Atom("mozgeneratedcontentimage", "_moz_generated_content_image"),
Atom("mozquote", "_moz_quote"),
Atom("mozsignature", "moz-signature"), # Used by MailNews.
+ Atom("_moz_bullet_font", "-moz-bullet-font"),
Atom("_moz_is_glyph", "-moz-is-glyph"),
Atom("_moz_original_size", "_moz_original_size"),
Atom("_moz_print_preview", "-moz-print-preview"),