Bug 1385089 - Move the logic for Servo_NoteExplicitHints into wrapper.rs. r?emilio
In a subsequent patch in this series, we will call it from servo side.
MozReview-Commit-ID: D2s9RLOPify
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -14,17 +14,17 @@
//! style system it's kind of pointless in the Stylo case, and only Servo forces
//! the separation between the style system implementation and everything else.
use CaseSensitivityExt;
use app_units::Au;
use applicable_declarations::ApplicableDeclarationBlock;
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
use context::{QuirksMode, SharedStyleContext, UpdateAnimationsTasks};
-use data::ElementData;
+use data::{ElementData, RestyleData};
use dom::{self, DescendantsBit, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode};
use dom::{OpaqueNode, PresentationalHintsSynthesizer};
use element_state::{ElementState, DocumentState, NS_DOCUMENT_STATE_WINDOW_INACTIVE};
use error_reporting::ParseErrorReporter;
use font_metrics::{FontMetrics, FontMetricsProvider, FontMetricsQueryResult};
use gecko::data::PerDocumentStyleData;
use gecko::global_style_data::GLOBAL_STYLE_DATA;
use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement};
@@ -58,17 +58,19 @@ use gecko_bindings::structs::{RawGeckoEl
use gecko_bindings::structs::{nsIAtom, nsIContent, nsINode_BooleanFlag, nsStyleContext};
use gecko_bindings::structs::ELEMENT_HANDLED_SNAPSHOT;
use gecko_bindings::structs::ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO;
use gecko_bindings::structs::ELEMENT_HAS_SNAPSHOT;
use gecko_bindings::structs::EffectCompositor_CascadeLevel as CascadeLevel;
use gecko_bindings::structs::NODE_IS_IN_NATIVE_ANONYMOUS_SUBTREE;
use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
+use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme;
+use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::{ComputedValues, parse_style_attribute};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::animated_properties::{AnimatableLonghand, AnimationValue, AnimationValueMap};
use properties::animated_properties::TransitionProperty;
use properties::style_structs::Font;
@@ -665,16 +667,74 @@ impl<'le> GeckoElement<'le> {
let node = self.as_node();
unsafe { Gecko_GetDocumentLWTheme(node.owner_doc()) }
}
/// Owner document quirks mode getter.
pub fn owner_document_quirks_mode(&self) -> QuirksMode {
self.as_node().owner_doc().mCompatMode.into()
}
+
+ /// Only safe to call on the main thread, with exclusive access to the element and
+ /// its ancestors.
+ /// This function is also called after display property changed for SMIL animation.
+ ///
+ /// Also this function schedules style flush.
+ unsafe fn maybe_restyle<'a>(&self,
+ data: &'a mut ElementData,
+ animation_only: bool) -> Option<&'a mut RestyleData> {
+ use dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
+
+ // Don't generate a useless RestyleData if the element hasn't been styled.
+ if !data.has_styles() {
+ return None;
+ }
+
+ // Propagate the bit up the chain.
+ if let Some(p) = self.traversal_parent() {
+ if animation_only {
+ p.note_descendants::<AnimationOnlyDirtyDescendants>();
+ } else {
+ p.note_descendants::<DirtyDescendants>();
+ }
+ };
+
+ bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(self.0);
+
+ // Ensure and return the RestyleData.
+ Some(&mut data.restyle)
+ }
+
+ /// Set restyle and change hints to the element data.
+ pub fn note_explicit_hints(&self,
+ restyle_hint: nsRestyleHint,
+ change_hint: nsChangeHint) {
+ use invalidation::element::restyle_hints::RestyleHint;
+ use gecko::restyle_damage::GeckoRestyleDamage;
+
+ let damage = GeckoRestyleDamage::new(change_hint);
+ debug!("note_explicit_hints: {:?}, restyle_hint={:?}, change_hint={:?}",
+ self, restyle_hint, change_hint);
+
+ let restyle_hint: RestyleHint = restyle_hint.into();
+ debug_assert!(!(restyle_hint.has_animation_hint() &&
+ restyle_hint.has_non_animation_hint()),
+ "Animation restyle hints should not appear with non-animation restyle hints");
+
+ let mut maybe_data = self.mutate_data();
+ let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe {
+ self.maybe_restyle(d, restyle_hint.has_animation_hint())
+ });
+ if let Some(restyle_data) = maybe_restyle_data {
+ restyle_data.hint.insert(restyle_hint.into());
+ restyle_data.damage |= damage;
+ } else {
+ debug!("(Element not styled, discarding hints)");
+ }
+ }
}
/// Converts flags from the layout used by rust-selectors to the layout used
/// by Gecko. We could align these and then do this without conditionals, but
/// it's probably not worth the trouble.
fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 {
use gecko_bindings::structs::*;
use selectors::matching::*;
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -1,37 +1,34 @@
/* 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 http://mozilla.org/MPL/2.0/. */
-use atomic_refcell::AtomicRefMut;
use cssparser::{Parser, ParserInput};
use cssparser::ToCss as ParserToCss;
use env_logger::LogBuilder;
use selectors::Element;
use selectors::matching::{MatchingContext, MatchingMode, matches_selector};
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
use std::env;
use std::fmt::Write;
use std::ptr;
use style::context::{CascadeInputs, QuirksMode, SharedStyleContext, StyleContext};
use style::context::ThreadLocalStyleContext;
-use style::data::{ElementData, ElementStyles, RestyleData};
-use style::dom::{AnimationOnlyDirtyDescendants, DirtyDescendants};
+use style::data::ElementStyles;
use style::dom::{ShowSubtreeData, TElement, TNode};
use style::element_state::ElementState;
use style::error_reporting::{NullReporter, ParseErrorReporter};
use style::font_metrics::{FontMetricsProvider, get_metrics_provider_for_product};
use style::gecko::data::{GeckoStyleSheet, PerDocumentStyleData, PerDocumentStyleDataImpl};
use style::gecko::global_style_data::{GLOBAL_STYLE_DATA, GlobalStyleData, STYLE_THREAD_POOL};
use style::gecko::restyle_damage::GeckoRestyleDamage;
use style::gecko::selector_parser::PseudoElement;
use style::gecko::traversal::RecalcStyleOnly;
use style::gecko::wrapper::GeckoElement;
-use style::gecko_bindings::bindings;
use style::gecko_bindings::bindings::{RawGeckoElementBorrowed, RawGeckoElementBorrowedOrNull};
use style::gecko_bindings::bindings::{RawGeckoKeyframeListBorrowed, RawGeckoKeyframeListBorrowedMut};
use style::gecko_bindings::bindings::{RawServoDeclarationBlockBorrowed, RawServoDeclarationBlockStrong};
use style::gecko_bindings::bindings::{RawServoDocumentRule, RawServoDocumentRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoFontFeatureValuesRule, RawServoFontFeatureValuesRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoImportRule, RawServoImportRuleBorrowed};
use style::gecko_bindings::bindings::{RawServoKeyframe, RawServoKeyframeBorrowed, RawServoKeyframeStrong};
use style::gecko_bindings::bindings::{RawServoKeyframesRule, RawServoKeyframesRuleBorrowed};
@@ -86,17 +83,17 @@ use style::gecko_bindings::structs::nsCo
use style::gecko_bindings::structs::nsIDocument;
use style::gecko_bindings::structs::nsStyleTransformMatrix::MatrixTransformOperator;
use style::gecko_bindings::structs::nsTArray;
use style::gecko_bindings::structs::nsresult;
use style::gecko_bindings::sugar::ownership::{FFIArcHelpers, HasFFI, HasArcFFI, HasBoxFFI};
use style::gecko_bindings::sugar::ownership::{HasSimpleFFI, Strong};
use style::gecko_bindings::sugar::refptr::RefPtr;
use style::gecko_properties::style_structs;
-use style::invalidation::element::restyle_hints::{self, RestyleHint};
+use style::invalidation::element::restyle_hints::{self};
use style::media_queries::{MediaList, parse_media_query_list};
use style::parallel;
use style::parser::{ParserContext, self};
use style::properties::{CascadeFlags, ComputedValues, Importance};
use style::properties::{IS_FIELDSET_CONTENT, IS_LINK, IS_VISITED_LINK, LonghandIdSet};
use style::properties::{PropertyDeclaration, PropertyDeclarationBlock, PropertyId, ShorthandId};
use style::properties::{SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, SourcePropertyDeclaration, StyleBuilder};
use style::properties::PROHIBIT_DISPLAY_CONTENTS;
@@ -2718,67 +2715,21 @@ pub extern "C" fn Servo_CSSSupports(cond
PARSING_MODE_DEFAULT,
QuirksMode::NoQuirks);
cond.eval(&context)
} else {
false
}
}
-/// Only safe to call on the main thread, with exclusive access to the element and
-/// its ancestors.
-unsafe fn maybe_restyle<'a>(data: &'a mut AtomicRefMut<ElementData>,
- element: GeckoElement,
- animation_only: bool)
- -> Option<&'a mut RestyleData>
-{
- // Don't generate a useless RestyleData if the element hasn't been styled.
- if !data.has_styles() {
- return None;
- }
-
- // Propagate the bit up the chain.
- if let Some(p) = element.traversal_parent() {
- if animation_only {
- p.note_descendants::<AnimationOnlyDirtyDescendants>();
- } else {
- p.note_descendants::<DirtyDescendants>();
- }
- };
-
- bindings::Gecko_SetOwnerDocumentNeedsStyleFlush(element.0);
-
- // Ensure and return the RestyleData.
- Some(&mut data.restyle)
-}
-
#[no_mangle]
pub extern "C" fn Servo_NoteExplicitHints(element: RawGeckoElementBorrowed,
restyle_hint: nsRestyleHint,
change_hint: nsChangeHint) {
- let element = GeckoElement(element);
- let damage = GeckoRestyleDamage::new(change_hint);
- debug!("Servo_NoteExplicitHints: {:?}, restyle_hint={:?}, change_hint={:?}",
- element, restyle_hint, change_hint);
-
- let restyle_hint: RestyleHint = restyle_hint.into();
- debug_assert!(!(restyle_hint.has_animation_hint() &&
- restyle_hint.has_non_animation_hint()),
- "Animation restyle hints should not appear with non-animation restyle hints");
-
- let mut maybe_data = element.mutate_data();
- let maybe_restyle_data = maybe_data.as_mut().and_then(|d| unsafe {
- maybe_restyle(d, element, restyle_hint.has_animation_hint())
- });
- if let Some(restyle_data) = maybe_restyle_data {
- restyle_data.hint.insert(restyle_hint.into());
- restyle_data.damage |= damage;
- } else {
- debug!("(Element not styled, discarding hints)");
- }
+ GeckoElement(element).note_explicit_hints(restyle_hint, change_hint);
}
#[no_mangle]
pub extern "C" fn Servo_TakeChangeHint(element: RawGeckoElementBorrowed,
raw_flags: ServoTraversalFlags,
was_restyled: *mut bool) -> nsChangeHint
{
let flags = TraversalFlags::from_bits_truncate(raw_flags);