Yann Pringault 8a8f34ae10 Improve dark mode for debugger
Summary:
* Added a label so we can click on the text to toggle the dark mode
* Added `height: 100%` in the CSS to make the dark background fill the entire view
* Improving JS code with `classList.toggle()` instead of redundant `if else` and fragile `document.styleSheets` access
* Adjusted the link color in dark mode to be less flashy

![image](https://cloud.githubusercontent.com/assets/5436545/24155304/bb80bb9a-0e53-11e7-9298-ce2c1ec6672c.png)

![image](https://cloud.githubusercontent.com/assets/5436545/24155311/c27e85f8-0e53-11e7-87ae-0245f54870c5.png)
Closes https://github.com/facebook/react-native/pull/13052

Differential Revision: D4748893

fbshipit-source-id: a81266c52b24f8e5dcedf0b9f37134688342d8d2
2017-03-23 04:38:57 -07:00

196 lines
9.5 KiB
HTML

<!doctype html>
<!--
Copyright (c) 2015-present, Facebook, Inc.
All rights reserved.
This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
-->
<html>
<head>
<meta charset=utf-8>
<!-- Base 64 encoded favicon, to avoid extra request to server -->
<link rel="icon" href="data:;base64,iVBORw0KGgo=">
<title>React Native Debugger</title>
<script>
/* eslint-env browser */
(function() {
function setStatus(status) {
document.getElementById('status').innerHTML = status;
}
const RUNNING_ICON = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAABAJJREFUWMPNV0tIlFEU/nsaPSCrhVFZBBFRFkXvKCpCw6BFtagkWoS1CApp0YMKclHRYxNpj0UUQWUavYmeEi2MsFVS/s7oqOPo6DjqzKjpzOjpnDl35s7MP/8/vyUxFy7c/5x7z/nued5fUcwOgLGKBXIUFYqUaijHqeL0iamGaMSjPbR32IYNMpQaKEbhHlQCpibtpTN09q+HBdJQSCEK7DatWDu7QzJI1pBvrULFPyiOt0iFeWtUw2I8YB825RKEXamFLDM31yifqAIcbwO40QmQ3wIwXtUqmFwDcNQJcKeL96apOiB0LUF+0jH7u26AwUEA3wCERmsAYF+z5B9CUF1B5rmDvPeBx8AdCWOCA05zYEEdCz6JtxqB3xsbACp/M+0WWuR+F6+/9ACsqOczV90AQQSRYdEBQbo0pteJ9p1NrCAsnOYYnNc7IDIuocJRUWdyGpm+qcEgO2JcQTmrEzxkahpZdbH0aABX3LG89Q1M3243CErSGalwBkVmi7gN3SpM2+uQLrgrXLCjSfJ3Cautqk9SrEIVk0qnQfrMtrKwtxiIj70A33vZvwGcA2IGxKxE3j0E9MLHZ6ZZkqQm6Ra1XcOcjofPtwO4AtLULbhuD7DSpwjmspvNTwop8tuQ5wnK/U1+gNMYvFNqdK1QpIjGEsPY7eC0IqFvUPgrHys90MKCz7p43xy0TqaV1xSINPaLmHmNZz73yLTdljgeyhXRySLEXDsr/tYrA29tPQtqxhtZ+zkLnnjlTcns41S+sd3PtCU2Prsaz1b1AfgHOTjjAKiKaKcR4kf0dS0qmRBXyYhGg4rOLCtoBvm7oJXXP/u0VZLc98yrAeDTAHiPAGx+LQCLAJCPJp6ZAMBUVFLg5PWvOADpyHMG2GpxALwaF1C6kb+/ogvm1zJtjXABCSEgo5H20COV3+5kF5D5G4ULVooUpAL2AwH1o8x1Oi7QBOEeB0czpVYpoi71cFwcFEF4RgThDCtnC60vtDMvz8F7X/rYmrQ2DkKdNCQ/X+uQDYgE1fSzMLJQiYeVXsRZ5mUaWSg6bem70GVQD0JpmKQQzauVzYZSsrqPlVExCo+g+K7CJvUIgT0XGTLXaqYQJSnF2aIUZ0eV4jxRim+ihYpETyC3hflb7Uzb3GimFCdpRuHCsiiuGRVHNSPqCdG8ZTYtKP1mlKQdhxvLcpuk0bvgnEsCoDgYGXVmg+iGuXaz7djgQbJQPEhOtPE3AfkkSizldYlIx3KkLbXJjKCgzbSafZAkeZJ96ObAc4tG48XMOOKU/MNOmS3UkEh5mXeoTzKDR+kklbsaPTjp4ZmeoLtRxzvWyn3hVBsXpqE9SlPiWZ4SPyYp8WuWEj+n/+n3/A8emj1HwPlGOgAAAABJRU5ErkJggg==';
const SLOW_ICON = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAABGZJREFUWMPNV+tvFFUU30/4L/i9K0gQImoiQTQmGtEQQAWCoSGgJiZqojZCYsoHQkNIwAcJppWgHwjqLi1SHrVP2m4tfdAULKUW2NLSx0ILbGsf293ZeR7OOXc72+nM7GwbQjrJze7eufeex+/3O+euz5flAyUrliSL/esTAX9hIugPJYI5YfyMicHfQ/SO1tBa35N68LBnpaC/KB7wT8YDOZDd8E/SHtq7cMMV/mfiwZwCjGo6e8PWwXvxDDpr3lFjSlsXatjmCJ6VdTbkwLJV6HnkSRmflY2IXPL8Su/InYyXrAS54zAoPX9Csi0f4sUr7EbOvAjy1QJQ+87w2vjp5Y5OuGaCcHJLuzZ8GQzDAEOZBnoMaRSSLd+a7+W2fWDIU+JdcpzXqv0X3eFw4gSRxXHD3+/wwfL17/m3VLsD9LEunlPuBEG9W8rftUftIFW9z2uUW7+BoWsQL33VGRK05ZR6R7YnG79gAzOHiwOWgRI+BTOPcvMEzj1nvpfqd4s9tbmu6rBAIXTuTB5KNT2J8vcs81YHfrW8ky5t5/nkP5+5kpJsmhUuU5GR6naKaDAq06nmb3hOJQj6zgpjjZ+n31/+Uuyp/jBjseKKSaUzo3wuvC6MDTeCOlgO2mgXkkxDjFX81MXQNR7a6A3kxFlQI7W8J/7XKxmlSbZ9VL8dF5SuAeW/ImT1mJlqI/EIf//PRtVIDWNP6Vfv1TLzdWkMlTJlrtfjIyB3/oiOvOTGhUIfNRGbZ01fsazoUO1+AxqoZ6PJK98JRXQeTWXnDUicXyc4gc4wFC17Rcbuh0B72GbKVmr41EmSIR91MgvmoU+E4dFOk3hSzbZURA9BnxpgFahDVWaklHYqPBQxDSZtxQaxt3oL6ONhhEhhclodyAlTBmKWojPSAnpsEKvdC5bFNMcRYtGhqOc+hLd87aCoCRN3bFWS4CPY5mQg5uBAExqL2BzQMHLhQD4kzr3m4MDLpgP6ZO8cB1ajA1HO2hwOTNkhQLkR3lq0AxJlb6fSuDVFwihC0I8QLAV1oCwNAcpRQDDMQxSuD8ReLGAMgSYzlE4Q2EnY/DWzmaSmDlbwIF5Q9IKEP4kDzq1ltTAJu38RhpvzRC+4V8fZ5B6SkYQuMiScldsn0w2IZIbRG1KUM6QMlLNRpfs4KEOVPKdjhqyyjYLS9bNrPWAZehaii2+ZzYYkqU/0mgXINESFCYc+3sPQqJFLQgkX3vQuRJ6luH5XqhTvmgVRnugBPQEcvwtyImxpKX8s9tTlepdiz2bUuifVjN61NqOeP6wknJ21yk02p1ybkWc7nmksVZutDtw4lu6GyAOMaFY3/EjswaKWVTvOeCHByJn5HUdSstoM2oMWETnqWkUyMkcetGLkG01FEGlnyrTnhcTzSjbSLIiH1y0mnRLD+9+B9JWsfb/lusYyRGXM60qW+VK6irsaXzjx4kmVzbYGO5787yHuC/L1H+Z/KV0U1/JF8cdkUfw1WxR/Tp/W3/PHSyH/l51SdaoAAAAASUVORK5CYII=';
const STOPPED_ICON = 'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAA9VJREFUWMPNV+dKJEEQnl93r3Avcfcavpe/zHlXzDmLYlZU1oSrYEDFsGZdVDBvUBTUuv6K6aZ34ioiW1BMT1dPdXWFr3oMI03q7u7+lZOTk5WbmxsQz5DgiOCEyRiHTFkW1hrfRXl5eX+E0qDgmGBKk7E2iG+/vHFZWdlvcaJswclPbJzC+BY6oOvTpxYfhr+6sYMh4bS9kZ+f/098EP2uzTUjoPNvOie3bV5YWEihUIjW1tZobGyMCgoKbBsUFxfT5OQkbWxs8FpxEEcjXD1hxtzR7cfHx/Tx8UGvr68ESiaTNDQ0pOTj4+P08vLCsufnZ167vb3tGg7HnECyOH1QU1PDimdmZvi9ra2Nrq6ueG59fZ22trZ4HI1GqbGxkdcsLy/T+/s7lZeXuxmR7eR6x2zv6+vjDaRysFhPq6urJGlpaQlKlbyrq4vn29vbXasjJRRmnTsuhqtBdXV1KfO6ATixLmttbeX53t5er8QM6gjnCjIdHR2sDKeSc4ODgyoEm5ubPIanpLy/v5/nmpqaPMGKERPQ6VU+wWCQlSERd3d3Of6ILxjJBpbvl5eXnBP7+/v8TWlpqV95ZhkmftuESKDFxUV6enpSrk4kEirLI5EIxx7ux4aYw1pZDaB4PE6zs7NUUlLilgsBw2wsKYKBgQFWBKVHR0d0cHDA45GREVY8NzenvAPGGMaAhoeH+Xl4eEjn5+eqbHt6epyMCBlmJ1OTIi68GdwpE6+lpUWd6P7+nqtgb29PnRRuB/BADtaTtrm5ma6vr+nt7Y2T02JAxDDbqZo8PT2lh4cHRj99HnMgIGEgECArId5TU1M8vrm5saEkwodQWQxI2Aw4OTmhx8dHmwE4OWh0dNTRAMRZGnB7e2szAGGA1yw5ELeFAOWGEFxcXFB1dbVyo4wlDAHoAGoloRwRglgsxqyXIABMhgChdAqBaxKitFB6YBgF9+tJWFFRoeA2HA6zDBiBtUhceBNjzyR0K0O4eWVlRTUgKLq7u2NlGO/s7PCmYGkgZHrZ4n1hYcEVD2QZegJRVVUVK0NJoSSRYBJ8JEkggqthmASiyspKfyDyg+LOzk5WhqcVinE/kD0BYUu3GaVAsV8zksBSW1ubMo/N9STUZQ0NDTajXJuRXzuWjUVvx+D5+XllAPLAqRsC1NJqx14XEpxcv5DAEIAVCHWNmIPOzs6ovr5eVQTyRMK074XE70omywmNCIQSxf1PyicmJlS1oAqw1go6vlcyr0tpUVERdzVcOLExkM26Bkg4PT3NfQHe+vSlNCOu5RnxY5IRv2YZ8XP6U7/n/wFyU6HBPUWxjAAAAABJRU5ErkJggg==';
function setFavicon(base64) {
document.querySelector('link[rel=icon]').href = 'data:image/png;base64,' + base64;
}
var isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
var refresh_shortcut = isMacLike ? '⌘R' : 'Ctrl R';
window.onload = function() {
if (!isMacLike) {
document.getElementById('dev_tools_shortcut').innerHTML = 'Ctrl⇧J';
}
};
var INITIAL_MESSAGE = 'Waiting, press <span class="shortcut">' + refresh_shortcut + '</span> in simulator to reload and connect.';
function connectToDebuggerProxy() {
var worker;
var ws = new WebSocket('ws://' + window.location.host + '/debugger-proxy?role=debugger&name=Chrome');
function createJSRuntime() {
// This worker will run the application javascript code,
// making sure that it's run in an environment without a global
// document, to make it consistent with the JSC executor environment.
worker = new Worker('debuggerWorker.js');
worker.onmessage = function(message) {
ws.send(JSON.stringify(message.data));
};
window.onbeforeunload = function() {
return 'If you reload this page, it is going to break the debugging session. ' +
'You should press' + refresh_shortcut + 'in simulator to reload.';
};
updateVisibility();
updateFavicon();
}
function shutdownJSRuntime() {
if (worker) {
worker.terminate();
worker = null;
window.onbeforeunload = null;
updateFavicon();
}
}
function updateVisibility() {
if (worker) {
worker.postMessage({
method: 'setDebuggerVisibility',
visibilityState: document.visibilityState,
});
}
updateFavicon();
}
function updateFavicon() {
if (worker) {
if (document.visibilityState === 'visible') {
setFavicon(RUNNING_ICON);
} else {
setFavicon(SLOW_ICON);
}
} else {
setFavicon(STOPPED_ICON);
}
}
ws.onopen = function() {
setStatus(INITIAL_MESSAGE);
};
ws.onmessage = function(message) {
if (!message.data) {
return;
}
var object = JSON.parse(message.data);
if (object.$event === 'client-disconnected') {
shutdownJSRuntime();
setStatus('Waiting, press <span class="shortcut">' + refresh_shortcut + '</span> in simulator to reload and connect.');
return;
}
if (!object.method) {
return;
}
// Special message that asks for a new JS runtime
if (object.method === 'prepareJSRuntime') {
shutdownJSRuntime();
console.clear();
createJSRuntime();
ws.send(JSON.stringify({replyID: object.id}));
setStatus('Debugger session #' + object.id + ' active.');
} else if (object.method === '$disconnected') {
shutdownJSRuntime();
setStatus(INITIAL_MESSAGE);
} else {
// Otherwise, pass through to the worker.
worker.postMessage(object);
}
};
ws.onclose = function(e) {
shutdownJSRuntime();
setStatus('Disconnected from proxy. Attempting reconnection. Is node server running?');
if (e.reason) {
setStatus(e.reason);
console.warn(e.reason);
}
setTimeout(connectToDebuggerProxy, 500);
};
// Let debuggerWorker.js know when we're not visible so that we can warn about
// poor performance when using remote debugging.
document.addEventListener('visibilitychange', updateVisibility, false);
}
connectToDebuggerProxy();
})();
</script>
<style type="text/css">
html,
body {
font-family: Helvetica, Verdana, sans-serif;
font-size: large;
font-weight: 200;
height: 100%;
margin: 0;
padding: 0;
}
.shortcut {
border-radius: 4px;
color: #eee;
background-color: #333;
font-family: "Monaco", monospace;
font-size: medium;
letter-spacing: 3px;
padding: 4px;
}
.content {
padding: 10px;
}
body.dark {
background-color: #242424;
color: #666;
}
.dark .shortcut {
color: #777;
}
.dark a {
color: #3b99fc;
}
</style>
</head>
<body>
<div class="content">
<label for="dark">
<input type="checkbox" id="dark" onclick="document.body.classList.toggle('dark')"> Dark background
</label>
<p>
React Native JS code runs inside this Chrome tab.
</p>
<p>Press <kbd id='dev_tools_shortcut' class="shortcut">⌘⌥J</kbd> to open Developer Tools. Enable <a href="https://stackoverflow.com/a/17324511/232122" target="_blank">Pause On Caught Exceptions</a> for a better debugging experience.</p>
<p>Status: <span id="status">Loading...</span></p>
</div>
</body>
</html>