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::properties::PropertyDeclarationBlock; 8 use crate::selector_parser::SelectorImpl; 9 use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; 10 use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; 11 use crate::str::CssStringWriter; 12 use cssparser::SourceLocation; 13 #[cfg(feature = "gecko")] 14 use malloc_size_of::MallocUnconditionalShallowSizeOf; 15 #[cfg(feature = "gecko")] 16 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; 17 use selectors::SelectorList; 18 use servo_arc::Arc; 19 use std::fmt::{self, Write}; 20 21 /// A style rule, with selectors and declarations. 22 #[derive(Debug, ToShmem)] 23 pub struct StyleRule { 24 /// The list of selectors in this rule. 25 pub selectors: SelectorList<SelectorImpl>, 26 /// The declaration block with the properties it contains. 27 pub block: Arc<Locked<PropertyDeclarationBlock>>, 28 /// The location in the sheet where it was found. 29 pub source_location: SourceLocation, 30 } 31 32 impl DeepCloneWithLock for StyleRule { 33 /// Deep clones this StyleRule. deep_clone_with_lock( &self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard, _params: &DeepCloneParams, ) -> StyleRule34 fn deep_clone_with_lock( 35 &self, 36 lock: &SharedRwLock, 37 guard: &SharedRwLockReadGuard, 38 _params: &DeepCloneParams, 39 ) -> StyleRule { 40 StyleRule { 41 selectors: self.selectors.clone(), 42 block: Arc::new(lock.wrap(self.block.read_with(guard).clone())), 43 source_location: self.source_location.clone(), 44 } 45 } 46 } 47 48 impl StyleRule { 49 /// Measure heap usage. 50 #[cfg(feature = "gecko")] size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize51 pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 52 let mut n = 0; 53 n += self.selectors.0.size_of(ops); 54 n += self.block.unconditional_shallow_size_of(ops) + 55 self.block.read_with(guard).size_of(ops); 56 n 57 } 58 } 59 60 impl ToCssWithGuard for StyleRule { 61 /// https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result62 fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 63 use cssparser::ToCss; 64 65 // Step 1 66 self.selectors.to_css(dest)?; 67 // Step 2 68 dest.write_str(" { ")?; 69 // Step 3 70 let declaration_block = self.block.read_with(guard); 71 declaration_block.to_css(dest)?; 72 // Step 4 73 if !declaration_block.declarations().is_empty() { 74 dest.write_str(" ")?; 75 } 76 // Step 5 77 dest.write_str("}") 78 } 79 } 80