remove dependency to layout box model
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java
index 09a4a62..f06433d 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/AbstractNavigateTableCellHandler.java
@@ -10,10 +10,16 @@
*******************************************************************************/
package org.eclipse.vex.ui.internal.handlers;
+import java.util.NoSuchElementException;
+
import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.vex.core.internal.layout.Box;
-import org.eclipse.vex.core.internal.layout.TableRowBox;
-import org.eclipse.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.vex.core.IFilter;
+import org.eclipse.vex.core.internal.css.CSS;
+import org.eclipse.vex.core.internal.css.StyleSheet;
+import org.eclipse.vex.core.provisional.dom.IAxis;
+import org.eclipse.vex.core.provisional.dom.IElement;
+import org.eclipse.vex.core.provisional.dom.INode;
+import org.eclipse.vex.core.provisional.dom.IParent;
import org.eclipse.vex.ui.internal.swt.VexWidget;
/**
@@ -25,20 +31,16 @@
@Override
public void execute(final VexWidget widget) throws ExecutionException {
- final IBoxFilter filter = new IBoxFilter() {
- public boolean matches(final Box box) {
- return box instanceof TableRowBox;
- }
- };
- final TableRowBox row = (TableRowBox) widget.findInnermostBox(filter);
-
- // not in a table row?
- if (row == null) {
+ final IAxis<? extends IParent> parentTableRows = widget.getCurrentElement().ancestors().matching(displayedAsTableRow(widget.getStyleSheet()));
+ final IElement tableRow;
+ try {
+ tableRow = (IElement) parentTableRows.first();
+ } catch (final NoSuchElementException e) {
return;
}
final int offset = widget.getCaretOffset();
- navigate(widget, row, offset);
+ navigate(widget, tableRow, offset);
}
/**
@@ -46,11 +48,19 @@
*
* @param widget
* the Vex widget containing the document
- * @param row
+ * @param tableRow
* the current row
* @param offset
* the current offset
*/
- protected abstract void navigate(VexWidget widget, TableRowBox row, int offset);
+ protected abstract void navigate(VexWidget widget, IElement tableRow, int offset);
+
+ private static IFilter<INode> displayedAsTableRow(final StyleSheet stylesheet) {
+ return new IFilter<INode>() {
+ public boolean matches(final INode node) {
+ return stylesheet.getStyles(node).getDisplay().equals(CSS.TABLE_ROW);
+ }
+ };
+ }
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/MoveSelectionUpHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/MoveSelectionUpHandler.java
index 9a80710..c557ffc 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/MoveSelectionUpHandler.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/MoveSelectionUpHandler.java
@@ -11,11 +11,12 @@
package org.eclipse.vex.ui.internal.handlers;
import org.eclipse.core.commands.ExecutionException;
-import org.eclipse.vex.core.internal.layout.BlockBox;
-import org.eclipse.vex.core.internal.layout.Box;
-import org.eclipse.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.vex.core.IFilter;
+import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.provisional.dom.ContentRange;
+import org.eclipse.vex.core.provisional.dom.IAxis;
import org.eclipse.vex.core.provisional.dom.INode;
+import org.eclipse.vex.core.provisional.dom.IParent;
import org.eclipse.vex.ui.internal.swt.VexWidget;
/**
@@ -27,39 +28,18 @@
@Override
public void execute(final VexWidget widget) throws ExecutionException {
- // First we determine whether we should expand the selection
- // to contain an entire block box.
+ final ContentRange selectedRange = widget.getSelectedRange();
+ final IAxis<? extends IParent> parentsContainingSelection = widget.getCurrentElement().ancestors().matching(containingRange(selectedRange));
- // Find the lowest block box that completely contains the selection
- final Box box = widget.findInnermostBox(new IBoxFilter() {
- public boolean matches(final Box box) {
- final ContentRange selectedRange = widget.getSelectedRange();
- return box instanceof BlockBox && box.getNode() != null && new ContentRange(box.getStartOffset(), box.getEndOffset()).contains(selectedRange);
- }
- });
-
- final Box[] children = box.getChildren();
- if (children.length > 0 && children[0] instanceof BlockBox) {
- // The found box contains other block children, so we do NOT have to
- // expand the selection
- } else {
- // Expand selection to the containing box
-
- // (Note: This "if" is caused by the fact that getStartOffset is
- // treated differently between elements and boxes. Boxes own their
- // startOffset, while elements don't own theirs. Perhaps we should
- // fix this by having box.getStartOffset() return
- // box.getStartPosition() + 1, but this would be a VERY large
- // change.)
- System.out.println("Box is " + box);
- final INode node = box.getNode();
- if (node != null) {
- widget.moveTo(node.getEndOffset() + 1);
- widget.moveTo(node.getStartOffset(), true);
-
+ // expand the selection until a parent has other block-children
+ final StyleSheet stylesheet = widget.getStyleSheet();
+ for (final IParent parent : parentsContainingSelection) {
+ final IAxis<? extends INode> blockChildren = parent.children().matching(displayedAsBlock(stylesheet));
+ if (blockChildren.isEmpty()) {
+ widget.moveTo(parent.getStartOffset(), false);
+ widget.moveTo(parent.getEndOffset(), true);
} else {
- widget.moveTo(box.getEndOffset() + 1);
- widget.moveTo(box.getStartOffset(), true);
+ break;
}
}
@@ -76,4 +56,19 @@
// });
}
+ private static IFilter<INode> containingRange(final ContentRange range) {
+ return new IFilter<INode>() {
+ public boolean matches(final INode node) {
+ return node.getRange().contains(range);
+ }
+ };
+ }
+
+ private static IFilter<INode> displayedAsBlock(final StyleSheet stylesheet) {
+ return new IFilter<INode>() {
+ public boolean matches(final INode node) {
+ return stylesheet.getStyles(node).isBlock();
+ }
+ };
+ }
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/NextTableCellHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/NextTableCellHandler.java
index 6d36957..4f16f0b 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/NextTableCellHandler.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/NextTableCellHandler.java
@@ -11,8 +11,9 @@
*******************************************************************************/
package org.eclipse.vex.ui.internal.handlers;
-import org.eclipse.vex.core.internal.layout.Box;
-import org.eclipse.vex.core.internal.layout.TableRowBox;
+import java.util.NoSuchElementException;
+
+import org.eclipse.vex.core.provisional.dom.IElement;
import org.eclipse.vex.ui.internal.swt.VexWidget;
/**
@@ -23,11 +24,9 @@
public class NextTableCellHandler extends AbstractNavigateTableCellHandler {
@Override
- protected void navigate(final VexWidget widget, final TableRowBox row, final int offset) {
- final Box[] cells = row.getChildren();
-
+ protected void navigate(final VexWidget widget, final IElement tableRow, final int offset) {
// in this row
- for (final Box cell : cells) {
+ for (final IElement cell : tableRow.childElements()) {
if (cell.getStartOffset() > offset) {
widget.moveTo(cell.getStartOffset());
widget.moveTo(cell.getEndOffset(), true);
@@ -36,14 +35,13 @@
}
// in other row
- final Box[] rows = row.getParent().getChildren();
- for (final Box boxRow : rows) {
- if (boxRow.getStartOffset() > offset) {
- final Box[] rowCells = boxRow.getChildren();
- if (rowCells.length > 0) {
- final Box cell = rowCells[0];
- widget.moveTo(cell.getStartOffset());
- widget.moveTo(cell.getEndOffset(), true);
+ for (final IElement siblingRow : tableRow.getParentElement().childElements()) {
+ if (siblingRow.getStartOffset() > offset) {
+ final IElement firstCell = firstCellOf(siblingRow);
+
+ if (firstCell != null) {
+ widget.moveTo(firstCell.getStartOffset());
+ widget.moveTo(firstCell.getEndOffset(), true);
} else {
System.out.println("TODO - dup row into new empty row");
}
@@ -52,8 +50,15 @@
}
// We didn't find a "next row", so let's dup the current one
- VexHandlerUtil.duplicateTableRow(widget, row);
+ VexHandlerUtil.duplicateTableRow(widget, tableRow);
+ }
+ private static IElement firstCellOf(final IElement tableRow) {
+ try {
+ return tableRow.childElements().first();
+ } catch (final NoSuchElementException e) {
+ return null;
+ }
}
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/PreviousTableCellHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/PreviousTableCellHandler.java
index 70dfdfa..26b7a87 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/PreviousTableCellHandler.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/PreviousTableCellHandler.java
@@ -10,8 +10,9 @@
*******************************************************************************/
package org.eclipse.vex.ui.internal.handlers;
-import org.eclipse.vex.core.internal.layout.Box;
-import org.eclipse.vex.core.internal.layout.TableRowBox;
+import java.util.NoSuchElementException;
+
+import org.eclipse.vex.core.provisional.dom.IElement;
import org.eclipse.vex.ui.internal.swt.VexWidget;
/**
@@ -22,31 +23,45 @@
public class PreviousTableCellHandler extends AbstractNavigateTableCellHandler {
@Override
- protected void navigate(final VexWidget widget, final TableRowBox row, final int offset) {
- Box[] cells = row.getChildren();
+ protected void navigate(final VexWidget widget, final IElement tableRow, final int offset) {
+ IElement siblingCell = null;
+ for (final IElement cell : tableRow.childElements()) {
+ if (cell.getStartOffset() >= offset) {
+ break;
+ }
+ siblingCell = cell;
+ }
// in this row
- for (int i = cells.length - 1; i >= 0; i--) {
- if (cells[i].getEndOffset() < offset) {
- widget.moveTo(cells[i].getStartOffset());
- widget.moveTo(cells[i].getEndOffset(), true);
- return;
+ if (siblingCell != null) {
+ widget.moveTo(siblingCell.getStartOffset());
+ widget.moveTo(siblingCell.getEndOffset(), true);
+ return;
+ }
+
+ IElement siblingRow = null;
+ for (final IElement row : tableRow.getParentElement().childElements()) {
+ if (row.getStartOffset() >= offset) {
+ break;
}
+ siblingRow = row;
}
// in other row
- final Box[] rows = row.getParent().getChildren();
- for (int i = rows.length - 1; i >= 0; i--) {
- if (rows[i].getEndOffset() < offset) {
- cells = rows[i].getChildren();
- if (cells.length > 0) {
- final Box cell = cells[cells.length - 1];
- widget.moveTo(cell.getStartOffset());
- widget.moveTo(cell.getEndOffset(), true);
- }
- return;
+ if (siblingRow != null) {
+ final IElement lastCell = lastCellOf(siblingRow);
+ if (lastCell != null) {
+ widget.moveTo(lastCell.getStartOffset());
+ widget.moveTo(lastCell.getEndOffset(), true);
}
}
}
+ private static IElement lastCellOf(final IElement tableRow) {
+ try {
+ return tableRow.childElements().last();
+ } catch (final NoSuchElementException e) {
+ return null;
+ }
+ }
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/SplitItemHandler.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/SplitItemHandler.java
index 84e069e..b9f67e3 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/SplitItemHandler.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/SplitItemHandler.java
@@ -10,13 +10,15 @@
*******************************************************************************/
package org.eclipse.vex.ui.internal.handlers;
+import java.util.NoSuchElementException;
+
import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.vex.core.IFilter;
import org.eclipse.vex.core.internal.css.CSS;
import org.eclipse.vex.core.internal.css.StyleSheet;
-import org.eclipse.vex.core.internal.layout.Box;
-import org.eclipse.vex.core.internal.layout.TableRowBox;
-import org.eclipse.vex.core.internal.widget.IBoxFilter;
+import org.eclipse.vex.core.provisional.dom.IAxis;
import org.eclipse.vex.core.provisional.dom.INode;
+import org.eclipse.vex.core.provisional.dom.IParent;
import org.eclipse.vex.ui.internal.swt.VexWidget;
/**
@@ -29,27 +31,36 @@
@Override
public void execute(final VexWidget widget) throws ExecutionException {
- final StyleSheet ss = widget.getStyleSheet();
+ final StyleSheet stylesheet = widget.getStyleSheet();
+ final IAxis<? extends IParent> parentTableRowOrListItems = widget.getCurrentElement().ancestors().matching(displayedAsTableRowOrListItem(stylesheet));
- // Item is either a TableRowBox or a BlockElementBox representing
- // a list item
- final Box item = widget.findInnermostBox(new IBoxFilter() {
- public boolean matches(final Box box) {
- if (box instanceof TableRowBox) {
- return true;
- } else {
- final INode node = box.getNode();
- return node != null && ss.getStyles(node).getDisplay().equals(CSS.LIST_ITEM);
- }
- }
- });
+ final IParent firstTableRowOrListItem;
+ try {
+ firstTableRowOrListItem = parentTableRowOrListItems.first();
+ } catch (final NoSuchElementException e) {
+ return;
+ }
- if (item instanceof TableRowBox) {
+ final String displayStyle = stylesheet.getStyles(firstTableRowOrListItem).getDisplay();
+ if (displayStyle.equals(CSS.TABLE_ROW)) {
new AddRowBelowHandler().execute(widget);
- // VexHandlerUtil.duplicateTableRow(vexWidget, (TableRowBox) item);
- } else if (item != null) {
- splitElement(widget, item.getNode());
+ } else if (displayStyle.equals(CSS.LIST_ITEM)) {
+ splitElement(widget, firstTableRowOrListItem);
}
}
+ private final IFilter<INode> displayedAsTableRowOrListItem(final StyleSheet stylesheet) {
+ return new IFilter<INode>() {
+ public boolean matches(final INode node) {
+ final String displayStyle = stylesheet.getStyles(node).getDisplay();
+ if (displayStyle.equals(CSS.TABLE_ROW)) {
+ return true;
+ }
+ if (displayStyle.equals(CSS.LIST_ITEM)) {
+ return true;
+ }
+ return false;
+ }
+ };
+ }
}
diff --git a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/VexHandlerUtil.java b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/VexHandlerUtil.java
index 87287b6..329da03 100644
--- a/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/VexHandlerUtil.java
+++ b/org.eclipse.vex.ui/src/org/eclipse/vex/ui/internal/handlers/VexHandlerUtil.java
@@ -22,10 +22,8 @@
import org.eclipse.vex.core.internal.css.CSS;
import org.eclipse.vex.core.internal.css.StyleSheet;
import org.eclipse.vex.core.internal.dom.CopyOfElement;
-import org.eclipse.vex.core.internal.layout.Box;
import org.eclipse.vex.core.internal.layout.ElementOrRangeCallback;
import org.eclipse.vex.core.internal.layout.LayoutUtils;
-import org.eclipse.vex.core.internal.layout.TableRowBox;
import org.eclipse.vex.core.internal.widget.IVexWidget;
import org.eclipse.vex.core.provisional.dom.ContentRange;
import org.eclipse.vex.core.provisional.dom.IDocument;
@@ -93,38 +91,25 @@
*
* @param vexWidget
* IVexWidget to modify.
- * @param tr
+ * @param tableRow
* TableRowBox whose cells are to be cloned.
* @param moveToFirstCell
* TODO
*/
- public static void cloneTableCells(final IVexWidget vexWidget, final TableRowBox tr, final boolean moveToFirstCell) {
+ public static void cloneTableCells(final IVexWidget vexWidget, final IElement tableRow, final boolean moveToFirstCell) {
vexWidget.doWork(new Runnable() {
public void run() {
-
- final int offset = vexWidget.getCaretOffset();
-
- boolean firstCellIsAnonymous = false;
- final Box[] cells = tr.getChildren();
- for (int i = 0; i < cells.length; i++) {
- if (cells[i].isAnonymous()) {
- vexWidget.insertText(" ");
- if (i == 0) {
- firstCellIsAnonymous = true;
- }
- } else {
- final IElement element = (IElement) cells[i].getNode();
- final IElement newElement = vexWidget.insertElement(element.getQualifiedName());
- newElement.accept(new CopyOfElement(element));
- vexWidget.moveBy(+1);
+ int firstCellOffset = -1;
+ for (final IElement cell : tableRow.childElements()) {
+ final IElement newElement = vexWidget.insertElement(cell.getQualifiedName());
+ newElement.accept(new CopyOfElement(cell));
+ if (firstCellOffset == -1) {
+ firstCellOffset = newElement.getEndOffset();
}
}
- if (moveToFirstCell) {
- vexWidget.moveTo(offset + 1);
- if (firstCellIsAnonymous) {
- vexWidget.moveBy(-1, true);
- }
+ if (moveToFirstCell && firstCellOffset != -1) {
+ vexWidget.moveTo(firstCellOffset);
}
}
});
@@ -136,23 +121,17 @@
*
* @param vexWidget
* IVexWidget with which we're working
- * @param tr
+ * @param tableRow
* TableRowBox to be duplicated.
*/
- public static void duplicateTableRow(final IVexWidget vexWidget, final TableRowBox tr) {
+ public static void duplicateTableRow(final IVexWidget vexWidget, final IElement tableRow) {
vexWidget.doWork(new Runnable() {
public void run() {
-
- vexWidget.moveTo(tr.getEndOffset());
-
- if (!tr.isAnonymous()) {
- vexWidget.moveBy(+1); // Move past sentinel in current row
- final IElement element = (IElement) tr.getNode();
- final IElement newElement = vexWidget.insertElement(element.getQualifiedName());
- newElement.accept(new CopyOfElement(element));
- }
-
- cloneTableCells(vexWidget, tr, true);
+ vexWidget.moveTo(tableRow.getEndOffset());
+ vexWidget.moveBy(+1); // Move past sentinel in current row
+ final IElement newElement = vexWidget.insertElement(tableRow.getQualifiedName());
+ newElement.accept(new CopyOfElement(tableRow));
+ cloneTableCells(vexWidget, tableRow, true);
}
});
}