diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-01-04 14:45:54 +0100 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-01-04 14:45:54 +0100 |
commit | f3ea2481884ec957d7c4f5fa2fc395753f4a574f (patch) | |
tree | 1824830484d93d11d9c01fbe990b0d562c563e8a | |
parent | 10a1e1e15f713756ebb38509d619abb3c79a1f25 (diff) | |
download | servo-f3ea2481884ec957d7c4f5fa2fc395753f4a574f.tar.gz servo-f3ea2481884ec957d7c4f5fa2fc395753f4a574f.zip |
style: Remove TNode::set_can_be_fragmented and TNode::can_be_fragmented.
Replace them instead by a computed value flag, the same way as the
IS_IN_DISPLAY_NONE_SUBTREE flag works.
-rw-r--r-- | components/layout/construct.rs | 18 | ||||
-rw-r--r-- | components/layout/flow.rs | 4 | ||||
-rw-r--r-- | components/layout/traversal.rs | 3 | ||||
-rw-r--r-- | components/layout_thread/dom_wrapper.rs | 12 | ||||
-rw-r--r-- | components/script/dom/node.rs | 5 | ||||
-rw-r--r-- | components/script_layout_interface/wrapper_traits.rs | 2 | ||||
-rw-r--r-- | components/style/dom.rs | 7 | ||||
-rw-r--r-- | components/style/gecko/wrapper.rs | 12 | ||||
-rw-r--r-- | components/style/matching.rs | 19 | ||||
-rw-r--r-- | components/style/properties/computed_value_flags.rs | 5 | ||||
-rw-r--r-- | components/style/properties/gecko.mako.rs | 4 | ||||
-rw-r--r-- | components/style/properties/properties.mako.rs | 27 | ||||
-rw-r--r-- | components/style/style_adjuster.rs | 9 |
13 files changed, 46 insertions, 81 deletions
diff --git a/components/layout/construct.rs b/components/layout/construct.rs index 67e61b7dfcb..8efeeb97e83 100644 --- a/components/layout/construct.rs +++ b/components/layout/construct.rs @@ -1353,13 +1353,14 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> return false } - if node.can_be_fragmented() || node.style(self.style_context()).is_multicol() { - return false - } - let mut set_has_newly_constructed_flow_flag = false; let result = { let style = node.style(self.style_context()); + + if style.can_be_fragmented() || style.is_multicol() { + return false + } + let damage = node.restyle_damage(); let mut data = node.mutate_layout_data().unwrap(); @@ -1657,16 +1658,9 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode } #[inline(always)] - fn set_flow_construction_result(self, mut result: ConstructionResult) { - if self.can_be_fragmented() { - if let ConstructionResult::Flow(ref mut flow, _) = result { - FlowRef::deref_mut(flow).mut_base().flags.insert(FlowFlags::CAN_BE_FRAGMENTED); - } - } - + fn set_flow_construction_result(self, result: ConstructionResult) { let mut layout_data = self.mutate_layout_data().unwrap(); let dst = self.construction_result_mut(&mut *layout_data); - *dst = result; } diff --git a/components/layout/flow.rs b/components/layout/flow.rs index e4b19e20b0c..894c7f1e528 100644 --- a/components/layout/flow.rs +++ b/components/layout/flow.rs @@ -992,6 +992,10 @@ impl BaseFlow { let mut flags = FlowFlags::empty(); match style { Some(style) => { + if style.can_be_fragmented() { + flags.insert(FlowFlags::CAN_BE_FRAGMENTED); + } + match style.get_box().position { Position::Absolute | Position::Fixed => { flags.insert(FlowFlags::IS_ABSOLUTELY_POSITIONED); diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs index 8dac0180171..f1729f01b0f 100644 --- a/components/layout/traversal.rs +++ b/components/layout/traversal.rs @@ -280,7 +280,8 @@ impl<'a> PostorderFlowTraversal for AssignBSizes<'a> { fn should_process(&self, flow: &mut Flow) -> bool { let base = flow.base(); base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) && - // The fragmentation countainer is responsible for calling Flow::fragment recursively + // The fragmentation countainer is responsible for calling + // Flow::fragment recursively !base.flags.contains(FlowFlags::CAN_BE_FRAGMENTED) } } diff --git a/components/layout_thread/dom_wrapper.rs b/components/layout_thread/dom_wrapper.rs index 82a9678d7da..e595ac06f45 100644 --- a/components/layout_thread/dom_wrapper.rs +++ b/components/layout_thread/dom_wrapper.rs @@ -209,17 +209,9 @@ impl<'ln> TNode for ServoLayoutNode<'ln> { self.node.downcast().map(ServoLayoutDocument::from_layout_js) } - fn can_be_fragmented(&self) -> bool { - unsafe { self.node.get_flag(NodeFlags::CAN_BE_FRAGMENTED) } - } - fn is_in_document(&self) -> bool { unsafe { self.node.get_flag(NodeFlags::IS_IN_DOC) } } - - unsafe fn set_can_be_fragmented(&self, value: bool) { - self.node.set_flag(NodeFlags::CAN_BE_FRAGMENTED, value) - } } impl<'ln> LayoutNode for ServoLayoutNode<'ln> { @@ -930,10 +922,6 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> { self.node } - fn can_be_fragmented(&self) -> bool { - self.node.can_be_fragmented() - } - fn node_text_content(&self) -> String { let this = unsafe { self.get_jsmanaged() }; return this.text_content(); diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 664afb72e97..91df38cf1f6 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -164,10 +164,7 @@ bitflags! { to be reachable with using sequential focus navigation."] const SEQUENTIALLY_FOCUSABLE = 1 << 3; - /// Whether any ancestor is a fragmentation container - const CAN_BE_FRAGMENTED = 1 << 4; - - // There's a free bit here. + // There are two free bits here. #[doc = "Specifies whether the parser has set an associated form owner for \ this element. Only applicable for form-associatable elements."] diff --git a/components/script_layout_interface/wrapper_traits.rs b/components/script_layout_interface/wrapper_traits.rs index 49f157f9158..8a47117a0ce 100644 --- a/components/script_layout_interface/wrapper_traits.rs +++ b/components/script_layout_interface/wrapper_traits.rs @@ -240,8 +240,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo /// data flags, and we have this annoying trait separation between script and layout :-( unsafe fn unsafe_get(self) -> Self::ConcreteNode; - fn can_be_fragmented(&self) -> bool; - fn node_text_content(&self) -> String; /// If the insertion point is within this node, returns it. Otherwise, returns `None`. diff --git a/components/style/dom.rs b/components/style/dom.rs index 90f4933b5ef..ea438b66dd9 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -239,13 +239,6 @@ pub trait TNode : Sized + Copy + Clone + Debug + NodeInfo + PartialEq { /// Get this node as a document, if it's one. fn as_document(&self) -> Option<Self::ConcreteDocument>; - - /// Whether this node can be fragmented. This is used for multicol, and only - /// for Servo. - fn can_be_fragmented(&self) -> bool; - - /// Set whether this node can be fragmented. - unsafe fn set_can_be_fragmented(&self, value: bool); } /// Wrapper to output the subtree rather than the single node when formatting diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 32871baf50a..66b7f538dd6 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -345,18 +345,6 @@ impl<'ln> TNode for GeckoNode<'ln> { None } } - - #[inline] - fn can_be_fragmented(&self) -> bool { - // FIXME(SimonSapin): Servo uses this to implement CSS multicol / fragmentation - // Maybe this isn’t useful for Gecko? - false - } - - unsafe fn set_can_be_fragmented(&self, _value: bool) { - // FIXME(SimonSapin): Servo uses this to implement CSS multicol / fragmentation - // Maybe this isn’t useful for Gecko? - } } /// A wrapper on top of two kind of iterators, depending on the parent being diff --git a/components/style/matching.rs b/components/style/matching.rs index 83000be5274..cf6da78bc19 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -504,7 +504,6 @@ pub trait MatchMethods : TElement { mut new_styles: ResolvedElementStyles, important_rules_changed: bool, ) -> ChildCascadeRequirement { - use dom::TNode; use std::cmp; self.process_animations( @@ -518,24 +517,6 @@ pub trait MatchMethods : TElement { // First of all, update the styles. let old_styles = data.set_styles(new_styles); - // Propagate the "can be fragmented" bit. It would be nice to - // encapsulate this better. - if cfg!(feature = "servo") { - let layout_parent = - self.inheritance_parent().map(|e| e.layout_parent()); - let layout_parent_data = - layout_parent.as_ref().and_then(|e| e.borrow_data()); - let layout_parent_style = - layout_parent_data.as_ref().map(|d| d.styles.primary()); - - if let Some(ref p) = layout_parent_style { - let can_be_fragmented = - p.is_multicol() || - layout_parent.as_ref().unwrap().as_node().can_be_fragmented(); - unsafe { self.as_node().set_can_be_fragmented(can_be_fragmented); } - } - } - let new_primary_style = data.styles.primary.as_ref().unwrap(); let mut cascade_requirement = ChildCascadeRequirement::CanSkipCascade; diff --git a/components/style/properties/computed_value_flags.rs b/components/style/properties/computed_value_flags.rs index ca045946201..612f7c0470b 100644 --- a/components/style/properties/computed_value_flags.rs +++ b/components/style/properties/computed_value_flags.rs @@ -62,6 +62,11 @@ bitflags! { /// A flag to mark a style which is a visited style. const IS_STYLE_IF_VISITED = 1 << 9; + + /// Whether the style or any of the ancestors has a multicol style. + /// + /// Only used in Servo. + const CAN_BE_FRAGMENTED = 1 << 10; } } diff --git a/components/style/properties/gecko.mako.rs b/components/style/properties/gecko.mako.rs index 3f8cd13a103..1c3e30f97ec 100644 --- a/components/style/properties/gecko.mako.rs +++ b/components/style/properties/gecko.mako.rs @@ -300,10 +300,6 @@ impl ComputedValuesInner { !self.get_box().gecko.mBinding.mRawPtr.is_null() } - // FIXME(bholley): Implement this properly. - #[inline] - pub fn is_multicol(&self) -> bool { false } - pub fn to_declaration_block(&self, property: PropertyDeclarationId) -> PropertyDeclarationBlock { let value = match property { % for prop in data.longhands: diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index fa8a1fdf1fa..cbc2b685828 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -2049,6 +2049,18 @@ pub mod style_structs { .take(self.transition_property_count()) .any(|t| t.seconds() > 0.) } + % elif style_struct.name == "Column": + /// Whether this is a multicol style. + #[cfg(feature = "servo")] + pub fn is_multicol(&self) -> bool { + match self.column_width { + Either::First(_width) => true, + Either::Second(_auto) => match self.column_count { + Either::First(_n) => true, + Either::Second(_auto) => false, + } + } + } % endif } @@ -2267,17 +2279,16 @@ impl ComputedValuesInner { } } + /// Whether the current style or any of its ancestors is multicolumn. + #[inline] + pub fn can_be_fragmented(&self) -> bool { + self.flags.contains(ComputedValueFlags::CAN_BE_FRAGMENTED) + } + /// Whether the current style is multicolumn. #[inline] pub fn is_multicol(&self) -> bool { - let style = self.get_column(); - match style.column_width { - Either::First(_width) => true, - Either::Second(_auto) => match style.column_count { - Either::First(_n) => true, - Either::Second(_auto) => false, - } - } + self.get_column().is_multicol() } /// Resolves the currentColor keyword. diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 965d61af10a..4da9f0f9227 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -104,6 +104,15 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { self.style.is_pseudo_element() { self.style.flags.insert(ComputedValueFlags::IS_IN_PSEUDO_ELEMENT_SUBTREE); } + + #[cfg(feature = "servo")] + { + if self.style.inherited_flags().contains(ComputedValueFlags::CAN_BE_FRAGMENTED) || + self.style.get_parent_column().is_multicol() + { + self.style.flags.insert(ComputedValueFlags::CAN_BE_FRAGMENTED); + } + } } /// Adjust the style for text style. |