introduce the concept of a height-adjustable structural box

Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BoxFactory.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BoxFactory.java
index 39700ea..39be6e6 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BoxFactory.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/BoxFactory.java
@@ -177,7 +177,7 @@
 		return tableRow;
 	}
 
-	public static TableCell tableCell(final IStructuralBox component) {
+	public static TableCell tableCell(final IHeightAdjustableBox component) {
 		final TableCell tableCell = new TableCell();
 		tableCell.setComponent(component);
 		return tableCell;
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IHeightAdjustableBox.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IHeightAdjustableBox.java
new file mode 100644
index 0000000..24f23e1
--- /dev/null
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/IHeightAdjustableBox.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 2016 Florian Thienel and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * 		Florian Thienel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.vex.core.internal.boxes;
+
+/**
+ * @author Florian Thienel
+ */
+public interface IHeightAdjustableBox extends IStructuralBox {
+
+	void setHeight(int height);
+
+}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
index 2495bce..ee3c244 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/StructuralFrame.java
@@ -17,7 +17,7 @@
 /**
  * @author Florian Thienel
  */
-public class StructuralFrame extends BaseBox implements IStructuralBox, IDecoratorBox<IStructuralBox> {
+public class StructuralFrame extends BaseBox implements IHeightAdjustableBox, IDecoratorBox<IStructuralBox> {
 
 	private IBox parent;
 	private int top;
@@ -85,6 +85,7 @@
 		return height;
 	}
 
+	@Override
 	public void setHeight(final int height) {
 		this.height = height;
 	}
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
index 03a7b45..d64911c 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/boxes/TableCell.java
@@ -16,14 +16,14 @@
 /**
  * @author Florian Thienel
  */
-public class TableCell extends BaseBox implements IStructuralBox, IDecoratorBox<IStructuralBox> {
+public class TableCell extends BaseBox implements IStructuralBox, IDecoratorBox<IHeightAdjustableBox> {
 
 	private IBox parent;
 	private int top;
 	private int left;
 	private int width;
 
-	private IStructuralBox component;
+	private IHeightAdjustableBox component;
 
 	private int startColumnIndex;
 	private int endColumnIndex;
@@ -113,13 +113,13 @@
 		return visitor.visit(this);
 	}
 
-	public void setComponent(final IStructuralBox component) {
+	public void setComponent(final IHeightAdjustableBox component) {
 		this.component = component;
 		component.setParent(this);
 	}
 
 	@Override
-	public IStructuralBox getComponent() {
+	public IHeightAdjustableBox getComponent() {
 		return component;
 	}
 
@@ -199,21 +199,11 @@
 		}
 
 		component.setPosition(0, 0);
-		adjustFrameHeight();
+		adjustComponentHeight();
 	}
 
-	private void adjustFrameHeight() {
-		final StructuralFrame frame = accept(new DepthFirstBoxTraversal<StructuralFrame>() {
-			@Override
-			public StructuralFrame visit(final StructuralFrame box) {
-				return box;
-			}
-		});
-		if (frame == null) {
-			return;
-		}
-
-		frame.setHeight(usedHeight);
+	private void adjustComponentHeight() {
+		component.setHeight(usedHeight);
 	}
 
 	@Override
@@ -226,7 +216,7 @@
 		}
 
 		component.setPosition(0, 0);
-		adjustFrameHeight();
+		adjustComponentHeight();
 		return true;
 	}
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/visualization/CssBasedBoxModelBuilder.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/visualization/CssBasedBoxModelBuilder.java
index b929ded..a45df61 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/visualization/CssBasedBoxModelBuilder.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/visualization/CssBasedBoxModelBuilder.java
@@ -51,6 +51,7 @@
 import org.eclipse.vex.core.internal.boxes.LineWrappingRule;
 import org.eclipse.vex.core.internal.boxes.Paragraph;
 import org.eclipse.vex.core.internal.boxes.RootBox;
+import org.eclipse.vex.core.internal.boxes.StructuralFrame;
 import org.eclipse.vex.core.internal.boxes.Table;
 import org.eclipse.vex.core.internal.boxes.TableCell;
 import org.eclipse.vex.core.internal.boxes.TableColumnSpec;
@@ -315,7 +316,8 @@
 	}
 
 	private IStructuralBox visualizeAsTableCell(final IElement element, final Styles styles, final Collection<VisualizeResult> childrenResults) {
-		final TableCell cell = tableCell(wrapUpStructuralElementContent(element, styles, childrenResults, visualizeStructuralElementContent(element, styles, childrenResults)));
+		final IStructuralBox cellContent = visualizeStructuralElementContent(element, styles, childrenResults);
+		final TableCell cell = tableCell(frame(surroundWithPseudoElements(cellContent, element, styles), styles));
 
 		if ("entry".equals(element.getLocalName())) {
 			final IAttribute colName = element.getAttribute("colname");
@@ -339,7 +341,7 @@
 			// TODO HTML table
 		}
 
-		return cell;
+		return wrapWithNodeReference(element, childrenResults, cell);
 	}
 
 	private static int toInt(final IAttribute attribute) {
@@ -481,14 +483,19 @@
 	}
 
 	private static IStructuralBox wrapUpStructuralElementContent(final IElement element, final Styles styles, final Collection<VisualizeResult> childrenResults, final IStructuralBox content) {
+		final StructuralFrame frame = frame(surroundWithPseudoElements(content, element, styles), styles);
+		return wrapWithNodeReference(element, childrenResults, frame);
+	}
+
+	private static IStructuralBox wrapWithNodeReference(final IElement element, final Collection<VisualizeResult> childrenResults, final IStructuralBox content) {
 		final boolean mayContainText = mayContainText(element);
 		final boolean containsInlineContent = containsInlineContent(childrenResults);
 		if (mayContainText) {
-			return nodeReferenceWithText(element, frame(surroundWithPseudoElements(content, element, styles), styles));
+			return nodeReferenceWithText(element, content);
 		} else if (containsInlineContent) {
-			return nodeReferenceWithInlineContent(element, frame(surroundWithPseudoElements(content, element, styles), styles));
+			return nodeReferenceWithInlineContent(element, content);
 		} else {
-			return nodeReference(element, frame(surroundWithPseudoElements(content, element, styles), styles));
+			return nodeReference(element, content);
 		}
 	}
 
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMVisualization.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMVisualization.java
index 57a501d..d231581 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMVisualization.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMVisualization.java
@@ -18,6 +18,8 @@
 import org.eclipse.vex.core.internal.boxes.BaseBoxVisitor;
 import org.eclipse.vex.core.internal.boxes.IBox;
 import org.eclipse.vex.core.internal.boxes.IContentBox;
+import org.eclipse.vex.core.internal.boxes.IHeightAdjustableBox;
+import org.eclipse.vex.core.internal.boxes.IStructuralBox;
 import org.eclipse.vex.core.internal.boxes.InlineContainer;
 import org.eclipse.vex.core.internal.boxes.InlineFrame;
 import org.eclipse.vex.core.internal.boxes.InlineNodeReference;
@@ -163,7 +165,9 @@
 
 			@Override
 			public void visit(final TableCell box) {
-				box.setComponent(boxModelBuilder.visualizeStructure(node));
+				final IStructuralBox component = boxModelBuilder.visualizeStructure(node);
+				Assert.isTrue(component instanceof IHeightAdjustableBox);
+				box.setComponent((IHeightAdjustableBox) component);
 			}
 
 			@Override