lexxy 0.1.25.beta → 0.1.26.beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/javascript/lexxy.js +220 -37
- data/app/assets/javascript/lexxy.js.br +0 -0
- data/app/assets/javascript/lexxy.js.gz +0 -0
- data/app/assets/javascript/lexxy.js.map +1 -1
- data/app/assets/javascript/lexxy.min.js +3 -3
- data/app/assets/javascript/lexxy.min.js.br +0 -0
- data/app/assets/javascript/lexxy.min.js.gz +0 -0
- data/app/assets/stylesheets/lexxy-editor.css +12 -13
- data/lib/lexxy/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ff57bf7093680549f0e8a16c40c9d2e3b9c399ddea811fb8164b0915e6c869d4
|
|
4
|
+
data.tar.gz: 2e95ef8aedf887e717f9a7c8ea5b086ed0de1dc7840057fe50f2a4349ceba3d2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8eb3289e99dd46a96dc938b4e6b5a3b184b89dcb7650b9dab3ac256229151a74756e5d0d91d175bb4e38c82ead28a4dccfa5bcd31fbbcd7f4c69a270ee4d0e38
|
|
7
|
+
data.tar.gz: 946690466243ccec4590977b68a00948001c58b2e82f0e77f63b2293d4b850ef3c382b0e6006bd53ae95f0e0a32e8ca58cb304e19fd47ccc4509974998ab9ec1
|
|
@@ -6337,6 +6337,93 @@ function hasHighlightStyles(cssOrStyles) {
|
|
|
6337
6337
|
return !!(styles.color || styles["background-color"])
|
|
6338
6338
|
}
|
|
6339
6339
|
|
|
6340
|
+
function handleRollingTabIndex(elements, event) {
|
|
6341
|
+
const previousActiveElement = document.activeElement;
|
|
6342
|
+
|
|
6343
|
+
if (elements.includes(previousActiveElement)) {
|
|
6344
|
+
const finder = new NextElementFinder(elements, event.key);
|
|
6345
|
+
|
|
6346
|
+
if (finder.selectNext(previousActiveElement)) {
|
|
6347
|
+
event.preventDefault();
|
|
6348
|
+
}
|
|
6349
|
+
}
|
|
6350
|
+
}
|
|
6351
|
+
|
|
6352
|
+
class NextElementFinder {
|
|
6353
|
+
constructor(elements, key) {
|
|
6354
|
+
this.elements = elements;
|
|
6355
|
+
this.key = key;
|
|
6356
|
+
}
|
|
6357
|
+
|
|
6358
|
+
selectNext(fromElement) {
|
|
6359
|
+
const nextElement = this.#findNextElement(fromElement);
|
|
6360
|
+
|
|
6361
|
+
if (nextElement) {
|
|
6362
|
+
const inactiveElements = this.elements.filter(element => element !== nextElement);
|
|
6363
|
+
this.#unsetTabIndex(inactiveElements);
|
|
6364
|
+
this.#focusWithActiveTabIndex(nextElement);
|
|
6365
|
+
return true
|
|
6366
|
+
}
|
|
6367
|
+
|
|
6368
|
+
return false
|
|
6369
|
+
}
|
|
6370
|
+
|
|
6371
|
+
#findNextElement(fromElement) {
|
|
6372
|
+
switch (this.key) {
|
|
6373
|
+
case "ArrowRight":
|
|
6374
|
+
case "ArrowDown":
|
|
6375
|
+
return this.#findNextSibling(fromElement)
|
|
6376
|
+
|
|
6377
|
+
case "ArrowLeft":
|
|
6378
|
+
case "ArrowUp":
|
|
6379
|
+
return this.#findPreviousSibling(fromElement)
|
|
6380
|
+
|
|
6381
|
+
case "Home":
|
|
6382
|
+
return this.#findFirst()
|
|
6383
|
+
|
|
6384
|
+
case "End":
|
|
6385
|
+
return this.#findLast()
|
|
6386
|
+
}
|
|
6387
|
+
}
|
|
6388
|
+
|
|
6389
|
+
#findFirst(elements = this.elements) {
|
|
6390
|
+
return elements.find(isActiveAndVisible)
|
|
6391
|
+
}
|
|
6392
|
+
|
|
6393
|
+
#findLast(elements = this.elements) {
|
|
6394
|
+
return elements.findLast(isActiveAndVisible)
|
|
6395
|
+
}
|
|
6396
|
+
|
|
6397
|
+
#findNextSibling(element) {
|
|
6398
|
+
const afterElements = this.elements.slice(this.#indexOf(element) + 1);
|
|
6399
|
+
return this.#findFirst(afterElements)
|
|
6400
|
+
}
|
|
6401
|
+
|
|
6402
|
+
#findPreviousSibling(element) {
|
|
6403
|
+
const beforeElements = this.elements.slice(0, this.#indexOf(element));
|
|
6404
|
+
return this.#findLast(beforeElements)
|
|
6405
|
+
}
|
|
6406
|
+
|
|
6407
|
+
#indexOf(element) {
|
|
6408
|
+
return this.elements.indexOf(element)
|
|
6409
|
+
}
|
|
6410
|
+
|
|
6411
|
+
#focusWithActiveTabIndex(element) {
|
|
6412
|
+
if (isActiveAndVisible(element)) {
|
|
6413
|
+
element.tabIndex = 0;
|
|
6414
|
+
element.focus();
|
|
6415
|
+
}
|
|
6416
|
+
}
|
|
6417
|
+
|
|
6418
|
+
#unsetTabIndex(elements) {
|
|
6419
|
+
elements.forEach(element => element.tabIndex = -1);
|
|
6420
|
+
}
|
|
6421
|
+
}
|
|
6422
|
+
|
|
6423
|
+
function isActiveAndVisible(element) {
|
|
6424
|
+
return element && !element.disabled && element.checkVisibility()
|
|
6425
|
+
}
|
|
6426
|
+
|
|
6340
6427
|
class LexicalToolbarElement extends HTMLElement {
|
|
6341
6428
|
static observedAttributes = [ "connected" ]
|
|
6342
6429
|
|
|
@@ -6348,17 +6435,14 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6348
6435
|
|
|
6349
6436
|
connectedCallback() {
|
|
6350
6437
|
requestAnimationFrame(() => this.#refreshToolbarOverflow());
|
|
6351
|
-
|
|
6352
|
-
this
|
|
6353
|
-
this._resizeObserver.observe(this);
|
|
6438
|
+
this.setAttribute("role", "toolbar");
|
|
6439
|
+
this.#installResizeObserver();
|
|
6354
6440
|
}
|
|
6355
6441
|
|
|
6356
6442
|
disconnectedCallback() {
|
|
6357
|
-
|
|
6358
|
-
this._resizeObserver.disconnect();
|
|
6359
|
-
this._resizeObserver = null;
|
|
6360
|
-
}
|
|
6443
|
+
this.#uninstallResizeObserver();
|
|
6361
6444
|
this.#unbindHotkeys();
|
|
6445
|
+
this.#unbindFocusListeners();
|
|
6362
6446
|
}
|
|
6363
6447
|
|
|
6364
6448
|
attributeChangedCallback(name, oldValue, newValue) {
|
|
@@ -6372,11 +6456,12 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6372
6456
|
this.editor = editorElement.editor;
|
|
6373
6457
|
this.#bindButtons();
|
|
6374
6458
|
this.#bindHotkeys();
|
|
6375
|
-
this.#
|
|
6459
|
+
this.#resetTabIndexValues();
|
|
6376
6460
|
this.#setItemPositionValues();
|
|
6377
6461
|
this.#monitorSelectionChanges();
|
|
6378
6462
|
this.#monitorHistoryChanges();
|
|
6379
6463
|
this.#refreshToolbarOverflow();
|
|
6464
|
+
this.#bindFocusListeners();
|
|
6380
6465
|
|
|
6381
6466
|
this.toggleAttribute("connected", true);
|
|
6382
6467
|
}
|
|
@@ -6386,24 +6471,39 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6386
6471
|
this.connectedCallback();
|
|
6387
6472
|
}
|
|
6388
6473
|
|
|
6474
|
+
#installResizeObserver() {
|
|
6475
|
+
this.resizeObserver = new ResizeObserver(() => this.#refreshToolbarOverflow());
|
|
6476
|
+
this.resizeObserver.observe(this);
|
|
6477
|
+
}
|
|
6478
|
+
|
|
6479
|
+
#uninstallResizeObserver() {
|
|
6480
|
+
if (this.resizeObserver) {
|
|
6481
|
+
this.resizeObserver.disconnect();
|
|
6482
|
+
this.resizeObserver = null;
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
6485
|
+
|
|
6389
6486
|
#bindButtons() {
|
|
6390
6487
|
this.addEventListener("click", this.#handleButtonClicked.bind(this));
|
|
6391
6488
|
}
|
|
6392
6489
|
|
|
6393
|
-
#handleButtonClicked(
|
|
6394
|
-
this.#handleTargetClicked(
|
|
6490
|
+
#handleButtonClicked(event) {
|
|
6491
|
+
this.#handleTargetClicked(event, "[data-command]", this.#dispatchButtonCommand.bind(this));
|
|
6395
6492
|
}
|
|
6396
6493
|
|
|
6397
|
-
#handleTargetClicked(
|
|
6398
|
-
const button = target.closest(selector);
|
|
6494
|
+
#handleTargetClicked(event, selector, callback) {
|
|
6495
|
+
const button = event.target.closest(selector);
|
|
6399
6496
|
if (button) {
|
|
6400
|
-
callback(button);
|
|
6497
|
+
callback(event, button);
|
|
6401
6498
|
}
|
|
6402
6499
|
}
|
|
6403
6500
|
|
|
6404
|
-
#dispatchButtonCommand(
|
|
6405
|
-
const
|
|
6406
|
-
|
|
6501
|
+
#dispatchButtonCommand(event, { dataset: { command, payload } }) {
|
|
6502
|
+
const isKeyboard = event instanceof PointerEvent && event.pointerId === -1;
|
|
6503
|
+
|
|
6504
|
+
this.editor.update(() => {
|
|
6505
|
+
this.editor.dispatchCommand(command, payload);
|
|
6506
|
+
}, { tag: isKeyboard ? zn : undefined } );
|
|
6407
6507
|
}
|
|
6408
6508
|
|
|
6409
6509
|
#bindHotkeys() {
|
|
@@ -6438,9 +6538,38 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6438
6538
|
return [ ...modifiers, pressedKey ].join("+")
|
|
6439
6539
|
}
|
|
6440
6540
|
|
|
6441
|
-
#
|
|
6442
|
-
this
|
|
6443
|
-
|
|
6541
|
+
#bindFocusListeners() {
|
|
6542
|
+
this.editorElement.addEventListener("lexxy:focus", this.#handleFocus);
|
|
6543
|
+
this.editorElement.addEventListener("lexxy:blur", this.#handleFocusOut);
|
|
6544
|
+
this.addEventListener("focusout", this.#handleFocusOut);
|
|
6545
|
+
this.addEventListener("keydown", this.#handleKeydown);
|
|
6546
|
+
}
|
|
6547
|
+
|
|
6548
|
+
#unbindFocusListeners() {
|
|
6549
|
+
this.editorElement.removeEventListener("lexxy:focus", this.#handleFocus);
|
|
6550
|
+
this.editorElement.removeEventListener("lexxy:blur", this.#handleFocusOut);
|
|
6551
|
+
this.removeEventListener("focusout", this.#handleFocusOut);
|
|
6552
|
+
this.removeEventListener("keydown", this.#handleKeydown);
|
|
6553
|
+
}
|
|
6554
|
+
|
|
6555
|
+
#handleFocus = () => {
|
|
6556
|
+
this.#resetTabIndexValues();
|
|
6557
|
+
this.#focusableItems[0].tabIndex = 0;
|
|
6558
|
+
}
|
|
6559
|
+
|
|
6560
|
+
#handleFocusOut = () => {
|
|
6561
|
+
if (!this.contains(document.activeElement)) {
|
|
6562
|
+
this.#resetTabIndexValues();
|
|
6563
|
+
}
|
|
6564
|
+
}
|
|
6565
|
+
|
|
6566
|
+
#handleKeydown = (event) => {
|
|
6567
|
+
handleRollingTabIndex(this.#focusableItems, event);
|
|
6568
|
+
}
|
|
6569
|
+
|
|
6570
|
+
#resetTabIndexValues() {
|
|
6571
|
+
this.#focusableItems.forEach((button) => {
|
|
6572
|
+
button.tabIndex = -1;
|
|
6444
6573
|
});
|
|
6445
6574
|
}
|
|
6446
6575
|
|
|
@@ -6550,6 +6679,7 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6550
6679
|
|
|
6551
6680
|
const isOverflowing = this.#overflowMenu.children.length > 0;
|
|
6552
6681
|
this.toggleAttribute("overflowing", isOverflowing);
|
|
6682
|
+
this.#overflowMenu.toggleAttribute("disabled", !isOverflowing);
|
|
6553
6683
|
}
|
|
6554
6684
|
|
|
6555
6685
|
#compactMenu() {
|
|
@@ -6601,6 +6731,10 @@ class LexicalToolbarElement extends HTMLElement {
|
|
|
6601
6731
|
return Array.from(this.querySelectorAll(":scope > button"))
|
|
6602
6732
|
}
|
|
6603
6733
|
|
|
6734
|
+
get #focusableItems() {
|
|
6735
|
+
return Array.from(this.querySelectorAll(":scope button, :scope > details > summary"))
|
|
6736
|
+
}
|
|
6737
|
+
|
|
6604
6738
|
get #toolbarItems() {
|
|
6605
6739
|
return Array.from(this.querySelectorAll(":scope > *:not(.lexxy-editor__toolbar-overflow)"))
|
|
6606
6740
|
}
|
|
@@ -7598,7 +7732,7 @@ class CommandDispatcher {
|
|
|
7598
7732
|
}
|
|
7599
7733
|
|
|
7600
7734
|
#registerKeyboardCommands() {
|
|
7601
|
-
this.editor.registerCommand(Me$2, this.#
|
|
7735
|
+
this.editor.registerCommand(Me$2, this.#handleTabKey.bind(this), Ri);
|
|
7602
7736
|
}
|
|
7603
7737
|
|
|
7604
7738
|
#registerDragAndDropHandlers() {
|
|
@@ -7648,18 +7782,28 @@ class CommandDispatcher {
|
|
|
7648
7782
|
this.editor.focus();
|
|
7649
7783
|
}
|
|
7650
7784
|
|
|
7651
|
-
#
|
|
7785
|
+
#handleTabKey(event) {
|
|
7652
7786
|
if (this.selection.isInsideList) {
|
|
7653
|
-
event
|
|
7654
|
-
|
|
7655
|
-
|
|
7656
|
-
} else {
|
|
7657
|
-
return this.editor.dispatchCommand(Pe$2, undefined)
|
|
7658
|
-
}
|
|
7787
|
+
return this.#handleTabForList(event)
|
|
7788
|
+
} else if (this.selection.isInsideCodeBlock) {
|
|
7789
|
+
return this.#handleTabForCode()
|
|
7659
7790
|
}
|
|
7660
7791
|
return false
|
|
7661
7792
|
}
|
|
7662
7793
|
|
|
7794
|
+
#handleTabForList(event) {
|
|
7795
|
+
if (event.shiftKey && !this.selection.isIndentedList) return false
|
|
7796
|
+
|
|
7797
|
+
event.preventDefault();
|
|
7798
|
+
const command = event.shiftKey? De$2 : Pe$2;
|
|
7799
|
+
return this.editor.dispatchCommand(command)
|
|
7800
|
+
}
|
|
7801
|
+
|
|
7802
|
+
#handleTabForCode() {
|
|
7803
|
+
const selection = Lr();
|
|
7804
|
+
return yr(selection) && selection.isCollapsed()
|
|
7805
|
+
}
|
|
7806
|
+
|
|
7663
7807
|
// Not using TOGGLE_LINK_COMMAND because it's not handled unless you use React/LinkPlugin
|
|
7664
7808
|
#toggleLink(url) {
|
|
7665
7809
|
this.editor.update(() => {
|
|
@@ -7836,6 +7980,29 @@ class Selection {
|
|
|
7836
7980
|
return getNearestListItemNode(anchorNode) !== null
|
|
7837
7981
|
}
|
|
7838
7982
|
|
|
7983
|
+
get isIndentedList() {
|
|
7984
|
+
const selection = Lr();
|
|
7985
|
+
if (!yr(selection)) return false
|
|
7986
|
+
|
|
7987
|
+
const nodes = selection.getNodes();
|
|
7988
|
+
for (const node of nodes) {
|
|
7989
|
+
const closestListNode = wt$5(node, lt$3);
|
|
7990
|
+
if (closestListNode && W$4(closestListNode) > 1) {
|
|
7991
|
+
return true
|
|
7992
|
+
}
|
|
7993
|
+
}
|
|
7994
|
+
|
|
7995
|
+
return false
|
|
7996
|
+
}
|
|
7997
|
+
|
|
7998
|
+
get isInsideCodeBlock() {
|
|
7999
|
+
const selection = Lr();
|
|
8000
|
+
if (!yr(selection)) return false
|
|
8001
|
+
|
|
8002
|
+
const anchorNode = selection.anchor.getNode();
|
|
8003
|
+
return wt$5(anchorNode, q$1) !== null
|
|
8004
|
+
}
|
|
8005
|
+
|
|
7839
8006
|
get nodeAfterCursor() {
|
|
7840
8007
|
const { anchorNode, offset } = this.#getCollapsedSelectionData();
|
|
7841
8008
|
if (!anchorNode) return null
|
|
@@ -10255,8 +10422,6 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
10255
10422
|
|
|
10256
10423
|
this.container.addEventListener("toggle", this.#handleToggle.bind(this));
|
|
10257
10424
|
this.container.addEventListener("keydown", this.#handleKeyDown.bind(this));
|
|
10258
|
-
|
|
10259
|
-
this.#setTabIndexValues();
|
|
10260
10425
|
}
|
|
10261
10426
|
|
|
10262
10427
|
disconnectedCallback() {
|
|
@@ -10284,14 +10449,14 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
10284
10449
|
}
|
|
10285
10450
|
}
|
|
10286
10451
|
|
|
10287
|
-
#handleOpen(
|
|
10288
|
-
this.trigger = trigger;
|
|
10452
|
+
#handleOpen() {
|
|
10289
10453
|
this.#interactiveElements[0].focus();
|
|
10290
10454
|
this.#setupClickOutsideHandler();
|
|
10455
|
+
|
|
10456
|
+
this.#resetTabIndexValues();
|
|
10291
10457
|
}
|
|
10292
10458
|
|
|
10293
10459
|
#handleClose() {
|
|
10294
|
-
this.trigger = null;
|
|
10295
10460
|
this.#removeClickOutsideHandler();
|
|
10296
10461
|
this.editor.focus();
|
|
10297
10462
|
}
|
|
@@ -10321,16 +10486,20 @@ class ToolbarDropdown extends HTMLElement {
|
|
|
10321
10486
|
}
|
|
10322
10487
|
}
|
|
10323
10488
|
|
|
10324
|
-
async #
|
|
10489
|
+
async #resetTabIndexValues() {
|
|
10325
10490
|
await nextFrame();
|
|
10326
|
-
this.#
|
|
10327
|
-
element.setAttribute("tabindex", 0);
|
|
10491
|
+
this.#buttons.forEach((element, index) => {
|
|
10492
|
+
element.setAttribute("tabindex", index === 0 ? 0 : "-1");
|
|
10328
10493
|
});
|
|
10329
10494
|
}
|
|
10330
10495
|
|
|
10331
10496
|
get #interactiveElements() {
|
|
10332
10497
|
return Array.from(this.querySelectorAll("button, input"))
|
|
10333
10498
|
}
|
|
10499
|
+
|
|
10500
|
+
get #buttons() {
|
|
10501
|
+
return Array.from(this.querySelectorAll("button"))
|
|
10502
|
+
}
|
|
10334
10503
|
}
|
|
10335
10504
|
|
|
10336
10505
|
class LinkDropdown extends ToolbarDropdown {
|
|
@@ -10526,15 +10695,19 @@ class TableHandler extends HTMLElement {
|
|
|
10526
10695
|
return Ue$1(currentCell)
|
|
10527
10696
|
}
|
|
10528
10697
|
|
|
10698
|
+
get #tableHandlerButtons() {
|
|
10699
|
+
return Array.from(this.buttonsContainer.querySelectorAll("button, details > summary"))
|
|
10700
|
+
}
|
|
10701
|
+
|
|
10529
10702
|
#registerKeyboardShortcuts() {
|
|
10530
|
-
this.unregisterKeyboardShortcuts = this.#editor.registerCommand(me$1, this.#handleKeyDown
|
|
10703
|
+
this.unregisterKeyboardShortcuts = this.#editor.registerCommand(me$1, this.#handleKeyDown, Bi);
|
|
10531
10704
|
}
|
|
10532
10705
|
|
|
10533
10706
|
#unregisterKeyboardShortcuts() {
|
|
10534
10707
|
this.unregisterKeyboardShortcuts();
|
|
10535
10708
|
}
|
|
10536
10709
|
|
|
10537
|
-
#handleKeyDown(event) {
|
|
10710
|
+
#handleKeyDown = (event) => {
|
|
10538
10711
|
if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === "F10") {
|
|
10539
10712
|
const firstButton = this.buttonsContainer?.querySelector("button, [tabindex]:not([tabindex='-1'])");
|
|
10540
10713
|
this.#setFocusStateOnSelectedCell();
|
|
@@ -10552,6 +10725,14 @@ class TableHandler extends HTMLElement {
|
|
|
10552
10725
|
}
|
|
10553
10726
|
}
|
|
10554
10727
|
|
|
10728
|
+
#handleTableHandlerKeydown = (event) => {
|
|
10729
|
+
if (event.key === "Escape") {
|
|
10730
|
+
this.#editor.focus();
|
|
10731
|
+
} else {
|
|
10732
|
+
handleRollingTabIndex(this.#tableHandlerButtons, event);
|
|
10733
|
+
}
|
|
10734
|
+
}
|
|
10735
|
+
|
|
10555
10736
|
#setUpButtons() {
|
|
10556
10737
|
this.buttonsContainer = createElement("div", {
|
|
10557
10738
|
className: "lexxy-table-handle-buttons"
|
|
@@ -10562,6 +10743,7 @@ class TableHandler extends HTMLElement {
|
|
|
10562
10743
|
|
|
10563
10744
|
this.moreMenu = this.#createMoreMenu();
|
|
10564
10745
|
this.buttonsContainer.appendChild(this.moreMenu);
|
|
10746
|
+
this.buttonsContainer.addEventListener("keydown", this.#handleTableHandlerKeydown);
|
|
10565
10747
|
|
|
10566
10748
|
this.#editorElement.appendChild(this.buttonsContainer);
|
|
10567
10749
|
}
|
|
@@ -11674,3 +11856,4 @@ function highlightElement(preElement) {
|
|
|
11674
11856
|
}
|
|
11675
11857
|
|
|
11676
11858
|
export { highlightAll };
|
|
11859
|
+
//# sourceMappingURL=lexxy.js.map
|
|
Binary file
|
|
Binary file
|