Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 30 additions & 44 deletions app/assets/javascript/lexxy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6353,6 +6353,12 @@ const Ne$1=/^(\d+(?:\.\d+)?)px$/,ve$1={BOTH:3,COLUMN:2,NO_STATUS:0,ROW:1};class

const SILENT_UPDATE_TAGS = [ Dn, zn, Kn ];

function $createNodeSelectionWith(...nodes) {
const selection = Pr();
nodes.forEach(node => selection.add(node.getKey()));
return selection
}

function getNearestListItemNode(node) {
let current = node;
while (current !== null) {
Expand Down Expand Up @@ -6447,14 +6453,6 @@ function isPreviewableImage(contentType) {
return contentType.startsWith("image/") && !contentType.includes("svg")
}

function dispatchCustomEvent(element, name, detail) {
const event = new CustomEvent(name, {
detail: detail,
bubbles: true,
});
element.dispatchEvent(event);
}

function dispatch(element, eventName, detail = null, cancelable = false) {
return element.dispatchEvent(new CustomEvent(eventName, { bubbles: true, detail, cancelable }))
}
Expand Down Expand Up @@ -7249,10 +7247,6 @@ class ActionTextAttachmentNode extends ki {
createDOM() {
const figure = this.createAttachmentFigure();

figure.addEventListener("click", () => {
this.#select(figure);
});

if (this.isPreviewableAttachment) {
figure.appendChild(this.#createDOMForImage());
figure.appendChild(this.#createEditableCaption());
Expand Down Expand Up @@ -7325,6 +7319,11 @@ class ActionTextAttachmentNode extends ki {
return createAttachmentFigure(this.contentType, this.isPreviewableAttachment, this.fileName)
}

select() {
wo($createNodeSelectionWith(this));
return true
}

get #isPreviewableImage() {
return isPreviewableImage(this.contentType)
}
Expand Down Expand Up @@ -7365,10 +7364,6 @@ class ActionTextAttachmentNode extends ki {
return figcaption
}

#select(figure) {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() });
}

#createEditableCaption() {
const caption = createElement("figcaption", { className: "attachment__caption" });
const input = createElement("textarea", {
Expand Down Expand Up @@ -7703,10 +7698,6 @@ class HorizontalDividerNode extends ki {
const figure = createElement("figure", { className: "horizontal-divider" });
const hr = createElement("hr");

figure.addEventListener("click", (event) => {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() });
});

figure.appendChild(hr);

return figure
Expand All @@ -7720,6 +7711,11 @@ class HorizontalDividerNode extends ki {
return "┄\n\n"
}

select() {
wo($createNodeSelectionWith(this));
return true
}

isInline() {
return false
}
Expand Down Expand Up @@ -8460,20 +8456,14 @@ class Selection {
}

#listenForNodeSelections() {
this.editor.getRootElement().addEventListener("lexxy:internal:select-node", async (event) => {
await nextFrame();
this.editor.registerCommand(se$1, ({ target }) => {
if (!Ss(target)) return

const { key } = event.detail;
this.editor.update(() => {
const node = xo(key);
if (node) {
const selection = Pr();
selection.add(node.getKey());
wo(selection);
}
this.editor.focus();
});
});
const targetNode = vo(target);
if (!Ti(targetNode)) return

return targetNode.select?.()
}, zi);

this.editor.getRootElement().addEventListener("lexxy:internal:move-to-next-line", (event) => {
this.#selectOrAppendNextLine();
Expand Down Expand Up @@ -8687,13 +8677,8 @@ class Selection {
}

#selectInLexical(node) {
if (!node || !(node instanceof ki)) return

this.editor.update(() => {
const selection = Pr();
selection.add(node.getKey());
wo(selection);
});
if (node && (node instanceof ki)) node.select();
return true
}

#deleteSelectedOrNext() {
Expand Down Expand Up @@ -9007,16 +8992,17 @@ class CustomActionTextAttachmentNode extends ki {
createDOM() {
const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true });

figure.addEventListener("click", (event) => {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() });
});

figure.insertAdjacentHTML("beforeend", this.innerHtml);

return figure
}

updateDOM() {
return false
}

select() {
wo($createNodeSelectionWith(this));
return true
}

Expand Down
Binary file modified app/assets/javascript/lexxy.js.br
Binary file not shown.
Binary file modified app/assets/javascript/lexxy.js.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion app/assets/javascript/lexxy.min.js

Large diffs are not rendered by default.

Binary file modified app/assets/javascript/lexxy.min.js.br
Binary file not shown.
Binary file modified app/assets/javascript/lexxy.min.js.gz
Binary file not shown.
35 changes: 12 additions & 23 deletions src/editor/selection.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
$createNodeSelection, $createParagraphNode, $getNodeByKey, $getRoot, $getSelection, $isElementNode,
$isLineBreakNode, $isNodeSelection, $isRangeSelection, $isTextNode, $setSelection, COMMAND_PRIORITY_LOW, DecoratorNode,
$createParagraphNode, $getNearestNodeFromDOMNode, $getRoot, $getSelection, $isDecoratorNode, $isElementNode,
$isLineBreakNode, $isNodeSelection, $isRangeSelection, $isTextNode, CLICK_COMMAND, COMMAND_PRIORITY_LOW, DecoratorNode,
KEY_ARROW_DOWN_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND,
KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, SELECTION_CHANGE_COMMAND
KEY_BACKSPACE_COMMAND, KEY_DELETE_COMMAND, SELECTION_CHANGE_COMMAND, isDOMNode
} from "lexical"
import { $getNearestNodeOfType } from "@lexical/utils"
import { $getListDepth, ListNode } from "@lexical/list"
Expand Down Expand Up @@ -272,20 +272,14 @@ export default class Selection {
}

#listenForNodeSelections() {
this.editor.getRootElement().addEventListener("lexxy:internal:select-node", async (event) => {
await nextFrame()
this.editor.registerCommand(CLICK_COMMAND, ({ target }) => {
if (!isDOMNode(target)) return

const { key } = event.detail
this.editor.update(() => {
const node = $getNodeByKey(key)
if (node) {
const selection = $createNodeSelection()
selection.add(node.getKey())
$setSelection(selection)
}
this.editor.focus()
})
})
const targetNode = $getNearestNodeFromDOMNode(target)
if (!$isDecoratorNode(targetNode)) return

return targetNode.select?.()
}, COMMAND_PRIORITY_LOW)

this.editor.getRootElement().addEventListener("lexxy:internal:move-to-next-line", (event) => {
this.#selectOrAppendNextLine()
Expand Down Expand Up @@ -499,13 +493,8 @@ export default class Selection {
}

#selectInLexical(node) {
if (!node || !(node instanceof DecoratorNode)) return

this.editor.update(() => {
const selection = $createNodeSelection()
selection.add(node.getKey())
$setSelection(selection)
})
if (node && (node instanceof DecoratorNode)) node.select()
return true
}

#deleteSelectedOrNext() {
Expand Down
8 changes: 7 additions & 1 deletion src/helpers/lexical_helper.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { $isTextNode, TextNode } from "lexical"
import { $createNodeSelection, $isTextNode, TextNode } from "lexical"
import { HISTORY_MERGE_TAG, SKIP_DOM_SELECTION_TAG, SKIP_SCROLL_INTO_VIEW_TAG } from "lexical"
import { $isListItemNode, $isListNode } from "@lexical/list"

export const SILENT_UPDATE_TAGS = [ HISTORY_MERGE_TAG, SKIP_DOM_SELECTION_TAG, SKIP_SCROLL_INTO_VIEW_TAG ]

export function $createNodeSelectionWith(...nodes) {
const selection = $createNodeSelection()
nodes.forEach(node => selection.add(node.getKey()))
return selection
}

export function getNearestListItemNode(node) {
let current = node
while (current !== null) {
Expand Down
18 changes: 8 additions & 10 deletions src/nodes/action_text_attachment_node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Lexxy from "../config/lexxy"
import { $getEditor, DecoratorNode, HISTORY_MERGE_TAG } from "lexical"
import { createAttachmentFigure, createElement, dispatchCustomEvent, isPreviewableImage } from "../helpers/html_helper"
import { $getEditor, $setSelection, DecoratorNode, HISTORY_MERGE_TAG } from "lexical"
import { createAttachmentFigure, createElement, isPreviewableImage } from "../helpers/html_helper"
import { bytesToHumanSize } from "../helpers/storage_helper"
import { $createNodeSelectionWith } from "../helpers/lexical_helper"


export class ActionTextAttachmentNode extends DecoratorNode {
Expand Down Expand Up @@ -95,10 +96,6 @@ export class ActionTextAttachmentNode extends DecoratorNode {
createDOM() {
const figure = this.createAttachmentFigure()

figure.addEventListener("click", () => {
this.#select(figure)
})

if (this.isPreviewableAttachment) {
figure.appendChild(this.#createDOMForImage())
figure.appendChild(this.#createEditableCaption())
Expand Down Expand Up @@ -171,6 +168,11 @@ export class ActionTextAttachmentNode extends DecoratorNode {
return createAttachmentFigure(this.contentType, this.isPreviewableAttachment, this.fileName)
}

select() {
$setSelection($createNodeSelectionWith(this))
return true
}

get #isPreviewableImage() {
return isPreviewableImage(this.contentType)
}
Expand Down Expand Up @@ -211,10 +213,6 @@ export class ActionTextAttachmentNode extends DecoratorNode {
return figcaption
}

#select(figure) {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() })
}

#createEditableCaption() {
const caption = createElement("figcaption", { className: "attachment__caption" })
const input = createElement("textarea", {
Expand Down
14 changes: 8 additions & 6 deletions src/nodes/custom_action_text_attachment_node.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import Lexxy from "../config/lexxy"
import { $createTextNode, DecoratorNode } from "lexical"
import { $createTextNode, $setSelection, DecoratorNode } from "lexical"

import { createElement, dispatchCustomEvent } from "../helpers/html_helper"
import { createElement } from "../helpers/html_helper"
import { $createNodeSelectionWith } from "../helpers/lexical_helper"

export class CustomActionTextAttachmentNode extends DecoratorNode {
static getType() {
Expand Down Expand Up @@ -67,16 +68,17 @@ export class CustomActionTextAttachmentNode extends DecoratorNode {
createDOM() {
const figure = createElement(this.tagName, { "content-type": this.contentType, "data-lexxy-decorator": true })

figure.addEventListener("click", (event) => {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() })
})

figure.insertAdjacentHTML("beforeend", this.innerHtml)

return figure
}

updateDOM() {
return false
}

select() {
$setSelection($createNodeSelectionWith(this))
return true
}

Expand Down
14 changes: 8 additions & 6 deletions src/nodes/horizontal_divider_node.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { DecoratorNode } from "lexical"
import { createElement, dispatchCustomEvent } from "../helpers/html_helper"
import { $setSelection, DecoratorNode } from "lexical"
import { createElement } from "../helpers/html_helper"
import { $createNodeSelectionWith } from "../helpers/lexical_helper"

export class HorizontalDividerNode extends DecoratorNode {
static getType() {
Expand Down Expand Up @@ -35,10 +36,6 @@ export class HorizontalDividerNode extends DecoratorNode {
const figure = createElement("figure", { className: "horizontal-divider" })
const hr = createElement("hr")

figure.addEventListener("click", (event) => {
dispatchCustomEvent(figure, "lexxy:internal:select-node", { key: this.getKey() })
})

figure.appendChild(hr)

return figure
Expand All @@ -52,6 +49,11 @@ export class HorizontalDividerNode extends DecoratorNode {
return "┄\n\n"
}

select() {
$setSelection($createNodeSelectionWith(this))
return true
}

isInline() {
return false
}
Expand Down
2 changes: 0 additions & 2 deletions test/system/attachments_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,8 @@ class AttachmentsTest < ApplicationSystemTestCase
assert_image_figure_attachment content_type: "image/png", caption: "example.png"

find("figure.attachment img").click
wait_for_node_selection

find_editor.send_key "Delete"
wait_for_node_selection false

assert_no_attachment content_type: "image/png"
assert_editor_html ""
Expand Down
2 changes: 0 additions & 2 deletions test/system/horizontal_divider_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ class HorizontalDividerTest < ApplicationSystemTestCase
find_editor.send "Text after"

find("figure.horizontal-divider").click
wait_for_node_selection

find_editor.send_key "Delete"
wait_for_node_selection false

assert_no_selector "figure.horizontal-divider"
assert_editor_html "<p>Text before</p><p>Text after</p>"
Expand Down
4 changes: 0 additions & 4 deletions test/test_helpers/editor_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,6 @@ def wait_for_editor
assert_css "lexxy-toolbar[connected]" if has_css?("lexxy-toolbar")
end

def wait_for_node_selection(expected = true)
wait_until { expected == find_editor.has_node_selection? }
end

def click_table_handler_button(aria_label)
find("lexxy-table-tools button[aria-label='#{aria_label}']").click
end
Expand Down