Zundler/zundler/assets/zundler_common.js
Adrian Vollmer 6648b5e619 Fix fixLinks
Don't touch links starting with `javascript:`
2024-04-22 20:41:34 +02:00

117 lines
3.4 KiB
JavaScript

/*
* Functions that will be needed by several files
*/
var retrieveFile = function(path) {
// console.log("Retrieving file: " + path);
var fileTree = window.globalContext.fileTree;
var file = fileTree[path];
if (!file) {
console.warn("File not found: " + path);
return "";
} else {
return file;
}
};
var isVirtual = function(url) {
// Return true if the url should be retrieved from the virtual file tree
var _url = url.toString().toLowerCase();
return (! (
_url == "" ||
_url[0] == "#" ||
_url.startsWith('https:/') ||
_url.startsWith('http:/') ||
_url.startsWith('data:') ||
_url.startsWith('javascript:') ||
_url.startsWith('about:srcdoc') ||
_url.startsWith('blob:')
));
};
var splitUrl = function(url) {
// Return a list of three elements: path, GET parameters, anchor
var anchor = url.split('#')[1] || "";
var getParameters = url.split('#')[0].split('?')[1] || "";
var path = url.split('#')[0];
path = path.split('?')[0];
let result = [path, getParameters, anchor];
// console.log("Split URL", url, result);
return result;
};
var fixLink = function(a) {
const href = a.getAttribute("href");
if (isVirtual(href)) {
// virtualClick will be defined in the iFrame, but fixLink may be
// called in the parent document, so we use `onclick`, because we
// can define the function as a string
a.setAttribute("onclick", "virtualClick(event)");
} else if (href.startsWith('#')) {
a.setAttribute('href', "about:srcdoc" + a.getAttribute('href'))
} else if (
!href.startsWith('about:srcdoc')
&& !href.startsWith('javascript:')
) {
// External links should open in a new tab. Browsers block links to
// sites of different origin within an iframe for security reasons.
a.setAttribute('target', "_blank");
}
};
var fixForm = function(form) {
var href = form.getAttribute('action');
if (isVirtual(href) && form.getAttribute('method').toLowerCase() == 'get') {
form.setAttribute("onsubmit", "virtualClick(event)");
}
};
var embedImg = function(img) {
if (img.hasAttribute('src')) {
const src = img.getAttribute('src');
if (isVirtual(src)) {
var path = normalizePath(src);
const file = retrieveFile(path);
const mime_type = file.mime_type;
if (mime_type == 'image/svg+xml') {
img.setAttribute('src', "data:image/svg+xml;charset=utf-8;base64, " + btoa(file.data));
} else {
img.setAttribute('src', `data:${mime_type};base64, ${file.data}`);
}
};
};
};
var normalizePath = function(path) {
// make relative paths absolute
var result = window.globalContext.current_path;
result = result.split('/');
result.pop();
result = result.concat(path.split('/'));
// resolve relative directories
var array = [];
Array.from(result).forEach( component => {
if (component == '..') {
if (array) {
array.pop();
}
} else if (component == '.') {
} else {
if (component) { array.push(component); }
}
});
result = array.join('/');
// console.log(`Normalized path: ${path} -> ${result} (@${window.globalContext.current_path})`);
return result;
};