зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #16888 - Implement @counter-style for stylo (from upsuper:bug1328319); r=heycam,Manishearth,SimonSapin
Servo side change of [bug 1328319](https://bugzilla.mozilla.org/show_bug.cgi?id=1328319). Source-Repo: https://github.com/servo/servo Source-Revision: 1afc89e944c7ea7e4510b4b678a95a8faaa309b1 --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : c05b40bd3b03187aa1ea82629385669156bd9cf4
This commit is contained in:
Родитель
267a890b22
Коммит
fc0ebbbaff
|
@ -319,6 +319,7 @@ mod bindings {
|
|||
.include(add_include("mozilla/dom/NameSpaceConstants.h"))
|
||||
.include(add_include("mozilla/LookAndFeel.h"))
|
||||
.include(add_include("mozilla/ServoBindings.h"))
|
||||
.include(add_include("nsCSSCounterStyleRule.h"))
|
||||
.include(add_include("nsCSSFontFaceRule.h"))
|
||||
.include(add_include("nsMediaFeatures.h"))
|
||||
.include(add_include("nsMediaList.h"))
|
||||
|
@ -402,6 +403,7 @@ mod bindings {
|
|||
"nsBorderColors",
|
||||
"nscolor",
|
||||
"nsChangeHint",
|
||||
"nsCSSCounterStyleRule",
|
||||
"nsCSSFontFaceRule",
|
||||
"nsCSSKeyword",
|
||||
"nsCSSPropertyID",
|
||||
|
@ -691,6 +693,7 @@ mod bindings {
|
|||
"StyleBasicShapeType",
|
||||
"StyleShapeSource",
|
||||
"StyleTransition",
|
||||
"nsCSSCounterStyleRule",
|
||||
"nsCSSFontFaceRule",
|
||||
"nsCSSKeyword",
|
||||
"nsCSSPropertyID",
|
||||
|
|
|
@ -49,9 +49,9 @@ pub fn parse_counter_style_name(input: &mut Parser) -> Result<CustomIdent, ()> {
|
|||
|
||||
/// Parse the body (inside `{}`) of an @counter-style rule
|
||||
pub fn parse_counter_style_body(name: CustomIdent, context: &ParserContext, input: &mut Parser)
|
||||
-> Result<CounterStyleRule, ()> {
|
||||
-> Result<CounterStyleRuleData, ()> {
|
||||
let start = input.position();
|
||||
let mut rule = CounterStyleRule::empty(name);
|
||||
let mut rule = CounterStyleRuleData::empty(name);
|
||||
{
|
||||
let parser = CounterStyleRuleParser {
|
||||
context: context,
|
||||
|
@ -108,7 +108,7 @@ pub fn parse_counter_style_body(name: CustomIdent, context: &ParserContext, inpu
|
|||
|
||||
struct CounterStyleRuleParser<'a, 'b: 'a> {
|
||||
context: &'a ParserContext<'b>,
|
||||
rule: &'a mut CounterStyleRule,
|
||||
rule: &'a mut CounterStyleRuleData,
|
||||
}
|
||||
|
||||
/// Default methods reject all at rules.
|
||||
|
@ -143,7 +143,7 @@ macro_rules! counter_style_descriptors {
|
|||
) => {
|
||||
/// An @counter-style rule
|
||||
#[derive(Debug)]
|
||||
pub struct CounterStyleRule {
|
||||
pub struct CounterStyleRuleData {
|
||||
name: CustomIdent,
|
||||
$(
|
||||
#[$doc]
|
||||
|
@ -151,9 +151,9 @@ macro_rules! counter_style_descriptors {
|
|||
)+
|
||||
}
|
||||
|
||||
impl CounterStyleRule {
|
||||
impl CounterStyleRuleData {
|
||||
fn empty(name: CustomIdent) -> Self {
|
||||
CounterStyleRule {
|
||||
CounterStyleRuleData {
|
||||
name: name,
|
||||
$(
|
||||
$ident: None,
|
||||
|
@ -161,15 +161,20 @@ macro_rules! counter_style_descriptors {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the name of the counter style rule.
|
||||
pub fn name(&self) -> &CustomIdent {
|
||||
&self.name
|
||||
}
|
||||
|
||||
$(
|
||||
accessor!(#[$doc] $name $ident: $ty = $initial);
|
||||
)+
|
||||
|
||||
/// Convert to Gecko types
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn set_descriptors(&self, descriptors: &mut CounterStyleDescriptors) {
|
||||
pub fn set_descriptors(self, descriptors: &mut CounterStyleDescriptors) {
|
||||
$(
|
||||
if let Some(ref value) = self.$ident {
|
||||
if let Some(value) = self.$ident {
|
||||
descriptors[nsCSSCounterDesc::$gecko_ident as usize].set_from(value)
|
||||
}
|
||||
)*
|
||||
|
@ -197,7 +202,7 @@ macro_rules! counter_style_descriptors {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToCssWithGuard for CounterStyleRule {
|
||||
impl ToCssWithGuard for CounterStyleRuleData {
|
||||
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
dest.write_str("@counter-style ")?;
|
||||
|
@ -531,7 +536,7 @@ impl Parse for AdditiveSymbols {
|
|||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let tuples = Vec::<AdditiveTuple>::parse(context, input)?;
|
||||
// FIXME maybe? https://github.com/w3c/csswg-drafts/issues/1220
|
||||
if tuples.windows(2).any(|window| window[0].value <= window[1].value) {
|
||||
if tuples.windows(2).any(|window| window[0].weight <= window[1].weight) {
|
||||
return Err(())
|
||||
}
|
||||
Ok(AdditiveSymbols(tuples))
|
||||
|
@ -547,8 +552,10 @@ impl ToCss for AdditiveSymbols {
|
|||
/// <integer> && <symbol>
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AdditiveTuple {
|
||||
value: u32,
|
||||
symbol: Symbol,
|
||||
/// <integer>
|
||||
pub weight: u32,
|
||||
/// <symbol>
|
||||
pub symbol: Symbol,
|
||||
}
|
||||
|
||||
impl OneOrMoreCommaSeparated for AdditiveTuple {}
|
||||
|
@ -556,13 +563,13 @@ impl OneOrMoreCommaSeparated for AdditiveTuple {}
|
|||
impl Parse for AdditiveTuple {
|
||||
fn parse(context: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
let symbol = input.try(|input| Symbol::parse(context, input));
|
||||
let value = input.expect_integer()?;
|
||||
if value < 0 {
|
||||
let weight = input.expect_integer()?;
|
||||
if weight < 0 {
|
||||
return Err(())
|
||||
}
|
||||
let symbol = symbol.or_else(|()| Symbol::parse(context, input))?;
|
||||
Ok(AdditiveTuple {
|
||||
value: value as u32,
|
||||
weight: weight as u32,
|
||||
symbol: symbol,
|
||||
})
|
||||
}
|
||||
|
@ -570,7 +577,7 @@ impl Parse for AdditiveTuple {
|
|||
|
||||
impl ToCss for AdditiveTuple {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
write!(dest, "{} ", self.value)?;
|
||||
write!(dest, "{} ", self.weight)?;
|
||||
self.symbol.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,9 +208,9 @@ macro_rules! font_face_descriptors_common {
|
|||
|
||||
/// Convert to Gecko types
|
||||
#[cfg(feature = "gecko")]
|
||||
pub fn set_descriptors(&self, descriptors: &mut CSSFontFaceDescriptors) {
|
||||
pub fn set_descriptors(self, descriptors: &mut CSSFontFaceDescriptors) {
|
||||
$(
|
||||
if let Some(ref value) = self.$ident {
|
||||
if let Some(value) = self.$ident {
|
||||
descriptors.$gecko_ident.set_from(value)
|
||||
}
|
||||
)*
|
||||
|
|
|
@ -4,9 +4,11 @@
|
|||
|
||||
//! Data needed to style a Gecko document.
|
||||
|
||||
use Atom;
|
||||
use animation::Animation;
|
||||
use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut};
|
||||
use dom::OpaqueNode;
|
||||
use gecko::rules::{CounterStyleRule, FontFaceRule};
|
||||
use gecko_bindings::bindings::RawServoStyleSet;
|
||||
use gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use gecko_bindings::structs::nsIDocument;
|
||||
|
@ -19,7 +21,7 @@ use std::collections::HashMap;
|
|||
use std::sync::mpsc::{Receiver, Sender, channel};
|
||||
use stylearc::Arc;
|
||||
use stylesheet_set::StylesheetSet;
|
||||
use stylesheets::{FontFaceRule, Origin};
|
||||
use stylesheets::Origin;
|
||||
use stylist::{ExtraStyleData, Stylist};
|
||||
|
||||
/// The container for data that a Servo-backed Gecko document needs to style
|
||||
|
@ -47,6 +49,8 @@ pub struct PerDocumentStyleDataImpl {
|
|||
|
||||
/// List of effective font face rules.
|
||||
pub font_faces: Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
|
||||
/// Map for effective counter style rules.
|
||||
pub counter_styles: HashMap<Atom, Arc<Locked<CounterStyleRule>>>,
|
||||
}
|
||||
|
||||
/// The data itself is an `AtomicRefCell`, which guarantees the proper semantics
|
||||
|
@ -71,6 +75,7 @@ impl PerDocumentStyleData {
|
|||
running_animations: Arc::new(RwLock::new(HashMap::new())),
|
||||
expired_animations: Arc::new(RwLock::new(HashMap::new())),
|
||||
font_faces: vec![],
|
||||
counter_styles: HashMap::new(),
|
||||
}))
|
||||
}
|
||||
|
||||
|
@ -103,6 +108,7 @@ impl PerDocumentStyleDataImpl {
|
|||
|
||||
let mut extra_data = ExtraStyleData {
|
||||
font_faces: &mut self.font_faces,
|
||||
counter_styles: &mut self.counter_styles,
|
||||
};
|
||||
|
||||
let author_style_disabled = self.stylesheets.author_style_disabled();
|
||||
|
|
|
@ -2382,6 +2382,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_splitter: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms6springE"]
|
||||
pub static nsGkAtoms_spring: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms6squareE"]
|
||||
pub static nsGkAtoms_square: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms3srcE"]
|
||||
pub static nsGkAtoms_src: *mut nsIAtom;
|
||||
#[link_name = "_ZN9nsGkAtoms6srcdocE"]
|
||||
|
@ -7395,6 +7397,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_splitter: *mut nsIAtom;
|
||||
#[link_name = "?spring@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
pub static nsGkAtoms_spring: *mut nsIAtom;
|
||||
#[link_name = "?square@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
pub static nsGkAtoms_square: *mut nsIAtom;
|
||||
#[link_name = "?src@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
pub static nsGkAtoms_src: *mut nsIAtom;
|
||||
#[link_name = "?srcdoc@nsGkAtoms@@2PEAVnsIAtom@@EA"]
|
||||
|
@ -12408,6 +12412,8 @@ cfg_if! {
|
|||
pub static nsGkAtoms_splitter: *mut nsIAtom;
|
||||
#[link_name = "\x01?spring@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
pub static nsGkAtoms_spring: *mut nsIAtom;
|
||||
#[link_name = "\x01?square@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
pub static nsGkAtoms_square: *mut nsIAtom;
|
||||
#[link_name = "\x01?src@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
pub static nsGkAtoms_src: *mut nsIAtom;
|
||||
#[link_name = "\x01?srcdoc@nsGkAtoms@@2PAVnsIAtom@@A"]
|
||||
|
@ -17424,6 +17430,8 @@ macro_rules! atom {
|
|||
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_splitter as *mut _) } };
|
||||
("spring") =>
|
||||
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_spring as *mut _) } };
|
||||
("square") =>
|
||||
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_square as *mut _) } };
|
||||
("src") =>
|
||||
{ unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_src as *mut _) } };
|
||||
("srcdoc") =>
|
||||
|
|
|
@ -43,6 +43,7 @@ use gecko_bindings::structs::StyleBasicShape;
|
|||
use gecko_bindings::structs::StyleBasicShapeType;
|
||||
use gecko_bindings::structs::StyleShapeSource;
|
||||
use gecko_bindings::structs::StyleTransition;
|
||||
use gecko_bindings::structs::nsCSSCounterStyleRule;
|
||||
use gecko_bindings::structs::nsCSSFontFaceRule;
|
||||
use gecko_bindings::structs::nsCSSKeyword;
|
||||
use gecko_bindings::structs::nsCSSPropertyID;
|
||||
|
@ -813,7 +814,8 @@ extern "C" {
|
|||
aSrc: *const nsStyleVisibility);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetListStyleType(style_struct: *mut nsStyleList, type_: u32);
|
||||
pub fn Gecko_SetListStyleType(style_struct: *mut nsStyleList,
|
||||
name: *mut nsIAtom);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CopyListStyleTypeFrom(dst: *mut nsStyleList,
|
||||
|
@ -833,11 +835,15 @@ extern "C" {
|
|||
pub fn Gecko_ReleaseImageValueArbitraryThread(aPtr: *mut ImageValue);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_ImageValue_Create(uri: ServoBundledURI) -> *mut ImageValue;
|
||||
pub fn Gecko_ImageValue_Create(aURI: ServoBundledURI) -> *mut ImageValue;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetLayerImageImageValue(image: *mut nsStyleImage,
|
||||
imageValue: *mut ImageValue);
|
||||
aImageValue: *mut ImageValue);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetUrlImageValue(image: *mut nsStyleImage,
|
||||
uri: ServoBundledURI);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetImageElement(image: *mut nsStyleImage,
|
||||
|
@ -860,7 +866,11 @@ extern "C" {
|
|||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetListStyleImageImageValue(style_struct: *mut nsStyleList,
|
||||
imageValue: *mut ImageValue);
|
||||
aImageValue: *mut ImageValue);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetListStyleImage(style_struct: *mut nsStyleList,
|
||||
uri: ServoBundledURI);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CopyListStyleImageFrom(dest: *mut nsStyleList,
|
||||
|
@ -871,16 +881,24 @@ extern "C" {
|
|||
len: usize);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetCursorImageValue(cursor: *mut nsCursorImage,
|
||||
imageValue: *mut ImageValue);
|
||||
pub fn Gecko_SetCursorImageValue(aCursor: *mut nsCursorImage,
|
||||
aImageValue: *mut ImageValue);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetCursorImage(cursor: *mut nsCursorImage,
|
||||
uri: ServoBundledURI);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CopyCursorArrayFrom(dest: *mut nsStyleUserInterface,
|
||||
src: *const nsStyleUserInterface);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetContentDataImageValue(content_data: *mut nsStyleContentData,
|
||||
imageValue: *mut ImageValue);
|
||||
pub fn Gecko_SetContentDataImageValue(aList: *mut nsStyleContentData,
|
||||
aImageValue: *mut ImageValue);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetContentDataImage(content_data: *mut nsStyleContentData,
|
||||
uri: ServoBundledURI);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_SetContentDataArray(content_data: *mut nsStyleContentData,
|
||||
|
@ -1157,9 +1175,6 @@ extern "C" {
|
|||
pub fn Gecko_CSSValue_SetAbsoluteLength(css_value: nsCSSValueBorrowedMut,
|
||||
len: nscoord);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetNormal(css_value: nsCSSValueBorrowedMut);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetNumber(css_value: nsCSSValueBorrowedMut,
|
||||
number: f32);
|
||||
|
@ -1206,6 +1221,18 @@ extern "C" {
|
|||
pub fn Gecko_CSSValue_SetInt(css_value: nsCSSValueBorrowedMut,
|
||||
integer: i32, unit: nsCSSUnit);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetPair(css_value: nsCSSValueBorrowedMut,
|
||||
xvalue: nsCSSValueBorrowed,
|
||||
yvalue: nsCSSValueBorrowed);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetList(css_value: nsCSSValueBorrowedMut, len: u32);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_SetPairList(css_value: nsCSSValueBorrowedMut,
|
||||
len: u32);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSValue_Drop(css_value: nsCSSValueBorrowedMut);
|
||||
}
|
||||
|
@ -1272,6 +1299,22 @@ extern "C" {
|
|||
extern "C" {
|
||||
pub fn Gecko_CSSFontFaceRule_Release(aPtr: *mut nsCSSFontFaceRule);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSCounterStyle_Create(name: *mut nsIAtom)
|
||||
-> *mut nsCSSCounterStyleRule;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSCounterStyle_GetCssText(rule:
|
||||
*const nsCSSCounterStyleRule,
|
||||
result: *mut nsAString);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSCounterStyleRule_AddRef(aPtr: *mut nsCSSCounterStyleRule);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_CSSCounterStyleRule_Release(aPtr:
|
||||
*mut nsCSSCounterStyleRule);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Gecko_GetBody(pres_context: RawGeckoPresContextBorrowed)
|
||||
-> RawGeckoElementBorrowedOrNull;
|
||||
|
@ -1706,6 +1749,11 @@ extern "C" {
|
|||
list:
|
||||
RawGeckoFontFaceRuleListBorrowedMut);
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_GetCounterStyleRule(set: RawServoStyleSetBorrowed,
|
||||
name: *mut nsIAtom)
|
||||
-> *mut nsCSSCounterStyleRule;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleSet_ResolveForDeclarations(set:
|
||||
RawServoStyleSetBorrowed,
|
||||
|
@ -1832,6 +1880,11 @@ extern "C" {
|
|||
index: u32)
|
||||
-> *mut nsCSSFontFaceRule;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_CssRules_GetCounterStyleRuleAt(rules: ServoCssRulesBorrowed,
|
||||
index: u32)
|
||||
-> *mut nsCSSCounterStyleRule;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed)
|
||||
-> RawServoDeclarationBlockStrong;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -10,7 +10,8 @@ use counter_style;
|
|||
use cssparser::UnicodeRange;
|
||||
use font_face::{FontFaceRuleData, Source};
|
||||
use gecko_bindings::bindings;
|
||||
use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue, nsCSSCounterDesc};
|
||||
use gecko_bindings::structs::{self, nsCSSFontFaceRule, nsCSSValue};
|
||||
use gecko_bindings::structs::{nsCSSCounterDesc, nsCSSCounterStyleRule};
|
||||
use gecko_bindings::sugar::ns_css_value::ToNsCssValue;
|
||||
use gecko_bindings::sugar::refptr::{RefPtr, UniqueRefPtr};
|
||||
use shared_lock::{ToCssWithGuard, SharedRwLockReadGuard};
|
||||
|
@ -20,14 +21,14 @@ use std::fmt;
|
|||
pub type FontFaceRule = RefPtr<nsCSSFontFaceRule>;
|
||||
|
||||
impl ToNsCssValue for FamilyName {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_string_from_atom(&self.name)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for font_weight::T {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_integer(*self as i32)
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_integer(self as i32)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,8 +42,8 @@ macro_rules! map_enum {
|
|||
) => {
|
||||
$(
|
||||
impl ToNsCssValue for $prop::T {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_enum(match *self {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_enum(match self {
|
||||
$( $prop::T::$servo => structs::$gecko as i32, )+
|
||||
})
|
||||
}
|
||||
|
@ -72,7 +73,7 @@ map_enum! {
|
|||
}
|
||||
|
||||
impl ToNsCssValue for Vec<Source> {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
let src_len = self.iter().fold(0, |acc, src| {
|
||||
acc + match *src {
|
||||
// Each format hint takes one position in the array of mSrc.
|
||||
|
@ -85,15 +86,15 @@ impl ToNsCssValue for Vec<Source> {
|
|||
macro_rules! next { () => {
|
||||
target_srcs.next().expect("Length of target_srcs should be enough")
|
||||
} }
|
||||
for src in self.iter() {
|
||||
match *src {
|
||||
Source::Url(ref url) => {
|
||||
for src in self.into_iter() {
|
||||
match src {
|
||||
Source::Url(url) => {
|
||||
next!().set_url(&url.url);
|
||||
for hint in url.format_hints.iter() {
|
||||
next!().set_font_format(&hint);
|
||||
}
|
||||
}
|
||||
Source::Local(ref family) => {
|
||||
Source::Local(family) => {
|
||||
next!().set_local_font(&family.name);
|
||||
}
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ impl ToNsCssValue for Vec<Source> {
|
|||
}
|
||||
|
||||
impl ToNsCssValue for Vec<UnicodeRange> {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
let target_ranges = nscssvalue
|
||||
.set_array((self.len() * 2) as i32)
|
||||
.as_mut_slice().chunks_mut(2);
|
||||
|
@ -137,13 +138,38 @@ impl ToCssWithGuard for FontFaceRule {
|
|||
}
|
||||
}
|
||||
|
||||
/// A @counter-style rule
|
||||
pub type CounterStyleRule = RefPtr<nsCSSCounterStyleRule>;
|
||||
|
||||
impl From<counter_style::CounterStyleRuleData> for CounterStyleRule {
|
||||
fn from(data: counter_style::CounterStyleRuleData) -> CounterStyleRule {
|
||||
let mut result = unsafe {
|
||||
UniqueRefPtr::from_addrefed(
|
||||
bindings::Gecko_CSSCounterStyle_Create(data.name().0.as_ptr()))
|
||||
};
|
||||
data.set_descriptors(&mut result.mValues);
|
||||
result.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCssWithGuard for CounterStyleRule {
|
||||
fn to_css<W>(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result
|
||||
where W: fmt::Write {
|
||||
ns_auto_string!(css_text);
|
||||
unsafe {
|
||||
bindings::Gecko_CSSCounterStyle_GetCssText(self.get(), &mut *css_text);
|
||||
}
|
||||
write!(dest, "{}", css_text)
|
||||
}
|
||||
}
|
||||
|
||||
/// The type of nsCSSCounterStyleRule::mValues
|
||||
pub type CounterStyleDescriptors = [nsCSSValue; nsCSSCounterDesc::eCSSCounterDesc_COUNT as usize];
|
||||
|
||||
impl ToNsCssValue for counter_style::System {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
use counter_style::System::*;
|
||||
match *self {
|
||||
match self {
|
||||
Cyclic => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_CYCLIC as i32),
|
||||
Numeric => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_NUMERIC as i32),
|
||||
Alphabetic => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_ALPHABETIC as i32),
|
||||
|
@ -154,48 +180,48 @@ impl ToNsCssValue for counter_style::System {
|
|||
let mut b = nsCSSValue::null();
|
||||
a.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_FIXED as i32);
|
||||
b.set_integer(first_symbol_value.unwrap_or(1));
|
||||
//nscssvalue.set_pair(a, b); // FIXME: add bindings for nsCSSValue::SetPairValue
|
||||
nscssvalue.set_pair(&a, &b);
|
||||
}
|
||||
Extends(ref other) => {
|
||||
Extends(other) => {
|
||||
let mut a = nsCSSValue::null();
|
||||
let mut b = nsCSSValue::null();
|
||||
a.set_enum(structs::NS_STYLE_COUNTER_SYSTEM_EXTENDS as i32);
|
||||
b.set_string_from_atom(&other.0);
|
||||
//nscssvalue.set_pair(a, b); // FIXME: add bindings for nsCSSValue::SetPairValue
|
||||
b.set_atom_ident(other.0);
|
||||
nscssvalue.set_pair(&a, &b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Negative {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
if let Some(ref second) = self.1 {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
if let Some(second) = self.1 {
|
||||
let mut a = nsCSSValue::null();
|
||||
let mut b = nsCSSValue::null();
|
||||
a.set_from(&self.0);
|
||||
a.set_from(self.0);
|
||||
b.set_from(second);
|
||||
//nscssvalue.set_pair(a, b); // FIXME: add bindings for nsCSSValue::SetPairValue
|
||||
nscssvalue.set_pair(&a, &b);
|
||||
} else {
|
||||
nscssvalue.set_from(&self.0)
|
||||
nscssvalue.set_from(self.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Symbol {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
match *self {
|
||||
counter_style::Symbol::String(ref s) => nscssvalue.set_string(s),
|
||||
counter_style::Symbol::Ident(ref s) => nscssvalue.set_ident(s),
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
match self {
|
||||
counter_style::Symbol::String(s) => nscssvalue.set_string(&s),
|
||||
counter_style::Symbol::Ident(s) => nscssvalue.set_ident(&s),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Ranges {
|
||||
fn convert(&self, _nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
if self.0.is_empty() {
|
||||
//nscssvalue.set_auto(); // FIXME: add bindings for nsCSSValue::SetAutoValue
|
||||
nscssvalue.set_auto();
|
||||
} else {
|
||||
for range in &self.0 {
|
||||
nscssvalue.set_pair_list(self.0.into_iter().map(|range| {
|
||||
fn set_bound(bound: Option<i32>, nscssvalue: &mut nsCSSValue) {
|
||||
if let Some(finite) = bound {
|
||||
nscssvalue.set_integer(finite)
|
||||
|
@ -207,52 +233,59 @@ impl ToNsCssValue for counter_style::Ranges {
|
|||
let mut end = nsCSSValue::null();
|
||||
set_bound(range.start, &mut start);
|
||||
set_bound(range.end, &mut end);
|
||||
// FIXME: add bindings for nsCSSValuePairList
|
||||
}
|
||||
(start, end)
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Pad {
|
||||
fn convert(&self, _nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
let mut min_length = nsCSSValue::null();
|
||||
let mut pad_with = nsCSSValue::null();
|
||||
min_length.set_integer(self.0 as i32);
|
||||
pad_with.set_from(&self.1);
|
||||
// FIXME: add bindings for nsCSSValue::SetPairValue
|
||||
//nscssvalue.set_pair(min_length, pad_with);
|
||||
pad_with.set_from(self.1);
|
||||
nscssvalue.set_pair(&min_length, &pad_with);
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Fallback {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_ident_from_atom(&self.0 .0)
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_atom_ident(self.0 .0)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::Symbols {
|
||||
fn convert(&self, _nscssvalue: &mut nsCSSValue) {
|
||||
debug_assert!(!self.0.is_empty());
|
||||
// FIXME: add bindings for nsCSSValueList
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_list(self.0.into_iter().map(|item| {
|
||||
let mut value = nsCSSValue::null();
|
||||
value.set_from(item);
|
||||
value
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::AdditiveSymbols {
|
||||
fn convert(&self, _nscssvalue: &mut nsCSSValue) {
|
||||
debug_assert!(!self.0.is_empty());
|
||||
// FIXME: add bindings for nsCSSValuePairList
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
nscssvalue.set_pair_list(self.0.into_iter().map(|tuple| {
|
||||
let mut weight = nsCSSValue::null();
|
||||
let mut symbol = nsCSSValue::null();
|
||||
weight.set_integer(tuple.weight as i32);
|
||||
symbol.set_from(tuple.symbol);
|
||||
(weight, symbol)
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
impl ToNsCssValue for counter_style::SpeakAs {
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue) {
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue) {
|
||||
use counter_style::SpeakAs::*;
|
||||
match *self {
|
||||
Auto => {} //nscssvalue.set_auto(), // FIXME: add bindings for nsCSSValue::SetAutoValue
|
||||
match self {
|
||||
Auto => nscssvalue.set_auto(),
|
||||
Bullets => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SPEAKAS_BULLETS as i32),
|
||||
Numbers => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SPEAKAS_NUMBERS as i32),
|
||||
Words => nscssvalue.set_enum(structs::NS_STYLE_COUNTER_SPEAKAS_WORDS as i32),
|
||||
Other(ref other) => nscssvalue.set_ident_from_atom(&other.0),
|
||||
Other(other) => nscssvalue.set_atom_ident(other.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ pub fn each_class<F, T>(item: T,
|
|||
let length = getter(item, &mut class, &mut list);
|
||||
match length {
|
||||
0 => {}
|
||||
1 => Atom::with(class, &mut callback),
|
||||
1 => Atom::with(class, callback),
|
||||
n => {
|
||||
let classes = slice::from_raw_parts(list, n as usize);
|
||||
for c in classes {
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
use app_units::Au;
|
||||
use gecko_bindings::bindings;
|
||||
use gecko_bindings::structs;
|
||||
use gecko_bindings::structs::{nsCSSValue, nsCSSUnit};
|
||||
use gecko_bindings::structs::{nsCSSValue_Array, nscolor};
|
||||
use gecko_string_cache::Atom;
|
||||
|
@ -101,9 +102,24 @@ impl nsCSSValue {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_valueless_unit(&mut self, unit: nsCSSUnit) {
|
||||
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_Null);
|
||||
debug_assert!(unit as u32 <= nsCSSUnit::eCSSUnit_DummyInherit as u32, "Not a valueless unit");
|
||||
self.mUnit = unit;
|
||||
}
|
||||
|
||||
/// Set to an auto value
|
||||
///
|
||||
/// This method requires the current value to be null.
|
||||
pub fn set_auto(&mut self) {
|
||||
self.set_valueless_unit(nsCSSUnit::eCSSUnit_Auto);
|
||||
}
|
||||
|
||||
/// Set to a normal value
|
||||
///
|
||||
/// This method requires the current value to be null.
|
||||
pub fn set_normal(&mut self) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetNormal(self) }
|
||||
self.set_valueless_unit(nsCSSUnit::eCSSUnit_Normal);
|
||||
}
|
||||
|
||||
fn set_string_internal(&mut self, s: &str, unit: nsCSSUnit) {
|
||||
|
@ -175,7 +191,7 @@ impl nsCSSValue {
|
|||
}
|
||||
|
||||
/// Generic set from any value that implements the ToNsCssValue trait.
|
||||
pub fn set_from<T: ToNsCssValue>(&mut self, value: &T) {
|
||||
pub fn set_from<T: ToNsCssValue>(&mut self, value: T) {
|
||||
value.convert(self)
|
||||
}
|
||||
|
||||
|
@ -198,6 +214,52 @@ impl nsCSSValue {
|
|||
*self.mValue.mFloat.as_mut() = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// Set to a pair value
|
||||
///
|
||||
/// This is only supported on the main thread.
|
||||
pub fn set_pair(&mut self, x: &nsCSSValue, y: &nsCSSValue) {
|
||||
unsafe { bindings::Gecko_CSSValue_SetPair(self, x, y) }
|
||||
}
|
||||
|
||||
/// Set to a list value
|
||||
///
|
||||
/// This is only supported on the main thread.
|
||||
pub fn set_list<I>(&mut self, mut values: I) where I: ExactSizeIterator<Item=nsCSSValue> {
|
||||
debug_assert!(values.len() > 0, "Empty list is not supported");
|
||||
unsafe { bindings::Gecko_CSSValue_SetList(self, values.len() as u32); }
|
||||
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_List);
|
||||
let mut item_ptr = &mut unsafe {
|
||||
self.mValue.mList.as_ref() // &*nsCSSValueList_heap
|
||||
.as_mut().expect("List pointer should be non-null")
|
||||
}._base as *mut structs::nsCSSValueList;
|
||||
while let Some(item) = unsafe { item_ptr.as_mut() } {
|
||||
item.mValue = values.next().expect("Values shouldn't have been exhausted");
|
||||
item_ptr = item.mNext;
|
||||
}
|
||||
debug_assert!(values.next().is_none(), "Values should have been exhausted");
|
||||
}
|
||||
|
||||
/// Set to a pair list value
|
||||
///
|
||||
/// This is only supported on the main thread.
|
||||
pub fn set_pair_list<I>(&mut self, mut values: I)
|
||||
where I: ExactSizeIterator<Item=(nsCSSValue, nsCSSValue)> {
|
||||
debug_assert!(values.len() > 0, "Empty list is not supported");
|
||||
unsafe { bindings::Gecko_CSSValue_SetPairList(self, values.len() as u32); }
|
||||
debug_assert_eq!(self.mUnit, nsCSSUnit::eCSSUnit_PairList);
|
||||
let mut item_ptr = &mut unsafe {
|
||||
self.mValue.mPairList.as_ref() // &*nsCSSValuePairList_heap
|
||||
.as_mut().expect("List pointer should be non-null")
|
||||
}._base as *mut structs::nsCSSValuePairList;
|
||||
while let Some(item) = unsafe { item_ptr.as_mut() } {
|
||||
let value = values.next().expect("Values shouldn't have been exhausted");
|
||||
item.mXValue = value.0;
|
||||
item.mYValue = value.1;
|
||||
item_ptr = item.mNext;
|
||||
}
|
||||
debug_assert!(values.next().is_none(), "Values should have been exhausted");
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for nsCSSValue {
|
||||
|
@ -249,5 +311,5 @@ impl IndexMut<usize> for nsCSSValue_Array {
|
|||
/// Generic conversion to nsCSSValue
|
||||
pub trait ToNsCssValue {
|
||||
/// Convert
|
||||
fn convert(&self, nscssvalue: &mut nsCSSValue);
|
||||
fn convert(self, nscssvalue: &mut nsCSSValue);
|
||||
}
|
||||
|
|
|
@ -255,6 +255,8 @@ macro_rules! impl_refcount {
|
|||
|
||||
impl_refcount!(::gecko_bindings::structs::nsCSSFontFaceRule,
|
||||
Gecko_CSSFontFaceRule_AddRef, Gecko_CSSFontFaceRule_Release);
|
||||
impl_refcount!(::gecko_bindings::structs::nsCSSCounterStyleRule,
|
||||
Gecko_CSSCounterStyleRule_AddRef, Gecko_CSSCounterStyleRule_Release);
|
||||
|
||||
// Companion of NS_DECL_THREADSAFE_FFI_REFCOUNTING.
|
||||
//
|
||||
|
|
|
@ -198,7 +198,7 @@ impl fmt::Display for WeakAtom {
|
|||
|
||||
impl Atom {
|
||||
/// Execute a callback with the atom represented by `ptr`.
|
||||
pub unsafe fn with<F, R: 'static>(ptr: *mut nsIAtom, callback: &mut F) -> R where F: FnMut(&Atom) -> R {
|
||||
pub unsafe fn with<F, R>(ptr: *mut nsIAtom, callback: F) -> R where F: FnOnce(&Atom) -> R {
|
||||
let atom = Atom(WeakAtom::new(ptr));
|
||||
let ret = callback(&atom);
|
||||
mem::forget(atom);
|
||||
|
|
|
@ -2987,29 +2987,12 @@ fn static_assert() {
|
|||
}
|
||||
|
||||
pub fn set_list_style_type(&mut self, v: longhands::list_style_type::computed_value::T) {
|
||||
use properties::longhands::list_style_type::computed_value::T as Keyword;
|
||||
<%
|
||||
keyword = data.longhands_by_name["list-style-type"].keyword
|
||||
# The first four are @counter-styles
|
||||
# The rest have special fallback behavior
|
||||
special = """upper-roman lower-roman upper-alpha lower-alpha
|
||||
japanese-informal japanese-formal korean-hangul-formal korean-hanja-informal
|
||||
korean-hanja-formal simp-chinese-informal simp-chinese-formal
|
||||
trad-chinese-informal trad-chinese-formal""".split()
|
||||
%>
|
||||
let result = match v {
|
||||
% for value in keyword.values_for('gecko'):
|
||||
% if value in special:
|
||||
// Special keywords are implemented as @counter-styles
|
||||
// and need to be manually set as strings
|
||||
Keyword::${to_rust_ident(value)} => structs::${keyword.gecko_constant("none")},
|
||||
% else:
|
||||
Keyword::${to_rust_ident(value)} =>
|
||||
structs::${keyword.gecko_constant(value)},
|
||||
% endif
|
||||
% endfor
|
||||
use values::generics::CounterStyleOrNone;
|
||||
let name = match v.0 {
|
||||
CounterStyleOrNone::None_ => atom!("none"),
|
||||
CounterStyleOrNone::Name(name) => name.0,
|
||||
};
|
||||
unsafe { Gecko_SetListStyleType(&mut self.gecko, result as u32); }
|
||||
unsafe { Gecko_SetListStyleType(&mut self.gecko, name.as_ptr()); }
|
||||
}
|
||||
|
||||
|
||||
|
@ -4072,7 +4055,8 @@ clip-path
|
|||
pub fn set_content(&mut self, v: longhands::content::computed_value::T) {
|
||||
use properties::longhands::content::computed_value::T;
|
||||
use properties::longhands::content::computed_value::ContentItem;
|
||||
use style_traits::ToCss;
|
||||
use values::generics::CounterStyleOrNone;
|
||||
use gecko_bindings::structs::nsCSSValue;
|
||||
use gecko_bindings::structs::nsStyleContentType::*;
|
||||
use gecko_bindings::bindings::Gecko_ClearAndResizeStyleContents;
|
||||
|
||||
|
@ -4086,6 +4070,13 @@ clip-path
|
|||
ptr
|
||||
}
|
||||
|
||||
fn set_counter_style(style: CounterStyleOrNone, dest: &mut nsCSSValue) {
|
||||
dest.set_atom_ident(match style {
|
||||
CounterStyleOrNone::None_ => atom!("none"),
|
||||
CounterStyleOrNone::Name(name) => name.0,
|
||||
});
|
||||
}
|
||||
|
||||
match v {
|
||||
T::none |
|
||||
T::normal => {
|
||||
|
@ -4147,8 +4138,7 @@ clip-path
|
|||
}
|
||||
let mut array = unsafe { &mut **self.gecko.mContents[i].mContent.mCounters.as_mut() };
|
||||
array[0].set_string(&name);
|
||||
// When we support <custom-ident> values for list-style-type this will need to be updated
|
||||
array[1].set_atom_ident(style.to_css_string().into());
|
||||
set_counter_style(style, &mut array[1]);
|
||||
}
|
||||
ContentItem::Counters(name, sep, style) => {
|
||||
unsafe {
|
||||
|
@ -4158,8 +4148,7 @@ clip-path
|
|||
let mut array = unsafe { &mut **self.gecko.mContents[i].mContent.mCounters.as_mut() };
|
||||
array[0].set_string(&name);
|
||||
array[1].set_string(&sep);
|
||||
// When we support <custom-ident> values for list-style-type this will need to be updated
|
||||
array[2].set_atom_ident(style.to_css_string().into());
|
||||
set_counter_style(style, &mut array[2]);
|
||||
}
|
||||
ContentItem::Url(ref url) => {
|
||||
unsafe {
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
use cssparser::Token;
|
||||
use std::ascii::AsciiExt;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
#[cfg(feature = "gecko")]
|
||||
use values::generics::CounterStyleOrNone;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
use values::HasViewportPercentage;
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
use super::list_style_type;
|
||||
|
||||
pub use self::computed_value::T as SpecifiedValue;
|
||||
|
@ -23,22 +26,25 @@
|
|||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
pub mod computed_value {
|
||||
use super::super::list_style_type;
|
||||
|
||||
use cssparser;
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::specified::url::SpecifiedUrl;
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
type CounterStyleType = super::super::list_style_type::computed_value::T;
|
||||
#[cfg(feature = "gecko")]
|
||||
type CounterStyleType = ::values::generics::CounterStyleOrNone;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||
pub enum ContentItem {
|
||||
/// Literal string content.
|
||||
String(String),
|
||||
/// `counter(name, style)`.
|
||||
Counter(String, list_style_type::computed_value::T),
|
||||
Counter(String, CounterStyleType),
|
||||
/// `counters(name, separator, style)`.
|
||||
Counters(String, String, list_style_type::computed_value::T),
|
||||
Counters(String, String, CounterStyleType),
|
||||
/// `open-quote`.
|
||||
OpenQuote,
|
||||
/// `close-quote`.
|
||||
|
@ -64,20 +70,20 @@
|
|||
ContentItem::String(ref s) => {
|
||||
cssparser::serialize_string(&**s, dest)
|
||||
}
|
||||
ContentItem::Counter(ref s, ref list_style_type) => {
|
||||
ContentItem::Counter(ref s, ref counter_style) => {
|
||||
try!(dest.write_str("counter("));
|
||||
try!(cssparser::serialize_identifier(&**s, dest));
|
||||
try!(dest.write_str(", "));
|
||||
try!(list_style_type.to_css(dest));
|
||||
try!(counter_style.to_css(dest));
|
||||
dest.write_str(")")
|
||||
}
|
||||
ContentItem::Counters(ref s, ref separator, ref list_style_type) => {
|
||||
ContentItem::Counters(ref s, ref separator, ref counter_style) => {
|
||||
try!(dest.write_str("counters("));
|
||||
try!(cssparser::serialize_identifier(&**s, dest));
|
||||
try!(dest.write_str(", "));
|
||||
try!(cssparser::serialize_string(&**separator, dest));
|
||||
try!(dest.write_str(", "));
|
||||
try!(list_style_type.to_css(dest));
|
||||
try!(counter_style.to_css(dest));
|
||||
dest.write_str(")")
|
||||
}
|
||||
ContentItem::OpenQuote => dest.write_str("open-quote"),
|
||||
|
@ -134,6 +140,22 @@
|
|||
computed_value::T::normal
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> list_style_type::computed_value::T {
|
||||
input.try(|input| {
|
||||
input.expect_comma()?;
|
||||
list_style_type::parse(context, input)
|
||||
}).unwrap_or(list_style_type::computed_value::T::decimal)
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyleOrNone {
|
||||
input.try(|input| {
|
||||
input.expect_comma()?;
|
||||
CounterStyleOrNone::parse(context, input)
|
||||
}).unwrap_or(CounterStyleOrNone::decimal())
|
||||
}
|
||||
|
||||
// normal | none | [ <string> | <counter> | open-quote | close-quote | no-open-quote |
|
||||
// no-close-quote ]+
|
||||
// TODO: <uri>, attr(<identifier>)
|
||||
|
@ -162,20 +184,14 @@
|
|||
content.push(try!(match_ignore_ascii_case! { &name,
|
||||
"counter" => input.parse_nested_block(|input| {
|
||||
let name = try!(input.expect_ident()).into_owned();
|
||||
let style = input.try(|input| {
|
||||
try!(input.expect_comma());
|
||||
list_style_type::parse(context, input)
|
||||
}).unwrap_or(list_style_type::computed_value::T::decimal);
|
||||
let style = parse_counter_style(context, input);
|
||||
Ok(ContentItem::Counter(name, style))
|
||||
}),
|
||||
"counters" => input.parse_nested_block(|input| {
|
||||
let name = try!(input.expect_ident()).into_owned();
|
||||
try!(input.expect_comma());
|
||||
let separator = try!(input.expect_string()).into_owned();
|
||||
let style = input.try(|input| {
|
||||
try!(input.expect_comma());
|
||||
list_style_type::parse(context, input)
|
||||
}).unwrap_or(list_style_type::computed_value::T::decimal);
|
||||
let style = parse_counter_style(context, input);
|
||||
Ok(ContentItem::Counters(name, separator, style))
|
||||
}),
|
||||
% if product == "gecko":
|
||||
|
|
|
@ -721,7 +721,7 @@ ${helpers.single_keyword_system("font-variant-caps",
|
|||
// XXXManishearth handle quirks mode
|
||||
|
||||
let ref gecko_font = cx.style().get_font().gecko();
|
||||
let base_size = unsafe { Atom::with(gecko_font.mLanguage.raw::<nsIAtom>(), &mut |atom| {
|
||||
let base_size = unsafe { Atom::with(gecko_font.mLanguage.raw::<nsIAtom>(), |atom| {
|
||||
cx.font_metrics_provider.get_size(atom, gecko_font.mGenericID).0
|
||||
}) };
|
||||
|
||||
|
|
|
@ -21,21 +21,85 @@ ${helpers.single_keyword("list-style-position", "outside inside", animation_valu
|
|||
// we may need to look into this and handle these differently.
|
||||
//
|
||||
// [1]: http://dev.w3.org/csswg/css-counter-styles/
|
||||
${helpers.single_keyword("list-style-type", """
|
||||
disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha
|
||||
""", extra_servo_values="""arabic-indic bengali cambodian cjk-decimal devanagari
|
||||
gujarati gurmukhi kannada khmer lao malayalam mongolian
|
||||
myanmar oriya persian telugu thai tibetan cjk-earthly-branch
|
||||
cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana
|
||||
katakana-iroha""",
|
||||
extra_gecko_values="""japanese-informal japanese-formal korean-hangul-formal
|
||||
korean-hanja-formal korean-hanja-informal simp-chinese-informal simp-chinese-formal
|
||||
trad-chinese-informal trad-chinese-formal ethiopic-numeric upper-roman lower-roman
|
||||
""",
|
||||
gecko_constant_prefix="NS_STYLE_LIST_STYLE",
|
||||
needs_conversion="True",
|
||||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")}
|
||||
% if product == "servo":
|
||||
${helpers.single_keyword("list-style-type", """
|
||||
disc none circle square decimal disclosure-open disclosure-closed lower-alpha upper-alpha
|
||||
arabic-indic bengali cambodian cjk-decimal devanagari gujarati gurmukhi kannada khmer lao
|
||||
malayalam mongolian myanmar oriya persian telugu thai tibetan cjk-earthly-branch
|
||||
cjk-heavenly-stem lower-greek hiragana hiragana-iroha katakana katakana-iroha""",
|
||||
needs_conversion="True",
|
||||
animation_value_type="none",
|
||||
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type")}
|
||||
% else:
|
||||
<%helpers:longhand name="list-style-type" animation_value_type="none"
|
||||
spec="https://drafts.csswg.org/css-lists/#propdef-list-style-type">
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use values::CustomIdent;
|
||||
use values::HasViewportPercentage;
|
||||
use values::computed::ComputedValueAsSpecified;
|
||||
use values::generics::CounterStyleOrNone;
|
||||
|
||||
pub use self::computed_value::T as SpecifiedValue;
|
||||
|
||||
pub mod computed_value {
|
||||
use values::generics::CounterStyleOrNone;
|
||||
|
||||
/// <counter-style> | none
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct T(pub CounterStyleOrNone);
|
||||
}
|
||||
|
||||
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||
no_viewport_percentage!(SpecifiedValue);
|
||||
|
||||
impl ToCss for SpecifiedValue {
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
self.0.to_css(dest)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl SpecifiedValue {
|
||||
/// Convert from gecko keyword to list-style-type.
|
||||
///
|
||||
/// This should only be used for mapping type attribute to
|
||||
/// list-style-type, and thus only values possible in that
|
||||
/// attribute is considered here.
|
||||
pub fn from_gecko_keyword(value: u32) -> Self {
|
||||
use gecko_bindings::structs;
|
||||
SpecifiedValue(if value == structs::NS_STYLE_LIST_STYLE_NONE {
|
||||
CounterStyleOrNone::None_
|
||||
} else {
|
||||
<%
|
||||
values = """disc circle square decimal lower-roman
|
||||
upper-roman lower-alpha upper-alpha""".split()
|
||||
%>
|
||||
CounterStyleOrNone::Name(CustomIdent(match value {
|
||||
% for style in values:
|
||||
structs::NS_STYLE_LIST_STYLE_${style.replace('-', '_').upper()} => atom!("${style}"),
|
||||
% endfor
|
||||
_ => unreachable!("Unknown counter style keyword value"),
|
||||
}))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_value() -> computed_value::T {
|
||||
computed_value::T(CounterStyleOrNone::disc())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_initial_specified_value() -> SpecifiedValue {
|
||||
SpecifiedValue(CounterStyleOrNone::disc())
|
||||
}
|
||||
|
||||
pub fn parse(context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
|
||||
CounterStyleOrNone::parse(context, input).map(SpecifiedValue)
|
||||
}
|
||||
</%helpers:longhand>
|
||||
% endif
|
||||
|
||||
<%helpers:longhand name="list-style-image" animation_value_type="none"
|
||||
boxed="${product == 'gecko'}"
|
||||
|
|
|
@ -25,14 +25,6 @@
|
|||
continue
|
||||
}
|
||||
|
||||
if list_style_type.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) {
|
||||
list_style_type = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if image.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_image::parse(context, input)) {
|
||||
image = Some(value);
|
||||
|
@ -48,11 +40,31 @@
|
|||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// list-style-type must be checked the last, because it accepts
|
||||
// arbitrary identifier for custom counter style, and thus may
|
||||
// affect values of list-style-position.
|
||||
if list_style_type.is_none() {
|
||||
if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) {
|
||||
list_style_type = Some(value);
|
||||
any = true;
|
||||
continue
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
let position = unwrap_or_initial!(list_style_position, position);
|
||||
|
||||
fn list_style_type_none() -> list_style_type::SpecifiedValue {
|
||||
% if product == "servo":
|
||||
list_style_type::SpecifiedValue::none
|
||||
% else:
|
||||
use values::generics::CounterStyleOrNone;
|
||||
list_style_type::SpecifiedValue(CounterStyleOrNone::None_)
|
||||
% endif
|
||||
}
|
||||
|
||||
// If there are two `none`s, then we can't have a type or image; if there is one `none`,
|
||||
// then we can't have both a type *and* an image; if there is no `none` then we're fine as
|
||||
// long as we parsed something.
|
||||
|
@ -61,14 +73,14 @@
|
|||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)),
|
||||
list_style_type: list_style_type::SpecifiedValue::none,
|
||||
list_style_type: list_style_type_none(),
|
||||
})
|
||||
}
|
||||
(true, 1, None, Some(image)) => {
|
||||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: image,
|
||||
list_style_type: list_style_type::SpecifiedValue::none,
|
||||
list_style_type: list_style_type_none(),
|
||||
})
|
||||
}
|
||||
(true, 1, Some(list_style_type), None) => {
|
||||
|
@ -82,7 +94,7 @@
|
|||
Ok(Longhands {
|
||||
list_style_position: position,
|
||||
list_style_image: list_style_image::SpecifiedValue(Either::Second(None_)),
|
||||
list_style_type: list_style_type::SpecifiedValue::none,
|
||||
list_style_type: list_style_type_none(),
|
||||
})
|
||||
}
|
||||
(true, 0, list_style_type, image) => {
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
use {Atom, Prefix, Namespace};
|
||||
use context::QuirksMode;
|
||||
use counter_style::{CounterStyleRule, parse_counter_style_name, parse_counter_style_body};
|
||||
use counter_style::{parse_counter_style_name, parse_counter_style_body};
|
||||
#[cfg(feature = "servo")]
|
||||
use counter_style::CounterStyleRuleData;
|
||||
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser};
|
||||
use cssparser::{AtRuleType, RuleListParser, parse_one_rule, SourceLocation};
|
||||
use cssparser::ToCss as ParserToCss;
|
||||
|
@ -18,7 +20,7 @@ use error_reporting::{ParseErrorReporter, NullReporter};
|
|||
use font_face::FontFaceRuleData;
|
||||
use font_face::parse_font_face_block;
|
||||
#[cfg(feature = "gecko")]
|
||||
pub use gecko::rules::FontFaceRule;
|
||||
pub use gecko::rules::{CounterStyleRule, FontFaceRule};
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::URLExtraData;
|
||||
#[cfg(feature = "gecko")]
|
||||
|
@ -697,6 +699,10 @@ impl ToCssWithGuard for StyleRule {
|
|||
#[cfg(feature = "servo")]
|
||||
pub type FontFaceRule = FontFaceRuleData;
|
||||
|
||||
/// A @counter-style rule
|
||||
#[cfg(feature = "servo")]
|
||||
pub type CounterStyleRule = CounterStyleRuleData;
|
||||
|
||||
#[derive(Debug)]
|
||||
/// A @-moz-document rule
|
||||
pub struct DocumentRule {
|
||||
|
@ -1282,7 +1288,7 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> {
|
|||
AtRulePrelude::CounterStyle(name) => {
|
||||
let context = ParserContext::new_with_rule_type(self.context, Some(CssRuleType::CounterStyle));
|
||||
Ok(CssRule::CounterStyle(Arc::new(self.shared_lock.wrap(
|
||||
parse_counter_style_body(name, &context, input)?))))
|
||||
parse_counter_style_body(name, &context, input)?.into()))))
|
||||
}
|
||||
AtRulePrelude::Media(media_queries, location) => {
|
||||
Ok(CssRule::Media(Arc::new(self.shared_lock.wrap(MediaRule {
|
||||
|
|
|
@ -14,6 +14,8 @@ use dom::{AnimationRules, TElement};
|
|||
use element_state::ElementState;
|
||||
use error_reporting::RustLogReporter;
|
||||
use font_metrics::FontMetricsProvider;
|
||||
#[cfg(feature = "gecko")]
|
||||
use gecko_bindings::structs::nsIAtom;
|
||||
use keyframes::KeyframesAnimation;
|
||||
use media_queries::Device;
|
||||
use pdqsort::sort_by;
|
||||
|
@ -41,7 +43,10 @@ use std::hash::Hash;
|
|||
use std::marker::PhantomData;
|
||||
use style_traits::viewport::ViewportConstraints;
|
||||
use stylearc::Arc;
|
||||
use stylesheets::{CssRule, FontFaceRule, Origin, StyleRule, Stylesheet, UserAgentStylesheets};
|
||||
#[cfg(feature = "gecko")]
|
||||
use stylesheets::{CounterStyleRule, FontFaceRule};
|
||||
use stylesheets::{CssRule, Origin};
|
||||
use stylesheets::{StyleRule, Stylesheet, UserAgentStylesheets};
|
||||
#[cfg(feature = "servo")]
|
||||
use stylesheets::NestedRulesResult;
|
||||
use thread_state;
|
||||
|
@ -168,33 +173,44 @@ pub struct Stylist {
|
|||
|
||||
/// This struct holds data which user of Stylist may want to extract
|
||||
/// from stylesheets which can be done at the same time as updating.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub struct ExtraStyleData<'a> {
|
||||
/// A list of effective font-face rules and their origin.
|
||||
#[cfg(feature = "gecko")]
|
||||
pub font_faces: &'a mut Vec<(Arc<Locked<FontFaceRule>>, Origin)>,
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg(feature = "servo")]
|
||||
pub marker: PhantomData<&'a usize>,
|
||||
/// A map of effective counter-style rules.
|
||||
pub counter_styles: &'a mut HashMap<Atom, Arc<Locked<CounterStyleRule>>>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
impl<'a> ExtraStyleData<'a> {
|
||||
/// Clear the internal @font-face rule list.
|
||||
fn clear_font_faces(&mut self) {
|
||||
/// Clear the internal data.
|
||||
fn clear(&mut self) {
|
||||
self.font_faces.clear();
|
||||
self.counter_styles.clear();
|
||||
}
|
||||
|
||||
/// Add the given @font-face rule.
|
||||
fn add_font_face(&mut self, rule: &Arc<Locked<FontFaceRule>>, origin: Origin) {
|
||||
self.font_faces.push((rule.clone(), origin));
|
||||
}
|
||||
|
||||
/// Add the given @counter-style rule.
|
||||
fn add_counter_style(&mut self, guard: &SharedRwLockReadGuard,
|
||||
rule: &Arc<Locked<CounterStyleRule>>) {
|
||||
let name = rule.read_with(guard).mName.raw::<nsIAtom>().into();
|
||||
self.counter_styles.insert(name, rule.clone());
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[cfg(feature = "servo")]
|
||||
pub struct ExtraStyleData<'a> {
|
||||
pub marker: PhantomData<&'a usize>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "servo")]
|
||||
impl<'a> ExtraStyleData<'a> {
|
||||
fn clear_font_faces(&mut self) {}
|
||||
fn add_font_face(&mut self, _: &Arc<Locked<FontFaceRule>>, _: Origin) {}
|
||||
fn clear(&mut self) {}
|
||||
}
|
||||
|
||||
impl Stylist {
|
||||
|
@ -343,7 +359,7 @@ impl Stylist {
|
|||
self.pseudos_map.insert(pseudo, PerPseudoElementSelectorMap::new());
|
||||
});
|
||||
|
||||
extra_data.clear_font_faces();
|
||||
extra_data.clear();
|
||||
|
||||
if let Some(ua_stylesheets) = ua_stylesheets {
|
||||
for stylesheet in &ua_stylesheets.user_or_user_agent_stylesheets {
|
||||
|
@ -443,9 +459,14 @@ impl Stylist {
|
|||
self.animations.insert(keyframes_rule.name.as_atom().clone(), animation);
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
CssRule::FontFace(ref rule) => {
|
||||
extra_data.add_font_face(&rule, stylesheet.origin);
|
||||
}
|
||||
#[cfg(feature = "gecko")]
|
||||
CssRule::CounterStyle(ref rule) => {
|
||||
extra_data.add_counter_style(guard, &rule);
|
||||
}
|
||||
// We don't care about any other rule.
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,13 @@
|
|||
//! Generic types that share their serialization implementations
|
||||
//! for both specified and computed values.
|
||||
|
||||
use counter_style::parse_counter_style_name;
|
||||
use cssparser::Parser;
|
||||
use euclid::size::Size2D;
|
||||
use parser::{Parse, ParserContext};
|
||||
use std::fmt;
|
||||
use style_traits::ToCss;
|
||||
use super::CustomIdent;
|
||||
use super::HasViewportPercentage;
|
||||
use super::computed::{Context, ToComputedValue};
|
||||
|
||||
|
@ -75,3 +79,49 @@ impl<L: ToComputedValue> ToComputedValue for BorderRadiusSize<L> {
|
|||
BorderRadiusSize(Size2D::new(w, h))
|
||||
}
|
||||
}
|
||||
|
||||
/// https://drafts.csswg.org/css-counter-styles/#typedef-counter-style
|
||||
///
|
||||
/// Since wherever <counter-style> is used, 'none' is a valid value as
|
||||
/// well, we combine them into one type to make code simpler.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum CounterStyleOrNone {
|
||||
/// none
|
||||
None_,
|
||||
/// <counter-style-name>
|
||||
Name(CustomIdent),
|
||||
}
|
||||
|
||||
impl CounterStyleOrNone {
|
||||
/// disc value
|
||||
pub fn disc() -> Self {
|
||||
CounterStyleOrNone::Name(CustomIdent(atom!("disc")))
|
||||
}
|
||||
|
||||
/// decimal value
|
||||
pub fn decimal() -> Self {
|
||||
CounterStyleOrNone::Name(CustomIdent(atom!("decimal")))
|
||||
}
|
||||
}
|
||||
|
||||
no_viewport_percentage!(CounterStyleOrNone);
|
||||
|
||||
impl Parse for CounterStyleOrNone {
|
||||
fn parse(_: &ParserContext, input: &mut Parser) -> Result<Self, ()> {
|
||||
input.try(|input| {
|
||||
parse_counter_style_name(input).map(CounterStyleOrNone::Name)
|
||||
}).or_else(|_| {
|
||||
input.expect_ident_matching("none").map(|_| CounterStyleOrNone::None_)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCss for CounterStyleOrNone {
|
||||
#[inline]
|
||||
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
|
||||
match self {
|
||||
&CounterStyleOrNone::None_ => dest.write_str("none"),
|
||||
&CounterStyleOrNone::Name(ref name) => name.to_css(dest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,8 @@ use style::gecko_bindings::structs;
|
|||
use style::gecko_bindings::structs::{CSSPseudoElementType, CompositeOperation};
|
||||
use style::gecko_bindings::structs::{RawServoStyleRule, ServoStyleSheet};
|
||||
use style::gecko_bindings::structs::{SheetParsingMode, nsIAtom, nsCSSPropertyID};
|
||||
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint, nsCSSFontFaceRule};
|
||||
use style::gecko_bindings::structs::{nsCSSFontFaceRule, nsCSSCounterStyleRule};
|
||||
use style::gecko_bindings::structs::{nsRestyleHint, nsChangeHint};
|
||||
use style::gecko_bindings::structs::Loader;
|
||||
use style::gecko_bindings::structs::RawGeckoPresContextOwned;
|
||||
use style::gecko_bindings::structs::ServoElementSnapshotTable;
|
||||
|
@ -871,19 +872,28 @@ impl_group_rule_funcs! { (Document, DocumentRule, RawServoDocumentRule),
|
|||
to_css: Servo_DocumentRule_GetCssText,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_CssRules_GetFontFaceRuleAt(rules: ServoCssRulesBorrowed, index: u32)
|
||||
-> *mut nsCSSFontFaceRule
|
||||
{
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
|
||||
match rules.0[index as usize] {
|
||||
CssRule::FontFace(ref rule) => rule.read_with(&guard).get(),
|
||||
_ => unreachable!("Servo_CssRules_GetFontFaceRuleAt should only be called on a FontFace rule"),
|
||||
macro_rules! impl_getter_for_embedded_rule {
|
||||
($getter:ident: $name:ident -> $ty:ty) => {
|
||||
#[no_mangle]
|
||||
pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> *mut $ty
|
||||
{
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
|
||||
match rules.0[index as usize] {
|
||||
CssRule::$name(ref rule) => rule.read_with(&guard).get(),
|
||||
_ => unreachable!(concat!(stringify!($getter), " should only be called on a ",
|
||||
stringify!($name), " rule")),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl_getter_for_embedded_rule!(Servo_CssRules_GetFontFaceRuleAt:
|
||||
FontFace -> nsCSSFontFaceRule);
|
||||
impl_getter_for_embedded_rule!(Servo_CssRules_GetCounterStyleRuleAt:
|
||||
CounterStyle -> nsCSSCounterStyleRule);
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleRule_GetStyle(rule: RawServoStyleRuleBorrowed) -> RawServoDeclarationBlockStrong {
|
||||
read_locked_arc(rule, |rule: &StyleRule| {
|
||||
|
@ -2374,6 +2384,19 @@ pub extern "C" fn Servo_StyleSet_GetFontFaceRules(raw_data: RawServoStyleSetBorr
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_GetCounterStyleRule(raw_data: RawServoStyleSetBorrowed,
|
||||
name: *mut nsIAtom) -> *mut nsCSSCounterStyleRule {
|
||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
unsafe {
|
||||
Atom::with(name, |name| data.counter_styles.get(name))
|
||||
}.map(|rule| {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
rule.read_with(&guard).get()
|
||||
}).unwrap_or(ptr::null_mut())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(raw_data: RawServoStyleSetBorrowed,
|
||||
parent_style_or_null: ServoComputedValuesBorrowedOrNull,
|
||||
|
@ -2401,7 +2424,7 @@ pub extern "C" fn Servo_StyleSet_ResolveForDeclarations(raw_data: RawServoStyleS
|
|||
pub extern "C" fn Servo_StyleSet_MightHaveAttributeDependency(raw_data: RawServoStyleSetBorrowed,
|
||||
local_name: *mut nsIAtom) -> bool {
|
||||
let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
|
||||
unsafe { Atom::with(local_name, &mut |atom| data.stylist.might_have_attribute_dependency(atom)) }
|
||||
unsafe { Atom::with(local_name, |atom| data.stylist.might_have_attribute_dependency(atom)) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
Загрузка…
Ссылка в новой задаче