aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilio Cobos Álvarez <emilio@crisal.io>2018-01-04 14:45:54 +0100
committerEmilio Cobos Álvarez <emilio@crisal.io>2018-01-04 14:45:54 +0100
commitf3ea2481884ec957d7c4f5fa2fc395753f4a574f (patch)
tree1824830484d93d11d9c01fbe990b0d562c563e8a
parent10a1e1e15f713756ebb38509d619abb3c79a1f25 (diff)
downloadservo-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.rs18
-rw-r--r--components/layout/flow.rs4
-rw-r--r--components/layout/traversal.rs3
-rw-r--r--components/layout_thread/dom_wrapper.rs12
-rw-r--r--components/script/dom/node.rs5
-rw-r--r--components/script_layout_interface/wrapper_traits.rs2
-rw-r--r--components/style/dom.rs7
-rw-r--r--components/style/gecko/wrapper.rs12
-rw-r--r--components/style/matching.rs19
-rw-r--r--components/style/properties/computed_value_flags.rs5
-rw-r--r--components/style/properties/gecko.mako.rs4
-rw-r--r--components/style/properties/properties.mako.rs27
-rw-r--r--components/style/style_adjuster.rs9
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.