Files
2026-09-22 18:59:48 +00:00

117 lines
4.8 KiB
JavaScript

// Lokale Bilder/Videos von diesem PC in den Bild-/Video-Feldern von nightTab nutzen.
//
// Die Seite laeuft unter https://mystart.local; der Browser blockt von dort aus
// file://-Adressen. Die App (Program.cs) liefert deshalb lokale Dateien unter
// https://files.mystart.local/<laufwerk>/<pfad> (C:\a\b.jpg -> /c/a/b.jpg)
// https://files.mystart.local/unc/<server>/<freigabe>/<pfad> (\\server\share\x.png)
// aus. Dieses Skript wandelt eingetippte/eingefuegte Pfade in solche Adressen um
// und haengt an die Bild-/Video-Felder einen "Lokale Datei waehlen"-Knopf.
(function () {
if (!(window.chrome && window.chrome.webview)) return;
var HOST = 'https://files.mystart.local/';
var FIELD = /(image|video)-url$/; // theme-background-image-url, display-visual-image-url, ...
function encodeSegments(path) {
return path.split(/[\\/]+/).filter(Boolean).map(encodeURIComponent).join('/');
}
// Ein Pfad (auch "In Anfuehrungszeichen", wie "Als Pfad kopieren" ihn liefert,
// oder file:///) -> Adresse der App. Alles andere -> null (bleibt unveraendert).
function toUrl(line) {
var s = line.trim();
if (s.length > 1 && s.charAt(0) === '"' && s.charAt(s.length - 1) === '"') s = s.slice(1, -1).trim();
if (/^file:\/\/\//i.test(s)) {
s = s.replace(/^file:\/\/\//i, '');
try { s = decodeURI(s); } catch (e) { /* unveraendert lassen */ }
}
if (/^[A-Za-z]:[\\/]/.test(s)) return HOST + s.charAt(0).toLowerCase() + '/' + encodeSegments(s.slice(3));
if (/^\\\\[^\\]/.test(s)) return HOST + 'unc/' + encodeSegments(s.slice(2));
return null;
}
function isMediaField(el) {
return el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') && FIELD.test(el.id || '');
}
function setValue(el, value) {
el.value = value;
el.dispatchEvent(new Event('input', { bubbles: true }));
el.dispatchEvent(new Event('change', { bubbles: true }));
}
// Pfade in einem Feld (auch mehrzeilig, z. B. mehrere Hintergrundbilder) umschreiben.
function fix(el) {
if (!isMediaField(el) || !el.value) return;
var changed = false;
var out = el.value.split(/\r?\n/).map(function (l) {
var u = toUrl(l);
if (u === null) return l;
changed = true;
return u;
});
if (changed) setValue(el, out.join('\n'));
}
// Erst beim Verlassen des Felds/Enter (change) bzw. nach dem Einfuegen umwandeln,
// sonst wuerde schon "C:\" waehrend des Tippens umgeschrieben.
document.addEventListener('change', function (ev) { fix(ev.target); }, true);
document.addEventListener('paste', function (ev) {
var t = ev.target;
setTimeout(function () { fix(t); }, 0);
}, true);
// --- "Lokale Datei waehlen"-Knopf ---
var targets = {};
var nextToken = 1;
window.chrome.webview.addEventListener('message', function (ev) {
var d = ev.data;
if (!d || d.type !== 'file-picked') return;
var el = targets[d.token];
delete targets[d.token];
if (!el || !d.paths || !d.paths.length) return;
var urls = d.paths.map(function (p) { return toUrl(p) || p; });
var multi = /theme-background-image-url$/.test(el.id || '');
var existing = el.value.trim();
setValue(el, multi && existing ? existing + '\n' + urls.join('\n') : urls.join('\n'));
});
function addButton(el) {
if (el.getAttribute('data-mystart-pick')) return;
el.setAttribute('data-mystart-pick', '1');
var b = document.createElement('div');
b.textContent = 'Lokale Datei wählen…';
b.title = 'Bild/Video von diesem PC auswählen';
b.style.cssText = 'display:inline-block;margin-top:6px;padding:5px 10px;border-radius:6px;' +
'background:rgba(128,128,128,.25);cursor:pointer;user-select:none;font-size:12px;';
b.onmouseenter = function () { b.style.background = 'rgba(128,128,128,.4)'; };
b.onmouseleave = function () { b.style.background = 'rgba(128,128,128,.25)'; };
b.addEventListener('click', function () {
var token = nextToken++;
targets[token] = el;
try {
window.chrome.webview.postMessage({
type: 'pick-file',
token: token,
kind: /video-url$/.test(el.id) ? 'video' : 'image',
multiple: /theme-background-image-url$/.test(el.id)
});
} catch (e) { /* ignore */ }
});
el.insertAdjacentElement('afterend', b);
}
var SELECTOR = '#theme-background-image-url,#theme-background-video-url,#display-visual-image-url,' +
'#background-image-url,#background-video-url';
var scheduled = false;
function scan() {
scheduled = false;
var list = document.querySelectorAll(SELECTOR);
for (var i = 0; i < list.length; i++) addButton(list[i]);
}
new MutationObserver(function () {
if (!scheduled) { scheduled = true; requestAnimationFrame(scan); }
}).observe(document.documentElement, { childList: true, subtree: true });
})();