Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
seleniumhq
GitHub Repository: seleniumhq/selenium
Path: blob/trunk/third_party/closure/goog/dom/pattern/matcher.js
2868 views
1
// Copyright 2007 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
/**
16
* @fileoverview DOM pattern matcher. Allows for simple searching of DOM
17
* using patterns descended from {@link goog.dom.pattern.AbstractPattern}.
18
*
19
* @author [email protected] (Robby Walker)
20
*/
21
22
goog.provide('goog.dom.pattern.Matcher');
23
24
goog.require('goog.dom.TagIterator');
25
goog.require('goog.dom.pattern.MatchType');
26
goog.require('goog.iter');
27
28
29
// TODO(robbyw): Allow for backtracks of size > 1.
30
31
32
33
/**
34
* Given a set of patterns and a root node, this class tests the patterns in
35
* parallel.
36
*
37
* It is not (yet) a smart matcher - it doesn't do any advanced backtracking.
38
* Given the pattern <code>DIV, SPAN</code> the matcher will not match
39
* <code>DIV, DIV, SPAN</code> because it starts matching at the first
40
* <code>DIV</code>, fails to match <code>SPAN</code> at the second, and never
41
* backtracks to try again.
42
*
43
* It is also possible to have a set of complex patterns that when matched in
44
* parallel will miss some possible matches. Running multiple times will catch
45
* all matches eventually.
46
*
47
* @constructor
48
* @final
49
*/
50
goog.dom.pattern.Matcher = function() {
51
/**
52
* Array of patterns to attempt to match in parallel.
53
*
54
* @private {Array<goog.dom.pattern.AbstractPattern>}
55
*/
56
this.patterns_ = [];
57
58
/**
59
* Array of callbacks to call when a pattern is matched. The indexing is the
60
* same as the {@link #patterns_} array.
61
*
62
* @private {Array<Function>}
63
*/
64
this.callbacks_ = [];
65
};
66
67
68
/**
69
* Adds a pattern to be matched. The callback can return an object whose keys
70
* are processing instructions.
71
*
72
* @param {goog.dom.pattern.AbstractPattern} pattern The pattern to add.
73
* @param {Function} callback Function to call when a match is found. Uses
74
* the above semantics.
75
*/
76
goog.dom.pattern.Matcher.prototype.addPattern = function(pattern, callback) {
77
this.patterns_.push(pattern);
78
this.callbacks_.push(callback);
79
};
80
81
82
/**
83
* Resets all the patterns.
84
*
85
* @private
86
*/
87
goog.dom.pattern.Matcher.prototype.reset_ = function() {
88
for (var i = 0, len = this.patterns_.length; i < len; i++) {
89
this.patterns_[i].reset();
90
}
91
};
92
93
94
/**
95
* Test the given node against all patterns.
96
*
97
* @param {goog.dom.TagIterator} position A position in a node walk that is
98
* located at the token to process.
99
* @return {boolean} Whether a pattern modified the position or tree
100
* and its callback resulted in DOM structure or position modification.
101
* @private
102
*/
103
goog.dom.pattern.Matcher.prototype.matchToken_ = function(position) {
104
for (var i = 0, len = this.patterns_.length; i < len; i++) {
105
var pattern = this.patterns_[i];
106
switch (pattern.matchToken(position.node, position.tagType)) {
107
case goog.dom.pattern.MatchType.MATCH:
108
case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
109
var callback = this.callbacks_[i];
110
111
// Callbacks are allowed to modify the current position, but must
112
// return true if the do.
113
if (callback(pattern.matchedNode, position, pattern)) {
114
return true;
115
}
116
117
default:
118
// Do nothing.
119
break;
120
}
121
}
122
123
return false;
124
};
125
126
127
/**
128
* Match the set of patterns against a match tree.
129
*
130
* @param {Node} node The root node of the tree to match.
131
*/
132
goog.dom.pattern.Matcher.prototype.match = function(node) {
133
var position = new goog.dom.TagIterator(node);
134
135
this.reset_();
136
137
goog.iter.forEach(position, function() {
138
while (this.matchToken_(position)) {
139
// Since we've moved, our old pattern statuses don't make sense any more.
140
// Reset them.
141
this.reset_();
142
}
143
}, this);
144
};
145
146