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

[29/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/fontsizemonitor.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/fontsizemonitor.js b/externs/GCL/externs/goog/dom/fontsizemonitor.js
new file mode 100644
index 0000000..6c7c8b4
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/fontsizemonitor.js
@@ -0,0 +1,162 @@
+// 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 A class that can be used to listen to font size changes.
+ * @author arv@google.com (Erik Arvidsson)
+ */
+
+goog.provide('goog.dom.FontSizeMonitor');
+goog.provide('goog.dom.FontSizeMonitor.EventType');
+
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.events');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
+goog.require('goog.userAgent');
+
+
+// TODO(arv): Move this to goog.events instead.
+
+
+
+/**
+ * This class can be used to monitor changes in font size.  Instances will
+ * dispatch a {@code goog.dom.FontSizeMonitor.EventType.CHANGE} event.
+ * Example usage:
+ * <pre>
+ * var fms = new goog.dom.FontSizeMonitor();
+ * goog.events.listen(fms, goog.dom.FontSizeMonitor.EventType.CHANGE,
+ *     function(e) {
+ *       alert('Font size was changed');
+ *     });
+ * </pre>
+ * @param {goog.dom.DomHelper=} opt_domHelper DOM helper object that is used to
+ *     determine where to insert the DOM nodes used to determine when the font
+ *     size changes.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ * @final
+ */
+goog.dom.FontSizeMonitor = function(opt_domHelper) {
+  goog.events.EventTarget.call(this);
+
+  var dom = opt_domHelper || goog.dom.getDomHelper();
+
+  /**
+   * Offscreen iframe which we use to detect resize events.
+   * @type {Element}
+   * @private
+   */
+  this.sizeElement_ = dom.createDom(
+      // The size of the iframe is expressed in em, which are font size relative
+      // which will cause the iframe to be resized when the font size changes.
+      // The actual values are not relevant as long as we can ensure that the
+      // iframe has a non zero size and is completely off screen.
+      goog.userAgent.IE ? goog.dom.TagName.DIV : goog.dom.TagName.IFRAME, {
+        'style': 'position:absolute;width:9em;height:9em;top:-99em',
+        'tabIndex': -1,
+        'aria-hidden': 'true'
+      });
+  var p = dom.getDocument().body;
+  p.insertBefore(this.sizeElement_, p.firstChild);
+
+  /**
+   * The object that we listen to resize events on.
+   * @type {Element|Window}
+   * @private
+   */
+  var resizeTarget = this.resizeTarget_ =
+      goog.userAgent.IE ? this.sizeElement_ :
+          goog.dom.getFrameContentWindow(
+              /** @type {HTMLIFrameElement} */ (this.sizeElement_));
+
+  // We need to open and close the document to get Firefox 2 to work.  We must
+  // not do this for IE in case we are using HTTPS since accessing the document
+  // on an about:blank iframe in IE using HTTPS raises a Permission Denied
+  // error.
+  if (goog.userAgent.GECKO) {
+    var doc = resizeTarget.document;
+    doc.open();
+    doc.close();
+  }
+
+  // Listen to resize event on the window inside the iframe.
+  goog.events.listen(resizeTarget, goog.events.EventType.RESIZE,
+                     this.handleResize_, false, this);
+
+  /**
+   * Last measured width of the iframe element.
+   * @type {number}
+   * @private
+   */
+  this.lastWidth_ = this.sizeElement_.offsetWidth;
+};
+goog.inherits(goog.dom.FontSizeMonitor, goog.events.EventTarget);
+
+
+/**
+ * The event types that the FontSizeMonitor fires.
+ * @enum {string}
+ */
+goog.dom.FontSizeMonitor.EventType = {
+  // TODO(arv): Change value to 'change' after updating the callers.
+  CHANGE: 'fontsizechange'
+};
+
+
+/**
+ * Constant for the change event.
+ * @type {string}
+ * @deprecated Use {@code goog.dom.FontSizeMonitor.EventType.CHANGE} instead.
+ */
+goog.dom.FontSizeMonitor.CHANGE_EVENT =
+    goog.dom.FontSizeMonitor.EventType.CHANGE;
+
+
+/** @override */
+goog.dom.FontSizeMonitor.prototype.disposeInternal = function() {
+  goog.dom.FontSizeMonitor.superClass_.disposeInternal.call(this);
+
+  goog.events.unlisten(this.resizeTarget_, goog.events.EventType.RESIZE,
+                       this.handleResize_, false, this);
+  this.resizeTarget_ = null;
+
+  // Firefox 2 crashes if the iframe is removed during the unload phase.
+  if (!goog.userAgent.GECKO ||
+      goog.userAgent.isVersionOrHigher('1.9')) {
+    goog.dom.removeNode(this.sizeElement_);
+  }
+  delete this.sizeElement_;
+};
+
+
+/**
+ * Handles the onresize event of the iframe and dispatches a change event in
+ * case its size really changed.
+ * @param {goog.events.BrowserEvent} e The event object.
+ * @private
+ */
+goog.dom.FontSizeMonitor.prototype.handleResize_ = function(e) {
+  // Only dispatch the event if the size really changed.  Some newer browsers do
+  // not really change the font-size,  instead they zoom the whole page.  This
+  // does trigger window resize events on the iframe but the logical pixel size
+  // remains the same (the device pixel size changes but that is irrelevant).
+  var currentWidth = this.sizeElement_.offsetWidth;
+  if (this.lastWidth_ != currentWidth) {
+    this.lastWidth_ = currentWidth;
+    this.dispatchEvent(goog.dom.FontSizeMonitor.EventType.CHANGE);
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/forms.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/forms.js b/externs/GCL/externs/goog/dom/forms.js
new file mode 100644
index 0000000..75dc2e5
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/forms.js
@@ -0,0 +1,417 @@
+// 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 manipulating a form and elements.
+ *
+ * @author arv@google.com (Erik Arvidsson)
+ */
+
+goog.provide('goog.dom.forms');
+
+goog.require('goog.dom.InputType');
+goog.require('goog.dom.TagName');
+goog.require('goog.structs.Map');
+
+
+/**
+ * Returns form data as a map of name to value arrays. This doesn't
+ * support file inputs.
+ * @param {HTMLFormElement} form The form.
+ * @return {!goog.structs.Map.<string, !Array.<string>>} A map of the form data
+ *     as field name to arrays of values.
+ */
+goog.dom.forms.getFormDataMap = function(form) {
+  var map = new goog.structs.Map();
+  goog.dom.forms.getFormDataHelper_(form, map,
+      goog.dom.forms.addFormDataToMap_);
+  return map;
+};
+
+
+/**
+ * Returns the form data as an application/x-www-url-encoded string. This
+ * doesn't support file inputs.
+ * @param {HTMLFormElement} form The form.
+ * @return {string} An application/x-www-url-encoded string.
+ */
+goog.dom.forms.getFormDataString = function(form) {
+  var sb = [];
+  goog.dom.forms.getFormDataHelper_(form, sb,
+      goog.dom.forms.addFormDataToStringBuffer_);
+  return sb.join('&');
+};
+
+
+/**
+ * Returns the form data as a map or an application/x-www-url-encoded
+ * string. This doesn't support file inputs.
+ * @param {HTMLFormElement} form The form.
+ * @param {Object} result The object form data is being put in.
+ * @param {Function} fnAppend Function that takes {@code result}, an element
+ *     name, and an element value, and adds the name/value pair to the result
+ *     object.
+ * @private
+ */
+goog.dom.forms.getFormDataHelper_ = function(form, result, fnAppend) {
+  var els = form.elements;
+  for (var el, i = 0; el = els[i]; i++) {
+    if (// Make sure we don't include elements that are not part of the form.
+        // Some browsers include non-form elements. Check for 'form' property.
+        // See http://code.google.com/p/closure-library/issues/detail?id=227
+        // and
+        // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#the-input-element
+        (el.form != form) ||
+        el.disabled ||
+        // HTMLFieldSetElement has a form property but no value.
+        el.tagName == goog.dom.TagName.FIELDSET) {
+      continue;
+    }
+
+    var name = el.name;
+    switch (el.type.toLowerCase()) {
+      case goog.dom.InputType.FILE:
+        // file inputs are not supported
+      case goog.dom.InputType.SUBMIT:
+      case goog.dom.InputType.RESET:
+      case goog.dom.InputType.BUTTON:
+        // don't submit these
+        break;
+      case goog.dom.InputType.SELECT_MULTIPLE:
+        var values = goog.dom.forms.getValue(el);
+        if (values != null) {
+          for (var value, j = 0; value = values[j]; j++) {
+            fnAppend(result, name, value);
+          }
+        }
+        break;
+      default:
+        var value = goog.dom.forms.getValue(el);
+        if (value != null) {
+          fnAppend(result, name, value);
+        }
+    }
+  }
+
+  // input[type=image] are not included in the elements collection
+  var inputs = form.getElementsByTagName(goog.dom.TagName.INPUT);
+  for (var input, i = 0; input = inputs[i]; i++) {
+    if (input.form == form &&
+        input.type.toLowerCase() == goog.dom.InputType.IMAGE) {
+      name = input.name;
+      fnAppend(result, name, input.value);
+      fnAppend(result, name + '.x', '0');
+      fnAppend(result, name + '.y', '0');
+    }
+  }
+};
+
+
+/**
+ * Adds the name/value pair to the map.
+ * @param {!goog.structs.Map.<string, !Array.<string>>} map The map to add to.
+ * @param {string} name The name.
+ * @param {string} value The value.
+ * @private
+ */
+goog.dom.forms.addFormDataToMap_ = function(map, name, value) {
+  var array = map.get(name);
+  if (!array) {
+    array = [];
+    map.set(name, array);
+  }
+  array.push(value);
+};
+
+
+/**
+ * Adds a name/value pair to an string buffer array in the form 'name=value'.
+ * @param {Array<string>} sb The string buffer array for storing data.
+ * @param {string} name The name.
+ * @param {string} value The value.
+ * @private
+ */
+goog.dom.forms.addFormDataToStringBuffer_ = function(sb, name, value) {
+  sb.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
+};
+
+
+/**
+ * Whether the form has a file input.
+ * @param {HTMLFormElement} form The form.
+ * @return {boolean} Whether the form has a file input.
+ */
+goog.dom.forms.hasFileInput = function(form) {
+  var els = form.elements;
+  for (var el, i = 0; el = els[i]; i++) {
+    if (!el.disabled && el.type &&
+        el.type.toLowerCase() == goog.dom.InputType.FILE) {
+      return true;
+    }
+  }
+  return false;
+};
+
+
+/**
+ * Enables or disables either all elements in a form or a single form element.
+ * @param {Element} el The element, either a form or an element within a form.
+ * @param {boolean} disabled Whether the element should be disabled.
+ */
+goog.dom.forms.setDisabled = function(el, disabled) {
+  // disable all elements in a form
+  if (el.tagName == goog.dom.TagName.FORM) {
+    var els = el.elements;
+    for (var i = 0; el = els[i]; i++) {
+      goog.dom.forms.setDisabled(el, disabled);
+    }
+  } else {
+    // makes sure to blur buttons, multi-selects, and any elements which
+    // maintain keyboard/accessibility focus when disabled
+    if (disabled == true) {
+      el.blur();
+    }
+    el.disabled = disabled;
+  }
+};
+
+
+/**
+ * Focuses, and optionally selects the content of, a form element.
+ * @param {Element} el The form element.
+ */
+goog.dom.forms.focusAndSelect = function(el) {
+  el.focus();
+  if (el.select) {
+    el.select();
+  }
+};
+
+
+/**
+ * Whether a form element has a value.
+ * @param {Element} el The element.
+ * @return {boolean} Whether the form has a value.
+ */
+goog.dom.forms.hasValue = function(el) {
+  var value = goog.dom.forms.getValue(el);
+  return !!value;
+};
+
+
+/**
+ * Whether a named form field has a value.
+ * @param {HTMLFormElement} form The form element.
+ * @param {string} name Name of an input to the form.
+ * @return {boolean} Whether the form has a value.
+ */
+goog.dom.forms.hasValueByName = function(form, name) {
+  var value = goog.dom.forms.getValueByName(form, name);
+  return !!value;
+};
+
+
+/**
+ * Gets the current value of any element with a type.
+ * @param {Element} el The element.
+ * @return {string|Array<string>|null} The current value of the element
+ *     (or null).
+ */
+goog.dom.forms.getValue = function(el) {
+  var type = el.type;
+  if (!goog.isDef(type)) {
+    return null;
+  }
+  switch (type.toLowerCase()) {
+    case goog.dom.InputType.CHECKBOX:
+    case goog.dom.InputType.RADIO:
+      return goog.dom.forms.getInputChecked_(el);
+    case goog.dom.InputType.SELECT_ONE:
+      return goog.dom.forms.getSelectSingle_(el);
+    case goog.dom.InputType.SELECT_MULTIPLE:
+      return goog.dom.forms.getSelectMultiple_(el);
+    default:
+      return goog.isDef(el.value) ? el.value : null;
+  }
+};
+
+
+/**
+ * Alias for goog.dom.form.element.getValue
+ * @type {Function}
+ * @deprecated Use {@link goog.dom.forms.getValue} instead.
+ * @suppress {missingProvide}
+ */
+goog.dom.$F = goog.dom.forms.getValue;
+
+
+/**
+ * Returns the value of the named form field. In the case of radio buttons,
+ * returns the value of the checked button with the given name.
+ *
+ * @param {HTMLFormElement} form The form element.
+ * @param {string} name Name of an input to the form.
+ *
+ * @return {Array<string>|string|null} The value of the form element, or
+ *     null if the form element does not exist or has no value.
+ */
+goog.dom.forms.getValueByName = function(form, name) {
+  var els = form.elements[name];
+
+  if (els) {
+    if (els.type) {
+      return goog.dom.forms.getValue(els);
+    } else {
+      for (var i = 0; i < els.length; i++) {
+        var val = goog.dom.forms.getValue(els[i]);
+        if (val) {
+          return val;
+        }
+      }
+    }
+  }
+  return null;
+};
+
+
+/**
+ * Gets the current value of a checkable input element.
+ * @param {Element} el The element.
+ * @return {?string} The value of the form element (or null).
+ * @private
+ */
+goog.dom.forms.getInputChecked_ = function(el) {
+  return el.checked ? el.value : null;
+};
+
+
+/**
+ * Gets the current value of a select-one element.
+ * @param {Element} el The element.
+ * @return {?string} The value of the form element (or null).
+ * @private
+ */
+goog.dom.forms.getSelectSingle_ = function(el) {
+  var selectedIndex = el.selectedIndex;
+  return selectedIndex >= 0 ? el.options[selectedIndex].value : null;
+};
+
+
+/**
+ * Gets the current value of a select-multiple element.
+ * @param {Element} el The element.
+ * @return {Array<string>?} The value of the form element (or null).
+ * @private
+ */
+goog.dom.forms.getSelectMultiple_ = function(el) {
+  var values = [];
+  for (var option, i = 0; option = el.options[i]; i++) {
+    if (option.selected) {
+      values.push(option.value);
+    }
+  }
+  return values.length ? values : null;
+};
+
+
+/**
+ * Sets the current value of any element with a type.
+ * @param {Element} el The element.
+ * @param {*=} opt_value The value to give to the element, which will be coerced
+ *     by the browser in the default case using toString. This value should be
+ *     an array for setting the value of select multiple elements.
+ */
+goog.dom.forms.setValue = function(el, opt_value) {
+  var type = el.type;
+  if (goog.isDef(type)) {
+    switch (type.toLowerCase()) {
+      case goog.dom.InputType.CHECKBOX:
+      case goog.dom.InputType.RADIO:
+        goog.dom.forms.setInputChecked_(el,
+            /** @type {string} */ (opt_value));
+        break;
+      case goog.dom.InputType.SELECT_ONE:
+        goog.dom.forms.setSelectSingle_(el,
+            /** @type {string} */ (opt_value));
+        break;
+      case goog.dom.InputType.SELECT_MULTIPLE:
+        goog.dom.forms.setSelectMultiple_(el,
+            /** @type {Array<string>} */ (opt_value));
+        break;
+      default:
+        el.value = goog.isDefAndNotNull(opt_value) ? opt_value : '';
+    }
+  }
+};
+
+
+/**
+ * Sets a checkable input element's checked property.
+ * #TODO(user): This seems potentially unintuitive since it doesn't set
+ * the value property but my hunch is that the primary use case is to check a
+ * checkbox, not to reset its value property.
+ * @param {Element} el The element.
+ * @param {string|boolean=} opt_value The value, sets the element checked if
+ *     val is set.
+ * @private
+ */
+goog.dom.forms.setInputChecked_ = function(el, opt_value) {
+  el.checked = opt_value;
+};
+
+
+/**
+ * Sets the value of a select-one element.
+ * @param {Element} el The element.
+ * @param {string=} opt_value The value of the selected option element.
+ * @private
+ */
+goog.dom.forms.setSelectSingle_ = function(el, opt_value) {
+  // unset any prior selections
+  el.selectedIndex = -1;
+  if (goog.isString(opt_value)) {
+    for (var option, i = 0; option = el.options[i]; i++) {
+      if (option.value == opt_value) {
+        option.selected = true;
+        break;
+      }
+    }
+  }
+};
+
+
+/**
+ * Sets the value of a select-multiple element.
+ * @param {Element} el The element.
+ * @param {Array<string>|string=} opt_value The value of the selected option
+ *     element(s).
+ * @private
+ */
+goog.dom.forms.setSelectMultiple_ = function(el, opt_value) {
+  // reset string opt_values as an array
+  if (goog.isString(opt_value)) {
+    opt_value = [opt_value];
+  }
+  for (var option, i = 0; option = el.options[i]; i++) {
+    // we have to reset the other options to false for select-multiple
+    option.selected = false;
+    if (opt_value) {
+      for (var value, j = 0; value = opt_value[j]; j++) {
+        if (option.value == value) {
+          option.selected = true;
+        }
+      }
+    }
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/fullscreen.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/fullscreen.js b/externs/GCL/externs/goog/dom/fullscreen.js
new file mode 100644
index 0000000..1954213
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/fullscreen.js
@@ -0,0 +1,144 @@
+// 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 Functions for managing full screen status of the DOM.
+ *
+ */
+
+goog.provide('goog.dom.fullscreen');
+goog.provide('goog.dom.fullscreen.EventType');
+
+goog.require('goog.dom');
+goog.require('goog.userAgent');
+
+
+/**
+ * Event types for full screen.
+ * @enum {string}
+ */
+goog.dom.fullscreen.EventType = {
+  /** Dispatched by the Document when the fullscreen status changes. */
+  CHANGE: (function() {
+    if (goog.userAgent.WEBKIT) {
+      return 'webkitfullscreenchange';
+    }
+    if (goog.userAgent.GECKO) {
+      return 'mozfullscreenchange';
+    }
+    if (goog.userAgent.IE) {
+      return 'MSFullscreenChange';
+    }
+    // Opera 12-14, and W3C standard (Draft):
+    // https://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html
+    return 'fullscreenchange';
+  })()
+};
+
+
+/**
+ * Determines if full screen is supported.
+ * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being
+ *     queried. If not provided, use the current DOM.
+ * @return {boolean} True iff full screen is supported.
+ */
+goog.dom.fullscreen.isSupported = function(opt_domHelper) {
+  var doc = goog.dom.fullscreen.getDocument_(opt_domHelper);
+  var body = doc.body;
+  return !!(body.webkitRequestFullscreen ||
+      (body.mozRequestFullScreen && doc.mozFullScreenEnabled) ||
+      (body.msRequestFullscreen && doc.msFullscreenEnabled) ||
+      (body.requestFullscreen && doc.fullscreenEnabled));
+};
+
+
+/**
+ * Requests putting the element in full screen.
+ * @param {!Element} element The element to put full screen.
+ */
+goog.dom.fullscreen.requestFullScreen = function(element) {
+  if (element.webkitRequestFullscreen) {
+    element.webkitRequestFullscreen();
+  } else if (element.mozRequestFullScreen) {
+    element.mozRequestFullScreen();
+  } else if (element.msRequestFullscreen) {
+    element.msRequestFullscreen();
+  } else if (element.requestFullscreen) {
+    element.requestFullscreen();
+  }
+};
+
+
+/**
+ * Requests putting the element in full screen with full keyboard access.
+ * @param {!Element} element The element to put full screen.
+ */
+goog.dom.fullscreen.requestFullScreenWithKeys = function(
+    element) {
+  if (element.mozRequestFullScreenWithKeys) {
+    element.mozRequestFullScreenWithKeys();
+  } else if (element.webkitRequestFullscreen) {
+    element.webkitRequestFullscreen();
+  } else {
+    goog.dom.fullscreen.requestFullScreen(element);
+  }
+};
+
+
+/**
+ * Exits full screen.
+ * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being
+ *     queried. If not provided, use the current DOM.
+ */
+goog.dom.fullscreen.exitFullScreen = function(opt_domHelper) {
+  var doc = goog.dom.fullscreen.getDocument_(opt_domHelper);
+  if (doc.webkitCancelFullScreen) {
+    doc.webkitCancelFullScreen();
+  } else if (doc.mozCancelFullScreen) {
+    doc.mozCancelFullScreen();
+  } else if (doc.msExitFullscreen) {
+    doc.msExitFullscreen();
+  } else if (doc.exitFullscreen) {
+    doc.exitFullscreen();
+  }
+};
+
+
+/**
+ * Determines if the document is full screen.
+ * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being
+ *     queried. If not provided, use the current DOM.
+ * @return {boolean} Whether the document is full screen.
+ */
+goog.dom.fullscreen.isFullScreen = function(opt_domHelper) {
+  var doc = goog.dom.fullscreen.getDocument_(opt_domHelper);
+  // IE 11 doesn't have similar boolean property, so check whether
+  // document.msFullscreenElement is null instead.
+  return !!(doc.webkitIsFullScreen || doc.mozFullScreen ||
+      doc.msFullscreenElement || doc.fullscreenElement);
+};
+
+
+/**
+ * Gets the document object of the dom.
+ * @param {!goog.dom.DomHelper=} opt_domHelper The DomHelper for the DOM being
+ *     queried. If not provided, use the current DOM.
+ * @return {!Document} The dom document.
+ * @private
+ */
+goog.dom.fullscreen.getDocument_ = function(opt_domHelper) {
+  return opt_domHelper ?
+      opt_domHelper.getDocument() :
+      goog.dom.getDomHelper().getDocument();
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/iframe.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/iframe.js b/externs/GCL/externs/goog/dom/iframe.js
new file mode 100644
index 0000000..a22b8b7
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/iframe.js
@@ -0,0 +1,216 @@
+// 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 Utilities for creating and working with iframes
+ * cross-browser.
+ * @author gboyer@google.com (Garry Boyer)
+ */
+
+
+goog.provide('goog.dom.iframe');
+
+goog.require('goog.dom');
+goog.require('goog.dom.safe');
+goog.require('goog.html.SafeHtml');
+goog.require('goog.html.SafeStyle');
+goog.require('goog.html.legacyconversions');
+goog.require('goog.userAgent');
+
+
+/**
+ * Safe source for a blank iframe.
+ *
+ * Intentionally not about:blank, which gives mixed content warnings in IE6
+ * over HTTPS.
+ *
+ * @type {string}
+ */
+goog.dom.iframe.BLANK_SOURCE = 'javascript:""';
+
+
+/**
+ * Safe source for a new blank iframe that may not cause a new load of the
+ * iframe. This is different from {@code goog.dom.iframe.BLANK_SOURCE} in that
+ * it will allow an iframe to be loaded synchronously in more browsers, notably
+ * Gecko, following the javascript protocol spec.
+ *
+ * NOTE: This should not be used to replace the source of an existing iframe.
+ * The new src value will be ignored, per the spec.
+ *
+ * Due to cross-browser differences, the load is not guaranteed  to be
+ * synchronous. If code depends on the load of the iframe,
+ * then {@code goog.net.IframeLoadMonitor} or a similar technique should be
+ * used.
+ *
+ * According to
+ * http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#javascript-protocol
+ * the 'javascript:""' URL should trigger a new load of the iframe, which may be
+ * asynchronous. A void src, such as 'javascript:undefined', does not change
+ * the browsing context document's, and thus should not trigger another load.
+ *
+ * Intentionally not about:blank, which also triggers a load.
+ *
+ * NOTE: 'javascript:' URL handling spec compliance varies per browser. IE
+ * throws an error with 'javascript:undefined'. Webkit browsers will reload the
+ * iframe when setting this source on an existing iframe.
+ *
+ * @type {string}
+ */
+goog.dom.iframe.BLANK_SOURCE_NEW_FRAME = goog.userAgent.IE ?
+    'javascript:""' :
+    'javascript:undefined';
+
+
+/**
+ * Styles to help ensure an undecorated iframe.
+ * @type {string}
+ * @private
+ */
+goog.dom.iframe.STYLES_ = 'border:0;vertical-align:bottom;';
+
+
+/**
+ * Creates a completely blank iframe element.
+ *
+ * The iframe will not caused mixed-content warnings for IE6 under HTTPS.
+ * The iframe will also have no borders or padding, so that the styled width
+ * and height will be the actual width and height of the iframe.
+ *
+ * This function currently only attempts to create a blank iframe.  There
+ * are no guarantees to the contents of the iframe or whether it is rendered
+ * in quirks mode.
+ *
+ * @param {goog.dom.DomHelper} domHelper The dom helper to use.
+ * @param {!goog.html.SafeStyle|string=} opt_styles CSS styles for the
+ *     iframe. If possible pass a SafeStyle; string is supported for
+ *     backwards-compatibility only and uses goog.html.legacyconversions.
+ * @return {!HTMLIFrameElement} A completely blank iframe.
+ */
+goog.dom.iframe.createBlank = function(domHelper, opt_styles) {
+  var styles;
+  if (goog.isString(opt_styles)) {
+    styles = goog.html.legacyconversions.safeStyleFromString(opt_styles)
+        .getTypedStringValue();
+  } else if (opt_styles instanceof goog.html.SafeStyle) {
+    // SafeStyle has to be converted back to a string for now, since there's
+    // no safe alternative to createDom().
+    styles = goog.html.SafeStyle.unwrap(opt_styles);
+  } else {  // undefined.
+    styles = '';
+  }
+  return /** @type {!HTMLIFrameElement} */ (domHelper.createDom('iframe', {
+    'frameborder': 0,
+    // Since iframes are inline elements, we must align to bottom to
+    // compensate for the line descent.
+    'style': goog.dom.iframe.STYLES_ + styles,
+    'src': goog.dom.iframe.BLANK_SOURCE
+  }));
+};
+
+
+/**
+ * Writes the contents of a blank iframe that has already been inserted
+ * into the document. If possible use {@link #writeSafeContent},
+ * this function exists for backwards-compatibility only and uses
+ * goog.html.legacyconversions.
+ * @param {!HTMLIFrameElement} iframe An iframe with no contents, such as
+ *     one created by goog.dom.iframe.createBlank, but already appended to
+ *     a parent document.
+ * @param {string} content Content to write to the iframe, from doctype to
+ *     the HTML close tag.
+ */
+goog.dom.iframe.writeContent = function(iframe, content) {
+  goog.dom.iframe.writeSafeContent(
+      iframe, goog.html.legacyconversions.safeHtmlFromString(content));
+};
+
+
+/**
+ * Writes the contents of a blank iframe that has already been inserted
+ * into the document.
+ * @param {!HTMLIFrameElement} iframe An iframe with no contents, such as
+ *     one created by {@link #createBlank}, but already appended to
+ *     a parent document.
+ * @param {!goog.html.SafeHtml} content Content to write to the iframe,
+ *     from doctype to the HTML close tag.
+ */
+goog.dom.iframe.writeSafeContent = function(iframe, content) {
+  var doc = goog.dom.getFrameContentDocument(iframe);
+  doc.open();
+  goog.dom.safe.documentWrite(doc, content);
+  doc.close();
+};
+
+
+// TODO(gboyer): Provide a higher-level API for the most common use case, so
+// that you can just provide a list of stylesheets and some content HTML.
+/**
+ * Creates a same-domain iframe containing preloaded content.
+ *
+ * This is primarily useful for DOM sandboxing.  One use case is to embed
+ * a trusted Javascript app with potentially conflicting CSS styles.  The
+ * second case is to reduce the cost of layout passes by the browser -- for
+ * example, you can perform sandbox sizing of characters in an iframe while
+ * manipulating a heavy DOM in the main window.  The iframe and parent frame
+ * can access each others' properties and functions without restriction.
+ *
+ * @param {!Element} parentElement The parent element in which to append the
+ *     iframe.
+ * @param {!goog.html.SafeHtml|string=} opt_headContents Contents to go into
+ *     the iframe's head. If possible pass a SafeHtml; string is supported for
+ *     backwards-compatibility only and uses goog.html.legacyconversions.
+ * @param {!goog.html.SafeHtml|string=} opt_bodyContents Contents to go into
+ *     the iframe's body. If possible pass a SafeHtml; string is supported for
+ *     backwards-compatibility only and uses goog.html.legacyconversions.
+ * @param {!goog.html.SafeStyle|string=} opt_styles CSS styles for the iframe
+ *     itself, before adding to the parent element. If possible pass a
+ *     SafeStyle; string is supported for backwards-compatibility only and
+ *     uses goog.html.legacyconversions.
+ * @param {boolean=} opt_quirks Whether to use quirks mode (false by default).
+ * @return {!HTMLIFrameElement} An iframe that has the specified contents.
+ */
+goog.dom.iframe.createWithContent = function(
+    parentElement, opt_headContents, opt_bodyContents, opt_styles, opt_quirks) {
+  var domHelper = goog.dom.getDomHelper(parentElement);
+
+  if (goog.isString(opt_headContents)) {
+    opt_headContents =
+        goog.html.legacyconversions.safeHtmlFromString(opt_headContents);
+  }
+  if (goog.isString(opt_bodyContents)) {
+    opt_bodyContents =
+        goog.html.legacyconversions.safeHtmlFromString(opt_bodyContents);
+  }
+  if (goog.isString(opt_styles)) {
+    opt_styles =
+        goog.html.legacyconversions.safeStyleFromString(opt_styles);
+  }
+
+  var content = goog.html.SafeHtml.create('html', {}, goog.html.SafeHtml.concat(
+      goog.html.SafeHtml.create('head', {}, opt_headContents),
+      goog.html.SafeHtml.create('body', {}, opt_bodyContents)));
+  if (!opt_quirks) {
+    content =
+        goog.html.SafeHtml.concat(goog.html.SafeHtml.DOCTYPE_HTML, content);
+  }
+
+  var iframe = goog.dom.iframe.createBlank(domHelper, opt_styles);
+
+  // Cannot manipulate iframe content until it is in a document.
+  parentElement.appendChild(iframe);
+  goog.dom.iframe.writeSafeContent(iframe, content);
+
+  return iframe;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/inputtype.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/inputtype.js b/externs/GCL/externs/goog/dom/inputtype.js
new file mode 100644
index 0000000..f5db6c8
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/inputtype.js
@@ -0,0 +1,66 @@
+// Copyright 2015 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.InputType enum.  This enumerates
+ * all input element types (for INPUT, BUTTON, SELECT and TEXTAREA
+ * elements) in either the the W3C HTML 4.01 index of elements or the
+ * HTML5 draft specification.
+ *
+ * References:
+ * http://www.w3.org/TR/html401/sgml/dtd.html#InputType
+ * http://www.w3.org/TR/html-markup/input.html#input
+ * https://html.spec.whatwg.org/multipage/forms.html#dom-input-type
+ * https://html.spec.whatwg.org/multipage/forms.html#dom-button-type
+ * https://html.spec.whatwg.org/multipage/forms.html#dom-select-type
+ * https://html.spec.whatwg.org/multipage/forms.html#dom-textarea-type
+ *
+ */
+goog.provide('goog.dom.InputType');
+
+
+/**
+ * Enum of all input types (for INPUT, BUTTON, SELECT and TEXTAREA elements)
+ * specified by the W3C HTML4.01 and HTML5 specifications.
+ * @enum {string}
+ */
+goog.dom.InputType = {
+  BUTTON: 'button',
+  CHECKBOX: 'checkbox',
+  COLOR: 'color',
+  DATE: 'date',
+  DATETIME: 'datetime',
+  DATETIME_LOCAL: 'datetime-local',
+  EMAIL: 'email',
+  FILE: 'file',
+  HIDDEN: 'hidden',
+  IMAGE: 'image',
+  MENU: 'menu',
+  MONTH: 'month',
+  NUMBER: 'number',
+  PASSWORD: 'password',
+  RADIO: 'radio',
+  RANGE: 'range',
+  RESET: 'reset',
+  SEARCH: 'search',
+  SELECT_MULTIPLE: 'select-multiple',
+  SELECT_ONE: 'select-one',
+  SUBMIT: 'submit',
+  TEL: 'tel',
+  TEXT: 'text',
+  TEXTAREA: 'textarea',
+  TIME: 'time',
+  URL: 'url',
+  WEEK: 'week'
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/iter.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/iter.js b/externs/GCL/externs/goog/dom/iter.js
new file mode 100644
index 0000000..7516414
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/iter.js
@@ -0,0 +1,129 @@
+// 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 Iterators over DOM nodes.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.iter.AncestorIterator');
+goog.provide('goog.dom.iter.ChildIterator');
+goog.provide('goog.dom.iter.SiblingIterator');
+
+goog.require('goog.iter.Iterator');
+goog.require('goog.iter.StopIteration');
+
+
+
+/**
+ * Iterator over a Node's siblings.
+ * @param {Node} node The node to start with.
+ * @param {boolean=} opt_includeNode Whether to return the given node as the
+ *     first return value from next.
+ * @param {boolean=} opt_reverse Whether to traverse siblings in reverse
+ *     document order.
+ * @constructor
+ * @extends {goog.iter.Iterator}
+ */
+goog.dom.iter.SiblingIterator = function(node, opt_includeNode, opt_reverse) {
+  /**
+   * The current node, or null if iteration is finished.
+   * @type {Node}
+   * @private
+   */
+  this.node_ = node;
+
+  /**
+   * Whether to iterate in reverse.
+   * @type {boolean}
+   * @private
+   */
+  this.reverse_ = !!opt_reverse;
+
+  if (node && !opt_includeNode) {
+    this.next();
+  }
+};
+goog.inherits(goog.dom.iter.SiblingIterator, goog.iter.Iterator);
+
+
+/** @override */
+goog.dom.iter.SiblingIterator.prototype.next = function() {
+  var node = this.node_;
+  if (!node) {
+    throw goog.iter.StopIteration;
+  }
+  this.node_ = this.reverse_ ? node.previousSibling : node.nextSibling;
+  return node;
+};
+
+
+
+/**
+ * Iterator over an Element's children.
+ * @param {Element} element The element to iterate over.
+ * @param {boolean=} opt_reverse Optionally traverse children from last to
+ *     first.
+ * @param {number=} opt_startIndex Optional starting index.
+ * @constructor
+ * @extends {goog.dom.iter.SiblingIterator}
+ * @final
+ */
+goog.dom.iter.ChildIterator = function(element, opt_reverse, opt_startIndex) {
+  if (!goog.isDef(opt_startIndex)) {
+    opt_startIndex = opt_reverse && element.childNodes.length ?
+        element.childNodes.length - 1 : 0;
+  }
+  goog.dom.iter.SiblingIterator.call(this, element.childNodes[opt_startIndex],
+      true, opt_reverse);
+};
+goog.inherits(goog.dom.iter.ChildIterator, goog.dom.iter.SiblingIterator);
+
+
+
+/**
+ * Iterator over a Node's ancestors, stopping after the document body.
+ * @param {Node} node The node to start with.
+ * @param {boolean=} opt_includeNode Whether to return the given node as the
+ *     first return value from next.
+ * @constructor
+ * @extends {goog.iter.Iterator}
+ * @final
+ */
+goog.dom.iter.AncestorIterator = function(node, opt_includeNode) {
+  /**
+   * The current node, or null if iteration is finished.
+   * @type {Node}
+   * @private
+   */
+  this.node_ = node;
+
+  if (node && !opt_includeNode) {
+    this.next();
+  }
+};
+goog.inherits(goog.dom.iter.AncestorIterator, goog.iter.Iterator);
+
+
+/** @override */
+goog.dom.iter.AncestorIterator.prototype.next = function() {
+  var node = this.node_;
+  if (!node) {
+    throw goog.iter.StopIteration;
+  }
+  this.node_ = node.parentNode;
+  return node;
+};
+

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/multirange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/multirange.js b/externs/GCL/externs/goog/dom/multirange.js
new file mode 100644
index 0000000..9a57d25
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/multirange.js
@@ -0,0 +1,510 @@
+// 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 Utilities for working with W3C multi-part ranges.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.MultiRange');
+goog.provide('goog.dom.MultiRangeIterator');
+
+goog.require('goog.array');
+goog.require('goog.dom.AbstractMultiRange');
+goog.require('goog.dom.AbstractRange');
+goog.require('goog.dom.RangeIterator');
+goog.require('goog.dom.RangeType');
+goog.require('goog.dom.SavedRange');
+goog.require('goog.dom.TextRange');
+goog.require('goog.iter.StopIteration');
+goog.require('goog.log');
+
+
+
+/**
+ * Creates a new multi part range with no properties.  Do not use this
+ * constructor: use one of the goog.dom.Range.createFrom* methods instead.
+ * @constructor
+ * @extends {goog.dom.AbstractMultiRange}
+ * @final
+ */
+goog.dom.MultiRange = function() {
+  /**
+   * Logging object.
+   * @private {goog.log.Logger}
+   */
+  this.logger_ = goog.log.getLogger('goog.dom.MultiRange');
+
+  /**
+   * Array of browser sub-ranges comprising this multi-range.
+   * @private {Array<Range>}
+   */
+  this.browserRanges_ = [];
+
+  /**
+   * Lazily initialized array of range objects comprising this multi-range.
+   * @private {Array<goog.dom.TextRange>}
+   */
+  this.ranges_ = [];
+
+  /**
+   * Lazily computed sorted version of ranges_, sorted by start point.
+   * @private {Array<goog.dom.TextRange>?}
+   */
+  this.sortedRanges_ = null;
+
+  /**
+   * Lazily computed container node.
+   * @private {Node}
+   */
+  this.container_ = null;
+};
+goog.inherits(goog.dom.MultiRange, goog.dom.AbstractMultiRange);
+
+
+/**
+ * Creates a new range wrapper from the given browser selection object.  Do not
+ * use this method directly - please use goog.dom.Range.createFrom* instead.
+ * @param {Selection} selection The browser selection object.
+ * @return {!goog.dom.MultiRange} A range wrapper object.
+ */
+goog.dom.MultiRange.createFromBrowserSelection = function(selection) {
+  var range = new goog.dom.MultiRange();
+  for (var i = 0, len = selection.rangeCount; i < len; i++) {
+    range.browserRanges_.push(selection.getRangeAt(i));
+  }
+  return range;
+};
+
+
+/**
+ * Creates a new range wrapper from the given browser ranges.  Do not
+ * use this method directly - please use goog.dom.Range.createFrom* instead.
+ * @param {Array<Range>} browserRanges The browser ranges.
+ * @return {!goog.dom.MultiRange} A range wrapper object.
+ */
+goog.dom.MultiRange.createFromBrowserRanges = function(browserRanges) {
+  var range = new goog.dom.MultiRange();
+  range.browserRanges_ = goog.array.clone(browserRanges);
+  return range;
+};
+
+
+/**
+ * Creates a new range wrapper from the given goog.dom.TextRange objects.  Do
+ * not use this method directly - please use goog.dom.Range.createFrom* instead.
+ * @param {Array<goog.dom.TextRange>} textRanges The text range objects.
+ * @return {!goog.dom.MultiRange} A range wrapper object.
+ */
+goog.dom.MultiRange.createFromTextRanges = function(textRanges) {
+  var range = new goog.dom.MultiRange();
+  range.ranges_ = textRanges;
+  range.browserRanges_ = goog.array.map(textRanges, function(range) {
+    return range.getBrowserRangeObject();
+  });
+  return range;
+};
+
+
+// Method implementations
+
+
+/**
+ * Clears cached values.  Should be called whenever this.browserRanges_ is
+ * modified.
+ * @private
+ */
+goog.dom.MultiRange.prototype.clearCachedValues_ = function() {
+  this.ranges_ = [];
+  this.sortedRanges_ = null;
+  this.container_ = null;
+};
+
+
+/**
+ * @return {!goog.dom.MultiRange} A clone of this range.
+ * @override
+ */
+goog.dom.MultiRange.prototype.clone = function() {
+  return goog.dom.MultiRange.createFromBrowserRanges(this.browserRanges_);
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getType = function() {
+  return goog.dom.RangeType.MULTI;
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getBrowserRangeObject = function() {
+  // NOTE(robbyw): This method does not make sense for multi-ranges.
+  if (this.browserRanges_.length > 1) {
+    goog.log.warning(this.logger_,
+        'getBrowserRangeObject called on MultiRange with more than 1 range');
+  }
+  return this.browserRanges_[0];
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.setBrowserRangeObject = function(nativeRange) {
+  // TODO(robbyw): Look in to adding setBrowserSelectionObject.
+  return false;
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getTextRangeCount = function() {
+  return this.browserRanges_.length;
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getTextRange = function(i) {
+  if (!this.ranges_[i]) {
+    this.ranges_[i] = goog.dom.TextRange.createFromBrowserRange(
+        this.browserRanges_[i]);
+  }
+  return this.ranges_[i];
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getContainer = function() {
+  if (!this.container_) {
+    var nodes = [];
+    for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
+      nodes.push(this.getTextRange(i).getContainer());
+    }
+    this.container_ = goog.dom.findCommonAncestor.apply(null, nodes);
+  }
+  return this.container_;
+};
+
+
+/**
+ * @return {!Array<goog.dom.TextRange>} An array of sub-ranges, sorted by start
+ *     point.
+ */
+goog.dom.MultiRange.prototype.getSortedRanges = function() {
+  if (!this.sortedRanges_) {
+    this.sortedRanges_ = this.getTextRanges();
+    this.sortedRanges_.sort(function(a, b) {
+      var aStartNode = a.getStartNode();
+      var aStartOffset = a.getStartOffset();
+      var bStartNode = b.getStartNode();
+      var bStartOffset = b.getStartOffset();
+
+      if (aStartNode == bStartNode && aStartOffset == bStartOffset) {
+        return 0;
+      }
+
+      return goog.dom.Range.isReversed(aStartNode, aStartOffset, bStartNode,
+          bStartOffset) ? 1 : -1;
+    });
+  }
+  return this.sortedRanges_;
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getStartNode = function() {
+  return this.getSortedRanges()[0].getStartNode();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getStartOffset = function() {
+  return this.getSortedRanges()[0].getStartOffset();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getEndNode = function() {
+  // NOTE(robbyw): This may return the wrong node if any subranges overlap.
+  return goog.array.peek(this.getSortedRanges()).getEndNode();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getEndOffset = function() {
+  // NOTE(robbyw): This may return the wrong value if any subranges overlap.
+  return goog.array.peek(this.getSortedRanges()).getEndOffset();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.isRangeInDocument = function() {
+  return goog.array.every(this.getTextRanges(), function(range) {
+    return range.isRangeInDocument();
+  });
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.isCollapsed = function() {
+  return this.browserRanges_.length == 0 ||
+      this.browserRanges_.length == 1 && this.getTextRange(0).isCollapsed();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getText = function() {
+  return goog.array.map(this.getTextRanges(), function(range) {
+    return range.getText();
+  }).join('');
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getHtmlFragment = function() {
+  return this.getValidHtml();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getValidHtml = function() {
+  // NOTE(robbyw): This does not behave well if the sub-ranges overlap.
+  return goog.array.map(this.getTextRanges(), function(range) {
+    return range.getValidHtml();
+  }).join('');
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.getPastableHtml = function() {
+  // TODO(robbyw): This should probably do something smart like group TR and TD
+  // selections in to the same table.
+  return this.getValidHtml();
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.__iterator__ = function(opt_keys) {
+  return new goog.dom.MultiRangeIterator(this);
+};
+
+
+// RANGE ACTIONS
+
+
+/** @override */
+goog.dom.MultiRange.prototype.select = function() {
+  var selection = goog.dom.AbstractRange.getBrowserSelectionForWindow(
+      this.getWindow());
+  selection.removeAllRanges();
+  for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
+    selection.addRange(this.getTextRange(i).getBrowserRangeObject());
+  }
+};
+
+
+/** @override */
+goog.dom.MultiRange.prototype.removeContents = function() {
+  goog.array.forEach(this.getTextRanges(), function(range) {
+    range.removeContents();
+  });
+};
+
+
+// SAVE/RESTORE
+
+
+/** @override */
+goog.dom.MultiRange.prototype.saveUsingDom = function() {
+  return new goog.dom.DomSavedMultiRange_(this);
+};
+
+
+// RANGE MODIFICATION
+
+
+/**
+ * Collapses this range to a single point, either the first or last point
+ * depending on the parameter.  This will result in the number of ranges in this
+ * multi range becoming 1.
+ * @param {boolean} toAnchor Whether to collapse to the anchor.
+ * @override
+ */
+goog.dom.MultiRange.prototype.collapse = function(toAnchor) {
+  if (!this.isCollapsed()) {
+    var range = toAnchor ? this.getTextRange(0) : this.getTextRange(
+        this.getTextRangeCount() - 1);
+
+    this.clearCachedValues_();
+    range.collapse(toAnchor);
+    this.ranges_ = [range];
+    this.sortedRanges_ = [range];
+    this.browserRanges_ = [range.getBrowserRangeObject()];
+  }
+};
+
+
+// SAVED RANGE OBJECTS
+
+
+
+/**
+ * A SavedRange implementation using DOM endpoints.
+ * @param {goog.dom.MultiRange} range The range to save.
+ * @constructor
+ * @extends {goog.dom.SavedRange}
+ * @private
+ */
+goog.dom.DomSavedMultiRange_ = function(range) {
+  /**
+   * Array of saved ranges.
+   * @type {Array<goog.dom.SavedRange>}
+   * @private
+   */
+  this.savedRanges_ = goog.array.map(range.getTextRanges(), function(range) {
+    return range.saveUsingDom();
+  });
+};
+goog.inherits(goog.dom.DomSavedMultiRange_, goog.dom.SavedRange);
+
+
+/**
+ * @return {!goog.dom.MultiRange} The restored range.
+ * @override
+ */
+goog.dom.DomSavedMultiRange_.prototype.restoreInternal = function() {
+  var ranges = goog.array.map(this.savedRanges_, function(savedRange) {
+    return savedRange.restore();
+  });
+  return goog.dom.MultiRange.createFromTextRanges(ranges);
+};
+
+
+/** @override */
+goog.dom.DomSavedMultiRange_.prototype.disposeInternal = function() {
+  goog.dom.DomSavedMultiRange_.superClass_.disposeInternal.call(this);
+
+  goog.array.forEach(this.savedRanges_, function(savedRange) {
+    savedRange.dispose();
+  });
+  delete this.savedRanges_;
+};
+
+
+// RANGE ITERATION
+
+
+
+/**
+ * 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 {goog.dom.MultiRange} range The range to traverse.
+ * @constructor
+ * @extends {goog.dom.RangeIterator}
+ * @final
+ */
+goog.dom.MultiRangeIterator = function(range) {
+  /**
+   * The list of range iterators left to traverse.
+   * @private {Array<goog.dom.RangeIterator>}
+   */
+  this.iterators_ = null;
+
+  /**
+   * The index of the current sub-iterator being traversed.
+   * @private {number}
+   */
+  this.currentIdx_ = 0;
+
+  if (range) {
+    this.iterators_ = goog.array.map(
+        range.getSortedRanges(),
+        function(r) {
+          return goog.iter.toIterator(r);
+        });
+  }
+
+  goog.dom.MultiRangeIterator.base(
+      this, 'constructor', range ? this.getStartNode() : null, false);
+};
+goog.inherits(goog.dom.MultiRangeIterator, goog.dom.RangeIterator);
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.getStartTextOffset = function() {
+  return this.iterators_[this.currentIdx_].getStartTextOffset();
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.getEndTextOffset = function() {
+  return this.iterators_[this.currentIdx_].getEndTextOffset();
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.getStartNode = function() {
+  return this.iterators_[0].getStartNode();
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.getEndNode = function() {
+  return goog.array.peek(this.iterators_).getEndNode();
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.isLast = function() {
+  return this.iterators_[this.currentIdx_].isLast();
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.next = function() {
+  /** @preserveTry */
+  try {
+    var it = this.iterators_[this.currentIdx_];
+    var next = it.next();
+    this.setPosition(it.node, it.tagType, it.depth);
+    return next;
+  } catch (ex) {
+    if (ex !== goog.iter.StopIteration ||
+        this.iterators_.length - 1 == this.currentIdx_) {
+      throw ex;
+    } else {
+      // In case we got a StopIteration, increment counter and try again.
+      this.currentIdx_++;
+      return this.next();
+    }
+  }
+};
+
+
+/** @override */
+goog.dom.MultiRangeIterator.prototype.copyFrom = function(other) {
+  this.iterators_ = goog.array.clone(other.iterators_);
+  goog.dom.MultiRangeIterator.superClass_.copyFrom.call(this, other);
+};
+
+
+/**
+ * @return {!goog.dom.MultiRangeIterator} An identical iterator.
+ * @override
+ */
+goog.dom.MultiRangeIterator.prototype.clone = function() {
+  var copy = new goog.dom.MultiRangeIterator(null);
+  copy.copyFrom(this);
+  return copy;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodeiterator.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/nodeiterator.js b/externs/GCL/externs/goog/dom/nodeiterator.js
new file mode 100644
index 0000000..bca563c
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/nodeiterator.js
@@ -0,0 +1,87 @@
+// 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.NodeIterator');
+
+goog.require('goog.dom.TagIterator');
+
+
+
+/**
+ * A DOM tree traversal iterator.
+ *
+ * Starting with the given node, the iterator walks the DOM in order, reporting
+ * events for each node.  The iterator acts as a prefix iterator:
+ *
+ * <pre>
+ * &lt;div&gt;1&lt;span&gt;2&lt;/span&gt;3&lt;/div&gt;
+ * </pre>
+ *
+ * Will return the following nodes:
+ *
+ * <code>[div, 1, span, 2, 3]</code>
+ *
+ * With the following depths
+ *
+ * <code>[1, 1, 2, 2, 1]</code>
+ *
+ * Imagining <code>|</code> represents iterator position, the traversal stops at
+ * each of the following locations:
+ *
+ * <pre>&lt;div&gt;|1|&lt;span&gt;|2|&lt;/span&gt;3|&lt;/div&gt;</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 last move.
+ *
+ * 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.  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 {number=} opt_depth The starting tree depth.
+ * @constructor
+ * @extends {goog.dom.TagIterator}
+ * @final
+ */
+goog.dom.NodeIterator = function(opt_node, opt_reversed,
+    opt_unconstrained, opt_depth) {
+  goog.dom.TagIterator.call(this, opt_node, opt_reversed, opt_unconstrained,
+      null, opt_depth);
+};
+goog.inherits(goog.dom.NodeIterator, goog.dom.TagIterator);
+
+
+/**
+ * Moves 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.NodeIterator.prototype.next = function() {
+  do {
+    goog.dom.NodeIterator.superClass_.next.call(this);
+  } while (this.isEndTag());
+
+  return this.node;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodeoffset.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/nodeoffset.js b/externs/GCL/externs/goog/dom/nodeoffset.js
new file mode 100644
index 0000000..9a65dbe
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/nodeoffset.js
@@ -0,0 +1,114 @@
+// 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 Object to store the offset from one node to another in a way
+ * that works on any similar DOM structure regardless of whether it is the same
+ * actual nodes.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.NodeOffset');
+
+goog.require('goog.Disposable');
+goog.require('goog.dom.TagName');
+
+
+
+/**
+ * Object to store the offset from one node to another in a way that works on
+ * any similar DOM structure regardless of whether it is the same actual nodes.
+ * @param {Node} node The node to get the offset for.
+ * @param {Node} baseNode The node to calculate the offset from.
+ * @extends {goog.Disposable}
+ * @constructor
+ * @final
+ */
+goog.dom.NodeOffset = function(node, baseNode) {
+  goog.Disposable.call(this);
+
+  /**
+   * A stack of childNode offsets.
+   * @type {Array<number>}
+   * @private
+   */
+  this.offsetStack_ = [];
+
+  /**
+   * A stack of childNode names.
+   * @type {Array<string>}
+   * @private
+   */
+  this.nameStack_ = [];
+
+  while (node && node.nodeName != goog.dom.TagName.BODY && node != baseNode) {
+    // Compute the sibling offset.
+    var siblingOffset = 0;
+    var sib = node.previousSibling;
+    while (sib) {
+      sib = sib.previousSibling;
+      ++siblingOffset;
+    }
+    this.offsetStack_.unshift(siblingOffset);
+    this.nameStack_.unshift(node.nodeName);
+
+    node = node.parentNode;
+  }
+};
+goog.inherits(goog.dom.NodeOffset, goog.Disposable);
+
+
+/**
+ * @return {string} A string representation of this object.
+ * @override
+ */
+goog.dom.NodeOffset.prototype.toString = function() {
+  var strs = [];
+  var name;
+  for (var i = 0; name = this.nameStack_[i]; i++) {
+    strs.push(this.offsetStack_[i] + ',' + name);
+  }
+  return strs.join('\n');
+};
+
+
+/**
+ * Walk the dom and find the node relative to baseNode.  Returns null on
+ * failure.
+ * @param {Node} baseNode The node to start walking from.  Should be equivalent
+ *     to the node passed in to the constructor, in that it should have the
+ *     same contents.
+ * @return {Node} The node relative to baseNode, or null on failure.
+ */
+goog.dom.NodeOffset.prototype.findTargetNode = function(baseNode) {
+  var name;
+  var curNode = baseNode;
+  for (var i = 0; name = this.nameStack_[i]; ++i) {
+    curNode = curNode.childNodes[this.offsetStack_[i]];
+
+    // Sanity check and make sure the element names match.
+    if (!curNode || curNode.nodeName != name) {
+      return null;
+    }
+  }
+  return curNode;
+};
+
+
+/** @override */
+goog.dom.NodeOffset.prototype.disposeInternal = function() {
+  delete this.offsetStack_;
+  delete this.nameStack_;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/nodetype.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/nodetype.js b/externs/GCL/externs/goog/dom/nodetype.js
new file mode 100644
index 0000000..cccb470
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/nodetype.js
@@ -0,0 +1,48 @@
+// 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 Definition of goog.dom.NodeType.
+ */
+
+goog.provide('goog.dom.NodeType');
+
+
+/**
+ * Constants for the nodeType attribute in the Node interface.
+ *
+ * These constants match those specified in the Node interface. These are
+ * usually present on the Node object in recent browsers, but not in older
+ * browsers (specifically, early IEs) and thus are given here.
+ *
+ * In some browsers (early IEs), these are not defined on the Node object,
+ * so they are provided here.
+ *
+ * See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
+ * @enum {number}
+ */
+goog.dom.NodeType = {
+  ELEMENT: 1,
+  ATTRIBUTE: 2,
+  TEXT: 3,
+  CDATA_SECTION: 4,
+  ENTITY_REFERENCE: 5,
+  ENTITY: 6,
+  PROCESSING_INSTRUCTION: 7,
+  COMMENT: 8,
+  DOCUMENT: 9,
+  DOCUMENT_TYPE: 10,
+  DOCUMENT_FRAGMENT: 11,
+  NOTATION: 12
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/abstractpattern.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/abstractpattern.js b/externs/GCL/externs/goog/dom/pattern/abstractpattern.js
new file mode 100644
index 0000000..e785f76
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/abstractpattern.js
@@ -0,0 +1,58 @@
+// 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 base class.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.AbstractPattern');
+
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Base pattern class for DOM matching.
+ *
+ * @constructor
+ */
+goog.dom.pattern.AbstractPattern = function() {
+  /**
+   * The first node matched by this pattern.
+   * @type {Node}
+   */
+  this.matchedNode = null;
+};
+
+
+/**
+ * Reset any internal state this pattern keeps.
+ */
+goog.dom.pattern.AbstractPattern.prototype.reset = function() {
+  // The base implementation does nothing.
+};
+
+
+/**
+ * Test whether this pattern matches the given token.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} {@code MATCH} if the pattern matches.
+ */
+goog.dom.pattern.AbstractPattern.prototype.matchToken = function(token, type) {
+  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/allchildren.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/allchildren.js b/externs/GCL/externs/goog/dom/pattern/allchildren.js
new file mode 100644
index 0000000..36abae4
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/allchildren.js
@@ -0,0 +1,72 @@
+// 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 any children of a tag.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.AllChildren');
+
+goog.require('goog.dom.pattern.AbstractPattern');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches any nodes at or below the current tree depth.
+ *
+ * @constructor
+ * @extends {goog.dom.pattern.AbstractPattern}
+ */
+goog.dom.pattern.AllChildren = function() {
+  /**
+   * Tracks the matcher's depth to detect the end of the tag.
+   *
+   * @private {number}
+   */
+  this.depth_ = 0;
+};
+goog.inherits(goog.dom.pattern.AllChildren, goog.dom.pattern.AbstractPattern);
+
+
+/**
+ * Test whether the given token is on the same level.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} {@code MATCHING} if the token is on the
+ *     same level or deeper and {@code BACKTRACK_MATCH} if not.
+ * @override
+ */
+goog.dom.pattern.AllChildren.prototype.matchToken = function(token, type) {
+  this.depth_ += type;
+
+  if (this.depth_ >= 0) {
+    return goog.dom.pattern.MatchType.MATCHING;
+  } else {
+    this.depth_ = 0;
+    return goog.dom.pattern.MatchType.BACKTRACK_MATCH;
+  }
+};
+
+
+/**
+ * Reset any internal state this pattern keeps.
+ * @override
+ */
+goog.dom.pattern.AllChildren.prototype.reset = function() {
+  this.depth_ = 0;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/callback/callback.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/callback/callback.js b/externs/GCL/externs/goog/dom/pattern/callback/callback.js
new file mode 100644
index 0000000..7d7aa60
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/callback/callback.js
@@ -0,0 +1,82 @@
+// 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 Useful callback functions for the DOM matcher.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.callback');
+
+goog.require('goog.dom');
+goog.require('goog.dom.TagWalkType');
+goog.require('goog.iter');
+
+
+/**
+ * Callback function for use in {@link goog.dom.pattern.Matcher.addPattern}
+ * that removes the matched node from the tree.  Should be used in conjunciton
+ * with a {@link goog.dom.pattern.StartTag} pattern.
+ *
+ * @param {Node} node The node matched by the pattern.
+ * @param {goog.dom.TagIterator} position The position where the match
+ *     finished.
+ * @return {boolean} Returns true to indicate tree changes were made.
+ */
+goog.dom.pattern.callback.removeNode = function(node, position) {
+  // Find out which position would be next.
+  position.setPosition(node, goog.dom.TagWalkType.END_TAG);
+
+  goog.iter.nextOrValue(position, null);
+
+  // Remove the node.
+  goog.dom.removeNode(node);
+
+  // Correct for the depth change.
+  position.depth -= 1;
+
+  // Indicate that we made position/tree changes.
+  return true;
+};
+
+
+/**
+ * Callback function for use in {@link goog.dom.pattern.Matcher.addPattern}
+ * that removes the matched node from the tree and replaces it with its
+ * children.  Should be used in conjunction with a
+ * {@link goog.dom.pattern.StartTag} pattern.
+ *
+ * @param {Element} node The node matched by the pattern.
+ * @param {goog.dom.TagIterator} position The position where the match
+ *     finished.
+ * @return {boolean} Returns true to indicate tree changes were made.
+ */
+goog.dom.pattern.callback.flattenElement = function(node, position) {
+  // Find out which position would be next.
+  position.setPosition(node, node.firstChild ?
+      goog.dom.TagWalkType.START_TAG :
+      goog.dom.TagWalkType.END_TAG);
+
+  goog.iter.nextOrValue(position, null);
+
+  // Flatten the node.
+  goog.dom.flattenElement(node);
+
+  // Correct for the depth change.
+  position.depth -= 1;
+
+  // Indicate that we made position/tree changes.
+  return true;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/callback/counter.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/callback/counter.js b/externs/GCL/externs/goog/dom/pattern/callback/counter.js
new file mode 100644
index 0000000..7e9a7aa
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/callback/counter.js
@@ -0,0 +1,69 @@
+// 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 Callback object that counts matches.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.callback.Counter');
+
+
+
+/**
+ * Callback class for counting matches.
+ * @constructor
+ * @final
+ */
+goog.dom.pattern.callback.Counter = function() {
+  /**
+   * The count of objects matched so far.
+   *
+   * @type {number}
+   */
+  this.count = 0;
+
+  /**
+   * The callback function.  Suitable as a callback for
+   * {@link goog.dom.pattern.Matcher}.
+   * @private {Function}
+   */
+  this.callback_ = null;
+};
+
+
+/**
+ * Get a bound callback function that is suitable as a callback for
+ * {@link goog.dom.pattern.Matcher}.
+ *
+ * @return {!Function} A callback function.
+ */
+goog.dom.pattern.callback.Counter.prototype.getCallback = function() {
+  if (!this.callback_) {
+    this.callback_ = goog.bind(function() {
+      this.count++;
+      return false;
+    }, this);
+  }
+  return this.callback_;
+};
+
+
+/**
+ * Reset the counter.
+ */
+goog.dom.pattern.callback.Counter.prototype.reset = function() {
+  this.count = 0;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/childmatches.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/childmatches.js b/externs/GCL/externs/goog/dom/pattern/childmatches.js
new file mode 100644
index 0000000..72d6674
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/childmatches.js
@@ -0,0 +1,145 @@
+// 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 any children of a tag, and
+ * specifically collect those that match a child pattern.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.ChildMatches');
+
+goog.require('goog.dom.pattern.AllChildren');
+goog.require('goog.dom.pattern.MatchType');
+
+
+
+/**
+ * Pattern object that matches any nodes at or below the current tree depth.
+ *
+ * @param {goog.dom.pattern.AbstractPattern} childPattern Pattern to collect
+ *     child matches of.
+ * @param {number=} opt_minimumMatches Enforce a minimum nuber of matches.
+ *     Defaults to 0.
+ * @constructor
+ * @extends {goog.dom.pattern.AllChildren}
+ * @final
+ */
+goog.dom.pattern.ChildMatches = function(childPattern, opt_minimumMatches) {
+  /**
+   * The child pattern to collect matches from.
+   *
+   * @private {goog.dom.pattern.AbstractPattern}
+   */
+  this.childPattern_ = childPattern;
+
+  /**
+   * Array of matched child nodes.
+   *
+   * @type {Array<Node>}
+   */
+  this.matches = [];
+
+  /**
+   * Minimum number of matches.
+   *
+   * @private {number}
+   */
+  this.minimumMatches_ = opt_minimumMatches || 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.dom.pattern.ChildMatches.base(this, 'constructor');
+};
+goog.inherits(goog.dom.pattern.ChildMatches, goog.dom.pattern.AllChildren);
+
+
+/**
+ * Test whether the given token is on the same level.
+ *
+ * @param {Node} token Token to match against.
+ * @param {goog.dom.TagWalkType} type The type of token.
+ * @return {goog.dom.pattern.MatchType} {@code MATCHING} if the token is on the
+ *     same level or deeper and {@code BACKTRACK_MATCH} if not.
+ * @override
+ */
+goog.dom.pattern.ChildMatches.prototype.matchToken = function(token, type) {
+  // Defer resets so we maintain our matches array until the last possible time.
+  if (this.needsReset_) {
+    this.reset();
+  }
+
+  // Call the super-method to ensure we stay in the child tree.
+  var status =
+      goog.dom.pattern.AllChildren.prototype.matchToken.apply(this, arguments);
+
+  switch (status) {
+    case goog.dom.pattern.MatchType.MATCHING:
+      var backtrack = false;
+
+      switch (this.childPattern_.matchToken(token, type)) {
+        case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
+          backtrack = true;
+        case goog.dom.pattern.MatchType.MATCH:
+          // Collect the match.
+          this.matches.push(this.childPattern_.matchedNode);
+          break;
+
+        default:
+          // Keep trying if we haven't hit a terminal state.
+          break;
+      }
+
+      if (backtrack) {
+        // The only interesting result is a MATCH, since BACKTRACK_MATCH means
+        // we are hitting an infinite loop on something like a Repeat(0).
+        if (this.childPattern_.matchToken(token, type) ==
+            goog.dom.pattern.MatchType.MATCH) {
+          this.matches.push(this.childPattern_.matchedNode);
+        }
+      }
+      return goog.dom.pattern.MatchType.MATCHING;
+
+    case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
+      // TODO(robbyw): this should return something like BACKTRACK_NO_MATCH
+      // when we don't meet our minimum.
+      this.needsReset_ = true;
+      return (this.matches.length >= this.minimumMatches_) ?
+             goog.dom.pattern.MatchType.BACKTRACK_MATCH :
+             goog.dom.pattern.MatchType.NO_MATCH;
+
+    default:
+      this.needsReset_ = true;
+      return status;
+  }
+};
+
+
+/**
+ * Reset any internal state this pattern keeps.
+ * @override
+ */
+goog.dom.pattern.ChildMatches.prototype.reset = function() {
+  this.needsReset_ = false;
+  this.matches.length = 0;
+  this.childPattern_.reset();
+  goog.dom.pattern.AllChildren.prototype.reset.call(this);
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/endtag.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/endtag.js b/externs/GCL/externs/goog/dom/pattern/endtag.js
new file mode 100644
index 0000000..409f952
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/endtag.js
@@ -0,0 +1,54 @@
+// 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 end of a tag.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.EndTag');
+
+goog.require('goog.dom.TagWalkType');
+goog.require('goog.dom.pattern.Tag');
+
+
+
+/**
+ * Pattern object that matches a closing 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}
+ * @final
+ */
+goog.dom.pattern.EndTag = function(tag, opt_attrs, opt_styles, opt_test) {
+  goog.dom.pattern.Tag.call(
+      this,
+      tag,
+      goog.dom.TagWalkType.END_TAG,
+      opt_attrs,
+      opt_styles,
+      opt_test);
+};
+goog.inherits(goog.dom.pattern.EndTag, goog.dom.pattern.Tag);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/fulltag.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/fulltag.js b/externs/GCL/externs/goog/dom/pattern/fulltag.js
new file mode 100644
index 0000000..d12ded1
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/fulltag.js
@@ -0,0 +1,88 @@
+// 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.FullTag');
+
+goog.require('goog.dom.pattern.MatchType');
+goog.require('goog.dom.pattern.StartTag');
+goog.require('goog.dom.pattern.Tag');
+
+
+
+/**
+ * Pattern object that matches a full tag including all its children.
+ *
+ * @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.StartTag}
+ * @final
+ */
+goog.dom.pattern.FullTag = function(tag, opt_attrs, opt_styles, opt_test) {
+  /**
+   * Tracks the matcher's depth to detect the end of the tag.
+   *
+   * @private {number}
+   */
+  this.depth_ = 0;
+
+  goog.dom.pattern.FullTag.base(
+      this, 'constructor', tag, opt_attrs, opt_styles, opt_test);
+};
+goog.inherits(goog.dom.pattern.FullTag, goog.dom.pattern.StartTag);
+
+
+/**
+ * Test whether the given token is a start 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> at the end of our
+ *    tag, <code>MATCHING</code> if we are within the tag, and
+ *    <code>NO_MATCH</code> if the starting tag does not match.
+ * @override
+ */
+goog.dom.pattern.FullTag.prototype.matchToken = function(token, type) {
+  if (!this.depth_) {
+    // If we have not yet started, make sure we match as a StartTag.
+    if (goog.dom.pattern.Tag.prototype.matchToken.call(this, token, type)) {
+      this.depth_ = type;
+      return goog.dom.pattern.MatchType.MATCHING;
+
+    } else {
+      return goog.dom.pattern.MatchType.NO_MATCH;
+    }
+  } else {
+    this.depth_ += type;
+
+    return this.depth_ ?
+           goog.dom.pattern.MatchType.MATCHING :
+           goog.dom.pattern.MatchType.MATCH;
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/pattern/matcher.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/pattern/matcher.js b/externs/GCL/externs/goog/dom/pattern/matcher.js
new file mode 100644
index 0000000..ea4a1e5
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/pattern/matcher.js
@@ -0,0 +1,144 @@
+// 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 matcher.  Allows for simple searching of DOM
+ * using patterns descended from {@link goog.dom.pattern.AbstractPattern}.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+goog.provide('goog.dom.pattern.Matcher');
+
+goog.require('goog.dom.TagIterator');
+goog.require('goog.dom.pattern.MatchType');
+goog.require('goog.iter');
+
+
+// TODO(robbyw): Allow for backtracks of size > 1.
+
+
+
+/**
+ * Given a set of patterns and a root node, this class tests the patterns in
+ * parallel.
+ *
+ * It is not (yet) a smart matcher - it doesn't do any advanced backtracking.
+ * Given the pattern <code>DIV, SPAN</code> the matcher will not match
+ * <code>DIV, DIV, SPAN</code> because it starts matching at the first
+ * <code>DIV</code>, fails to match <code>SPAN</code> at the second, and never
+ * backtracks to try again.
+ *
+ * It is also possible to have a set of complex patterns that when matched in
+ * parallel will miss some possible matches.  Running multiple times will catch
+ * all matches eventually.
+ *
+ * @constructor
+ * @final
+ */
+goog.dom.pattern.Matcher = function() {
+  /**
+   * Array of patterns to attempt to match in parallel.
+   *
+   * @private {Array<goog.dom.pattern.AbstractPattern>}
+   */
+  this.patterns_ = [];
+
+  /**
+   * Array of callbacks to call when a pattern is matched.  The indexing is the
+   * same as the {@link #patterns_} array.
+   *
+   * @private {Array<Function>}
+   */
+  this.callbacks_ = [];
+};
+
+
+/**
+ * Adds a pattern to be matched.  The callback can return an object whose keys
+ * are processing instructions.
+ *
+ * @param {goog.dom.pattern.AbstractPattern} pattern The pattern to add.
+ * @param {Function} callback Function to call when a match is found.  Uses
+ *     the above semantics.
+ */
+goog.dom.pattern.Matcher.prototype.addPattern = function(pattern, callback) {
+  this.patterns_.push(pattern);
+  this.callbacks_.push(callback);
+};
+
+
+/**
+ * Resets all the patterns.
+ *
+ * @private
+ */
+goog.dom.pattern.Matcher.prototype.reset_ = function() {
+  for (var i = 0, len = this.patterns_.length; i < len; i++) {
+    this.patterns_[i].reset();
+  }
+};
+
+
+/**
+ * Test the given node against all patterns.
+ *
+ * @param {goog.dom.TagIterator} position A position in a node walk that is
+ *     located at the token to process.
+ * @return {boolean} Whether a pattern modified the position or tree
+ *     and its callback resulted in DOM structure or position modification.
+ * @private
+ */
+goog.dom.pattern.Matcher.prototype.matchToken_ = function(position) {
+  for (var i = 0, len = this.patterns_.length; i < len; i++) {
+    var pattern = this.patterns_[i];
+    switch (pattern.matchToken(position.node, position.tagType)) {
+      case goog.dom.pattern.MatchType.MATCH:
+      case goog.dom.pattern.MatchType.BACKTRACK_MATCH:
+        var callback = this.callbacks_[i];
+
+        // Callbacks are allowed to modify the current position, but must
+        // return true if the do.
+        if (callback(pattern.matchedNode, position, pattern)) {
+          return true;
+        }
+
+      default:
+        // Do nothing.
+        break;
+    }
+  }
+
+  return false;
+};
+
+
+/**
+ * Match the set of patterns against a match tree.
+ *
+ * @param {Node} node The root node of the tree to match.
+ */
+goog.dom.pattern.Matcher.prototype.match = function(node) {
+  var position = new goog.dom.TagIterator(node);
+
+  this.reset_();
+
+  goog.iter.forEach(position, function() {
+    while (this.matchToken_(position)) {
+      // Since we've moved, our old pattern statuses don't make sense any more.
+      // Reset them.
+      this.reset_();
+    }
+  }, this);
+};