mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #26978 - servo:gecko-sync, r=jdm
style: Sync changes from mozilla-central
This commit is contained in:
commit
8e3b4b6fe5
82 changed files with 693 additions and 672 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -519,6 +519,7 @@ dependencies = [
|
||||||
"servo_config",
|
"servo_config",
|
||||||
"sparkle",
|
"sparkle",
|
||||||
"style",
|
"style",
|
||||||
|
"style_traits",
|
||||||
"surfman",
|
"surfman",
|
||||||
"surfman-chains",
|
"surfman-chains",
|
||||||
"surfman-chains-api",
|
"surfman-chains-api",
|
||||||
|
@ -5466,7 +5467,6 @@ dependencies = [
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"euclid",
|
"euclid",
|
||||||
"fallible",
|
"fallible",
|
||||||
"font-kit",
|
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"hashglobe",
|
"hashglobe",
|
||||||
"html5ever",
|
"html5ever",
|
||||||
|
|
|
@ -37,6 +37,7 @@ servo_arc = { path = "../servo_arc" }
|
||||||
servo_config = { path = "../config" }
|
servo_config = { path = "../config" }
|
||||||
sparkle = "0.1.25"
|
sparkle = "0.1.25"
|
||||||
style = { path = "../style" }
|
style = { path = "../style" }
|
||||||
|
style_traits = { path = "../style_traits" }
|
||||||
# NOTE: the sm-angle feature only enables ANGLE on Windows, not other platforms!
|
# NOTE: the sm-angle feature only enables ANGLE on Windows, not other platforms!
|
||||||
surfman = { version = "0.2", features = ["sm-angle", "sm-angle-default"] }
|
surfman = { version = "0.2", features = ["sm-angle", "sm-angle-default"] }
|
||||||
surfman-chains = "0.3"
|
surfman-chains = "0.3"
|
||||||
|
|
|
@ -11,7 +11,7 @@ use euclid::{point2, vec2};
|
||||||
use font_kit::family_name::FamilyName;
|
use font_kit::family_name::FamilyName;
|
||||||
use font_kit::font::Font;
|
use font_kit::font::Font;
|
||||||
use font_kit::metrics::Metrics;
|
use font_kit::metrics::Metrics;
|
||||||
use font_kit::properties::Properties;
|
use font_kit::properties::{Properties, Stretch, Style, Weight};
|
||||||
use font_kit::source::SystemSource;
|
use font_kit::source::SystemSource;
|
||||||
use gfx::font::FontHandleMethods;
|
use gfx::font::FontHandleMethods;
|
||||||
use gfx::font_cache_thread::FontCacheThread;
|
use gfx::font_cache_thread::FontCacheThread;
|
||||||
|
@ -25,6 +25,8 @@ use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use style::properties::style_structs::Font as FontStyleStruct;
|
use style::properties::style_structs::Font as FontStyleStruct;
|
||||||
|
use style::values::computed::font;
|
||||||
|
use style_traits::values::ToCss;
|
||||||
use webrender_api::units::RectExt as RectExt_;
|
use webrender_api::units::RectExt as RectExt_;
|
||||||
|
|
||||||
/// The canvas data stores a state machine for the current status of
|
/// The canvas data stores a state machine for the current status of
|
||||||
|
@ -1372,6 +1374,22 @@ impl RectExt for Rect<u32> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn to_font_kit_family(font_family: &font::SingleFontFamily) -> FamilyName {
|
||||||
|
match font_family {
|
||||||
|
font::SingleFontFamily::FamilyName(family_name) => {
|
||||||
|
FamilyName::Title(family_name.to_css_string())
|
||||||
|
},
|
||||||
|
font::SingleFontFamily::Generic(generic) => match generic {
|
||||||
|
font::GenericFontFamily::Serif => FamilyName::Serif,
|
||||||
|
font::GenericFontFamily::SansSerif => FamilyName::SansSerif,
|
||||||
|
font::GenericFontFamily::Monospace => FamilyName::Monospace,
|
||||||
|
font::GenericFontFamily::Fantasy => FamilyName::Fantasy,
|
||||||
|
font::GenericFontFamily::Cursive => FamilyName::Cursive,
|
||||||
|
font::GenericFontFamily::None => unreachable!("Shouldn't appear in computed values"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn load_system_font_from_style(font_style: Option<&FontStyleStruct>) -> Font {
|
fn load_system_font_from_style(font_style: Option<&FontStyleStruct>) -> Font {
|
||||||
let mut properties = Properties::new();
|
let mut properties = Properties::new();
|
||||||
let style = match font_style {
|
let style = match font_style {
|
||||||
|
@ -1382,12 +1400,19 @@ fn load_system_font_from_style(font_style: Option<&FontStyleStruct>) -> Font {
|
||||||
.font_family
|
.font_family
|
||||||
.families
|
.families
|
||||||
.iter()
|
.iter()
|
||||||
.map(|family_name| family_name.into())
|
.map(to_font_kit_family)
|
||||||
.collect::<Vec<FamilyName>>();
|
.collect::<Vec<_>>();
|
||||||
let properties = properties
|
let properties = properties
|
||||||
.style(style.font_style.into())
|
.style(match style.font_style {
|
||||||
.weight(style.font_weight.into())
|
font::FontStyle::Normal => Style::Normal,
|
||||||
.stretch(style.font_stretch.into());
|
font::FontStyle::Italic => Style::Italic,
|
||||||
|
font::FontStyle::Oblique(..) => {
|
||||||
|
// TODO: support oblique angle.
|
||||||
|
Style::Oblique
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.weight(Weight(style.font_weight.0))
|
||||||
|
.stretch(Stretch(style.font_stretch.value()));
|
||||||
let font_handle = match SystemSource::new().select_best_match(&family_names, &properties) {
|
let font_handle = match SystemSource::new().select_best_match(&family_names, &properties) {
|
||||||
Ok(handle) => handle,
|
Ok(handle) => handle,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
|
@ -6,6 +6,7 @@ license = "MPL-2.0"
|
||||||
publish = false
|
publish = false
|
||||||
|
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
# https://github.com/rust-lang/cargo/issues/3544
|
# https://github.com/rust-lang/cargo/issues/3544
|
||||||
links = "servo_style_crate"
|
links = "servo_style_crate"
|
||||||
|
@ -39,7 +40,6 @@ derive_more = "0.99"
|
||||||
encoding_rs = { version = "0.8", optional = true }
|
encoding_rs = { version = "0.8", optional = true }
|
||||||
euclid = "0.20"
|
euclid = "0.20"
|
||||||
fallible = { path = "../fallible" }
|
fallible = { path = "../fallible" }
|
||||||
font-kit = "0.7"
|
|
||||||
fxhash = "0.2"
|
fxhash = "0.2"
|
||||||
hashglobe = { path = "../hashglobe" }
|
hashglobe = { path = "../hashglobe" }
|
||||||
html5ever = { version = "0.25", optional = true }
|
html5ever = { version = "0.25", optional = true }
|
||||||
|
|
|
@ -889,7 +889,8 @@ impl ElementAnimationSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn apply_active_animations(
|
/// Apply all active animations.
|
||||||
|
pub fn apply_active_animations(
|
||||||
&self,
|
&self,
|
||||||
context: &SharedStyleContext,
|
context: &SharedStyleContext,
|
||||||
style: &mut Arc<ComputedValues>,
|
style: &mut Arc<ComputedValues>,
|
||||||
|
@ -1237,7 +1238,7 @@ impl DocumentAnimationSet {
|
||||||
|
|
||||||
/// Get all the animation declarations for the given key, returning an empty
|
/// Get all the animation declarations for the given key, returning an empty
|
||||||
/// `AnimationDeclarations` if there are no animations.
|
/// `AnimationDeclarations` if there are no animations.
|
||||||
pub(crate) fn get_all_declarations(
|
pub fn get_all_declarations(
|
||||||
&self,
|
&self,
|
||||||
key: &AnimationSetKey,
|
key: &AnimationSetKey,
|
||||||
time: f64,
|
time: f64,
|
||||||
|
@ -1264,7 +1265,7 @@ impl DocumentAnimationSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cancel all animations for set at the given key.
|
/// Cancel all animations for set at the given key.
|
||||||
pub(crate) fn cancel_all_animations_for_key(&self, key: &AnimationSetKey) {
|
pub fn cancel_all_animations_for_key(&self, key: &AnimationSetKey) {
|
||||||
if let Some(set) = self.sets.write().get_mut(key) {
|
if let Some(set) = self.sets.write().get_mut(key) {
|
||||||
set.cancel_all_animations();
|
set.cancel_all_animations();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,15 +4,6 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate bindgen;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate log;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate regex;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate toml;
|
|
||||||
extern crate walkdir;
|
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
|
@ -318,7 +318,7 @@ fn generate_structs() {
|
||||||
|
|
||||||
fixups.push(Fixup {
|
fixups.push(Fixup {
|
||||||
pat: format!("\\broot\\s*::\\s*{}\\b", gecko),
|
pat: format!("\\broot\\s*::\\s*{}\\b", gecko),
|
||||||
rep: format!("::gecko_bindings::structs::{}", gecko_name),
|
rep: format!("crate::gecko_bindings::structs::{}", gecko_name),
|
||||||
});
|
});
|
||||||
builder.blacklist_type(gecko).raw_line(format!(
|
builder.blacklist_type(gecko).raw_line(format!(
|
||||||
"pub type {0}{2} = {1}{2};",
|
"pub type {0}{2} = {1}{2};",
|
||||||
|
|
|
@ -369,7 +369,7 @@ impl Parse for System {
|
||||||
"symbolic" => Ok(System::Symbolic),
|
"symbolic" => Ok(System::Symbolic),
|
||||||
"additive" => Ok(System::Additive),
|
"additive" => Ok(System::Additive),
|
||||||
"fixed" => {
|
"fixed" => {
|
||||||
let first_symbol_value = input.try(|i| Integer::parse(context, i)).ok();
|
let first_symbol_value = input.try_parse(|i| Integer::parse(context, i)).ok();
|
||||||
Ok(System::Fixed { first_symbol_value })
|
Ok(System::Fixed { first_symbol_value })
|
||||||
},
|
},
|
||||||
"extends" => {
|
"extends" => {
|
||||||
|
@ -458,7 +458,7 @@ impl Parse for Negative {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
Ok(Negative(
|
Ok(Negative(
|
||||||
Symbol::parse(context, input)?,
|
Symbol::parse(context, input)?,
|
||||||
input.try(|input| Symbol::parse(context, input)).ok(),
|
input.try_parse(|input| Symbol::parse(context, input)).ok(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,7 @@ impl Parse for CounterRanges {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("auto"))
|
.try_parse(|input| input.expect_ident_matching("auto"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(CounterRanges(Default::default()));
|
return Ok(CounterRanges(Default::default()));
|
||||||
|
@ -519,7 +519,7 @@ fn parse_bound<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<CounterBound, ParseError<'i>> {
|
) -> Result<CounterBound, ParseError<'i>> {
|
||||||
if let Ok(integer) = input.try(|input| Integer::parse(context, input)) {
|
if let Ok(integer) = input.try_parse(|input| Integer::parse(context, input)) {
|
||||||
return Ok(CounterBound::Integer(integer));
|
return Ok(CounterBound::Integer(integer));
|
||||||
}
|
}
|
||||||
input.expect_ident_matching("infinite")?;
|
input.expect_ident_matching("infinite")?;
|
||||||
|
@ -535,7 +535,7 @@ impl Parse for Pad {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let pad_with = input.try(|input| Symbol::parse(context, input));
|
let pad_with = input.try_parse(|input| Symbol::parse(context, input));
|
||||||
let min_length = Integer::parse_non_negative(context, input)?;
|
let min_length = Integer::parse_non_negative(context, input)?;
|
||||||
let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?;
|
let pad_with = pad_with.or_else(|_| Symbol::parse(context, input))?;
|
||||||
Ok(Pad(min_length, pad_with))
|
Ok(Pad(min_length, pad_with))
|
||||||
|
@ -568,7 +568,7 @@ impl Parse for Symbols {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut symbols = Vec::new();
|
let mut symbols = Vec::new();
|
||||||
while let Ok(s) = input.try(|input| Symbol::parse(context, input)) {
|
while let Ok(s) = input.try_parse(|input| Symbol::parse(context, input)) {
|
||||||
symbols.push(s);
|
symbols.push(s);
|
||||||
}
|
}
|
||||||
if symbols.is_empty() {
|
if symbols.is_empty() {
|
||||||
|
@ -618,7 +618,7 @@ impl Parse for AdditiveTuple {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let symbol = input.try(|input| Symbol::parse(context, input));
|
let symbol = input.try_parse(|input| Symbol::parse(context, input));
|
||||||
let weight = Integer::parse_non_negative(context, input)?;
|
let weight = Integer::parse_non_negative(context, input)?;
|
||||||
let symbol = symbol.or_else(|_| Symbol::parse(context, input))?;
|
let symbol = symbol.or_else(|_| Symbol::parse(context, input))?;
|
||||||
Ok(Self { weight, symbol })
|
Ok(Self { weight, symbol })
|
||||||
|
@ -648,7 +648,7 @@ impl Parse for SpeakAs {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut is_spell_out = false;
|
let mut is_spell_out = false;
|
||||||
let result = input.try(|input| {
|
let result = input.try_parse(|input| {
|
||||||
let ident = input.expect_ident().map_err(|_| ())?;
|
let ident = input.expect_ident().map_err(|_| ())?;
|
||||||
match_ignore_ascii_case! { &*ident,
|
match_ignore_ascii_case! { &*ident,
|
||||||
"auto" => Ok(SpeakAs::Auto),
|
"auto" => Ok(SpeakAs::Auto),
|
||||||
|
|
|
@ -489,7 +489,7 @@ fn parse_var_function<'i, 't>(
|
||||||
let name = parse_name(&name).map_err(|()| {
|
let name = parse_name(&name).map_err(|()| {
|
||||||
input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))
|
input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone()))
|
||||||
})?;
|
})?;
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
parse_fallback(input)?;
|
parse_fallback(input)?;
|
||||||
}
|
}
|
||||||
if let Some(refs) = references {
|
if let Some(refs) = references {
|
||||||
|
@ -505,7 +505,7 @@ fn parse_env_function<'i, 't>(
|
||||||
// TODO(emilio): This should be <custom-ident> per spec, but no other
|
// TODO(emilio): This should be <custom-ident> per spec, but no other
|
||||||
// browser does that, see https://github.com/w3c/csswg-drafts/issues/3262.
|
// browser does that, see https://github.com/w3c/csswg-drafts/issues/3262.
|
||||||
input.expect_ident()?;
|
input.expect_ident()?;
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
parse_fallback(input)?;
|
parse_fallback(input)?;
|
||||||
}
|
}
|
||||||
if let Some(references) = references {
|
if let Some(references) = references {
|
||||||
|
|
|
@ -816,7 +816,7 @@ pub trait TElement:
|
||||||
Self: 'a,
|
Self: 'a,
|
||||||
F: FnMut(&'a CascadeData, Self),
|
F: FnMut(&'a CascadeData, Self),
|
||||||
{
|
{
|
||||||
use rule_collector::containing_shadow_ignoring_svg_use;
|
use crate::rule_collector::containing_shadow_ignoring_svg_use;
|
||||||
|
|
||||||
let target = self.rule_hash_target();
|
let target = self.rule_hash_target();
|
||||||
if !target.matches_user_and_author_rules() {
|
if !target.matches_user_and_author_rules() {
|
||||||
|
@ -884,18 +884,6 @@ pub trait TElement:
|
||||||
doc_rules_apply
|
doc_rules_apply
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Does a rough (and cheap) check for whether or not transitions might need to be updated that
|
|
||||||
/// will quickly return false for the common case of no transitions specified or running. If
|
|
||||||
/// this returns false, we definitely don't need to update transitions but if it returns true
|
|
||||||
/// we can perform the more thoroughgoing check, needs_transitions_update, to further
|
|
||||||
/// reduce the possibility of false positives.
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
fn might_need_transitions_update(
|
|
||||||
&self,
|
|
||||||
old_values: Option<&ComputedValues>,
|
|
||||||
new_values: &ComputedValues,
|
|
||||||
) -> bool;
|
|
||||||
|
|
||||||
/// Returns true if one of the transitions needs to be updated on this element. We check all
|
/// Returns true if one of the transitions needs to be updated on this element. We check all
|
||||||
/// the transition properties to make sure that updating transitions is necessary.
|
/// the transition properties to make sure that updating transitions is necessary.
|
||||||
/// This method should only be called if might_needs_transitions_update returns true when
|
/// This method should only be called if might_needs_transitions_update returns true when
|
||||||
|
|
|
@ -4,8 +4,6 @@
|
||||||
|
|
||||||
//! Parsing stylesheets from bytes (not `&str`).
|
//! Parsing stylesheets from bytes (not `&str`).
|
||||||
|
|
||||||
extern crate encoding_rs;
|
|
||||||
|
|
||||||
use crate::context::QuirksMode;
|
use crate::context::QuirksMode;
|
||||||
use crate::error_reporting::ParseErrorReporter;
|
use crate::error_reporting::ParseErrorReporter;
|
||||||
use crate::media_queries::MediaList;
|
use crate::media_queries::MediaList;
|
||||||
|
|
|
@ -122,7 +122,7 @@ macro_rules! impl_range {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let first = $component::parse(context, input)?;
|
let first = $component::parse(context, input)?;
|
||||||
let second = input
|
let second = input
|
||||||
.try(|input| $component::parse(context, input))
|
.try_parse(|input| $component::parse(context, input))
|
||||||
.unwrap_or_else(|_| first.clone());
|
.unwrap_or_else(|_| first.clone());
|
||||||
Ok($range(first, second))
|
Ok($range(first, second))
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ impl Parse for FontStyle {
|
||||||
GenericFontStyle::Italic => FontStyle::Italic,
|
GenericFontStyle::Italic => FontStyle::Italic,
|
||||||
GenericFontStyle::Oblique(angle) => {
|
GenericFontStyle::Oblique(angle) => {
|
||||||
let second_angle = input
|
let second_angle = input
|
||||||
.try(|input| SpecifiedFontStyle::parse_angle(context, input))
|
.try_parse(|input| SpecifiedFontStyle::parse_angle(context, input))
|
||||||
.unwrap_or_else(|_| angle.clone());
|
.unwrap_or_else(|_| angle.clone());
|
||||||
|
|
||||||
FontStyle::Oblique(angle, second_angle)
|
FontStyle::Oblique(angle, second_angle)
|
||||||
|
@ -383,7 +383,7 @@ impl Parse for Source {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Source, ParseError<'i>> {
|
) -> Result<Source, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_function_matching("local"))
|
.try_parse(|input| input.expect_function_matching("local"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return input
|
return input
|
||||||
|
@ -395,7 +395,7 @@ impl Parse for Source {
|
||||||
|
|
||||||
// Parsing optional format()
|
// Parsing optional format()
|
||||||
let format_hints = if input
|
let format_hints = if input
|
||||||
.try(|input| input.expect_function_matching("format"))
|
.try_parse(|input| input.expect_function_matching("format"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
|
|
|
@ -278,6 +278,10 @@ enum PrefersReducedMotion {
|
||||||
Reduce,
|
Reduce,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn color_scheme_no_preference_enabled(_: &crate::parser::ParserContext) -> bool {
|
||||||
|
static_prefs::pref!("layout.css.prefers-color-scheme-no-preference.enabled")
|
||||||
|
}
|
||||||
|
|
||||||
/// Values for the prefers-color-scheme media feature.
|
/// Values for the prefers-color-scheme media feature.
|
||||||
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)]
|
#[derive(Clone, Copy, Debug, FromPrimitive, Parse, PartialEq, ToCss)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -285,6 +289,7 @@ enum PrefersReducedMotion {
|
||||||
pub enum PrefersColorScheme {
|
pub enum PrefersColorScheme {
|
||||||
Light,
|
Light,
|
||||||
Dark,
|
Dark,
|
||||||
|
#[parse(condition = "color_scheme_no_preference_enabled")]
|
||||||
NoPreference,
|
NoPreference,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -567,6 +567,12 @@ impl<'le> GeckoElement<'le> {
|
||||||
unsafe { self.0.mServoData.get().as_ref() }
|
unsafe { self.0.mServoData.get().as_ref() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether any animation applies to this element.
|
||||||
|
#[inline]
|
||||||
|
pub fn has_any_animation(&self) -> bool {
|
||||||
|
self.may_have_animations() && unsafe { Gecko_ElementHasAnimations(self.0) }
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn attrs(&self) -> &[structs::AttrArray_InternalAttr] {
|
fn attrs(&self) -> &[structs::AttrArray_InternalAttr] {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -1235,11 +1241,17 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn animation_rule(&self) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
fn animation_rule(
|
||||||
|
&self,
|
||||||
|
_: &SharedStyleContext,
|
||||||
|
) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
get_animation_rule(self, CascadeLevel::Animations)
|
get_animation_rule(self, CascadeLevel::Animations)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transition_rule(&self) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
fn transition_rule(
|
||||||
|
&self,
|
||||||
|
_: &SharedStyleContext,
|
||||||
|
) -> Option<Arc<Locked<PropertyDeclarationBlock>>> {
|
||||||
get_animation_rule(self, CascadeLevel::Transitions)
|
get_animation_rule(self, CascadeLevel::Transitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1516,8 +1528,9 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_animations(&self) -> bool {
|
#[inline]
|
||||||
self.may_have_animations() && unsafe { Gecko_ElementHasAnimations(self.0) }
|
fn has_animations(&self, _: &SharedStyleContext) -> bool {
|
||||||
|
self.has_any_animation()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn has_css_animations(&self, _: &SharedStyleContext, _: Option<PseudoElement>) -> bool {
|
fn has_css_animations(&self, _: &SharedStyleContext, _: Option<PseudoElement>) -> bool {
|
||||||
|
@ -1529,7 +1542,8 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Detect if there are any changes that require us to update transitions.
|
// Detect if there are any changes that require us to update transitions.
|
||||||
// This is used as a more thoroughgoing check than the, cheaper
|
//
|
||||||
|
// This is used as a more thoroughgoing check than the cheaper
|
||||||
// might_need_transitions_update check.
|
// might_need_transitions_update check.
|
||||||
//
|
//
|
||||||
// The following logic shadows the logic used on the Gecko side
|
// The following logic shadows the logic used on the Gecko side
|
||||||
|
@ -1544,12 +1558,6 @@ impl<'le> TElement for GeckoElement<'le> {
|
||||||
) -> bool {
|
) -> bool {
|
||||||
use crate::properties::LonghandIdSet;
|
use crate::properties::LonghandIdSet;
|
||||||
|
|
||||||
debug_assert!(
|
|
||||||
self.might_need_transitions_update(Some(before_change_style), after_change_style),
|
|
||||||
"We should only call needs_transitions_update if \
|
|
||||||
might_need_transitions_update returns true"
|
|
||||||
);
|
|
||||||
|
|
||||||
let after_change_box_style = after_change_style.get_box();
|
let after_change_box_style = after_change_style.get_box();
|
||||||
let existing_transitions = self.css_transitions_info();
|
let existing_transitions = self.css_transitions_info();
|
||||||
let mut transitions_to_keep = LonghandIdSet::new();
|
let mut transitions_to_keep = LonghandIdSet::new();
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
//! Helpers for different FFI pointer kinds that Gecko's FFI layer uses.
|
//! Helpers for different FFI pointer kinds that Gecko's FFI layer uses.
|
||||||
|
|
||||||
use gecko_bindings::structs::root::mozilla::detail::CopyablePtr;
|
use crate::gecko_bindings::structs::root::mozilla::detail::CopyablePtr;
|
||||||
use servo_arc::{Arc, RawOffsetArc};
|
use servo_arc::{Arc, RawOffsetArc};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::{forget, transmute};
|
use std::mem::{forget, transmute};
|
||||||
|
|
|
@ -25,34 +25,20 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
extern crate app_units;
|
|
||||||
extern crate arrayvec;
|
|
||||||
extern crate atomic_refcell;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate bitflags;
|
extern crate bitflags;
|
||||||
#[allow(unused_extern_crates)]
|
|
||||||
extern crate byteorder;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate cssparser;
|
extern crate cssparser;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate debug_unreachable;
|
extern crate debug_unreachable;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate derive_more;
|
extern crate derive_more;
|
||||||
extern crate euclid;
|
|
||||||
extern crate fallible;
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
extern crate font_kit;
|
|
||||||
extern crate fxhash;
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod gecko_string_cache;
|
pub mod gecko_string_cache;
|
||||||
extern crate hashglobe;
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate html5ever;
|
extern crate html5ever;
|
||||||
extern crate indexmap;
|
|
||||||
extern crate itertools;
|
|
||||||
extern crate itoa;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -62,48 +48,21 @@ extern crate malloc_size_of;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate malloc_size_of_derive;
|
extern crate malloc_size_of_derive;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
pub extern crate nsstring;
|
pub use nsstring;
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate num_derive;
|
extern crate num_derive;
|
||||||
extern crate num_integer;
|
|
||||||
extern crate num_traits;
|
|
||||||
extern crate owning_ref;
|
|
||||||
extern crate parking_lot;
|
|
||||||
extern crate precomputed_hash;
|
|
||||||
extern crate rayon;
|
|
||||||
extern crate selectors;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
pub extern crate servo_arc;
|
pub use servo_arc;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate servo_atoms;
|
extern crate servo_atoms;
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
extern crate servo_config;
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
extern crate servo_url;
|
|
||||||
extern crate smallbitvec;
|
|
||||||
extern crate smallvec;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate static_prefs;
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
extern crate string_cache;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate style_derive;
|
extern crate style_derive;
|
||||||
extern crate style_traits;
|
|
||||||
#[cfg(feature = "gecko")]
|
|
||||||
extern crate thin_slice;
|
|
||||||
extern crate time;
|
|
||||||
extern crate to_shmem;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate to_shmem_derive;
|
extern crate to_shmem_derive;
|
||||||
extern crate uluru;
|
|
||||||
extern crate unicode_bidi;
|
|
||||||
#[allow(unused_extern_crates)]
|
|
||||||
extern crate unicode_segmentation;
|
|
||||||
extern crate void;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
|
|
@ -371,7 +371,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
// since we have no way to know whether the decendants
|
// since we have no way to know whether the decendants
|
||||||
// need to be traversed at the beginning of the animation-only
|
// need to be traversed at the beginning of the animation-only
|
||||||
// restyle).
|
// restyle).
|
||||||
let task = ::context::SequentialTask::process_post_animation(
|
let task = crate::context::SequentialTask::process_post_animation(
|
||||||
*self,
|
*self,
|
||||||
PostAnimationTasks::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL,
|
PostAnimationTasks::DISPLAY_CHANGED_FROM_NONE_FOR_SMIL,
|
||||||
);
|
);
|
||||||
|
@ -391,6 +391,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
use crate::context::UpdateAnimationsTasks;
|
use crate::context::UpdateAnimationsTasks;
|
||||||
|
|
||||||
let new_values = new_styles.primary_style_mut();
|
let new_values = new_styles.primary_style_mut();
|
||||||
|
let old_values = &old_styles.primary;
|
||||||
if context.shared.traversal_flags.for_animation_only() {
|
if context.shared.traversal_flags.for_animation_only() {
|
||||||
self.handle_display_change_for_smil_if_needed(
|
self.handle_display_change_for_smil_if_needed(
|
||||||
context,
|
context,
|
||||||
|
@ -420,11 +421,12 @@ trait PrivateMatchMethods: TElement {
|
||||||
new_values,
|
new_values,
|
||||||
/* pseudo_element = */ None,
|
/* pseudo_element = */ None,
|
||||||
) {
|
) {
|
||||||
let after_change_style = if self.has_css_transitions(context.shared) {
|
let after_change_style =
|
||||||
self.after_change_style(context, new_values)
|
if self.has_css_transitions(context.shared, /* pseudo_element = */ None) {
|
||||||
} else {
|
self.after_change_style(context, new_values)
|
||||||
None
|
} else {
|
||||||
};
|
None
|
||||||
|
};
|
||||||
|
|
||||||
// In order to avoid creating a SequentialTask for transitions which
|
// In order to avoid creating a SequentialTask for transitions which
|
||||||
// may not be updated, we check it per property to make sure Gecko
|
// may not be updated, we check it per property to make sure Gecko
|
||||||
|
@ -453,7 +455,7 @@ trait PrivateMatchMethods: TElement {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.has_animations() {
|
if self.has_animations(&context.shared) {
|
||||||
tasks.insert(UpdateAnimationsTasks::EFFECT_PROPERTIES);
|
tasks.insert(UpdateAnimationsTasks::EFFECT_PROPERTIES);
|
||||||
if important_rules_changed {
|
if important_rules_changed {
|
||||||
tasks.insert(UpdateAnimationsTasks::CASCADE_RESULTS);
|
tasks.insert(UpdateAnimationsTasks::CASCADE_RESULTS);
|
||||||
|
@ -464,8 +466,11 @@ trait PrivateMatchMethods: TElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !tasks.is_empty() {
|
if !tasks.is_empty() {
|
||||||
let task =
|
let task = crate::context::SequentialTask::update_animations(
|
||||||
::context::SequentialTask::update_animations(*self, before_change_style, tasks);
|
*self,
|
||||||
|
before_change_style,
|
||||||
|
tasks,
|
||||||
|
);
|
||||||
context.thread_local.tasks.push(task);
|
context.thread_local.tasks.push(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,7 +114,7 @@ impl MediaCondition {
|
||||||
|
|
||||||
// ParenthesisBlock.
|
// ParenthesisBlock.
|
||||||
let first_condition = Self::parse_paren_block(context, input)?;
|
let first_condition = Self::parse_paren_block(context, input)?;
|
||||||
let operator = match input.try(Operator::parse) {
|
let operator = match input.try_parse(Operator::parse) {
|
||||||
Ok(op) => op,
|
Ok(op) => op,
|
||||||
Err(..) => return Ok(first_condition),
|
Err(..) => return Ok(first_condition),
|
||||||
};
|
};
|
||||||
|
@ -133,7 +133,7 @@ impl MediaCondition {
|
||||||
};
|
};
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if input.try(|i| i.expect_ident_matching(delim)).is_err() {
|
if input.try_parse(|i| i.expect_ident_matching(delim)).is_err() {
|
||||||
return Ok(MediaCondition::Operation(
|
return Ok(MediaCondition::Operation(
|
||||||
conditions.into_boxed_slice(),
|
conditions.into_boxed_slice(),
|
||||||
operator,
|
operator,
|
||||||
|
@ -159,7 +159,7 @@ impl MediaCondition {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
// Base case.
|
// Base case.
|
||||||
if let Ok(inner) = input.try(|i| Self::parse(context, i)) {
|
if let Ok(inner) = input.try_parse(|i| Self::parse(context, i)) {
|
||||||
return Ok(MediaCondition::InParens(Box::new(inner)));
|
return Ok(MediaCondition::InParens(Box::new(inner)));
|
||||||
}
|
}
|
||||||
let expr = MediaFeatureExpression::parse_in_parenthesis_block(context, input)?;
|
let expr = MediaFeatureExpression::parse_in_parenthesis_block(context, input)?;
|
||||||
|
|
|
@ -200,14 +200,14 @@ fn consume_operation_or_colon(input: &mut Parser) -> Result<Option<Operator>, ()
|
||||||
Ok(Some(match first_delim {
|
Ok(Some(match first_delim {
|
||||||
'=' => Operator::Equal,
|
'=' => Operator::Equal,
|
||||||
'>' => {
|
'>' => {
|
||||||
if input.try(|i| i.expect_delim('=')).is_ok() {
|
if input.try_parse(|i| i.expect_delim('=')).is_ok() {
|
||||||
Operator::GreaterThanEqual
|
Operator::GreaterThanEqual
|
||||||
} else {
|
} else {
|
||||||
Operator::GreaterThan
|
Operator::GreaterThan
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'<' => {
|
'<' => {
|
||||||
if input.try(|i| i.expect_delim('=')).is_ok() {
|
if input.try_parse(|i| i.expect_delim('=')).is_ok() {
|
||||||
Operator::LessThanEqual
|
Operator::LessThanEqual
|
||||||
} else {
|
} else {
|
||||||
Operator::LessThan
|
Operator::LessThan
|
||||||
|
@ -314,7 +314,7 @@ impl MediaFeatureExpression {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let operator = input.try(consume_operation_or_colon);
|
let operator = input.try_parse(consume_operation_or_colon);
|
||||||
let operator = match operator {
|
let operator = match operator {
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
// If there's no colon, this is a media query of the
|
// If there's no colon, this is a media query of the
|
||||||
|
|
|
@ -125,8 +125,8 @@ impl MediaQuery {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let (qualifier, explicit_media_type) = input
|
let (qualifier, explicit_media_type) = input
|
||||||
.try(|input| -> Result<_, ()> {
|
.try_parse(|input| -> Result<_, ()> {
|
||||||
let qualifier = input.try(Qualifier::parse).ok();
|
let qualifier = input.try_parse(Qualifier::parse).ok();
|
||||||
let ident = input.expect_ident().map_err(|_| ())?;
|
let ident = input.expect_ident().map_err(|_| ())?;
|
||||||
let media_type = MediaQueryType::parse(&ident)?;
|
let media_type = MediaQueryType::parse(&ident)?;
|
||||||
Ok((qualifier, Some(media_type)))
|
Ok((qualifier, Some(media_type)))
|
||||||
|
@ -135,7 +135,7 @@ impl MediaQuery {
|
||||||
|
|
||||||
let condition = if explicit_media_type.is_none() {
|
let condition = if explicit_media_type.is_none() {
|
||||||
Some(MediaCondition::parse(context, input)?)
|
Some(MediaCondition::parse(context, input)?)
|
||||||
} else if input.try(|i| i.expect_ident_matching("and")).is_ok() {
|
} else if input.try_parse(|i| i.expect_ident_matching("and")).is_ok() {
|
||||||
Some(MediaCondition::parse_disallow_or(context, input)?)
|
Some(MediaCondition::parse_disallow_or(context, input)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -854,12 +854,13 @@ impl<'a, 'b: 'a> Cascade<'a, 'b> {
|
||||||
|
|
||||||
let new_size = {
|
let new_size = {
|
||||||
let font = self.context.builder.get_font();
|
let font = self.context.builder.get_font();
|
||||||
let new_size = match font.clone_font_size().keyword_info {
|
let info = font.clone_font_size().keyword_info;
|
||||||
Some(info) => {
|
let new_size = match info.kw {
|
||||||
|
specified::FontSizeKeyword::None => return,
|
||||||
|
_ => {
|
||||||
self.context.for_non_inherited_property = None;
|
self.context.for_non_inherited_property = None;
|
||||||
specified::FontSize::Keyword(info).to_computed_value(self.context)
|
specified::FontSize::Keyword(info).to_computed_value(self.context)
|
||||||
}
|
}
|
||||||
None => return,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if font.gecko().mScriptUnconstrainedSize == Au::from(new_size.size()).0 {
|
if font.gecko().mScriptUnconstrainedSize == Au::from(new_size.size()).0 {
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct AnimationDeclarations {
|
||||||
|
|
||||||
impl AnimationDeclarations {
|
impl AnimationDeclarations {
|
||||||
/// Whether or not this `AnimationDeclarations` is empty.
|
/// Whether or not this `AnimationDeclarations` is empty.
|
||||||
pub(crate) fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.animations.is_none() && self.transitions.is_none()
|
self.animations.is_none() && self.transitions.is_none()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,6 +348,21 @@ impl PropertyDeclarationBlock {
|
||||||
.find(|(declaration, _)| declaration.id() == property)
|
.find(|(declaration, _)| declaration.id() == property)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get a declaration for a given property with the specified importance.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_at_importance(
|
||||||
|
&self,
|
||||||
|
property: PropertyDeclarationId,
|
||||||
|
importance: Importance,
|
||||||
|
) -> Option<&PropertyDeclaration> {
|
||||||
|
let (declaration, i) = self.get(property)?;
|
||||||
|
if i == importance {
|
||||||
|
Some(declaration)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Tries to serialize a given shorthand from the declarations in this
|
/// Tries to serialize a given shorthand from the declarations in this
|
||||||
/// block.
|
/// block.
|
||||||
pub fn shorthand_to_css(
|
pub fn shorthand_to_css(
|
||||||
|
@ -1347,7 +1362,6 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
let id = match PropertyId::parse(&name, self.context) {
|
let id = match PropertyId::parse(&name, self.context) {
|
||||||
Ok(id) => id,
|
Ok(id) => id,
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
self.last_parsed_property_id = None;
|
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name)));
|
return Err(input.new_custom_error(StyleParseErrorKind::UnknownProperty(name)));
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1357,7 +1371,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for PropertyDeclarationParser<'a, 'b> {
|
||||||
input.parse_until_before(Delimiter::Bang, |input| {
|
input.parse_until_before(Delimiter::Bang, |input| {
|
||||||
PropertyDeclaration::parse_into(self.declarations, id, self.context, input)
|
PropertyDeclaration::parse_into(self.declarations, id, self.context, input)
|
||||||
})?;
|
})?;
|
||||||
let importance = match input.try(parse_important) {
|
let importance = match input.try_parse(parse_important) {
|
||||||
Ok(()) => Importance::Important,
|
Ok(()) => Importance::Important,
|
||||||
Err(_) => Importance::Normal,
|
Err(_) => Importance::Normal,
|
||||||
};
|
};
|
||||||
|
@ -1469,6 +1483,10 @@ pub fn parse_property_declaration_list(
|
||||||
match declaration {
|
match declaration {
|
||||||
Ok(importance) => {
|
Ok(importance) => {
|
||||||
block.extend(iter.parser.declarations.drain(), importance);
|
block.extend(iter.parser.declarations.drain(), importance);
|
||||||
|
// We've successfully parsed a declaration, so forget about
|
||||||
|
// `last_parsed_property_id`. It'd be wrong to associate any
|
||||||
|
// following error with this property.
|
||||||
|
iter.parser.last_parsed_property_id = None;
|
||||||
},
|
},
|
||||||
Err((error, slice)) => {
|
Err((error, slice)) => {
|
||||||
iter.parser.declarations.clear();
|
iter.parser.declarations.clear();
|
||||||
|
|
|
@ -942,62 +942,26 @@ fn static_assert() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_font_size(&mut self, v: FontSize) {
|
pub fn set_font_size(&mut self, v: FontSize) {
|
||||||
use crate::values::specified::font::KeywordSize;
|
|
||||||
|
|
||||||
let size = Au::from(v.size());
|
let size = Au::from(v.size());
|
||||||
self.gecko.mScriptUnconstrainedSize = size.0;
|
self.gecko.mScriptUnconstrainedSize = size.0;
|
||||||
|
|
||||||
// These two may be changed from Cascade::fixup_font_stuff.
|
// These two may be changed from Cascade::fixup_font_stuff.
|
||||||
self.gecko.mSize = size.0;
|
self.gecko.mSize = size.0;
|
||||||
self.gecko.mFont.size = size.0;
|
self.gecko.mFont.size = size.0;
|
||||||
|
self.gecko.mFontSizeKeyword = v.keyword_info.kw;
|
||||||
if let Some(info) = v.keyword_info {
|
self.gecko.mFontSizeFactor = v.keyword_info.factor;
|
||||||
self.gecko.mFontSizeKeyword = match info.kw {
|
self.gecko.mFontSizeOffset = v.keyword_info.offset.to_i32_au();
|
||||||
KeywordSize::XXSmall => structs::StyleFontSize::Xxsmall,
|
|
||||||
KeywordSize::XSmall => structs::StyleFontSize::Xsmall,
|
|
||||||
KeywordSize::Small => structs::StyleFontSize::Small,
|
|
||||||
KeywordSize::Medium => structs::StyleFontSize::Medium,
|
|
||||||
KeywordSize::Large => structs::StyleFontSize::Large,
|
|
||||||
KeywordSize::XLarge => structs::StyleFontSize::Xxlarge,
|
|
||||||
KeywordSize::XXLarge => structs::StyleFontSize::Xxlarge,
|
|
||||||
KeywordSize::XXXLarge => structs::StyleFontSize::Xxxlarge,
|
|
||||||
};
|
|
||||||
self.gecko.mFontSizeFactor = info.factor;
|
|
||||||
self.gecko.mFontSizeOffset = info.offset.to_i32_au();
|
|
||||||
} else {
|
|
||||||
self.gecko.mFontSizeKeyword = structs::StyleFontSize::NoKeyword;
|
|
||||||
self.gecko.mFontSizeFactor = 1.;
|
|
||||||
self.gecko.mFontSizeOffset = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clone_font_size(&self) -> FontSize {
|
pub fn clone_font_size(&self) -> FontSize {
|
||||||
use crate::values::specified::font::{KeywordInfo, KeywordSize};
|
use crate::values::specified::font::KeywordInfo;
|
||||||
let size = Au(self.gecko.mSize).into();
|
|
||||||
let kw = match self.gecko.mFontSizeKeyword {
|
|
||||||
structs::StyleFontSize::Xxsmall => KeywordSize::XXSmall,
|
|
||||||
structs::StyleFontSize::Xsmall => KeywordSize::XSmall,
|
|
||||||
structs::StyleFontSize::Small => KeywordSize::Small,
|
|
||||||
structs::StyleFontSize::Medium => KeywordSize::Medium,
|
|
||||||
structs::StyleFontSize::Large => KeywordSize::Large,
|
|
||||||
structs::StyleFontSize::Xlarge => KeywordSize::XLarge,
|
|
||||||
structs::StyleFontSize::Xxlarge => KeywordSize::XXLarge,
|
|
||||||
structs::StyleFontSize::Xxxlarge => KeywordSize::XXXLarge,
|
|
||||||
structs::StyleFontSize::NoKeyword => {
|
|
||||||
return FontSize {
|
|
||||||
size,
|
|
||||||
keyword_info: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => unreachable!("mFontSizeKeyword should be an absolute keyword or NO_KEYWORD")
|
|
||||||
};
|
|
||||||
FontSize {
|
FontSize {
|
||||||
size,
|
size: Au(self.gecko.mSize).into(),
|
||||||
keyword_info: Some(KeywordInfo {
|
keyword_info: KeywordInfo {
|
||||||
kw,
|
kw: self.gecko.mFontSizeKeyword,
|
||||||
factor: self.gecko.mFontSizeFactor,
|
factor: self.gecko.mFontSizeFactor,
|
||||||
offset: Au(self.gecko.mFontSizeOffset).into()
|
offset: Au(self.gecko.mFontSizeOffset).into()
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -354,7 +354,7 @@
|
||||||
use style_traits::Separator;
|
use style_traits::Separator;
|
||||||
|
|
||||||
% if allow_empty:
|
% if allow_empty:
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(SpecifiedValue(Default::default()))
|
return Ok(SpecifiedValue(Default::default()))
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
@ -994,7 +994,7 @@
|
||||||
|
|
||||||
let first = parse_one(context, input)?;
|
let first = parse_one(context, input)?;
|
||||||
let second =
|
let second =
|
||||||
input.try(|input| parse_one(context, input)).unwrap_or_else(|_| first.clone());
|
input.try_parse(|input| parse_one(context, input)).unwrap_or_else(|_| first.clone());
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
${to_rust_ident(first_property)}: first,
|
${to_rust_ident(first_property)}: first,
|
||||||
${to_rust_ident(second_property)}: second,
|
${to_rust_ident(second_property)}: second,
|
||||||
|
|
|
@ -35,7 +35,7 @@ use void::{self, Void};
|
||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
impl From<nsCSSPropertyID> for TransitionProperty {
|
impl From<nsCSSPropertyID> for TransitionProperty {
|
||||||
fn from(property: nsCSSPropertyID) -> TransitionProperty {
|
fn from(property: nsCSSPropertyID) -> TransitionProperty {
|
||||||
use properties::ShorthandId;
|
use crate::properties::ShorthandId;
|
||||||
match property {
|
match property {
|
||||||
% for prop in data.longhands:
|
% for prop in data.longhands:
|
||||||
${prop.nscsspropertyid()} => {
|
${prop.nscsspropertyid()} => {
|
||||||
|
|
|
@ -627,6 +627,21 @@ ${helpers.predefined_type(
|
||||||
gecko_ffi_name="mAppearance",
|
gecko_ffi_name="mAppearance",
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
// A UA-sheet only property that is always set to the same value as
|
||||||
|
// -moz-appearance. Used to record telemetry for when author sheets
|
||||||
|
// override the value of -moz-appearance; see
|
||||||
|
// nsIFrame::RecordAppearanceTelemetry.
|
||||||
|
${helpers.predefined_type(
|
||||||
|
"-moz-default-appearance",
|
||||||
|
"Appearance",
|
||||||
|
"computed::Appearance::None",
|
||||||
|
engines="gecko",
|
||||||
|
animation_value_type="none",
|
||||||
|
spec="Internal (not web-exposed)",
|
||||||
|
enabled_in="ua",
|
||||||
|
gecko_ffi_name="mDefaultAppearance",
|
||||||
|
)}
|
||||||
|
|
||||||
${helpers.single_keyword(
|
${helpers.single_keyword(
|
||||||
"-moz-orient",
|
"-moz-orient",
|
||||||
"inline block horizontal vertical",
|
"inline block horizontal vertical",
|
||||||
|
|
|
@ -362,13 +362,14 @@ ${helpers.predefined_type(
|
||||||
use crate::gecko_bindings::structs::{LookAndFeel_FontID, nsFont};
|
use crate::gecko_bindings::structs::{LookAndFeel_FontID, nsFont};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use crate::values::computed::Percentage;
|
use crate::values::computed::Percentage;
|
||||||
|
use crate::values::specified::font::KeywordInfo;
|
||||||
use crate::values::computed::font::{FontFamily, FontSize, FontStretch, FontStyle, FontFamilyList};
|
use crate::values::computed::font::{FontFamily, FontSize, FontStretch, FontStyle, FontFamilyList};
|
||||||
use crate::values::generics::NonNegative;
|
use crate::values::generics::NonNegative;
|
||||||
|
|
||||||
let id = match *self {
|
let id = match *self {
|
||||||
% for font in system_fonts:
|
% for font in system_fonts:
|
||||||
SystemFont::${to_camel_case(font)} => {
|
SystemFont::${to_camel_case(font)} => {
|
||||||
LookAndFeel_FontID::eFont_${to_camel_case(font.replace("-moz-", ""))}
|
LookAndFeel_FontID::${to_camel_case(font.replace("-moz-", ""))}
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
};
|
};
|
||||||
|
@ -397,7 +398,7 @@ ${helpers.predefined_type(
|
||||||
},
|
},
|
||||||
font_size: FontSize {
|
font_size: FontSize {
|
||||||
size: NonNegative(cx.maybe_zoom_text(Au(system.size).into())),
|
size: NonNegative(cx.maybe_zoom_text(Au(system.size).into())),
|
||||||
keyword_info: None
|
keyword_info: KeywordInfo::none()
|
||||||
},
|
},
|
||||||
font_weight,
|
font_weight,
|
||||||
font_stretch,
|
font_stretch,
|
||||||
|
|
|
@ -77,13 +77,7 @@ ${helpers.predefined_type(
|
||||||
"Default::default()",
|
"Default::default()",
|
||||||
engines="gecko",
|
engines="gecko",
|
||||||
spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-color",
|
spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-color",
|
||||||
gecko_pref="layout.css.scrollbar-color.enabled",
|
|
||||||
# Surprisingly, yes the computed value of scrollbar-color has no effect on
|
|
||||||
# Gecko scrollbar elements, since the value only matters on the scrollable
|
|
||||||
# element itself.
|
|
||||||
has_effect_on_gecko_scrollbars=False,
|
|
||||||
animation_value_type="ScrollbarColor",
|
animation_value_type="ScrollbarColor",
|
||||||
boxed=True,
|
boxed=True,
|
||||||
ignored_when_colors_disabled=True,
|
ignored_when_colors_disabled=True,
|
||||||
enabled_in="chrome",
|
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -27,8 +27,6 @@ ${helpers.single_keyword(
|
||||||
engines="gecko",
|
engines="gecko",
|
||||||
gecko_enum_prefix="StyleScrollbarWidth",
|
gecko_enum_prefix="StyleScrollbarWidth",
|
||||||
animation_value_type="discrete",
|
animation_value_type="discrete",
|
||||||
gecko_pref="layout.css.scrollbar-width.enabled",
|
|
||||||
enabled_in="chrome",
|
|
||||||
spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-width"
|
spec="https://drafts.csswg.org/css-scrollbars-1/#scrollbar-width"
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|
|
@ -1655,7 +1655,7 @@ impl UnparsedValue {
|
||||||
let mut input = ParserInput::new(&css);
|
let mut input = ParserInput::new(&css);
|
||||||
let mut input = Parser::new(&mut input);
|
let mut input = Parser::new(&mut input);
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
if let Ok(keyword) = input.try(CSSWideKeyword::parse) {
|
if let Ok(keyword) = input.try_parse(CSSWideKeyword::parse) {
|
||||||
return PropertyDeclaration::css_wide_keyword(longhand_id, keyword);
|
return PropertyDeclaration::css_wide_keyword(longhand_id, keyword);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2111,7 +2111,8 @@ impl PropertyId {
|
||||||
pub struct WideKeywordDeclaration {
|
pub struct WideKeywordDeclaration {
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
id: LonghandId,
|
id: LonghandId,
|
||||||
keyword: CSSWideKeyword,
|
/// The CSS-wide keyword.
|
||||||
|
pub keyword: CSSWideKeyword,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An unparsed declaration that contains `var()` functions.
|
/// An unparsed declaration that contains `var()` functions.
|
||||||
|
@ -2380,7 +2381,7 @@ impl PropertyDeclaration {
|
||||||
// FIXME: fully implement https://github.com/w3c/csswg-drafts/issues/774
|
// FIXME: fully implement https://github.com/w3c/csswg-drafts/issues/774
|
||||||
// before adding skip_whitespace here.
|
// before adding skip_whitespace here.
|
||||||
// This probably affects some test results.
|
// This probably affects some test results.
|
||||||
let value = match input.try(CSSWideKeyword::parse) {
|
let value = match input.try_parse(CSSWideKeyword::parse) {
|
||||||
Ok(keyword) => CustomDeclarationValue::CSSWideKeyword(keyword),
|
Ok(keyword) => CustomDeclarationValue::CSSWideKeyword(keyword),
|
||||||
Err(()) => CustomDeclarationValue::Value(
|
Err(()) => CustomDeclarationValue::Value(
|
||||||
crate::custom_properties::SpecifiedValue::parse(input)?
|
crate::custom_properties::SpecifiedValue::parse(input)?
|
||||||
|
@ -2395,7 +2396,7 @@ impl PropertyDeclaration {
|
||||||
PropertyId::LonghandAlias(id, _) |
|
PropertyId::LonghandAlias(id, _) |
|
||||||
PropertyId::Longhand(id) => {
|
PropertyId::Longhand(id) => {
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
input.try(CSSWideKeyword::parse).map(|keyword| {
|
input.try_parse(CSSWideKeyword::parse).map(|keyword| {
|
||||||
PropertyDeclaration::css_wide_keyword(id, keyword)
|
PropertyDeclaration::css_wide_keyword(id, keyword)
|
||||||
}).or_else(|()| {
|
}).or_else(|()| {
|
||||||
input.look_for_var_or_env_functions();
|
input.look_for_var_or_env_functions();
|
||||||
|
@ -2425,7 +2426,7 @@ impl PropertyDeclaration {
|
||||||
PropertyId::ShorthandAlias(id, _) |
|
PropertyId::ShorthandAlias(id, _) |
|
||||||
PropertyId::Shorthand(id) => {
|
PropertyId::Shorthand(id) => {
|
||||||
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
input.skip_whitespace(); // Unnecessary for correctness, but may help try() rewind less.
|
||||||
if let Ok(keyword) = input.try(CSSWideKeyword::parse) {
|
if let Ok(keyword) = input.try_parse(CSSWideKeyword::parse) {
|
||||||
if id == ShorthandId::All {
|
if id == ShorthandId::All {
|
||||||
declarations.all_shorthand = AllShorthand::CSSWideKeyword(keyword)
|
declarations.all_shorthand = AllShorthand::CSSWideKeyword(keyword)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -59,19 +59,19 @@
|
||||||
% endfor
|
% endfor
|
||||||
loop {
|
loop {
|
||||||
if background_color.is_none() {
|
if background_color.is_none() {
|
||||||
if let Ok(value) = input.try(|i| Color::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| Color::parse(context, i)) {
|
||||||
background_color = Some(value);
|
background_color = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if position.is_none() {
|
if position.is_none() {
|
||||||
if let Ok(value) = input.try(|input| {
|
if let Ok(value) = input.try_parse(|input| {
|
||||||
Position::parse_three_value_quirky(context, input, AllowQuirks::No)
|
Position::parse_three_value_quirky(context, input, AllowQuirks::No)
|
||||||
}) {
|
}) {
|
||||||
position = Some(value);
|
position = Some(value);
|
||||||
|
|
||||||
// Parse background size, if applicable.
|
// Parse background size, if applicable.
|
||||||
size = input.try(|input| {
|
size = input.try_parse(|input| {
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
background_size::single_value::parse(context, input)
|
background_size::single_value::parse(context, input)
|
||||||
}).ok();
|
}).ok();
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
}
|
}
|
||||||
% for name in "image repeat attachment origin clip".split():
|
% for name in "image repeat attachment origin clip".split():
|
||||||
if ${name}.is_none() {
|
if ${name}.is_none() {
|
||||||
if let Ok(value) = input.try(|input| background_${name}::single_value
|
if let Ok(value) = input.try_parse(|input| background_${name}::single_value
|
||||||
::parse(context, input)) {
|
::parse(context, input)) {
|
||||||
${name} = Some(value);
|
${name} = Some(value);
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -71,20 +71,20 @@ pub fn parse_border<'i, 't>(
|
||||||
let mut any = false;
|
let mut any = false;
|
||||||
loop {
|
loop {
|
||||||
if width.is_none() {
|
if width.is_none() {
|
||||||
if let Ok(value) = input.try(|i| BorderSideWidth::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| BorderSideWidth::parse(context, i)) {
|
||||||
width = Some(value);
|
width = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if style.is_none() {
|
if style.is_none() {
|
||||||
if let Ok(value) = input.try(BorderStyle::parse) {
|
if let Ok(value) = input.try_parse(BorderStyle::parse) {
|
||||||
style = Some(value);
|
style = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if color.is_none() {
|
if color.is_none() {
|
||||||
if let Ok(value) = input.try(|i| Color::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| Color::parse(context, i)) {
|
||||||
color = Some(value);
|
color = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
@ -301,24 +301,24 @@ pub fn parse_border<'i, 't>(
|
||||||
let mut border_image_${name} = border_image_${name}::get_initial_specified_value();
|
let mut border_image_${name} = border_image_${name}::get_initial_specified_value();
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
let result: Result<_, ParseError> = input.try(|input| {
|
let result: Result<_, ParseError> = input.try_parse(|input| {
|
||||||
% for name in "outset repeat slice source width".split():
|
% for name in "outset repeat slice source width".split():
|
||||||
let mut ${name} = None;
|
let mut ${name} = None;
|
||||||
% endfor
|
% endfor
|
||||||
loop {
|
loop {
|
||||||
if slice.is_none() {
|
if slice.is_none() {
|
||||||
if let Ok(value) = input.try(|input| border_image_slice::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| border_image_slice::parse(context, input)) {
|
||||||
slice = Some(value);
|
slice = Some(value);
|
||||||
// Parse border image width and outset, if applicable.
|
// Parse border image width and outset, if applicable.
|
||||||
let maybe_width_outset: Result<_, ParseError> = input.try(|input| {
|
let maybe_width_outset: Result<_, ParseError> = input.try_parse(|input| {
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
|
|
||||||
// Parse border image width, if applicable.
|
// Parse border image width, if applicable.
|
||||||
let w = input.try(|input|
|
let w = input.try_parse(|input|
|
||||||
border_image_width::parse(context, input)).ok();
|
border_image_width::parse(context, input)).ok();
|
||||||
|
|
||||||
// Parse border image outset if applicable.
|
// Parse border image outset if applicable.
|
||||||
let o = input.try(|input| {
|
let o = input.try_parse(|input| {
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
border_image_outset::parse(context, input)
|
border_image_outset::parse(context, input)
|
||||||
}).ok();
|
}).ok();
|
||||||
|
@ -339,7 +339,7 @@ pub fn parse_border<'i, 't>(
|
||||||
}
|
}
|
||||||
% for name in "source repeat".split():
|
% for name in "source repeat".split():
|
||||||
if ${name}.is_none() {
|
if ${name}.is_none() {
|
||||||
if let Ok(value) = input.try(|input| border_image_${name}::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| border_image_${name}::parse(context, input)) {
|
||||||
${name} = Some(value);
|
${name} = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -407,7 +407,7 @@ pub fn parse_border<'i, 't>(
|
||||||
) -> Result<Longhands, ParseError<'i>> {
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let start_value = border_${axis}_start_${prop}::parse(context, input)?;
|
let start_value = border_${axis}_start_${prop}::parse(context, input)?;
|
||||||
let end_value =
|
let end_value =
|
||||||
input.try(|input| border_${axis}_start_${prop}::parse(context, input))
|
input.try_parse(|input| border_${axis}_start_${prop}::parse(context, input))
|
||||||
.unwrap_or_else(|_| start_value.clone());
|
.unwrap_or_else(|_| start_value.clone());
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -31,7 +31,7 @@ ${helpers.two_properties_shorthand(
|
||||||
macro_rules! try_parse_one {
|
macro_rules! try_parse_one {
|
||||||
($context: expr, $input: expr, $var: ident, $prop_module: ident) => {
|
($context: expr, $input: expr, $var: ident, $prop_module: ident) => {
|
||||||
if $var.is_none() {
|
if $var.is_none() {
|
||||||
if let Ok(value) = $input.try(|i| {
|
if let Ok(value) = $input.try_parse(|i| {
|
||||||
$prop_module::single_value::parse($context, i)
|
$prop_module::single_value::parse($context, i)
|
||||||
}) {
|
}) {
|
||||||
$var = Some(value);
|
$var = Some(value);
|
||||||
|
@ -85,12 +85,12 @@ macro_rules! try_parse_one {
|
||||||
// Must check 'transition-property' after 'transition-timing-function' since
|
// Must check 'transition-property' after 'transition-timing-function' since
|
||||||
// 'transition-property' accepts any keyword.
|
// 'transition-property' accepts any keyword.
|
||||||
if property.is_none() {
|
if property.is_none() {
|
||||||
if let Ok(value) = input.try(|i| TransitionProperty::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| TransitionProperty::parse(context, i)) {
|
||||||
property = Some(Some(value));
|
property = Some(Some(value));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
// 'none' is not a valid value for <single-transition-property>,
|
// 'none' is not a valid value for <single-transition-property>,
|
||||||
// so it's not acceptable in the function above.
|
// so it's not acceptable in the function above.
|
||||||
property = Some(None);
|
property = Some(None);
|
||||||
|
@ -389,13 +389,13 @@ ${helpers.two_properties_shorthand(
|
||||||
let mut offset_rotate = None;
|
let mut offset_rotate = None;
|
||||||
loop {
|
loop {
|
||||||
if offset_distance.is_none() {
|
if offset_distance.is_none() {
|
||||||
if let Ok(value) = input.try(|i| LengthPercentage::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| LengthPercentage::parse(context, i)) {
|
||||||
offset_distance = Some(value);
|
offset_distance = Some(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if offset_rotate.is_none() {
|
if offset_rotate.is_none() {
|
||||||
if let Ok(value) = input.try(|i| OffsetRotate::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| OffsetRotate::parse(context, i)) {
|
||||||
offset_rotate = Some(value);
|
offset_rotate = Some(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -403,7 +403,7 @@ ${helpers.two_properties_shorthand(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let offset_anchor = input.try(|i| {
|
let offset_anchor = input.try_parse(|i| {
|
||||||
i.expect_delim('/')?;
|
i.expect_delim('/')?;
|
||||||
PositionOrAuto::parse(context, i)
|
PositionOrAuto::parse(context, i)
|
||||||
}).ok();
|
}).ok();
|
||||||
|
@ -454,7 +454,7 @@ ${helpers.two_properties_shorthand(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Longhands, ParseError<'i>> {
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let zoom = match input.try(|input| NumberOrPercentage::parse(context, input)) {
|
let zoom = match input.try_parse(|input| NumberOrPercentage::parse(context, input)) {
|
||||||
Ok(number_or_percent) => number_or_percent.to_number(),
|
Ok(number_or_percent) => number_or_percent.to_number(),
|
||||||
Err(..) => {
|
Err(..) => {
|
||||||
input.expect_ident_matching("normal")?;
|
input.expect_ident_matching("normal")?;
|
||||||
|
|
|
@ -22,21 +22,21 @@
|
||||||
let mut autos = 0;
|
let mut autos = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if input.try(|input| input.expect_ident_matching("auto")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("auto")).is_ok() {
|
||||||
// Leave the options to None, 'auto' is the initial value.
|
// Leave the options to None, 'auto' is the initial value.
|
||||||
autos += 1;
|
autos += 1;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if column_count.is_none() {
|
if column_count.is_none() {
|
||||||
if let Ok(value) = input.try(|input| column_count::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| column_count::parse(context, input)) {
|
||||||
column_count = Some(value);
|
column_count = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if column_width.is_none() {
|
if column_width.is_none() {
|
||||||
if let Ok(value) = input.try(|input| column_width::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| column_width::parse(context, input)) {
|
||||||
column_width = Some(value);
|
column_width = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@
|
||||||
loop {
|
loop {
|
||||||
% for name in "width style color".split():
|
% for name in "width style color".split():
|
||||||
if column_rule_${name}.is_none() {
|
if column_rule_${name}.is_none() {
|
||||||
if let Ok(value) = input.try(|input|
|
if let Ok(value) = input.try_parse(|input|
|
||||||
column_rule_${name}::parse(context, input)) {
|
column_rule_${name}::parse(context, input)) {
|
||||||
column_rule_${name} = Some(value);
|
column_rule_${name} = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
let mut stretch = None;
|
let mut stretch = None;
|
||||||
let size;
|
let size;
|
||||||
% if engine == "gecko":
|
% if engine == "gecko":
|
||||||
if let Ok(sys) = input.try(SystemFont::parse) {
|
if let Ok(sys) = input.try_parse(SystemFont::parse) {
|
||||||
return Ok(expanded! {
|
return Ok(expanded! {
|
||||||
% for name in SYSTEM_FONT_LONGHANDS:
|
% for name in SYSTEM_FONT_LONGHANDS:
|
||||||
% if name == "font_size":
|
% if name == "font_size":
|
||||||
|
@ -83,30 +83,30 @@
|
||||||
// Special-case 'normal' because it is valid in each of
|
// Special-case 'normal' because it is valid in each of
|
||||||
// font-style, font-weight, font-variant and font-stretch.
|
// font-style, font-weight, font-variant and font-stretch.
|
||||||
// Leaves the values to None, 'normal' is the initial value for each of them.
|
// Leaves the values to None, 'normal' is the initial value for each of them.
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||||
nb_normals += 1;
|
nb_normals += 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if style.is_none() {
|
if style.is_none() {
|
||||||
if let Ok(value) = input.try(|input| font_style::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| font_style::parse(context, input)) {
|
||||||
style = Some(value);
|
style = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if weight.is_none() {
|
if weight.is_none() {
|
||||||
if let Ok(value) = input.try(|input| font_weight::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| font_weight::parse(context, input)) {
|
||||||
weight = Some(value);
|
weight = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if variant_caps.is_none() {
|
if variant_caps.is_none() {
|
||||||
if let Ok(value) = input.try(|input| font_variant_caps::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| font_variant_caps::parse(context, input)) {
|
||||||
variant_caps = Some(value);
|
variant_caps = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if stretch.is_none() {
|
if stretch.is_none() {
|
||||||
if let Ok(value) = input.try(FontStretchKeyword::parse) {
|
if let Ok(value) = input.try_parse(FontStretchKeyword::parse) {
|
||||||
stretch = Some(FontStretch::Keyword(value));
|
stretch = Some(FontStretch::Keyword(value));
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let line_height = if input.try(|input| input.expect_delim('/')).is_ok() {
|
let line_height = if input.try_parse(|input| input.expect_delim('/')).is_ok() {
|
||||||
Some(LineHeight::parse(context, input)?)
|
Some(LineHeight::parse(context, input)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -325,9 +325,9 @@
|
||||||
let mut ${prop} = None;
|
let mut ${prop} = None;
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("normal")).is_ok() {
|
||||||
// Leave the values to None, 'normal' is the initial value for all the sub properties.
|
// Leave the values to None, 'normal' is the initial value for all the sub properties.
|
||||||
} else if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
} else if input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
// The 'none' value sets 'font-variant-ligatures' to 'none' and resets all other sub properties
|
// The 'none' value sets 'font-variant-ligatures' to 'none' and resets all other sub properties
|
||||||
// to their initial value.
|
// to their initial value.
|
||||||
% if engine == "gecko":
|
% if engine == "gecko":
|
||||||
|
@ -336,13 +336,13 @@
|
||||||
} else {
|
} else {
|
||||||
let mut has_custom_value: bool = false;
|
let mut has_custom_value: bool = false;
|
||||||
loop {
|
loop {
|
||||||
if input.try(|input| input.expect_ident_matching("normal")).is_ok() ||
|
if input.try_parse(|input| input.expect_ident_matching("normal")).is_ok() ||
|
||||||
input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError))
|
||||||
}
|
}
|
||||||
% for prop in sub_properties:
|
% for prop in sub_properties:
|
||||||
if ${prop}.is_none() {
|
if ${prop}.is_none() {
|
||||||
if let Ok(value) = input.try(|i| font_variant_${prop}::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| font_variant_${prop}::parse(context, i)) {
|
||||||
has_custom_value = true;
|
has_custom_value = true;
|
||||||
${prop} = Some(value);
|
${prop} = Some(value);
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -22,13 +22,13 @@
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if color.is_none() {
|
if color.is_none() {
|
||||||
if let Ok(value) = input.try(|input| text_emphasis_color::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| text_emphasis_color::parse(context, input)) {
|
||||||
color = Some(value);
|
color = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if style.is_none() {
|
if style.is_none() {
|
||||||
if let Ok(value) = input.try(|input| text_emphasis_style::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| text_emphasis_style::parse(context, input)) {
|
||||||
style = Some(value);
|
style = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -64,14 +64,14 @@
|
||||||
let mut width = None;
|
let mut width = None;
|
||||||
loop {
|
loop {
|
||||||
if color.is_none() {
|
if color.is_none() {
|
||||||
if let Ok(value) = input.try(|input| _webkit_text_stroke_color::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| _webkit_text_stroke_color::parse(context, input)) {
|
||||||
color = Some(value);
|
color = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if width.is_none() {
|
if width.is_none() {
|
||||||
if let Ok(value) = input.try(|input| _webkit_text_stroke_width::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| _webkit_text_stroke_width::parse(context, input)) {
|
||||||
width = Some(value);
|
width = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
let mut nones = 0u8;
|
let mut nones = 0u8;
|
||||||
let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false);
|
let (mut image, mut position, mut list_style_type, mut any) = (None, None, None, false);
|
||||||
loop {
|
loop {
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
nones = nones + 1;
|
nones = nones + 1;
|
||||||
if nones > 2 {
|
if nones > 2 {
|
||||||
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("none".into())))
|
return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("none".into())))
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if image.is_none() {
|
if image.is_none() {
|
||||||
if let Ok(value) = input.try(|input| list_style_image::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| list_style_image::parse(context, input)) {
|
||||||
image = Some(value);
|
image = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
if position.is_none() {
|
if position.is_none() {
|
||||||
if let Ok(value) = input.try(|input| list_style_position::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| list_style_position::parse(context, input)) {
|
||||||
position = Some(value);
|
position = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
// arbitrary identifier for custom counter style, and thus may
|
// arbitrary identifier for custom counter style, and thus may
|
||||||
// affect values of list-style-position.
|
// affect values of list-style-position.
|
||||||
if list_style_type.is_none() {
|
if list_style_type.is_none() {
|
||||||
if let Ok(value) = input.try(|input| list_style_type::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| list_style_type::parse(context, input)) {
|
||||||
list_style_type = Some(value);
|
list_style_type = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -24,21 +24,21 @@
|
||||||
let mut any = false;
|
let mut any = false;
|
||||||
loop {
|
loop {
|
||||||
if color.is_none() {
|
if color.is_none() {
|
||||||
if let Ok(value) = input.try(|i| specified::Color::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| specified::Color::parse(context, i)) {
|
||||||
color = Some(value);
|
color = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if style.is_none() {
|
if style.is_none() {
|
||||||
if let Ok(value) = input.try(|input| outline_style::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| outline_style::parse(context, input)) {
|
||||||
style = Some(value);
|
style = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if width.is_none() {
|
if width.is_none() {
|
||||||
if let Ok(value) = input.try(|input| outline_width::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| outline_width::parse(context, input)) {
|
||||||
width = Some(value);
|
width = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -21,13 +21,13 @@
|
||||||
let mut wrap = None;
|
let mut wrap = None;
|
||||||
loop {
|
loop {
|
||||||
if direction.is_none() {
|
if direction.is_none() {
|
||||||
if let Ok(value) = input.try(|input| flex_direction::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| flex_direction::parse(context, input)) {
|
||||||
direction = Some(value);
|
direction = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if wrap.is_none() {
|
if wrap.is_none() {
|
||||||
if let Ok(value) = input.try(|input| flex_wrap::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| flex_wrap::parse(context, input)) {
|
||||||
wrap = Some(value);
|
wrap = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<(NonNegativeNumber, Option<NonNegativeNumber>),ParseError<'i>> {
|
) -> Result<(NonNegativeNumber, Option<NonNegativeNumber>),ParseError<'i>> {
|
||||||
let grow = NonNegativeNumber::parse(context, input)?;
|
let grow = NonNegativeNumber::parse(context, input)?;
|
||||||
let shrink = input.try(|i| NonNegativeNumber::parse(context, i)).ok();
|
let shrink = input.try_parse(|i| NonNegativeNumber::parse(context, i)).ok();
|
||||||
Ok((grow, shrink))
|
Ok((grow, shrink))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
let mut shrink = None;
|
let mut shrink = None;
|
||||||
let mut basis = None;
|
let mut basis = None;
|
||||||
|
|
||||||
if input.try(|input| input.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(expanded! {
|
return Ok(expanded! {
|
||||||
flex_grow: NonNegativeNumber::new(0.0),
|
flex_grow: NonNegativeNumber::new(0.0),
|
||||||
flex_shrink: NonNegativeNumber::new(0.0),
|
flex_shrink: NonNegativeNumber::new(0.0),
|
||||||
|
@ -82,14 +82,14 @@
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
if grow.is_none() {
|
if grow.is_none() {
|
||||||
if let Ok((flex_grow, flex_shrink)) = input.try(|i| parse_flexibility(context, i)) {
|
if let Ok((flex_grow, flex_shrink)) = input.try_parse(|i| parse_flexibility(context, i)) {
|
||||||
grow = Some(flex_grow);
|
grow = Some(flex_grow);
|
||||||
shrink = flex_shrink;
|
shrink = flex_shrink;
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if basis.is_none() {
|
if basis.is_none() {
|
||||||
if let Ok(value) = input.try(|input| FlexBasis::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| FlexBasis::parse(context, input)) {
|
||||||
basis = Some(value);
|
basis = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@
|
||||||
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
pub fn parse_value<'i, 't>(context: &ParserContext, input: &mut Parser<'i, 't>)
|
||||||
-> Result<Longhands, ParseError<'i>> {
|
-> Result<Longhands, ParseError<'i>> {
|
||||||
let r_gap = row_gap::parse(context, input)?;
|
let r_gap = row_gap::parse(context, input)?;
|
||||||
let c_gap = input.try(|input| column_gap::parse(context, input)).unwrap_or(r_gap.clone());
|
let c_gap = input.try_parse(|input| column_gap::parse(context, input)).unwrap_or(r_gap.clone());
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
row_gap: r_gap,
|
row_gap: r_gap,
|
||||||
|
@ -164,8 +164,8 @@
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Longhands, ParseError<'i>> {
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let start = input.try(|i| GridLine::parse(context, i))?;
|
let start = input.try_parse(|i| GridLine::parse(context, i))?;
|
||||||
let end = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let end = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
GridLine::parse(context, input)?
|
GridLine::parse(context, input)?
|
||||||
} else {
|
} else {
|
||||||
let mut line = GridLine::auto();
|
let mut line = GridLine::auto();
|
||||||
|
@ -226,12 +226,12 @@
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
let row_start = input.try(|i| GridLine::parse(context, i))?;
|
let row_start = input.try_parse(|i| GridLine::parse(context, i))?;
|
||||||
let (column_start, row_end, column_end) = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let (column_start, row_end, column_end) = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
let column_start = GridLine::parse(context, input)?;
|
let column_start = GridLine::parse(context, input)?;
|
||||||
let (row_end, column_end) = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let (row_end, column_end) = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
let row_end = GridLine::parse(context, input)?;
|
let row_end = GridLine::parse(context, input)?;
|
||||||
let column_end = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let column_end = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
GridLine::parse(context, input)?
|
GridLine::parse(context, input)?
|
||||||
} else { // grid-column-end has not been given
|
} else { // grid-column-end has not been given
|
||||||
line_with_ident_from(&column_start)
|
line_with_ident_from(&column_start)
|
||||||
|
@ -324,8 +324,8 @@
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
% for keyword, rust_type in keywords.items():
|
% for keyword, rust_type in keywords.items():
|
||||||
if let Ok(x) = input.try(|i| {
|
if let Ok(x) = input.try_parse(|i| {
|
||||||
if i.try(|i| i.expect_ident_matching("${keyword}")).is_ok() {
|
if i.try_parse(|i| i.expect_ident_matching("${keyword}")).is_ok() {
|
||||||
if !i.is_exhausted() {
|
if !i.is_exhausted() {
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
|
@ -337,20 +337,20 @@
|
||||||
}
|
}
|
||||||
% endfor
|
% endfor
|
||||||
|
|
||||||
let first_line_names = input.try(parse_line_names).unwrap_or_default();
|
let first_line_names = input.try_parse(parse_line_names).unwrap_or_default();
|
||||||
if let Ok(string) = input.try(|i| i.expect_string().map(|s| s.as_ref().to_owned().into())) {
|
if let Ok(string) = input.try_parse(|i| i.expect_string().map(|s| s.as_ref().to_owned().into())) {
|
||||||
let mut strings = vec![];
|
let mut strings = vec![];
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
let mut line_names = vec![];
|
let mut line_names = vec![];
|
||||||
line_names.push(first_line_names);
|
line_names.push(first_line_names);
|
||||||
strings.push(string);
|
strings.push(string);
|
||||||
loop {
|
loop {
|
||||||
let size = input.try(|i| TrackSize::parse(context, i)).unwrap_or_default();
|
let size = input.try_parse(|i| TrackSize::parse(context, i)).unwrap_or_default();
|
||||||
values.push(TrackListValue::TrackSize(size));
|
values.push(TrackListValue::TrackSize(size));
|
||||||
let mut names = input.try(parse_line_names).unwrap_or_default();
|
let mut names = input.try_parse(parse_line_names).unwrap_or_default();
|
||||||
let more_names = input.try(parse_line_names);
|
let more_names = input.try_parse(parse_line_names);
|
||||||
|
|
||||||
match input.try(|i| i.expect_string().map(|s| s.as_ref().to_owned().into())) {
|
match input.try_parse(|i| i.expect_string().map(|s| s.as_ref().to_owned().into())) {
|
||||||
Ok(string) => {
|
Ok(string) => {
|
||||||
strings.push(string);
|
strings.push(string);
|
||||||
if let Ok(v) = more_names {
|
if let Ok(v) = more_names {
|
||||||
|
@ -387,7 +387,7 @@
|
||||||
auto_repeat_index: std::usize::MAX,
|
auto_repeat_index: std::usize::MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
let template_cols = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let template_cols = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
let value = GridTemplateComponent::parse_without_none(context, input)?;
|
let value = GridTemplateComponent::parse_without_none(context, input)?;
|
||||||
if let GenericGridTemplateComponent::TrackList(ref list) = value {
|
if let GenericGridTemplateComponent::TrackList(ref list) = value {
|
||||||
if !list.is_explicit() {
|
if !list.is_explicit() {
|
||||||
|
@ -572,13 +572,13 @@
|
||||||
let mut dense = GridAutoFlow::empty();
|
let mut dense = GridAutoFlow::empty();
|
||||||
|
|
||||||
for _ in 0..2 {
|
for _ in 0..2 {
|
||||||
if input.try(|i| i.expect_ident_matching("auto-flow")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("auto-flow")).is_ok() {
|
||||||
track = if is_row {
|
track = if is_row {
|
||||||
Some(GridAutoFlow::ROW)
|
Some(GridAutoFlow::ROW)
|
||||||
} else {
|
} else {
|
||||||
Some(GridAutoFlow::COLUMN)
|
Some(GridAutoFlow::COLUMN)
|
||||||
};
|
};
|
||||||
} else if input.try(|i| i.expect_ident_matching("dense")).is_ok() {
|
} else if input.try_parse(|i| i.expect_ident_matching("dense")).is_ok() {
|
||||||
dense = GridAutoFlow::DENSE
|
dense = GridAutoFlow::DENSE
|
||||||
} else {
|
} else {
|
||||||
break
|
break
|
||||||
|
@ -592,18 +592,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok((rows, cols, areas)) = input.try(|i| super::grid_template::parse_grid_template(context, i)) {
|
if let Ok((rows, cols, areas)) = input.try_parse(|i| super::grid_template::parse_grid_template(context, i)) {
|
||||||
temp_rows = rows;
|
temp_rows = rows;
|
||||||
temp_cols = cols;
|
temp_cols = cols;
|
||||||
temp_areas = areas;
|
temp_areas = areas;
|
||||||
} else if let Ok(rows) = input.try(|i| GridTemplateComponent::parse(context, i)) {
|
} else if let Ok(rows) = input.try_parse(|i| GridTemplateComponent::parse(context, i)) {
|
||||||
temp_rows = rows;
|
temp_rows = rows;
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
flow = parse_auto_flow(input, false)?;
|
flow = parse_auto_flow(input, false)?;
|
||||||
auto_cols = grid_auto_columns::parse(context, input).unwrap_or_default();
|
auto_cols = grid_auto_columns::parse(context, input).unwrap_or_default();
|
||||||
} else {
|
} else {
|
||||||
flow = parse_auto_flow(input, true)?;
|
flow = parse_auto_flow(input, true)?;
|
||||||
auto_rows = input.try(|i| grid_auto_rows::parse(context, i)).unwrap_or_default();
|
auto_rows = input.try_parse(|i| grid_auto_rows::parse(context, i)).unwrap_or_default();
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
temp_cols = GridTemplateComponent::parse(context, input)?;
|
temp_cols = GridTemplateComponent::parse(context, input)?;
|
||||||
}
|
}
|
||||||
|
@ -710,7 +710,7 @@
|
||||||
let align_content =
|
let align_content =
|
||||||
ContentDistribution::parse(input, AxisDirection::Block)?;
|
ContentDistribution::parse(input, AxisDirection::Block)?;
|
||||||
|
|
||||||
let justify_content = input.try(|input| {
|
let justify_content = input.try_parse(|input| {
|
||||||
ContentDistribution::parse(input, AxisDirection::Inline)
|
ContentDistribution::parse(input, AxisDirection::Inline)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -763,7 +763,7 @@
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Longhands, ParseError<'i>> {
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let align = SelfAlignment::parse(input, AxisDirection::Block)?;
|
let align = SelfAlignment::parse(input, AxisDirection::Block)?;
|
||||||
let justify = input.try(|input| SelfAlignment::parse(input, AxisDirection::Inline));
|
let justify = input.try_parse(|input| SelfAlignment::parse(input, AxisDirection::Inline));
|
||||||
|
|
||||||
let justify = match justify {
|
let justify = match justify {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
|
@ -812,7 +812,7 @@
|
||||||
) -> Result<Longhands, ParseError<'i>> {
|
) -> Result<Longhands, ParseError<'i>> {
|
||||||
let align = AlignItems::parse(context, input)?;
|
let align = AlignItems::parse(context, input)?;
|
||||||
let justify =
|
let justify =
|
||||||
input.try(|input| JustifyItems::parse(context, input))
|
input.try_parse(|input| JustifyItems::parse(context, input))
|
||||||
.unwrap_or_else(|_| JustifyItems::from(align));
|
.unwrap_or_else(|_| JustifyItems::from(align));
|
||||||
|
|
||||||
Ok(expanded! {
|
Ok(expanded! {
|
||||||
|
|
|
@ -55,18 +55,18 @@
|
||||||
% endfor
|
% endfor
|
||||||
loop {
|
loop {
|
||||||
if image.is_none() {
|
if image.is_none() {
|
||||||
if let Ok(value) = input.try(|input| mask_image::single_value
|
if let Ok(value) = input.try_parse(|input| mask_image::single_value
|
||||||
::parse(context, input)) {
|
::parse(context, input)) {
|
||||||
image = Some(value);
|
image = Some(value);
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if position.is_none() {
|
if position.is_none() {
|
||||||
if let Ok(value) = input.try(|input| Position::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| Position::parse(context, input)) {
|
||||||
position = Some(value);
|
position = Some(value);
|
||||||
|
|
||||||
// Parse mask size, if applicable.
|
// Parse mask size, if applicable.
|
||||||
size = input.try(|input| {
|
size = input.try_parse(|input| {
|
||||||
input.expect_delim('/')?;
|
input.expect_delim('/')?;
|
||||||
mask_size::single_value::parse(context, input)
|
mask_size::single_value::parse(context, input)
|
||||||
}).ok();
|
}).ok();
|
||||||
|
@ -76,7 +76,7 @@
|
||||||
}
|
}
|
||||||
% for name in "repeat origin clip composite mode".split():
|
% for name in "repeat origin clip composite mode".split():
|
||||||
if ${name}.is_none() {
|
if ${name}.is_none() {
|
||||||
if let Ok(value) = input.try(|input| mask_${name}::single_value
|
if let Ok(value) = input.try_parse(|input| mask_${name}::single_value
|
||||||
::parse(context, input)) {
|
::parse(context, input)) {
|
||||||
${name} = Some(value);
|
${name} = Some(value);
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
macro_rules! parse_component {
|
macro_rules! parse_component {
|
||||||
($value:ident, $module:ident) => (
|
($value:ident, $module:ident) => (
|
||||||
if $value.is_none() {
|
if $value.is_none() {
|
||||||
if let Ok(value) = input.try(|input| $module::parse(context, input)) {
|
if let Ok(value) = input.try_parse(|input| $module::parse(context, input)) {
|
||||||
$value = Some(value);
|
$value = Some(value);
|
||||||
any = true;
|
any = true;
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -258,6 +258,8 @@ impl<T> Locked<T> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
impl<T: ToShmem> ToShmem for Locked<T> {
|
impl<T: ToShmem> ToShmem for Locked<T> {
|
||||||
fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
|
fn to_shmem(&self, builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
|
||||||
|
use std::mem::ManuallyDrop;
|
||||||
|
|
||||||
let guard = self.shared_lock.read();
|
let guard = self.shared_lock.read();
|
||||||
Ok(ManuallyDrop::new(Locked {
|
Ok(ManuallyDrop::new(Locked {
|
||||||
shared_lock: SharedRwLock::read_only(),
|
shared_lock: SharedRwLock::read_only(),
|
||||||
|
|
|
@ -307,7 +307,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Cascade a set of rules for pseudo element, using the default parent for inheritance.
|
/// Cascade a set of rules for pseudo element, using the default parent for inheritance.
|
||||||
pub(crate) fn cascade_style_and_visited_for_pseudo_with_default_parents(
|
pub fn cascade_style_and_visited_for_pseudo_with_default_parents(
|
||||||
&mut self,
|
&mut self,
|
||||||
inputs: CascadeInputs,
|
inputs: CascadeInputs,
|
||||||
pseudo: &PseudoElement,
|
pseudo: &PseudoElement,
|
||||||
|
|
|
@ -135,7 +135,7 @@ impl DocumentMatchingFunction {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(url) = input.try(|input| CssUrl::parse(context, input)) {
|
if let Ok(url) = input.try_parse(|input| CssUrl::parse(context, input)) {
|
||||||
return Ok(DocumentMatchingFunction::Url(url));
|
return Ok(DocumentMatchingFunction::Url(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> {
|
||||||
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedNamespaceRule))
|
return Err(input.new_custom_error(StyleParseErrorKind::UnexpectedNamespaceRule))
|
||||||
}
|
}
|
||||||
|
|
||||||
let prefix = input.try(|i| i.expect_ident_cloned())
|
let prefix = input.try_parse(|i| i.expect_ident_cloned())
|
||||||
.map(|s| Prefix::from(s.as_ref())).ok();
|
.map(|s| Prefix::from(s.as_ref())).ok();
|
||||||
let maybe_namespace = match input.expect_url_or_string() {
|
let maybe_namespace = match input.expect_url_or_string() {
|
||||||
Ok(url_or_string) => url_or_string,
|
Ok(url_or_string) => url_or_string,
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl SupportsCondition {
|
||||||
///
|
///
|
||||||
/// <https://drafts.csswg.org/css-conditional/#supports_condition>
|
/// <https://drafts.csswg.org/css-conditional/#supports_condition>
|
||||||
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 input.try(|i| i.expect_ident_matching("not")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("not")).is_ok() {
|
||||||
let inner = SupportsCondition::parse_in_parens(input)?;
|
let inner = SupportsCondition::parse_in_parens(input)?;
|
||||||
return Ok(SupportsCondition::Not(Box::new(inner)));
|
return Ok(SupportsCondition::Not(Box::new(inner)));
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ impl SupportsCondition {
|
||||||
loop {
|
loop {
|
||||||
conditions.push(SupportsCondition::parse_in_parens(input)?);
|
conditions.push(SupportsCondition::parse_in_parens(input)?);
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching(keyword))
|
.try_parse(|input| input.expect_ident_matching(keyword))
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
// Did not find the expected keyword.
|
// Did not find the expected keyword.
|
||||||
|
@ -175,20 +175,20 @@ impl SupportsCondition {
|
||||||
fn parse_in_parens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
fn parse_in_parens<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
|
||||||
// Whitespace is normally taken care of in `Parser::next`,
|
// Whitespace is normally taken care of in `Parser::next`,
|
||||||
// but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases.
|
// but we want to not include it in `pos` for the SupportsCondition::FutureSyntax cases.
|
||||||
while input.try(Parser::expect_whitespace).is_ok() {}
|
while input.try_parse(Parser::expect_whitespace).is_ok() {}
|
||||||
let pos = input.position();
|
let pos = input.position();
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
match *input.next()? {
|
match *input.next()? {
|
||||||
Token::ParenthesisBlock => {
|
Token::ParenthesisBlock => {
|
||||||
let nested =
|
let nested = input
|
||||||
input.try(|input| input.parse_nested_block(parse_condition_or_declaration));
|
.try_parse(|input| input.parse_nested_block(parse_condition_or_declaration));
|
||||||
if nested.is_ok() {
|
if nested.is_ok() {
|
||||||
return nested;
|
return nested;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Token::Function(ref ident) => {
|
Token::Function(ref ident) => {
|
||||||
let ident = ident.clone();
|
let ident = ident.clone();
|
||||||
let nested = input.try(|input| {
|
let nested = input.try_parse(|input| {
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
SupportsCondition::parse_functional(&ident, input)
|
SupportsCondition::parse_functional(&ident, input)
|
||||||
})
|
})
|
||||||
|
@ -239,7 +239,7 @@ fn eval_moz_bool_pref(_: &CStr, _: &ParserContext) -> bool {
|
||||||
pub fn parse_condition_or_declaration<'i, 't>(
|
pub fn parse_condition_or_declaration<'i, 't>(
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<SupportsCondition, ParseError<'i>> {
|
) -> Result<SupportsCondition, ParseError<'i>> {
|
||||||
if let Ok(condition) = input.try(SupportsCondition::parse) {
|
if let Ok(condition) = input.try_parse(SupportsCondition::parse) {
|
||||||
Ok(SupportsCondition::Parenthesized(Box::new(condition)))
|
Ok(SupportsCondition::Parenthesized(Box::new(condition)))
|
||||||
} else {
|
} else {
|
||||||
Declaration::parse(input).map(SupportsCondition::Declaration)
|
Declaration::parse(input).map(SupportsCondition::Declaration)
|
||||||
|
@ -414,7 +414,7 @@ impl Declaration {
|
||||||
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
PropertyDeclaration::parse_into(&mut declarations, id, &context, input)
|
||||||
.map_err(|_| input.new_custom_error(()))
|
.map_err(|_| input.new_custom_error(()))
|
||||||
})?;
|
})?;
|
||||||
let _ = input.try(parse_important);
|
let _ = input.try_parse(parse_important);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
.is_ok()
|
.is_ok()
|
||||||
|
|
|
@ -267,7 +267,7 @@ fn parse_shorthand<'i, 't>(
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<(ViewportLength, ViewportLength), ParseError<'i>> {
|
) -> Result<(ViewportLength, ViewportLength), ParseError<'i>> {
|
||||||
let min = ViewportLength::parse(context, input)?;
|
let min = ViewportLength::parse(context, input)?;
|
||||||
match input.try(|i| ViewportLength::parse(context, i)) {
|
match input.try_parse(|i| ViewportLength::parse(context, i)) {
|
||||||
Err(_) => Ok((min.clone(), min)),
|
Err(_) => Ok((min.clone(), min)),
|
||||||
Ok(max) => Ok((min, max)),
|
Ok(max) => Ok((min, max)),
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
||||||
($declaration:ident($parse:expr)) => {
|
($declaration:ident($parse:expr)) => {
|
||||||
declaration!($declaration {
|
declaration!($declaration {
|
||||||
value: $parse(input)?,
|
value: $parse(input)?,
|
||||||
important: input.try(parse_important).is_ok(),
|
important: input.try_parse(parse_important).is_ok(),
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
($declaration:ident { value: $value:expr, important: $important:expr, }) => {
|
($declaration:ident { value: $value:expr, important: $important:expr, }) => {
|
||||||
|
@ -311,7 +311,7 @@ impl<'a, 'b, 'i> DeclarationParser<'i> for ViewportRuleParser<'a, 'b> {
|
||||||
};
|
};
|
||||||
(shorthand -> [$min:ident, $max:ident]) => {{
|
(shorthand -> [$min:ident, $max:ident]) => {{
|
||||||
let shorthand = parse_shorthand(self.context, input)?;
|
let shorthand = parse_shorthand(self.context, input)?;
|
||||||
let important = input.try(parse_important).is_ok();
|
let important = input.try_parse(parse_important).is_ok();
|
||||||
|
|
||||||
Ok(vec![
|
Ok(vec![
|
||||||
declaration!($min {
|
declaration!($min {
|
||||||
|
|
|
@ -22,12 +22,6 @@ use crate::values::specified::length::{FontBaseSize, NoCalcLength};
|
||||||
use crate::values::CSSFloat;
|
use crate::values::CSSFloat;
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use cssparser::{serialize_identifier, CssStringWriter, Parser};
|
use cssparser::{serialize_identifier, CssStringWriter, Parser};
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
use font_kit::family_name::FamilyName as FontKitFamilyName;
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
use font_kit::properties::{
|
|
||||||
Stretch as FontKitFontStretch, Style as FontKitFontStyle, Weight as FontKitFontWeight,
|
|
||||||
};
|
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
|
@ -75,13 +69,6 @@ impl ToAnimatedValue for FontWeight {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
impl From<FontWeight> for FontKitFontWeight {
|
|
||||||
fn from(font_weight: FontWeight) -> Self {
|
|
||||||
FontKitFontWeight(font_weight.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Animate,
|
Animate,
|
||||||
Clone,
|
Clone,
|
||||||
|
@ -101,7 +88,7 @@ pub struct FontSize {
|
||||||
pub size: NonNegativeLength,
|
pub size: NonNegativeLength,
|
||||||
/// If derived from a keyword, the keyword and additional transformations applied to it
|
/// If derived from a keyword, the keyword and additional transformations applied to it
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
pub keyword_info: Option<KeywordInfo>,
|
pub keyword_info: KeywordInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontWeight {
|
impl FontWeight {
|
||||||
|
@ -170,7 +157,7 @@ impl FontSize {
|
||||||
pub fn medium() -> Self {
|
pub fn medium() -> Self {
|
||||||
Self {
|
Self {
|
||||||
size: NonNegative(Length::new(specified::FONT_MEDIUM_PX as CSSFloat)),
|
size: NonNegative(Length::new(specified::FONT_MEDIUM_PX as CSSFloat)),
|
||||||
keyword_info: Some(KeywordInfo::medium()),
|
keyword_info: KeywordInfo::medium(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -187,7 +174,7 @@ impl ToAnimatedValue for FontSize {
|
||||||
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
fn from_animated_value(animated: Self::AnimatedValue) -> Self {
|
||||||
FontSize {
|
FontSize {
|
||||||
size: NonNegative(animated.clamp_to_non_negative()),
|
size: NonNegative(animated.clamp_to_non_negative()),
|
||||||
keyword_info: None,
|
keyword_info: KeywordInfo::none(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,7 +345,7 @@ pub enum GenericFontFamily {
|
||||||
impl SingleFontFamily {
|
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_parse(|i| i.expect_string_cloned()) {
|
||||||
return Ok(SingleFontFamily::FamilyName(FamilyName {
|
return Ok(SingleFontFamily::FamilyName(FamilyName {
|
||||||
name: Atom::from(&*value),
|
name: Atom::from(&*value),
|
||||||
syntax: FontFamilyNameSyntax::Quoted,
|
syntax: FontFamilyNameSyntax::Quoted,
|
||||||
|
@ -393,7 +380,7 @@ impl SingleFontFamily {
|
||||||
value.push(' ');
|
value.push(' ');
|
||||||
value.push_str(&ident);
|
value.push_str(&ident);
|
||||||
}
|
}
|
||||||
while let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
|
while let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||||
serialize_quoted = serialize_quoted || ident.contains(' ');
|
serialize_quoted = serialize_quoted || ident.contains(' ');
|
||||||
value.push(' ');
|
value.push(' ');
|
||||||
value.push_str(&ident);
|
value.push_str(&ident);
|
||||||
|
@ -458,29 +445,19 @@ impl SingleFontFamily {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
impl From<&SingleFontFamily> for FontKitFamilyName {
|
|
||||||
fn from(font_family: &SingleFontFamily) -> Self {
|
|
||||||
match font_family {
|
|
||||||
SingleFontFamily::FamilyName(family_name) => {
|
|
||||||
FontKitFamilyName::Title(family_name.to_css_string())
|
|
||||||
},
|
|
||||||
SingleFontFamily::Generic(GenericFontFamily::Serif) => FontKitFamilyName::Serif,
|
|
||||||
SingleFontFamily::Generic(GenericFontFamily::SansSerif) => FontKitFamilyName::SansSerif,
|
|
||||||
SingleFontFamily::Generic(GenericFontFamily::Monospace) => FontKitFamilyName::Monospace,
|
|
||||||
SingleFontFamily::Generic(GenericFontFamily::Fantasy) => FontKitFamilyName::Fantasy,
|
|
||||||
SingleFontFamily::Generic(GenericFontFamily::Cursive) => FontKitFamilyName::Cursive,
|
|
||||||
SingleFontFamily::Generic(family_name) => {
|
|
||||||
warn!("unsupported font family name: {:?}", family_name);
|
|
||||||
FontKitFamilyName::SansSerif
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
Clone, Debug, Eq, Hash, MallocSizeOf, PartialEq, ToComputedValue, ToResolvedValue, ToShmem,
|
Clone,
|
||||||
|
Debug,
|
||||||
|
Deserialize,
|
||||||
|
Eq,
|
||||||
|
Hash,
|
||||||
|
MallocSizeOf,
|
||||||
|
PartialEq,
|
||||||
|
Serialize,
|
||||||
|
ToComputedValue,
|
||||||
|
ToResolvedValue,
|
||||||
|
ToShmem,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "servo", derive(Serialize, Deserialize))]
|
|
||||||
/// A list of SingleFontFamily
|
/// A list of SingleFontFamily
|
||||||
pub struct FontFamilyList(Box<[SingleFontFamily]>);
|
pub struct FontFamilyList(Box<[SingleFontFamily]>);
|
||||||
|
|
||||||
|
@ -965,17 +942,6 @@ impl ToCss for FontStyle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
impl From<FontStyle> for FontKitFontStyle {
|
|
||||||
fn from(font_style: FontStyle) -> Self {
|
|
||||||
match font_style {
|
|
||||||
FontStyle::Normal => FontKitFontStyle::Normal,
|
|
||||||
FontStyle::Italic => FontKitFontStyle::Italic,
|
|
||||||
FontStyle::Oblique(_) => FontKitFontStyle::Oblique,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A value for the font-stretch property per:
|
/// A value for the font-stretch property per:
|
||||||
///
|
///
|
||||||
/// https://drafts.csswg.org/css-fonts-4/#propdef-font-stretch
|
/// https://drafts.csswg.org/css-fonts-4/#propdef-font-stretch
|
||||||
|
@ -998,13 +964,6 @@ impl FontStretch {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
|
||||||
impl From<FontStretch> for FontKitFontStretch {
|
|
||||||
fn from(stretch: FontStretch) -> Self {
|
|
||||||
FontKitFontStretch(stretch.value())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ToAnimatedValue for FontStretch {
|
impl ToAnimatedValue for FontStretch {
|
||||||
type AnimatedValue = Percentage;
|
type AnimatedValue = Percentage;
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ macro_rules! computed_length_percentage_or_auto {
|
||||||
/// Returns true if the computed value is absolute 0 or 0%.
|
/// Returns true if the computed value is absolute 0 or 0%.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_definitely_zero(&self) -> bool {
|
pub fn is_definitely_zero(&self) -> bool {
|
||||||
use values::generics::length::LengthPercentageOrAuto::*;
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
match *self {
|
match *self {
|
||||||
LengthPercentage(ref l) => l.is_definitely_zero(),
|
LengthPercentage(ref l) => l.is_definitely_zero(),
|
||||||
Auto => false,
|
Auto => false,
|
||||||
|
@ -102,7 +102,7 @@ pub type LengthPercentageOrAuto = generics::GenericLengthPercentageOrAuto<Length
|
||||||
impl LengthPercentageOrAuto {
|
impl LengthPercentageOrAuto {
|
||||||
/// Clamps the value to a non-negative value.
|
/// Clamps the value to a non-negative value.
|
||||||
pub fn clamp_to_non_negative(self) -> Self {
|
pub fn clamp_to_non_negative(self) -> Self {
|
||||||
use values::generics::length::LengthPercentageOrAuto::*;
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
match self {
|
match self {
|
||||||
LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()),
|
LengthPercentage(l) => LengthPercentage(l.clamp_to_non_negative()),
|
||||||
Auto => Auto,
|
Auto => Auto,
|
||||||
|
@ -111,7 +111,7 @@ impl LengthPercentageOrAuto {
|
||||||
|
|
||||||
/// Convert to have a borrow inside the enum
|
/// Convert to have a borrow inside the enum
|
||||||
pub fn as_ref(&self) -> generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
|
pub fn as_ref(&self) -> generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
|
||||||
use values::generics::length::LengthPercentageOrAuto::*;
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
match *self {
|
match *self {
|
||||||
LengthPercentage(ref lp) => LengthPercentage(lp),
|
LengthPercentage(ref lp) => LengthPercentage(lp),
|
||||||
Auto => Auto,
|
Auto => Auto,
|
||||||
|
@ -125,7 +125,7 @@ impl generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
|
||||||
/// Resolves the percentage.
|
/// Resolves the percentage.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn percentage_relative_to(&self, basis: Length) -> LengthOrAuto {
|
pub fn percentage_relative_to(&self, basis: Length) -> LengthOrAuto {
|
||||||
use values::generics::length::LengthPercentageOrAuto::*;
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
match self {
|
match self {
|
||||||
LengthPercentage(length_percentage) => {
|
LengthPercentage(length_percentage) => {
|
||||||
LengthPercentage(length_percentage.percentage_relative_to(basis))
|
LengthPercentage(length_percentage.percentage_relative_to(basis))
|
||||||
|
@ -137,7 +137,7 @@ impl generics::GenericLengthPercentageOrAuto<&LengthPercentage> {
|
||||||
/// Maybe resolves the percentage.
|
/// Maybe resolves the percentage.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn maybe_percentage_relative_to(&self, basis: Option<Length>) -> LengthOrAuto {
|
pub fn maybe_percentage_relative_to(&self, basis: Option<Length>) -> LengthOrAuto {
|
||||||
use values::generics::length::LengthPercentageOrAuto::*;
|
use crate::values::generics::length::LengthPercentageOrAuto::*;
|
||||||
match self {
|
match self {
|
||||||
LengthPercentage(length_percentage) => length_percentage
|
LengthPercentage(length_percentage) => length_percentage
|
||||||
.maybe_percentage_relative_to(basis)
|
.maybe_percentage_relative_to(basis)
|
||||||
|
|
|
@ -107,7 +107,10 @@ impl<T: Parse> Parse for FontSettings<T> {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("normal"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(Self::normal());
|
return Ok(Self::normal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut grid_line = Self::auto();
|
let mut grid_line = Self::auto();
|
||||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||||
return Ok(grid_line);
|
return Ok(grid_line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
for _ in 0..3 {
|
for _ in 0..3 {
|
||||||
// Maximum possible entities for <grid-line>
|
// Maximum possible entities for <grid-line>
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
if input.try(|i| i.expect_ident_matching("span")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("span")).is_ok() {
|
||||||
if grid_line.is_span {
|
if grid_line.is_span {
|
||||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
}
|
}
|
||||||
|
|
||||||
grid_line.is_span = true;
|
grid_line.is_span = true;
|
||||||
} else if let Ok(i) = input.try(|i| specified::Integer::parse(context, i)) {
|
} else if let Ok(i) = input.try_parse(|i| specified::Integer::parse(context, i)) {
|
||||||
// FIXME(emilio): Probably shouldn't reject if it's calc()...
|
// FIXME(emilio): Probably shouldn't reject if it's calc()...
|
||||||
let value = i.value();
|
let value = i.value();
|
||||||
if value == 0 || val_before_span || !grid_line.line_num.is_zero() {
|
if value == 0 || val_before_span || !grid_line.line_num.is_zero() {
|
||||||
|
@ -165,7 +165,7 @@ impl Parse for GridLine<specified::Integer> {
|
||||||
MIN_GRID_LINE,
|
MIN_GRID_LINE,
|
||||||
cmp::min(value, MAX_GRID_LINE),
|
cmp::min(value, MAX_GRID_LINE),
|
||||||
));
|
));
|
||||||
} else if let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
|
} else if let Ok(name) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||||
if val_before_span || grid_line.ident != atom!("") {
|
if val_before_span || grid_line.ident != atom!("") {
|
||||||
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
return Err(location.new_custom_error(StyleParseErrorKind::UnspecifiedError));
|
||||||
}
|
}
|
||||||
|
@ -432,7 +432,7 @@ impl Parse for RepeatCount<specified::Integer> {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(mut i) = input.try(|i| specified::Integer::parse_positive(context, i)) {
|
if let Ok(mut i) = input.try_parse(|i| specified::Integer::parse_positive(context, i)) {
|
||||||
if i.value() > MAX_GRID_LINE {
|
if i.value() > MAX_GRID_LINE {
|
||||||
i = specified::Integer::new(MAX_GRID_LINE);
|
i = specified::Integer::new(MAX_GRID_LINE);
|
||||||
}
|
}
|
||||||
|
@ -671,14 +671,14 @@ impl Parse for LineNameList {
|
||||||
let mut fill_data = None;
|
let mut fill_data = None;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let repeat_parse_result = input.try(|input| {
|
let repeat_parse_result = input.try_parse(|input| {
|
||||||
input.expect_function_matching("repeat")?;
|
input.expect_function_matching("repeat")?;
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let count = RepeatCount::parse(context, input)?;
|
let count = RepeatCount::parse(context, input)?;
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
let mut names_list = vec![];
|
let mut names_list = vec![];
|
||||||
names_list.push(parse_line_names(input)?); // there should be at least one
|
names_list.push(parse_line_names(input)?); // there should be at least one
|
||||||
while let Ok(names) = input.try(parse_line_names) {
|
while let Ok(names) = input.try_parse(parse_line_names) {
|
||||||
names_list.push(names);
|
names_list.push(names);
|
||||||
}
|
}
|
||||||
Ok((names_list, count))
|
Ok((names_list, count))
|
||||||
|
@ -703,7 +703,7 @@ impl Parse for LineNameList {
|
||||||
},
|
},
|
||||||
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
_ => return Err(input.new_custom_error(StyleParseErrorKind::UnspecifiedError)),
|
||||||
}
|
}
|
||||||
} else if let Ok(names) = input.try(parse_line_names) {
|
} else if let Ok(names) = input.try_parse(parse_line_names) {
|
||||||
line_names.push(names);
|
line_names.push(names);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -7,13 +7,13 @@
|
||||||
//! [images]: https://drafts.csswg.org/css-images/#image-values
|
//! [images]: https://drafts.csswg.org/css-images/#image-values
|
||||||
|
|
||||||
use crate::custom_properties;
|
use crate::custom_properties;
|
||||||
|
use crate::values::generics::position::PositionComponent;
|
||||||
use crate::values::serialize_atom_identifier;
|
use crate::values::serialize_atom_identifier;
|
||||||
use crate::Atom;
|
use crate::Atom;
|
||||||
use crate::Zero;
|
use crate::Zero;
|
||||||
use servo_arc::Arc;
|
use servo_arc::Arc;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
use values::generics::position::PositionComponent;
|
|
||||||
|
|
||||||
/// An `<image> | none` value.
|
/// An `<image> | none` value.
|
||||||
///
|
///
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl<LengthPercentage> LengthPercentageOrAuto<LengthPercentage> {
|
||||||
&mut Parser<'i, 't>,
|
&mut Parser<'i, 't>,
|
||||||
) -> Result<LengthPercentage, ParseError<'i>>,
|
) -> Result<LengthPercentage, ParseError<'i>>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||||
return Ok(LengthPercentageOrAuto::Auto);
|
return Ok(LengthPercentageOrAuto::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,13 +101,13 @@ impl Parse for CounterStyle {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(name) = input.try(|i| parse_counter_style_name(i)) {
|
if let Ok(name) = input.try_parse(|i| parse_counter_style_name(i)) {
|
||||||
return Ok(CounterStyle::Name(name));
|
return Ok(CounterStyle::Name(name));
|
||||||
}
|
}
|
||||||
input.expect_function_matching("symbols")?;
|
input.expect_function_matching("symbols")?;
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let symbols_type = input
|
let symbols_type = input
|
||||||
.try(SymbolsType::parse)
|
.try_parse(SymbolsType::parse)
|
||||||
.unwrap_or(SymbolsType::Symbolic);
|
.unwrap_or(SymbolsType::Symbolic);
|
||||||
let symbols = Symbols::parse(context, input)?;
|
let symbols = Symbols::parse(context, input)?;
|
||||||
// There must be at least two symbols for alphabetic or
|
// There must be at least two symbols for alphabetic or
|
||||||
|
|
|
@ -55,7 +55,7 @@ where
|
||||||
Parse: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>>,
|
Parse: Fn(&ParserContext, &mut Parser<'i, 't>) -> Result<T, ParseError<'i>>,
|
||||||
{
|
{
|
||||||
let first = parse(context, input)?;
|
let first = parse(context, input)?;
|
||||||
let second = if let Ok(second) = input.try(|i| parse(context, i)) {
|
let second = if let Ok(second) = input.try_parse(|i| parse(context, i)) {
|
||||||
second
|
second
|
||||||
} else {
|
} else {
|
||||||
// <first>
|
// <first>
|
||||||
|
@ -66,13 +66,13 @@ where
|
||||||
first,
|
first,
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
let third = if let Ok(third) = input.try(|i| parse(context, i)) {
|
let third = if let Ok(third) = input.try_parse(|i| parse(context, i)) {
|
||||||
third
|
third
|
||||||
} else {
|
} else {
|
||||||
// <first> <second>
|
// <first> <second>
|
||||||
return Ok(Self::new(first.clone(), second.clone(), first, second));
|
return Ok(Self::new(first.clone(), second.clone(), first, second));
|
||||||
};
|
};
|
||||||
let fourth = if let Ok(fourth) = input.try(|i| parse(context, i)) {
|
let fourth = if let Ok(fourth) = input.try_parse(|i| parse(context, i)) {
|
||||||
fourth
|
fourth
|
||||||
} else {
|
} else {
|
||||||
// <first> <second> <third>
|
// <first> <second> <third>
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl<L> Size2D<L> {
|
||||||
{
|
{
|
||||||
let first = parse_one(context, input)?;
|
let first = parse_one(context, input)?;
|
||||||
let second = input
|
let second = input
|
||||||
.try(|i| parse_one(context, i))
|
.try_parse(|i| parse_one(context, i))
|
||||||
.unwrap_or_else(|_| first.clone());
|
.unwrap_or_else(|_| first.clone());
|
||||||
Ok(Self::new(first, second))
|
Ok(Self::new(first, second))
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,7 +129,7 @@ impl<C: Parse, U: Parse> Parse for SVGPaint<C, U> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let fallback = input
|
let fallback = input
|
||||||
.try(|i| SVGPaintFallback::parse(context, i))
|
.try_parse(|i| SVGPaintFallback::parse(context, i))
|
||||||
.unwrap_or(SVGPaintFallback::Unset);
|
.unwrap_or(SVGPaintFallback::Unset);
|
||||||
Ok(SVGPaint { kind, fallback })
|
Ok(SVGPaint { kind, fallback })
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,10 @@ impl<Value> Spacing<Value> {
|
||||||
where
|
where
|
||||||
F: FnOnce(&ParserContext, &mut Parser<'i, 't>) -> Result<Value, ParseError<'i>>,
|
F: FnOnce(&ParserContext, &mut Parser<'i, 't>) -> Result<Value, ParseError<'i>>,
|
||||||
{
|
{
|
||||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("normal"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(Spacing::Normal);
|
return Ok(Spacing::Normal);
|
||||||
}
|
}
|
||||||
parse(context, input).map(Spacing::Value)
|
parse(context, input).map(Spacing::Value)
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
//! Generic values for UI properties.
|
//! Generic values for UI properties.
|
||||||
|
|
||||||
|
use crate::values::specified::ui::CursorKind;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
use values::specified::ui::CursorKind;
|
|
||||||
|
|
||||||
/// A generic value for the `cursor` property.
|
/// A generic value for the `cursor` property.
|
||||||
///
|
///
|
||||||
|
|
|
@ -194,25 +194,28 @@ impl ContentDistribution {
|
||||||
// when this function is updated.
|
// when this function is updated.
|
||||||
|
|
||||||
// Try to parse normal first
|
// Try to parse normal first
|
||||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("normal"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(ContentDistribution::normal());
|
return Ok(ContentDistribution::normal());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse <baseline-position>, but only on the block axis.
|
// Parse <baseline-position>, but only on the block axis.
|
||||||
if axis == AxisDirection::Block {
|
if axis == AxisDirection::Block {
|
||||||
if let Ok(value) = input.try(parse_baseline) {
|
if let Ok(value) = input.try_parse(parse_baseline) {
|
||||||
return Ok(ContentDistribution::new(value));
|
return Ok(ContentDistribution::new(value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// <content-distribution>
|
// <content-distribution>
|
||||||
if let Ok(value) = input.try(parse_content_distribution) {
|
if let Ok(value) = input.try_parse(parse_content_distribution) {
|
||||||
return Ok(ContentDistribution::new(value));
|
return Ok(ContentDistribution::new(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// <overflow-position>? <content-position>
|
// <overflow-position>? <content-position>
|
||||||
let overflow_position = input
|
let overflow_position = input
|
||||||
.try(parse_overflow_position)
|
.try_parse(parse_overflow_position)
|
||||||
.unwrap_or(AlignFlags::empty());
|
.unwrap_or(AlignFlags::empty());
|
||||||
|
|
||||||
let content_position = try_match_ident_ignore_ascii_case! { input,
|
let content_position = try_match_ident_ignore_ascii_case! { input,
|
||||||
|
@ -426,18 +429,18 @@ impl SelfAlignment {
|
||||||
//
|
//
|
||||||
// It's weird that this accepts <baseline-position>, but not
|
// It's weird that this accepts <baseline-position>, but not
|
||||||
// justify-content...
|
// justify-content...
|
||||||
if let Ok(value) = input.try(parse_baseline) {
|
if let Ok(value) = input.try_parse(parse_baseline) {
|
||||||
return Ok(SelfAlignment(value));
|
return Ok(SelfAlignment(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// auto | normal | stretch
|
// auto | normal | stretch
|
||||||
if let Ok(value) = input.try(parse_auto_normal_stretch) {
|
if let Ok(value) = input.try_parse(parse_auto_normal_stretch) {
|
||||||
return Ok(SelfAlignment(value));
|
return Ok(SelfAlignment(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// <overflow-position>? <self-position>
|
// <overflow-position>? <self-position>
|
||||||
let overflow_position = input
|
let overflow_position = input
|
||||||
.try(parse_overflow_position)
|
.try_parse(parse_overflow_position)
|
||||||
.unwrap_or(AlignFlags::empty());
|
.unwrap_or(AlignFlags::empty());
|
||||||
let self_position = parse_self_position(input, axis)?;
|
let self_position = parse_self_position(input, axis)?;
|
||||||
Ok(SelfAlignment(overflow_position | self_position))
|
Ok(SelfAlignment(overflow_position | self_position))
|
||||||
|
@ -564,17 +567,17 @@ impl Parse for AlignItems {
|
||||||
// this function is updated.
|
// this function is updated.
|
||||||
|
|
||||||
// <baseline-position>
|
// <baseline-position>
|
||||||
if let Ok(baseline) = input.try(parse_baseline) {
|
if let Ok(baseline) = input.try_parse(parse_baseline) {
|
||||||
return Ok(AlignItems(baseline));
|
return Ok(AlignItems(baseline));
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal | stretch
|
// normal | stretch
|
||||||
if let Ok(value) = input.try(parse_normal_stretch) {
|
if let Ok(value) = input.try_parse(parse_normal_stretch) {
|
||||||
return Ok(AlignItems(value));
|
return Ok(AlignItems(value));
|
||||||
}
|
}
|
||||||
// <overflow-position>? <self-position>
|
// <overflow-position>? <self-position>
|
||||||
let overflow = input
|
let overflow = input
|
||||||
.try(parse_overflow_position)
|
.try_parse(parse_overflow_position)
|
||||||
.unwrap_or(AlignFlags::empty());
|
.unwrap_or(AlignFlags::empty());
|
||||||
let self_position = parse_self_position(input, AxisDirection::Block)?;
|
let self_position = parse_self_position(input, AxisDirection::Block)?;
|
||||||
Ok(AlignItems(self_position | overflow))
|
Ok(AlignItems(self_position | overflow))
|
||||||
|
@ -623,23 +626,23 @@ impl Parse for JustifyItems {
|
||||||
//
|
//
|
||||||
// It's weird that this accepts <baseline-position>, but not
|
// It's weird that this accepts <baseline-position>, but not
|
||||||
// justify-content...
|
// justify-content...
|
||||||
if let Ok(baseline) = input.try(parse_baseline) {
|
if let Ok(baseline) = input.try_parse(parse_baseline) {
|
||||||
return Ok(JustifyItems(baseline));
|
return Ok(JustifyItems(baseline));
|
||||||
}
|
}
|
||||||
|
|
||||||
// normal | stretch
|
// normal | stretch
|
||||||
if let Ok(value) = input.try(parse_normal_stretch) {
|
if let Ok(value) = input.try_parse(parse_normal_stretch) {
|
||||||
return Ok(JustifyItems(value));
|
return Ok(JustifyItems(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// legacy | [ legacy && [ left | right | center ] ]
|
// legacy | [ legacy && [ left | right | center ] ]
|
||||||
if let Ok(value) = input.try(parse_legacy) {
|
if let Ok(value) = input.try_parse(parse_legacy) {
|
||||||
return Ok(JustifyItems(value));
|
return Ok(JustifyItems(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// <overflow-position>? <self-position>
|
// <overflow-position>? <self-position>
|
||||||
let overflow = input
|
let overflow = input
|
||||||
.try(parse_overflow_position)
|
.try_parse(parse_overflow_position)
|
||||||
.unwrap_or(AlignFlags::empty());
|
.unwrap_or(AlignFlags::empty());
|
||||||
let self_position = parse_self_position(input, AxisDirection::Inline)?;
|
let self_position = parse_self_position(input, AxisDirection::Inline)?;
|
||||||
Ok(JustifyItems(overflow | self_position))
|
Ok(JustifyItems(overflow | self_position))
|
||||||
|
@ -795,7 +798,7 @@ fn parse_legacy<'i, 't>(input: &mut Parser<'i, 't>) -> Result<AlignFlags, ParseE
|
||||||
// when this function is updated.
|
// when this function is updated.
|
||||||
let flags = try_match_ident_ignore_ascii_case! { input,
|
let flags = try_match_ident_ignore_ascii_case! { input,
|
||||||
"legacy" => {
|
"legacy" => {
|
||||||
let flags = input.try(parse_left_right_center)
|
let flags = input.try_parse(parse_left_right_center)
|
||||||
.unwrap_or(AlignFlags::empty());
|
.unwrap_or(AlignFlags::empty());
|
||||||
|
|
||||||
return Ok(AlignFlags::LEGACY | flags)
|
return Ok(AlignFlags::LEGACY | flags)
|
||||||
|
|
|
@ -22,9 +22,10 @@ impl Parse for BackgroundSize {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(width) = input.try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i)) {
|
if let Ok(width) = input.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
|
||||||
|
{
|
||||||
let height = input
|
let height = input
|
||||||
.try(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
|
.try_parse(|i| NonNegativeLengthPercentageOrAuto::parse(context, i))
|
||||||
.unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
|
.unwrap_or(NonNegativeLengthPercentageOrAuto::auto());
|
||||||
return Ok(GenericBackgroundSize::ExplicitSize { width, height });
|
return Ok(GenericBackgroundSize::ExplicitSize { width, height });
|
||||||
}
|
}
|
||||||
|
@ -136,7 +137,7 @@ impl Parse for BackgroundRepeat {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let vertical = input.try(BackgroundRepeatKeyword::parse).ok();
|
let vertical = input.try_parse(BackgroundRepeatKeyword::parse).ok();
|
||||||
Ok(BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)))
|
Ok(BackgroundRepeat(horizontal, vertical.unwrap_or(horizontal)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ where
|
||||||
return false; // already parsed this component
|
return false; // already parsed this component
|
||||||
}
|
}
|
||||||
|
|
||||||
*component = input.try(|i| U::parse(context, i)).ok();
|
*component = input.try_parse(|i| U::parse(context, i)).ok();
|
||||||
component.is_some()
|
component.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,17 +112,17 @@ impl Parse for ClipPath {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(ClipPath::None);
|
return Ok(ClipPath::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_clip_path_path_enabled(context) {
|
if is_clip_path_path_enabled(context) {
|
||||||
if let Ok(p) = input.try(|i| Path::parse(context, i)) {
|
if let Ok(p) = input.try_parse(|i| Path::parse(context, i)) {
|
||||||
return Ok(ClipPath::Path(p));
|
return Ok(ClipPath::Path(p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
|
if let Ok(url) = input.try_parse(|i| SpecifiedUrl::parse(context, i)) {
|
||||||
return Ok(ClipPath::Url(url));
|
return Ok(ClipPath::Url(url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +138,11 @@ impl Parse for ShapeOutside {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
// Need to parse this here so that `Image::parse_with_cors_anonymous`
|
// Need to parse this here so that `Image::parse_with_cors_anonymous`
|
||||||
// doesn't parse it.
|
// doesn't parse it.
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(ShapeOutside::None);
|
return Ok(ShapeOutside::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(image) = input.try(|i| Image::parse_with_cors_anonymous(context, i)) {
|
if let Ok(image) = input.try_parse(|i| Image::parse_with_cors_anonymous(context, i)) {
|
||||||
debug_assert_ne!(image, Image::None);
|
debug_assert_ne!(image, Image::None);
|
||||||
return Ok(ShapeOutside::Image(image));
|
return Ok(ShapeOutside::Image(image));
|
||||||
}
|
}
|
||||||
|
@ -189,7 +189,10 @@ impl InsetRect {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let rect = Rect::parse_with(context, input, LengthPercentage::parse)?;
|
let rect = Rect::parse_with(context, input, LengthPercentage::parse)?;
|
||||||
let round = if input.try(|i| i.expect_ident_matching("round")).is_ok() {
|
let round = if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("round"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
BorderRadius::parse(context, input)?
|
BorderRadius::parse(context, input)?
|
||||||
} else {
|
} else {
|
||||||
BorderRadius::zero()
|
BorderRadius::zero()
|
||||||
|
@ -214,9 +217,9 @@ impl Circle {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let radius = input
|
let radius = input
|
||||||
.try(|i| ShapeRadius::parse(context, i))
|
.try_parse(|i| ShapeRadius::parse(context, i))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let position = if input.try(|i| i.expect_ident_matching("at")).is_ok() {
|
let position = if input.try_parse(|i| i.expect_ident_matching("at")).is_ok() {
|
||||||
Position::parse(context, input)?
|
Position::parse(context, input)?
|
||||||
} else {
|
} else {
|
||||||
Position::center()
|
Position::center()
|
||||||
|
@ -242,14 +245,14 @@ impl Ellipse {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let (a, b) = input
|
let (a, b) = input
|
||||||
.try(|i| -> Result<_, ParseError> {
|
.try_parse(|i| -> Result<_, ParseError> {
|
||||||
Ok((
|
Ok((
|
||||||
ShapeRadius::parse(context, i)?,
|
ShapeRadius::parse(context, i)?,
|
||||||
ShapeRadius::parse(context, i)?,
|
ShapeRadius::parse(context, i)?,
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
let position = if input.try(|i| i.expect_ident_matching("at")).is_ok() {
|
let position = if input.try_parse(|i| i.expect_ident_matching("at")).is_ok() {
|
||||||
Position::parse(context, input)?
|
Position::parse(context, input)?
|
||||||
} else {
|
} else {
|
||||||
Position::center()
|
Position::center()
|
||||||
|
@ -280,7 +283,7 @@ impl Polygon {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let fill = input
|
let fill = input
|
||||||
.try(|i| -> Result<_, ParseError> {
|
.try_parse(|i| -> Result<_, ParseError> {
|
||||||
let fill = FillRule::parse(i)?;
|
let fill = FillRule::parse(i)?;
|
||||||
i.expect_comma()?; // only eat the comma if there is something before it
|
i.expect_comma()?; // only eat the comma if there is something before it
|
||||||
Ok(fill)
|
Ok(fill)
|
||||||
|
@ -317,7 +320,7 @@ impl Path {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let fill = input
|
let fill = input
|
||||||
.try(|i| -> Result<_, ParseError> {
|
.try_parse(|i| -> Result<_, ParseError> {
|
||||||
let fill = FillRule::parse(i)?;
|
let fill = FillRule::parse(i)?;
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
Ok(fill)
|
Ok(fill)
|
||||||
|
|
|
@ -121,7 +121,8 @@ impl BorderSideWidth {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(length) = input.try(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks))
|
if let Ok(length) =
|
||||||
|
input.try_parse(|i| NonNegativeLength::parse_quirky(context, i, allow_quirks))
|
||||||
{
|
{
|
||||||
return Ok(BorderSideWidth::Length(length));
|
return Ok(BorderSideWidth::Length(length));
|
||||||
}
|
}
|
||||||
|
@ -178,10 +179,10 @@ impl Parse for BorderImageSlice {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
let mut fill = input.try_parse(|i| i.expect_ident_matching("fill")).is_ok();
|
||||||
let offsets = Rect::parse_with(context, input, NonNegativeNumberOrPercentage::parse)?;
|
let offsets = Rect::parse_with(context, input, NonNegativeNumberOrPercentage::parse)?;
|
||||||
if !fill {
|
if !fill {
|
||||||
fill = input.try(|i| i.expect_ident_matching("fill")).is_ok();
|
fill = input.try_parse(|i| i.expect_ident_matching("fill")).is_ok();
|
||||||
}
|
}
|
||||||
Ok(GenericBorderImageSlice { offsets, fill })
|
Ok(GenericBorderImageSlice { offsets, fill })
|
||||||
}
|
}
|
||||||
|
@ -193,7 +194,7 @@ impl Parse for BorderRadius {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let widths = Rect::parse_with(context, input, NonNegativeLengthPercentage::parse)?;
|
let widths = Rect::parse_with(context, input, NonNegativeLengthPercentage::parse)?;
|
||||||
let heights = if input.try(|i| i.expect_delim('/')).is_ok() {
|
let heights = if input.try_parse(|i| i.expect_delim('/')).is_ok() {
|
||||||
Rect::parse_with(context, input, NonNegativeLengthPercentage::parse)?
|
Rect::parse_with(context, input, NonNegativeLengthPercentage::parse)?
|
||||||
} else {
|
} else {
|
||||||
widths.clone()
|
widths.clone()
|
||||||
|
@ -301,7 +302,7 @@ impl Parse for BorderImageRepeat {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let horizontal = BorderImageRepeatKeyword::parse(input)?;
|
let horizontal = BorderImageRepeatKeyword::parse(input)?;
|
||||||
let vertical = input.try(BorderImageRepeatKeyword::parse).ok();
|
let vertical = input.try_parse(BorderImageRepeatKeyword::parse).ok();
|
||||||
Ok(BorderImageRepeat(
|
Ok(BorderImageRepeat(
|
||||||
horizontal,
|
horizontal,
|
||||||
vertical.unwrap_or(horizontal),
|
vertical.unwrap_or(horizontal),
|
||||||
|
|
|
@ -34,15 +34,17 @@ fn moz_box_display_values_enabled(context: &ParserContext) -> bool {
|
||||||
static_prefs::pref!("layout.css.xul-box-display-values.content.enabled")
|
static_prefs::pref!("layout.css.xul-box-display-values.content.enabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "servo-layout-2020"))]
|
||||||
fn flexbox_enabled() -> bool {
|
fn flexbox_enabled() -> bool {
|
||||||
if cfg!(feature = "servo-layout-2020") {
|
true
|
||||||
servo_config::prefs::pref_map()
|
}
|
||||||
.get("layout.flexbox.enabled")
|
|
||||||
.as_bool()
|
#[cfg(feature = "servo-layout-2020")]
|
||||||
.unwrap_or(false)
|
fn flexbox_enabled() -> bool {
|
||||||
} else {
|
servo_config::prefs::pref_map()
|
||||||
true
|
.get("layout.flexbox.enabled")
|
||||||
}
|
.as_bool()
|
||||||
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines an element’s display type, which consists of
|
/// Defines an element’s display type, which consists of
|
||||||
|
@ -530,30 +532,30 @@ impl Parse for Display {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Display, ParseError<'i>> {
|
) -> Result<Display, ParseError<'i>> {
|
||||||
// Parse all combinations of <display-inside/outside>? and `list-item`? first.
|
// Parse all combinations of <display-inside/outside>? and `list-item`? first.
|
||||||
let mut got_list_item = input.try(parse_list_item).is_ok();
|
let mut got_list_item = input.try_parse(parse_list_item).is_ok();
|
||||||
let mut inside = if got_list_item {
|
let mut inside = if got_list_item {
|
||||||
input.try(parse_display_inside_for_list_item)
|
input.try_parse(parse_display_inside_for_list_item)
|
||||||
} else {
|
} else {
|
||||||
input.try(parse_display_inside)
|
input.try_parse(parse_display_inside)
|
||||||
};
|
};
|
||||||
// <display-listitem> = <display-outside>? && [ flow | flow-root ]? && list-item
|
// <display-listitem> = <display-outside>? && [ flow | flow-root ]? && list-item
|
||||||
// https://drafts.csswg.org/css-display/#typedef-display-listitem
|
// https://drafts.csswg.org/css-display/#typedef-display-listitem
|
||||||
if !got_list_item && is_valid_inside_for_list_item(&inside) {
|
if !got_list_item && is_valid_inside_for_list_item(&inside) {
|
||||||
got_list_item = input.try(parse_list_item).is_ok();
|
got_list_item = input.try_parse(parse_list_item).is_ok();
|
||||||
}
|
}
|
||||||
let outside = input.try(parse_display_outside);
|
let outside = input.try_parse(parse_display_outside);
|
||||||
if outside.is_ok() {
|
if outside.is_ok() {
|
||||||
if !got_list_item && (inside.is_err() || is_valid_inside_for_list_item(&inside)) {
|
if !got_list_item && (inside.is_err() || is_valid_inside_for_list_item(&inside)) {
|
||||||
got_list_item = input.try(parse_list_item).is_ok();
|
got_list_item = input.try_parse(parse_list_item).is_ok();
|
||||||
}
|
}
|
||||||
if inside.is_err() {
|
if inside.is_err() {
|
||||||
inside = if got_list_item {
|
inside = if got_list_item {
|
||||||
input.try(parse_display_inside_for_list_item)
|
input.try_parse(parse_display_inside_for_list_item)
|
||||||
} else {
|
} else {
|
||||||
input.try(parse_display_inside)
|
input.try_parse(parse_display_inside)
|
||||||
};
|
};
|
||||||
if !got_list_item && is_valid_inside_for_list_item(&inside) {
|
if !got_list_item && is_valid_inside_for_list_item(&inside) {
|
||||||
got_list_item = input.try(parse_list_item).is_ok();
|
got_list_item = input.try_parse(parse_list_item).is_ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -677,7 +679,8 @@ impl Parse for VerticalAlign {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(lp) = input.try(|i| LengthPercentage::parse_quirky(context, i, AllowQuirks::Yes))
|
if let Ok(lp) =
|
||||||
|
input.try_parse(|i| LengthPercentage::parse_quirky(context, i, AllowQuirks::Yes))
|
||||||
{
|
{
|
||||||
return Ok(GenericVerticalAlign::Length(lp));
|
return Ok(GenericVerticalAlign::Length(lp));
|
||||||
}
|
}
|
||||||
|
@ -697,7 +700,7 @@ impl Parse for AnimationIterationCount {
|
||||||
input: &mut ::cssparser::Parser<'i, 't>,
|
input: &mut ::cssparser::Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("infinite"))
|
.try_parse(|input| input.expect_ident_matching("infinite"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(GenericAnimationIterationCount::Infinite);
|
return Ok(GenericAnimationIterationCount::Infinite);
|
||||||
|
@ -761,7 +764,7 @@ impl Parse for AnimationName {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(name) = input.try(|input| KeyframesName::parse(context, input)) {
|
if let Ok(name) = input.try_parse(|input| KeyframesName::parse(context, input)) {
|
||||||
return Ok(AnimationName(Some(name)));
|
return Ok(AnimationName(Some(name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -860,7 +863,7 @@ impl Parse for ScrollSnapType {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(ScrollSnapType::none());
|
return Ok(ScrollSnapType::none());
|
||||||
|
@ -868,7 +871,7 @@ impl Parse for ScrollSnapType {
|
||||||
|
|
||||||
let axis = ScrollSnapAxis::parse(input)?;
|
let axis = ScrollSnapAxis::parse(input)?;
|
||||||
let strictness = input
|
let strictness = input
|
||||||
.try(ScrollSnapStrictness::parse)
|
.try_parse(ScrollSnapStrictness::parse)
|
||||||
.unwrap_or(ScrollSnapStrictness::Proximity);
|
.unwrap_or(ScrollSnapStrictness::Proximity);
|
||||||
Ok(Self { axis, strictness })
|
Ok(Self { axis, strictness })
|
||||||
}
|
}
|
||||||
|
@ -955,7 +958,9 @@ impl Parse for ScrollSnapAlign {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<ScrollSnapAlign, ParseError<'i>> {
|
) -> Result<ScrollSnapAlign, ParseError<'i>> {
|
||||||
let block = ScrollSnapAlignKeyword::parse(input)?;
|
let block = ScrollSnapAlignKeyword::parse(input)?;
|
||||||
let inline = input.try(ScrollSnapAlignKeyword::parse).unwrap_or(block);
|
let inline = input
|
||||||
|
.try_parse(ScrollSnapAlignKeyword::parse)
|
||||||
|
.unwrap_or(block);
|
||||||
Ok(ScrollSnapAlign { block, inline })
|
Ok(ScrollSnapAlign { block, inline })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1150,7 +1155,7 @@ impl Parse for WillChange {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("auto"))
|
.try_parse(|input| input.expect_ident_matching("auto"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(Self::default());
|
return Ok(Self::default());
|
||||||
|
@ -1238,14 +1243,14 @@ impl Parse for TouchAction {
|
||||||
"none" => Ok(TouchAction::NONE),
|
"none" => Ok(TouchAction::NONE),
|
||||||
"manipulation" => Ok(TouchAction::MANIPULATION),
|
"manipulation" => Ok(TouchAction::MANIPULATION),
|
||||||
"pan-x" => {
|
"pan-x" => {
|
||||||
if input.try(|i| i.expect_ident_matching("pan-y")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("pan-y")).is_ok() {
|
||||||
Ok(TouchAction::PAN_X | TouchAction::PAN_Y)
|
Ok(TouchAction::PAN_X | TouchAction::PAN_Y)
|
||||||
} else {
|
} else {
|
||||||
Ok(TouchAction::PAN_X)
|
Ok(TouchAction::PAN_X)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"pan-y" => {
|
"pan-y" => {
|
||||||
if input.try(|i| i.expect_ident_matching("pan-x")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("pan-x")).is_ok() {
|
||||||
Ok(TouchAction::PAN_X | TouchAction::PAN_Y)
|
Ok(TouchAction::PAN_X | TouchAction::PAN_Y)
|
||||||
} else {
|
} else {
|
||||||
Ok(TouchAction::PAN_Y)
|
Ok(TouchAction::PAN_Y)
|
||||||
|
@ -1323,7 +1328,7 @@ impl Parse for Contain {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Contain, ParseError<'i>> {
|
) -> Result<Contain, ParseError<'i>> {
|
||||||
let mut result = Contain::empty();
|
let mut result = Contain::empty();
|
||||||
while let Ok(name) = input.try(|i| i.expect_ident_cloned()) {
|
while let Ok(name) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||||
let flag = match_ignore_ascii_case! { &name,
|
let flag = match_ignore_ascii_case! { &name,
|
||||||
"size" => Some(Contain::SIZE),
|
"size" => Some(Contain::SIZE),
|
||||||
"layout" => Some(Contain::LAYOUT),
|
"layout" => Some(Contain::LAYOUT),
|
||||||
|
|
|
@ -245,6 +245,12 @@ pub enum SystemColor {
|
||||||
|
|
||||||
MozGtkInfoBarText,
|
MozGtkInfoBarText,
|
||||||
|
|
||||||
|
/// Color of tree column headers
|
||||||
|
#[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
|
||||||
|
MozColheadertext,
|
||||||
|
#[parse(condition = "ParserContext::in_ua_or_chrome_sheet")]
|
||||||
|
MozColheaderhovertext,
|
||||||
|
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
End, // Just for array-indexing purposes.
|
End, // Just for array-indexing purposes.
|
||||||
}
|
}
|
||||||
|
@ -356,7 +362,7 @@ impl Parse for Color {
|
||||||
input.reset(&start);
|
input.reset(&start);
|
||||||
|
|
||||||
let compontent_parser = ColorComponentParser(&*context);
|
let compontent_parser = ColorComponentParser(&*context);
|
||||||
match input.try(|i| CSSParserColor::parse_with(&compontent_parser, i)) {
|
match input.try_parse(|i| CSSParserColor::parse_with(&compontent_parser, i)) {
|
||||||
Ok(value) => Ok(match value {
|
Ok(value) => Ok(match value {
|
||||||
CSSParserColor::CurrentColor => Color::CurrentColor,
|
CSSParserColor::CurrentColor => Color::CurrentColor,
|
||||||
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
CSSParserColor::RGBA(rgba) => Color::Numeric {
|
||||||
|
@ -367,7 +373,7 @@ impl Parse for Color {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if let Ok(system) = input.try(|i| SystemColor::parse(context, i)) {
|
if let Ok(system) = input.try_parse(|i| SystemColor::parse(context, i)) {
|
||||||
return Ok(Color::System(system));
|
return Ok(Color::System(system));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -451,7 +457,7 @@ impl Color {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.try(|i| Self::parse(context, i)).or_else(|e| {
|
input.try_parse(|i| Self::parse(context, i)).or_else(|e| {
|
||||||
if !allow_quirks.allowed(context.quirks_mode) {
|
if !allow_quirks.allowed(context.quirks_mode) {
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ fn parse_counters<'i, 't>(
|
||||||
default_value: i32,
|
default_value: i32,
|
||||||
) -> Result<Vec<CounterPair<Integer>>, ParseError<'i>> {
|
) -> Result<Vec<CounterPair<Integer>>, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
|
@ -69,7 +69,7 @@ fn parse_counters<'i, 't>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = input
|
let value = input
|
||||||
.try(|input| Integer::parse(context, input))
|
.try_parse(|input| Integer::parse(context, input))
|
||||||
.unwrap_or(Integer::new(default_value));
|
.unwrap_or(Integer::new(default_value));
|
||||||
counters.push(CounterPair { name, value });
|
counters.push(CounterPair { name, value });
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ impl Content {
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
fn parse_counter_style(_: &ParserContext, input: &mut Parser) -> ListStyleType {
|
fn parse_counter_style(_: &ParserContext, input: &mut Parser) -> ListStyleType {
|
||||||
input
|
input
|
||||||
.try(|input| {
|
.try_parse(|input| {
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
ListStyleType::parse(input)
|
ListStyleType::parse(input)
|
||||||
})
|
})
|
||||||
|
@ -101,7 +101,7 @@ impl Content {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyle {
|
fn parse_counter_style(context: &ParserContext, input: &mut Parser) -> CounterStyle {
|
||||||
input
|
input
|
||||||
.try(|input| {
|
.try_parse(|input| {
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
CounterStyle::parse(context, input)
|
CounterStyle::parse(context, input)
|
||||||
})
|
})
|
||||||
|
@ -119,13 +119,13 @@ impl Parse for Content {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(generics::Content::Normal);
|
return Ok(generics::Content::Normal);
|
||||||
}
|
}
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(generics::Content::None);
|
return Ok(generics::Content::None);
|
||||||
|
@ -136,7 +136,7 @@ impl Parse for Content {
|
||||||
loop {
|
loop {
|
||||||
#[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
|
#[cfg(any(feature = "gecko", feature = "servo-layout-2020"))]
|
||||||
{
|
{
|
||||||
if let Ok(url) = input.try(|i| SpecifiedImageUrl::parse(context, i)) {
|
if let Ok(url) = input.try_parse(|i| SpecifiedImageUrl::parse(context, i)) {
|
||||||
content.push(generics::ContentItem::Url(url));
|
content.push(generics::ContentItem::Url(url));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,10 +21,10 @@ impl Parse for TimingFunction {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(keyword) = input.try(TimingKeyword::parse) {
|
if let Ok(keyword) = input.try_parse(TimingKeyword::parse) {
|
||||||
return Ok(GenericTimingFunction::Keyword(keyword));
|
return Ok(GenericTimingFunction::Keyword(keyword));
|
||||||
}
|
}
|
||||||
if let Ok(ident) = input.try(|i| i.expect_ident_cloned()) {
|
if let Ok(ident) = input.try_parse(|i| i.expect_ident_cloned()) {
|
||||||
let position = match_ignore_ascii_case! { &ident,
|
let position = match_ignore_ascii_case! { &ident,
|
||||||
"step-start" => StepPosition::Start,
|
"step-start" => StepPosition::Start,
|
||||||
"step-end" => StepPosition::End,
|
"step-end" => StepPosition::End,
|
||||||
|
@ -57,7 +57,7 @@ impl Parse for TimingFunction {
|
||||||
},
|
},
|
||||||
"steps" => {
|
"steps" => {
|
||||||
let steps = Integer::parse_positive(context, i)?;
|
let steps = Integer::parse_positive(context, i)?;
|
||||||
let position = i.try(|i| {
|
let position = i.try_parse(|i| {
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
StepPosition::parse(context, i)
|
StepPosition::parse(context, i)
|
||||||
}).unwrap_or(StepPosition::End);
|
}).unwrap_or(StepPosition::End);
|
||||||
|
|
|
@ -141,7 +141,7 @@ impl Parse for BoxShadow {
|
||||||
loop {
|
loop {
|
||||||
if !inset {
|
if !inset {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("inset"))
|
.try_parse(|input| input.expect_ident_matching("inset"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
inset = true;
|
inset = true;
|
||||||
|
@ -149,18 +149,17 @@ impl Parse for BoxShadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if lengths.is_none() {
|
if lengths.is_none() {
|
||||||
let value = input.try::<_, _, ParseError>(|i| {
|
let value = input.try_parse::<_, _, ParseError>(|i| {
|
||||||
let horizontal = Length::parse(context, i)?;
|
let horizontal = Length::parse(context, i)?;
|
||||||
let vertical = Length::parse(context, i)?;
|
let vertical = Length::parse(context, i)?;
|
||||||
let (blur, spread) = match i
|
let (blur, spread) =
|
||||||
.try::<_, _, ParseError>(|i| Length::parse_non_negative(context, i))
|
match i.try_parse(|i| Length::parse_non_negative(context, i)) {
|
||||||
{
|
Ok(blur) => {
|
||||||
Ok(blur) => {
|
let spread = i.try_parse(|i| Length::parse(context, i)).ok();
|
||||||
let spread = i.try(|i| Length::parse(context, i)).ok();
|
(Some(blur.into()), spread)
|
||||||
(Some(blur.into()), spread)
|
},
|
||||||
},
|
Err(_) => (None, None),
|
||||||
Err(_) => (None, None),
|
};
|
||||||
};
|
|
||||||
Ok((horizontal, vertical, blur, spread))
|
Ok((horizontal, vertical, blur, spread))
|
||||||
});
|
});
|
||||||
if let Ok(value) = value {
|
if let Ok(value) = value {
|
||||||
|
@ -169,7 +168,7 @@ impl Parse for BoxShadow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if color.is_none() {
|
if color.is_none() {
|
||||||
if let Ok(value) = input.try(|i| Color::parse(context, i)) {
|
if let Ok(value) = input.try_parse(|i| Color::parse(context, i)) {
|
||||||
color = Some(value);
|
color = Some(value);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -226,7 +225,7 @@ impl Parse for Filter {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if let Ok(url) = input.try(|i| SpecifiedUrl::parse(context, i)) {
|
if let Ok(url) = input.try_parse(|i| SpecifiedUrl::parse(context, i)) {
|
||||||
return Ok(GenericFilter::Url(url));
|
return Ok(GenericFilter::Url(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,22 +241,22 @@ impl Parse for Filter {
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|i| {
|
||||||
match_ignore_ascii_case! { &*function,
|
match_ignore_ascii_case! { &*function,
|
||||||
"blur" => Ok(GenericFilter::Blur(
|
"blur" => Ok(GenericFilter::Blur(
|
||||||
i.try(|i| NonNegativeLength::parse(context, i))
|
i.try_parse(|i| NonNegativeLength::parse(context, i))
|
||||||
.unwrap_or(Zero::zero()),
|
.unwrap_or(Zero::zero()),
|
||||||
)),
|
)),
|
||||||
"brightness" => Ok(GenericFilter::Brightness(
|
"brightness" => Ok(GenericFilter::Brightness(
|
||||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
i.try_parse(|i| NonNegativeFactor::parse(context, i))
|
||||||
.unwrap_or(NonNegativeFactor::one()),
|
.unwrap_or(NonNegativeFactor::one()),
|
||||||
)),
|
)),
|
||||||
"contrast" => Ok(GenericFilter::Contrast(
|
"contrast" => Ok(GenericFilter::Contrast(
|
||||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
i.try_parse(|i| NonNegativeFactor::parse(context, i))
|
||||||
.unwrap_or(NonNegativeFactor::one()),
|
.unwrap_or(NonNegativeFactor::one()),
|
||||||
)),
|
)),
|
||||||
"grayscale" => {
|
"grayscale" => {
|
||||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-grayscale
|
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-grayscale
|
||||||
Ok(GenericFilter::Grayscale(
|
Ok(GenericFilter::Grayscale(
|
||||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
i.try_parse(|i| ZeroToOneFactor::parse(context, i))
|
||||||
.unwrap_or(ZeroToOneFactor::one()),
|
.unwrap_or(ZeroToOneFactor::one()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -265,7 +264,7 @@ impl Parse for Filter {
|
||||||
// We allow unitless zero here, see:
|
// We allow unitless zero here, see:
|
||||||
// https://github.com/w3c/fxtf-drafts/issues/228
|
// https://github.com/w3c/fxtf-drafts/issues/228
|
||||||
Ok(GenericFilter::HueRotate(
|
Ok(GenericFilter::HueRotate(
|
||||||
i.try(|i| Angle::parse_with_unitless(context, i))
|
i.try_parse(|i| Angle::parse_with_unitless(context, i))
|
||||||
.unwrap_or(Zero::zero()),
|
.unwrap_or(Zero::zero()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -273,7 +272,7 @@ impl Parse for Filter {
|
||||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-invert
|
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-invert
|
||||||
Ok(GenericFilter::Invert(
|
Ok(GenericFilter::Invert(
|
||||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
i.try_parse(|i| ZeroToOneFactor::parse(context, i))
|
||||||
.unwrap_or(ZeroToOneFactor::one()),
|
.unwrap_or(ZeroToOneFactor::one()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -281,19 +280,19 @@ impl Parse for Filter {
|
||||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-opacity
|
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-opacity
|
||||||
Ok(GenericFilter::Opacity(
|
Ok(GenericFilter::Opacity(
|
||||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
i.try_parse(|i| ZeroToOneFactor::parse(context, i))
|
||||||
.unwrap_or(ZeroToOneFactor::one()),
|
.unwrap_or(ZeroToOneFactor::one()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
"saturate" => Ok(GenericFilter::Saturate(
|
"saturate" => Ok(GenericFilter::Saturate(
|
||||||
i.try(|i| NonNegativeFactor::parse(context, i))
|
i.try_parse(|i| NonNegativeFactor::parse(context, i))
|
||||||
.unwrap_or(NonNegativeFactor::one()),
|
.unwrap_or(NonNegativeFactor::one()),
|
||||||
)),
|
)),
|
||||||
"sepia" => {
|
"sepia" => {
|
||||||
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
// Values of amount over 100% are allowed but UAs must clamp the values to 1.
|
||||||
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-sepia
|
// https://drafts.fxtf.org/filter-effects/#funcdef-filter-sepia
|
||||||
Ok(GenericFilter::Sepia(
|
Ok(GenericFilter::Sepia(
|
||||||
i.try(|i| ZeroToOneFactor::parse(context, i))
|
i.try_parse(|i| ZeroToOneFactor::parse(context, i))
|
||||||
.unwrap_or(ZeroToOneFactor::one()),
|
.unwrap_or(ZeroToOneFactor::one()),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
@ -312,12 +311,14 @@ impl Parse for SimpleShadow {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let color = input.try(|i| Color::parse(context, i)).ok();
|
let color = input.try_parse(|i| Color::parse(context, i)).ok();
|
||||||
let horizontal = Length::parse(context, input)?;
|
let horizontal = Length::parse(context, input)?;
|
||||||
let vertical = Length::parse(context, input)?;
|
let vertical = Length::parse(context, input)?;
|
||||||
let blur = input.try(|i| Length::parse_non_negative(context, i)).ok();
|
let blur = input
|
||||||
|
.try_parse(|i| Length::parse_non_negative(context, i))
|
||||||
|
.ok();
|
||||||
let blur = blur.map(NonNegative::<Length>);
|
let blur = blur.map(NonNegative::<Length>);
|
||||||
let color = color.or_else(|| input.try(|i| Color::parse(context, i)).ok());
|
let color = color.or_else(|| input.try_parse(|i| Color::parse(context, i)).ok());
|
||||||
|
|
||||||
Ok(SimpleShadow {
|
Ok(SimpleShadow {
|
||||||
color,
|
color,
|
||||||
|
|
|
@ -171,7 +171,7 @@ impl Parse for AbsoluteFontWeight {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(number) = input.try(|input| Number::parse(context, input)) {
|
if let Ok(number) = input.try_parse(|input| Number::parse(context, input)) {
|
||||||
// We could add another AllowedNumericType value, but it doesn't
|
// We could add another AllowedNumericType value, but it doesn't
|
||||||
// seem worth it just for a single property with such a weird range,
|
// seem worth it just for a single property with such a weird range,
|
||||||
// so we do the clamping here manually.
|
// so we do the clamping here manually.
|
||||||
|
@ -223,7 +223,7 @@ impl Parse for SpecifiedFontStyle {
|
||||||
"normal" => generics::FontStyle::Normal,
|
"normal" => generics::FontStyle::Normal,
|
||||||
"italic" => generics::FontStyle::Italic,
|
"italic" => generics::FontStyle::Italic,
|
||||||
"oblique" => {
|
"oblique" => {
|
||||||
let angle = input.try(|input| Self::parse_angle(context, input))
|
let angle = input.try_parse(|input| Self::parse_angle(context, input))
|
||||||
.unwrap_or_else(|_| Self::default_angle());
|
.unwrap_or_else(|_| Self::default_angle());
|
||||||
|
|
||||||
generics::FontStyle::Oblique(angle)
|
generics::FontStyle::Oblique(angle)
|
||||||
|
@ -453,7 +453,9 @@ impl Parse for FontStretch {
|
||||||
//
|
//
|
||||||
// Values less than 0% are not allowed and are treated as parse
|
// Values less than 0% are not allowed and are treated as parse
|
||||||
// errors.
|
// errors.
|
||||||
if let Ok(percentage) = input.try(|input| Percentage::parse_non_negative(context, input)) {
|
if let Ok(percentage) =
|
||||||
|
input.try_parse(|input| Percentage::parse_non_negative(context, input))
|
||||||
|
{
|
||||||
return Ok(FontStretch::Stretch(percentage));
|
return Ok(FontStretch::Stretch(percentage));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,10 +498,12 @@ impl ToComputedValue for FontStretch {
|
||||||
ToCss,
|
ToCss,
|
||||||
ToResolvedValue,
|
ToResolvedValue,
|
||||||
ToShmem,
|
ToShmem,
|
||||||
|
Serialize,
|
||||||
|
Deserialize,
|
||||||
)]
|
)]
|
||||||
#[cfg_attr(feature = "servo", derive(Serialize, Deserialize))]
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
pub enum KeywordSize {
|
#[repr(u8)]
|
||||||
|
pub enum FontSizeKeyword {
|
||||||
#[css(keyword = "xx-small")]
|
#[css(keyword = "xx-small")]
|
||||||
XXSmall,
|
XXSmall,
|
||||||
XSmall,
|
XSmall,
|
||||||
|
@ -511,9 +515,11 @@ pub enum KeywordSize {
|
||||||
XXLarge,
|
XXLarge,
|
||||||
#[css(keyword = "xxx-large")]
|
#[css(keyword = "xxx-large")]
|
||||||
XXXLarge,
|
XXXLarge,
|
||||||
|
#[css(skip)]
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeywordSize {
|
impl FontSizeKeyword {
|
||||||
/// Convert to an HTML <font size> value
|
/// Convert to an HTML <font size> value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn html_size(self) -> u8 {
|
pub fn html_size(self) -> u8 {
|
||||||
|
@ -521,9 +527,9 @@ impl KeywordSize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for KeywordSize {
|
impl Default for FontSizeKeyword {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
KeywordSize::Medium
|
FontSizeKeyword::Medium
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,7 +552,7 @@ impl Default for KeywordSize {
|
||||||
/// Additional information for keyword-derived font sizes.
|
/// Additional information for keyword-derived font sizes.
|
||||||
pub struct KeywordInfo {
|
pub struct KeywordInfo {
|
||||||
/// The keyword used
|
/// The keyword used
|
||||||
pub kw: KeywordSize,
|
pub kw: FontSizeKeyword,
|
||||||
/// A factor to be multiplied by the computed size of the keyword
|
/// A factor to be multiplied by the computed size of the keyword
|
||||||
#[css(skip)]
|
#[css(skip)]
|
||||||
pub factor: f32,
|
pub factor: f32,
|
||||||
|
@ -559,10 +565,15 @@ pub struct KeywordInfo {
|
||||||
impl KeywordInfo {
|
impl KeywordInfo {
|
||||||
/// KeywordInfo value for font-size: medium
|
/// KeywordInfo value for font-size: medium
|
||||||
pub fn medium() -> Self {
|
pub fn medium() -> Self {
|
||||||
Self::new(KeywordSize::Medium)
|
Self::new(FontSizeKeyword::Medium)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new(kw: KeywordSize) -> Self {
|
/// KeywordInfo value for font-size: none
|
||||||
|
pub fn none() -> Self {
|
||||||
|
Self::new(FontSizeKeyword::None)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(kw: FontSizeKeyword) -> Self {
|
||||||
KeywordInfo {
|
KeywordInfo {
|
||||||
kw,
|
kw,
|
||||||
factor: 1.,
|
factor: 1.,
|
||||||
|
@ -573,6 +584,7 @@ impl KeywordInfo {
|
||||||
/// Computes the final size for this font-size keyword, accounting for
|
/// Computes the final size for this font-size keyword, accounting for
|
||||||
/// text-zoom.
|
/// text-zoom.
|
||||||
fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
|
fn to_computed_value(&self, context: &Context) -> CSSPixelLength {
|
||||||
|
debug_assert_ne!(self.kw, FontSizeKeyword::None);
|
||||||
let base = context.maybe_zoom_text(self.kw.to_length(context).0);
|
let base = context.maybe_zoom_text(self.kw.to_length(context).0);
|
||||||
base * self.factor + context.maybe_zoom_text(self.offset)
|
base * self.factor + context.maybe_zoom_text(self.offset)
|
||||||
}
|
}
|
||||||
|
@ -580,6 +592,9 @@ impl KeywordInfo {
|
||||||
/// Given a parent keyword info (self), apply an additional factor/offset to
|
/// Given a parent keyword info (self), apply an additional factor/offset to
|
||||||
/// it.
|
/// it.
|
||||||
fn compose(self, factor: f32) -> Self {
|
fn compose(self, factor: f32) -> Self {
|
||||||
|
if self.kw == FontSizeKeyword::None {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
KeywordInfo {
|
KeywordInfo {
|
||||||
kw: self.kw,
|
kw: self.kw,
|
||||||
factor: self.factor * factor,
|
factor: self.factor * factor,
|
||||||
|
@ -590,7 +605,7 @@ impl KeywordInfo {
|
||||||
|
|
||||||
impl SpecifiedValueInfo for KeywordInfo {
|
impl SpecifiedValueInfo for KeywordInfo {
|
||||||
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
fn collect_completion_keywords(f: KeywordsCollectFn) {
|
||||||
<KeywordSize as SpecifiedValueInfo>::collect_completion_keywords(f);
|
<FontSizeKeyword as SpecifiedValueInfo>::collect_completion_keywords(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -766,21 +781,22 @@ const LARGER_FONT_SIZE_RATIO: f32 = 1.2;
|
||||||
/// The default font size.
|
/// The default font size.
|
||||||
pub const FONT_MEDIUM_PX: i32 = 16;
|
pub const FONT_MEDIUM_PX: i32 = 16;
|
||||||
|
|
||||||
impl KeywordSize {
|
impl FontSizeKeyword {
|
||||||
#[inline]
|
#[inline]
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
fn to_length(&self, _: &Context) -> NonNegativeLength {
|
fn to_length(&self, _: &Context) -> NonNegativeLength {
|
||||||
let medium = Length::new(FONT_MEDIUM_PX as f32);
|
let medium = Length::new(FONT_MEDIUM_PX as f32);
|
||||||
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
|
// https://drafts.csswg.org/css-fonts-3/#font-size-prop
|
||||||
NonNegative(match *self {
|
NonNegative(match *self {
|
||||||
KeywordSize::XXSmall => medium * 3.0 / 5.0,
|
FontSizeKeyword::XXSmall => medium * 3.0 / 5.0,
|
||||||
KeywordSize::XSmall => medium * 3.0 / 4.0,
|
FontSizeKeyword::XSmall => medium * 3.0 / 4.0,
|
||||||
KeywordSize::Small => medium * 8.0 / 9.0,
|
FontSizeKeyword::Small => medium * 8.0 / 9.0,
|
||||||
KeywordSize::Medium => medium,
|
FontSizeKeyword::Medium => medium,
|
||||||
KeywordSize::Large => medium * 6.0 / 5.0,
|
FontSizeKeyword::Large => medium * 6.0 / 5.0,
|
||||||
KeywordSize::XLarge => medium * 3.0 / 2.0,
|
FontSizeKeyword::XLarge => medium * 3.0 / 2.0,
|
||||||
KeywordSize::XXLarge => medium * 2.0,
|
FontSizeKeyword::XXLarge => medium * 2.0,
|
||||||
KeywordSize::XXXLarge => medium * 3.0,
|
FontSizeKeyword::XXXLarge => medium * 3.0,
|
||||||
|
FontSizeKeyword::None => unreachable!(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -861,14 +877,14 @@ impl FontSize {
|
||||||
pub fn from_html_size(size: u8) -> Self {
|
pub fn from_html_size(size: u8) -> Self {
|
||||||
FontSize::Keyword(KeywordInfo::new(match size {
|
FontSize::Keyword(KeywordInfo::new(match size {
|
||||||
// If value is less than 1, let it be 1.
|
// If value is less than 1, let it be 1.
|
||||||
0 | 1 => KeywordSize::XSmall,
|
0 | 1 => FontSizeKeyword::XSmall,
|
||||||
2 => KeywordSize::Small,
|
2 => FontSizeKeyword::Small,
|
||||||
3 => KeywordSize::Medium,
|
3 => FontSizeKeyword::Medium,
|
||||||
4 => KeywordSize::Large,
|
4 => FontSizeKeyword::Large,
|
||||||
5 => KeywordSize::XLarge,
|
5 => FontSizeKeyword::XLarge,
|
||||||
6 => KeywordSize::XXLarge,
|
6 => FontSizeKeyword::XXLarge,
|
||||||
// If value is greater than 7, let it be 7.
|
// If value is greater than 7, let it be 7.
|
||||||
_ => KeywordSize::XXXLarge,
|
_ => FontSizeKeyword::XXXLarge,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -886,9 +902,9 @@ impl FontSize {
|
||||||
.get_parent_font()
|
.get_parent_font()
|
||||||
.clone_font_size()
|
.clone_font_size()
|
||||||
.keyword_info
|
.keyword_info
|
||||||
.map(|i| i.compose(factor))
|
.compose(factor)
|
||||||
};
|
};
|
||||||
let mut info = None;
|
let mut info = KeywordInfo::none();
|
||||||
let size = match *self {
|
let size = match *self {
|
||||||
FontSize::Length(LengthPercentage::Length(NoCalcLength::FontRelative(value))) => {
|
FontSize::Length(LengthPercentage::Length(NoCalcLength::FontRelative(value))) => {
|
||||||
if let FontRelativeLength::Em(em) = value {
|
if let FontRelativeLength::Em(em) = value {
|
||||||
|
@ -917,7 +933,7 @@ impl FontSize {
|
||||||
},
|
},
|
||||||
FontSize::Keyword(i) => {
|
FontSize::Keyword(i) => {
|
||||||
// As a specified keyword, this is keyword derived
|
// As a specified keyword, this is keyword derived
|
||||||
info = Some(i);
|
info = i;
|
||||||
i.to_computed_value(context).clamp_to_non_negative()
|
i.to_computed_value(context).clamp_to_non_negative()
|
||||||
},
|
},
|
||||||
FontSize::Smaller => {
|
FontSize::Smaller => {
|
||||||
|
@ -985,13 +1001,13 @@ impl FontSize {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<FontSize, ParseError<'i>> {
|
) -> Result<FontSize, ParseError<'i>> {
|
||||||
if let Ok(lp) =
|
if let Ok(lp) = input
|
||||||
input.try(|i| LengthPercentage::parse_non_negative_quirky(context, i, allow_quirks))
|
.try_parse(|i| LengthPercentage::parse_non_negative_quirky(context, i, allow_quirks))
|
||||||
{
|
{
|
||||||
return Ok(FontSize::Length(lp));
|
return Ok(FontSize::Length(lp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(kw) = input.try(KeywordSize::parse) {
|
if let Ok(kw) = input.try_parse(FontSizeKeyword::parse) {
|
||||||
return Ok(FontSize::Keyword(KeywordInfo::new(kw)));
|
return Ok(FontSize::Keyword(KeywordInfo::new(kw)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,7 +1160,7 @@ impl Parse for FontVariantAlternates {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<FontVariantAlternates, ParseError<'i>> {
|
) -> Result<FontVariantAlternates, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontVariantAlternates::Value(Default::default()));
|
return Ok(FontVariantAlternates::Value(Default::default()));
|
||||||
|
@ -1160,7 +1176,7 @@ impl Parse for FontVariantAlternates {
|
||||||
parsed_alternates |= $flag;
|
parsed_alternates |= $flag;
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
while let Ok(_) = input.try(|input| match *input.next()? {
|
while let Ok(_) = input.try_parse(|input| match *input.next()? {
|
||||||
Token::Ident(ref value) if value.eq_ignore_ascii_case("historical-forms") => {
|
Token::Ident(ref value) if value.eq_ignore_ascii_case("historical-forms") => {
|
||||||
check_if_parsed!(input, VariantAlternatesParsingFlags::HISTORICAL_FORMS);
|
check_if_parsed!(input, VariantAlternatesParsingFlags::HISTORICAL_FORMS);
|
||||||
alternates.push(VariantAlternates::HistoricalForms);
|
alternates.push(VariantAlternates::HistoricalForms);
|
||||||
|
@ -1375,13 +1391,13 @@ impl Parse for FontVariantEastAsian {
|
||||||
let mut result = VariantEastAsian::empty();
|
let mut result = VariantEastAsian::empty();
|
||||||
|
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontVariantEastAsian::Value(result));
|
return Ok(FontVariantEastAsian::Value(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(flag) = input.try(|input| {
|
while let Ok(flag) = input.try_parse(|input| {
|
||||||
Ok(
|
Ok(
|
||||||
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
||||||
"jis78" =>
|
"jis78" =>
|
||||||
|
@ -1599,19 +1615,19 @@ impl Parse for FontVariantLigatures {
|
||||||
let mut result = VariantLigatures::empty();
|
let mut result = VariantLigatures::empty();
|
||||||
|
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontVariantLigatures::Value(result));
|
return Ok(FontVariantLigatures::Value(result));
|
||||||
}
|
}
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontVariantLigatures::Value(VariantLigatures::NONE));
|
return Ok(FontVariantLigatures::Value(VariantLigatures::NONE));
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(flag) = input.try(|input| {
|
while let Ok(flag) = input.try_parse(|input| {
|
||||||
Ok(
|
Ok(
|
||||||
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
||||||
"common-ligatures" =>
|
"common-ligatures" =>
|
||||||
|
@ -1808,13 +1824,13 @@ impl Parse for FontVariantNumeric {
|
||||||
let mut result = VariantNumeric::empty();
|
let mut result = VariantNumeric::empty();
|
||||||
|
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontVariantNumeric::Value(result));
|
return Ok(FontVariantNumeric::Value(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
while let Ok(flag) = input.try(|input| {
|
while let Ok(flag) = input.try_parse(|input| {
|
||||||
Ok(
|
Ok(
|
||||||
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
match_ignore_ascii_case! { &input.expect_ident().map_err(|_| ())?,
|
||||||
"ordinal" =>
|
"ordinal" =>
|
||||||
|
@ -1958,14 +1974,14 @@ impl Parse for FontSynthesis {
|
||||||
"none" => Ok(result),
|
"none" => Ok(result),
|
||||||
"weight" => {
|
"weight" => {
|
||||||
result.weight = true;
|
result.weight = true;
|
||||||
if input.try(|input| input.expect_ident_matching("style")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("style")).is_ok() {
|
||||||
result.style = true;
|
result.style = true;
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
},
|
},
|
||||||
"style" => {
|
"style" => {
|
||||||
result.style = true;
|
result.style = true;
|
||||||
if input.try(|input| input.expect_ident_matching("weight")).is_ok() {
|
if input.try_parse(|input| input.expect_ident_matching("weight")).is_ok() {
|
||||||
result.weight = true;
|
result.weight = true;
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
@ -2085,7 +2101,7 @@ impl Parse for FontLanguageOverride {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<FontLanguageOverride, ParseError<'i>> {
|
) -> Result<FontLanguageOverride, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("normal"))
|
.try_parse(|input| input.expect_ident_matching("normal"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(FontLanguageOverride::Normal);
|
return Ok(FontLanguageOverride::Normal);
|
||||||
|
@ -2152,7 +2168,7 @@ fn parse_one_feature_value<'i, 't>(
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Integer, ParseError<'i>> {
|
) -> Result<Integer, ParseError<'i>> {
|
||||||
if let Ok(integer) = input.try(|i| Integer::parse_non_negative(context, i)) {
|
if let Ok(integer) = input.try_parse(|i| Integer::parse_non_negative(context, i)) {
|
||||||
return Ok(integer);
|
return Ok(integer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2170,7 +2186,7 @@ impl Parse for FeatureTagValue<Integer> {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let tag = FontTag::parse(context, input)?;
|
let tag = FontTag::parse(context, input)?;
|
||||||
let value = input
|
let value = input
|
||||||
.try(|i| parse_one_feature_value(context, i))
|
.try_parse(|i| parse_one_feature_value(context, i))
|
||||||
.unwrap_or_else(|_| Integer::new(1));
|
.unwrap_or_else(|_| Integer::new(1));
|
||||||
|
|
||||||
Ok(Self { tag, value })
|
Ok(Self { tag, value })
|
||||||
|
@ -2307,7 +2323,7 @@ impl Parse for MozScriptLevel {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<MozScriptLevel, ParseError<'i>> {
|
) -> Result<MozScriptLevel, ParseError<'i>> {
|
||||||
// We don't bother to handle calc here.
|
// We don't bother to handle calc here.
|
||||||
if let Ok(i) = input.try(|i| i.expect_integer()) {
|
if let Ok(i) = input.try_parse(|i| i.expect_integer()) {
|
||||||
return Ok(MozScriptLevel::Relative(i));
|
return Ok(MozScriptLevel::Relative(i));
|
||||||
}
|
}
|
||||||
input.expect_ident_matching("auto")?;
|
input.expect_ident_matching("auto")?;
|
||||||
|
|
|
@ -52,11 +52,11 @@ impl Parse for TrackBreadth<LengthPercentage> {
|
||||||
// NonNegativeLengthPercentage instead.
|
// NonNegativeLengthPercentage instead.
|
||||||
//
|
//
|
||||||
// Though it seems these cannot be animated so it's ~ok.
|
// Though it seems these cannot be animated so it's ~ok.
|
||||||
if let Ok(lp) = input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
if let Ok(lp) = input.try_parse(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||||
return Ok(TrackBreadth::Breadth(lp));
|
return Ok(TrackBreadth::Breadth(lp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(f) = input.try(parse_flex) {
|
if let Ok(f) = input.try_parse(parse_flex) {
|
||||||
return Ok(TrackBreadth::Fr(f));
|
return Ok(TrackBreadth::Fr(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,14 +69,17 @@ impl Parse for TrackSize<LengthPercentage> {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(b) = input.try(|i| TrackBreadth::parse(context, i)) {
|
if let Ok(b) = input.try_parse(|i| TrackBreadth::parse(context, i)) {
|
||||||
return Ok(TrackSize::Breadth(b));
|
return Ok(TrackSize::Breadth(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.try(|i| i.expect_function_matching("minmax")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_function_matching("minmax"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return input.parse_nested_block(|input| {
|
return input.parse_nested_block(|input| {
|
||||||
let inflexible_breadth =
|
let inflexible_breadth =
|
||||||
match input.try(|i| LengthPercentage::parse_non_negative(context, i)) {
|
match input.try_parse(|i| LengthPercentage::parse_non_negative(context, i)) {
|
||||||
Ok(lp) => TrackBreadth::Breadth(lp),
|
Ok(lp) => TrackBreadth::Breadth(lp),
|
||||||
Err(..) => TrackBreadth::parse_keyword(input)?,
|
Err(..) => TrackBreadth::parse_keyword(input)?,
|
||||||
};
|
};
|
||||||
|
@ -119,7 +122,7 @@ pub fn parse_line_names<'i, 't>(
|
||||||
input.expect_square_bracket_block()?;
|
input.expect_square_bracket_block()?;
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
while let Ok((loc, ident)) = input.try(|i| -> Result<_, CssParseError<()>> {
|
while let Ok((loc, ident)) = input.try_parse(|i| -> Result<_, CssParseError<()>> {
|
||||||
Ok((i.current_source_location(), i.expect_ident_cloned()?))
|
Ok((i.current_source_location(), i.expect_ident_cloned()?))
|
||||||
}) {
|
}) {
|
||||||
let ident = CustomIdent::from_ident(loc, &ident, &["span", "auto"])?;
|
let ident = CustomIdent::from_ident(loc, &ident, &["span", "auto"])?;
|
||||||
|
@ -150,7 +153,7 @@ impl TrackRepeat<LengthPercentage, Integer> {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<(Self, RepeatType), ParseError<'i>> {
|
) -> Result<(Self, RepeatType), ParseError<'i>> {
|
||||||
input
|
input
|
||||||
.try(|i| i.expect_function_matching("repeat").map_err(|e| e.into()))
|
.try_parse(|i| i.expect_function_matching("repeat").map_err(|e| e.into()))
|
||||||
.and_then(|_| {
|
.and_then(|_| {
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let count = RepeatCount::parse(context, input)?;
|
let count = RepeatCount::parse(context, input)?;
|
||||||
|
@ -169,8 +172,8 @@ impl TrackRepeat<LengthPercentage, Integer> {
|
||||||
let mut current_names;
|
let mut current_names;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
current_names = input.try(parse_line_names).unwrap_or_default();
|
current_names = input.try_parse(parse_line_names).unwrap_or_default();
|
||||||
if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) {
|
if let Ok(track_size) = input.try_parse(|i| TrackSize::parse(context, i)) {
|
||||||
if !track_size.is_fixed() {
|
if !track_size.is_fixed() {
|
||||||
if is_auto {
|
if is_auto {
|
||||||
// should be <fixed-size> for <auto-repeat>
|
// should be <fixed-size> for <auto-repeat>
|
||||||
|
@ -224,8 +227,9 @@ impl Parse for TrackList<LengthPercentage, Integer> {
|
||||||
// assume that everything is <fixed-size>. This flag is useful when we encounter <auto-repeat>
|
// assume that everything is <fixed-size>. This flag is useful when we encounter <auto-repeat>
|
||||||
let mut at_least_one_not_fixed = false;
|
let mut at_least_one_not_fixed = false;
|
||||||
loop {
|
loop {
|
||||||
current_names.extend_from_slice(&mut input.try(parse_line_names).unwrap_or_default());
|
current_names
|
||||||
if let Ok(track_size) = input.try(|i| TrackSize::parse(context, i)) {
|
.extend_from_slice(&mut input.try_parse(parse_line_names).unwrap_or_default());
|
||||||
|
if let Ok(track_size) = input.try_parse(|i| TrackSize::parse(context, i)) {
|
||||||
if !track_size.is_fixed() {
|
if !track_size.is_fixed() {
|
||||||
at_least_one_not_fixed = true;
|
at_least_one_not_fixed = true;
|
||||||
if auto_repeat_index.is_some() {
|
if auto_repeat_index.is_some() {
|
||||||
|
@ -238,7 +242,7 @@ impl Parse for TrackList<LengthPercentage, Integer> {
|
||||||
names.push(vec.into());
|
names.push(vec.into());
|
||||||
values.push(TrackListValue::TrackSize(track_size));
|
values.push(TrackListValue::TrackSize(track_size));
|
||||||
} else if let Ok((repeat, type_)) =
|
} else if let Ok((repeat, type_)) =
|
||||||
input.try(|i| TrackRepeat::parse_with_repeat_type(context, i))
|
input.try_parse(|i| TrackRepeat::parse_with_repeat_type(context, i))
|
||||||
{
|
{
|
||||||
match type_ {
|
match type_ {
|
||||||
RepeatType::Normal => {
|
RepeatType::Normal => {
|
||||||
|
@ -312,7 +316,7 @@ impl Parse for GridTemplateComponent<LengthPercentage, Integer> {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(GridTemplateComponent::None);
|
return Ok(GridTemplateComponent::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,12 +331,15 @@ impl GridTemplateComponent<LengthPercentage, Integer> {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if allow_grid_template_subgrids() {
|
if allow_grid_template_subgrids() {
|
||||||
if let Ok(t) = input.try(|i| LineNameList::parse(context, i)) {
|
if let Ok(t) = input.try_parse(|i| LineNameList::parse(context, i)) {
|
||||||
return Ok(GridTemplateComponent::Subgrid(Box::new(t)));
|
return Ok(GridTemplateComponent::Subgrid(Box::new(t)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if allow_grid_template_masonry() {
|
if allow_grid_template_masonry() {
|
||||||
if input.try(|i| i.expect_ident_matching("masonry")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("masonry"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(GridTemplateComponent::Masonry);
|
return Ok(GridTemplateComponent::Masonry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,24 +132,24 @@ impl Parse for Image {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Image, ParseError<'i>> {
|
) -> Result<Image, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(generic::Image::None);
|
return Ok(generic::Image::None);
|
||||||
}
|
}
|
||||||
if let Ok(url) = input.try(|input| SpecifiedImageUrl::parse(context, input)) {
|
if let Ok(url) = input.try_parse(|input| SpecifiedImageUrl::parse(context, input)) {
|
||||||
return Ok(generic::Image::Url(url));
|
return Ok(generic::Image::Url(url));
|
||||||
}
|
}
|
||||||
if let Ok(gradient) = input.try(|i| Gradient::parse(context, i)) {
|
if let Ok(gradient) = input.try_parse(|i| Gradient::parse(context, i)) {
|
||||||
return Ok(generic::Image::Gradient(Box::new(gradient)));
|
return Ok(generic::Image::Gradient(Box::new(gradient)));
|
||||||
}
|
}
|
||||||
#[cfg(feature = "servo-layout-2013")]
|
#[cfg(feature = "servo-layout-2013")]
|
||||||
{
|
{
|
||||||
if let Ok(paint_worklet) = input.try(|i| PaintWorklet::parse(context, i)) {
|
if let Ok(paint_worklet) = input.try_parse(|i| PaintWorklet::parse(context, i)) {
|
||||||
return Ok(generic::Image::PaintWorklet(paint_worklet));
|
return Ok(generic::Image::PaintWorklet(paint_worklet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if let Ok(image_rect) = input.try(|input| MozImageRect::parse(context, input)) {
|
if let Ok(image_rect) = input.try_parse(|input| MozImageRect::parse(context, input)) {
|
||||||
return Ok(generic::Image::Rect(Box::new(image_rect)));
|
return Ok(generic::Image::Rect(Box::new(image_rect)));
|
||||||
}
|
}
|
||||||
Ok(generic::Image::Element(Image::parse_element(input)?))
|
Ok(generic::Image::Element(Image::parse_element(input)?))
|
||||||
|
@ -171,7 +171,7 @@ impl Image {
|
||||||
/// Parses a `-moz-element(# <element-id>)`.
|
/// Parses a `-moz-element(# <element-id>)`.
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> {
|
fn parse_element<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Atom, ParseError<'i>> {
|
||||||
input.try(|i| i.expect_function_matching("-moz-element"))?;
|
input.try_parse(|i| i.expect_function_matching("-moz-element"))?;
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
input.parse_nested_block(|i| match *i.next()? {
|
input.parse_nested_block(|i| match *i.next()? {
|
||||||
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
Token::IDHash(ref id) => Ok(Atom::from(id.as_ref())),
|
||||||
|
@ -189,7 +189,7 @@ impl Image {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Image, ParseError<'i>> {
|
) -> Result<Image, ParseError<'i>> {
|
||||||
if let Ok(url) =
|
if let Ok(url) =
|
||||||
input.try(|input| SpecifiedImageUrl::parse_with_cors_anonymous(context, input))
|
input.try_parse(|input| SpecifiedImageUrl::parse_with_cors_anonymous(context, input))
|
||||||
{
|
{
|
||||||
return Ok(generic::Image::Url(url));
|
return Ok(generic::Image::Url(url));
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ impl Gradient {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.try(|i| {
|
input.try_parse(|i| {
|
||||||
let x = Component::parse(context, i)?;
|
let x = Component::parse(context, i)?;
|
||||||
let y = Component::parse(context, i)?;
|
let y = Component::parse(context, i)?;
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ impl Gradient {
|
||||||
reverse_stops: bool,
|
reverse_stops: bool,
|
||||||
) -> Result<LengthPercentageItemList, ParseError<'i>> {
|
) -> Result<LengthPercentageItemList, ParseError<'i>> {
|
||||||
let mut items = input
|
let mut items = input
|
||||||
.try(|i| {
|
.try_parse(|i| {
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
i.parse_comma_separated(|i| {
|
i.parse_comma_separated(|i| {
|
||||||
let function = i.expect_function()?.clone();
|
let function = i.expect_function()?.clone();
|
||||||
|
@ -551,18 +551,19 @@ impl Gradient {
|
||||||
repeating: bool,
|
repeating: bool,
|
||||||
mut compat_mode: GradientCompatMode,
|
mut compat_mode: GradientCompatMode,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let direction =
|
let direction = if let Ok(d) =
|
||||||
if let Ok(d) = input.try(|i| LineDirection::parse(context, i, &mut compat_mode)) {
|
input.try_parse(|i| LineDirection::parse(context, i, &mut compat_mode))
|
||||||
input.expect_comma()?;
|
{
|
||||||
d
|
input.expect_comma()?;
|
||||||
} else {
|
d
|
||||||
match compat_mode {
|
} else {
|
||||||
GradientCompatMode::Modern => {
|
match compat_mode {
|
||||||
LineDirection::Vertical(VerticalPositionKeyword::Bottom)
|
GradientCompatMode::Modern => {
|
||||||
},
|
LineDirection::Vertical(VerticalPositionKeyword::Bottom)
|
||||||
_ => LineDirection::Vertical(VerticalPositionKeyword::Top),
|
},
|
||||||
}
|
_ => LineDirection::Vertical(VerticalPositionKeyword::Top),
|
||||||
};
|
}
|
||||||
|
};
|
||||||
let items = Gradient::parse_stops(context, input)?;
|
let items = Gradient::parse_stops(context, input)?;
|
||||||
|
|
||||||
Ok(Gradient::Linear {
|
Ok(Gradient::Linear {
|
||||||
|
@ -582,16 +583,16 @@ impl Gradient {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let (shape, position) = match compat_mode {
|
let (shape, position) = match compat_mode {
|
||||||
GradientCompatMode::Modern => {
|
GradientCompatMode::Modern => {
|
||||||
let shape = input.try(|i| EndingShape::parse(context, i, compat_mode));
|
let shape = input.try_parse(|i| EndingShape::parse(context, i, compat_mode));
|
||||||
let position = input.try(|i| {
|
let position = input.try_parse(|i| {
|
||||||
i.expect_ident_matching("at")?;
|
i.expect_ident_matching("at")?;
|
||||||
Position::parse(context, i)
|
Position::parse(context, i)
|
||||||
});
|
});
|
||||||
(shape, position.ok())
|
(shape, position.ok())
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
let position = input.try(|i| Position::parse(context, i));
|
let position = input.try_parse(|i| Position::parse(context, i));
|
||||||
let shape = input.try(|i| {
|
let shape = input.try_parse(|i| {
|
||||||
if position.is_ok() {
|
if position.is_ok() {
|
||||||
i.expect_comma()?;
|
i.expect_comma()?;
|
||||||
}
|
}
|
||||||
|
@ -626,13 +627,13 @@ impl Gradient {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
repeating: bool,
|
repeating: bool,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let angle = input.try(|i| {
|
let angle = input.try_parse(|i| {
|
||||||
i.expect_ident_matching("from")?;
|
i.expect_ident_matching("from")?;
|
||||||
// Spec allows unitless zero start angles
|
// Spec allows unitless zero start angles
|
||||||
// https://drafts.csswg.org/css-images-4/#valdef-conic-gradient-angle
|
// https://drafts.csswg.org/css-images-4/#valdef-conic-gradient-angle
|
||||||
Angle::parse_with_unitless(context, i)
|
Angle::parse_with_unitless(context, i)
|
||||||
});
|
});
|
||||||
let position = input.try(|i| {
|
let position = input.try_parse(|i| {
|
||||||
i.expect_ident_matching("at")?;
|
i.expect_ident_matching("at")?;
|
||||||
Position::parse(context, i)
|
Position::parse(context, i)
|
||||||
});
|
});
|
||||||
|
@ -713,12 +714,12 @@ impl LineDirection {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
// Gradients allow unitless zero angles as an exception, see:
|
// Gradients allow unitless zero angles as an exception, see:
|
||||||
// https://github.com/w3c/csswg-drafts/issues/1162
|
// https://github.com/w3c/csswg-drafts/issues/1162
|
||||||
if let Ok(angle) = input.try(|i| Angle::parse_with_unitless(context, i)) {
|
if let Ok(angle) = input.try_parse(|i| Angle::parse_with_unitless(context, i)) {
|
||||||
return Ok(LineDirection::Angle(angle));
|
return Ok(LineDirection::Angle(angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
input.try(|i| {
|
input.try_parse(|i| {
|
||||||
let to_ident = i.try(|i| i.expect_ident_matching("to"));
|
let to_ident = i.try_parse(|i| i.expect_ident_matching("to"));
|
||||||
match *compat_mode {
|
match *compat_mode {
|
||||||
// `to` keyword is mandatory in modern syntax.
|
// `to` keyword is mandatory in modern syntax.
|
||||||
GradientCompatMode::Modern => to_ident?,
|
GradientCompatMode::Modern => to_ident?,
|
||||||
|
@ -738,14 +739,14 @@ impl LineDirection {
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(x) = i.try(HorizontalPositionKeyword::parse) {
|
if let Ok(x) = i.try_parse(HorizontalPositionKeyword::parse) {
|
||||||
if let Ok(y) = i.try(VerticalPositionKeyword::parse) {
|
if let Ok(y) = i.try_parse(VerticalPositionKeyword::parse) {
|
||||||
return Ok(LineDirection::Corner(x, y));
|
return Ok(LineDirection::Corner(x, y));
|
||||||
}
|
}
|
||||||
return Ok(LineDirection::Horizontal(x));
|
return Ok(LineDirection::Horizontal(x));
|
||||||
}
|
}
|
||||||
let y = VerticalPositionKeyword::parse(i)?;
|
let y = VerticalPositionKeyword::parse(i)?;
|
||||||
if let Ok(x) = i.try(HorizontalPositionKeyword::parse) {
|
if let Ok(x) = i.try_parse(HorizontalPositionKeyword::parse) {
|
||||||
return Ok(LineDirection::Corner(x, y));
|
return Ok(LineDirection::Corner(x, y));
|
||||||
}
|
}
|
||||||
Ok(LineDirection::Vertical(y))
|
Ok(LineDirection::Vertical(y))
|
||||||
|
@ -759,19 +760,28 @@ impl EndingShape {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
compat_mode: GradientCompatMode,
|
compat_mode: GradientCompatMode,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(extent) = input.try(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode)) {
|
if let Ok(extent) = input.try_parse(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode))
|
||||||
if input.try(|i| i.expect_ident_matching("circle")).is_ok() {
|
{
|
||||||
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("circle"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
||||||
}
|
}
|
||||||
let _ = input.try(|i| i.expect_ident_matching("ellipse"));
|
let _ = input.try_parse(|i| i.expect_ident_matching("ellipse"));
|
||||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(extent)));
|
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(extent)));
|
||||||
}
|
}
|
||||||
if input.try(|i| i.expect_ident_matching("circle")).is_ok() {
|
if input
|
||||||
if let Ok(extent) = input.try(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode)) {
|
.try_parse(|i| i.expect_ident_matching("circle"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
if let Ok(extent) =
|
||||||
|
input.try_parse(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode))
|
||||||
|
{
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
return Ok(generic::EndingShape::Circle(Circle::Extent(extent)));
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
if let Ok(length) = input.try(|i| NonNegativeLength::parse(context, i)) {
|
if let Ok(length) = input.try_parse(|i| NonNegativeLength::parse(context, i)) {
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -779,12 +789,17 @@ impl EndingShape {
|
||||||
ShapeExtent::FarthestCorner,
|
ShapeExtent::FarthestCorner,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if input.try(|i| i.expect_ident_matching("ellipse")).is_ok() {
|
if input
|
||||||
if let Ok(extent) = input.try(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode)) {
|
.try_parse(|i| i.expect_ident_matching("ellipse"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
if let Ok(extent) =
|
||||||
|
input.try_parse(|i| ShapeExtent::parse_with_compat_mode(i, compat_mode))
|
||||||
|
{
|
||||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(extent)));
|
return Ok(generic::EndingShape::Ellipse(Ellipse::Extent(extent)));
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let pair: Result<_, ParseError> = input.try(|i| {
|
let pair: Result<_, ParseError> = input.try_parse(|i| {
|
||||||
let x = NonNegativeLengthPercentage::parse(context, i)?;
|
let x = NonNegativeLengthPercentage::parse(context, i)?;
|
||||||
let y = NonNegativeLengthPercentage::parse(context, i)?;
|
let y = NonNegativeLengthPercentage::parse(context, i)?;
|
||||||
Ok((x, y))
|
Ok((x, y))
|
||||||
|
@ -797,10 +812,10 @@ impl EndingShape {
|
||||||
ShapeExtent::FarthestCorner,
|
ShapeExtent::FarthestCorner,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if let Ok(length) = input.try(|i| NonNegativeLength::parse(context, i)) {
|
if let Ok(length) = input.try_parse(|i| NonNegativeLength::parse(context, i)) {
|
||||||
if let Ok(y) = input.try(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
if let Ok(y) = input.try_parse(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let _ = input.try(|i| i.expect_ident_matching("ellipse"));
|
let _ = input.try_parse(|i| i.expect_ident_matching("ellipse"));
|
||||||
}
|
}
|
||||||
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
return Ok(generic::EndingShape::Ellipse(Ellipse::Radii(
|
||||||
NonNegative(LengthPercentage::from(length.0)),
|
NonNegative(LengthPercentage::from(length.0)),
|
||||||
|
@ -808,7 +823,7 @@ impl EndingShape {
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let y = input.try(|i| {
|
let y = input.try_parse(|i| {
|
||||||
i.expect_ident_matching("ellipse")?;
|
i.expect_ident_matching("ellipse")?;
|
||||||
NonNegativeLengthPercentage::parse(context, i)
|
NonNegativeLengthPercentage::parse(context, i)
|
||||||
});
|
});
|
||||||
|
@ -818,16 +833,16 @@ impl EndingShape {
|
||||||
y,
|
y,
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
let _ = input.try(|i| i.expect_ident_matching("circle"));
|
let _ = input.try_parse(|i| i.expect_ident_matching("circle"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
return Ok(generic::EndingShape::Circle(Circle::Radius(length)));
|
||||||
}
|
}
|
||||||
input.try(|i| {
|
input.try_parse(|i| {
|
||||||
let x = Percentage::parse_non_negative(context, i)?;
|
let x = Percentage::parse_non_negative(context, i)?;
|
||||||
let y = if let Ok(y) = i.try(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
let y = if let Ok(y) = i.try_parse(|i| NonNegativeLengthPercentage::parse(context, i)) {
|
||||||
if compat_mode == GradientCompatMode::Modern {
|
if compat_mode == GradientCompatMode::Modern {
|
||||||
let _ = i.try(|i| i.expect_ident_matching("ellipse"));
|
let _ = i.try_parse(|i| i.expect_ident_matching("ellipse"));
|
||||||
}
|
}
|
||||||
y
|
y
|
||||||
} else {
|
} else {
|
||||||
|
@ -875,7 +890,7 @@ impl<T> generic::GradientItem<Color, T> {
|
||||||
loop {
|
loop {
|
||||||
input.parse_until_before(Delimiter::Comma, |input| {
|
input.parse_until_before(Delimiter::Comma, |input| {
|
||||||
if seen_stop {
|
if seen_stop {
|
||||||
if let Ok(hint) = input.try(|i| parse_position(context, i)) {
|
if let Ok(hint) = input.try_parse(|i| parse_position(context, i)) {
|
||||||
seen_stop = false;
|
seen_stop = false;
|
||||||
items.push(generic::GradientItem::InterpolationHint(hint));
|
items.push(generic::GradientItem::InterpolationHint(hint));
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -884,7 +899,7 @@ impl<T> generic::GradientItem<Color, T> {
|
||||||
|
|
||||||
let stop = generic::ColorStop::parse(context, input, parse_position)?;
|
let stop = generic::ColorStop::parse(context, input, parse_position)?;
|
||||||
|
|
||||||
if let Ok(multi_position) = input.try(|i| parse_position(context, i)) {
|
if let Ok(multi_position) = input.try_parse(|i| parse_position(context, i)) {
|
||||||
let stop_color = stop.color.clone();
|
let stop_color = stop.color.clone();
|
||||||
items.push(stop.into_item());
|
items.push(stop.into_item());
|
||||||
items.push(
|
items.push(
|
||||||
|
@ -927,7 +942,7 @@ impl<T> generic::ColorStop<Color, T> {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
Ok(generic::ColorStop {
|
Ok(generic::ColorStop {
|
||||||
color: Color::parse(context, input)?,
|
color: Color::parse(context, input)?,
|
||||||
position: input.try(|i| parse_position(context, i)).ok(),
|
position: input.try_parse(|i| parse_position(context, i)).ok(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -941,7 +956,7 @@ impl Parse for PaintWorklet {
|
||||||
input.parse_nested_block(|input| {
|
input.parse_nested_block(|input| {
|
||||||
let name = Atom::from(&**input.expect_ident()?);
|
let name = Atom::from(&**input.expect_ident()?);
|
||||||
let arguments = input
|
let arguments = input
|
||||||
.try(|input| {
|
.try_parse(|input| {
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
input.parse_comma_separated(|input| SpecifiedValue::parse(input))
|
input.parse_comma_separated(|input| SpecifiedValue::parse(input))
|
||||||
})
|
})
|
||||||
|
@ -965,7 +980,7 @@ impl Parse for MozImageRect {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
input.try(|i| i.expect_function_matching("-moz-image-rect"))?;
|
input.try_parse(|i| i.expect_function_matching("-moz-image-rect"))?;
|
||||||
input.parse_nested_block(|i| {
|
input.parse_nested_block(|i| {
|
||||||
let string = i.expect_url_or_string()?;
|
let string = i.expect_url_or_string()?;
|
||||||
let url = SpecifiedImageUrl::parse_from_string(
|
let url = SpecifiedImageUrl::parse_from_string(
|
||||||
|
|
|
@ -1226,12 +1226,12 @@ impl Size {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if let Ok(l) = input.try(computed::ExtremumLength::parse) {
|
if let Ok(l) = input.try_parse(computed::ExtremumLength::parse) {
|
||||||
return Ok(GenericSize::ExtremumLength(l));
|
return Ok(GenericSize::ExtremumLength(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||||
return Ok(GenericSize::Auto);
|
return Ok(GenericSize::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1267,12 +1267,12 @@ impl MaxSize {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
#[cfg(feature = "gecko")]
|
#[cfg(feature = "gecko")]
|
||||||
{
|
{
|
||||||
if let Ok(l) = input.try(computed::ExtremumLength::parse) {
|
if let Ok(l) = input.try_parse(computed::ExtremumLength::parse) {
|
||||||
return Ok(GenericMaxSize::ExtremumLength(l));
|
return Ok(GenericMaxSize::ExtremumLength(l));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(GenericMaxSize::None);
|
return Ok(GenericMaxSize::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,10 +75,10 @@ impl Parse for ListStyleType {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(style) = input.try(|i| CounterStyle::parse(context, i)) {
|
if let Ok(style) = input.try_parse(|i| CounterStyle::parse(context, i)) {
|
||||||
return Ok(ListStyleType::CounterStyle(style));
|
return Ok(ListStyleType::CounterStyle(style));
|
||||||
}
|
}
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(ListStyleType::None);
|
return Ok(ListStyleType::None);
|
||||||
}
|
}
|
||||||
Ok(ListStyleType::String(
|
Ok(ListStyleType::String(
|
||||||
|
@ -155,14 +155,14 @@ impl Parse for Quotes {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Quotes, ParseError<'i>> {
|
) -> Result<Quotes, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("auto"))
|
.try_parse(|input| input.expect_ident_matching("auto"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(Quotes::Auto);
|
return Ok(Quotes::Auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(Quotes::QuoteList(QuoteList::default()));
|
return Ok(Quotes::QuoteList(QuoteList::default()));
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub use self::effects::{BoxShadow, Filter, SimpleShadow};
|
||||||
pub use self::flex::FlexBasis;
|
pub use self::flex::FlexBasis;
|
||||||
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle};
|
pub use self::font::{FontFamily, FontLanguageOverride, FontStyle};
|
||||||
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
|
pub use self::font::{FontFeatureSettings, FontVariantLigatures, FontVariantNumeric};
|
||||||
pub use self::font::{FontSize, FontSizeAdjust, FontStretch, FontSynthesis};
|
pub use self::font::{FontSize, FontSizeAdjust, FontSizeKeyword, FontStretch, FontSynthesis};
|
||||||
pub use self::font::{FontVariantAlternates, FontWeight};
|
pub use self::font::{FontVariantAlternates, FontWeight};
|
||||||
pub use self::font::{FontVariantEastAsian, FontVariationSettings};
|
pub use self::font::{FontVariantEastAsian, FontVariationSettings};
|
||||||
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
pub use self::font::{MozScriptLevel, MozScriptMinSize, MozScriptSizeMultiplier, XLang, XTextZoom};
|
||||||
|
@ -148,7 +148,7 @@ impl AngleOrPercentage {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_unitless_zero: AllowUnitlessZeroAngle,
|
allow_unitless_zero: AllowUnitlessZeroAngle,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(per) = input.try(|i| Percentage::parse(context, i)) {
|
if let Ok(per) = input.try_parse(|i| Percentage::parse(context, i)) {
|
||||||
return Ok(AngleOrPercentage::Percentage(per));
|
return Ok(AngleOrPercentage::Percentage(per));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +431,9 @@ impl NumberOrPercentage {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
type_: AllowedNumericType,
|
type_: AllowedNumericType,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(per) = input.try(|i| Percentage::parse_with_clamping_mode(context, i, type_)) {
|
if let Ok(per) =
|
||||||
|
input.try_parse(|i| Percentage::parse_with_clamping_mode(context, i, type_))
|
||||||
|
{
|
||||||
return Ok(NumberOrPercentage::Percentage(per));
|
return Ok(NumberOrPercentage::Percentage(per));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +752,7 @@ impl ClipRect {
|
||||||
let bottom;
|
let bottom;
|
||||||
let left;
|
let left;
|
||||||
|
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
right = parse_argument(context, input, allow_quirks)?;
|
right = parse_argument(context, input, allow_quirks)?;
|
||||||
input.expect_comma()?;
|
input.expect_comma()?;
|
||||||
bottom = parse_argument(context, input, allow_quirks)?;
|
bottom = parse_argument(context, input, allow_quirks)?;
|
||||||
|
@ -782,7 +784,7 @@ impl ClipRectOrAuto {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(v) = input.try(|i| ClipRect::parse_quirky(context, i, allow_quirks)) {
|
if let Ok(v) = input.try_parse(|i| ClipRect::parse_quirky(context, i, allow_quirks)) {
|
||||||
return Ok(generics::GenericClipRectOrAuto::Rect(v));
|
return Ok(generics::GenericClipRectOrAuto::Rect(v));
|
||||||
}
|
}
|
||||||
input.expect_ident_matching("auto")?;
|
input.expect_ident_matching("auto")?;
|
||||||
|
@ -866,8 +868,8 @@ impl Attr {
|
||||||
) -> Result<Attr, ParseError<'i>> {
|
) -> Result<Attr, ParseError<'i>> {
|
||||||
// Syntax is `[namespace? `|`]? ident`
|
// Syntax is `[namespace? `|`]? ident`
|
||||||
// no spaces allowed
|
// no spaces allowed
|
||||||
let first = input.try(|i| i.expect_ident_cloned()).ok();
|
let first = input.try_parse(|i| i.expect_ident_cloned()).ok();
|
||||||
if let Ok(token) = input.try(|i| i.next_including_whitespace().map(|t| t.clone())) {
|
if let Ok(token) = input.try_parse(|i| i.next_including_whitespace().map(|t| t.clone())) {
|
||||||
match token {
|
match token {
|
||||||
Token::Delim('|') => {
|
Token::Delim('|') => {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
|
|
|
@ -39,18 +39,20 @@ impl Parse for RayFunction<Angle> {
|
||||||
let mut contain = false;
|
let mut contain = false;
|
||||||
loop {
|
loop {
|
||||||
if angle.is_none() {
|
if angle.is_none() {
|
||||||
angle = input.try(|i| Angle::parse(context, i)).ok();
|
angle = input.try_parse(|i| Angle::parse(context, i)).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
if size.is_none() {
|
if size.is_none() {
|
||||||
size = input.try(RaySize::parse).ok();
|
size = input.try_parse(RaySize::parse).ok();
|
||||||
if size.is_some() {
|
if size.is_some() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !contain {
|
if !contain {
|
||||||
contain = input.try(|i| i.expect_ident_matching("contain")).is_ok();
|
contain = input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("contain"))
|
||||||
|
.is_ok();
|
||||||
if contain {
|
if contain {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +78,7 @@ impl Parse for OffsetPath {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
// Parse none.
|
// Parse none.
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(OffsetPath::none());
|
return Ok(OffsetPath::none());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,12 +168,12 @@ impl Parse for OffsetRotate {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let mut direction = input.try(OffsetRotateDirection::parse);
|
let mut direction = input.try_parse(OffsetRotateDirection::parse);
|
||||||
let angle = input.try(|i| Angle::parse(context, i));
|
let angle = input.try_parse(|i| Angle::parse(context, i));
|
||||||
if direction.is_err() {
|
if direction.is_err() {
|
||||||
// The direction and angle could be any order, so give it a change to parse
|
// The direction and angle could be any order, so give it a change to parse
|
||||||
// direction again.
|
// direction again.
|
||||||
direction = input.try(OffsetRotateDirection::parse);
|
direction = input.try_parse(OffsetRotateDirection::parse);
|
||||||
}
|
}
|
||||||
|
|
||||||
if direction.is_err() && angle.is_err() {
|
if direction.is_err() && angle.is_err() {
|
||||||
|
|
|
@ -56,7 +56,7 @@ impl Parse for OutlineStyle {
|
||||||
_context: &ParserContext,
|
_context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<OutlineStyle, ParseError<'i>> {
|
) -> Result<OutlineStyle, ParseError<'i>> {
|
||||||
if let Ok(border_style) = input.try(BorderStyle::parse) {
|
if let Ok(border_style) = input.try_parse(BorderStyle::parse) {
|
||||||
if let BorderStyle::Hidden = border_style {
|
if let BorderStyle::Hidden = border_style {
|
||||||
return Err(input
|
return Err(input
|
||||||
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
.new_custom_error(SelectorParseErrorKind::UnexpectedIdent("hidden".into())));
|
||||||
|
|
|
@ -116,28 +116,31 @@ impl Position {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
match input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
match input.try_parse(|i| PositionComponent::parse_quirky(context, i, allow_quirks)) {
|
||||||
Ok(x_pos @ PositionComponent::Center) => {
|
Ok(x_pos @ PositionComponent::Center) => {
|
||||||
if let Ok(y_pos) =
|
if let Ok(y_pos) =
|
||||||
input.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
input.try_parse(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
||||||
{
|
{
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
}
|
}
|
||||||
let x_pos = input
|
let x_pos = input
|
||||||
.try(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
.try_parse(|i| PositionComponent::parse_quirky(context, i, allow_quirks))
|
||||||
.unwrap_or(x_pos);
|
.unwrap_or(x_pos);
|
||||||
let y_pos = PositionComponent::Center;
|
let y_pos = PositionComponent::Center;
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
},
|
},
|
||||||
Ok(PositionComponent::Side(x_keyword, lp)) => {
|
Ok(PositionComponent::Side(x_keyword, lp)) => {
|
||||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("center"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
let x_pos = PositionComponent::Side(x_keyword, lp);
|
let x_pos = PositionComponent::Side(x_keyword, lp);
|
||||||
let y_pos = PositionComponent::Center;
|
let y_pos = PositionComponent::Center;
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
}
|
}
|
||||||
if let Ok(y_keyword) = input.try(VerticalPositionKeyword::parse) {
|
if let Ok(y_keyword) = input.try_parse(VerticalPositionKeyword::parse) {
|
||||||
let y_lp = input
|
let y_lp = input
|
||||||
.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
.ok();
|
.ok();
|
||||||
let x_pos = PositionComponent::Side(x_keyword, lp);
|
let x_pos = PositionComponent::Side(x_keyword, lp);
|
||||||
let y_pos = PositionComponent::Side(y_keyword, y_lp);
|
let y_pos = PositionComponent::Side(y_keyword, y_lp);
|
||||||
|
@ -148,30 +151,30 @@ impl Position {
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
},
|
},
|
||||||
Ok(x_pos @ PositionComponent::Length(_)) => {
|
Ok(x_pos @ PositionComponent::Length(_)) => {
|
||||||
if let Ok(y_keyword) = input.try(VerticalPositionKeyword::parse) {
|
if let Ok(y_keyword) = input.try_parse(VerticalPositionKeyword::parse) {
|
||||||
let y_pos = PositionComponent::Side(y_keyword, None);
|
let y_pos = PositionComponent::Side(y_keyword, None);
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
}
|
}
|
||||||
if let Ok(y_lp) =
|
if let Ok(y_lp) =
|
||||||
input.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
input.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
{
|
{
|
||||||
let y_pos = PositionComponent::Length(y_lp);
|
let y_pos = PositionComponent::Length(y_lp);
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
}
|
}
|
||||||
let y_pos = PositionComponent::Center;
|
let y_pos = PositionComponent::Center;
|
||||||
let _ = input.try(|i| i.expect_ident_matching("center"));
|
let _ = input.try_parse(|i| i.expect_ident_matching("center"));
|
||||||
return Ok(Self::new(x_pos, y_pos));
|
return Ok(Self::new(x_pos, y_pos));
|
||||||
},
|
},
|
||||||
Err(_) => {},
|
Err(_) => {},
|
||||||
}
|
}
|
||||||
let y_keyword = VerticalPositionKeyword::parse(input)?;
|
let y_keyword = VerticalPositionKeyword::parse(input)?;
|
||||||
let lp_and_x_pos: Result<_, ParseError> = input.try(|i| {
|
let lp_and_x_pos: Result<_, ParseError> = input.try_parse(|i| {
|
||||||
let y_lp = i
|
let y_lp = i
|
||||||
.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
.ok();
|
.ok();
|
||||||
if let Ok(x_keyword) = i.try(HorizontalPositionKeyword::parse) {
|
if let Ok(x_keyword) = i.try_parse(HorizontalPositionKeyword::parse) {
|
||||||
let x_lp = i
|
let x_lp = i
|
||||||
.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
.ok();
|
.ok();
|
||||||
let x_pos = PositionComponent::Side(x_keyword, x_lp);
|
let x_pos = PositionComponent::Side(x_keyword, x_lp);
|
||||||
return Ok((y_lp, x_pos));
|
return Ok((y_lp, x_pos));
|
||||||
|
@ -250,15 +253,20 @@ impl<S: Parse> PositionComponent<S> {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
allow_quirks: AllowQuirks,
|
allow_quirks: AllowQuirks,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("center"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(PositionComponent::Center);
|
return Ok(PositionComponent::Center);
|
||||||
}
|
}
|
||||||
if let Ok(lp) = input.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks)) {
|
if let Ok(lp) =
|
||||||
|
input.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
|
{
|
||||||
return Ok(PositionComponent::Length(lp));
|
return Ok(PositionComponent::Length(lp));
|
||||||
}
|
}
|
||||||
let keyword = S::parse(context, input)?;
|
let keyword = S::parse(context, input)?;
|
||||||
let lp = input
|
let lp = input
|
||||||
.try(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
.try_parse(|i| LengthPercentage::parse_quirky(context, i, allow_quirks))
|
||||||
.ok();
|
.ok();
|
||||||
Ok(PositionComponent::Side(keyword, lp))
|
Ok(PositionComponent::Side(keyword, lp))
|
||||||
}
|
}
|
||||||
|
@ -730,7 +738,7 @@ impl Parse for TemplateAreas {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut strings = vec![];
|
let mut strings = vec![];
|
||||||
while let Ok(string) =
|
while let Ok(string) =
|
||||||
input.try(|i| i.expect_string().map(|s| s.as_ref().to_owned().into()))
|
input.try_parse(|i| i.expect_string().map(|s| s.as_ref().to_owned().into()))
|
||||||
{
|
{
|
||||||
strings.push(string);
|
strings.push(string);
|
||||||
}
|
}
|
||||||
|
@ -889,10 +897,10 @@ impl Parse for AspectRatio {
|
||||||
use crate::values::generics::position::PreferredRatio;
|
use crate::values::generics::position::PreferredRatio;
|
||||||
|
|
||||||
let location = input.current_source_location();
|
let location = input.current_source_location();
|
||||||
let mut auto = input.try(|i| i.expect_ident_matching("auto"));
|
let mut auto = input.try_parse(|i| i.expect_ident_matching("auto"));
|
||||||
let ratio = input.try(|i| Ratio::parse(context, i));
|
let ratio = input.try_parse(|i| Ratio::parse(context, i));
|
||||||
if auto.is_err() {
|
if auto.is_err() {
|
||||||
auto = input.try(|i| i.expect_ident_matching("auto"));
|
auto = input.try_parse(|i| i.expect_ident_matching("auto"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if auto.is_err() && ratio.is_err() {
|
if auto.is_err() && ratio.is_err() {
|
||||||
|
|
|
@ -87,7 +87,7 @@ impl Parse for SourceSizeOrLength {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(size) = input.try(|input| SourceSize::parse(context, input)) {
|
if let Ok(size) = input.try_parse(|input| SourceSize::parse(context, input)) {
|
||||||
return Ok(SourceSizeOrLength::SourceSize(size));
|
return Ok(SourceSizeOrLength::SourceSize(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,8 @@ macro_rules! parse_svg_length {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(lp) = input.try(|i| <$lp>::parse_quirky(context, i, AllowQuirks::Always))
|
if let Ok(lp) =
|
||||||
|
input.try_parse(|i| <$lp>::parse_quirky(context, i, AllowQuirks::Always))
|
||||||
{
|
{
|
||||||
return Ok(generic::SVGLength::LengthPercentage(lp));
|
return Ok(generic::SVGLength::LengthPercentage(lp));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +72,7 @@ impl Parse for SVGStrokeDashArray {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(values) = input.try(|i| {
|
if let Ok(values) = input.try_parse(|i| {
|
||||||
CommaWithSpace::parse(i, |i| {
|
CommaWithSpace::parse(i, |i| {
|
||||||
NonNegativeLengthPercentage::parse_quirky(context, i, AllowQuirks::Always)
|
NonNegativeLengthPercentage::parse_quirky(context, i, AllowQuirks::Always)
|
||||||
})
|
})
|
||||||
|
@ -161,7 +162,7 @@ impl Parse for SVGPaintOrder {
|
||||||
_context: &ParserContext,
|
_context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<SVGPaintOrder, ParseError<'i>> {
|
) -> Result<SVGPaintOrder, ParseError<'i>> {
|
||||||
if let Ok(()) = input.try(|i| i.expect_ident_matching("normal")) {
|
if let Ok(()) = input.try_parse(|i| i.expect_ident_matching("normal")) {
|
||||||
return Ok(SVGPaintOrder::normal());
|
return Ok(SVGPaintOrder::normal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +173,7 @@ impl Parse for SVGPaintOrder {
|
||||||
let mut pos = 0;
|
let mut pos = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let result: Result<_, ParseError> = input.try(|input| {
|
let result: Result<_, ParseError> = input.try_parse(|input| {
|
||||||
try_match_ident_ignore_ascii_case! { input,
|
try_match_ident_ignore_ascii_case! { input,
|
||||||
"fill" => Ok(PaintOrder::Fill),
|
"fill" => Ok(PaintOrder::Fill),
|
||||||
"stroke" => Ok(PaintOrder::Stroke),
|
"stroke" => Ok(PaintOrder::Stroke),
|
||||||
|
|
|
@ -41,11 +41,16 @@ impl Parse for InitialLetter {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("normal")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("normal"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
return Ok(GenericInitialLetter::Normal);
|
return Ok(GenericInitialLetter::Normal);
|
||||||
}
|
}
|
||||||
let size = Number::parse_at_least_one(context, input)?;
|
let size = Number::parse_at_least_one(context, input)?;
|
||||||
let sink = input.try(|i| Integer::parse_positive(context, i)).ok();
|
let sink = input
|
||||||
|
.try_parse(|i| Integer::parse_positive(context, i))
|
||||||
|
.ok();
|
||||||
Ok(GenericInitialLetter::Specified(size, sink))
|
Ok(GenericInitialLetter::Specified(size, sink))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +166,7 @@ impl Parse for TextOverflow {
|
||||||
) -> Result<TextOverflow, ParseError<'i>> {
|
) -> Result<TextOverflow, ParseError<'i>> {
|
||||||
let first = TextOverflowSide::parse(context, input)?;
|
let first = TextOverflowSide::parse(context, input)?;
|
||||||
let second = input
|
let second = input
|
||||||
.try(|input| TextOverflowSide::parse(context, input))
|
.try_parse(|input| TextOverflowSide::parse(context, input))
|
||||||
.ok();
|
.ok();
|
||||||
Ok(TextOverflow { first, second })
|
Ok(TextOverflow { first, second })
|
||||||
}
|
}
|
||||||
|
@ -251,7 +256,7 @@ impl Parse for TextDecorationLine {
|
||||||
// ensure we don't return an error if we don't consume the whole thing
|
// ensure we don't return an error if we don't consume the whole thing
|
||||||
// because we find an invalid identifier or other kind of token.
|
// because we find an invalid identifier or other kind of token.
|
||||||
loop {
|
loop {
|
||||||
let flag: Result<_, ParseError<'i>> = input.try(|input| {
|
let flag: Result<_, ParseError<'i>> = input.try_parse(|input| {
|
||||||
let flag = try_match_ident_ignore_ascii_case! { input,
|
let flag = try_match_ident_ignore_ascii_case! { input,
|
||||||
"none" if result.is_empty() => TextDecorationLine::NONE,
|
"none" if result.is_empty() => TextDecorationLine::NONE,
|
||||||
"underline" => TextDecorationLine::UNDERLINE,
|
"underline" => TextDecorationLine::UNDERLINE,
|
||||||
|
@ -791,22 +796,22 @@ impl Parse for TextEmphasisStyle {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(TextEmphasisStyle::None);
|
return Ok(TextEmphasisStyle::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(s) = input.try(|i| i.expect_string().map(|s| s.as_ref().to_owned())) {
|
if let Ok(s) = input.try_parse(|i| i.expect_string().map(|s| s.as_ref().to_owned())) {
|
||||||
// Handle <string>
|
// Handle <string>
|
||||||
return Ok(TextEmphasisStyle::String(s.into()));
|
return Ok(TextEmphasisStyle::String(s.into()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a pair of keywords
|
// Handle a pair of keywords
|
||||||
let mut shape = input.try(TextEmphasisShapeKeyword::parse).ok();
|
let mut shape = input.try_parse(TextEmphasisShapeKeyword::parse).ok();
|
||||||
let fill = input.try(TextEmphasisFillMode::parse).ok();
|
let fill = input.try_parse(TextEmphasisFillMode::parse).ok();
|
||||||
if shape.is_none() {
|
if shape.is_none() {
|
||||||
shape = input.try(TextEmphasisShapeKeyword::parse).ok();
|
shape = input.try_parse(TextEmphasisShapeKeyword::parse).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
if shape.is_none() && fill.is_none() {
|
if shape.is_none() && fill.is_none() {
|
||||||
|
@ -922,7 +927,7 @@ impl Parse for TextEmphasisPosition {
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if let Ok(horizontal) =
|
if let Ok(horizontal) =
|
||||||
input.try(|input| TextEmphasisHorizontalWritingModeValue::parse(input))
|
input.try_parse(|input| TextEmphasisHorizontalWritingModeValue::parse(input))
|
||||||
{
|
{
|
||||||
let vertical = TextEmphasisVerticalWritingModeValue::parse(input)?;
|
let vertical = TextEmphasisVerticalWritingModeValue::parse(input)?;
|
||||||
Ok(TextEmphasisPosition(horizontal, vertical))
|
Ok(TextEmphasisPosition(horizontal, vertical))
|
||||||
|
|
|
@ -68,7 +68,7 @@ impl Transform {
|
||||||
use style_traits::{Separator, Space};
|
use style_traits::{Separator, Space};
|
||||||
|
|
||||||
if input
|
if input
|
||||||
.try(|input| input.expect_ident_matching("none"))
|
.try_parse(|input| input.expect_ident_matching("none"))
|
||||||
.is_ok()
|
.is_ok()
|
||||||
{
|
{
|
||||||
return Ok(generic::Transform::none());
|
return Ok(generic::Transform::none());
|
||||||
|
@ -137,7 +137,7 @@ impl Transform {
|
||||||
},
|
},
|
||||||
"translate" => {
|
"translate" => {
|
||||||
let sx = specified::LengthPercentage::parse(context, input)?;
|
let sx = specified::LengthPercentage::parse(context, input)?;
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
let sy = specified::LengthPercentage::parse(context, input)?;
|
let sy = specified::LengthPercentage::parse(context, input)?;
|
||||||
Ok(generic::TransformOperation::Translate(sx, sy))
|
Ok(generic::TransformOperation::Translate(sx, sy))
|
||||||
} else {
|
} else {
|
||||||
|
@ -166,7 +166,7 @@ impl Transform {
|
||||||
},
|
},
|
||||||
"scale" => {
|
"scale" => {
|
||||||
let sx = NumberOrPercentage::parse(context, input)?.to_number();
|
let sx = NumberOrPercentage::parse(context, input)?.to_number();
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
let sy = NumberOrPercentage::parse(context, input)?.to_number();
|
let sy = NumberOrPercentage::parse(context, input)?.to_number();
|
||||||
Ok(generic::TransformOperation::Scale(sx, sy))
|
Ok(generic::TransformOperation::Scale(sx, sy))
|
||||||
} else {
|
} else {
|
||||||
|
@ -222,7 +222,7 @@ impl Transform {
|
||||||
},
|
},
|
||||||
"skew" => {
|
"skew" => {
|
||||||
let ax = specified::Angle::parse_with_unitless(context, input)?;
|
let ax = specified::Angle::parse_with_unitless(context, input)?;
|
||||||
if input.try(|input| input.expect_comma()).is_ok() {
|
if input.try_parse(|input| input.expect_comma()).is_ok() {
|
||||||
let ay = specified::Angle::parse_with_unitless(context, input)?;
|
let ay = specified::Angle::parse_with_unitless(context, input)?;
|
||||||
Ok(generic::TransformOperation::Skew(ax, ay))
|
Ok(generic::TransformOperation::Skew(ax, ay))
|
||||||
} else {
|
} else {
|
||||||
|
@ -282,17 +282,17 @@ impl Parse for TransformOrigin {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let parse_depth = |input: &mut Parser| {
|
let parse_depth = |input: &mut Parser| {
|
||||||
input
|
input
|
||||||
.try(|i| Length::parse(context, i))
|
.try_parse(|i| Length::parse(context, i))
|
||||||
.unwrap_or(Length::zero())
|
.unwrap_or(Length::zero())
|
||||||
};
|
};
|
||||||
match input.try(|i| OriginComponent::parse(context, i)) {
|
match input.try_parse(|i| OriginComponent::parse(context, i)) {
|
||||||
Ok(x_origin @ OriginComponent::Center) => {
|
Ok(x_origin @ OriginComponent::Center) => {
|
||||||
if let Ok(y_origin) = input.try(|i| OriginComponent::parse(context, i)) {
|
if let Ok(y_origin) = input.try_parse(|i| OriginComponent::parse(context, i)) {
|
||||||
let depth = parse_depth(input);
|
let depth = parse_depth(input);
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
}
|
}
|
||||||
let y_origin = OriginComponent::Center;
|
let y_origin = OriginComponent::Center;
|
||||||
if let Ok(x_keyword) = input.try(HorizontalPositionKeyword::parse) {
|
if let Ok(x_keyword) = input.try_parse(HorizontalPositionKeyword::parse) {
|
||||||
let x_origin = OriginComponent::Side(x_keyword);
|
let x_origin = OriginComponent::Side(x_keyword);
|
||||||
let depth = parse_depth(input);
|
let depth = parse_depth(input);
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
@ -301,7 +301,7 @@ impl Parse for TransformOrigin {
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
},
|
},
|
||||||
Ok(x_origin) => {
|
Ok(x_origin) => {
|
||||||
if let Ok(y_origin) = input.try(|i| OriginComponent::parse(context, i)) {
|
if let Ok(y_origin) = input.try_parse(|i| OriginComponent::parse(context, i)) {
|
||||||
let depth = parse_depth(input);
|
let depth = parse_depth(input);
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
}
|
}
|
||||||
|
@ -313,12 +313,15 @@ impl Parse for TransformOrigin {
|
||||||
}
|
}
|
||||||
let y_keyword = VerticalPositionKeyword::parse(input)?;
|
let y_keyword = VerticalPositionKeyword::parse(input)?;
|
||||||
let y_origin = OriginComponent::Side(y_keyword);
|
let y_origin = OriginComponent::Side(y_keyword);
|
||||||
if let Ok(x_keyword) = input.try(HorizontalPositionKeyword::parse) {
|
if let Ok(x_keyword) = input.try_parse(HorizontalPositionKeyword::parse) {
|
||||||
let x_origin = OriginComponent::Side(x_keyword);
|
let x_origin = OriginComponent::Side(x_keyword);
|
||||||
let depth = parse_depth(input);
|
let depth = parse_depth(input);
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
}
|
}
|
||||||
if input.try(|i| i.expect_ident_matching("center")).is_ok() {
|
if input
|
||||||
|
.try_parse(|i| i.expect_ident_matching("center"))
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
let x_origin = OriginComponent::Center;
|
let x_origin = OriginComponent::Center;
|
||||||
let depth = parse_depth(input);
|
let depth = parse_depth(input);
|
||||||
return Ok(Self::new(x_origin, y_origin, depth));
|
return Ok(Self::new(x_origin, y_origin, depth));
|
||||||
|
@ -368,7 +371,7 @@ impl Parse for Rotate {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(generic::Rotate::None);
|
return Ok(generic::Rotate::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,9 +379,11 @@ impl Parse for Rotate {
|
||||||
//
|
//
|
||||||
// The rotate axis and angle could be in any order, so we parse angle twice to cover
|
// The rotate axis and angle could be in any order, so we parse angle twice to cover
|
||||||
// two cases. i.e. `<number>{3} <angle>` or `<angle> <number>{3}`
|
// two cases. i.e. `<number>{3} <angle>` or `<angle> <number>{3}`
|
||||||
let angle = input.try(|i| specified::Angle::parse(context, i)).ok();
|
let angle = input
|
||||||
|
.try_parse(|i| specified::Angle::parse(context, i))
|
||||||
|
.ok();
|
||||||
let axis = input
|
let axis = input
|
||||||
.try(|i| {
|
.try_parse(|i| {
|
||||||
Ok(try_match_ident_ignore_ascii_case! { i,
|
Ok(try_match_ident_ignore_ascii_case! { i,
|
||||||
"x" => (Number::new(1.), Number::new(0.), Number::new(0.)),
|
"x" => (Number::new(1.), Number::new(0.), Number::new(0.)),
|
||||||
"y" => (Number::new(0.), Number::new(1.), Number::new(0.)),
|
"y" => (Number::new(0.), Number::new(1.), Number::new(0.)),
|
||||||
|
@ -386,7 +391,7 @@ impl Parse for Rotate {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.or_else(|_: ParseError| -> Result<_, ParseError> {
|
.or_else(|_: ParseError| -> Result<_, ParseError> {
|
||||||
input.try(|i| {
|
input.try_parse(|i| {
|
||||||
Ok((
|
Ok((
|
||||||
Number::parse(context, i)?,
|
Number::parse(context, i)?,
|
||||||
Number::parse(context, i)?,
|
Number::parse(context, i)?,
|
||||||
|
@ -415,13 +420,13 @@ impl Parse for Translate {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(generic::Translate::None);
|
return Ok(generic::Translate::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tx = specified::LengthPercentage::parse(context, input)?;
|
let tx = specified::LengthPercentage::parse(context, input)?;
|
||||||
if let Ok(ty) = input.try(|i| specified::LengthPercentage::parse(context, i)) {
|
if let Ok(ty) = input.try_parse(|i| specified::LengthPercentage::parse(context, i)) {
|
||||||
if let Ok(tz) = input.try(|i| specified::Length::parse(context, i)) {
|
if let Ok(tz) = input.try_parse(|i| specified::Length::parse(context, i)) {
|
||||||
// 'translate: <length-percentage> <length-percentage> <length>'
|
// 'translate: <length-percentage> <length-percentage> <length>'
|
||||||
return Ok(generic::Translate::Translate(tx, ty, tz));
|
return Ok(generic::Translate::Translate(tx, ty, tz));
|
||||||
}
|
}
|
||||||
|
@ -454,14 +459,14 @@ impl Parse for Scale {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("none")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("none")).is_ok() {
|
||||||
return Ok(generic::Scale::None);
|
return Ok(generic::Scale::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
let sx = NumberOrPercentage::parse(context, input)?.to_number();
|
let sx = NumberOrPercentage::parse(context, input)?.to_number();
|
||||||
if let Ok(sy) = input.try(|i| NumberOrPercentage::parse(context, i)) {
|
if let Ok(sy) = input.try_parse(|i| NumberOrPercentage::parse(context, i)) {
|
||||||
let sy = sy.to_number();
|
let sy = sy.to_number();
|
||||||
if let Ok(sz) = input.try(|i| NumberOrPercentage::parse(context, i)) {
|
if let Ok(sz) = input.try_parse(|i| NumberOrPercentage::parse(context, i)) {
|
||||||
// 'scale: <number> <number> <number>'
|
// 'scale: <number> <number> <number>'
|
||||||
return Ok(generic::Scale::Scale(sx, sy, sz.to_number()));
|
return Ok(generic::Scale::Scale(sx, sy, sz.to_number()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ impl Parse for Cursor {
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
let mut images = vec![];
|
let mut images = vec![];
|
||||||
loop {
|
loop {
|
||||||
match input.try(|input| CursorImage::parse(context, input)) {
|
match input.try_parse(|input| CursorImage::parse(context, input)) {
|
||||||
Ok(image) => images.push(image),
|
Ok(image) => images.push(image),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ impl Parse for CursorImage {
|
||||||
let mut hotspot_x = Number::zero();
|
let mut hotspot_x = Number::zero();
|
||||||
let mut hotspot_y = Number::zero();
|
let mut hotspot_y = Number::zero();
|
||||||
|
|
||||||
if let Ok(x) = input.try(|input| Number::parse(context, input)) {
|
if let Ok(x) = input.try_parse(|input| Number::parse(context, input)) {
|
||||||
has_hotspot = true;
|
has_hotspot = true;
|
||||||
hotspot_x = x;
|
hotspot_x = x;
|
||||||
hotspot_y = Number::parse(context, input)?;
|
hotspot_y = Number::parse(context, input)?;
|
||||||
|
@ -136,7 +136,7 @@ impl Parse for ScrollbarColor {
|
||||||
context: &ParserContext,
|
context: &ParserContext,
|
||||||
input: &mut Parser<'i, 't>,
|
input: &mut Parser<'i, 't>,
|
||||||
) -> Result<Self, ParseError<'i>> {
|
) -> Result<Self, ParseError<'i>> {
|
||||||
if input.try(|i| i.expect_ident_matching("auto")).is_ok() {
|
if input.try_parse(|i| i.expect_ident_matching("auto")).is_ok() {
|
||||||
return Ok(generics::ScrollbarColor::Auto);
|
return Ok(generics::ScrollbarColor::Auto);
|
||||||
}
|
}
|
||||||
Ok(generics::ScrollbarColor::Colors {
|
Ok(generics::ScrollbarColor::Colors {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue