fix: restore default title when device name cleared, fix stale comments, set title at load
This commit is contained in:
@@ -1792,9 +1792,7 @@ function openSettings() {
|
||||
}
|
||||
|
||||
// Update document.title from device_name setting
|
||||
if (ss && ss.device_name) {
|
||||
document.title = ss.device_name;
|
||||
}
|
||||
document.title = (ss && ss.device_name) || 'muxplex';
|
||||
|
||||
// Multi-device enabled checkbox (with smart default: checked if remote_instances non-empty)
|
||||
const multiDeviceEnabledEl = $('setting-multi-device-enabled');
|
||||
@@ -2351,7 +2349,7 @@ function bindStaticEventListeners() {
|
||||
on($('setting-device-name'), 'input', function() {
|
||||
clearTimeout(_deviceNameDebounceTimer);
|
||||
var val = this.value;
|
||||
if (val) document.title = val;
|
||||
document.title = val || 'muxplex';
|
||||
_deviceNameDebounceTimer = setTimeout(function() {
|
||||
patchServerSetting('device_name', val).then(function() {
|
||||
_sources = buildSources(_serverSettings);
|
||||
@@ -2359,7 +2357,7 @@ function bindStaticEventListeners() {
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// Sessions tab — add remote instance button
|
||||
// Multi-Device tab — add remote instance button
|
||||
on($('add-remote-instance-btn'), 'click', function() {
|
||||
var container = $('setting-remote-instances');
|
||||
if (container) {
|
||||
@@ -2367,7 +2365,7 @@ function bindStaticEventListeners() {
|
||||
}
|
||||
});
|
||||
|
||||
// Sessions tab — delegated remove handler on remote instances container
|
||||
// Multi-Device tab — delegated remove handler on remote instances container
|
||||
var remoteInstancesContainer = $('setting-remote-instances');
|
||||
if (remoteInstancesContainer) {
|
||||
remoteInstancesContainer.addEventListener('click', function(e) {
|
||||
@@ -2519,7 +2517,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
restoreState()
|
||||
.then(() => {
|
||||
startPolling();
|
||||
loadServerSettings();
|
||||
loadServerSettings().then(function() {
|
||||
document.title = _serverSettings.device_name || 'muxplex';
|
||||
});
|
||||
startHeartbeat();
|
||||
bindStaticEventListeners();
|
||||
})
|
||||
|
||||
@@ -3564,3 +3564,62 @@ test('CSS style.css has scrollbar-width none for fit mode pre to hide scrollbar'
|
||||
'style.css must have scrollbar-width: none for hidden scrollbar in fit mode pre'
|
||||
);
|
||||
});
|
||||
|
||||
// --- document.title quality fixes ---
|
||||
|
||||
test('device name input handler restores default title when value is cleared', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
// Must use fallback form, not the conditional-only form
|
||||
assert.ok(
|
||||
source.includes("document.title = val || 'muxplex'"),
|
||||
"device name input handler must set document.title = val || 'muxplex' to restore default when cleared"
|
||||
);
|
||||
assert.ok(
|
||||
!source.includes("if (val) document.title = val"),
|
||||
"device name input handler must NOT use conditional 'if (val) document.title = val' (skips restore)"
|
||||
);
|
||||
});
|
||||
|
||||
test('openSettings restores default title unconditionally when device_name is absent', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
assert.ok(
|
||||
source.includes("document.title = (ss && ss.device_name) || 'muxplex'"),
|
||||
"openSettings must set document.title = (ss && ss.device_name) || 'muxplex' unconditionally"
|
||||
);
|
||||
assert.ok(
|
||||
!source.includes("if (ss && ss.device_name) {\n document.title = ss.device_name;\n }"),
|
||||
"openSettings must NOT use conditional block that skips restore when device_name is absent"
|
||||
);
|
||||
});
|
||||
|
||||
test('remote instance event listener comments say Multi-Device tab not Sessions tab', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
assert.ok(
|
||||
!source.includes('// Sessions tab \u2014 add remote instance button'),
|
||||
"comment for add-remote-instance-btn must say 'Multi-Device tab', not 'Sessions tab'"
|
||||
);
|
||||
assert.ok(
|
||||
!source.includes('// Sessions tab \u2014 delegated remove handler'),
|
||||
"comment for delegated remove handler must say 'Multi-Device tab', not 'Sessions tab'"
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('// Multi-Device tab \u2014 add remote instance button'),
|
||||
"add-remote-instance-btn comment must say '// Multi-Device tab \u2014 add remote instance button'"
|
||||
);
|
||||
assert.ok(
|
||||
source.includes('// Multi-Device tab \u2014 delegated remove handler'),
|
||||
"delegated remove handler comment must say '// Multi-Device tab \u2014 delegated remove handler'"
|
||||
);
|
||||
});
|
||||
|
||||
test('DOMContentLoaded sets document.title from server settings at page load', () => {
|
||||
const source = fs.readFileSync(new URL('../app.js', import.meta.url), 'utf8');
|
||||
// Find the DOMContentLoaded block
|
||||
const domIdx = source.indexOf("document.addEventListener('DOMContentLoaded'");
|
||||
assert.ok(domIdx !== -1, 'DOMContentLoaded handler must exist');
|
||||
const domBlock = source.substring(domIdx, domIdx + 800);
|
||||
assert.ok(
|
||||
domBlock.includes("document.title = _serverSettings.device_name || 'muxplex'"),
|
||||
"DOMContentLoaded must set document.title = _serverSettings.device_name || 'muxplex' after loadServerSettings resolves"
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user