/* 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/. */
use cssparser::{Parser, SourceLocation, Token}; use servo_arc::Arc; use smallvec::SmallVec; use std::fmt::{self, Write}; use style_traits::{CssWriter, ParseError, ToCss};
/// The order of a given layer. We use 16 bits so that we can pack LayerOrder /// and CascadeLevel in a single 32-bit struct. If we need more bits we can go /// back to packing CascadeLevel in a single byte as we did before. #[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, PartialEq, PartialOrd, Ord)] pubstruct LayerOrder(u16);
impl LayerOrder { /// The order of the root layer. pubconstfn root() -> Self { Self(std::u16::MAX - 1)
}
/// The order of the style attribute layer. pubconstfn style_attribute() -> Self { Self(std::u16::MAX)
}
/// Returns whether this layer is for the style attribute, which behaves /// differently in terms of !important, see /// https://github.com/w3c/csswg-drafts/issues/6872 /// /// (This is a bit silly, mind-you, but it's needed so that revert-layer /// behaves correctly). #[inline] pubfn is_style_attribute_layer(&self) -> bool {
*self == Self::style_attribute()
}
/// The first cascade layer order. pubconstfn first() -> Self { Self(0)
}
impl LayerName { /// Returns an empty layer name (which isn't a valid final state, so caller /// is responsible to fill up the name before use). pubfn new_empty() -> Self { Self(Default::default())
}
/// Returns a synthesized name for an anonymous layer. pubfn new_anonymous() -> Self { use std::sync::atomic::{AtomicUsize, Ordering}; static NEXT_ANONYMOUS_LAYER_NAME: AtomicUsize = AtomicUsize::new(0);
letmut name = SmallVec::new(); let next_id = NEXT_ANONYMOUS_LAYER_NAME.fetch_add(1, Ordering::Relaxed); // The parens don't _technically_ prevent conflicts with authors, as // authors could write escaped parens as part of the identifier, I // think, but highly reduces the possibility.
name.push(AtomIdent::from(&*format!("-moz-anon-layer({})", next_id)));
LayerName(name)
}
/// Returns the names of the layers. That is, for a layer like `foo.bar`, /// it'd return [foo, bar]. pubfn layer_names(&self) -> &[AtomIdent] {
&self.0
}
}
impl Parse for LayerName { fn parse<'i, 't>(
_: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> { letmut result = SmallVec::new();
result.push(AtomIdent::from(&**input.expect_ident()?)); loop { let next_name = input.try_parse(|input| -> Result<AtomIdent, ParseError<'i>> { match input.next_including_whitespace()? {
Token::Delim('.') => {},
other => { let t = other.clone(); return Err(input.new_unexpected_token_error(t));
},
}
let name = match input.next_including_whitespace()? {
Token::Ident(ref ident) => ident,
other => { let t = other.clone(); return Err(input.new_unexpected_token_error(t));
},
};
impl ToCss for LayerName { fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result where
W: Write,
{ letmut first = true; for name inself.0.iter() { if !first {
dest.write_char('.')?;
}
first = false;
name.to_css(dest)?;
}
Ok(())
}
}
#[derive(Debug, ToShmem)] /// A block `@layer <name>? { ... }` /// https://drafts.csswg.org/css-cascade-5/#layer-block pubstruct LayerBlockRule { /// The layer name, or `None` if anonymous. pub name: Option<LayerName>, /// The nested rules. pub rules: Arc<Locked<CssRules>>, /// The source position where this rule was found. pub source_location: SourceLocation,
}
/// A statement `@layer <name>, <name>, <name>;` /// /// https://drafts.csswg.org/css-cascade-5/#layer-empty #[derive(Clone, Debug, ToShmem)] pubstruct LayerStatementRule { /// The list of layers to sort. pub names: Vec<LayerName>, /// The source position where this rule was found. pub source_location: SourceLocation,
}
impl ToCssWithGuard for LayerStatementRule { fn to_css(
&self,
_: &SharedRwLockReadGuard,
dest: &mutcrate::str::CssStringWriter,
) -> fmt::Result { letmut writer = CssWriter::new(dest);
writer.write_str("@layer ")?; letmut first = true; for name in &*self.names { if !first {
writer.write_str(", ")?;
}
first = false;
name.to_css(&mut writer)?;
}
writer.write_char(';')
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-06-17)
¤
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.