/**
* {@inheritDoc}
*/
public DomDocumentFragment extractContents() throws DOMException {
// Clone the common ancestor.
final DomNode ancestor = (DomNode) getCommonAncestorContainer();
final DomNode ancestorClone = ancestor.cloneNode(true);
// Find the start container and end container clones.
DomNode startClone = null;
DomNode endClone = null;
final DomNode start = (DomNode) startContainer_;
final DomNode end = (DomNode) endContainer_;
if (start == ancestor) {
startClone = ancestorClone;
}
if (end == ancestor) {
endClone = ancestorClone;
}
final Iterable< DomNode > descendants = ancestor.getDescendants();
if (startClone == null || endClone == null) {
final Iterator<DomNode> i = descendants.iterator();
final Iterator<DomNode> ci = ancestorClone.getDescendants().iterator();
while (i.hasNext()) {
final DomNode e = i.next();
final DomNode ce = ci.next();
if (start == e) {
startClone = ce;
}
else if (end == e) {
endClone = ce;
break;
}
}
}
// Remove everything prior to the selection start from the clones.
if (startClone == null) {
throw Context.reportRuntimeError("Unable to find start node clone.");
}
deleteBefore(startClone, startOffset_);
for (DomNode n = startClone; n != null; n = n.getParentNode()) {
for (DomNode prev = n.getPreviousSibling(); prev != null; prev = prev.getPreviousSibling()) {
prev.remove();
}
}
// Remove everything following the selection end from the clones.
if (endClone == null) {
throw Context.reportRuntimeError("Unable to find end node clone.");
}
deleteAfter(endClone, endOffset_);
for (DomNode n = endClone; n != null; n = n.getParentNode()) {
for (DomNode next = n.getNextSibling(); next != null; next = next.getNextSibling()) {
next.remove();
}
}
// Remove everything inside the range from the original nodes.
boolean foundStartNode = (ancestor == start); // whether or not we have found the start node yet
boolean started = false; // whether or not we have found the start node *and* start offset yet
boolean foundEndNode = false; // whether or not we have found the end node yet
final Iterator<DomNode> i = ancestor.getDescendants().iterator();
while (i.hasNext()) {
final DomNode n = i.next();
if (!foundStartNode) {
foundStartNode = (n == start);
if (foundStartNode && isOffsetChars(n)) {
started = true;
String text = getText(n);
text = text.substring(0, startOffset_);
setText(n, text);
}
}
else if (!started) {
final boolean atStart = (n.getParentNode() == start && n.getIndex() == startOffset_);
final boolean beyondStart = !start.isAncestorOf(n);
started = (atStart || beyondStart);
}
if (started) {
if (!foundEndNode) {
foundEndNode = (n == end);
}
if (!foundEndNode) {
// We're inside the range.
if (!n.isAncestorOfAny(start, end)) {
i.remove();
}
}
else {
// We've reached the end of the range.
if (isOffsetChars(n)) {
String text = getText(n);
text = text.substring(endOffset_);
setText(n, text);
}
else {
final DomNodeList< DomNode > children = n.getChildNodes();
for (int j = endOffset_ - 1; j >= 0; j--) {
children.get(j).remove();
}
}
break;