var slice =
exports.slice = function(start, end, root) {
var swap, extract;
start = start == null ? null : Cursor.toCursor(start);
end = end == null ? null : Cursor.toCursor(end);
if (root == null) {
if (start == null || end == null) throw new Error("Must specify a root node if start and end cursors are not defined.");
root = getRootNode(start == null ? end.node : start.node);
}
if (!start) start = new Cursor(root, false);
if (!end) end = new Cursor(root, true);
if (!contains(root, start.node)) throw new Error("Start node isn't in the root node.");
if (!contains(root, end.node)) throw new Error("End node isn't in the root node.");
if (start.isAfter(end)) {
swap = start;
start = end;
end = swap;
}
return (extract = function(node) {
if (contains(node, start.node) || contains(node, end.node) || (start.isBefore(node) && end.isAfter(node))) {
var clone = node.cloneNode(false);
if (node.nodeType === Node.TEXT_NODE) {
var text = node.nodeValue,
isStart = matches(node, start.node),
isEnd = matches(node, end.node);
if (isStart && isEnd) {
text = text.substring(start.index, end.index);
} else if (isStart) {
text = text.substr(start.index);
} else if (isEnd) {
text = text.substr(0, end.index);
}
clone.nodeValue = text;
}
if (node.hasChildNodes()) {
Array.prototype.slice.call(node.childNodes, 0).forEach(function(child) {
var nc = extract(child);
if (nc != null) clone.appendChild(nc);
});
}
return clone;
}
})(root);
}