1mod appearance_base_rule;
8pub mod container_rule;
9mod counter_style_rule;
10mod document_rule;
11mod font_face_rule;
12pub mod font_feature_values_rule;
13pub mod font_palette_values_rule;
14pub mod import_rule;
15pub mod keyframes_rule;
16pub mod layer_rule;
17mod loader;
18mod margin_rule;
19mod media_rule;
20mod namespace_rule;
21mod nested_declarations_rule;
22pub mod origin;
23mod page_rule;
24pub mod position_try_rule;
25mod property_rule;
26mod rule_list;
27mod rule_parser;
28mod rules_iterator;
29pub mod scope_rule;
30mod starting_style_rule;
31mod style_rule;
32mod stylesheet;
33pub mod supports_rule;
34pub mod view_transition_rule;
35
36use crate::derives::*;
37#[cfg(feature = "gecko")]
38use crate::gecko_bindings::sugar::refptr::RefCounted;
39#[cfg(feature = "gecko")]
40use crate::gecko_bindings::{bindings, structs};
41use crate::parser::{NestingContext, ParserContext};
42use crate::properties::{PropertyDeclarationBlock, parse_property_declaration_list};
43use crate::shared_lock::{DeepCloneWithLock, Locked};
44use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard};
45use cssparser::{Parser, parse_one_rule};
46#[cfg(feature = "gecko")]
47use malloc_size_of::{MallocSizeOfOps, MallocUnconditionalShallowSizeOf};
48use servo_arc::Arc;
49use std::borrow::Cow;
50use std::fmt::{self, Write};
51#[cfg(feature = "gecko")]
52use std::mem::{self, ManuallyDrop};
53use style_traits::{CssStringWriter, ParsingMode};
54use to_shmem::{SharedMemoryBuilder, ToShmem};
55
56pub use self::appearance_base_rule::AppearanceBaseRule;
57pub use self::container_rule::ContainerRule;
58pub use self::counter_style_rule::CounterStyleRule;
59pub use self::document_rule::DocumentRule;
60pub use self::font_face_rule::FontFaceRule;
61pub use self::font_feature_values_rule::FontFeatureValuesRule;
62pub use self::font_palette_values_rule::FontPaletteValuesRule;
63pub use self::import_rule::ImportRule;
64pub use self::keyframes_rule::KeyframesRule;
65pub use self::layer_rule::{LayerBlockRule, LayerStatementRule};
66pub use self::loader::StylesheetLoader;
67pub use self::margin_rule::{MarginRule, MarginRuleType};
68pub use self::media_rule::{
69 CustomMediaCondition, CustomMediaEvaluator, CustomMediaMap, CustomMediaRule, MediaRule,
70};
71pub use self::namespace_rule::NamespaceRule;
72pub use self::nested_declarations_rule::NestedDeclarationsRule;
73pub use self::origin::{Origin, OriginSet, OriginSetIterator, PerOrigin, PerOriginIter};
74pub use self::page_rule::{PagePseudoClassFlags, PageRule, PageSelector, PageSelectors};
75pub use self::position_try_rule::PositionTryRule;
76pub use self::property_rule::PropertyRule;
77pub use self::rule_list::CssRules;
78pub use self::rule_parser::{InsertRuleContext, State, TopLevelRuleParser};
79pub use self::rules_iterator::{AllRules, EffectiveRules};
80pub use self::rules_iterator::{
81 EffectiveRulesIterator, NestedRuleIterationCondition, RulesIterator,
82};
83pub use self::scope_rule::ScopeRule;
84pub use self::starting_style_rule::StartingStyleRule;
85pub use self::style_rule::StyleRule;
86pub use self::stylesheet::{AllowImportRules, SanitizationData, SanitizationKind};
87pub use self::stylesheet::{DocumentStyleSheet, Namespaces, Stylesheet};
88pub use self::stylesheet::{StylesheetContents, StylesheetInDocument};
89pub use self::supports_rule::SupportsRule;
90pub use self::view_transition_rule::{NavigationType, ViewTransitionRule};
91
92#[repr(u8)]
94#[derive(Clone, Copy, Debug, Eq, PartialEq, ToShmem)]
95pub enum CorsMode {
96 None,
98 Anonymous,
100}
101
102#[cfg(feature = "gecko")]
116#[derive(MallocSizeOf, PartialEq)]
119#[repr(C)]
120pub struct UrlExtraData(usize);
121
122#[cfg(feature = "servo")]
124#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq)]
125pub struct UrlExtraData(#[ignore_malloc_size_of = "Arc"] pub Arc<::url::Url>);
126
127#[cfg(feature = "servo")]
128impl UrlExtraData {
129 pub fn chrome_rules_enabled(&self) -> bool {
131 self.0.scheme() == "chrome"
132 }
133
134 pub fn as_str(&self) -> &str {
136 self.0.as_str()
137 }
138}
139
140#[cfg(feature = "servo")]
141impl From<::url::Url> for UrlExtraData {
142 fn from(url: ::url::Url) -> Self {
143 Self(Arc::new(url))
144 }
145}
146
147#[cfg(not(feature = "gecko"))]
148impl ToShmem for UrlExtraData {
149 fn to_shmem(&self, _builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
150 unimplemented!(
151 "If servo wants to share stylesheets across processes, ToShmem for Url must be implemented"
152 );
153 }
154}
155
156#[cfg(feature = "gecko")]
157impl Clone for UrlExtraData {
158 fn clone(&self) -> UrlExtraData {
159 UrlExtraData::new(self.ptr())
160 }
161}
162
163#[cfg(feature = "gecko")]
164impl Drop for UrlExtraData {
165 fn drop(&mut self) {
166 if self.0 & 1 == 0 {
168 unsafe {
169 self.as_ref().release();
170 }
171 }
172 }
173}
174
175#[cfg(feature = "gecko")]
176impl ToShmem for UrlExtraData {
177 fn to_shmem(&self, _builder: &mut SharedMemoryBuilder) -> to_shmem::Result<Self> {
178 if self.0 & 1 == 0 {
179 let shared_extra_datas = unsafe {
180 std::ptr::addr_of!(structs::URLExtraData_sShared)
181 .as_ref()
182 .unwrap()
183 };
184 let self_ptr = self.as_ref() as *const _ as *mut _;
185 let sheet_id = shared_extra_datas
186 .iter()
187 .position(|r| r.mRawPtr == self_ptr);
188 let sheet_id = match sheet_id {
189 Some(id) => id,
190 None => {
191 return Err(String::from(
192 "ToShmem failed for UrlExtraData: expected sheet's URLExtraData to be in \
193 URLExtraData::sShared",
194 ));
195 },
196 };
197 Ok(ManuallyDrop::new(UrlExtraData((sheet_id << 1) | 1)))
198 } else {
199 Ok(ManuallyDrop::new(UrlExtraData(self.0)))
200 }
201 }
202}
203
204#[cfg(feature = "gecko")]
205impl UrlExtraData {
206 pub fn new(ptr: *mut structs::URLExtraData) -> UrlExtraData {
209 unsafe {
210 (*ptr).addref();
211 }
212 UrlExtraData(ptr as usize)
213 }
214
215 #[inline]
217 pub fn chrome_rules_enabled(&self) -> bool {
218 self.as_ref().mChromeRulesEnabled
219 }
220
221 #[inline]
227 pub unsafe fn from_ptr_ref(ptr: &*mut structs::URLExtraData) -> &Self {
228 unsafe { mem::transmute(ptr) }
229 }
230
231 pub fn ptr(&self) -> *mut structs::URLExtraData {
233 if self.0 & 1 == 0 {
234 self.0 as *mut structs::URLExtraData
235 } else {
236 unsafe {
237 let sheet_id = self.0 >> 1;
238 structs::URLExtraData_sShared[sheet_id].mRawPtr
239 }
240 }
241 }
242
243 fn as_ref(&self) -> &structs::URLExtraData {
244 unsafe { &*(self.ptr() as *const structs::URLExtraData) }
245 }
246}
247
248#[cfg(feature = "gecko")]
249impl fmt::Debug for UrlExtraData {
250 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
251 macro_rules! define_debug_struct {
252 ($struct_name:ident, $gecko_class:ident, $debug_fn:ident) => {
253 struct $struct_name(*mut structs::$gecko_class);
254 impl fmt::Debug for $struct_name {
255 fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
256 use nsstring::nsCString;
257 let mut spec = nsCString::new();
258 unsafe {
259 bindings::$debug_fn(self.0, &mut spec);
260 }
261 spec.fmt(formatter)
262 }
263 }
264 };
265 }
266
267 define_debug_struct!(DebugURI, nsIURI, Gecko_nsIURI_Debug);
268 define_debug_struct!(
269 DebugReferrerInfo,
270 nsIReferrerInfo,
271 Gecko_nsIReferrerInfo_Debug
272 );
273
274 formatter
275 .debug_struct("URLExtraData")
276 .field("chrome_rules_enabled", &self.chrome_rules_enabled())
277 .field("base", &DebugURI(self.as_ref().mBaseURI.raw()))
278 .field(
279 "referrer",
280 &DebugReferrerInfo(self.as_ref().mReferrerInfo.raw()),
281 )
282 .finish()
283 }
284}
285
286#[cfg(feature = "gecko")]
289impl Eq for UrlExtraData {}
290
291fn style_or_page_rule_to_css(
298 rules: Option<&Arc<Locked<CssRules>>>,
299 block: &Locked<PropertyDeclarationBlock>,
300 guard: &SharedRwLockReadGuard,
301 dest: &mut CssStringWriter,
302) -> fmt::Result {
303 dest.write_char('{')?;
305
306 let declaration_block = block.read_with(guard);
308 let has_declarations = !declaration_block.declarations().is_empty();
309
310 if let Some(rules) = rules {
312 let rules = rules.read_with(guard);
313 if !rules.is_empty() {
315 if has_declarations {
316 dest.write_str("\n ")?;
317 declaration_block.to_css(dest)?;
318 }
319 return rules.to_css_block_without_opening(guard, dest);
320 }
321 }
322
323 if has_declarations {
325 dest.write_char(' ')?;
326 declaration_block.to_css(dest)?;
327 }
328 dest.write_str(" }")
329}
330
331#[derive(Clone, Debug, ToShmem)]
335#[allow(missing_docs)]
336pub enum CssRule {
337 Style(Arc<Locked<StyleRule>>),
338 Namespace(Arc<NamespaceRule>),
341 Import(Arc<Locked<ImportRule>>),
342 Media(Arc<MediaRule>),
343 CustomMedia(Arc<CustomMediaRule>),
344 Container(Arc<ContainerRule>),
345 FontFace(Arc<Locked<FontFaceRule>>),
346 FontFeatureValues(Arc<FontFeatureValuesRule>),
347 FontPaletteValues(Arc<FontPaletteValuesRule>),
348 CounterStyle(Arc<Locked<CounterStyleRule>>),
349 Keyframes(Arc<Locked<KeyframesRule>>),
350 Margin(Arc<MarginRule>),
351 Supports(Arc<SupportsRule>),
352 Page(Arc<Locked<PageRule>>),
353 Property(Arc<PropertyRule>),
354 Document(Arc<DocumentRule>),
355 LayerBlock(Arc<LayerBlockRule>),
356 LayerStatement(Arc<LayerStatementRule>),
357 Scope(Arc<ScopeRule>),
358 StartingStyle(Arc<StartingStyleRule>),
359 AppearanceBase(Arc<AppearanceBaseRule>),
360 PositionTry(Arc<Locked<PositionTryRule>>),
361 NestedDeclarations(Arc<Locked<NestedDeclarationsRule>>),
362 ViewTransition(Arc<ViewTransitionRule>),
363}
364
365impl CssRule {
366 #[cfg(feature = "gecko")]
368 fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize {
369 match *self {
370 CssRule::Namespace(_) => 0,
373
374 CssRule::Import(_) => 0,
377
378 CssRule::Style(ref lock) => {
379 lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
380 },
381 CssRule::Media(ref arc) => {
382 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
383 },
384 CssRule::CustomMedia(ref arc) => {
385 arc.unconditional_shallow_size_of(ops)
387 },
388 CssRule::Container(ref arc) => {
389 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
390 },
391 CssRule::FontFace(_) => 0,
392 CssRule::FontFeatureValues(_) => 0,
393 CssRule::FontPaletteValues(_) => 0,
394 CssRule::CounterStyle(_) => 0,
395 CssRule::Keyframes(_) => 0,
396 CssRule::Margin(ref arc) => {
397 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
398 },
399 CssRule::Supports(ref arc) => {
400 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
401 },
402 CssRule::Page(ref lock) => {
403 lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
404 },
405 CssRule::Property(ref rule) => {
406 rule.unconditional_shallow_size_of(ops) + rule.size_of(guard, ops)
407 },
408 CssRule::Document(ref arc) => {
409 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
410 },
411 CssRule::StartingStyle(ref arc) => {
412 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
413 },
414 CssRule::AppearanceBase(ref arc) => {
415 arc.unconditional_shallow_size_of(ops) + arc.size_of(guard, ops)
416 },
417 CssRule::LayerBlock(_) | CssRule::LayerStatement(_) => 0,
419 CssRule::Scope(ref rule) => {
420 rule.unconditional_shallow_size_of(ops) + rule.size_of(guard, ops)
421 },
422 CssRule::PositionTry(ref lock) => {
423 lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
424 },
425 CssRule::NestedDeclarations(ref lock) => {
426 lock.unconditional_shallow_size_of(ops) + lock.read_with(guard).size_of(guard, ops)
427 },
428 CssRule::ViewTransition(ref rule) => {
429 use malloc_size_of::MallocSizeOf;
430
431 rule.unconditional_shallow_size_of(ops) + rule.size_of(ops)
432 },
433 }
434 }
435
436 fn is_empty_nested_declarations(&self, guard: &SharedRwLockReadGuard) -> bool {
437 match *self {
438 CssRule::NestedDeclarations(ref lock) => {
439 lock.read_with(guard).block.read_with(guard).is_empty()
440 },
441 _ => false,
442 }
443 }
444
445 pub fn children<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> &'a [CssRule] {
447 match *self {
448 CssRule::Namespace(_)
449 | CssRule::FontFace(_)
450 | CssRule::CounterStyle(_)
451 | CssRule::CustomMedia(_)
452 | CssRule::Keyframes(_)
453 | CssRule::Margin(_)
454 | CssRule::Property(_)
455 | CssRule::LayerStatement(_)
456 | CssRule::FontFeatureValues(_)
457 | CssRule::FontPaletteValues(_)
458 | CssRule::NestedDeclarations(_)
459 | CssRule::PositionTry(_)
460 | CssRule::ViewTransition(_) => &[],
461 CssRule::Page(ref page_rule) => {
462 let page_rule = page_rule.read_with(guard);
463 let rules = page_rule.rules.read_with(guard);
464 rules.0.as_slice()
465 },
466 CssRule::Style(ref style_rule) => {
467 let style_rule = style_rule.read_with(guard);
468 match style_rule.rules.as_ref() {
469 Some(r) => r.read_with(guard).0.as_slice(),
470 None => &[],
471 }
472 },
473 CssRule::Import(ref import_rule) => {
474 let import_rule = import_rule.read_with(guard);
475 import_rule.stylesheet.rules(guard)
476 },
477 CssRule::Document(ref doc_rule) => doc_rule.rules.read_with(guard).0.as_slice(),
478 CssRule::Container(ref container_rule) => {
479 container_rule.rules.read_with(guard).0.as_slice()
480 },
481 CssRule::Media(ref media_rule) => media_rule.rules.read_with(guard).0.as_slice(),
482 CssRule::Supports(ref supports_rule) => {
483 supports_rule.rules.read_with(guard).0.as_slice()
484 },
485 CssRule::LayerBlock(ref layer_rule) => layer_rule.rules.read_with(guard).0.as_slice(),
486 CssRule::Scope(ref rule) => rule.rules.read_with(guard).0.as_slice(),
487 CssRule::StartingStyle(ref rule) => rule.rules.read_with(guard).0.as_slice(),
488 CssRule::AppearanceBase(ref rule) => rule.rules.read_with(guard).0.as_slice(),
489 }
490 }
491}
492
493pub type LockedStyleRule = Locked<StyleRule>;
496pub type LockedImportRule = Locked<ImportRule>;
498pub type LockedFontFaceRule = Locked<FontFaceRule>;
500pub type LockedCounterStyleRule = Locked<CounterStyleRule>;
502pub type LockedKeyframesRule = Locked<KeyframesRule>;
504pub type LockedPageRule = Locked<PageRule>;
506pub type LockedPositionTryRule = Locked<PositionTryRule>;
508pub type LockedNestedDeclarationsRule = Locked<NestedDeclarationsRule>;
510
511#[repr(C)]
513#[allow(missing_docs)]
514pub enum CssRuleRef<'a> {
515 Style(&'a LockedStyleRule),
516 Namespace(&'a NamespaceRule),
517 Import(&'a LockedImportRule),
518 Media(&'a MediaRule),
519 CustomMedia(&'a CustomMediaRule),
520 Container(&'a ContainerRule),
521 FontFace(&'a LockedFontFaceRule),
522 FontFeatureValues(&'a FontFeatureValuesRule),
523 FontPaletteValues(&'a FontPaletteValuesRule),
524 CounterStyle(&'a LockedCounterStyleRule),
525 Keyframes(&'a LockedKeyframesRule),
526 Margin(&'a MarginRule),
527 Supports(&'a SupportsRule),
528 Page(&'a LockedPageRule),
529 Property(&'a PropertyRule),
530 Document(&'a DocumentRule),
531 LayerBlock(&'a LayerBlockRule),
532 LayerStatement(&'a LayerStatementRule),
533 Scope(&'a ScopeRule),
534 StartingStyle(&'a StartingStyleRule),
535 AppearanceBase(&'a AppearanceBaseRule),
536 PositionTry(&'a LockedPositionTryRule),
537 NestedDeclarations(&'a LockedNestedDeclarationsRule),
538 ViewTransition(&'a ViewTransitionRule),
539}
540
541impl<'a> From<&'a CssRule> for CssRuleRef<'a> {
542 fn from(value: &'a CssRule) -> Self {
543 match value {
544 CssRule::Style(r) => CssRuleRef::Style(r.as_ref()),
545 CssRule::Namespace(r) => CssRuleRef::Namespace(r.as_ref()),
546 CssRule::Import(r) => CssRuleRef::Import(r.as_ref()),
547 CssRule::Media(r) => CssRuleRef::Media(r.as_ref()),
548 CssRule::CustomMedia(r) => CssRuleRef::CustomMedia(r.as_ref()),
549 CssRule::Container(r) => CssRuleRef::Container(r.as_ref()),
550 CssRule::FontFace(r) => CssRuleRef::FontFace(r.as_ref()),
551 CssRule::FontFeatureValues(r) => CssRuleRef::FontFeatureValues(r.as_ref()),
552 CssRule::FontPaletteValues(r) => CssRuleRef::FontPaletteValues(r.as_ref()),
553 CssRule::CounterStyle(r) => CssRuleRef::CounterStyle(r.as_ref()),
554 CssRule::Keyframes(r) => CssRuleRef::Keyframes(r.as_ref()),
555 CssRule::Margin(r) => CssRuleRef::Margin(r.as_ref()),
556 CssRule::Supports(r) => CssRuleRef::Supports(r.as_ref()),
557 CssRule::Page(r) => CssRuleRef::Page(r.as_ref()),
558 CssRule::Property(r) => CssRuleRef::Property(r.as_ref()),
559 CssRule::Document(r) => CssRuleRef::Document(r.as_ref()),
560 CssRule::LayerBlock(r) => CssRuleRef::LayerBlock(r.as_ref()),
561 CssRule::LayerStatement(r) => CssRuleRef::LayerStatement(r.as_ref()),
562 CssRule::Scope(r) => CssRuleRef::Scope(r.as_ref()),
563 CssRule::StartingStyle(r) => CssRuleRef::StartingStyle(r.as_ref()),
564 CssRule::AppearanceBase(r) => CssRuleRef::AppearanceBase(r.as_ref()),
565 CssRule::PositionTry(r) => CssRuleRef::PositionTry(r.as_ref()),
566 CssRule::NestedDeclarations(r) => CssRuleRef::NestedDeclarations(r.as_ref()),
567 CssRule::ViewTransition(r) => CssRuleRef::ViewTransition(r.as_ref()),
568 }
569 }
570}
571
572#[allow(missing_docs)]
574#[derive(Clone, Copy, Debug, Eq, FromPrimitive, PartialEq)]
575#[repr(u8)]
576pub enum CssRuleType {
577 Style = 1,
579 Import = 3,
581 Media = 4,
582 FontFace = 5,
583 Page = 6,
584 Keyframes = 7,
586 Keyframe = 8,
587 Margin = 9,
589 Namespace = 10,
590 CounterStyle = 11,
592 Supports = 12,
594 Document = 13,
596 FontFeatureValues = 14,
598 LayerBlock = 16,
601 LayerStatement = 17,
602 Container = 18,
603 FontPaletteValues = 19,
604 Property = 20,
606 Scope = 21,
607 StartingStyle = 22,
609 PositionTry = 23,
611 NestedDeclarations = 24,
613 CustomMedia = 25,
614 AppearanceBase = 26,
616 ViewTransition = 27,
618}
619
620impl CssRuleType {
621 #[inline]
623 pub const fn bit(self) -> u32 {
624 1 << self as u32
625 }
626}
627
628#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
630pub struct CssRuleTypes(u32);
631
632impl From<CssRuleType> for CssRuleTypes {
633 fn from(ty: CssRuleType) -> Self {
634 Self(ty.bit())
635 }
636}
637
638impl CssRuleTypes {
639 pub const IMPORTANT_FORBIDDEN: Self =
641 Self(CssRuleType::PositionTry.bit() | CssRuleType::Keyframe.bit());
642
643 pub const WITHOUT_ELEMENT_CONTEXT: Self = Self(
645 CssRuleType::CounterStyle.bit()
646 | CssRuleType::FontFace.bit()
647 | CssRuleType::FontFeatureValues.bit()
648 | CssRuleType::FontPaletteValues.bit()
649 | CssRuleType::Page.bit(),
650 );
651
652 #[inline]
654 pub fn contains(self, ty: CssRuleType) -> bool {
655 self.0 & ty.bit() != 0
656 }
657
658 #[inline]
660 pub fn bits(self) -> u32 {
661 self.0
662 }
663
664 #[inline]
666 pub fn from_bits(bits: u32) -> Self {
667 Self(bits)
668 }
669
670 #[inline]
672 pub fn is_empty(self) -> bool {
673 self.0 == 0
674 }
675
676 #[inline]
678 pub fn insert(&mut self, ty: CssRuleType) {
679 self.0 |= ty.bit()
680 }
681
682 #[inline]
684 pub fn intersects(self, other: Self) -> bool {
685 self.0 & other.0 != 0
686 }
687}
688
689#[allow(missing_docs)]
690pub enum RulesMutateError {
691 Syntax,
692 IndexSize,
693 HierarchyRequest,
694 InvalidState,
695}
696
697impl CssRule {
698 pub fn rule_type(&self) -> CssRuleType {
700 match *self {
701 CssRule::Style(_) => CssRuleType::Style,
702 CssRule::Import(_) => CssRuleType::Import,
703 CssRule::Media(_) => CssRuleType::Media,
704 CssRule::CustomMedia(_) => CssRuleType::CustomMedia,
705 CssRule::FontFace(_) => CssRuleType::FontFace,
706 CssRule::FontFeatureValues(_) => CssRuleType::FontFeatureValues,
707 CssRule::FontPaletteValues(_) => CssRuleType::FontPaletteValues,
708 CssRule::CounterStyle(_) => CssRuleType::CounterStyle,
709 CssRule::Keyframes(_) => CssRuleType::Keyframes,
710 CssRule::Margin(_) => CssRuleType::Margin,
711 CssRule::Namespace(_) => CssRuleType::Namespace,
712 CssRule::Supports(_) => CssRuleType::Supports,
713 CssRule::Page(_) => CssRuleType::Page,
714 CssRule::Property(_) => CssRuleType::Property,
715 CssRule::Document(_) => CssRuleType::Document,
716 CssRule::LayerBlock(_) => CssRuleType::LayerBlock,
717 CssRule::LayerStatement(_) => CssRuleType::LayerStatement,
718 CssRule::Container(_) => CssRuleType::Container,
719 CssRule::Scope(_) => CssRuleType::Scope,
720 CssRule::StartingStyle(_) => CssRuleType::StartingStyle,
721 CssRule::AppearanceBase(_) => CssRuleType::AppearanceBase,
722 CssRule::PositionTry(_) => CssRuleType::PositionTry,
723 CssRule::NestedDeclarations(_) => CssRuleType::NestedDeclarations,
724 CssRule::ViewTransition(_) => CssRuleType::ViewTransition,
725 }
726 }
727
728 pub fn parse(
732 css: &str,
733 insert_rule_context: InsertRuleContext,
734 parent_stylesheet_contents: &StylesheetContents,
735 shared_lock: &SharedRwLock,
736 loader: Option<&dyn StylesheetLoader>,
737 allow_import_rules: AllowImportRules,
738 ) -> Result<Self, RulesMutateError> {
739 let url_data = &parent_stylesheet_contents.url_data;
740 let namespaces = &parent_stylesheet_contents.namespaces;
741 let mut context = ParserContext::new(
742 parent_stylesheet_contents.origin,
743 url_data,
744 None,
745 ParsingMode::DEFAULT,
746 parent_stylesheet_contents.quirks_mode,
747 Cow::Borrowed(namespaces),
748 None,
749 None,
750 Default::default(),
751 );
752 context.nesting_context = NestingContext::new(
754 insert_rule_context.containing_rule_types,
755 insert_rule_context.parse_relative_rule_type,
756 );
757
758 let state = if !insert_rule_context.containing_rule_types.is_empty() {
759 State::Body
760 } else if insert_rule_context.index == 0 {
761 State::Start
762 } else {
763 let index = insert_rule_context.index;
764 insert_rule_context.max_rule_state_at_index(index - 1)
765 };
766
767 let mut input = Parser::new(css);
768
769 let mut parser = TopLevelRuleParser {
771 context,
772 shared_lock,
773 loader,
774 state,
775 dom_error: None,
776 insert_rule_context: Some(insert_rule_context),
777 allow_import_rules,
778 declaration_parser_state: Default::default(),
779 first_declaration_block: Default::default(),
780 wants_first_declaration_block: false,
781 error_reporting_state: Default::default(),
782 rules: Default::default(),
783 };
784
785 if input
786 .try_parse(|input| parse_one_rule(input, &mut parser))
787 .is_ok()
788 {
789 return Ok(parser.rules.pop().unwrap());
790 }
791
792 let error = parser.dom_error.take().unwrap_or(RulesMutateError::Syntax);
793 if matches!(error, RulesMutateError::Syntax) && parser.can_parse_declarations() {
795 let declarations =
796 parse_property_declaration_list(&mut parser.context, &mut input, &[]);
797 if !declarations.is_empty() {
798 return Ok(CssRule::NestedDeclarations(Arc::new(
799 parser.shared_lock.wrap(NestedDeclarationsRule {
800 block: Arc::new(parser.shared_lock.wrap(declarations)),
801 source_location: input.current_source_location(),
802 }),
803 )));
804 }
805 }
806 Err(error)
807 }
808}
809
810impl DeepCloneWithLock for CssRule {
811 fn deep_clone_with_lock(&self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard) -> CssRule {
813 match *self {
814 CssRule::Namespace(ref arc) => CssRule::Namespace(arc.clone()),
815 CssRule::Import(ref arc) => {
816 let rule = arc.read_with(guard).deep_clone_with_lock(lock, guard);
817 CssRule::Import(Arc::new(lock.wrap(rule)))
818 },
819 CssRule::Style(ref arc) => {
820 let rule = arc.read_with(guard);
821 CssRule::Style(Arc::new(lock.wrap(rule.deep_clone_with_lock(lock, guard))))
822 },
823 CssRule::Container(ref arc) => {
824 CssRule::Container(Arc::new(arc.deep_clone_with_lock(lock, guard)))
825 },
826 CssRule::Media(ref arc) => {
827 CssRule::Media(Arc::new(arc.deep_clone_with_lock(lock, guard)))
828 },
829 CssRule::CustomMedia(ref arc) => {
830 CssRule::CustomMedia(Arc::new(arc.deep_clone_with_lock(lock, guard)))
831 },
832 CssRule::FontFace(ref arc) => {
833 let rule = arc.read_with(guard);
834 CssRule::FontFace(Arc::new(lock.wrap(rule.clone())))
835 },
836 CssRule::FontFeatureValues(ref arc) => CssRule::FontFeatureValues(arc.clone()),
837 CssRule::FontPaletteValues(ref arc) => CssRule::FontPaletteValues(arc.clone()),
838 CssRule::CounterStyle(ref arc) => {
839 let rule = arc.read_with(guard);
840 CssRule::CounterStyle(Arc::new(lock.wrap(rule.clone())))
841 },
842 CssRule::Keyframes(ref arc) => {
843 let rule = arc.read_with(guard);
844 CssRule::Keyframes(Arc::new(lock.wrap(rule.deep_clone_with_lock(lock, guard))))
845 },
846 CssRule::Margin(ref arc) => {
847 CssRule::Margin(Arc::new(arc.deep_clone_with_lock(lock, guard)))
848 },
849 CssRule::Supports(ref arc) => {
850 CssRule::Supports(Arc::new(arc.deep_clone_with_lock(lock, guard)))
851 },
852 CssRule::Page(ref arc) => {
853 let rule = arc.read_with(guard);
854 CssRule::Page(Arc::new(lock.wrap(rule.deep_clone_with_lock(lock, guard))))
855 },
856 CssRule::Property(ref arc) => {
857 CssRule::Property(arc.clone())
860 },
861 CssRule::Document(ref arc) => {
862 CssRule::Document(Arc::new(arc.deep_clone_with_lock(lock, guard)))
863 },
864 CssRule::LayerStatement(ref arc) => CssRule::LayerStatement(arc.clone()),
865 CssRule::LayerBlock(ref arc) => {
866 CssRule::LayerBlock(Arc::new(arc.deep_clone_with_lock(lock, guard)))
867 },
868 CssRule::Scope(ref arc) => {
869 CssRule::Scope(Arc::new(arc.deep_clone_with_lock(lock, guard)))
870 },
871 CssRule::StartingStyle(ref arc) => {
872 CssRule::StartingStyle(Arc::new(arc.deep_clone_with_lock(lock, guard)))
873 },
874 CssRule::AppearanceBase(ref arc) => {
875 CssRule::AppearanceBase(Arc::new(arc.deep_clone_with_lock(lock, guard)))
876 },
877 CssRule::PositionTry(ref arc) => {
878 let rule = arc.read_with(guard);
879 CssRule::PositionTry(Arc::new(lock.wrap(rule.deep_clone_with_lock(lock, guard))))
880 },
881 CssRule::NestedDeclarations(ref arc) => {
882 let decls = arc.read_with(guard);
883 CssRule::NestedDeclarations(Arc::new(lock.wrap(decls.clone())))
884 },
885 CssRule::ViewTransition(ref arc) => {
886 CssRule::ViewTransition(Arc::new(arc.deep_clone_with_lock(lock, guard)))
887 },
888 }
889 }
890}
891
892impl ToCssWithGuard for CssRule {
893 fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result {
895 match *self {
896 CssRule::Namespace(ref rule) => rule.to_css(guard, dest),
897 CssRule::Import(ref lock) => lock.read_with(guard).to_css(guard, dest),
898 CssRule::Style(ref lock) => lock.read_with(guard).to_css(guard, dest),
899 CssRule::FontFace(ref lock) => lock.read_with(guard).to_css(guard, dest),
900 CssRule::FontFeatureValues(ref rule) => rule.to_css(guard, dest),
901 CssRule::FontPaletteValues(ref rule) => rule.to_css(guard, dest),
902 CssRule::CounterStyle(ref lock) => lock.read_with(guard).to_css(guard, dest),
903 CssRule::Keyframes(ref lock) => lock.read_with(guard).to_css(guard, dest),
904 CssRule::Margin(ref rule) => rule.to_css(guard, dest),
905 CssRule::Media(ref rule) => rule.to_css(guard, dest),
906 CssRule::CustomMedia(ref rule) => rule.to_css(guard, dest),
907 CssRule::Supports(ref rule) => rule.to_css(guard, dest),
908 CssRule::Page(ref lock) => lock.read_with(guard).to_css(guard, dest),
909 CssRule::Property(ref rule) => rule.to_css(guard, dest),
910 CssRule::Document(ref rule) => rule.to_css(guard, dest),
911 CssRule::LayerBlock(ref rule) => rule.to_css(guard, dest),
912 CssRule::LayerStatement(ref rule) => rule.to_css(guard, dest),
913 CssRule::Container(ref rule) => rule.to_css(guard, dest),
914 CssRule::Scope(ref rule) => rule.to_css(guard, dest),
915 CssRule::StartingStyle(ref rule) => rule.to_css(guard, dest),
916 CssRule::AppearanceBase(ref rule) => rule.to_css(guard, dest),
917 CssRule::PositionTry(ref lock) => lock.read_with(guard).to_css(guard, dest),
918 CssRule::NestedDeclarations(ref lock) => lock.read_with(guard).to_css(guard, dest),
919 CssRule::ViewTransition(ref rule) => rule.to_css(guard, dest),
920 }
921 }
922}