style_rule.rs (2927B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 5 //! A style rule. 6 7 use crate::derives::*; 8 use crate::properties::PropertyDeclarationBlock; 9 use crate::selector_parser::SelectorImpl; 10 use crate::shared_lock::{ 11 DeepCloneWithLock, Locked, SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard, 12 }; 13 use crate::stylesheets::{style_or_page_rule_to_css, CssRules}; 14 use cssparser::SourceLocation; 15 #[cfg(feature = "gecko")] 16 use malloc_size_of::{ 17 MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf, MallocUnconditionalSizeOf, 18 }; 19 use selectors::SelectorList; 20 use servo_arc::Arc; 21 use std::fmt::{self, Write}; 22 use style_traits::CssStringWriter; 23 24 /// A style rule, with selectors and declarations. 25 #[derive(Debug, ToShmem)] 26 pub struct StyleRule { 27 /// The list of selectors in this rule. 28 pub selectors: SelectorList<SelectorImpl>, 29 /// The declaration block with the properties it contains. 30 pub block: Arc<Locked<PropertyDeclarationBlock>>, 31 /// The nested rules to this style rule. Only non-`None` when nesting is enabled. 32 pub rules: Option<Arc<Locked<CssRules>>>, 33 /// The location in the sheet where it was found. 34 pub source_location: SourceLocation, 35 } 36 37 impl DeepCloneWithLock for StyleRule { 38 /// Deep clones this StyleRule. 39 fn deep_clone_with_lock( 40 &self, 41 lock: &SharedRwLock, 42 guard: &SharedRwLockReadGuard, 43 ) -> StyleRule { 44 StyleRule { 45 selectors: self.selectors.clone(), 46 block: Arc::new(lock.wrap(self.block.read_with(guard).clone())), 47 rules: self.rules.as_ref().map(|rules| { 48 let rules = rules.read_with(guard); 49 Arc::new(lock.wrap(rules.deep_clone_with_lock(lock, guard))) 50 }), 51 source_location: self.source_location.clone(), 52 } 53 } 54 } 55 56 impl StyleRule { 57 /// Measure heap usage. 58 #[cfg(feature = "gecko")] 59 pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 60 let mut n = 0; 61 n += self.selectors.unconditional_size_of(ops); 62 n += self.block.unconditional_shallow_size_of(ops) 63 + self.block.read_with(guard).size_of(ops); 64 if let Some(ref rules) = self.rules { 65 n += rules.unconditional_shallow_size_of(ops) 66 + rules.read_with(guard).size_of(guard, ops) 67 } 68 n 69 } 70 } 71 72 impl ToCssWithGuard for StyleRule { 73 /// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule 74 fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 75 use cssparser::ToCss; 76 self.selectors.to_css(dest)?; 77 dest.write_char(' ')?; 78 style_or_page_rule_to_css(self.rules.as_ref(), &self.block, guard, dest) 79 } 80 }