layout: Don't delete non-text boxes from the list of input boxes when

flushing text clumps. Fixes this page:

    http://en.wikipedia.org/wiki/Yellow_River

This is not the most efficient thing to do; a FIXME has been added
noting what is most correct.
This commit is contained in:
Patrick Walton 2013-12-11 14:35:13 -08:00
parent c9c9984d47
commit dcacab8149
4 changed files with 22 additions and 12 deletions

View file

@ -982,10 +982,13 @@ impl Box {
} }
/// Returns a debugging string describing this box. /// Returns a debugging string describing this box.
///
/// TODO(pcwalton): Reimplement.
pub fn debug_str(&self) -> ~str { pub fn debug_str(&self) -> ~str {
~"(Box)" match self.specific {
GenericBox => "(GenericBox)",
ImageBox(_) => "(ImageBox)",
ScannedTextBox(_) => "(ScannedTextBox)",
UnscannedTextBox(_) => "(UnscannedTextBox)",
}.to_str()
} }
} }

View file

@ -280,6 +280,9 @@ impl<'self> FlowConstructor<'self> {
// Flush any inline boxes that we were gathering up. This allows us to handle // Flush any inline boxes that we were gathering up. This allows us to handle
// {ib} splits. // {ib} splits.
debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref()
.map_default(0, |boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow, self.flush_inline_boxes_to_flow_if_necessary(&mut opt_boxes_for_inline_flow,
flow, flow,
node); node);
@ -312,6 +315,10 @@ impl<'self> FlowConstructor<'self> {
} }
// Flush any inline boxes that we were gathering up. // Flush any inline boxes that we were gathering up.
debug!("flushing {} inline box(es) to flow A",
opt_boxes_for_inline_flow.as_ref()
.map_default(0,
|boxes| boxes.len()));
self.flush_inline_boxes_to_flow_if_necessary( self.flush_inline_boxes_to_flow_if_necessary(
&mut opt_boxes_for_inline_flow, &mut opt_boxes_for_inline_flow,
flow, flow,
@ -473,6 +480,8 @@ impl<'self> PostorderNodeMutTraversal for FlowConstructor<'self> {
DocumentNodeTypeId(_) => (display::none, float::none), DocumentNodeTypeId(_) => (display::none, float::none),
}; };
debug!("building flow for node: {:?} {:?}", display, float);
// Switch on display and floatedness. // Switch on display and floatedness.
match (display, float) { match (display, float) {
// `display: none` contributes no flow construction result. Nuke the flow construction // `display: none` contributes no flow construction result. Nuke the flow construction
@ -573,6 +582,7 @@ fn strip_ignorable_whitespace_from_start(opt_boxes: &mut Option<~[Box]>) {
let mut result = ~[]; let mut result = ~[];
for box in boxes.move_iter() { for box in boxes.move_iter() {
if !found_nonwhitespace && box.is_whitespace_only() { if !found_nonwhitespace && box.is_whitespace_only() {
debug!("stripping ignorable whitespace from start");
continue continue
} }
@ -591,6 +601,7 @@ fn strip_ignorable_whitespace_from_end(opt_boxes: &mut Option<~[Box]>) {
None => {} None => {}
Some(ref mut boxes) => { Some(ref mut boxes) => {
while boxes.len() > 0 && boxes.last().is_whitespace_only() { while boxes.len() > 0 && boxes.last().is_whitespace_only() {
debug!("stripping ignorable whitespace from end");
let _ = boxes.pop(); let _ = boxes.pop();
} }
} }

View file

@ -28,9 +28,6 @@ impl TextRunScanner {
pub fn scan_for_runs(&mut self, ctx: &mut LayoutContext, flow: &mut Flow) { pub fn scan_for_runs(&mut self, ctx: &mut LayoutContext, flow: &mut Flow) {
{ {
let inline = flow.as_immutable_inline(); let inline = flow.as_immutable_inline();
// FIXME: this assertion fails on wikipedia, but doesn't seem
// to cause problems.
// assert!(inline.boxes.len() > 0);
debug!("TextRunScanner: scanning {:u} boxes for text runs...", inline.boxes.len()); debug!("TextRunScanner: scanning {:u} boxes for text runs...", inline.boxes.len());
} }
@ -71,9 +68,8 @@ impl TextRunScanner {
/// for correct painting order. Since we compress several leaf boxes here, the mapping must be /// for correct painting order. Since we compress several leaf boxes here, the mapping must be
/// adjusted. /// adjusted.
/// ///
/// N.B. `in_boxes` is passed by reference, since the old code used a `DVec`. The caller is /// FIXME(pcwalton): Stop cloning boxes. Instead we will need to consume the `in_box`es as we
/// responsible for swapping out the list. It is not clear to me (pcwalton) that this is still /// iterate over them.
/// necessary.
pub fn flush_clump_to_list(&mut self, pub fn flush_clump_to_list(&mut self,
ctx: &mut LayoutContext, ctx: &mut LayoutContext,
flow: &mut Flow, flow: &mut Flow,
@ -99,10 +95,9 @@ impl TextRunScanner {
fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!") fail!(~"WAT: can't coalesce non-text nodes in flush_clump_to_list()!")
} }
(true, false) => { (true, false) => {
// FIXME(pcwalton): Stop cloning boxes, as above.
debug!("TextRunScanner: pushing single non-text box in range: {}", self.clump); debug!("TextRunScanner: pushing single non-text box in range: {}", self.clump);
// out_boxes.push(in_boxes[self.clump.begin()]); out_boxes.push(in_boxes[self.clump.begin()].clone());
let first_box = in_boxes.remove(self.clump.begin());
out_boxes.push(first_box);
}, },
(true, true) => { (true, true) => {
let old_box = &in_boxes[self.clump.begin()]; let old_box = &in_boxes[self.clump.begin()];

View file

@ -0,0 +1 @@
<a><img></a> <div>a</div>