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 [email protected] (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 [email protected] (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 [email protected] (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 [email protected] (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 [email protected] (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 [email protected] (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 [email protected] (Erik Arvidsson) + * @author [email protected] (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 [email protected] (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' +};
