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