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 [`@page`][page] rule. 6 //! 7 //! [page]: https://drafts.csswg.org/css2/page.html#page-box 8 9 use crate::properties::PropertyDeclarationBlock; 10 use crate::shared_lock::{DeepCloneParams, DeepCloneWithLock, Locked}; 11 use crate::shared_lock::{SharedRwLock, SharedRwLockReadGuard, ToCssWithGuard}; 12 use crate::str::CssStringWriter; 13 use cssparser::SourceLocation; 14 #[cfg(feature = "gecko")] 15 use malloc_size_of::{MallocSizeOf, MallocSizeOfOps, MallocUnconditionalShallowSizeOf}; 16 use servo_arc::Arc; 17 use std::fmt::{self, Write}; 18 19 /// A [`@page`][page] rule. 20 /// 21 /// This implements only a limited subset of the CSS 22 /// 2.2 syntax. 23 /// 24 /// In this subset, [page selectors][page-selectors] are not implemented. 25 /// 26 /// [page]: https://drafts.csswg.org/css2/page.html#page-box 27 /// [page-selectors]: https://drafts.csswg.org/css2/page.html#page-selectors 28 #[derive(Debug, ToShmem)] 29 pub struct PageRule { 30 /// The declaration block this page rule contains. 31 pub block: Arc<Locked<PropertyDeclarationBlock>>, 32 /// The source position this rule was found at. 33 pub source_location: SourceLocation, 34 } 35 36 impl PageRule { 37 /// Measure heap usage. 38 #[cfg(feature = "gecko")] size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize39 pub fn size_of(&self, guard: &SharedRwLockReadGuard, ops: &mut MallocSizeOfOps) -> usize { 40 // Measurement of other fields may be added later. 41 self.block.unconditional_shallow_size_of(ops) + self.block.read_with(guard).size_of(ops) 42 } 43 } 44 45 impl ToCssWithGuard for PageRule { 46 /// Serialization of PageRule is not specced, adapted from steps for 47 /// StyleRule. to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result48 fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut CssStringWriter) -> fmt::Result { 49 dest.write_str("@page { ")?; 50 let declaration_block = self.block.read_with(guard); 51 declaration_block.to_css(dest)?; 52 if !declaration_block.declarations().is_empty() { 53 dest.write_str(" ")?; 54 } 55 dest.write_str("}") 56 } 57 } 58 59 impl DeepCloneWithLock for PageRule { deep_clone_with_lock( &self, lock: &SharedRwLock, guard: &SharedRwLockReadGuard, _params: &DeepCloneParams, ) -> Self60 fn deep_clone_with_lock( 61 &self, 62 lock: &SharedRwLock, 63 guard: &SharedRwLockReadGuard, 64 _params: &DeepCloneParams, 65 ) -> Self { 66 PageRule { 67 block: Arc::new(lock.wrap(self.block.read_with(&guard).clone())), 68 source_location: self.source_location.clone(), 69 } 70 } 71 } 72