lexxy 0.9.1.beta → 0.9.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 857d629c986ab28555fc79821525be30888fdfa3083b900dfbc8a1b74f42b1db
4
- data.tar.gz: 34c6e06b8a36438eaed68aaf9421a6388b85d1004bf1a8682e3d83bf0d29ed55
3
+ metadata.gz: a8ee9866b0433459ec013e80632d58c956e8183ac5fe33b42d046195714e943e
4
+ data.tar.gz: f7801f5dec0979471d9b6e079632ed8b17b23564b13b3cebd5ea85609366f871
5
5
  SHA512:
6
- metadata.gz: 0c1ef0dfa8299890c9d165b9e76a254f465f107404fb2c281ad1f830d5f2c9f97641eae0070d88bf24a201f5358448793d00d2cea3f2131edd08bdc56358339f
7
- data.tar.gz: c06d85591d104ca856ddcea2cfa5fe00d678eab8eed4455b88bfef8338535bd1d1de4299debb0c873d4790104433ad06f9be18ad964df365817fde8e7d1c6b3d
6
+ metadata.gz: fd915f18f31b55b22500c2c9d7a749fcb9cbe7cba02ec835f773ea697853d5c9a90617e1509bf5802664285adb4c31bc716fc70c99bcbf701a8fb79167ccbaf9
7
+ data.tar.gz: 43e49d501e92e3fca8338ab1f09a9ae449f4e6ad733d4a6b4542ec9e3be3676cdc20780a87f476e0c804b61fea2be88220c888ea4b13bf49ca1b1eb3322891c9
@@ -4952,9 +4952,22 @@ class LexicalToolbarElement extends HTMLElement {
4952
4952
  }
4953
4953
 
4954
4954
  disconnectedCallback() {
4955
+ this.dispose();
4956
+ }
4957
+
4958
+ dispose() {
4955
4959
  this.#uninstallResizeObserver();
4960
+ this.#unbindButtons();
4956
4961
  this.#unbindHotkeys();
4957
4962
  this.#unbindFocusListeners();
4963
+ this.unregisterSelectionListener?.();
4964
+ this.unregisterHistoryListener?.();
4965
+
4966
+ this.editorElement = null;
4967
+ this.editor = null;
4968
+ this.selection = null;
4969
+
4970
+ this.#createEditorPromise();
4958
4971
  }
4959
4972
 
4960
4973
  attributeChangedCallback(name, oldValue, newValue) {
@@ -4998,10 +5011,12 @@ class LexicalToolbarElement extends HTMLElement {
4998
5011
  this.connectedCallback();
4999
5012
  }
5000
5013
 
5001
- #createEditorPromise() {
5014
+ async #createEditorPromise() {
5002
5015
  this.editorPromise = new Promise((resolve) => {
5003
5016
  this.resolveEditorPromise = resolve;
5004
5017
  });
5018
+
5019
+ this.editorElement = await this.editorPromise;
5005
5020
  }
5006
5021
 
5007
5022
  #installResizeObserver() {
@@ -5017,10 +5032,14 @@ class LexicalToolbarElement extends HTMLElement {
5017
5032
  }
5018
5033
 
5019
5034
  #bindButtons() {
5020
- this.addEventListener("click", this.#handleButtonClicked.bind(this));
5035
+ this.addEventListener("click", this.#handleButtonClicked);
5036
+ }
5037
+
5038
+ #unbindButtons() {
5039
+ this.removeEventListener("click", this.#handleButtonClicked);
5021
5040
  }
5022
5041
 
5023
- #handleButtonClicked(event) {
5042
+ #handleButtonClicked = (event) => {
5024
5043
  this.#handleTargetClicked(event, "[data-command]", this.#dispatchButtonCommand.bind(this));
5025
5044
  }
5026
5045
 
@@ -5080,8 +5099,8 @@ class LexicalToolbarElement extends HTMLElement {
5080
5099
  }
5081
5100
 
5082
5101
  #unbindFocusListeners() {
