mirror of
https://github.com/servo/servo.git
synced 2025-06-18 22:34:30 +01:00
layout: Destroy flows properly under display: none
.
Fixes a crash on http://en.wikipedia.org/wiki/South_China_Sea It plants a destructor bomb on flows so that this can't happen again.
This commit is contained in:
parent
6662fb0c32
commit
5cc744d25d
3 changed files with 86 additions and 15 deletions
|
@ -26,7 +26,7 @@ use layout::box_::{Box, GenericBox, IframeBox, IframeBoxInfo, ImageBox, ImageBox
|
|||
use layout::box_::{UnscannedTextBox, UnscannedTextBoxInfo, InlineInfo, InlineParentInfo};
|
||||
use layout::context::LayoutContext;
|
||||
use layout::float_context::FloatType;
|
||||
use layout::flow::{BaseFlow, Flow, MutableOwnedFlowUtils};
|
||||
use layout::flow::{BaseFlow, Flow, LeafSet, MutableOwnedFlowUtils};
|
||||
use layout::inline::InlineFlow;
|
||||
use layout::text::TextRunScanner;
|
||||
use layout::util::LayoutDataAccess;
|
||||
|
@ -56,6 +56,16 @@ pub enum ConstructionResult {
|
|||
ConstructionItemConstructionResult(ConstructionItem),
|
||||
}
|
||||
|
||||
impl ConstructionResult {
|
||||
fn destroy(&mut self, leaf_set: &mut LeafSet) {
|
||||
match *self {
|
||||
NoConstructionResult => {}
|
||||
FlowConstructionResult(ref mut flow) => flow.destroy(leaf_set),
|
||||
ConstructionItemConstructionResult(ref mut item) => item.destroy(leaf_set),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents the output of flow construction for a DOM node that has not yet resulted in a
|
||||
/// complete flow. Construction items bubble up the tree until they find a `Flow` to be
|
||||
/// attached to.
|
||||
|
@ -64,6 +74,20 @@ enum ConstructionItem {
|
|||
InlineBoxesConstructionItem(InlineBoxesConstructionResult),
|
||||
}
|
||||
|
||||
impl ConstructionItem {
|
||||
fn destroy(&mut self, leaf_set: &mut LeafSet) {
|
||||
match *self {
|
||||
InlineBoxesConstructionItem(ref mut result) => {
|
||||
for splits in result.splits.mut_iter() {
|
||||
for split in splits.mut_iter() {
|
||||
split.destroy(leaf_set)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents inline boxes and {ib} splits that are bubbling up from an inline.
|
||||
struct InlineBoxesConstructionResult {
|
||||
/// Any {ib} splits that we're bubbling up.
|
||||
|
@ -107,6 +131,12 @@ struct InlineBlockSplit {
|
|||
flow: ~Flow,
|
||||
}
|
||||
|
||||
impl InlineBlockSplit {
|
||||
fn destroy(&mut self, leaf_set: &mut LeafSet) {
|
||||
self.flow.destroy(leaf_set)
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods on optional vectors.
|
||||
///
|
||||
/// TODO(pcwalton): I think this will no longer be necessary once Rust #8981 lands.
|
||||
|
@ -539,9 +569,12 @@ impl<'a> PostorderNodeMutTraversal for FlowConstructor<'a> {
|
|||
// `display: none` contributes no flow construction result. Nuke the flow construction
|
||||
// results of children.
|
||||
(display::none, _, _) => {
|
||||
for child in node.children() {
|
||||
child.set_flow_construction_result(NoConstructionResult)
|
||||
}
|
||||
self.layout_context.shared.leaf_set.access(|leaf_set| {
|
||||
for child in node.children() {
|
||||
let mut old_result = child.swap_out_construction_result();
|
||||
old_result.destroy(leaf_set)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Inline items contribute inline box construction results.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue