pull/483/head
Zef Hemel 2023-07-27 17:02:53 +02:00
parent 4ba11ac66c
commit 804d87436c
7 changed files with 60 additions and 40 deletions

View File

@ -166,7 +166,6 @@ export const Attribute: MarkdownConfig = {
return -1; return -1;
} }
const [fullMatch, attributeName, attributeColon] = match; const [fullMatch, attributeName, attributeColon] = match;
const attributeValueStart = pos + fullMatch.length;
let bracketNestingDepth = 1; let bracketNestingDepth = 1;
let valueLength = fullMatch.length; let valueLength = fullMatch.length;
loopLabel: loopLabel:

View File

@ -32,15 +32,19 @@ export class HttpSpacePrimitives implements SpacePrimitives {
"Got a redirect via the API so will redirect to URL", "Got a redirect via the API so will redirect to URL",
result.url, result.url,
); );
alert("You are not authenticated, redirecting to login page...");
location.href = result.url; location.href = result.url;
throw new Error("Not authenticated"); throw new Error("Not authenticated");
} }
return result; return result;
} catch (e: any) { } catch (e: any) {
// Firefox: NetworkError when attempting to fetch resource (with SW and without) // Errors when there is no internet connection:
// Safari: FetchEvent.respondWith received an error: TypeError: Load failed (service worker) //
// Safari: Load failed (no service worker) // * Firefox: NetworkError when attempting to fetch resource (with SW and without)
// Chrome: Failed to fetch (with service worker and without) // * Safari (service worker enabled): FetchEvent.respondWith received an error: TypeError: Load failed
// * Safari (no service worker): Load failed
// * Chrome: Failed to fetch
//
// Common substrings: "fetch" "load failed" // Common substrings: "fetch" "load failed"
const errorMessage = e.message.toLowerCase(); const errorMessage = e.message.toLowerCase();
if ( if (

View File

@ -31,6 +31,10 @@ functions:
command: command:
name: "Editor: Center Cursor" name: "Editor: Center Cursor"
key: "Ctrl-Alt-l" key: "Ctrl-Alt-l"
moveToPos:
path: "./editor.ts:moveToPosCommand"
command:
name: "Editor: Move Cursor to Position"
clearPageIndex: clearPageIndex:
path: "./page.ts:clearPageIndex" path: "./page.ts:clearPageIndex"
events: events:

View File

@ -42,3 +42,12 @@ export async function centerCursorCommand() {
const pos = await editor.getCursor(); const pos = await editor.getCursor();
await editor.moveCursor(pos, true); await editor.moveCursor(pos, true);
} }
export async function moveToPosCommand() {
const posString = await editor.prompt("Move to position:");
if (!posString) {
return;
}
const pos = +posString;
await editor.moveCursor(pos);
}

View File

@ -13,14 +13,7 @@ import {
import { events } from "$sb/plugos-syscall/mod.ts"; import { events } from "$sb/plugos-syscall/mod.ts";
import { import { findNodeOfType, traverseTree } from "$sb/lib/tree.ts";
addParentPointers,
findNodeOfType,
ParseTree,
renderToText,
replaceNodesMatching,
traverseTree,
} from "$sb/lib/tree.ts";
import { applyQuery } from "$sb/lib/query.ts"; import { applyQuery } from "$sb/lib/query.ts";
import { extractFrontmatter } from "$sb/lib/frontmatter.ts"; import { extractFrontmatter } from "$sb/lib/frontmatter.ts";
import { invokeFunction } from "$sb/silverbullet-syscall/system.ts"; import { invokeFunction } from "$sb/silverbullet-syscall/system.ts";
@ -37,6 +30,7 @@ export type BacklinkEntry = {
name: string; name: string;
alias?: string; alias?: string;
inDirective?: boolean; inDirective?: boolean;
asTemplate?: boolean;
}; };
export async function indexLinks({ name, tree }: IndexTreeEvent) { export async function indexLinks({ name, tree }: IndexTreeEvent) {
const backLinks: { key: string; value: BacklinkEntry }[] = []; const backLinks: { key: string; value: BacklinkEntry }[] = [];
@ -65,6 +59,29 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
traverseTree(tree, (n): boolean => { traverseTree(tree, (n): boolean => {
if (n.type === "DirectiveStart") { if (n.type === "DirectiveStart") {
directiveDepth++; directiveDepth++;
const pageRef = findNodeOfType(n, "PageRef")!;
if (pageRef) {
const pageRefName = pageRef.children![0].text!.slice(2, -2);
backLinks.push({
key: `${backlinkPrefix}${pageRefName}:${pageRef.from! + 2}`,
value: { name, asTemplate: true },
});
}
const directiveText = n.children![0].text;
// #use or #import
if (directiveText) {
const match = /\[\[(.+)\]\]/.exec(directiveText);
if (match) {
const pageRefName = match[1];
backLinks.push({
key: `${backlinkPrefix}${pageRefName}:${
n.from! + match.index! + 2
}`,
value: { name, asTemplate: true },
});
}
}
return true; return true;
} }
if (n.type === "DirectiveStop") { if (n.type === "DirectiveStop") {
@ -94,7 +111,7 @@ export async function indexLinks({ name, tree }: IndexTreeEvent) {
} }
return false; return false;
}); });
// console.log("Found", backLinks.length, "wiki link(s)"); // console.log("Found", backLinks.length, "page link(s)");
await index.batchSet(name, backLinks); await index.batchSet(name, backLinks);
} }
@ -118,6 +135,9 @@ export async function linkQueryProvider({
if (!blEntry.inDirective) { if (!blEntry.inDirective) {
blEntry.inDirective = false; blEntry.inDirective = false;
} }
if (!blEntry.asTemplate) {
blEntry.asTemplate = false;
}
links.push({ ...blEntry, pos }); links.push({ ...blEntry, pos });
} }
return applyQuery(query, links); return applyQuery(query, links);
@ -247,29 +267,14 @@ export async function renamePage(cmdDef: any) {
// Page likely does not exist, but at least we can skip it // Page likely does not exist, but at least we can skip it
continue; continue;
} }
const mdTree = await markdown.parseMarkdown(text);
addParentPointers(mdTree); const newText = text.replaceAll(`[[${oldName}]]`, () => {
// The links in the page are going to be relative pointers to the old name
replaceNodesMatching(mdTree, (n): ParseTree | undefined | null => {
if (n.type === "WikiLinkPage") {
const pageName = n.children![0].text!;
if (pageName === oldName) {
n.children![0].text = newName;
updatedReferences++; updatedReferences++;
return n; return `[[${newName}]]`;
} }).replaceAll(`[[${oldName}@`, () => {
// page name with @pos position
if (pageName.startsWith(`${oldName}@`)) {
const [, pos] = pageName.split("@");
n.children![0].text = `${newName}@${pos}`;
updatedReferences++; updatedReferences++;
return n; return `[[${newName}@`;
}
}
return;
}); });
// let newText = text.replaceAll(`[[${oldName}]]`, `[[${newName}]]`);
const newText = renderToText(mdTree);
if (text !== newText) { if (text !== newText) {
console.log("Changes made, saving..."); console.log("Changes made, saving...");
await space.writePage(pageToUpdate, newText); await space.writePage(pageToUpdate, newText);

View File

@ -428,8 +428,7 @@ export class Client {
); );
} }
progressTimeout?: number; private progressTimeout?: number;
showProgress(progressPerc: number) { showProgress(progressPerc: number) {
this.ui.viewDispatch({ this.ui.viewDispatch({
type: "set-progress", type: "set-progress",
@ -714,7 +713,7 @@ export class Client {
} }
async loadCustomStyles() { async loadCustomStyles() {
if (this.settings?.customStyles) { if (this.settings.customStyles) {
try { try {
const { text: stylesText } = await this.space.readPage( const { text: stylesText } = await this.space.readPage(
this.settings?.customStyles, this.settings?.customStyles,

View File

@ -43,7 +43,7 @@ self.addEventListener("install", (event: any) => {
}); });
self.addEventListener("activate", (event: any) => { self.addEventListener("activate", (event: any) => {
console.log("[Service worker]", "Activating new service worker!!!"); console.log("[Service worker]", "Activating new service worker!");
event.waitUntil( event.waitUntil(
(async () => { (async () => {
const cacheNames = await caches.keys(); const cacheNames = await caches.keys();