1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * @fileoverview Utilities for finding DOM nodes and CursorSelection's.
10 goog
.provide('cvox.FindUtil');
12 goog
.require('cvox.BareObjectWalker');
13 goog
.require('cvox.CursorSelection');
17 * @type {!cvox.BareObjectWalker}
20 cvox
.FindUtil
.objectWalker_
= new cvox
.BareObjectWalker();
24 * Finds the next selection that matches the predicate function starting from
25 * sel. Undefined if the nodes in sel are not attached to the document.
26 * @param {!cvox.CursorSelection} sel The selection from which to start.
27 * @param {function(Array<Node>):Node} predicate A function taking a
28 * unique ancestor tree and outputting Node if the ancestor tree matches
29 * the desired node to find.
30 * @param {boolean=} opt_initialNode Whether to start the search from node
31 * (true), or the next node (false); defaults to false.
32 * @return {cvox.CursorSelection} The selection that was found.
33 * null if end of document reached.
35 cvox
.FindUtil
.findNext = function(sel
, predicate
, opt_initialNode
) {
36 var r
= sel
.isReversed();
37 var cur
= new cvox
.CursorSelection(sel
.absStart(), sel
.absStart())
40 // We may have been sync'ed into a subtree of the current predicate match.
41 // Find our ancestor that matches the predicate.
43 if (ancestor
= predicate(cvox
.DomUtil
.getAncestors(cur
.start
.node
))) {
44 cur
= cvox
.CursorSelection
.fromNode(ancestor
).setReversed(r
);
45 if (opt_initialNode
) {
51 // Use ObjectWalker's traversal which guarantees us a stable iteration of
52 // the DOM including returning null at page bounds.
53 cur
= cvox
.FindUtil
.objectWalker_
.next(cur
);
56 (retNode
= predicate(cvox
.DomUtil
.getAncestors(cur
.start
.node
)))) {
57 return retNode
? cvox
.CursorSelection
.fromNode(retNode
) : null;
60 // Iframes require inter-frame messaging.
61 if (cur
.start
.node
.tagName
== 'IFRAME') {