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

[18/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/events/eventtype.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/eventtype.js b/externs/GCL/externs/goog/events/eventtype.js
new file mode 100644
index 0000000..befc372
--- /dev/null
+++ b/externs/GCL/externs/goog/events/eventtype.js
@@ -0,0 +1,233 @@
+// 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 Event Types.
+ *
+ * @author arv@google.com (Erik Arvidsson)
+ */
+
+
+goog.provide('goog.events.EventType');
+
+goog.require('goog.userAgent');
+
+
+/**
+ * Returns a prefixed event name for the current browser.
+ * @param {string} eventName The name of the event.
+ * @return {string} The prefixed event name.
+ * @suppress {missingRequire|missingProvide}
+ * @private
+ */
+goog.events.getVendorPrefixedName_ = function(eventName) {
+  return goog.userAgent.WEBKIT ? 'webkit' + eventName :
+      (goog.userAgent.OPERA ? 'o' + eventName.toLowerCase() :
+          eventName.toLowerCase());
+};
+
+
+/**
+ * Constants for event names.
+ * @enum {string}
+ */
+goog.events.EventType = {
+  // Mouse events
+  CLICK: 'click',
+  RIGHTCLICK: 'rightclick',
+  DBLCLICK: 'dblclick',
+  MOUSEDOWN: 'mousedown',
+  MOUSEUP: 'mouseup',
+  MOUSEOVER: 'mouseover',
+  MOUSEOUT: 'mouseout',
+  MOUSEMOVE: 'mousemove',
+  MOUSEENTER: 'mouseenter',
+  MOUSELEAVE: 'mouseleave',
+  // Select start is non-standard.
+  // See http://msdn.microsoft.com/en-us/library/ie/ms536969(v=vs.85).aspx.
+  SELECTSTART: 'selectstart', // IE, Safari, Chrome
+
+  // Wheel events
+  // http://www.w3.org/TR/DOM-Level-3-Events/#events-wheelevents
+  WHEEL: 'wheel',
+
+  // Key events
+  KEYPRESS: 'keypress',
+  KEYDOWN: 'keydown',
+  KEYUP: 'keyup',
+
+  // Focus
+  BLUR: 'blur',
+  FOCUS: 'focus',
+  DEACTIVATE: 'deactivate', // IE only
+  // NOTE: The following two events are not stable in cross-browser usage.
+  //     WebKit and Opera implement DOMFocusIn/Out.
+  //     IE implements focusin/out.
+  //     Gecko implements neither see bug at
+  //     https://bugzilla.mozilla.org/show_bug.cgi?id=396927.
+  // The DOM Events Level 3 Draft deprecates DOMFocusIn in favor of focusin:
+  //     http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html
+  // You can use FOCUS in Capture phase until implementations converge.
+  FOCUSIN: goog.userAgent.IE ? 'focusin' : 'DOMFocusIn',
+  FOCUSOUT: goog.userAgent.IE ? 'focusout' : 'DOMFocusOut',
+
+  // Forms
+  CHANGE: 'change',
+  RESET: 'reset',
+  SELECT: 'select',
+  SUBMIT: 'submit',
+  INPUT: 'input',
+  PROPERTYCHANGE: 'propertychange', // IE only
+
+  // Drag and drop
+  DRAGSTART: 'dragstart',
+  DRAG: 'drag',
+  DRAGENTER: 'dragenter',
+  DRAGOVER: 'dragover',
+  DRAGLEAVE: 'dragleave',
+  DROP: 'drop',
+  DRAGEND: 'dragend',
+
+  // Touch events
+  // Note that other touch events exist, but we should follow the W3C list here.
+  // http://www.w3.org/TR/touch-events/#list-of-touchevent-types
+  TOUCHSTART: 'touchstart',
+  TOUCHMOVE: 'touchmove',
+  TOUCHEND: 'touchend',
+  TOUCHCANCEL: 'touchcancel',
+
+  // Misc
+  BEFOREUNLOAD: 'beforeunload',
+  CONSOLEMESSAGE: 'consolemessage',
+  CONTEXTMENU: 'contextmenu',
+  DOMCONTENTLOADED: 'DOMContentLoaded',
+  ERROR: 'error',
+  HELP: 'help',
+  LOAD: 'load',
+  LOSECAPTURE: 'losecapture',
+  ORIENTATIONCHANGE: 'orientationchange',
+  READYSTATECHANGE: 'readystatechange',
+  RESIZE: 'resize',
+  SCROLL: 'scroll',
+  UNLOAD: 'unload',
+
+  // HTML 5 History events
+  // See http://www.w3.org/TR/html5/history.html#event-definitions
+  HASHCHANGE: 'hashchange',
+  PAGEHIDE: 'pagehide',
+  PAGESHOW: 'pageshow',
+  POPSTATE: 'popstate',
+
+  // Copy and Paste
+  // Support is limited. Make sure it works on your favorite browser
+  // before using.
+  // http://www.quirksmode.org/dom/events/cutcopypaste.html
+  COPY: 'copy',
+  PASTE: 'paste',
+  CUT: 'cut',
+  BEFORECOPY: 'beforecopy',
+  BEFORECUT: 'beforecut',
+  BEFOREPASTE: 'beforepaste',
+
+  // HTML5 online/offline events.
+  // http://www.w3.org/TR/offline-webapps/#related
+  ONLINE: 'online',
+  OFFLINE: 'offline',
+
+  // HTML 5 worker events
+  MESSAGE: 'message',
+  CONNECT: 'connect',
+
+  // CSS animation events.
+  /** @suppress {missingRequire} */
+  ANIMATIONSTART: goog.events.getVendorPrefixedName_('AnimationStart'),
+  /** @suppress {missingRequire} */
+  ANIMATIONEND: goog.events.getVendorPrefixedName_('AnimationEnd'),
+  /** @suppress {missingRequire} */
+  ANIMATIONITERATION: goog.events.getVendorPrefixedName_('AnimationIteration'),
+
+  // CSS transition events. Based on the browser support described at:
+  // https://developer.mozilla.org/en/css/css_transitions#Browser_compatibility
+  /** @suppress {missingRequire} */
+  TRANSITIONEND: goog.events.getVendorPrefixedName_('TransitionEnd'),
+
+  // W3C Pointer Events
+  // http://www.w3.org/TR/pointerevents/
+  POINTERDOWN: 'pointerdown',
+  POINTERUP: 'pointerup',
+  POINTERCANCEL: 'pointercancel',
+  POINTERMOVE: 'pointermove',
+  POINTEROVER: 'pointerover',
+  POINTEROUT: 'pointerout',
+  POINTERENTER: 'pointerenter',
+  POINTERLEAVE: 'pointerleave',
+  GOTPOINTERCAPTURE: 'gotpointercapture',
+  LOSTPOINTERCAPTURE: 'lostpointercapture',
+
+  // IE specific events.
+  // See http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx
+  // Note: these events will be supplanted in IE11.
+  MSGESTURECHANGE: 'MSGestureChange',
+  MSGESTUREEND: 'MSGestureEnd',
+  MSGESTUREHOLD: 'MSGestureHold',
+  MSGESTURESTART: 'MSGestureStart',
+  MSGESTURETAP: 'MSGestureTap',
+  MSGOTPOINTERCAPTURE: 'MSGotPointerCapture',
+  MSINERTIASTART: 'MSInertiaStart',
+  MSLOSTPOINTERCAPTURE: 'MSLostPointerCapture',
+  MSPOINTERCANCEL: 'MSPointerCancel',
+  MSPOINTERDOWN: 'MSPointerDown',
+  MSPOINTERENTER: 'MSPointerEnter',
+  MSPOINTERHOVER: 'MSPointerHover',
+  MSPOINTERLEAVE: 'MSPointerLeave',
+  MSPOINTERMOVE: 'MSPointerMove',
+  MSPOINTEROUT: 'MSPointerOut',
+  MSPOINTEROVER: 'MSPointerOver',
+  MSPOINTERUP: 'MSPointerUp',
+
+  // Native IMEs/input tools events.
+  TEXT: 'text',
+  TEXTINPUT: 'textInput',
+  COMPOSITIONSTART: 'compositionstart',
+  COMPOSITIONUPDATE: 'compositionupdate',
+  COMPOSITIONEND: 'compositionend',
+
+  // Webview tag events
+  // See http://developer.chrome.com/dev/apps/webview_tag.html
+  EXIT: 'exit',
+  LOADABORT: 'loadabort',
+  LOADCOMMIT: 'loadcommit',
+  LOADREDIRECT: 'loadredirect',
+  LOADSTART: 'loadstart',
+  LOADSTOP: 'loadstop',
+  RESPONSIVE: 'responsive',
+  SIZECHANGED: 'sizechanged',
+  UNRESPONSIVE: 'unresponsive',
+
+  // HTML5 Page Visibility API.  See details at
+  // {@code goog.labs.dom.PageVisibilityMonitor}.
+  VISIBILITYCHANGE: 'visibilitychange',
+
+  // LocalStorage event.
+  STORAGE: 'storage',
+
+  // DOM Level 2 mutation events (deprecated).
+  DOMSUBTREEMODIFIED: 'DOMSubtreeModified',
+  DOMNODEINSERTED: 'DOMNodeInserted',
+  DOMNODEREMOVED: 'DOMNodeRemoved',
+  DOMNODEREMOVEDFROMDOCUMENT: 'DOMNodeRemovedFromDocument',
+  DOMNODEINSERTEDINTODOCUMENT: 'DOMNodeInsertedIntoDocument',
+  DOMATTRMODIFIED: 'DOMAttrModified',
+  DOMCHARACTERDATAMODIFIED: 'DOMCharacterDataModified'
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/eventwrapper.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/eventwrapper.js b/externs/GCL/externs/goog/events/eventwrapper.js
new file mode 100644
index 0000000..1581774
--- /dev/null
+++ b/externs/GCL/externs/goog/events/eventwrapper.js
@@ -0,0 +1,66 @@
+// Copyright 2009 The Closure Library Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview Definition of the goog.events.EventWrapper interface.
+ *
+ * @author eae@google.com (Emil A Eklund)
+ */
+
+goog.provide('goog.events.EventWrapper');
+
+
+
+/**
+ * Interface for event wrappers.
+ * @interface
+ */
+goog.events.EventWrapper = function() {
+};
+
+
+/**
+ * Adds an event listener using the wrapper on a DOM Node or an object that has
+ * implemented {@link goog.events.EventTarget}. A listener can only be added
+ * once to an object.
+ *
+ * @param {goog.events.ListenableType} src The node to listen to events on.
+ * @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback
+ *     method, or an object with a handleEvent function.
+ * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
+ *     false).
+ * @param {Object=} opt_scope Element in whose scope to call the listener.
+ * @param {goog.events.EventHandler=} opt_eventHandler Event handler to add
+ *     listener to.
+ */
+goog.events.EventWrapper.prototype.listen = function(src, listener, opt_capt,
+    opt_scope, opt_eventHandler) {
+};
+
+
+/**
+ * Removes an event listener added using goog.events.EventWrapper.listen.
+ *
+ * @param {goog.events.ListenableType} src The node to remove listener from.
+ * @param {function(?):?|{handleEvent:function(?):?}|null} listener Callback
+ *     method, or an object with a handleEvent function.
+ * @param {boolean=} opt_capt Whether to fire in capture phase (defaults to
+ *     false).
+ * @param {Object=} opt_scope Element in whose scope to call the listener.
+ * @param {goog.events.EventHandler=} opt_eventHandler Event handler to remove
+ *     listener from.
+ */
+goog.events.EventWrapper.prototype.unlisten = function(src, listener, opt_capt,
+    opt_scope, opt_eventHandler) {
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/filedrophandler.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/filedrophandler.js b/externs/GCL/externs/goog/events/filedrophandler.js
new file mode 100644
index 0000000..5678fe3
--- /dev/null
+++ b/externs/GCL/externs/goog/events/filedrophandler.js
@@ -0,0 +1,222 @@
+// 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 Provides a files drag and drop event detector. It works on
+ * HTML5 browsers.
+ *
+ * @see ../demos/filedrophandler.html
+ */
+
+goog.provide('goog.events.FileDropHandler');
+goog.provide('goog.events.FileDropHandler.EventType');
+
+goog.require('goog.array');
+goog.require('goog.dom');
+goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventHandler');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
+goog.require('goog.log');
+goog.require('goog.log.Level');
+
+
+
+/**
+ * A files drag and drop event detector. Gets an {@code element} as parameter
+ * and fires {@code goog.events.FileDropHandler.EventType.DROP} event when files
+ * are dropped in the {@code element}.
+ *
+ * @param {Element|Document} element The element or document to listen on.
+ * @param {boolean=} opt_preventDropOutside Whether to prevent a drop on the
+ *     area outside the {@code element}. Default false.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ * @final
+ */
+goog.events.FileDropHandler = function(element, opt_preventDropOutside) {
+  goog.events.EventTarget.call(this);
+
+  /**
+   * Handler for drag/drop events.
+   * @type {!goog.events.EventHandler<!goog.events.FileDropHandler>}
+   * @private
+   */
+  this.eventHandler_ = new goog.events.EventHandler(this);
+
+  var doc = element;
+  if (opt_preventDropOutside) {
+    doc = goog.dom.getOwnerDocument(element);
+  }
+
+  // Add dragenter listener to the owner document of the element.
+  this.eventHandler_.listen(doc,
+                            goog.events.EventType.DRAGENTER,
+                            this.onDocDragEnter_);
+
+  // Add dragover listener to the owner document of the element only if the
+  // document is not the element itself.
+  if (doc != element) {
+    this.eventHandler_.listen(doc,
+                              goog.events.EventType.DRAGOVER,
+                              this.onDocDragOver_);
+  }
+
+  // Add dragover and drop listeners to the element.
+  this.eventHandler_.listen(element,
+                            goog.events.EventType.DRAGOVER,
+                            this.onElemDragOver_);
+  this.eventHandler_.listen(element,
+                            goog.events.EventType.DROP,
+                            this.onElemDrop_);
+};
+goog.inherits(goog.events.FileDropHandler, goog.events.EventTarget);
+
+
+/**
+ * Whether the drag event contains files. It is initialized only in the
+ * dragenter event. It is used in all the drag events to prevent default actions
+ * only if the drag contains files. Preventing default actions is necessary to
+ * go from dragenter to dragover and from dragover to drop. However we do not
+ * always want to prevent default actions, e.g. when the user drags text or
+ * links on a text area we should not prevent the browser default action that
+ * inserts the text in the text area. It is also necessary to stop propagation
+ * when handling drag events on the element to prevent them from propagating
+ * to the document.
+ * @private
+ * @type {boolean}
+ */
+goog.events.FileDropHandler.prototype.dndContainsFiles_ = false;
+
+
+/**
+ * A logger, used to help us debug the algorithm.
+ * @type {goog.log.Logger}
+ * @private
+ */
+goog.events.FileDropHandler.prototype.logger_ =
+    goog.log.getLogger('goog.events.FileDropHandler');
+
+
+/**
+ * The types of events fired by this class.
+ * @enum {string}
+ */
+goog.events.FileDropHandler.EventType = {
+  DROP: goog.events.EventType.DROP
+};
+
+
+/** @override */
+goog.events.FileDropHandler.prototype.disposeInternal = function() {
+  goog.events.FileDropHandler.superClass_.disposeInternal.call(this);
+  this.eventHandler_.dispose();
+};
+
+
+/**
+ * Dispatches the DROP event.
+ * @param {goog.events.BrowserEvent} e The underlying browser event.
+ * @private
+ */
+goog.events.FileDropHandler.prototype.dispatch_ = function(e) {
+  goog.log.fine(this.logger_, 'Firing DROP event...');
+  var event = new goog.events.BrowserEvent(e.getBrowserEvent());
+  event.type = goog.events.FileDropHandler.EventType.DROP;
+  this.dispatchEvent(event);
+};
+
+
+/**
+ * Handles dragenter on the document.
+ * @param {goog.events.BrowserEvent} e The dragenter event.
+ * @private
+ */
+goog.events.FileDropHandler.prototype.onDocDragEnter_ = function(e) {
+  goog.log.log(this.logger_, goog.log.Level.FINER,
+      '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type);
+  var dt = e.getBrowserEvent().dataTransfer;
+  // Check whether the drag event contains files.
+  this.dndContainsFiles_ = !!(dt &&
+      ((dt.types &&
+          (goog.array.contains(dt.types, 'Files') ||
+          goog.array.contains(dt.types, 'public.file-url'))) ||
+      (dt.files && dt.files.length > 0)));
+  // If it does
+  if (this.dndContainsFiles_) {
+    // Prevent default actions.
+    e.preventDefault();
+  }
+  goog.log.log(this.logger_, goog.log.Level.FINER,
+      'dndContainsFiles_: ' + this.dndContainsFiles_);
+};
+
+
+/**
+ * Handles dragging something over the document.
+ * @param {goog.events.BrowserEvent} e The dragover event.
+ * @private
+ */
+goog.events.FileDropHandler.prototype.onDocDragOver_ = function(e) {
+  goog.log.log(this.logger_, goog.log.Level.FINEST,
+      '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type);
+  if (this.dndContainsFiles_) {
+    // Prevent default actions.
+    e.preventDefault();
+    // Disable the drop on the document outside the drop zone.
+    var dt = e.getBrowserEvent().dataTransfer;
+    dt.dropEffect = 'none';
+  }
+};
+
+
+/**
+ * Handles dragging something over the element (drop zone).
+ * @param {goog.events.BrowserEvent} e The dragover event.
+ * @private
+ */
+goog.events.FileDropHandler.prototype.onElemDragOver_ = function(e) {
+  goog.log.log(this.logger_, goog.log.Level.FINEST,
+      '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type);
+  if (this.dndContainsFiles_) {
+    // Prevent default actions and stop the event from propagating further to
+    // the document. Both lines are needed! (See comment above).
+    e.preventDefault();
+    e.stopPropagation();
+    // Allow the drop on the drop zone.
+    var dt = e.getBrowserEvent().dataTransfer;
+    dt.effectAllowed = 'all';
+    dt.dropEffect = 'copy';
+  }
+};
+
+
+/**
+ * Handles dropping something onto the element (drop zone).
+ * @param {goog.events.BrowserEvent} e The drop event.
+ * @private
+ */
+goog.events.FileDropHandler.prototype.onElemDrop_ = function(e) {
+  goog.log.log(this.logger_, goog.log.Level.FINER,
+      '"' + e.target.id + '" (' + e.target + ') dispatched: ' + e.type);
+  // If the drag and drop event contains files.
+  if (this.dndContainsFiles_) {
+    // Prevent default actions and stop the event from propagating further to
+    // the document. Both lines are needed! (See comment above).
+    e.preventDefault();
+    e.stopPropagation();
+    // Dispatch DROP event.
+    this.dispatch_(e);
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/focushandler.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/focushandler.js b/externs/GCL/externs/goog/events/focushandler.js
new file mode 100644
index 0000000..f4e1000
--- /dev/null
+++ b/externs/GCL/externs/goog/events/focushandler.js
@@ -0,0 +1,107 @@
+// 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 This event handler allows you to catch focusin and focusout
+ * events on  descendants. Unlike the "focus" and "blur" events which do not
+ * propagate consistently, and therefore must be added to the element that is
+ * focused, this allows you to attach one listener to an ancester and you will
+ * be notified when the focus state changes of ony of its descendants.
+ * @author arv@google.com (Erik Arvidsson)
+ * @see ../demos/focushandler.html
+ */
+
+goog.provide('goog.events.FocusHandler');
+goog.provide('goog.events.FocusHandler.EventType');
+
+goog.require('goog.events');
+goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventTarget');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * This event handler allows you to catch focus events when descendants gain or
+ * loses focus.
+ * @param {Element|Document} element  The node to listen on.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ * @final
+ */
+goog.events.FocusHandler = function(element) {
+  goog.events.EventTarget.call(this);
+
+  /**
+   * This is the element that we will listen to the real focus events on.
+   * @type {Element|Document}
+   * @private
+   */
+  this.element_ = element;
+
+  // In IE we use focusin/focusout and in other browsers we use a capturing
+  // listner for focus/blur
+  var typeIn = goog.userAgent.IE ? 'focusin' : 'focus';
+  var typeOut = goog.userAgent.IE ? 'focusout' : 'blur';
+
+  /**
+   * Store the listen key so it easier to unlisten in dispose.
+   * @private
+   * @type {goog.events.Key}
+   */
+  this.listenKeyIn_ =
+      goog.events.listen(this.element_, typeIn, this, !goog.userAgent.IE);
+
+  /**
+   * Store the listen key so it easier to unlisten in dispose.
+   * @private
+   * @type {goog.events.Key}
+   */
+  this.listenKeyOut_ =
+      goog.events.listen(this.element_, typeOut, this, !goog.userAgent.IE);
+};
+goog.inherits(goog.events.FocusHandler, goog.events.EventTarget);
+
+
+/**
+ * Enum type for the events fired by the focus handler
+ * @enum {string}
+ */
+goog.events.FocusHandler.EventType = {
+  FOCUSIN: 'focusin',
+  FOCUSOUT: 'focusout'
+};
+
+
+/**
+ * This handles the underlying events and dispatches a new event.
+ * @param {goog.events.BrowserEvent} e  The underlying browser event.
+ */
+goog.events.FocusHandler.prototype.handleEvent = function(e) {
+  var be = e.getBrowserEvent();
+  var event = new goog.events.BrowserEvent(be);
+  event.type = e.type == 'focusin' || e.type == 'focus' ?
+      goog.events.FocusHandler.EventType.FOCUSIN :
+      goog.events.FocusHandler.EventType.FOCUSOUT;
+  this.dispatchEvent(event);
+};
+
+
+/** @override */
+goog.events.FocusHandler.prototype.disposeInternal = function() {
+  goog.events.FocusHandler.superClass_.disposeInternal.call(this);
+  goog.events.unlistenByKey(this.listenKeyIn_);
+  goog.events.unlistenByKey(this.listenKeyOut_);
+  delete this.element_;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/imehandler.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/imehandler.js b/externs/GCL/externs/goog/events/imehandler.js
new file mode 100644
index 0000000..661f91f
--- /dev/null
+++ b/externs/GCL/externs/goog/events/imehandler.js
@@ -0,0 +1,369 @@
+// 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 Input Method Editors (IMEs) are OS-level widgets that make
+ * it easier to type non-ascii characters on ascii keyboards (in particular,
+ * characters that require more than one keystroke).
+ *
+ * When the user wants to type such a character, a modal menu pops up and
+ * suggests possible "next" characters in the IME character sequence. After
+ * typing N characters, the user hits "enter" to commit the IME to the field.
+ * N differs from language to language.
+ *
+ * This class offers high-level events for how the user is interacting with the
+ * IME in editable regions.
+ *
+ * Known Issues:
+ *
+ * Firefox always fires an extra pair of compositionstart/compositionend events.
+ * We do not normalize for this.
+ *
+ * Opera does not fire any IME events.
+ *
+ * Spurious UPDATE events are common on all browsers.
+ *
+ * We currently do a bad job detecting when the IME closes on IE, and
+ * make a "best effort" guess on when we know it's closed.
+ *
+ * @author nicksantos@google.com (Nick Santos) (Ported to Closure)
+ */
+
+goog.provide('goog.events.ImeHandler');
+goog.provide('goog.events.ImeHandler.Event');
+goog.provide('goog.events.ImeHandler.EventType');
+
+goog.require('goog.events.Event');
+goog.require('goog.events.EventHandler');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
+goog.require('goog.events.KeyCodes');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * Dispatches high-level events for IMEs.
+ * @param {Element} el The element to listen on.
+ * @extends {goog.events.EventTarget}
+ * @constructor
+ * @final
+ */
+goog.events.ImeHandler = function(el) {
+  goog.events.ImeHandler.base(this, 'constructor');
+
+  /**
+   * The element to listen on.
+   * @type {Element}
+   * @private
+   */
+  this.el_ = el;
+
+  /**
+   * Tracks the keyup event only, because it has a different life-cycle from
+   * other events.
+   * @type {goog.events.EventHandler<!goog.events.ImeHandler>}
+   * @private
+   */
+  this.keyUpHandler_ = new goog.events.EventHandler(this);
+
+  /**
+   * Tracks all the browser events.
+   * @type {goog.events.EventHandler<!goog.events.ImeHandler>}
+   * @private
+   */
+  this.handler_ = new goog.events.EventHandler(this);
+
+  if (goog.events.ImeHandler.USES_COMPOSITION_EVENTS) {
+    this.handler_.
+        listen(el, goog.events.EventType.COMPOSITIONSTART,
+            this.handleCompositionStart_).
+        listen(el, goog.events.EventType.COMPOSITIONEND,
+            this.handleCompositionEnd_).
+        listen(el, goog.events.EventType.COMPOSITIONUPDATE,
+            this.handleTextModifyingInput_);
+  }
+
+  this.handler_.
+      listen(el, goog.events.EventType.TEXTINPUT, this.handleTextInput_).
+      listen(el, goog.events.EventType.TEXT, this.handleTextModifyingInput_).
+      listen(el, goog.events.EventType.KEYDOWN, this.handleKeyDown_);
+};
+goog.inherits(goog.events.ImeHandler, goog.events.EventTarget);
+
+
+/**
+ * Event types fired by ImeHandler. These events do not make any guarantees
+ * about whether they were fired before or after the event in question.
+ * @enum {string}
+ */
+goog.events.ImeHandler.EventType = {
+  // After the IME opens.
+  START: 'startIme',
+
+  // An update to the state of the IME. An 'update' does not necessarily mean
+  // that the text contents of the field were modified in any way.
+  UPDATE: 'updateIme',
+
+  // After the IME closes.
+  END: 'endIme'
+};
+
+
+
+/**
+ * An event fired by ImeHandler.
+ * @param {goog.events.ImeHandler.EventType} type The type.
+ * @param {goog.events.BrowserEvent} reason The trigger for this event.
+ * @constructor
+ * @extends {goog.events.Event}
+ * @final
+ */
+goog.events.ImeHandler.Event = function(type, reason) {
+  goog.events.ImeHandler.Event.base(this, 'constructor', type);
+
+  /**
+   * The event that triggered this.
+   * @type {goog.events.BrowserEvent}
+   */
+  this.reason = reason;
+};
+goog.inherits(goog.events.ImeHandler.Event, goog.events.Event);
+
+
+/**
+ * Whether to use the composition events.
+ * @type {boolean}
+ */
+goog.events.ImeHandler.USES_COMPOSITION_EVENTS =
+    goog.userAgent.GECKO ||
+    (goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher(532));
+
+
+/**
+ * Stores whether IME mode is active.
+ * @type {boolean}
+ * @private
+ */
+goog.events.ImeHandler.prototype.imeMode_ = false;
+
+
+/**
+ * The keyCode value of the last keyDown event. This value is used for
+ * identiying whether or not a textInput event is sent by an IME.
+ * @type {number}
+ * @private
+ */
+goog.events.ImeHandler.prototype.lastKeyCode_ = 0;
+
+
+/**
+ * @return {boolean} Whether an IME is active.
+ */
+goog.events.ImeHandler.prototype.isImeMode = function() {
+  return this.imeMode_;
+};
+
+
+/**
+ * Handles the compositionstart event.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleCompositionStart_ =
+    function(e) {
+  this.handleImeActivate_(e);
+};
+
+
+/**
+ * Handles the compositionend event.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleCompositionEnd_ = function(e) {
+  this.handleImeDeactivate_(e);
+};
+
+
+/**
+ * Handles the compositionupdate and text events.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleTextModifyingInput_ =
+    function(e) {
+  if (this.isImeMode()) {
+    this.processImeComposition_(e);
+  }
+};
+
+
+/**
+ * Handles IME activation.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleImeActivate_ = function(e) {
+  if (this.imeMode_) {
+    return;
+  }
+
+  // Listens for keyup events to handle unexpected IME keydown events on older
+  // versions of webkit.
+  //
+  // In those versions, we currently use textInput events deactivate IME
+  // (see handleTextInput_() for the reason). However,
+  // Safari fires a keydown event (as a result of pressing keys to commit IME
+  // text) with keyCode == WIN_IME after textInput event. This activates IME
+  // mode again unnecessarily. To prevent this problem, listens keyup events
+  // which can use to determine whether IME text has been committed.
+  if (goog.userAgent.WEBKIT &&
+      !goog.events.ImeHandler.USES_COMPOSITION_EVENTS) {
+    this.keyUpHandler_.listen(this.el_,
+        goog.events.EventType.KEYUP, this.handleKeyUpSafari4_);
+  }
+
+  this.imeMode_ = true;
+  this.dispatchEvent(
+      new goog.events.ImeHandler.Event(
+          goog.events.ImeHandler.EventType.START, e));
+};
+
+
+/**
+ * Handles the IME compose changes.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.processImeComposition_ = function(e) {
+  this.dispatchEvent(
+      new goog.events.ImeHandler.Event(
+          goog.events.ImeHandler.EventType.UPDATE, e));
+};
+
+
+/**
+ * Handles IME deactivation.
+ * @param {goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleImeDeactivate_ = function(e) {
+  this.imeMode_ = false;
+  this.keyUpHandler_.removeAll();
+  this.dispatchEvent(
+      new goog.events.ImeHandler.Event(
+          goog.events.ImeHandler.EventType.END, e));
+};
+
+
+/**
+ * Handles a key down event.
+ * @param {!goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleKeyDown_ = function(e) {
+  // Firefox and Chrome have a separate event for IME composition ('text'
+  // and 'compositionupdate', respectively), other browsers do not.
+  if (!goog.events.ImeHandler.USES_COMPOSITION_EVENTS) {
+    var imeMode = this.isImeMode();
+    // If we're in IE and we detect an IME input on keyDown then activate
+    // the IME, otherwise if the imeMode was previously active, deactivate.
+    if (!imeMode && e.keyCode == goog.events.KeyCodes.WIN_IME) {
+      this.handleImeActivate_(e);
+    } else if (imeMode && e.keyCode != goog.events.KeyCodes.WIN_IME) {
+      if (goog.events.ImeHandler.isImeDeactivateKeyEvent_(e)) {
+        this.handleImeDeactivate_(e);
+      }
+    } else if (imeMode) {
+      this.processImeComposition_(e);
+    }
+  }
+
+  // Safari on Mac doesn't send IME events in the right order so that we must
+  // ignore some modifier key events to insert IME text correctly.
+  if (goog.events.ImeHandler.isImeDeactivateKeyEvent_(e)) {
+    this.lastKeyCode_ = e.keyCode;
+  }
+};
+
+
+/**
+ * Handles a textInput event.
+ * @param {!goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleTextInput_ = function(e) {
+  // Some WebKit-based browsers including Safari 4 don't send composition
+  // events. So, we turn down IME mode when it's still there.
+  if (!goog.events.ImeHandler.USES_COMPOSITION_EVENTS &&
+      goog.userAgent.WEBKIT &&
+      this.lastKeyCode_ == goog.events.KeyCodes.WIN_IME &&
+      this.isImeMode()) {
+    this.handleImeDeactivate_(e);
+  }
+};
+
+
+/**
+ * Handles the key up event for any IME activity. This handler is just used to
+ * prevent activating IME unnecessary in Safari at this time.
+ * @param {!goog.events.BrowserEvent} e The event.
+ * @private
+ */
+goog.events.ImeHandler.prototype.handleKeyUpSafari4_ = function(e) {
+  if (this.isImeMode()) {
+    switch (e.keyCode) {
+      // These keyup events indicates that IME text has been committed or
+      // cancelled. We should turn off IME mode when these keyup events
+      // received.
+      case goog.events.KeyCodes.ENTER:
+      case goog.events.KeyCodes.TAB:
+      case goog.events.KeyCodes.ESC:
+        this.handleImeDeactivate_(e);
+        break;
+    }
+  }
+};
+
+
+/**
+ * Returns whether the given event should be treated as an IME
+ * deactivation trigger.
+ * @param {!goog.events.Event} e The event.
+ * @return {boolean} Whether the given event is an IME deactivate trigger.
+ * @private
+ */
+goog.events.ImeHandler.isImeDeactivateKeyEvent_ = function(e) {
+  // Which key events involve IME deactivation depends on the user's
+  // environment (i.e. browsers, platforms, and IMEs). Usually Shift key
+  // and Ctrl key does not involve IME deactivation, so we currently assume
+  // that these keys are not IME deactivation trigger.
+  switch (e.keyCode) {
+    case goog.events.KeyCodes.SHIFT:
+    case goog.events.KeyCodes.CTRL:
+      return false;
+    default:
+      return true;
+  }
+};
+
+
+/** @override */
+goog.events.ImeHandler.prototype.disposeInternal = function() {
+  this.handler_.dispose();
+  this.keyUpHandler_.dispose();
+  this.el_ = null;
+  goog.events.ImeHandler.base(this, 'disposeInternal');
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/inputhandler.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/inputhandler.js b/externs/GCL/externs/goog/events/inputhandler.js
new file mode 100644
index 0000000..b4d8740
--- /dev/null
+++ b/externs/GCL/externs/goog/events/inputhandler.js
@@ -0,0 +1,212 @@
+// 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 An object that encapsulates text changed events for textareas
+ * and input element of type text and password. The event occurs after the value
+ * has been changed. The event does not occur if value was changed
+ * programmatically.<br>
+ * <br>
+ * Note: this does not guarantee the correctness of {@code keyCode} or
+ * {@code charCode}, or attempt to unify them across browsers. See
+ * {@code goog.events.KeyHandler} for that functionality<br>
+ * <br>
+ * Known issues:
+ * <ul>
+ * <li>IE doesn't have native support for input event. WebKit before version 531
+ *     doesn't have support for textareas. For those browsers an emulation mode
+ *     based on key, clipboard and drop events is used. Thus this event won't
+ *     trigger in emulation mode if text was modified by context menu commands
+ *     such as 'Undo' and 'Delete'.
+ * </ul>
+ * @author arv@google.com (Erik Arvidsson)
+ * @see ../demos/inputhandler.html
+ */
+
+goog.provide('goog.events.InputHandler');
+goog.provide('goog.events.InputHandler.EventType');
+
+goog.require('goog.Timer');
+goog.require('goog.dom.TagName');
+goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventHandler');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.KeyCodes');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * This event handler will dispatch events when the user types into a text
+ * input, password input or a textarea
+ * @param {Element} element  The element that you want to listen for input
+ *     events on.
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ */
+goog.events.InputHandler = function(element) {
+  goog.events.InputHandler.base(this, 'constructor');
+
+  /**
+   * Id of a timer used to postpone firing input event in emulation mode.
+   * @type {?number}
+   * @private
+   */
+  this.timer_ = null;
+
+  /**
+   * The element that you want to listen for input events on.
+   * @type {Element}
+   * @private
+   */
+  this.element_ = element;
+
+  // Determine whether input event should be emulated.
+  // IE8 doesn't support input events. We could use property change events but
+  // they are broken in many ways:
+  // - Fire even if value was changed programmatically.
+  // - Aren't always delivered. For example, if you change value or even width
+  //   of input programmatically, next value change made by user won't fire an
+  //   event.
+  // IE9 supports input events when characters are inserted, but not deleted.
+  // WebKit before version 531 did not support input events for textareas.
+  var emulateInputEvents = goog.userAgent.IE ||
+      (goog.userAgent.WEBKIT && !goog.userAgent.isVersionOrHigher('531') &&
+          element.tagName == goog.dom.TagName.TEXTAREA);
+
+  /**
+   * @type {goog.events.EventHandler<!goog.events.InputHandler>}
+   * @private
+   */
+  this.eventHandler_ = new goog.events.EventHandler(this);
+
+  // Even if input event emulation is enabled, still listen for input events
+  // since they may be partially supported by the browser (such as IE9).
+  // If the input event does fire, we will be able to dispatch synchronously.
+  // (InputHandler events being asynchronous for IE is a common issue for
+  // cases like auto-grow textareas where they result in a quick flash of
+  // scrollbars between the textarea content growing and it being resized to
+  // fit.)
+  this.eventHandler_.listen(
+      this.element_,
+      emulateInputEvents ?
+          ['keydown', 'paste', 'cut', 'drop', 'input'] :
+          'input',
+      this);
+};
+goog.inherits(goog.events.InputHandler, goog.events.EventTarget);
+
+
+/**
+ * Enum type for the events fired by the input handler
+ * @enum {string}
+ */
+goog.events.InputHandler.EventType = {
+  INPUT: 'input'
+};
+
+
+/**
+ * This handles the underlying events and dispatches a new event as needed.
+ * @param {goog.events.BrowserEvent} e The underlying browser event.
+ */
+goog.events.InputHandler.prototype.handleEvent = function(e) {
+  if (e.type == 'input') {
+    // http://stackoverflow.com/questions/18389732/changing-placeholder-triggers-input-event-in-ie-10
+    // IE 10+ fires an input event when there are inputs with placeholders.
+    // It fires the event with keycode 0, so if we detect it we don't
+    // propagate the input event.
+    if (goog.userAgent.IE && goog.userAgent.isVersionOrHigher(10) &&
+        e.keyCode == 0 && e.charCode == 0) {
+      return;
+    }
+    // This event happens after all the other events we listen to, so cancel
+    // an asynchronous event dispatch if we have it queued up.  Otherwise, we
+    // will end up firing an extra event.
+    this.cancelTimerIfSet_();
+
+    this.dispatchEvent(this.createInputEvent_(e));
+  } else {
+    // Filter out key events that don't modify text.
+    if (e.type == 'keydown' &&
+        !goog.events.KeyCodes.isTextModifyingKeyEvent(e)) {
+      return;
+    }
+
+    // It is still possible that pressed key won't modify the value of an
+    // element. Storing old value will help us to detect modification but is
+    // also a little bit dangerous. If value is changed programmatically in
+    // another key down handler, we will detect it as user-initiated change.
+    var valueBeforeKey = e.type == 'keydown' ? this.element_.value : null;
+
+    // In IE on XP, IME the element's value has already changed when we get
+    // keydown events when the user is using an IME. In this case, we can't
+    // check the current value normally, so we assume that it's a modifying key
+    // event. This means that ENTER when used to commit will fire a spurious
+    // input event, but it's better to have a false positive than let some input
+    // slip through the cracks.
+    if (goog.userAgent.IE && e.keyCode == goog.events.KeyCodes.WIN_IME) {
+      valueBeforeKey = null;
+    }
+
+    // Create an input event now, because when we fire it on timer, the
+    // underlying event will already be disposed.
+    var inputEvent = this.createInputEvent_(e);
+
+    // Since key down, paste, cut and drop events are fired before actual value
+    // of the element has changed, we need to postpone dispatching input event
+    // until value is updated.
+    this.cancelTimerIfSet_();
+    this.timer_ = goog.Timer.callOnce(function() {
+      this.timer_ = null;
+      if (this.element_.value != valueBeforeKey) {
+        this.dispatchEvent(inputEvent);
+      }
+    }, 0, this);
+  }
+};
+
+
+/**
+ * Cancels timer if it is set, does nothing otherwise.
+ * @private
+ */
+goog.events.InputHandler.prototype.cancelTimerIfSet_ = function() {
+  if (this.timer_ != null) {
+    goog.Timer.clear(this.timer_);
+    this.timer_ = null;
+  }
+};
+
+
+/**
+ * Creates an input event from the browser event.
+ * @param {goog.events.BrowserEvent} be A browser event.
+ * @return {!goog.events.BrowserEvent} An input event.
+ * @private
+ */
+goog.events.InputHandler.prototype.createInputEvent_ = function(be) {
+  var e = new goog.events.BrowserEvent(be.getBrowserEvent());
+  e.type = goog.events.InputHandler.EventType.INPUT;
+  return e;
+};
+
+
+/** @override */
+goog.events.InputHandler.prototype.disposeInternal = function() {
+  goog.events.InputHandler.base(this, 'disposeInternal');
+  this.eventHandler_.dispose();
+  this.cancelTimerIfSet_();
+  delete this.element_;
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/keycodes.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/keycodes.js b/externs/GCL/externs/goog/events/keycodes.js
new file mode 100644
index 0000000..ec269ae
--- /dev/null
+++ b/externs/GCL/externs/goog/events/keycodes.js
@@ -0,0 +1,420 @@
+// 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 Constant declarations for common key codes.
+ *
+ * @author eae@google.com (Emil A Eklund)
+ * @see ../demos/keyhandler.html
+ */
+
+goog.provide('goog.events.KeyCodes');
+
+goog.require('goog.userAgent');
+
+
+/**
+ * Key codes for common characters.
+ *
+ * This list is not localized and therefore some of the key codes are not
+ * correct for non US keyboard layouts. See comments below.
+ *
+ * @enum {number}
+ */
+goog.events.KeyCodes = {
+  WIN_KEY_FF_LINUX: 0,
+  MAC_ENTER: 3,
+  BACKSPACE: 8,
+  TAB: 9,
+  NUM_CENTER: 12,  // NUMLOCK on FF/Safari Mac
+  ENTER: 13,
+  SHIFT: 16,
+  CTRL: 17,
+  ALT: 18,
+  PAUSE: 19,
+  CAPS_LOCK: 20,
+  ESC: 27,
+  SPACE: 32,
+  PAGE_UP: 33,     // also NUM_NORTH_EAST
+  PAGE_DOWN: 34,   // also NUM_SOUTH_EAST
+  END: 35,         // also NUM_SOUTH_WEST
+  HOME: 36,        // also NUM_NORTH_WEST
+  LEFT: 37,        // also NUM_WEST
+  UP: 38,          // also NUM_NORTH
+  RIGHT: 39,       // also NUM_EAST
+  DOWN: 40,        // also NUM_SOUTH
+  PRINT_SCREEN: 44,
+  INSERT: 45,      // also NUM_INSERT
+  DELETE: 46,      // also NUM_DELETE
+  ZERO: 48,
+  ONE: 49,
+  TWO: 50,
+  THREE: 51,
+  FOUR: 52,
+  FIVE: 53,
+  SIX: 54,
+  SEVEN: 55,
+  EIGHT: 56,
+  NINE: 57,
+  FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 186
+  FF_EQUALS: 61, // Firefox (Gecko) fires this for equals instead of 187
+  FF_DASH: 173, // Firefox (Gecko) fires this for dash instead of 189
+  QUESTION_MARK: 63, // needs localization
+  A: 65,
+  B: 66,
+  C: 67,
+  D: 68,
+  E: 69,
+  F: 70,
+  G: 71,
+  H: 72,
+  I: 73,
+  J: 74,
+  K: 75,
+  L: 76,
+  M: 77,
+  N: 78,
+  O: 79,
+  P: 80,
+  Q: 81,
+  R: 82,
+  S: 83,
+  T: 84,
+  U: 85,
+  V: 86,
+  W: 87,
+  X: 88,
+  Y: 89,
+  Z: 90,
+  META: 91, // WIN_KEY_LEFT
+  WIN_KEY_RIGHT: 92,
+  CONTEXT_MENU: 93,
+  NUM_ZERO: 96,
+  NUM_ONE: 97,
+  NUM_TWO: 98,
+  NUM_THREE: 99,
+  NUM_FOUR: 100,
+  NUM_FIVE: 101,
+  NUM_SIX: 102,
+  NUM_SEVEN: 103,
+  NUM_EIGHT: 104,
+  NUM_NINE: 105,
+  NUM_MULTIPLY: 106,
+  NUM_PLUS: 107,
+  NUM_MINUS: 109,
+  NUM_PERIOD: 110,
+  NUM_DIVISION: 111,
+  F1: 112,
+  F2: 113,
+  F3: 114,
+  F4: 115,
+  F5: 116,
+  F6: 117,
+  F7: 118,
+  F8: 119,
+  F9: 120,
+  F10: 121,
+  F11: 122,
+  F12: 123,
+  NUMLOCK: 144,
+  SCROLL_LOCK: 145,
+
+  // OS-specific media keys like volume controls and browser controls.
+  FIRST_MEDIA_KEY: 166,
+  LAST_MEDIA_KEY: 183,
+
+  SEMICOLON: 186,            // needs localization
+  DASH: 189,                 // needs localization
+  EQUALS: 187,               // needs localization
+  COMMA: 188,                // needs localization
+  PERIOD: 190,               // needs localization
+  SLASH: 191,                // needs localization
+  APOSTROPHE: 192,           // needs localization
+  TILDE: 192,                // needs localization
+  SINGLE_QUOTE: 222,         // needs localization
+  OPEN_SQUARE_BRACKET: 219,  // needs localization
+  BACKSLASH: 220,            // needs localization
+  CLOSE_SQUARE_BRACKET: 221, // needs localization
+  WIN_KEY: 224,
+  MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
+  MAC_WK_CMD_LEFT: 91,  // WebKit Left Command key fired, same as META
+  MAC_WK_CMD_RIGHT: 93, // WebKit Right Command key fired, different from META
+  WIN_IME: 229,
+
+  // "Reserved for future use". Some programs (e.g. the SlingPlayer 2.4 ActiveX
+  // control) fire this as a hacky way to disable screensavers.
+  VK_NONAME: 252,
+
+  // We've seen users whose machines fire this keycode at regular one
+  // second intervals. The common thread among these users is that
+  // they're all using Dell Inspiron laptops, so we suspect that this
+  // indicates a hardware/bios problem.
+  // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx
+  PHANTOM: 255
+};
+
+
+/**
+ * Returns true if the event contains a text modifying key.
+ * @param {goog.events.BrowserEvent} e A key event.
+ * @return {boolean} Whether it's a text modifying key.
+ */
+goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
+  if (e.altKey && !e.ctrlKey ||
+      e.metaKey ||
+      // Function keys don't generate text
+      e.keyCode >= goog.events.KeyCodes.F1 &&
+      e.keyCode <= goog.events.KeyCodes.F12) {
+    return false;
+  }
+
+  // The following keys are quite harmless, even in combination with
+  // CTRL, ALT or SHIFT.
+  switch (e.keyCode) {
+    case goog.events.KeyCodes.ALT:
+    case goog.events.KeyCodes.CAPS_LOCK:
+    case goog.events.KeyCodes.CONTEXT_MENU:
+    case goog.events.KeyCodes.CTRL:
+    case goog.events.KeyCodes.DOWN:
+    case goog.events.KeyCodes.END:
+    case goog.events.KeyCodes.ESC:
+    case goog.events.KeyCodes.HOME:
+    case goog.events.KeyCodes.INSERT:
+    case goog.events.KeyCodes.LEFT:
+    case goog.events.KeyCodes.MAC_FF_META:
+    case goog.events.KeyCodes.META:
+    case goog.events.KeyCodes.NUMLOCK:
+    case goog.events.KeyCodes.NUM_CENTER:
+    case goog.events.KeyCodes.PAGE_DOWN:
+    case goog.events.KeyCodes.PAGE_UP:
+    case goog.events.KeyCodes.PAUSE:
+    case goog.events.KeyCodes.PHANTOM:
+    case goog.events.KeyCodes.PRINT_SCREEN:
+    case goog.events.KeyCodes.RIGHT:
+    case goog.events.KeyCodes.SCROLL_LOCK:
+    case goog.events.KeyCodes.SHIFT:
+    case goog.events.KeyCodes.UP:
+    case goog.events.KeyCodes.VK_NONAME:
+    case goog.events.KeyCodes.WIN_KEY:
+    case goog.events.KeyCodes.WIN_KEY_RIGHT:
+      return false;
+    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
+      return !goog.userAgent.GECKO;
+    default:
+      return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||
+          e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
+  }
+};
+
+
+/**
+ * Returns true if the key fires a keypress event in the current browser.
+ *
+ * Accoridng to MSDN [1] IE only fires keypress events for the following keys:
+ * - Letters: A - Z (uppercase and lowercase)
+ * - Numerals: 0 - 9
+ * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
+ * - System: ESC, SPACEBAR, ENTER
+ *
+ * That's not entirely correct though, for instance there's no distinction
+ * between upper and lower case letters.
+ *
+ * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
+ *
+ * Safari is similar to IE, but does not fire keypress for ESC.
+ *
+ * Additionally, IE6 does not fire keydown or keypress events for letters when
+ * the control or alt keys are held down and the shift key is not. IE7 does
+ * fire keydown in these cases, though, but not keypress.
+ *
+ * @param {number} keyCode A key code.
+ * @param {number=} opt_heldKeyCode Key code of a currently-held key.
+ * @param {boolean=} opt_shiftKey Whether the shift key is held down.
+ * @param {boolean=} opt_ctrlKey Whether the control key is held down.
+ * @param {boolean=} opt_altKey Whether the alt key is held down.
+ * @return {boolean} Whether it's a key that fires a keypress event.
+ */
+goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode,
+    opt_shiftKey, opt_ctrlKey, opt_altKey) {
+  if (!goog.userAgent.IE &&
+      !(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) {
+    return true;
+  }
+
+  if (goog.userAgent.MAC && opt_altKey) {
+    return goog.events.KeyCodes.isCharacterKey(keyCode);
+  }
+
+  // Alt but not AltGr which is represented as Alt+Ctrl.
+  if (opt_altKey && !opt_ctrlKey) {
+    return false;
+  }
+
+  // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.
+  // Non-IE browsers and WebKit prior to 525 won't get this far so no need to
+  // check the user agent.
+  if (goog.isNumber(opt_heldKeyCode)) {
+    opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode);
+  }
+  if (!opt_shiftKey &&
+      (opt_heldKeyCode == goog.events.KeyCodes.CTRL ||
+       opt_heldKeyCode == goog.events.KeyCodes.ALT ||
+       goog.userAgent.MAC &&
+       opt_heldKeyCode == goog.events.KeyCodes.META)) {
+    return false;
+  }
+
+  // Some keys with Ctrl/Shift do not issue keypress in WEBKIT.
+  if (goog.userAgent.WEBKIT && opt_ctrlKey && opt_shiftKey) {
+    switch (keyCode) {
+      case goog.events.KeyCodes.BACKSLASH:
+      case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
+      case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
+      case goog.events.KeyCodes.TILDE:
+      case goog.events.KeyCodes.SEMICOLON:
+      case goog.events.KeyCodes.DASH:
+      case goog.events.KeyCodes.EQUALS:
+      case goog.events.KeyCodes.COMMA:
+      case goog.events.KeyCodes.PERIOD:
+      case goog.events.KeyCodes.SLASH:
+      case goog.events.KeyCodes.APOSTROPHE:
+      case goog.events.KeyCodes.SINGLE_QUOTE:
+        return false;
+    }
+  }
+
+  // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
+  // continues to fire keydown events as the event repeats.
+  if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
+    return false;
+  }
+
+  switch (keyCode) {
+    case goog.events.KeyCodes.ENTER:
+      return true;
+    case goog.events.KeyCodes.ESC:
+      return !goog.userAgent.WEBKIT;
+  }
+
+  return goog.events.KeyCodes.isCharacterKey(keyCode);
+};
+
+
+/**
+ * Returns true if the key produces a character.
+ * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).
+ *
+ * @param {number} keyCode A key code.
+ * @return {boolean} Whether it's a character key.
+ */
+goog.events.KeyCodes.isCharacterKey = function(keyCode) {
+  if (keyCode >= goog.events.KeyCodes.ZERO &&
+      keyCode <= goog.events.KeyCodes.NINE) {
+    return true;
+  }
+
+  if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&
+      keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
+    return true;
+  }
+
+  if (keyCode >= goog.events.KeyCodes.A &&
+      keyCode <= goog.events.KeyCodes.Z) {
+    return true;
+  }
+
+  // Safari sends zero key code for non-latin characters.
+  if (goog.userAgent.WEBKIT && keyCode == 0) {
+    return true;
+  }
+
+  switch (keyCode) {
+    case goog.events.KeyCodes.SPACE:
+    case goog.events.KeyCodes.QUESTION_MARK:
+    case goog.events.KeyCodes.NUM_PLUS:
+    case goog.events.KeyCodes.NUM_MINUS:
+    case goog.events.KeyCodes.NUM_PERIOD:
+    case goog.events.KeyCodes.NUM_DIVISION:
+    case goog.events.KeyCodes.SEMICOLON:
+    case goog.events.KeyCodes.FF_SEMICOLON:
+    case goog.events.KeyCodes.DASH:
+    case goog.events.KeyCodes.EQUALS:
+    case goog.events.KeyCodes.FF_EQUALS:
+    case goog.events.KeyCodes.COMMA:
+    case goog.events.KeyCodes.PERIOD:
+    case goog.events.KeyCodes.SLASH:
+    case goog.events.KeyCodes.APOSTROPHE:
+    case goog.events.KeyCodes.SINGLE_QUOTE:
+    case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
+    case goog.events.KeyCodes.BACKSLASH:
+    case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
+      return true;
+    default:
+      return false;
+  }
+};
+
+
+/**
+ * Normalizes key codes from OS/Browser-specific value to the general one.
+ * @param {number} keyCode The native key code.
+ * @return {number} The normalized key code.
+ */
+goog.events.KeyCodes.normalizeKeyCode = function(keyCode) {
+  if (goog.userAgent.GECKO) {
+    return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode);
+  } else if (goog.userAgent.MAC && goog.userAgent.WEBKIT) {
+    return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode);
+  } else {
+    return keyCode;
+  }
+};
+
+
+/**
+ * Normalizes key codes from their Gecko-specific value to the general one.
+ * @param {number} keyCode The native key code.
+ * @return {number} The normalized key code.
+ */
+goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) {
+  switch (keyCode) {
+    case goog.events.KeyCodes.FF_EQUALS:
+      return goog.events.KeyCodes.EQUALS;
+    case goog.events.KeyCodes.FF_SEMICOLON:
+      return goog.events.KeyCodes.SEMICOLON;
+    case goog.events.KeyCodes.FF_DASH:
+      return goog.events.KeyCodes.DASH;
+    case goog.events.KeyCodes.MAC_FF_META:
+      return goog.events.KeyCodes.META;
+    case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
+      return goog.events.KeyCodes.WIN_KEY;
+    default:
+      return keyCode;
+  }
+};
+
+
+/**
+ * Normalizes key codes from their Mac WebKit-specific value to the general one.
+ * @param {number} keyCode The native key code.
+ * @return {number} The normalized key code.
+ */
+goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) {
+  switch (keyCode) {
+    case goog.events.KeyCodes.MAC_WK_CMD_RIGHT:  // 93
+      return goog.events.KeyCodes.META;          // 91
+    default:
+      return keyCode;
+  }
+};

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/keyhandler.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/keyhandler.js b/externs/GCL/externs/goog/events/keyhandler.js
new file mode 100644
index 0000000..9f20250
--- /dev/null
+++ b/externs/GCL/externs/goog/events/keyhandler.js
@@ -0,0 +1,556 @@
+// 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 This file contains a class for working with keyboard events
+ * that repeat consistently across browsers and platforms. It also unifies the
+ * key code so that it is the same in all browsers and platforms.
+ *
+ * Different web browsers have very different keyboard event handling. Most
+ * importantly is that only certain browsers repeat keydown events:
+ * IE, Opera, FF/Win32, and Safari 3 repeat keydown events.
+ * FF/Mac and Safari 2 do not.
+ *
+ * For the purposes of this code, "Safari 3" means WebKit 525+, when WebKit
+ * decided that they should try to match IE's key handling behavior.
+ * Safari 3.0.4, which shipped with Leopard (WebKit 523), has the
+ * Safari 2 behavior.
+ *
+ * Firefox, Safari, Opera prevent on keypress
+ *
+ * IE prevents on keydown
+ *
+ * Firefox does not fire keypress for shift, ctrl, alt
+ * Firefox does fire keydown for shift, ctrl, alt, meta
+ * Firefox does not repeat keydown for shift, ctrl, alt, meta
+ *
+ * Firefox does not fire keypress for up and down in an input
+ *
+ * Opera fires keypress for shift, ctrl, alt, meta
+ * Opera does not repeat keypress for shift, ctrl, alt, meta
+ *
+ * Safari 2 and 3 do not fire keypress for shift, ctrl, alt
+ * Safari 2 does not fire keydown for shift, ctrl, alt
+ * Safari 3 *does* fire keydown for shift, ctrl, alt
+ *
+ * IE provides the keycode for keyup/down events and the charcode (in the
+ * keycode field) for keypress.
+ *
+ * Mozilla provides the keycode for keyup/down and the charcode for keypress
+ * unless it's a non text modifying key in which case the keycode is provided.
+ *
+ * Safari 3 provides the keycode and charcode for all events.
+ *
+ * Opera provides the keycode for keyup/down event and either the charcode or
+ * the keycode (in the keycode field) for keypress events.
+ *
+ * Firefox x11 doesn't fire keydown events if a another key is already held down
+ * until the first key is released. This can cause a key event to be fired with
+ * a keyCode for the first key and a charCode for the second key.
+ *
+ * Safari in keypress
+ *
+ *        charCode keyCode which
+ * ENTER:       13      13    13
+ * F1:       63236   63236 63236
+ * F8:       63243   63243 63243
+ * ...
+ * p:          112     112   112
+ * P:           80      80    80
+ *
+ * Firefox, keypress:
+ *
+ *        charCode keyCode which
+ * ENTER:        0      13    13
+ * F1:           0     112     0
+ * F8:           0     119     0
+ * ...
+ * p:          112       0   112
+ * P:           80       0    80
+ *
+ * Opera, Mac+Win32, keypress:
+ *
+ *         charCode keyCode which
+ * ENTER: undefined      13    13
+ * F1:    undefined     112     0
+ * F8:    undefined     119     0
+ * ...
+ * p:     undefined     112   112
+ * P:     undefined      80    80
+ *
+ * IE7, keydown
+ *
+ *         charCode keyCode     which
+ * ENTER: undefined      13 undefined
+ * F1:    undefined     112 undefined
+ * F8:    undefined     119 undefined
+ * ...
+ * p:     undefined      80 undefined
+ * P:     undefined      80 undefined
+ *
+ * @author arv@google.com (Erik Arvidsson)
+ * @author eae@google.com (Emil A Eklund)
+ * @see ../demos/keyhandler.html
+ */
+
+goog.provide('goog.events.KeyEvent');
+goog.provide('goog.events.KeyHandler');
+goog.provide('goog.events.KeyHandler.EventType');
+
+goog.require('goog.events');
+goog.require('goog.events.BrowserEvent');
+goog.require('goog.events.EventTarget');
+goog.require('goog.events.EventType');
+goog.require('goog.events.KeyCodes');
+goog.require('goog.userAgent');
+
+
+
+/**
+ * A wrapper around an element that you want to listen to keyboard events on.
+ * @param {Element|Document=} opt_element The element or document to listen on.
+ * @param {boolean=} opt_capture Whether to listen for browser events in
+ *     capture phase (defaults to false).
+ * @constructor
+ * @extends {goog.events.EventTarget}
+ * @final
+ */
+goog.events.KeyHandler = function(opt_element, opt_capture) {
+  goog.events.EventTarget.call(this);
+
+  if (opt_element) {
+    this.attach(opt_element, opt_capture);
+  }
+};
+goog.inherits(goog.events.KeyHandler, goog.events.EventTarget);
+
+
+/**
+ * This is the element that we will listen to the real keyboard events on.
+ * @type {Element|Document|null}
+ * @private
+ */
+goog.events.KeyHandler.prototype.element_ = null;
+
+
+/**
+ * The key for the key press listener.
+ * @type {goog.events.Key}
+ * @private
+ */
+goog.events.KeyHandler.prototype.keyPressKey_ = null;
+
+
+/**
+ * The key for the key down listener.
+ * @type {goog.events.Key}
+ * @private
+ */
+goog.events.KeyHandler.prototype.keyDownKey_ = null;
+
+
+/**
+ * The key for the key up listener.
+ * @type {goog.events.Key}
+ * @private
+ */
+goog.events.KeyHandler.prototype.keyUpKey_ = null;
+
+
+/**
+ * Used to detect keyboard repeat events.
+ * @private
+ * @type {number}
+ */
+goog.events.KeyHandler.prototype.lastKey_ = -1;
+
+
+/**
+ * Keycode recorded for key down events. As most browsers don't report the
+ * keycode in the key press event we need to record it in the key down phase.
+ * @private
+ * @type {number}
+ */
+goog.events.KeyHandler.prototype.keyCode_ = -1;
+
+
+/**
+ * Alt key recorded for key down events. FF on Mac does not report the alt key
+ * flag in the key press event, we need to record it in the key down phase.
+ * @type {boolean}
+ * @private
+ */
+goog.events.KeyHandler.prototype.altKey_ = false;
+
+
+/**
+ * Enum type for the events fired by the key handler
+ * @enum {string}
+ */
+goog.events.KeyHandler.EventType = {
+  KEY: 'key'
+};
+
+
+/**
+ * An enumeration of key codes that Safari 2 does incorrectly
+ * @type {Object}
+ * @private
+ */
+goog.events.KeyHandler.safariKey_ = {
+  '3': goog.events.KeyCodes.ENTER, // 13
+  '12': goog.events.KeyCodes.NUMLOCK, // 144
+  '63232': goog.events.KeyCodes.UP, // 38
+  '63233': goog.events.KeyCodes.DOWN, // 40
+  '63234': goog.events.KeyCodes.LEFT, // 37
+  '63235': goog.events.KeyCodes.RIGHT, // 39
+  '63236': goog.events.KeyCodes.F1, // 112
+  '63237': goog.events.KeyCodes.F2, // 113
+  '63238': goog.events.KeyCodes.F3, // 114
+  '63239': goog.events.KeyCodes.F4, // 115
+  '63240': goog.events.KeyCodes.F5, // 116
+  '63241': goog.events.KeyCodes.F6, // 117
+  '63242': goog.events.KeyCodes.F7, // 118
+  '63243': goog.events.KeyCodes.F8, // 119
+  '63244': goog.events.KeyCodes.F9, // 120
+  '63245': goog.events.KeyCodes.F10, // 121
+  '63246': goog.events.KeyCodes.F11, // 122
+  '63247': goog.events.KeyCodes.F12, // 123
+  '63248': goog.events.KeyCodes.PRINT_SCREEN, // 44
+  '63272': goog.events.KeyCodes.DELETE, // 46
+  '63273': goog.events.KeyCodes.HOME, // 36
+  '63275': goog.events.KeyCodes.END, // 35
+  '63276': goog.events.KeyCodes.PAGE_UP, // 33
+  '63277': goog.events.KeyCodes.PAGE_DOWN, // 34
+  '63289': goog.events.KeyCodes.NUMLOCK, // 144
+  '63302': goog.events.KeyCodes.INSERT // 45
+};
+
+
+/**
+ * An enumeration of key identifiers currently part of the W3C draft for DOM3
+ * and their mappings to keyCodes.
+ * http://www.w3.org/TR/DOM-Level-3-Events/keyset.html#KeySet-Set
+ * This is currently supported in Safari and should be platform independent.
+ * @type {Object}
+ * @private
+ */
+goog.events.KeyHandler.keyIdentifier_ = {
+  'Up': goog.events.KeyCodes.UP, // 38
+  'Down': goog.events.KeyCodes.DOWN, // 40
+  'Left': goog.events.KeyCodes.LEFT, // 37
+  'Right': goog.events.KeyCodes.RIGHT, // 39
+  'Enter': goog.events.KeyCodes.ENTER, // 13
+  'F1': goog.events.KeyCodes.F1, // 112
+  'F2': goog.events.KeyCodes.F2, // 113
+  'F3': goog.events.KeyCodes.F3, // 114
+  'F4': goog.events.KeyCodes.F4, // 115
+  'F5': goog.events.KeyCodes.F5, // 116
+  'F6': goog.events.KeyCodes.F6, // 117
+  'F7': goog.events.KeyCodes.F7, // 118
+  'F8': goog.events.KeyCodes.F8, // 119
+  'F9': goog.events.KeyCodes.F9, // 120
+  'F10': goog.events.KeyCodes.F10, // 121
+  'F11': goog.events.KeyCodes.F11, // 122
+  'F12': goog.events.KeyCodes.F12, // 123
+  'U+007F': goog.events.KeyCodes.DELETE, // 46
+  'Home': goog.events.KeyCodes.HOME, // 36
+  'End': goog.events.KeyCodes.END, // 35
+  'PageUp': goog.events.KeyCodes.PAGE_UP, // 33
+  'PageDown': goog.events.KeyCodes.PAGE_DOWN, // 34
+  'Insert': goog.events.KeyCodes.INSERT // 45
+};
+
+
+/**
+ * If true, the KeyEvent fires on keydown. Otherwise, it fires on keypress.
+ *
+ * @type {boolean}
+ * @private
+ */
+goog.events.KeyHandler.USES_KEYDOWN_ = goog.userAgent.IE ||
+    goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525');
+
+
+/**
+ * If true, the alt key flag is saved during the key down and reused when
+ * handling the key press. FF on Mac does not set the alt flag in the key press
+ * event.
+ * @type {boolean}
+ * @private
+ */
+goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_ = goog.userAgent.MAC &&
+    goog.userAgent.GECKO;
+
+
+/**
+ * Records the keycode for browsers that only returns the keycode for key up/
+ * down events. For browser/key combinations that doesn't trigger a key pressed
+ * event it also fires the patched key event.
+ * @param {goog.events.BrowserEvent} e The key down event.
+ * @private
+ */
+goog.events.KeyHandler.prototype.handleKeyDown_ = function(e) {
+  // Ctrl-Tab and Alt-Tab can cause the focus to be moved to another window
+  // before we've caught a key-up event.  If the last-key was one of these we
+  // reset the state.
+  if (goog.userAgent.WEBKIT) {
+    if (this.lastKey_ == goog.events.KeyCodes.CTRL && !e.ctrlKey ||
+        this.lastKey_ == goog.events.KeyCodes.ALT && !e.altKey ||
+        goog.userAgent.MAC &&
+        this.lastKey_ == goog.events.KeyCodes.META && !e.metaKey) {
+      this.lastKey_ = -1;
+      this.keyCode_ = -1;
+    }
+  }
+
+  if (this.lastKey_ == -1) {
+    if (e.ctrlKey && e.keyCode != goog.events.KeyCodes.CTRL) {
+      this.lastKey_ = goog.events.KeyCodes.CTRL;
+    } else if (e.altKey && e.keyCode != goog.events.KeyCodes.ALT) {
+      this.lastKey_ = goog.events.KeyCodes.ALT;
+    } else if (e.metaKey && e.keyCode != goog.events.KeyCodes.META) {
+      this.lastKey_ = goog.events.KeyCodes.META;
+    }
+  }
+
+  if (goog.events.KeyHandler.USES_KEYDOWN_ &&
+      !goog.events.KeyCodes.firesKeyPressEvent(e.keyCode,
+          this.lastKey_, e.shiftKey, e.ctrlKey, e.altKey)) {
+    this.handleEvent(e);
+  } else {
+    this.keyCode_ = goog.events.KeyCodes.normalizeKeyCode(e.keyCode);
+    if (goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_) {
+      this.altKey_ = e.altKey;
+    }
+  }
+};
+
+
+/**
+ * Resets the stored previous values. Needed to be called for webkit which will
+ * not generate a key up for meta key operations. This should only be called
+ * when having finished with repeat key possiblities.
+ */
+goog.events.KeyHandler.prototype.resetState = function() {
+  this.lastKey_ = -1;
+  this.keyCode_ = -1;
+};
+
+
+/**
+ * Clears the stored previous key value, resetting the key repeat status. Uses
+ * -1 because the Safari 3 Windows beta reports 0 for certain keys (like Home
+ * and End.)
+ * @param {goog.events.BrowserEvent} e The keyup event.
+ * @private
+ */
+goog.events.KeyHandler.prototype.handleKeyup_ = function(e) {
+  this.resetState();
+  this.altKey_ = e.altKey;
+};
+
+
+/**
+ * Handles the events on the element.
+ * @param {goog.events.BrowserEvent} e  The keyboard event sent from the
+ *     browser.
+ */
+goog.events.KeyHandler.prototype.handleEvent = function(e) {
+  var be = e.getBrowserEvent();
+  var keyCode, charCode;
+  var altKey = be.altKey;
+
+  // IE reports the character code in the keyCode field for keypress events.
+  // There are two exceptions however, Enter and Escape.
+  if (goog.userAgent.IE && e.type == goog.events.EventType.KEYPRESS) {
+    keyCode = this.keyCode_;
+    charCode = keyCode != goog.events.KeyCodes.ENTER &&
+        keyCode != goog.events.KeyCodes.ESC ?
+            be.keyCode : 0;
+
+  // Safari reports the character code in the keyCode field for keypress
+  // events but also has a charCode field.
+  } else if (goog.userAgent.WEBKIT &&
+      e.type == goog.events.EventType.KEYPRESS) {
+    keyCode = this.keyCode_;
+    charCode = be.charCode >= 0 && be.charCode < 63232 &&
+        goog.events.KeyCodes.isCharacterKey(keyCode) ?
+            be.charCode : 0;
+
+  // Opera reports the keycode or the character code in the keyCode field.
+  } else if (goog.userAgent.OPERA && !goog.userAgent.WEBKIT) {
+    keyCode = this.keyCode_;
+    charCode = goog.events.KeyCodes.isCharacterKey(keyCode) ?
+        be.keyCode : 0;
+
+  // Mozilla reports the character code in the charCode field.
+  } else {
+    keyCode = be.keyCode || this.keyCode_;
+    charCode = be.charCode || 0;
+    if (goog.events.KeyHandler.SAVE_ALT_FOR_KEYPRESS_) {
+      altKey = this.altKey_;
+    }
+    // On the Mac, shift-/ triggers a question mark char code and no key code
+    // (normalized to WIN_KEY), so we synthesize the latter.
+    if (goog.userAgent.MAC &&
+        charCode == goog.events.KeyCodes.QUESTION_MARK &&
+        keyCode == goog.events.KeyCodes.WIN_KEY) {
+      keyCode = goog.events.KeyCodes.SLASH;
+    }
+  }
+
+  keyCode = goog.events.KeyCodes.normalizeKeyCode(keyCode);
+  var key = keyCode;
+  var keyIdentifier = be.keyIdentifier;
+
+  // Correct the key value for certain browser-specific quirks.
+  if (keyCode) {
+    if (keyCode >= 63232 && keyCode in goog.events.KeyHandler.safariKey_) {
+      // NOTE(nicksantos): Safari 3 has fixed this problem,
+      // this is only needed for Safari 2.
+      key = goog.events.KeyHandler.safariKey_[keyCode];
+    } else {
+
+      // Safari returns 25 for Shift+Tab instead of 9.
+      if (keyCode == 25 && e.shiftKey) {
+        key = 9;
+      }
+    }
+  } else if (keyIdentifier &&
+             keyIdentifier in goog.events.KeyHandler.keyIdentifier_) {
+    // This is needed for Safari Windows because it currently doesn't give a
+    // keyCode/which for non printable keys.
+    key = goog.events.KeyHandler.keyIdentifier_[keyIdentifier];
+  }
+
+  // If we get the same keycode as a keydown/keypress without having seen a
+  // keyup event, then this event was caused by key repeat.
+  var repeat = key == this.lastKey_;
+  this.lastKey_ = key;
+
+  var event = new goog.events.KeyEvent(key, charCode, repeat, be);
+  event.altKey = altKey;
+  this.dispatchEvent(event);
+};
+
+
+/**
+ * Returns the element listened on for the real keyboard events.
+ * @return {Element|Document|null} The element listened on for the real
+ *     keyboard events.
+ */
+goog.events.KeyHandler.prototype.getElement = function() {
+  return this.element_;
+};
+
+
+/**
+ * Adds the proper key event listeners to the element.
+ * @param {Element|Document} element The element to listen on.
+ * @param {boolean=} opt_capture Whether to listen for browser events in
+ *     capture phase (defaults to false).
+ */
+goog.events.KeyHandler.prototype.attach = function(element, opt_capture) {
+  if (this.keyUpKey_) {
+    this.detach();
+  }
+
+  this.element_ = element;
+
+  this.keyPressKey_ = goog.events.listen(this.element_,
+                                         goog.events.EventType.KEYPRESS,
+                                         this,
+                                         opt_capture);
+
+  // Most browsers (Safari 2 being the notable exception) doesn't include the
+  // keyCode in keypress events (IE has the char code in the keyCode field and
+  // Mozilla only included the keyCode if there's no charCode). Thus we have to
+  // listen for keydown to capture the keycode.
+  this.keyDownKey_ = goog.events.listen(this.element_,
+                                        goog.events.EventType.KEYDOWN,
+                                        this.handleKeyDown_,
+                                        opt_capture,
+                                        this);
+
+
+  this.keyUpKey_ = goog.events.listen(this.element_,
+                                      goog.events.EventType.KEYUP,
+                                      this.handleKeyup_,
+                                      opt_capture,
+                                      this);
+};
+
+
+/**
+ * Removes the listeners that may exist.
+ */
+goog.events.KeyHandler.prototype.detach = function() {
+  if (this.keyPressKey_) {
+    goog.events.unlistenByKey(this.keyPressKey_);
+    goog.events.unlistenByKey(this.keyDownKey_);
+    goog.events.unlistenByKey(this.keyUpKey_);
+    this.keyPressKey_ = null;
+    this.keyDownKey_ = null;
+    this.keyUpKey_ = null;
+  }
+  this.element_ = null;
+  this.lastKey_ = -1;
+  this.keyCode_ = -1;
+};
+
+
+/** @override */
+goog.events.KeyHandler.prototype.disposeInternal = function() {
+  goog.events.KeyHandler.superClass_.disposeInternal.call(this);
+  this.detach();
+};
+
+
+
+/**
+ * This class is used for the goog.events.KeyHandler.EventType.KEY event and
+ * it overrides the key code with the fixed key code.
+ * @param {number} keyCode The adjusted key code.
+ * @param {number} charCode The unicode character code.
+ * @param {boolean} repeat Whether this event was generated by keyboard repeat.
+ * @param {Event} browserEvent Browser event object.
+ * @constructor
+ * @extends {goog.events.BrowserEvent}
+ * @final
+ */
+goog.events.KeyEvent = function(keyCode, charCode, repeat, browserEvent) {
+  goog.events.BrowserEvent.call(this, browserEvent);
+  this.type = goog.events.KeyHandler.EventType.KEY;
+
+  /**
+   * Keycode of key press.
+   * @type {number}
+   */
+  this.keyCode = keyCode;
+
+  /**
+   * Unicode character code.
+   * @type {number}
+   */
+  this.charCode = charCode;
+
+  /**
+   * True if this event was generated by keyboard auto-repeat (i.e., the user is
+   * holding the key down.)
+   * @type {boolean}
+   */
+  this.repeat = repeat;
+};
+goog.inherits(goog.events.KeyEvent, goog.events.BrowserEvent);

http://git-wip-us.apache.org/repos/asf/flex-falcon/blob/e2cad6e6/externs/GCL/externs/goog/events/keynames.js
----------------------------------------------------------------------
diff --git a/externs/GCL/externs/goog/events/keynames.js b/externs/GCL/externs/goog/events/keynames.js
new file mode 100644
index 0000000..b8e36af
--- /dev/null
+++ b/externs/GCL/externs/goog/events/keynames.js
@@ -0,0 +1,139 @@
+// 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 Constant declarations for common key codes.
+ *
+ * @author eae@google.com (Emil A Eklund)
+ */
+
+goog.provide('goog.events.KeyNames');
+
+
+/**
+ * Key names for common characters. These should be used with keyup/keydown
+ * events, since the .keyCode property on those is meant to indicate the
+ * *physical key* the user held down on the keyboard. Hence the mapping uses
+ * only the unshifted version of each key (e.g. no '#', since that's shift+3).
+ * Keypress events on the other hand generate (mostly) ASCII codes since they
+ * correspond to *characters* the user typed.
+ *
+ * For further reference: http://unixpapa.com/js/key.html
+ *
+ * This list is not localized and therefore some of the key codes are not
+ * correct for non-US keyboard layouts.
+ *
+ * @see goog.events.KeyCodes
+ * @enum {string}
+ */
+goog.events.KeyNames = {
+  8: 'backspace',
+  9: 'tab',
+  13: 'enter',
+  16: 'shift',
+  17: 'ctrl',
+  18: 'alt',
+  19: 'pause',
+  20: 'caps-lock',
+  27: 'esc',
+  32: 'space',
+  33: 'pg-up',
+  34: 'pg-down',
+  35: 'end',
+  36: 'home',
+  37: 'left',
+  38: 'up',
+  39: 'right',
+  40: 'down',
+  45: 'insert',
+  46: 'delete',
+  48: '0',
+  49: '1',
+  50: '2',
+  51: '3',
+  52: '4',
+  53: '5',
+  54: '6',
+  55: '7',
+  56: '8',
+  57: '9',
+  59: 'semicolon',
+  61: 'equals',
+  65: 'a',
+  66: 'b',
+  67: 'c',
+  68: 'd',
+  69: 'e',
+  70: 'f',
+  71: 'g',
+  72: 'h',
+  73: 'i',
+  74: 'j',
+  75: 'k',
+  76: 'l',
+  77: 'm',
+  78: 'n',
+  79: 'o',
+  80: 'p',
+  81: 'q',
+  82: 'r',
+  83: 's',
+  84: 't',
+  85: 'u',
+  86: 'v',
+  87: 'w',
+  88: 'x',
+  89: 'y',
+  90: 'z',
+  93: 'context',
+  96: 'num-0',
+  97: 'num-1',
+  98: 'num-2',
+  99: 'num-3',
+  100: 'num-4',
+  101: 'num-5',
+  102: 'num-6',
+  103: 'num-7',
+  104: 'num-8',
+  105: 'num-9',
+  106: 'num-multiply',
+  107: 'num-plus',
+  109: 'num-minus',
+  110: 'num-period',
+  111: 'num-division',
+  112: 'f1',
+  113: 'f2',
+  114: 'f3',
+  115: 'f4',
+  116: 'f5',
+  117: 'f6',
+  118: 'f7',
+  119: 'f8',
+  120: 'f9',
+  121: 'f10',
+  122: 'f11',
+  123: 'f12',
+  186: 'semicolon',
+  187: 'equals',
+  189: 'dash',
+  188: ',',
+  190: '.',
+  191: '/',
+  192: '`',
+  219: 'open-square-bracket',
+  220: '\\',
+  221: 'close-square-bracket',
+  222: 'single-quote',
+  224: 'win'
+};