lexxy 0.9.2.beta → 0.9.3.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 +387 -35
- 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 +2 -2
- data/app/assets/javascript/lexxy.min.js.br +0 -0
- data/app/assets/javascript/lexxy.min.js.gz +0 -0
- 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: 3ca2c3eeb9fff2ac0a2a3db6b68fc9bda7868fde5a36158ea77ac61d0eaea40d
|
|
4
|
+
data.tar.gz: c0390bfc97b15a212dd6cc07b273c21da5d641c37232fc039c2fde9c5c772d43
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab64196f9538299e4c731b4d0be010455f14b705b3fe2f3936091f9c33387957b8d74ac2f7a3aa03a7044224ebb32574a26dae33c563a878a77f00b8c6e79c58
|
|
7
|
+
data.tar.gz: 790f9af92cb872bdc45b68e55976e54f23b75a83f1cb95ac93218294cd5f44415fde9d8d53e02f752577d74c648e73dd86d3799bf40fbab2524b77fa32d00e7d
|
|
@@ -7688,6 +7688,24 @@ function isSelectionHighlighted(selection) {
|
|
|
7688
7688
|
}
|
|
7689
7689
|
}
|
|
7690
7690
|
|
|
7691
|
+
function getHighlightStyles(selection) {
|
|
7692
|
+
if (!wr(selection)) return null
|
|
7693
|
+
|
|
7694
|
+
let styles = b$3(selection.style);
|
|
7695
|
+
if (!styles.color && !styles["background-color"]) {
|
|
7696
|
+
const anchorNode = selection.anchor.getNode();
|
|
7697
|
+
if (yr(anchorNode)) {
|
|
7698
|
+
styles = b$3(anchorNode.getStyle());
|
|
7699
|
+
}
|
|
7700
|
+
}
|
|
7701
|
+
|
|
7702
|
+
const color = styles.color || null;
|
|
7703
|
+
const backgroundColor = styles["background-color"] || null;
|
|
7704
|
+
if (!color && !backgroundColor) return null
|
|
7705
|
+
|
|
7706
|
+
return { color, backgroundColor }
|
|
7707
|
+
}
|
|
7708
|
+
|
|
7691
7709
|
function hasHighlightStyles(cssOrStyles) {
|
|
7692
7710
|
const styles = typeof cssOrStyles === "string" ? b$3(cssOrStyles) : cssOrStyles;
|
|
7693
7711
|
return !!(styles.color || styles["background-color"])
|
|
@@ -8250,6 +8268,7 @@ const COMMANDS = [
|
|
|
8250
8268
|
"insertOrderedList",
|
|
8251
8269
|
"insertQuoteBlock",
|
|
8252
8270
|
"insertCodeBlock",
|
|
8271
|
+
"setCodeLanguage",
|
|
8253
8272
|
"insertHorizontalDivider",
|
|
8254
8273
|
"uploadImage",
|
|
8255
8274
|
"uploadFile",
|
|
@@ -8325,7 +8344,14 @@ class CommandDispatcher {
|
|
|
8325
8344
|
}
|
|
8326
8345
|
|
|
8327
8346
|
dispatchUnlink() {
|
|
8328
|
-
this
|
|
8347
|
+
this.editor.update(() => {
|
|
8348
|
+
// Let adapters signal whether unlink should target a frozen link key.
|
|
8349
|
+
if (this.editorElement.adapter.unlinkFrozenNode?.()) {
|
|
8350
|
+
return
|
|
8351
|
+
}
|
|
8352
|
+
|
|
8353
|
+
Z$1(null);
|
|
8354
|
+
});
|
|
8329
8355
|
}
|
|
8330
8356
|
|
|
8331
8357
|
dispatchInsertUnorderedList() {
|
|
@@ -8416,6 +8442,17 @@ class CommandDispatcher {
|
|
|
8416
8442
|
}
|
|
8417
8443
|
}
|
|
8418
8444
|
|
|
8445
|
+
dispatchSetCodeLanguage(language) {
|
|
8446
|
+
this.editor.update(() => {
|
|
8447
|
+
if (!this.selection.isInsideCodeBlock) return
|
|
8448
|
+
|
|
8449
|
+
const codeNode = this.selection.nearestNodeOfType(U$1);
|
|
8450
|
+
if (!codeNode) return
|
|
8451
|
+
|
|
8452
|
+
codeNode.setLanguage(language);
|
|
8453
|
+
});
|
|
8454
|
+
}
|
|
8455
|
+
|
|
8419
8456
|
dispatchInsertHorizontalDivider() {
|
|
8420
8457
|
this.contents.insertAtCursorEnsuringLineBelow(new HorizontalDividerNode());
|
|
8421
8458
|
this.editor.focus();
|
|
@@ -8614,16 +8651,6 @@ class CommandDispatcher {
|
|
|
8614
8651
|
return wr(selection) && selection.isCollapsed()
|
|
8615
8652
|
}
|
|
8616
8653
|
|
|
8617
|
-
// Not using TOGGLE_LINK_COMMAND because it's not handled unless you use React/LinkPlugin
|
|
8618
|
-
#toggleLink(url) {
|
|
8619
|
-
this.editor.update(() => {
|
|
8620
|
-
if (url === null) {
|
|
8621
|
-
Z$1(null);
|
|
8622
|
-
} else {
|
|
8623
|
-
Z$1(url);
|
|
8624
|
-
}
|
|
8625
|
-
});
|
|
8626
|
-
}
|
|
8627
8654
|
}
|
|
8628
8655
|
|
|
8629
8656
|
function capitalize(str) {
|
|
@@ -8850,8 +8877,8 @@ class ActionTextAttachmentNode extends Fi {
|
|
|
8850
8877
|
return null
|
|
8851
8878
|
}
|
|
8852
8879
|
|
|
8853
|
-
createAttachmentFigure() {
|
|
8854
|
-
const figure = createAttachmentFigure(this.contentType,
|
|
8880
|
+
createAttachmentFigure(previewable = this.isPreviewableAttachment) {
|
|
8881
|
+
const figure = createAttachmentFigure(this.contentType, previewable, this.fileName);
|
|
8855
8882
|
figure.draggable = true;
|
|
8856
8883
|
figure.dataset.lexicalNodeKey = this.__key;
|
|
8857
8884
|
|
|
@@ -9936,9 +9963,12 @@ class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
|
|
|
9936
9963
|
// node is reloaded from saved state such as from history.
|
|
9937
9964
|
this.#startUploadIfNeeded();
|
|
9938
9965
|
|
|
9939
|
-
|
|
9966
|
+
// Bridge-managed uploads (uploadUrl is null) don't have file data to show
|
|
9967
|
+
// an image preview, so always show the file icon during upload.
|
|
9968
|
+
const canPreviewFile = this.isPreviewableAttachment && this.uploadUrl != null;
|
|
9969
|
+
const figure = this.createAttachmentFigure(canPreviewFile);
|
|
9940
9970
|
|
|
9941
|
-
if (
|
|
9971
|
+
if (canPreviewFile) {
|
|
9942
9972
|
const img = figure.appendChild(this.#createDOMForImage());
|
|
9943
9973
|
|
|
9944
9974
|
// load file locally to set dimensions and prevent vertical shifting
|
|
@@ -10038,6 +10068,7 @@ class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
|
|
|
10038
10068
|
|
|
10039
10069
|
async #startUploadIfNeeded() {
|
|
10040
10070
|
if (this.#uploadStarted) return
|
|
10071
|
+
if (!this.uploadUrl) return // Bridge-managed upload — skip DirectUpload
|
|
10041
10072
|
|
|
10042
10073
|
this.#setUploadStarted();
|
|
10043
10074
|
|
|
@@ -10054,7 +10085,9 @@ class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
|
|
|
10054
10085
|
this.#handleUploadError(error);
|
|
10055
10086
|
} else {
|
|
10056
10087
|
this.#dispatchEvent("lexxy:upload-end", { file: this.file, error: null });
|
|
10057
|
-
this
|
|
10088
|
+
this.editor.update(() => {
|
|
10089
|
+
this.showUploadedAttachment(blob);
|
|
10090
|
+
}, { tag: this.#backgroundUpdateTags });
|
|
10058
10091
|
}
|
|
10059
10092
|
});
|
|
10060
10093
|
}
|
|
@@ -10098,17 +10131,15 @@ class ActionTextAttachmentUploadNode extends ActionTextAttachmentNode {
|
|
|
10098
10131
|
}, { tag: this.#backgroundUpdateTags });
|
|
10099
10132
|
}
|
|
10100
10133
|
|
|
10101
|
-
|
|
10102
|
-
const
|
|
10134
|
+
showUploadedAttachment(blob) {
|
|
10135
|
+
const replacementNode = this.#toActionTextAttachmentNodeWith(blob);
|
|
10136
|
+
this.replace(replacementNode);
|
|
10103
10137
|
|
|
10104
|
-
|
|
10105
|
-
|
|
10106
|
-
|
|
10138
|
+
if (xs(replacementNode.getParent())) {
|
|
10139
|
+
replacementNode.selectNext();
|
|
10140
|
+
}
|
|
10107
10141
|
|
|
10108
|
-
|
|
10109
|
-
replacementNode.selectNext();
|
|
10110
|
-
}
|
|
10111
|
-
}, { tag: this.#backgroundUpdateTags });
|
|
10142
|
+
return replacementNode.getKey()
|
|
10112
10143
|
}
|
|
10113
10144
|
|
|
10114
10145
|
// Upload lifecycle methods (progress, completion, errors) run asynchronously and may
|
|
@@ -10710,6 +10741,53 @@ class Contents {
|
|
|
10710
10741
|
});
|
|
10711
10742
|
}
|
|
10712
10743
|
|
|
10744
|
+
insertPendingAttachment(file) {
|
|
10745
|
+
if (!this.editorElement.supportsAttachments) return null
|
|
10746
|
+
|
|
10747
|
+
let nodeKey = null;
|
|
10748
|
+
this.editor.update(() => {
|
|
10749
|
+
const uploadNode = new ActionTextAttachmentUploadNode({
|
|
10750
|
+
file,
|
|
10751
|
+
uploadUrl: null,
|
|
10752
|
+
blobUrlTemplate: this.editorElement.blobUrlTemplate,
|
|
10753
|
+
editor: this.editor
|
|
10754
|
+
});
|
|
10755
|
+
this.insertAtCursor(uploadNode);
|
|
10756
|
+
nodeKey = uploadNode.getKey();
|
|
10757
|
+
}, { tag: Wn });
|
|
10758
|
+
|
|
10759
|
+
if (!nodeKey) return null
|
|
10760
|
+
|
|
10761
|
+
const editor = this.editor;
|
|
10762
|
+
return {
|
|
10763
|
+
setAttributes(blob) {
|
|
10764
|
+
editor.update(() => {
|
|
10765
|
+
const node = Mo(nodeKey);
|
|
10766
|
+
if (!(node instanceof ActionTextAttachmentUploadNode)) return
|
|
10767
|
+
|
|
10768
|
+
const replacementNodeKey = node.showUploadedAttachment(blob);
|
|
10769
|
+
if (replacementNodeKey) {
|
|
10770
|
+
nodeKey = replacementNodeKey;
|
|
10771
|
+
}
|
|
10772
|
+
}, { tag: Wn });
|
|
10773
|
+
},
|
|
10774
|
+
setUploadProgress(progress) {
|
|
10775
|
+
editor.update(() => {
|
|
10776
|
+
const node = Mo(nodeKey);
|
|
10777
|
+
if (!(node instanceof ActionTextAttachmentUploadNode)) return
|
|
10778
|
+
|
|
10779
|
+
node.getWritable().progress = progress;
|
|
10780
|
+
}, { tag: Wn });
|
|
10781
|
+
},
|
|
10782
|
+
remove() {
|
|
10783
|
+
editor.update(() => {
|
|
10784
|
+
const node = Mo(nodeKey);
|
|
10785
|
+
if (node) node.remove();
|
|
10786
|
+
});
|
|
10787
|
+
}
|
|
10788
|
+
}
|
|
10789
|
+
}
|
|
10790
|
+
|
|
10713
10791
|
replaceNodeWithHTML(nodeKey, html, options = {}) {
|
|
10714
10792
|
this.editor.update(() => {
|
|
10715
10793
|
const node = Mo(nodeKey);
|
|
@@ -11266,6 +11344,18 @@ class Extensions {
|
|
|
11266
11344
|
}
|
|
11267
11345
|
}
|
|
11268
11346
|
|
|
11347
|
+
class BrowserAdapter {
|
|
11348
|
+
frozenLinkKey = null
|
|
11349
|
+
|
|
11350
|
+
dispatchAttributesChange(attributes, linkHref, highlight, headingTag) {}
|
|
11351
|
+
dispatchEditorInitialized(detail) {}
|
|
11352
|
+
freeze() {}
|
|
11353
|
+
thaw() {}
|
|
11354
|
+
unlinkFrozenNode() {
|
|
11355
|
+
return false
|
|
11356
|
+
}
|
|
11357
|
+
}
|
|
11358
|
+
|
|
11269
11359
|
// Custom TextNode exportDOM that avoids redundant bold/italic wrapping.
|
|
11270
11360
|
//
|
|
11271
11361
|
// Lexical's built-in TextNode.exportDOM() calls createDOM() which produces semantic tags
|
|
@@ -12317,6 +12407,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12317
12407
|
|
|
12318
12408
|
#initialValue = ""
|
|
12319
12409
|
#validationTextArea = document.createElement("textarea")
|
|
12410
|
+
#editorInitializedRafId = null
|
|
12320
12411
|
#disposables = []
|
|
12321
12412
|
|
|
12322
12413
|
constructor() {
|
|
@@ -12326,7 +12417,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12326
12417
|
}
|
|
12327
12418
|
|
|
12328
12419
|
connectedCallback() {
|
|
12329
|
-
this.id
|
|
12420
|
+
this.id ||= generateDomId("lexxy-editor");
|
|
12330
12421
|
this.config = new EditorConfiguration(this);
|
|
12331
12422
|
this.extensions = new Extensions(this);
|
|
12332
12423
|
|
|
@@ -12340,13 +12431,14 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12340
12431
|
this.#disposables.push(this.selection);
|
|
12341
12432
|
|
|
12342
12433
|
this.clipboard = new Clipboard(this);
|
|
12434
|
+
this.adapter = new BrowserAdapter();
|
|
12343
12435
|
|
|
12344
12436
|
const commandDispatcher = CommandDispatcher.configureFor(this);
|
|
12345
12437
|
this.#disposables.push(commandDispatcher);
|
|
12346
12438
|
|
|
12347
12439
|
this.#initialize();
|
|
12348
12440
|
|
|
12349
|
-
|
|
12441
|
+
this.#scheduleEditorInitializedDispatch();
|
|
12350
12442
|
this.toggleAttribute("connected", true);
|
|
12351
12443
|
|
|
12352
12444
|
this.#handleAutofocus();
|
|
@@ -12355,6 +12447,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12355
12447
|
}
|
|
12356
12448
|
|
|
12357
12449
|
disconnectedCallback() {
|
|
12450
|
+
this.#cancelEditorInitializedDispatch();
|
|
12358
12451
|
this.valueBeforeDisconnect = this.value;
|
|
12359
12452
|
this.#reset(); // Prevent hangs with Safari when morphing
|
|
12360
12453
|
}
|
|
@@ -12451,6 +12544,32 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12451
12544
|
return this.config.get("richText")
|
|
12452
12545
|
}
|
|
12453
12546
|
|
|
12547
|
+
registerAdapter(adapter) {
|
|
12548
|
+
this.adapter = adapter;
|
|
12549
|
+
|
|
12550
|
+
if (!this.editor) return
|
|
12551
|
+
|
|
12552
|
+
this.#cancelEditorInitializedDispatch();
|
|
12553
|
+
this.#dispatchEditorInitialized();
|
|
12554
|
+
this.#dispatchAttributesChange();
|
|
12555
|
+
}
|
|
12556
|
+
|
|
12557
|
+
freezeSelection() {
|
|
12558
|
+
this.adapter.freeze();
|
|
12559
|
+
}
|
|
12560
|
+
|
|
12561
|
+
thawSelection() {
|
|
12562
|
+
this.adapter.thaw();
|
|
12563
|
+
}
|
|
12564
|
+
|
|
12565
|
+
dispatchAttributesChange() {
|
|
12566
|
+
this.#dispatchAttributesChange();
|
|
12567
|
+
}
|
|
12568
|
+
|
|
12569
|
+
dispatchEditorInitialized() {
|
|
12570
|
+
this.#dispatchEditorInitialized();
|
|
12571
|
+
}
|
|
12572
|
+
|
|
12454
12573
|
// TODO: Deprecate `single-line` attribute
|
|
12455
12574
|
get isSingleLineMode() {
|
|
12456
12575
|
return this.hasAttribute("single-line")
|
|
@@ -12575,6 +12694,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12575
12694
|
const editorContentElement = createElement("div", {
|
|
12576
12695
|
classList: "lexxy-editor__content",
|
|
12577
12696
|
contenteditable: true,
|
|
12697
|
+
autocapitalize: "none",
|
|
12578
12698
|
role: "textbox",
|
|
12579
12699
|
"aria-multiline": true,
|
|
12580
12700
|
"aria-label": this.#labelText,
|
|
@@ -12636,6 +12756,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12636
12756
|
this.#internalFormValue = this.value;
|
|
12637
12757
|
this.#toggleEmptyStatus();
|
|
12638
12758
|
this.#setValidity();
|
|
12759
|
+
this.#dispatchAttributesChange();
|
|
12639
12760
|
}));
|
|
12640
12761
|
}
|
|
12641
12762
|
|
|
@@ -12731,6 +12852,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12731
12852
|
|
|
12732
12853
|
#handleFocusIn(event) {
|
|
12733
12854
|
if (this.#elementInEditorOrToolbar(event.target) && !this.currentlyFocused) {
|
|
12855
|
+
this.#dispatchAttributesChange();
|
|
12734
12856
|
dispatch(this, "lexxy:focus");
|
|
12735
12857
|
this.currentlyFocused = true;
|
|
12736
12858
|
}
|
|
@@ -12811,7 +12933,112 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12811
12933
|
}
|
|
12812
12934
|
}
|
|
12813
12935
|
|
|
12936
|
+
#dispatchAttributesChange() {
|
|
12937
|
+
let attributes = null;
|
|
12938
|
+
let linkHref = null;
|
|
12939
|
+
let highlight = null;
|
|
12940
|
+
let headingTag = null;
|
|
12941
|
+
|
|
12942
|
+
this.editor.getEditorState().read(() => {
|
|
12943
|
+
const selection = $r();
|
|
12944
|
+
if (!wr(selection)) return
|
|
12945
|
+
|
|
12946
|
+
const format = this.selection.getFormat();
|
|
12947
|
+
if (Object.keys(format).length === 0) return
|
|
12948
|
+
|
|
12949
|
+
const anchorNode = selection.anchor.getNode();
|
|
12950
|
+
const linkNode = vt$4(anchorNode, E$3);
|
|
12951
|
+
|
|
12952
|
+
attributes = {
|
|
12953
|
+
bold: { active: format.isBold, enabled: true },
|
|
12954
|
+
italic: { active: format.isItalic, enabled: true },
|
|
12955
|
+
strikethrough: { active: format.isStrikethrough, enabled: true },
|
|
12956
|
+
code: { active: format.isInCode, enabled: true },
|
|
12957
|
+
highlight: { active: format.isHighlight, enabled: true },
|
|
12958
|
+
link: { active: format.isInLink, enabled: true },
|
|
12959
|
+
quote: { active: format.isInQuote, enabled: true },
|
|
12960
|
+
heading: { active: format.isInHeading, enabled: true },
|
|
12961
|
+
"unordered-list": { active: format.isInList && format.listType === "bullet", enabled: true },
|
|
12962
|
+
"ordered-list": { active: format.isInList && format.listType === "number", enabled: true },
|
|
12963
|
+
undo: { active: false, enabled: this.historyState?.undoStack.length > 0 },
|
|
12964
|
+
redo: { active: false, enabled: this.historyState?.redoStack.length > 0 }
|
|
12965
|
+
};
|
|
12966
|
+
|
|
12967
|
+
linkHref = linkNode ? linkNode.getURL() : null;
|
|
12968
|
+
highlight = format.isHighlight ? getHighlightStyles(selection) : null;
|
|
12969
|
+
headingTag = format.headingTag ?? null;
|
|
12970
|
+
});
|
|
12971
|
+
|
|
12972
|
+
if (attributes) {
|
|
12973
|
+
this.adapter.dispatchAttributesChange(attributes, linkHref, highlight, headingTag);
|
|
12974
|
+
}
|
|
12975
|
+
}
|
|
12976
|
+
|
|
12977
|
+
#dispatchEditorInitialized() {
|
|
12978
|
+
if (!this.adapter) return
|
|
12979
|
+
|
|
12980
|
+
this.adapter.dispatchEditorInitialized({
|
|
12981
|
+
highlightColors: this.#resolvedHighlightColors,
|
|
12982
|
+
headingFormats: this.#supportedHeadingFormats
|
|
12983
|
+
});
|
|
12984
|
+
}
|
|
12985
|
+
|
|
12986
|
+
#scheduleEditorInitializedDispatch() {
|
|
12987
|
+
this.#cancelEditorInitializedDispatch();
|
|
12988
|
+
this.#editorInitializedRafId = requestAnimationFrame(() => {
|
|
12989
|
+
this.#editorInitializedRafId = null;
|
|
12990
|
+
if (!this.isConnected || !this.adapter) return
|
|
12991
|
+
|
|
12992
|
+
dispatch(this, "lexxy:initialize");
|
|
12993
|
+
this.#dispatchEditorInitialized();
|
|
12994
|
+
});
|
|
12995
|
+
}
|
|
12996
|
+
|
|
12997
|
+
#cancelEditorInitializedDispatch() {
|
|
12998
|
+
if (this.#editorInitializedRafId == null) return
|
|
12999
|
+
|
|
13000
|
+
cancelAnimationFrame(this.#editorInitializedRafId);
|
|
13001
|
+
this.#editorInitializedRafId = null;
|
|
13002
|
+
}
|
|
13003
|
+
|
|
13004
|
+
get #resolvedHighlightColors() {
|
|
13005
|
+
const buttons = this.config.get("highlight.buttons");
|
|
13006
|
+
if (!buttons) return null
|
|
13007
|
+
|
|
13008
|
+
const colors = this.#resolveColors("color", buttons.color || []);
|
|
13009
|
+
const backgroundColors = this.#resolveColors("background-color", buttons["background-color"] || []);
|
|
13010
|
+
return { colors, backgroundColors }
|
|
13011
|
+
}
|
|
13012
|
+
|
|
13013
|
+
get #supportedHeadingFormats() {
|
|
13014
|
+
if (!this.supportsRichText) return []
|
|
13015
|
+
|
|
13016
|
+
return [
|
|
13017
|
+
{ label: "Normal", command: "setFormatParagraph", tag: null },
|
|
13018
|
+
{ label: "Large heading", command: "setFormatHeadingLarge", tag: "h2" },
|
|
13019
|
+
{ label: "Medium heading", command: "setFormatHeadingMedium", tag: "h3" },
|
|
13020
|
+
{ label: "Small heading", command: "setFormatHeadingSmall", tag: "h4" },
|
|
13021
|
+
]
|
|
13022
|
+
}
|
|
13023
|
+
|
|
13024
|
+
#resolveColors(property, cssValues) {
|
|
13025
|
+
const resolver = document.createElement("span");
|
|
13026
|
+
resolver.style.display = "none";
|
|
13027
|
+
this.appendChild(resolver);
|
|
13028
|
+
|
|
13029
|
+
const resolved = cssValues.map(cssValue => {
|
|
13030
|
+
resolver.style.setProperty(property, cssValue);
|
|
13031
|
+
const value = window.getComputedStyle(resolver).getPropertyValue(property);
|
|
13032
|
+
resolver.style.removeProperty(property);
|
|
13033
|
+
return { name: cssValue, value }
|
|
13034
|
+
});
|
|
13035
|
+
|
|
13036
|
+
resolver.remove();
|
|
13037
|
+
return resolved
|
|
13038
|
+
}
|
|
13039
|
+
|
|
12814
13040
|
#reset() {
|
|
13041
|
+
this.#cancelEditorInitializedDispatch();
|
|
12815
13042
|
this.#dispose();
|
|
12816
13043
|
this.editorContentElement?.remove();
|
|
12817
13044
|
this.editorContentElement = null;
|
|
@@ -12823,6 +13050,7 @@ class LexicalEditorElement extends HTMLElement {
|
|
|
12823
13050
|
|
|
12824
13051
|
#dispose() {
|
|
12825
13052
|
this.#unregisterHandlers();
|
|
13053
|
+
this.adapter = null;
|
|
12826
13054
|
document.removeEventListener("turbo:before-cache", this.#handleTurboBeforeCache);
|
|
12827
13055
|
|
|
12828
13056
|
while (this.#disposables.length) {
|
|
@@ -13728,10 +13956,13 @@ class LexicalPromptElement extends HTMLElement {
|
|
|
13728
13956
|
}
|
|
13729
13957
|
|
|
13730
13958
|
class CodeLanguagePicker extends HTMLElement {
|
|
13959
|
+
#abortController = null
|
|
13960
|
+
|
|
13731
13961
|
connectedCallback() {
|
|
13732
13962
|
this.editorElement = this.closest("lexxy-editor");
|
|
13733
13963
|
this.editor = this.editorElement.editor;
|
|
13734
13964
|
this.classList.add("lexxy-floating-controls");
|
|
13965
|
+
this.#abortController = new AbortController();
|
|
13735
13966
|
|
|
13736
13967
|
this.#attachLanguagePicker();
|
|
13737
13968
|
this.#hide();
|
|
@@ -13743,13 +13974,27 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
13743
13974
|
}
|
|
13744
13975
|
|
|
13745
13976
|
dispose() {
|
|
13977
|
+
this.#abortController?.abort();
|
|
13978
|
+
this.#abortController = null;
|
|
13746
13979
|
this.unregisterUpdateListener?.();
|
|
13747
13980
|
this.unregisterUpdateListener = null;
|
|
13748
13981
|
}
|
|
13749
13982
|
|
|
13750
13983
|
#attachLanguagePicker() {
|
|
13751
13984
|
this.languagePickerElement = this.#findLanguagePicker() ?? this.#createLanguagePicker();
|
|
13752
|
-
|
|
13985
|
+
|
|
13986
|
+
const signal = this.#abortController.signal;
|
|
13987
|
+
|
|
13988
|
+
this.languagePickerElement.addEventListener("change", () => {
|
|
13989
|
+
this.#updateCodeBlockLanguage(this.languagePickerElement.value);
|
|
13990
|
+
}, { signal });
|
|
13991
|
+
|
|
13992
|
+
this.languagePickerElement.addEventListener("mousedown", (event) => {
|
|
13993
|
+
this.#dispatchOpenEvent(event);
|
|
13994
|
+
}, { signal });
|
|
13995
|
+
|
|
13996
|
+
this.languagePickerElement.setAttribute("nonce", getNonce());
|
|
13997
|
+
this.appendChild(this.languagePickerElement);
|
|
13753
13998
|
}
|
|
13754
13999
|
|
|
13755
14000
|
#findLanguagePicker() {
|
|
@@ -13766,12 +14011,6 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
13766
14011
|
selectElement.appendChild(option);
|
|
13767
14012
|
}
|
|
13768
14013
|
|
|
13769
|
-
selectElement.addEventListener("change", () => {
|
|
13770
|
-
this.#updateCodeBlockLanguage(this.languagePickerElement.value);
|
|
13771
|
-
});
|
|
13772
|
-
|
|
13773
|
-
selectElement.setAttribute("nonce", getNonce());
|
|
13774
|
-
|
|
13775
14014
|
return selectElement
|
|
13776
14015
|
}
|
|
13777
14016
|
|
|
@@ -13794,6 +14033,21 @@ class CodeLanguagePicker extends HTMLElement {
|
|
|
13794
14033
|
return Object.fromEntries([ plainEntry, ...sortedEntries ])
|
|
13795
14034
|
}
|
|
13796
14035
|
|
|
14036
|
+
#dispatchOpenEvent(event) {
|
|
14037
|
+
const handled = !dispatch(this.editorElement, "lexxy:code-language-picker-open", {
|
|
14038
|
+
languages: this.#bridgeLanguages,
|
|
14039
|
+
currentLanguage: this.languagePickerElement.value
|
|
14040
|
+
}, true);
|
|
14041
|
+
|
|
14042
|
+
if (handled) {
|
|
14043
|
+
event.preventDefault();
|
|
14044
|
+
}
|
|
14045
|
+
}
|
|
14046
|
+
|
|
14047
|
+
get #bridgeLanguages() {
|
|
14048
|
+
return Object.entries(this.#languages).map(([ key, name ]) => ({ key, name }))
|
|
14049
|
+
}
|
|
14050
|
+
|
|
13797
14051
|
#updateCodeBlockLanguage(language) {
|
|
13798
14052
|
this.editor.update(() => {
|
|
13799
14053
|
const codeNode = this.#getCurrentCodeNode();
|
|
@@ -14789,10 +15043,108 @@ function collectTextNodes(root) {
|
|
|
14789
15043
|
return nodes
|
|
14790
15044
|
}
|
|
14791
15045
|
|
|
15046
|
+
class NativeAdapter {
|
|
15047
|
+
frozenLinkKey = null
|
|
15048
|
+
|
|
15049
|
+
constructor(editorElement) {
|
|
15050
|
+
this.editorElement = editorElement;
|
|
15051
|
+
this.editorContentElement = editorElement.editorContentElement;
|
|
15052
|
+
}
|
|
15053
|
+
|
|
15054
|
+
dispatchAttributesChange(attributes, linkHref, highlight, headingTag) {
|
|
15055
|
+
dispatch(this.editorElement, "lexxy:attributes-change", {
|
|
15056
|
+
attributes,
|
|
15057
|
+
link: linkHref ? { href: linkHref } : null,
|
|
15058
|
+
highlight,
|
|
15059
|
+
headingTag
|
|
15060
|
+
});
|
|
15061
|
+
}
|
|
15062
|
+
|
|
15063
|
+
dispatchEditorInitialized(detail) {
|
|
15064
|
+
dispatch(this.editorElement, "lexxy:editor-initialized", detail);
|
|
15065
|
+
}
|
|
15066
|
+
|
|
15067
|
+
freeze() {
|
|
15068
|
+
let frozenLinkKey = null;
|
|
15069
|
+
this.editorElement.editor?.getEditorState().read(() => {
|
|
15070
|
+
const selection = $r();
|
|
15071
|
+
if (!wr(selection)) return
|
|
15072
|
+
|
|
15073
|
+
const linkNode = vt$4(selection.anchor.getNode(), E$3);
|
|
15074
|
+
if (linkNode) {
|
|
15075
|
+
frozenLinkKey = linkNode.getKey();
|
|
15076
|
+
}
|
|
15077
|
+
});
|
|
15078
|
+
|
|
15079
|
+
this.frozenLinkKey = frozenLinkKey;
|
|
15080
|
+
this.editorContentElement.contentEditable = "false";
|
|
15081
|
+
}
|
|
15082
|
+
|
|
15083
|
+
thaw() {
|
|
15084
|
+
this.editorContentElement.contentEditable = "true";
|
|
15085
|
+
}
|
|
15086
|
+
|
|
15087
|
+
unlinkFrozenNode() {
|
|
15088
|
+
const key = this.frozenLinkKey;
|
|
15089
|
+
if (!key) return false
|
|
15090
|
+
|
|
15091
|
+
const linkNode = Mo(key);
|
|
15092
|
+
if (!B$2(linkNode)) {
|
|
15093
|
+
this.frozenLinkKey = null;
|
|
15094
|
+
return false
|
|
15095
|
+
}
|
|
15096
|
+
|
|
15097
|
+
const children = linkNode.getChildren();
|
|
15098
|
+
for (const child of children) {
|
|
15099
|
+
linkNode.insertBefore(child);
|
|
15100
|
+
}
|
|
15101
|
+
linkNode.remove();
|
|
15102
|
+
|
|
15103
|
+
// Select the former link text so a follow-up createLink can re-wrap it.
|
|
15104
|
+
const firstText = this.#findFirstTextDescendant(children);
|
|
15105
|
+
const lastText = this.#findLastTextDescendant(children);
|
|
15106
|
+
if (firstText && lastText) {
|
|
15107
|
+
const selection = $r();
|
|
15108
|
+
if (wr(selection)) {
|
|
15109
|
+
selection.anchor.set(firstText.getKey(), 0, "text");
|
|
15110
|
+
selection.focus.set(lastText.getKey(), lastText.getTextContent().length, "text");
|
|
15111
|
+
}
|
|
15112
|
+
}
|
|
15113
|
+
|
|
15114
|
+
this.frozenLinkKey = null;
|
|
15115
|
+
return true
|
|
15116
|
+
}
|
|
15117
|
+
|
|
15118
|
+
#findFirstTextDescendant(nodes) {
|
|
15119
|
+
for (const node of nodes) {
|
|
15120
|
+
if (yr(node)) return node
|
|
15121
|
+
if (Pi(node)) {
|
|
15122
|
+
const nestedTextNode = this.#findFirstTextDescendant(node.getChildren());
|
|
15123
|
+
if (nestedTextNode) return nestedTextNode
|
|
15124
|
+
}
|
|
15125
|
+
}
|
|
15126
|
+
|
|
15127
|
+
return null
|
|
15128
|
+
}
|
|
15129
|
+
|
|
15130
|
+
#findLastTextDescendant(nodes) {
|
|
15131
|
+
for (let index = nodes.length - 1; index >= 0; index--) {
|
|
15132
|
+
const node = nodes[index];
|
|
15133
|
+
if (yr(node)) return node
|
|
15134
|
+
if (Pi(node)) {
|
|
15135
|
+
const nestedTextNode = this.#findLastTextDescendant(node.getChildren());
|
|
15136
|
+
if (nestedTextNode) return nestedTextNode
|
|
15137
|
+
}
|
|
15138
|
+
}
|
|
15139
|
+
|
|
15140
|
+
return null
|
|
15141
|
+
}
|
|
15142
|
+
}
|
|
15143
|
+
|
|
14792
15144
|
const configure = Lexxy.configure;
|
|
14793
15145
|
|
|
14794
15146
|
// Pushing elements definition to after the current call stack to allow global configuration to take place first
|
|
14795
15147
|
setTimeout(defineElements, 0);
|
|
14796
15148
|
|
|
14797
|
-
export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, LexxyExtension as Extension, HorizontalDividerNode, configure, highlightCode as highlightAll, highlightCode };
|
|
15149
|
+
export { $createActionTextAttachmentNode, $createActionTextAttachmentUploadNode, $isActionTextAttachmentNode, ActionTextAttachmentNode, ActionTextAttachmentUploadNode, CustomActionTextAttachmentNode, LexxyExtension as Extension, HorizontalDividerNode, NativeAdapter, configure, highlightCode as highlightAll, highlightCode };
|
|
14798
15150
|
//# sourceMappingURL=lexxy.js.map
|
|
Binary file
|
|
Binary file
|