Path: blob/trunk/third_party/closure/goog/dom/pattern/sequence.js
2868 views
// Copyright 2007 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 DOM pattern to match a sequence of other patterns.16*17* @author [email protected] (Robby Walker)18*/1920goog.provide('goog.dom.pattern.Sequence');2122goog.require('goog.dom.NodeType');23goog.require('goog.dom.pattern');24goog.require('goog.dom.pattern.AbstractPattern');25goog.require('goog.dom.pattern.MatchType');26272829/**30* Pattern object that matches a sequence of other patterns.31*32* @param {Array<goog.dom.pattern.AbstractPattern>} patterns Ordered array of33* patterns to match.34* @param {boolean=} opt_ignoreWhitespace Optional flag to ignore text nodes35* consisting entirely of whitespace. The default is to not ignore them.36* @constructor37* @extends {goog.dom.pattern.AbstractPattern}38* @final39*/40goog.dom.pattern.Sequence = function(patterns, opt_ignoreWhitespace) {41/**42* Ordered array of patterns to match.43*44* @type {Array<goog.dom.pattern.AbstractPattern>}45*/46this.patterns = patterns;4748/**49* Whether or not to ignore whitespace only Text nodes.50*51* @private {boolean}52*/53this.ignoreWhitespace_ = !!opt_ignoreWhitespace;5455/**56* Position in the patterns array we have reached by successful matches.57*58* @private {number}59*/60this.currentPosition_ = 0;61};62goog.inherits(goog.dom.pattern.Sequence, goog.dom.pattern.AbstractPattern);636465/**66* Regular expression for breaking text nodes.67* @private {!RegExp}68*/69goog.dom.pattern.Sequence.BREAKING_TEXTNODE_RE_ = /^\s*$/;707172/**73* Test whether the given token starts, continues, or finishes the sequence74* of patterns given in the constructor.75*76* @param {Node} token Token to match against.77* @param {goog.dom.TagWalkType} type The type of token.78* @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern79* matches, <code>MATCHING</code> if the pattern starts a match, and80* <code>NO_MATCH</code> if the pattern does not match.81* @override82*/83goog.dom.pattern.Sequence.prototype.matchToken = function(token, type) {84// If the option is set, ignore any whitespace only text nodes85if (this.ignoreWhitespace_ && token.nodeType == goog.dom.NodeType.TEXT &&86goog.dom.pattern.Sequence.BREAKING_TEXTNODE_RE_.test(token.nodeValue)) {87return goog.dom.pattern.MatchType.MATCHING;88}8990switch (this.patterns[this.currentPosition_].matchToken(token, type)) {91case goog.dom.pattern.MatchType.MATCH:92// Record the first token we match.93if (this.currentPosition_ == 0) {94this.matchedNode = token;95}9697// Move forward one position.98this.currentPosition_++;99100// Check if this is the last position.101if (this.currentPosition_ == this.patterns.length) {102this.reset();103return goog.dom.pattern.MatchType.MATCH;104} else {105return goog.dom.pattern.MatchType.MATCHING;106}107108case goog.dom.pattern.MatchType.MATCHING:109// This can happen when our child pattern is a sequence or a repetition.110return goog.dom.pattern.MatchType.MATCHING;111112case goog.dom.pattern.MatchType.BACKTRACK_MATCH:113// This means a repetitive match succeeded 1 token ago.114// TODO(robbyw): Backtrack further if necessary.115this.currentPosition_++;116117if (this.currentPosition_ == this.patterns.length) {118this.reset();119return goog.dom.pattern.MatchType.BACKTRACK_MATCH;120} else {121// Retry the same token on the next pattern.122return this.matchToken(token, type);123}124125default:126this.reset();127return goog.dom.pattern.MatchType.NO_MATCH;128}129};130131132/**133* Reset any internal state this pattern keeps.134* @override135*/136goog.dom.pattern.Sequence.prototype.reset = function() {137if (this.patterns[this.currentPosition_]) {138this.patterns[this.currentPosition_].reset();139}140this.currentPosition_ = 0;141};142143144