From 9334c6824156877551d21570fea46dae8a527cc2 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 26 Jun 2020 15:57:09 +0200 Subject: [PATCH 1/5] Handle all settings via UI.getSetting() Makes sure everything behaves the same way, even if there is no visible UI for a settings. --- app/ui.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/app/ui.js b/app/ui.js index 90dc71893..caba8e180 100644 --- a/app/ui.js +++ b/app/ui.js @@ -120,7 +120,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(); @@ -160,11 +160,14 @@ const UI = { /* Populate the controls if defaults are provided in the URL */ 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'); @@ -759,9 +762,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) { @@ -794,7 +800,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 { @@ -998,7 +1005,7 @@ const UI = { const path = UI.getSetting('path'); if (typeof password === 'undefined') { - password = WebUtil.getConfigVar('password'); + password = UI.getSetting('password'); UI.reconnectPassword = password; } @@ -1728,7 +1735,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) { From c6606a5caf9b9895e89b580351201ece2f1a49e4 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 26 Jun 2020 15:59:00 +0200 Subject: [PATCH 2/5] Merge UI startup in to a single routine Makes it easier to see how things are connected. --- app/ui.js | 67 ++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/app/ui.js b/app/ui.js index caba8e180..e4dfd5af8 100644 --- a/app/ui.js +++ b/app/ui.js @@ -20,6 +20,8 @@ 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 = { connected: false, @@ -42,20 +44,23 @@ const UI = { reconnectCallback: null, reconnectPassword: null, - prime() { - return WebUtil.initSettings().then(() => { - if (document.readyState === "interactive" || document.readyState === "complete") { - return UI.start(); - } + async start() { + // Set up translations + try { + await l10n.setup(LINGUAS, "app/locale/"); + } catch (err) { + Log.Error("Failed to load translations: " + err); + } - return new Promise((resolve, reject) => { - document.addEventListener('DOMContentLoaded', () => UI.start().then(resolve).catch(reject)); - }); - }); - }, + // Initialize setting storage + await WebUtil.initSettings(); - // Render default UI and initialize settings menu - start() { + // Wait for the page to load + if (document.readyState !== "interactive" && document.readyState !== "complete") { + await new Promise((resolve, reject) => { + document.addEventListener('DOMContentLoaded', resolve); + }); + } UI.initSettings(); @@ -70,22 +75,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) { @@ -129,8 +132,6 @@ const UI = { // Show the connect panel on first load unless autoconnecting UI.openConnectPanel(); } - - return Promise.resolve(UI.rfb); }, initFullscreen() { @@ -1766,10 +1767,6 @@ 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); +UI.start(); export default UI; From 84897fd1103d7e4603d7cadc4957111ee6bd66d0 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 26 Jun 2020 16:15:09 +0200 Subject: [PATCH 3/5] Handle disabling settings without label --- app/ui.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/ui.js b/app/ui.js index e4dfd5af8..316042911 100644 --- a/app/ui.js +++ b/app/ui.js @@ -818,13 +818,17 @@ const UI = { disableSetting(name) { const ctrl = document.getElementById('noVNC_setting_' + name); ctrl.disabled = true; - ctrl.label.classList.add('noVNC_disabled'); + 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.label !== undefined) { + ctrl.label.classList.remove('noVNC_disabled'); + } }, /* ------^------- From 438e5b360826b435036ee981f2588526ac08fcaa Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 26 Jun 2020 16:00:32 +0200 Subject: [PATCH 4/5] Make it easier for downstream to modify settings Expose a simple and stable API to override default settings, and force settings that users shouldn't be able to change. --- app/ui.js | 43 ++++++++++++++++++++++++++++++++----------- vnc.html | 22 +++++++++++++++++++++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/app/ui.js b/app/ui.js index 316042911..49c6c2579 100644 --- a/app/ui.js +++ b/app/ui.js @@ -24,6 +24,8 @@ const LINGUAS = ["cs", "de", "el", "es", "fr", "it", "ja", "ko", "nl", "pl", "pt const UI = { + customSettings: {}, + connected: false, desktopName: "", @@ -44,7 +46,15 @@ const UI = { reconnectCallback: null, reconnectPassword: null, - async start() { + async start(options={}) { + UI.customSettings = options.settings || {}; + if (UI.customSettings.defaults === undefined) { + UI.customSettings.defaults = {}; + } + if (UI.customSettings.mandatory === undefined) { + UI.customSettings.mandatory = {}; + } + // Set up translations try { await l10n.setup(LINGUAS, "app/locale/"); @@ -159,6 +169,8 @@ const UI = { UI.initSetting('logging', 'warn'); UI.updateLogging(); + UI.setupSettingLabels(); + /* Populate the controls if defaults are provided in the URL */ UI.initSetting('encrypt', (window.location.protocol === "https:")); UI.initSetting('password'); @@ -175,8 +187,6 @@ const UI = { 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() { @@ -738,6 +748,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) { @@ -745,6 +759,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; }, @@ -817,17 +836,21 @@ const UI = { // disable the labels that belong to disabled input elements. disableSetting(name) { const ctrl = document.getElementById('noVNC_setting_' + name); - ctrl.disabled = true; - if (ctrl.label !== undefined) { - 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; - if (ctrl.label !== undefined) { - ctrl.label.classList.remove('noVNC_disabled'); + if (ctrl !== null) { + ctrl.disabled = false; + if (ctrl.label !== undefined) { + ctrl.label.classList.remove('noVNC_disabled'); + } } }, @@ -1771,6 +1794,4 @@ const UI = { */ }; -UI.start(); - export default UI; diff --git a/vnc.html b/vnc.html index 89ee11e36..d6a7e56aa 100644 --- a/vnc.html +++ b/vnc.html @@ -46,7 +46,27 @@ - + + From 28d4020302e155fb693ee297d6aa51366ba71518 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Thu, 8 Aug 2024 16:20:51 +0200 Subject: [PATCH 5/5] Load settings from web server Make it even easier to customize things by loading the settings from separate configuration files. --- defaults.json | 1 + mandatory.json | 1 + vnc.html | 31 ++++++++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 defaults.json create mode 100644 mandatory.json diff --git a/defaults.json b/defaults.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/defaults.json @@ -0,0 +1 @@ +{} diff --git a/mandatory.json b/mandatory.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/mandatory.json @@ -0,0 +1 @@ +{} diff --git a/vnc.html b/vnc.html index d6a7e56aa..fd8877304 100644 --- a/vnc.html +++ b/vnc.html @@ -49,11 +49,40 @@