From 83f957c43a76e2e2e47338964be9bec876b2c511 Mon Sep 17 00:00:00 2001 From: Alexandre Date: Wed, 3 Jul 2024 12:51:31 -0300 Subject: [PATCH] Create a component structure for QuickMenuInsert. Create a linked list and circular linked list to allow move the focus easily. Improve the folder structire. --- .vscode/settings.json | 5 + demo/assets/bundle.js | 164 ++++++++++---- demo/index.html | 6 +- src/block-operation.js | 4 +- src/{ => commands}/command-factory.js | 12 +- src/common/JCircularLinkedList.js | 55 +++++ src/common/JLinkedList.js | 53 +++++ src/common/JNode.js | 49 +++++ .../quick-insert-menu/QuickInsertMenu.js | 206 ++++++++++++++++++ .../quick-insert-menu/QuickInsertMenuItem.js | 81 +++++++ .../QuickInsertMenuSection.js | 95 ++++++++ src/components/quick-insert-menu/helperDOM.js | 23 ++ .../quick-insert-menu/quick-insert-menu.js} | 8 +- .../color-selection-box.js | 0 .../text-formatting-bar/insert-link-box.js | 0 .../text-formatting-bar/more-options-box.js | 0 .../text-formatting-bar.js} | 8 +- .../text-formatting-bar/turn-into-box.js | 0 src/core/DOMSelectionFocusManager .js | 149 +++++++++++++ src/element-factory.js | 15 ++ src/index.js | 14 +- src/j-selection.js | 54 ++++- src/{ => triggers}/click-events.js | 39 +++- src/{ => triggers}/keypress-events.js | 22 +- src/{ => triggers}/load-events.js | 9 + 25 files changed, 986 insertions(+), 85 deletions(-) create mode 100644 .vscode/settings.json rename src/{ => commands}/command-factory.js (89%) create mode 100644 src/common/JCircularLinkedList.js create mode 100644 src/common/JLinkedList.js create mode 100644 src/common/JNode.js create mode 100644 src/components/quick-insert-menu/QuickInsertMenu.js create mode 100644 src/components/quick-insert-menu/QuickInsertMenuItem.js create mode 100644 src/components/quick-insert-menu/QuickInsertMenuSection.js create mode 100644 src/components/quick-insert-menu/helperDOM.js rename src/{block-options-operation.js => components/quick-insert-menu/quick-insert-menu.js} (97%) create mode 100644 src/components/text-formatting-bar/color-selection-box.js create mode 100644 src/components/text-formatting-bar/insert-link-box.js create mode 100644 src/components/text-formatting-bar/more-options-box.js rename src/{text-formatting-bar-operation.js => components/text-formatting-bar/text-formatting-bar.js} (99%) create mode 100644 src/components/text-formatting-bar/turn-into-box.js create mode 100644 src/core/DOMSelectionFocusManager .js rename src/{ => triggers}/click-events.js (63%) rename src/{ => triggers}/keypress-events.js (92%) rename src/{ => triggers}/load-events.js (87%) diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..df10c14 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "Triggable" + ] +} \ No newline at end of file diff --git a/demo/assets/bundle.js b/demo/assets/bundle.js index b4bf80e..8f83c5c 100644 --- a/demo/assets/bundle.js +++ b/demo/assets/bundle.js @@ -27,40 +27,117 @@ eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extr /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createListItem: () => (/* binding */ createListItem),\n/* harmony export */ createNewElement: () => (/* binding */ createNewElement),\n/* harmony export */ deleteAndFocusOnNext: () => (/* binding */ deleteAndFocusOnNext),\n/* harmony export */ deleteAndFocusOnPrevious: () => (/* binding */ deleteAndFocusOnPrevious),\n/* harmony export */ deleteDraggableParentBlock: () => (/* binding */ deleteDraggableParentBlock),\n/* harmony export */ duplicateSelectedBlock: () => (/* binding */ duplicateSelectedBlock),\n/* harmony export */ moveDownBlock: () => (/* binding */ moveDownBlock),\n/* harmony export */ moveUpBlock: () => (/* binding */ moveUpBlock),\n/* harmony export */ transformBlock: () => (/* binding */ transformBlock)\n/* harmony export */ });\n/* harmony import */ var _element_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./element-factory */ \"./src/element-factory.js\");\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _j_window__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./j-window */ \"./src/j-window.js\");\n/* harmony import */ var _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./text-formatting-bar-operation */ \"./src/text-formatting-bar-operation.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n//** Create a default block or a element list */\r\nfunction createNewElement(event) {\r\n\r\n const element = event.target;\r\n\r\n const contentElement = element.closest('.johannes-content-element');\r\n\r\n if (contentElement && contentElement.classList.contains('list')) {\r\n createListItem(contentElement);\r\n } else {\r\n createADefaultBlock(contentElement);\r\n }\r\n}\r\n\r\n//** Just create a new paragraph draggable block and insert in the DOM */\r\nfunction createADefaultBlock(eventParagraph) {\r\n\r\n const newBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement();\r\n\r\n if (eventParagraph && eventParagraph.closest('.draggable-block')) {\r\n const sibling = eventParagraph.closest('.draggable-block');\r\n sibling.insertAdjacentElement('afterend', newBlock);\r\n } else {\r\n document.querySelector('.johannes-editor > .content').appendChild(newBlock);\r\n }\r\n\r\n const focusable = newBlock.querySelector('.johannes-content-element');\r\n // focusable.focus();\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(focusable);\r\n}\r\n\r\nfunction createListItem(element) {\r\n\r\n let newContentElement = null;\r\n\r\n let activeElement = document.activeElement;\r\n let contentElement = element.closest('.johannes-content-element');\r\n\r\n if (contentElement.classList.contains('checkbox-list')) {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewCheckboxLiElement)();\r\n } else if (contentElement.classList.contains('list')) {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewLiElement)();\r\n } else {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement)();\r\n }\r\n\r\n let parentBlock = null;\r\n\r\n if (contentElement.classList.contains('list')) {\r\n\r\n parentBlock = contentElement;\r\n\r\n const textContent = activeElement.textContent.trim();\r\n\r\n if (textContent === '') {\r\n\r\n parentBlock = element.closest('.draggable-block');\r\n\r\n element.closest('.deletable').remove();\r\n\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement)();\r\n parentBlock.insertAdjacentElement('afterend', newContentElement);\r\n\r\n } else {\r\n const activeElement = document.activeElement.closest('.list-item');\r\n activeElement.insertAdjacentElement('afterend', newContentElement);\r\n }\r\n\r\n } else {\r\n parentBlock = element.closest('.draggable-block');\r\n\r\n if (parentBlock) {\r\n if (parentBlock.nextSibling) {\r\n parentBlock.parentNode.insertBefore(newContentElement, parentBlock.nextSibling);\r\n } else {\r\n parentBlock.parentNode.appendChild(newContentElement);\r\n }\r\n }\r\n }\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(newContentElement);\r\n}\r\n\r\n//** Delete the closest draggable-block parent of a child. Take the current selection if a child is not passed. */\r\nfunction deleteDraggableParentBlock(child) {\r\n\r\n let draggableBlockToRemove = null;\r\n\r\n if (child && child instanceof HTMLElement && child.closest('.draggable-block')) {\r\n draggableBlockToRemove = child.closest('.draggable-block');\r\n } else {\r\n draggableBlockToRemove = _j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused();\r\n }\r\n\r\n if (draggableBlockToRemove) {\r\n draggableBlockToRemove.remove();\r\n } else {\r\n throw new Error('Focusable Element Not Found Exception');\r\n }\r\n\r\n clearAllAfterDelete();\r\n}\r\n\r\nfunction deleteAndFocusOnPrevious() {\r\n\r\n const currentActiveElement = document.activeElement;\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnPrevious)(currentActiveElement);\r\n deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentActiveElement);\r\n}\r\n\r\nfunction deleteAndFocusOnNext() {\r\n\r\n const currentActiveElement = document.activeElement;\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnNext)(currentActiveElement);\r\n deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentActiveElement);\r\n}\r\n\r\n\r\n//** Delete the current element and the draggable-block parent if empty. A block is empty if has no editable element inside. */\r\nfunction deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentElement) {\r\n\r\n const parentBlock = currentElement.closest('.draggable-block');\r\n const actual = currentElement.closest('.deletable');\r\n\r\n actual.remove();\r\n\r\n if (parentBlock && parentBlock.querySelectorAll('.editable').length == 0) {\r\n parentBlock.remove();\r\n }\r\n}\r\n\r\n/** Transform a block type into another */\r\nfunction transformBlock(blockElement, type) {\r\n\r\n //blockElement, type\r\n\r\n\r\n let contentElement = blockElement.querySelector('.swittable');\r\n let content = contentElement.innerText;\r\n\r\n // if (content.endsWith('/')) {\r\n // content = content.slice(0, -1); // Remove the last '/'\r\n // }\r\n\r\n let newContentBlock;\r\n\r\n switch (type) {\r\n case 'p':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewParagraphElement();\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h1':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(1);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h2':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(2);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h3':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(3);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h4':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(4);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h5':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(5);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h6':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(6);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'code':\r\n newContentBlock = document.createElement('pre');\r\n const code = document.createElement('code');\r\n code.innerText = content;\r\n newContentBlock.appendChild(code);\r\n break;\r\n case 'image':\r\n newContentBlock = document.createElement('img');\r\n newContentBlock.src = content;\r\n newContentBlock.alt = \"Descriptive text\";\r\n break;\r\n case 'quote':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewQuoteElement(content);\r\n\r\n break;\r\n }\r\n case 'bulleted-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewListElement(content);\r\n\r\n break;\r\n }\r\n\r\n case 'numbered-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewListElement(content, 'ol');\r\n\r\n break;\r\n }\r\n case 'todo-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewTodoListElement(content, 'ul');\r\n\r\n break;\r\n }\r\n\r\n case 'separator':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewSeparatorElement();\r\n break;\r\n }\r\n\r\n default:\r\n console.error('Unsupported type');\r\n return;\r\n }\r\n\r\n blockElement.replaceChild(newContentBlock, contentElement);\r\n\r\n const focusable = newContentBlock.closest('.focusable') || blockElement.querySelector('.focusable');\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(focusable);\r\n}\r\n\r\n\r\nfunction moveDownBlock() {\r\n\r\n}\r\n\r\nfunction moveUpBlock() {\r\n\r\n}\r\n\r\nfunction duplicateSelectedBlock() {\r\n\r\n let element = _j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused();\r\n\r\n if (!element || !element.parentNode) {\r\n console.error('O elemento fornecido é inválido ou não está no DOM.');\r\n return;\r\n }\r\n\r\n const clone = element.cloneNode(true);\r\n\r\n // Obtem o próximo elemento irmão\r\n const nextElement = element.nextSibling;\r\n\r\n // Insere o clone antes do próximo elemento irmão no pai\r\n // Se o próximo elemento irmão não existir, 'insertBefore' funcionará como 'appendChild'\r\n element.parentNode.insertBefore(clone, nextElement);\r\n\r\n\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.hideAllDependentBox)();\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.hideTextFormattingBar)();\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(clone);\r\n}\r\n\r\nfunction clearAllAfterDelete() {\r\n _j_selection__WEBPACK_IMPORTED_MODULE_1__.clearAllSelection();\r\n\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.hideAllDependentBox)();\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.hideTextFormattingBar)();\r\n}\n\n//# sourceURL=webpack://johannes/./src/block-operation.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createListItem: () => (/* binding */ createListItem),\n/* harmony export */ createNewElement: () => (/* binding */ createNewElement),\n/* harmony export */ deleteAndFocusOnNext: () => (/* binding */ deleteAndFocusOnNext),\n/* harmony export */ deleteAndFocusOnPrevious: () => (/* binding */ deleteAndFocusOnPrevious),\n/* harmony export */ deleteDraggableParentBlock: () => (/* binding */ deleteDraggableParentBlock),\n/* harmony export */ duplicateSelectedBlock: () => (/* binding */ duplicateSelectedBlock),\n/* harmony export */ moveDownBlock: () => (/* binding */ moveDownBlock),\n/* harmony export */ moveUpBlock: () => (/* binding */ moveUpBlock),\n/* harmony export */ transformBlock: () => (/* binding */ transformBlock)\n/* harmony export */ });\n/* harmony import */ var _element_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./element-factory */ \"./src/element-factory.js\");\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _j_window__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./j-window */ \"./src/j-window.js\");\n/* harmony import */ var _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/text-formatting-bar/text-formatting-bar */ \"./src/components/text-formatting-bar/text-formatting-bar.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n//** Create a default block or a element list */\r\nfunction createNewElement(event) {\r\n\r\n const element = event.target;\r\n\r\n const contentElement = element.closest('.johannes-content-element');\r\n\r\n if (contentElement && contentElement.classList.contains('list')) {\r\n createListItem(contentElement);\r\n } else {\r\n createADefaultBlock(contentElement);\r\n }\r\n}\r\n\r\n//** Just create a new paragraph draggable block and insert in the DOM */\r\nfunction createADefaultBlock(eventParagraph) {\r\n\r\n const newBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement();\r\n\r\n if (eventParagraph && eventParagraph.closest('.draggable-block')) {\r\n const sibling = eventParagraph.closest('.draggable-block');\r\n sibling.insertAdjacentElement('afterend', newBlock);\r\n } else {\r\n document.querySelector('.johannes-editor > .content').appendChild(newBlock);\r\n }\r\n\r\n const focusable = newBlock.querySelector('.johannes-content-element');\r\n // focusable.focus();\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(focusable);\r\n}\r\n\r\nfunction createListItem(element) {\r\n\r\n let newContentElement = null;\r\n\r\n let activeElement = document.activeElement;\r\n let contentElement = element.closest('.johannes-content-element');\r\n\r\n if (contentElement.classList.contains('checkbox-list')) {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewCheckboxLiElement)();\r\n } else if (contentElement.classList.contains('list')) {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewLiElement)();\r\n } else {\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement)();\r\n }\r\n\r\n let parentBlock = null;\r\n\r\n if (contentElement.classList.contains('list')) {\r\n\r\n parentBlock = contentElement;\r\n\r\n const textContent = activeElement.textContent.trim();\r\n\r\n if (textContent === '') {\r\n\r\n parentBlock = element.closest('.draggable-block');\r\n\r\n element.closest('.deletable').remove();\r\n\r\n newContentElement = (0,_element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewDraggableParagraphElement)();\r\n parentBlock.insertAdjacentElement('afterend', newContentElement);\r\n\r\n } else {\r\n const activeElement = document.activeElement.closest('.list-item');\r\n activeElement.insertAdjacentElement('afterend', newContentElement);\r\n }\r\n\r\n } else {\r\n parentBlock = element.closest('.draggable-block');\r\n\r\n if (parentBlock) {\r\n if (parentBlock.nextSibling) {\r\n parentBlock.parentNode.insertBefore(newContentElement, parentBlock.nextSibling);\r\n } else {\r\n parentBlock.parentNode.appendChild(newContentElement);\r\n }\r\n }\r\n }\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(newContentElement);\r\n}\r\n\r\n//** Delete the closest draggable-block parent of a child. Take the current selection if a child is not passed. */\r\nfunction deleteDraggableParentBlock(child) {\r\n\r\n let draggableBlockToRemove = null;\r\n\r\n if (child && child instanceof HTMLElement && child.closest('.draggable-block')) {\r\n draggableBlockToRemove = child.closest('.draggable-block');\r\n } else {\r\n draggableBlockToRemove = _j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused();\r\n }\r\n\r\n if (draggableBlockToRemove) {\r\n draggableBlockToRemove.remove();\r\n } else {\r\n throw new Error('Focusable Element Not Found Exception');\r\n }\r\n\r\n clearAllAfterDelete();\r\n}\r\n\r\nfunction deleteAndFocusOnPrevious() {\r\n\r\n const currentActiveElement = document.activeElement;\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnPrevious)(currentActiveElement);\r\n deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentActiveElement);\r\n}\r\n\r\nfunction deleteAndFocusOnNext() {\r\n\r\n const currentActiveElement = document.activeElement;\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnNext)(currentActiveElement);\r\n deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentActiveElement);\r\n}\r\n\r\n\r\n//** Delete the current element and the draggable-block parent if empty. A block is empty if has no editable element inside. */\r\nfunction deleteTheCurrentElementAndTheDraggableBlockIfEmpty(currentElement) {\r\n\r\n const parentBlock = currentElement.closest('.draggable-block');\r\n const actual = currentElement.closest('.deletable');\r\n\r\n actual.remove();\r\n\r\n if (parentBlock && parentBlock.querySelectorAll('.editable').length == 0) {\r\n parentBlock.remove();\r\n }\r\n}\r\n\r\n/** Transform a block type into another */\r\nfunction transformBlock(blockElement, type) {\r\n\r\n //blockElement, type\r\n\r\n\r\n let contentElement = blockElement.querySelector('.swittable');\r\n let content = contentElement.innerText;\r\n\r\n // if (content.endsWith('/')) {\r\n // content = content.slice(0, -1); // Remove the last '/'\r\n // }\r\n\r\n let newContentBlock;\r\n\r\n switch (type) {\r\n case 'p':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewParagraphElement();\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h1':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(1);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h2':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(2);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h3':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(3);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h4':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(4);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h5':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(5);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'h6':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewHeadingElement(6);\r\n newContentBlock.innerText = content;\r\n break;\r\n }\r\n case 'code':\r\n newContentBlock = document.createElement('pre');\r\n const code = document.createElement('code');\r\n code.innerText = content;\r\n newContentBlock.appendChild(code);\r\n break;\r\n case 'image':\r\n newContentBlock = document.createElement('img');\r\n newContentBlock.src = content;\r\n newContentBlock.alt = \"Descriptive text\";\r\n break;\r\n case 'quote':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewQuoteElement(content);\r\n\r\n break;\r\n }\r\n case 'bulleted-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewListElement(content);\r\n\r\n break;\r\n }\r\n\r\n case 'numbered-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewListElement(content, 'ol');\r\n\r\n break;\r\n }\r\n case 'todo-list':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewTodoListElement(content, 'ul');\r\n\r\n break;\r\n }\r\n\r\n case 'separator':\r\n {\r\n newContentBlock = _element_factory__WEBPACK_IMPORTED_MODULE_0__.createNewSeparatorElement();\r\n break;\r\n }\r\n\r\n default:\r\n console.error('Unsupported type');\r\n return;\r\n }\r\n\r\n blockElement.replaceChild(newContentBlock, contentElement);\r\n\r\n const focusable = newContentBlock.closest('.focusable') || blockElement.querySelector('.focusable');\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(focusable);\r\n}\r\n\r\n\r\nfunction moveDownBlock() {\r\n\r\n}\r\n\r\nfunction moveUpBlock() {\r\n\r\n}\r\n\r\nfunction duplicateSelectedBlock() {\r\n\r\n let element = _j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused();\r\n\r\n if (!element || !element.parentNode) {\r\n console.error('O elemento fornecido é inválido ou não está no DOM.');\r\n return;\r\n }\r\n\r\n const clone = element.cloneNode(true);\r\n\r\n // Obtem o próximo elemento irmão\r\n const nextElement = element.nextSibling;\r\n\r\n // Insere o clone antes do próximo elemento irmão no pai\r\n // Se o próximo elemento irmão não existir, 'insertBefore' funcionará como 'appendChild'\r\n element.parentNode.insertBefore(clone, nextElement);\r\n\r\n\r\n (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.hideAllDependentBox)();\r\n (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.hideTextFormattingBar)();\r\n\r\n (0,_j_window__WEBPACK_IMPORTED_MODULE_2__.focusOnTheEndOfTheText)(clone);\r\n}\r\n\r\nfunction clearAllAfterDelete() {\r\n _j_selection__WEBPACK_IMPORTED_MODULE_1__.clearAllSelection();\r\n\r\n (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.hideAllDependentBox)();\r\n (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.hideTextFormattingBar)();\r\n}\n\n//# sourceURL=webpack://johannes/./src/block-operation.js?"); /***/ }), -/***/ "./src/block-options-operation.js": -/*!****************************************!*\ - !*** ./src/block-options-operation.js ***! - \****************************************/ +/***/ "./src/commands/command-factory.js": +/*!*****************************************!*\ + !*** ./src/commands/command-factory.js ***! + \*****************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ applySelectedBlockType: () => (/* binding */ applySelectedBlockType),\n/* harmony export */ clear: () => (/* binding */ clear),\n/* harmony export */ filterContact: () => (/* binding */ filterContact),\n/* harmony export */ filterRemoveLast: () => (/* binding */ filterRemoveLast),\n/* harmony export */ hideAndClearBlockOptions: () => (/* binding */ hideAndClearBlockOptions),\n/* harmony export */ isShowingBlockOptions: () => (/* binding */ isShowingBlockOptions),\n/* harmony export */ moveTheFakeFocusToPreviousBlockOption: () => (/* binding */ moveTheFakeFocusToPreviousBlockOption),\n/* harmony export */ moveTheFakeFocusToTheNextBlockOption: () => (/* binding */ moveTheFakeFocusToTheNextBlockOption),\n/* harmony export */ removeDisplayNoneFromAllBlockOptions: () => (/* binding */ removeDisplayNoneFromAllBlockOptions),\n/* harmony export */ setCurrentDraggableBlock: () => (/* binding */ setCurrentDraggableBlock),\n/* harmony export */ setCurrentFakeFocusElement: () => (/* binding */ setCurrentFakeFocusElement),\n/* harmony export */ setRealFocusedElement: () => (/* binding */ setRealFocusedElement),\n/* harmony export */ showDependentBlockOptions: () => (/* binding */ showDependentBlockOptions),\n/* harmony export */ showMainBlockOptions: () => (/* binding */ showMainBlockOptions)\n/* harmony export */ });\n/* harmony import */ var _block_operation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./block-operation */ \"./src/block-operation.js\");\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./text-formatting-bar-operation */ \"./src/text-formatting-bar-operation.js\");\n\r\n\r\n\r\n\r\n\r\nlet currentDraggableBlock = null; //This element represents the block where block-options will be displayed close to\r\nlet currentFakeFocusedOption = null; //Fake focus is where the visual focus in on\r\nlet realFocusedElement = null; // This element is where the real/actual focus is on / TODO: change the name\r\nlet filterText = '';\r\n\r\nfunction isShowingBlockOptions() {\r\n return blockOptionsWrapper.style.display !== 'none'\r\n}\r\n\r\nfunction setCurrentDraggableBlock(element) {\r\n if (!element.classList.contains('draggable-block')) {\r\n throw new Error('The Element is Not a Draggable Block');\r\n }\r\n\r\n currentDraggableBlock = element;\r\n}\r\n\r\nfunction setRealFocusedElement(element) {\r\n realFocusedElement = element;\r\n}\r\n\r\nfunction setCurrentFakeFocusElement(element) {\r\n currentFakeFocusedOption = element;\r\n}\r\n\r\nfunction filterContact(event) {\r\n\r\n filterText += event.key.toLowerCase();\r\n\r\n updateBlockVisibility(filterText);\r\n\r\n const firstVisibleOption = getTheFirstVisibleBlockOption();\r\n removeAllVisualFakeFocus();\r\n\r\n setCurrentFakeFocusElement(firstVisibleOption);\r\n applyVisualFakeFocus(realFocusedElement, firstVisibleOption);\r\n}\r\n\r\nfunction filterRemoveLast() {\r\n\r\n if (filterText.length > 0) {\r\n\r\n filterText = filterText.slice(0, -1);\r\n\r\n updateBlockVisibility(filterText);\r\n\r\n const firstVisibleOption = getTheFirstVisibleBlockOption();\r\n removeAllVisualFakeFocus();\r\n\r\n setCurrentFakeFocusElement(firstVisibleOption);\r\n applyVisualFakeFocus(realFocusedElement, firstVisibleOption);\r\n\r\n } else {\r\n hideAndClearBlockOptions();\r\n }\r\n}\r\n\r\nfunction clear() {\r\n throw new Error('Not Implement Exception')\r\n}\r\n\r\nfunction showDependentBlockOptions(element) {\r\n // The timeout in necessary to wait the browser process the selection before show the Block Options\r\n setTimeout(() => {\r\n\r\n removeAllVisualFakeFocus();\r\n\r\n let draggableBlock = (0,_j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused)();\r\n\r\n const realFocusedElement = draggableBlock.querySelector('.focusable');\r\n const currentDraggableBlock = draggableBlock;\r\n const firstBlockOption = getTheFirstVisibleBlockOptionV2(element);\r\n\r\n setRealFocusedElement(realFocusedElement);\r\n setCurrentDraggableBlock(currentDraggableBlock);\r\n setCurrentFakeFocusElement(null);\r\n\r\n applyVisualFakeFocus(realFocusedElement, null);\r\n\r\n }, 10);\r\n}\r\n\r\nfunction showMainBlockOptions() {\r\n\r\n // The timeout in necessary to wait the browser process the selection before show the Block Options\r\n setTimeout(() => {\r\n\r\n const realFocusedElement = document.activeElement;\r\n const currentDraggableBlock = realFocusedElement.closest('.draggable-block');\r\n const firstBlockOption = getTheFirstVisibleBlockOption();\r\n\r\n setRealFocusedElement(realFocusedElement);\r\n setCurrentDraggableBlock(currentDraggableBlock);\r\n setCurrentFakeFocusElement(firstBlockOption);\r\n\r\n applyVisualFakeFocus(realFocusedElement, firstBlockOption);\r\n\r\n\r\n //TODO: create a clear filter\r\n // removeDisplayNoneFromAllBlockOptions();\r\n\r\n const range = document.getSelection().getRangeAt(0);\r\n const cursorPos = range.getBoundingClientRect();\r\n\r\n const remSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\r\n const menuWidth = 19 * remSize;\r\n\r\n let xPosition = cursorPos.right;\r\n let yPosition = cursorPos.bottom + window.scrollY;\r\n\r\n const margin = remSize * 1.25;\r\n\r\n blockOptionsWrapper.style.display = 'block';\r\n\r\n let blockWidth = blockOptionsWrapper.offsetWidth;\r\n\r\n\r\n if (xPosition + blockWidth + margin > window.innerWidth) {\r\n xPosition = cursorPos.left - menuWidth;\r\n if (xPosition < 0) xPosition = 0;\r\n }\r\n\r\n blockOptionsWrapper.style.left = `${xPosition}px`;\r\n blockOptionsWrapper.style.top = `${yPosition}px`;\r\n\r\n\r\n }, 10);\r\n}\r\n\r\nfunction hideAndClearBlockOptions(elementToFocus) {\r\n\r\n if (elementToFocus) {\r\n elementToFocus.focus();\r\n }\r\n\r\n blockOptionsWrapper.style.display = 'none';\r\n clearFilter();\r\n\r\n //TODO: rename this\r\n removeDisplayNoneFromAllBlockOptions();\r\n}\r\n\r\n\r\n\r\n// TODO:Rename this function\r\nfunction removeDisplayNoneFromAllBlockOptions() {\r\n let sections = document.querySelectorAll('.johannes-editor .block-options-wrapper section');\r\n\r\n sections.forEach(section => {\r\n let options = section.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.style.display = '';\r\n });\r\n\r\n section.style.display = '';\r\n });\r\n}\r\n\r\nfunction moveTheFakeFocusToPreviousBlockOption() {\r\n\r\n if (!currentFakeFocusedOption) {\r\n let options = document.getElementById(getVisibleSelectionId()).querySelectorAll('.option');\r\n currentFakeFocusedOption = options[options.length - 1];\r\n\r\n applyVisualFakeFocus(realFocusedElement, currentFakeFocusedOption);\r\n\r\n return;\r\n }\r\n\r\n let previous = currentFakeFocusedOption.previousElementSibling;\r\n\r\n while (previous && (!previous.classList.contains('option') || !isElementVisible(previous))) {\r\n previous = previous.previousElementSibling;\r\n }\r\n\r\n if (!previous) {\r\n let currentSection = currentFakeFocusedOption.closest('section');\r\n let siblingSection;\r\n\r\n if (currentSection) {\r\n siblingSection = currentSection.previousElementSibling;\r\n } else {\r\n siblingSection = currentFakeFocusedOption.closest('ul');\r\n }\r\n\r\n while (siblingSection) {\r\n let options = siblingSection.querySelectorAll('.option');\r\n for (let i = options.length - 1; i >= 0; i--) {\r\n if (isElementVisible(options[i])) {\r\n previous = options[i];\r\n break;\r\n }\r\n }\r\n if (previous) break;\r\n siblingSection = siblingSection.previousElementSibling;\r\n }\r\n\r\n if (!previous) {\r\n let options = document.querySelectorAll('.block-options-wrapper .option');\r\n for (let i = options.length - 1; i >= 0; i--) {\r\n if (isElementVisible(options[i])) {\r\n previous = options[i];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n removeAllVisualFakeFocus();\r\n setCurrentFakeFocusElement(previous);\r\n applyVisualFakeFocus(realFocusedElement, previous);\r\n}\r\n\r\n\r\nfunction getVisibleSelectionId() {\r\n if (turnIntoSelect.style.display !== 'none') {\r\n return 'turnIntoSelect';\r\n }\r\n\r\n if (colorTextOptionSelect.style.display !== 'none') {\r\n return 'colorTextOptionSelect';\r\n }\r\n\r\n if (moreTextOptionSelect.style.display !== 'none') {\r\n return 'moreTextOptionSelect';\r\n }\r\n}\r\n\r\nfunction moveTheFakeFocusToTheNextBlockOption() {\r\n\r\n if (!currentFakeFocusedOption) {\r\n currentFakeFocusedOption = document.getElementById(getVisibleSelectionId()).querySelectorAll('.option')[0];\r\n\r\n applyVisualFakeFocus(realFocusedElement, currentFakeFocusedOption);\r\n\r\n return;\r\n }\r\n\r\n let next = currentFakeFocusedOption.nextElementSibling;\r\n\r\n while (next && (!next.classList.contains('option') || !isElementVisible(next))) {\r\n next = next.nextElementSibling;\r\n }\r\n\r\n if (!next) {\r\n let currentSection = currentFakeFocusedOption.closest('section');\r\n let siblingSection;\r\n\r\n if (currentSection) {\r\n siblingSection = currentSection.nextElementSibling;\r\n } else {\r\n siblingSection = currentFakeFocusedOption.closest('ul');\r\n }\r\n\r\n while (siblingSection) {\r\n next = siblingSection.querySelector('.option');\r\n if (next && isElementVisible(next)) {\r\n break;\r\n }\r\n siblingSection = siblingSection.nextElementSibling;\r\n }\r\n\r\n if (!next) {\r\n next = document.querySelector('.block-options-wrapper .option');\r\n while (next && !isElementVisible(next)) {\r\n next = next.nextElementSibling;\r\n }\r\n }\r\n }\r\n\r\n removeAllVisualFakeFocus();\r\n setCurrentFakeFocusElement(next);\r\n applyVisualFakeFocus(realFocusedElement, next);\r\n}\r\n\r\n\r\nfunction applySelectedBlockType(event) {\r\n\r\n const draggableBlock = realFocusedElement.closest('.draggable-block');\r\n const newBlockType = event.target.closest('.option') ?\r\n event.target.closest('.option').getAttribute('data-type') :\r\n currentFakeFocusedOption.getAttribute('data-type');\r\n\r\n const lastSlashIndex = realFocusedElement.innerText.lastIndexOf('/');\r\n realFocusedElement.innerText = lastSlashIndex !== -1 ? realFocusedElement.innerText.slice(0, lastSlashIndex) : realFocusedElement.innerText;\r\n\r\n\r\n (0,_block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock)(draggableBlock, newBlockType);\r\n\r\n hideAndClearBlockOptions();\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_2__.hideAllDependentBox)();\r\n (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_2__.hideTextFormattingBar)();\r\n}\r\n\r\nfunction clearFilter() {\r\n filterText = '';\r\n}\r\n\r\nfunction isElementVisible(element) {\r\n return element && element.style.display !== 'none' && element.style.visibility !== 'hidden' && element.offsetParent !== null;\r\n}\r\n\r\nfunction getTheFirstVisibleBlockOptionV2(element) {\r\n\r\n let button = element.closest('button');\r\n let listId = button.getAttribute('aria-controls');\r\n let list = document.querySelector(`#${listId}`);\r\n\r\n let options = list.querySelectorAll('.option');\r\n\r\n // for (let option of options) {\r\n // if (option.style.display !== 'none') {\r\n // return option;\r\n // }\r\n // }\r\n\r\n return options[0];\r\n\r\n}\r\n\r\nfunction getTheFirstVisibleBlockOption() {\r\n\r\n let options = blockOptionsWrapper.querySelectorAll('.option');\r\n\r\n for (let option of options) {\r\n if (option.style.display !== 'none') {\r\n return option;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction applyVisualFakeFocus(realFocusedElement, elementToApplyFakeFocus) {\r\n\r\n if (elementToApplyFakeFocus) {\r\n elementToApplyFakeFocus.focus();\r\n elementToApplyFakeFocus.classList.add('block-options-focused');\r\n }\r\n\r\n realFocusedElement.focus();\r\n}\r\n\r\n// function applyVisualFakeAndRealFocus(elementToApplyFakeFocus) {\r\n\r\n// if (elementToApplyFakeFocus) {\r\n// elementToApplyFakeFocus.focus();\r\n// elementToApplyFakeFocus.classList.add('block-options-focused');\r\n// }\r\n// }\r\n\r\nfunction removeAllVisualFakeFocus() {\r\n let focusedElements = document.querySelectorAll('.block-options-focused');\r\n\r\n focusedElements.forEach(element => {\r\n element.classList.remove('block-options-focused');\r\n });\r\n}\r\n\r\nfunction updateBlockVisibility(filter) {\r\n\r\n let sections = blockOptionsWrapper.querySelectorAll('section');\r\n\r\n sections.forEach(section => {\r\n let options = section.querySelectorAll('.option');\r\n let allHidden = true;\r\n\r\n options.forEach(option => {\r\n const type = option.getAttribute('data-type');\r\n const title = option.querySelector('.block-title').textContent.toLowerCase();\r\n\r\n if (type.includes(filter) || title.includes(filter.toLowerCase())) {\r\n option.style.display = '';\r\n allHidden = false;\r\n } else {\r\n option.style.display = 'none';\r\n }\r\n });\r\n\r\n section.style.display = allHidden ? 'none' : '';\r\n });\r\n\r\n let emptyListIndicator = document.querySelector('.empty-block-options');\r\n\r\n let allOptions = blockOptionsWrapper.querySelectorAll('.option');\r\n\r\n let hasVisibleOption = Array.from(allOptions).some(option => {\r\n let style = window.getComputedStyle(option);\r\n return style.display !== 'none';\r\n });\r\n\r\n if (hasVisibleOption) {\r\n emptyListIndicator.style.display = 'none';\r\n\r\n } else {\r\n emptyListIndicator.style.display = 'block';\r\n }\r\n}\n\n//# sourceURL=webpack://johannes/./src/block-options-operation.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OPERATIONS: () => (/* binding */ OPERATIONS),\n/* harmony export */ createCommand: () => (/* binding */ createCommand),\n/* harmony export */ getBlockOperationFunction: () => (/* binding */ getBlockOperationFunction),\n/* harmony export */ operationMap: () => (/* binding */ operationMap)\n/* harmony export */ });\n/* harmony import */ var _block_operation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../block-operation */ \"./src/block-operation.js\");\n/* harmony import */ var _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/quick-insert-menu/quick-insert-menu */ \"./src/components/quick-insert-menu/quick-insert-menu.js\");\n/* harmony import */ var _j_window__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../j-window */ \"./src/j-window.js\");\n/* harmony import */ var _components_quick_insert_menu_QuickInsertMenu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/quick-insert-menu/QuickInsertMenu */ \"./src/components/quick-insert-menu/QuickInsertMenu.js\");\n/* harmony import */ var _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../components/text-formatting-bar/text-formatting-bar */ \"./src/components/text-formatting-bar/text-formatting-bar.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction createCommand(operationName, elements = null) {\r\n return new Command(operationName, elements);\r\n}\r\n\r\nclass Command {\r\n\r\n constructor(operationName, elements) {\r\n this.elements = elements;\r\n this.operation = getBlockOperationFunction(operationName);\r\n }\r\n\r\n execute() {\r\n if (this.elements !== null) {\r\n this.operation(...this.elements);\r\n } else {\r\n this.operation();\r\n }\r\n }\r\n}\r\n\r\nconst OPERATIONS = {\r\n BLOCK: {\r\n CREATE_LIST_ELEMENT: 'create-list-element',\r\n CREATE_NEW_ELEMENT: 'create-new-element',\r\n DELETE_DRAGGABLE_BLOCK: 'delete-draggable-block',\r\n DELETE_AND_FOCUS_ON_NEXT: 'delete-and-focus-on-next',\r\n DELETE_AND_FOCUS_ON_PREVIOUS: 'delete-and-focus-on-previous',\r\n DUPLICATE_SELECTED_BLOCK: 'duplicate-selected-block',\r\n TRANSFORM_BLOCK: 'transform-block',\r\n MOVE_UP_BLOCK: 'move-up-block',\r\n MOVE_DOWN_BLOCK: 'move-down-block',\r\n SHOW_TURN_INTO_BOX: 'show-turn-into-box',\r\n SHOW_COLOR_BOX: 'show-color-box',\r\n SHOW_MORE_OPTIONS_BOX: 'show-more-options-box'\r\n },\r\n BLOCK_OPTIONS: {\r\n SHOW_BLOCK_OPTIONS: 'show-block-options',\r\n HIDE_CLEAR_BLOCK_OPTIONS: 'hide-clear-block-options',\r\n MOVE_FAKE_FOCUS_TO_NEXT_OPTION: 'move-fake-focus-to-next-option',\r\n MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION: 'move-fake-focus-to-previous-option',\r\n APPLY_SELECTED_BLOCK_TYPE: 'apply-selected-block-type',\r\n FILTER_CONCAT: 'filter-contact',\r\n FILTER_REMOVE_LAST: 'filter-remove-last',\r\n },\r\n FORMATTING_BAR: {\r\n SHOW_TEXT_FORMATTING_BAR: 'show-text-formatting-bar',\r\n HIDE_TEXT_FORMATTING_BAR: 'hide-text-formatting-bar',\r\n TOGGLE_MORE_OPTIONS_BOX: 'toggle-more-options-box',\r\n TOGGLE_CHANGE_COLOR_BOX: 'toggle-change-color-box',\r\n TOGGLE_TURN_INTO_BOX: 'toggle-turn-into-box',\r\n TOGGLE_INPUT_LINK_BOX: 'toggle-input-link-box',\r\n INPUT_LINK_URL: 'input-link-url', \r\n TOGGLE_ENCLOSE_SELECTED_TEXT_TO: 'toggle-enclose-selected-text-to',\r\n },\r\n\r\n};\r\n\r\nconst operationMap = {\r\n [OPERATIONS.BLOCK.CREATE_LIST_ELEMENT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.createListItem,\r\n [OPERATIONS.BLOCK.CREATE_NEW_ELEMENT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.createNewElement,\r\n [OPERATIONS.BLOCK.DELETE_DRAGGABLE_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteDraggableParentBlock,\r\n [OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_NEXT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteAndFocusOnNext,\r\n [OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_PREVIOUS]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteAndFocusOnPrevious,\r\n [OPERATIONS.BLOCK.DUPLICATE_SELECTED_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.duplicateSelectedBlock,\r\n [OPERATIONS.BLOCK.TRANSFORM_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.BLOCK.MOVE_UP_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.moveUpBlock,\r\n [OPERATIONS.BLOCK.MOVE_DOWN_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.moveDownBlock,\r\n [OPERATIONS.BLOCK_OPTIONS.SHOW_BLOCK_OPTIONS]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.showMainBlockOptions,\r\n [OPERATIONS.BLOCK_OPTIONS.HIDE_CLEAR_BLOCK_OPTIONS]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.hideAndClearBlockOptions,\r\n [OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION]: _components_quick_insert_menu_QuickInsertMenu__WEBPACK_IMPORTED_MODULE_3__[\"default\"].moveTheFakeFocusToTheNextMenuItem, // blockOptionOperation.moveTheFakeFocusToTheNextBlockOption,\r\n [OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.moveTheFakeFocusToPreviousBlockOption,\r\n [OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.applySelectedBlockType,\r\n [OPERATIONS.BLOCK_OPTIONS.FILTER_CONCAT]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.filterContact,\r\n [OPERATIONS.BLOCK_OPTIONS.FILTER_REMOVE_LAST]: _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.filterRemoveLast,\r\n [OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.showTextFormattingBar,\r\n [OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.hideTextFormattingBar,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_MORE_OPTIONS_BOX]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.toggleMoreOptionsBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_CHANGE_COLOR_BOX]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.toggleChangeColorBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_TURN_INTO_BOX]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.toggleTurnIntoBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_INPUT_LINK_BOX]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.toggleInputLinkBox,\r\n [OPERATIONS.FORMATTING_BAR.INPUT_LINK_URL]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.inputLinkUrl,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_ENCLOSE_SELECTED_TEXT_TO]: _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_4__.toggleEncloseSelectedTextTo,\r\n [OPERATIONS.SHOW_TURN_INTO_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.SHOW_COLOR_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.SHOW_MORE_OPTIONS_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock\r\n};\r\n\r\nfunction getBlockOperationFunction(blockOperation) {\r\n const operationFunction = operationMap[blockOperation];\r\n if (!operationFunction) {\r\n throw new Error('Operation Not Found Exception');\r\n }\r\n return operationFunction;\r\n}\n\n//# sourceURL=webpack://johannes/./src/commands/command-factory.js?"); /***/ }), -/***/ "./src/click-events.js": +/***/ "./src/common/JCircularLinkedList.js": +/*!*******************************************!*\ + !*** ./src/common/JCircularLinkedList.js ***! + \*******************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _JNode__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./JNode */ \"./src/common/JNode.js\");\n\r\n\r\nclass JCircularLinkedList {\r\n\r\n constructor() {\r\n this.head = null;\r\n this.tail = null;\r\n this.length = 0;\r\n }\r\n\r\n /**\r\n * Append a new node with the given value to the end of the list.\r\n * @param {JNode} node - The node to append.\r\n */\r\n append(node) {\r\n if (!(node instanceof _JNode__WEBPACK_IMPORTED_MODULE_0__[\"default\"])) {\r\n throw new TypeError(\"Expected an instance of JNode.\");\r\n }\r\n\r\n if (this.length === 0) {\r\n this.head = node;\r\n this.tail = node;\r\n\r\n this.head.setNext(this.tail);\r\n this.head.setPrevious(this.tail);\r\n } else {\r\n node.setPrevious(this.tail);\r\n node.setNext(this.head);\r\n\r\n this.tail.setNext(node);\r\n this.head.setPrevious(node);\r\n\r\n this.tail = node;\r\n }\r\n this.length++;\r\n }\r\n\r\n /**\r\n * Get the first node (head) of the list.\r\n * @returns {JNode} The first node.\r\n */\r\n getFirst() {\r\n return this.head;\r\n }\r\n\r\n /**\r\n * Get the last node (tail) of the list.\r\n * @returns {JNode} The last node.\r\n */\r\n getLast() {\r\n return this.tail;\r\n }\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (JCircularLinkedList);\n\n//# sourceURL=webpack://johannes/./src/common/JCircularLinkedList.js?"); + +/***/ }), + +/***/ "./src/common/JLinkedList.js": +/*!***********************************!*\ + !*** ./src/common/JLinkedList.js ***! + \***********************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _JNode__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./JNode */ \"./src/common/JNode.js\");\n\r\n\r\nclass JLinkedList {\r\n\r\n constructor() {\r\n this.head = null;\r\n this.tail = null;\r\n this.length = 0;\r\n }\r\n\r\n /**\r\n * Append a new node with the given value to the end of the list.\r\n * @param {*} HTMLElement - The value to store in the new node.\r\n */\r\n append(node) {\r\n\r\n if (!(node instanceof _JNode__WEBPACK_IMPORTED_MODULE_0__[\"default\"])) {\r\n throw new TypeError(\"Expected an instance of JNode.\");\r\n }\r\n\r\n if (this.length === 0) {\r\n this.head = node;\r\n this.tail = node;\r\n } else {\r\n\r\n this.tail.setNext(node);\r\n node.setPrevious(this.tail);\r\n\r\n this.tail = node;\r\n }\r\n\r\n this.length++;\r\n\r\n\r\n /**\r\n * Get the node in the head.\r\n * @returns {JNode} node.\r\n */\r\n this.getFirst = () => {\r\n return this.head;\r\n }\r\n\r\n /**\r\n * Get the node in the tail.\r\n * @returns {JNode} node.\r\n */\r\n this.getLast = () => {\r\n return this.tail;\r\n }\r\n }\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (JLinkedList);\n\n//# sourceURL=webpack://johannes/./src/common/JLinkedList.js?"); + +/***/ }), + +/***/ "./src/common/JNode.js": /*!*****************************!*\ - !*** ./src/click-events.js ***! + !*** ./src/common/JNode.js ***! \*****************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _command_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./command-factory */ \"./src/command-factory.js\");\n/* harmony import */ var _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./text-formatting-bar-operation */ \"./src/text-formatting-bar-operation.js\");\n/* harmony import */ var _helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./helper */ \"./src/helper.js\");\n// The start point for click events\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nlet isMousedownKeyTrigger = false;\r\n\r\n// Block operations events\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n if (johannesEditor) {\r\n document.querySelectorAll('.block-operation').forEach(option => {\r\n option.addEventListener('click', function (event) {\r\n\r\n const operation = this.getAttribute('data-block-operation');\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(operation, [event]);\r\n\r\n command.execute();\r\n });\r\n });\r\n }\r\n});\r\n\r\n\r\n// Text operations events\r\n//CODE...\r\n\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n if (johannesEditor) {\r\n document.querySelectorAll('.text-formatting-operation').forEach(option => {\r\n option.addEventListener('click', function (event) {\r\n\r\n const operation = this.getAttribute('data-text-formatting-operation');\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(operation, [event]);\r\n\r\n command.execute();\r\n\r\n });\r\n });\r\n }\r\n});\r\n\r\n\r\n\r\n\r\ndocument.addEventListener('mousedown', function(event){\r\n if((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)){\r\n isMousedownKeyTrigger = true;\r\n }\r\n});\r\n\r\n//Mouse up + selection event\r\ndocument.addEventListener('mouseup', function (event) {\r\n if (window.getSelection().toString().trim() !== '' && isMousedownKeyTrigger && !(0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingTextFormattingBar)()) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n // clearTextFormattingButtonActive();\r\n // showTextFormattingBar(event);\r\n // updateTextFormattingActiveButtons();\r\n\r\n }\r\n});\r\n\r\n\r\n//\r\ndocument.addEventListener('mouseup', function (event) {\r\n if ((0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingTextFormattingBar)() && (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_1__.canHideTextFormattingBar)() && (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_1__.isOutOfTextFormattingBar)(event)) {\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n});\n\n//# sourceURL=webpack://johannes/./src/click-events.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/**\r\n * JNode is custom generic Johannes node\r\n */\r\nclass JNode {\r\n\r\n constructor(htmlElement) {\r\n this.previousNode;\r\n this.nextNode;\r\n\r\n /**\r\n * The HTML element of the component in the DOM.\r\n * @type {HTMLElement}\r\n */\r\n this.htmlElement = htmlElement;\r\n\r\n\r\n /**\r\n * Sets the next node.\r\n * If the input is not a JNode, an error is thrown.\r\n *\r\n * @param {JNode} node - The node to be set as the next item.\r\n * @throws {TypeError} Throws an error if the provided node is not an instance of JNode.\r\n */\r\n this.setNext = (node) => {\r\n if (!(node instanceof JNode)) {\r\n throw new TypeError(\"Expected an instance of JNode.\");\r\n }\r\n\r\n this.nextNode = node;\r\n }\r\n\r\n /**\r\n * Sets the previous node.\r\n * If the input is not a JNode, an error is thrown.\r\n *\r\n * @param {JNode} node - The node to be set as the previous item.\r\n * @throws {TypeError} Throws an error if the provided node is not an instance of JNode.\r\n */\r\n this.setPrevious = (node) => {\r\n if (!(node instanceof JNode)) {\r\n throw new TypeError(\"Expected an instance of JNode.\");\r\n }\r\n\r\n this.previousNode = node;\r\n }\r\n }\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (JNode);\n\n//# sourceURL=webpack://johannes/./src/common/JNode.js?"); /***/ }), -/***/ "./src/command-factory.js": -/*!********************************!*\ - !*** ./src/command-factory.js ***! - \********************************/ +/***/ "./src/components/quick-insert-menu/QuickInsertMenu.js": +/*!*************************************************************!*\ + !*** ./src/components/quick-insert-menu/QuickInsertMenu.js ***! + \*************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _QuickInsertMenuSection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./QuickInsertMenuSection */ \"./src/components/quick-insert-menu/QuickInsertMenuSection.js\");\n/* harmony import */ var _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./QuickInsertMenuItem */ \"./src/components/quick-insert-menu/QuickInsertMenuItem.js\");\n/* harmony import */ var _common_JCircularLinkedList__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../common/JCircularLinkedList */ \"./src/common/JCircularLinkedList.js\");\n\r\n\r\n\r\n\r\nclass QuickInsertMenu {\r\n\r\n constructor() {\r\n\r\n /**\r\n * The QuickInsertMenu element of the component in the DOM.\r\n * @type {HTMLElement}\r\n */\r\n this.htmlElement = document.createElement('div');\r\n this.htmlElement.id = 'blockOptionsWrapper';\r\n\r\n this.isShowing = false;\r\n\r\n /**\r\n * The QuickInsertMenuItem current focused.\r\n * @type {QuickInsertMenuItem|null}\r\n */\r\n this.currentFocusedMenuItem = null;\r\n\r\n /**\r\n * The QuickInsertMenuSection elements in a CircularLinkedList.\r\n * @type {JCircularLinkedList}\r\n */\r\n this.menuSections = new _common_JCircularLinkedList__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\r\n\r\n this.htmlElement.classList.add('block-options-wrapper', 'soft-box-shadow');\r\n this.htmlElement.style.display = 'none';\r\n\r\n const blockOptions = document.createElement('div');\r\n blockOptions.classList.add('block-options');\r\n blockOptions.style.position = 'relative';\r\n\r\n this.htmlElement.appendChild(blockOptions);\r\n\r\n const basicBlocksSection = new _QuickInsertMenuSection__WEBPACK_IMPORTED_MODULE_0__[\"default\"](this, 'Basic blocks', 'basic-section');\r\n\r\n basicBlocksSection.appendQuickInsertMenuItem([\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Paragraph', 'Just start writing with plain text.', 'icon-wordpress-paragraph', 'p'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Image', 'Just start writing with plain text.', 'icon-wordpress-paragraph', 'image'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Bulleted list', 'Organize items with bullet points.', 'icon-wordpress-bulleted-list', 'bulleted-list'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Numbered list', 'List items in a numbered format.', 'icon-wordpress-numbered-list', 'numbered-list'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Code', 'Insert code snippets with syntax highlighting.', 'icon-wordpress-code-mark', 'code'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Quote', 'Highlight text as a significant quote.', 'icon-wordpress-quote', 'quote'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Heading 2', 'Medium header for subsections.', 'icon-julia-head-2', 'h2'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Heading 3', 'Small header for detailed sections.', 'icon-julia-head-2', 'h3'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](basicBlocksSection, 'Separator', 'Visually divide blocks.', 'icon-wordpress-separator', 'separator')\r\n ]);\r\n\r\n this.menuSections.append(basicBlocksSection);\r\n blockOptions.appendChild(basicBlocksSection.htmlElement);\r\n\r\n\r\n const headingBlocksSection = new _QuickInsertMenuSection__WEBPACK_IMPORTED_MODULE_0__[\"default\"](this, 'Heading', 'heading-section');\r\n\r\n headingBlocksSection.appendQuickInsertMenuItem([\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 1', 'Large header to organize content.', 'icon-julia-head-1', 'h1'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 2', 'Medium header for subsections.', 'icon-julia-head-2', 'h2'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 3', 'Small header for detailed sections.', 'icon-julia-head-3', 'h3'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 4', 'Small header for detailed sections.', 'icon-julia-head-4', 'h4'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 5', 'Small header for detailed sections.', 'icon-julia-head-5', 'h5'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](headingBlocksSection, 'Heading 6', 'Small header for detailed sections.', 'icon-julia-head-6', 'h6'),\r\n ]);\r\n\r\n this.menuSections.append(headingBlocksSection);\r\n blockOptions.appendChild(headingBlocksSection.htmlElement);\r\n\r\n\r\n const listBlocksSection = new _QuickInsertMenuSection__WEBPACK_IMPORTED_MODULE_0__[\"default\"](this, 'List', 'list-section');\r\n\r\n listBlocksSection.appendQuickInsertMenuItem([\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](listBlocksSection, 'Todo list', 'Organize items with bullet points.', 'icon-material-check-list', 'todo-list'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](listBlocksSection, 'Bulleted list', 'Organize items with bullet points.', 'icon-wordpress-bulleted-list', 'bulleted-list'),\r\n new _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"](listBlocksSection, 'Numbered list', 'List items in a numbered format.', 'icon-wordpress-numbered-list', 'numbered-list')\r\n ]);\r\n\r\n this.menuSections.append(listBlocksSection);\r\n blockOptions.appendChild(listBlocksSection.htmlElement);\r\n\r\n\r\n /**\r\n * Change the current fake focus and remove the current fake focus.\r\n * If the input is not a QuickInsertMenuItem or contains an item that is not a QuickInsertMenuItem, an error is thrown.\r\n *\r\n * @param {QuickInsertMenuItem} menuItems The item(s) to be focused.\r\n * @throws {TypeError} Throws an 'Expected an instance of QuickInsertMenuItem. if item is not a QuickInsertMenuItem.\r\n */\r\n this.changeFocus = (item) => {\r\n\r\n if (!(item instanceof _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"])) {\r\n throw new TypeError(\"Expected an instance of QuickInsertMenuItem.\");\r\n }\r\n\r\n if (this.currentFocusedMenuItem == item) {\r\n return;\r\n }\r\n\r\n if (this.currentFocusedMenuItem) {\r\n this.currentFocusedMenuItem.removeFocus();\r\n }\r\n\r\n this.currentFocusedMenuItem = item;\r\n this.currentFocusedMenuItem.focus();\r\n }\r\n\r\n /**\r\n * Move the fake focus menu indication to the next element.\r\n * If no element is currently focused the first QuickInsertMenuItem is used.\r\n */\r\n this.moveTheFakeFocusToTheNextMenuItem = () => {\r\n\r\n let nextItem;\r\n\r\n if (!this.currentFocusedMenuItem) {\r\n\r\n nextItem = this.menuSections.getFirst().getFirstMenuItem();\r\n } else {\r\n\r\n nextItem = this.currentFocusedMenuItem.nextNode;\r\n\r\n if (!nextItem) {\r\n nextItem = this.currentFocusedMenuItem.quickInsertMenuSectionInstance.nextNode.getFirstMenuItem();\r\n }\r\n }\r\n\r\n this.changeFocus(nextItem);\r\n }\r\n\r\n /**\r\n * Get the QuickInsertMenu HTML Element.\r\n * @returns {HTMLElement} htmlElement.\r\n */\r\n this.getMenuElement = () => {\r\n return this.htmlElement;\r\n }\r\n\r\n this.attachEvents = () => {\r\n\r\n document.addEventListener('keydown', (event) => {\r\n if (event.key === '/' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n alert('show the Quick Insert Menu');\r\n }\r\n });\r\n }\r\n\r\n this.attachEvents();\r\n }\r\n\r\n\r\n showMenu() {\r\n\r\n // The timeout in necessary to wait the browser process the selection before show the Block Options\r\n setTimeout(() => {\r\n\r\n const realFocusedElement = document.activeElement;\r\n const currentDraggableBlock = realFocusedElement.closest('.draggable-block');\r\n const firstBlockOption = getTheFirstVisibleBlockOption();\r\n\r\n setRealFocusedElement(realFocusedElement);\r\n setCurrentDraggableBlock(currentDraggableBlock);\r\n setCurrentFakeFocusElement(firstBlockOption);\r\n\r\n applyVisualFakeFocus(realFocusedElement, firstBlockOption);\r\n\r\n\r\n //TODO: create a clear filter\r\n // removeDisplayNoneFromAllBlockOptions();\r\n\r\n const range = document.getSelection().getRangeAt(0);\r\n const cursorPos = range.getBoundingClientRect();\r\n\r\n const remSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\r\n const menuWidth = 19 * remSize;\r\n\r\n let xPosition = cursorPos.right;\r\n let yPosition = cursorPos.bottom + window.scrollY;\r\n\r\n const margin = remSize * 1.25;\r\n\r\n blockOptionsWrapper.style.display = 'block';\r\n\r\n let blockWidth = blockOptionsWrapper.offsetWidth;\r\n\r\n\r\n if (xPosition + blockWidth + margin > window.innerWidth) {\r\n xPosition = cursorPos.left - menuWidth;\r\n if (xPosition < 0) xPosition = 0;\r\n }\r\n\r\n blockOptionsWrapper.style.left = `${xPosition}px`;\r\n blockOptionsWrapper.style.top = `${yPosition}px`;\r\n\r\n\r\n }, 10);\r\n }\r\n\r\n\r\n\r\n\r\n}\r\n\r\nconst instance = new QuickInsertMenu();\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (instance);\n\n//# sourceURL=webpack://johannes/./src/components/quick-insert-menu/QuickInsertMenu.js?"); + +/***/ }), + +/***/ "./src/components/quick-insert-menu/QuickInsertMenuItem.js": +/*!*****************************************************************!*\ + !*** ./src/components/quick-insert-menu/QuickInsertMenuItem.js ***! + \*****************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _helperDOM__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helperDOM */ \"./src/components/quick-insert-menu/helperDOM.js\");\n/* harmony import */ var _common_JNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../common/JNode */ \"./src/common/JNode.js\");\n/* harmony import */ var _QuickInsertMenuSection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./QuickInsertMenuSection */ \"./src/components/quick-insert-menu/QuickInsertMenuSection.js\");\n\r\n\r\n\r\n\r\nclass QuickInsertMenuItem extends _common_JNode__WEBPACK_IMPORTED_MODULE_1__[\"default\"] {\r\n\r\n constructor(quickInsertMenuSectionInstance, itemName, itemDescription, SVGHrefUseId, dataType) {\r\n\r\n // if (!(quickInsertMenuSectionInstance instanceof QuickInsertMenuSection)) {\r\n // throw new TypeError(\"Expected an instance of QuickInsertMenuSection.\");\r\n // }\r\n\r\n /**\r\n * The QuickInsertMenuItem element of the component in the DOM.\r\n * @type {HTMLElement}\r\n */\r\n const htmlElement = document.createElement('div');\r\n htmlElement.classList.add('option', 'option-hover', 'block-operation');\r\n\r\n super(htmlElement);\r\n\r\n /**\r\n * The QuickInsertMenuSection parent.\r\n * @type {QuickInsertMenuSection}\r\n */\r\n this.quickInsertMenuSectionInstance = quickInsertMenuSectionInstance;\r\n\r\n htmlElement.setAttribute('data-block-operation', 'apply-selected-block-type');\r\n htmlElement.setAttribute('data-type', dataType);\r\n htmlElement.setAttribute('tabindex', '0');\r\n htmlElement.setAttribute('role', 'option');\r\n\r\n const optionImage = document.createElement('div');\r\n optionImage.classList.add('option-image');\r\n\r\n const svg = _helperDOM__WEBPACK_IMPORTED_MODULE_0__.createSVG(SVGHrefUseId, '', '100%', '100%');\r\n\r\n optionImage.appendChild(svg);\r\n\r\n htmlElement.appendChild(optionImage);\r\n\r\n\r\n const optionText = document.createElement('div');\r\n optionText.classList.add('option-text');\r\n\r\n const blockTitle = document.createElement('p');\r\n blockTitle.classList.add('block-title');\r\n blockTitle.innerText = itemName;\r\n\r\n optionText.appendChild(blockTitle);\r\n\r\n const blockDescription = document.createElement('p');\r\n blockDescription.classList.add('block-description');\r\n blockDescription.innerText = itemDescription;\r\n\r\n optionText.appendChild(blockDescription);\r\n\r\n htmlElement.appendChild(optionText);\r\n\r\n\r\n /** Apply a fake focus in the element */\r\n this.focus = () => {\r\n this.htmlElement.classList.add('block-options-focused');\r\n this.htmlElement.focus();\r\n }\r\n\r\n this.removeFocus = () => {\r\n this.htmlElement.classList.remove('block-options-focused');\r\n }\r\n\r\n this.attachEvents = () => {\r\n this.htmlElement.addEventListener('mousemove', () => {\r\n this.quickInsertMenuSectionInstance.quickInsertMenuInstance.changeFocus(this);\r\n });\r\n }\r\n\r\n this.attachEvents();\r\n }\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (QuickInsertMenuItem);\n\n//# sourceURL=webpack://johannes/./src/components/quick-insert-menu/QuickInsertMenuItem.js?"); + +/***/ }), + +/***/ "./src/components/quick-insert-menu/QuickInsertMenuSection.js": +/*!********************************************************************!*\ + !*** ./src/components/quick-insert-menu/QuickInsertMenuSection.js ***! + \********************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/* harmony import */ var _QuickInsertMenu__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./QuickInsertMenu */ \"./src/components/quick-insert-menu/QuickInsertMenu.js\");\n/* harmony import */ var _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./QuickInsertMenuItem */ \"./src/components/quick-insert-menu/QuickInsertMenuItem.js\");\n/* harmony import */ var _common_JLinkedList__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../common/JLinkedList */ \"./src/common/JLinkedList.js\");\n/* harmony import */ var _common_JNode__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../common/JNode */ \"./src/common/JNode.js\");\n\r\n\r\n\r\n\r\n\r\n/**\r\n * Represents a section within a QuickInsertMenu, acting as a node in a doubly-linked list.\r\n * Each section contains a collection of QuickInsertMenuItem nodes, managed as a linked list with references to both the head and tail of the list.\r\n * This setup facilitates efficient addition and removal of items at both ends of the list.\r\n *\r\n * @class QuickInsertMenuSection\r\n * @property {HTMLElement} htmlElement - The DOM element representing the section in the UI.\r\n * @property {QuickInsertMenuItem[]} menuItems - An array of menu items contained within the section.\r\n * @property {QuickInsertMenuItem} #head - Private field holding a reference to the first QuickInsertMenuItem in the section.\r\n * @property {QuickInsertMenuItem} #tail - Private field holding a reference to the last QuickInsertMenuItem in the section.\r\n */\r\nclass QuickInsertMenuSection extends _common_JNode__WEBPACK_IMPORTED_MODULE_3__[\"default\"] {\r\n\r\n constructor(quickInsertMenuInstance, sectionName, classList) {\r\n\r\n // if (!(quickInsertMenuInstance instanceof QuickInsertMenu)) {\r\n // throw new TypeError(\"Expected an instance of QuickInsertMenu.\");\r\n // }\r\n\r\n /**\r\n * The QuickInsertMenuSection element of the component in the DOM.\r\n * @type {HTMLElement}\r\n */\r\n let htmlElement = document.createElement('section');\r\n htmlElement.classList.add(classList);\r\n\r\n super(htmlElement);\r\n\r\n /**\r\n * The QuickInsertMenu parent.\r\n * @type {QuickInsertMenu}\r\n */\r\n this.quickInsertMenuInstance = quickInsertMenuInstance;\r\n\r\n let heading = document.createElement('h2');\r\n heading.textContent = sectionName;\r\n\r\n /**\r\n * The QuickInsertMenuItem elements in a LinkedList.\r\n * @type {JLinkedList}\r\n */\r\n this.menuItems = new _common_JLinkedList__WEBPACK_IMPORTED_MODULE_2__[\"default\"]();\r\n\r\n htmlElement.appendChild(heading);\r\n\r\n /**\r\n * Inserts a QuickInsertMenuItem or an array of QuickInsertMenuItems into the menu.\r\n * If the input is not a QuickInsertMenuItem or contains an item that is not a QuickInsertMenuItem, an error is thrown.\r\n *\r\n * @param {QuickInsertMenuItem|QuickInsertMenuItem[]} menuItems The item(s) to be inserted.\r\n * @throws {Error} Throws an 'Out Of Range Exception' if any item is not a QuickInsertMenuItem.\r\n */\r\n this.appendQuickInsertMenuItem = (menuItems) => {\r\n\r\n if (Array.isArray(menuItems)) {\r\n menuItems.forEach(item => {\r\n\r\n if (!(item instanceof _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"])) {\r\n throw new Error('Out Of Range Exception');\r\n }\r\n\r\n this.menuItems.append(item);\r\n this.htmlElement.appendChild(item.htmlElement);\r\n });\r\n } else {\r\n\r\n if (!(item instanceof _QuickInsertMenuItem__WEBPACK_IMPORTED_MODULE_1__[\"default\"])) {\r\n throw new Error('Out Of Range Exception');\r\n }\r\n\r\n this.menuItems.append(menuItems);\r\n this.htmlElement.appendChild(menuItems.htmlElement);\r\n }\r\n }\r\n\r\n /**\r\n * Gets the first item from the list of menu items.\r\n * @returns {QuickInsertMenuItem|null} The first menu item if the list is not empty, or null if it is empty.\r\n */\r\n this.getFirstMenuItem = () => {\r\n if (this.menuItems.length) {\r\n return this.menuItems.getFirst();\r\n } else {\r\n return null;\r\n }\r\n }\r\n }\r\n}\r\n\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (QuickInsertMenuSection);\n\n//# sourceURL=webpack://johannes/./src/components/quick-insert-menu/QuickInsertMenuSection.js?"); + +/***/ }), + +/***/ "./src/components/quick-insert-menu/helperDOM.js": +/*!*******************************************************!*\ + !*** ./src/components/quick-insert-menu/helperDOM.js ***! + \*******************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ OPERATIONS: () => (/* binding */ OPERATIONS),\n/* harmony export */ createCommand: () => (/* binding */ createCommand),\n/* harmony export */ getBlockOperationFunction: () => (/* binding */ getBlockOperationFunction),\n/* harmony export */ operationMap: () => (/* binding */ operationMap)\n/* harmony export */ });\n/* harmony import */ var _block_operation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./block-operation */ \"./src/block-operation.js\");\n/* harmony import */ var _block_options_operation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block-options-operation */ \"./src/block-options-operation.js\");\n/* harmony import */ var _j_window__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./j-window */ \"./src/j-window.js\");\n/* harmony import */ var _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./text-formatting-bar-operation */ \"./src/text-formatting-bar-operation.js\");\n\r\n\r\n\r\n\r\n\r\n\r\nfunction createCommand(operationName, elements = null) {\r\n return new Command(operationName, elements);\r\n}\r\n\r\nclass Command {\r\n\r\n constructor(operationName, elements) {\r\n this.elements = elements;\r\n this.operation = getBlockOperationFunction(operationName);\r\n }\r\n\r\n execute() {\r\n if (this.elements !== null) {\r\n this.operation(...this.elements);\r\n } else {\r\n this.operation();\r\n }\r\n }\r\n}\r\n\r\nconst OPERATIONS = {\r\n BLOCK: {\r\n CREATE_LIST_ELEMENT: 'create-list-element',\r\n CREATE_NEW_ELEMENT: 'create-new-element',\r\n DELETE_DRAGGABLE_BLOCK: 'delete-draggable-block',\r\n DELETE_AND_FOCUS_ON_NEXT: 'delete-and-focus-on-next',\r\n DELETE_AND_FOCUS_ON_PREVIOUS: 'delete-and-focus-on-previous',\r\n DUPLICATE_SELECTED_BLOCK: 'duplicate-selected-block',\r\n TRANSFORM_BLOCK: 'transform-block',\r\n MOVE_UP_BLOCK: 'move-up-block',\r\n MOVE_DOWN_BLOCK: 'move-down-block',\r\n SHOW_TURN_INTO_BOX: 'show-turn-into-box',\r\n SHOW_COLOR_BOX: 'show-color-box',\r\n SHOW_MORE_OPTIONS_BOX: 'show-more-options-box'\r\n },\r\n BLOCK_OPTIONS: {\r\n SHOW_BLOCK_OPTIONS: 'show-block-options',\r\n HIDE_CLEAR_BLOCK_OPTIONS: 'hide-clear-block-options',\r\n MOVE_FAKE_FOCUS_TO_NEXT_OPTION: 'move-fake-focus-to-next-option',\r\n MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION: 'move-fake-focus-to-previous-option',\r\n APPLY_SELECTED_BLOCK_TYPE: 'apply-selected-block-type',\r\n FILTER_CONCAT: 'filter-contact',\r\n FILTER_REMOVE_LAST: 'filter-remove-last',\r\n },\r\n FORMATTING_BAR: {\r\n SHOW_TEXT_FORMATTING_BAR: 'show-text-formatting-bar',\r\n HIDE_TEXT_FORMATTING_BAR: 'hide-text-formatting-bar',\r\n TOGGLE_MORE_OPTIONS_BOX: 'toggle-more-options-box',\r\n TOGGLE_CHANGE_COLOR_BOX: 'toggle-change-color-box',\r\n TOGGLE_TURN_INTO_BOX: 'toggle-turn-into-box',\r\n TOGGLE_INPUT_LINK_BOX: 'toggle-input-link-box',\r\n INPUT_LINK_URL: 'input-link-url', \r\n TOGGLE_ENCLOSE_SELECTED_TEXT_TO: 'toggle-enclose-selected-text-to',\r\n },\r\n\r\n};\r\n\r\nconst operationMap = {\r\n [OPERATIONS.BLOCK.CREATE_LIST_ELEMENT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.createListItem,\r\n [OPERATIONS.BLOCK.CREATE_NEW_ELEMENT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.createNewElement,\r\n [OPERATIONS.BLOCK.DELETE_DRAGGABLE_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteDraggableParentBlock,\r\n [OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_NEXT]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteAndFocusOnNext,\r\n [OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_PREVIOUS]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.deleteAndFocusOnPrevious,\r\n [OPERATIONS.BLOCK.DUPLICATE_SELECTED_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.duplicateSelectedBlock,\r\n [OPERATIONS.BLOCK.TRANSFORM_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.BLOCK.MOVE_UP_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.moveUpBlock,\r\n [OPERATIONS.BLOCK.MOVE_DOWN_BLOCK]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.moveDownBlock,\r\n [OPERATIONS.BLOCK_OPTIONS.SHOW_BLOCK_OPTIONS]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.showMainBlockOptions,\r\n [OPERATIONS.BLOCK_OPTIONS.HIDE_CLEAR_BLOCK_OPTIONS]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.hideAndClearBlockOptions,\r\n [OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.moveTheFakeFocusToTheNextBlockOption,\r\n [OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.moveTheFakeFocusToPreviousBlockOption,\r\n [OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.applySelectedBlockType,\r\n [OPERATIONS.BLOCK_OPTIONS.FILTER_CONCAT]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.filterContact,\r\n [OPERATIONS.BLOCK_OPTIONS.FILTER_REMOVE_LAST]: _block_options_operation__WEBPACK_IMPORTED_MODULE_1__.filterRemoveLast,\r\n [OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.showTextFormattingBar,\r\n [OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.hideTextFormattingBar,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_MORE_OPTIONS_BOX]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.toggleMoreOptionsBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_CHANGE_COLOR_BOX]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.toggleChangeColorBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_TURN_INTO_BOX]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.toggleTurnIntoBox,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_INPUT_LINK_BOX]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.toggleInputLinkBox,\r\n [OPERATIONS.FORMATTING_BAR.INPUT_LINK_URL]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.inputLinkUrl,\r\n [OPERATIONS.FORMATTING_BAR.TOGGLE_ENCLOSE_SELECTED_TEXT_TO]: _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.toggleEncloseSelectedTextTo,\r\n [OPERATIONS.SHOW_TURN_INTO_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.SHOW_COLOR_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock,\r\n [OPERATIONS.SHOW_MORE_OPTIONS_BOX]: _block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock\r\n};\r\n\r\nfunction getBlockOperationFunction(blockOperation) {\r\n const operationFunction = operationMap[blockOperation];\r\n if (!operationFunction) {\r\n throw new Error('Operation Not Found Exception');\r\n }\r\n return operationFunction;\r\n}\n\n//# sourceURL=webpack://johannes/./src/command-factory.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createSVG: () => (/* binding */ createSVG)\n/* harmony export */ });\nfunction createSVG(hrefUseId, classList = \"\", width = 16, height = 16) {\r\n\r\n if (!hrefUseId) {\r\n throw new Error('Invalid Argument Exception');\r\n }\r\n\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n\r\n if (classList && classList.trim() !== \"\") {\r\n const classes = classList.split(',');\r\n svg.classList.add(...classes);\r\n }\r\n\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", `#${hrefUseId}`);\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', width);\r\n svg.setAttribute('height', height);\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n return svg;\r\n}\n\n//# sourceURL=webpack://johannes/./src/components/quick-insert-menu/helperDOM.js?"); + +/***/ }), + +/***/ "./src/components/quick-insert-menu/quick-insert-menu.js": +/*!***************************************************************!*\ + !*** ./src/components/quick-insert-menu/quick-insert-menu.js ***! + \***************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ applySelectedBlockType: () => (/* binding */ applySelectedBlockType),\n/* harmony export */ clear: () => (/* binding */ clear),\n/* harmony export */ filterContact: () => (/* binding */ filterContact),\n/* harmony export */ filterRemoveLast: () => (/* binding */ filterRemoveLast),\n/* harmony export */ hideAndClearBlockOptions: () => (/* binding */ hideAndClearBlockOptions),\n/* harmony export */ isShowingBlockOptions: () => (/* binding */ isShowingBlockOptions),\n/* harmony export */ moveTheFakeFocusToPreviousBlockOption: () => (/* binding */ moveTheFakeFocusToPreviousBlockOption),\n/* harmony export */ moveTheFakeFocusToTheNextBlockOption: () => (/* binding */ moveTheFakeFocusToTheNextBlockOption),\n/* harmony export */ removeDisplayNoneFromAllBlockOptions: () => (/* binding */ removeDisplayNoneFromAllBlockOptions),\n/* harmony export */ setCurrentDraggableBlock: () => (/* binding */ setCurrentDraggableBlock),\n/* harmony export */ setCurrentFakeFocusElement: () => (/* binding */ setCurrentFakeFocusElement),\n/* harmony export */ setRealFocusedElement: () => (/* binding */ setRealFocusedElement),\n/* harmony export */ showDependentBlockOptions: () => (/* binding */ showDependentBlockOptions),\n/* harmony export */ showMainBlockOptions: () => (/* binding */ showMainBlockOptions)\n/* harmony export */ });\n/* harmony import */ var _block_operation__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../block-operation */ \"./src/block-operation.js\");\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../text-formatting-bar/text-formatting-bar */ \"./src/components/text-formatting-bar/text-formatting-bar.js\");\n\r\n\r\n\r\n\r\n\r\nlet currentDraggableBlock = null; //This element represents the block where block-options will be displayed close to\r\nlet currentFakeFocusedOption = null; //Fake focus is where the visual focus in on\r\nlet realFocusedElement = null; // This element is where the real/actual focus is on / TODO: change the name\r\nlet filterText = '';\r\n\r\nfunction isShowingBlockOptions() {\r\n return blockOptionsWrapper.style.display !== 'none'\r\n}\r\n\r\nfunction setCurrentDraggableBlock(element) {\r\n if (!element.classList.contains('draggable-block')) {\r\n throw new Error('The Element is Not a Draggable Block');\r\n }\r\n\r\n currentDraggableBlock = element;\r\n}\r\n\r\nfunction setRealFocusedElement(element) {\r\n realFocusedElement = element;\r\n}\r\n\r\nfunction setCurrentFakeFocusElement(element) {\r\n currentFakeFocusedOption = element;\r\n}\r\n\r\nfunction filterContact(event) {\r\n\r\n filterText += event.key.toLowerCase();\r\n\r\n updateBlockVisibility(filterText);\r\n\r\n const firstVisibleOption = getTheFirstVisibleBlockOption();\r\n removeAllVisualFakeFocus();\r\n\r\n setCurrentFakeFocusElement(firstVisibleOption);\r\n applyVisualFakeFocus(realFocusedElement, firstVisibleOption);\r\n}\r\n\r\nfunction filterRemoveLast() {\r\n\r\n if (filterText.length > 0) {\r\n\r\n filterText = filterText.slice(0, -1);\r\n\r\n updateBlockVisibility(filterText);\r\n\r\n const firstVisibleOption = getTheFirstVisibleBlockOption();\r\n removeAllVisualFakeFocus();\r\n\r\n setCurrentFakeFocusElement(firstVisibleOption);\r\n applyVisualFakeFocus(realFocusedElement, firstVisibleOption);\r\n\r\n } else {\r\n hideAndClearBlockOptions();\r\n }\r\n}\r\n\r\nfunction clear() {\r\n throw new Error('Not Implement Exception')\r\n}\r\n\r\nfunction showDependentBlockOptions(element) {\r\n // The timeout in necessary to wait the browser process the selection before show the Block Options\r\n setTimeout(() => {\r\n\r\n removeAllVisualFakeFocus();\r\n\r\n let draggableBlock = (0,_j_selection__WEBPACK_IMPORTED_MODULE_1__.getCurrentDraggableBlockFocused)();\r\n\r\n const realFocusedElement = draggableBlock.querySelector('.focusable');\r\n const currentDraggableBlock = draggableBlock;\r\n const firstBlockOption = getTheFirstVisibleBlockOptionV2(element);\r\n\r\n setRealFocusedElement(realFocusedElement);\r\n setCurrentDraggableBlock(currentDraggableBlock);\r\n setCurrentFakeFocusElement(null);\r\n\r\n applyVisualFakeFocus(realFocusedElement, null);\r\n\r\n }, 10);\r\n}\r\n\r\nfunction showMainBlockOptions() {\r\n\r\n // The timeout in necessary to wait the browser process the selection before show the Block Options\r\n setTimeout(() => {\r\n\r\n const realFocusedElement = document.activeElement;\r\n const currentDraggableBlock = realFocusedElement.closest('.draggable-block');\r\n const firstBlockOption = getTheFirstVisibleBlockOption();\r\n\r\n setRealFocusedElement(realFocusedElement);\r\n setCurrentDraggableBlock(currentDraggableBlock);\r\n setCurrentFakeFocusElement(firstBlockOption);\r\n\r\n applyVisualFakeFocus(realFocusedElement, firstBlockOption);\r\n\r\n\r\n //TODO: create a clear filter\r\n // removeDisplayNoneFromAllBlockOptions();\r\n\r\n const range = document.getSelection().getRangeAt(0);\r\n const cursorPos = range.getBoundingClientRect();\r\n\r\n const remSize = parseFloat(getComputedStyle(document.documentElement).fontSize);\r\n const menuWidth = 19 * remSize;\r\n\r\n let xPosition = cursorPos.right;\r\n let yPosition = cursorPos.bottom + window.scrollY;\r\n\r\n const margin = remSize * 1.25;\r\n\r\n blockOptionsWrapper.style.display = 'block';\r\n\r\n let blockWidth = blockOptionsWrapper.offsetWidth;\r\n\r\n\r\n if (xPosition + blockWidth + margin > window.innerWidth) {\r\n xPosition = cursorPos.left - menuWidth;\r\n if (xPosition < 0) xPosition = 0;\r\n }\r\n\r\n blockOptionsWrapper.style.left = `${xPosition}px`;\r\n blockOptionsWrapper.style.top = `${yPosition}px`;\r\n\r\n\r\n }, 10);\r\n}\r\n\r\nfunction hideAndClearBlockOptions(elementToFocus) {\r\n\r\n if (elementToFocus) {\r\n elementToFocus.focus();\r\n }\r\n\r\n blockOptionsWrapper.style.display = 'none';\r\n clearFilter();\r\n\r\n //TODO: rename this\r\n removeDisplayNoneFromAllBlockOptions();\r\n}\r\n\r\n\r\n\r\n// TODO:Rename this function\r\nfunction removeDisplayNoneFromAllBlockOptions() {\r\n let sections = document.querySelectorAll('.johannes-editor .block-options-wrapper section');\r\n\r\n sections.forEach(section => {\r\n let options = section.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.style.display = '';\r\n });\r\n\r\n section.style.display = '';\r\n });\r\n}\r\n\r\nfunction moveTheFakeFocusToPreviousBlockOption() {\r\n\r\n if (!currentFakeFocusedOption) {\r\n let options = document.getElementById(getVisibleSelectionId()).querySelectorAll('.option');\r\n currentFakeFocusedOption = options[options.length - 1];\r\n\r\n applyVisualFakeFocus(realFocusedElement, currentFakeFocusedOption);\r\n\r\n return;\r\n }\r\n\r\n let previous = currentFakeFocusedOption.previousElementSibling;\r\n\r\n while (previous && (!previous.classList.contains('option') || !isElementVisible(previous))) {\r\n previous = previous.previousElementSibling;\r\n }\r\n\r\n if (!previous) {\r\n let currentSection = currentFakeFocusedOption.closest('section');\r\n let siblingSection;\r\n\r\n if (currentSection) {\r\n siblingSection = currentSection.previousElementSibling;\r\n } else {\r\n siblingSection = currentFakeFocusedOption.closest('ul');\r\n }\r\n\r\n while (siblingSection) {\r\n let options = siblingSection.querySelectorAll('.option');\r\n for (let i = options.length - 1; i >= 0; i--) {\r\n if (isElementVisible(options[i])) {\r\n previous = options[i];\r\n break;\r\n }\r\n }\r\n if (previous) break;\r\n siblingSection = siblingSection.previousElementSibling;\r\n }\r\n\r\n if (!previous) {\r\n let options = document.querySelectorAll('.block-options-wrapper .option');\r\n for (let i = options.length - 1; i >= 0; i--) {\r\n if (isElementVisible(options[i])) {\r\n previous = options[i];\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n\r\n removeAllVisualFakeFocus();\r\n setCurrentFakeFocusElement(previous);\r\n applyVisualFakeFocus(realFocusedElement, previous);\r\n}\r\n\r\n\r\nfunction getVisibleSelectionId() {\r\n if (turnIntoSelect.style.display !== 'none') {\r\n return 'turnIntoSelect';\r\n }\r\n\r\n if (colorTextOptionSelect.style.display !== 'none') {\r\n return 'colorTextOptionSelect';\r\n }\r\n\r\n if (moreTextOptionSelect.style.display !== 'none') {\r\n return 'moreTextOptionSelect';\r\n }\r\n}\r\n\r\nfunction moveTheFakeFocusToTheNextBlockOption() {\r\n\r\n if (!currentFakeFocusedOption) {\r\n currentFakeFocusedOption = document.getElementById(getVisibleSelectionId()).querySelectorAll('.option')[0];\r\n\r\n applyVisualFakeFocus(realFocusedElement, currentFakeFocusedOption);\r\n\r\n return;\r\n }\r\n\r\n let next = currentFakeFocusedOption.nextElementSibling;\r\n\r\n while (next && (!next.classList.contains('option') || !isElementVisible(next))) {\r\n next = next.nextElementSibling;\r\n }\r\n\r\n if (!next) {\r\n let currentSection = currentFakeFocusedOption.closest('section');\r\n let siblingSection;\r\n\r\n if (currentSection) {\r\n siblingSection = currentSection.nextElementSibling;\r\n } else {\r\n siblingSection = currentFakeFocusedOption.closest('ul');\r\n }\r\n\r\n while (siblingSection) {\r\n next = siblingSection.querySelector('.option');\r\n if (next && isElementVisible(next)) {\r\n break;\r\n }\r\n siblingSection = siblingSection.nextElementSibling;\r\n }\r\n\r\n if (!next) {\r\n next = document.querySelector('.block-options-wrapper .option');\r\n while (next && !isElementVisible(next)) {\r\n next = next.nextElementSibling;\r\n }\r\n }\r\n }\r\n\r\n removeAllVisualFakeFocus();\r\n setCurrentFakeFocusElement(next);\r\n applyVisualFakeFocus(realFocusedElement, next);\r\n}\r\n\r\n\r\nfunction applySelectedBlockType(event) {\r\n\r\n const draggableBlock = realFocusedElement.closest('.draggable-block');\r\n const newBlockType = event.target.closest('.option') ?\r\n event.target.closest('.option').getAttribute('data-type') :\r\n currentFakeFocusedOption.getAttribute('data-type');\r\n\r\n const lastSlashIndex = realFocusedElement.innerText.lastIndexOf('/');\r\n realFocusedElement.innerText = lastSlashIndex !== -1 ? realFocusedElement.innerText.slice(0, lastSlashIndex) : realFocusedElement.innerText;\r\n\r\n\r\n (0,_block_operation__WEBPACK_IMPORTED_MODULE_0__.transformBlock)(draggableBlock, newBlockType);\r\n\r\n hideAndClearBlockOptions();\r\n (0,_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_2__.hideAllDependentBox)();\r\n (0,_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_2__.hideTextFormattingBar)();\r\n}\r\n\r\nfunction clearFilter() {\r\n filterText = '';\r\n}\r\n\r\nfunction isElementVisible(element) {\r\n return element && element.style.display !== 'none' && element.style.visibility !== 'hidden' && element.offsetParent !== null;\r\n}\r\n\r\nfunction getTheFirstVisibleBlockOptionV2(element) {\r\n\r\n let button = element.closest('button');\r\n let listId = button.getAttribute('aria-controls');\r\n let list = document.querySelector(`#${listId}`);\r\n\r\n let options = list.querySelectorAll('.option');\r\n\r\n // for (let option of options) {\r\n // if (option.style.display !== 'none') {\r\n // return option;\r\n // }\r\n // }\r\n\r\n return options[0];\r\n\r\n}\r\n\r\nfunction getTheFirstVisibleBlockOption() {\r\n\r\n let options = blockOptionsWrapper.querySelectorAll('.option');\r\n\r\n for (let option of options) {\r\n if (option.style.display !== 'none') {\r\n return option;\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\nfunction applyVisualFakeFocus(realFocusedElement, elementToApplyFakeFocus) {\r\n\r\n if (elementToApplyFakeFocus) {\r\n elementToApplyFakeFocus.focus();\r\n elementToApplyFakeFocus.classList.add('block-options-focused');\r\n }\r\n\r\n realFocusedElement.focus();\r\n}\r\n\r\n// function applyVisualFakeAndRealFocus(elementToApplyFakeFocus) {\r\n\r\n// if (elementToApplyFakeFocus) {\r\n// elementToApplyFakeFocus.focus();\r\n// elementToApplyFakeFocus.classList.add('block-options-focused');\r\n// }\r\n// }\r\n\r\nfunction removeAllVisualFakeFocus() {\r\n let focusedElements = document.querySelectorAll('.block-options-focused');\r\n\r\n focusedElements.forEach(element => {\r\n element.classList.remove('block-options-focused');\r\n });\r\n}\r\n\r\nfunction updateBlockVisibility(filter) {\r\n\r\n let sections = blockOptionsWrapper.querySelectorAll('section');\r\n\r\n sections.forEach(section => {\r\n let options = section.querySelectorAll('.option');\r\n let allHidden = true;\r\n\r\n options.forEach(option => {\r\n const type = option.getAttribute('data-type');\r\n const title = option.querySelector('.block-title').textContent.toLowerCase();\r\n\r\n if (type.includes(filter) || title.includes(filter.toLowerCase())) {\r\n option.style.display = '';\r\n allHidden = false;\r\n } else {\r\n option.style.display = 'none';\r\n }\r\n });\r\n\r\n section.style.display = allHidden ? 'none' : '';\r\n });\r\n\r\n let emptyListIndicator = document.querySelector('.empty-block-options');\r\n\r\n let allOptions = blockOptionsWrapper.querySelectorAll('.option');\r\n\r\n let hasVisibleOption = Array.from(allOptions).some(option => {\r\n let style = window.getComputedStyle(option);\r\n return style.display !== 'none';\r\n });\r\n\r\n if (hasVisibleOption) {\r\n emptyListIndicator.style.display = 'none';\r\n\r\n } else {\r\n emptyListIndicator.style.display = 'block';\r\n }\r\n}\n\n//# sourceURL=webpack://johannes/./src/components/quick-insert-menu/quick-insert-menu.js?"); + +/***/ }), + +/***/ "./src/components/text-formatting-bar/text-formatting-bar.js": +/*!*******************************************************************!*\ + !*** ./src/components/text-formatting-bar/text-formatting-bar.js ***! + \*******************************************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ canHideTextFormattingBar: () => (/* binding */ canHideTextFormattingBar),\n/* harmony export */ hideAllDependentBox: () => (/* binding */ hideAllDependentBox),\n/* harmony export */ hideTextFormattingBar: () => (/* binding */ hideTextFormattingBar),\n/* harmony export */ inputLinkUrl: () => (/* binding */ inputLinkUrl),\n/* harmony export */ isOutOfTextFormattingBar: () => (/* binding */ isOutOfTextFormattingBar),\n/* harmony export */ isShowingTextFormattingBar: () => (/* binding */ isShowingTextFormattingBar),\n/* harmony export */ isShowingTextFormattingSelectableDependentBox: () => (/* binding */ isShowingTextFormattingSelectableDependentBox),\n/* harmony export */ showTextFormattingBar: () => (/* binding */ showTextFormattingBar),\n/* harmony export */ toggleChangeColorBox: () => (/* binding */ toggleChangeColorBox),\n/* harmony export */ toggleEncloseSelectedTextTo: () => (/* binding */ toggleEncloseSelectedTextTo),\n/* harmony export */ toggleInputLinkBox: () => (/* binding */ toggleInputLinkBox),\n/* harmony export */ toggleMoreOptionsBox: () => (/* binding */ toggleMoreOptionsBox),\n/* harmony export */ toggleTurnIntoBox: () => (/* binding */ toggleTurnIntoBox)\n/* harmony export */ });\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _j_anchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../j-anchor */ \"./src/j-anchor.js\");\n/* harmony import */ var _quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../quick-insert-menu/quick-insert-menu */ \"./src/components/quick-insert-menu/quick-insert-menu.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nlet textFormattingBarVisible = false;\r\nlet textFormattingBarPreventHide = false;\r\n\r\n\r\n\r\nfunction isShowingTextFormattingSelectableDependentBox() {\r\n let isShowing = (\r\n turnIntoSelect.style.display !== 'none' ||\r\n moreTextOptionSelect.style.display !== 'none' ||\r\n colorTextOptionSelect.style.display !== 'none');\r\n return isShowing;\r\n}\r\n\r\nfunction isOutOfTextFormattingBar(event) {\r\n\r\n if (!event.target.closest('#textFormattingBar') && !event.target.closest('#linkBox')) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction canHideTextFormattingBar() {\r\n return !textFormattingBarPreventHide;\r\n}\r\n\r\nfunction isShowingTextFormattingBar() {\r\n return textFormattingBar.style.display !== 'none';\r\n}\r\n\r\nfunction showTextFormattingBar(event) {\r\n\r\n console.log('show text formatting bar');\r\n\r\n hideAllDependentBox();\r\n\r\n textFormattingBarVisible = true;\r\n textFormattingBarPreventHide = true;\r\n\r\n setTimeout(() => {\r\n textFormattingBarPreventHide = false;\r\n }, 300);\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.removeSavedSelection();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.saveSelection();\r\n\r\n clearTextFormattingButtonActive();\r\n updateTextFormattingActiveButtons();\r\n\r\n changeTurnIntoButtonText();\r\n\r\n const selection = window.getSelection();\r\n\r\n if (selection.rangeCount > 0 && document.querySelector('.johannes-editor').contains(selection.anchorNode) && selection.toString().trim() !== '') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n let range = selection.getRangeAt(0);\r\n let rect = range.getBoundingClientRect();\r\n\r\n textFormattingBar.style.display = 'flex';\r\n textFormattingBar.style.left = `${rect.left + window.scrollX - 50}px`;\r\n textFormattingBar.style.top = `${rect.top + window.scrollY - textFormattingBar.offsetHeight - 10}px`;\r\n }\r\n}\r\n\r\nfunction hideTextFormattingBar() {\r\n\r\n console.log('hide text formatting bar ');\r\n\r\n // textFormattingBar.style.display = 'none';\r\n\r\n tryHideTextFormattingBar();\r\n}\r\n\r\n\r\nfunction clearTextFormattingButtonActive() {\r\n linkTextButton.classList.remove('text-formatting-button-active');\r\n boldTextButton.classList.remove('text-formatting-button-active');\r\n italicTextButton.classList.remove('text-formatting-button-active');\r\n underlineTextButton.classList.remove('text-formatting-button-active');\r\n codeTextButton.classList.remove('text-formatting-button-active');\r\n strikeThroughTextButton.classList.remove('text-formatting-button-active');\r\n mathTextButton.classList.remove('text-formatting-button-active');\r\n colorCircle.classList.remove('text-formatting-circle-active');\r\n}\r\n\r\nfunction updateTextFormattingActiveButtons() {\r\n\r\n const selectedTags = getSelectedTags();\r\n\r\n selectedTags.forEach(tag => {\r\n\r\n if (tag == \"a\") {\r\n linkTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"strong\") {\r\n boldTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"em\") {\r\n italicTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"u\") {\r\n underlineTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"s\") {\r\n strikeThroughTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"code\") {\r\n codeTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"math\") {\r\n mathTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"mark\") {\r\n colorCircle.classList.add('text-formatting-circle-active');\r\n }\r\n });\r\n}\r\n\r\nfunction getSelectedTags() {\r\n const selection = window.getSelection();\r\n const tags = [];\r\n\r\n const tagNames = [\"STRONG\", \"S\", \"EM\", \"U\", \"CODE\", \"MATH\", \"A\", \"MARK\"];\r\n\r\n if (selection.rangeCount) {\r\n const range = selection.getRangeAt(0);\r\n const startContainer = range.startContainer;\r\n const endContainer = range.endContainer;\r\n\r\n if (startContainer !== endContainer) {\r\n const commonAncestor = range.commonAncestorContainer;\r\n const elements = commonAncestor.nodeType === 1 ? commonAncestor.querySelectorAll(\"*\") : [];\r\n\r\n elements.forEach(el => {\r\n if (tagNames.includes(el.tagName) && selection.containsNode(el, true)) {\r\n tags.push(el.tagName.toLowerCase());\r\n }\r\n });\r\n } else {\r\n let node = startContainer.nodeType === 1 ? startContainer : startContainer.parentNode;\r\n while (node && node !== document) {\r\n if (tagNames.includes(node.tagName)) {\r\n tags.push(node.tagName.toLowerCase());\r\n }\r\n node = node.parentNode;\r\n }\r\n }\r\n }\r\n\r\n return [...new Set(tags)];\r\n}\r\n\r\n\r\nfunction toggleEncloseSelectedTextTo(event) {\r\n const dataTag = event.target.closest('.entry').getAttribute('data-tag');\r\n const dataClass = event.target.closest('.entry').getAttribute('data-class');\r\n\r\n if (dataClass) {\r\n toggleSelectedTextTo(dataTag, dataClass);\r\n } else {\r\n toggleSelectedTextTo(dataTag);\r\n }\r\n\r\n hideAllDependentBox();\r\n hideTextFormattingBar();\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n}\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n\r\n// boldTextButton.addEventListener('click', function (event) {\r\n// toggleSelectedTextTo('strong');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// italicTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('em');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// underlineTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('u');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// codeTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('code');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// strikeThroughTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('s');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// mathTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('math');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// linkTextButton.addEventListener('click', function () {\r\n// jAnchor.save(toggleSelectedTextTo('a'));\r\n\r\n// if (jAnchor.any()) {\r\n// showInputLinkBox();\r\n// }\r\n// });\r\n\r\n// linkBoxInput.addEventListener('keypress', function (event) {\r\n// if (event.key === 'Enter') {\r\n// urlInsert();\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n// });\r\n\r\n\r\n\r\nfunction inputLinkUrl() {\r\n const url = linkBoxInput.value.trim();\r\n if (!url) return;\r\n\r\n // Simples verificação de URL\r\n if (!url.match(/^https?:\\/\\/.+/)) {\r\n alert('Please enter a valid URL.');\r\n return;\r\n }\r\n\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.setURL(url);\r\n\r\n //Move this to windows manager\r\n hideLinkBox();\r\n\r\n // jAnchor.clear();\r\n // jSelection.clearAllSelection();\r\n\r\n\r\n //Ops\r\n linkBoxInput.value = '';\r\n}\r\n\r\n\r\nfunction toggleSelectedTextTo(tagName, classList = '') {\r\n let newElement = null;\r\n\r\n const range = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange();\r\n const selectedText = range.toString().trim();\r\n if (!selectedText) return;\r\n\r\n const container = range.commonAncestorContainer;\r\n\r\n // Encontrar o elemento formatado mais próximo\r\n let formattedElement = null;\r\n if (container.nodeType === 3) { // Nó de texto\r\n formattedElement = container.parentNode.tagName.toLowerCase() === tagName.toLowerCase() ? container.parentNode : null;\r\n } else {\r\n formattedElement = container.tagName.toLowerCase() === tagName.toLowerCase() ? container : container.querySelector(tagName);\r\n }\r\n\r\n if (formattedElement) {\r\n // Remover todos os irmãos dentro da seleção que correspondem ao tagName\r\n const siblings = Array.from(formattedElement.parentNode.childNodes).filter(child =>\r\n child.nodeType === 1 && // Element node\r\n child.tagName.toLowerCase() === tagName.toLowerCase() &&\r\n range.intersectsNode(child) // Verifica se o nó está dentro da seleção\r\n );\r\n\r\n const parent = formattedElement.parentNode;\r\n siblings.forEach(sibling => {\r\n while (sibling.firstChild) {\r\n parent.insertBefore(sibling.firstChild, sibling);\r\n }\r\n parent.removeChild(sibling);\r\n });\r\n\r\n parent.normalize();\r\n\r\n // Atualizar a seleção para refletir as mudanças\r\n range.setStart(parent, 0);\r\n range.setEnd(parent, parent.childNodes.length);\r\n } else {\r\n // A seleção não está na formatação especificada, então adicionar\r\n newElement = document.createElement(tagName);\r\n if (tagName === 'mark') {\r\n let classes = classList.split(',').filter(e => e.length > 0);\r\n classes.forEach(className => {\r\n newElement.classList.add(className);\r\n });\r\n }\r\n\r\n try {\r\n range.surroundContents(newElement);\r\n } catch (e) {\r\n console.error(\"Erro ao aplicar a tag:\", e);\r\n return;\r\n }\r\n\r\n range.selectNodeContents(newElement);\r\n }\r\n\r\n // Restaurar a seleção\r\n // selection.removeAllRanges();\r\n // selection.addRange(range);\r\n\r\n return newElement;\r\n}\r\n\r\n//original funcional\r\n// function toggleSelectedTextTo(tagName, classList = '') {\r\n\r\n// let newElement = null;\r\n\r\n\r\n\r\n// const range = jSelection.getSavedRange();\r\n// const selectedText = range.toString().trim();\r\n// if (!selectedText) return;\r\n\r\n// const container = range.commonAncestorContainer;\r\n\r\n// // Verificar se a seleção atual está dentro de uma tag específica\r\n// let formattedElement = null;\r\n\r\n// if (container.nodeType === 3) { // Nó de texto\r\n// formattedElement = container.parentNode.tagName.toLowerCase() === tagName.toLowerCase() ? container.parentNode : null;\r\n// } else {\r\n// formattedElement = container.tagName.toLowerCase() === tagName.toLowerCase() ? container : container.querySelector(tagName);\r\n// }\r\n\r\n// if (formattedElement) {\r\n// // A seleção está dentro da formatação especificada, então devemos remover\r\n// const parent = formattedElement.parentNode;\r\n// while (formattedElement.firstChild) {\r\n// parent.insertBefore(formattedElement.firstChild, formattedElement);\r\n// }\r\n// parent.removeChild(formattedElement);\r\n\r\n// // Mesclar nós de texto adjacentes\r\n// parent.normalize();\r\n\r\n// // Atualizar a seleção para refletir as mudanças\r\n// range.setStart(parent, 0);\r\n// range.setEnd(parent, parent.childNodes.length);\r\n// } else {\r\n// // A seleção não está na formatação especificada, então adicionar\r\n// newElement = document.createElement(tagName);\r\n\r\n// if (tagName == 'mark') {\r\n// let classes = classList.split(',').filter(e => e.length > 0);\r\n\r\n// for (let className of classes) {\r\n// newElement.classList.add(className);\r\n// }\r\n// }\r\n\r\n// try {\r\n// range.surroundContents(newElement);\r\n// } catch (e) {\r\n// console.error(\"Erro ao aplicar a tag:\", e);\r\n// return;\r\n// }\r\n\r\n// // Atualizar a seleção para refletir as mudanças\r\n// range.selectNodeContents(newElement);\r\n// }\r\n\r\n// // Restaurar a seleção\r\n// // selection.removeAllRanges();\r\n// // selection.addRange(range);\r\n\r\n// return newElement;\r\n// }\r\n\r\n\r\n// function clearSelection() {\r\n// const selection = window.getSelection();\r\n// selection.removeAllRanges();\r\n// }\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n\r\n// //MOUSE-UP\r\n// document.addEventListener('mouseup', function (event) {\r\n// if (window.getSelection().toString().trim() !== '') {\r\n\r\n// clearTextFormattingButtonActive();\r\n// showTextFormattingBar(event);\r\n// updateTextFormattingActiveButtons();\r\n\r\n// } else if (!event.target.closest('#linkBox') && !event.target.closest('#link-text-button')) {\r\n\r\n// console.log('MOUSEUP ocultar tool text-formatting-bar e link-box');\r\n\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n\r\n// //KEY\r\n// document.addEventListener('keyup', function (event) {\r\n// if (event.key === 'Shift' && window.getSelection().toString().trim() !== '') {\r\n// // text selected\r\n\r\n// showTextFormattingBar(event);\r\n\r\n// } else if (event.key === 'Escape') {\r\n// // scape hide the link-box and text-formatting-bar\r\n// console.log('ESC ocultar tool text-formatting-bar e link-box');\r\n\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n\r\n// });\r\n\r\n\r\n\r\n\r\n// function adjustWidth() {\r\n// const selectedOption = turnIntoSelect.options[turnIntoSelect.selectedIndex];\r\n// const tempSpan = document.createElement(\"span\");\r\n// tempSpan.style.visibility = \"hidden\";\r\n// tempSpan.style.position = \"fixed\";\r\n// tempSpan.style.whiteSpace = \"nowrap\";\r\n// tempSpan.innerText = selectedOption.text;\r\n// document.body.appendChild(tempSpan);\r\n// turnIntoSelect.style.width = tempSpan.offsetWidth + 24 + \"px\"; // +20 para incluir o padding e o botão de dropdown\r\n// document.body.removeChild(tempSpan);\r\n// }\r\n\r\n\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// turnIntoButton.addEventListener('click', function () {\r\n\r\n// if (turnIntoSelect.style.display == 'none') {\r\n// closeAllDependentBox();\r\n// turnIntoSelect.style.display = 'flex';\r\n// } else {\r\n// turnIntoSelect.style.display = 'none';\r\n// }\r\n// });\r\n// });\r\n\r\n\r\nfunction changeTurnIntoButtonText() {\r\n\r\n let text = getBlockTypeText();\r\n\r\n turnIntoButton.querySelector('span').innerText = text;\r\n}\r\n\r\nfunction getBlockTypeText() {\r\n let currentBlockRange = window.getSelection().getRangeAt(0);\r\n\r\n let commonAncestor = currentBlockRange.commonAncestorContainer;\r\n\r\n if (commonAncestor.nodeType === 3) { //* text node */\r\n commonAncestor = commonAncestor.parentNode;\r\n }\r\n\r\n const currentBlock = commonAncestor.closest('.johannes-content-element');\r\n\r\n if (currentBlock.tagName === 'H1') {\r\n return 'Heading 1';\r\n } else if (currentBlock.tagName === 'H2') {\r\n return 'Heading 2';\r\n } else if (currentBlock.tagName === 'H3') {\r\n return 'Heading 3';\r\n } else if (currentBlock.tagName === 'H4') {\r\n return 'Heading 4';\r\n } else if (currentBlock.tagName === 'H5') {\r\n return 'Heading 5';\r\n } else if (currentBlock.tagName === 'H6') {\r\n return 'Heading 6';\r\n } else if (currentBlock.tagName === 'P') {\r\n return 'Text';\r\n } else if (currentBlock.tagName === 'UL' && currentBlock.classList.contains('checkbox-list')) {\r\n return 'Todo list';\r\n } else if (currentBlock.tagName === 'UL') {\r\n return 'Bulleted list';\r\n } else if (currentBlock.tagName === 'OL') {\r\n return 'Numbered list';\r\n } else if (currentBlock.tagName === 'BLOCKQUOTE') {\r\n return 'Quote';\r\n } else if (currentBlock.tagName === 'PRE') {\r\n return 'Code';\r\n } else {\r\n return '';\r\n }\r\n\r\n}\r\n\r\nfunction setTurnIntoCurrentSelectedBlockOptionIcon() {\r\n let block = (0,_j_selection__WEBPACK_IMPORTED_MODULE_0__.getCurrentDraggableBlockFocused)().querySelector('.johannes-content-element');\r\n\r\n if (block) {\r\n let type = block.getAttribute('data-type');\r\n let option = turnIntoSelect.querySelector(`[data-type=\"${type}\"]`);\r\n\r\n if (option) {\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n svg.classList.add('checked-svg');\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", \"#icon-material-small-check\");\r\n\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', '16');\r\n svg.setAttribute('height', '16');\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n // let textOption = option.querySelector('.text-option');\r\n option.appendChild(svg);\r\n }\r\n }\r\n}\r\n\r\nfunction extractMarkClasses(element) {\r\n const marks = element.querySelectorAll('mark');\r\n const classes = [];\r\n\r\n marks.forEach(mark => {\r\n mark.classList.forEach(cls => {\r\n if (!classes.includes(cls)) {\r\n classes.push(cls);\r\n }\r\n });\r\n });\r\n\r\n return classes;\r\n}\r\n\r\nfunction setColorCurrentSelectedIcon() {\r\n let currentRange = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange();\r\n\r\n if (currentRange) {\r\n let fragment = currentRange.cloneContents();\r\n\r\n let tempDiv = document.createElement(\"div\");\r\n tempDiv.appendChild(fragment);\r\n\r\n let marks = extractMarkClasses(tempDiv);\r\n\r\n marks.forEach(markClass => {\r\n let option = colorTextOptionSelect.querySelector(`[data-class=\"${markClass}\"]`);\r\n\r\n if (option && !option.querySelector('.checked-svg')) {\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n svg.classList.add('checked-svg');\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", \"#icon-material-small-check\");\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', '16');\r\n svg.setAttribute('height', '16');\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n option.appendChild(svg);\r\n }\r\n });\r\n\r\n if (marks.length > 0) {\r\n let options = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.setAttribute('disabled', 'true');\r\n option.style.cursor = \"not-allowed\";\r\n });\r\n\r\n clearColorBackgroundOption.removeAttribute('disabled');\r\n clearColorBackgroundOption.style.display = 'flex';\r\n clearColorBackgroundOption.style.cursor = \"auto\";\r\n\r\n } else {\r\n clearColorBackgroundOption.style.display = 'none';\r\n }\r\n\r\n\r\n }\r\n}\r\n\r\nfunction removeAllSVGsFromTurnIntoTextOptions() {\r\n const textOptions = turnIntoSelect.querySelectorAll('.option');\r\n\r\n textOptions.forEach(textOption => {\r\n const svgs = textOption.querySelectorAll('.checked-svg');\r\n\r\n svgs.forEach(svg => {\r\n svg.parentNode.removeChild(svg);\r\n });\r\n });\r\n}\r\n\r\nfunction removeAllSVGsFromColorsTextOptions() {\r\n const textOptions = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n textOptions.forEach(textOption => {\r\n const svgs = textOption.querySelectorAll('.checked-svg');\r\n\r\n svgs.forEach(svg => {\r\n svg.parentNode.removeChild(svg);\r\n });\r\n });\r\n\r\n let options = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.removeAttribute('disabled');\r\n option.style.cursor = \"auto\";\r\n });\r\n\r\n clearColorBackgroundOption.style.display = 'none';\r\n clearColorBackgroundOption.style.cursor = \"auto\";\r\n}\r\n\r\n\r\nfunction toggleMoreOptionsBox(event) {\r\n\r\n console.log('toggle more options');\r\n\r\n const isHidden = moreTextOptionSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n moreTextOptionSelect.style.display = 'flex';\r\n (0,_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.temporarySelectContentFromCurrentSelection();\r\n\r\n } else {\r\n hideMoreOptionsBox();\r\n }\r\n\r\n hideChangeColorBox();\r\n hideTurnIntoBox();\r\n hideLinkBox();\r\n}\r\n\r\nfunction toggleChangeColorBox(event) {\r\n\r\n console.log('toggle change color');\r\n\r\n const isHidden = colorTextOptionSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n colorTextOptionSelect.style.display = 'flex';\r\n (0,_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n\r\n removeAllSVGsFromColorsTextOptions();\r\n setColorCurrentSelectedIcon();\r\n\r\n } else {\r\n colorTextOptionSelect.style.display = 'none';\r\n }\r\n\r\n hideTurnIntoBox();\r\n hideMoreOptionsBox();\r\n hideLinkBox();\r\n}\r\n\r\nfunction toggleTurnIntoBox(event) {\r\n\r\n console.log('toggle turn into box');\r\n\r\n const isHidden = turnIntoSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n turnIntoSelect.style.display = 'flex';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.temporarySelectContentFromCurrentSelection();\r\n\r\n (0,_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n removeAllSVGsFromTurnIntoTextOptions();\r\n setTurnIntoCurrentSelectedBlockOptionIcon();\r\n } else {\r\n hideTurnIntoBox();\r\n }\r\n\r\n hideChangeColorBox();\r\n hideMoreOptionsBox();\r\n hideLinkBox();\r\n}\r\n\r\n//**Show */\r\nfunction toggleInputLinkBox() {\r\n\r\n\r\n console.log('toggle input link box');\r\n\r\n const isHidden = linkBox.style.display == 'none';\r\n\r\n if (isHidden) {\r\n // turnIntoSelect.style.display = 'flex';\r\n\r\n showInputLinkBox();\r\n\r\n } else {\r\n turnIntoSelect.style.display = 'none';\r\n }\r\n\r\n hideChangeColorBox();\r\n hideMoreOptionsBox();\r\n hideTurnIntoBox();\r\n}\r\n\r\n\r\n\r\nfunction showInputLinkBox() {\r\n\r\n const rect = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange().getBoundingClientRect();\r\n\r\n const containerWidth = textFormattingBar.offsetWidth;\r\n const linkInputDivWidth = linkBox.offsetWidth;\r\n const containerCenter = (textFormattingBar.getBoundingClientRect().left + containerWidth) / 2;\r\n const linkInputDivCenter = (linkBox.getBoundingClientRect().left + linkInputDivWidth) / 2;\r\n\r\n linkBox.style.position = 'absolute';\r\n linkBox.style.left = `${containerCenter - linkInputDivCenter + window.scrollX}px`;\r\n linkBox.style.top = `${rect.bottom + window.scrollY + 5}px`;\r\n linkBox.style.display = 'block';\r\n\r\n // linkBoxInput.focus();\r\n\r\n highlightTheSelectionText();\r\n\r\n}\r\n\r\n//The highlight is added using a anchor. It's ok? I swap to span\r\nfunction highlightTheSelectionText() {\r\n const a = toggleSelectedTextTo('a');\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.setAnchor(a);\r\n}\r\n\r\n\r\n\r\n\r\n// toggle-change-color-formatting-bar\r\n\r\n//Show color options\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// colorTextButton.addEventListener('click', function () {\r\n// if (colorTextOptionSelect.style.display == 'none') {\r\n// showColorOptions();\r\n// } else {\r\n// hideColorOptions();\r\n// }\r\n// });\r\n// });\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction showColorOptions() {\r\n hideAllDependentBox();\r\n colorTextOptionSelect.style.display = 'flex';\r\n}\r\n\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// colorTextOptionSelect.querySelectorAll('.option').forEach(option => {\r\n// option.addEventListener('click', function (event) {\r\n// let background = event.target.closest('.option').getAttribute('data-color');\r\n// toggleSelectedTextTo('mark', background);\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n// });\r\n// });\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction tryHideTextFormattingBar() {\r\n\r\n // check before if a dependent box is opened, then close the dependent box\r\n\r\n //1. try close text-formatting-bar before linkBox (the actual only one dependency box)\r\n if (isShowingTextFormattingBar() && !anyDependentBoxVisible()) {\r\n // only hide if the dependency box is closed\r\n textFormattingBar.style.display = 'none';\r\n // restoreSelection();\r\n }\r\n\r\n // 2. close the dependency box (linkBox)\r\n if (anyDependentBoxVisible()) {\r\n\r\n // Remove a if has no href attribute or if href is empty\r\n //Move this to a logic inside the linking box\r\n // if (anchorElement && (anchorElement.href == '' || anchorElement.href == null)) {\r\n // const parent = anchorElement.parentNode;\r\n // while (anchorElement.firstChild) {\r\n // parent.insertBefore(anchorElement.firstChild, anchorElement);\r\n // }\r\n\r\n // if (parent) {\r\n // parent.removeChild(anchorElement);\r\n // parent.normalize(); // Mesclar nós de texto adjacentes, se necessário\r\n // }\r\n // }\r\n\r\n // linkBox.style.display = 'none';\r\n hideAllDependentBox();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n }\r\n}\r\n\r\nfunction anyDependentBoxVisible() {\r\n const dependentBoxes = document.querySelectorAll('.dependent-box');\r\n\r\n for (const box of dependentBoxes) {\r\n if (box.style.display !== 'none') {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction hideMoreOptionsBox() {\r\n\r\n if (moreTextOptionSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide more options');\r\n\r\n moreTextOptionSelect.style.display = 'none';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n}\r\n\r\nfunction hideTurnIntoBox() {\r\n\r\n if (turnIntoSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide turn into box');\r\n turnIntoSelect.style.display = 'none';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n //jSelection.restoreSelection(); //TODO. Do I need this?\r\n //jSelection.removeSavedSelection();\r\n}\r\n\r\nfunction hideChangeColorBox() {\r\n\r\n if (colorTextOptionSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide change color box');\r\n colorTextOptionSelect.style.display = 'none';\r\n}\r\n\r\nfunction hideLinkBox() {\r\n\r\n if (linkBox.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide link box');\r\n\r\n // if(linkBox.style.display != 'none'){\r\n\r\n // }\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.clear();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n linkBox.style.display = 'none';\r\n}\r\n\r\n\r\n\r\nfunction hideAllDependentBox() {\r\n hideMoreOptionsBox();\r\n hideTurnIntoBox();\r\n hideChangeColorBox();\r\n hideLinkBox();\r\n}\r\n\n\n//# sourceURL=webpack://johannes/./src/components/text-formatting-bar/text-formatting-bar.js?"); /***/ }), @@ -81,7 +158,7 @@ eval("document.addEventListener('DOMContentLoaded', function () {\r\n const c /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createNewCheckboxLiElement: () => (/* binding */ createNewCheckboxLiElement),\n/* harmony export */ createNewDraggableParagraphElement: () => (/* binding */ createNewDraggableParagraphElement),\n/* harmony export */ createNewHeadingElement: () => (/* binding */ createNewHeadingElement),\n/* harmony export */ createNewLiElement: () => (/* binding */ createNewLiElement),\n/* harmony export */ createNewListElement: () => (/* binding */ createNewListElement),\n/* harmony export */ createNewParagraphElement: () => (/* binding */ createNewParagraphElement),\n/* harmony export */ createNewQuoteElement: () => (/* binding */ createNewQuoteElement),\n/* harmony export */ createNewSeparatorElement: () => (/* binding */ createNewSeparatorElement),\n/* harmony export */ createNewTodoListElement: () => (/* binding */ createNewTodoListElement)\n/* harmony export */ });\nfunction createNewHeadingElement(number = 2) {\r\n\r\n let newElement = document.createElement(`h${number}`);\r\n newElement.setAttribute('data-type', `h${number}`);\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('swittable');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('focus');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.setAttribute('data-placeholder', `Heading ${number}`);\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewParagraphElement(text) {\r\n\r\n let newElement = document.createElement('p');\r\n newElement.setAttribute('data-type', 'p');\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('swittable');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', 'Write something or type / (slash) to choose a block...');\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewDraggableParagraphElement() {\r\n\r\n let newDiv = document.createElement('div');\r\n let newElement = createNewParagraphElement();\r\n\r\n let newButton = document.createElement('button');\r\n newButton.innerHTML = '';\r\n\r\n newDiv.appendChild(newButton);\r\n newDiv.appendChild(newElement);\r\n\r\n newDiv.classList.add('draggable-block');\r\n newDiv.classList.add('deletable');\r\n newButton.classList.add('drag-handler');\r\n newButton.classList.add('button-reset');\r\n newButton.draggable = true;\r\n\r\n return newDiv;\r\n}\r\n\r\nfunction createNewListElement(text, type = 'ul') {\r\n const newList = document.createElement(type);\r\n newList.classList.add('johannes-content-element');\r\n newList.classList.add('swittable');\r\n newList.classList.add('list');\r\n\r\n if (type == 'ul') {\r\n newList.setAttribute('data-type', 'bulleted-list');\r\n } else {\r\n newList.setAttribute('data-type', 'numbered-list');\r\n }\r\n\r\n const initialItem = createNewLiElement(text);\r\n\r\n newList.appendChild(initialItem);\r\n\r\n return newList;\r\n}\r\n\r\nfunction createNewTodoListElement(text, type = 'ul') {\r\n const newList = document.createElement(type);\r\n newList.classList.add('johannes-content-element');\r\n newList.classList.add('checkbox-list');\r\n newList.classList.add('list');\r\n newList.setAttribute('data-type', 'todo-list');\r\n\r\n const initialItem = createNewCheckboxLiElement(text);\r\n\r\n newList.appendChild(initialItem);\r\n\r\n return newList;\r\n}\r\n\r\n\r\nfunction createNewLiElement(text = '') {\r\n\r\n let initialItem = document.createElement('li');\r\n\r\n initialItem.classList.add('focusable');\r\n initialItem.classList.add('deletable');\r\n initialItem.classList.add('editable');\r\n initialItem.classList.add('focus');\r\n initialItem.classList.add('key-trigger');\r\n initialItem.classList.add('list-item');\r\n\r\n initialItem.innerText = text;\r\n\r\n initialItem.contentEditable = true;\r\n initialItem.setAttribute('data-placeholder', 'Item');\r\n\r\n return initialItem;\r\n\r\n}\r\n\r\nfunction createNewCheckboxLiElement(text = '') {\r\n\r\n let li = document.createElement('li');\r\n li.classList.add('deletable');\r\n li.classList.add('list-item');\r\n\r\n initialItem.classList.add('key-trigger');\r\n\r\n let checkbox = document.createElement('input');\r\n checkbox.setAttribute('type', 'checkbox');\r\n\r\n let span = document.createElement('span');\r\n span.textContent = text || \"\";\r\n span.setAttribute('data-placeholder', 'To-do');\r\n span.contentEditable = true;\r\n\r\n span.classList.add('focusable');\r\n span.classList.add('editable');\r\n span.classList.add('focus');\r\n\r\n li.appendChild(checkbox);\r\n li.appendChild(span);\r\n\r\n return li;\r\n}\r\n\r\nfunction createNewSeparatorElement() {\r\n let newElement = document.createElement('hr');\r\n return newElement;\r\n}\r\n\r\n\r\nfunction createNewQuoteElement(text) {\r\n\r\n const quote = document.createElement('blockquote');\r\n quote.classList.add('swittable');\r\n quote.classList.add('johannes-content-element');\r\n quote.setAttribute('data-type', 'quote');\r\n\r\n const p = createNewNoSwittableParagraphElement(text);\r\n const cite = createNewNoSwittableCiteElement();\r\n\r\n quote.appendChild(p);\r\n quote.appendChild(cite);\r\n\r\n return quote;\r\n}\r\n\r\nfunction createNewNoSwittableParagraphElement(text) {\r\n\r\n let newElement = document.createElement('p');\r\n newElement.classList.add('focus');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('editable');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', '”To be, or not to be, that is the question”');\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewNoSwittableCiteElement(text) {\r\n\r\n let newElement = document.createElement('cite');\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('deletable');\r\n newElement.classList.add('editable');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', '— Socrates');\r\n\r\n return newElement;\r\n}\n\n//# sourceURL=webpack://johannes/./src/element-factory.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ createCheckedSVG: () => (/* binding */ createCheckedSVG),\n/* harmony export */ createNewCheckboxLiElement: () => (/* binding */ createNewCheckboxLiElement),\n/* harmony export */ createNewDraggableParagraphElement: () => (/* binding */ createNewDraggableParagraphElement),\n/* harmony export */ createNewHeadingElement: () => (/* binding */ createNewHeadingElement),\n/* harmony export */ createNewLiElement: () => (/* binding */ createNewLiElement),\n/* harmony export */ createNewListElement: () => (/* binding */ createNewListElement),\n/* harmony export */ createNewParagraphElement: () => (/* binding */ createNewParagraphElement),\n/* harmony export */ createNewQuoteElement: () => (/* binding */ createNewQuoteElement),\n/* harmony export */ createNewSeparatorElement: () => (/* binding */ createNewSeparatorElement),\n/* harmony export */ createNewTodoListElement: () => (/* binding */ createNewTodoListElement)\n/* harmony export */ });\nfunction createNewHeadingElement(number = 2) {\r\n\r\n let newElement = document.createElement(`h${number}`);\r\n newElement.setAttribute('data-type', `h${number}`);\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('swittable');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('focus');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.setAttribute('data-placeholder', `Heading ${number}`);\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewParagraphElement(text) {\r\n\r\n let newElement = document.createElement('p');\r\n newElement.setAttribute('data-type', 'p');\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('swittable');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', 'Write something or type / (slash) to choose a block...');\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewDraggableParagraphElement() {\r\n\r\n let newDiv = document.createElement('div');\r\n let newElement = createNewParagraphElement();\r\n\r\n let newButton = document.createElement('button');\r\n newButton.innerHTML = '';\r\n\r\n newDiv.appendChild(newButton);\r\n newDiv.appendChild(newElement);\r\n\r\n newDiv.classList.add('draggable-block');\r\n newDiv.classList.add('deletable');\r\n newButton.classList.add('drag-handler');\r\n newButton.classList.add('button-reset');\r\n newButton.draggable = true;\r\n\r\n return newDiv;\r\n}\r\n\r\nfunction createNewListElement(text, type = 'ul') {\r\n const newList = document.createElement(type);\r\n newList.classList.add('johannes-content-element');\r\n newList.classList.add('swittable');\r\n newList.classList.add('list');\r\n\r\n if (type == 'ul') {\r\n newList.setAttribute('data-type', 'bulleted-list');\r\n } else {\r\n newList.setAttribute('data-type', 'numbered-list');\r\n }\r\n\r\n const initialItem = createNewLiElement(text);\r\n\r\n newList.appendChild(initialItem);\r\n\r\n return newList;\r\n}\r\n\r\nfunction createNewTodoListElement(text, type = 'ul') {\r\n const newList = document.createElement(type);\r\n newList.classList.add('johannes-content-element');\r\n newList.classList.add('checkbox-list');\r\n newList.classList.add('list');\r\n newList.setAttribute('data-type', 'todo-list');\r\n\r\n const initialItem = createNewCheckboxLiElement(text);\r\n\r\n newList.appendChild(initialItem);\r\n\r\n return newList;\r\n}\r\n\r\n\r\nfunction createNewLiElement(text = '') {\r\n\r\n let initialItem = document.createElement('li');\r\n\r\n initialItem.classList.add('focusable');\r\n initialItem.classList.add('deletable');\r\n initialItem.classList.add('editable');\r\n initialItem.classList.add('focus');\r\n initialItem.classList.add('key-trigger');\r\n initialItem.classList.add('list-item');\r\n\r\n initialItem.innerText = text;\r\n\r\n initialItem.contentEditable = true;\r\n initialItem.setAttribute('data-placeholder', 'Item');\r\n\r\n return initialItem;\r\n\r\n}\r\n\r\nfunction createNewCheckboxLiElement(text = '') {\r\n\r\n let li = document.createElement('li');\r\n li.classList.add('deletable');\r\n li.classList.add('list-item');\r\n\r\n initialItem.classList.add('key-trigger');\r\n\r\n let checkbox = document.createElement('input');\r\n checkbox.setAttribute('type', 'checkbox');\r\n\r\n let span = document.createElement('span');\r\n span.textContent = text || \"\";\r\n span.setAttribute('data-placeholder', 'To-do');\r\n span.contentEditable = true;\r\n\r\n span.classList.add('focusable');\r\n span.classList.add('editable');\r\n span.classList.add('focus');\r\n\r\n li.appendChild(checkbox);\r\n li.appendChild(span);\r\n\r\n return li;\r\n}\r\n\r\nfunction createNewSeparatorElement() {\r\n let newElement = document.createElement('hr');\r\n return newElement;\r\n}\r\n\r\n\r\nfunction createNewQuoteElement(text) {\r\n\r\n const quote = document.createElement('blockquote');\r\n quote.classList.add('swittable');\r\n quote.classList.add('johannes-content-element');\r\n quote.setAttribute('data-type', 'quote');\r\n\r\n const p = createNewNoSwittableParagraphElement(text);\r\n const cite = createNewNoSwittableCiteElement();\r\n\r\n quote.appendChild(p);\r\n quote.appendChild(cite);\r\n\r\n return quote;\r\n}\r\n\r\nfunction createNewNoSwittableParagraphElement(text) {\r\n\r\n let newElement = document.createElement('p');\r\n newElement.classList.add('focus');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('editable');\r\n newElement.classList.add('key-trigger');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', '”To be, or not to be, that is the question”');\r\n\r\n return newElement;\r\n}\r\n\r\nfunction createNewNoSwittableCiteElement(text) {\r\n\r\n let newElement = document.createElement('cite');\r\n newElement.classList.add('johannes-content-element');\r\n newElement.classList.add('focusable');\r\n newElement.classList.add('deletable');\r\n newElement.classList.add('editable');\r\n\r\n newElement.contentEditable = true;\r\n\r\n newElement.innerText = text || \"\";\r\n\r\n newElement.setAttribute('data-placeholder', '— Socrates');\r\n\r\n return newElement;\r\n}\r\n\r\n\r\nfunction createCheckedSVG() {\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n svg.classList.add('checked-svg');\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", \"#icon-material-small-check\");\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', '16');\r\n svg.setAttribute('height', '16');\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n return svg;\r\n}\n\n//# sourceURL=webpack://johannes/./src/element-factory.js?"); /***/ }), @@ -103,7 +180,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./style.css */ \"./src/style.css\");\n/* harmony import */ var _block_operation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block-operation.js */ \"./src/block-operation.js\");\n/* harmony import */ var _drag_and_drop_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./drag-and-drop.js */ \"./src/drag-and-drop.js\");\n/* harmony import */ var _drag_and_drop_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_drag_and_drop_js__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _switch_block_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./switch-block.js */ \"./src/switch-block.js\");\n/* harmony import */ var _switch_block_js__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_switch_block_js__WEBPACK_IMPORTED_MODULE_3__);\n/* harmony import */ var _keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./keyboard-navigation.js */ \"./src/keyboard-navigation.js\");\n/* harmony import */ var _keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _text_blocks_from_newlines_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./text-blocks-from-newlines.js */ \"./src/text-blocks-from-newlines.js\");\n/* harmony import */ var _click_events_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./click-events.js */ \"./src/click-events.js\");\n/* harmony import */ var _memento_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./memento.js */ \"./src/memento.js\");\n/* harmony import */ var _memento_js__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(_memento_js__WEBPACK_IMPORTED_MODULE_7__);\n/* harmony import */ var _keypress_events_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./keypress-events.js */ \"./src/keypress-events.js\");\n/* harmony import */ var _load_events_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./load-events.js */ \"./src/load-events.js\");\n/* harmony import */ var _load_events_js__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(_load_events_js__WEBPACK_IMPORTED_MODULE_9__);\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\n\n//# sourceURL=webpack://johannes/./src/index.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _triggers_load_events_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./triggers/load-events.js */ \"./src/triggers/load-events.js\");\n/* harmony import */ var _triggers_keypress_events_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./triggers/keypress-events.js */ \"./src/triggers/keypress-events.js\");\n/* harmony import */ var _triggers_click_events_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./triggers/click-events.js */ \"./src/triggers/click-events.js\");\n/* harmony import */ var _block_operation_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./block-operation.js */ \"./src/block-operation.js\");\n/* harmony import */ var _drag_and_drop_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./drag-and-drop.js */ \"./src/drag-and-drop.js\");\n/* harmony import */ var _drag_and_drop_js__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(_drag_and_drop_js__WEBPACK_IMPORTED_MODULE_4__);\n/* harmony import */ var _switch_block_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./switch-block.js */ \"./src/switch-block.js\");\n/* harmony import */ var _switch_block_js__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(_switch_block_js__WEBPACK_IMPORTED_MODULE_5__);\n/* harmony import */ var _keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./keyboard-navigation.js */ \"./src/keyboard-navigation.js\");\n/* harmony import */ var _keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_keyboard_navigation_js__WEBPACK_IMPORTED_MODULE_6__);\n/* harmony import */ var _text_blocks_from_newlines_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./text-blocks-from-newlines.js */ \"./src/text-blocks-from-newlines.js\");\n/* harmony import */ var _memento_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./memento.js */ \"./src/memento.js\");\n/* harmony import */ var _memento_js__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(_memento_js__WEBPACK_IMPORTED_MODULE_8__);\n/* harmony import */ var _style_css__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./style.css */ \"./src/style.css\");\n// listen events in keyboard, mouse and document load\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// default style\r\n\n\n//# sourceURL=webpack://johannes/./src/index.js?"); /***/ }), @@ -125,7 +202,7 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpac /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearAllSelection: () => (/* binding */ clearAllSelection),\n/* harmony export */ getCurrentDraggableBlockFocused: () => (/* binding */ getCurrentDraggableBlockFocused),\n/* harmony export */ getSavedRange: () => (/* binding */ getSavedRange),\n/* harmony export */ hasSelection: () => (/* binding */ hasSelection),\n/* harmony export */ removeSavedSelection: () => (/* binding */ removeSavedSelection),\n/* harmony export */ restoreSelection: () => (/* binding */ restoreSelection),\n/* harmony export */ saveSelection: () => (/* binding */ saveSelection),\n/* harmony export */ savedRange: () => (/* binding */ savedRange),\n/* harmony export */ temporarySelectContentFromCurrentSelection: () => (/* binding */ temporarySelectContentFromCurrentSelection)\n/* harmony export */ });\nlet savedRange = null;\r\n\r\nfunction saveSelection() {\r\n if (window.getSelection) {\r\n const sel = window.getSelection();\r\n if (sel.rangeCount > 0) {\r\n savedRange = sel.getRangeAt(0).cloneRange();\r\n }\r\n }\r\n}\r\n\r\nfunction temporarySelectContentFromCurrentSelection() {\r\n\r\n setTimeout(() => {\r\n console.log('select all content temporarrly')\r\n if (window.getSelection) {\r\n const selection = window.getSelection();\r\n\r\n if (selection.rangeCount > 0) {\r\n const range = savedRange || selection.getRangeAt(0);\r\n let container = range.commonAncestorContainer;\r\n\r\n if (container.nodeType !== 1) {\r\n container = container.parentNode;\r\n }\r\n\r\n const contentElement = container.closest('.johannes-content-element');\r\n\r\n if (contentElement) {\r\n selection.removeAllRanges();\r\n\r\n const newRange = document.createRange();\r\n newRange.selectNodeContents(contentElement);\r\n\r\n selection.addRange(newRange);\r\n } else {\r\n console.log(\"Nenhum elemento '.content' envolvendo a seleção atual foi encontrado.\");\r\n }\r\n }\r\n }\r\n }, 11);\r\n}\r\n\r\nfunction restoreSelection() {\r\n\r\n setTimeout(() => {\r\n console.log('restore selection');\r\n\r\n const selection = window.getSelection();\r\n if (savedRange) {\r\n selection.removeAllRanges();\r\n selection.addRange(savedRange);\r\n }\r\n }, 10);\r\n}\r\n\r\nfunction getSavedRange() {\r\n return savedRange;\r\n}\r\n\r\nfunction clearAllSelection() {\r\n savedRange = null;\r\n window.getSelection().removeAllRanges();\r\n}\r\n\r\nfunction removeSavedSelection() {\r\n savedRange = null;\r\n}\r\n\r\nfunction getCurrentDraggableBlockFocused() {\r\n\r\n let currentBlockRange = window.getSelection().getRangeAt(0);\r\n\r\n let commonAncestor = currentBlockRange.commonAncestorContainer;\r\n\r\n if (commonAncestor.nodeType === 3) { //* text node */\r\n commonAncestor = commonAncestor.parentNode;\r\n }\r\n\r\n const currentBlock = commonAncestor.closest('.draggable-block');\r\n\r\n return currentBlock;\r\n}\r\n\r\n\r\nfunction hasSelection(){\r\n savedRange != null;\r\n}\n\n//# sourceURL=webpack://johannes/./src/j-selection.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ clearAllSelection: () => (/* binding */ clearAllSelection),\n/* harmony export */ getClosestContentEditable: () => (/* binding */ getClosestContentEditable),\n/* harmony export */ getCurrentDraggableBlockFocused: () => (/* binding */ getCurrentDraggableBlockFocused),\n/* harmony export */ getSavedRange: () => (/* binding */ getSavedRange),\n/* harmony export */ getSelectedClosestElementAcceptingClosest: () => (/* binding */ getSelectedClosestElementAcceptingClosest),\n/* harmony export */ hasSelection: () => (/* binding */ hasSelection),\n/* harmony export */ isRangeCoveringElement: () => (/* binding */ isRangeCoveringElement),\n/* harmony export */ removeSavedSelection: () => (/* binding */ removeSavedSelection),\n/* harmony export */ restoreSelection: () => (/* binding */ restoreSelection),\n/* harmony export */ saveSelection: () => (/* binding */ saveSelection),\n/* harmony export */ savedRange: () => (/* binding */ savedRange),\n/* harmony export */ temporarySelectContentFromCurrentSelection: () => (/* binding */ temporarySelectContentFromCurrentSelection)\n/* harmony export */ });\nlet savedRange = null;\r\n\r\nfunction saveSelection() {\r\n if (window.getSelection) {\r\n const sel = window.getSelection();\r\n if (sel.rangeCount > 0) {\r\n savedRange = sel.getRangeAt(0).cloneRange();\r\n }\r\n }\r\n}\r\n\r\nfunction temporarySelectContentFromCurrentSelection() {\r\n\r\n setTimeout(() => {\r\n console.log('select all content temporarrly')\r\n if (window.getSelection) {\r\n const selection = window.getSelection();\r\n\r\n if (selection.rangeCount > 0) {\r\n const range = savedRange || selection.getRangeAt(0);\r\n let container = range.commonAncestorContainer;\r\n\r\n if (container.nodeType !== 1) {\r\n container = container.parentNode;\r\n }\r\n\r\n const contentElement = container.closest('.johannes-content-element');\r\n\r\n if (contentElement) {\r\n selection.removeAllRanges();\r\n\r\n const newRange = document.createRange();\r\n newRange.selectNodeContents(contentElement);\r\n\r\n selection.addRange(newRange);\r\n } else {\r\n console.log(\"Nenhum elemento '.content' envolvendo a seleção atual foi encontrado.\");\r\n }\r\n }\r\n }\r\n }, 11);\r\n}\r\n\r\nfunction restoreSelection() {\r\n\r\n setTimeout(() => {\r\n console.log('restore selection');\r\n\r\n const selection = window.getSelection();\r\n if (savedRange) {\r\n selection.removeAllRanges();\r\n selection.addRange(savedRange);\r\n }\r\n }, 10);\r\n}\r\n\r\nfunction getSavedRange() {\r\n return savedRange;\r\n}\r\n\r\nfunction clearAllSelection() {\r\n savedRange = null;\r\n window.getSelection().removeAllRanges();\r\n}\r\n\r\nfunction removeSavedSelection() {\r\n savedRange = null;\r\n}\r\n\r\nfunction getCurrentDraggableBlockFocused() {\r\n\r\n let currentBlockRange = window.getSelection().getRangeAt(0);\r\n\r\n let commonAncestor = currentBlockRange.commonAncestorContainer;\r\n\r\n if (commonAncestor.nodeType === 3) { //* text node */\r\n commonAncestor = commonAncestor.parentNode;\r\n }\r\n\r\n const currentBlock = commonAncestor.closest('.draggable-block');\r\n\r\n return currentBlock;\r\n}\r\n\r\n\r\nfunction hasSelection() {\r\n savedRange != null;\r\n}\r\n\r\nfunction isRangeCoveringElement(element, range) {\r\n const textNodes = getTextNodes(element);\r\n\r\n if (textNodes.length === 0) {\r\n return false;\r\n }\r\n\r\n const firstNode = textNodes[0];\r\n if (range.startContainer !== firstNode || range.startOffset !== 0) {\r\n return false;\r\n }\r\n\r\n const lastNode = textNodes[textNodes.length - 1];\r\n if (range.endContainer !== lastNode || range.endOffset !== lastNode.length) {\r\n return false;\r\n }\r\n\r\n return true;\r\n}\r\n\r\nfunction getTextNodes(node) {\r\n let textNodes = [];\r\n if (node.nodeType === Node.TEXT_NODE) {\r\n textNodes.push(node);\r\n } else {\r\n node.childNodes.forEach(child => {\r\n textNodes = textNodes.concat(getTextNodes(child));\r\n });\r\n }\r\n return textNodes;\r\n}\r\n\r\nfunction getSelectedClosestElementAcceptingClosest() {\r\n let currentRange = window.getSelection().getRangeAt(0);\r\n if (!currentRange || currentRange.collapsed) {\r\n console.error('No valid selection found.');\r\n return null;\r\n }\r\n\r\n let commonAncestor = currentRange.commonAncestorContainer;\r\n\r\n while (commonAncestor.nodeType !== 1) {\r\n commonAncestor = commonAncestor.parentNode;\r\n }\r\n\r\n return commonAncestor;\r\n}\r\n\r\nfunction getClosestContentEditable() {\r\n return getSelectedClosestElementAcceptingClosest().closest('.editable');\r\n}\n\n//# sourceURL=webpack://johannes/./src/j-selection.js?"); /***/ }), @@ -150,27 +227,6 @@ eval("// import { focusOnPrevious } from './j-window';\r\n// import { focusOnNex /***/ }), -/***/ "./src/keypress-events.js": -/*!********************************!*\ - !*** ./src/keypress-events.js ***! - \********************************/ -/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { - -"use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _command_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./command-factory */ \"./src/command-factory.js\");\n/* harmony import */ var _block_options_operation__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./block-options-operation */ \"./src/block-options-operation.js\");\n/* harmony import */ var _helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./helper */ \"./src/helper.js\");\n/* harmony import */ var _text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./text-formatting-bar-operation */ \"./src/text-formatting-bar-operation.js\");\n//The start point for key press events\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Block operations is operations related to the block it self. Create a block, delete a block, change the block type, etc...\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n\r\n document.addEventListener('keydown', function (event) {\r\n\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event) && !(0,_block_options_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n\r\n if (event.key === 'Enter' && !(0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() && !(0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n //TODO: pass the event not event.target/it`s more simple to deal with event when create a click eventListener\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.CREATE_NEW_ELEMENT, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'Backspace' && isActiveContentBlank(event) && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_PREVIOUS);\r\n command.execute();\r\n\r\n } else if (event.key === 'Delete' && isActiveContentBlank() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_NEXT);\r\n command.execute();\r\n\r\n }\r\n }\r\n });\r\n\r\n document.addEventListener('keyup', function (event) {\r\n\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event) && !(0,_block_options_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n if (event.key === 'Escape' && isActiveContentBlank() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n //TODO: write the code to select the all text\r\n\r\n }\r\n }\r\n });\r\n});\r\n\r\n// Block options operations is operations related to the Block Options. Show the block options, hide the block options, filter, ...\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n document.addEventListener('keydown', function (event) {\r\n\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event) && !(0,_block_options_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n\r\n if (event.key === '/' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.SHOW_BLOCK_OPTIONS);\r\n command.execute();\r\n }\r\n }\r\n\r\n if ((0,_block_options_operation__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n\r\n if (event.key === 'Escape' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const elementToFocusAfterHide = event.target;\r\n\r\n //TODO: pass the event not event.target/it`s more simple to deal with event when create a click eventListener\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.HIDE_CLEAR_BLOCK_OPTIONS, [elementToFocusAfterHide]);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowDown' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowUp' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'Enter' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE, [event]);\r\n command.execute();\r\n\r\n } else if (/^[a-z0-9]$/i.test(event.key) && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.FILTER_CONCAT, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'Backspace') {\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.FILTER_REMOVE_LAST);\r\n command.execute();\r\n }\r\n }\r\n\r\n\r\n if ((0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)()) {\r\n\r\n if (event.key === 'Escape' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowDown' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowUp' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'Enter' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE, [event]);\r\n command.execute();\r\n\r\n }\r\n }\r\n });\r\n});\r\n\r\n\r\n// Text formatting bar operations is operations related to text presentation, color, show or hide text formatting dependent boxes,...\r\ndocument.addEventListener('keyup', function (event) {\r\n if (event.key === 'Shift' && (0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n }\r\n});\r\n\r\ndocument.addEventListener('keydown', function (event) {\r\n if (event.ctrlKey && event.key.toLowerCase() === 'a' && (0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n } else if (event.key === 'Escape' && (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.canHideTextFormattingBar)() && (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)()) {\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n});\r\n\r\n\r\n\r\nfunction isActiveContentBlank() {\r\n return document.activeElement.textContent.trim() === '';\r\n}\r\n\r\n\r\n// Listen a input link\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n linkBoxInput.addEventListener('keydown', function (event) {\r\n if (event.key === 'Enter') {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.INPUT_LINK_URL);\r\n command.execute();\r\n }\r\n });\r\n});\r\n\r\n\r\n// Lock left and right key when is showing the dependent box\r\ndocument.addEventListener('keydown', function (event) {\r\n if ((0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() &&\r\n (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n});\r\n\r\n\r\ndocument.addEventListener('keyup', function (event) {\r\n if ((0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)() && (0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.canHideTextFormattingBar)() && !(0,_text_formatting_bar_operation__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() &&\r\n (event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowUp' || event.key === 'ArrowDown')) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() == '') {\r\n const command = _command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n }\r\n});\n\n//# sourceURL=webpack://johannes/./src/keypress-events.js?"); - -/***/ }), - -/***/ "./src/load-events.js": -/*!****************************!*\ - !*** ./src/load-events.js ***! - \****************************/ -/***/ (() => { - -eval("\r\n//Focus on P when load\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n const editor = document.querySelector('.johannes-editor');\r\n\r\n if (editor) {\r\n let blocks = editor.querySelectorAll('.draggable-block');\r\n\r\n if (blocks.length == 1) {\r\n\r\n const p = blocks[0].querySelector('.johannes-content-element');\r\n if (p.innerText == '') {\r\n p.focus();\r\n }\r\n }\r\n }\r\n});\r\n\r\n// Clear text when paste\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n const editor = document.querySelector('.johannes-editor');\r\n\r\n if (editor) {\r\n document.addEventListener('paste', function (e) {\r\n if (e.target.getAttribute('contenteditable') === 'true') {\r\n e.preventDefault();\r\n const text = (e.clipboardData || window.clipboardData).getData('text/plain');\r\n insertTextAtCursor(text);\r\n }\r\n }, true);\r\n\r\n function insertTextAtCursor(text) {\r\n const sel = window.getSelection();\r\n if (sel.rangeCount > 0) {\r\n const range = sel.getRangeAt(0);\r\n range.deleteContents();\r\n\r\n const textNode = document.createTextNode(text);\r\n range.insertNode(textNode);\r\n\r\n range.setStartAfter(textNode);\r\n range.setEndAfter(textNode);\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n }\r\n }\r\n});\n\n//# sourceURL=webpack://johannes/./src/load-events.js?"); - -/***/ }), - /***/ "./src/memento.js": /*!************************!*\ !*** ./src/memento.js ***! @@ -202,14 +258,36 @@ eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _ele /***/ }), -/***/ "./src/text-formatting-bar-operation.js": -/*!**********************************************!*\ - !*** ./src/text-formatting-bar-operation.js ***! - \**********************************************/ +/***/ "./src/triggers/click-events.js": +/*!**************************************!*\ + !*** ./src/triggers/click-events.js ***! + \**************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../commands/command-factory */ \"./src/commands/command-factory.js\");\n/* harmony import */ var _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/text-formatting-bar/text-formatting-bar */ \"./src/components/text-formatting-bar/text-formatting-bar.js\");\n/* harmony import */ var _helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../helper */ \"./src/helper.js\");\n// The start point for click events\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nlet lastClickTime = 0;\r\nlet isMousedownKeyTrigger = false;\r\nconst doubleClickThreshold = 300;\r\n\r\n// Block operations events\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n if (johannesEditor) {\r\n document.querySelectorAll('.block-operation').forEach(option => {\r\n option.addEventListener('click', function (event) {\r\n\r\n const operation = this.getAttribute('data-block-operation');\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(operation, [event]);\r\n\r\n command.execute();\r\n });\r\n });\r\n }\r\n});\r\n\r\n\r\n// Text operations events\r\n//CODE...\r\n\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n if (johannesEditor) {\r\n document.querySelectorAll('.text-formatting-operation').forEach(option => {\r\n option.addEventListener('click', function (event) {\r\n\r\n const operation = this.getAttribute('data-text-formatting-operation');\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(operation, [event]);\r\n\r\n command.execute();\r\n\r\n });\r\n });\r\n }\r\n});\r\n\r\n\r\n\r\n\r\ndocument.addEventListener('mousedown', function (event) {\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)) {\r\n isMousedownKeyTrigger = true;\r\n }\r\n});\r\n\r\n//Mouse up + selection event\r\ndocument.addEventListener('mouseup', function (event) {\r\n const currentTime = Date.now();\r\n const timeSinceLastClick = currentTime - lastClickTime;\r\n lastClickTime = currentTime;\r\n\r\n if (timeSinceLastClick < doubleClickThreshold) {\r\n return;\r\n }\r\n\r\n if (window.getSelection().toString().trim() !== '' && isMousedownKeyTrigger && !(0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__.isShowingTextFormattingBar)()) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n // clearTextFormattingButtonActive();\r\n // showTextFormattingBar(event);\r\n // updateTextFormattingActiveButtons();\r\n\r\n }\r\n});\r\n\r\ndocument.addEventListener('dblclick', function (event) {\r\n if (!(0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__.isShowingTextFormattingBar)()) {\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 15);\r\n }\r\n});\r\n\r\n\r\n//\r\ndocument.addEventListener('mouseup', function (event) {\r\n if ((0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__.isShowingTextFormattingBar)() && (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__.canHideTextFormattingBar)() && (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_1__.isOutOfTextFormattingBar)(event)) {\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n});\n\n//# sourceURL=webpack://johannes/./src/triggers/click-events.js?"); + +/***/ }), + +/***/ "./src/triggers/keypress-events.js": +/*!*****************************************!*\ + !*** ./src/triggers/keypress-events.js ***! + \*****************************************/ +/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { + +"use strict"; +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../commands/command-factory */ \"./src/commands/command-factory.js\");\n/* harmony import */ var _components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../components/quick-insert-menu/quick-insert-menu */ \"./src/components/quick-insert-menu/quick-insert-menu.js\");\n/* harmony import */ var _helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../helper */ \"./src/helper.js\");\n/* harmony import */ var _components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/text-formatting-bar/text-formatting-bar */ \"./src/components/text-formatting-bar/text-formatting-bar.js\");\n//The start point for key press events\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n// Block operations is operations related to the block it self. Create a block, delete a block, change the block type, etc...\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n\r\n document.addEventListener('keydown', function (event) {\r\n\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event) && !(0,_components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n\r\n if (event.key === 'Enter' && !(0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() && !(0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n //TODO: pass the event not event.target/it`s more simple to deal with event when create a click eventListener\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.CREATE_NEW_ELEMENT, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'Backspace' && isActiveContentBlank(event) && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_PREVIOUS);\r\n command.execute();\r\n\r\n } else if (event.key === 'Delete' && isActiveContentBlank() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK.DELETE_AND_FOCUS_ON_NEXT);\r\n command.execute();\r\n\r\n }\r\n }\r\n });\r\n\r\n document.addEventListener('keyup', function (event) {\r\n\r\n if ((0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event) && !(0,_components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n if (event.key === 'Escape' && isActiveContentBlank() && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n //TODO: write the code to select the all text\r\n\r\n }\r\n }\r\n });\r\n});\r\n\r\n// Block options operations is operations related to the Block Options. Show the block options, hide the block options, filter, ...\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n document.addEventListener('keydown', function (event) {\r\n\r\n // if (isTriggable(event) && !isShowingBlockOptions()) {\r\n\r\n // if (event.key === '/' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n // const command = commandFactory.createCommand(commandFactory.OPERATIONS.BLOCK_OPTIONS.SHOW_BLOCK_OPTIONS);\r\n // command.execute();\r\n // }\r\n // }\r\n\r\n if ((0,_components_quick_insert_menu_quick_insert_menu__WEBPACK_IMPORTED_MODULE_1__.isShowingBlockOptions)()) {\r\n\r\n if (event.key === 'Escape' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const elementToFocusAfterHide = event.target;\r\n\r\n //TODO: pass the event not event.target/it`s more simple to deal with event when create a click eventListener\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.HIDE_CLEAR_BLOCK_OPTIONS, [elementToFocusAfterHide]);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowDown' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowUp' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'Enter' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE, [event]);\r\n command.execute();\r\n\r\n } else if (/^[a-z0-9]$/i.test(event.key) && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.FILTER_CONCAT, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'Backspace') {\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.FILTER_REMOVE_LAST);\r\n command.execute();\r\n }\r\n }\r\n\r\n\r\n if ((0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)()) {\r\n\r\n if (event.key === 'Escape' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowDown' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_NEXT_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'ArrowUp' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.MOVE_FAKE_FOCUS_TO_PREVIOUS_OPTION);\r\n command.execute();\r\n\r\n } else if (event.key === 'Enter' && !event.ctrlKey && !event.shiftKey && !event.altKey) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.BLOCK_OPTIONS.APPLY_SELECTED_BLOCK_TYPE, [event]);\r\n command.execute();\r\n\r\n }\r\n }\r\n });\r\n});\r\n\r\n\r\n// Text formatting bar operations is operations related to text presentation, color, show or hide text formatting dependent boxes,...\r\ndocument.addEventListener('keyup', function (event) {\r\n if (event.key === 'Shift' && (0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n }\r\n});\r\n\r\ndocument.addEventListener('keydown', function (event) {\r\n if (event.ctrlKey && event.key.toLowerCase() === 'a' && (0,_helper__WEBPACK_IMPORTED_MODULE_2__.isTriggable)(event)) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() !== '') {\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.SHOW_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n\r\n } else if (event.key === 'Escape' && (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.canHideTextFormattingBar)() && (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)()) {\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n});\r\n\r\n\r\n\r\nfunction isActiveContentBlank() {\r\n return document.activeElement.textContent.trim() === '';\r\n}\r\n\r\n\r\n// Listen a input link\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n linkBoxInput.addEventListener('keydown', function (event) {\r\n if (event.key === 'Enter') {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.INPUT_LINK_URL);\r\n command.execute();\r\n }\r\n });\r\n});\r\n\r\n\r\n// Lock left and right key when is showing the dependent box\r\ndocument.addEventListener('keydown', function (event) {\r\n if ((0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() &&\r\n (event.key === 'ArrowLeft' || event.key === 'ArrowRight')) {\r\n\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n});\r\n\r\n\r\ndocument.addEventListener('keyup', function (event) {\r\n if ((0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingBar)() && (0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.canHideTextFormattingBar)() && !(0,_components_text_formatting_bar_text_formatting_bar__WEBPACK_IMPORTED_MODULE_3__.isShowingTextFormattingSelectableDependentBox)() &&\r\n (event.key === 'ArrowLeft' || event.key === 'ArrowRight' || event.key === 'ArrowUp' || event.key === 'ArrowDown')) {\r\n\r\n setTimeout(() => {\r\n if (window.getSelection().toString().trim() == '') {\r\n const command = _commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.createCommand(_commands_command_factory__WEBPACK_IMPORTED_MODULE_0__.OPERATIONS.FORMATTING_BAR.HIDE_TEXT_FORMATTING_BAR, [event]);\r\n command.execute();\r\n }\r\n }, 10);\r\n }\r\n});\n\n//# sourceURL=webpack://johannes/./src/triggers/keypress-events.js?"); + +/***/ }), + +/***/ "./src/triggers/load-events.js": +/*!*************************************!*\ + !*** ./src/triggers/load-events.js ***! + \*************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; -eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ canHideTextFormattingBar: () => (/* binding */ canHideTextFormattingBar),\n/* harmony export */ hideAllDependentBox: () => (/* binding */ hideAllDependentBox),\n/* harmony export */ hideTextFormattingBar: () => (/* binding */ hideTextFormattingBar),\n/* harmony export */ inputLinkUrl: () => (/* binding */ inputLinkUrl),\n/* harmony export */ isOutOfTextFormattingBar: () => (/* binding */ isOutOfTextFormattingBar),\n/* harmony export */ isShowingTextFormattingBar: () => (/* binding */ isShowingTextFormattingBar),\n/* harmony export */ isShowingTextFormattingSelectableDependentBox: () => (/* binding */ isShowingTextFormattingSelectableDependentBox),\n/* harmony export */ showTextFormattingBar: () => (/* binding */ showTextFormattingBar),\n/* harmony export */ toggleChangeColorBox: () => (/* binding */ toggleChangeColorBox),\n/* harmony export */ toggleEncloseSelectedTextTo: () => (/* binding */ toggleEncloseSelectedTextTo),\n/* harmony export */ toggleInputLinkBox: () => (/* binding */ toggleInputLinkBox),\n/* harmony export */ toggleMoreOptionsBox: () => (/* binding */ toggleMoreOptionsBox),\n/* harmony export */ toggleTurnIntoBox: () => (/* binding */ toggleTurnIntoBox)\n/* harmony export */ });\n/* harmony import */ var _j_selection__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./j-selection */ \"./src/j-selection.js\");\n/* harmony import */ var _j_anchor__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./j-anchor */ \"./src/j-anchor.js\");\n/* harmony import */ var _block_options_operation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./block-options-operation */ \"./src/block-options-operation.js\");\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nlet textFormattingBarVisible = false;\r\nlet textFormattingBarPreventHide = false;\r\n\r\n\r\n\r\nfunction isShowingTextFormattingSelectableDependentBox() {\r\n let isShowing = (\r\n turnIntoSelect.style.display !== 'none' ||\r\n moreTextOptionSelect.style.display !== 'none' ||\r\n colorTextOptionSelect.style.display !== 'none');\r\n return isShowing;\r\n}\r\n\r\nfunction isOutOfTextFormattingBar(event) {\r\n\r\n if (!event.target.closest('#textFormattingBar') && !event.target.closest('#linkBox')) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\nfunction canHideTextFormattingBar() {\r\n return !textFormattingBarPreventHide;\r\n}\r\n\r\nfunction isShowingTextFormattingBar() {\r\n return textFormattingBar.style.display !== 'none';\r\n}\r\n\r\nfunction showTextFormattingBar(event) {\r\n\r\n console.log('show text formatting bar');\r\n\r\n hideAllDependentBox();\r\n\r\n textFormattingBarVisible = true;\r\n textFormattingBarPreventHide = true;\r\n\r\n setTimeout(() => {\r\n textFormattingBarPreventHide = false;\r\n }, 300);\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.removeSavedSelection();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.saveSelection();\r\n\r\n clearTextFormattingButtonActive();\r\n updateTextFormattingActiveButtons();\r\n\r\n changeTurnIntoButtonText();\r\n\r\n const selection = window.getSelection();\r\n\r\n if (selection.rangeCount > 0 && document.querySelector('.johannes-editor').contains(selection.anchorNode) && selection.toString().trim() !== '') {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n\r\n let range = selection.getRangeAt(0);\r\n let rect = range.getBoundingClientRect();\r\n\r\n textFormattingBar.style.display = 'flex';\r\n textFormattingBar.style.left = `${rect.left + window.scrollX - 50}px`;\r\n textFormattingBar.style.top = `${rect.top + window.scrollY - textFormattingBar.offsetHeight - 10}px`;\r\n }\r\n}\r\n\r\nfunction hideTextFormattingBar() {\r\n\r\n console.log('hide text formatting bar ');\r\n\r\n // textFormattingBar.style.display = 'none';\r\n\r\n tryHideTextFormattingBar();\r\n}\r\n\r\n\r\nfunction clearTextFormattingButtonActive() {\r\n linkTextButton.classList.remove('text-formatting-button-active');\r\n boldTextButton.classList.remove('text-formatting-button-active');\r\n italicTextButton.classList.remove('text-formatting-button-active');\r\n underlineTextButton.classList.remove('text-formatting-button-active');\r\n codeTextButton.classList.remove('text-formatting-button-active');\r\n strikeThroughTextButton.classList.remove('text-formatting-button-active');\r\n mathTextButton.classList.remove('text-formatting-button-active');\r\n colorCircle.classList.remove('text-formatting-circle-active');\r\n}\r\n\r\nfunction updateTextFormattingActiveButtons() {\r\n\r\n const selectedTags = getSelectedTags();\r\n\r\n selectedTags.forEach(tag => {\r\n\r\n if (tag == \"a\") {\r\n linkTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"strong\") {\r\n boldTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"em\") {\r\n italicTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"u\") {\r\n underlineTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"s\") {\r\n strikeThroughTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"code\") {\r\n codeTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"math\") {\r\n mathTextButton.classList.add('text-formatting-button-active');\r\n }\r\n\r\n if (tag == \"mark\") {\r\n colorCircle.classList.add('text-formatting-circle-active');\r\n }\r\n });\r\n}\r\n\r\nfunction getSelectedTags() {\r\n const selection = window.getSelection();\r\n const tags = [];\r\n\r\n const tagNames = [\"STRONG\", \"S\", \"EM\", \"U\", \"CODE\", \"MATH\", \"A\", \"MARK\"];\r\n\r\n if (selection.rangeCount) {\r\n const range = selection.getRangeAt(0);\r\n const startContainer = range.startContainer;\r\n const endContainer = range.endContainer;\r\n\r\n if (startContainer !== endContainer) {\r\n const commonAncestor = range.commonAncestorContainer;\r\n const elements = commonAncestor.nodeType === 1 ? commonAncestor.querySelectorAll(\"*\") : [];\r\n\r\n elements.forEach(el => {\r\n if (tagNames.includes(el.tagName) && selection.containsNode(el, true)) {\r\n tags.push(el.tagName.toLowerCase());\r\n }\r\n });\r\n } else {\r\n let node = startContainer.nodeType === 1 ? startContainer : startContainer.parentNode;\r\n while (node && node !== document) {\r\n if (tagNames.includes(node.tagName)) {\r\n tags.push(node.tagName.toLowerCase());\r\n }\r\n node = node.parentNode;\r\n }\r\n }\r\n }\r\n\r\n return [...new Set(tags)];\r\n}\r\n\r\n\r\nfunction toggleEncloseSelectedTextTo(event) {\r\n const dataTag = event.target.closest('.entry').getAttribute('data-tag');\r\n const dataClass = event.target.closest('.entry').getAttribute('data-class');\r\n\r\n if (dataClass) {\r\n toggleSelectedTextTo(dataTag, dataClass);\r\n } else {\r\n toggleSelectedTextTo(dataTag);\r\n }\r\n\r\n hideAllDependentBox();\r\n hideTextFormattingBar();\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n}\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n\r\n// boldTextButton.addEventListener('click', function (event) {\r\n// toggleSelectedTextTo('strong');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// italicTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('em');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// underlineTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('u');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// codeTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('code');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// strikeThroughTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('s');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// mathTextButton.addEventListener('click', function () {\r\n// toggleSelectedTextTo('math');\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n\r\n// linkTextButton.addEventListener('click', function () {\r\n// jAnchor.save(toggleSelectedTextTo('a'));\r\n\r\n// if (jAnchor.any()) {\r\n// showInputLinkBox();\r\n// }\r\n// });\r\n\r\n// linkBoxInput.addEventListener('keypress', function (event) {\r\n// if (event.key === 'Enter') {\r\n// urlInsert();\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n// });\r\n\r\n\r\n\r\nfunction inputLinkUrl() {\r\n const url = linkBoxInput.value.trim();\r\n if (!url) return;\r\n\r\n // Simples verificação de URL\r\n if (!url.match(/^https?:\\/\\/.+/)) {\r\n alert('Please enter a valid URL.');\r\n return;\r\n }\r\n\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.setURL(url);\r\n\r\n //Move this to windows manager\r\n hideLinkBox();\r\n\r\n // jAnchor.clear();\r\n // jSelection.clearAllSelection();\r\n\r\n\r\n //Ops\r\n linkBoxInput.value = '';\r\n}\r\n\r\n\r\nfunction toggleSelectedTextTo(tagName, classList = '') {\r\n let newElement = null;\r\n\r\n const range = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange();\r\n const selectedText = range.toString().trim();\r\n if (!selectedText) return;\r\n\r\n const container = range.commonAncestorContainer;\r\n\r\n // Encontrar o elemento formatado mais próximo\r\n let formattedElement = null;\r\n if (container.nodeType === 3) { // Nó de texto\r\n formattedElement = container.parentNode.tagName.toLowerCase() === tagName.toLowerCase() ? container.parentNode : null;\r\n } else {\r\n formattedElement = container.tagName.toLowerCase() === tagName.toLowerCase() ? container : container.querySelector(tagName);\r\n }\r\n\r\n if (formattedElement) {\r\n // Remover todos os irmãos dentro da seleção que correspondem ao tagName\r\n const siblings = Array.from(formattedElement.parentNode.childNodes).filter(child =>\r\n child.nodeType === 1 && // Element node\r\n child.tagName.toLowerCase() === tagName.toLowerCase() &&\r\n range.intersectsNode(child) // Verifica se o nó está dentro da seleção\r\n );\r\n\r\n const parent = formattedElement.parentNode;\r\n siblings.forEach(sibling => {\r\n while (sibling.firstChild) {\r\n parent.insertBefore(sibling.firstChild, sibling);\r\n }\r\n parent.removeChild(sibling);\r\n });\r\n\r\n parent.normalize();\r\n\r\n // Atualizar a seleção para refletir as mudanças\r\n range.setStart(parent, 0);\r\n range.setEnd(parent, parent.childNodes.length);\r\n } else {\r\n // A seleção não está na formatação especificada, então adicionar\r\n newElement = document.createElement(tagName);\r\n if (tagName === 'mark') {\r\n let classes = classList.split(',').filter(e => e.length > 0);\r\n classes.forEach(className => {\r\n newElement.classList.add(className);\r\n });\r\n }\r\n\r\n try {\r\n range.surroundContents(newElement);\r\n } catch (e) {\r\n console.error(\"Erro ao aplicar a tag:\", e);\r\n return;\r\n }\r\n\r\n range.selectNodeContents(newElement);\r\n }\r\n\r\n // Restaurar a seleção\r\n // selection.removeAllRanges();\r\n // selection.addRange(range);\r\n\r\n return newElement;\r\n}\r\n\r\n//original funcional\r\n// function toggleSelectedTextTo(tagName, classList = '') {\r\n\r\n// let newElement = null;\r\n\r\n\r\n\r\n// const range = jSelection.getSavedRange();\r\n// const selectedText = range.toString().trim();\r\n// if (!selectedText) return;\r\n\r\n// const container = range.commonAncestorContainer;\r\n\r\n// // Verificar se a seleção atual está dentro de uma tag específica\r\n// let formattedElement = null;\r\n\r\n// if (container.nodeType === 3) { // Nó de texto\r\n// formattedElement = container.parentNode.tagName.toLowerCase() === tagName.toLowerCase() ? container.parentNode : null;\r\n// } else {\r\n// formattedElement = container.tagName.toLowerCase() === tagName.toLowerCase() ? container : container.querySelector(tagName);\r\n// }\r\n\r\n// if (formattedElement) {\r\n// // A seleção está dentro da formatação especificada, então devemos remover\r\n// const parent = formattedElement.parentNode;\r\n// while (formattedElement.firstChild) {\r\n// parent.insertBefore(formattedElement.firstChild, formattedElement);\r\n// }\r\n// parent.removeChild(formattedElement);\r\n\r\n// // Mesclar nós de texto adjacentes\r\n// parent.normalize();\r\n\r\n// // Atualizar a seleção para refletir as mudanças\r\n// range.setStart(parent, 0);\r\n// range.setEnd(parent, parent.childNodes.length);\r\n// } else {\r\n// // A seleção não está na formatação especificada, então adicionar\r\n// newElement = document.createElement(tagName);\r\n\r\n// if (tagName == 'mark') {\r\n// let classes = classList.split(',').filter(e => e.length > 0);\r\n\r\n// for (let className of classes) {\r\n// newElement.classList.add(className);\r\n// }\r\n// }\r\n\r\n// try {\r\n// range.surroundContents(newElement);\r\n// } catch (e) {\r\n// console.error(\"Erro ao aplicar a tag:\", e);\r\n// return;\r\n// }\r\n\r\n// // Atualizar a seleção para refletir as mudanças\r\n// range.selectNodeContents(newElement);\r\n// }\r\n\r\n// // Restaurar a seleção\r\n// // selection.removeAllRanges();\r\n// // selection.addRange(range);\r\n\r\n// return newElement;\r\n// }\r\n\r\n\r\n// function clearSelection() {\r\n// const selection = window.getSelection();\r\n// selection.removeAllRanges();\r\n// }\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n\r\n// //MOUSE-UP\r\n// document.addEventListener('mouseup', function (event) {\r\n// if (window.getSelection().toString().trim() !== '') {\r\n\r\n// clearTextFormattingButtonActive();\r\n// showTextFormattingBar(event);\r\n// updateTextFormattingActiveButtons();\r\n\r\n// } else if (!event.target.closest('#linkBox') && !event.target.closest('#link-text-button')) {\r\n\r\n// console.log('MOUSEUP ocultar tool text-formatting-bar e link-box');\r\n\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n\r\n// //KEY\r\n// document.addEventListener('keyup', function (event) {\r\n// if (event.key === 'Shift' && window.getSelection().toString().trim() !== '') {\r\n// // text selected\r\n\r\n// showTextFormattingBar(event);\r\n\r\n// } else if (event.key === 'Escape') {\r\n// // scape hide the link-box and text-formatting-bar\r\n// console.log('ESC ocultar tool text-formatting-bar e link-box');\r\n\r\n// tryHideTextFormattingBar();\r\n// }\r\n// });\r\n\r\n// });\r\n\r\n\r\n\r\n\r\n// function adjustWidth() {\r\n// const selectedOption = turnIntoSelect.options[turnIntoSelect.selectedIndex];\r\n// const tempSpan = document.createElement(\"span\");\r\n// tempSpan.style.visibility = \"hidden\";\r\n// tempSpan.style.position = \"fixed\";\r\n// tempSpan.style.whiteSpace = \"nowrap\";\r\n// tempSpan.innerText = selectedOption.text;\r\n// document.body.appendChild(tempSpan);\r\n// turnIntoSelect.style.width = tempSpan.offsetWidth + 24 + \"px\"; // +20 para incluir o padding e o botão de dropdown\r\n// document.body.removeChild(tempSpan);\r\n// }\r\n\r\n\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// turnIntoButton.addEventListener('click', function () {\r\n\r\n// if (turnIntoSelect.style.display == 'none') {\r\n// closeAllDependentBox();\r\n// turnIntoSelect.style.display = 'flex';\r\n// } else {\r\n// turnIntoSelect.style.display = 'none';\r\n// }\r\n// });\r\n// });\r\n\r\n\r\nfunction changeTurnIntoButtonText() {\r\n\r\n let text = getBlockTypeText();\r\n\r\n turnIntoButton.querySelector('span').innerText = text;\r\n}\r\n\r\nfunction getBlockTypeText() {\r\n let currentBlockRange = window.getSelection().getRangeAt(0);\r\n\r\n let commonAncestor = currentBlockRange.commonAncestorContainer;\r\n\r\n if (commonAncestor.nodeType === 3) { //* text node */\r\n commonAncestor = commonAncestor.parentNode;\r\n }\r\n\r\n const currentBlock = commonAncestor.closest('.johannes-content-element');\r\n\r\n if (currentBlock.tagName === 'H1') {\r\n return 'Heading 1';\r\n } else if (currentBlock.tagName === 'H2') {\r\n return 'Heading 2';\r\n } else if (currentBlock.tagName === 'H3') {\r\n return 'Heading 3';\r\n } else if (currentBlock.tagName === 'H4') {\r\n return 'Heading 4';\r\n } else if (currentBlock.tagName === 'H5') {\r\n return 'Heading 5';\r\n } else if (currentBlock.tagName === 'H6') {\r\n return 'Heading 6';\r\n } else if (currentBlock.tagName === 'P') {\r\n return 'Text';\r\n } else if (currentBlock.tagName === 'UL' && currentBlock.classList.contains('checkbox-list')) {\r\n return 'Todo list';\r\n } else if (currentBlock.tagName === 'UL') {\r\n return 'Bulleted list';\r\n } else if (currentBlock.tagName === 'OL') {\r\n return 'Numbered list';\r\n } else if (currentBlock.tagName === 'BLOCKQUOTE') {\r\n return 'Quote';\r\n } else if (currentBlock.tagName === 'PRE') {\r\n return 'Code';\r\n } else {\r\n return '';\r\n }\r\n\r\n}\r\n\r\nfunction setTurnIntoCurrentSelectedBlockOptionIcon() {\r\n let block = (0,_j_selection__WEBPACK_IMPORTED_MODULE_0__.getCurrentDraggableBlockFocused)().querySelector('.johannes-content-element');\r\n\r\n if (block) {\r\n let type = block.getAttribute('data-type');\r\n let option = turnIntoSelect.querySelector(`[data-type=\"${type}\"]`);\r\n\r\n if (option) {\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n svg.classList.add('checked-svg');\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", \"#icon-material-small-check\");\r\n\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', '16');\r\n svg.setAttribute('height', '16');\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n // let textOption = option.querySelector('.text-option');\r\n option.appendChild(svg);\r\n }\r\n }\r\n}\r\n\r\nfunction extractMarkClasses(element) {\r\n const marks = element.querySelectorAll('mark');\r\n const classes = [];\r\n\r\n marks.forEach(mark => {\r\n mark.classList.forEach(cls => {\r\n if (!classes.includes(cls)) {\r\n classes.push(cls);\r\n }\r\n });\r\n });\r\n\r\n return classes;\r\n}\r\n\r\nfunction setColorCurrentSelectedIcon() {\r\n let currentRange = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange();\r\n\r\n if (currentRange) {\r\n let fragment = currentRange.cloneContents();\r\n\r\n let tempDiv = document.createElement(\"div\");\r\n tempDiv.appendChild(fragment);\r\n\r\n let marks = extractMarkClasses(tempDiv);\r\n\r\n marks.forEach(markClass => {\r\n let option = colorTextOptionSelect.querySelector(`[data-class=\"${markClass}\"]`);\r\n\r\n if (option && !option.querySelector('.checked-svg')) {\r\n let svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n svg.classList.add('checked-svg');\r\n let use = document.createElementNS(\"http://www.w3.org/2000/svg\", \"use\");\r\n use.setAttributeNS(\"http://www.w3.org/1999/xlink\", \"href\", \"#icon-material-small-check\");\r\n\r\n svg.appendChild(use);\r\n svg.setAttribute('width', '16');\r\n svg.setAttribute('height', '16');\r\n svg.setAttribute('fill', 'currentColor');\r\n\r\n option.appendChild(svg);\r\n }\r\n });\r\n\r\n if (marks.length > 0) {\r\n let options = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.setAttribute('disabled', 'true');\r\n option.style.cursor = \"not-allowed\";\r\n });\r\n\r\n clearColorBackgroundOption.removeAttribute('disabled');\r\n clearColorBackgroundOption.style.display = 'flex';\r\n clearColorBackgroundOption.style.cursor = \"auto\";\r\n\r\n } else {\r\n clearColorBackgroundOption.style.display = 'none';\r\n }\r\n\r\n\r\n }\r\n}\r\n\r\nfunction removeAllSVGsFromTurnIntoTextOptions() {\r\n const textOptions = turnIntoSelect.querySelectorAll('.option');\r\n\r\n textOptions.forEach(textOption => {\r\n const svgs = textOption.querySelectorAll('.checked-svg');\r\n\r\n svgs.forEach(svg => {\r\n svg.parentNode.removeChild(svg);\r\n });\r\n });\r\n}\r\n\r\nfunction removeAllSVGsFromColorsTextOptions() {\r\n const textOptions = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n textOptions.forEach(textOption => {\r\n const svgs = textOption.querySelectorAll('.checked-svg');\r\n\r\n svgs.forEach(svg => {\r\n svg.parentNode.removeChild(svg);\r\n });\r\n });\r\n\r\n let options = colorTextOptionSelect.querySelectorAll('.option');\r\n\r\n options.forEach(option => {\r\n option.removeAttribute('disabled');\r\n option.style.cursor = \"auto\";\r\n });\r\n\r\n clearColorBackgroundOption.style.display = 'none';\r\n clearColorBackgroundOption.style.cursor = \"auto\";\r\n}\r\n\r\n\r\nfunction toggleMoreOptionsBox(event) {\r\n\r\n console.log('toggle more options');\r\n\r\n const isHidden = moreTextOptionSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n moreTextOptionSelect.style.display = 'flex';\r\n (0,_block_options_operation__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.temporarySelectContentFromCurrentSelection();\r\n\r\n } else {\r\n hideMoreOptionsBox();\r\n }\r\n\r\n hideChangeColorBox();\r\n hideTurnIntoBox();\r\n hideLinkBox();\r\n}\r\n\r\nfunction toggleChangeColorBox(event) {\r\n\r\n console.log('toggle change color');\r\n\r\n const isHidden = colorTextOptionSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n colorTextOptionSelect.style.display = 'flex';\r\n (0,_block_options_operation__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n\r\n removeAllSVGsFromColorsTextOptions();\r\n setColorCurrentSelectedIcon();\r\n\r\n } else {\r\n colorTextOptionSelect.style.display = 'none';\r\n }\r\n\r\n hideTurnIntoBox();\r\n hideMoreOptionsBox();\r\n hideLinkBox();\r\n}\r\n\r\nfunction toggleTurnIntoBox(event) {\r\n\r\n console.log('toggle turn into box');\r\n\r\n const isHidden = turnIntoSelect.style.display == 'none';\r\n\r\n if (isHidden) {\r\n turnIntoSelect.style.display = 'flex';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.temporarySelectContentFromCurrentSelection();\r\n\r\n (0,_block_options_operation__WEBPACK_IMPORTED_MODULE_2__.showDependentBlockOptions)(event.target);\r\n removeAllSVGsFromTurnIntoTextOptions();\r\n setTurnIntoCurrentSelectedBlockOptionIcon();\r\n } else {\r\n hideTurnIntoBox();\r\n }\r\n\r\n hideChangeColorBox();\r\n hideMoreOptionsBox();\r\n hideLinkBox();\r\n}\r\n\r\n//**Show */\r\nfunction toggleInputLinkBox() {\r\n\r\n\r\n console.log('toggle input link box');\r\n\r\n const isHidden = linkBox.style.display == 'none';\r\n\r\n if (isHidden) {\r\n // turnIntoSelect.style.display = 'flex';\r\n\r\n showInputLinkBox();\r\n\r\n } else {\r\n turnIntoSelect.style.display = 'none';\r\n }\r\n\r\n hideChangeColorBox();\r\n hideMoreOptionsBox();\r\n hideTurnIntoBox();\r\n}\r\n\r\n\r\n\r\nfunction showInputLinkBox() {\r\n\r\n const rect = _j_selection__WEBPACK_IMPORTED_MODULE_0__.getSavedRange().getBoundingClientRect();\r\n\r\n const containerWidth = textFormattingBar.offsetWidth;\r\n const linkInputDivWidth = linkBox.offsetWidth;\r\n const containerCenter = (textFormattingBar.getBoundingClientRect().left + containerWidth) / 2;\r\n const linkInputDivCenter = (linkBox.getBoundingClientRect().left + linkInputDivWidth) / 2;\r\n\r\n linkBox.style.position = 'absolute';\r\n linkBox.style.left = `${containerCenter - linkInputDivCenter + window.scrollX}px`;\r\n linkBox.style.top = `${rect.bottom + window.scrollY + 5}px`;\r\n linkBox.style.display = 'block';\r\n\r\n // linkBoxInput.focus();\r\n\r\n highlightTheSelectionText();\r\n\r\n}\r\n\r\n//The highlight is added using a anchor. It's ok? I swap to span\r\nfunction highlightTheSelectionText() {\r\n const a = toggleSelectedTextTo('a');\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.setAnchor(a);\r\n}\r\n\r\n\r\n\r\n\r\n// toggle-change-color-formatting-bar\r\n\r\n//Show color options\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// colorTextButton.addEventListener('click', function () {\r\n// if (colorTextOptionSelect.style.display == 'none') {\r\n// showColorOptions();\r\n// } else {\r\n// hideColorOptions();\r\n// }\r\n// });\r\n// });\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction showColorOptions() {\r\n hideAllDependentBox();\r\n colorTextOptionSelect.style.display = 'flex';\r\n}\r\n\r\n\r\n\r\n// document.addEventListener('DOMContentLoaded', function () {\r\n// colorTextOptionSelect.querySelectorAll('.option').forEach(option => {\r\n// option.addEventListener('click', function (event) {\r\n// let background = event.target.closest('.option').getAttribute('data-color');\r\n// toggleSelectedTextTo('mark', background);\r\n// clearSelection();\r\n// tryHideTextFormattingBar();\r\n// });\r\n// });\r\n// });\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction tryHideTextFormattingBar() {\r\n\r\n // check before if a dependent box is opened, then close the dependent box\r\n\r\n //1. try close text-formatting-bar before linkBox (the actual only one dependency box)\r\n if (isShowingTextFormattingBar() && !anyDependentBoxVisible()) {\r\n // only hide if the dependency box is closed\r\n textFormattingBar.style.display = 'none';\r\n // restoreSelection();\r\n }\r\n\r\n // 2. close the dependency box (linkBox)\r\n if (anyDependentBoxVisible()) {\r\n\r\n // Remove a if has no href attribute or if href is empty\r\n //Move this to a logic inside the linking box\r\n // if (anchorElement && (anchorElement.href == '' || anchorElement.href == null)) {\r\n // const parent = anchorElement.parentNode;\r\n // while (anchorElement.firstChild) {\r\n // parent.insertBefore(anchorElement.firstChild, anchorElement);\r\n // }\r\n\r\n // if (parent) {\r\n // parent.removeChild(anchorElement);\r\n // parent.normalize(); // Mesclar nós de texto adjacentes, se necessário\r\n // }\r\n // }\r\n\r\n // linkBox.style.display = 'none';\r\n hideAllDependentBox();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n }\r\n}\r\n\r\nfunction anyDependentBoxVisible() {\r\n const dependentBoxes = document.querySelectorAll('.dependent-box');\r\n\r\n for (const box of dependentBoxes) {\r\n if (box.style.display !== 'none') {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n}\r\n\r\n\r\n\r\n\r\n\r\n\r\nfunction hideMoreOptionsBox() {\r\n\r\n if (moreTextOptionSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide more options');\r\n\r\n moreTextOptionSelect.style.display = 'none';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n}\r\n\r\nfunction hideTurnIntoBox() {\r\n\r\n if (turnIntoSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide turn into box');\r\n turnIntoSelect.style.display = 'none';\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n //jSelection.restoreSelection(); //TODO. Do I need this?\r\n //jSelection.removeSavedSelection();\r\n}\r\n\r\nfunction hideChangeColorBox() {\r\n\r\n if (colorTextOptionSelect.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide change color box');\r\n colorTextOptionSelect.style.display = 'none';\r\n}\r\n\r\nfunction hideLinkBox() {\r\n\r\n if (linkBox.style.display == 'none') {\r\n return;\r\n }\r\n\r\n console.log('hide link box');\r\n\r\n // if(linkBox.style.display != 'none'){\r\n\r\n // }\r\n _j_anchor__WEBPACK_IMPORTED_MODULE_1__.clear();\r\n _j_selection__WEBPACK_IMPORTED_MODULE_0__.restoreSelection();\r\n linkBox.style.display = 'none';\r\n}\r\n\r\n\r\n\r\nfunction hideAllDependentBox() {\r\n hideMoreOptionsBox();\r\n hideTurnIntoBox();\r\n hideChangeColorBox();\r\n hideLinkBox();\r\n}\r\n\n\n//# sourceURL=webpack://johannes/./src/text-formatting-bar-operation.js?"); +eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _components_quick_insert_menu_QuickInsertMenu__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../components/quick-insert-menu/QuickInsertMenu */ \"./src/components/quick-insert-menu/QuickInsertMenu.js\");\n//TODO use commands\r\n\r\n\r\n//Focus on P when load\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n const editor = document.querySelector('.johannes-editor');\r\n\r\n if (editor) {\r\n let blocks = editor.querySelectorAll('.draggable-block');\r\n\r\n if (blocks.length == 1) {\r\n\r\n const p = blocks[0].querySelector('.johannes-content-element');\r\n if (p.innerText == '') {\r\n p.focus();\r\n }\r\n }\r\n }\r\n});\r\n\r\n// Clear text when paste\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n const editor = document.querySelector('.johannes-editor');\r\n\r\n if (editor) {\r\n document.addEventListener('paste', function (e) {\r\n if (e.target.getAttribute('contenteditable') === 'true') {\r\n e.preventDefault();\r\n const text = (e.clipboardData || window.clipboardData).getData('text/plain');\r\n insertTextAtCursor(text);\r\n }\r\n }, true);\r\n\r\n function insertTextAtCursor(text) {\r\n const sel = window.getSelection();\r\n if (sel.rangeCount > 0) {\r\n const range = sel.getRangeAt(0);\r\n range.deleteContents();\r\n\r\n const textNode = document.createTextNode(text);\r\n range.insertNode(textNode);\r\n\r\n range.setStartAfter(textNode);\r\n range.setEndAfter(textNode);\r\n sel.removeAllRanges();\r\n sel.addRange(range);\r\n }\r\n }\r\n }\r\n});\r\n\r\n\r\ndocument.addEventListener('DOMContentLoaded', function () {\r\n\r\n\r\n johannesEditor.appendChild(_components_quick_insert_menu_QuickInsertMenu__WEBPACK_IMPORTED_MODULE_0__[\"default\"].getMenuElement());\r\n});\n\n//# sourceURL=webpack://johannes/./src/triggers/load-events.js?"); /***/ }) diff --git a/demo/index.html b/demo/index.html index 44d8d09..b71b6c3 100644 --- a/demo/index.html +++ b/demo/index.html @@ -35,7 +35,7 @@

-

@@ -49,7 +49,7 @@

-