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:42 UTC

[27/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/tagname.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/tagname.js b/externs/GCL/externs/goog/dom/tagname.js
new file mode 100644
index 0000000..ad44d85
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/tagname.js
@@ -0,0 +1,160 @@
+// 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 Defines the goog.dom.TagName enum.  This enumerates
+ * all HTML tag names specified in either the the W3C HTML 4.01 index of
+ * elements or the HTML5 draft specification.
+ *
+ * References:
+ * http://www.w3.org/TR/html401/index/elements.html
+ * http://dev.w3.org/html5/spec/section-index.html
+ *
+ */
+goog.provide('goog.dom.TagName');
+
+
+/**
+ * Enum of all html tag names specified by the W3C HTML4.01 and HTML5
+ * specifications.
+ * @enum {string}
+ */
+goog.dom.TagName = {
+  A: 'A',
+  ABBR: 'ABBR',
+  ACRONYM: 'ACRONYM',
+  ADDRESS: 'ADDRESS',
+  APPLET: 'APPLET',
+  AREA: 'AREA',
+  ARTICLE: 'ARTICLE',
+  ASIDE: 'ASIDE',
+  AUDIO: 'AUDIO',
+  B: 'B',
+  BASE: 'BASE',
+  BASEFONT: 'BASEFONT',
+  BDI: 'BDI',
+  BDO: 'BDO',
+  BIG: 'BIG',
+  BLOCKQUOTE: 'BLOCKQUOTE',
+  BODY: 'BODY',
+  BR: 'BR',
+  BUTTON: 'BUTTON',
+  CANVAS: 'CANVAS',
+  CAPTION: 'CAPTION',
+  CENTER: 'CENTER',
+  CITE: 'CITE',
+  CODE: 'CODE',
+  COL: 'COL',
+  COLGROUP: 'COLGROUP',
+  COMMAND: 'COMMAND',
+  DATA: 'DATA',
+  DATALIST: 'DATALIST',
+  DD: 'DD',
+  DEL: 'DEL',
+  DETAILS: 'DETAILS',
+  DFN: 'DFN',
+  DIALOG: 'DIALOG',
+  DIR: 'DIR',
+  DIV: 'DIV',
+  DL: 'DL',
+  DT: 'DT',
+  EM: 'EM',
+  EMBED: 'EMBED',
+  FIELDSET: 'FIELDSET',
+  FIGCAPTION: 'FIGCAPTION',
+  FIGURE: 'FIGURE',
+  FONT: 'FONT',
+  FOOTER: 'FOOTER',
+  FORM: 'FORM',
+  FRAME: 'FRAME',
+  FRAMESET: 'FRAMESET',
+  H1: 'H1',
+  H2: 'H2',
+  H3: 'H3',
+  H4: 'H4',
+  H5: 'H5',
+  H6: 'H6',
+  HEAD: 'HEAD',
+  HEADER: 'HEADER',
+  HGROUP: 'HGROUP',
+  HR: 'HR',
+  HTML: 'HTML',
+  I: 'I',
+  IFRAME: 'IFRAME',
+  IMG: 'IMG',
+  INPUT: 'INPUT',
+  INS: 'INS',
+  ISINDEX: 'ISINDEX',
+  KBD: 'KBD',
+  KEYGEN: 'KEYGEN',
+  LABEL: 'LABEL',
+  LEGEND: 'LEGEND',
+  LI: 'LI',
+  LINK: 'LINK',
+  MAP: 'MAP',
+  MARK: 'MARK',
+  MATH: 'MATH',
+  MENU: 'MENU',
+  META: 'META',
+  METER: 'METER',
+  NAV: 'NAV',
+  NOFRAMES: 'NOFRAMES',
+  NOSCRIPT: 'NOSCRIPT',
+  OBJECT: 'OBJECT',
+  OL: 'OL',
+  OPTGROUP: 'OPTGROUP',
+  OPTION: 'OPTION',
+  OUTPUT: 'OUTPUT',
+  P: 'P',
+  PARAM: 'PARAM',
+  PRE: 'PRE',
+  PROGRESS: 'PROGRESS',
+  Q: 'Q',
+  RP: 'RP',
+  RT: 'RT',
+  RUBY: 'RUBY',
+  S: 'S',
+  SAMP: 'SAMP',
+  SCRIPT: 'SCRIPT',
+  SECTION: 'SECTION',
+  SELECT: 'SELECT',
+  SMALL: 'SMALL',
+  SOURCE: 'SOURCE',
+  SPAN: 'SPAN',
+  STRIKE: 'STRIKE',
+  STRONG: 'STRONG',
+  STYLE: 'STYLE',
+  SUB: 'SUB',
+  SUMMARY: 'SUMMARY',
+  SUP: 'SUP',
+  SVG: 'SVG',
+  TABLE: 'TABLE',
+  TBODY: 'TBODY',
+  TD: 'TD',
+  TEMPLATE: 'TEMPLATE',
+  TEXTAREA: 'TEXTAREA',
+  TFOOT: 'TFOOT',
+  TH: 'TH',
+  THEAD: 'THEAD',
+  TIME: 'TIME',
+  TITLE: 'TITLE',
+  TR: 'TR',
+  TRACK: 'TRACK',
+  TT: 'TT',
+  U: 'U',
+  UL: 'UL',
+  VAR: 'VAR',
+  VIDEO: 'VIDEO',
+  WBR: 'WBR'
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/tags.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/tags.js b/externs/GCL/externs/goog/dom/tags.js
new file mode 100644
index 0000000..159abe0
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/tags.js
@@ -0,0 +1,42 @@
+// Copyright 2014 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 HTML element tag names.
+ */
+goog.provide('goog.dom.tags');
+
+goog.require('goog.object');
+
+
+/**
+ * The void elements specified by
+ * http://www.w3.org/TR/html-markup/syntax.html#void-elements.
+ * @const
+ * @type {!Object}
+ * @private
+ */
+goog.dom.tags.VOID_TAGS_ = goog.object.createSet(('area,base,br,col,command,' +
+    'embed,hr,img,input,keygen,link,meta,param,source,track,wbr').split(','));
+
+
+/**
+ * Checks whether the tag is void (with no contents allowed and no legal end
+ * tag), for example 'br'.
+ * @param {string} tagName The tag name in lower case.
+ * @return {boolean}
+ */
+goog.dom.tags.isVoidTag = function(tagName) {
+  return goog.dom.tags.VOID_TAGS_[tagName] === true;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/textrange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/textrange.js b/externs/GCL/externs/goog/dom/textrange.js
new file mode 100644
index 0000000..f5cfee0
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/textrange.js
@@ -0,0 +1,615 @@
+// 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 text ranges in HTML documents.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.TextRange');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.dom.AbstractRange');
+goog.require('goog.dom.RangeType');
+goog.require('goog.dom.SavedRange');
+goog.require('goog.dom.TagName');
+goog.require('goog.dom.TextRangeIterator');
+goog.require('goog.dom.browserrange');
+goog.require('goog.string');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * Create a new text selection with no properties.  Do not use this constructor:
+ * use one of the goog.dom.Range.createFrom* methods instead.
+ * @constructor
+ * @extends {goog.dom.AbstractRange}
+ * @final
+ */
+goog.dom.TextRange = function() {
+  /**
+   * The browser specific range wrapper.  This can be null if one of the other
+   * representations of the range is specified.
+   * @private {goog.dom.browserrange.AbstractRange?}
+   */
+  this.browserRangeWrapper_ = null;
+
+  /**
+   * The start node of the range.  This can be null if one of the other
+   * representations of the range is specified.
+   * @private {Node}
+   */
+  this.startNode_ = null;
+
+  /**
+   * The start offset of the range.  This can be null if one of the other
+   * representations of the range is specified.
+   * @private {?number}
+   */
+  this.startOffset_ = null;
+
+  /**
+   * The end node of the range.  This can be null if one of the other
+   * representations of the range is specified.
+   * @private {Node}
+   */
+  this.endNode_ = null;
+
+  /**
+   * The end offset of the range.  This can be null if one of the other
+   * representations of the range is specified.
+   * @private {?number}
+   */
+  this.endOffset_ = null;
+
+  /**
+   * Whether the focus node is before the anchor node.
+   * @private {boolean}
+   */
+  this.isReversed_ = false;
+};
+goog.inherits(goog.dom.TextRange, goog.dom.AbstractRange);
+
+
+/**
+ * Create a new range wrapper from the given browser range object.  Do not use
+ * this method directly - please use goog.dom.Range.createFrom* instead.
+ * @param {Range|TextRange} range The browser range object.
+ * @param {boolean=} opt_isReversed Whether the focus node is before the anchor
+ *     node.
+ * @return {!goog.dom.TextRange} A range wrapper object.
+ */
+goog.dom.TextRange.createFromBrowserRange = function(range, opt_isReversed) {
+  return goog.dom.TextRange.createFromBrowserRangeWrapper_(
+      goog.dom.browserrange.createRange(range), opt_isReversed);
+};
+
+
+/**
+ * Create a new range wrapper from the given browser range wrapper.
+ * @param {goog.dom.browserrange.AbstractRange} browserRange The browser range
+ *     wrapper.
+ * @param {boolean=} opt_isReversed Whether the focus node is before the anchor
+ *     node.
+ * @return {!goog.dom.TextRange} A range wrapper object.
+ * @private
+ */
+goog.dom.TextRange.createFromBrowserRangeWrapper_ = function(browserRange,
+    opt_isReversed) {
+  var range = new goog.dom.TextRange();
+
+  // Initialize the range as a browser range wrapper type range.
+  range.browserRangeWrapper_ = browserRange;
+  range.isReversed_ = !!opt_isReversed;
+
+  return range;
+};
+
+
+/**
+ * Create a new range wrapper that selects the given node's text.  Do not use
+ * this method directly - please use goog.dom.Range.createFrom* instead.
+ * @param {Node} node The node to select.
+ * @param {boolean=} opt_isReversed Whether the focus node is before the anchor
+ *     node.
+ * @return {!goog.dom.TextRange} A range wrapper object.
+ */
+goog.dom.TextRange.createFromNodeContents = function(node, opt_isReversed) {
+  return goog.dom.TextRange.createFromBrowserRangeWrapper_(
+      goog.dom.browserrange.createRangeFromNodeContents(node),
+      opt_isReversed);
+};
+
+
+/**
+ * Create a new range wrapper that selects the area between the given nodes,
+ * accounting for the given offsets.  Do not use this method directly - please
+ * use goog.dom.Range.createFrom* instead.
+ * @param {Node} anchorNode The node to start with.
+ * @param {number} anchorOffset The offset within the node to start.
+ * @param {Node} focusNode The node to end with.
+ * @param {number} focusOffset The offset within the node to end.
+ * @return {!goog.dom.TextRange} A range wrapper object.
+ */
+goog.dom.TextRange.createFromNodes = function(anchorNode, anchorOffset,
+    focusNode, focusOffset) {
+  var range = new goog.dom.TextRange();
+  range.isReversed_ = /** @suppress {missingRequire} */ (
+      goog.dom.Range.isReversed(anchorNode, anchorOffset,
+                                focusNode, focusOffset));
+
+  // Avoid selecting terminal elements directly
+  if (goog.dom.isElement(anchorNode) && !goog.dom.canHaveChildren(anchorNode)) {
+    var parent = anchorNode.parentNode;
+    anchorOffset = goog.array.indexOf(parent.childNodes, anchorNode);
+    anchorNode = parent;
+  }
+
+  if (goog.dom.isElement(focusNode) && !goog.dom.canHaveChildren(focusNode)) {
+    var parent = focusNode.parentNode;
+    focusOffset = goog.array.indexOf(parent.childNodes, focusNode);
+    focusNode = parent;
+  }
+
+  // Initialize the range as a W3C style range.
+  if (range.isReversed_) {
+    range.startNode_ = focusNode;
+    range.startOffset_ = focusOffset;
+    range.endNode_ = anchorNode;
+    range.endOffset_ = anchorOffset;
+  } else {
+    range.startNode_ = anchorNode;
+    range.startOffset_ = anchorOffset;
+    range.endNode_ = focusNode;
+    range.endOffset_ = focusOffset;
+  }
+
+  return range;
+};
+
+
+// Method implementations
+
+
+/**
+ * @return {!goog.dom.TextRange} A clone of this range.
+ * @override
+ */
+goog.dom.TextRange.prototype.clone = function() {
+  var range = new goog.dom.TextRange();
+  range.browserRangeWrapper_ =
+      this.browserRangeWrapper_ && this.browserRangeWrapper_.clone();
+  range.startNode_ = this.startNode_;
+  range.startOffset_ = this.startOffset_;
+  range.endNode_ = this.endNode_;
+  range.endOffset_ = this.endOffset_;
+  range.isReversed_ = this.isReversed_;
+
+  return range;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getType = function() {
+  return goog.dom.RangeType.TEXT;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getBrowserRangeObject = function() {
+  return this.getBrowserRangeWrapper_().getBrowserRange();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.setBrowserRangeObject = function(nativeRange) {
+  // Test if it's a control range by seeing if a control range only method
+  // exists.
+  if (goog.dom.AbstractRange.isNativeControlRange(nativeRange)) {
+    return false;
+  }
+  this.browserRangeWrapper_ = goog.dom.browserrange.createRange(
+      nativeRange);
+  this.clearCachedValues_();
+  return true;
+};
+
+
+/**
+ * Clear all cached values.
+ * @private
+ */
+goog.dom.TextRange.prototype.clearCachedValues_ = function() {
+  this.startNode_ = this.startOffset_ = this.endNode_ = this.endOffset_ = null;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getTextRangeCount = function() {
+  return 1;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getTextRange = function(i) {
+  return this;
+};
+
+
+/**
+ * @return {!goog.dom.browserrange.AbstractRange} The range wrapper object.
+ * @private
+ */
+goog.dom.TextRange.prototype.getBrowserRangeWrapper_ = function() {
+  return this.browserRangeWrapper_ ||
+      (this.browserRangeWrapper_ = goog.dom.browserrange.createRangeFromNodes(
+          this.getStartNode(), this.getStartOffset(),
+          this.getEndNode(), this.getEndOffset()));
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getContainer = function() {
+  return this.getBrowserRangeWrapper_().getContainer();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getStartNode = function() {
+  return this.startNode_ ||
+      (this.startNode_ = this.getBrowserRangeWrapper_().getStartNode());
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getStartOffset = function() {
+  return this.startOffset_ != null ? this.startOffset_ :
+      (this.startOffset_ = this.getBrowserRangeWrapper_().getStartOffset());
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getStartPosition = function() {
+  return this.isReversed() ?
+      this.getBrowserRangeWrapper_().getEndPosition() :
+      this.getBrowserRangeWrapper_().getStartPosition();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getEndNode = function() {
+  return this.endNode_ ||
+      (this.endNode_ = this.getBrowserRangeWrapper_().getEndNode());
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getEndOffset = function() {
+  return this.endOffset_ != null ? this.endOffset_ :
+      (this.endOffset_ = this.getBrowserRangeWrapper_().getEndOffset());
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getEndPosition = function() {
+  return this.isReversed() ?
+      this.getBrowserRangeWrapper_().getStartPosition() :
+      this.getBrowserRangeWrapper_().getEndPosition();
+};
+
+
+/**
+ * Moves a TextRange to the provided nodes and offsets.
+ * @param {Node} startNode The node to start with.
+ * @param {number} startOffset The offset within the node to start.
+ * @param {Node} endNode The node to end with.
+ * @param {number} endOffset The offset within the node to end.
+ * @param {boolean} isReversed Whether the range is reversed.
+ */
+goog.dom.TextRange.prototype.moveToNodes = function(startNode, startOffset,
+                                                    endNode, endOffset,
+                                                    isReversed) {
+  this.startNode_ = startNode;
+  this.startOffset_ = startOffset;
+  this.endNode_ = endNode;
+  this.endOffset_ = endOffset;
+  this.isReversed_ = isReversed;
+  this.browserRangeWrapper_ = null;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.isReversed = function() {
+  return this.isReversed_;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.containsRange = function(otherRange,
+                                                      opt_allowPartial) {
+  var otherRangeType = otherRange.getType();
+  if (otherRangeType == goog.dom.RangeType.TEXT) {
+    return this.getBrowserRangeWrapper_().containsRange(
+        otherRange.getBrowserRangeWrapper_(), opt_allowPartial);
+  } else if (otherRangeType == goog.dom.RangeType.CONTROL) {
+    var elements = otherRange.getElements();
+    var fn = opt_allowPartial ? goog.array.some : goog.array.every;
+    return fn(elements, function(el) {
+      return this.containsNode(el, opt_allowPartial);
+    }, this);
+  }
+  return false;
+};
+
+
+/**
+ * Tests if the given node is in a document.
+ * @param {Node} node The node to check.
+ * @return {boolean} Whether the given node is in the given document.
+ */
+goog.dom.TextRange.isAttachedNode = function(node) {
+  if (goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) {
+    var returnValue = false;
+    /** @preserveTry */
+    try {
+      returnValue = node.parentNode;
+    } catch (e) {
+      // IE sometimes throws Invalid Argument errors when a node is detached.
+      // Note: trying to return a value from the above try block can cause IE
+      // to crash.  It is necessary to use the local returnValue
+    }
+    return !!returnValue;
+  } else {
+    return goog.dom.contains(node.ownerDocument.body, node);
+  }
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.isRangeInDocument = function() {
+  // Ensure any cached nodes are in the document.  IE also allows ranges to
+  // become detached, so we check if the range is still in the document as
+  // well for IE.
+  return (!this.startNode_ ||
+          goog.dom.TextRange.isAttachedNode(this.startNode_)) &&
+         (!this.endNode_ ||
+          goog.dom.TextRange.isAttachedNode(this.endNode_)) &&
+         (!(goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)) ||
+          this.getBrowserRangeWrapper_().isRangeInDocument());
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.isCollapsed = function() {
+  return this.getBrowserRangeWrapper_().isCollapsed();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getText = function() {
+  return this.getBrowserRangeWrapper_().getText();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getHtmlFragment = function() {
+  // TODO(robbyw): Generalize the code in browserrange so it is static and
+  // just takes an iterator.  This would mean we don't always have to create a
+  // browser range.
+  return this.getBrowserRangeWrapper_().getHtmlFragment();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getValidHtml = function() {
+  return this.getBrowserRangeWrapper_().getValidHtml();
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.getPastableHtml = function() {
+  // TODO(robbyw): Get any attributes the table or tr has.
+
+  var html = this.getValidHtml();
+
+  if (html.match(/^\s*<td\b/i)) {
+    // Match html starting with a TD.
+    html = '<table><tbody><tr>' + html + '</tr></tbody></table>';
+  } else if (html.match(/^\s*<tr\b/i)) {
+    // Match html starting with a TR.
+    html = '<table><tbody>' + html + '</tbody></table>';
+  } else if (html.match(/^\s*<tbody\b/i)) {
+    // Match html starting with a TBODY.
+    html = '<table>' + html + '</table>';
+  } else if (html.match(/^\s*<li\b/i)) {
+    // Match html starting with an LI.
+    var container = this.getContainer();
+    var tagType = goog.dom.TagName.UL;
+    while (container) {
+      if (container.tagName == goog.dom.TagName.OL) {
+        tagType = goog.dom.TagName.OL;
+        break;
+      } else if (container.tagName == goog.dom.TagName.UL) {
+        break;
+      }
+      container = container.parentNode;
+    }
+    html = goog.string.buildString('<', tagType, '>', html, '</', tagType, '>');
+  }
+
+  return html;
+};
+
+
+/**
+ * Returns a TextRangeIterator over the contents of the range.  Regardless of
+ * the direction of the range, the iterator will move in document order.
+ * @param {boolean=} opt_keys Unused for this iterator.
+ * @return {!goog.dom.TextRangeIterator} An iterator over tags in the range.
+ * @override
+ */
+goog.dom.TextRange.prototype.__iterator__ = function(opt_keys) {
+  return new goog.dom.TextRangeIterator(this.getStartNode(),
+      this.getStartOffset(), this.getEndNode(), this.getEndOffset());
+};
+
+
+// RANGE ACTIONS
+
+
+/** @override */
+goog.dom.TextRange.prototype.select = function() {
+  this.getBrowserRangeWrapper_().select(this.isReversed_);
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.removeContents = function() {
+  this.getBrowserRangeWrapper_().removeContents();
+  this.clearCachedValues_();
+};
+
+
+/**
+ * Surrounds the text range with the specified element (on Mozilla) or with a
+ * clone of the specified element (on IE).  Returns a reference to the
+ * surrounding element if the operation was successful; returns null if the
+ * operation failed.
+ * @param {Element} element The element with which the selection is to be
+ *    surrounded.
+ * @return {Element} The surrounding element (same as the argument on Mozilla,
+ *    but not on IE), or null if unsuccessful.
+ */
+goog.dom.TextRange.prototype.surroundContents = function(element) {
+  var output = this.getBrowserRangeWrapper_().surroundContents(element);
+  this.clearCachedValues_();
+  return output;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.insertNode = function(node, before) {
+  var output = this.getBrowserRangeWrapper_().insertNode(node, before);
+  this.clearCachedValues_();
+  return output;
+};
+
+
+/** @override */
+goog.dom.TextRange.prototype.surroundWithNodes = function(startNode, endNode) {
+  this.getBrowserRangeWrapper_().surroundWithNodes(startNode, endNode);
+  this.clearCachedValues_();
+};
+
+
+// SAVE/RESTORE
+
+
+/** @override */
+goog.dom.TextRange.prototype.saveUsingDom = function() {
+  return new goog.dom.DomSavedTextRange_(this);
+};
+
+
+// RANGE MODIFICATION
+
+
+/** @override */
+goog.dom.TextRange.prototype.collapse = function(toAnchor) {
+  var toStart = this.isReversed() ? !toAnchor : toAnchor;
+
+  if (this.browserRangeWrapper_) {
+    this.browserRangeWrapper_.collapse(toStart);
+  }
+
+  if (toStart) {
+    this.endNode_ = this.startNode_;
+    this.endOffset_ = this.startOffset_;
+  } else {
+    this.startNode_ = this.endNode_;
+    this.startOffset_ = this.endOffset_;
+  }
+
+  // Collapsed ranges can't be reversed
+  this.isReversed_ = false;
+};
+
+
+// SAVED RANGE OBJECTS
+
+
+
+/**
+ * A SavedRange implementation using DOM endpoints.
+ * @param {goog.dom.AbstractRange} range The range to save.
+ * @constructor
+ * @extends {goog.dom.SavedRange}
+ * @private
+ */
+goog.dom.DomSavedTextRange_ = function(range) {
+  goog.dom.DomSavedTextRange_.base(this, 'constructor');
+
+  /**
+   * The anchor node.
+   * @type {Node}
+   * @private
+   */
+  this.anchorNode_ = range.getAnchorNode();
+
+  /**
+   * The anchor node offset.
+   * @type {number}
+   * @private
+   */
+  this.anchorOffset_ = range.getAnchorOffset();
+
+  /**
+   * The focus node.
+   * @type {Node}
+   * @private
+   */
+  this.focusNode_ = range.getFocusNode();
+
+  /**
+   * The focus node offset.
+   * @type {number}
+   * @private
+   */
+  this.focusOffset_ = range.getFocusOffset();
+};
+goog.inherits(goog.dom.DomSavedTextRange_, goog.dom.SavedRange);
+
+
+/**
+ * @return {!goog.dom.AbstractRange} The restored range.
+ * @override
+ */
+goog.dom.DomSavedTextRange_.prototype.restoreInternal = function() {
+  return /** @suppress {missingRequire} */ (
+      goog.dom.Range.createFromNodes(this.anchorNode_, this.anchorOffset_,
+                                     this.focusNode_, this.focusOffset_));
+};
+
+
+/** @override */
+goog.dom.DomSavedTextRange_.prototype.disposeInternal = function() {
+  goog.dom.DomSavedTextRange_.superClass_.disposeInternal.call(this);
+
+  this.anchorNode_ = null;
+  this.focusNode_ = null;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/textrangeiterator.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/textrangeiterator.js b/externs/GCL/externs/goog/dom/textrangeiterator.js
new file mode 100644
index 0000000..efb5221
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/textrangeiterator.js
@@ -0,0 +1,239 @@
+// 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 Iterator between two DOM text range positions.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.TextRangeIterator');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.RangeIterator');
+goog.require('goog.dom.TagName');
+goog.require('goog.iter.StopIteration');
+
+
+
+/**
+ * Subclass of goog.dom.TagIterator that iterates over a DOM range.  It
+ * adds functions to determine the portion of each text node that is selected.
+ *
+ * @param {Node} startNode The starting node position.
+ * @param {number} startOffset The offset in to startNode.  If startNode is
+ *     an element, indicates an offset in to childNodes.  If startNode is a
+ *     text node, indicates an offset in to nodeValue.
+ * @param {Node} endNode The ending node position.
+ * @param {number} endOffset The offset in to endNode.  If endNode is
+ *     an element, indicates an offset in to childNodes.  If endNode is a
+ *     text node, indicates an offset in to nodeValue.
+ * @param {boolean=} opt_reverse Whether to traverse nodes in reverse.
+ * @constructor
+ * @extends {goog.dom.RangeIterator}
+ * @final
+ */
+goog.dom.TextRangeIterator = function(startNode, startOffset, endNode,
+    endOffset, opt_reverse) {
+  /**
+   * The first node in the selection.
+   * @private {Node}
+   */
+  this.startNode_ = null;
+
+  /**
+   * The last node in the selection.
+   * @private {Node}
+   */
+  this.endNode_ = null;
+
+  /**
+   * The offset within the first node in the selection.
+   * @private {number}
+   */
+  this.startOffset_ = 0;
+
+  /**
+   * The offset within the last node in the selection.
+   * @private {number}
+   */
+  this.endOffset_ = 0;
+
+  var goNext;
+
+  if (startNode) {
+    this.startNode_ = startNode;
+    this.startOffset_ = startOffset;
+    this.endNode_ = endNode;
+    this.endOffset_ = endOffset;
+
+    // Skip to the offset nodes - being careful to special case BRs since these
+    // have no children but still can appear as the startContainer of a range.
+    if (startNode.nodeType == goog.dom.NodeType.ELEMENT &&
+        startNode.tagName != goog.dom.TagName.BR) {
+      var startChildren = startNode.childNodes;
+      var candidate = startChildren[startOffset];
+      if (candidate) {
+        this.startNode_ = candidate;
+        this.startOffset_ = 0;
+      } else {
+        if (startChildren.length) {
+          this.startNode_ =
+              /** @type {Node} */ (goog.array.peek(startChildren));
+        }
+        goNext = true;
+      }
+    }
+
+    if (endNode.nodeType == goog.dom.NodeType.ELEMENT) {
+      this.endNode_ = endNode.childNodes[endOffset];
+      if (this.endNode_) {
+        this.endOffset_ = 0;
+      } else {
+        // The offset was past the last element.
+        this.endNode_ = endNode;
+      }
+    }
+  }
+
+  goog.dom.TextRangeIterator.base(
+      this, 'constructor', opt_reverse ? this.endNode_ : this.startNode_,
+      opt_reverse);
+
+  if (goNext) {
+    try {
+      this.next();
+    } catch (e) {
+      if (e != goog.iter.StopIteration) {
+        throw e;
+      }
+    }
+  }
+};
+goog.inherits(goog.dom.TextRangeIterator, goog.dom.RangeIterator);
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.getStartTextOffset = function() {
+  // Offsets only apply to text nodes.  If our current node is the start node,
+  // return the saved offset.  Otherwise, return 0.
+  return this.node.nodeType != goog.dom.NodeType.TEXT ? -1 :
+         this.node == this.startNode_ ? this.startOffset_ : 0;
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.getEndTextOffset = function() {
+  // Offsets only apply to text nodes.  If our current node is the end node,
+  // return the saved offset.  Otherwise, return the length of the node.
+  return this.node.nodeType != goog.dom.NodeType.TEXT ? -1 :
+      this.node == this.endNode_ ? this.endOffset_ : this.node.nodeValue.length;
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.getStartNode = function() {
+  return this.startNode_;
+};
+
+
+/**
+ * Change the start node of the iterator.
+ * @param {Node} node The new start node.
+ */
+goog.dom.TextRangeIterator.prototype.setStartNode = function(node) {
+  if (!this.isStarted()) {
+    this.setPosition(node);
+  }
+
+  this.startNode_ = node;
+  this.startOffset_ = 0;
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.getEndNode = function() {
+  return this.endNode_;
+};
+
+
+/**
+ * Change the end node of the iterator.
+ * @param {Node} node The new end node.
+ */
+goog.dom.TextRangeIterator.prototype.setEndNode = function(node) {
+  this.endNode_ = node;
+  this.endOffset_ = 0;
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.isLast = function() {
+  return this.isStarted() && this.node == this.endNode_ &&
+      (!this.endOffset_ || !this.isStartTag());
+};
+
+
+/**
+ * Move to the next position in the selection.
+ * Throws {@code goog.iter.StopIteration} when it passes the end of the range.
+ * @return {Node} The node at the next position.
+ * @override
+ */
+goog.dom.TextRangeIterator.prototype.next = function() {
+  if (this.isLast()) {
+    throw goog.iter.StopIteration;
+  }
+
+  // Call the super function.
+  return goog.dom.TextRangeIterator.superClass_.next.call(this);
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.skipTag = function() {
+  goog.dom.TextRangeIterator.superClass_.skipTag.apply(this);
+
+  // If the node we are skipping contains the end node, we just skipped past
+  // the end, so we stop the iteration.
+  if (goog.dom.contains(this.node, this.endNode_)) {
+    throw goog.iter.StopIteration;
+  }
+};
+
+
+/** @override */
+goog.dom.TextRangeIterator.prototype.copyFrom = function(other) {
+  this.startNode_ = other.startNode_;
+  this.endNode_ = other.endNode_;
+  this.startOffset_ = other.startOffset_;
+  this.endOffset_ = other.endOffset_;
+  this.isReversed_ = other.isReversed_;
+
+  goog.dom.TextRangeIterator.superClass_.copyFrom.call(this, other);
+};
+
+
+/**
+ * @return {!goog.dom.TextRangeIterator} An identical iterator.
+ * @override
+ */
+goog.dom.TextRangeIterator.prototype.clone = function() {
+  var copy = new goog.dom.TextRangeIterator(this.startNode_,
+      this.startOffset_, this.endNode_, this.endOffset_, this.isReversed_);
+  copy.copyFrom(this);
+  return copy;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/vendor.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/vendor.js b/externs/GCL/externs/goog/dom/vendor.js
new file mode 100644
index 0000000..7c1123e
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/vendor.js
@@ -0,0 +1,96 @@
+// Copyright 2012 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 Vendor prefix getters.
+ */
+
+goog.provide('goog.dom.vendor');
+
+goog.require('goog.string');
+goog.require('goog.userAgent');
+
+
+/**
+ * Returns the JS vendor prefix used in CSS properties. Different vendors
+ * use different methods of changing the case of the property names.
+ *
+ * @return {?string} The JS vendor prefix or null if there is none.
+ */
+goog.dom.vendor.getVendorJsPrefix = function() {
+  if (goog.userAgent.WEBKIT) {
+    return 'Webkit';
+  } else if (goog.userAgent.GECKO) {
+    return 'Moz';
+  } else if (goog.userAgent.IE) {
+    return 'ms';
+  } else if (goog.userAgent.OPERA) {
+    return 'O';
+  }
+
+  return null;
+};
+
+
+/**
+ * Returns the vendor prefix used in CSS properties.
+ *
+ * @return {?string} The vendor prefix or null if there is none.
+ */
+goog.dom.vendor.getVendorPrefix = function() {
+  if (goog.userAgent.WEBKIT) {
+    return '-webkit';
+  } else if (goog.userAgent.GECKO) {
+    return '-moz';
+  } else if (goog.userAgent.IE) {
+    return '-ms';
+  } else if (goog.userAgent.OPERA) {
+    return '-o';
+  }
+
+  return null;
+};
+
+
+/**
+ * @param {string} propertyName A property name.
+ * @param {!Object=} opt_object If provided, we verify if the property exists in
+ *     the object.
+ * @return {?string} A vendor prefixed property name, or null if it does not
+ *     exist.
+ */
+goog.dom.vendor.getPrefixedPropertyName = function(propertyName, opt_object) {
+  // We first check for a non-prefixed property, if available.
+  if (opt_object && propertyName in opt_object) {
+    return propertyName;
+  }
+  var prefix = goog.dom.vendor.getVendorJsPrefix();
+  if (prefix) {
+    prefix = prefix.toLowerCase();
+    var prefixedPropertyName = prefix + goog.string.toTitleCase(propertyName);
+    return (!goog.isDef(opt_object) || prefixedPropertyName in opt_object) ?
+        prefixedPropertyName : null;
+  }
+  return null;
+};
+
+
+/**
+ * @param {string} eventType An event type.
+ * @return {string} A lower-cased vendor prefixed event type.
+ */
+goog.dom.vendor.getPrefixedEventType = function(eventType) {
+  var prefix = goog.dom.vendor.getVendorJsPrefix() || '';
+  return (prefix + eventType).toLowerCase();
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/viewportsizemonitor.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/viewportsizemonitor.js b/externs/GCL/externs/goog/dom/viewportsizemonitor.js
new file mode 100644
index 0000000..2f5f30e
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/viewportsizemonitor.js
@@ -0,0 +1,165 @@
+// 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 Utility class that monitors viewport size changes.
+ *
+ * @author attila@google.com (Attila Bodis)
+ * @see ../demos/viewportsizemonitor.html
+ */
+
+goog.provide('goog.dom.ViewportSizeMonitor');
+
+goog.require('goog.dom');
+goog.require('goog.events');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
+goog.require('goog.math.Size');
+
+
+
+/**
+ * This class can be used to monitor changes in the viewport size.  Instances
+ * dispatch a {@link goog.events.EventType.RESIZE} event when the viewport size
+ * changes.  Handlers can call {@link goog.dom.ViewportSizeMonitor#getSize} to
+ * get the new viewport size.
+ *
+ * Use this class if you want to execute resize/reflow logic each time the
+ * user resizes the browser window.  This class is guaranteed to only dispatch
+ * {@code RESIZE} events when the pixel dimensions of the viewport change.
+ * (Internet Explorer fires resize events if any element on the page is resized,
+ * even if the viewport dimensions are unchanged, which can lead to infinite
+ * resize loops.)
+ *
+ * Example usage:
+ *  <pre>
+ *    var vsm = new goog.dom.ViewportSizeMonitor();
+ *    goog.events.listen(vsm, goog.events.EventType.RESIZE, function(e) {
+ *      alert('Viewport size changed to ' + vsm.getSize());
+ *    });
+ *  </pre>
+ *
+ * Manually verified on IE6, IE7, FF2, Opera 11, Safari 4 and Chrome.
+ *
+ * @param {Window=} opt_window The window to monitor; defaults to the window in
+ *    which this code is executing.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ */
+goog.dom.ViewportSizeMonitor = function(opt_window) {
+  goog.dom.ViewportSizeMonitor.base(this, 'constructor');
+
+  /**
+   * The window to monitor. Defaults to the window in which the code is running.
+   * @private {Window}
+   */
+  this.window_ = opt_window || window;
+
+  /**
+   * Event listener key for window the window resize handler, as returned by
+   * {@link goog.events.listen}.
+   * @private {goog.events.Key}
+   */
+  this.listenerKey_ = goog.events.listen(this.window_,
+      goog.events.EventType.RESIZE, this.handleResize_, false, this);
+
+  /**
+   * The most recently recorded size of the viewport, in pixels.
+   * @private {goog.math.Size}
+   */
+  this.size_ = goog.dom.getViewportSize(this.window_);
+};
+goog.inherits(goog.dom.ViewportSizeMonitor, goog.events.EventTarget);
+
+
+/**
+ * Returns a viewport size monitor for the given window.  A new one is created
+ * if it doesn't exist already.  This prevents the unnecessary creation of
+ * multiple spooling monitors for a window.
+ * @param {Window=} opt_window The window to monitor; defaults to the window in
+ *     which this code is executing.
+ * @return {!goog.dom.ViewportSizeMonitor} Monitor for the given window.
+ */
+goog.dom.ViewportSizeMonitor.getInstanceForWindow = function(opt_window) {
+  var currentWindow = opt_window || window;
+  var uid = goog.getUid(currentWindow);
+
+  return goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid] =
+      goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid] ||
+      new goog.dom.ViewportSizeMonitor(currentWindow);
+};
+
+
+/**
+ * Removes and disposes a viewport size monitor for the given window if one
+ * exists.
+ * @param {Window=} opt_window The window whose monitor should be removed;
+ *     defaults to the window in which this code is executing.
+ */
+goog.dom.ViewportSizeMonitor.removeInstanceForWindow = function(opt_window) {
+  var uid = goog.getUid(opt_window || window);
+
+  goog.dispose(goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid]);
+  delete goog.dom.ViewportSizeMonitor.windowInstanceMap_[uid];
+};
+
+
+/**
+ * Map of window hash code to viewport size monitor for that window, if
+ * created.
+ * @type {Object<number,goog.dom.ViewportSizeMonitor>}
+ * @private
+ */
+goog.dom.ViewportSizeMonitor.windowInstanceMap_ = {};
+
+
+/**
+ * Returns the most recently recorded size of the viewport, in pixels.  May
+ * return null if no window resize event has been handled yet.
+ * @return {goog.math.Size} The viewport dimensions, in pixels.
+ */
+goog.dom.ViewportSizeMonitor.prototype.getSize = function() {
+  // Return a clone instead of the original to preserve encapsulation.
+  return this.size_ ? this.size_.clone() : null;
+};
+
+
+/** @override */
+goog.dom.ViewportSizeMonitor.prototype.disposeInternal = function() {
+  goog.dom.ViewportSizeMonitor.superClass_.disposeInternal.call(this);
+
+  if (this.listenerKey_) {
+    goog.events.unlistenByKey(this.listenerKey_);
+    this.listenerKey_ = null;
+  }
+
+  this.window_ = null;
+  this.size_ = null;
+};
+
+
+/**
+ * Handles window resize events by measuring the dimensions of the
+ * viewport and dispatching a {@link goog.events.EventType.RESIZE} event if the
+ * current dimensions are different from the previous ones.
+ * @param {goog.events.Event} event The window resize event to handle.
+ * @private
+ */
+goog.dom.ViewportSizeMonitor.prototype.handleResize_ = function(event) {
+  var size = goog.dom.getViewportSize(this.window_);
+  if (!goog.math.Size.equals(size, this.size_)) {
+    this.size_ = size;
+    this.dispatchEvent(goog.events.EventType.RESIZE);
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/xml.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/xml.js b/externs/GCL/externs/goog/dom/xml.js
new file mode 100644
index 0000000..59f123a
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/xml.js
@@ -0,0 +1,204 @@
+// 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
+ * XML utilities.
+ *
+ */
+
+goog.provide('goog.dom.xml');
+
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+
+
+/**
+ * Max XML size for MSXML2.  Used to prevent potential DoS attacks.
+ * @type {number}
+ */
+goog.dom.xml.MAX_XML_SIZE_KB = 2 * 1024;  // In kB
+
+
+/**
+ * Max XML size for MSXML2.  Used to prevent potential DoS attacks.
+ * @type {number}
+ */
+goog.dom.xml.MAX_ELEMENT_DEPTH = 256; // Same default as MSXML6.
+
+
+/**
+ * Creates an XML document appropriate for the current JS runtime
+ * @param {string=} opt_rootTagName The root tag name.
+ * @param {string=} opt_namespaceUri Namespace URI of the document element.
+ * @return {Document} The new document.
+ */
+goog.dom.xml.createDocument = function(opt_rootTagName, opt_namespaceUri) {
+  if (opt_namespaceUri && !opt_rootTagName) {
+    throw Error("Can't create document with namespace and no root tag");
+  }
+  if (document.implementation && document.implementation.createDocument) {
+    return document.implementation.createDocument(opt_namespaceUri || '',
+                                                  opt_rootTagName || '',
+                                                  null);
+  } else if (typeof ActiveXObject != 'undefined') {
+    var doc = goog.dom.xml.createMsXmlDocument_();
+    if (doc) {
+      if (opt_rootTagName) {
+        doc.appendChild(doc.createNode(goog.dom.NodeType.ELEMENT,
+                                       opt_rootTagName,
+                                       opt_namespaceUri || ''));
+      }
+      return doc;
+    }
+  }
+  throw Error('Your browser does not support creating new documents');
+};
+
+
+/**
+ * Creates an XML document from a string
+ * @param {string} xml The text.
+ * @return {Document} XML document from the text.
+ */
+goog.dom.xml.loadXml = function(xml) {
+  if (typeof DOMParser != 'undefined') {
+    return new DOMParser().parseFromString(xml, 'application/xml');
+  } else if (typeof ActiveXObject != 'undefined') {
+    var doc = goog.dom.xml.createMsXmlDocument_();
+    doc.loadXML(xml);
+    return doc;
+  }
+  throw Error('Your browser does not support loading xml documents');
+};
+
+
+/**
+ * Serializes an XML document or subtree to string.
+ * @param {Document|Element} xml The document or the root node of the subtree.
+ * @return {string} The serialized XML.
+ */
+goog.dom.xml.serialize = function(xml) {
+  // Compatible with Firefox, Opera and WebKit.
+  if (typeof XMLSerializer != 'undefined') {
+    return new XMLSerializer().serializeToString(xml);
+  }
+  // Compatible with Internet Explorer.
+  var text = xml.xml;
+  if (text) {
+    return text;
+  }
+  throw Error('Your browser does not support serializing XML documents');
+};
+
+
+/**
+ * Selects a single node using an Xpath expression and a root node
+ * @param {Node} node The root node.
+ * @param {string} path Xpath selector.
+ * @return {Node} The selected node, or null if no matching node.
+ */
+goog.dom.xml.selectSingleNode = function(node, path) {
+  if (typeof node.selectSingleNode != 'undefined') {
+    var doc = goog.dom.getOwnerDocument(node);
+    if (typeof doc.setProperty != 'undefined') {
+      doc.setProperty('SelectionLanguage', 'XPath');
+    }
+    return node.selectSingleNode(path);
+  } else if (document.implementation.hasFeature('XPath', '3.0')) {
+    var doc = goog.dom.getOwnerDocument(node);
+    var resolver = doc.createNSResolver(doc.documentElement);
+    var result = doc.evaluate(path, node, resolver,
+        XPathResult.FIRST_ORDERED_NODE_TYPE, null);
+    return result.singleNodeValue;
+  }
+  return null;
+};
+
+
+/**
+ * Selects multiple nodes using an Xpath expression and a root node
+ * @param {Node} node The root node.
+ * @param {string} path Xpath selector.
+ * @return {(NodeList|Array<Node>)} The selected nodes, or empty array if no
+ *     matching nodes.
+ */
+goog.dom.xml.selectNodes = function(node, path) {
+  if (typeof node.selectNodes != 'undefined') {
+    var doc = goog.dom.getOwnerDocument(node);
+    if (typeof doc.setProperty != 'undefined') {
+      doc.setProperty('SelectionLanguage', 'XPath');
+    }
+    return node.selectNodes(path);
+  } else if (document.implementation.hasFeature('XPath', '3.0')) {
+    var doc = goog.dom.getOwnerDocument(node);
+    var resolver = doc.createNSResolver(doc.documentElement);
+    var nodes = doc.evaluate(path, node, resolver,
+        XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+    var results = [];
+    var count = nodes.snapshotLength;
+    for (var i = 0; i < count; i++) {
+      results.push(nodes.snapshotItem(i));
+    }
+    return results;
+  } else {
+    return [];
+  }
+};
+
+
+/**
+ * Sets multiple attributes on an element. Differs from goog.dom.setProperties
+ * in that it exclusively uses the element's setAttributes method. Use this
+ * when you need to ensure that the exact property is available as an attribute
+ * and can be read later by the native getAttribute method.
+ * @param {!Element} element XML or DOM element to set attributes on.
+ * @param {!Object<string, string>} attributes Map of property:value pairs.
+ */
+goog.dom.xml.setAttributes = function(element, attributes) {
+  for (var key in attributes) {
+    if (attributes.hasOwnProperty(key)) {
+      element.setAttribute(key, attributes[key]);
+    }
+  }
+};
+
+
+/**
+ * Creates an instance of the MSXML2.DOMDocument.
+ * @return {Document} The new document.
+ * @private
+ */
+goog.dom.xml.createMsXmlDocument_ = function() {
+  var doc = new ActiveXObject('MSXML2.DOMDocument');
+  if (doc) {
+    // Prevent potential vulnerabilities exposed by MSXML2, see
+    // http://b/1707300 and http://wiki/Main/ISETeamXMLAttacks for details.
+    doc.resolveExternals = false;
+    doc.validateOnParse = false;
+    // Add a try catch block because accessing these properties will throw an
+    // error on unsupported MSXML versions. This affects Windows machines
+    // running IE6 or IE7 that are on XP SP2 or earlier without MSXML updates.
+    // See http://msdn.microsoft.com/en-us/library/ms766391(VS.85).aspx for
+    // specific details on which MSXML versions support these properties.
+    try {
+      doc.setProperty('ProhibitDTD', true);
+      doc.setProperty('MaxXMLSize', goog.dom.xml.MAX_XML_SIZE_KB);
+      doc.setProperty('MaxElementDepth', goog.dom.xml.MAX_ELEMENT_DEPTH);
+    } catch (e) {
+      // No-op.
+    }
+  }
+  return doc;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/editor/browserfeature2.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/editor/browserfeature2.js b/externs/GCL/externs/goog/editor/browserfeature2.js
new file mode 100644
index 0000000..10ac05e
--- /dev/null
+++ b/externs/GCL/externs/goog/editor/browserfeature2.js
@@ -0,0 +1,273 @@
+// Copyright 2005 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 Trogedit constants for browser features and quirks that should
+ * be used by the rich text editor.
+ */
+
+goog.provide('goog.editor.BrowserFeature');
+
+goog.require('goog.editor.defines');
+goog.require('goog.userAgent');
+goog.require('goog.userAgent.product');
+goog.require('goog.userAgent.product.isVersion');
+
+
+/**
+ * Maps browser quirks to boolean values, detailing what the current
+ * browser supports.
+ * @const
+ */
+goog.editor.BrowserFeature = {
+  // Whether this browser uses the IE TextRange object.
+  HAS_IE_RANGES: goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9),
+
+  // Whether this browser uses the W3C standard Range object.
+  // Assumes IE higher versions will be compliance with W3C standard.
+  HAS_W3C_RANGES: goog.userAgent.GECKO || goog.userAgent.WEBKIT ||
+      goog.userAgent.OPERA ||
+      (goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9)),
+
+  // Has the contentEditable attribute, which makes nodes editable.
+  //
+  // NOTE(nicksantos): FF3 has contentEditable, but there are 3 major reasons
+  // why we don't use it:
+  // 1) In FF3, we listen for key events on the document, and we'd have to
+  //    filter them properly. See TR_Browser.USE_DOCUMENT_FOR_KEY_EVENTS.
+  // 2) In FF3, we listen for focus/blur events on the document, which
+  //    simply doesn't make sense in contentEditable. focus/blur
+  //    on contentEditable elements still has some quirks, which we're
+  //    talking to Firefox-team about.
+  // 3) We currently use Mutation events in FF3 to detect changes,
+  //    and these are dispatched on the document only.
+  // If we ever hope to support FF3/contentEditable, all 3 of these issues
+  // will need answers. Most just involve refactoring at our end.
+  HAS_CONTENT_EDITABLE: goog.userAgent.IE || goog.userAgent.WEBKIT ||
+      goog.userAgent.OPERA ||
+      (goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 &&
+       goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9')),
+
+  // Whether to use mutation event types to detect changes
+  // in the field contents.
+  USE_MUTATION_EVENTS: goog.userAgent.GECKO,
+
+  // Whether the browser has a functional DOMSubtreeModified event.
+  // TODO(user): Enable for all FF3 once we're confident this event fires
+  // reliably. Currently it's only enabled if using contentEditable in FF as
+  // we have no other choice in that case but to use this event.
+  HAS_DOM_SUBTREE_MODIFIED_EVENT: goog.userAgent.WEBKIT ||
+      (goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3 &&
+       goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9')),
+
+  // Whether nodes can be copied from one document to another
+  HAS_DOCUMENT_INDEPENDENT_NODES: goog.userAgent.GECKO,
+
+  // Whether the cursor goes before or inside the first block element on
+  // focus, e.g., <body><p>foo</p></body>. FF will put the cursor before the
+  // paragraph on focus, which is wrong.
+  PUTS_CURSOR_BEFORE_FIRST_BLOCK_ELEMENT_ON_FOCUS: goog.userAgent.GECKO,
+
+  // Whether the selection of one frame is cleared when another frame
+  // is focused.
+  CLEARS_SELECTION_WHEN_FOCUS_LEAVES:
+      goog.userAgent.IE || goog.userAgent.WEBKIT || goog.userAgent.OPERA,
+
+  // Whether "unselectable" is supported as an element style.
+  HAS_UNSELECTABLE_STYLE: goog.userAgent.GECKO || goog.userAgent.WEBKIT,
+
+  // Whether this browser's "FormatBlock" command does not suck.
+  FORMAT_BLOCK_WORKS_FOR_BLOCKQUOTES: goog.userAgent.GECKO ||
+      goog.userAgent.WEBKIT || goog.userAgent.OPERA,
+
+  // Whether this browser's "FormatBlock" command may create multiple
+  // blockquotes.
+  CREATES_MULTIPLE_BLOCKQUOTES:
+      (goog.userAgent.WEBKIT &&
+       !goog.userAgent.isVersionOrHigher('534.16')) ||
+      goog.userAgent.OPERA,
+
+  // Whether this browser's "FormatBlock" command will wrap blockquotes
+  // inside of divs, instead of replacing divs with blockquotes.
+  WRAPS_BLOCKQUOTE_IN_DIVS: goog.userAgent.OPERA,
+
+  // Whether the readystatechange event is more reliable than load.
+  PREFERS_READY_STATE_CHANGE_EVENT: goog.userAgent.IE,
+
+  // Whether hitting the tab key will fire a keypress event.
+  // see http://www.quirksmode.org/js/keys.html
+  TAB_FIRES_KEYPRESS: !goog.userAgent.IE,
+
+  // Has a standards mode quirk where width=100% doesn't do the right thing,
+  // but width=99% does.
+  // TODO(user|user): This should be fixable by less hacky means
+  NEEDS_99_WIDTH_IN_STANDARDS_MODE: goog.userAgent.IE,
+
+  // Whether keyboard events only reliably fire on the document.
+  // On Gecko without contentEditable, keyboard events only fire reliably on the
+  // document element. With contentEditable, the field itself is focusable,
+  // which means that it will fire key events. This does not apply if
+  // application is using ContentEditableField or otherwise overriding Field
+  // not to use an iframe.
+  USE_DOCUMENT_FOR_KEY_EVENTS: goog.userAgent.GECKO &&
+      !goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3,
+
+  // Whether this browser shows non-standard attributes in innerHTML.
+  SHOWS_CUSTOM_ATTRS_IN_INNER_HTML: goog.userAgent.IE,
+
+  // Whether this browser shrinks empty nodes away to nothing.
+  // (If so, we need to insert some space characters into nodes that
+  //  shouldn't be collapsed)
+  COLLAPSES_EMPTY_NODES:
+      goog.userAgent.GECKO || goog.userAgent.WEBKIT || goog.userAgent.OPERA,
+
+  // Whether we must convert <strong> and <em> tags to <b>, <i>.
+  CONVERT_TO_B_AND_I_TAGS: goog.userAgent.GECKO || goog.userAgent.OPERA,
+
+  // Whether this browser likes to tab through images in contentEditable mode,
+  // and we like to disable this feature.
+  TABS_THROUGH_IMAGES: goog.userAgent.IE,
+
+  // Whether this browser unescapes urls when you extract it from the href tag.
+  UNESCAPES_URLS_WITHOUT_ASKING: goog.userAgent.IE &&
+      !goog.userAgent.isVersionOrHigher('7.0'),
+
+  // Whether this browser supports execCommand("styleWithCSS") to toggle between
+  // inserting html tags or inline styling for things like bold, italic, etc.
+  HAS_STYLE_WITH_CSS:
+      goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.8') ||
+      goog.userAgent.WEBKIT || goog.userAgent.OPERA,
+
+  // Whether clicking on an editable link will take you to that site.
+  FOLLOWS_EDITABLE_LINKS: goog.userAgent.WEBKIT ||
+      goog.userAgent.IE && goog.userAgent.isVersionOrHigher('9'),
+
+  // Whether this browser has document.activeElement available.
+  HAS_ACTIVE_ELEMENT:
+      goog.userAgent.IE || goog.userAgent.OPERA ||
+      goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9'),
+
+  // Whether this browser supports the setCapture method on DOM elements.
+  HAS_SET_CAPTURE: goog.userAgent.IE,
+
+  // Whether this browser can't set background color when the selection
+  // is collapsed.
+  EATS_EMPTY_BACKGROUND_COLOR: goog.userAgent.GECKO ||
+      goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('527'),
+
+  // Whether this browser supports the "focusin" or "DOMFocusIn" event
+  // consistently.
+  // NOTE(nicksantos): FF supports DOMFocusIn, but doesn't seem to do so
+  // consistently.
+  SUPPORTS_FOCUSIN: goog.userAgent.IE || goog.userAgent.OPERA,
+
+  // Whether clicking on an image will cause the selection to move to the image.
+  // Note: Gecko moves the selection, but it won't always go to the image.
+  // For example, if the image is wrapped in a div, and you click on the img,
+  // anchorNode = focusNode = div, anchorOffset = 0, focusOffset = 1, so this
+  // is another way of "selecting" the image, but there are too many special
+  // cases like this so we will do the work manually.
+  SELECTS_IMAGES_ON_CLICK: goog.userAgent.IE || goog.userAgent.OPERA,
+
+  // Whether this browser moves <style> tags into new <head> elements.
+  MOVES_STYLE_TO_HEAD: goog.userAgent.WEBKIT,
+
+  // Whether this browser collapses the selection in a contenteditable when the
+  // mouse is pressed in a non-editable portion of the same frame, even if
+  // Event.preventDefault is called. This field is deprecated and unused -- only
+  // old versions of Opera have this bug.
+  COLLAPSES_SELECTION_ONMOUSEDOWN: false,
+
+  // Whether the user can actually create a selection in this browser with the
+  // caret in the MIDDLE of the selection by double-clicking.
+  CARET_INSIDE_SELECTION: goog.userAgent.OPERA,
+
+  // Whether the browser focuses <body contenteditable> automatically when
+  // the user clicks on <html>. This field is deprecated and unused -- only old
+  // versions of Opera don't have this behavior.
+  FOCUSES_EDITABLE_BODY_ON_HTML_CLICK: true,
+
+  // Whether to use keydown for key listening (uses keypress otherwise). Taken
+  // from goog.events.KeyHandler.
+  USES_KEYDOWN: goog.userAgent.IE ||
+      goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'),
+
+  // Whether this browser converts spaces to non-breaking spaces when calling
+  // execCommand's RemoveFormat.
+  // See: https://bugs.webkit.org/show_bug.cgi?id=14062
+  ADDS_NBSPS_IN_REMOVE_FORMAT:
+      goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('531'),
+
+  // Whether the browser will get stuck inside a link.  That is, if your cursor
+  // is after a link and you type, does your text go inside the link tag.
+  // Bug: http://bugs.webkit.org/show_bug.cgi?id=17697
+  GETS_STUCK_IN_LINKS:
+      goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('528'),
+
+  // Whether the browser corrupts empty text nodes in Node#normalize,
+  // removing them from the Document instead of merging them.
+  NORMALIZE_CORRUPTS_EMPTY_TEXT_NODES: goog.userAgent.GECKO &&
+      goog.userAgent.isVersionOrHigher('1.9') || goog.userAgent.IE ||
+      goog.userAgent.OPERA ||
+      goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('531'),
+
+  // Whether the browser corrupts all text nodes in Node#normalize,
+  // removing them from the Document instead of merging them.
+  NORMALIZE_CORRUPTS_ALL_TEXT_NODES: goog.userAgent.IE,
+
+  // Browsers where executing subscript then superscript (or vv) will cause both
+  // to be applied in a nested fashion instead of the first being overwritten by
+  // the second.
+  NESTS_SUBSCRIPT_SUPERSCRIPT: goog.userAgent.IE || goog.userAgent.GECKO ||
+      goog.userAgent.OPERA,
+
+  // Whether this browser can place a cursor in an empty element natively.
+  CAN_SELECT_EMPTY_ELEMENT: !goog.userAgent.IE && !goog.userAgent.WEBKIT,
+
+  FORGETS_FORMATTING_WHEN_LISTIFYING: goog.userAgent.GECKO ||
+      goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('526'),
+
+  LEAVES_P_WHEN_REMOVING_LISTS: goog.userAgent.IE || goog.userAgent.OPERA,
+
+  CAN_LISTIFY_BR: !goog.userAgent.IE && !goog.userAgent.OPERA,
+
+  // See bug 1286408. When somewhere inside your selection there is an element
+  // with a style attribute that sets the font size, if you change the font
+  // size, the browser creates a font tag, but the font size in the style attr
+  // overrides the font tag. Only webkit removes that font size from the style
+  // attr.
+  DOESNT_OVERRIDE_FONT_SIZE_IN_STYLE_ATTR: !goog.userAgent.WEBKIT,
+
+  // Implements this spec about dragging files from the filesystem to the
+  // browser: http://www.whatwg/org/specs/web-apps/current-work/#dnd
+  SUPPORTS_HTML5_FILE_DRAGGING: (goog.userAgent.product.CHROME &&
+                                 goog.userAgent.product.isVersion('4')) ||
+      (goog.userAgent.product.SAFARI &&
+       goog.userAgent.isVersionOrHigher('533')) ||
+      (goog.userAgent.GECKO &&
+       goog.userAgent.isVersionOrHigher('2.0')) ||
+      (goog.userAgent.IE &&
+       goog.userAgent.isVersionOrHigher('10')),
+
+  // Version of Opera that supports the opera-defaultBlock execCommand to change
+  // the default block inserted when [return] is pressed. Note that this only is
+  // used if the caret is not already in a block that can be repeated.
+  // TODO(user): Link to public documentation of this feature if Opera puts
+  // something up about it.
+  SUPPORTS_OPERA_DEFAULTBLOCK_COMMAND:
+      goog.userAgent.OPERA && goog.userAgent.isVersionOrHigher('11.10'),
+
+  SUPPORTS_FILE_PASTING: goog.userAgent.product.CHROME &&
+      goog.userAgent.product.isVersion('12')
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/editor/clicktoeditwrapper.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/editor/clicktoeditwrapper.js b/externs/GCL/externs/goog/editor/clicktoeditwrapper.js
new file mode 100644
index 0000000..1623f0d
--- /dev/null
+++ b/externs/GCL/externs/goog/editor/clicktoeditwrapper.js
@@ -0,0 +1,423 @@
+// 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 wrapper around a goog.editor.Field
+ * that listens to mouse events on the specified un-editable field, and makes
+ * the field editable if the user clicks on it. Clients are still responsible
+ * for determining when to make the field un-editable again.
+ *
+ * Clients can still determine when the field has loaded by listening to
+ * field's load event.
+ *
+ * @author nicksantos@google.com (Nick Santos)
+ */
+
+goog.provide('goog.editor.ClickToEditWrapper');
+
+goog.require('goog.Disposable');
+goog.require('goog.dom');
+goog.require('goog.dom.Range');
+goog.require('goog.dom.TagName');
+goog.require('goog.editor.BrowserFeature');
+goog.require('goog.editor.Command');
+goog.require('goog.editor.Field');
+goog.require('goog.editor.range');
+goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventHandler');
+goog.require('goog.events.EventType');
+
+
+
+/**
+ * Initialize the wrapper, and begin listening to mouse events immediately.
+ * @param {goog.editor.Field} fieldObj The editable field being wrapped.
+ * @constructor
+ * @extends {goog.Disposable}
+ */
+goog.editor.ClickToEditWrapper = function(fieldObj) {
+  goog.Disposable.call(this);
+
+  /**
+   * The field this wrapper interacts with.
+   * @type {goog.editor.Field}
+   * @private
+   */
+  this.fieldObj_ = fieldObj;
+
+  /**
+   * DOM helper for the field's original element.
+   * @type {goog.dom.DomHelper}
+   * @private
+   */
+  this.originalDomHelper_ = goog.dom.getDomHelper(
+      fieldObj.getOriginalElement());
+
+  /**
+   * @type {goog.dom.SavedCaretRange}
+   * @private
+   */
+  this.savedCaretRange_ = null;
+
+  /**
+   * Event handler for field related events.
+   * @type {!goog.events.EventHandler<!goog.editor.ClickToEditWrapper>}
+   * @private
+   */
+  this.fieldEventHandler_ = new goog.events.EventHandler(this);
+
+  /**
+   * Bound version of the finishMouseUp method.
+   * @type {Function}
+   * @private
+   */
+  this.finishMouseUpBound_ = goog.bind(this.finishMouseUp_, this);
+
+  /**
+   * Event handler for mouse events.
+   * @type {!goog.events.EventHandler<!goog.editor.ClickToEditWrapper>}
+   * @private
+   */
+  this.mouseEventHandler_ = new goog.events.EventHandler(this);
+
+  // Start listening to mouse events immediately if necessary.
+  if (!this.fieldObj_.isLoaded()) {
+    this.enterDocument();
+  }
+
+  this.fieldEventHandler_.
+      // Whenever the field is made editable, we need to check if there
+      // are any carets in it, and if so, use them to render the selection.
+      listen(
+          this.fieldObj_, goog.editor.Field.EventType.LOAD,
+          this.renderSelection_).
+      // Whenever the field is made uneditable, we need to set up
+      // the click-to-edit listeners.
+      listen(
+          this.fieldObj_, goog.editor.Field.EventType.UNLOAD,
+          this.enterDocument);
+};
+goog.inherits(goog.editor.ClickToEditWrapper, goog.Disposable);
+
+
+
+/** @return {goog.editor.Field} The field. */
+goog.editor.ClickToEditWrapper.prototype.getFieldObject = function() {
+  return this.fieldObj_;
+};
+
+
+/** @return {goog.dom.DomHelper} The dom helper of the uneditable element. */
+goog.editor.ClickToEditWrapper.prototype.getOriginalDomHelper = function() {
+  return this.originalDomHelper_;
+};
+
+
+/** @override */
+goog.editor.ClickToEditWrapper.prototype.disposeInternal = function() {
+  goog.editor.ClickToEditWrapper.base(this, 'disposeInternal');
+  this.exitDocument();
+
+  if (this.savedCaretRange_) {
+    this.savedCaretRange_.dispose();
+  }
+
+  this.fieldEventHandler_.dispose();
+  this.mouseEventHandler_.dispose();
+  this.savedCaretRange_ = null;
+  delete this.fieldEventHandler_;
+  delete this.mouseEventHandler_;
+};
+
+
+/**
+ * Initialize listeners when the uneditable field is added to the document.
+ * Also sets up lorem ipsum text.
+ */
+goog.editor.ClickToEditWrapper.prototype.enterDocument = function() {
+  if (this.isInDocument_) {
+    return;
+  }
+
+  this.isInDocument_ = true;
+
+  this.mouseEventTriggeredLoad_ = false;
+  var field = this.fieldObj_.getOriginalElement();
+
+  // To do artificial selection preservation, we have to listen to mouseup,
+  // get the current selection, and re-select the same text in the iframe.
+  //
+  // NOTE(nicksantos): Artificial selection preservation is needed in all cases
+  // where we set the field contents by setting innerHTML. There are a few
+  // rare cases where we don't need it. But these cases are highly
+  // implementation-specific, and computationally hard to detect (bidi
+  // and ig modules both set innerHTML), so we just do it in all cases.
+  this.savedAnchorClicked_ = null;
+  this.mouseEventHandler_.
+      listen(field, goog.events.EventType.MOUSEUP, this.handleMouseUp_).
+      listen(field, goog.events.EventType.CLICK, this.handleClick_);
+
+  // manage lorem ipsum text, if necessary
+  this.fieldObj_.execCommand(goog.editor.Command.UPDATE_LOREM);
+};
+
+
+/**
+ * Destroy listeners when the field is removed from the document.
+ */
+goog.editor.ClickToEditWrapper.prototype.exitDocument = function() {
+  this.mouseEventHandler_.removeAll();
+  this.isInDocument_ = false;
+};
+
+
+/**
+ * Returns the uneditable field element if the field is not yet editable
+ * (equivalent to EditableField.getOriginalElement()), and the editable DOM
+ * element if the field is currently editable (equivalent to
+ * EditableField.getElement()).
+ * @return {Element} The element containing the editable field contents.
+ */
+goog.editor.ClickToEditWrapper.prototype.getElement = function() {
+  return this.fieldObj_.isLoaded() ?
+      this.fieldObj_.getElement() : this.fieldObj_.getOriginalElement();
+};
+
+
+/**
+ * True if a mouse event should be handled, false if it should be ignored.
+ * @param {goog.events.BrowserEvent} e The mouse event.
+ * @return {boolean} Wether or not this mouse event should be handled.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.shouldHandleMouseEvent_ = function(e) {
+  return e.isButton(goog.events.BrowserEvent.MouseButton.LEFT) &&
+      !(e.shiftKey || e.ctrlKey || e.altKey || e.metaKey);
+};
+
+
+/**
+ * Handle mouse click events on the field.
+ * @param {goog.events.BrowserEvent} e The click event.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.handleClick_ = function(e) {
+  // If the user clicked on a link in an uneditable field,
+  // we want to cancel the click.
+  var anchorAncestor = goog.dom.getAncestorByTagNameAndClass(
+      /** @type {Node} */ (e.target),
+      goog.dom.TagName.A);
+  if (anchorAncestor) {
+    e.preventDefault();
+
+    if (!goog.editor.BrowserFeature.HAS_ACTIVE_ELEMENT) {
+      this.savedAnchorClicked_ = anchorAncestor;
+    }
+  }
+};
+
+
+/**
+ * Handle a mouse up event on the field.
+ * @param {goog.events.BrowserEvent} e The mouseup event.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.handleMouseUp_ = function(e) {
+  // Only respond to the left mouse button.
+  if (this.shouldHandleMouseEvent_(e)) {
+    // We need to get the selection when the user mouses up, but the
+    // selection doesn't actually change until after the mouseup event has
+    // propagated. So we need to do this asynchronously.
+    this.originalDomHelper_.getWindow().setTimeout(this.finishMouseUpBound_, 0);
+  }
+};
+
+
+/**
+ * A helper function for handleMouseUp_ -- does the actual work
+ * when the event is finished propagating.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.finishMouseUp_ = function() {
+  // Make sure that the field is still not editable.
+  if (!this.fieldObj_.isLoaded()) {
+    if (this.savedCaretRange_) {
+      this.savedCaretRange_.dispose();
+      this.savedCaretRange_ = null;
+    }
+
+    if (!this.fieldObj_.queryCommandValue(goog.editor.Command.USING_LOREM)) {
+      // We need carets (blank span nodes) to maintain the selection when
+      // the html is copied into an iframe. However, because our code
+      // clears the selection to make the behavior consistent, we need to do
+      // this even when we're not using an iframe.
+      this.insertCarets_();
+    }
+
+    this.ensureFieldEditable_();
+  }
+
+  this.exitDocument();
+  this.savedAnchorClicked_ = null;
+};
+
+
+/**
+ * Ensure that the field is editable. If the field is not editable,
+ * make it so, and record the fact that it was done by a user mouse event.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.ensureFieldEditable_ = function() {
+  if (!this.fieldObj_.isLoaded()) {
+    this.mouseEventTriggeredLoad_ = true;
+    this.makeFieldEditable(this.fieldObj_);
+  }
+};
+
+
+/**
+ * Once the field has loaded in an iframe, re-create the selection
+ * as marked by the carets.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.renderSelection_ = function() {
+  if (this.savedCaretRange_) {
+    // Make sure that the restoration document is inside the iframe
+    // if we're using one.
+    this.savedCaretRange_.setRestorationDocument(
+        this.fieldObj_.getEditableDomHelper().getDocument());
+
+    var startCaret = this.savedCaretRange_.getCaret(true);
+    var endCaret = this.savedCaretRange_.getCaret(false);
+    var hasCarets = startCaret && endCaret;
+  }
+
+  // There are two reasons why we might want to focus the field:
+  // 1) makeFieldEditable was triggered by the click-to-edit wrapper.
+  //    In this case, the mouse event should have triggered a focus, but
+  //    the editor might have taken the focus away to create lorem ipsum
+  //    text or create an iframe for the field. So we make sure the focus
+  //    is restored.
+  // 2) somebody placed carets, and we need to select those carets. The field
+  //    needs focus to ensure that the selection appears.
+  if (this.mouseEventTriggeredLoad_ || hasCarets) {
+    this.focusOnFieldObj(this.fieldObj_);
+  }
+
+  if (hasCarets) {
+
+    this.savedCaretRange_.restore();
+    this.fieldObj_.dispatchSelectionChangeEvent();
+
+    // NOTE(nicksantos): Bubbles aren't actually enabled until the end
+    // if the load sequence, so if the user clicked on a link, the bubble
+    // will not pop up.
+  }
+
+  if (this.savedCaretRange_) {
+    this.savedCaretRange_.dispose();
+    this.savedCaretRange_ = null;
+  }
+
+  this.mouseEventTriggeredLoad_ = false;
+};
+
+
+/**
+ * Focus on the field object.
+ * @param {goog.editor.Field} field The field to focus.
+ * @protected
+ */
+goog.editor.ClickToEditWrapper.prototype.focusOnFieldObj = function(field) {
+  field.focusAndPlaceCursorAtStart();
+};
+
+
+/**
+ * Make the field object editable.
+ * @param {goog.editor.Field} field The field to make editable.
+ * @protected
+ */
+goog.editor.ClickToEditWrapper.prototype.makeFieldEditable = function(field) {
+  field.makeEditable();
+};
+
+
+//================================================================
+// Caret-handling methods
+
+
+/**
+ * Gets a saved caret range for the given range.
+ * @param {goog.dom.AbstractRange} range A range wrapper.
+ * @return {goog.dom.SavedCaretRange} The range, saved with carets, or null
+ *    if the range wrapper was null.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.createCaretRange_ = function(range) {
+  return range && goog.editor.range.saveUsingNormalizedCarets(range);
+};
+
+
+/**
+ * Inserts the carets, given the current selection.
+ *
+ * Note that for all practical purposes, a cursor position is just
+ * a selection with the start and end at the same point.
+ * @private
+ */
+goog.editor.ClickToEditWrapper.prototype.insertCarets_ = function() {
+  var fieldElement = this.fieldObj_.getOriginalElement();
+
+  this.savedCaretRange_ = null;
+  var originalWindow = this.originalDomHelper_.getWindow();
+  if (goog.dom.Range.hasSelection(originalWindow)) {
+    var range = goog.dom.Range.createFromWindow(originalWindow);
+    range = range && goog.editor.range.narrow(range, fieldElement);
+    this.savedCaretRange_ =
+        goog.editor.ClickToEditWrapper.createCaretRange_(range);
+  }
+
+  if (!this.savedCaretRange_) {
+    // We couldn't figure out where to put the carets.
+    // But in FF2/IE6+, this could mean that the user clicked on a
+    // 'special' node, (e.g., a link or an unselectable item). So the
+    // selection appears to be null or the full page, even though the user did
+    // click on something. In IE, we can determine the real selection via
+    // document.activeElement. In FF, we have to be more hacky.
+    var specialNodeClicked;
+    if (goog.editor.BrowserFeature.HAS_ACTIVE_ELEMENT) {
+      specialNodeClicked = goog.dom.getActiveElement(
+          this.originalDomHelper_.getDocument());
+    } else {
+      specialNodeClicked = this.savedAnchorClicked_;
+    }
+
+    var isFieldElement = function(node) {
+      return node == fieldElement;
+    };
+    if (specialNodeClicked &&
+        goog.dom.getAncestor(specialNodeClicked, isFieldElement, true)) {
+      // Insert the cursor at the beginning of the active element to be
+      // consistent with the behavior in FF1.5, where clicking on a
+      // link makes the current selection equal to the cursor position
+      // directly before that link.
+      //
+      // TODO(nicksantos): Is there a way to more accurately place the cursor?
+      this.savedCaretRange_ = goog.editor.ClickToEditWrapper.createCaretRange_(
+          goog.dom.Range.createFromNodes(
+              specialNodeClicked, 0, specialNodeClicked, 0));
+    }
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/editor/command.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/editor/command.js b/externs/GCL/externs/goog/editor/command.js
new file mode 100644
index 0000000..2996b8c
--- /dev/null
+++ b/externs/GCL/externs/goog/editor/command.js
@@ -0,0 +1,76 @@
+// Copyright 2009 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 Commands that the editor can execute.
+ * @see ../demos/editor/editor.html
+ */
+goog.provide('goog.editor.Command');
+
+
+/**
+ * Commands that the editor can excute via execCommand or queryCommandValue.
+ * @enum {string}
+ */
+goog.editor.Command = {
+  // Prepend all the strings of built in execCommands with a plus to ensure
+  // that there's no conflict if a client wants to use the
+  // browser's execCommand.
+  UNDO: '+undo',
+  REDO: '+redo',
+  LINK: '+link',
+  FORMAT_BLOCK: '+formatBlock',
+  INDENT: '+indent',
+  OUTDENT: '+outdent',
+  REMOVE_FORMAT: '+removeFormat',
+  STRIKE_THROUGH: '+strikeThrough',
+  HORIZONTAL_RULE: '+insertHorizontalRule',
+  SUBSCRIPT: '+subscript',
+  SUPERSCRIPT: '+superscript',
+  UNDERLINE: '+underline',
+  BOLD: '+bold',
+  ITALIC: '+italic',
+  FONT_SIZE: '+fontSize',
+  FONT_FACE: '+fontName',
+  FONT_COLOR: '+foreColor',
+  EMOTICON: '+emoticon',
+  EQUATION: '+equation',
+  BACKGROUND_COLOR: '+backColor',
+  ORDERED_LIST: '+insertOrderedList',
+  UNORDERED_LIST: '+insertUnorderedList',
+  TABLE: '+table',
+  JUSTIFY_CENTER: '+justifyCenter',
+  JUSTIFY_FULL: '+justifyFull',
+  JUSTIFY_RIGHT: '+justifyRight',
+  JUSTIFY_LEFT: '+justifyLeft',
+  BLOCKQUOTE: '+BLOCKQUOTE', // This is a nodename. Should be all caps.
+  DIR_LTR: 'ltr', // should be exactly 'ltr' as it becomes dir attribute value
+  DIR_RTL: 'rtl', // same here
+  IMAGE: 'image',
+  EDIT_HTML: 'editHtml',
+  UPDATE_LINK_BUBBLE: 'updateLinkBubble',
+
+  // queryCommandValue only: returns the default tag name used in the field.
+  // DIV should be considered the default if no plugin responds.
+  DEFAULT_TAG: '+defaultTag',
+
+  // TODO(nicksantos): Try to give clients an API so that they don't need
+  // these execCommands.
+  CLEAR_LOREM: 'clearlorem',
+  UPDATE_LOREM: 'updatelorem',
+  USING_LOREM: 'usinglorem',
+
+  // Modal editor commands (usually dialogs).
+  MODAL_LINK_EDITOR: 'link'
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/editor/contenteditablefield.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/editor/contenteditablefield.js b/externs/GCL/externs/goog/editor/contenteditablefield.js
new file mode 100644
index 0000000..a30d245
--- /dev/null
+++ b/externs/GCL/externs/goog/editor/contenteditablefield.js
@@ -0,0 +1,108 @@
+// Copyright 2012 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 Class to encapsulate an editable field that blends into the
+ * style of the page and never uses an iframe.  The field's height can be
+ * controlled by CSS styles like min-height, max-height, and overflow.  This is
+ * a goog.editor.Field, but overrides everything iframe related to use
+ * contentEditable divs.  This is essentially a much lighter alternative to
+ * goog.editor.SeamlessField, but only works in Firefox 3+, and only works
+ * *well* in Firefox 12+ due to
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=669026.
+ *
+ * @author gboyer@google.com (Garrett Boyer)
+ * @author nicksantos@google.com (Nick Santos)
+ */
+
+
+goog.provide('goog.editor.ContentEditableField');
+
+goog.require('goog.asserts');
+goog.require('goog.editor.Field');
+goog.require('goog.log');
+
+
+
+/**
+ * This class encapsulates an editable field that is just a contentEditable
+ * div.
+ *
+ * To see events fired by this object, please see the base class.
+ *
+ * @param {string} id An identifer for the field. This is used to find the
+ *     field and the element associated with this field.
+ * @param {Document=} opt_doc The document that the element with the given
+ *     id can be found in.
+ * @constructor
+ * @extends {goog.editor.Field}
+ */
+goog.editor.ContentEditableField = function(id, opt_doc) {
+  goog.editor.Field.call(this, id, opt_doc);
+};
+goog.inherits(goog.editor.ContentEditableField, goog.editor.Field);
+
+
+/**
+ * @override
+ */
+goog.editor.ContentEditableField.prototype.logger =
+    goog.log.getLogger('goog.editor.ContentEditableField');
+
+
+/** @override */
+goog.editor.ContentEditableField.prototype.usesIframe = function() {
+  // Never uses an iframe in any browser.
+  return false;
+};
+
+
+// Overridden to improve dead code elimination only.
+/** @override */
+goog.editor.ContentEditableField.prototype.turnOnDesignModeGecko =
+    goog.nullFunction;
+
+
+/** @override */
+goog.editor.ContentEditableField.prototype.installStyles = function() {
+  goog.asserts.assert(!this.cssStyles, 'ContentEditableField does not support' +
+      ' CSS styles; instead just write plain old CSS on the main page.');
+};
+
+
+/** @override */
+goog.editor.ContentEditableField.prototype.makeEditableInternal = function(
+    opt_iframeSrc) {
+  var field = this.getOriginalElement();
+  if (field) {
+    this.setupFieldObject(field);
+    // TODO(gboyer): Allow clients/plugins to override with 'plaintext-only'
+    // for WebKit.
+    field.contentEditable = true;
+
+    this.injectContents(field.innerHTML, field);
+
+    this.handleFieldLoad();
+  }
+};
+
+
+/**
+ * @override
+ *
+ * ContentEditableField does not make any changes to the DOM when it is made
+ * editable other than setting contentEditable to true.
+ */
+goog.editor.ContentEditableField.prototype.restoreDom =
+    goog.nullFunction;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/editor/defines.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/editor/defines.js b/externs/GCL/externs/goog/editor/defines.js
new file mode 100644
index 0000000..1bf57ba
--- /dev/null
+++ b/externs/GCL/externs/goog/editor/defines.js
@@ -0,0 +1,34 @@
+// 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 Text editor constants for compile time feature selection.
+ *
+ */
+
+goog.provide('goog.editor.defines');
+
+
+/**
+ * @define {boolean} Use contentEditable in FF.
+ * There are a number of known bugs when the only content in your field is
+ * inline (e.g. just text, no block elements):
+ * -indent is a noop and then DOMSubtreeModified events stop firing until
+ *    the structure of the DOM is changed (e.g. make something bold).
+ * -inserting lists inserts just a NBSP, no list!
+ * Once those two are fixed, we should have one client guinea pig it and put
+ * it through a QA run. If we can file the bugs with Mozilla, there's a chance
+ * they'll fix them for a dot release of Firefox 3.
+ */
+goog.define('goog.editor.defines.USE_CONTENTEDITABLE_IN_FIREFOX_3', false);