mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Stop generating flows under display: none.
Because this is a bottom-up traversal it can generates flows and throw them away. To prevent that, this cascades an internal `-servo-under-display-none` property and then checks that during flow construction. Fixes #1536.
This commit is contained in:
parent
116faa7617
commit
5c09e26e55
5 changed files with 50 additions and 10 deletions
|
@ -1501,7 +1501,15 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadS
|
||||||
//
|
//
|
||||||
// TODO: This should actually consult the table in that section to get the
|
// TODO: This should actually consult the table in that section to get the
|
||||||
// final computed value for 'display'.
|
// final computed value for 'display'.
|
||||||
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) -> bool {
|
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) {
|
||||||
|
node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
|
||||||
|
|
||||||
|
// Bail out if this node has an ancestor with display: none.
|
||||||
|
if node.style(self.style_context()).get_inheritedbox()._servo_under_display_none.0 {
|
||||||
|
self.set_flow_construction_result(node, ConstructionResult::None);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the `display` property for this node, and determine whether this node is floated.
|
// Get the `display` property for this node, and determine whether this node is floated.
|
||||||
let (display, float, positioning) = match node.type_id() {
|
let (display, float, positioning) = match node.type_id() {
|
||||||
None => {
|
None => {
|
||||||
|
@ -1542,12 +1550,8 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadS
|
||||||
|
|
||||||
// Switch on display and floatedness.
|
// Switch on display and floatedness.
|
||||||
match (display, float, positioning) {
|
match (display, float, positioning) {
|
||||||
// `display: none` contributes no flow construction result. Nuke the flow construction
|
// `display: none` contributes no flow construction result.
|
||||||
// results of children.
|
|
||||||
(display::T::none, _, _) => {
|
(display::T::none, _, _) => {
|
||||||
for child in node.children() {
|
|
||||||
self.set_flow_construction_result(&child, ConstructionResult::None);
|
|
||||||
}
|
|
||||||
self.set_flow_construction_result(node, ConstructionResult::None);
|
self.set_flow_construction_result(node, ConstructionResult::None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1654,9 +1658,6 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadS
|
||||||
self.set_flow_construction_result(node, construction_result)
|
self.set_flow_construction_result(node, construction_result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ pub fn compute_damage(old: Option<&Arc<ServoComputedValues>>, new: &ServoCompute
|
||||||
], [
|
], [
|
||||||
get_box.float, get_box.display, get_box.position, get_counters.content,
|
get_box.float, get_box.display, get_box.position, get_counters.content,
|
||||||
get_counters.counter_reset, get_counters.counter_increment,
|
get_counters.counter_reset, get_counters.counter_increment,
|
||||||
|
get_inheritedbox._servo_under_display_none,
|
||||||
get_list.quotes, get_list.list_style_type,
|
get_list.quotes, get_list.list_style_type,
|
||||||
|
|
||||||
// If these text or font properties change, we need to reconstruct the flow so that
|
// If these text or font properties change, we need to reconstruct the flow so that
|
||||||
|
|
|
@ -72,7 +72,7 @@ impl<'lc, 'ln> DomTraversalContext<ServoLayoutNode<'ln>> for RecalcStyleAndConst
|
||||||
/// A bottom-up, parallelizable traversal.
|
/// A bottom-up, parallelizable traversal.
|
||||||
pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> {
|
pub trait PostorderNodeMutTraversal<ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode> {
|
||||||
/// The operation to perform. Return true to continue or false to stop.
|
/// The operation to perform. Return true to continue or false to stop.
|
||||||
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) -> bool;
|
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The flow construction traversal, which builds flows for styled nodes.
|
/// The flow construction traversal, which builds flows for styled nodes.
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
|
_error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
|
||||||
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
|
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
|
||||||
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
|
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
|
||||||
|
longhands::_servo_under_display_none::derive_from_display(context);
|
||||||
}
|
}
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
|
|
@ -88,3 +88,40 @@ ${helpers.single_keyword("color-adjust", "economy exact", products="gecko")}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</%helpers:longhand>
|
</%helpers:longhand>
|
||||||
|
|
||||||
|
// Used in the bottom-up flow construction traversal to avoid constructing flows for
|
||||||
|
// descendants of nodes with `display: none`.
|
||||||
|
<%helpers:longhand name="-servo-under-display-none" derived_from="display" products="servo">
|
||||||
|
use cssparser::ToCss;
|
||||||
|
use std::fmt;
|
||||||
|
use values::computed::ComputedValueAsSpecified;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, HeapSizeOf, Serialize, Deserialize)]
|
||||||
|
pub struct SpecifiedValue(pub bool);
|
||||||
|
|
||||||
|
pub mod computed_value {
|
||||||
|
pub type T = super::SpecifiedValue;
|
||||||
|
}
|
||||||
|
impl ComputedValueAsSpecified for SpecifiedValue {}
|
||||||
|
|
||||||
|
pub fn get_initial_value() -> computed_value::T {
|
||||||
|
SpecifiedValue(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToCss for SpecifiedValue {
|
||||||
|
fn to_css<W>(&self, _: &mut W) -> fmt::Result where W: fmt::Write {
|
||||||
|
Ok(()) // Internal property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn derive_from_display<Cx: TContext>(context: &mut Cx) {
|
||||||
|
use properties::style_struct_traits::Box;
|
||||||
|
use super::display::computed_value::T as Display;
|
||||||
|
|
||||||
|
if context.style().get_box().clone_display() == Display::none {
|
||||||
|
context.mutate_style().mutate_inheritedbox()
|
||||||
|
.set__servo_under_display_none(SpecifiedValue(true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</%helpers:longhand>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue