Commit 6af3ad72 authored by jamiewalch's avatar jamiewalch Committed by Commit bot

Clean-up key tester.

This fixes a bunch of small nits:
* JSCompile is now enabled for this app.
* No need to manually focus the PNaCl plugin.
* Distinguishes between left and right modifiers for PNaCl events.
* Debug log is hidden by default, and selectable when shown.
* Minor CSS tweaks and code clean-up.

Review URL: https://codereview.chromium.org/900983003

Cr-Commit-Position: refs/heads/master@{#314674}
parent 2828c829
......@@ -11,6 +11,7 @@
'remoting_key_tester_js_files': [
'tools/javascript_key_tester/background.js',
'tools/javascript_key_tester/chord_tracker.js',
'tools/javascript_key_tester/event_listeners.js',
'tools/javascript_key_tester/keyboard_map.js',
'tools/javascript_key_tester/main.js',
],
......@@ -45,9 +46,7 @@
'target_name': 'remoting_key_tester_jscompile',
'type': 'none',
'conditions': [
# TODO(lukasza): Enable when remoting_key_tester_jscompile is clean.
# ['run_jscompile != 0', {
['0 != 0', {
['run_jscompile != 0', {
'variables': {
'success_stamp': '<(PRODUCT_DIR)/<(_target_name).stamp',
},
......@@ -56,6 +55,7 @@
'action_name': 'jscompile remoting_key_tester',
'inputs': [
'<@(remoting_key_tester_js_files)',
'webapp/js_proto/chrome_proto.js'
],
'outputs': [
'<(success_stamp)',
......@@ -66,6 +66,7 @@
'--no-single-file',
'--success-stamp', '<(success_stamp)',
'<@(remoting_key_tester_js_files)',
'webapp/js_proto/chrome_proto.js'
],
},
], # actions
......
......@@ -8,34 +8,39 @@
* @param {HTMLElement} parentDiv
*/
var ChordTracker = function(parentDiv) {
/** @type {HTMLElement} */
this.parentDiv_ = parentDiv;
/** @type {HTMLElement} */
this.currentDiv_ = null;
/** @type {Object.<HTMLElement>} */
this.pressedKeys_ = {};
};
/**
* @param {number} keyCode
* @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code"
* string.
* @param {string} title
* @return {void}
*/
ChordTracker.prototype.addKeyUpEvent = function(keyCode, title) {
var text = this.keyName_(keyCode);
ChordTracker.prototype.addKeyUpEvent = function(keyId, title) {
var text = this.keyName_(keyId);
var span = this.addSpanElement_('key-up', text, title);
delete this.pressedKeys_[keyCode];
delete this.pressedKeys_[keyId];
if (!this.keysPressed_()) {
this.end_();
}
};
/**
* @param {number} keyCode
* @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code"
* string.
* @param {string} title
* @return {void}
*/
ChordTracker.prototype.addKeyDownEvent = function(keyCode, title) {
var text = this.keyName_(keyCode);
ChordTracker.prototype.addKeyDownEvent = function(keyId, title) {
var text = this.keyName_(keyId);
var span = this.addSpanElement_('key-down', text, title);
this.pressedKeys_[keyCode] = span;
this.pressedKeys_[keyId] = span;
};
/**
......@@ -63,11 +68,13 @@ ChordTracker.prototype.releaseAllKeys = function() {
* @param {string} className
* @param {string} text
* @param {string} title
* @return {HTMLElement}
*/
ChordTracker.prototype.addSpanElement_ = function(className, text, title) {
this.begin_();
var span = document.createElement('span');
var span = /** @type {HTMLElement} */ (document.createElement('span'));
span.classList.add(className);
span.classList.add('key-div');
span.innerText = text;
span.title = title;
this.currentDiv_.appendChild(span);
......@@ -81,7 +88,7 @@ ChordTracker.prototype.begin_ = function() {
if (this.currentDiv_) {
return;
}
this.currentDiv_ = document.createElement('div');
this.currentDiv_ = /** @type {HTMLElement} */ (document.createElement('div'));
this.currentDiv_.classList.add('chord-div');
this.parentDiv_.appendChild(this.currentDiv_);
};
......@@ -113,15 +120,18 @@ ChordTracker.prototype.keysPressed_ = function() {
};
/**
* @param {number} keyCode The keyCode field of the keyup or keydown event.
* @param {number|string} keyId Either a Javascript key-code, or a PNaCl "code"
* string.
* @return {string} A human-readable representation of the key.
* @private
*/
ChordTracker.prototype.keyName_ = function(keyCode) {
var result = keyboardMap[keyCode];
ChordTracker.prototype.keyName_ = function(keyId) {
if (typeof keyId == 'string') {
return keyId;
}
var result = keyboardMap[keyId];
if (!result) {
result = '<' + keyCode + '>';
result = '<' + keyId + '>';
}
return result;
};
/* Copyright 2015 The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/** @constructor */
var PNaClEvent = function() {
/** @type {string} */
this.type = "";
/** @type {number} */
this.modifiers = 0;
/** @type {number} */
this.keyCode = 0;
/** @type {string} */
this.characterText = '';
/** @type {string} */
this.code = '';
};
/**
* @param {HTMLElement} jsLog
* @param {HTMLElement} pnaclLog
* @param {HTMLElement} textLog
* @param {HTMLElement} pnaclPlugin
* @param {HTMLElement} pnaclListener
* @constructor
*/
var EventListeners = function(jsLog, pnaclLog, textLog,
pnaclPlugin, pnaclListener) {
this.pnaclPlugin_ = pnaclPlugin;
this.pnaclListener_ = pnaclListener;
this.textLog_ = textLog;
this.onKeyDownHandler_ = this.onKeyDown_.bind(this);
this.onKeyUpHandler_ = this.onKeyUp_.bind(this);
this.onMessageHandler_ = this.onMessage_.bind(this);
this.onBlurHandler_ = this.onBlur_.bind(this);
this.jsChordTracker_ = new ChordTracker(jsLog);
this.pnaclChordTracker_ = new ChordTracker(pnaclLog);
this.startTime_ = new Date();
};
/**
* Start listening for keyboard events.
*/
EventListeners.prototype.activate = function() {
document.body.addEventListener('keydown', this.onKeyDownHandler_, false);
document.body.addEventListener('keyup', this.onKeyUpHandler_, false);
this.pnaclListener_.addEventListener('message', this.onMessageHandler_, true);
this.pnaclPlugin_.addEventListener('blur', this.onBlurHandler_, false);
this.onBlur_();
};
/**
* Stop listening for keyboard events.
*/
EventListeners.prototype.deactivate = function() {
document.body.removeEventListener('keydown', this.onKeyDownHandler_, false);
document.body.removeEventListener('keyup', this.onKeyUpHandler_, false);
this.pnaclListener_.removeEventListener(
'message', this.onMessageHandler_, true);
this.pnaclPlugin_.removeEventListener('blur', this.onBlurHandler_, false);
};
/**
* @param {Event} event
* @private
*/
EventListeners.prototype.onKeyDown_ = function(event) {
this.appendToTextLog_(this.jsonifyJavascriptKeyEvent_(event, 'keydown'));
this.jsChordTracker_.addKeyDownEvent(
event.keyCode, this.jsonifyJavascriptKeyEvent_(event, 'keydown', 2));
};
/**
* @param {Event} event
* @return {void}
*/
EventListeners.prototype.onKeyUp_ = function(event) {
this.appendToTextLog_(this.jsonifyJavascriptKeyEvent_(event, 'keyup'));
this.jsChordTracker_.addKeyUpEvent(
event.keyCode, this.jsonifyJavascriptKeyEvent_(event, 'keyup', 2));
}
/**
* @param {Event} event
* @return {void}
*/
EventListeners.prototype.onMessage_ = function (event) {
var pnaclEvent = /** @type {PNaClEvent} */ (event['data']);
this.appendToTextLog_(this.jsonifyPnaclKeyboardInputEvent_(pnaclEvent));
var title = this.jsonifyPnaclKeyboardInputEvent_(pnaclEvent, 2);
if (pnaclEvent.type == "KEYDOWN") {
this.pnaclChordTracker_.addKeyDownEvent(pnaclEvent.code, title);
}
if (pnaclEvent.type == "KEYUP") {
this.pnaclChordTracker_.addKeyUpEvent(pnaclEvent.code, title);
}
if (pnaclEvent.type == "CHAR") {
this.pnaclChordTracker_.addCharEvent(pnaclEvent.characterText, title);
}
}
/**
* @return {void}
*/
EventListeners.prototype.onBlur_ = function() {
this.pnaclPlugin_.focus();
};
/**
* @param {string} str
* @private
*/
EventListeners.prototype.appendToTextLog_ = function(str) {
var div = document.createElement('div');
div.innerText = (new Date() - this.startTime_) + ':' + str;
this.textLog_.appendChild(div);
};
/**
* @param {Event} event
* @param {string} eventName
* @param {number=} opt_space
* @return {string}
* @private
*/
EventListeners.prototype.jsonifyJavascriptKeyEvent_ =
function(event, eventName, opt_space) {
return "JavaScript '" + eventName + "' event = " + JSON.stringify(
event,
['type', 'alt', 'shift', 'control', 'meta', 'charCode', 'keyCode',
'keyIdentifier', 'repeat'],
opt_space);
};
/**
* @param {PNaClEvent} event
* @param {number=} opt_space
* @return {string}
* @private
*/
EventListeners.prototype.jsonifyPnaclKeyboardInputEvent_ =
function(event, opt_space) {
return "PNaCl KeyboardInputEvent = " + JSON.stringify(
event,
['type', 'modifiers', 'keyCode', 'characterText', 'code'],
opt_space);
};
......@@ -12,44 +12,44 @@ html {
height: 100%;
}
#pnacl-plugin {
background-color: gray;
border: 1px solid
}
#pnacl-plugin:focus {
background-color: yellow;
}
.summary-log-container {
width: 50%;
height: 50vh;
height: 100%;
overflow-y: auto;
float: left;
}
.text-log-container {
width: 100%;
max-height: 25vh;
overflow-y: auto;
float: left;
#text-log-container {
position: fixed;
top: 32px;
left: 16px;
right: 16px;
bottom: 32px;
border: 1px solid gray;
box-shadow: 0px 4px 10px 4px rgba(0,0,0,0.3);
background-color: white;
overflow: scroll;
}
.char-event,
.key-down,
.key-up {
#text-log {
padding: 8px;
}
.selectable {
-webkit-user-select: text;
cursor: text;
}
.key-div {
border-radius: 4px;
border: 1px solid rgba(0, 0, 0, 0.3);
padding: 2px;
margin-right: 2px;
display: inline-block;
}
.char-event {
background-color: yellow;
}
.char-event::before {
content: "char:";
background-color: #DDF;
}
.key-up {
......@@ -57,7 +57,7 @@ html {
}
.key-up::before {
content: "-";
content: "\2011"; /** non-breaking hyphen */
}
.key-down {
......@@ -93,3 +93,9 @@ html {
content: " \2716"; /* cross */
color: red;
}
.controls {
position: absolute;
right: 8px;
top: 8px;
}
\ No newline at end of file
......@@ -9,20 +9,21 @@ found in the LICENSE file.
<head>
<title>Chrome AppsV2 Key Event Tester</title>
<script src="chord_tracker.js"></script>
<script src="event_listeners.js"></script>
<script src="keyboard_map.js"></script>
<script src="main.js"></script>
<link rel="stylesheet" href="main.css">
</head>
<body>
<h2>Chrome AppsV2 Key Event Tester</h2>
<div class="controls">
<button id="show-log">Debug log</button>
<button id="clear-log">Clear logs</button>
</div>
<div id="pnacl-listener">
PNaCl focus box:
<embed id="pnacl-plugin" width=100 height=12
<embed id="pnacl-plugin" width=0 height=0
src="remoting_key_tester.nmf" type="application/x-pnacl" />
(click inside to get focus, yellow background means it has focus).
</div>
<button id="clear-log">Clear logs</button>
<hr/>
<div class="logs">
<div class="summary-log-container">
Summary of JavaScript logs:
......@@ -34,9 +35,13 @@ found in the LICENSE file.
<div id="pnacl-log">
</div>
</div>
<div class="text-log-container">
Text log of JSON-ified events:
<div id="text-log">
<div id="text-log-container" hidden>
<div>
</div>
<div class="controls">
<button id="hide-log">Close</button>
</div>
<div id="text-log" class="selectable">
</div>
</div>
</div>
......
......@@ -3,140 +3,44 @@
* found in the LICENSE file.
*/
/**
* @param {string} eventName
* @param {number=} opt_space
* @return {string}
*/
function jsonifyJavascriptKeyEvent(event, eventName, opt_space) {
return "JavaScript '" + eventName + "' event = " + JSON.stringify(
event,
['type', 'alt', 'shift', 'control', 'meta', 'charCode', 'keyCode',
'keyIdentifier', 'repeat'],
opt_space);
};
/**
* @param {ChordTracker} jsChordTracker
* @param {Event} event
* @return {void}
*/
function handleJavascriptKeyDownEvent(jsChordTracker, event) {
appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keydown', undefined));
jsChordTracker.addKeyDownEvent(
event.keyCode, jsonifyJavascriptKeyEvent(event, 'keydown', 2));
}
/**
* @param {ChordTracker} jsChordTracker
* @param {Event} event
* @return {void}
*/
function handleJavascriptKeyUpEvent(jsChordTracker, event) {
appendToTextLog(jsonifyJavascriptKeyEvent(event, 'keyup', undefined));
jsChordTracker.addKeyUpEvent(
event.keyCode, jsonifyJavascriptKeyEvent(event, 'keyup', 2));
}
/** @constructor */
var PNaClEvent = function() {
/** @type {string} */
this.type = "";
/** @type {number} */
this.modifiers = 0;
/** @type {number} */
this.keyCode = 0;
/** @type {string|undefined} */
this.characterText = undefined;
/** @type {string} */
this.code = "";
};
/**
* @param {PNaClEvent} event
* @param {number|undefined} space
* @return {string}
*/
function jsonifyPnaclKeyboardInputEvent(event, space) {
return "PNaCl KeyboardInputEvent = " + JSON.stringify(
event,
['type', 'modifiers', 'keyCode', 'characterText', 'code'],
space);
};
/**
* @param {ChordTracker} pnaclChordTracker
* @param {Event} event
* @return {void}
*/
function handlePNaclMessage(pnaclChordTracker, event) {
var pnaclEvent = /** @type {PNaClEvent} */ (event.data);
appendToTextLog(jsonifyPnaclKeyboardInputEvent(pnaclEvent, undefined));
var title = jsonifyPnaclKeyboardInputEvent(pnaclEvent, 2);
if (pnaclEvent.type == "KEYDOWN") {
pnaclChordTracker.addKeyDownEvent(pnaclEvent.keyCode, title);
}
if (pnaclEvent.type == "KEYUP") {
pnaclChordTracker.addKeyUpEvent(pnaclEvent.keyCode, title);
}
if (pnaclEvent.type == "CHAR") {
pnaclChordTracker.addCharEvent(pnaclEvent.characterText, title);
}
}
/**
* @param {string} str
* @return {void}
*/
function appendToTextLog(str) {
var textLog = document.getElementById('text-log');
var div = document.createElement('div');
div.innerText = str;
textLog.appendChild(div);
}
function onLoad() {
// Start listening to Javascript keyup/keydown events.
var jsLog = document.getElementById('javascript-log');
var jsChordTracker = new ChordTracker(jsLog);
document.body.addEventListener(
'keydown',
function (event) {
handleJavascriptKeyDownEvent(jsChordTracker, event);
},
false);
document.body.addEventListener(
'keyup',
function (event) {
handleJavascriptKeyUpEvent(jsChordTracker, event);
},
false);
// Start listening to PNaCl keyboard input events.
var pnaclLog = document.getElementById('pnacl-log');
var pnaclChordTracker = new ChordTracker(pnaclLog);
document.getElementById('pnacl-listener').addEventListener(
'message',
function (message) {
handlePNaclMessage(pnaclChordTracker, message);
},
true);
var pnaclPlugin = document.getElementById('pnacl-plugin');
var pnaclListener = document.getElementById('pnacl-listener');
var textLog = document.getElementById('text-log');
var textLogContainer = document.getElementById('text-log-container');
var eventListeners = new EventListeners(jsLog, pnaclLog, textLog,
pnaclPlugin, pnaclListener);
eventListeners.activate();
// Start listening to generic, source-agnostic events.
window.addEventListener(
'blur',
function () {
jsChordTracker.releaseAllKeys();
pnaclChordTracker.releaseAllKeys();
},
false);
document.getElementById('clear-log').addEventListener(
'click',
function() {
jsLog.innerText = '';
pnaclLog.innerText = '';
document.getElementById('text-log').innerText = '';
textLog.innerText = '';
},
false);
document.getElementById('show-log').addEventListener(
'click',
function() {
eventListeners.deactivate();
textLogContainer.hidden = false;
var selection = window.getSelection();
var range = document.createRange();
range.selectNodeContents(textLog);
selection.removeAllRanges();
selection.addRange(range);
},
false);
document.getElementById('hide-log').addEventListener(
'click',
function() {
eventListeners.activate();
textLogContainer.hidden = true;
},
false);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment