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

[33/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/demos/samplecomponent.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/demos/samplecomponent.js b/externs/GCL/externs/goog/demos/samplecomponent.js
new file mode 100644
index 0000000..14d3a15
--- /dev/null
+++ b/externs/GCL/externs/goog/demos/samplecomponent.js
@@ -0,0 +1,189 @@
+// 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 simple, sample component.
+ *
+ */
+goog.provide('goog.demos.SampleComponent');
+
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.dom.classlist');
+goog.require('goog.events.EventType');
+goog.require('goog.events.KeyCodes');
+goog.require('goog.events.KeyHandler');
+goog.require('goog.ui.Component');
+
+
+
+/**
+ * A simple box that changes colour when clicked. This class demonstrates the
+ * goog.ui.Component API, and is keyboard accessible, as per
+ * http://wiki/Main/ClosureKeyboardAccessible
+ *
+ * @param {string=} opt_label A label to display. Defaults to "Click Me" if none
+ *     provided.
+ * @param {goog.dom.DomHelper=} opt_domHelper DOM helper to use.
+ *
+ * @extends {goog.ui.Component}
+ * @constructor
+ * @final
+ */
+goog.demos.SampleComponent = function(opt_label, opt_domHelper) {
+  goog.demos.SampleComponent.base(this, 'constructor', opt_domHelper);
+
+  /**
+   * The label to display.
+   * @type {string}
+   * @private
+   */
+  this.initialLabel_ = opt_label || 'Click Me';
+
+  /**
+   * The current color.
+   * @type {string}
+   * @private
+   */
+  this.color_ = 'red';
+
+  /**
+   * Keyboard handler for this object. This object is created once the
+   * component's DOM element is known.
+   *
+   * @type {goog.events.KeyHandler?}
+   * @private
+   */
+  this.kh_ = null;
+};
+goog.inherits(goog.demos.SampleComponent, goog.ui.Component);
+
+
+/**
+ * Changes the color of the element.
+ * @private
+ */
+goog.demos.SampleComponent.prototype.changeColor_ = function() {
+  if (this.color_ == 'red') {
+    this.color_ = 'green';
+  } else if (this.color_ == 'green') {
+    this.color_ = 'blue';
+  } else {
+    this.color_ = 'red';
+  }
+  this.getElement().style.backgroundColor = this.color_;
+};
+
+
+/**
+ * Creates an initial DOM representation for the component.
+ * @override
+ */
+goog.demos.SampleComponent.prototype.createDom = function() {
+  this.decorateInternal(this.dom_.createElement(goog.dom.TagName.DIV));
+};
+
+
+/**
+ * Decorates an existing HTML DIV element as a SampleComponent.
+ *
+ * @param {Element} element The DIV element to decorate. The element's
+ *    text, if any will be used as the component's label.
+ * @override
+ */
+goog.demos.SampleComponent.prototype.decorateInternal = function(element) {
+  goog.demos.SampleComponent.base(this, 'decorateInternal', element);
+  if (!this.getLabelText()) {
+    this.setLabelText(this.initialLabel_);
+  }
+
+  var elem = this.getElement();
+  goog.dom.classlist.add(elem, goog.getCssName('goog-sample-component'));
+  elem.style.backgroundColor = this.color_;
+  elem.tabIndex = 0;
+
+  this.kh_ = new goog.events.KeyHandler(elem);
+  this.getHandler().listen(this.kh_, goog.events.KeyHandler.EventType.KEY,
+      this.onKey_);
+};
+
+
+/** @override */
+goog.demos.SampleComponent.prototype.disposeInternal = function() {
+  goog.demos.SampleComponent.base(this, 'disposeInternal');
+  if (this.kh_) {
+    this.kh_.dispose();
+  }
+};
+
+
+/**
+ * Called when component's element is known to be in the document.
+ * @override
+ */
+goog.demos.SampleComponent.prototype.enterDocument = function() {
+  goog.demos.SampleComponent.base(this, 'enterDocument');
+  this.getHandler().listen(this.getElement(), goog.events.EventType.CLICK,
+      this.onDivClicked_);
+};
+
+
+/**
+ * Gets the current label text.
+ *
+ * @return {string} The current text set into the label, or empty string if
+ *     none set.
+ */
+goog.demos.SampleComponent.prototype.getLabelText = function() {
+  if (!this.getElement()) {
+    return '';
+  }
+  return goog.dom.getTextContent(this.getElement());
+};
+
+
+/**
+ * Handles DIV element clicks, causing the DIV's colour to change.
+ * @param {goog.events.Event} event The click event.
+ * @private
+ */
+goog.demos.SampleComponent.prototype.onDivClicked_ = function(event) {
+  this.changeColor_();
+};
+
+
+/**
+ * Fired when user presses a key while the DIV has focus. If the user presses
+ * space or enter, the color will be changed.
+ * @param {goog.events.Event} event The key event.
+ * @private
+ */
+goog.demos.SampleComponent.prototype.onKey_ = function(event) {
+  var keyCodes = goog.events.KeyCodes;
+  if (event.keyCode == keyCodes.SPACE || event.keyCode == keyCodes.ENTER) {
+    this.changeColor_();
+  }
+};
+
+
+/**
+ * Sets the current label text. Has no effect if component is not rendered.
+ *
+ * @param {string} text The text to set as the label.
+ */
+goog.demos.SampleComponent.prototype.setLabelText = function(text) {
+  if (this.getElement()) {
+    goog.dom.setTextContent(this.getElement(), text);
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/demos/xpc/xpcdemo.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/demos/xpc/xpcdemo.js b/externs/GCL/externs/goog/demos/xpc/xpcdemo.js
new file mode 100644
index 0000000..1e403ee
--- /dev/null
+++ b/externs/GCL/externs/goog/demos/xpc/xpcdemo.js
@@ -0,0 +1,308 @@
+// 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 Contains application code for the XPC demo.
+ * This script is used in both the container page and the iframe.
+ *
+ */
+
+goog.require('goog.Uri');
+goog.require('goog.dom');
+goog.require('goog.dom.TagName');
+goog.require('goog.events');
+goog.require('goog.events.EventType');
+goog.require('goog.json');
+goog.require('goog.log');
+goog.require('goog.log.Level');
+goog.require('goog.net.xpc.CfgFields');
+goog.require('goog.net.xpc.CrossPageChannel');
+
+
+/**
+ * Namespace for the demo. We don't use goog.provide here because it's not a
+ * real module (cannot be required).
+ */
+var xpcdemo = {};
+
+
+/**
+ * Global function to kick off initialization in the containing document.
+ */
+goog.global.initOuter = function() {
+  goog.events.listen(window, 'load', function() { xpcdemo.initOuter(); });
+};
+
+
+/**
+ * Global function to kick off initialization in the iframe.
+ */
+goog.global.initInner = function() {
+  goog.events.listen(window, 'load', function() { xpcdemo.initInner(); });
+};
+
+
+/**
+ * Initializes XPC in the containing page.
+ */
+xpcdemo.initOuter = function() {
+  // Build the configuration object.
+  var cfg = {};
+
+  var ownUri = new goog.Uri(window.location.href);
+  var relayUri = ownUri.resolve(new goog.Uri('relay.html'));
+  var pollUri = ownUri.resolve(new goog.Uri('blank.html'));
+
+  // Determine the peer domain. Uses the value of the URI-parameter
+  // 'peerdomain'. If that parameter is not present, it falls back to
+  // the own domain so that the demo will work out of the box (but
+  // communication will of course not cross domain-boundaries).  For
+  // real cross-domain communication, the easiest way is to point two
+  // different host-names to the same webserver and then hit the
+  // following URI:
+  // http://host1.com/path/to/closure/demos/xpc/index.html?peerdomain=host2.com
+  var peerDomain = ownUri.getParameterValue('peerdomain') || ownUri.getDomain();
+
+  cfg[goog.net.xpc.CfgFields.LOCAL_RELAY_URI] = relayUri.toString();
+  cfg[goog.net.xpc.CfgFields.PEER_RELAY_URI] =
+      relayUri.setDomain(peerDomain).toString();
+
+  cfg[goog.net.xpc.CfgFields.LOCAL_POLL_URI] = pollUri.toString();
+  cfg[goog.net.xpc.CfgFields.PEER_POLL_URI] =
+      pollUri.setDomain(peerDomain).toString();
+
+
+  // Force transport to be used if tp-parameter is set.
+  var tp = ownUri.getParameterValue('tp');
+  if (tp) {
+    cfg[goog.net.xpc.CfgFields.TRANSPORT] = parseInt(tp, 10);
+  }
+
+
+  // Construct the URI of the peer page.
+
+  var peerUri = ownUri.resolve(
+      new goog.Uri('inner.html')).setDomain(peerDomain);
+  // Passthrough of verbose and compiled flags.
+  if (goog.isDef(ownUri.getParameterValue('verbose'))) {
+    peerUri.setParameterValue('verbose', '');
+  }
+  if (goog.isDef(ownUri.getParameterValue('compiled'))) {
+    peerUri.setParameterValue('compiled', '');
+  }
+
+  cfg[goog.net.xpc.CfgFields.PEER_URI] = peerUri;
+
+  // Instantiate the channel.
+  xpcdemo.channel = new goog.net.xpc.CrossPageChannel(cfg);
+
+  // Create the peer iframe.
+  xpcdemo.peerIframe = xpcdemo.channel.createPeerIframe(
+      goog.dom.getElement('iframeContainer'));
+
+  xpcdemo.initCommon_();
+
+  goog.dom.getElement('inactive').style.display = 'none';
+  goog.dom.getElement('active').style.display = '';
+};
+
+
+/**
+ * Initialization in the iframe.
+ */
+xpcdemo.initInner = function() {
+  // Get the channel configuration passed by the containing document.
+  var cfg = goog.json.parse(
+      (new goog.Uri(window.location.href)).getParameterValue('xpc'));
+
+  xpcdemo.channel = new goog.net.xpc.CrossPageChannel(cfg);
+
+  xpcdemo.initCommon_();
+};
+
+
+/**
+ * Initializes the demo.
+ * Registers service-handlers and connects the channel.
+ * @private
+ */
+xpcdemo.initCommon_ = function() {
+  var xpcLogger = goog.log.getLogger('goog.net.xpc');
+  goog.log.addHandler(xpcLogger, function(logRecord) {
+    xpcdemo.log('[XPC] ' + logRecord.getMessage());
+  });
+  xpcLogger.setLevel(window.location.href.match(/verbose/) ?
+      goog.log.Level.ALL : goog.log.Level.INFO);
+
+  // Register services.
+  xpcdemo.channel.registerService('log', xpcdemo.log);
+  xpcdemo.channel.registerService('ping', xpcdemo.pingHandler_);
+  xpcdemo.channel.registerService('events', xpcdemo.eventsMsgHandler_);
+
+  // Connect the channel.
+  xpcdemo.channel.connect(function() {
+    xpcdemo.channel.send('log', 'Hi from ' + window.location.host);
+    goog.events.listen(goog.dom.getElement('clickfwd'),
+                       'click', xpcdemo.mouseEventHandler_);
+  });
+};
+
+
+/**
+ * Kills the peer iframe and the disposes the channel.
+ */
+xpcdemo.teardown = function() {
+  goog.events.unlisten(goog.dom.getElement('clickfwd'),
+                       goog.events.EventType.CLICK, xpcdemo.mouseEventHandler_);
+
+  xpcdemo.channel.dispose();
+  delete xpcdemo.channel;
+
+  goog.dom.removeNode(xpcdemo.peerIframe);
+  xpcdemo.peerIframe = null;
+
+  goog.dom.getElement('inactive').style.display = '';
+  goog.dom.getElement('active').style.display = 'none';
+};
+
+
+/**
+ * Logging function. Inserts log-message into element with it id 'console'.
+ * @param {string} msgString The log-message.
+ */
+xpcdemo.log = function(msgString) {
+  xpcdemo.consoleElm || (xpcdemo.consoleElm = goog.dom.getElement('console'));
+  var msgElm = goog.dom.createDom(goog.dom.TagName.DIV);
+  msgElm.innerHTML = msgString;
+  xpcdemo.consoleElm.insertBefore(msgElm, xpcdemo.consoleElm.firstChild);
+};
+
+
+/**
+ * Sends a ping request to the peer.
+ */
+xpcdemo.ping = function() {
+  // send current time
+  xpcdemo.channel.send('ping', goog.now() + '');
+};
+
+
+/**
+ * The handler function for incoming pings (messages sent to the service
+ * called 'ping');
+ * @param {string} payload The message payload.
+ * @private
+ */
+xpcdemo.pingHandler_ = function(payload) {
+  // is the incoming message a response to a ping we sent?
+  if (payload.charAt(0) == '#') {
+    // calculate roundtrip time and log
+    var dt = goog.now() - parseInt(payload.substring(1), 10);
+    xpcdemo.log('roundtrip: ' + dt + 'ms');
+  } else {
+    // incoming message is a ping initiated from peer
+    // -> prepend with '#' and send back
+    xpcdemo.channel.send('ping', '#' + payload);
+    xpcdemo.log('ping reply sent');
+  }
+};
+
+
+/**
+ * Counter for mousemove events.
+ * @type {number}
+ * @private
+ */
+xpcdemo.mmCount_ = 0;
+
+
+/**
+ * Holds timestamp when the last mousemove rate has been logged.
+ * @type {number}
+ * @private
+ */
+xpcdemo.mmLastRateOutput_ = 0;
+
+
+/**
+ * Start mousemove event forwarding. Registers a listener on the document which
+ * sends them over the channel.
+ */
+xpcdemo.startMousemoveForwarding = function() {
+  goog.events.listen(document, goog.events.EventType.MOUSEMOVE,
+                     xpcdemo.mouseEventHandler_);
+  xpcdemo.mmLastRateOutput_ = goog.now();
+};
+
+
+/**
+ * Stop mousemove event forwarding.
+ */
+xpcdemo.stopMousemoveForwarding = function() {
+  goog.events.unlisten(document, goog.events.EventType.MOUSEMOVE,
+                       xpcdemo.mouseEventHandler_);
+};
+
+
+/**
+ * Function to be used as handler for mouse-events.
+ * @param {goog.events.BrowserEvent} e The mouse event.
+ * @private
+ */
+xpcdemo.mouseEventHandler_ = function(e) {
+  xpcdemo.channel.send('events',
+      [e.type, e.clientX, e.clientY, goog.now()].join(','));
+};
+
+
+/**
+ * Handler for the 'events' service.
+ * @param {string} payload The string returned from the xpcdemo.
+ * @private
+ */
+xpcdemo.eventsMsgHandler_ = function(payload) {
+  var now = goog.now();
+  var args = payload.split(',');
+  var type = args[0];
+  var pageX = args[1];
+  var pageY = args[2];
+  var time = parseInt(args[3], 10);
+
+  var msg = type + ': (' + pageX + ',' + pageY + '), latency: ' + (now - time);
+  xpcdemo.log(msg);
+
+  if (type == goog.events.EventType.MOUSEMOVE) {
+    xpcdemo.mmCount_++;
+    var dt = now - xpcdemo.mmLastRateOutput_;
+    if (dt > 1000) {
+      msg = 'RATE (mousemove/s): ' + (1000 * xpcdemo.mmCount_ / dt);
+      xpcdemo.log(msg);
+      xpcdemo.mmLastRateOutput_ = now;
+      xpcdemo.mmCount_ = 0;
+    }
+  }
+};
+
+
+/**
+ * Send multiple messages.
+ * @param {number} n The number of messages to send.
+ */
+xpcdemo.sendN = function(n) {
+  xpcdemo.count_ || (xpcdemo.count_ = 1);
+
+  for (var i = 0; i < n; i++) {
+    xpcdemo.channel.send('log', '' + xpcdemo.count_++);
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/disposable/disposable.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/disposable/disposable.js b/externs/GCL/externs/goog/disposable/disposable.js
new file mode 100644
index 0000000..d9c89d9
--- /dev/null
+++ b/externs/GCL/externs/goog/disposable/disposable.js
@@ -0,0 +1,307 @@
+// 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 Implements the disposable interface. The dispose method is used
+ * to clean up references and resources.
+ * @author arv@google.com (Erik Arvidsson)
+ */
+
+
+goog.provide('goog.Disposable');
+/** @suppress {extraProvide} */
+goog.provide('goog.dispose');
+/** @suppress {extraProvide} */
+goog.provide('goog.disposeAll');
+
+goog.require('goog.disposable.IDisposable');
+
+
+
+/**
+ * Class that provides the basic implementation for disposable objects. If your
+ * class holds one or more references to COM objects, DOM nodes, or other
+ * disposable objects, it should extend this class or implement the disposable
+ * interface (defined in goog.disposable.IDisposable).
+ * @constructor
+ * @implements {goog.disposable.IDisposable}
+ */
+goog.Disposable = function() {
+  if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
+    if (goog.Disposable.INCLUDE_STACK_ON_CREATION) {
+      this.creationStack = new Error().stack;
+    }
+    goog.Disposable.instances_[goog.getUid(this)] = this;
+  }
+  // Support sealing
+  this.disposed_ = this.disposed_;
+  this.onDisposeCallbacks_ = this.onDisposeCallbacks_;
+};
+
+
+/**
+ * @enum {number} Different monitoring modes for Disposable.
+ */
+goog.Disposable.MonitoringMode = {
+  /**
+   * No monitoring.
+   */
+  OFF: 0,
+  /**
+   * Creating and disposing the goog.Disposable instances is monitored. All
+   * disposable objects need to call the {@code goog.Disposable} base
+   * constructor. The PERMANENT mode must be switched on before creating any
+   * goog.Disposable instances.
+   */
+  PERMANENT: 1,
+  /**
+   * INTERACTIVE mode can be switched on and off on the fly without producing
+   * errors. It also doesn't warn if the disposable objects don't call the
+   * {@code goog.Disposable} base constructor.
+   */
+  INTERACTIVE: 2
+};
+
+
+/**
+ * @define {number} The monitoring mode of the goog.Disposable
+ *     instances. Default is OFF. Switching on the monitoring is only
+ *     recommended for debugging because it has a significant impact on
+ *     performance and memory usage. If switched off, the monitoring code
+ *     compiles down to 0 bytes.
+ */
+goog.define('goog.Disposable.MONITORING_MODE', 0);
+
+
+/**
+ * @define {boolean} Whether to attach creation stack to each created disposable
+ *     instance; This is only relevant for when MonitoringMode != OFF.
+ */
+goog.define('goog.Disposable.INCLUDE_STACK_ON_CREATION', true);
+
+
+/**
+ * Maps the unique ID of every undisposed {@code goog.Disposable} object to
+ * the object itself.
+ * @type {!Object<number, !goog.Disposable>}
+ * @private
+ */
+goog.Disposable.instances_ = {};
+
+
+/**
+ * @return {!Array<!goog.Disposable>} All {@code goog.Disposable} objects that
+ *     haven't been disposed of.
+ */
+goog.Disposable.getUndisposedObjects = function() {
+  var ret = [];
+  for (var id in goog.Disposable.instances_) {
+    if (goog.Disposable.instances_.hasOwnProperty(id)) {
+      ret.push(goog.Disposable.instances_[Number(id)]);
+    }
+  }
+  return ret;
+};
+
+
+/**
+ * Clears the registry of undisposed objects but doesn't dispose of them.
+ */
+goog.Disposable.clearUndisposedObjects = function() {
+  goog.Disposable.instances_ = {};
+};
+
+
+/**
+ * Whether the object has been disposed of.
+ * @type {boolean}
+ * @private
+ */
+goog.Disposable.prototype.disposed_ = false;
+
+
+/**
+ * Callbacks to invoke when this object is disposed.
+ * @type {Array<!Function>}
+ * @private
+ */
+goog.Disposable.prototype.onDisposeCallbacks_;
+
+
+/**
+ * If monitoring the goog.Disposable instances is enabled, stores the creation
+ * stack trace of the Disposable instance.
+ * @const {string}
+ */
+goog.Disposable.prototype.creationStack;
+
+
+/**
+ * @return {boolean} Whether the object has been disposed of.
+ * @override
+ */
+goog.Disposable.prototype.isDisposed = function() {
+  return this.disposed_;
+};
+
+
+/**
+ * @return {boolean} Whether the object has been disposed of.
+ * @deprecated Use {@link #isDisposed} instead.
+ */
+goog.Disposable.prototype.getDisposed = goog.Disposable.prototype.isDisposed;
+
+
+/**
+ * Disposes of the object. If the object hasn't already been disposed of, calls
+ * {@link #disposeInternal}. Classes that extend {@code goog.Disposable} should
+ * override {@link #disposeInternal} in order to delete references to COM
+ * objects, DOM nodes, and other disposable objects. Reentrant.
+ *
+ * @return {void} Nothing.
+ * @override
+ */
+goog.Disposable.prototype.dispose = function() {
+  if (!this.disposed_) {
+    // Set disposed_ to true first, in case during the chain of disposal this
+    // gets disposed recursively.
+    this.disposed_ = true;
+    this.disposeInternal();
+    if (goog.Disposable.MONITORING_MODE != goog.Disposable.MonitoringMode.OFF) {
+      var uid = goog.getUid(this);
+      if (goog.Disposable.MONITORING_MODE ==
+          goog.Disposable.MonitoringMode.PERMANENT &&
+          !goog.Disposable.instances_.hasOwnProperty(uid)) {
+        throw Error(this + ' did not call the goog.Disposable base ' +
+            'constructor or was disposed of after a clearUndisposedObjects ' +
+            'call');
+      }
+      delete goog.Disposable.instances_[uid];
+    }
+  }
+};
+
+
+/**
+ * Associates a disposable object with this object so that they will be disposed
+ * together.
+ * @param {goog.disposable.IDisposable} disposable that will be disposed when
+ *     this object is disposed.
+ */
+goog.Disposable.prototype.registerDisposable = function(disposable) {
+  this.addOnDisposeCallback(goog.partial(goog.dispose, disposable));
+};
+
+
+/**
+ * Invokes a callback function when this object is disposed. Callbacks are
+ * invoked in the order in which they were added. If a callback is added to
+ * an already disposed Disposable, it will be called immediately.
+ * @param {function(this:T):?} callback The callback function.
+ * @param {T=} opt_scope An optional scope to call the callback in.
+ * @template T
+ */
+goog.Disposable.prototype.addOnDisposeCallback = function(callback, opt_scope) {
+  if (this.disposed_) {
+    callback.call(opt_scope);
+    return;
+  }
+  if (!this.onDisposeCallbacks_) {
+    this.onDisposeCallbacks_ = [];
+  }
+
+  this.onDisposeCallbacks_.push(
+      goog.isDef(opt_scope) ? goog.bind(callback, opt_scope) : callback);
+};
+
+
+/**
+ * Deletes or nulls out any references to COM objects, DOM nodes, or other
+ * disposable objects. Classes that extend {@code goog.Disposable} should
+ * override this method.
+ * Not reentrant. To avoid calling it twice, it must only be called from the
+ * subclass' {@code disposeInternal} method. Everywhere else the public
+ * {@code dispose} method must be used.
+ * For example:
+ * <pre>
+ *   mypackage.MyClass = function() {
+ *     mypackage.MyClass.base(this, 'constructor');
+ *     // Constructor logic specific to MyClass.
+ *     ...
+ *   };
+ *   goog.inherits(mypackage.MyClass, goog.Disposable);
+ *
+ *   mypackage.MyClass.prototype.disposeInternal = function() {
+ *     // Dispose logic specific to MyClass.
+ *     ...
+ *     // Call superclass's disposeInternal at the end of the subclass's, like
+ *     // in C++, to avoid hard-to-catch issues.
+ *     mypackage.MyClass.base(this, 'disposeInternal');
+ *   };
+ * </pre>
+ * @protected
+ */
+goog.Disposable.prototype.disposeInternal = function() {
+  if (this.onDisposeCallbacks_) {
+    while (this.onDisposeCallbacks_.length) {
+      this.onDisposeCallbacks_.shift()();
+    }
+  }
+};
+
+
+/**
+ * Returns True if we can verify the object is disposed.
+ * Calls {@code isDisposed} on the argument if it supports it.  If obj
+ * is not an object with an isDisposed() method, return false.
+ * @param {*} obj The object to investigate.
+ * @return {boolean} True if we can verify the object is disposed.
+ */
+goog.Disposable.isDisposed = function(obj) {
+  if (obj && typeof obj.isDisposed == 'function') {
+    return obj.isDisposed();
+  }
+  return false;
+};
+
+
+/**
+ * Calls {@code dispose} on the argument if it supports it. If obj is not an
+ *     object with a dispose() method, this is a no-op.
+ * @param {*} obj The object to dispose of.
+ */
+goog.dispose = function(obj) {
+  if (obj && typeof obj.dispose == 'function') {
+    obj.dispose();
+  }
+};
+
+
+/**
+ * Calls {@code dispose} on each member of the list that supports it. (If the
+ * member is an ArrayLike, then {@code goog.disposeAll()} will be called
+ * recursively on each of its members.) If the member is not an object with a
+ * {@code dispose()} method, then it is ignored.
+ * @param {...*} var_args The list.
+ */
+goog.disposeAll = function(var_args) {
+  for (var i = 0, len = arguments.length; i < len; ++i) {
+    var disposable = arguments[i];
+    if (goog.isArrayLike(disposable)) {
+      goog.disposeAll.apply(null, disposable);
+    } else {
+      goog.dispose(disposable);
+    }
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/disposable/idisposable.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/disposable/idisposable.js b/externs/GCL/externs/goog/disposable/idisposable.js
new file mode 100644
index 0000000..917d17e
--- /dev/null
+++ b/externs/GCL/externs/goog/disposable/idisposable.js
@@ -0,0 +1,45 @@
+// Copyright 2011 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 the disposable interface.  A disposable object
+ * has a dispose method to to clean up references and resources.
+ * @author nnaze@google.com (Nathan Naze)
+ */
+
+
+goog.provide('goog.disposable.IDisposable');
+
+
+
+/**
+ * Interface for a disposable object.  If a instance requires cleanup
+ * (references COM objects, DOM notes, or other disposable objects), it should
+ * implement this interface (it may subclass goog.Disposable).
+ * @interface
+ */
+goog.disposable.IDisposable = function() {};
+
+
+/**
+ * Disposes of the object and its resources.
+ * @return {void} Nothing.
+ */
+goog.disposable.IDisposable.prototype.dispose = goog.abstractMethod;
+
+
+/**
+ * @return {boolean} Whether the object has been disposed of.
+ */
+goog.disposable.IDisposable.prototype.isDisposed = goog.abstractMethod;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/abstractmultirange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/abstractmultirange.js b/externs/GCL/externs/goog/dom/abstractmultirange.js
new file mode 100644
index 0000000..d45d38d
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/abstractmultirange.js
@@ -0,0 +1,76 @@
+// 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 ranges comprised of multiple
+ * sub-ranges.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.AbstractMultiRange');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.dom.AbstractRange');
+
+
+
+/**
+ * Creates a new multi range with no properties.  Do not use this
+ * constructor: use one of the goog.dom.Range.createFrom* methods instead.
+ * @constructor
+ * @extends {goog.dom.AbstractRange}
+ */
+goog.dom.AbstractMultiRange = function() {
+};
+goog.inherits(goog.dom.AbstractMultiRange, goog.dom.AbstractRange);
+
+
+/** @override */
+goog.dom.AbstractMultiRange.prototype.containsRange = function(
+    otherRange, opt_allowPartial) {
+  // TODO(user): This will incorrectly return false if two (or more) adjacent
+  // elements are both in the control range, and are also in the text range
+  // being compared to.
+  var ranges = this.getTextRanges();
+  var otherRanges = otherRange.getTextRanges();
+
+  var fn = opt_allowPartial ? goog.array.some : goog.array.every;
+  return fn(otherRanges, function(otherRange) {
+    return goog.array.some(ranges, function(range) {
+      return range.containsRange(otherRange, opt_allowPartial);
+    });
+  });
+};
+
+
+/** @override */
+goog.dom.AbstractMultiRange.prototype.insertNode = function(node, before) {
+  if (before) {
+    goog.dom.insertSiblingBefore(node, this.getStartNode());
+  } else {
+    goog.dom.insertSiblingAfter(node, this.getEndNode());
+  }
+  return node;
+};
+
+
+/** @override */
+goog.dom.AbstractMultiRange.prototype.surroundWithNodes = function(startNode,
+    endNode) {
+  this.insertNode(startNode, true);
+  this.insertNode(endNode, false);
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/abstractrange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/abstractrange.js b/externs/GCL/externs/goog/dom/abstractrange.js
new file mode 100644
index 0000000..7d66bfb
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/abstractrange.js
@@ -0,0 +1,529 @@
+// 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 Interface definitions for working with ranges
+ * in HTML documents.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.AbstractRange');
+goog.provide('goog.dom.RangeIterator');
+goog.provide('goog.dom.RangeType');
+
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.SavedCaretRange');
+goog.require('goog.dom.TagIterator');
+goog.require('goog.userAgent');
+
+
+/**
+ * Types of ranges.
+ * @enum {string}
+ */
+goog.dom.RangeType = {
+  TEXT: 'text',
+  CONTROL: 'control',
+  MULTI: 'mutli'
+};
+
+
+
+/**
+ * Creates a new selection with no properties.  Do not use this constructor -
+ * use one of the goog.dom.Range.from* methods instead.
+ * @constructor
+ */
+goog.dom.AbstractRange = function() {
+};
+
+
+/**
+ * Gets the browser native selection object from the given window.
+ * @param {Window} win The window to get the selection object from.
+ * @return {Object} The browser native selection object, or null if it could
+ *     not be retrieved.
+ */
+goog.dom.AbstractRange.getBrowserSelectionForWindow = function(win) {
+  if (win.getSelection) {
+    // W3C
+    return win.getSelection();
+  } else {
+    // IE
+    var doc = win.document;
+    var sel = doc.selection;
+    if (sel) {
+      // IE has a bug where it sometimes returns a selection from the wrong
+      // document. Catching these cases now helps us avoid problems later.
+      try {
+        var range = sel.createRange();
+        // Only TextRanges have a parentElement method.
+        if (range.parentElement) {
+          if (range.parentElement().document != doc) {
+            return null;
+          }
+        } else if (!range.length ||
+            /** @type {ControlRange} */ (range).item(0).document != doc) {
+          // For ControlRanges, check that the range has items, and that
+          // the first item in the range is in the correct document.
+          return null;
+        }
+      } catch (e) {
+        // If the selection is in the wrong document, and the wrong document is
+        // in a different domain, IE will throw an exception.
+        return null;
+      }
+      // TODO(user|robbyw) Sometimes IE 6 returns a selection instance
+      // when there is no selection.  This object has a 'type' property equals
+      // to 'None' and a typeDetail property bound to undefined. Ideally this
+      // function should not return this instance.
+      return sel;
+    }
+    return null;
+  }
+};
+
+
+/**
+ * Tests if the given Object is a controlRange.
+ * @param {Object} range The range object to test.
+ * @return {boolean} Whether the given Object is a controlRange.
+ */
+goog.dom.AbstractRange.isNativeControlRange = function(range) {
+  // For now, tests for presence of a control range function.
+  return !!range && !!range.addElement;
+};
+
+
+/**
+ * @return {!goog.dom.AbstractRange} A clone of this range.
+ */
+goog.dom.AbstractRange.prototype.clone = goog.abstractMethod;
+
+
+/**
+ * @return {goog.dom.RangeType} The type of range represented by this object.
+ */
+goog.dom.AbstractRange.prototype.getType = goog.abstractMethod;
+
+
+/**
+ * @return {Range|TextRange} The native browser range object.
+ */
+goog.dom.AbstractRange.prototype.getBrowserRangeObject = goog.abstractMethod;
+
+
+/**
+ * Sets the native browser range object, overwriting any state this range was
+ * storing.
+ * @param {Range|TextRange} nativeRange The native browser range object.
+ * @return {boolean} Whether the given range was accepted.  If not, the caller
+ *     will need to call goog.dom.Range.createFromBrowserRange to create a new
+ *     range object.
+ */
+goog.dom.AbstractRange.prototype.setBrowserRangeObject = function(nativeRange) {
+  return false;
+};
+
+
+/**
+ * @return {number} The number of text ranges in this range.
+ */
+goog.dom.AbstractRange.prototype.getTextRangeCount = goog.abstractMethod;
+
+
+/**
+ * Get the i-th text range in this range.  The behavior is undefined if
+ * i >= getTextRangeCount or i < 0.
+ * @param {number} i The range number to retrieve.
+ * @return {goog.dom.TextRange} The i-th text range.
+ */
+goog.dom.AbstractRange.prototype.getTextRange = goog.abstractMethod;
+
+
+/**
+ * Gets an array of all text ranges this range is comprised of.  For non-multi
+ * ranges, returns a single element array containing this.
+ * @return {!Array<goog.dom.TextRange>} Array of text ranges.
+ */
+goog.dom.AbstractRange.prototype.getTextRanges = function() {
+  var output = [];
+  for (var i = 0, len = this.getTextRangeCount(); i < len; i++) {
+    output.push(this.getTextRange(i));
+  }
+  return output;
+};
+
+
+/**
+ * @return {Node} The deepest node that contains the entire range.
+ */
+goog.dom.AbstractRange.prototype.getContainer = goog.abstractMethod;
+
+
+/**
+ * Returns the deepest element in the tree that contains the entire range.
+ * @return {Element} The deepest element that contains the entire range.
+ */
+goog.dom.AbstractRange.prototype.getContainerElement = function() {
+  var node = this.getContainer();
+  return /** @type {Element} */ (
+      node.nodeType == goog.dom.NodeType.ELEMENT ? node : node.parentNode);
+};
+
+
+/**
+ * @return {Node} The element or text node the range starts in.  For text
+ *     ranges, the range comprises all text between the start and end position.
+ *     For other types of range, start and end give bounds of the range but
+ *     do not imply all nodes in those bounds are selected.
+ */
+goog.dom.AbstractRange.prototype.getStartNode = goog.abstractMethod;
+
+
+/**
+ * @return {number} The offset into the node the range starts in.  For text
+ *     nodes, this is an offset into the node value.  For elements, this is
+ *     an offset into the childNodes array.
+ */
+goog.dom.AbstractRange.prototype.getStartOffset = goog.abstractMethod;
+
+
+/**
+ * @return {goog.math.Coordinate} The coordinate of the selection start node
+ *     and offset.
+ */
+goog.dom.AbstractRange.prototype.getStartPosition = goog.abstractMethod;
+
+
+/**
+ * @return {Node} The element or text node the range ends in.
+ */
+goog.dom.AbstractRange.prototype.getEndNode = goog.abstractMethod;
+
+
+/**
+ * @return {number} The offset into the node the range ends in.  For text
+ *     nodes, this is an offset into the node value.  For elements, this is
+ *     an offset into the childNodes array.
+ */
+goog.dom.AbstractRange.prototype.getEndOffset = goog.abstractMethod;
+
+
+/**
+ * @return {goog.math.Coordinate} The coordinate of the selection end
+ *     node and offset.
+ */
+goog.dom.AbstractRange.prototype.getEndPosition = goog.abstractMethod;
+
+
+/**
+ * @return {Node} The element or text node the range is anchored at.
+ */
+goog.dom.AbstractRange.prototype.getAnchorNode = function() {
+  return this.isReversed() ? this.getEndNode() : this.getStartNode();
+};
+
+
+/**
+ * @return {number} The offset into the node the range is anchored at.  For
+ *     text nodes, this is an offset into the node value.  For elements, this
+ *     is an offset into the childNodes array.
+ */
+goog.dom.AbstractRange.prototype.getAnchorOffset = function() {
+  return this.isReversed() ? this.getEndOffset() : this.getStartOffset();
+};
+
+
+/**
+ * @return {Node} The element or text node the range is focused at - i.e. where
+ *     the cursor is.
+ */
+goog.dom.AbstractRange.prototype.getFocusNode = function() {
+  return this.isReversed() ? this.getStartNode() : this.getEndNode();
+};
+
+
+/**
+ * @return {number} The offset into the node the range is focused at - i.e.
+ *     where the cursor is.  For text nodes, this is an offset into the node
+ *     value.  For elements, this is an offset into the childNodes array.
+ */
+goog.dom.AbstractRange.prototype.getFocusOffset = function() {
+  return this.isReversed() ? this.getStartOffset() : this.getEndOffset();
+};
+
+
+/**
+ * @return {boolean} Whether the selection is reversed.
+ */
+goog.dom.AbstractRange.prototype.isReversed = function() {
+  return false;
+};
+
+
+/**
+ * @return {!Document} The document this selection is a part of.
+ */
+goog.dom.AbstractRange.prototype.getDocument = function() {
+  // Using start node in IE was crashing the browser in some cases so use
+  // getContainer for that browser. It's also faster for IE, but still slower
+  // than start node for other browsers so we continue to use getStartNode when
+  // it is not problematic. See bug 1687309.
+  return goog.dom.getOwnerDocument(goog.userAgent.IE ?
+      this.getContainer() : this.getStartNode());
+};
+
+
+/**
+ * @return {!Window} The window this selection is a part of.
+ */
+goog.dom.AbstractRange.prototype.getWindow = function() {
+  return goog.dom.getWindow(this.getDocument());
+};
+
+
+/**
+ * Tests if this range contains the given range.
+ * @param {goog.dom.AbstractRange} range The range to test.
+ * @param {boolean=} opt_allowPartial If true, the range can be partially
+ *     contained in the selection, otherwise the range must be entirely
+ *     contained.
+ * @return {boolean} Whether this range contains the given range.
+ */
+goog.dom.AbstractRange.prototype.containsRange = goog.abstractMethod;
+
+
+/**
+ * Tests if this range contains the given node.
+ * @param {Node} node The node to test for.
+ * @param {boolean=} opt_allowPartial If not set or false, the node must be
+ *     entirely contained in the selection for this function to return true.
+ * @return {boolean} Whether this range contains the given node.
+ */
+goog.dom.AbstractRange.prototype.containsNode = function(node,
+    opt_allowPartial) {
+  return this.containsRange(goog.dom.Range.createFromNodeContents(node),
+      opt_allowPartial);
+};
+
+
+/**
+ * Tests whether this range is valid (i.e. whether its endpoints are still in
+ * the document).  A range becomes invalid when, after this object was created,
+ * either one or both of its endpoints are removed from the document.  Use of
+ * an invalid range can lead to runtime errors, particularly in IE.
+ * @return {boolean} Whether the range is valid.
+ */
+goog.dom.AbstractRange.prototype.isRangeInDocument = goog.abstractMethod;
+
+
+/**
+ * @return {boolean} Whether the range is collapsed.
+ */
+goog.dom.AbstractRange.prototype.isCollapsed = goog.abstractMethod;
+
+
+/**
+ * @return {string} The text content of the range.
+ */
+goog.dom.AbstractRange.prototype.getText = goog.abstractMethod;
+
+
+/**
+ * Returns the HTML fragment this range selects.  This is slow on all browsers.
+ * The HTML fragment may not be valid HTML, for instance if the user selects
+ * from a to b inclusively in the following html:
+ *
+ * &gt;div&lt;a&gt;/div&lt;b
+ *
+ * This method will return
+ *
+ * a&lt;/div&gt;b
+ *
+ * If you need valid HTML, use {@link #getValidHtml} instead.
+ *
+ * @return {string} HTML fragment of the range, does not include context
+ *     containing elements.
+ */
+goog.dom.AbstractRange.prototype.getHtmlFragment = goog.abstractMethod;
+
+
+/**
+ * Returns valid HTML for this range.  This is fast on IE, and semi-fast on
+ * other browsers.
+ * @return {string} Valid HTML of the range, including context containing
+ *     elements.
+ */
+goog.dom.AbstractRange.prototype.getValidHtml = goog.abstractMethod;
+
+
+/**
+ * Returns pastable HTML for this range.  This guarantees that any child items
+ * that must have specific ancestors will have them, for instance all TDs will
+ * be contained in a TR in a TBODY in a TABLE and all LIs will be contained in
+ * a UL or OL as appropriate.  This is semi-fast on all browsers.
+ * @return {string} Pastable HTML of the range, including context containing
+ *     elements.
+ */
+goog.dom.AbstractRange.prototype.getPastableHtml = goog.abstractMethod;
+
+
+/**
+ * Returns a RangeIterator 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.RangeIterator} An iterator over tags in the range.
+ */
+goog.dom.AbstractRange.prototype.__iterator__ = goog.abstractMethod;
+
+
+// RANGE ACTIONS
+
+
+/**
+ * Sets this range as the selection in its window.
+ */
+goog.dom.AbstractRange.prototype.select = goog.abstractMethod;
+
+
+/**
+ * Removes the contents of the range from the document.
+ */
+goog.dom.AbstractRange.prototype.removeContents = goog.abstractMethod;
+
+
+/**
+ * Inserts a node before (or after) the range.  The range may be disrupted
+ * beyond recovery because of the way this splits nodes.
+ * @param {Node} node The node to insert.
+ * @param {boolean} before True to insert before, false to insert after.
+ * @return {Node} The node added to the document.  This may be different
+ *     than the node parameter because on IE we have to clone it.
+ */
+goog.dom.AbstractRange.prototype.insertNode = goog.abstractMethod;
+
+
+/**
+ * Replaces the range contents with (possibly a copy of) the given node.  The
+ * range may be disrupted beyond recovery because of the way this splits nodes.
+ * @param {Node} node The node to insert.
+ * @return {Node} The node added to the document.  This may be different
+ *     than the node parameter because on IE we have to clone it.
+ */
+goog.dom.AbstractRange.prototype.replaceContentsWithNode = function(node) {
+  if (!this.isCollapsed()) {
+    this.removeContents();
+  }
+
+  return this.insertNode(node, true);
+};
+
+
+/**
+ * Surrounds this range with the two given nodes.  The range may be disrupted
+ * beyond recovery because of the way this splits nodes.
+ * @param {Element} startNode The node to insert at the start.
+ * @param {Element} endNode The node to insert at the end.
+ */
+goog.dom.AbstractRange.prototype.surroundWithNodes = goog.abstractMethod;
+
+
+// SAVE/RESTORE
+
+
+/**
+ * Saves the range so that if the start and end nodes are left alone, it can
+ * be restored.
+ * @return {!goog.dom.SavedRange} A range representation that can be restored
+ *     as long as the endpoint nodes of the selection are not modified.
+ */
+goog.dom.AbstractRange.prototype.saveUsingDom = goog.abstractMethod;
+
+
+/**
+ * Saves the range using HTML carets. As long as the carets remained in the
+ * HTML, the range can be restored...even when the HTML is copied across
+ * documents.
+ * @return {goog.dom.SavedCaretRange?} A range representation that can be
+ *     restored as long as carets are not removed. Returns null if carets
+ *     could not be created.
+ */
+goog.dom.AbstractRange.prototype.saveUsingCarets = function() {
+  return (this.getStartNode() && this.getEndNode()) ?
+      new goog.dom.SavedCaretRange(this) : null;
+};
+
+
+// RANGE MODIFICATION
+
+
+/**
+ * Collapses the range to one of its boundary points.
+ * @param {boolean} toAnchor Whether to collapse to the anchor of the range.
+ */
+goog.dom.AbstractRange.prototype.collapse = goog.abstractMethod;
+
+// 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 {Node} node The node to start traversal at.  When null, creates an
+ *     empty iterator.
+ * @param {boolean=} opt_reverse Whether to traverse nodes in reverse.
+ * @constructor
+ * @extends {goog.dom.TagIterator}
+ */
+goog.dom.RangeIterator = function(node, opt_reverse) {
+  goog.dom.TagIterator.call(this, node, opt_reverse, true);
+};
+goog.inherits(goog.dom.RangeIterator, goog.dom.TagIterator);
+
+
+/**
+ * @return {number} The offset into the current node, or -1 if the current node
+ *     is not a text node.
+ */
+goog.dom.RangeIterator.prototype.getStartTextOffset = goog.abstractMethod;
+
+
+/**
+ * @return {number} The end offset into the current node, or -1 if the current
+ *     node is not a text node.
+ */
+goog.dom.RangeIterator.prototype.getEndTextOffset = goog.abstractMethod;
+
+
+/**
+ * @return {Node} node The iterator's start node.
+ */
+goog.dom.RangeIterator.prototype.getStartNode = goog.abstractMethod;
+
+
+/**
+ * @return {Node} The iterator's end node.
+ */
+goog.dom.RangeIterator.prototype.getEndNode = goog.abstractMethod;
+
+
+/**
+ * @return {boolean} Whether a call to next will fail.
+ */
+goog.dom.RangeIterator.prototype.isLast = goog.abstractMethod;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/animationframe/animationframe.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/animationframe/animationframe.js b/externs/GCL/externs/goog/dom/animationframe/animationframe.js
new file mode 100644
index 0000000..b9bccff
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/animationframe/animationframe.js
@@ -0,0 +1,287 @@
+// 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 goog.dom.animationFrame permits work to be done in-sync with
+ * the render refresh rate of the browser and to divide work up globally based
+ * on whether the intent is to measure or to mutate the DOM. The latter avoids
+ * repeated style recalculation which can be really slow.
+ *
+ * Goals of the API:
+ * <ul>
+ *   <li>Make it easy to schedule work for the next animation frame.
+ *   <li>Make it easy to only do work once per animation frame, even if two
+ *       events fire that trigger the same work.
+ *   <li>Make it easy to do all work in two phases to avoid repeated style
+ *       recalculation caused by interleaved reads and writes.
+ *   <li>Avoid creating closures per schedule operation.
+ * </ul>
+ *
+ *
+ * Programmatic:
+ * <pre>
+ * var animationTask = goog.dom.animationFrame.createTask({
+ *     measure: function(state) {
+ *       state.width = goog.style.getSize(elem).width;
+ *       this.animationTask();
+ *     },
+ *     mutate: function(state) {
+ *       goog.style.setWidth(elem, Math.floor(state.width / 2));
+ *     }
+ *   }, this);
+ * });
+ * </pre>
+ *
+ * See also
+ * https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame
+ */
+
+goog.provide('goog.dom.animationFrame');
+goog.provide('goog.dom.animationFrame.Spec');
+goog.provide('goog.dom.animationFrame.State');
+
+goog.require('goog.dom.animationFrame.polyfill');
+
+// Install the polyfill.
+goog.dom.animationFrame.polyfill.install();
+
+
+/**
+ * @typedef {{
+ *   id: number,
+ *   fn: !Function,
+ *   context: (!Object|undefined)
+ * }}
+ * @private
+ */
+goog.dom.animationFrame.Task_;
+
+
+/**
+ * @typedef {{
+ *   measureTask: goog.dom.animationFrame.Task_,
+ *   mutateTask: goog.dom.animationFrame.Task_,
+ *   state: (!Object|undefined),
+ *   args: (!Array|undefined),
+ *   isScheduled: boolean
+ * }}
+ * @private
+ */
+goog.dom.animationFrame.TaskSet_;
+
+
+/**
+ * @typedef {{
+ *   measure: (!Function|undefined),
+ *   mutate: (!Function|undefined)
+ * }}
+ */
+goog.dom.animationFrame.Spec;
+
+
+
+/**
+ * A type to represent state. Users may add properties as desired.
+ * @constructor
+ * @final
+ */
+goog.dom.animationFrame.State = function() {};
+
+
+/**
+ * Saves a set of tasks to be executed in the next requestAnimationFrame phase.
+ * This list is initialized once before any event firing occurs. It is not
+ * affected by the fired events or the requestAnimationFrame processing (unless
+ * a new event is created during the processing).
+ * @private {!Array<!Array<goog.dom.animationFrame.TaskSet_>>}
+ */
+goog.dom.animationFrame.tasks_ = [[], []];
+
+
+/**
+ * Values are 0 or 1, for whether the first or second array should be used to
+ * lookup or add tasks.
+ * @private {number}
+ */
+goog.dom.animationFrame.doubleBufferIndex_ = 0;
+
+
+/**
+ * Whether we have already requested an animation frame that hasn't happened
+ * yet.
+ * @private {boolean}
+ */
+goog.dom.animationFrame.requestedFrame_ = false;
+
+
+/**
+ * Counter to generate IDs for tasks.
+ * @private {number}
+ */
+goog.dom.animationFrame.taskId_ = 0;
+
+
+/**
+ * Whether the animationframe runTasks_ loop is currently running.
+ * @private {boolean}
+ */
+goog.dom.animationFrame.running_ = false;
+
+
+/**
+ * Returns a function that schedules the two passed-in functions to be run upon
+ * the next animation frame. Calling the function again during the same
+ * animation frame does nothing.
+ *
+ * The function under the "measure" key will run first and together with all
+ * other functions scheduled under this key and the function under "mutate" will
+ * run after that.
+ *
+ * @param {{
+ *   measure: (function(this:THIS, !goog.dom.animationFrame.State)|undefined),
+ *   mutate: (function(this:THIS, !goog.dom.animationFrame.State)|undefined)
+ * }} spec
+ * @param {THIS=} opt_context Context in which to run the function.
+ * @return {function(...?)}
+ * @template THIS
+ */
+goog.dom.animationFrame.createTask = function(spec, opt_context) {
+  var id = goog.dom.animationFrame.taskId_++;
+  var measureTask = {
+    id: id,
+    fn: spec.measure,
+    context: opt_context
+  };
+  var mutateTask = {
+    id: id,
+    fn: spec.mutate,
+    context: opt_context
+  };
+
+  var taskSet = {
+    measureTask: measureTask,
+    mutateTask: mutateTask,
+    state: {},
+    args: undefined,
+    isScheduled: false
+  };
+
+  return function() {
+    // Default the context to the one that was used to call the tasks scheduler
+    // (this function).
+    if (!opt_context) {
+      measureTask.context = this;
+      mutateTask.context = this;
+    }
+
+    // Save args and state.
+    if (arguments.length > 0) {
+      // The state argument goes last. That is kinda horrible but compatible
+      // with {@see wiz.async.method}.
+      if (!taskSet.args) {
+        taskSet.args = [];
+      }
+      taskSet.args.length = 0;
+      taskSet.args.push.apply(taskSet.args, arguments);
+      taskSet.args.push(taskSet.state);
+    } else {
+      if (!taskSet.args || taskSet.args.length == 0) {
+        taskSet.args = [taskSet.state];
+      } else {
+        taskSet.args[0] = taskSet.state;
+        taskSet.args.length = 1;
+      }
+    }
+    if (!taskSet.isScheduled) {
+      taskSet.isScheduled = true;
+      var tasksArray = goog.dom.animationFrame.tasks_[
+          goog.dom.animationFrame.doubleBufferIndex_];
+      tasksArray.push(taskSet);
+    }
+    goog.dom.animationFrame.requestAnimationFrame_();
+  };
+};
+
+
+/**
+ * Run scheduled tasks.
+ * @private
+ */
+goog.dom.animationFrame.runTasks_ = function() {
+  goog.dom.animationFrame.running_ = true;
+  goog.dom.animationFrame.requestedFrame_ = false;
+  var tasksArray = goog.dom.animationFrame
+                       .tasks_[goog.dom.animationFrame.doubleBufferIndex_];
+  var taskLength = tasksArray.length;
+
+  // During the runTasks_, if there is a recursive call to queue up more
+  // task(s) for the next frame, we use double-buffering for that.
+  goog.dom.animationFrame.doubleBufferIndex_ =
+      (goog.dom.animationFrame.doubleBufferIndex_ + 1) % 2;
+
+  var task;
+
+  // Run all the measure tasks first.
+  for (var i = 0; i < taskLength; ++i) {
+    task = tasksArray[i];
+    var measureTask = task.measureTask;
+    task.isScheduled = false;
+    if (measureTask.fn) {
+      // TODO (perumaal): Handle any exceptions thrown by the lambda.
+      measureTask.fn.apply(measureTask.context, task.args);
+    }
+  }
+
+  // Run the mutate tasks next.
+  for (var i = 0; i < taskLength; ++i) {
+    task = tasksArray[i];
+    var mutateTask = task.mutateTask;
+    task.isScheduled = false;
+    if (mutateTask.fn) {
+      // TODO (perumaal): Handle any exceptions thrown by the lambda.
+      mutateTask.fn.apply(mutateTask.context, task.args);
+    }
+
+    // Clear state for next vsync.
+    task.state = {};
+  }
+
+  // Clear the tasks array as we have finished processing all the tasks.
+  tasksArray.length = 0;
+  goog.dom.animationFrame.running_ = false;
+};
+
+
+/**
+ * @return {boolean} Whether the animationframe is currently running. For use
+ *     by callers who need not to delay tasks scheduled during runTasks_ for an
+ *     additional frame.
+ */
+goog.dom.animationFrame.isRunning = function() {
+  return goog.dom.animationFrame.running_;
+};
+
+
+/**
+ * Request {@see goog.dom.animationFrame.runTasks_} to be called upon the
+ * next animation frame if we haven't done so already.
+ * @private
+ */
+goog.dom.animationFrame.requestAnimationFrame_ = function() {
+  if (goog.dom.animationFrame.requestedFrame_) {
+    return;
+  }
+  goog.dom.animationFrame.requestedFrame_ = true;
+  window.requestAnimationFrame(goog.dom.animationFrame.runTasks_);
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/animationframe/polyfill.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/animationframe/polyfill.js b/externs/GCL/externs/goog/dom/animationframe/polyfill.js
new file mode 100644
index 0000000..19e8866
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/animationframe/polyfill.js
@@ -0,0 +1,61 @@
+// 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 A polyfill for window.requestAnimationFrame and
+ * window.cancelAnimationFrame.
+ * Code based on https://gist.github.com/paulirish/1579671
+ */
+
+goog.provide('goog.dom.animationFrame.polyfill');
+
+
+/**
+ * @define {boolean} If true, will install the requestAnimationFrame polyfill.
+ */
+goog.define('goog.dom.animationFrame.polyfill.ENABLED', true);
+
+
+/**
+ * Installs the requestAnimationFrame (and cancelAnimationFrame) polyfill.
+ */
+goog.dom.animationFrame.polyfill.install =
+    goog.dom.animationFrame.polyfill.ENABLED ? function() {
+  var vendors = ['ms', 'moz', 'webkit', 'o'];
+  for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
+    window.requestAnimationFrame = window[vendors[x] +
+        'RequestAnimationFrame'];
+    window.cancelAnimationFrame = window[vendors[x] +
+        'CancelAnimationFrame'] ||
+            window[vendors[x] + 'CancelRequestAnimationFrame'];
+  }
+
+  if (!window.requestAnimationFrame) {
+    var lastTime = 0;
+    window.requestAnimationFrame = function(callback, element) {
+      var currTime = new Date().getTime();
+      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
+      lastTime = currTime + timeToCall;
+      return window.setTimeout(function() {
+        callback(currTime + timeToCall);
+      }, timeToCall);
+    };
+
+    if (!window.cancelAnimationFrame) {
+      window.cancelAnimationFrame = function(id) {
+        clearTimeout(id);
+      };
+    }
+  }
+} : goog.nullFunction;

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/annotate.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/annotate.js b/externs/GCL/externs/goog/dom/annotate.js
new file mode 100644
index 0000000..7a772e8
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/annotate.js
@@ -0,0 +1,357 @@
+// 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 Methods for annotating occurrences of query terms in text or
+ *   in a DOM tree. Adapted from Gmail code.
+ *
+ */
+
+goog.provide('goog.dom.annotate');
+goog.provide('goog.dom.annotate.AnnotateFn');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.TagName');
+goog.require('goog.dom.safe');
+goog.require('goog.html.SafeHtml');
+
+
+/**
+ * A function that takes:
+ *   (1) the number of the term that is "hit",
+ *   (2) the HTML (search term) to be annotated,
+ * and returns the annotated term as an HTML.
+ * @typedef {function(number, !goog.html.SafeHtml): !goog.html.SafeHtml}
+ */
+goog.dom.annotate.AnnotateFn;
+
+
+/**
+ * Calls {@code annotateFn} for each occurrence of a search term in text nodes
+ * under {@code node}. Returns the number of hits.
+ *
+ * @param {Node} node  A DOM node.
+ * @param {Array<!Array<string|boolean>>} terms
+ *   An array of [searchTerm, matchWholeWordOnly] tuples.
+ *   The matchWholeWordOnly value is a per-term attribute because some terms
+ *   may be CJK, while others are not. (For correctness, matchWholeWordOnly
+ *   should always be false for CJK terms.).
+ * @param {goog.dom.annotate.AnnotateFn} annotateFn
+ * @param {*=} opt_ignoreCase  Whether to ignore the case of the query
+ *   terms when looking for matches.
+ * @param {Array<string>=} opt_classesToSkip  Nodes with one of these CSS class
+ *   names (and its descendants) will be skipped.
+ * @param {number=} opt_maxMs  Number of milliseconds after which this function,
+ *   if still annotating, should stop and return.
+ *
+ * @return {boolean} Whether any terms were annotated.
+ */
+goog.dom.annotate.annotateTerms = function(node, terms, annotateFn,
+                                           opt_ignoreCase,
+                                           opt_classesToSkip,
+                                           opt_maxMs) {
+  if (opt_ignoreCase) {
+    terms = goog.dom.annotate.lowercaseTerms_(terms);
+  }
+  var stopTime = opt_maxMs > 0 ? goog.now() + opt_maxMs : 0;
+
+  return goog.dom.annotate.annotateTermsInNode_(
+      node, terms, annotateFn, opt_ignoreCase, opt_classesToSkip || [],
+      stopTime, 0);
+};
+
+
+/**
+ * The maximum recursion depth allowed. Any DOM nodes deeper than this are
+ * ignored.
+ * @type {number}
+ * @private
+ */
+goog.dom.annotate.MAX_RECURSION_ = 200;
+
+
+/**
+ * The node types whose descendants should not be affected by annotation.
+ * @private {Array<string>}
+ */
+goog.dom.annotate.NODES_TO_SKIP_ = [
+  goog.dom.TagName.SCRIPT, goog.dom.TagName.STYLE, goog.dom.TagName.TEXTAREA];
+
+
+/**
+ * Recursive helper function.
+ *
+ * @param {Node} node  A DOM node.
+ * @param {Array<!Array<string|boolean>>} terms
+ *     An array of [searchTerm, matchWholeWordOnly] tuples.
+ *     The matchWholeWordOnly value is a per-term attribute because some terms
+ *     may be CJK, while others are not. (For correctness, matchWholeWordOnly
+ *     should always be false for CJK terms.).
+ * @param {goog.dom.annotate.AnnotateFn} annotateFn
+ * @param {*} ignoreCase  Whether to ignore the case of the query terms
+ *     when looking for matches.
+ * @param {Array<string>} classesToSkip  Nodes with one of these CSS class
+ *     names will be skipped (as will their descendants).
+ * @param {number} stopTime  Deadline for annotation operation (ignored if 0).
+ * @param {number} recursionLevel  How deep this recursive call is; pass the
+ *     value 0 in the initial call.
+ * @return {boolean} Whether any terms were annotated.
+ * @private
+ */
+goog.dom.annotate.annotateTermsInNode_ =
+    function(node, terms, annotateFn, ignoreCase, classesToSkip,
+             stopTime, recursionLevel) {
+  if ((stopTime > 0 && goog.now() >= stopTime) ||
+      recursionLevel > goog.dom.annotate.MAX_RECURSION_) {
+    return false;
+  }
+
+  var annotated = false;
+
+  if (node.nodeType == goog.dom.NodeType.TEXT) {
+    var html = goog.dom.annotate.helpAnnotateText_(node.nodeValue, terms,
+                                                   annotateFn, ignoreCase);
+    if (html != null) {
+      // Replace the text with the annotated html. First we put the html into
+      // a temporary node, to get its DOM structure. To avoid adding a wrapper
+      // element as a side effect, we'll only actually use the temporary node's
+      // children.
+      var tempNode = goog.dom.getOwnerDocument(node).createElement(
+          goog.dom.TagName.SPAN);
+      goog.dom.safe.setInnerHtml(tempNode, html);
+
+      var parentNode = node.parentNode;
+      var nodeToInsert;
+      while ((nodeToInsert = tempNode.firstChild) != null) {
+        // Each parentNode.insertBefore call removes the inserted node from
+        // tempNode's list of children.
+        parentNode.insertBefore(nodeToInsert, node);
+      }
+
+      parentNode.removeChild(node);
+      annotated = true;
+    }
+  } else if (node.hasChildNodes() &&
+             !goog.array.contains(goog.dom.annotate.NODES_TO_SKIP_,
+                 node.tagName)) {
+    var classes = node.className.split(/\s+/);
+    var skip = goog.array.some(classes, function(className) {
+      return goog.array.contains(classesToSkip, className);
+    });
+
+    if (!skip) {
+      ++recursionLevel;
+      var curNode = node.firstChild;
+      while (curNode) {
+        var nextNode = curNode.nextSibling;
+        var curNodeAnnotated = goog.dom.annotate.annotateTermsInNode_(
+            curNode, terms, annotateFn, ignoreCase, classesToSkip,
+            stopTime, recursionLevel);
+        annotated = annotated || curNodeAnnotated;
+        curNode = nextNode;
+      }
+    }
+  }
+
+  return annotated;
+};
+
+
+/**
+ * Regular expression that matches non-word characters.
+ *
+ * Performance note: Testing a one-character string using this regex is as fast
+ * as the equivalent string test ("a-zA-Z0-9_".indexOf(c) < 0), give or take a
+ * few percent. (The regex is about 5% faster in IE 6 and about 4% slower in
+ * Firefox 1.5.) If performance becomes critical, it may be better to convert
+ * the character to a numerical char code and check whether it falls in the
+ * word character ranges. A quick test suggests that could be 33% faster.
+ *
+ * @type {RegExp}
+ * @private
+ */
+goog.dom.annotate.NONWORD_RE_ = /\W/;
+
+
+/**
+ * Annotates occurrences of query terms in plain text. This process consists of
+ * identifying all occurrences of all query terms, calling a provided function
+ * to get the appropriate replacement HTML for each occurrence, and
+ * HTML-escaping all the text.
+ *
+ * @param {string} text  The plain text to be searched.
+ * @param {Array<Array<?>>} terms  An array of
+ *   [{string} searchTerm, {boolean} matchWholeWordOnly] tuples.
+ *   The matchWholeWordOnly value is a per-term attribute because some terms
+ *   may be CJK, while others are not. (For correctness, matchWholeWordOnly
+ *   should always be false for CJK terms.).
+ * @param {goog.dom.annotate.AnnotateFn} annotateFn
+ * @param {*=} opt_ignoreCase  Whether to ignore the case of the query
+ *   terms when looking for matches.
+ * @return {goog.html.SafeHtml} The HTML equivalent of {@code text} with terms
+ *   annotated, or null if the text did not contain any of the terms.
+ */
+goog.dom.annotate.annotateText = function(text, terms, annotateFn,
+                                          opt_ignoreCase) {
+  if (opt_ignoreCase) {
+    terms = goog.dom.annotate.lowercaseTerms_(terms);
+  }
+  return goog.dom.annotate.helpAnnotateText_(text, terms, annotateFn,
+                                             opt_ignoreCase);
+};
+
+
+/**
+ * Annotates occurrences of query terms in plain text. This process consists of
+ * identifying all occurrences of all query terms, calling a provided function
+ * to get the appropriate replacement HTML for each occurrence, and
+ * HTML-escaping all the text.
+ *
+ * @param {string} text  The plain text to be searched.
+ * @param {Array<Array<?>>} terms  An array of
+ *   [{string} searchTerm, {boolean} matchWholeWordOnly] tuples.
+ *   If {@code ignoreCase} is true, each search term must already be lowercase.
+ *   The matchWholeWordOnly value is a per-term attribute because some terms
+ *   may be CJK, while others are not. (For correctness, matchWholeWordOnly
+ *   should always be false for CJK terms.).
+ * @param {goog.dom.annotate.AnnotateFn} annotateFn
+ * @param {*} ignoreCase  Whether to ignore the case of the query terms
+ *   when looking for matches.
+ * @return {goog.html.SafeHtml} The HTML equivalent of {@code text} with terms
+ *   annotated, or null if the text did not contain any of the terms.
+ * @private
+ */
+goog.dom.annotate.helpAnnotateText_ = function(text, terms, annotateFn,
+                                               ignoreCase) {
+  var hit = false;
+  var textToSearch = ignoreCase ? text.toLowerCase() : text;
+  var textLen = textToSearch.length;
+  var numTerms = terms.length;
+
+  // Each element will be an array of hit positions for the term.
+  var termHits = new Array(numTerms);
+
+  // First collect all the hits into allHits.
+  for (var i = 0; i < numTerms; i++) {
+    var term = terms[i];
+    var hits = [];
+    var termText = term[0];
+    if (termText != '') {
+      var matchWholeWordOnly = term[1];
+      var termLen = termText.length;
+      var pos = 0;
+      // Find each hit for term t and append to termHits.
+      while (pos < textLen) {
+        var hitPos = textToSearch.indexOf(termText, pos);
+        if (hitPos == -1) {
+          break;
+        } else {
+          var prevCharPos = hitPos - 1;
+          var nextCharPos = hitPos + termLen;
+          if (!matchWholeWordOnly ||
+              ((prevCharPos < 0 ||
+                goog.dom.annotate.NONWORD_RE_.test(
+                    textToSearch.charAt(prevCharPos))) &&
+               (nextCharPos >= textLen ||
+                goog.dom.annotate.NONWORD_RE_.test(
+                    textToSearch.charAt(nextCharPos))))) {
+            hits.push(hitPos);
+            hit = true;
+          }
+          pos = hitPos + termLen;
+        }
+      }
+    }
+    termHits[i] = hits;
+  }
+
+  if (hit) {
+    var html = [];
+    var pos = 0;
+
+    while (true) {
+      // First determine which of the n terms is the next hit.
+      var termIndexOfNextHit;
+      var posOfNextHit = -1;
+
+      for (var i = 0; i < numTerms; i++) {
+        var hits = termHits[i];
+        // pull off the position of the next hit of term t
+        // (it's always the first in the array because we're shifting
+        // hits off the front of the array as we process them)
+        // this is the next candidate to consider for the next overall hit
+        if (!goog.array.isEmpty(hits)) {
+          var hitPos = hits[0];
+
+          // Discard any hits embedded in the previous hit.
+          while (hitPos >= 0 && hitPos < pos) {
+            hits.shift();
+            hitPos = goog.array.isEmpty(hits) ? -1 : hits[0];
+          }
+
+          if (hitPos >= 0 && (posOfNextHit < 0 || hitPos < posOfNextHit)) {
+            termIndexOfNextHit = i;
+            posOfNextHit = hitPos;
+          }
+        }
+      }
+
+      // Quit if there are no more hits.
+      if (posOfNextHit < 0) break;
+
+      // Remove the next hit from our hit list.
+      termHits[termIndexOfNextHit].shift();
+
+      // Append everything from the end of the last hit up to this one.
+      html.push(text.substr(pos, posOfNextHit - pos));
+
+      // Append the annotated term.
+      var termLen = terms[termIndexOfNextHit][0].length;
+      var termHtml = goog.html.SafeHtml.htmlEscape(
+          text.substr(posOfNextHit, termLen));
+      html.push(
+          annotateFn(goog.asserts.assertNumber(termIndexOfNextHit), termHtml));
+
+      pos = posOfNextHit + termLen;
+    }
+
+    // Append everything after the last hit.
+    html.push(text.substr(pos));
+    return goog.html.SafeHtml.concat(html);
+  } else {
+    return null;
+  }
+};
+
+
+/**
+ * Converts terms to lowercase.
+ *
+ * @param {Array<Array<?>>} terms  An array of
+ *   [{string} searchTerm, {boolean} matchWholeWordOnly] tuples.
+ * @return {!Array<Array<?>>}  An array of
+ *   [{string} searchTerm, {boolean} matchWholeWordOnly] tuples.
+ * @private
+ */
+goog.dom.annotate.lowercaseTerms_ = function(terms) {
+  var lowercaseTerms = [];
+  for (var i = 0; i < terms.length; ++i) {
+    var term = terms[i];
+    lowercaseTerms[i] = [term[0].toLowerCase(), term[1]];
+  }
+  return lowercaseTerms;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/browserfeature1.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/browserfeature1.js b/externs/GCL/externs/goog/dom/browserfeature1.js
new file mode 100644
index 0000000..2c70cda
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/browserfeature1.js
@@ -0,0 +1,72 @@
+// Copyright 2010 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 Browser capability checks for the dom package.
+ *
+ */
+
+
+goog.provide('goog.dom.BrowserFeature');
+
+goog.require('goog.userAgent');
+
+
+/**
+ * Enum of browser capabilities.
+ * @enum {boolean}
+ */
+goog.dom.BrowserFeature = {
+  /**
+   * Whether attributes 'name' and 'type' can be added to an element after it's
+   * created. False in Internet Explorer prior to version 9.
+   */
+  CAN_ADD_NAME_OR_TYPE_ATTRIBUTES: !goog.userAgent.IE ||
+      goog.userAgent.isDocumentModeOrHigher(9),
+
+  /**
+   * Whether we can use element.children to access an element's Element
+   * children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment
+   * nodes in the collection.)
+   */
+  CAN_USE_CHILDREN_ATTRIBUTE: !goog.userAgent.GECKO && !goog.userAgent.IE ||
+      goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) ||
+      goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1'),
+
+  /**
+   * Opera, Safari 3, and Internet Explorer 9 all support innerText but they
+   * include text nodes in script and style tags. Not document-mode-dependent.
+   */
+  CAN_USE_INNER_TEXT: (
+      goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')),
+
+  /**
+   * MSIE, Opera, and Safari>=4 support element.parentElement to access an
+   * element's parent if it is an Element.
+   */
+  CAN_USE_PARENT_ELEMENT_PROPERTY: goog.userAgent.IE || goog.userAgent.OPERA ||
+      goog.userAgent.WEBKIT,
+
+  /**
+   * Whether NoScope elements need a scoped element written before them in
+   * innerHTML.
+   * MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
+   */
+  INNER_HTML_NEEDS_SCOPED_ELEMENT: goog.userAgent.IE,
+
+  /**
+   * Whether we use legacy IE range API.
+   */
+  LEGACY_IE_RANGES: goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/dom/browserrange/abstractrange.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/dom/browserrange/abstractrange.js b/externs/GCL/externs/goog/dom/browserrange/abstractrange.js
new file mode 100644
index 0000000..3956f3a
--- /dev/null
+++ b/externs/GCL/externs/goog/dom/browserrange/abstractrange.js
@@ -0,0 +1,350 @@
+// 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 Definition of the browser range interface.
+ *
+ * DO NOT USE THIS FILE DIRECTLY.  Use goog.dom.Range instead.
+ *
+ * @author robbyw@google.com (Robby Walker)
+ */
+
+
+goog.provide('goog.dom.browserrange.AbstractRange');
+
+goog.require('goog.array');
+goog.require('goog.asserts');
+goog.require('goog.dom');
+goog.require('goog.dom.NodeType');
+goog.require('goog.dom.RangeEndpoint');
+goog.require('goog.dom.TagName');
+goog.require('goog.dom.TextRangeIterator');
+goog.require('goog.iter');
+goog.require('goog.math.Coordinate');
+goog.require('goog.string');
+goog.require('goog.string.StringBuffer');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * The constructor for abstract ranges.  Don't call this from subclasses.
+ * @constructor
+ */
+goog.dom.browserrange.AbstractRange = function() {
+};
+
+
+/**
+ * @return {goog.dom.browserrange.AbstractRange} A clone of this range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.clone = goog.abstractMethod;
+
+
+/**
+ * Returns the browser native implementation of the range.  Please refrain from
+ * using this function - if you find you need the range please add wrappers for
+ * the functionality you need rather than just using the native range.
+ * @return {Range|TextRange} The browser native range object.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getBrowserRange =
+    goog.abstractMethod;
+
+
+/**
+ * Returns the deepest node in the tree that contains the entire range.
+ * @return {Node} The deepest node that contains the entire range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getContainer =
+    goog.abstractMethod;
+
+
+/**
+ * Returns the node the range starts in.
+ * @return {Node} The element or text node the range starts in.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getStartNode =
+    goog.abstractMethod;
+
+
+/**
+ * Returns the offset into the node the range starts in.
+ * @return {number} The offset into the node the range starts in.  For text
+ *     nodes, this is an offset into the node value.  For elements, this is
+ *     an offset into the childNodes array.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getStartOffset =
+    goog.abstractMethod;
+
+
+/**
+ * @return {goog.math.Coordinate} The coordinate of the selection start node
+ *     and offset.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getStartPosition = function() {
+  goog.asserts.assert(this.range_.getClientRects,
+      'Getting selection coordinates is not supported.');
+
+  var rects = this.range_.getClientRects();
+  if (rects.length) {
+    return new goog.math.Coordinate(rects[0]['left'], rects[0]['top']);
+  }
+  return null;
+};
+
+
+/**
+ * Returns the node the range ends in.
+ * @return {Node} The element or text node the range ends in.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getEndNode =
+    goog.abstractMethod;
+
+
+/**
+ * Returns the offset into the node the range ends in.
+ * @return {number} The offset into the node the range ends in.  For text
+ *     nodes, this is an offset into the node value.  For elements, this is
+ *     an offset into the childNodes array.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getEndOffset =
+    goog.abstractMethod;
+
+
+/**
+ * @return {goog.math.Coordinate} The coordinate of the selection end node
+ *     and offset.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getEndPosition = function() {
+  goog.asserts.assert(this.range_.getClientRects,
+      'Getting selection coordinates is not supported.');
+
+  var rects = this.range_.getClientRects();
+  if (rects.length) {
+    var lastRect = goog.array.peek(rects);
+    return new goog.math.Coordinate(lastRect['right'], lastRect['bottom']);
+  }
+  return null;
+};
+
+
+/**
+ * Compares one endpoint of this range with the endpoint of another browser
+ * native range object.
+ * @param {Range|TextRange} range The browser native range to compare against.
+ * @param {goog.dom.RangeEndpoint} thisEndpoint The endpoint of this range
+ *     to compare with.
+ * @param {goog.dom.RangeEndpoint} otherEndpoint The endpoint of the other
+ *     range to compare with.
+ * @return {number} 0 if the endpoints are equal, negative if this range
+ *     endpoint comes before the other range endpoint, and positive otherwise.
+ */
+goog.dom.browserrange.AbstractRange.prototype.compareBrowserRangeEndpoints =
+    goog.abstractMethod;
+
+
+/**
+ * Tests if this range contains the given range.
+ * @param {goog.dom.browserrange.AbstractRange} abstractRange The range to test.
+ * @param {boolean=} opt_allowPartial If not set or false, the range must be
+ *     entirely contained in the selection for this function to return true.
+ * @return {boolean} Whether this range contains the given range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.containsRange =
+    function(abstractRange, opt_allowPartial) {
+  // IE sometimes misreports the boundaries for collapsed ranges. So if the
+  // other range is collapsed, make sure the whole range is contained. This is
+  // logically equivalent, and works around IE's bug.
+  var checkPartial = opt_allowPartial && !abstractRange.isCollapsed();
+
+  var range = abstractRange.getBrowserRange();
+  var start = goog.dom.RangeEndpoint.START, end = goog.dom.RangeEndpoint.END;
+  /** @preserveTry */
+  try {
+    if (checkPartial) {
+      // There are two ways to not overlap.  Being before, and being after.
+      // Before is represented by this.end before range.start: comparison < 0.
+      // After is represented by this.start after range.end: comparison > 0.
+      // The below is the negation of not overlapping.
+      return this.compareBrowserRangeEndpoints(range, end, start) >= 0 &&
+             this.compareBrowserRangeEndpoints(range, start, end) <= 0;
+
+    } else {
+      // Return true if this range bounds the parameter range from both sides.
+      return this.compareBrowserRangeEndpoints(range, end, end) >= 0 &&
+          this.compareBrowserRangeEndpoints(range, start, start) <= 0;
+    }
+  } catch (e) {
+    if (!goog.userAgent.IE) {
+      throw e;
+    }
+    // IE sometimes throws exceptions when one range is invalid, i.e. points
+    // to a node that has been removed from the document.  Return false in this
+    // case.
+    return false;
+  }
+};
+
+
+/**
+ * Tests if this range contains the given node.
+ * @param {Node} node The node to test.
+ * @param {boolean=} opt_allowPartial If not set or false, the node must be
+ *     entirely contained in the selection for this function to return true.
+ * @return {boolean} Whether this range contains the given node.
+ */
+goog.dom.browserrange.AbstractRange.prototype.containsNode = function(node,
+    opt_allowPartial) {
+  return this.containsRange(
+      goog.dom.browserrange.createRangeFromNodeContents(node),
+      opt_allowPartial);
+};
+
+
+/**
+ * Tests if the selection is collapsed - i.e. is just a caret.
+ * @return {boolean} Whether the range is collapsed.
+ */
+goog.dom.browserrange.AbstractRange.prototype.isCollapsed =
+    goog.abstractMethod;
+
+
+/**
+ * @return {string} The text content of the range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getText =
+    goog.abstractMethod;
+
+
+/**
+ * Returns the HTML fragment this range selects.  This is slow on all browsers.
+ * @return {string} HTML fragment of the range, does not include context
+ *     containing elements.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getHtmlFragment = function() {
+  var output = new goog.string.StringBuffer();
+  goog.iter.forEach(this, function(node, ignore, it) {
+    if (node.nodeType == goog.dom.NodeType.TEXT) {
+      output.append(goog.string.htmlEscape(node.nodeValue.substring(
+          it.getStartTextOffset(), it.getEndTextOffset())));
+    } else if (node.nodeType == goog.dom.NodeType.ELEMENT) {
+      if (it.isEndTag()) {
+        if (goog.dom.canHaveChildren(node)) {
+          output.append('</' + node.tagName + '>');
+        }
+      } else {
+        var shallow = node.cloneNode(false);
+        var html = goog.dom.getOuterHtml(shallow);
+        if (goog.userAgent.IE && node.tagName == goog.dom.TagName.LI) {
+          // For an LI, IE just returns "<li>" with no closing tag
+          output.append(html);
+        } else {
+          var index = html.lastIndexOf('<');
+          output.append(index ? html.substr(0, index) : html);
+        }
+      }
+    }
+  }, this);
+
+  return output.toString();
+};
+
+
+/**
+ * Returns valid HTML for this range.  This is fast on IE, and semi-fast on
+ * other browsers.
+ * @return {string} Valid HTML of the range, including context containing
+ *     elements.
+ */
+goog.dom.browserrange.AbstractRange.prototype.getValidHtml =
+    goog.abstractMethod;
+
+
+/**
+ * Returns a RangeIterator 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.RangeIterator} An iterator over tags in the range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.__iterator__ = function(
+    opt_keys) {
+  return new goog.dom.TextRangeIterator(this.getStartNode(),
+      this.getStartOffset(), this.getEndNode(), this.getEndOffset());
+};
+
+
+// SELECTION MODIFICATION
+
+
+/**
+ * Set this range as the selection in its window.
+ * @param {boolean=} opt_reverse Whether to select the range in reverse,
+ *     if possible.
+ */
+goog.dom.browserrange.AbstractRange.prototype.select =
+    goog.abstractMethod;
+
+
+/**
+ * Removes the contents of the range from the document.  As a side effect, the
+ * selection will be collapsed.  The behavior of content removal is normalized
+ * across browsers.  For instance, IE sometimes creates extra text nodes that
+ * a W3C browser does not.  That behavior is corrected for.
+ */
+goog.dom.browserrange.AbstractRange.prototype.removeContents =
+    goog.abstractMethod;
+
+
+/**
+ * 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.browserrange.AbstractRange.prototype.surroundContents =
+    goog.abstractMethod;
+
+
+/**
+ * Inserts a node before (or after) the range.  The range may be disrupted
+ * beyond recovery because of the way this splits nodes.
+ * @param {Node} node The node to insert.
+ * @param {boolean} before True to insert before, false to insert after.
+ * @return {Node} The node added to the document.  This may be different
+ *     than the node parameter because on IE we have to clone it.
+ */
+goog.dom.browserrange.AbstractRange.prototype.insertNode =
+    goog.abstractMethod;
+
+
+/**
+ * Surrounds this range with the two given nodes.  The range may be disrupted
+ * beyond recovery because of the way this splits nodes.
+ * @param {Element} startNode The node to insert at the start.
+ * @param {Element} endNode The node to insert at the end.
+ */
+goog.dom.browserrange.AbstractRange.prototype.surroundWithNodes =
+    goog.abstractMethod;
+
+
+/**
+ * Collapses the range to one of its boundary points.
+ * @param {boolean} toStart Whether to collapse to the start of the range.
+ */
+goog.dom.browserrange.AbstractRange.prototype.collapse =
+    goog.abstractMethod;