]>
Commit | Line | Data |
---|---|---|
40f281eb | 1 | <!DOCTYPE html> |
91308399 | 2 | <html> |
e84101b3 PÅ |
3 | <head> |
4 | ||
82744aa8 | 5 | <!-- |
83391ffc | 6 | noVNC example: lightweight example using minimal UI and features |
8c2866df SM |
7 | |
8 | This is a self-contained file which doesn't import WebUtil or external CSS. | |
9 | ||
d58f8b51 | 10 | Copyright (C) 2012 Joel Martin |
0f207c80 | 11 | Copyright (C) 2018 Samuel Mannehed for Cendio AB |
1d728ace | 12 | noVNC is licensed under the MPL 2.0 (see LICENSE.txt) |
d58f8b51 | 13 | This file is licensed under the 2-Clause BSD license (see LICENSE.txt). |
d595e656 JM |
14 | |
15 | Connect parameters are provided in query string: | |
51f9f009 | 16 | http://example.com/?host=HOST&port=PORT&scale=true |
d595e656 | 17 | --> |
e84101b3 PÅ |
18 | <title>noVNC</title> |
19 | ||
33f5d3bd PÅ |
20 | <meta charset="utf-8"> |
21 | ||
e84101b3 PÅ |
22 | <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame |
23 | Remove this if you use the .htaccess --> | |
33f5d3bd PÅ |
24 | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
25 | ||
e0d4e5a1 SM |
26 | <style type="text/css"> |
27 | ||
28 | body { | |
29 | margin: 0; | |
de79ae92 | 30 | background-color: dimgrey; |
e0d4e5a1 SM |
31 | height: 100%; |
32 | display: flex; | |
33 | flex-direction: column; | |
34 | } | |
35 | html { | |
e0d4e5a1 SM |
36 | height: 100%; |
37 | } | |
38 | ||
39 | #noVNC_status_bar { | |
de79ae92 | 40 | background-color: #6e84a3; |
e0d4e5a1 SM |
41 | width: 100%; |
42 | display: flex; | |
43 | justify-content: space-between; | |
de79ae92 | 44 | border-bottom: 1px outset; |
e0d4e5a1 SM |
45 | } |
46 | #noVNC_status { | |
47 | color: #ffffff; | |
48 | font: bold 12px Helvetica; | |
49 | margin: auto; | |
50 | } | |
51 | ||
e0d4e5a1 SM |
52 | #noVNC_left_dummy_elem { |
53 | flex: 1; | |
54 | } | |
55 | ||
56 | #noVNC_buttons { | |
57 | padding: 1px; | |
58 | flex: 1; | |
59 | display: flex; | |
60 | justify-content: flex-end; | |
61 | } | |
62 | ||
63 | </style> | |
e84101b3 | 64 | |
8c2866df | 65 | <!-- Promise polyfill for IE11 --> |
7569cdc2 | 66 | <script src="vendor/promise.js"></script> |
8c2866df | 67 | |
14ecdc62 FC |
68 | <!-- ES2015/ES6 modules polyfill --> |
69 | <script type="module"> | |
70 | window._noVNC_has_module_support = true; | |
71 | </script> | |
72 | <script> | |
73 | window.addEventListener("load", function() { | |
74 | if (window._noVNC_has_module_support) return; | |
75 | var loader = document.createElement("script"); | |
76 | loader.src = "vendor/browser-es-module-loader/dist/browser-es-module-loader.js"; | |
77 | document.head.appendChild(loader); | |
78 | }); | |
79 | </script> | |
80 | ||
81 | <!-- actual script modules --> | |
bf826444 | 82 | <script type="module" crossorigin="anonymous"> |
8c2866df | 83 | // RFB holds the API to connect and communicate with a VNC server |
7569cdc2 | 84 | import RFB from './core/rfb.js'; |
6f4b1e40 | 85 | |
8db09746 | 86 | var rfb; |
3bb12056 | 87 | var desktopName; |
8db09746 | 88 | |
8c2866df SM |
89 | // When this function is called we have received |
90 | // a desktop name from the server | |
e89eef94 PO |
91 | function updateDesktopName(e) { |
92 | desktopName = e.detail.name; | |
3bb12056 | 93 | } |
8c2866df SM |
94 | |
95 | // When this function is called, the server requires | |
96 | // credentials to authenticate | |
e89eef94 | 97 | function credentials(e) { |
8c2866df | 98 | // Let's create a password input |
7569cdc2 | 99 | var form = document.createElement('form'); |
cf3b5282 | 100 | form.innerHTML = '<label></label>'; |
8167e459 | 101 | form.innerHTML += '<input type=password size=10 id="password_input">'; |
7569cdc2 | 102 | form.onsubmit = setPassword; |
6048299a | 103 | |
8c2866df SM |
104 | // Bypass status() because it sets text content |
105 | // which doesn't allow adding elements | |
7569cdc2 SR |
106 | document.getElementById('noVNC_status').innerHTML = ''; |
107 | document.getElementById('noVNC_status').appendChild(form); | |
430f00d6 | 108 | document.getElementById('noVNC_status').querySelector('label').textContent = 'Password Required: '; |
d890e864 | 109 | } |
8c2866df SM |
110 | |
111 | // Send the credentials from the input element | |
91308399 | 112 | function setPassword() { |
430f00d6 | 113 | rfb.sendCredentials({ password: document.getElementById('password_input').value }); |
91308399 JM |
114 | return false; |
115 | } | |
8c2866df SM |
116 | |
117 | // Since most operating systems will catch Ctrl+Alt+Del | |
118 | // before they get a chance to be intercepted by the browser, | |
119 | // we provide a way to emulate this key sequence. | |
63708ff5 | 120 | function sendCtrlAltDel() { |
8db09746 | 121 | rfb.sendCtrlAltDel(); |
a8edf9d8 | 122 | return false; |
63708ff5 | 123 | } |
8c2866df | 124 | // Show a status text in the top bar |
de79ae92 | 125 | function status(text) { |
6048299a | 126 | document.getElementById('noVNC_status').textContent = text; |
3bb12056 | 127 | } |
91308399 | 128 | |
8c2866df SM |
129 | // When this function is called we have |
130 | // successfully connected to a server | |
ee5cae9f SM |
131 | function connected(e) { |
132 | document.getElementById('sendCtrlAltDelButton').disabled = false; | |
27dff4a0 | 133 | status("Connected to " + desktopName); |
3bb12056 | 134 | } |
ee5cae9f | 135 | |
8c2866df | 136 | // This function is called when we are disconnected |
ee5cae9f SM |
137 | function disconnected(e) { |
138 | document.getElementById('sendCtrlAltDelButton').disabled = true; | |
d472f3f1 | 139 | if (e.detail.clean) { |
de79ae92 | 140 | status("Disconnected"); |
d472f3f1 | 141 | } else { |
de79ae92 | 142 | status("Something went wrong, connection is closed"); |
91308399 | 143 | } |
91308399 JM |
144 | } |
145 | ||
6517c498 SM |
146 | // This function extracts the value of one variable from the |
147 | // query string. If the variable isn't defined in the URL | |
148 | // it returns the default value instead. | |
149 | function readQueryVariable(name, defaultValue) { | |
150 | // A URL with a query parameter can look like this: | |
151 | // https://www.example.com?myqueryparam=myvalue | |
152 | // | |
153 | // Note that we use location.href instead of location.search | |
154 | // because Firefox < 53 has a bug w.r.t location.search | |
155 | const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), | |
156 | match = document.location.href.match(re); | |
157 | if (typeof defaultValue === 'undefined') { defaultValue = null; } | |
158 | ||
159 | if (match) { | |
160 | // We have to decode the URL since want the cleartext value | |
161 | return decodeURIComponent(match[1]); | |
162 | } | |
163 | ||
164 | return defaultValue; | |
165 | } | |
166 | ||
7569cdc2 | 167 | document.getElementById('sendCtrlAltDelButton').onclick = sendCtrlAltDel; |
91308399 | 168 | |
6517c498 | 169 | // Read parameters specified in the URL query string |
7569cdc2 | 170 | // By default, use the host and port of server that served this file |
6517c498 SM |
171 | var host = readQueryVariable('host', window.location.hostname); |
172 | var port = readQueryVariable('port', window.location.port); | |
173 | var password = readQueryVariable('password', ''); | |
174 | var path = readQueryVariable('path', 'websockify'); | |
c55f05f6 | 175 | |
8c2866df SM |
176 | // | | | | | | |
177 | // | | | Connect | | | | |
178 | // v v v v v v | |
7569cdc2 | 179 | (function() { |
0139b256 | 180 | |
de79ae92 | 181 | status("Connecting"); |
91308399 | 182 | |
8c2866df | 183 | // Build the websocket URL used to connect |
5b4e5d01 | 184 | var url; |
51f9f009 | 185 | if (window.location.protocol === "https:") { |
5b4e5d01 PO |
186 | url = 'wss'; |
187 | } else { | |
188 | url = 'ws'; | |
189 | } | |
5b4e5d01 PO |
190 | url += '://' + host; |
191 | if(port) { | |
192 | url += ':' + port; | |
d9fc1c7b | 193 | } |
5b4e5d01 | 194 | url += '/' + path; |
d9fc1c7b | 195 | |
8c2866df | 196 | // Creating a new RFB object will start a new connection |
9b84f516 | 197 | rfb = new RFB(document.body, url, |
51f9f009 | 198 | { credentials: { password: password } }); |
8c2866df SM |
199 | |
200 | // Add listeners to important events from the RFB module | |
ee5cae9f SM |
201 | rfb.addEventListener("connect", connected); |
202 | rfb.addEventListener("disconnect", disconnected); | |
e89eef94 PO |
203 | rfb.addEventListener("credentialsrequired", credentials); |
204 | rfb.addEventListener("desktopname", updateDesktopName); | |
8c2866df SM |
205 | |
206 | // Set parameters that can be changed on an active connection | |
6517c498 SM |
207 | rfb.viewOnly = readQueryVariable('view_only', false); |
208 | rfb.scaleViewport = readQueryVariable('scale', false); | |
7569cdc2 SR |
209 | })(); |
210 | </script> | |
211 | </head> | |
212 | ||
178bf8ec | 213 | <body> |
dc905e85 | 214 | <div id="noVNC_status_bar"> |
4023a6e1 SM |
215 | <div id="noVNC_left_dummy_elem"></div> |
216 | <div id="noVNC_status">Loading</div> | |
217 | <div id="noVNC_buttons"> | |
218 | <input type=button value="Send CtrlAltDel" | |
de79ae92 | 219 | id="sendCtrlAltDelButton"> |
4023a6e1 | 220 | </div> |
178bf8ec | 221 | </div> |
178bf8ec | 222 | </body> |
91308399 | 223 | </html> |