fix (embed): migrate embed to fastboot

This commit is contained in:
MickaelK 2025-09-02 22:36:19 +10:00
parent 3d571b7a08
commit 11c4a74f97
9 changed files with 122 additions and 97 deletions

View file

@ -11,7 +11,7 @@ window.bundler = (function(origin) {
); );
code = code.replace(/(?<!["])\bimport\.meta\.url\b(?!["])/g, `"${origin + path}"`); code = code.replace(/(?<!["])\bimport\.meta\.url\b(?!["])/g, `"${origin + path}"`);
code += `\n//# sourceURL=${path}`; code += `\n//# sourceURL=${path}`;
esModules[path] = "data:text/javascript," + encodeURIComponent(code); esModules[origin + path] = "data:text/javascript," + encodeURIComponent(code);
} else if (path.endsWith(".css")) { } else if (path.endsWith(".css")) {
code = code.replace(/@import url\("([^"]+)"\);/g, (m, rel) => { code = code.replace(/@import url\("([^"]+)"\);/g, (m, rel) => {
const $style = document.head.querySelector(`style[id="${new URL(rel, origin + path).href}"]`); const $style = document.head.querySelector(`style[id="${new URL(rel, origin + path).href}"]`);

View file

@ -143,35 +143,6 @@ select:-moz-focusring {
scrollbar-track-color: rgba(0, 0, 0, .1); scrollbar-track-color: rgba(0, 0, 0, .1);
} }
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(../fonts/SourceCodePro-Regular-400-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(../fonts/SourceCodePro-Regular-400-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local('Source Code Pro Semibold'), local('SourceCodePro-Semibold'), url(../fonts/SourceCodePro-Semibold-600-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(../fonts/SourceCodePro-Semibold-600-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* skip link */ /* skip link */
body > a[aria-role="navigation"] { body > a[aria-role="navigation"] {
position: absolute; position: absolute;

View file

@ -1,9 +1,3 @@
import { init as initConfig, getVersion, get } from "../model/config.js";
const DEBOUNCETIME = 100;
await initConfig();
class FilestashImage extends HTMLElement { class FilestashImage extends HTMLElement {
constructor() { constructor() {
super(); super();
@ -31,7 +25,7 @@ class FilestashImage extends HTMLElement {
type: "refresh", type: "refresh",
payload: { name: this.getAttribute("name"), src: this.getAttribute("src") }, payload: { name: this.getAttribute("name"), src: this.getAttribute("src") },
}, "*"); }, "*");
}, DEBOUNCETIME); }, 100);
} }
} }
@ -43,7 +37,6 @@ class FilestashImage extends HTMLElement {
connectedCallback() { connectedCallback() {
const src = this.getAttribute("src") || ""; const src = this.getAttribute("src") || "";
const name = this.getAttribute("name") || "main.dat"; const name = this.getAttribute("name") || "main.dat";
const mime = get("mime", {})[name.split(".").pop().toLowerCase()];
this.style.display = "inline-block"; this.style.display = "inline-block";
this.iframe.srcdoc = `<!DOCTYPE html> this.iframe.srcdoc = `<!DOCTYPE html>
@ -84,32 +77,45 @@ class FilestashImage extends HTMLElement {
</script> </script>
<script type="module" defer> <script type="module" defer>
import { render } from "${import.meta.url}/../../${getVersion()}/index.js"; const [{ version, mimes }] = await Promise.all([
import * as Application from "${import.meta.url}/../../${getVersion()}/pages/viewerpage/application_image.js"; fetch("${import.meta.url}/../../../api/config").then(async (resp) => {
import { init as initCache } from "${import.meta.url}/../../${getVersion()}/pages/filespage/cache.js"; if (!resp.ok) return "na";
const { result } = await resp.json();
return { version: result.version, mimes: result.mime };
}),
import("${import.meta.url}/../../boot/bundler_init.js").then(async () => {
await new Promise((resolve, reject) => document.head.appendChild(Object.assign(document.createElement("script"), {
type: "module",
src: new URL("../bundle.js", "${import.meta.url}"),
onload: resolve,
onerror: reject,
})));
await import("${import.meta.url}/../../boot/bundler_complete.js");
}),
]);
await initCache(); const { render } = await import("${import.meta.url}/../../"+ version +"/index.js");
const Application = await import("${import.meta.url}/../../"+ version +"/pages/viewerpage/application_image.js");
const $app = document.querySelector("#app"); const $app = document.querySelector("#app");
render(Application, $app, { const mime = mimes["${name}".split(".").pop().toLowerCase()];
mime: "${mime}", render(Application, $app, {
hasMenubar: true, mime: mime,
getFilename: () => "${name}", hasMenubar: true,
getDownloadUrl: () => "${src}", getFilename: () => "${name}",
}); getDownloadUrl: () => "${src}",
window.addEventListener("message", (event) => { });
if(event.data.type === "refresh") { window.addEventListener("message", (event) => {
if(event.data.type !== "refresh") return;
render(Application, $app, { render(Application, $app, {
mime: "${mime}", mime: mime,
hasMenubar: true, hasMenubar: true,
getFilename: () => event.data.payload.name, getFilename: () => event.data.payload.name,
getDownloadUrl: () => event.data.payload.src, getDownloadUrl: () => event.data.payload.src,
}); });
} });
});
</script> </script>
<script type="module" src="${import.meta.url}/../../${getVersion()}/components/modal.js"></script>
<component-modal></component-modal> <component-modal></component-modal>
</body> </body>
</html>`; </html>`;

View file

@ -1,9 +1,3 @@
import { init as initConfig, getVersion } from "../model/config.js";
const DEBOUNCETIME = 100;
await initConfig();
class FilestashMap extends HTMLElement { class FilestashMap extends HTMLElement {
constructor() { constructor() {
super(); super();
@ -30,7 +24,7 @@ class FilestashMap extends HTMLElement {
type: "refresh", type: "refresh",
payload: { name: this.getAttribute("name"), src: this.getAttribute("src") }, payload: { name: this.getAttribute("name"), src: this.getAttribute("src") },
}, "*"); }, "*");
}, DEBOUNCETIME); }, 100);
} }
} }
@ -41,12 +35,7 @@ class FilestashMap extends HTMLElement {
connectedCallback() { connectedCallback() {
const src = this.getAttribute("src") || ""; const src = this.getAttribute("src") || "";
const name = this.getAttribute("name") || "main.dbf"; const name = this.getAttribute("name") || "main.dat";
const mime = {
"geojson": "application/geo+json",
"shp": "application/vnd.shp",
"wms": "application/vnd.ogc.wms_xml",
}[name.split(".").pop().toLowerCase()];
this.style.display = "inline-block"; this.style.display = "inline-block";
this.iframe.srcdoc = `<!DOCTYPE html> this.iframe.srcdoc = `<!DOCTYPE html>
@ -87,29 +76,45 @@ class FilestashMap extends HTMLElement {
</script> </script>
<script type="module" defer> <script type="module" defer>
import { render } from "${import.meta.url}/../../${getVersion()}/index.js"; const [{ version, mimes }] = await Promise.all([
import * as Application from "${import.meta.url}/../../${getVersion()}/pages/viewerpage/application_map.js"; fetch("${import.meta.url}/../../../api/config").then(async (resp) => {
if (!resp.ok) return "na";
const { result } = await resp.json();
return { version: result.version, mimes: result.mime };
}),
import("${import.meta.url}/../../boot/bundler_init.js").then(async () => {
await new Promise((resolve, reject) => document.head.appendChild(Object.assign(document.createElement("script"), {
type: "module",
src: new URL("../bundle.js", "${import.meta.url}"),
onload: resolve,
onerror: reject,
})));
await import("${import.meta.url}/../../boot/bundler_complete.js");
}),
]);
const $app = document.querySelector("#app"); const { render } = await import("${import.meta.url}/../../"+ version +"/index.js");
render(Application, $app, { const Application = await import("${import.meta.url}/../../"+ version +"/pages/viewerpage/application_map.js");
mime: "${mime}",
hasMenubar: true, const $app = document.querySelector("#app");
getFilename: () => "${name}", const mime = mimes["${name}".split(".").pop().toLowerCase()];
getDownloadUrl: () => "${src}", render(Application, $app, {
}); mime: mime,
window.addEventListener("message", (event) => { hasMenubar: true,
if(event.data.type === "refresh") { getFilename: () => "${name}",
getDownloadUrl: () => "${src}",
});
window.addEventListener("message", (event) => {
if(event.data.type !== "refresh") return;
render(Application, $app, { render(Application, $app, {
mime: "${mime}", mime: mime,
hasMenubar: true, hasMenubar: true,
getFilename: () => event.data.payload.name, getFilename: () => event.data.payload.name,
getDownloadUrl: () => event.data.payload.src, getDownloadUrl: () => event.data.payload.src,
}); });
} });
});
</script> </script>
<script type="module" src="${import.meta.url}/../../${getVersion()}/components/modal.js"></script>
<component-modal></component-modal> <component-modal></component-modal>
</body> </body>
</html>`; </html>`;

View file

@ -75,14 +75,28 @@ class FilestashTable extends HTMLElement {
}); });
</script> </script>
<script type="module" defer> <script type="module" defer>
import { init as initConfig, getVersion, get } from "${import.meta.url}/../../model/config.js"; const [{ version, mimes }] = await Promise.all([
fetch("${import.meta.url}/../../../api/config").then(async (resp) => {
if (!resp.ok) return "na";
const { result } = await resp.json();
return { version: result.version, mimes: result.mime };
}),
import("${import.meta.url}/../../boot/bundler_init.js").then(async () => {
await new Promise((resolve, reject) => document.head.appendChild(Object.assign(document.createElement("script"), {
type: "module",
src: new URL("../bundle.js", "${import.meta.url}"),
onload: resolve,
onerror: reject,
})));
await import("${import.meta.url}/../../boot/bundler_complete.js");
}),
]);
await initConfig(); const { render } = await import("${import.meta.url}/../../"+ version +"/index.js");
const { render } = await import("${import.meta.url}/../../"+ getVersion() +"/index.js"); const Application = await import("${import.meta.url}/../../"+ version +"/pages/viewerpage/application_table.js");
const Application = await import("${import.meta.url}/../../"+ getVersion() +"/pages/viewerpage/application_table.js");
const $app = document.querySelector("#app"); const $app = document.querySelector("#app");
const mime = get("mime", {})["${name}".split(".").pop().toLowerCase()]; const mime = mimes["${name}".split(".").pop().toLowerCase()];
render(Application, $app, { render(Application, $app, {
mime: mime, mime: mime,
hasMenubar: true, hasMenubar: true,
@ -90,14 +104,13 @@ class FilestashTable extends HTMLElement {
getDownloadUrl: () => "${src}", getDownloadUrl: () => "${src}",
}); });
window.addEventListener("message", (event) => { window.addEventListener("message", (event) => {
if(event.data.type === "refresh") { if(event.data.type !== "refresh") return;
render(Application, $app, { render(Application, $app, {
mime: mime, mime: mime,
hasMenubar: true, hasMenubar: true,
getFilename: () => event.data.payload.name, getFilename: () => event.data.payload.name,
getDownloadUrl: () => event.data.payload.src, getDownloadUrl: () => event.data.payload.src,
}); });
}
}); });
</script> </script>

View file

@ -221,6 +221,7 @@ export async function init() {
const setup_cache = () => { const setup_cache = () => {
cache = new InMemoryCache(); cache = new InMemoryCache();
if (!("indexedDB" in window)) return; if (!("indexedDB" in window)) return;
else if (window.self !== window.top) return;
cache = assert.truthy(new IndexDBCache()); cache = assert.truthy(new IndexDBCache());
return cache.db.catch((err) => { return cache.db.catch((err) => {

View file

@ -98,6 +98,34 @@
font-size: 16px; font-size: 16px;
font-family: "Source Code Pro", monospace; font-family: "Source Code Pro", monospace;
} }
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(../../fonts/SourceCodePro-Regular-400-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(../../fonts/SourceCodePro-Regular-400-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local('Source Code Pro Semibold'), local('SourceCodePro-Semibold'), url(../../fonts/SourceCodePro-Semibold-600-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(../../fonts/SourceCodePro-Semibold-600-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
.cm-s-default .cm-header { .cm-s-default .cm-header {
font-size: 18px; font-size: 18px;

View file

@ -44,7 +44,7 @@
src: `./assets/bundle.js?version=${window.VERSION}`, src: `./assets/bundle.js?version=${window.VERSION}`,
onload: resolve, onload: resolve,
onerror: reject, onerror: reject,
}))) })));
{{ load_asset "assets/boot/bundler_complete.js" }} {{ load_asset "assets/boot/bundler_complete.js" }}
} catch (err) { console.error(err); } } catch (err) { console.error(err); }

View file

@ -376,6 +376,7 @@ func ServeBundle() func(*App, http.ResponseWriter, *http.Request) {
"/assets/" + BUILD_REF + "/pages/viewerpage/model_files.js", "/assets/" + BUILD_REF + "/pages/viewerpage/model_files.js",
"/assets/" + BUILD_REF + "/pages/viewerpage/common.js", "/assets/" + BUILD_REF + "/pages/viewerpage/common.js",
"/assets/" + BUILD_REF + "/pages/viewerpage/application_downloader.js", "/assets/" + BUILD_REF + "/pages/viewerpage/application_downloader.js",
"/assets/" + BUILD_REF + "/pages/viewerpage/application_downloader.css",
"/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.js", "/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.js",
"/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.css", "/assets/" + BUILD_REF + "/pages/viewerpage/component_menubar.css",
} }