Skip to content

Commit

Permalink
fix: Set initial props in custom node views
Browse files Browse the repository at this point in the history
  • Loading branch information
areknawo committed Apr 17, 2024
1 parent 3645517 commit adf4d46
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 25 deletions.
26 changes: 4 additions & 22 deletions apps/web/src/lib/editor/extensions/element/node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
applyStructure,
createCustomView,
getCustomElements,
getElementPath
getElementPath,
updateElementProps
} from "./utils";
import { Element as BaseElement, ElementAttributes } from "@vrite/editor";
import { SolidEditor } from "@vrite/tiptap-solid";
Expand Down Expand Up @@ -242,6 +243,7 @@ const Element = BaseElement.extend<Partial<ExtensionsContextData>>({
const customView = await createCustomView(
customElement.element,
customElement.extension,
editor,
{
getPos: props.getPos,
node: () => node
Expand Down Expand Up @@ -285,27 +287,7 @@ const Element = BaseElement.extend<Partial<ExtensionsContextData>>({
return JSON.parse(elementPropsJSON());
},
updateProps(newProps) {
const pos = customView.getPos();
const node = customView.node();

if (typeof pos !== "number" || pos > editor.view.state.doc.nodeSize) return;

editor.commands.command(({ tr, dispatch }) => {
if (!dispatch) return false;

if (typeof pos !== "number" || pos > editor.view.state.doc.nodeSize) {
return false;
}

if (node && node.type.name === "element") {
tr.setNodeMarkup(pos, node.type, {
props: { ...newProps },
type: node.attrs.type
});
}

return true;
});
updateElementProps(newProps, editor, customView);
}
});
resolveLoader();
Expand Down
47 changes: 46 additions & 1 deletion apps/web/src/lib/editor/extensions/element/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
import { ResolvedPos, Node as PMNode } from "@tiptap/pm/model";
import { nanoid } from "nanoid";
import { JSONContent } from "@vrite/sdk/api";
import { SolidEditor } from "@vrite/tiptap-solid";
import { ExtensionDetails } from "#context";
import { ContextObject } from "#collections";

type StructureNode = { element?: string; content?: true | StructureNode[]; allowed?: string[] };
type CustomView = {
Expand Down Expand Up @@ -90,12 +92,50 @@ const getElementPath = (

return path;
};
const updateElementProps = (
newProps: Record<string, any>,
editor: SolidEditor,
getters: Pick<CustomView, "getPos" | "node">
): void => {
const pos = getters.getPos();
const node = getters.node();

if (typeof pos !== "number" || pos > editor.view.state.doc.nodeSize) return;

editor.commands.command(({ tr, dispatch }) => {
if (!dispatch) return false;

if (typeof pos !== "number" || pos > editor.view.state.doc.nodeSize) {
return false;
}

if (node && node.type.name === "element") {
tr.setNodeMarkup(pos, node.type, {
props: { ...newProps },
type: node.attrs.type
});
}

return true;
});
};
const createCustomView = async (
elementSpec: ExtensionElementSpec,
extension: ExtensionDetails,
editor: SolidEditor,
getters: Pick<CustomView, "getPos" | "node">
): Promise<CustomView | null> => {
const uid = nanoid();

await extension.sandbox?.setEnvDataAsync((envData) => {
return {
...envData,
[uid]: {
props: getters.node().attrs.props || {}
}
};
});

const generatedViewData = await extension.sandbox?.generateView<ExtensionElementViewContext>(
elementSpec.view,
{
Expand Down Expand Up @@ -166,6 +206,11 @@ const createCustomView = async (
};

processElementTree([elementSpec.type.toLowerCase()], structure, generatedViewData.view);
updateElementProps(
((generatedViewData.envData[uid] as ContextObject).props as ContextObject) || {},
editor,
getters
);

return {
uid,
Expand Down Expand Up @@ -225,5 +270,5 @@ const applyStructure = (node: PMNode, structure: StructureNode): JSONContent =>
return applyStructureToNode(nodeJSON, structure)!;
};

export { getCustomElements, getElementPath, createCustomView, applyStructure };
export { getCustomElements, getElementPath, createCustomView, applyStructure, updateElementProps };
export type { CustomView, StructureNode };
17 changes: 15 additions & 2 deletions apps/web/src/lib/extensions/sandbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,27 @@ type UsableEnvData<C extends ExtensionBaseContext> = {
? C[ExtensionMetadata["__usableEnv"]]["readable"][K]
: C[ExtensionMetadata["__usableEnv"]]["writable"][K];
};
type AsyncSetter<in out T> = {
<U extends T>(
...args: undefined extends T ? [] : [value: (prev: T) => U]
): undefined extends T ? Promise<undefined> : Promise<U>;
<U extends T>(value: (prev: T) => U): Promise<U>;
<U extends T>(value: Exclude<U, Function>): Promise<U>;
<U extends T>(value: Exclude<U, Function> | ((prev: T) => U)): Promise<U>;
};

interface ExtensionSandbox {
spec: ExtensionSpec & ExtensionRuntimeSpec;
envData: Accessor<ContextObject>;
setEnvData: Setter<ContextObject>;
setEnvDataAsync: AsyncSetter<ContextObject>;
destroy(): void;
generateView<C extends ExtensionBaseViewContext>(
id: string,
ctx: SerializedContext<C>,
func: ContextFunctions<C>,
uid?: string
): Promise<{ view: ExtensionElement; css: string } | null>;
): Promise<{ view: ExtensionElement; css: string; envData: ContextObject } | null>;
runFunction<C extends ExtensionBaseContext>(
id: string,
ctx: SerializedContext<C>,
Expand Down Expand Up @@ -128,6 +137,10 @@ const loadExtensionSandbox = async (
setEnvData(...args);
sandbox.connection?.remote.updateEnvData(JSON.parse(JSON.stringify(envData())));
},
async setEnvDataAsync(...args: Parameters<typeof setEnvData>) {
setEnvData(...args);
await sandbox.connection?.remote.updateEnvData(JSON.parse(JSON.stringify(envData())));
},
destroy: () => sandbox.destroy(),
generateView: async <C extends ExtensionBaseViewContext>(
id: string,
Expand All @@ -153,7 +166,7 @@ const loadExtensionSandbox = async (

document.head.insertAdjacentHTML("beforeend", `<style data-uid="${uid}">${css}</style>`);

return { view: result.view, css };
return { view: result.view, css, envData: result.envData };
}

return null;
Expand Down

0 comments on commit adf4d46

Please sign in to comment.