5083
- this.editorElement.removeEventListener("lexxy:focus", this.#handleEditorFocus);
5084
- this.editorElement.removeEventListener("lexxy:blur", this.#handleEditorBlur);
5102
+ this.editorElement?.removeEventListener("lexxy:focus", this.#handleEditorFocus);
5103
+ this.editorElement?.removeEventListener("lexxy:blur", this.#handleEditorBlur);
5085
5104
  this.removeEventListener("keydown", this.#handleKeydown);
5086
5105
  }
5087
5106
 
@@ -5105,7 +5124,7 @@ class LexicalToolbarElement extends HTMLElement {
5105
5124
  }
5106
5125
 
5107
5126
  #monitorSelectionChanges() {
5108
- this.editor.registerUpdateListener(() => {
5127
+ this.unregisterSelectionListener = this.editor.registerUpdateListener(() => {
5109
5128
  this.editor.getEditorState().read(() => {
5110
5129
  this.#updateButtonStates();
5111
5130
  this.#closeDropdowns();
@@ -5114,7 +5133,7 @@ class LexicalToolbarElement extends HTMLElement {
5114
5133
  }
5115
5134
 
5116
5135
  #monitorHistoryChanges() {
5117
- this.editor.registerUpdateListener(() => {
5136
+ this.unregisterHistoryListener = this.editor.registerUpdateListener(() => {
5118
5137
  this.#updateUndoRedoButtonStates();
5119
5138
  });
5120
5139
  }
@@ -8243,9 +8262,10 @@ const COMMANDS = [
8243
8262
 
8244
8263
  class CommandDispatcher {
8245
8264
  #selectionBeforeDrag = null
8265
+ #unregister = []
8246
8266
 
8247
8267
  static configureFor(editorElement) {
8248
- new CommandDispatcher(editorElement);
8268
+ return new CommandDispatcher(editorElement)
8249
8269
  }
8250
8270
 
8251
8271
  constructor(editorElement) {
@@ -8457,6 +8477,13 @@ class CommandDispatcher {
8457
8477
  this.editor.dispatchCommand(Ce$1, undefined);
8458
8478
  }
8459
8479
 
8480
+ dispose() {
8481
+ while (this.#unregister.length) {
8482
+ const unregister = this.#unregister.pop();
8483
+ unregister();
8484
+ }
8485
+ }
8486
+
8460
8487
  #registerCommands() {
8461
8488
  for (const command of COMMANDS) {
8462
8489
  const methodName = `dispatch${capitalize(command)}`;
@@ -8467,12 +8494,12 @@ class CommandDispatcher {
8467
8494
  }
8468
8495
 
8469
8496
  #registerCommandHandler(command, priority, handler) {
8470
- this.editor.registerCommand(command, handler, priority);
8497
+ this.#unregister.push(this.editor.registerCommand(command, handler, priority));
8471
8498
  }
8472
8499
 
8473
8500
  #registerKeyboardCommands() {
8474
- this.editor.registerCommand(ve$1, this.#handleArrowRightKey.bind(this), Gi);
8475
- this.editor.registerCommand(De$2, this.#handleTabKey.bind(this), Gi);
8501
+ this.#registerCommandHandler(ve$1, Gi, this.#handleArrowRightKey.bind(this));
8502
+ this.#registerCommandHandler(De$2, Gi, this.#handleTabKey.bind(this));
8476
8503
  }
8477
8504
 
8478
8505
  #handleArrowRightKey(event) {
@@ -8958,6 +8985,8 @@ function $isActionTextAttachmentNode(node) {
8958
8985
  }
8959
8986
 
8960
8987
  class Selection {
8988
+ #unregister = []
8989
+
8961
8990
  constructor(editorElement) {
8962
8991
  this.editorElement = editorElement;
8963
8992
  this.editorContentElement = editorElement.editorContentElement;
@@ -9214,6 +9243,18 @@ class Selection {
9214
9243
  return this.#findPreviousSiblingUp(anchorNode)
9215
9244
  }
9216
9245
 
9246
+ dispose() {
9247
+ this.editorElement = null;
9248
+ this.editorContentElement = null;
9249
+ this.editor = null;
9250
+ this.previouslySelectedKeys = null;
9251
+
9252
+ while (this.#unregister.length) {
9253
+ const unregister = this.#unregister.pop();
9254
+ unregister();
9255
+ }
9256
+ }
9257
+
9217
9258
  // When all inline code text is deleted, Lexical's selection retains the stale
9218
9259
  // code format flag. Verify the flag is backed by actual code-formatted content:
9219
9260
  // a code block ancestor or a text node that carries the code format.
@@ -9229,7 +9270,7 @@ class Selection {
9229
9270
  // detects that stale state and clears it so newly typed text won't be
9230
9271
  // code-formatted.
9231
9272
  #clearStaleInlineCodeFormat() {
9232
- this.editor.registerUpdateListener(({ editorState, tags }) => {
9273
+ this.#unregister.push(this.editor.registerUpdateListener(({ editorState, tags }) => {
9233
9274
  if (tags.has("history-merge") || tags.has("skip-dom-selection")) return
9234
9275
 
9235
9276
  let isStale = false;
@@ -9258,7 +9299,7 @@ class Selection {
9258
9299
  });
9259
9300
  }, 0);
9260
9301
  }
9261
- });
9302
+ }));
9262
9303
  }
9263
9304
 
9264
9305
  get #currentlySelectedKeys() {
@@ -9277,29 +9318,32 @@ class Selection {
9277
9318
  }
9278
9319
 
9279
9320
  #processSelectionChangeCommands() {
9280
- this.editor.registerCommand(ke$3, this.#selectPreviousNode.bind(this), Hi);
9281
- this.editor.registerCommand(ve$1, this.#selectNextNode.bind(this), Hi);
9282
- this.editor.registerCommand(be$2, this.#selectPreviousTopLevelNode.bind(this), Hi);
9283
- this.editor.registerCommand(we$1, this.#selectNextTopLevelNode.bind(this), Hi);
9321
+ this.#unregister.push(ec(
9322
+ this.editor.registerCommand(ke$3, this.#selectPreviousNode.bind(this), Hi),
9323
+ this.editor.registerCommand(ve$1, this.#selectNextNode.bind(this), Hi),
9324
+ this.editor.registerCommand(be$2, this.#selectPreviousTopLevelNode.bind(this), Hi),
9325
+ this.editor.registerCommand(we$1, this.#selectNextTopLevelNode.bind(this), Hi),
9284
9326
 
9285
- this.editor.registerCommand(ue$2, this.#selectDecoratorNodeBeforeDeletion.bind(this), Hi);
9327
+ this.editor.registerCommand(ue$2, this.#selectDecoratorNodeBeforeDeletion.bind(this), Hi),
9286
9328
 
9287
- this.editor.registerCommand(re$2, () => {
9288
- this.current = $r();
9289
- }, Hi);
9329
+ this.editor.registerCommand(re$2, () => {
9330
+ this.current = $r();
9331
+ }, Hi)
9332
+ ));
9290
9333
  }
9291
9334
 
9292
9335
  #listenForNodeSelections() {
9293
- this.editor.registerCommand(oe$4, ({ target }) => {
9336
+ this.#unregister.push(this.editor.registerCommand(oe$4, ({ target }) => {
9294
9337
  if (!As(target)) return false
9295
9338
 
9296
9339
  const targetNode = Do(target);
9297
9340
  return Li(targetNode) && this.#selectInLexical(targetNode)
9298
- }, Hi);
9341
+ }, Hi));
9299
9342
 
9300
- this.editor.getRootElement().addEventListener("lexxy:internal:move-to-next-line", (event) => {
9301
- this.#selectOrAppendNextLine();
9302
- });
9343
+ const moveNextLineHandler = () => this.#selectOrAppendNextLine();
9344
+ const rootElement = this.editor.getRootElement();
9345
+ rootElement.addEventListener("lexxy:internal:move-to-next-line", moveNextLineHandler);
9346
+ this.#unregister.push(() => rootElement.removeEventListener("lexxy:internal:move-to-next-line", moveNextLineHandler));
9303
9347
  }
9304
9348
 
9305
9349
  #containEditorFocus() {
@@ -10434,7 +10478,11 @@ class Contents {
10434
10478
  constructor(editorElement) {
10435
10479
  this.editorElement = editorElement;
10436
10480
  this.editor = editorElement.editor;
10481
+ }
10437
10482
 
10483
+ dispose() {
10484
+ this.editorElement = null;
10485
+ this.editor = null;
10438
10486
  }
10439
10487
 
10440
10488
  insertHtml(html, { tag } = {}) {
@@ -11537,11 +11585,12 @@ class TablesExtension extends LexxyExtension {
11537
11585
  ze$1
11538
11586
  ],
11539
11587
  register(editor) {
11588
+ Cn(editor);
11589
+
11540
11590
  return ec(
11541
11591
  // Register Lexical table plugins
11542
11592
  Kn(editor),
11543
11593
  An(editor, true),
11544
- Cn(editor),
11545
11594
 
11546
11595
  // Bug fix: Prevent hardcoded background color (Lexical #8089)
11547
11596
  editor.registerNodeTransform(Ke$1, (node) => {
@@ -12268,6 +12317,7 @@ class LexicalEditorElement extends HTMLElement {
12268
12317
 
12269
12318
  #initialValue = ""
12270
12319
  #validationTextArea = document.createElement("textarea")
12320
+ #disposables = []
12271
12321
 
12272
12322
  constructor() {
12273
12323
  super();
@@ -12281,12 +12331,19 @@ class LexicalEditorElement extends HTMLElement {
12281
12331
  this.extensions = new Extensions(this);
12282
12332
 
12283
12333
  this.editor = this.#createEditor();
12334
+ this.#disposables.push(this.editor);
12284
12335
 
12285
12336
  this.contents = new Contents(this);
12337
+ this.#disposables.push(this.contents);
12338
+
12286
12339
  this.selection = new Selection(this);
12340
+ this.#disposables.push(this.selection);
12341
+
12287
12342
  this.clipboard = new Clipboard(this);
12288
12343
 
12289
- CommandDispatcher.configureFor(this);
12344
+ const commandDispatcher = CommandDispatcher.configureFor(this);
12345
+ this.#disposables.push(commandDispatcher);
12346
+
12290
12347
  this.#initialize();
12291
12348
 
12292
12349
  requestAnimationFrame(() => dispatch(this, "lexxy:initialize"));
@@ -12339,7 +12396,7 @@ class LexicalEditorElement extends HTMLElement {
12339
12396
  get toolbarElement() {
12340
12397
  if (!this.#hasToolbar) return null
12341
12398
 
12342
- this.toolbar = this.toolbar || this.#findOrCreateDefaultToolbar();
12399
+ this.toolbar ??= this.#findOrCreateDefaultToolbar();
12343
12400
  return this.toolbar
12344
12401
  }
12345
12402
 
@@ -12475,6 +12532,7 @@ class LexicalEditorElement extends HTMLElement {
12475
12532
 
12476
12533
  #createEditor() {
12477
12534
  this.editorContentElement ||= this.#createEditorContentElement();
12535
+ this.appendChild(this.editorContentElement);
12478
12536
 
12479
12537
  const editor = Qt$2({
12480
12538
  name: "lexxy/core",
@@ -12524,7 +12582,6 @@ class LexicalEditorElement extends HTMLElement {
12524
12582
  });
12525
12583
  editorContentElement.id = `${this.id}-content`;
12526
12584
  this.#ariaAttributes.forEach(attribute => editorContentElement.setAttribute(attribute.name, attribute.value));
12527
- this.appendChild(editorContentElement);
12528
12585
 
12529
12586
  if (this.getAttribute("tabindex")) {
12530
12587
  editorContentElement.setAttribute("tabindex", this.getAttribute("tabindex"));
@@ -12600,36 +12657,48 @@ class LexicalEditorElement extends HTMLElement {
12600
12657
  }
12601
12658
 
12602
12659
  #registerComponents() {
12660
+ const registered = [];
12661
+
12603
12662
  if (this.supportsRichText) {
12604
- Jt$2(this.editor);
12605
- Le$2(this.editor);
12663
+ registered.push(
12664
+ Jt$2(this.editor),
12665
+ Le$2(this.editor)
12666
+ );
12606
12667
  this.#registerTableComponents();
12607
12668
  this.#registerCodeHiglightingComponents();
12608
12669
  if (this.supportsMarkdown) {
12609
- Yt$1(this.editor, Jt$1);
12610
- registerMarkdownLeadingTagHandler(this.editor, Jt$1);
12670
+ registered.push(
12671
+ Yt$1(this.editor, Jt$1),
12672
+ registerMarkdownLeadingTagHandler(this.editor, Jt$1)
12673
+ );
12611
12674
  }
12612
12675
  } else {
12613
- z$1(this.editor);
12676
+ registered.push(z$1(this.editor));
12614
12677
  }
12615
12678
  this.historyState = H();
12616
- E$1(this.editor, this.historyState, 20);
12679
+ registered.push(E$1(this.editor, this.historyState, 20));
12680
+
12681
+ this.#addUnregisterHandler(ec(...registered));
12617
12682
  }
12618
12683
 
12619
12684
  #registerTableComponents() {
12620
- this.tableTools = createElement("lexxy-table-tools");
12621
- this.append(this.tableTools);
12685
+ let tableTools = this.querySelector("lexxy-table-tools");
12686
+ tableTools ??= createElement("lexxy-table-tools");
12687
+ this.append(tableTools);
12688
+ this.#disposables.push(tableTools);
12622
12689
  }
12623
12690
 
12624
12691
  #registerCodeHiglightingComponents() {
12625
12692
  zt$2(this.editor);
12626
- this.codeLanguagePicker = createElement("lexxy-code-language-picker");
12627
- this.append(this.codeLanguagePicker);
12693
+ let codeLanguagePicker = this.querySelector("lexxy-code-language-picker");
12694
+ codeLanguagePicker ??= createElement("lexxy-code-language-picker");
12695
+ this.append(codeLanguagePicker);
12696
+ this.#disposables.push(codeLanguagePicker);
12628
12697
  }
12629
12698
 
12630
12699
  #handleEnter() {
12631
12700
  // We can't prevent these externally using regular keydown because Lexical handles it first.
12632
- this.editor.registerCommand(
12701
+ this.#addUnregisterHandler(this.editor.registerCommand(
12633
12702
  Ee$2,
12634
12703
  (event) => {
12635
12704
  // Prevent CTRL+ENTER
@@ -12647,12 +12716,17 @@ class LexicalEditorElement extends HTMLElement {
12647
12716
  return false
12648
12717
  },
12649
12718
  Gi
12650
- );
12719
+ ));
12651
12720
  }
12652
12721
 
12653
12722
  #registerFocusEvents() {
12654
12723
  this.addEventListener("focusin", this.#handleFocusIn);
12655
12724
  this.addEventListener("focusout", this.#handleFocusOut);
12725
+
12726
+ this.#addUnregisterHandler(() => {
12727
+ this.removeEventListener("focusin", this.#handleFocusIn);
12728
+ this.removeEventListener("focusout", this.#handleFocusOut);
12729
+ });
12656
12730
  }
12657
12731
 
12658
12732
  #handleFocusIn(event) {
@@ -12695,6 +12769,10 @@ class LexicalEditorElement extends HTMLElement {
12695
12769
  #attachToolbar() {
12696
12770
  if (this.#hasToolbar) {
12697
12771
  this.toolbarElement.setEditor(this);
12772
+ if (typeof this.toolbarElement.dispose === "function") {
12773
+ this.#disposables.push(this.toolbarElement);
12774
+ }
12775
+
12698
12776
  this.extensions.initializeToolbars();
12699
12777
  }
12700
12778
  }
@@ -12704,7 +12782,7 @@ class LexicalEditorElement extends HTMLElement {
12704
12782
  if (typeof toolbarConfig === "string") {
12705
12783
  return document.getElementById(toolbarConfig)
12706
12784
  } else {
12707
- return this.#createDefaultToolbar()
12785
+ return this.querySelector("lexxy-toolbar") ?? this.#createDefaultToolbar()
12708
12786
  }
12709
12787
  }
12710
12788
 
@@ -12734,34 +12812,22 @@ class LexicalEditorElement extends HTMLElement {
12734
12812
  }
12735
12813
 
12736
12814
  #reset() {
12737
- this.#unregisterHandlers();
12738
-
12739
- if (this.editorContentElement) {
12740
- this.editorContentElement.remove();
12741
- this.editorContentElement = null;
12742
- }
12743
-
12744
- this.contents = null;
12745
- this.editor = null;
12815
+ this.#dispose();
12816
+ this.editorContentElement?.remove();
12817
+ this.editorContentElement = null;
12746
12818
 
12747
- if (this.toolbar) {
12748
- if (!this.getAttribute("toolbar")) { this.toolbar.remove(); }
12749
- this.toolbar = null;
12750
- }
12819
+ // Prevents issues with turbo morphing receiving an empty <lexxy-editor> which wipes
12820
+ // out the DOM for the tools, and the old toolbar reference will cause issues
12821
+ this.toolbar = null;
12822
+ }
12751
12823
 
12752
- if (this.codeLanguagePicker) {
12753
- this.codeLanguagePicker.remove();
12754
- this.codeLanguagePicker = null;
12755
- }
12824
+ #dispose() {
12825
+ this.#unregisterHandlers();
12826
+ document.removeEventListener("turbo:before-cache", this.#handleTurboBeforeCache);
12756
12827
 
12757
- if (this.tableHandler) {
12758
- this.tableHandler.remove();
12759
- this.tableHandler = null;
12828
+ while (this.#disposables.length) {
12829
+ this.#disposables.pop().dispose();
12760
12830
  }
12761
-
12762
- this.selection = null;
12763
-
12764
- document.removeEventListener("turbo:before-cache", this.#handleTurboBeforeCache);
12765
12831
  }
12766
12832
 
12767
12833
  #reconnect() {
@@ -12802,14 +12868,15 @@ class ToolbarDropdown extends HTMLElement {
12802
12868
  connectedCallback() {
12803
12869
  this.container = this.closest("details");
12804
12870
 
12805
- this.container.addEventListener("toggle", this.#handleToggle.bind(this));
12806
- this.container.addEventListener("keydown", this.#handleKeyDown.bind(this));
12871
+ this.container.addEventListener("toggle", this.#handleToggle);
12872
+ this.container.addEventListener("keydown", this.#handleKeyDown);
12807
12873
 
12808
12874
  this.#onToolbarEditor(this.initialize.bind(this));
12809
12875
  }
12810
12876
 
12811
12877
  disconnectedCallback() {
12812
- this.container.removeEventListener("keydown", this.#handleKeyDown.bind(this));
12878
+ this.container?.removeEventListener("toggle", this.#handleToggle);
12879
+ this.container?.removeEventListener("keydown", this.#handleKeyDown);
12813
12880
  }
12814
12881
 
12815
12882
  get toolbar() {
@@ -12834,11 +12901,11 @@ class ToolbarDropdown extends HTMLElement {
12834
12901
  }
12835
12902
 
12836
12903
  async #onToolbarEditor(callback) {
12837
- await this.toolbar.editorConnected;
12904
+ await this.toolbar.editorElement;
12838
12905
  callback();
12839
12906
  }
12840
12907
 
12841
- #handleToggle() {
12908
+ #handleToggle = () => {
12842
12909
  if (this.container.open) {
12843
12910
  this.#handleOpen();
12844
12911
  }
@@ -12849,7 +12916,7 @@ class ToolbarDropdown extends HTMLElement {
12849
12916
  this.#resetTabIndexValues();
12850
12917
  }
12851
12918
 
12852
- #handleKeyDown(event) {
12919
+ #handleKeyDown = (event) => {
12853
12920
  if (event.key === "Escape") {
12854
12921
  event.stopPropagation();
12855
12922
  this.close();
@@ -12877,27 +12944,30 @@ class LinkDropdown extends ToolbarDropdown {
12877
12944
  super.connectedCallback();
12878
12945
  this.input = this.querySelector("input");
12879
12946
 
12880
- this.#registerHandlers();
12947
+ this.container.addEventListener("toggle", this.#handleToggle);
12948
+ this.addEventListener("submit", this.#handleSubmit);
12949
+ this.querySelector("[value='unlink']").addEventListener("click", this.#handleUnlink);
12881
12950
  }
12882
12951
 
12883
- #registerHandlers() {
12884
- this.container.addEventListener("toggle", this.#handleToggle.bind(this));
12885
- this.addEventListener("submit", this.#handleSubmit.bind(this));
12886
- this.querySelector("[value='unlink']").addEventListener("click", this.#handleUnlink.bind(this));
12952
+ disconnectedCallback() {
12953
+ this.container?.removeEventListener("toggle", this.#handleToggle);
12954
+ this.removeEventListener("submit", this.#handleSubmit);
12955
+ this.querySelector("[value='unlink']")?.removeEventListener("click", this.#handleUnlink);
12956
+ super.disconnectedCallback();
12887
12957
  }
12888
12958
 
12889
- #handleToggle({ newState }) {
12959
+ #handleToggle = ({ newState }) => {
12890
12960
  this.input.value = this.#selectedLinkUrl;
12891
12961
  this.input.required = newState === "open";
12892
12962
  }
12893
12963
 
12894
- #handleSubmit(event) {
12964
+ #handleSubmit = (event) => {
12895
12965
  const command = event.submitter?.value;
12896
12966
  this.editor.dispatchCommand(command, this.input.value);
12897
12967
  this.close();
12898
12968
  }
12899
12969
 
12900
- #handleUnlink() {
12970
+ #handleUnlink = () => {
12901
12971
  this.editor.dispatchCommand("unlink");
12902
12972
  this.close();
12903
12973
  }
@@ -12932,26 +13002,35 @@ const REMOVE_HIGHLIGHT_SELECTOR = "[data-command='removeHighlight']";
12932
13002
  const NO_STYLE = Symbol("no_style");
12933
13003
 
12934
13004
  class HighlightDropdown extends ToolbarDropdown {
12935
- connectedCallback() {
12936
- super.connectedCallback();
12937
- this.#registerToggleHandler();
12938
- }
12939
-
12940
13005
  initialize() {
12941
13006
  this.#setUpButtons();
12942
13007
  this.#registerButtonHandlers();
12943
13008
  }
12944
13009
 
12945
- #registerToggleHandler() {
12946
- this.container.addEventListener("toggle", this.#handleToggle.bind(this));
13010
+ connectedCallback() {
13011
+ super.connectedCallback();
13012
+ this.container.addEventListener("toggle", this.#handleToggle);
13013
+ }
13014
+
13015
+ disconnectedCallback() {
13016
+ this.container?.removeEventListener("toggle", this.#handleToggle);
13017
+ this.#removeButtonHandlers();
13018
+ super.disconnectedCallback();
12947
13019
  }
12948
13020
 
12949
13021
  #registerButtonHandlers() {
12950
- this.#colorButtons.forEach(button => button.addEventListener("click", this.#handleColorButtonClick.bind(this)));
12951
- this.querySelector(REMOVE_HIGHLIGHT_SELECTOR).addEventListener("click", this.#handleRemoveHighlightClick.bind(this));
13022
+ this.#colorButtons.forEach(button => button.addEventListener("click", this.#handleColorButtonClick));
13023
+ this.querySelector(REMOVE_HIGHLIGHT_SELECTOR).addEventListener("click", this.#handleRemoveHighlightClick);
13024
+ }
13025
+
13026
+ #removeButtonHandlers() {
13027
+ this.#colorButtons.forEach(button => button.removeEventListener("click", this.#handleColorButtonClick));
13028
+ this.querySelector(REMOVE_HIGHLIGHT_SELECTOR)?.removeEventListener("click", this.#handleRemoveHighlightClick);
12952
13029
  }
12953
13030
 
12954
13031
  #setUpButtons() {
13032
+ this.#buttonContainer.innerHTML = "";
13033
+
12955
13034
  const colorGroups = this.editorElement.config.get("highlight.buttons");
12956
13035
 
12957
13036
  this.#populateButtonGroup("color", colorGroups.color);
@@ -12977,7 +13056,7 @@ class HighlightDropdown extends ToolbarDropdown {
12977
13056
  return button
12978
13057
  }
12979
13058
 
12980
- #handleToggle({ newState }) {
13059
+ #handleToggle = ({ newState }) => {
12981
13060
  if (newState === "open") {
12982
13061
  this.editor.getEditorState().read(() => {
12983
13062
  this.#updateColorButtonStates($r());
@@ -12985,7 +13064,7 @@ class HighlightDropdown extends ToolbarDropdown {
12985
13064
  }
12986
13065
  }
12987
13066
 
12988
- #handleColorButtonClick(event) {
13067
+ #handleColorButtonClick = (event) => {
12989
13068
  event.preventDefault();
12990
13069
 
12991
13070
  const button = event.target.closest(APPLY_HIGHLIGHT_SELECTOR);
@@ -12998,7 +13077,7 @@ class HighlightDropdown extends ToolbarDropdown {
12998
13077
  this.close();
12999
13078
  }
13000
13079
 
13001
- #handleRemoveHighlightClick(event) {
13080
+ #handleRemoveHighlightClick = (event) => {
13002
13081
  event.preventDefault();
13003
13082
 
13004
13083
  this.editor.dispatchCommand("removeHighlight");
@@ -13660,19 +13739,21 @@ class CodeLanguagePicker extends HTMLElement {
13660
13739
  }
13661
13740
 
13662
13741
  disconnectedCallback() {
13742
+ this.dispose();
13743
+ }
13744
+
13745
+ dispose() {
13663
13746
  this.unregisterUpdateListener?.();
13664
13747
  this.unregisterUpdateListener = null;
13665
13748
  }
13666
13749
 
13667
13750
  #attachLanguagePicker() {
13668
- this.languagePickerElement = this.#createLanguagePicker();
13669
-
13670
- this.languagePickerElement.addEventListener("change", () => {
13671
- this.#updateCodeBlockLanguage(this.languagePickerElement.value);
13672
- });
13751
+ this.languagePickerElement = this.#findLanguagePicker() ?? this.#createLanguagePicker();
13752
+ this.append(this.languagePickerElement);
13753
+ }
13673
13754
 
13674
- this.languagePickerElement.setAttribute("nonce", getNonce());
13675
- this.appendChild(this.languagePickerElement);
13755
+ #findLanguagePicker() {
13756
+ return this.querySelector("select")
13676
13757
  }
13677
13758
 
13678
13759
  #createLanguagePicker() {
@@ -13685,6 +13766,12 @@ class CodeLanguagePicker extends HTMLElement {
13685
13766
  selectElement.appendChild(option);
13686
13767
  }
13687
13768
 
13769
+ selectElement.addEventListener("change", () => {
13770
+ this.#updateCodeBlockLanguage(this.languagePickerElement.value);
13771
+ });
13772
+
13773
+ selectElement.setAttribute("nonce", getNonce());
13774
+
13688
13775
  return selectElement
13689
13776
  }
13690
13777
 
@@ -14245,6 +14332,10 @@ class TableTools extends HTMLElement {
14245
14332
  }
14246
14333
 
14247
14334
  disconnectedCallback() {
14335
+ this.dispose();
14336
+ }
14337
+
14338
+ dispose() {
14248
14339
  this.#unregisterKeyboardShortcuts();
14249
14340
 
14250
14341
  this.unregisterUpdateListener?.();
@@ -14269,6 +14360,8 @@ class TableTools extends HTMLElement {
14269
14360
  }
14270
14361
 
14271
14362
  #setUpButtons() {
14363
+ this.innerHTML = "";
14364
+
14272
14365
  this.appendChild(this.#createRowButtonsContainer());
14273
14366
  this.appendChild(this.#createColumnButtonsContainer());
14274
14367
 
Binary file
Binary file