iter.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2008 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview Iterators over DOM nodes.
  16. *
  17. * @author robbyw@google.com (Robby Walker)
  18. */
  19. goog.provide('goog.dom.iter.AncestorIterator');
  20. goog.provide('goog.dom.iter.ChildIterator');
  21. goog.provide('goog.dom.iter.SiblingIterator');
  22. goog.require('goog.iter.Iterator');
  23. goog.require('goog.iter.StopIteration');
  24. /**
  25. * Iterator over a Node's siblings.
  26. * @param {Node} node The node to start with.
  27. * @param {boolean=} opt_includeNode Whether to return the given node as the
  28. * first return value from next.
  29. * @param {boolean=} opt_reverse Whether to traverse siblings in reverse
  30. * document order.
  31. * @constructor
  32. * @extends {goog.iter.Iterator}
  33. */
  34. goog.dom.iter.SiblingIterator = function(node, opt_includeNode, opt_reverse) {
  35. /**
  36. * The current node, or null if iteration is finished.
  37. * @type {Node}
  38. * @private
  39. */
  40. this.node_ = node;
  41. /**
  42. * Whether to iterate in reverse.
  43. * @type {boolean}
  44. * @private
  45. */
  46. this.reverse_ = !!opt_reverse;
  47. if (node && !opt_includeNode) {
  48. this.next();
  49. }
  50. };
  51. goog.inherits(goog.dom.iter.SiblingIterator, goog.iter.Iterator);
  52. /** @override */
  53. goog.dom.iter.SiblingIterator.prototype.next = function() {
  54. var node = this.node_;
  55. if (!node) {
  56. throw goog.iter.StopIteration;
  57. }
  58. this.node_ = this.reverse_ ? node.previousSibling : node.nextSibling;
  59. return node;
  60. };
  61. /**
  62. * Iterator over an Element's children.
  63. * @param {Element} element The element to iterate over.
  64. * @param {boolean=} opt_reverse Optionally traverse children from last to
  65. * first.
  66. * @param {number=} opt_startIndex Optional starting index.
  67. * @constructor
  68. * @extends {goog.dom.iter.SiblingIterator}
  69. * @final
  70. */
  71. goog.dom.iter.ChildIterator = function(element, opt_reverse, opt_startIndex) {
  72. if (!goog.isDef(opt_startIndex)) {
  73. opt_startIndex = opt_reverse && element.childNodes.length ?
  74. element.childNodes.length - 1 :
  75. 0;
  76. }
  77. goog.dom.iter.SiblingIterator.call(
  78. this, element.childNodes[opt_startIndex], true, opt_reverse);
  79. };
  80. goog.inherits(goog.dom.iter.ChildIterator, goog.dom.iter.SiblingIterator);
  81. /**
  82. * Iterator over a Node's ancestors, stopping after the document body.
  83. * @param {Node} node The node to start with.
  84. * @param {boolean=} opt_includeNode Whether to return the given node as the
  85. * first return value from next.
  86. * @constructor
  87. * @extends {goog.iter.Iterator}
  88. * @final
  89. */
  90. goog.dom.iter.AncestorIterator = function(node, opt_includeNode) {
  91. /**
  92. * The current node, or null if iteration is finished.
  93. * @type {Node}
  94. * @private
  95. */
  96. this.node_ = node;
  97. if (node && !opt_includeNode) {
  98. this.next();
  99. }
  100. };
  101. goog.inherits(goog.dom.iter.AncestorIterator, goog.iter.Iterator);
  102. /** @override */
  103. goog.dom.iter.AncestorIterator.prototype.next = function() {
  104. var node = this.node_;
  105. if (!node) {
  106. throw goog.iter.StopIteration;
  107. }
  108. this.node_ = node.parentNode;
  109. return node;
  110. };