Try to add url_prefix support
parent
8acb112e4e
commit
b1de476116
|
@ -5,6 +5,7 @@ import {
|
||||||
unregisterServiceWorkers,
|
unregisterServiceWorkers,
|
||||||
} from "../sw_util.ts";
|
} from "../sw_util.ts";
|
||||||
import { encodePageURI } from "@silverbulletmd/silverbullet/lib/page_ref";
|
import { encodePageURI } from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||||
|
import { urlPrefix, toRealUrl } from "../../lib/url_hack.ts";
|
||||||
|
|
||||||
const defaultFetchTimeout = 30000; // 30 seconds
|
const defaultFetchTimeout = 30000; // 30 seconds
|
||||||
|
|
||||||
|
@ -38,7 +39,8 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
try {
|
try {
|
||||||
options.signal = AbortSignal.timeout(fetchTimeout);
|
options.signal = AbortSignal.timeout(fetchTimeout);
|
||||||
options.redirect = "manual";
|
options.redirect = "manual";
|
||||||
const result = await fetch(url, options);
|
|
||||||
|
const result = await fetch(toRealUrl(url), options);
|
||||||
if (result.status === 503) {
|
if (result.status === 503) {
|
||||||
throw new Error("Offline");
|
throw new Error("Offline");
|
||||||
}
|
}
|
||||||
|
@ -67,7 +69,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
"Received an authentication redirect, redirecting to URL: " +
|
"Received an authentication redirect, redirecting to URL: " +
|
||||||
redirectHeader,
|
redirectHeader,
|
||||||
);
|
);
|
||||||
location.href = redirectHeader;
|
location.href = redirectHeader.startsWith(urlPrefix) ? redirectHeader : toRealUrl(redirectHeader);
|
||||||
throw new Error("Redirected");
|
throw new Error("Redirected");
|
||||||
} else {
|
} else {
|
||||||
console.error("Got a redirect status but no location header", result);
|
console.error("Got a redirect status but no location header", result);
|
||||||
|
@ -82,7 +84,7 @@ export class HttpSpacePrimitives implements SpacePrimitives {
|
||||||
result.url,
|
result.url,
|
||||||
);
|
);
|
||||||
alert("You are not authenticated, redirecting to: " + redirectHeader);
|
alert("You are not authenticated, redirecting to: " + redirectHeader);
|
||||||
location.href = redirectHeader;
|
location.href = redirectHeader.startsWith(urlPrefix) ? redirectHeader : toRealUrl(redirectHeader);
|
||||||
throw new Error("Not authenticated");
|
throw new Error("Not authenticated");
|
||||||
} else {
|
} else {
|
||||||
// If not, let's reload
|
// If not, let's reload
|
||||||
|
|
|
@ -3,6 +3,7 @@ import type { ControllerMessage, WorkerMessage } from "../protocol.ts";
|
||||||
import type { Plug } from "../plug.ts";
|
import type { Plug } from "../plug.ts";
|
||||||
import { AssetBundle, type AssetJson } from "../../asset_bundle/bundle.ts";
|
import { AssetBundle, type AssetJson } from "../../asset_bundle/bundle.ts";
|
||||||
import type { Sandbox } from "./sandbox.ts";
|
import type { Sandbox } from "./sandbox.ts";
|
||||||
|
import { toRealUrl } from "../../url_hack.ts";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a "safe" execution environment for plug code
|
* Represents a "safe" execution environment for plug code
|
||||||
|
@ -36,7 +37,7 @@ export class WorkerSandbox<HookT> implements Sandbox<HookT> {
|
||||||
console.warn("Double init of sandbox, ignoring");
|
console.warn("Double init of sandbox, ignoring");
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
this.worker = new Worker(this.workerUrl, {
|
this.worker = new Worker(toRealUrl(this.workerUrl), {
|
||||||
...this.workerOptions,
|
...this.workerOptions,
|
||||||
type: "module",
|
type: "module",
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
export const urlPrefix = Deno.env.get('SB_URL_PREFIX') ?? (globalThis.silverBulletConfig ? globalThis.silverBulletConfig.urlPrefix : null) ?? '';
|
||||||
|
|
||||||
|
export const toRealUrl = <T extends (string | URL)>(url : T) : T => {
|
||||||
|
if (typeof url === 'string') {
|
||||||
|
const stringUrl = url as string;
|
||||||
|
if (stringUrl.startsWith('http://') || stringUrl.startsWith('https://')) {
|
||||||
|
const parsedUrl = new URL(stringUrl);
|
||||||
|
parsedUrl.pathname = urlPrefix + parsedUrl.pathname;
|
||||||
|
//console.log("Converted ", url, parsedUrl.href)
|
||||||
|
return String(parsedUrl.href) as T;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!stringUrl.startsWith('/')) {
|
||||||
|
console.log("Don't know how to deal with relative path: ", url);
|
||||||
|
}
|
||||||
|
//console.log("Converted ", url, urlPrefix + stringUrl)
|
||||||
|
return (urlPrefix + stringUrl) as T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (url.protocol === 'http:' || url.protocol === 'https:') {
|
||||||
|
const parsedUrl = new URL(url as URL);
|
||||||
|
parsedUrl.pathname = urlPrefix + parsedUrl.pathname;
|
||||||
|
//console.log("Converted ", url, parsedUrl)
|
||||||
|
return parsedUrl as T;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const toInternalUrl = (url : string) => {
|
||||||
|
if (url.startsWith('http://') || url.startsWith('https://')) {
|
||||||
|
var parsedUrl = new URL(url);
|
||||||
|
if (parsedUrl.pathname.startsWith(urlPrefix)) {
|
||||||
|
parsedUrl.pathname = parsedUrl.pathname.substr(urlPrefix.length);
|
||||||
|
return parsedUrl.href;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
} else if (url.startsWith(urlPrefix)) {
|
||||||
|
return url.substr(urlPrefix.length);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.log("Don't know how to deal with relative path: ", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@ import {
|
||||||
parsePageRef,
|
parsePageRef,
|
||||||
} from "@silverbulletmd/silverbullet/lib/page_ref";
|
} from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||||
import { base64Encode } from "$lib/crypto.ts";
|
import { base64Encode } from "$lib/crypto.ts";
|
||||||
|
import { urlPrefix, toRealUrl } from "$lib/url_hack.ts";
|
||||||
|
|
||||||
const authenticationExpirySeconds = 60 * 60 * 24 * 7; // 1 week
|
const authenticationExpirySeconds = 60 * 60 * 24 * 7; // 1 week
|
||||||
|
|
||||||
|
@ -102,6 +103,9 @@ export class HttpServer {
|
||||||
.replace(
|
.replace(
|
||||||
"{{SPACE_PATH}}",
|
"{{SPACE_PATH}}",
|
||||||
spaceServer.pagesPath.replaceAll("\\", "\\\\"),
|
spaceServer.pagesPath.replaceAll("\\", "\\\\"),
|
||||||
|
).replaceAll(
|
||||||
|
"{{URL_PREFIX}}",
|
||||||
|
urlPrefix
|
||||||
)
|
)
|
||||||
.replace(
|
.replace(
|
||||||
"{{DESCRIPTION}}",
|
"{{DESCRIPTION}}",
|
||||||
|
@ -283,7 +287,7 @@ export class HttpServer {
|
||||||
if (req.method === "GET") {
|
if (req.method === "GET") {
|
||||||
if (assetName === "service_worker.js") {
|
if (assetName === "service_worker.js") {
|
||||||
c.header("Cache-Control", "no-cache");
|
c.header("Cache-Control", "no-cache");
|
||||||
const textData = new TextDecoder().decode(data);
|
const textData = new TextDecoder().decode(data as Uint8Array);
|
||||||
// console.log(
|
// console.log(
|
||||||
// "Swapping out config hash in service worker",
|
// "Swapping out config hash in service worker",
|
||||||
// );
|
// );
|
||||||
|
@ -298,6 +302,12 @@ export class HttpServer {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (assetName.endsWith(".css")) {
|
||||||
|
const textData = new TextDecoder().decode(data as Uint8Array);
|
||||||
|
data = textData.replaceAll(
|
||||||
|
"{{URL_PREFIX}}",
|
||||||
|
urlPrefix);
|
||||||
|
}
|
||||||
return Promise.resolve(c.body(data));
|
return Promise.resolve(c.body(data));
|
||||||
} // else e.g. HEAD, OPTIONS, don't send body
|
} // else e.g. HEAD, OPTIONS, don't send body
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -320,11 +330,15 @@ export class HttpServer {
|
||||||
const url = new URL(c.req.url);
|
const url = new URL(c.req.url);
|
||||||
deleteCookie(c, authCookieName(url.host));
|
deleteCookie(c, authCookieName(url.host));
|
||||||
|
|
||||||
return c.redirect("/.auth");
|
return c.redirect(toRealUrl("/.auth"));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.app.get("/.auth", (c) => {
|
this.app.get("/.auth", (c) => {
|
||||||
const html = this.clientAssetBundle.readTextFileSync(".client/auth.html");
|
const html = this.clientAssetBundle.readTextFileSync(".client/auth.html")
|
||||||
|
.replaceAll(
|
||||||
|
"{{URL_PREFIX}}",
|
||||||
|
urlPrefix
|
||||||
|
);
|
||||||
|
|
||||||
return c.html(html);
|
return c.html(html);
|
||||||
}).post(
|
}).post(
|
||||||
|
@ -336,7 +350,7 @@ export class HttpServer {
|
||||||
!username || typeof username !== "string" ||
|
!username || typeof username !== "string" ||
|
||||||
!password || typeof password !== "string"
|
!password || typeof password !== "string"
|
||||||
) {
|
) {
|
||||||
return c.redirect("/.auth?error=0");
|
return c.redirect(toRealUrl("/.auth?error=0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { username, password };
|
return { username, password };
|
||||||
|
@ -367,14 +381,16 @@ export class HttpServer {
|
||||||
});
|
});
|
||||||
const values = await c.req.parseBody();
|
const values = await c.req.parseBody();
|
||||||
const from = values["from"];
|
const from = values["from"];
|
||||||
return c.redirect(typeof from === "string" ? from : "/");
|
const result = toRealUrl(typeof from === "string" ? from : "/");
|
||||||
|
console.log(result);
|
||||||
|
return c.redirect(result);
|
||||||
} else {
|
} else {
|
||||||
console.error("Authentication failed, redirecting to auth page.");
|
console.error("Authentication failed, redirecting to auth page.");
|
||||||
return c.redirect("/.auth?error=1", 401);
|
return c.redirect(toRealUrl("/.auth?error=1"), 401);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
).all((c) => {
|
).all((c) => {
|
||||||
return c.redirect("/.auth");
|
return c.redirect(toRealUrl("/.auth"));
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check auth
|
// Check auth
|
||||||
|
@ -389,9 +405,9 @@ export class HttpServer {
|
||||||
const redirectToAuth = () => {
|
const redirectToAuth = () => {
|
||||||
// Try filtering api paths
|
// Try filtering api paths
|
||||||
if (req.path.startsWith("/.") || req.path.endsWith(".md")) {
|
if (req.path.startsWith("/.") || req.path.endsWith(".md")) {
|
||||||
return c.redirect("/.auth", 401);
|
return c.redirect(toRealUrl("/.auth"), 401);
|
||||||
} else {
|
} else {
|
||||||
return c.redirect(`/.auth?from=${req.path}`, 401);
|
return c.redirect(toRealUrl(`/.auth?from=${req.path}`), 401);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (!excludedPaths.includes(url.pathname)) {
|
if (!excludedPaths.includes(url.pathname)) {
|
||||||
|
@ -462,7 +478,7 @@ export class HttpServer {
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, redirect to the UI
|
// Otherwise, redirect to the UI
|
||||||
// The reason to do this is to handle authentication systems like Authelia nicely
|
// The reason to do this is to handle authentication systems like Authelia nicely
|
||||||
return c.redirect("/");
|
return c.redirect(toRealUrl("/"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -541,7 +557,7 @@ export class HttpServer {
|
||||||
console.warn(
|
console.warn(
|
||||||
"Request was without X-Sync-Mode nor a CORS request, redirecting to page",
|
"Request was without X-Sync-Mode nor a CORS request, redirecting to page",
|
||||||
);
|
);
|
||||||
return c.redirect(`/${name.slice(0, -mdExt.length)}`);
|
return c.redirect(toRealUrl(`/${name.slice(0, -mdExt.length)}`));
|
||||||
}
|
}
|
||||||
if (name.startsWith(".")) {
|
if (name.startsWith(".")) {
|
||||||
// Don't expose hidden files
|
// Don't expose hidden files
|
||||||
|
|
|
@ -69,11 +69,11 @@
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1>
|
<h1>
|
||||||
Login to <img src="/.client/logo.png" style="height: 1ch" />
|
Login to <img src="{{URL_PREFIX}}/.client/logo.png" style="height: 1ch" />
|
||||||
SilverBullet
|
SilverBullet
|
||||||
</h1>
|
</h1>
|
||||||
</header>
|
</header>
|
||||||
<form action="/.auth" method="POST" id="login">
|
<form action="{{URL_PREFIX}}/.auth" method="POST" id="login">
|
||||||
<div class="error-message"></div>
|
<div class="error-message"></div>
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
|
|
|
@ -88,6 +88,7 @@ declare global {
|
||||||
syncOnly: boolean;
|
syncOnly: boolean;
|
||||||
readOnly: boolean;
|
readOnly: boolean;
|
||||||
enableSpaceScript: boolean;
|
enableSpaceScript: boolean;
|
||||||
|
urlPrefix : string;
|
||||||
};
|
};
|
||||||
// deno-lint-ignore no-var
|
// deno-lint-ignore no-var
|
||||||
var client: Client;
|
var client: Client;
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
name="viewport"
|
name="viewport"
|
||||||
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
/>
|
/>
|
||||||
<base href="/" />
|
<base href="{{URL_PREFIX}}/" />
|
||||||
<link rel="apple-touch-icon" href="/.client/logo.png" />
|
<link rel="apple-touch-icon" href="{{URL_PREFIX}}/.client/logo.png" />
|
||||||
<meta
|
<meta
|
||||||
name="theme-color"
|
name="theme-color"
|
||||||
content="#e1e1e1"
|
content="#e1e1e1"
|
||||||
|
@ -21,7 +21,7 @@
|
||||||
<meta name="referrer" content="no-referrer" />
|
<meta name="referrer" content="no-referrer" />
|
||||||
|
|
||||||
<title>{{TITLE}}</title>
|
<title>{{TITLE}}</title>
|
||||||
<meta property="og:image" content="/.client/logo.png" />
|
<meta property="og:image" content="{{URL_PREFIX}}/.client/logo.png" />
|
||||||
<meta property="og:description" content="{{DESCRIPTION}}" />
|
<meta property="og:description" content="{{DESCRIPTION}}" />
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -55,6 +55,7 @@
|
||||||
syncOnly: "{{SYNC_ONLY}}" === "true",
|
syncOnly: "{{SYNC_ONLY}}" === "true",
|
||||||
enableSpaceScript: "{{ENABLE_SPACE_SCRIPT}}" === "true",
|
enableSpaceScript: "{{ENABLE_SPACE_SCRIPT}}" === "true",
|
||||||
readOnly: "{{READ_ONLY}}" === "true",
|
readOnly: "{{READ_ONLY}}" === "true",
|
||||||
|
urlPrefix: "{{URL_PREFIX}}",
|
||||||
};
|
};
|
||||||
// But in case these variables aren't replaced by the server, fall back sync only mode
|
// But in case these variables aren't replaced by the server, fall back sync only mode
|
||||||
if (window.silverBulletConfig.spaceFolderPath.includes("{{")) {
|
if (window.silverBulletConfig.spaceFolderPath.includes("{{")) {
|
||||||
|
@ -63,14 +64,15 @@
|
||||||
syncOnly: true,
|
syncOnly: true,
|
||||||
readOnly: false,
|
readOnly: false,
|
||||||
enableSpaceScripts: false,
|
enableSpaceScripts: false,
|
||||||
|
urlPrefix: "",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<link rel="stylesheet" href="/.client/main.css" />
|
<link rel="stylesheet" href="{{URL_PREFIX}}/.client/main.css" />
|
||||||
<style id="custom-styles"></style>
|
<style id="custom-styles"></style>
|
||||||
<script type="module" src="/.client/client.js"></script>
|
<script type="module" src="{{URL_PREFIX}}/.client/client.js"></script>
|
||||||
<link rel="manifest" href="/.client/manifest.json" />
|
<link rel="manifest" href="{{URL_PREFIX}}/.client/manifest.json" />
|
||||||
<link rel="icon" type="image/x-icon" href="/.client/favicon.png" />
|
<link rel="icon" type="image/x-icon" href="{{URL_PREFIX}}/.client/favicon.png" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -7,6 +7,7 @@ import type { Client } from "./client.ts";
|
||||||
import { cleanPageRef } from "@silverbulletmd/silverbullet/lib/resolve";
|
import { cleanPageRef } from "@silverbulletmd/silverbullet/lib/resolve";
|
||||||
import { renderTheTemplate } from "$common/syscalls/template.ts";
|
import { renderTheTemplate } from "$common/syscalls/template.ts";
|
||||||
import { safeRun } from "../lib/async.ts";
|
import { safeRun } from "../lib/async.ts";
|
||||||
|
import { toRealUrl, toInternalUrl } from "../lib/url_hack.ts";
|
||||||
|
|
||||||
export type PageState = PageRef & {
|
export type PageState = PageRef & {
|
||||||
scrollTop?: number;
|
scrollTop?: number;
|
||||||
|
@ -61,18 +62,18 @@ export class PathPageNavigator {
|
||||||
globalThis.history.replaceState(
|
globalThis.history.replaceState(
|
||||||
cleanState,
|
cleanState,
|
||||||
"",
|
"",
|
||||||
`/${encodePageURI(currentState.page)}`,
|
toRealUrl(`/${encodePageURI(currentState.page)}`),
|
||||||
);
|
);
|
||||||
globalThis.history.pushState(
|
globalThis.history.pushState(
|
||||||
pageRef,
|
pageRef,
|
||||||
"",
|
"",
|
||||||
`/${encodePageURI(pageRef.page)}`,
|
toRealUrl(`/${encodePageURI(pageRef.page)}`),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
globalThis.history.replaceState(
|
globalThis.history.replaceState(
|
||||||
pageRef,
|
pageRef,
|
||||||
"",
|
"",
|
||||||
`/${encodePageURI(pageRef.page)}`,
|
toRealUrl(`/${encodePageURI(pageRef.page)}`),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
globalThis.dispatchEvent(
|
globalThis.dispatchEvent(
|
||||||
|
@ -148,7 +149,7 @@ export class PathPageNavigator {
|
||||||
|
|
||||||
export function parsePageRefFromURI(): PageRef {
|
export function parsePageRefFromURI(): PageRef {
|
||||||
const pageRef = parsePageRef(decodeURIComponent(
|
const pageRef = parsePageRef(decodeURIComponent(
|
||||||
location.pathname.substring(1),
|
toInternalUrl(location.pathname).substring(1),
|
||||||
));
|
));
|
||||||
|
|
||||||
if (location.hash) {
|
if (location.hash) {
|
||||||
|
|
|
@ -5,28 +5,28 @@
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iA-Mono";
|
font-family: "iA-Mono";
|
||||||
src: url("/.client/iAWriterMonoS-Regular.woff2");
|
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Regular.woff2");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iA-Mono";
|
font-family: "iA-Mono";
|
||||||
src: url("/.client/iAWriterMonoS-Bold.woff2");
|
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Bold.woff2");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iA-Mono";
|
font-family: "iA-Mono";
|
||||||
src: url("/.client/iAWriterMonoS-Italic.woff2");
|
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-Italic.woff2");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iA-Mono";
|
font-family: "iA-Mono";
|
||||||
src: url("/.client/iAWriterMonoS-BoldItalic.woff2");
|
src: url("{{URL_PREFIX}}/.client/iAWriterMonoS-BoldItalic.woff2");
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import type { UploadFile } from "../../plug-api/types.ts";
|
||||||
import type { PageRef } from "@silverbulletmd/silverbullet/lib/page_ref";
|
import type { PageRef } from "@silverbulletmd/silverbullet/lib/page_ref";
|
||||||
import { openSearchPanel } from "@codemirror/search";
|
import { openSearchPanel } from "@codemirror/search";
|
||||||
import { diffAndPrepareChanges } from "../cm_util.ts";
|
import { diffAndPrepareChanges } from "../cm_util.ts";
|
||||||
|
import { toRealUrl, toInternalUrl } from "../../lib/url_hack.ts";
|
||||||
|
|
||||||
export function editorSyscalls(client: Client): SysCallMapping {
|
export function editorSyscalls(client: Client): SysCallMapping {
|
||||||
const syscalls: SysCallMapping = {
|
const syscalls: SysCallMapping = {
|
||||||
|
@ -75,17 +76,17 @@ export function editorSyscalls(client: Client): SysCallMapping {
|
||||||
},
|
},
|
||||||
"editor.openUrl": (_ctx, url: string, existingWindow = false) => {
|
"editor.openUrl": (_ctx, url: string, existingWindow = false) => {
|
||||||
if (!existingWindow) {
|
if (!existingWindow) {
|
||||||
const win = globalThis.open(url, "_blank");
|
const win = globalThis.open(toRealUrl(url), "_blank");
|
||||||
if (win) {
|
if (win) {
|
||||||
win.focus();
|
win.focus();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
location.href = url;
|
location.href = toRealUrl(url);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editor.newWindow": () => {
|
"editor.newWindow": () => {
|
||||||
globalThis.open(
|
globalThis.open(
|
||||||
location.href,
|
toInternalUrl(location.href),
|
||||||
"rnd" + Math.random(),
|
"rnd" + Math.random(),
|
||||||
`width=${globalThis.innerWidth},heigh=${globalThis.innerHeight}`,
|
`width=${globalThis.innerWidth},heigh=${globalThis.innerHeight}`,
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue