1
0
This commit is contained in:
Zef Hemel 2024-01-24 14:44:39 +01:00
parent a9ce68860e
commit 8a89d69c22
16 changed files with 69 additions and 54 deletions

View File

@ -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,
},

View File

@ -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",

View File

@ -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,

View File

@ -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,

View File

@ -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)})`;

View File

@ -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) {

View File

@ -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({

View File

@ -37,7 +37,7 @@ export function linkPlugin(client: Client) {
if (!cleanLink.includes("://")) {
cleanLink = resolveAttachmentPath(
client.currentPage!,
client.currentPage,
decodeURI(cleanLink),
);
}

View File

@ -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;

View File

@ -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),
);
}

View File

@ -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;

View File

@ -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,

View File

@ -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;
}

View File

@ -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();

View File

@ -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).

View File

@ -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: |