Fix some things with transclusions, and added a renderWidgets page decoration
parent
40e07dbea0
commit
b7c56a8379
|
@ -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;
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ export type PageDecoration = {
|
|||
prefix?: string;
|
||||
cssClasses?: string[];
|
||||
hide?: boolean;
|
||||
renderWidgets?: boolean; // Defaults to true
|
||||
};
|
||||
|
||||
export type AttachmentMeta = ObjectValue<
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
Loading…
Reference in New Issue