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