You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by ft...@apache.org on 2015/09/17 17:28:43 UTC
[28/51] [abbrv] [partial] git commit: [flex-falcon]
[refs/heads/JsToAs] - Added GCL extern.
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/nodetype.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/nodetype.js b/externs/GCL/externs/goog/dom/pattern/nodetype.js
new file mode 100644
index 0000000..a12c9a1
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/nodetype.js
@@ -0,0 +1,59 @@
+// Copyright 2008 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match a node of the given type.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.NodeType');
+
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches any node of the given type.
+ * @param {goog.dom.NodeType} nodeType The node type to match.
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ * @final
+ */
+goog.dom.pattern.NodeType = function(nodeType) {
+ /**
+ * The node type to match.
+ * @type {goog.dom.NodeType}
+ * @private
+ */
+ this.nodeType_ = nodeType;
+};
+goog.inherits(goog.dom.pattern.NodeType, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token is a text token which matches the string or
+ * regular expression provided in the constructor.
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern
+ * matches, <code>NO_MATCH</code> otherwise.
+ * @override
+ */
+goog.dom.pattern.NodeType.prototype.matchToken = function(token, type) {
+ return token.nodeType == this.nodeType_ ?
+ goog.dom.pattern.MatchType.MATCH :
+ goog.dom.pattern.MatchType.NO_MATCH;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/pattern.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/pattern.js b/externs/GCL/externs/goog/dom/pattern/pattern.js
new file mode 100644
index 0000000..19f4d1b
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/pattern.js
@@ -0,0 +1,93 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM patterns. Allows for description of complex DOM patterns
+ * using regular expression like constructs.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern');
+goog.provide('goog.dom.pattern.MatchType');
+
+
+/**
+ * Regular expression for breaking text nodes.
+ * @type {RegExp}
+ */
+goog.dom.pattern.BREAKING_TEXTNODE_RE = /^\s*$/;
+
+
+/**
+ * Utility function to match a string against either a string or a regular
+ * expression.
+ *
+ * @param {string|RegExp} obj Either a string or a regular expression.
+ * @param {string} str The string to match.
+ * @return {boolean} Whether the strings are equal, or if the string matches
+ * the regular expression.
+ */
+goog.dom.pattern.matchStringOrRegex = function(obj, str) {
+ if (goog.isString(obj)) {
+ // Match a string
+ return str == obj;
+ } else {
+ // Match a regular expression
+ return !!(str && str.match(obj));
+ }
+};
+
+
+/**
+ * Utility function to match a DOM attribute against either a string or a
+ * regular expression. Conforms to the interface spec for
+ * {@link goog.object#every}.
+ *
+ * @param {string|RegExp} elem Either a string or a regular expression.
+ * @param {string} index The attribute name to match.
+ * @param {Object} orig The original map of matches to test.
+ * @return {boolean} Whether the strings are equal, or if the attribute matches
+ * the regular expression.
+ * @this {Element} Called using goog.object every on an Element.
+ */
+goog.dom.pattern.matchStringOrRegexMap = function(elem, index, orig) {
+ return goog.dom.pattern.matchStringOrRegex(elem,
+ index in this ? this[index] :
+ (this.getAttribute ? this.getAttribute(index) : null));
+};
+
+
+/**
+ * When matched to a token, a pattern may return any of the following statuses:
+ * <ol>
+ * <li><code>NO_MATCH</code> - The pattern does not match. This is the only
+ * value that evaluates to <code>false</code> in a boolean context.
+ * <li><code>MATCHING</code> - The token is part of an incomplete match.
+ * <li><code>MATCH</code> - The token completes a match.
+ * <li><code>BACKTRACK_MATCH</code> - The token does not match, but indicates
+ * the end of a repetitive match. For instance, in regular expressions,
+ * the pattern <code>/a+/</code> would match <code>'aaaaaaaab'</code>.
+ * Every <code>'a'</code> token would give a status of
+ * <code>MATCHING</code> while the <code>'b'</code> token would give a
+ * status of <code>BACKTRACK_MATCH</code>.
+ * </ol>
+ * @enum {number}
+ */
+goog.dom.pattern.MatchType = {
+ NO_MATCH: 0,
+ MATCHING: 1,
+ MATCH: 2,
+ BACKTRACK_MATCH: 3
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/repeat.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/repeat.js b/externs/GCL/externs/goog/dom/pattern/repeat.js
new file mode 100644
index 0000000..392a6a6
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/repeat.js
@@ -0,0 +1,177 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match a tag and all of its children.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.Repeat');
+
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches a repetition of another pattern.
+ * @param {goog.dom.pattern.AbstractPattern} pattern The pattern to
+ * repetitively match.
+ * @param {number=} opt_minimum The minimum number of times to match. Defaults
+ * to 0.
+ * @param {number=} opt_maximum The maximum number of times to match. Defaults
+ * to unlimited.
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ * @final
+ */
+goog.dom.pattern.Repeat = function(pattern,
+ opt_minimum,
+ opt_maximum) {
+ /**
+ * Pattern to repetitively match.
+ *
+ * @private {goog.dom.pattern.AbstractPattern}
+ */
+ this.pattern_ = pattern;
+
+ /**
+ * Minimum number of times to match the pattern.
+ *
+ * @private {number}
+ */
+ this.minimum_ = opt_minimum || 0;
+
+ /**
+ * Optional maximum number of times to match the pattern. A {@code null} value
+ * will be treated as infinity.
+ *
+ * @private {?number}
+ */
+ this.maximum_ = opt_maximum || null;
+
+ /**
+ * The matched nodes.
+ *
+ * @type {Array<Node>}
+ */
+ this.matches = [];
+
+ /**
+ * Number of times the pattern has matched.
+ *
+ * @type {number}
+ */
+ this.count = 0;
+
+ /**
+ * Whether the pattern has recently matched or failed to match and will need
+ * to be reset when starting a new round of matches.
+ *
+ * @private {boolean}
+ */
+ this.needsReset_ = false;
+};
+goog.inherits(goog.dom.pattern.Repeat, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token continues a repeated series of matches of the
+ * pattern given in the constructor.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern
+ * matches, <code>BACKTRACK_MATCH</code> if the pattern does not match
+ * but already had accumulated matches, <code>MATCHING</code> if the pattern
+ * starts a match, and <code>NO_MATCH</code> if the pattern does not match.
+ * @suppress {missingProperties} See the broken line below.
+ * @override
+ */
+goog.dom.pattern.Repeat.prototype.matchToken = function(token, type) {
+ // Reset if we're starting a new match
+ if (this.needsReset_) {
+ this.reset();
+ }
+
+ // If the option is set, ignore any whitespace only text nodes
+ if (token.nodeType == goog.dom.NodeType.TEXT &&
+ token.nodeValue.match(/^\s+$/)) {
+ return goog.dom.pattern.MatchType.MATCHING;
+ }
+
+ switch (this.pattern_.matchToken(token, type)) {
+ case goog.dom.pattern.MatchType.MATCH:
+ // Record the first token we match.
+ if (this.count == 0) {
+ this.matchedNode = token;
+ }
+
+ // Mark the match
+ this.count++;
+
+ // Add to the list
+ this.matches.push(this.pattern_.matchedNode);
+
+ // Check if this match hits our maximum
+ if (this.maximum_ !== null && this.count == this.maximum_) {
+ this.needsReset_ = true;
+ return goog.dom.pattern.MatchType.MATCH;
+ } else {
+ return goog.dom.pattern.MatchType.MATCHING;
+ }
+
+ case goog.dom.pattern.MatchType.MATCHING:
+ // This can happen when our child pattern is a sequence or a repetition.
+ return goog.dom.pattern.MatchType.MATCHING;
+
+ case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
+ // This happens if our child pattern is repetitive too.
+ // TODO(robbyw): Backtrack further if necessary.
+ this.count++;
+
+ // NOTE(nicksantos): This line of code is broken. this.patterns_ doesn't
+ // exist, and this.currentPosition_ doesn't exit. When this is fixed,
+ // remove the missingProperties suppression above.
+ if (this.currentPosition_ == this.patterns_.length) {
+ this.needsReset_ = true;
+ return goog.dom.pattern.MatchType.BACKTRACK_MATCH;
+ } else {
+ // Retry the same token on the next iteration of the child pattern.
+ return this.matchToken(token, type);
+ }
+
+ default:
+ this.needsReset_ = true;
+ if (this.count >= this.minimum_) {
+ return goog.dom.pattern.MatchType.BACKTRACK_MATCH;
+ } else {
+ return goog.dom.pattern.MatchType.NO_MATCH;
+ }
+ }
+};
+
+
+/**
+ * Reset any internal state this pattern keeps.
+ * @override
+ */
+goog.dom.pattern.Repeat.prototype.reset = function() {
+ this.pattern_.reset();
+ this.count = 0;
+ this.needsReset_ = false;
+ this.matches.length = 0;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/sequence.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/sequence.js b/externs/GCL/externs/goog/dom/pattern/sequence.js
new file mode 100644
index 0000000..2282361
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/sequence.js
@@ -0,0 +1,135 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match a sequence of other patterns.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.Sequence');
+
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.pattern');
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches a sequence of other patterns.
+ *
+ * @param {Array<goog.dom.pattern.AbstractPattern>} patterns Ordered array of
+ * patterns to match.
+ * @param {boolean=} opt_ignoreWhitespace Optional flag to ignore text nodes
+ * consisting entirely of whitespace. The default is to not ignore them.
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ * @final
+ */
+goog.dom.pattern.Sequence = function(patterns, opt_ignoreWhitespace) {
+ /**
+ * Ordered array of patterns to match.
+ *
+ * @type {Array<goog.dom.pattern.AbstractPattern>}
+ */
+ this.patterns = patterns;
+
+ /**
+ * Whether or not to ignore whitespace only Text nodes.
+ *
+ * @private {boolean}
+ */
+ this.ignoreWhitespace_ = !!opt_ignoreWhitespace;
+
+ /**
+ * Position in the patterns array we have reached by successful matches.
+ *
+ * @private {number}
+ */
+ this.currentPosition_ = 0;
+};
+goog.inherits(goog.dom.pattern.Sequence, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token starts, continues, or finishes the sequence
+ * of patterns given in the constructor.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern
+ * matches, <code>MATCHING</code> if the pattern starts a match, and
+ * <code>NO_MATCH</code> if the pattern does not match.
+ * @override
+ */
+goog.dom.pattern.Sequence.prototype.matchToken = function(token, type) {
+ // If the option is set, ignore any whitespace only text nodes
+ if (this.ignoreWhitespace_ && token.nodeType == goog.dom.NodeType.TEXT &&
+ goog.dom.pattern.BREAKING_TEXTNODE_RE.test(token.nodeValue)) {
+ return goog.dom.pattern.MatchType.MATCHING;
+ }
+
+ switch (this.patterns[this.currentPosition_].matchToken(token, type)) {
+ case goog.dom.pattern.MatchType.MATCH:
+ // Record the first token we match.
+ if (this.currentPosition_ == 0) {
+ this.matchedNode = token;
+ }
+
+ // Move forward one position.
+ this.currentPosition_++;
+
+ // Check if this is the last position.
+ if (this.currentPosition_ == this.patterns.length) {
+ this.reset();
+ return goog.dom.pattern.MatchType.MATCH;
+ } else {
+ return goog.dom.pattern.MatchType.MATCHING;
+ }
+
+ case goog.dom.pattern.MatchType.MATCHING:
+ // This can happen when our child pattern is a sequence or a repetition.
+ return goog.dom.pattern.MatchType.MATCHING;
+
+ case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
+ // This means a repetitive match succeeded 1 token ago.
+ // TODO(robbyw): Backtrack further if necessary.
+ this.currentPosition_++;
+
+ if (this.currentPosition_ == this.patterns.length) {
+ this.reset();
+ return goog.dom.pattern.MatchType.BACKTRACK_MATCH;
+ } else {
+ // Retry the same token on the next pattern.
+ return this.matchToken(token, type);
+ }
+
+ default:
+ this.reset();
+ return goog.dom.pattern.MatchType.NO_MATCH;
+ }
+};
+
+
+/**
+ * Reset any internal state this pattern keeps.
+ * @override
+ */
+goog.dom.pattern.Sequence.prototype.reset = function() {
+ if (this.patterns[this.currentPosition_]) {
+ this.patterns[this.currentPosition_].reset();
+ }
+ this.currentPosition_ = 0;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/starttag.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/starttag.js b/externs/GCL/externs/goog/dom/pattern/starttag.js
new file mode 100644
index 0000000..4ce0113
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/starttag.js
@@ -0,0 +1,53 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match the start of a tag.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.StartTag');
+
+goog.require('goog.dom.TagWalkType');
+goog.require('goog.dom.pattern.Tag');
+
+
+
+/**
+ * Pattern object that matches an opening tag.
+ *
+ * @param {string|RegExp} tag Name of the tag. Also will accept a regular
+ * expression to match against the tag name.
+ * @param {Object=} opt_attrs Optional map of attribute names to desired values.
+ * This pattern will only match when all attributes are present and match
+ * the string or regular expression value provided here.
+ * @param {Object=} opt_styles Optional map of CSS style names to desired
+ * values. This pattern will only match when all styles are present and
+ * match the string or regular expression value provided here.
+ * @param {Function=} opt_test Optional function that takes the element as a
+ * parameter and returns true if this pattern should match it.
+ * @constructor
+ * @extends {goog.dom.pattern.Tag}
+ */
+goog.dom.pattern.StartTag = function(tag, opt_attrs, opt_styles, opt_test) {
+ goog.dom.pattern.Tag.call(
+ this,
+ tag,
+ goog.dom.TagWalkType.START_TAG,
+ opt_attrs,
+ opt_styles,
+ opt_test);
+};
+goog.inherits(goog.dom.pattern.StartTag, goog.dom.pattern.Tag);
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/tag.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/tag.js b/externs/GCL/externs/goog/dom/pattern/tag.js
new file mode 100644
index 0000000..ba95123
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/tag.js
@@ -0,0 +1,128 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match a tag.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.Tag');
+
+goog.require('goog.dom.pattern');
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+goog.require('goog.object');
+
+
+
+/**
+ * Pattern object that matches an tag.
+ *
+ * @param {string|RegExp} tag Name of the tag. Also will accept a regular
+ * expression to match against the tag name.
+ * @param {goog.dom.TagWalkType} type Type of token to match.
+ * @param {Object=} opt_attrs Optional map of attribute names to desired values.
+ * This pattern will only match when all attributes are present and match
+ * the string or regular expression value provided here.
+ * @param {Object=} opt_styles Optional map of CSS style names to desired
+ * values. This pattern will only match when all styles are present and
+ * match the string or regular expression value provided here.
+ * @param {Function=} opt_test Optional function that takes the element as a
+ * parameter and returns true if this pattern should match it.
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ */
+goog.dom.pattern.Tag = function(tag, type, opt_attrs, opt_styles, opt_test) {
+ /**
+ * The tag to match.
+ *
+ * @private {string|RegExp}
+ */
+ this.tag_ = goog.isString(tag) ? tag.toUpperCase() : tag;
+
+ /**
+ * The type of token to match.
+ *
+ * @private {goog.dom.TagWalkType}
+ */
+ this.type_ = type;
+
+ /**
+ * The attributes to test for.
+ *
+ * @private {Object}
+ */
+ this.attrs_ = opt_attrs || null;
+
+ /**
+ * The styles to test for.
+ *
+ * @private {Object}
+ */
+ this.styles_ = opt_styles || null;
+
+ /**
+ * Function that takes the element as a parameter and returns true if this
+ * pattern should match it.
+ *
+ * @private {Function}
+ */
+ this.test_ = opt_test || null;
+};
+goog.inherits(goog.dom.pattern.Tag, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token is a tag token which matches the tag name,
+ * style, and attributes provided in the constructor.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern
+ * matches, <code>NO_MATCH</code> otherwise.
+ * @override
+ */
+goog.dom.pattern.Tag.prototype.matchToken = function(token, type) {
+ // Check the direction and tag name.
+ if (type == this.type_ &&
+ goog.dom.pattern.matchStringOrRegex(this.tag_, token.nodeName)) {
+ // Check the attributes.
+ if (this.attrs_ &&
+ !goog.object.every(
+ this.attrs_,
+ goog.dom.pattern.matchStringOrRegexMap,
+ token)) {
+ return goog.dom.pattern.MatchType.NO_MATCH;
+ }
+ // Check the styles.
+ if (this.styles_ &&
+ !goog.object.every(
+ this.styles_,
+ goog.dom.pattern.matchStringOrRegexMap,
+ token.style)) {
+ return goog.dom.pattern.MatchType.NO_MATCH;
+ }
+
+ if (this.test_ && !this.test_(token)) {
+ return goog.dom.pattern.MatchType.NO_MATCH;
+ }
+
+ // If we reach this point, we have a match and should save it.
+ this.matchedNode = token;
+ return goog.dom.pattern.MatchType.MATCH;
+ }
+
+ return goog.dom.pattern.MatchType.NO_MATCH;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/text.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/text.js b/externs/GCL/externs/goog/dom/pattern/text.js
new file mode 100644
index 0000000..cf920e1
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/text.js
@@ -0,0 +1,67 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview DOM pattern to match a text node.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.Text');
+
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.pattern');
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches text by exact matching or regular expressions.
+ *
+ * @param {string|RegExp} match String or regular expression to match against.
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ * @final
+ */
+goog.dom.pattern.Text = function(match) {
+ /**
+ * The text or regular expression to match.
+ *
+ * @private {string|RegExp}
+ */
+ this.match_ = match;
+};
+goog.inherits(goog.dom.pattern.Text, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token is a text token which matches the string or
+ * regular expression provided in the constructor.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} <code>MATCH</code> if the pattern
+ * matches, <code>NO_MATCH</code> otherwise.
+ * @override
+ */
+goog.dom.pattern.Text.prototype.matchToken = function(token, type) {
+ if (token.nodeType == goog.dom.NodeType.TEXT &&
+ goog.dom.pattern.matchStringOrRegex(this.match_, token.nodeValue)) {
+ this.matchedNode = token;
+ return goog.dom.pattern.MatchType.MATCH;
+ }
+
+ return goog.dom.pattern.MatchType.NO_MATCH;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/range.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/range.js b/externs/GCL/externs/goog/dom/range.js
new file mode 100644
index 0000000..eec784a
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/range.js
@@ -0,0 +1,226 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Utilities for working with ranges in HTML documents.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.Range');
+
+goog.require('goog.dom');
+goog.require('goog.dom.AbstractRange');
+goog.require('goog.dom.BrowserFeature');
+goog.require('goog.dom.ControlRange');
+goog.require('goog.dom.MultiRange');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.TextRange');
+
+
+/**
+ * Create a new selection from the given browser window's current selection.
+ * Note that this object does not auto-update if the user changes their
+ * selection and should be used as a snapshot.
+ * @param {Window=} opt_win The window to get the selection of. Defaults to the
+ * window this class was defined in.
+ * @return {goog.dom.AbstractRange?} A range wrapper object, or null if there
+ * was an error.
+ */
+goog.dom.Range.createFromWindow = function(opt_win) {
+ var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(
+ opt_win || window);
+ return sel && goog.dom.Range.createFromBrowserSelection(sel);
+};
+
+
+/**
+ * Create a new range wrapper from the given browser selection object. Note
+ * that this object does not auto-update if the user changes their selection and
+ * should be used as a snapshot.
+ * @param {!Object} selection The browser selection object.
+ * @return {goog.dom.AbstractRange?} A range wrapper object or null if there
+ * was an error.
+ */
+goog.dom.Range.createFromBrowserSelection = function(selection) {
+ var range;
+ var isReversed = false;
+ if (selection.createRange) {
+ /** @preserveTry */
+ try {
+ range = selection.createRange();
+ } catch (e) {
+ // Access denied errors can be thrown here in IE if the selection was
+ // a flash obj or if there are cross domain issues
+ return null;
+ }
+ } else if (selection.rangeCount) {
+ if (selection.rangeCount > 1) {
+ return goog.dom.MultiRange.createFromBrowserSelection(
+ /** @type {!Selection} */ (selection));
+ } else {
+ range = selection.getRangeAt(0);
+ isReversed = goog.dom.Range.isReversed(selection.anchorNode,
+ selection.anchorOffset, selection.focusNode, selection.focusOffset);
+ }
+ } else {
+ return null;
+ }
+
+ return goog.dom.Range.createFromBrowserRange(range, isReversed);
+};
+
+
+/**
+ * Create a new range wrapper from the given browser range object.
+ * @param {Range|TextRange} range The browser range object.
+ * @param {boolean=} opt_isReversed Whether the focus node is before the anchor
+ * node.
+ * @return {!goog.dom.AbstractRange} A range wrapper object.
+ */
+goog.dom.Range.createFromBrowserRange = function(range, opt_isReversed) {
+ // Create an IE control range when appropriate.
+ return goog.dom.AbstractRange.isNativeControlRange(range) ?
+ goog.dom.ControlRange.createFromBrowserRange(range) :
+ goog.dom.TextRange.createFromBrowserRange(range, opt_isReversed);
+};
+
+
+/**
+ * Create a new range wrapper that selects the given node's text.
+ * @param {Node} node The node to select.
+ * @param {boolean=} opt_isReversed Whether the focus node is before the anchor
+ * node.
+ * @return {!goog.dom.AbstractRange} A range wrapper object.
+ */
+goog.dom.Range.createFromNodeContents = function(node, opt_isReversed) {
+ return goog.dom.TextRange.createFromNodeContents(node, opt_isReversed);
+};
+
+
+/**
+ * Create a new range wrapper that represents a caret at the given node,
+ * accounting for the given offset. This always creates a TextRange, regardless
+ * of whether node is an image node or other control range type node.
+ * @param {Node} node The node to place a caret at.
+ * @param {number} offset The offset within the node to place the caret at.
+ * @return {!goog.dom.AbstractRange} A range wrapper object.
+ */
+goog.dom.Range.createCaret = function(node, offset) {
+ return goog.dom.TextRange.createFromNodes(node, offset, node, offset);
+};
+
+
+/**
+ * Create a new range wrapper that selects the area between the given nodes,
+ * accounting for the given offsets.
+ * @param {Node} anchorNode The node to anchor on.
+ * @param {number} anchorOffset The offset within the node to anchor on.
+ * @param {Node} focusNode The node to focus on.
+ * @param {number} focusOffset The offset within the node to focus on.
+ * @return {!goog.dom.AbstractRange} A range wrapper object.
+ */
+goog.dom.Range.createFromNodes = function(anchorNode, anchorOffset, focusNode,
+ focusOffset) {
+ return goog.dom.TextRange.createFromNodes(anchorNode, anchorOffset, focusNode,
+ focusOffset);
+};
+
+
+/**
+ * Clears the window's selection.
+ * @param {Window=} opt_win The window to get the selection of. Defaults to the
+ * window this class was defined in.
+ */
+goog.dom.Range.clearSelection = function(opt_win) {
+ var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(
+ opt_win || window);
+ if (!sel) {
+ return;
+ }
+ if (sel.empty) {
+ // We can't just check that the selection is empty, becuase IE
+ // sometimes gets confused.
+ try {
+ sel.empty();
+ } catch (e) {
+ // Emptying an already empty selection throws an exception in IE
+ }
+ } else {
+ try {
+ sel.removeAllRanges();
+ } catch (e) {
+ // This throws in IE9 if the range has been invalidated; for example, if
+ // the user clicked on an element which disappeared during the event
+ // handler.
+ }
+ }
+};
+
+
+/**
+ * Tests if the window has a selection.
+ * @param {Window=} opt_win The window to check the selection of. Defaults to
+ * the window this class was defined in.
+ * @return {boolean} Whether the window has a selection.
+ */
+goog.dom.Range.hasSelection = function(opt_win) {
+ var sel = goog.dom.AbstractRange.getBrowserSelectionForWindow(
+ opt_win || window);
+ return !!sel &&
+ (goog.dom.BrowserFeature.LEGACY_IE_RANGES ?
+ sel.type != 'None' : !!sel.rangeCount);
+};
+
+
+/**
+ * Returns whether the focus position occurs before the anchor position.
+ * @param {Node} anchorNode The node to anchor on.
+ * @param {number} anchorOffset The offset within the node to anchor on.
+ * @param {Node} focusNode The node to focus on.
+ * @param {number} focusOffset The offset within the node to focus on.
+ * @return {boolean} Whether the focus position occurs before the anchor
+ * position.
+ */
+goog.dom.Range.isReversed = function(anchorNode, anchorOffset, focusNode,
+ focusOffset) {
+ if (anchorNode == focusNode) {
+ return focusOffset < anchorOffset;
+ }
+ var child;
+ if (anchorNode.nodeType == goog.dom.NodeType.ELEMENT && anchorOffset) {
+ child = anchorNode.childNodes[anchorOffset];
+ if (child) {
+ anchorNode = child;
+ anchorOffset = 0;
+ } else if (goog.dom.contains(anchorNode, focusNode)) {
+ // If focus node is contained in anchorNode, it must be before the
+ // end of the node. Hence we are reversed.
+ return true;
+ }
+ }
+ if (focusNode.nodeType == goog.dom.NodeType.ELEMENT && focusOffset) {
+ child = focusNode.childNodes[focusOffset];
+ if (child) {
+ focusNode = child;
+ focusOffset = 0;
+ } else if (goog.dom.contains(focusNode, anchorNode)) {
+ // If anchor node is contained in focusNode, it must be before the
+ // end of the node. Hence we are not reversed.
+ return false;
+ }
+ }
+ return (goog.dom.compareNodeOrder(anchorNode, focusNode) ||
+ anchorOffset - focusOffset) > 0;
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/rangeendpoint.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/rangeendpoint.js b/externs/GCL/externs/goog/dom/rangeendpoint.js
new file mode 100644
index 0000000..f8d0fe4
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/rangeendpoint.js
@@ -0,0 +1,32 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Simple struct for endpoints of a range.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.RangeEndpoint');
+
+
+/**
+ * Constants for selection endpoints.
+ * @enum {number}
+ */
+goog.dom.RangeEndpoint = {
+ START: 1,
+ END: 0
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/safe.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/safe.js b/externs/GCL/externs/goog/dom/safe.js
new file mode 100644
index 0000000..8aa9d9e
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/safe.js
@@ -0,0 +1,325 @@
+// Copyright 2013 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Type-safe wrappers for unsafe DOM APIs.
+ *
+ * This file provides type-safe wrappers for DOM APIs that can result in
+ * cross-site scripting (XSS) vulnerabilities, if the API is supplied with
+ * untrusted (attacker-controlled) input. Instead of plain strings, the type
+ * safe wrappers consume values of types from the goog.html package whose
+ * contract promises that values are safe to use in the corresponding context.
+ *
+ * Hence, a program that exclusively uses the wrappers in this file (i.e., whose
+ * only reference to security-sensitive raw DOM APIs are in this file) is
+ * guaranteed to be free of XSS due to incorrect use of such DOM APIs (modulo
+ * correctness of code that produces values of the respective goog.html types,
+ * and absent code that violates type safety).
+ *
+ * For example, assigning to an element's .innerHTML property a string that is
+ * derived (even partially) from untrusted input typically results in an XSS
+ * vulnerability. The type-safe wrapper goog.html.setInnerHtml consumes a value
+ * of type goog.html.SafeHtml, whose contract states that using its values in a
+ * HTML context will not result in XSS. Hence a program that is free of direct
+ * assignments to any element's innerHTML property (with the exception of the
+ * assignment to .innerHTML in this file) is guaranteed to be free of XSS due to
+ * assignment of untrusted strings to the innerHTML property.
+ */
+
+goog.provide('goog.dom.safe');
+
+goog.require('goog.asserts');
+goog.require('goog.html.SafeHtml');
+goog.require('goog.html.SafeUrl');
+goog.require('goog.html.TrustedResourceUrl');
+goog.require('goog.string');
+goog.require('goog.string.Const');
+
+
+/**
+ * Assigns known-safe HTML to an element's innerHTML property.
+ * @param {!Element} elem The element whose innerHTML is to be assigned to.
+ * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
+ */
+goog.dom.safe.setInnerHtml = function(elem, html) {
+ elem.innerHTML = goog.html.SafeHtml.unwrap(html);
+};
+
+
+/**
+ * Assigns known-safe HTML to an element's outerHTML property.
+ * @param {!Element} elem The element whose outerHTML is to be assigned to.
+ * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
+ */
+goog.dom.safe.setOuterHtml = function(elem, html) {
+ elem.outerHTML = goog.html.SafeHtml.unwrap(html);
+};
+
+
+/**
+ * Writes known-safe HTML to a document.
+ * @param {!Document} doc The document to be written to.
+ * @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
+ */
+goog.dom.safe.documentWrite = function(doc, html) {
+ doc.write(goog.html.SafeHtml.unwrap(html));
+};
+
+
+/**
+ * Safely assigns a URL to an anchor element's href property.
+ *
+ * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
+ * anchor's href property. If url is of type string however, it is first
+ * sanitized using goog.html.SafeUrl.sanitize.
+ *
+ * Example usage:
+ * goog.dom.safe.setAnchorHref(anchorEl, url);
+ * which is a safe alternative to
+ * anchorEl.href = url;
+ * The latter can result in XSS vulnerabilities if url is a
+ * user-/attacker-controlled value.
+ *
+ * @param {!HTMLAnchorElement} anchor The anchor element whose href property
+ * is to be assigned to.
+ * @param {string|!goog.html.SafeUrl} url The URL to assign.
+ * @see goog.html.SafeUrl#sanitize
+ */
+goog.dom.safe.setAnchorHref = function(anchor, url) {
+ /** @type {!goog.html.SafeUrl} */
+ var safeUrl;
+ if (url instanceof goog.html.SafeUrl) {
+ safeUrl = url;
+ } else {
+ safeUrl = goog.html.SafeUrl.sanitize(url);
+ }
+ anchor.href = goog.html.SafeUrl.unwrap(safeUrl);
+};
+
+
+/**
+ * Safely assigns a URL to an embed element's src property.
+ *
+ * Example usage:
+ * goog.dom.safe.setEmbedSrc(embedEl, url);
+ * which is a safe alternative to
+ * embedEl.src = url;
+ * The latter can result in loading untrusted code unless it is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLEmbedElement} embed The embed element whose src property
+ * is to be assigned to.
+ * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
+ */
+goog.dom.safe.setEmbedSrc = function(embed, url) {
+ embed.src = goog.html.TrustedResourceUrl.unwrap(url);
+};
+
+
+/**
+ * Safely assigns a URL to a frame element's src property.
+ *
+ * Example usage:
+ * goog.dom.safe.setFrameSrc(frameEl, url);
+ * which is a safe alternative to
+ * frameEl.src = url;
+ * The latter can result in loading untrusted code unless it is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLFrameElement} frame The frame element whose src property
+ * is to be assigned to.
+ * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
+ */
+goog.dom.safe.setFrameSrc = function(frame, url) {
+ frame.src = goog.html.TrustedResourceUrl.unwrap(url);
+};
+
+
+/**
+ * Safely assigns a URL to an iframe element's src property.
+ *
+ * Example usage:
+ * goog.dom.safe.setIframeSrc(iframeEl, url);
+ * which is a safe alternative to
+ * iframeEl.src = url;
+ * The latter can result in loading untrusted code unless it is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLIFrameElement} iframe The iframe element whose src property
+ * is to be assigned to.
+ * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
+ */
+goog.dom.safe.setIframeSrc = function(iframe, url) {
+ iframe.src = goog.html.TrustedResourceUrl.unwrap(url);
+};
+
+
+/**
+ * Safely sets a link element's href and rel properties. Whether or not
+ * the URL assigned to href has to be a goog.html.TrustedResourceUrl
+ * depends on the value of the rel property. If rel contains "stylesheet"
+ * then a TrustedResourceUrl is required.
+ *
+ * Example usage:
+ * goog.dom.safe.setLinkHrefAndRel(linkEl, url, 'stylesheet');
+ * which is a safe alternative to
+ * linkEl.rel = 'stylesheet';
+ * linkEl.href = url;
+ * The latter can result in loading untrusted code unless it is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLLinkElement} link The link element whose href property
+ * is to be assigned to.
+ * @param {string|!goog.html.SafeUrl|!goog.html.TrustedResourceUrl} url The URL
+ * to assign to the href property. Must be a TrustedResourceUrl if the
+ * value assigned to rel contains "stylesheet". A string value is
+ * sanitized with goog.html.SafeUrl.sanitize.
+ * @param {string} rel The value to assign to the rel property.
+ * @throws {Error} if rel contains "stylesheet" and url is not a
+ * TrustedResourceUrl
+ * @see goog.html.SafeUrl#sanitize
+ */
+goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
+ link.rel = rel;
+ if (goog.string.caseInsensitiveContains(rel, 'stylesheet')) {
+ goog.asserts.assert(
+ url instanceof goog.html.TrustedResourceUrl,
+ 'URL must be TrustedResourceUrl because "rel" contains "stylesheet"');
+ link.href = goog.html.TrustedResourceUrl.unwrap(url);
+ } else if (url instanceof goog.html.TrustedResourceUrl) {
+ link.href = goog.html.TrustedResourceUrl.unwrap(url);
+ } else if (url instanceof goog.html.SafeUrl) {
+ link.href = goog.html.SafeUrl.unwrap(url);
+ } else { // string
+ // SafeUrl.sanitize must return legitimate SafeUrl when passed a string.
+ link.href = goog.html.SafeUrl.sanitize(url).getTypedStringValue();
+ }
+};
+
+
+/**
+ * Safely assigns a URL to an object element's data property.
+ *
+ * Example usage:
+ * goog.dom.safe.setObjectData(objectEl, url);
+ * which is a safe alternative to
+ * objectEl.data = url;
+ * The latter can result in loading untrusted code unless setit is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLObjectElement} object The object element whose data property
+ * is to be assigned to.
+ * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
+ */
+goog.dom.safe.setObjectData = function(object, url) {
+ object.data = goog.html.TrustedResourceUrl.unwrap(url);
+};
+
+
+/**
+ * Safely assigns a URL to an iframe element's src property.
+ *
+ * Example usage:
+ * goog.dom.safe.setScriptSrc(scriptEl, url);
+ * which is a safe alternative to
+ * scriptEl.src = url;
+ * The latter can result in loading untrusted code unless it is ensured that
+ * the URL refers to a trustworthy resource.
+ *
+ * @param {!HTMLScriptElement} script The script element whose src property
+ * is to be assigned to.
+ * @param {!goog.html.TrustedResourceUrl} url The URL to assign.
+ */
+goog.dom.safe.setScriptSrc = function(script, url) {
+ script.src = goog.html.TrustedResourceUrl.unwrap(url);
+};
+
+
+/**
+ * Safely assigns a URL to a Location object's href property.
+ *
+ * If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
+ * loc's href property. If url is of type string however, it is first sanitized
+ * using goog.html.SafeUrl.sanitize.
+ *
+ * Example usage:
+ * goog.dom.safe.setLocationHref(document.location, redirectUrl);
+ * which is a safe alternative to
+ * document.location.href = redirectUrl;
+ * The latter can result in XSS vulnerabilities if redirectUrl is a
+ * user-/attacker-controlled value.
+ *
+ * @param {!Location} loc The Location object whose href property is to be
+ * assigned to.
+ * @param {string|!goog.html.SafeUrl} url The URL to assign.
+ * @see goog.html.SafeUrl#sanitize
+ */
+goog.dom.safe.setLocationHref = function(loc, url) {
+ /** @type {!goog.html.SafeUrl} */
+ var safeUrl;
+ if (url instanceof goog.html.SafeUrl) {
+ safeUrl = url;
+ } else {
+ safeUrl = goog.html.SafeUrl.sanitize(url);
+ }
+ loc.href = goog.html.SafeUrl.unwrap(safeUrl);
+};
+
+
+/**
+ * Safely opens a URL in a new window (via window.open).
+ *
+ * If url is of type goog.html.SafeUrl, its value is unwrapped and passed in to
+ * window.open. If url is of type string however, it is first sanitized
+ * using goog.html.SafeUrl.sanitize.
+ *
+ * Note that this function does not prevent leakages via the referer that is
+ * sent by window.open. It is advised to only use this to open 1st party URLs.
+ *
+ * Example usage:
+ * goog.dom.safe.openInWindow(url);
+ * which is a safe alternative to
+ * window.open(url);
+ * The latter can result in XSS vulnerabilities if redirectUrl is a
+ * user-/attacker-controlled value.
+ *
+ * @param {string|!goog.html.SafeUrl} url The URL to open.
+ * @param {Window=} opt_openerWin Window of which to call the .open() method.
+ * Defaults to the global window.
+ * @param {!goog.string.Const=} opt_name Name of the window to open in. Can be
+ * _top, etc as allowed by window.open().
+ * @param {string=} opt_specs Comma-separated list of specifications, same as
+ * in window.open().
+ * @param {boolean=} opt_replace Whether to replace the current entry in browser
+ * history, same as in window.open().
+ * @return {Window} Window the url was opened in.
+ */
+goog.dom.safe.openInWindow = function(
+ url, opt_openerWin, opt_name, opt_specs, opt_replace) {
+ /** @type {!goog.html.SafeUrl} */
+ var safeUrl;
+ if (url instanceof goog.html.SafeUrl) {
+ safeUrl = url;
+ } else {
+ safeUrl = goog.html.SafeUrl.sanitize(url);
+ }
+ var win = opt_openerWin || window;
+ return win.open(goog.html.SafeUrl.unwrap(safeUrl),
+ // If opt_name is undefined, simply passing that in to open() causes IE to
+ // reuse the current window instead of opening a new one. Thus we pass ''
+ // in instead, which according to spec opens a new window. See
+ // https://html.spec.whatwg.org/multipage/browsers.html#dom-open .
+ opt_name ? goog.string.Const.unwrap(opt_name) : '',
+ opt_specs, opt_replace);
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/savedcaretrange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/savedcaretrange.js b/externs/GCL/externs/goog/dom/savedcaretrange.js
new file mode 100644
index 0000000..ea61050
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/savedcaretrange.js
@@ -0,0 +1,215 @@
+// Copyright 2008 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview An API for saving and restoring ranges as HTML carets.
+ *
+ * @author nicksantos@google.com (Nick Santos)
+ */
+
+
+goog.provide('goog.dom.SavedCaretRange');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.dom.SavedRange');
+goog.require('goog.dom.TagName');
+goog.require('goog.string');
+
+
+
+/**
+ * A struct for holding context about saved selections.
+ * This can be used to preserve the selection and restore while the DOM is
+ * manipulated, or through an asynchronous call. Use goog.dom.Range factory
+ * methods to obtain an {@see goog.dom.AbstractRange} instance, and use
+ * {@see goog.dom.AbstractRange#saveUsingCarets} to obtain a SavedCaretRange.
+ * For editor ranges under content-editable elements or design-mode iframes,
+ * prefer using {@see goog.editor.range.saveUsingNormalizedCarets}.
+ * @param {goog.dom.AbstractRange} range The range being saved.
+ * @constructor
+ * @extends {goog.dom.SavedRange}
+ */
+goog.dom.SavedCaretRange = function(range) {
+ goog.dom.SavedRange.call(this);
+
+ /**
+ * The DOM id of the caret at the start of the range.
+ * @type {string}
+ * @private
+ */
+ this.startCaretId_ = goog.string.createUniqueString();
+
+ /**
+ * The DOM id of the caret at the end of the range.
+ * @type {string}
+ * @private
+ */
+ this.endCaretId_ = goog.string.createUniqueString();
+
+ /**
+ * Whether the range is reversed (anchor at the end).
+ * @private {boolean}
+ */
+ this.reversed_ = range.isReversed();
+
+ /**
+ * A DOM helper for storing the current document context.
+ * @type {goog.dom.DomHelper}
+ * @private
+ */
+ this.dom_ = goog.dom.getDomHelper(range.getDocument());
+
+ range.surroundWithNodes(this.createCaret_(true), this.createCaret_(false));
+};
+goog.inherits(goog.dom.SavedCaretRange, goog.dom.SavedRange);
+
+
+/**
+ * Gets the range that this SavedCaretRage represents, without selecting it
+ * or removing the carets from the DOM.
+ * @return {goog.dom.AbstractRange?} An abstract range.
+ */
+goog.dom.SavedCaretRange.prototype.toAbstractRange = function() {
+ var range = null;
+ var startCaret = this.getCaret(true);
+ var endCaret = this.getCaret(false);
+ if (startCaret && endCaret) {
+ /** @suppress {missingRequire} circular dependency */
+ range = goog.dom.Range.createFromNodes(startCaret, 0, endCaret, 0);
+ }
+ return range;
+};
+
+
+/**
+ * Gets carets.
+ * @param {boolean} start If true, returns the start caret. Otherwise, get the
+ * end caret.
+ * @return {Element} The start or end caret in the given document.
+ */
+goog.dom.SavedCaretRange.prototype.getCaret = function(start) {
+ return this.dom_.getElement(start ? this.startCaretId_ : this.endCaretId_);
+};
+
+
+/**
+ * Removes the carets from the current restoration document.
+ * @param {goog.dom.AbstractRange=} opt_range A range whose offsets have already
+ * been adjusted for caret removal; it will be adjusted if it is also
+ * affected by post-removal operations, such as text node normalization.
+ * @return {goog.dom.AbstractRange|undefined} The adjusted range, if opt_range
+ * was provided.
+ */
+goog.dom.SavedCaretRange.prototype.removeCarets = function(opt_range) {
+ goog.dom.removeNode(this.getCaret(true));
+ goog.dom.removeNode(this.getCaret(false));
+ return opt_range;
+};
+
+
+/**
+ * Sets the document where the range will be restored.
+ * @param {!Document} doc An HTML document.
+ */
+goog.dom.SavedCaretRange.prototype.setRestorationDocument = function(doc) {
+ this.dom_.setDocument(doc);
+};
+
+
+/**
+ * Reconstruct the selection from the given saved range. Removes carets after
+ * restoring the selection. If restore does not dispose this saved range, it may
+ * only be restored a second time if innerHTML or some other mechanism is used
+ * to restore the carets to the dom.
+ * @return {goog.dom.AbstractRange?} Restored selection.
+ * @override
+ * @protected
+ */
+goog.dom.SavedCaretRange.prototype.restoreInternal = function() {
+ var range = null;
+ var anchorCaret = this.getCaret(!this.reversed_);
+ var focusCaret = this.getCaret(this.reversed_);
+ if (anchorCaret && focusCaret) {
+ var anchorNode = anchorCaret.parentNode;
+ var anchorOffset = goog.array.indexOf(anchorNode.childNodes, anchorCaret);
+ var focusNode = focusCaret.parentNode;
+ var focusOffset = goog.array.indexOf(focusNode.childNodes, focusCaret);
+ if (focusNode == anchorNode) {
+ // Compensate for the start caret being removed.
+ if (this.reversed_) {
+ anchorOffset--;
+ } else {
+ focusOffset--;
+ }
+ }
+ /** @suppress {missingRequire} circular dependency */
+ range = goog.dom.Range.createFromNodes(anchorNode, anchorOffset,
+ focusNode, focusOffset);
+ range = this.removeCarets(range);
+ range.select();
+ } else {
+ // If only one caret was found, remove it.
+ this.removeCarets();
+ }
+ return range;
+};
+
+
+/**
+ * Dispose the saved range and remove the carets from the DOM.
+ * @override
+ * @protected
+ */
+goog.dom.SavedCaretRange.prototype.disposeInternal = function() {
+ this.removeCarets();
+ this.dom_ = null;
+};
+
+
+/**
+ * Creates a caret element.
+ * @param {boolean} start If true, creates the start caret. Otherwise,
+ * creates the end caret.
+ * @return {!Element} The new caret element.
+ * @private
+ */
+goog.dom.SavedCaretRange.prototype.createCaret_ = function(start) {
+ return this.dom_.createDom(goog.dom.TagName.SPAN,
+ {'id': start ? this.startCaretId_ : this.endCaretId_});
+};
+
+
+/**
+ * A regex that will match all saved range carets in a string.
+ * @type {RegExp}
+ */
+goog.dom.SavedCaretRange.CARET_REGEX = /<span\s+id="?goog_\d+"?><\/span>/ig;
+
+
+/**
+ * Returns whether two strings of html are equal, ignoring any saved carets.
+ * Thus two strings of html whose only difference is the id of their saved
+ * carets will be considered equal, since they represent html with the
+ * same selection.
+ * @param {string} str1 The first string.
+ * @param {string} str2 The second string.
+ * @return {boolean} Whether two strings of html are equal, ignoring any
+ * saved carets.
+ */
+goog.dom.SavedCaretRange.htmlEqual = function(str1, str2) {
+ return str1 == str2 ||
+ str1.replace(goog.dom.SavedCaretRange.CARET_REGEX, '') ==
+ str2.replace(goog.dom.SavedCaretRange.CARET_REGEX, '');
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/savedrange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/savedrange.js b/externs/GCL/externs/goog/dom/savedrange.js
new file mode 100644
index 0000000..5a7e951
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/savedrange.js
@@ -0,0 +1,74 @@
+// Copyright 2007 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview A generic interface for saving and restoring ranges.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.SavedRange');
+
+goog.require('goog.Disposable');
+goog.require('goog.log');
+
+
+
+/**
+ * Abstract interface for a saved range.
+ * @constructor
+ * @extends {goog.Disposable}
+ */
+goog.dom.SavedRange = function() {
+ goog.Disposable.call(this);
+};
+goog.inherits(goog.dom.SavedRange, goog.Disposable);
+
+
+/**
+ * Logging object.
+ * @type {goog.log.Logger}
+ * @private
+ */
+goog.dom.SavedRange.logger_ =
+ goog.log.getLogger('goog.dom.SavedRange');
+
+
+/**
+ * Restores the range and by default disposes of the saved copy. Take note:
+ * this means the by default SavedRange objects are single use objects.
+ * @param {boolean=} opt_stayAlive Whether this SavedRange should stay alive
+ * (not be disposed) after restoring the range. Defaults to false (dispose).
+ * @return {goog.dom.AbstractRange} The restored range.
+ */
+goog.dom.SavedRange.prototype.restore = function(opt_stayAlive) {
+ if (this.isDisposed()) {
+ goog.log.error(goog.dom.SavedRange.logger_,
+ 'Disposed SavedRange objects cannot be restored.');
+ }
+
+ var range = this.restoreInternal();
+ if (!opt_stayAlive) {
+ this.dispose();
+ }
+ return range;
+};
+
+
+/**
+ * Internal method to restore the saved range.
+ * @return {goog.dom.AbstractRange} The restored range.
+ */
+goog.dom.SavedRange.prototype.restoreInternal = goog.abstractMethod;
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/selection.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/selection.js b/externs/GCL/externs/goog/dom/selection.js
new file mode 100644
index 0000000..4afb4f7
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/selection.js
@@ -0,0 +1,472 @@
+// Copyright 2006 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Utilities for working with selections in input boxes and text
+ * areas.
+ *
+ * @author arv@google.com (Erik Arvidsson)
+ * @see ../demos/dom_selection.html
+ */
+
+
+goog.provide('goog.dom.selection');
+
+goog.require('goog.dom.InputType');
+goog.require('goog.string');
+goog.require('goog.userAgent');
+
+
+/**
+ * Sets the place where the selection should start inside a textarea or a text
+ * input
+ * @param {Element} textfield A textarea or text input.
+ * @param {number} pos The position to set the start of the selection at.
+ */
+goog.dom.selection.setStart = function(textfield, pos) {
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ textfield.selectionStart = pos;
+ } else if (goog.userAgent.IE) {
+ // destructuring assignment would have been sweet
+ var tmp = goog.dom.selection.getRangeIe_(textfield);
+ var range = tmp[0];
+ var selectionRange = tmp[1];
+
+ if (range.inRange(selectionRange)) {
+ pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
+
+ range.collapse(true);
+ range.move('character', pos);
+ range.select();
+ }
+ }
+};
+
+
+/**
+ * Return the place where the selection starts inside a textarea or a text
+ * input
+ * @param {Element} textfield A textarea or text input.
+ * @return {number} The position where the selection starts or 0 if it was
+ * unable to find the position or no selection exists. Note that we can't
+ * reliably tell the difference between an element that has no selection and
+ * one where it starts at 0.
+ */
+goog.dom.selection.getStart = function(textfield) {
+ return goog.dom.selection.getEndPoints_(textfield, true)[0];
+};
+
+
+/**
+ * Returns the start and end points of the selection within a textarea in IE.
+ * IE treats newline characters as \r\n characters, and we need to check for
+ * these characters at the edge of our selection, to ensure that we return the
+ * right cursor position.
+ * @param {TextRange} range Complete range object, e.g., "Hello\r\n".
+ * @param {TextRange} selRange Selected range object.
+ * @param {boolean} getOnlyStart Value indicating if only start
+ * cursor position is to be returned. In IE, obtaining the end position
+ * involves extra work, hence we have this parameter for calls which need
+ * only start position.
+ * @return {!Array<number>} An array with the start and end positions where the
+ * selection starts and ends or [0,0] if it was unable to find the
+ * positions or no selection exists. Note that we can't reliably tell the
+ * difference between an element that has no selection and one where
+ * it starts and ends at 0. If getOnlyStart was true, we return
+ * -1 as end offset.
+ * @private
+ */
+goog.dom.selection.getEndPointsTextareaIe_ = function(
+ range, selRange, getOnlyStart) {
+ // Create a duplicate of the selected range object to perform our actions
+ // against. Example of selectionRange = "" (assuming that the cursor is
+ // just after the \r\n combination)
+ var selectionRange = selRange.duplicate();
+
+ // Text before the selection start, e.g.,"Hello" (notice how range.text
+ // excludes the \r\n sequence)
+ var beforeSelectionText = range.text;
+ // Text before the selection start, e.g., "Hello" (this will later include
+ // the \r\n sequences also)
+ var untrimmedBeforeSelectionText = beforeSelectionText;
+ // Text within the selection , e.g. "" assuming that the cursor is just after
+ // the \r\n combination.
+ var selectionText = selectionRange.text;
+ // Text within the selection, e.g., "" (this will later include the \r\n
+ // sequences also)
+ var untrimmedSelectionText = selectionText;
+
+ // Boolean indicating whether we are done dealing with the text before the
+ // selection's beginning.
+ var isRangeEndTrimmed = false;
+ // Go over the range until it becomes a 0-lengthed range or until the range
+ // text starts changing when we move the end back by one character.
+ // If after moving the end back by one character, the text remains the same,
+ // then we need to add a "\r\n" at the end to get the actual text.
+ while (!isRangeEndTrimmed) {
+ if (range.compareEndPoints('StartToEnd', range) == 0) {
+ isRangeEndTrimmed = true;
+ } else {
+ range.moveEnd('character', -1);
+ if (range.text == beforeSelectionText) {
+ // If the start position of the cursor was after a \r\n string,
+ // we would skip over it in one go with the moveEnd call, but
+ // range.text will still show "Hello" (because of the IE range.text
+ // bug) - this implies that we should add a \r\n to our
+ // untrimmedBeforeSelectionText string.
+ untrimmedBeforeSelectionText += '\r\n';
+ } else {
+ isRangeEndTrimmed = true;
+ }
+ }
+ }
+
+ if (getOnlyStart) {
+ // We return -1 as end, since the caller is only interested in the start
+ // value.
+ return [untrimmedBeforeSelectionText.length, -1];
+ }
+ // Boolean indicating whether we are done dealing with the text inside the
+ // selection.
+ var isSelectionRangeEndTrimmed = false;
+ // Go over the selected range until it becomes a 0-lengthed range or until
+ // the range text starts changing when we move the end back by one character.
+ // If after moving the end back by one character, the text remains the same,
+ // then we need to add a "\r\n" at the end to get the actual text.
+ while (!isSelectionRangeEndTrimmed) {
+ if (selectionRange.compareEndPoints('StartToEnd', selectionRange) == 0) {
+ isSelectionRangeEndTrimmed = true;
+ } else {
+ selectionRange.moveEnd('character', -1);
+ if (selectionRange.text == selectionText) {
+ // If the selection was not empty, and the end point of the selection
+ // was just after a \r\n, we would have skipped it in one go with the
+ // moveEnd call, and this implies that we should add a \r\n to the
+ // untrimmedSelectionText string.
+ untrimmedSelectionText += '\r\n';
+ } else {
+ isSelectionRangeEndTrimmed = true;
+ }
+ }
+ }
+ return [
+ untrimmedBeforeSelectionText.length,
+ untrimmedBeforeSelectionText.length + untrimmedSelectionText.length];
+};
+
+
+/**
+ * Returns the start and end points of the selection inside a textarea or a
+ * text input.
+ * @param {Element} textfield A textarea or text input.
+ * @return {!Array<number>} An array with the start and end positions where the
+ * selection starts and ends or [0,0] if it was unable to find the
+ * positions or no selection exists. Note that we can't reliably tell the
+ * difference between an element that has no selection and one where
+ * it starts and ends at 0.
+ */
+goog.dom.selection.getEndPoints = function(textfield) {
+ return goog.dom.selection.getEndPoints_(textfield, false);
+};
+
+
+/**
+ * Returns the start and end points of the selection inside a textarea or a
+ * text input.
+ * @param {Element} textfield A textarea or text input.
+ * @param {boolean} getOnlyStart Value indicating if only start
+ * cursor position is to be returned. In IE, obtaining the end position
+ * involves extra work, hence we have this parameter. In FF, there is not
+ * much extra effort involved.
+ * @return {!Array<number>} An array with the start and end positions where the
+ * selection starts and ends or [0,0] if it was unable to find the
+ * positions or no selection exists. Note that we can't reliably tell the
+ * difference between an element that has no selection and one where
+ * it starts and ends at 0. If getOnlyStart was true, we return
+ * -1 as end offset.
+ * @private
+ */
+goog.dom.selection.getEndPoints_ = function(textfield, getOnlyStart) {
+ var startPos = 0;
+ var endPos = 0;
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ startPos = textfield.selectionStart;
+ endPos = getOnlyStart ? -1 : textfield.selectionEnd;
+ } else if (goog.userAgent.IE) {
+ var tmp = goog.dom.selection.getRangeIe_(textfield);
+ var range = tmp[0];
+ var selectionRange = tmp[1];
+
+ if (range.inRange(selectionRange)) {
+ range.setEndPoint('EndToStart', selectionRange);
+ if (textfield.type == goog.dom.InputType.TEXTAREA) {
+ return goog.dom.selection.getEndPointsTextareaIe_(
+ range, selectionRange, getOnlyStart);
+ }
+ startPos = range.text.length;
+ if (!getOnlyStart) {
+ endPos = range.text.length + selectionRange.text.length;
+ } else {
+ endPos = -1; // caller did not ask for end position
+ }
+ }
+ }
+ return [startPos, endPos];
+};
+
+
+/**
+ * Sets the place where the selection should end inside a text area or a text
+ * input
+ * @param {Element} textfield A textarea or text input.
+ * @param {number} pos The position to end the selection at.
+ */
+goog.dom.selection.setEnd = function(textfield, pos) {
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ textfield.selectionEnd = pos;
+ } else if (goog.userAgent.IE) {
+ var tmp = goog.dom.selection.getRangeIe_(textfield);
+ var range = tmp[0];
+ var selectionRange = tmp[1];
+
+ if (range.inRange(selectionRange)) {
+ // Both the current position and the start cursor position need
+ // to be canonicalized to take care of possible \r\n miscounts.
+ pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
+ var startCursorPos = goog.dom.selection.canonicalizePositionIe_(
+ textfield, goog.dom.selection.getStart(textfield));
+
+ selectionRange.collapse(true);
+ selectionRange.moveEnd('character', pos - startCursorPos);
+ selectionRange.select();
+ }
+ }
+};
+
+
+/**
+ * Returns the place where the selection ends inside a textarea or a text input
+ * @param {Element} textfield A textarea or text input.
+ * @return {number} The position where the selection ends or 0 if it was
+ * unable to find the position or no selection exists.
+ */
+goog.dom.selection.getEnd = function(textfield) {
+ return goog.dom.selection.getEndPoints_(textfield, false)[1];
+};
+
+
+/**
+ * Sets the cursor position within a textfield.
+ * @param {Element} textfield A textarea or text input.
+ * @param {number} pos The position within the text field.
+ */
+goog.dom.selection.setCursorPosition = function(textfield, pos) {
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ // Mozilla directly supports this
+ textfield.selectionStart = pos;
+ textfield.selectionEnd = pos;
+
+ } else if (goog.userAgent.IE) {
+ pos = goog.dom.selection.canonicalizePositionIe_(textfield, pos);
+
+ // IE has textranges. A textfield's textrange encompasses the
+ // entire textfield's text by default
+ var sel = textfield.createTextRange();
+
+ sel.collapse(true);
+ sel.move('character', pos);
+ sel.select();
+ }
+};
+
+
+/**
+ * Sets the selected text inside a textarea or a text input
+ * @param {Element} textfield A textarea or text input.
+ * @param {string} text The text to change the selection to.
+ */
+goog.dom.selection.setText = function(textfield, text) {
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ var value = textfield.value;
+ var oldSelectionStart = textfield.selectionStart;
+ var before = value.substr(0, oldSelectionStart);
+ var after = value.substr(textfield.selectionEnd);
+ textfield.value = before + text + after;
+ textfield.selectionStart = oldSelectionStart;
+ textfield.selectionEnd = oldSelectionStart + text.length;
+ } else if (goog.userAgent.IE) {
+ var tmp = goog.dom.selection.getRangeIe_(textfield);
+ var range = tmp[0];
+ var selectionRange = tmp[1];
+
+ if (!range.inRange(selectionRange)) {
+ return;
+ }
+ // When we set the selection text the selection range is collapsed to the
+ // end. We therefore duplicate the current selection so we know where it
+ // started. Once we've set the selection text we move the start of the
+ // selection range to the old start
+ var range2 = selectionRange.duplicate();
+ selectionRange.text = text;
+ selectionRange.setEndPoint('StartToStart', range2);
+ selectionRange.select();
+ } else {
+ throw Error('Cannot set the selection end');
+ }
+};
+
+
+/**
+ * Returns the selected text inside a textarea or a text input
+ * @param {Element} textfield A textarea or text input.
+ * @return {string} The selected text.
+ */
+goog.dom.selection.getText = function(textfield) {
+ if (goog.dom.selection.useSelectionProperties_(textfield)) {
+ var s = textfield.value;
+ return s.substring(textfield.selectionStart, textfield.selectionEnd);
+ }
+
+ if (goog.userAgent.IE) {
+ var tmp = goog.dom.selection.getRangeIe_(textfield);
+ var range = tmp[0];
+ var selectionRange = tmp[1];
+
+ if (!range.inRange(selectionRange)) {
+ return '';
+ } else if (textfield.type == goog.dom.InputType.TEXTAREA) {
+ return goog.dom.selection.getSelectionRangeText_(selectionRange);
+ }
+ return selectionRange.text;
+ }
+
+ throw Error('Cannot get the selection text');
+};
+
+
+/**
+ * Returns the selected text within a textarea in IE.
+ * IE treats newline characters as \r\n characters, and we need to check for
+ * these characters at the edge of our selection, to ensure that we return the
+ * right string.
+ * @param {TextRange} selRange Selected range object.
+ * @return {string} Selected text in the textarea.
+ * @private
+ */
+goog.dom.selection.getSelectionRangeText_ = function(selRange) {
+ // Create a duplicate of the selected range object to perform our actions
+ // against. Suppose the text in the textarea is "Hello\r\nWorld" and the
+ // selection encompasses the "o\r\n" bit, initial selectionRange will be "o"
+ // (assuming that the cursor is just after the \r\n combination)
+ var selectionRange = selRange.duplicate();
+
+ // Text within the selection , e.g. "o" assuming that the cursor is just after
+ // the \r\n combination.
+ var selectionText = selectionRange.text;
+ // Text within the selection, e.g., "o" (this will later include the \r\n
+ // sequences also)
+ var untrimmedSelectionText = selectionText;
+
+ // Boolean indicating whether we are done dealing with the text inside the
+ // selection.
+ var isSelectionRangeEndTrimmed = false;
+ // Go over the selected range until it becomes a 0-lengthed range or until
+ // the range text starts changing when we move the end back by one character.
+ // If after moving the end back by one character, the text remains the same,
+ // then we need to add a "\r\n" at the end to get the actual text.
+ while (!isSelectionRangeEndTrimmed) {
+ if (selectionRange.compareEndPoints('StartToEnd', selectionRange) == 0) {
+ isSelectionRangeEndTrimmed = true;
+ } else {
+ selectionRange.moveEnd('character', -1);
+ if (selectionRange.text == selectionText) {
+ // If the selection was not empty, and the end point of the selection
+ // was just after a \r\n, we would have skipped it in one go with the
+ // moveEnd call, and this implies that we should add a \r\n to the
+ // untrimmedSelectionText string.
+ untrimmedSelectionText += '\r\n';
+ } else {
+ isSelectionRangeEndTrimmed = true;
+ }
+ }
+ }
+ return untrimmedSelectionText;
+};
+
+
+/**
+ * Helper function for returning the range for an object as well as the
+ * selection range
+ * @private
+ * @param {Element} el The element to get the range for.
+ * @return {!Array<TextRange>} Range of object and selection range in two
+ * element array.
+ */
+goog.dom.selection.getRangeIe_ = function(el) {
+ var doc = el.ownerDocument || el.document;
+
+ var selectionRange = doc.selection.createRange();
+ // el.createTextRange() doesn't work on textareas
+ var range;
+
+ if (el.type == goog.dom.InputType.TEXTAREA) {
+ range = doc.body.createTextRange();
+ range.moveToElementText(el);
+ } else {
+ range = el.createTextRange();
+ }
+
+ return [range, selectionRange];
+};
+
+
+/**
+ * Helper function for canonicalizing a position inside a textfield in IE.
+ * Deals with the issue that \r\n counts as 2 characters, but
+ * move('character', n) passes over both characters in one move.
+ * @private
+ * @param {Element} textfield The text element.
+ * @param {number} pos The position desired in that element.
+ * @return {number} The canonicalized position that will work properly with
+ * move('character', pos).
+ */
+goog.dom.selection.canonicalizePositionIe_ = function(textfield, pos) {
+ if (textfield.type == goog.dom.InputType.TEXTAREA) {
+ // We do this only for textarea because it is the only one which can
+ // have a \r\n (input cannot have this).
+ var value = textfield.value.substring(0, pos);
+ pos = goog.string.canonicalizeNewlines(value).length;
+ }
+ return pos;
+};
+
+
+/**
+ * Helper function to determine whether it's okay to use
+ * selectionStart/selectionEnd.
+ *
+ * @param {Element} el The element to check for.
+ * @return {boolean} Whether it's okay to use the selectionStart and
+ * selectionEnd properties on {@code el}.
+ * @private
+ */
+goog.dom.selection.useSelectionProperties_ = function(el) {
+ try {
+ return typeof el.selectionStart == 'number';
+ } catch (e) {
+ // Firefox throws an exception if you try to access selectionStart
+ // on an element with display: none.
+ return false;
+ }
+};
http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/tagiterator.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/tagiterator.js b/externs/GCL/externs/goog/dom/tagiterator.js
new file mode 100644
index 0000000..4b6354c
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/tagiterator.js
@@ -0,0 +1,360 @@
+// Copyright 2008 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Iterator subclass for DOM tree traversal.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.TagIterator');
+goog.provide('goog.dom.TagWalkType');
+
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.iter.Iterator');
+goog.require('goog.iter.StopIteration');
+
+
+/**
+ * There are three types of token:
+ * <ol>
+ * <li>{@code START_TAG} - The beginning of a tag.
+ * <li>{@code OTHER} - Any non-element node position.
+ * <li>{@code END_TAG} - The end of a tag.
+ * </ol>
+ * Users of this enumeration can rely on {@code START_TAG + END_TAG = 0} and
+ * that {@code OTHER = 0}.
+ *
+ * @enum {number}
+ */
+goog.dom.TagWalkType = {
+ START_TAG: 1,
+ OTHER: 0,
+ END_TAG: -1
+};
+
+
+
+/**
+ * A DOM tree traversal iterator.
+ *
+ * Starting with the given node, the iterator walks the DOM in order, reporting
+ * events for the start and end of Elements, and the presence of text nodes. For
+ * example:
+ *
+ * <pre>
+ * <div>1<span>2</span>3</div>
+ * </pre>
+ *
+ * Will return the following nodes:
+ *
+ * <code>[div, 1, span, 2, span, 3, div]</code>
+ *
+ * With the following states:
+ *
+ * <code>[START, OTHER, START, OTHER, END, OTHER, END]</code>
+ *
+ * And the following depths
+ *
+ * <code>[1, 1, 2, 2, 1, 1, 0]</code>
+ *
+ * Imagining <code>|</code> represents iterator position, the traversal stops at
+ * each of the following locations:
+ *
+ * <pre>
+ * <div>|1|<span>|2|</span>|3|</div>|
+ * </pre>
+ *
+ * The iterator can also be used in reverse mode, which will return the nodes
+ * and states in the opposite order. The depths will be slightly different
+ * since, like in normal mode, the depth is computed *after* the given node.
+ *
+ * Lastly, it is possible to create an iterator that is unconstrained, meaning
+ * that it will continue iterating until the end of the document instead of
+ * until exiting the start node.
+ *
+ * @param {Node=} opt_node The start node. If unspecified or null, defaults to
+ * an empty iterator.
+ * @param {boolean=} opt_reversed Whether to traverse the tree in reverse.
+ * @param {boolean=} opt_unconstrained Whether the iterator is not constrained
+ * to the starting node and its children.
+ * @param {goog.dom.TagWalkType?=} opt_tagType The type of the position.
+ * Defaults to the start of the given node for forward iterators, and
+ * the end of the node for reverse iterators.
+ * @param {number=} opt_depth The starting tree depth.
+ * @constructor
+ * @extends {goog.iter.Iterator<Node>}
+ */
+goog.dom.TagIterator = function(opt_node, opt_reversed,
+ opt_unconstrained, opt_tagType, opt_depth) {
+ /**
+ * Whether the node iterator is moving in reverse.
+ * @type {boolean}
+ */
+ this.reversed = !!opt_reversed;
+
+ /**
+ * The node this position is located on.
+ * @type {Node}
+ */
+ this.node = null;
+
+ /**
+ * The type of this position.
+ * @type {goog.dom.TagWalkType}
+ */
+ this.tagType = goog.dom.TagWalkType.OTHER;
+
+ /**
+ * The tree depth of this position relative to where the iterator started.
+ * The depth is considered to be the tree depth just past the current node,
+ * so if an iterator is at position
+ * <pre>
+ * <div>|</div>
+ * </pre>
+ * (i.e. the node is the div and the type is START_TAG) its depth will be 1.
+ * @type {number}
+ */
+ this.depth;
+
+ /**
+ * Whether iteration has started.
+ * @private {boolean}
+ */
+ this.started_ = false;
+
+ /**
+ * Whether the iterator is constrained to the starting node and its children.
+ * @type {boolean}
+ */
+ this.constrained = !opt_unconstrained;
+
+ if (opt_node) {
+ this.setPosition(opt_node, opt_tagType);
+ }
+ this.depth = opt_depth != undefined ? opt_depth : this.tagType || 0;
+ if (this.reversed) {
+ this.depth *= -1;
+ }
+};
+goog.inherits(goog.dom.TagIterator, goog.iter.Iterator);
+
+
+/**
+ * Set the position of the iterator. Overwrite the tree node and the position
+ * type which can be one of the {@link goog.dom.TagWalkType} token types.
+ * Only overwrites the tree depth when the parameter is specified.
+ * @param {Node} node The node to set the position to.
+ * @param {goog.dom.TagWalkType?=} opt_tagType The type of the position
+ * Defaults to the start of the given node.
+ * @param {number=} opt_depth The tree depth.
+ */
+goog.dom.TagIterator.prototype.setPosition = function(node,
+ opt_tagType, opt_depth) {
+ this.node = node;
+
+ if (node) {
+ if (goog.isNumber(opt_tagType)) {
+ this.tagType = opt_tagType;
+ } else {
+ // Auto-determine the proper type
+ this.tagType = this.node.nodeType != goog.dom.NodeType.ELEMENT ?
+ goog.dom.TagWalkType.OTHER :
+ this.reversed ? goog.dom.TagWalkType.END_TAG :
+ goog.dom.TagWalkType.START_TAG;
+ }
+ }
+
+ if (goog.isNumber(opt_depth)) {
+ this.depth = opt_depth;
+ }
+};
+
+
+/**
+ * Replace this iterator's values with values from another. The two iterators
+ * must be of the same type.
+ * @param {goog.dom.TagIterator} other The iterator to copy.
+ * @protected
+ */
+goog.dom.TagIterator.prototype.copyFrom = function(other) {
+ this.node = other.node;
+ this.tagType = other.tagType;
+ this.depth = other.depth;
+ this.reversed = other.reversed;
+ this.constrained = other.constrained;
+};
+
+
+/**
+ * @return {!goog.dom.TagIterator} A copy of this iterator.
+ */
+goog.dom.TagIterator.prototype.clone = function() {
+ return new goog.dom.TagIterator(this.node, this.reversed,
+ !this.constrained, this.tagType, this.depth);
+};
+
+
+/**
+ * Skip the current tag.
+ */
+goog.dom.TagIterator.prototype.skipTag = function() {
+ var check = this.reversed ? goog.dom.TagWalkType.END_TAG :
+ goog.dom.TagWalkType.START_TAG;
+ if (this.tagType == check) {
+ this.tagType = /** @type {goog.dom.TagWalkType} */ (check * -1);
+ this.depth += this.tagType * (this.reversed ? -1 : 1);
+ }
+};
+
+
+/**
+ * Restart the current tag.
+ */
+goog.dom.TagIterator.prototype.restartTag = function() {
+ var check = this.reversed ? goog.dom.TagWalkType.START_TAG :
+ goog.dom.TagWalkType.END_TAG;
+ if (this.tagType == check) {
+ this.tagType = /** @type {goog.dom.TagWalkType} */ (check * -1);
+ this.depth += this.tagType * (this.reversed ? -1 : 1);
+ }
+};
+
+
+/**
+ * Move to the next position in the DOM tree.
+ * @return {Node} Returns the next node, or throws a goog.iter.StopIteration
+ * exception if the end of the iterator's range has been reached.
+ * @override
+ */
+goog.dom.TagIterator.prototype.next = function() {
+ var node;
+
+ if (this.started_) {
+ if (!this.node || this.constrained && this.depth == 0) {
+ throw goog.iter.StopIteration;
+ }
+ node = this.node;
+
+ var startType = this.reversed ? goog.dom.TagWalkType.END_TAG :
+ goog.dom.TagWalkType.START_TAG;
+
+ if (this.tagType == startType) {
+ // If we have entered the tag, test if there are any children to move to.
+ var child = this.reversed ? node.lastChild : node.firstChild;
+ if (child) {
+ this.setPosition(child);
+ } else {
+ // If not, move on to exiting this tag.
+ this.setPosition(node,
+ /** @type {goog.dom.TagWalkType} */ (startType * -1));
+ }
+ } else {
+ var sibling = this.reversed ? node.previousSibling : node.nextSibling;
+ if (sibling) {
+ // Try to move to the next node.
+ this.setPosition(sibling);
+ } else {
+ // If no such node exists, exit our parent.
+ this.setPosition(node.parentNode,
+ /** @type {goog.dom.TagWalkType} */ (startType * -1));
+ }
+ }
+
+ this.depth += this.tagType * (this.reversed ? -1 : 1);
+ } else {
+ this.started_ = true;
+ }
+
+ // Check the new position for being last, and return it if it's not.
+ node = this.node;
+ if (!this.node) {
+ throw goog.iter.StopIteration;
+ }
+ return node;
+};
+
+
+/**
+ * @return {boolean} Whether next has ever been called on this iterator.
+ * @protected
+ */
+goog.dom.TagIterator.prototype.isStarted = function() {
+ return this.started_;
+};
+
+
+/**
+ * @return {boolean} Whether this iterator's position is a start tag position.
+ */
+goog.dom.TagIterator.prototype.isStartTag = function() {
+ return this.tagType == goog.dom.TagWalkType.START_TAG;
+};
+
+
+/**
+ * @return {boolean} Whether this iterator's position is an end tag position.
+ */
+goog.dom.TagIterator.prototype.isEndTag = function() {
+ return this.tagType == goog.dom.TagWalkType.END_TAG;
+};
+
+
+/**
+ * @return {boolean} Whether this iterator's position is not at an element node.
+ */
+goog.dom.TagIterator.prototype.isNonElement = function() {
+ return this.tagType == goog.dom.TagWalkType.OTHER;
+};
+
+
+/**
+ * Test if two iterators are at the same position - i.e. if the node and tagType
+ * is the same. This will still return true if the two iterators are moving in
+ * opposite directions or have different constraints.
+ * @param {goog.dom.TagIterator} other The iterator to compare to.
+ * @return {boolean} Whether the two iterators are at the same position.
+ */
+goog.dom.TagIterator.prototype.equals = function(other) {
+ // Nodes must be equal, and we must either have reached the end of our tree
+ // or be at the same position.
+ return other.node == this.node && (!this.node ||
+ other.tagType == this.tagType);
+};
+
+
+/**
+ * Replace the current node with the list of nodes. Reset the iterator so that
+ * it visits the first of the nodes next.
+ * @param {...Object} var_args A list of nodes to replace the current node with.
+ * If the first argument is array-like, it will be used, otherwise all the
+ * arguments are assumed to be nodes.
+ */
+goog.dom.TagIterator.prototype.splice = function(var_args) {
+ // Reset the iterator so that it iterates over the first replacement node in
+ // the arguments on the next iteration.
+ var node = this.node;
+ this.restartTag();
+ this.reversed = !this.reversed;
+ goog.dom.TagIterator.prototype.next.call(this);
+ this.reversed = !this.reversed;
+
+ // Replace the node with the arguments.
+ var arr = goog.isArrayLike(arguments[0]) ? arguments[0] : arguments;
+ for (var i = arr.length - 1; i >= 0; i--) {
+ goog.dom.insertSiblingAfter(arr[i], node);
+ }
+ goog.dom.removeNode(node);
+};