7 $getNearestBlockNodeForCoords,
9 $insertNewBlockNodesAtSelection,
13 function $getNodeFromMouseEvent(event: MouseEvent, editor: LexicalEditor): LexicalNode|null {
14 const x = event.clientX;
15 const y = event.clientY;
16 const dom = document.elementFromPoint(x, y);
21 return $getNearestBlockNodeForCoords(editor, event.clientX, event.clientY);
24 function $insertNodesAtEvent(nodes: LexicalNode[], event: DragEvent, editor: LexicalEditor) {
25 const positionNode = $getNodeFromMouseEvent(event, editor);
28 $selectSingleNode(positionNode);
31 $insertNewBlockNodesAtSelection(nodes, true);
33 if (!$isDecoratorNode(positionNode) || !positionNode?.getTextContent()) {
34 positionNode?.remove();
38 async function insertTemplateToEditor(editor: LexicalEditor, templateId: string, event: DragEvent) {
39 const resp = await window.$http.get(`/templates/${templateId}`);
40 const data = (resp.data || {html: ''}) as {html: string}
41 const html: string = data.html || '';
44 const newNodes = $htmlToBlockNodes(editor, html);
45 $insertNodesAtEvent(newNodes, event, editor);
49 function createDropListener(editor: LexicalEditor): (event: DragEvent) => void {
50 return (event: DragEvent) => {
52 const templateId = event.dataTransfer?.getData('bookstack/template') || '';
54 insertTemplateToEditor(editor, templateId, event);
55 event.preventDefault();
60 const html = event.dataTransfer?.getData('text/html') || '';
63 const newNodes = $htmlToBlockNodes(editor, html);
64 $insertNodesAtEvent(newNodes, event, editor);
66 event.preventDefault();
72 export function handleDropEvents(editor: LexicalEditor) {
73 const dropListener = createDropListener(editor);
75 editor.registerRootListener((rootElement, prevRootElement) => {
76 rootElement?.addEventListener('drop', dropListener);
77 prevRootElement?.removeEventListener('drop', dropListener);