dynamically load obsidian scripts from our own index.html

This commit is contained in:
Nystik
2026-05-09 12:23:05 +02:00
parent 1323c28c0c
commit cee5ec6b6e
3 changed files with 52 additions and 17 deletions

View File

@@ -133,7 +133,7 @@ This project is licensed under the [GNU Affero General Public License v3.0](LICE
Ignis is not affiliated with, endorsed by, or associated with Dynalist Inc. or Obsidian.
Ignis is an independently developed interoperability tool. It contains no Obsidian source code, binaries, or assets. No part of Obsidian is distributed, bundled, or included in this repository. Obsidian's own files are not altered, patched, or modified on disk. The shim is loaded before Obsidian at runtime and intercepts API calls in memory.
Ignis is an independently developed interoperability tool. It contains no Obsidian source code, binaries, or assets. No part of Obsidian is distributed, bundled, or included in this repository. Ignis serves its own HTML page that loads the shim layer, then dynamically loads Obsidian's unmodified scripts. Obsidian's own files are never altered, patched, or transformed, either on disk or in transit.
Ignis works by providing a compatibility layer that implements browser-compatible equivalents of the Node.js and Electron APIs that Obsidian depends on. The user must obtain their own licensed copy of Obsidian separately. Ignis has no standalone functionality without it.

29
server/assets/index.html Normal file
View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"/>
<title>Obsidian</title>
<link href="app.css" type="text/css" rel="stylesheet"/>
<link rel="icon" type="image/png" href="favicon.png"/>
<link href="assets/overrides.css" type="text/css" rel="stylesheet"/>
</head>
<body class="theme-dark">
<!-- Ignis shims: must run before any Obsidian code. -->
<script type="text/javascript" src="__IGNIS_UI_SRC__"></script>
<script type="text/javascript" src="__SHIM_LOADER_SRC__"></script>
<!-- Obsidian scripts injected dynamically to avoid touching their files. -->
<script>
(function () {
var scripts = __OBSIDIAN_SCRIPTS__;
for (var i = 0; i < scripts.length; i++) {
var s = document.createElement("script");
s.type = "text/javascript";
s.src = scripts[i];
s.async = false;
document.body.appendChild(s);
}
})();
</script>
</body>
</html>

View File

@@ -82,30 +82,36 @@ app.use("/vault-files", (req, res, next) => {
express.static(vaultPath)(req, res, next);
});
// Serve index.html with ignis scripts injected in-flight (no files modified on disk)
// Serve our own index.html. Obsidian's scripts are discovered at startup
// and injected dynamically by the client -- no Obsidian files are read or
// transformed in the response.
let cachedHtml = null;
function getInjectedHtml() {
function buildIndexHtml() {
if (cachedHtml) {
return cachedHtml;
}
const htmlPath = path.join(config.obsidianAssetsPath, "index.html");
let html = fs.readFileSync(htmlPath, "utf-8");
const version = getVersion();
html = html.replace(
"</head>",
' <link rel="icon" type="image/png" href="favicon.png">\n</head>',
);
// Discover Obsidian's script tags from their index.html
const obsidianHtmlPath = path.join(config.obsidianAssetsPath, "index.html");
const obsidianHtml = fs.readFileSync(obsidianHtmlPath, "utf-8");
const scriptRegex = /<script[^>]+src="([^"]+)"[^>]*>/g;
const scripts = [];
let match;
html = html.replace(
'<script type="text/javascript"',
`<script type="text/javascript" src="ignis-ui.js?v=${version}"></script>\n` +
`<script type="text/javascript" src="shim-loader.js?v=${version}"></script>\n` +
'<script type="text/javascript"',
);
while ((match = scriptRegex.exec(obsidianHtml)) !== null) {
scripts.push(match[1]);
}
// Build from our own template
const templatePath = path.join(__dirname, "assets", "index.html");
let html = fs.readFileSync(templatePath, "utf-8");
html = html.replace("__IGNIS_UI_SRC__", `ignis-ui.js?v=${version}`);
html = html.replace("__SHIM_LOADER_SRC__", `shim-loader.js?v=${version}`);
html = html.replace("__OBSIDIAN_SCRIPTS__", JSON.stringify(scripts));
cachedHtml = html;
return cachedHtml;
@@ -114,7 +120,7 @@ function getInjectedHtml() {
app.get(["/", "/index.html"], (req, res) => {
res.set("Content-Type", "text/html; charset=utf-8");
res.set("Cache-Control", "no-cache");
res.send(getInjectedHtml());
res.send(buildIndexHtml());
});
app.get("/favicon.png", (req, res) => {