1 /*
  2  * ***** BEGIN LICENSE BLOCK *****
  3  * Zimbra Collaboration Suite Web Client
  4  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc.
  5  *
  6  * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at: https://www.zimbra.com/license
  9  * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15
 10  * have been added to cover use of software over a computer network and provide for limited attribution
 11  * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B.
 12  *
 13  * Software distributed under the License is distributed on an "AS IS" basis,
 14  * WITHOUT WARRANTY OF ANY KIND, either express or implied.
 15  * See the License for the specific language governing rights and limitations under the License.
 16  * The Original Code is Zimbra Open Source Web Client.
 17  * The Initial Developer of the Original Code is Zimbra, Inc.  All rights to the Original Code were
 18  * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015.
 19  *
 20  * All portions of the code are Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved.
 21  * ***** END LICENSE BLOCK *****
 22  */
 23 
 24 /**
 25  * 
 26  * @private
 27  */
 28 DwtKeyEvent = function() {
 29 	DwtUiEvent.call(this, true);
 30 	this.reset(true);
 31 };
 32 
 33 DwtKeyEvent.prototype.toString = function() { return "DwtKeyEvent"; }
 34 DwtKeyEvent.prototype.isDwtKeyEvent = true;
 35 
 36 // Constants for key codes
 37 DwtKeyEvent.KEY_END_OF_TEXT     = 3;      // Enter key on Mac
 38 DwtKeyEvent.KEY_BACKSPACE       = 8;
 39 DwtKeyEvent.KEY_TAB             = 9;
 40 DwtKeyEvent.KEY_RETURN          = 13;
 41 DwtKeyEvent.KEY_ENTER           = DwtKeyEvent.KEY_RETURN;
 42 DwtKeyEvent.KEY_ESCAPE          = 27;
 43 DwtKeyEvent.KEY_SPACE           = 32;
 44 DwtKeyEvent.KEY_ARROW_LEFT      = 37;
 45 DwtKeyEvent.KEY_ARROW_UP        = 38;
 46 DwtKeyEvent.KEY_ARROW_RIGHT     = 39;
 47 DwtKeyEvent.KEY_ARROW_DOWN      = 40;
 48 DwtKeyEvent.KEY_DELETE          = 46;
 49 DwtKeyEvent.KEY_SEMICOLON       = 59;
 50 DwtKeyEvent.KEY_SEMICOLON_1     = 186;
 51 DwtKeyEvent.KEY_COMMA           = 188;
 52 DwtKeyEvent.KEY_COMMAND         = 224;  // Mac FF
 53 
 54 // Easy way to check for 3 or 13
 55 DwtKeyEvent.IS_RETURN = {};
 56 DwtKeyEvent.IS_RETURN[ DwtKeyEvent.KEY_END_OF_TEXT ]    = true;
 57 DwtKeyEvent.IS_RETURN[ DwtKeyEvent.KEY_RETURN ]         = true;
 58 
 59 // FF on Mac reports keyCode of 0 for many shifted keys
 60 DwtKeyEvent.MAC_FF_CODE = {};
 61 DwtKeyEvent.MAC_FF_CODE["~"] = 192;
 62 DwtKeyEvent.MAC_FF_CODE["!"] = 49;
 63 DwtKeyEvent.MAC_FF_CODE["@"] = 50;
 64 DwtKeyEvent.MAC_FF_CODE["#"] = 51;
 65 DwtKeyEvent.MAC_FF_CODE["$"] = 52;
 66 DwtKeyEvent.MAC_FF_CODE["%"] = 53;
 67 DwtKeyEvent.MAC_FF_CODE["^"] = 54;
 68 DwtKeyEvent.MAC_FF_CODE["&"] = 55;
 69 DwtKeyEvent.MAC_FF_CODE["*"] = 56;
 70 DwtKeyEvent.MAC_FF_CODE["("] = 57;
 71 DwtKeyEvent.MAC_FF_CODE[")"] = 48;
 72 DwtKeyEvent.MAC_FF_CODE["-"] = 189;
 73 DwtKeyEvent.MAC_FF_CODE["_"] = 189;
 74 DwtKeyEvent.MAC_FF_CODE["+"] = 187;
 75 DwtKeyEvent.MAC_FF_CODE["|"] = 220;
 76 DwtKeyEvent.MAC_FF_CODE[":"] = 186;
 77 DwtKeyEvent.MAC_FF_CODE["<"] = 188;
 78 DwtKeyEvent.MAC_FF_CODE[">"] = 190;
 79 DwtKeyEvent.MAC_FF_CODE["?"] = 191;
 80 
 81 DwtKeyEvent.prototype = new DwtUiEvent;
 82 DwtKeyEvent.prototype.constructor = DwtKeyEvent;
 83 
 84 
 85 DwtKeyEvent.isKeyEvent =
 86 function(ev) {
 87 	return ev.type && ev.type.search(/^key/i) != -1;
 88 }
 89 
 90 DwtKeyEvent.isKeyPressEvent =
 91 function(ev) {
 92 	return (AjxEnv.isIE && ev.type == "keydown") || (ev.type == "keypress");
 93 }
 94 
 95 DwtKeyEvent.prototype.reset =
 96 function(dontCallParent) {
 97 	if (!dontCallParent)
 98 		DwtUiEvent.prototype.reset.call(this);
 99 	this.keyCode = 0;
100 	this.charCode = 0;
101 }
102 
103 DwtKeyEvent.prototype.isCommand =
104 function(ev) {
105 	return AjxEnv.isMac && this.metaKey || this.ctrlKey;
106 }
107 
108 DwtKeyEvent.prototype.setFromDhtmlEvent =
109 function(ev, obj) {
110 	ev = DwtUiEvent.prototype.setFromDhtmlEvent.apply(this, arguments);
111 	if (!ev) { return; }
112 	this.charCode = ev.charCode || ev.keyCode;
113 	this.keyCode = ev.keyCode;
114 }
115 
116 /**
117  * Simple function to return key code from a key event. The code is in keyCode for keydown/keyup.
118  * Gecko puts it in charCode for keypress.
119  */
120 DwtKeyEvent.getCharCode =
121 function(ev) {
122 	ev = DwtUiEvent.getEvent(ev);
123 	var key = AjxEnv.isSafari ? ev.keyCode : (ev.charCode || ev.keyCode);
124 	if (key == 0 && AjxEnv.isMac && AjxEnv.isGeckoBased && ev.type == "keyup" && DwtKeyEvent._geckoCode) {
125 		// if Mac Gecko, return keyCode saved from keypress event
126 		key = DwtKeyEvent._geckoCode;
127 		DwtKeyEvent._geckoCode = null;
128 	}
129 	return key;
130 }
131 
132 DwtKeyEvent.copy =
133 function(dest, src) {
134 	DwtUiEvent.copy(dest, src);
135 	dest.charCode = src.charCode;
136 	dest.keyCode = src.keyCode;
137 }
138 
139 /**
140  * Workaround for the bug where Mac Gecko returns a keycode of 0 for many shifted chars for
141  * keydown and keyup. Since it returns a char code for keypress, we save it so that the
142  * ensuing keyup can pick it up.
143  *
144  * FF2 returns keycode 0 for: ~ ! @ # $ % ^ & * ( ) - _ + | : < > ? Alt-anything
145  * FF3 returns keycode 0 for: ~ _ | : < > ?
146  *
147  * FF2 returns incorrect keycode for Ctrl plus any of: 1 2 3 4 5 6 7 8 9 0 ; ' , . /
148  *
149  * https://bugzilla.mozilla.org/show_bug.cgi?id=448434
150  *
151  * @param ev
152  */
153 DwtKeyEvent.geckoCheck =
154 function(ev) {
155 
156 	ev = DwtUiEvent.getEvent(ev);
157 	if (ev.type == "keypress") {
158 		DwtKeyEvent._geckoCode = null;
159 		if (AjxEnv.isMac && AjxEnv.isGeckoBased) {
160 			var ch = String.fromCharCode(ev.charCode);
161 			DwtKeyEvent._geckoCode = DwtKeyEvent.MAC_FF_CODE[ch];
162 		}
163 	}
164 };
165