2 $getNearestNodeFromDOMNode,
10 $getNearestBlockNodeForCoords,
12 $insertNewBlockNodeAtSelection, $insertNewBlockNodesAtSelection,
16 function $getNodeFromMouseEvent(event: MouseEvent, editor: LexicalEditor): LexicalNode|null {
17 const x = event.clientX;
18 const y = event.clientY;
19 const dom = document.elementFromPoint(x, y);
24 return $getNearestBlockNodeForCoords(editor, event.clientX, event.clientY);
27 function $insertNodesAtEvent(nodes: LexicalNode[], event: DragEvent, editor: LexicalEditor) {
28 const positionNode = $getNodeFromMouseEvent(event, editor);
31 $selectSingleNode(positionNode);
34 $insertNewBlockNodesAtSelection(nodes, true);
36 if (!$isDecoratorNode(positionNode) || !positionNode?.getTextContent()) {
37 positionNode?.remove();
41 async function insertTemplateToEditor(editor: LexicalEditor, templateId: string, event: DragEvent) {
42 const resp = await window.$http.get(`/templates/${templateId}`);
43 const data = (resp.data || {html: ''}) as {html: string}
44 const html: string = data.html || '';
47 const newNodes = $htmlToBlockNodes(editor, html);
48 $insertNodesAtEvent(newNodes, event, editor);
52 function createDropListener(editor: LexicalEditor): (event: DragEvent) => void {
53 return (event: DragEvent) => {
55 const templateId = event.dataTransfer?.getData('bookstack/template') || '';
57 event.preventDefault();
58 insertTemplateToEditor(editor, templateId, event);
64 export function handleDropEvents(editor: LexicalEditor) {
65 const dropListener = createDropListener(editor);
67 editor.registerRootListener((rootElement, prevRootElement) => {
68 rootElement?.addEventListener('drop', dropListener);
69 prevRootElement?.removeEventListener('drop', dropListener);