/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
//! The context within which CSS code is parsed.
usecrate::context::QuirksMode; usecrate::error_reporting::{ContextualParseError, ParseErrorReporter}; usecrate::stylesheets::{CssRuleType, CssRuleTypes, Namespaces, Origin, UrlExtraData}; usecrate::use_counters::UseCounters; use cssparser::{Parser, SourceLocation, UnicodeRange}; use selectors::parser::ParseRelative; use std::borrow::Cow; use style_traits::{OneOrMoreSeparated, ParseError, ParsingMode, Separator};
/// Nesting context for parsing rules. #[derive(Clone, Copy)] pubstruct NestingContext { /// All rule types we've nested into, if any. pub rule_types: CssRuleTypes, /// Whether or not parsing relative selector syntax should be allowed. pub parse_relative: ParseRelative,
}
/// Create a new nesting context based on the given rule. pubfn new_from_rule(rule_type: Option<CssRuleType>) -> Self { Self {
rule_types: rule_type.map(CssRuleTypes::from).unwrap_or_default(),
parse_relative: rule_type
.map(Self::parse_relative_for)
.unwrap_or(ParseRelative::No),
}
}
/// Save the current nesting context. pubfn save(&mutself, rule_type: CssRuleType) -> Self { let old = *self; self.rule_types.insert(rule_type); let new_parse_relative = Self::parse_relative_for(rule_type); if new_parse_relative != ParseRelative::No { self.parse_relative = new_parse_relative;
}
old
}
/// The data that the parser needs from outside in order to parse a stylesheet. pubstruct ParserContext<'a> { /// The `Origin` of the stylesheet, whether it's a user, author or /// user-agent stylesheet. pub stylesheet_origin: Origin, /// The extra data we need for resolving url values. pub url_data: &'a UrlExtraData, /// The mode to use when parsing. pub parsing_mode: ParsingMode, /// The quirks mode of this stylesheet. pub quirks_mode: QuirksMode, /// The active error reporter, or none if error reporting is disabled.
error_reporter: Option<&'a dyn ParseErrorReporter>, /// The currently active namespaces. pub namespaces: Cow<'a, Namespaces>, /// The use counters we want to record while parsing style rules, if any. pub use_counters: Option<&'a UseCounters>, /// Current nesting context. pub nesting_context: NestingContext,
}
/// Temporarily sets the rule_type and executes the callback function, returning its result. pubfn nest_for_rule<R>(
&mutself,
rule_type: CssRuleType,
cb: impl FnOnce(&mutSelf) -> R,
) -> R { let old = self.nesting_context.save(rule_type); let r = cb(self); self.nesting_context.restore(old);
r
}
/// Whether we're in a @page rule. #[inline] pubfn in_page_rule(&self) -> bool { self.nesting_context.rule_types.contains(CssRuleType::Page)
}
/// Whether we're in a user-agent stylesheet. #[inline] pubfn in_ua_sheet(&self) -> bool { self.stylesheet_origin == Origin::UserAgent
}
/// Returns whether chrome-only rules should be parsed. #[inline] pubfn chrome_rules_enabled(&self) -> bool { self.url_data.chrome_rules_enabled() || self.stylesheet_origin != Origin::Author
}
/// Whether the parsing mode allows units or functions that are not computationally independent. #[inline] pubfn allows_computational_dependence(&self) -> bool { self.parsing_mode.allows_computational_dependence()
}
}
/// A trait to abstract parsing of a specified value given a `ParserContext` and /// CSS input. /// /// This can be derived on keywords with `#[derive(Parse)]`. /// /// The derive code understands the following attributes on each of the variants: /// /// * `#[parse(aliases = "foo,bar")]` can be used to alias a value with another /// at parse-time. /// /// * `#[parse(condition = "function")]` can be used to make the parsing of the /// value conditional on `function`, which needs to fulfill /// `fn(&ParserContext) -> bool`. /// /// * `#[parse(parse_fn = "function")]` can be used to specify a function other than Parser::parse /// for a particular variant. pubtrait Parse: Sized { /// Parse a value of this type. /// /// Returns an error on failure. fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>>;
}
impl<T> Parse for Vec<T> where
T: Parse + OneOrMoreSeparated,
<T as OneOrMoreSeparated>::S: Separator,
{ fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
<T as OneOrMoreSeparated>::S::parse(input, |i| T::parse(context, i))
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.