main
html 247 lines 7.47 KB
Raw
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>React Developer Tools</title>
5 <meta charset="utf8" />
6 <style>
7 html {
8 height: 100%;
9 font-family: sans-serif;
10 }
11 body {
12 height: 100%;
13 margin: 0;
14 padding: 0;
15 background-color: #fff;
16 color: #777d88;
17 }
18
19 .container {
20 height: 100%;
21 display: flex;
22 flex-direction: column;
23 align-items: center;
24 justify-content: center;
25 overflow: auto;
26 }
27
28 p {
29 padding: 0;
30 margin: 0;
31 }
32
33 .input {
34 display: block;
35 font-weight: 100;
36 padding: 0 0.25rem;
37 border: 1px solid #aaa;
38 background-color: #fff;
39 color: #666;
40 }
41
42 .link {
43 color: #1478fa;
44 text-decoration: none;
45 }
46 .link:hover {
47 text-decoration: underline;
48 }
49
50 .waiting-header {
51 padding: 0.5rem;
52 display: inline-block;
53 position: absolute;
54 right: 0.5rem;
55 top: 0.5rem;
56 border-radius: 0.25rem;
57 background-color: rgba(0,1,2,.6);
58 color: white;
59 border: none;
60 font-weight: 100;
61 font-style: italic;
62 }
63
64 .boxes {
65 display: flex;
66 flex-direction: column;
67 align-items: stretch;
68 justify-content: center;
69 padding: 1rem;
70 }
71 .box {
72 text-align: center;
73 border-radius: 0.5rem;
74 background-color: #f7f7f7;
75 border: 1px solid #eee;
76 color: #777d88;
77 padding: 1rem;
78 margin-top: 1rem;
79 }
80 .box:first-of-type {
81 margin-top: 0;
82 }
83
84 .box-header {
85 text-align: center;
86 color: #5f6673;
87 font-size: 1.25rem;
88 margin-bottom: 0.5rem;
89 }
90 .box-content {
91 line-height: 1.5rem;
92 }
93
94 #loading-status {
95 text-align: center;
96 margin-top: 1rem;
97 }
98
99 .prompt,
100 .confirmation {
101 margin-bottom: 0.25rem;
102 }
103
104 .confirmation {
105 font-style: italic;
106 }
107
108 .hidden {
109 display: none;
110 }
111 </style>
112 </head>
113 <body>
114 <div id="container" class="container" style="-webkit-user-select: none; -webkit-app-region: drag;">
115 <div class="waiting-header">Waiting for React to connect…</div>
116 <div class="boxes" style="-webkit-app-region: none;">
117 <div class="box">
118 <div class="box-header">React Native</div>
119 <div class="box-content">
120 Open the <a
121 id="rn-help-link"
122 class="link"
123 target="_blank"
124 rel="noopener noreferrer"
125 href="https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu"
126 >in-app developer menu</a> to connect.
127 </div>
128 </div>
129 <div class="box">
130 <div class="box-header">React DOM</div>
131 <div class="box-content">
132 <div id="box-content-prompt" class="prompt">
133 Add one of the following (click to copy):
134 </div>
135 <div id="box-content-confirmation" class="confirmation hidden">
136 Copied to clipboard.
137 </div>
138 <span class="input" contenteditable="true" id="localhost"></span>
139 <span class="input" contenteditable="true" id="byip"></span>
140 to the top of the page you want to debug,
141 <br />
142 <strong>before</strong> importing React DOM.
143 </div>
144 </div>
145 <div class="box">
146 <div class="box-header">Profiler</div>
147 <div class="box-content">
148 Open the <a
149 id="profiler"
150 class="link"
151 href="#"
152 >Profiler tab</a> to inspect saved profiles.
153 </div>
154 </div>
155 <div id="loading-status">Starting the server…</div>
156 </div>
157 </div>
158 <script>
159 // window.api is defined in preload.js
160 const {electron, readEnv, ip, getDevTools} = window.api;
161 const {options, useHttps, host, protocol, port, path, clientHost, clientPort, clientUseHttps} = readEnv();
162
163 const localIp = ip.address();
164
165 // Effective values for display URLs: client overrides take precedence over server values.
166 const effectiveHost = clientHost != null ? clientHost : host;
167 const effectivePort = clientPort != null ? clientPort : port;
168 const effectiveUseHttps = clientUseHttps != null ? clientUseHttps : useHttps;
169 const effectiveProtocol = effectiveUseHttps ? 'https' : 'http';
170 const defaultPort = (effectivePort === 443 && effectiveUseHttps) || (effectivePort === 80 && !effectiveUseHttps);
171 const pathStr = path != null ? path : '';
172 const server = defaultPort ? `${effectiveProtocol}://${effectiveHost}${pathStr}` : `${effectiveProtocol}://${effectiveHost}:${effectivePort}${pathStr}`;
173 const serverIp = defaultPort ? `${effectiveProtocol}://${localIp}${pathStr}` : `${effectiveProtocol}://${localIp}:${effectivePort}${pathStr}`;
174 const $ = document.querySelector.bind(document);
175
176 let timeoutID;
177
178 function selectAllAndCopy(event) {
179 const element = event.target;
180 if (window.getSelection) {
181 const selection = window.getSelection();
182 const range = document.createRange();
183 range.selectNodeContents(element);
184 selection.removeAllRanges();
185 selection.addRange(range);
186 electron.clipboard.writeText(event.target.textContent);
187
188 const $promptDiv = $("#box-content-prompt");
189 const $confirmationDiv = $("#box-content-confirmation");
190 $promptDiv.classList.add('hidden');
191 $confirmationDiv.classList.remove('hidden');
192
193 if (timeoutID) {
194 clearTimeout(timeoutID);
195 }
196
197 timeoutID = setTimeout(() => {
198 $promptDiv.classList.remove('hidden');
199 $confirmationDiv.classList.add('hidden');
200 }, 1000);
201 }
202 }
203
204 function openProfiler() {
205 window.devtools
206 .setContentDOMNode(document.getElementById("container"))
207 .openProfiler();
208 }
209
210 function attachListeners() {
211 const link = $('#rn-help-link');
212 link.addEventListener('click', event => {
213 event.preventDefault();
214 electron.shell.openExternal(link.href);
215 });
216
217 const $localhost = $("#localhost");
218 $localhost.innerText = `<script src="${server}"></` + 'script>';
219 $localhost.addEventListener('click', selectAllAndCopy);
220 $localhost.addEventListener('focus', selectAllAndCopy);
221
222 const $byIp = $("#byip");
223 $byIp.innerText = `<script src="${serverIp}"></` + 'script>';
224 $byIp.addEventListener('click', selectAllAndCopy);
225 $byIp.addEventListener('focus', selectAllAndCopy);
226
227 const $profiler = $("#profiler");
228 $profiler.addEventListener('click', openProfiler);
229 };
230
231 // Initially attach the listeners
232 attachListeners();
233
234 window.devtools = getDevTools();
235 window.server = window.devtools
236 .setContentDOMNode(document.getElementById("container"))
237 .setDisconnectedCallback(attachListeners)
238 .setStatusListener(function(status) {
239 const element = document.getElementById("loading-status");
240 if (element) {
241 element.innerText = status;
242 }
243 })
244 .startServer(port, host, options, undefined, path, {host: clientHost, port: clientPort, useHttps: clientUseHttps});
245 </script>
246 </body>
247 </html>