index.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. require("./index.css");
  4. var _blueIcon = _interopRequireDefault(require("./assets/blue-icon.png"));
  5. var _grayIcon = _interopRequireDefault(require("./assets/gray-icon.png"));
  6. var _orangeIcon = _interopRequireDefault(require("./assets/orange-icon.png"));
  7. /**
  8. * Copyright (c) Facebook, Inc. and its affiliates.
  9. *
  10. * This source code is licensed under the MIT license found in the
  11. * LICENSE file in the root directory of this source tree.
  12. *
  13. */
  14. /* eslint-env browser */
  15. const isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform);
  16. const refreshShortcut = isMacLike ? '⌘R' : 'Ctrl R';
  17. window.onload = function () {
  18. if (!isMacLike) {
  19. document.getElementById('shortcut').innerHTML = 'Ctrl⇧J';
  20. }
  21. Page.render();
  22. };
  23. window.onReloadClicked = function () {
  24. var xhr = new XMLHttpRequest();
  25. xhr.open('GET', `${window.location.origin}/reload`, true);
  26. xhr.send();
  27. };
  28. const Page = window.Page = {
  29. state: {
  30. isDark: localStorage.getItem('darkTheme') === null ? window.matchMedia('(prefers-color-scheme: dark)').matches : localStorage.getItem('darkTheme') === 'on',
  31. isPriorityMaintained: localStorage.getItem('maintainPriority') === 'on',
  32. status: {
  33. type: 'disconnected'
  34. },
  35. visibilityState: document.visibilityState
  36. },
  37. setState(partialState) {
  38. Page.state = Object.assign({}, Page.state, partialState);
  39. Page.render();
  40. },
  41. render() {
  42. const {
  43. isDark,
  44. isPriorityMaintained,
  45. status,
  46. visibilityState
  47. } = Page.state;
  48. const statusNode = document.getElementById('status');
  49. switch (status.type) {
  50. case 'connected':
  51. statusNode.innerHTML = 'Debugger session #' + status.id + ' active.';
  52. break;
  53. case 'error':
  54. statusNode.innerHTML = status.error.reason || 'Disconnected from proxy. Attempting reconnection. Is node server running?';
  55. break;
  56. case 'connecting':
  57. case 'disconnected': // Fall through.
  58. default:
  59. statusNode.innerHTML = 'Waiting, press <span class="shortcut">' + refreshShortcut + '</span> in simulator to reload and connect.';
  60. break;
  61. }
  62. const linkNode = document.querySelector('link[rel=icon]');
  63. if (status.type === 'disconnected' || status.type === 'error') {
  64. linkNode.href = _grayIcon.default;
  65. } else {
  66. if (visibilityState === 'visible' || isPriorityMaintained) {
  67. linkNode.href = _blueIcon.default;
  68. } else {
  69. linkNode.href = _orangeIcon.default;
  70. }
  71. }
  72. const darkCheckbox = document.getElementById('dark');
  73. document.body.classList.toggle('dark', isDark);
  74. darkCheckbox.checked = isDark;
  75. localStorage.setItem('darkTheme', isDark ? 'on' : '');
  76. const maintainPriorityCheckbox = document.getElementById('maintain-priority');
  77. const silence = document.getElementById('silence');
  78. silence.volume = 0.1;
  79. if (isPriorityMaintained) {
  80. silence.play();
  81. } else {
  82. silence.pause();
  83. }
  84. maintainPriorityCheckbox.checked = isPriorityMaintained;
  85. localStorage.setItem('maintainPriority', isPriorityMaintained ? 'on' : '');
  86. },
  87. toggleDarkTheme() {
  88. Page.setState({
  89. isDark: !Page.state.isDark
  90. });
  91. },
  92. togglePriorityMaintenance() {
  93. Page.setState({
  94. isPriorityMaintained: !Page.state.isPriorityMaintained
  95. });
  96. }
  97. };
  98. function connectToDebuggerProxy() {
  99. const ws = new WebSocket('ws://' + window.location.host + '/debugger-proxy?role=debugger&name=Chrome');
  100. let worker;
  101. function createJSRuntime() {
  102. // This worker will run the application JavaScript code,
  103. // making sure that it's run in an environment without a global
  104. // document, to make it consistent with the JSC executor environment.
  105. worker = new Worker('./debuggerWorker.js');
  106. worker.onmessage = function (message) {
  107. ws.send(JSON.stringify(message.data));
  108. };
  109. window.onbeforeunload = function () {
  110. return 'If you reload this page, it is going to break the debugging session. ' + 'Press ' + refreshShortcut + ' on the device to reload.';
  111. };
  112. updateVisibility();
  113. }
  114. function shutdownJSRuntime() {
  115. if (worker) {
  116. worker.terminate();
  117. worker = null;
  118. window.onbeforeunload = null;
  119. }
  120. }
  121. function updateVisibility() {
  122. if (worker && !Page.state.isPriorityMaintained) {
  123. worker.postMessage({
  124. method: 'setDebuggerVisibility',
  125. visibilityState: document.visibilityState
  126. });
  127. }
  128. Page.setState({
  129. visibilityState: document.visibilityState
  130. });
  131. }
  132. ws.onopen = function () {
  133. Page.setState({
  134. status: {
  135. type: 'connecting'
  136. }
  137. });
  138. };
  139. ws.onmessage = async function (message) {
  140. if (!message.data) {
  141. return;
  142. }
  143. const object = JSON.parse(message.data);
  144. if (object.$event === 'client-disconnected') {
  145. shutdownJSRuntime();
  146. Page.setState({
  147. status: {
  148. type: 'disconnected'
  149. }
  150. });
  151. return;
  152. }
  153. if (!object.method) {
  154. return;
  155. } // Special message that asks for a new JS runtime
  156. if (object.method === 'prepareJSRuntime') {
  157. shutdownJSRuntime();
  158. console.clear();
  159. createJSRuntime();
  160. ws.send(JSON.stringify({
  161. replyID: object.id
  162. }));
  163. Page.setState({
  164. status: {
  165. type: 'connected',
  166. id: object.id
  167. }
  168. });
  169. } else if (object.method === '$disconnected') {
  170. shutdownJSRuntime();
  171. Page.setState({
  172. status: {
  173. type: 'disconnected'
  174. }
  175. });
  176. } else {
  177. worker.postMessage(object);
  178. }
  179. };
  180. ws.onclose = function (error) {
  181. shutdownJSRuntime();
  182. Page.setState({
  183. status: {
  184. type: 'error',
  185. error
  186. }
  187. });
  188. if (error.reason) {
  189. console.warn(error.reason);
  190. }
  191. setTimeout(connectToDebuggerProxy, 500);
  192. }; // Let debuggerWorker.js know when we're not visible so that we can warn about
  193. // poor performance when using remote debugging.
  194. document.addEventListener('visibilitychange', updateVisibility, false);
  195. }
  196. connectToDebuggerProxy();
  197. //# sourceMappingURL=index.js.map