in asdoc/library/closure/goog/dom/textrangeiterator.js [49:131]
goog.dom.TextRangeIterator = function(
startNode, startOffset, endNode, endOffset, opt_reverse) {
/**
* The first node in the selection.
* @private {Node}
*/
this.startNode_ = null;
/**
* The last node in the selection.
* @private {Node}
*/
this.endNode_ = null;
/**
* The offset within the first node in the selection.
* @private {number}
*/
this.startOffset_ = 0;
/**
* The offset within the last node in the selection.
* @private {number}
*/
this.endOffset_ = 0;
/**
* Whether the node iterator is moving in reverse.
* @private {boolean}
*/
this.isReversed_ = !!opt_reverse;
var goNext;
if (startNode) {
this.startNode_ = startNode;
this.startOffset_ = startOffset;
this.endNode_ = endNode;
this.endOffset_ = endOffset;
// Skip to the offset nodes - being careful to special case BRs since these
// have no children but still can appear as the startContainer of a range.
if (startNode.nodeType == goog.dom.NodeType.ELEMENT &&
/** @type {!Element} */ (startNode).tagName != goog.dom.TagName.BR) {
var startChildren = startNode.childNodes;
var candidate = startChildren[startOffset];
if (candidate) {
this.startNode_ = candidate;
this.startOffset_ = 0;
} else {
if (startChildren.length) {
this.startNode_ =
/** @type {Node} */ (goog.array.peek(startChildren));
}
goNext = true;
}
}
if (endNode.nodeType == goog.dom.NodeType.ELEMENT) {
this.endNode_ = endNode.childNodes[endOffset];
if (this.endNode_) {
this.endOffset_ = 0;
} else {
// The offset was past the last element.
this.endNode_ = endNode;
}
}
}
goog.dom.TextRangeIterator.base(
this, 'constructor', this.isReversed_ ? this.endNode_ : this.startNode_,
this.isReversed_);
if (goNext) {
try {
this.next();
} catch (e) {
if (e != goog.iter.StopIteration) {
throw e;
}
}
}
};