parent
4defc19ba3
commit
caa18fc5e2
|
|
@ -1,7 +1,7 @@
|
|||
import { EditorState, Plugin, PluginKey } from "prosemirror-state";
|
||||
import { Popup } from "./popup";
|
||||
|
||||
export { initLinkPreviewPlugin };
|
||||
export { initLinkPreviewPlugin, LinkPreviewOptions };
|
||||
|
||||
declare const _currentEditorInstance: {
|
||||
_editorCore: EditorCore;
|
||||
|
|
@ -191,43 +191,57 @@ class LinkPreviewState {
|
|||
}
|
||||
}
|
||||
|
||||
function initLinkPreviewPlugin(options: LinkPreviewOptions) {
|
||||
function initLinkPreviewPlugin(
|
||||
plugins: readonly Plugin[],
|
||||
options: LinkPreviewOptions,
|
||||
) {
|
||||
const core = _currentEditorInstance._editorCore;
|
||||
console.log("Init BN Link Preview Plugin");
|
||||
const key = new PluginKey("linkPreviewPlugin");
|
||||
const newState = core.view.state.reconfigure({
|
||||
plugins: [
|
||||
...core.view.state.plugins,
|
||||
new Plugin({
|
||||
key,
|
||||
state: {
|
||||
init(config, state) {
|
||||
return new LinkPreviewState(state, options);
|
||||
return [
|
||||
...plugins,
|
||||
new Plugin({
|
||||
key,
|
||||
state: {
|
||||
init(config, state) {
|
||||
return new LinkPreviewState(state, options);
|
||||
},
|
||||
apply: (tr, pluginState, oldState, newState) => {
|
||||
pluginState.update(newState, oldState);
|
||||
return pluginState;
|
||||
},
|
||||
},
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
mousemove: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.update(view.state);
|
||||
pluginState.handleMouseMove(event);
|
||||
},
|
||||
apply: (tr, pluginState, oldState, newState) => {
|
||||
pluginState.update(newState, oldState);
|
||||
return pluginState;
|
||||
keydown: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.handleKeydown(event);
|
||||
},
|
||||
wheel: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.popup?.layoutPopup(pluginState);
|
||||
},
|
||||
},
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
mousemove: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.update(view.state);
|
||||
pluginState.handleMouseMove(event);
|
||||
},
|
||||
keydown: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.handleKeydown(event);
|
||||
},
|
||||
wheel: (view, event) => {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.popup?.layoutPopup(pluginState);
|
||||
},
|
||||
},
|
||||
view: (editorView) => {
|
||||
return {
|
||||
update(view, prevState) {
|
||||
const pluginState = key.getState(view.state) as LinkPreviewState;
|
||||
pluginState.update(view.state, prevState);
|
||||
},
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
core.view.updateState(newState);
|
||||
destroy() {
|
||||
const pluginState = key.getState(
|
||||
editorView.state,
|
||||
) as LinkPreviewState;
|
||||
pluginState.destroy();
|
||||
},
|
||||
};
|
||||
},
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,91 +7,92 @@ declare const _currentEditorInstance: {
|
|||
_editorCore: EditorCore;
|
||||
};
|
||||
|
||||
function initPasteMarkdownPlugin() {
|
||||
function initPasteMarkdownPlugin(plugins: readonly Plugin[]) {
|
||||
const core = _currentEditorInstance._editorCore;
|
||||
console.log("Init BN Paste Markdown Plugin");
|
||||
const key = new PluginKey("pasteDropPlugin");
|
||||
const oldPlugins = core.view.state.plugins;
|
||||
const oldPastePluginIndex = oldPlugins.findIndex(
|
||||
const oldPastePluginIndex = plugins.findIndex(
|
||||
(plugin) => plugin.props.handlePaste && plugin.props.handleDrop,
|
||||
);
|
||||
if (oldPastePluginIndex === -1) {
|
||||
console.error("Paste plugin not found");
|
||||
return;
|
||||
return plugins;
|
||||
}
|
||||
const oldPastePlugin = oldPlugins[oldPastePluginIndex];
|
||||
const newState = core.view.state.reconfigure({
|
||||
plugins: [
|
||||
...oldPlugins.slice(0, oldPastePluginIndex),
|
||||
new Plugin({
|
||||
key,
|
||||
props: {
|
||||
handlePaste: (view, event, slice) => {
|
||||
if (!event.clipboardData) {
|
||||
return false;
|
||||
}
|
||||
const markdown = getMarkdown(event.clipboardData);
|
||||
const oldPastePlugin = plugins[oldPastePluginIndex];
|
||||
return [
|
||||
...plugins.slice(0, oldPastePluginIndex),
|
||||
new Plugin({
|
||||
key,
|
||||
props: {
|
||||
handlePaste: (view, event, slice) => {
|
||||
if (!event.clipboardData) {
|
||||
return false;
|
||||
}
|
||||
const markdown = getMarkdown(event.clipboardData);
|
||||
|
||||
if (!markdown) {
|
||||
// Try the old paste plugin
|
||||
return oldPastePlugin.props.handlePaste?.apply(oldPastePlugin, [
|
||||
view,
|
||||
event,
|
||||
slice,
|
||||
]);
|
||||
}
|
||||
if (!markdown) {
|
||||
// Try the old paste plugin
|
||||
return oldPastePlugin.props.handlePaste?.apply(oldPastePlugin, [
|
||||
view,
|
||||
event,
|
||||
slice,
|
||||
]);
|
||||
}
|
||||
|
||||
md2html(markdown).then((html: string) => {
|
||||
const slice = window.BetterNotesEditorAPI.getSliceFromHTML(
|
||||
view.state,
|
||||
html,
|
||||
);
|
||||
const tr = view.state.tr.replaceSelection(slice);
|
||||
view.dispatch(tr);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
handleDrop: (view, event, slice, moved) => {
|
||||
if (!event.dataTransfer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const markdown = getMarkdown(event.dataTransfer);
|
||||
if (!markdown) {
|
||||
// Try the old drop plugin first
|
||||
return oldPastePlugin.props.handleDrop?.apply(oldPastePlugin, [
|
||||
view,
|
||||
event,
|
||||
slice,
|
||||
moved,
|
||||
]);
|
||||
}
|
||||
|
||||
md2html(markdown).then((html: string) => {
|
||||
const slice = window.BetterNotesEditorAPI.getSliceFromHTML(
|
||||
view.state,
|
||||
html,
|
||||
);
|
||||
const pos = view.posAtCoords({
|
||||
left: event.clientX,
|
||||
top: event.clientY,
|
||||
});
|
||||
if (!pos) {
|
||||
return;
|
||||
}
|
||||
// Insert the slice to the current position
|
||||
const tr = view.state.tr.insert(pos.pos, slice);
|
||||
view.dispatch(tr);
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
md2html(markdown).then((html: string) => {
|
||||
const slice = window.BetterNotesEditorAPI.getSliceFromHTML(
|
||||
view.state,
|
||||
html,
|
||||
);
|
||||
const tr = view.state.tr.replaceSelection(slice);
|
||||
view.dispatch(tr);
|
||||
});
|
||||
return true;
|
||||
},
|
||||
}),
|
||||
...oldPlugins.slice(oldPastePluginIndex + 1),
|
||||
],
|
||||
});
|
||||
core.view.updateState(newState);
|
||||
handleDrop: (view, event, slice, moved) => {
|
||||
if (!event.dataTransfer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const markdown = getMarkdown(event.dataTransfer);
|
||||
if (!markdown) {
|
||||
// Try the old drop plugin first
|
||||
return oldPastePlugin.props.handleDrop?.apply(oldPastePlugin, [
|
||||
view,
|
||||
event,
|
||||
slice,
|
||||
moved,
|
||||
]);
|
||||
}
|
||||
|
||||
md2html(markdown).then((html: string) => {
|
||||
const slice = window.BetterNotesEditorAPI.getSliceFromHTML(
|
||||
view.state,
|
||||
html,
|
||||
);
|
||||
const pos = view.posAtCoords({
|
||||
left: event.clientX,
|
||||
top: event.clientY,
|
||||
});
|
||||
if (!pos) {
|
||||
return;
|
||||
}
|
||||
// Insert the slice to the current position
|
||||
const tr = view.state.tr.insert(pos.pos, slice);
|
||||
view.dispatch(tr);
|
||||
});
|
||||
|
||||
return true;
|
||||
},
|
||||
},
|
||||
view: (editorView) => {
|
||||
return {
|
||||
destroy() {},
|
||||
};
|
||||
},
|
||||
}),
|
||||
...plugins.slice(oldPastePluginIndex + 1),
|
||||
];
|
||||
}
|
||||
|
||||
function getMarkdown(clipboardData: DataTransfer) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
import { initLinkPreviewPlugin, LinkPreviewOptions } from "./linkPreview";
|
||||
import { initPasteMarkdownPlugin } from "./pasteMarkdown";
|
||||
|
||||
export { initPlugins };
|
||||
|
||||
declare const _currentEditorInstance: {
|
||||
_editorCore: EditorCore;
|
||||
};
|
||||
|
||||
function initPlugins(options: LinkPreviewOptions) {
|
||||
const core = _currentEditorInstance._editorCore;
|
||||
let plugins = core.view.state.plugins;
|
||||
plugins = initLinkPreviewPlugin(plugins, options);
|
||||
plugins = initPasteMarkdownPlugin(plugins);
|
||||
// Collect all plugins and reconfigure the state only once
|
||||
const newState = core.view.state.reconfigure({
|
||||
plugins,
|
||||
});
|
||||
core.view.updateState(newState);
|
||||
}
|
||||
|
|
@ -11,8 +11,7 @@ import {
|
|||
} from "prosemirror-model";
|
||||
import { EditorState, TextSelection } from "prosemirror-state";
|
||||
import { EditorView } from "prosemirror-view";
|
||||
import { initLinkPreviewPlugin } from "./editor/linkPreview";
|
||||
import { initPasteMarkdownPlugin } from "./editor/pasteMarkdown";
|
||||
import { initPlugins } from "./editor/plugins";
|
||||
|
||||
declare const _currentEditorInstance: {
|
||||
_editorCore: EditorCore;
|
||||
|
|
@ -378,8 +377,7 @@ export const BetterNotesEditorAPI = {
|
|||
getSliceFromHTML,
|
||||
getNodeFromHTML,
|
||||
setSelection,
|
||||
initLinkPreviewPlugin,
|
||||
initPasteMarkdownPlugin,
|
||||
initPlugins,
|
||||
};
|
||||
|
||||
// @ts-ignore
|
||||
|
|
|
|||
|
|
@ -453,7 +453,7 @@ function initLinkPreview(editor: Zotero.EditorInstance) {
|
|||
}
|
||||
const EditorAPI = getEditorAPI(editor);
|
||||
safeCall(() =>
|
||||
EditorAPI.initLinkPreviewPlugin(
|
||||
EditorAPI.initPlugins(
|
||||
Components.utils.cloneInto(
|
||||
{
|
||||
setPreviewContent: (
|
||||
|
|
@ -485,7 +485,6 @@ function initLinkPreview(editor: Zotero.EditorInstance) {
|
|||
),
|
||||
),
|
||||
);
|
||||
safeCall(() => EditorAPI.initPasteMarkdownPlugin());
|
||||
}
|
||||
|
||||
function safeCall(callback: () => void) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue