FIX: more robust tabindex restriction on preview (#14425)

FIX: more robust tabindex restriction on preview (#14425)

diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js
index 318a969..1a77971 100644
--- a/app/assets/javascripts/discourse/app/components/d-editor.js
+++ b/app/assets/javascripts/discourse/app/components/d-editor.js
@@ -289,6 +289,8 @@ export default Component.extend(TextareaTextManipulation, {
       });
     });
 
+    this._previewMutationObserver = this._disablePreviewTabIndex();
+
     // disable clicking on links in the preview
     $(this.element.querySelector(".d-editor-preview")).on(
       "click.preview",
@@ -340,6 +342,8 @@ export default Component.extend(TextareaTextManipulation, {
 
     $(this.element.querySelector(".d-editor-preview")).off("click.preview");
 
+    this._previewMutationObserver?.disconnect();
+
     if (isTesting()) {
       this.element.removeEventListener("paste", this.paste);
     }
@@ -428,11 +432,6 @@ export default Component.extend(TextareaTextManipulation, {
             return;
           }
 
-          // prevents any tab focus in preview
-          preview.querySelectorAll("a").forEach((anchor) => {
-            anchor.setAttribute("tabindex", "-1");
-          });
-
           if (this.previewUpdated) {
             this.previewUpdated($(preview));
           }
@@ -910,4 +909,20 @@ export default Component.extend(TextareaTextManipulation, {
       this.set("isEditorFocused", false);
     },
   },
+
+  _disablePreviewTabIndex() {
+    const observer = new MutationObserver(function () {
+      document.querySelectorAll(".d-editor-preview a").forEach((anchor) => {
+        anchor.setAttribute("tabindex", "-1");
+      });
+    });
+
+    observer.observe(document.querySelector(".d-editor-preview"), {
+      childList: true,
+      subtree: false,
+      attributes: false,
+    });
+
+    return observer;
+  },
 });
diff --git a/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js b/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js
index 372689b..847130a 100644
--- a/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/components/d-editor-test.js
@@ -37,6 +37,19 @@ discourseModule("Integration | Component | d-editor", function (hooks) {
     },
   });
 
+  componentTest("links in preview are not tabbable", {
+    template: hbs`{{d-editor value=value}}`,
+
+    async test(assert) {
+      await fillIn(".d-editor-input", "[discourse](https://www.discourse.org)");
+
+      assert.equal(
+        queryAll(".d-editor-preview").html().trim(),
+        '<p><a href="https://www.discourse.org" tabindex="-1">discourse</a></p>'
+      );
+    },
+  });
+
   componentTest("preview sanitizes HTML", {
     template: hbs`{{d-editor value=value}}`,
 

GitHub sha: 456189795a67d6d221af2629f811dd9ff9a270d8

This commit appears in #14425 which was approved by pmusaraj. It was merged by jjaffeux.