HtmlView filteredHtml = filteredHtmlView;
// The element before all previous text node siblings of target,
// or null if no such element
Node nodeletBeforeTextNodes;
ContentNode wrapperBeforeTextNodes;
// Our cursors
Text current = target;
ContentNode possibleOwnerNode;
// Go leftwards to find the start of the text nodelet sequence
for (nodeletBeforeTextNodes = filteredHtml.getPreviousSibling(target);
nodeletBeforeTextNodes != null;
nodeletBeforeTextNodes = filteredHtml.getPreviousSibling(nodeletBeforeTextNodes)) {
Text maybeText = filteredHtml.asText(nodeletBeforeTextNodes);
if (maybeText == null) {
break;
}
current = maybeText;
}
Element parentNodelet = filteredHtml.getParentElement(target);
if (parentNodelet == null) {
throw new RuntimeException(
"Somehow we are asking for the wrapper of something not in the editor??");
}
ContentElement parentElement = NodeManager.getBackReference(parentNodelet);
// Find our foothold in wrapper land
if (nodeletBeforeTextNodes == null) {
// reached the beginning
wrapperBeforeTextNodes = null;
possibleOwnerNode = renderedContent.getFirstChild(parentElement);
} else {
// reached an element
wrapperBeforeTextNodes = NodeManager.getBackReference(
nodeletBeforeTextNodes.<Element>cast());
possibleOwnerNode = renderedContent.getNextSibling(wrapperBeforeTextNodes);
}
// Scan to find a matching pair
while (true) {
// TODO(danilatos): Clarify and possibly reorganise this loop
// TODO(danilatos): Write more unit tests to thoroughly cover all scenarios
if (possibleOwnerNode == null) {
// Scenario (D)
throw new HtmlInserted(
Point.inElement(parentElement, (ContentNode) null),
Point.start(filteredHtml, parentNodelet)
);
}
ContentTextNode possibleOwner;
try {
possibleOwner = (ContentTextNode) possibleOwnerNode;
} catch (ClassCastException e) {
if (possibleOwnerNode.isImplAttached()) {
// Scenario (C)
throw new HtmlInserted(
Point.inElement(parentElement, possibleOwnerNode),
Point.inElementReverse(filteredHtml, parentNodelet, nodeletBeforeTextNodes)
);
} else {
// Scenario (A)
// Not minor, an element has gone missing
throw new HtmlMissing(possibleOwnerNode, parentNodelet);
}
}
ContentNode nextNode = renderedContent.getNextSibling(possibleOwner);
if (nextNode != null && !nextNode.isImplAttached()) {
// Scenario (E)
throw new HtmlMissing(nextNode, parentNodelet);
}
if (current != possibleOwner.getImplNodelet()) {
// Scenario (B)
if (attemptRepair) {
possibleOwner.setTextNodelet(current);
return nullifyIfWrongDocument(possibleOwner);
} else {
// TODO(danilatos): Ensure repairs handle nodes on either
// side, as this is kind of a "replace" error
throw new HtmlInserted(
Point.inElement(parentElement, possibleOwner),
Point.inElement(parentNodelet, current));
}
}
Node nextNodelet = nextNode == null ? null : nextNode.getImplNodelet();
while (current != nextNodelet && current != null) {
// TODO(danilatos): Fix up every where in the code to use .equals
// for GWT DOM.
if (current == target) {