Compare commits

..
2 Commits
4 changed files with 16 additions and 6 deletions
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "mrterm",
"version": "0.13.0",
"version": "0.13.1",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "mrterm",
"version": "0.13.0",
"version": "0.13.1",
"license": "MIT",
"dependencies": {
"@xterm/addon-fit": "^0.11.0",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "mrterm",
"productName": "MrTerm",
"version": "0.13.0",
"version": "0.13.1",
"description": "Moderner SSH-, SFTP- und RDP-Client",
"main": "src/main/main.js",
"author": "MrBlake",
+2 -1
View File
@@ -5,7 +5,8 @@
const $ = (sel, root = document) => root.querySelector(sel);
const $$ = (sel, root = document) => [...root.querySelectorAll(sel)];
const esc = (s) => String(s ?? '').replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
const uid = () => crypto.randomUUID();
// crypto.randomUUID gibt es nur in sicheren Kontexten (HTTPS/localhost) – die Web-Version läuft oft per http://<server>
const uid = () => (crypto.randomUUID ? crypto.randomUUID() : ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, (c) => (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)));
function h(html) { const t = document.createElement('template'); t.innerHTML = html.trim(); return t.content.firstElementChild; }
const T = I18N.t;
// Web-Version (Docker, src/web): gleiche Oberfläche im Browser; ohne RDP, VPN, Port-Forwarding und lokale Dateien
+11 -2
View File
@@ -67,8 +67,17 @@
// Kanäle, die im Browser selbst erledigt werden
const local = {
'clipboard:write': (t) => navigator.clipboard.writeText(String(t)),
'clipboard:read': () => navigator.clipboard.readText(),
// Ohne HTTPS gibt es navigator.clipboard nicht: Kopieren per execCommand, Einfügen dann nur per Strg+V
'clipboard:write': (t) => {
if (navigator.clipboard && window.isSecureContext) return navigator.clipboard.writeText(String(t));
const ta = Object.assign(document.createElement('textarea'), { value: String(t) });
ta.style.cssText = 'position:fixed;opacity:0';
document.body.append(ta); ta.select(); document.execCommand('copy'); ta.remove();
},
'clipboard:read': () => {
if (navigator.clipboard && window.isSecureContext) return navigator.clipboard.readText();
throw new Error('Pasting from the menu needs HTTPS. Use Ctrl+Shift+V or Ctrl+V instead.');
},
'shell:open': (url) => { if (/^https?:\/\//i.test(url)) window.open(url, '_blank', 'noopener'); },
'vault:export': async () => { downloadText('mrterm-backup.json', JSON.stringify(await remote('vault:exportData', []), null, 2)); return 'mrterm-backup.json'; },
'vault:import': async () => { const f = await pickFile('.json,application/json'); if (!f) return false; return remote('vault:importData', [JSON.parse(f.content)]); },