mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Handle cases where the layout root is None. Fixes #6375.
This commit is contained in:
parent
0bc7ad9b08
commit
a02d28a732
4 changed files with 199 additions and 99 deletions
|
@ -2436,7 +2436,7 @@ pub trait ISizeAndMarginsComputer {
|
||||||
|
|
||||||
// Invariant: inline-start_margin + inline-size + inline-end_margin ==
|
// Invariant: inline-start_margin + inline-size + inline-end_margin ==
|
||||||
// available_inline-size
|
// available_inline-size
|
||||||
let (inline_start_margin, mut inline_size, inline_end_margin) =
|
let (inline_start_margin, inline_size, inline_end_margin) =
|
||||||
match (inline_start_margin, computed_inline_size, inline_end_margin) {
|
match (inline_start_margin, computed_inline_size, inline_end_margin) {
|
||||||
// If all have a computed value other than 'auto', the system is over-constrained.
|
// If all have a computed value other than 'auto', the system is over-constrained.
|
||||||
(MaybeAuto::Specified(margin_start),
|
(MaybeAuto::Specified(margin_start),
|
||||||
|
@ -2922,7 +2922,7 @@ impl ISizeAndMarginsComputer for InlineBlockNonReplaced {
|
||||||
block: &mut BlockFlow,
|
block: &mut BlockFlow,
|
||||||
input: &ISizeConstraintInput)
|
input: &ISizeConstraintInput)
|
||||||
-> ISizeConstraintSolution {
|
-> ISizeConstraintSolution {
|
||||||
let (mut computed_inline_size,
|
let (computed_inline_size,
|
||||||
inline_start_margin,
|
inline_start_margin,
|
||||||
inline_end_margin,
|
inline_end_margin,
|
||||||
available_inline_size) =
|
available_inline_size) =
|
||||||
|
@ -2963,7 +2963,7 @@ impl ISizeAndMarginsComputer for InlineBlockReplaced {
|
||||||
MaybeAuto::Auto => false,
|
MaybeAuto::Auto => false,
|
||||||
});
|
});
|
||||||
|
|
||||||
let (mut computed_inline_size,
|
let (computed_inline_size,
|
||||||
inline_start_margin,
|
inline_start_margin,
|
||||||
inline_end_margin,
|
inline_end_margin,
|
||||||
available_inline_size) =
|
available_inline_size) =
|
||||||
|
|
|
@ -156,6 +156,14 @@ pub struct LayoutTaskData {
|
||||||
pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, DefaultState<FnvHasher>>>,
|
pub visible_rects: Arc<HashMap<LayerId, Rect<Au>, DefaultState<FnvHasher>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl LayoutTaskData {
|
||||||
|
pub fn layout_root(&self) -> Option<FlowRef> {
|
||||||
|
self.root_flow.as_ref().map(|root_flow| {
|
||||||
|
root_flow.clone()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Information needed by the layout task.
|
/// Information needed by the layout task.
|
||||||
pub struct LayoutTask {
|
pub struct LayoutTask {
|
||||||
/// The ID of the pipeline that we belong to.
|
/// The ID of the pipeline that we belong to.
|
||||||
|
@ -786,10 +794,6 @@ impl LayoutTask {
|
||||||
Some(flow)
|
Some(flow)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_layout_root(&self, node: LayoutNode) -> FlowRef {
|
|
||||||
self.try_get_layout_root(node).expect("no layout root")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Performs layout constraint solving.
|
/// Performs layout constraint solving.
|
||||||
///
|
///
|
||||||
/// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
|
/// This corresponds to `Reflow()` in Gecko and `layout()` in WebKit/Blink and should be
|
||||||
|
@ -1161,7 +1165,7 @@ impl LayoutTask {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Retrieve the (possibly rebuilt) root flow.
|
// Retrieve the (possibly rebuilt) root flow.
|
||||||
rw_data.root_flow = Some(self.get_layout_root((*node).clone()));
|
rw_data.root_flow = self.try_get_layout_root((*node).clone());
|
||||||
|
|
||||||
// Kick off animations if any were triggered.
|
// Kick off animations if any were triggered.
|
||||||
animation::process_new_animations(&mut *rw_data, self.id);
|
animation::process_new_animations(&mut *rw_data, self.id);
|
||||||
|
@ -1178,22 +1182,22 @@ impl LayoutTask {
|
||||||
&mut rw_data,
|
&mut rw_data,
|
||||||
&mut shared_layout_context);
|
&mut shared_layout_context);
|
||||||
|
|
||||||
let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone();
|
if let Some(mut root_flow) = rw_data.layout_root() {
|
||||||
match data.query_type {
|
match data.query_type {
|
||||||
ReflowQueryType::ContentBoxQuery(node) =>
|
ReflowQueryType::ContentBoxQuery(node) =>
|
||||||
process_content_box_request(node, &mut root_flow, &mut rw_data),
|
process_content_box_request(node, &mut root_flow, &mut rw_data),
|
||||||
ReflowQueryType::ContentBoxesQuery(node) =>
|
ReflowQueryType::ContentBoxesQuery(node) =>
|
||||||
process_content_boxes_request(node, &mut root_flow, &mut rw_data),
|
process_content_boxes_request(node, &mut root_flow, &mut rw_data),
|
||||||
ReflowQueryType::NodeGeometryQuery(node) =>
|
ReflowQueryType::NodeGeometryQuery(node) =>
|
||||||
self.process_node_geometry_request(node, &mut root_flow, &mut rw_data),
|
self.process_node_geometry_request(node, &mut root_flow, &mut rw_data),
|
||||||
ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) =>
|
ReflowQueryType::ResolvedStyleQuery(node, ref pseudo, ref property) =>
|
||||||
self.process_resolved_style_request(node, pseudo, property, &mut root_flow, &mut rw_data),
|
self.process_resolved_style_request(node, pseudo, property, &mut root_flow, &mut rw_data),
|
||||||
ReflowQueryType::OffsetParentQuery(node) =>
|
ReflowQueryType::OffsetParentQuery(node) =>
|
||||||
self.process_offset_parent_query(node, &mut root_flow, &mut rw_data),
|
self.process_offset_parent_query(node, &mut root_flow, &mut rw_data),
|
||||||
ReflowQueryType::NoQuery => {}
|
ReflowQueryType::NoQuery => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Tell script that we're done.
|
// Tell script that we're done.
|
||||||
//
|
//
|
||||||
// FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without
|
// FIXME(pcwalton): This should probably be *one* channel, but we can't fix this without
|
||||||
|
@ -1279,23 +1283,16 @@ impl LayoutTask {
|
||||||
&self.url,
|
&self.url,
|
||||||
reflow_info.goal);
|
reflow_info.goal);
|
||||||
|
|
||||||
match rw_data.root_flow.as_ref() {
|
if let Some(mut root_flow) = rw_data.layout_root() {
|
||||||
None => {
|
// Perform an abbreviated style recalc that operates without access to the DOM.
|
||||||
// We haven't performed a single layout yet! Do nothing.
|
let animations = &*rw_data.running_animations;
|
||||||
return
|
profile(time::ProfilerCategory::LayoutStyleRecalc,
|
||||||
}
|
self.profiler_metadata(),
|
||||||
Some(ref root_flow) => {
|
self.time_profiler_chan.clone(),
|
||||||
// Perform an abbreviated style recalc that operates without access to the DOM.
|
|| {
|
||||||
let mut root_flow = (*root_flow).clone();
|
animation::recalc_style_for_animations(flow_ref::deref_mut(&mut root_flow),
|
||||||
let animations = &*rw_data.running_animations;
|
animations)
|
||||||
profile(time::ProfilerCategory::LayoutStyleRecalc,
|
});
|
||||||
self.profiler_metadata(),
|
|
||||||
self.time_profiler_chan.clone(),
|
|
||||||
|| {
|
|
||||||
animation::recalc_style_for_animations(flow_ref::deref_mut(&mut root_flow),
|
|
||||||
animations)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
self.perform_post_style_recalc_layout_passes(&reflow_info,
|
||||||
|
@ -1307,54 +1304,55 @@ impl LayoutTask {
|
||||||
data: &Reflow,
|
data: &Reflow,
|
||||||
rw_data: &mut LayoutTaskData,
|
rw_data: &mut LayoutTaskData,
|
||||||
layout_context: &mut SharedLayoutContext) {
|
layout_context: &mut SharedLayoutContext) {
|
||||||
let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone();
|
if let Some(mut root_flow) = rw_data.layout_root() {
|
||||||
profile(time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
profile(time::ProfilerCategory::LayoutRestyleDamagePropagation,
|
||||||
self.profiler_metadata(),
|
self.profiler_metadata(),
|
||||||
self.time_profiler_chan.clone(),
|
self.time_profiler_chan.clone(),
|
||||||
|| {
|
|| {
|
||||||
if opts::get().nonincremental_layout || flow_ref::deref_mut(&mut root_flow)
|
if opts::get().nonincremental_layout || flow_ref::deref_mut(&mut root_flow)
|
||||||
.compute_layout_damage()
|
.compute_layout_damage()
|
||||||
.contains(REFLOW_ENTIRE_DOCUMENT) {
|
.contains(REFLOW_ENTIRE_DOCUMENT) {
|
||||||
flow_ref::deref_mut(&mut root_flow).reflow_entire_document()
|
flow_ref::deref_mut(&mut root_flow).reflow_entire_document()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Verification of the flow tree, which ensures that all nodes were either marked as leaves
|
||||||
|
// or as non-leaves. This becomes a no-op in release builds. (It is inconsequential to
|
||||||
|
// memory safety but is a useful debugging tool.)
|
||||||
|
self.verify_flow_tree(&mut root_flow);
|
||||||
|
|
||||||
|
if opts::get().trace_layout {
|
||||||
|
layout_debug::begin_trace(root_flow.clone());
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Verification of the flow tree, which ensures that all nodes were either marked as leaves
|
// Resolve generated content.
|
||||||
// or as non-leaves. This becomes a no-op in release builds. (It is inconsequential to
|
profile(time::ProfilerCategory::LayoutGeneratedContent,
|
||||||
// memory safety but is a useful debugging tool.)
|
self.profiler_metadata(),
|
||||||
self.verify_flow_tree(&mut root_flow);
|
self.time_profiler_chan.clone(),
|
||||||
|
|| sequential::resolve_generated_content(&mut root_flow, &layout_context));
|
||||||
|
|
||||||
if opts::get().trace_layout {
|
// Perform the primary layout passes over the flow tree to compute the locations of all
|
||||||
layout_debug::begin_trace(root_flow.clone());
|
// the boxes.
|
||||||
|
profile(time::ProfilerCategory::LayoutMain,
|
||||||
|
self.profiler_metadata(),
|
||||||
|
self.time_profiler_chan.clone(),
|
||||||
|
|| {
|
||||||
|
match rw_data.parallel_traversal {
|
||||||
|
None => {
|
||||||
|
// Sequential mode.
|
||||||
|
self.solve_constraints(&mut root_flow, &layout_context)
|
||||||
|
}
|
||||||
|
Some(ref mut parallel) => {
|
||||||
|
// Parallel mode.
|
||||||
|
self.solve_constraints_parallel(parallel,
|
||||||
|
&mut root_flow,
|
||||||
|
&mut *layout_context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
self.perform_post_main_layout_passes(data, rw_data, layout_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Resolve generated content.
|
|
||||||
profile(time::ProfilerCategory::LayoutGeneratedContent,
|
|
||||||
self.profiler_metadata(),
|
|
||||||
self.time_profiler_chan.clone(),
|
|
||||||
|| sequential::resolve_generated_content(&mut root_flow, &layout_context));
|
|
||||||
|
|
||||||
// Perform the primary layout passes over the flow tree to compute the locations of all
|
|
||||||
// the boxes.
|
|
||||||
profile(time::ProfilerCategory::LayoutMain,
|
|
||||||
self.profiler_metadata(),
|
|
||||||
self.time_profiler_chan.clone(),
|
|
||||||
|| {
|
|
||||||
match rw_data.parallel_traversal {
|
|
||||||
None => {
|
|
||||||
// Sequential mode.
|
|
||||||
self.solve_constraints(&mut root_flow, &layout_context)
|
|
||||||
}
|
|
||||||
Some(ref mut parallel) => {
|
|
||||||
// Parallel mode.
|
|
||||||
self.solve_constraints_parallel(parallel,
|
|
||||||
&mut root_flow,
|
|
||||||
&mut *layout_context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
self.perform_post_main_layout_passes(data, rw_data, layout_context);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_post_main_layout_passes<'a>(&'a self,
|
fn perform_post_main_layout_passes<'a>(&'a self,
|
||||||
|
@ -1362,22 +1360,23 @@ impl LayoutTask {
|
||||||
rw_data: &mut LayoutTaskData,
|
rw_data: &mut LayoutTaskData,
|
||||||
layout_context: &mut SharedLayoutContext) {
|
layout_context: &mut SharedLayoutContext) {
|
||||||
// Build the display list if necessary, and send it to the painter.
|
// Build the display list if necessary, and send it to the painter.
|
||||||
let mut root_flow = (*rw_data.root_flow.as_ref().unwrap()).clone();
|
if let Some(mut root_flow) = rw_data.layout_root() {
|
||||||
self.compute_abs_pos_and_build_display_list(data,
|
self.compute_abs_pos_and_build_display_list(data,
|
||||||
&mut root_flow,
|
&mut root_flow,
|
||||||
&mut *layout_context,
|
&mut *layout_context,
|
||||||
rw_data);
|
rw_data);
|
||||||
self.first_reflow.set(false);
|
self.first_reflow.set(false);
|
||||||
|
|
||||||
if opts::get().trace_layout {
|
if opts::get().trace_layout {
|
||||||
layout_debug::end_trace();
|
layout_debug::end_trace();
|
||||||
|
}
|
||||||
|
|
||||||
|
if opts::get().dump_flow_tree {
|
||||||
|
root_flow.dump();
|
||||||
|
}
|
||||||
|
|
||||||
|
rw_data.generation += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if opts::get().dump_flow_tree {
|
|
||||||
root_flow.dump();
|
|
||||||
}
|
|
||||||
|
|
||||||
rw_data.generation += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn dirty_all_nodes(node: &mut LayoutNode) {
|
unsafe fn dirty_all_nodes(node: &mut LayoutNode) {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
[root-box-003.htm]
|
[root-box-003.htm]
|
||||||
type: reftest
|
type: reftest
|
||||||
expected: CRASH
|
expected: TIMEOUT
|
||||||
|
|
|
@ -1,3 +1,104 @@
|
||||||
[Document-createElement-namespace.html]
|
[Document-createElement-namespace.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
disabled: Issue 6386
|
[Created element's namespace in created XML document]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in created XHTML document]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in created SVG document]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in created MathML document]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in empty.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in empty.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in empty.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in minimal_html.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in minimal_html.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in minimal_html.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in svg.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in svg.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in svg.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in mathml.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in mathml.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in mathml.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_xhtml.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_xhtml.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_xhtml.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_svg.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_svg.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_svg.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_mathml.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_mathml.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in bare_mathml.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_removed.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_removed.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_removed.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_changed.xhtml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_changed.xml]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[Created element's namespace in xhtml_ns_changed.svg]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue