@37signals/lexxy 0.9.6-beta.bc0 → 0.9.7-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.
- package/README.md +2 -2
- package/dist/lexxy.esm.js +26 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
A modern rich text editor for Rails.
|
|
4
4
|
|
|
5
5
|
> [!IMPORTANT]
|
|
6
|
-
> This is
|
|
6
|
+
> This is a beta. It hasn't been battle-tested yet. Please try it out and report any issues you find.
|
|
7
7
|
|
|
8
8
|
**[Try it out!](https://basecamp.github.io/lexxy/try-it)**
|
|
9
9
|
|
|
@@ -26,7 +26,7 @@ Visit the **[documentation site](https://basecamp.github.io/lexxy)**.
|
|
|
26
26
|
|
|
27
27
|
## Roadmap
|
|
28
28
|
|
|
29
|
-
This is
|
|
29
|
+
This is a beta. Here's what's coming next:
|
|
30
30
|
|
|
31
31
|
- [x] Configurable editors in Action Text: Choose your editor like you choose your database.
|
|
32
32
|
- [x] More editing features:
|
package/dist/lexxy.esm.js
CHANGED
|
@@ -2186,7 +2186,7 @@ class CommandDispatcher {
|
|
|
2186
2186
|
|
|
2187
2187
|
dispatchInsertUnorderedList() {
|
|
2188
2188
|
const selection = $getSelection();
|
|
2189
|
-
if (
|
|
2189
|
+
if (!$isRangeSelection(selection)) return
|
|
2190
2190
|
|
|
2191
2191
|
const anchorNode = selection.anchor.getNode();
|
|
2192
2192
|
|
|
@@ -2199,7 +2199,7 @@ class CommandDispatcher {
|
|
|
2199
2199
|
|
|
2200
2200
|
dispatchInsertOrderedList() {
|
|
2201
2201
|
const selection = $getSelection();
|
|
2202
|
-
if (
|
|
2202
|
+
if (!$isRangeSelection(selection)) return
|
|
2203
2203
|
|
|
2204
2204
|
const anchorNode = selection.anchor.getNode();
|
|
2205
2205
|
|
|
@@ -2491,6 +2491,15 @@ function capitalize(str) {
|
|
|
2491
2491
|
return str.charAt(0).toUpperCase() + str.slice(1)
|
|
2492
2492
|
}
|
|
2493
2493
|
|
|
2494
|
+
function debounce(fn, wait) {
|
|
2495
|
+
let timeout;
|
|
2496
|
+
|
|
2497
|
+
return (...args) => {
|
|
2498
|
+
clearTimeout(timeout);
|
|
2499
|
+
timeout = setTimeout(() => fn(...args), wait);
|
|
2500
|
+
}
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2494
2503
|
function debounceAsync(fn, wait) {
|
|
2495
2504
|
let timeout;
|
|
2496
2505
|
|
|
@@ -5914,9 +5923,9 @@ class AttachmentDragAndDrop {
|
|
|
5914
5923
|
// -- Event handlers --------------------------------------------------------
|
|
5915
5924
|
|
|
5916
5925
|
#handleDragStart(event) {
|
|
5917
|
-
if (event.target.closest("textarea")) return false
|
|
5926
|
+
if (event.target.closest?.("textarea")) return false
|
|
5918
5927
|
|
|
5919
|
-
const figure = event.target.closest("figure.attachment[data-lexical-node-key]");
|
|
5928
|
+
const figure = event.target.closest?.("figure.attachment[data-lexical-node-key]");
|
|
5920
5929
|
if (!figure) return false
|
|
5921
5930
|
|
|
5922
5931
|
this.#draggedNodeKey = figure.dataset.lexicalNodeKey;
|
|
@@ -7507,6 +7516,8 @@ class BaseSource {
|
|
|
7507
7516
|
}
|
|
7508
7517
|
}
|
|
7509
7518
|
|
|
7519
|
+
const MAX_RENDERED_SUGGESTIONS$1 = 100;
|
|
7520
|
+
|
|
7510
7521
|
class LocalFilterSource extends BaseSource {
|
|
7511
7522
|
async buildListItems(filter = "") {
|
|
7512
7523
|
const promptItems = await this.fetchPromptItems();
|
|
@@ -7525,7 +7536,10 @@ class LocalFilterSource extends BaseSource {
|
|
|
7525
7536
|
#buildListItemsFromPromptItems(promptItems, filter) {
|
|
7526
7537
|
const listItems = [];
|
|
7527
7538
|
this.promptItemByListItem = new WeakMap();
|
|
7528
|
-
|
|
7539
|
+
|
|
7540
|
+
for (const promptItem of promptItems) {
|
|
7541
|
+
if (listItems.length >= MAX_RENDERED_SUGGESTIONS$1) break
|
|
7542
|
+
|
|
7529
7543
|
const searchableText = promptItem.getAttribute("search");
|
|
7530
7544
|
|
|
7531
7545
|
if (!filter || filterMatches(searchableText, filter)) {
|
|
@@ -7533,7 +7547,7 @@ class LocalFilterSource extends BaseSource {
|
|
|
7533
7547
|
this.promptItemByListItem.set(listItem, promptItem);
|
|
7534
7548
|
listItems.push(listItem);
|
|
7535
7549
|
}
|
|
7536
|
-
}
|
|
7550
|
+
}
|
|
7537
7551
|
|
|
7538
7552
|
return listItems
|
|
7539
7553
|
}
|
|
@@ -7566,6 +7580,7 @@ class DeferredPromptSource extends LocalFilterSource {
|
|
|
7566
7580
|
}
|
|
7567
7581
|
|
|
7568
7582
|
const DEBOUNCE_INTERVAL = 200;
|
|
7583
|
+
const MAX_RENDERED_SUGGESTIONS = 100;
|
|
7569
7584
|
|
|
7570
7585
|
class RemoteFilterSource extends BaseSource {
|
|
7571
7586
|
constructor(url) {
|
|
@@ -7599,6 +7614,8 @@ class RemoteFilterSource extends BaseSource {
|
|
|
7599
7614
|
this.promptItemByListItem = new WeakMap();
|
|
7600
7615
|
|
|
7601
7616
|
for (const promptItem of promptItems) {
|
|
7617
|
+
if (listItems.length >= MAX_RENDERED_SUGGESTIONS) break
|
|
7618
|
+
|
|
7602
7619
|
const listItem = this.buildListItemElementFor(promptItem);
|
|
7603
7620
|
this.promptItemByListItem.set(listItem, promptItem);
|
|
7604
7621
|
listItems.push(listItem);
|
|
@@ -7609,10 +7626,12 @@ class RemoteFilterSource extends BaseSource {
|
|
|
7609
7626
|
}
|
|
7610
7627
|
|
|
7611
7628
|
const NOTHING_FOUND_DEFAULT_MESSAGE = "Nothing found";
|
|
7629
|
+
const FILTER_DEBOUNCE_INTERVAL = 50;
|
|
7612
7630
|
|
|
7613
7631
|
class LexicalPromptElement extends HTMLElement {
|
|
7614
7632
|
#globalListeners = new ListenerBin()
|
|
7615
7633
|
#popoverListeners = new ListenerBin()
|
|
7634
|
+
#debouncedFilterOptions = debounce(() => this.#filterOptions(), FILTER_DEBOUNCE_INTERVAL)
|
|
7616
7635
|
|
|
7617
7636
|
constructor() {
|
|
7618
7637
|
super();
|
|
@@ -7770,7 +7789,7 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
7770
7789
|
|
|
7771
7790
|
this.#popoverListeners.track(
|
|
7772
7791
|
registerEventListener(this.#editorElement, "keydown", this.#handleKeydownOnPopover),
|
|
7773
|
-
registerEventListener(this.#editorElement, "lexxy:change", this.#
|
|
7792
|
+
registerEventListener(this.#editorElement, "lexxy:change", this.#debouncedFilterOptions)
|
|
7774
7793
|
);
|
|
7775
7794
|
|
|
7776
7795
|
this.#registerKeyListeners();
|