/* 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/. */
//! Types used to report parsing errors.
#![deny(missing_docs)]
usecrate::selector_parser::SelectorImpl; usecrate::stylesheets::UrlExtraData; use cssparser::{BasicParseErrorKind, ParseErrorKind, SourceLocation, Token}; use selectors::parser::{Component, RelativeSelector, Selector}; use selectors::visitor::{SelectorListKind, SelectorVisitor}; use selectors::SelectorList; use std::fmt; use style_traits::ParseError;
/// Errors that can be encountered while parsing CSS. #[derive(Debug)] pubenum ContextualParseError<'a> { /// A property declaration was not recognized.
UnsupportedPropertyDeclaration(&'a str, ParseError<'a>, &tyle='color:blue'>'a [SelectorList<SelectorImpl>]), /// A property descriptor was not recognized.
UnsupportedPropertyDescriptor(&'a str, ParseError<'a>), /// A font face descriptor was not recognized.
UnsupportedFontFaceDescriptor(&'a str, ParseError<'a>), /// A font feature values descriptor was not recognized.
UnsupportedFontFeatureValuesDescriptor(&'a str, ParseError<'a>), /// A font palette values descriptor was not recognized.
UnsupportedFontPaletteValuesDescriptor(&'a str, ParseError<'a>), /// A keyframe rule was not valid.
InvalidKeyframeRule(&'a str, ParseError<'a>), /// A font feature values rule was not valid.
InvalidFontFeatureValuesRule(&'a str, ParseError<'a>), /// A rule was invalid for some reason.
InvalidRule(&'a str, ParseError<'a>), /// A rule was not recognized.
UnsupportedRule(&'a str, ParseError<'a>), /// A viewport descriptor declaration was not recognized.
UnsupportedViewportDescriptorDeclaration(&'a str, ParseError<'a>), /// A counter style descriptor declaration was not recognized.
UnsupportedCounterStyleDescriptorDeclaration(&'a str, ParseError<'a>), /// A counter style rule had no symbols.
InvalidCounterStyleWithoutSymbols(String), /// A counter style rule had less than two symbols.
InvalidCounterStyleNotEnoughSymbols(String), /// A counter style rule did not have additive-symbols.
InvalidCounterStyleWithoutAdditiveSymbols, /// A counter style rule had extends with symbols.
InvalidCounterStyleExtendsWithSymbols, /// A counter style rule had extends with additive-symbols.
InvalidCounterStyleExtendsWithAdditiveSymbols, /// A media rule was invalid for some reason.
InvalidMediaRule(&'a str, ParseError<'a>), /// A value was not recognized.
UnsupportedValue(&'a str, ParseError<'a>), /// A never-matching `:host` selector was found.
NeverMatchingHostSelector(String),
}
/// A generic trait for an error reporter. pubtrait ParseErrorReporter { /// Called when the style engine detects an error. /// /// Returns the current input being parsed, the source location it was /// reported from, and a message. fn report_error(
&self,
url: &UrlExtraData,
location: SourceLocation,
error: ContextualParseError,
);
}
/// Any warning a selector may generate. /// TODO(dshin): Bug 1860634 - Merge with never matching host selector warning, which is part of the rule parser. #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] pubenum SelectorWarningKind { /// Relative Selector with not enough constraint, either outside or inside the selector. e.g. `*:has(.a)`, `.a:has(*)`. /// May cause expensive invalidations for every element inserted and/or removed.
UnconstraintedRelativeSelector,
}
impl SelectorWarningKind { /// Get all warnings for this selector. pubfn from_selector(selector: &Selector<SelectorImpl>) -> Vec<Self> { letmut result = vec![]; if UnconstrainedRelativeSelectorVisitor::has_warning(selector, 0, false) {
result.push(SelectorWarningKind::UnconstraintedRelativeSelector);
}
result
}
}
/// Per-compound state for finding unconstrained relative selectors. struct PerCompoundState { /// Is there a relative selector in this compound?
relative_selector_found: bool, /// Is this compound constrained in any way?
constrained: bool, /// Nested below, or inside relative selector?
in_relative_selector: bool,
}
fn visit_selector_list(
&mutself,
_list_kind: SelectorListKind,
list: &[Selector<Self::Impl>],
) -> bool { letmut all_constrained = true; for s in list { letmut offset = 0; // First, check the rightmost compound for constraint at this level. if !self.compound_state.in_relative_selector { letmut nested = Self::new(false); letmut iter = s.iter(); loop { for c in &mut iter {
c.visit(&mut nested);
offset += 1;
}
let c = iter.next_sequence();
offset += 1; if c.map_or(true, |c| !c.is_pseudo_element()) { break;
}
} // Every single selector in the list must be constrained.
all_constrained &= nested.compound_state.constrained;
}
if offset >= s.len() { continue;
}
// Then, recurse in to check at the deeper level. ifSelf::has_warning(s, offset, self.compound_state.in_relative_selector) { self.compound_state.constrained = false; if !self.compound_state.in_relative_selector { self.compound_state.relative_selector_found = true;
} returnfalse;
}
} self.compound_state.constrained |= all_constrained; true
}
for rs in list { // If the inside is unconstrained, we are unconstrained no matter what. ifSelf::has_warning(&rs.selector, 0, true) { self.compound_state.constrained = false; returnfalse;
}
} true
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet am 2026-06-18)
¤
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.