diff options
Diffstat (limited to 'contexts/data/lib/closure-library/closure/goog/editor/node.js')
-rw-r--r-- | contexts/data/lib/closure-library/closure/goog/editor/node.js | 457 |
1 files changed, 0 insertions, 457 deletions
diff --git a/contexts/data/lib/closure-library/closure/goog/editor/node.js b/contexts/data/lib/closure-library/closure/goog/editor/node.js deleted file mode 100644 index b58ebb5..0000000 --- a/contexts/data/lib/closure-library/closure/goog/editor/node.js +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright 2005 The Closure Library Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS-IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -/** - * @fileoverview Utilties for working with DOM nodes related to rich text - * editing. Many of these are not general enough to go into goog.dom. - * - */ - -goog.provide('goog.editor.node'); - -goog.require('goog.dom'); -goog.require('goog.dom.NodeType'); -goog.require('goog.dom.TagName'); -goog.require('goog.dom.iter.ChildIterator'); -goog.require('goog.dom.iter.SiblingIterator'); -goog.require('goog.iter'); -goog.require('goog.object'); -goog.require('goog.string'); -goog.require('goog.string.Unicode'); - - -/** - * Names of all block-level tags - * @type {Object} - * @private - */ -goog.editor.node.BLOCK_TAG_NAMES_ = goog.object.createSet( - goog.dom.TagName.ADDRESS, - goog.dom.TagName.ARTICLE, - goog.dom.TagName.ASIDE, - goog.dom.TagName.BLOCKQUOTE, - goog.dom.TagName.BODY, - goog.dom.TagName.CAPTION, - goog.dom.TagName.CENTER, - goog.dom.TagName.COL, - goog.dom.TagName.COLGROUP, - goog.dom.TagName.DETAILS, - goog.dom.TagName.DIR, - goog.dom.TagName.DIV, - goog.dom.TagName.DL, - goog.dom.TagName.DD, - goog.dom.TagName.DT, - goog.dom.TagName.FIELDSET, - goog.dom.TagName.FIGCAPTION, - goog.dom.TagName.FIGURE, - goog.dom.TagName.FOOTER, - goog.dom.TagName.FORM, - goog.dom.TagName.H1, - goog.dom.TagName.H2, - goog.dom.TagName.H3, - goog.dom.TagName.H4, - goog.dom.TagName.H5, - goog.dom.TagName.H6, - goog.dom.TagName.HEADER, - goog.dom.TagName.HGROUP, - goog.dom.TagName.HR, - goog.dom.TagName.ISINDEX, - goog.dom.TagName.OL, - goog.dom.TagName.LI, - goog.dom.TagName.MAP, - goog.dom.TagName.MENU, - goog.dom.TagName.NAV, - goog.dom.TagName.OPTGROUP, - goog.dom.TagName.OPTION, - goog.dom.TagName.P, - goog.dom.TagName.PRE, - goog.dom.TagName.SECTION, - goog.dom.TagName.SUMMARY, - goog.dom.TagName.TABLE, - goog.dom.TagName.TBODY, - goog.dom.TagName.TD, - goog.dom.TagName.TFOOT, - goog.dom.TagName.TH, - goog.dom.TagName.THEAD, - goog.dom.TagName.TR, - goog.dom.TagName.UL); - - -/** - * Names of tags that have intrinsic content. - * TODO(robbyw): What about object, br, input, textarea, button, isindex, - * hr, keygen, select, table, tr, td? - * @type {Object} - * @private - */ -goog.editor.node.NON_EMPTY_TAGS_ = goog.object.createSet( - goog.dom.TagName.IMG, goog.dom.TagName.IFRAME, goog.dom.TagName.EMBED); - - -/** - * Check if the node is in a standards mode document. - * @param {Node} node The node to test. - * @return {boolean} Whether the node is in a standards mode document. - */ -goog.editor.node.isStandardsMode = function(node) { - return goog.dom.getDomHelper(node).isCss1CompatMode(); -}; - - -/** - * Get the right-most non-ignorable leaf node of the given node. - * @param {Node} parent The parent ndoe. - * @return {Node} The right-most non-ignorable leaf node. - */ -goog.editor.node.getRightMostLeaf = function(parent) { - var temp; - while (temp = goog.editor.node.getLastChild(parent)) { - parent = temp; - } - return parent; -}; - - -/** - * Get the left-most non-ignorable leaf node of the given node. - * @param {Node} parent The parent ndoe. - * @return {Node} The left-most non-ignorable leaf node. - */ -goog.editor.node.getLeftMostLeaf = function(parent) { - var temp; - while (temp = goog.editor.node.getFirstChild(parent)) { - parent = temp; - } - return parent; -}; - - -/** - * Version of firstChild that skips nodes that are entirely - * whitespace and comments. - * @param {Node} parent The reference node. - * @return {Node} The first child of sibling that is important according to - * goog.editor.node.isImportant, or null if no such node exists. - */ -goog.editor.node.getFirstChild = function(parent) { - return goog.editor.node.getChildHelper_(parent, false); -}; - - -/** - * Version of lastChild that skips nodes that are entirely whitespace or - * comments. (Normally lastChild is a property of all DOM nodes that gives the - * last of the nodes contained directly in the reference node.) - * @param {Node} parent The reference node. - * @return {Node} The last child of sibling that is important according to - * goog.editor.node.isImportant, or null if no such node exists. - */ -goog.editor.node.getLastChild = function(parent) { - return goog.editor.node.getChildHelper_(parent, true); -}; - - -/** - * Version of previoussibling that skips nodes that are entirely - * whitespace or comments. (Normally previousSibling is a property - * of all DOM nodes that gives the sibling node, the node that is - * a child of the same parent, that occurs immediately before the - * reference node.) - * @param {Node} sibling The reference node. - * @return {Node} The closest previous sibling to sibling that is - * important according to goog.editor.node.isImportant, or null if no such - * node exists. - */ -goog.editor.node.getPreviousSibling = function(sibling) { - return /** @type {Node} */ (goog.editor.node.getFirstValue_( - goog.iter.filter(new goog.dom.iter.SiblingIterator(sibling, false, true), - goog.editor.node.isImportant))); -}; - - -/** - * Version of nextSibling that skips nodes that are entirely whitespace or - * comments. - * @param {Node} sibling The reference node. - * @return {Node} The closest next sibling to sibling that is important - * according to goog.editor.node.isImportant, or null if no - * such node exists. - */ -goog.editor.node.getNextSibling = function(sibling) { - return /** @type {Node} */ (goog.editor.node.getFirstValue_( - goog.iter.filter(new goog.dom.iter.SiblingIterator(sibling), - goog.editor.node.isImportant))); -}; - - -/** - * Internal helper for lastChild/firstChild that skips nodes that are entirely - * whitespace or comments. - * @param {Node} parent The reference node. - * @param {boolean} isReversed Whether children should be traversed forward - * or backward. - * @return {Node} The first/last child of sibling that is important according - * to goog.editor.node.isImportant, or null if no such node exists. - * @private - */ -goog.editor.node.getChildHelper_ = function(parent, isReversed) { - return (!parent || parent.nodeType != goog.dom.NodeType.ELEMENT) ? null : - /** @type {Node} */ (goog.editor.node.getFirstValue_(goog.iter.filter( - new goog.dom.iter.ChildIterator( - /** @type {Element} */ (parent), isReversed), - goog.editor.node.isImportant))); -}; - - -/** - * Utility function that returns the first value from an iterator or null if - * the iterator is empty. - * @param {goog.iter.Iterator} iterator The iterator to get a value from. - * @return {*} The first value from the iterator. - * @private - */ -goog.editor.node.getFirstValue_ = function(iterator) { - /** @preserveTry */ - try { - return iterator.next(); - } catch (e) { - return null; - } -}; - - -/** - * Determine if a node should be returned by the iterator functions. - * @param {Node} node An object implementing the DOM1 Node interface. - * @return {boolean} Whether the node is an element, or a text node that - * is not all whitespace. - */ -goog.editor.node.isImportant = function(node) { - // Return true if the node is not either a TextNode or an ElementNode. - return node.nodeType == goog.dom.NodeType.ELEMENT || - node.nodeType == goog.dom.NodeType.TEXT && - !goog.editor.node.isAllNonNbspWhiteSpace(node); -}; - - -/** - * Determine whether a node's text content is entirely whitespace. - * @param {Node} textNode A node implementing the CharacterData interface (i.e., - * a Text, Comment, or CDATASection node. - * @return {boolean} Whether the text content of node is whitespace, - * otherwise false. - */ -goog.editor.node.isAllNonNbspWhiteSpace = function(textNode) { - return goog.string.isBreakingWhitespace(textNode.nodeValue); -}; - - -/** - * Returns true if the node contains only whitespace and is not and does not - * contain any images, iframes or embed tags. - * @param {Node} node The node to check. - * @param {boolean=} opt_prohibitSingleNbsp By default, this function treats a - * single nbsp as empty. Set this to true to treat this case as non-empty. - * @return {boolean} Whether the node contains only whitespace. - */ -goog.editor.node.isEmpty = function(node, opt_prohibitSingleNbsp) { - var nodeData = goog.dom.getRawTextContent(node); - - if (node.getElementsByTagName) { - for (var tag in goog.editor.node.NON_EMPTY_TAGS_) { - if (node.tagName == tag || node.getElementsByTagName(tag).length > 0) { - return false; - } - } - } - return (!opt_prohibitSingleNbsp && nodeData == goog.string.Unicode.NBSP) || - goog.string.isBreakingWhitespace(nodeData); -}; - - -/** - * Returns the length of the text in node if it is a text node, or the number - * of children of the node, if it is an element. Useful for range-manipulation - * code where you need to know the offset for the right side of the node. - * @param {Node} node The node to get the length of. - * @return {number} The length of the node. - */ -goog.editor.node.getLength = function(node) { - return node.length || node.childNodes.length; -}; - - -/** - * Search child nodes using a predicate function and return the first node that - * satisfies the condition. - * @param {Node} parent The parent node to search. - * @param {function(Node):boolean} hasProperty A function that takes a child - * node as a parameter and returns true if it meets the criteria. - * @return {?number} The index of the node found, or null if no node is found. - */ -goog.editor.node.findInChildren = function(parent, hasProperty) { - for (var i = 0, len = parent.childNodes.length; i < len; i++) { - if (hasProperty(parent.childNodes[i])) { - return i; - } - } - return null; -}; - - -/** - * Search ancestor nodes using a predicate function and returns the topmost - * ancestor in the chain of consecutive ancestors that satisfies the condition. - * - * @param {Node} node The node whose ancestors have to be searched. - * @param {function(Node): boolean} hasProperty A function that takes a parent - * node as a parameter and returns true if it meets the criteria. - * @return {Node} The topmost ancestor or null if no ancestor satisfies the - * predicate function. - */ -goog.editor.node.findHighestMatchingAncestor = function(node, hasProperty) { - var parent = node.parentNode; - var ancestor = null; - while (parent && hasProperty(parent)) { - ancestor = parent; - parent = parent.parentNode; - } - return ancestor; -}; - - -/** -* Checks if node is a block-level html element. The <tt>display</tt> css - * property is ignored. - * @param {Node} node The node to test. - * @return {boolean} Whether the node is a block-level node. - */ -goog.editor.node.isBlockTag = function(node) { - return !!goog.editor.node.BLOCK_TAG_NAMES_[node.tagName]; -}; - - -/** - * Skips siblings of a node that are empty text nodes. - * @param {Node} node A node. May be null. - * @return {Node} The node or the first sibling of the node that is not an - * empty text node. May be null. - */ -goog.editor.node.skipEmptyTextNodes = function(node) { - while (node && node.nodeType == goog.dom.NodeType.TEXT && - !node.nodeValue) { - node = node.nextSibling; - } - return node; -}; - - -/** - * Checks if an element is a top-level editable container (meaning that - * it itself is not editable, but all its child nodes are editable). - * @param {Node} element The element to test. - * @return {boolean} Whether the element is a top-level editable container. - */ -goog.editor.node.isEditableContainer = function(element) { - return element.getAttribute && - element.getAttribute('g_editable') == 'true'; -}; - - -/** - * Checks if a node is inside an editable container. - * @param {Node} node The node to test. - * @return {boolean} Whether the node is in an editable container. - */ -goog.editor.node.isEditable = function(node) { - return !!goog.dom.getAncestor(node, goog.editor.node.isEditableContainer); -}; - - -/** - * Finds the top-most DOM node inside an editable field that is an ancestor - * (or self) of a given DOM node and meets the specified criteria. - * @param {Node} node The DOM node where the search starts. - * @param {function(Node) : boolean} criteria A function that takes a DOM node - * as a parameter and returns a boolean to indicate whether the node meets - * the criteria or not. - * @return {Node} The DOM node if found, or null. - */ -goog.editor.node.findTopMostEditableAncestor = function(node, criteria) { - var targetNode = null; - while (node && !goog.editor.node.isEditableContainer(node)) { - if (criteria(node)) { - targetNode = node; - } - node = node.parentNode; - } - return targetNode; -}; - - -/** - * Splits off a subtree. - * @param {!Node} currentNode The starting splitting point. - * @param {Node=} opt_secondHalf The initial leftmost leaf the new subtree. - * If null, siblings after currentNode will be placed in the subtree, but - * no additional node will be. - * @param {Node=} opt_root The top of the tree where splitting stops at. - * @return {!Node} The new subtree. - */ -goog.editor.node.splitDomTreeAt = function(currentNode, - opt_secondHalf, opt_root) { - var parent; - while (currentNode != opt_root && (parent = currentNode.parentNode)) { - opt_secondHalf = goog.editor.node.getSecondHalfOfNode_(parent, currentNode, - opt_secondHalf); - currentNode = parent; - } - return /** @type {!Node} */(opt_secondHalf); -}; - - -/** - * Creates a clone of node, moving all children after startNode to it. - * When firstChild is not null or undefined, it is also appended to the clone - * as the first child. - * @param {!Node} node The node to clone. - * @param {!Node} startNode All siblings after this node will be moved to the - * clone. - * @param {Node|undefined} firstChild The first child of the new cloned element. - * @return {!Node} The cloned node that now contains the children after - * startNode. - * @private - */ -goog.editor.node.getSecondHalfOfNode_ = function(node, startNode, firstChild) { - var secondHalf = /** @type {!Node} */(node.cloneNode(false)); - while (startNode.nextSibling) { - goog.dom.appendChild(secondHalf, startNode.nextSibling); - } - if (firstChild) { - secondHalf.insertBefore(firstChild, secondHalf.firstChild); - } - return secondHalf; -}; - - -/** - * Appends all of oldNode's children to newNode. This removes all children from - * oldNode and appends them to newNode. oldNode is left with no children. - * @param {!Node} newNode Node to transfer children to. - * @param {Node} oldNode Node to transfer children from. - * @deprecated Use goog.dom.append directly instead. - */ -goog.editor.node.transferChildren = function(newNode, oldNode) { - goog.dom.append(newNode, oldNode.childNodes); -}; |