diff options
Diffstat (limited to 'servo/components/style/invalidation/viewport_units.rs')
-rw-r--r-- | servo/components/style/invalidation/viewport_units.rs | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/servo/components/style/invalidation/viewport_units.rs b/servo/components/style/invalidation/viewport_units.rs new file mode 100644 index 0000000000..06faeb14c4 --- /dev/null +++ b/servo/components/style/invalidation/viewport_units.rs @@ -0,0 +1,71 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +//! Invalidates style of all elements that depend on viewport units. + +use crate::data::ViewportUnitUsage; +use crate::dom::{TElement, TNode}; +use crate::invalidation::element::restyle_hints::RestyleHint; + +/// Invalidates style of all elements that depend on viewport units. +/// +/// Returns whether any element was invalidated. +pub fn invalidate<E>(root: E) -> bool +where + E: TElement, +{ + debug!("invalidation::viewport_units::invalidate({:?})", root); + invalidate_recursively(root) +} + +fn invalidate_recursively<E>(element: E) -> bool +where + E: TElement, +{ + let mut data = match element.mutate_data() { + Some(data) => data, + None => return false, + }; + + if data.hint.will_recascade_subtree() { + debug!("invalidate_recursively: {:?} was already invalid", element); + return false; + } + + let usage = data.styles.viewport_unit_usage(); + let uses_viewport_units = usage != ViewportUnitUsage::None; + if uses_viewport_units { + debug!( + "invalidate_recursively: {:?} uses viewport units {:?}", + element, usage + ); + } + + match usage { + ViewportUnitUsage::None => {}, + ViewportUnitUsage::FromQuery => { + data.hint.insert(RestyleHint::RESTYLE_SELF); + }, + ViewportUnitUsage::FromDeclaration => { + data.hint.insert(RestyleHint::RECASCADE_SELF); + }, + } + + let mut any_children_invalid = false; + for child in element.traversal_children() { + if let Some(child) = child.as_element() { + any_children_invalid |= invalidate_recursively(child); + } + } + + if any_children_invalid { + debug!( + "invalidate_recursively: Children of {:?} changed, setting dirty descendants", + element + ); + unsafe { element.set_dirty_descendants() } + } + + uses_viewport_units || any_children_invalid +} |