mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
style: Add basic @container rule parsing and boilerplate
For now parse a MediaFeatureCondition. That needs being made more specific, but that is probably worth its own patch. Differential Revision: https://phabricator.services.mozilla.com/D143192
This commit is contained in:
parent
6755548267
commit
b31ea25848
10 changed files with 134 additions and 6 deletions
|
@ -15,7 +15,7 @@ use crate::gecko_bindings::structs::{
|
||||||
RawServoKeyframesRule, RawServoLayerBlockRule, RawServoLayerStatementRule, RawServoMediaList,
|
RawServoKeyframesRule, RawServoLayerBlockRule, RawServoLayerStatementRule, RawServoMediaList,
|
||||||
RawServoMediaRule, RawServoMozDocumentRule, RawServoNamespaceRule, RawServoPageRule,
|
RawServoMediaRule, RawServoMozDocumentRule, RawServoNamespaceRule, RawServoPageRule,
|
||||||
RawServoScrollTimelineRule, RawServoStyleRule, RawServoStyleSheetContents,
|
RawServoScrollTimelineRule, RawServoStyleRule, RawServoStyleSheetContents,
|
||||||
RawServoSupportsRule, ServoCssRules,
|
RawServoSupportsRule, RawServoContainerRule, ServoCssRules,
|
||||||
};
|
};
|
||||||
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
|
use crate::gecko_bindings::sugar::ownership::{HasArcFFI, HasFFI, Strong};
|
||||||
use crate::media_queries::MediaList;
|
use crate::media_queries::MediaList;
|
||||||
|
@ -26,7 +26,7 @@ use crate::stylesheets::keyframes_rule::Keyframe;
|
||||||
use crate::stylesheets::{
|
use crate::stylesheets::{
|
||||||
CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule, ImportRule,
|
CounterStyleRule, CssRules, DocumentRule, FontFaceRule, FontFeatureValuesRule, ImportRule,
|
||||||
KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule, PageRule,
|
KeyframesRule, LayerBlockRule, LayerStatementRule, MediaRule, NamespaceRule, PageRule,
|
||||||
ScrollTimelineRule, StyleRule, StylesheetContents, SupportsRule,
|
ScrollTimelineRule, StyleRule, StylesheetContents, SupportsRule, ContainerRule,
|
||||||
};
|
};
|
||||||
use servo_arc::{Arc, ArcBorrow};
|
use servo_arc::{Arc, ArcBorrow};
|
||||||
use std::{mem, ptr};
|
use std::{mem, ptr};
|
||||||
|
@ -98,6 +98,9 @@ impl_arc_ffi!(Locked<ScrollTimelineRule> => RawServoScrollTimelineRule
|
||||||
impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
|
impl_arc_ffi!(Locked<SupportsRule> => RawServoSupportsRule
|
||||||
[Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
|
[Servo_SupportsRule_AddRef, Servo_SupportsRule_Release]);
|
||||||
|
|
||||||
|
impl_arc_ffi!(Locked<ContainerRule> => RawServoContainerRule
|
||||||
|
[Servo_ContainerRule_AddRef, Servo_ContainerRule_Release]);
|
||||||
|
|
||||||
impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
|
impl_arc_ffi!(Locked<DocumentRule> => RawServoMozDocumentRule
|
||||||
[Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);
|
[Servo_DocumentRule_AddRef, Servo_DocumentRule_Release]);
|
||||||
|
|
||||||
|
|
|
@ -556,6 +556,7 @@ impl StylesheetInvalidationSet {
|
||||||
FontFace(..) |
|
FontFace(..) |
|
||||||
Keyframes(..) |
|
Keyframes(..) |
|
||||||
ScrollTimeline(..) |
|
ScrollTimeline(..) |
|
||||||
|
Container(..) |
|
||||||
Style(..) => {
|
Style(..) => {
|
||||||
if is_generic_change {
|
if is_generic_change {
|
||||||
// TODO(emilio): We need to do this for selector / keyframe
|
// TODO(emilio): We need to do this for selector / keyframe
|
||||||
|
@ -610,7 +611,7 @@ impl StylesheetInvalidationSet {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Document(..) | Namespace(..) | Import(..) | Media(..) | Supports(..) |
|
Document(..) | Namespace(..) | Import(..) | Media(..) | Supports(..) |
|
||||||
LayerStatement(..) | LayerBlock(..) => {
|
Container(..) | LayerStatement(..) | LayerBlock(..) => {
|
||||||
// Do nothing, relevant nested rules are visited as part of the
|
// Do nothing, relevant nested rules are visited as part of the
|
||||||
// iteration.
|
// iteration.
|
||||||
},
|
},
|
||||||
|
|
79
components/style/stylesheets/container_rule.rs
Normal file
79
components/style/stylesheets/container_rule.rs
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
//! A [`@container`][container] rule.
|
||||||
|
//!
|
||||||
|
//! [container]: https://drafts.csswg.org/css-contain-3/#container-rule
|
||||||
|
|
||||||
|
use crate::media_queries::MediaCondition;
|
||||||
|
use crate::shared_lock::{
|
||||||
|
DeepCloneParams, DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard,
|
||||||
|
};
|
||||||
|
use crate::values::specified::ContainerName;
|
||||||
|
use crate::str::CssStringWriter;
|
||||||
|
use crate::stylesheets::CssRules;
|
||||||
|
use cssparser::SourceLocation;
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
|
||||||
|
use servo_arc::Arc;
|
||||||
|
use std::fmt::{self, Write};
|
||||||
|
use style_traits::{CssWriter, ToCss};
|
||||||
|
|
||||||
|
/// A container rule.
|
||||||
|
#[derive(Debug, ToShmem)]
|
||||||
|
pub struct ContainerRule {
|
||||||
|
/// The container name.
|
||||||
|
pub name: ContainerName,
|
||||||
|
/// The container query.
|
||||||
|
pub condition: ContainerCondition,
|
||||||
|
/// The nested rules inside the block.
|
||||||
|
pub rules: Arc<Locked<CssRules>>,
|
||||||
|
/// The source position where this rule was found.
|
||||||
|
pub source_location: SourceLocation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ContainerRule {
|
||||||
|
/// Measure heap usage.
|
||||||
|
#[cfg(feature = "gecko")]
|
||||||
|
pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
|
||||||
|
// Measurement of other fields may be added later.
|
||||||
|
self.rules.unconditional_shallow_size_of(ops)
|
||||||
|
+ self.rules.read_with(guard).size_of(guard, ops)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DeepCloneWithLock for ContainerRule {
|
||||||
|
fn deep_clone_with_lock(
|
||||||
|
&self,
|
||||||
|
lock: &SharedRwLock,
|
||||||
|
guard: &SharedRwLockReadGuard,
|
||||||
|
params: &DeepCloneParams,
|
||||||
|
) -> Self {
|
||||||
|
let rules = self.rules.read_with(guard);
|
||||||
|
Self {
|
||||||
|
name: self.name.clone(),
|
||||||
|
condition: self.condition.clone(),
|
||||||
|
rules: Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard, params))),
|
||||||
|
source_location: self.source_location.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCssWithGuard for ContainerRule {
|
||||||
|
fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
|
||||||
|
dest.write_str("@container ")?;
|
||||||
|
{
|
||||||
|
let mut writer = CssWriter::new(dest);
|
||||||
|
if !self.name.is_none() {
|
||||||
|
self.name.to_css(&mut writer)?;
|
||||||
|
writer.write_char(' ')?;
|
||||||
|
}
|
||||||
|
self.condition.to_css(&mut writer)?;
|
||||||
|
}
|
||||||
|
self.rules.read_with(guard).to_css_block(guard, dest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO: Factor out the media query code to work with containers.
|
||||||
|
pub type ContainerCondition = MediaCondition;
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! A [`@layer`][layer] urle.
|
//! A [`@layer`][layer] rule.
|
||||||
//!
|
//!
|
||||||
//! [layer]: https://drafts.csswg.org/css-cascade-5/#layering
|
//! [layer]: https://drafts.csswg.org/css-cascade-5/#layering
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
//! An [`@media`][media] urle.
|
//! An [`@media`][media] rule.
|
||||||
//!
|
//!
|
||||||
//! [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media
|
//! [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ use servo_arc::Arc;
|
||||||
use std::fmt::{self, Write};
|
use std::fmt::{self, Write};
|
||||||
use style_traits::{CssWriter, ToCss};
|
use style_traits::{CssWriter, ToCss};
|
||||||
|
|
||||||
/// An [`@media`][media] urle.
|
/// An [`@media`][media] rule.
|
||||||
///
|
///
|
||||||
/// [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media
|
/// [media]: https://drafts.csswg.org/css-conditional/#at-ruledef-media
|
||||||
#[derive(Debug, ToShmem)]
|
#[derive(Debug, ToShmem)]
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub mod font_feature_values_rule;
|
||||||
pub mod import_rule;
|
pub mod import_rule;
|
||||||
pub mod keyframes_rule;
|
pub mod keyframes_rule;
|
||||||
pub mod layer_rule;
|
pub mod layer_rule;
|
||||||
|
pub mod container_rule;
|
||||||
mod loader;
|
mod loader;
|
||||||
mod media_rule;
|
mod media_rule;
|
||||||
mod namespace_rule;
|
mod namespace_rule;
|
||||||
|
@ -53,6 +54,7 @@ pub use self::import_rule::ImportRule;
|
||||||
pub use self::keyframes_rule::KeyframesRule;
|
pub use self::keyframes_rule::KeyframesRule;
|
||||||
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
|
pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
|
||||||
pub use self::loader::StylesheetLoader;
|
pub use self::loader::StylesheetLoader;
|
||||||
|
pub use self::container_rule::ContainerRule;
|
||||||
pub use self::media_rule::MediaRule;
|
pub use self::media_rule::MediaRule;
|
||||||
pub use self::namespace_rule::NamespaceRule;
|
pub use self::namespace_rule::NamespaceRule;
|
||||||
pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter};
|
pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter};
|
||||||
|
@ -253,6 +255,7 @@ pub enum CssRule {
|
||||||
Import(Arc<Locked<ImportRule>>),
|
Import(Arc<Locked<ImportRule>>),
|
||||||
Style(Arc<Locked<StyleRule>>),
|
Style(Arc<Locked<StyleRule>>),
|
||||||
Media(Arc<Locked<MediaRule>>),
|
Media(Arc<Locked<MediaRule>>),
|
||||||
|
Container(Arc<Locked<ContainerRule>>),
|
||||||
FontFace(Arc<Locked<FontFaceRule>>),
|
FontFace(Arc<Locked<FontFaceRule>>),
|
||||||
FontFeatureValues(Arc<Locked<FontFeatureValuesRule>>),
|
FontFeatureValues(Arc<Locked<FontFeatureValuesRule>>),
|
||||||
CounterStyle(Arc<Locked<CounterStyleRule>>),
|
CounterStyle(Arc<Locked<CounterStyleRule>>),
|
||||||
|
@ -287,6 +290,10 @@ impl CssRule {
|
||||||
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
CssRule::Container(ref lock) => {
|
||||||
|
lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
|
||||||
|
},
|
||||||
|
|
||||||
CssRule::FontFace(_) => 0,
|
CssRule::FontFace(_) => 0,
|
||||||
CssRule::FontFeatureValues(_) => 0,
|
CssRule::FontFeatureValues(_) => 0,
|
||||||
CssRule::CounterStyle(_) => 0,
|
CssRule::CounterStyle(_) => 0,
|
||||||
|
@ -344,6 +351,7 @@ pub enum CssRuleType {
|
||||||
LayerBlock = 16,
|
LayerBlock = 16,
|
||||||
LayerStatement = 17,
|
LayerStatement = 17,
|
||||||
ScrollTimeline = 18,
|
ScrollTimeline = 18,
|
||||||
|
Container = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
|
@ -373,6 +381,7 @@ impl CssRule {
|
||||||
CssRule::LayerBlock(_) => CssRuleType::LayerBlock,
|
CssRule::LayerBlock(_) => CssRuleType::LayerBlock,
|
||||||
CssRule::LayerStatement(_) => CssRuleType::LayerStatement,
|
CssRule::LayerStatement(_) => CssRuleType::LayerStatement,
|
||||||
CssRule::ScrollTimeline(_) => CssRuleType::ScrollTimeline,
|
CssRule::ScrollTimeline(_) => CssRuleType::ScrollTimeline,
|
||||||
|
CssRule::Container(_) => CssRuleType::Container,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -460,6 +469,12 @@ impl DeepCloneWithLock for CssRule {
|
||||||
lock.wrap(rule.deep_clone_with_lock(lock, guard, params)),
|
lock.wrap(rule.deep_clone_with_lock(lock, guard, params)),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
|
CssRule::Container(ref arc) => {
|
||||||
|
let rule = arc.read_with(guard);
|
||||||
|
CssRule::Container(Arc::new(
|
||||||
|
lock.wrap(rule.deep_clone_with_lock(lock, guard, params)),
|
||||||
|
))
|
||||||
|
},
|
||||||
CssRule::Media(ref arc) => {
|
CssRule::Media(ref arc) => {
|
||||||
let rule = arc.read_with(guard);
|
let rule = arc.read_with(guard);
|
||||||
CssRule::Media(Arc::new(
|
CssRule::Media(Arc::new(
|
||||||
|
@ -545,6 +560,7 @@ impl ToCssWithGuard for CssRule {
|
||||||
CssRule::LayerBlock(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
CssRule::LayerBlock(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
CssRule::LayerStatement(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
CssRule::LayerStatement(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
CssRule::ScrollTimeline(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
CssRule::ScrollTimeline(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
|
CssRule::Container(ref lock) => lock.read_with(guard).to_css(guard, dest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ use crate::properties::parse_property_declaration_list;
|
||||||
use crate::selector_parser::{SelectorImpl, SelectorParser};
|
use crate::selector_parser::{SelectorImpl, SelectorParser};
|
||||||
use crate::shared_lock::{Locked, SharedRwLock};
|
use crate::shared_lock::{Locked, SharedRwLock};
|
||||||
use crate::str::starts_with_ignore_ascii_case;
|
use crate::str::starts_with_ignore_ascii_case;
|
||||||
|
use crate::stylesheets::container_rule::{ContainerRule, ContainerCondition};
|
||||||
use crate::stylesheets::document_rule::DocumentCondition;
|
use crate::stylesheets::document_rule::DocumentCondition;
|
||||||
use crate::stylesheets::font_feature_values_rule::parse_family_name_list;
|
use crate::stylesheets::font_feature_values_rule::parse_family_name_list;
|
||||||
use crate::stylesheets::import_rule::ImportLayer;
|
use crate::stylesheets::import_rule::ImportLayer;
|
||||||
|
@ -28,6 +29,7 @@ use crate::stylesheets::{
|
||||||
};
|
};
|
||||||
use crate::values::computed::font::FamilyName;
|
use crate::values::computed::font::FamilyName;
|
||||||
use crate::values::{CssUrl, CustomIdent, KeyframesName, TimelineName};
|
use crate::values::{CssUrl, CustomIdent, KeyframesName, TimelineName};
|
||||||
|
use crate::values::specified::ContainerName;
|
||||||
use crate::{Namespace, Prefix};
|
use crate::{Namespace, Prefix};
|
||||||
use cssparser::{
|
use cssparser::{
|
||||||
AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, Parser, ParserState,
|
AtRuleParser, BasicParseError, BasicParseErrorKind, CowRcStr, Parser, ParserState,
|
||||||
|
@ -162,6 +164,8 @@ pub enum AtRulePrelude {
|
||||||
CounterStyle(CustomIdent),
|
CounterStyle(CustomIdent),
|
||||||
/// A @media rule prelude, with its media queries.
|
/// A @media rule prelude, with its media queries.
|
||||||
Media(Arc<Locked<MediaList>>),
|
Media(Arc<Locked<MediaList>>),
|
||||||
|
/// A @container rule prelude.
|
||||||
|
Container(ContainerName, ContainerCondition),
|
||||||
/// An @supports rule, with its conditional
|
/// An @supports rule, with its conditional
|
||||||
Supports(SupportsCondition),
|
Supports(SupportsCondition),
|
||||||
/// A @viewport rule prelude.
|
/// A @viewport rule prelude.
|
||||||
|
@ -433,6 +437,15 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
"font-face" => {
|
"font-face" => {
|
||||||
AtRulePrelude::FontFace
|
AtRulePrelude::FontFace
|
||||||
},
|
},
|
||||||
|
"container" if static_prefs::pref!("layout.css.container-queries.enabled") => {
|
||||||
|
// FIXME: This is a bit ambiguous:
|
||||||
|
// https://github.com/w3c/csswg-drafts/issues/7203
|
||||||
|
let name = input.try_parse(|input| {
|
||||||
|
ContainerName::parse(self.context, input)
|
||||||
|
}).ok().unwrap_or_else(ContainerName::none);
|
||||||
|
let condition = ContainerCondition::parse(self.context, input)?;
|
||||||
|
AtRulePrelude::Container(name, condition)
|
||||||
|
},
|
||||||
"layer" => {
|
"layer" => {
|
||||||
let names = input.try_parse(|input| {
|
let names = input.try_parse(|input| {
|
||||||
input.parse_comma_separated(|input| {
|
input.parse_comma_separated(|input| {
|
||||||
|
@ -614,6 +627,16 @@ impl<'a, 'b, 'i> AtRuleParser<'i> for NestedRuleParser<'a, 'b> {
|
||||||
},
|
},
|
||||||
))))
|
))))
|
||||||
},
|
},
|
||||||
|
AtRulePrelude::Container(name, condition) => {
|
||||||
|
Ok(CssRule::Container(Arc::new(self.shared_lock.wrap(
|
||||||
|
ContainerRule {
|
||||||
|
name,
|
||||||
|
condition,
|
||||||
|
rules: self.parse_nested_rules(input, CssRuleType::Container),
|
||||||
|
source_location: start.source_location(),
|
||||||
|
},
|
||||||
|
))))
|
||||||
|
},
|
||||||
AtRulePrelude::Layer(names) => {
|
AtRulePrelude::Layer(names) => {
|
||||||
let name = match names.len() {
|
let name = match names.len() {
|
||||||
0 | 1 => names.into_iter().next(),
|
0 | 1 => names.into_iter().next(),
|
||||||
|
|
|
@ -88,6 +88,10 @@ where
|
||||||
}
|
}
|
||||||
Some(doc_rule.rules.read_with(guard).0.iter())
|
Some(doc_rule.rules.read_with(guard).0.iter())
|
||||||
},
|
},
|
||||||
|
CssRule::Container(ref lock) => {
|
||||||
|
let container_rule = lock.read_with(guard);
|
||||||
|
Some(container_rule.rules.read_with(guard).0.iter())
|
||||||
|
},
|
||||||
CssRule::Media(ref lock) => {
|
CssRule::Media(ref lock) => {
|
||||||
let media_rule = lock.read_with(guard);
|
let media_rule = lock.read_with(guard);
|
||||||
if !C::process_media(guard, device, quirks_mode, media_rule) {
|
if !C::process_media(guard, device, quirks_mode, media_rule) {
|
||||||
|
|
|
@ -370,6 +370,7 @@ impl SanitizationKind {
|
||||||
CssRule::Media(..) |
|
CssRule::Media(..) |
|
||||||
CssRule::Supports(..) |
|
CssRule::Supports(..) |
|
||||||
CssRule::Import(..) |
|
CssRule::Import(..) |
|
||||||
|
CssRule::Container(..) |
|
||||||
// TODO(emilio): Perhaps Layer should not be always sanitized? But
|
// TODO(emilio): Perhaps Layer should not be always sanitized? But
|
||||||
// we sanitize @media and co, so this seems safer for now.
|
// we sanitize @media and co, so this seems safer for now.
|
||||||
CssRule::LayerStatement(..) |
|
CssRule::LayerStatement(..) |
|
||||||
|
|
|
@ -2810,6 +2810,7 @@ impl CascadeData {
|
||||||
CssRule::Style(..) |
|
CssRule::Style(..) |
|
||||||
CssRule::Namespace(..) |
|
CssRule::Namespace(..) |
|
||||||
CssRule::FontFace(..) |
|
CssRule::FontFace(..) |
|
||||||
|
CssRule::Container(..) |
|
||||||
CssRule::CounterStyle(..) |
|
CssRule::CounterStyle(..) |
|
||||||
CssRule::Supports(..) |
|
CssRule::Supports(..) |
|
||||||
CssRule::Keyframes(..) |
|
CssRule::Keyframes(..) |
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue