Fixes #640
This commit is contained in:
parent
a9ce68860e
commit
8a89d69c22
@ -9,6 +9,7 @@ import {
|
||||
} from "$sb/lib/tree.ts";
|
||||
import { parsePageRef } from "$sb/lib/page.ts";
|
||||
import { Fragment, renderHtml, Tag } from "./html_render.ts";
|
||||
import { encodePageRef } from "$sb/lib/page.ts";
|
||||
|
||||
export type MarkdownRenderOptions = {
|
||||
failOnUnknown?: true;
|
||||
@ -246,11 +247,11 @@ function render(
|
||||
if (aliasNode) {
|
||||
linkText = aliasNode.children![0].text!;
|
||||
}
|
||||
const { page: pageName, anchor } = parsePageRef(ref);
|
||||
const pageRef = parsePageRef(ref);
|
||||
return {
|
||||
name: "a",
|
||||
attrs: {
|
||||
href: `/${pageName}${anchor ? "#" + anchor : ""}`,
|
||||
href: `/${encodePageRef(pageRef)}`,
|
||||
class: "wiki-link",
|
||||
"data-ref": ref,
|
||||
},
|
||||
|
@ -13,7 +13,11 @@ import { FilterOption } from "./types.ts";
|
||||
import { ensureSettingsAndIndex } from "../common/util.ts";
|
||||
import { EventHook } from "../plugos/hooks/event.ts";
|
||||
import { AppCommand } from "./hooks/command.ts";
|
||||
import { PageState, PathPageNavigator } from "./navigator.ts";
|
||||
import {
|
||||
PageState,
|
||||
parsePageRefFromURI,
|
||||
PathPageNavigator,
|
||||
} from "./navigator.ts";
|
||||
|
||||
import { AppViewState, BuiltinSettings } from "./types.ts";
|
||||
|
||||
@ -110,6 +114,7 @@ export class Client {
|
||||
|
||||
// Used by the "wiki link" highlighter to check if a page exists
|
||||
public allKnownPages = new Set<string>();
|
||||
onLoadPageRef: PageRef;
|
||||
|
||||
constructor(
|
||||
private parent: Element,
|
||||
@ -120,6 +125,7 @@ export class Client {
|
||||
}
|
||||
// Generate a semi-unique prefix for the database so not to reuse databases for different space paths
|
||||
this.dbPrefix = "" + simpleHash(window.silverBulletConfig.spaceFolderPath);
|
||||
this.onLoadPageRef = parsePageRefFromURI();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -224,7 +230,7 @@ export class Client {
|
||||
|
||||
setInterval(() => {
|
||||
try {
|
||||
this.syncService.syncFile(`${this.currentPage!}.md`).catch((e: any) => {
|
||||
this.syncService.syncFile(`${this.currentPage}.md`).catch((e: any) => {
|
||||
console.error("Interval sync error", e);
|
||||
});
|
||||
} catch (e: any) {
|
||||
@ -305,7 +311,11 @@ export class Client {
|
||||
let adjustedPosition = false;
|
||||
|
||||
// Was a particular scroll position persisted?
|
||||
if (pageState.scrollTop !== undefined) {
|
||||
if (
|
||||
pageState.scrollTop !== undefined &&
|
||||
!(pageState.scrollTop === 0 &&
|
||||
(pageState.pos !== undefined || pageState.anchor !== undefined))
|
||||
) {
|
||||
setTimeout(() => {
|
||||
console.log("Kicking off scroll to", pageState.scrollTop);
|
||||
this.editorView.scrollDOM.scrollTop = pageState.scrollTop!;
|
||||
@ -592,8 +602,10 @@ export class Client {
|
||||
return localSpacePrimitives;
|
||||
}
|
||||
|
||||
get currentPage(): string | undefined {
|
||||
return this.ui.viewState.currentPage;
|
||||
get currentPage(): string {
|
||||
return this.ui.viewState.currentPage !== undefined
|
||||
? this.ui.viewState.currentPage
|
||||
: this.onLoadPageRef.page; // best effort
|
||||
}
|
||||
|
||||
dispatchAppEvent(name: AppEvent, ...args: any[]): Promise<any[]> {
|
||||
@ -814,7 +826,7 @@ export class Client {
|
||||
}
|
||||
|
||||
const results = await this.dispatchAppEvent(eventName, {
|
||||
pageName: this.currentPage!,
|
||||
pageName: this.currentPage,
|
||||
linePrefix,
|
||||
pos: selection.from,
|
||||
parentNodes,
|
||||
@ -851,7 +863,7 @@ export class Client {
|
||||
async reloadPage() {
|
||||
console.log("Reloading page");
|
||||
clearTimeout(this.saveTimeout);
|
||||
await this.loadPage(this.currentPage!);
|
||||
await this.loadPage(this.currentPage);
|
||||
}
|
||||
|
||||
focus() {
|
||||
@ -889,6 +901,10 @@ export class Client {
|
||||
}
|
||||
|
||||
if (newWindow) {
|
||||
console.log(
|
||||
"Navigating to new page in new window",
|
||||
`${location.origin}/${encodePageRef(pageRef)}`,
|
||||
);
|
||||
const win = window.open(
|
||||
`${location.origin}/${encodePageRef(pageRef)}`,
|
||||
"_blank",
|
||||
|
@ -28,7 +28,7 @@ export function cleanModePlugins(client: Client) {
|
||||
// TODO: Move this logic elsewhere?
|
||||
onCheckboxClick: (pos) => {
|
||||
const clickEvent: ClickEvent = {
|
||||
page: client.currentPage!,
|
||||
page: client.currentPage,
|
||||
altKey: false,
|
||||
ctrlKey: false,
|
||||
metaKey: false,
|
||||
|
@ -55,7 +55,7 @@ export function cleanCommandLinkPlugin(editor: Client) {
|
||||
}
|
||||
// Dispatch click event to navigate there without moving the cursor
|
||||
const clickEvent: ClickEvent = {
|
||||
page: editor.currentPage!,
|
||||
page: editor.currentPage,
|
||||
ctrlKey: e.ctrlKey,
|
||||
metaKey: e.metaKey,
|
||||
altKey: e.altKey,
|
||||
|
@ -215,7 +215,7 @@ export function attachmentExtension(editor: Client) {
|
||||
return;
|
||||
}
|
||||
await editor.space.writeAttachment(
|
||||
resolve(folderName(editor.currentPage!), finalFileName),
|
||||
resolve(folderName(editor.currentPage), finalFileName),
|
||||
new Uint8Array(data),
|
||||
);
|
||||
let attachmentMarkdown = `[${finalFileName}](${encodeURI(finalFileName)})`;
|
||||
|
@ -22,7 +22,7 @@ export class IFrameWidget extends WidgetType {
|
||||
const iframe = createWidgetSandboxIFrame(
|
||||
this.client,
|
||||
this.bodyText,
|
||||
this.codeWidgetCallback(this.bodyText, this.client.currentPage!),
|
||||
this.codeWidgetCallback(this.bodyText, this.client.currentPage),
|
||||
(message) => {
|
||||
switch (message.type) {
|
||||
case "blur":
|
||||
@ -33,7 +33,7 @@ export class IFrameWidget extends WidgetType {
|
||||
|
||||
break;
|
||||
case "reload":
|
||||
this.codeWidgetCallback(this.bodyText, this.client.currentPage!)
|
||||
this.codeWidgetCallback(this.bodyText, this.client.currentPage)
|
||||
.then(
|
||||
(widgetContent: WidgetContent | null) => {
|
||||
if (widgetContent === null) {
|
||||
|
@ -33,7 +33,7 @@ class InlineImageWidget extends WidgetType {
|
||||
toDOM() {
|
||||
const img = document.createElement("img");
|
||||
let url = this.url;
|
||||
url = resolvePath(this.client.currentPage!, url, true);
|
||||
url = resolvePath(this.client.currentPage, url, true);
|
||||
// console.log("Creating DOM", this.url);
|
||||
const cachedImageHeight = this.client.getCachedWidgetHeight(
|
||||
`image:${this.url}`,
|
||||
@ -79,7 +79,7 @@ export function inlineImagesPlugin(client: Client) {
|
||||
const title = imageRexexResult.groups.title;
|
||||
|
||||
if (url.indexOf("://") === -1 && !url.startsWith("/")) {
|
||||
url = resolveAttachmentPath(client.currentPage!, decodeURI(url));
|
||||
url = resolveAttachmentPath(client.currentPage, decodeURI(url));
|
||||
}
|
||||
widgets.push(
|
||||
Decoration.widget({
|
||||
|
@ -37,7 +37,7 @@ export function linkPlugin(client: Client) {
|
||||
|
||||
if (!cleanLink.includes("://")) {
|
||||
cleanLink = resolveAttachmentPath(
|
||||
client.currentPage!,
|
||||
client.currentPage,
|
||||
decodeURI(cleanLink),
|
||||
);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ export function plugLinter(client: Client) {
|
||||
view.state.sliceDoc(),
|
||||
);
|
||||
const results = (await client.dispatchAppEvent("editor:lint", {
|
||||
name: client.currentPage!,
|
||||
name: client.currentPage,
|
||||
tree: tree,
|
||||
} as LintEvent)).flat();
|
||||
return results;
|
||||
|
@ -48,7 +48,7 @@ export class MarkdownWidget extends WidgetType {
|
||||
) {
|
||||
const widgetContent = await this.codeWidgetCallback(
|
||||
this.bodyText,
|
||||
this.client.currentPage!,
|
||||
this.client.currentPage,
|
||||
);
|
||||
activeWidgets.add(this);
|
||||
if (!widgetContent) {
|
||||
@ -79,7 +79,7 @@ export class MarkdownWidget extends WidgetType {
|
||||
translateUrls: (url) => {
|
||||
if (!url.includes("://")) {
|
||||
url = resolveAttachmentPath(
|
||||
this.client.currentPage!,
|
||||
this.client.currentPage,
|
||||
decodeURI(url),
|
||||
);
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ class TableViewWidget extends WidgetType {
|
||||
annotationPositions: true,
|
||||
translateUrls: (url) => {
|
||||
if (!url.includes("://")) {
|
||||
url = resolveAttachmentPath(this.client.currentPage!, decodeURI(url));
|
||||
url = resolveAttachmentPath(this.client.currentPage, decodeURI(url));
|
||||
}
|
||||
|
||||
return url;
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
LinkWidget,
|
||||
} from "./util.ts";
|
||||
import { resolvePath } from "$sb/lib/resolve.ts";
|
||||
import { parsePageRef } from "$sb/lib/page.ts";
|
||||
import { encodePageRef, parsePageRef } from "$sb/lib/page.ts";
|
||||
|
||||
/**
|
||||
* Plugin to hide path prefix when the cursor is not inside.
|
||||
@ -30,10 +30,9 @@ export function cleanWikiLinkPlugin(client: Client) {
|
||||
const [_fullMatch, page, pipePart, alias] = match;
|
||||
|
||||
let pageExists = !client.fullSyncCompleted;
|
||||
let cleanPage = page;
|
||||
cleanPage = parsePageRef(page).page;
|
||||
cleanPage = resolvePath(client.currentPage!, cleanPage);
|
||||
const lowerCasePageName = cleanPage.toLowerCase();
|
||||
const pageRef = parsePageRef(page);
|
||||
pageRef.page = resolvePath(client.currentPage, pageRef.page);
|
||||
const lowerCasePageName = pageRef.page.toLowerCase();
|
||||
for (const pageName of client.allKnownPages) {
|
||||
if (pageName.toLowerCase() === lowerCasePageName) {
|
||||
pageExists = true;
|
||||
@ -41,8 +40,8 @@ export function cleanWikiLinkPlugin(client: Client) {
|
||||
}
|
||||
}
|
||||
if (
|
||||
cleanPage === "" ||
|
||||
client.plugSpaceRemotePrimitives.isLikelyHandled(cleanPage)
|
||||
pageRef.page === "" ||
|
||||
client.plugSpaceRemotePrimitives.isLikelyHandled(pageRef.page)
|
||||
) {
|
||||
// Empty page name with local @anchor use or a link to a page that dynamically generated by a plug
|
||||
pageExists = true;
|
||||
@ -81,9 +80,9 @@ export function cleanWikiLinkPlugin(client: Client) {
|
||||
{
|
||||
text: linkText,
|
||||
title: pageExists
|
||||
? `Navigate to ${cleanPage}`
|
||||
: `Create ${cleanPage}`,
|
||||
href: `/${cleanPage}`,
|
||||
? `Navigate to ${encodePageRef(pageRef)}`
|
||||
: `Create ${pageRef.page}`,
|
||||
href: `/${encodePageRef(pageRef)}`,
|
||||
cssClass: pageExists
|
||||
? "sb-wiki-link-page"
|
||||
: "sb-wiki-link-page-missing",
|
||||
@ -96,7 +95,7 @@ export function cleanWikiLinkPlugin(client: Client) {
|
||||
}
|
||||
// Dispatch click event to navigate there without moving the cursor
|
||||
const clickEvent: ClickEvent = {
|
||||
page: client.currentPage!,
|
||||
page: client.currentPage,
|
||||
ctrlKey: e.ctrlKey,
|
||||
metaKey: e.metaKey,
|
||||
altKey: e.altKey,
|
||||
|
@ -14,7 +14,6 @@ export type PageState = PageRef & {
|
||||
|
||||
export class PathPageNavigator {
|
||||
navigationResolve?: () => void;
|
||||
root: string;
|
||||
indexPage: string;
|
||||
|
||||
openPages = new Map<string, PageState>();
|
||||
@ -22,7 +21,6 @@ export class PathPageNavigator {
|
||||
constructor(
|
||||
private client: Client,
|
||||
) {
|
||||
this.root = "";
|
||||
this.indexPage = cleanPageRef(
|
||||
renderHandlebarsTemplate(client.settings.indexPage, {}, {}),
|
||||
);
|
||||
@ -52,20 +50,20 @@ export class PathPageNavigator {
|
||||
window.history.replaceState(
|
||||
cleanState,
|
||||
"",
|
||||
`${this.root}/${currentState.page}`,
|
||||
`/${currentState.page}`,
|
||||
);
|
||||
console.log("Pushing new state", pageRef);
|
||||
window.history.pushState(
|
||||
pageRef,
|
||||
"",
|
||||
`${this.root}/${pageRef.page}`,
|
||||
`/${pageRef.page}`,
|
||||
);
|
||||
} else {
|
||||
// console.log("Replacing state", pageRef);
|
||||
window.history.replaceState(
|
||||
pageRef,
|
||||
"",
|
||||
`${this.root}/${pageRef.page}`,
|
||||
`/${pageRef.page}`,
|
||||
);
|
||||
}
|
||||
// console.log("Explicitly dispatching the popstate", pageRef);
|
||||
@ -81,7 +79,7 @@ export class PathPageNavigator {
|
||||
}
|
||||
|
||||
buildCurrentPageState(): PageState {
|
||||
const pageState: PageState = this.parseURI();
|
||||
const pageState: PageState = parsePageRefFromURI();
|
||||
const mainSelection = this.client.editorView.state.selection.main;
|
||||
pageState.scrollTop = this.client.editorView.scrollDOM.scrollTop;
|
||||
pageState.selection = {
|
||||
@ -122,7 +120,7 @@ export class PathPageNavigator {
|
||||
} else {
|
||||
// This occurs when the page is loaded completely fresh with no browser history around it
|
||||
// console.log("Got null state so using", this.parseURI());
|
||||
const pageRef = this.parseURI();
|
||||
const pageRef = parsePageRefFromURI();
|
||||
if (!pageRef.page) {
|
||||
pageRef.page = this.indexPage;
|
||||
}
|
||||
@ -141,16 +139,12 @@ export class PathPageNavigator {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
parseURI(): PageRef {
|
||||
const pageRef = parsePageRef(decodeURI(
|
||||
location.pathname.substring(this.root.length + 1),
|
||||
));
|
||||
|
||||
// if (!pageRef.page) {
|
||||
// pageRef.page = this.indexPage;
|
||||
// }
|
||||
|
||||
return pageRef;
|
||||
}
|
||||
}
|
||||
|
||||
export function parsePageRefFromURI(): PageRef {
|
||||
const pageRef = parsePageRef(decodeURI(
|
||||
location.pathname.substring(1),
|
||||
));
|
||||
|
||||
return pageRef;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ import { PageRef } from "$sb/lib/page.ts";
|
||||
export function editorSyscalls(client: Client): SysCallMapping {
|
||||
const syscalls: SysCallMapping = {
|
||||
"editor.getCurrentPage": (): string => {
|
||||
return client.currentPage!;
|
||||
return client.currentPage;
|
||||
},
|
||||
"editor.getText": () => {
|
||||
return client.editorView.state.sliceDoc();
|
||||
|
@ -6,6 +6,9 @@ release.
|
||||
## Edge
|
||||
_The changes below are not yet released “properly”. To them out early, check out [the docs on edge](https://community.silverbullet.md/t/living-on-the-edge-builds/27)._
|
||||
|
||||
* Bug fixes:
|
||||
* Improved Ctrl/Cmd-click (to open links in a new window) behavior: now actually follow `@pos` and `$anchor` links.
|
||||
* Right-clicking links now opens browser native context menu again
|
||||
* Internal changes:
|
||||
* Big refactor: of navigation and browser history, fixed some {[Page: Rename]} bugs along the way
|
||||
* Plugs now can no longer define their own markdown syntax, migrated all plug-specific syntax into the main parser. This should remove a bunch of editor “flashing” especially during sync.
|
||||
@ -118,8 +121,8 @@ _The changes below are not yet released “properly”. To them out early, check
|
||||
---
|
||||
## 0.5.3
|
||||
* Changes to [[Objects]]:
|
||||
* Paragraphs are now indexed, see [[Objects@paragraph]] (thanks to [Ian Shehadeh](https://github.com/silverbulletmd/silverbullet/pull/528))
|
||||
* For consistency, list items are now always indexed as well (whether they contain a [[Tags|tag]] or not) see [[Objects@item]].
|
||||
* Paragraphs are now indexed, see [[Objects$paragraph]] (thanks to [Ian Shehadeh](https://github.com/silverbulletmd/silverbullet/pull/528))
|
||||
* For consistency, list items are now always indexed as well (whether they contain a [[Tags|tag]] or not) see [[Objects$item]].
|
||||
* The {[Directive: Convert to Live Query/Template]} now also converts `#use` and `#include` directives
|
||||
* Styling improvements for Linked Mentions
|
||||
* SilverBullet now fully works when added as PWA on Safari 17 (via the “Add to Dock” option).
|
||||
|
@ -16,6 +16,8 @@ shortcuts:
|
||||
key: "Alt-x"
|
||||
- command: "{[Upload: File]}"
|
||||
priority: 1 # Make sure this appears at the top of the list in the command palette
|
||||
- command: "{[Open Command Palette]}"
|
||||
key: "Ctrl-."
|
||||
|
||||
# Defines files to ignore in a format compatible with .gitignore
|
||||
spaceIgnore: |
|
||||
|
Loading…
Reference in New Issue
Block a user