Skip to content

Commit

Permalink
feat: make spanner plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentdchan committed Dec 4, 2023
1 parent ec86a36 commit 6bbd6a6
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 90 deletions.
6 changes: 1 addition & 5 deletions packages/blocky-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,6 @@ export * from "./block/basic";
export { ContentBlock } from "./block/contentBlock";
export { CustomBlock } from "./block/customBlock";
export { makeDefaultIdGenerator, type IdGenerator } from "./helper/idHelper";
export {
type SpannerFactory,
type SpannerInstance,
SpannerDelegate,
} from "./view/spannerDelegate";
export { type ToolbarFactory, type Toolbar } from "./view/toolbarDelegate";
export { FollowerWidget } from "./view/followerWidget";
export {
Expand All @@ -25,6 +20,7 @@ export {
PluginRegistry,
PluginContext,
} from "./registry/pluginRegistry";
export * from "./plugins/spannerPlugin";
export { BlockRegistry } from "./registry/blockRegistry";
export { type SpanStyle, SpanRegistry } from "./registry/spanRegistry";
export {
Expand Down
13 changes: 13 additions & 0 deletions packages/blocky-core/src/plugins/spannerPlugin/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { SpannerPlugin } from "./spannerPlugin";
import {
SpannerDelegate,
type SpannerFactory,
type SpannerInstance,
} from "./spannerDelegate";

export {
SpannerPlugin,
SpannerDelegate,
type SpannerFactory,
type SpannerInstance,
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, it, vi } from "vitest";
import { SpannerDelegate, SpannerInstance } from "./spannerDelegate";
import { EditorController } from "./controller";
import { BlockDataElement } from "..";
import { EditorController } from "../../view/controller";
import { BlockDataElement } from "../..";

describe("SpannerDelegate", () => {
it("focusedNode", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type IDisposable } from "blocky-common/es";
import type { EditorController } from "@pkg/view/controller";
import type { BlockDataElement } from "@pkg/data";
import { UIDelegate } from "./uiDelegate";
import { UIDelegate } from "@pkg/view/uiDelegate";
import { fromEvent, takeUntil } from "rxjs";

export interface SpannerInstance extends IDisposable {
Expand Down
70 changes: 70 additions & 0 deletions packages/blocky-core/src/plugins/spannerPlugin/spannerPlugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { BlockDataElement, Editor, IPlugin, PluginContext } from "../..";
import { take, takeUntil, fromEvent } from "rxjs";
import { SpannerDelegate, SpannerFactory } from "./spannerDelegate";

export class SpannerPlugin implements IPlugin {
deletage: SpannerDelegate | undefined;
name = "spanner";

constructor(public readonly factory: SpannerFactory) {}

onInitialized(context: PluginContext): void {
const { editor, dispose$ } = context;
this.deletage = new SpannerDelegate(editor.controller, this.factory);
this.deletage.mount(editor.container);

editor.placeSpannerAt$
.pipe(takeUntil(dispose$))
.subscribe(({ blockContainer, node }) => {
this.placeSpannerAt(editor, blockContainer, node);
});

fromEvent(editor.container, "mouseleave")
.pipe(takeUntil(dispose$))
.subscribe(() => {
this.deletage?.hide();
});

dispose$.pipe(take(1)).subscribe(() => {
this.deletage?.dispose();
this.deletage = undefined;
});
}

protected placeSpannerAt(
editor: Editor,
blockContainer: HTMLElement,
node: BlockDataElement
) {
if (!this.deletage) {
return;
}
const block = editor.state.blocks.get(node.id);
if (!block) {
return;
}
let { x, y } = this.getRelativeOffsetByDom(editor, blockContainer);
const offset = block.getSpannerOffset();
x += offset.x;
y += offset.y;
x -= this.deletage.width;
this.deletage.focusedNode = node;
this.deletage.show();
this.deletage.setPosition(x, y);
}

/**
* Get the element's relative position to the container of the editor.
*/
protected getRelativeOffsetByDom(
editor: Editor,
element: HTMLElement
): { x: number; y: number } {
const containerRect = editor.container.getBoundingClientRect();
const blockRect = element.getBoundingClientRect();
return {
x: blockRect.x - containerRect.x,
y: blockRect.y - containerRect.y,
};
}
}
4 changes: 0 additions & 4 deletions packages/blocky-core/src/registry/pluginRegistry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,16 @@ describe("PluginRegistry", () => {
const plugin: IPlugin = {
name: "test",
onInitialized() {},
onDispose() {},
};
const onInitSpy = vi.spyOn(plugin, "onInitialized");
const disposeSpy = vi.spyOn(plugin, "onDispose");
const pluginRegistry = new PluginRegistry([plugin]);
const editorController = new EditorController("user");
const dom = document.createElement("div");
const editor = Editor.fromController(dom, editorController);
pluginRegistry.initAllPlugins(editor);

expect(onInitSpy).toBeCalledTimes(1);
expect(disposeSpy).toBeCalledTimes(0);

pluginRegistry.unload("test");
expect(disposeSpy).toBeCalledTimes(1);
});
});
3 changes: 0 additions & 3 deletions packages/blocky-core/src/registry/pluginRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ export interface IPlugin {
*/
onInitialized?(context: PluginContext): void;

onDispose?(context: PluginContext): void;

onPaste?(evt: BlockyPasteEvent): void;
}

Expand Down Expand Up @@ -99,7 +97,6 @@ export class PluginRegistry {
if (context) {
context.dispose();
this.contexts.delete(name);
plugin.onDispose?.(context);
}
}

Expand Down
2 changes: 0 additions & 2 deletions packages/blocky-core/src/view/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { PluginRegistry, type IPlugin } from "@pkg/registry/pluginRegistry";
import { SpanRegistry } from "@pkg/registry/spanRegistry";
import { EmbedRegistry } from "@pkg/registry/embedRegistry";
import { HTMLConverter } from "@pkg/helper/htmlConverter";
import { type SpannerFactory } from "@pkg/view/spannerDelegate";
import { type ToolbarFactory } from "@pkg/view/toolbarDelegate";
import { type IdGenerator, makeDefaultIdGenerator } from "@pkg/helper/idHelper";
import { BlockPasteEvent, TryParsePastedDOMEvent } from "@pkg/block/basic";
Expand Down Expand Up @@ -89,7 +88,6 @@ export interface IEditorControllerOptions {
blockRegistry?: BlockRegistry;
embedRegistry?: EmbedRegistry;
idGenerator?: IdGenerator;
spannerFactory?: SpannerFactory;
toolbarFactory?: ToolbarFactory;

/**
Expand Down
Loading

0 comments on commit 6bbd6a6

Please sign in to comment.