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