diff --git a/app/ui.js b/app/ui.js index 71933af6..39d28a33 100644 --- a/app/ui.js +++ b/app/ui.js @@ -20,8 +20,12 @@ import * as WebUtil from "./webutil.js"; const PAGE_TITLE = "noVNC"; +const LINGUAS = ["cs", "de", "el", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt_BR", "ru", "sv", "tr", "zh_CN", "zh_TW"]; + const UI = { + customSettings: {}, + connected: false, desktopName: "", @@ -42,20 +46,31 @@ const UI = { reconnectCallback: null, reconnectPassword: null, - prime() { - return WebUtil.initSettings().then(() => { - if (document.readyState === "interactive" || document.readyState === "complete") { - return UI.start(); - } + async start(options={}) { + UI.customSettings = options.settings || {}; + if (UI.customSettings.defaults === undefined) { + UI.customSettings.defaults = {}; + } + if (UI.customSettings.mandatory === undefined) { + UI.customSettings.mandatory = {}; + } - return new Promise((resolve, reject) => { - document.addEventListener('DOMContentLoaded', () => UI.start().then(resolve).catch(reject)); + // Set up translations + try { + await l10n.setup(LINGUAS, "app/locale/"); + } catch (err) { + Log.Error("Failed to load translations: " + err); + } + + // Initialize setting storage + await WebUtil.initSettings(); + + // Wait for the page to load + if (document.readyState !== "interactive" && document.readyState !== "complete") { + await new Promise((resolve, reject) => { + document.addEventListener('DOMContentLoaded', resolve); }); - }); - }, - - // Render default UI and initialize settings menu - start() { + } UI.initSettings(); @@ -70,22 +85,20 @@ const UI = { } // Try to fetch version number - fetch('./package.json') - .then((response) => { - if (!response.ok) { - throw Error("" + response.status + " " + response.statusText); - } - return response.json(); - }) - .then((packageInfo) => { - Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version); - }) - .catch((err) => { - Log.Error("Couldn't fetch package.json: " + err); - Array.from(document.getElementsByClassName('noVNC_version_wrapper')) - .concat(Array.from(document.getElementsByClassName('noVNC_version_separator'))) - .forEach(el => el.style.display = 'none'); - }); + try { + let response = await fetch('./package.json'); + if (!response.ok) { + throw Error("" + response.status + " " + response.statusText); + } + + let packageInfo = await response.json(); + Array.from(document.getElementsByClassName('noVNC_version')).forEach(el => el.innerText = packageInfo.version); + } catch (err) { + Log.Error("Couldn't fetch package.json: " + err); + Array.from(document.getElementsByClassName('noVNC_version_wrapper')) + .concat(Array.from(document.getElementsByClassName('noVNC_version_separator'))) + .forEach(el => el.style.display = 'none'); + } // Adapt the interface for touch screen devices if (isTouchDevice) { @@ -120,7 +133,7 @@ const UI = { document.documentElement.classList.remove("noVNC_loading"); - let autoconnect = WebUtil.getConfigVar('autoconnect', false); + let autoconnect = UI.getSetting('autoconnect'); if (autoconnect === 'true' || autoconnect == '1') { autoconnect = true; UI.connect(); @@ -129,8 +142,6 @@ const UI = { // Show the connect panel on first load unless autoconnecting UI.openConnectPanel(); } - - return Promise.resolve(UI.rfb); }, initFullscreen() { @@ -158,23 +169,26 @@ const UI = { UI.initSetting('logging', 'warn'); UI.updateLogging(); + UI.setupSettingLabels(); + /* Populate the controls if defaults are provided in the URL */ UI.initSetting('host', ''); UI.initSetting('port', 0); UI.initSetting('encrypt', (window.location.protocol === "https:")); + UI.initSetting('password'); + UI.initSetting('autoconnect', false); UI.initSetting('view_clip', false); UI.initSetting('resize', 'off'); UI.initSetting('quality', 6); UI.initSetting('compression', 2); UI.initSetting('shared', true); + UI.initSetting('bell', 'on'); UI.initSetting('view_only', false); UI.initSetting('show_dot', false); UI.initSetting('path', 'websockify'); UI.initSetting('repeaterID', ''); UI.initSetting('reconnect', false); UI.initSetting('reconnect_delay', 5000); - - UI.setupSettingLabels(); }, // Adds a link to the label elements on the corresponding input elements setupSettingLabels() { @@ -736,6 +750,10 @@ const UI = { // Initial page load read/initialization of settings initSetting(name, defVal) { + // Has the user overridden the default value? + if (name in UI.customSettings.defaults) { + defVal = UI.customSettings.defaults[name]; + } // Check Query string followed by cookie let val = WebUtil.getConfigVar(name); if (val === null) { @@ -743,6 +761,11 @@ const UI = { } WebUtil.setSetting(name, val); UI.updateSetting(name); + // Has the user forced a value? + if (name in UI.customSettings.mandatory) { + val = UI.customSettings.mandatory[name]; + UI.forceSetting(name, val); + } return val; }, @@ -761,9 +784,12 @@ const UI = { let value = UI.getSetting(name); const ctrl = document.getElementById('noVNC_setting_' + name); + if (ctrl === null) { + return; + } + if (ctrl.type === 'checkbox') { ctrl.checked = value; - } else if (typeof ctrl.options !== 'undefined') { for (let i = 0; i < ctrl.options.length; i += 1) { if (ctrl.options[i].value === value) { @@ -796,7 +822,8 @@ const UI = { getSetting(name) { const ctrl = document.getElementById('noVNC_setting_' + name); let val = WebUtil.readSetting(name); - if (typeof val !== 'undefined' && val !== null && ctrl.type === 'checkbox') { + if (typeof val !== 'undefined' && val !== null && + ctrl !== null && ctrl.type === 'checkbox') { if (val.toString().toLowerCase() in {'0': 1, 'no': 1, 'false': 1}) { val = false; } else { @@ -811,14 +838,22 @@ const UI = { // disable the labels that belong to disabled input elements. disableSetting(name) { const ctrl = document.getElementById('noVNC_setting_' + name); - ctrl.disabled = true; - ctrl.label.classList.add('noVNC_disabled'); + if (ctrl !== null) { + ctrl.disabled = true; + if (ctrl.label !== undefined) { + ctrl.label.classList.add('noVNC_disabled'); + } + } }, enableSetting(name) { const ctrl = document.getElementById('noVNC_setting_' + name); - ctrl.disabled = false; - ctrl.label.classList.remove('noVNC_disabled'); + if (ctrl !== null) { + ctrl.disabled = false; + if (ctrl.label !== undefined) { + ctrl.label.classList.remove('noVNC_disabled'); + } + } }, /* ------^------- @@ -1000,7 +1035,7 @@ const UI = { const path = UI.getSetting('path'); if (typeof password === 'undefined') { - password = WebUtil.getConfigVar('password'); + password = UI.getSetting('password'); UI.reconnectPassword = password; } @@ -1730,7 +1765,7 @@ const UI = { }, bell(e) { - if (WebUtil.getConfigVar('bell', 'on') === 'on') { + if (UI.getSetting('bell') === 'on') { const promise = document.getElementById('noVNC_bell').play(); // The standards disagree on the return value here if (promise) { @@ -1761,10 +1796,4 @@ const UI = { */ }; -// Set up translations -const LINGUAS = ["cs", "de", "el", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt_BR", "ru", "sv", "tr", "zh_CN", "zh_TW"]; -l10n.setup(LINGUAS, "app/locale/") - .catch(err => Log.Error("Failed to load translations: " + err)) - .then(UI.prime); - export default UI; diff --git a/defaults.json b/defaults.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/defaults.json @@ -0,0 +1 @@ +{} diff --git a/mandatory.json b/mandatory.json new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/mandatory.json @@ -0,0 +1 @@ +{} diff --git a/vnc.html b/vnc.html index 89ee11e3..fd887730 100644 --- a/vnc.html +++ b/vnc.html @@ -46,7 +46,56 @@ - + +