Path: blob/trunk/third_party/closure/goog/dom/nodeoffset.js
2868 views
// Copyright 2005 The Closure Library Authors. All Rights Reserved.1//2// Licensed under the Apache License, Version 2.0 (the "License");3// you may not use this file except in compliance with the License.4// You may obtain a copy of the License at5//6// http://www.apache.org/licenses/LICENSE-2.07//8// Unless required by applicable law or agreed to in writing, software9// distributed under the License is distributed on an "AS-IS" BASIS,10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.11// See the License for the specific language governing permissions and12// limitations under the License.1314/**15* @fileoverview Object to store the offset from one node to another in a way16* that works on any similar DOM structure regardless of whether it is the same17* actual nodes.18*19* @author [email protected] (Robby Walker)20*/2122goog.provide('goog.dom.NodeOffset');2324goog.require('goog.Disposable');25goog.require('goog.dom.TagName');26272829/**30* Object to store the offset from one node to another in a way that works on31* any similar DOM structure regardless of whether it is the same actual nodes.32* @param {Node} node The node to get the offset for.33* @param {Node} baseNode The node to calculate the offset from.34* @extends {goog.Disposable}35* @constructor36* @final37*/38goog.dom.NodeOffset = function(node, baseNode) {39goog.Disposable.call(this);4041/**42* A stack of childNode offsets.43* @type {Array<number>}44* @private45*/46this.offsetStack_ = [];4748/**49* A stack of childNode names.50* @type {Array<string>}51* @private52*/53this.nameStack_ = [];5455while (node && node.nodeName != goog.dom.TagName.BODY && node != baseNode) {56// Compute the sibling offset.57var siblingOffset = 0;58var sib = node.previousSibling;59while (sib) {60sib = sib.previousSibling;61++siblingOffset;62}63this.offsetStack_.unshift(siblingOffset);64this.nameStack_.unshift(node.nodeName);6566node = node.parentNode;67}68};69goog.inherits(goog.dom.NodeOffset, goog.Disposable);707172/**73* @return {string} A string representation of this object.74* @override75*/76goog.dom.NodeOffset.prototype.toString = function() {77var strs = [];78var name;79for (var i = 0; name = this.nameStack_[i]; i++) {80strs.push(this.offsetStack_[i] + ',' + name);81}82return strs.join('\n');83};848586/**87* Walk the dom and find the node relative to baseNode. Returns null on88* failure.89* @param {Node} baseNode The node to start walking from. Should be equivalent90* to the node passed in to the constructor, in that it should have the91* same contents.92* @return {Node} The node relative to baseNode, or null on failure.93*/94goog.dom.NodeOffset.prototype.findTargetNode = function(baseNode) {95var name;96var curNode = baseNode;97for (var i = 0; name = this.nameStack_[i]; ++i) {98curNode = curNode.childNodes[this.offsetStack_[i]];99100// Sanity check and make sure the element names match.101if (!curNode || curNode.nodeName != name) {102return null;103}104}105return curNode;106};107108109/** @override */110goog.dom.NodeOffset.prototype.disposeInternal = function() {111delete this.offsetStack_;112delete this.nameStack_;113};114115116