117 lines
4.8 KiB
JavaScript
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 });
|
|
})();
|