Set favicon from iframe

This commit is contained in:
Adrian Vollmer 2022-10-04 17:31:04 +02:00
parent 511ec5c0bb
commit de52a5d504
3 changed files with 56 additions and 2 deletions

View File

@ -22,6 +22,24 @@ var _base64ToArrayBuffer = function (base64) {
return bytes.buffer;
};
var set_favicon = function(href) {
var favicon = document.createElement("link");
favicon.setAttribute('rel', 'shortcut icon');
href = normalize_path(href);
const file = window.global_context.file_tree[href];
if (file.mime_type == 'image/svg+xml') {
favicon.setAttribute('href', 'data:' + file.mime_type + ';charset=utf-8;base64,' + btoa(file.data));
favicon.setAttribute('type', file.mime_type);
} else {
if (file.base64encoded) {
favicon.setAttribute('href', 'data:' + file.mime_type + ';base64,' + file.data);
}
}
document.head.appendChild(favicon);
};
var createIframe = function() {
var iframe = document.getElementById(iFrameId);
if (iframe) { iframe.remove() };
@ -46,6 +64,35 @@ var load_virtual_page = (function (path, get_params, anchor) {
window.history.pushState({path, get_params, anchor}, '', '#');
});
var normalize_path = function(path) {
// TODO remove redundant definition of this function (in inject.js)
// make relative paths absolute
var result = window.global_context.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.global_context.current_path})`);
return result;
};
window.onload = function() {
// Set up the virtual file tree
var FT = window.global_context.file_tree;
@ -61,7 +108,8 @@ window.onload = function() {
if (evnt.data.action == 'set_title') {
// iframe has finished loading and sent us its title
// parent sets the title and responds with the global_context object
window.document.title = evnt.data.argument;
window.document.title = evnt.data.argument.title;
set_favicon(evnt.data.argument.favicon);
var iframe = document.getElementById(iFrameId);
iframe.contentWindow.postMessage({
action: "set_data",

View File

@ -228,5 +228,8 @@ const observer = new MutationObserver((mutationList) => {
// Set parent window title and trigger data transmission
window.parent.postMessage({
action: "set_title",
argument: window.document.querySelector('head>title').innerText
argument: {
title: window.document.querySelector('head>title').innerText,
favicon: document.querySelector("link[rel*='icon']").getAttribute('href')
}
}, '*');

View File

@ -108,6 +108,7 @@ def prepare_file(filename, before, after):
ext = ext.lower()[1:]
data = open(filename, 'rb').read()
mime_type = mime_type_from_bytes(data)
base64encoded = False
if ext == 'css':
# assuming all CSS files have names ending in '.css'
@ -118,6 +119,7 @@ def prepare_file(filename, before, after):
]:
# JSON doesn't allow binary data
data = base64.b64encode(data)
base64encoded = True
elif ext in ['html', 'htm']:
data = embed_html_resources(
@ -138,6 +140,7 @@ def prepare_file(filename, before, after):
result = {
'data': data,
'mime_type': mime_type,
'base64encoded': base64encoded,
}
return result