// 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// (C:\a\b.jpg -> /c/a/b.jpg) // https://files.mystart.local/unc/// (\\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 }); })();