123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628 |
- goog.provide('goog.editor.range');
- goog.provide('goog.editor.range.Point');
- goog.require('goog.array');
- goog.require('goog.dom');
- goog.require('goog.dom.NodeType');
- goog.require('goog.dom.Range');
- goog.require('goog.dom.RangeEndpoint');
- goog.require('goog.dom.SavedCaretRange');
- goog.require('goog.editor.node');
- goog.require('goog.editor.style');
- goog.require('goog.iter');
- goog.require('goog.userAgent');
- goog.editor.range.narrow = function(range, el) {
- var startContainer = range.getStartNode();
- var endContainer = range.getEndNode();
- if (startContainer && endContainer) {
- var isElement = function(node) { return node == el; };
- var hasStart = goog.dom.getAncestor(startContainer, isElement, true);
- var hasEnd = goog.dom.getAncestor(endContainer, isElement, true);
- if (hasStart && hasEnd) {
-
- return range.clone();
- } else if (hasStart) {
-
- var leaf = goog.editor.node.getRightMostLeaf(el);
- return goog.dom.Range.createFromNodes(
- range.getStartNode(), range.getStartOffset(), leaf,
- goog.editor.node.getLength(leaf));
- } else if (hasEnd) {
-
- return goog.dom.Range.createFromNodes(
- goog.editor.node.getLeftMostLeaf(el), 0, range.getEndNode(),
- range.getEndOffset());
- }
- }
-
- return null;
- };
- goog.editor.range.expand = function(range, opt_stopNode) {
-
- var expandedRange = goog.editor.range.expandEndPointToContainer_(
- range, goog.dom.RangeEndpoint.START, opt_stopNode);
-
- expandedRange = goog.editor.range.expandEndPointToContainer_(
- expandedRange, goog.dom.RangeEndpoint.END, opt_stopNode);
- var startNode = expandedRange.getStartNode();
- var endNode = expandedRange.getEndNode();
- var startOffset = expandedRange.getStartOffset();
- var endOffset = expandedRange.getEndOffset();
-
- if (startNode == endNode) {
- while (endNode != opt_stopNode && startOffset == 0 &&
- endOffset == goog.editor.node.getLength(endNode)) {
-
- var parentNode = endNode.parentNode;
- startOffset = goog.array.indexOf(parentNode.childNodes, endNode);
- endOffset = startOffset + 1;
- endNode = parentNode;
- }
- startNode = endNode;
- }
- return goog.dom.Range.createFromNodes(
- startNode, startOffset, endNode, endOffset);
- };
- goog.editor.range.expandEndPointToContainer_ = function(
- range, endpoint, opt_stopNode) {
- var expandStart = endpoint == goog.dom.RangeEndpoint.START;
- var node = expandStart ? range.getStartNode() : range.getEndNode();
- var offset = expandStart ? range.getStartOffset() : range.getEndOffset();
- var container = range.getContainerElement();
-
- while (node != container && node != opt_stopNode) {
-
-
-
- if (expandStart && offset != 0 ||
- !expandStart && offset != goog.editor.node.getLength(node)) {
- break;
- }
- var parentNode = node.parentNode;
- var index = goog.array.indexOf(parentNode.childNodes, node);
- offset = expandStart ? index : index + 1;
- node = parentNode;
- }
- return goog.dom.Range.createFromNodes(
- expandStart ? node : range.getStartNode(),
- expandStart ? offset : range.getStartOffset(),
- expandStart ? range.getEndNode() : node,
- expandStart ? range.getEndOffset() : offset);
- };
- goog.editor.range.selectNodeStart = function(node) {
- goog.dom.Range.createCaret(goog.editor.node.getLeftMostLeaf(node), 0)
- .select();
- };
- goog.editor.range.placeCursorNextTo = function(node, toLeft) {
- var parent = node.parentNode;
- var offset = goog.array.indexOf(parent.childNodes, node) + (toLeft ? 0 : 1);
- var point =
- goog.editor.range.Point.createDeepestPoint(parent, offset, toLeft, true);
- var range = goog.dom.Range.createCaret(point.node, point.offset);
- range.select();
- return range;
- };
- goog.editor.range.selectionPreservingNormalize = function(node) {
- var doc = goog.dom.getOwnerDocument(node);
- var selection = goog.dom.Range.createFromWindow(goog.dom.getWindow(doc));
- var normalizedRange =
- goog.editor.range.rangePreservingNormalize(node, selection);
- if (normalizedRange) {
- normalizedRange.select();
- }
- };
- goog.editor.range.normalizeNodeIe_ = function(node) {
- var lastText = null;
- var child = node.firstChild;
- while (child) {
- var next = child.nextSibling;
- if (child.nodeType == goog.dom.NodeType.TEXT) {
- if (child.nodeValue == '') {
- node.removeChild(child);
- } else if (lastText) {
- lastText.nodeValue += child.nodeValue;
- node.removeChild(child);
- } else {
- lastText = child;
- }
- } else {
- goog.editor.range.normalizeNodeIe_(child);
- lastText = null;
- }
- child = next;
- }
- };
- goog.editor.range.normalizeNode = function(node) {
- if (goog.userAgent.IE) {
- goog.editor.range.normalizeNodeIe_(node);
- } else {
- node.normalize();
- }
- };
- goog.editor.range.rangePreservingNormalize = function(node, range) {
- if (range) {
- var rangeFactory = goog.editor.range.normalize(range);
-
-
-
-
-
-
- var container = goog.editor.style.getContainer(range.getContainerElement());
- }
- if (container) {
- goog.editor.range.normalizeNode(
- goog.dom.findCommonAncestor(container, node));
- } else if (node) {
- goog.editor.range.normalizeNode(node);
- }
- if (rangeFactory) {
- return rangeFactory();
- } else {
- return null;
- }
- };
- goog.editor.range.getDeepEndPoint = function(range, atStart) {
- return atStart ?
- goog.editor.range.Point.createDeepestPoint(
- range.getStartNode(), range.getStartOffset()) :
- goog.editor.range.Point.createDeepestPoint(
- range.getEndNode(), range.getEndOffset());
- };
- goog.editor.range.normalize = function(range) {
- var isReversed = range.isReversed();
- var anchorPoint = goog.editor.range.normalizePoint_(
- goog.editor.range.getDeepEndPoint(range, !isReversed));
- var anchorParent = anchorPoint.getParentPoint();
- var anchorPreviousSibling = anchorPoint.node.previousSibling;
- if (anchorPoint.node.nodeType == goog.dom.NodeType.TEXT) {
- anchorPoint.node = null;
- }
- var focusPoint = goog.editor.range.normalizePoint_(
- goog.editor.range.getDeepEndPoint(range, isReversed));
- var focusParent = focusPoint.getParentPoint();
- var focusPreviousSibling = focusPoint.node.previousSibling;
- if (focusPoint.node.nodeType == goog.dom.NodeType.TEXT) {
- focusPoint.node = null;
- }
- return function() {
- if (!anchorPoint.node && anchorPreviousSibling) {
-
-
-
-
- anchorPoint.node = anchorPreviousSibling.nextSibling;
- if (!anchorPoint.node) {
- anchorPoint =
- goog.editor.range.Point.getPointAtEndOfNode(anchorPreviousSibling);
- }
- }
- if (!focusPoint.node && focusPreviousSibling) {
-
-
-
-
- focusPoint.node = focusPreviousSibling.nextSibling;
- if (!focusPoint.node) {
- focusPoint =
- goog.editor.range.Point.getPointAtEndOfNode(focusPreviousSibling);
- }
- }
- return goog.dom.Range.createFromNodes(
- anchorPoint.node || anchorParent.node.firstChild || anchorParent.node,
- anchorPoint.offset,
- focusPoint.node || focusParent.node.firstChild || focusParent.node,
- focusPoint.offset);
- };
- };
- goog.editor.range.normalizePoint_ = function(point) {
- var previous;
- if (point.node.nodeType == goog.dom.NodeType.TEXT) {
-
-
-
- for (var current = point.node.previousSibling;
- current && current.nodeType == goog.dom.NodeType.TEXT;
- current = current.previousSibling) {
- point.offset += goog.editor.node.getLength(current);
- }
- previous = current;
- } else {
- previous = point.node.previousSibling;
- }
- var parent = point.node.parentNode;
- point.node = previous ? previous.nextSibling : parent.firstChild;
- return point;
- };
- goog.editor.range.isEditable = function(range) {
- var rangeContainer = range.getContainerElement();
-
-
-
-
-
-
- var rangeContainerIsOutsideRange =
- range.getStartNode() != rangeContainer.parentElement;
- return (rangeContainerIsOutsideRange &&
- goog.editor.node.isEditableContainer(rangeContainer)) ||
- goog.editor.node.isEditable(rangeContainer);
- };
- goog.editor.range.intersectsTag = function(range, tagName) {
- if (goog.dom.getAncestorByTagNameAndClass(
- range.getContainerElement(), tagName)) {
- return true;
- }
- return goog.iter.some(
- range, function(node) { return node.tagName == tagName; });
- };
- goog.editor.range.Point = function(node, offset) {
-
- this.node = node;
-
- this.offset = offset;
- };
- goog.editor.range.Point.prototype.getParentPoint = function() {
- var parent = this.node.parentNode;
- return new goog.editor.range.Point(
- parent, goog.array.indexOf(parent.childNodes, this.node));
- };
- goog.editor.range.Point.createDeepestPoint = function(
- node, offset, opt_trendLeft, opt_stopOnChildlessElement) {
- while (node.nodeType == goog.dom.NodeType.ELEMENT) {
- var child = node.childNodes[offset];
- if (!child && !node.lastChild) {
- break;
- } else if (child) {
- var prevSibling = child.previousSibling;
- if (opt_trendLeft && prevSibling) {
- if (opt_stopOnChildlessElement &&
- goog.editor.range.Point.isTerminalElement_(prevSibling)) {
- break;
- }
- node = prevSibling;
- offset = goog.editor.node.getLength(node);
- } else {
- if (opt_stopOnChildlessElement &&
- goog.editor.range.Point.isTerminalElement_(child)) {
- break;
- }
- node = child;
- offset = 0;
- }
- } else {
- if (opt_stopOnChildlessElement &&
- goog.editor.range.Point.isTerminalElement_(node.lastChild)) {
- break;
- }
- node = node.lastChild;
- offset = goog.editor.node.getLength(node);
- }
- }
- return new goog.editor.range.Point(node, offset);
- };
- goog.editor.range.Point.isTerminalElement_ = function(node) {
- return (
- node.nodeType == goog.dom.NodeType.ELEMENT &&
- !goog.dom.canHaveChildren(node));
- };
- goog.editor.range.Point.getPointAtEndOfNode = function(node) {
- return new goog.editor.range.Point(node, goog.editor.node.getLength(node));
- };
- goog.editor.range.saveUsingNormalizedCarets = function(range) {
- return new goog.editor.range.NormalizedCaretRange_(range);
- };
- goog.editor.range.NormalizedCaretRange_ = function(range) {
- goog.dom.SavedCaretRange.call(this, range);
- };
- goog.inherits(
- goog.editor.range.NormalizedCaretRange_, goog.dom.SavedCaretRange);
- goog.editor.range.NormalizedCaretRange_.prototype.removeCarets = function(
- opt_range) {
- var startCaret = this.getCaret(true);
- var endCaret = this.getCaret(false);
- var node = startCaret && endCaret ?
- goog.dom.findCommonAncestor(startCaret, endCaret) :
- startCaret || endCaret;
- goog.editor.range.NormalizedCaretRange_.superClass_.removeCarets.call(this);
- if (opt_range) {
- return goog.editor.range.rangePreservingNormalize(node, opt_range);
- } else if (node) {
- goog.editor.range.selectionPreservingNormalize(node);
- }
- };
|