Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Consider nested paragraphs for navigation #81

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

import org.w3c.dom.Node;

import java.util.Set;

/**
* Abstract class Navigation used to navigate the document and find the matched element by the user
* defined conditions
Expand Down Expand Up @@ -51,6 +53,13 @@ public abstract class Navigation {
*/
public abstract boolean match(Node element);

/**
* Checks if the given node can be matched by the navigation
* @param node the node
* @return true if the node is of interest for the navigation
*/
public abstract boolean isMatchingNode(Node node);

/**
* get the next matched element in a whole dom tree
*
Expand All @@ -63,28 +72,40 @@ protected Node getNextMatchElement(Node startpoint) {

Node currentpoint = startpoint;
while ((matchedNode == null) && (currentpoint != null)) {
Node sibling = currentpoint.getNextSibling();
if ((sibling != null)
&& (sibling.getNodeType() == Node.TEXT_NODE || sibling.getNodeType() == Node.ELEMENT_NODE)
&& (match(sibling))) {
matchedNode = sibling;
}
while ((sibling != null) && (matchedNode == null)) {
if ((sibling.getNodeType() == Node.TEXT_NODE
|| sibling.getNodeType() == Node.ELEMENT_NODE)) {
matchedNode = traverseTree(sibling);
}
sibling = sibling.getNextSibling();
if (sibling != null && match(sibling)) {
matchedNode = sibling;
}
if (isMatchingNode(currentpoint) && currentpoint != startpoint && parentMatches(currentpoint, startpoint)){
matchedNode = currentpoint;
} else {
Node sibling = currentpoint.getNextSibling();
if ((sibling != null)
&& (sibling.getNodeType() == Node.TEXT_NODE || sibling.getNodeType() == Node.ELEMENT_NODE)
&& (match(sibling))) {
matchedNode = sibling;
}
while ((sibling != null) && (matchedNode == null)) {
if ((sibling.getNodeType() == Node.TEXT_NODE
|| sibling.getNodeType() == Node.ELEMENT_NODE)) {
matchedNode = traverseTree(sibling);
}
sibling = sibling.getNextSibling();
if (sibling != null && match(sibling)) {
matchedNode = sibling;
}
}
currentpoint = currentpoint.getParentNode();
}
currentpoint = currentpoint.getParentNode();
}

return matchedNode;
}

/**
* Checks that a parent node matches given the current node
* @param parent The parent node
* @param current The current node
* @return true if the parent matches, false otherwise
*/
protected abstract boolean parentMatches(final Node parent, final Node current);

/**
* get the next matched element in a sub tree
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@

import java.util.Hashtable;
import java.util.Vector;

import org.odftoolkit.odfdom.incubator.doc.text.OdfWhitespaceProcessor;
import org.odftoolkit.odfdom.pkg.OdfElement;
import org.w3c.dom.Node;

/**
* Abstract class Selection describe one of the matched results The selection can be recognized by
Expand Down Expand Up @@ -220,16 +223,51 @@ public static void unregisterItem(Selection item) {
* @param offset the offset
* @param positionIndex the mIndex of a certain position
*/
public static synchronized void refresh(
OdfElement containerElement, int offset, int positionIndex) {
if (repository.containsKey(containerElement)) {
Vector<Selection> selections = repository.get(containerElement);
for (int i = 0; i < selections.size(); i++) {
if (selections.get(i).getIndex() >= positionIndex) {
selections.get(i).refresh(offset);
}
public synchronized static void refresh(OdfElement containerElement, int offset, int positionIndex) {
refreshParent(containerElement, offset);
if (repository.containsKey(containerElement)) {
Vector<Selection> selections = repository.get(containerElement);
for (Selection selection : selections) {
if (selection.getIndex() >= positionIndex) {
selection.refresh(offset);
}
}
}
}
}

private static void refreshParent(OdfElement containerElement, int offset) {
OdfElement parent = getOdfParent(containerElement);
while (parent != null) {
if (repository.containsKey(parent)) {
Vector<Selection> selections = repository.get(parent);
for (Selection selection : selections) {
if (isAfter(selection, containerElement)) {
selection.refresh(offset);
}
}
}
parent = getOdfParent(parent);
}
}

private static OdfElement getOdfParent(OdfElement element) {
Node parent = element.getParentNode();
while (parent != null && !(parent instanceof OdfElement) && parent != parent.getParentNode()) {
parent = parent.getParentNode();
}
return parent instanceof OdfElement ? (OdfElement) parent : null;
}

private static boolean isAfter(Selection selection, OdfElement reference) {
//Assumes that reference is a child of selection.getElement
final OdfWhitespaceProcessor processor = new OdfWhitespaceProcessor();
final String text = processor.getText(reference);
final int idx = processor.getText(selection.getElement()).indexOf(text);
if (idx == -1 || idx != processor.getText(selection.getElement()).lastIndexOf(text)) {
//TODO obviously don't do that, need to work with Text nodes perhaps
throw new IllegalStateException();
}
return selection.getIndex() >= idx + text.length();
}

private SelectionManager() {}
Expand Down
Loading