/* global window, document */ (function () { 'use strict'; function getServiceUrl(el) { var url = el.getAttribute('data-service-url') || ''; url = (url || '').trim(); if (!url) return ''; // strip trailing slashes return url.replace(/\/+$/, ''); } function getServiceToken(el) { var token = el.getAttribute('data-service-token') || ''; return (token || '').trim(); } function pingOpenViaImage(el, rawPath) { var baseUrl = getServiceUrl(el); if (!baseUrl) return; var token = getServiceToken(el); var url = baseUrl + '/open?path=' + encodeURIComponent(rawPath); if (token) url += '&token=' + encodeURIComponent(token); // Fire-and-forget without CORS. try { var img = new window.Image(); img.src = url; } catch (e) { // ignore } } function openViaService(el, rawPath) { var baseUrl = getServiceUrl(el); if (!baseUrl) return Promise.reject(new Error('No opener service configured')); var headers = { 'Content-Type': 'application/json' }; var token = getServiceToken(el); if (token) headers['X-Filetools-Token'] = token; return window.fetch(baseUrl + '/open', { method: 'POST', mode: 'cors', credentials: 'omit', headers: headers, body: JSON.stringify({ path: rawPath }) }).then(function (res) { if (!res.ok) { return res.json().catch(function () { return null; }).then(function (body) { var msg = (body && body.message) ? body.message : ('HTTP ' + res.status); throw new Error(msg); }); } return res.json().catch(function () { return { ok: true }; }); }); } function normalizeToFileUrl(path) { if (!path) return ''; // already a file URL if (/^file:\/\//i.test(path)) return path; // UNC path: \\server\share\path if (/^\\\\/.test(path)) { var p = path.replace(/^\\\\/, ''); p = p.replace(/\\/g, '/'); return 'file://///' + p; } // Windows drive: C:\path\to\file if (/^[a-zA-Z]:\\/.test(path)) { var drive = path[0].toUpperCase(); var rest = path.slice(2).replace(/\\/g, '/'); return 'file:///' + drive + ':' + rest; } // POSIX absolute: /home/user/file if (path[0] === '/') { return 'file://' + path; } // Fall back to using the provided string. return path; } function onClick(event) { var el = event.target; if (!el || !el.classList || !el.classList.contains('filetools-open')) return; var raw = el.getAttribute('data-path') || ''; if (!raw) return; // Prefer local opener service. openViaService(el, raw) .catch(function (err) { // If the browser blocks the request before it reaches localhost (mixed-content, // extensions, stricter CORS handling), fall back to a no-CORS GET ping. pingOpenViaImage(el, raw); // Fallback to old behavior (often blocked in modern browsers). var url = normalizeToFileUrl(raw); if (!url) return; console.warn('Local opener service failed, falling back to file:// navigation:', err); try { window.open(url, '_blank', 'noopener'); } catch (e) { try { window.location.href = url; } catch (e2) { console.error('Failed to open file URL:', e2); } } }); } document.addEventListener('click', onClick, false); })();