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 //! Invalidates style of all elements that depend on viewport units.
6 
7 use crate::dom::{TElement, TNode};
8 use crate::invalidation::element::restyle_hints::RestyleHint;
9 
10 /// Invalidates style of all elements that depend on viewport units.
11 ///
12 /// Returns whether any element was invalidated.
invalidate<E>(root: E) -> bool where E: TElement,13 pub fn invalidate<E>(root: E) -> bool
14 where
15     E: TElement,
16 {
17     debug!("invalidation::viewport_units::invalidate({:?})", root);
18     invalidate_recursively(root)
19 }
20 
invalidate_recursively<E>(element: E) -> bool where E: TElement,21 fn invalidate_recursively<E>(element: E) -> bool
22 where
23     E: TElement,
24 {
25     let mut data = match element.mutate_data() {
26         Some(data) => data,
27         None => return false,
28     };
29 
30     if data.hint.will_recascade_subtree() {
31         debug!("invalidate_recursively: {:?} was already invalid", element);
32         return false;
33     }
34 
35     let uses_viewport_units = data.styles.uses_viewport_units();
36     if uses_viewport_units {
37         debug!("invalidate_recursively: {:?} uses viewport units", element);
38         data.hint.insert(RestyleHint::RECASCADE_SELF);
39     }
40 
41     let mut any_children_invalid = false;
42     for child in element.traversal_children() {
43         if let Some(child) = child.as_element() {
44             any_children_invalid |= invalidate_recursively(child);
45         }
46     }
47 
48     if any_children_invalid {
49         debug!(
50             "invalidate_recursively: Children of {:?} changed, setting dirty descendants",
51             element
52         );
53         unsafe { element.set_dirty_descendants() }
54     }
55 
56     uses_viewport_units || any_children_invalid
57 }
58