Fix some things with transclusions, and added a renderWidgets page decoration

pull/1009/head^2
Zef Hemel 2024-08-12 20:12:28 +02:00
parent 40e07dbea0
commit b7c56a8379
8 changed files with 41 additions and 22 deletions

View File

@ -207,11 +207,11 @@ export class DiskSpacePrimitives implements SpacePrimitives {
this.fileListCache = allFiles;
this.fileListCacheTime = performance.now();
console.info(
"Updated file list cache in background:",
allFiles.length,
"files found",
);
// console.info(
// "Updated file list cache in background:",
// allFiles.length,
// "files found",
// );
}).catch((error) => {
if (abortController.signal.aborted) return;

View File

@ -29,6 +29,7 @@ export type PageDecoration = {
prefix?: string;
cssClasses?: string[];
hide?: boolean;
renderWidgets?: boolean; // Defaults to true
};
export type AttachmentMeta = ObjectValue<

View File

@ -25,13 +25,6 @@ export function cleanBlockPlugin() {
}).range(node.from),
);
}
if (
node.name === "Image" &&
!isCursorInRange(state, [node.from, node.to])
) {
widgets.push(invisibleDecoration.range(node.from, node.to));
}
},
});
return Decoration.set(widgets, true);

View File

@ -6,12 +6,12 @@ import {
decoratorStateField,
invisibleDecoration,
isCursorInRange,
shouldRenderWidgets,
} from "./util.ts";
import { MarkdownWidget } from "./markdown_widget.ts";
import { IFrameWidget } from "./iframe_widget.ts";
import { isTemplate } from "../../lib/cheap_yaml.ts";
export function fencedCodePlugin(editor: Client) {
export function fencedCodePlugin(client: Client) {
return decoratorStateField((state: EditorState) => {
const widgets: any[] = [];
syntaxTree(state).iterate({
@ -23,15 +23,15 @@ export function fencedCodePlugin(editor: Client) {
}
const text = state.sliceDoc(from, to);
const [_, lang] = text.match(/^(?:```+|~~~+)(\w+)?/)!;
const codeWidgetCallback = editor.clientSystem.codeWidgetHook
const codeWidgetCallback = client.clientSystem.codeWidgetHook
.codeWidgetCallbacks
.get(lang);
const renderMode = editor.clientSystem.codeWidgetHook.codeWidgetModes
const renderMode = client.clientSystem.codeWidgetHook.codeWidgetModes
.get(
lang,
);
// Only custom render when we have a custom renderer, and the current page is not a template
if (codeWidgetCallback && !isTemplate(state.sliceDoc(0, from))) {
if (codeWidgetCallback && shouldRenderWidgets(client)) {
// We got a custom renderer!
const lineStrings = text.split("\n");
@ -81,8 +81,8 @@ export function fencedCodePlugin(editor: Client) {
const widget = renderMode === "markdown"
? new MarkdownWidget(
from + lineStrings[0].length + 1,
editor,
`widget:${editor.currentPage}:${bodyText}`,
client,
`widget:${client.currentPage}:${bodyText}`,
bodyText,
codeWidgetCallback,
"sb-markdown-widget",
@ -90,7 +90,7 @@ export function fencedCodePlugin(editor: Client) {
: new IFrameWidget(
from + lineStrings[0].length + 1,
to - lineStrings[lineStrings.length - 1].length - 1,
editor,
client,
lineStrings.slice(1, lineStrings.length - 1).join("\n"),
codeWidgetCallback,
);

View File

@ -2,7 +2,12 @@ import type { EditorState, Range } from "@codemirror/state";
import { syntaxTree } from "@codemirror/language";
import { Decoration, WidgetType } from "@codemirror/view";
import { MarkdownWidget } from "./markdown_widget.ts";
import { decoratorStateField } from "./util.ts";
import {
decoratorStateField,
invisibleDecoration,
isCursorInRange,
shouldRenderWidgets,
} from "./util.ts";
import type { Client } from "../client.ts";
import {
isFederationPath,
@ -152,6 +157,9 @@ function parseAlias(
export function inlineContentPlugin(client: Client) {
return decoratorStateField((state: EditorState) => {
const widgets: Range<Decoration>[] = [];
if (!shouldRenderWidgets(client)) {
return Decoration.set([]);
}
syntaxTree(state).iterate({
enter: (node) => {
@ -232,8 +240,12 @@ export function inlineContentPlugin(client: Client) {
client,
),
block: true,
}).range(node.to + 1),
}).range(node.to),
);
if (!isCursorInRange(state, [node.from, node.to])) {
widgets.push(invisibleDecoration.range(node.from, node.to));
}
},
});

View File

@ -5,6 +5,7 @@ import {
decoratorStateField,
invisibleDecoration,
isCursorInRange,
shouldRenderWidgets,
} from "./util.ts";
import { renderMarkdownToHtml } from "../../plugs/markdown/markdown_render.ts";
@ -89,6 +90,8 @@ export function tablePlugin(editor: Client) {
if (name !== "Table") return;
if (isCursorInRange(state, [from, to])) return;
if (!shouldRenderWidgets(editor)) return;
const tableText = state.sliceDoc(from, to);
const lineStrings = tableText.split("\n");

View File

@ -8,6 +8,8 @@ import {
} from "@codemirror/state";
import type { DecorationSet } from "@codemirror/view";
import { Decoration, EditorView, WidgetType } from "@codemirror/view";
import type { Client } from "../client.ts";
type LinkOptions = {
text: string;
href?: string;
@ -16,6 +18,7 @@ type LinkOptions = {
from: number;
callback: (e: MouseEvent) => void;
};
export class LinkWidget extends WidgetType {
constructor(
readonly options: LinkOptions,
@ -172,3 +175,9 @@ export function isCursorInRange(state: EditorState, range: [number, number]) {
* Decoration to simply hide anything.
*/
export const invisibleDecoration = Decoration.replace({});
export function shouldRenderWidgets(client: Client) {
const currentPageMeta = client.ui.viewState.currentPageMeta;
return !currentPageMeta?.tags?.includes("template") &&
currentPageMeta?.pageDecoration?.renderWidgets !== false;
}

View File

@ -15,6 +15,7 @@ Page decorations allow you to “decorate” pages in various fun ways.
* `cssClasses`: (list of strings) Attaches one or more CSS classes the page's `<body>` tag, wiki links, auto complete items and [[Page Picker]] entries for more advanced styling through a [[Space Style]] (see [[#Use case: pimp my page]] for an example).
* `hide` When this is set to `true`, the page will not be shown in [[Page Picker]], [[Meta Picker]], or suggested for completion of [[Links]]. It will otherwise behave as normal - will be [[Plugs/Index|indexed]] and found in [[Live Queries]]. The page can be opened through [[All Pages Picker]], or linked normally when the full name is typed out without completion.
* `disableTOC` (not technically built-in, but a feature of the [[^Library/Core/Widget/Table of Contents]] widget): disable the [[Table of Contents]] for this particular page.
* `renderWidgets`: when set to `false` disables the [[Live Preview]] rendering of elements like [[Transclusions]], [[Live Queries]], [[Live Templates]] for this page.
There are two ways to apply decorations: