FIX: Show link count only once for oneboxes (#13444)

FIX: Show link count only once for oneboxes (#13444)

Sometimes oneboxes contain the same link multiple times and the link count was shown for each of them. This commit adds link count only to the most important link, that being either a heading or the header of the onebox.

diff --git a/app/assets/javascripts/discourse/app/widgets/post-cooked.js b/app/assets/javascripts/discourse/app/widgets/post-cooked.js
index 5a41b1d..eb870d3 100644
--- a/app/assets/javascripts/discourse/app/widgets/post-cooked.js
+++ b/app/assets/javascripts/discourse/app/widgets/post-cooked.js
@@ -95,6 +95,27 @@ export default class PostCooked {
       return;
     }
 
+    // find the best <a> element in each onebox and display link counts only
+    // for that one (the best element is the most significant one to the
+    // viewer)
+    const bestElements = [];
+    $html[0].querySelectorAll("aside.onebox").forEach((onebox) => {
+      // look in headings first
+      for (let i = 1; i <= 6; ++i) {
+        const hLinks = onebox.querySelectorAll(`h${i} a[href]`);
+        if (hLinks.length > 0) {
+          bestElements[onebox] = hLinks[0];
+          return;
+        }
+      }
+
+      // use the header otherwise
+      const hLinks = onebox.querySelectorAll("header a[href]");
+      if (hLinks.length > 0) {
+        bestElements[onebox] = hLinks[0];
+      }
+    });
+
     linkCounts.forEach((lc) => {
       if (!lc.clicks || lc.clicks < 1) {
         return;
@@ -118,12 +139,18 @@ export default class PostCooked {
 
         // don't display badge counts on category badge & oneboxes (unless when explicitly stated)
         if (valid && isValidLink($link)) {
-          const title = I18n.t("topic_map.clicks", { count: lc.clicks });
-          $link.append(
-            ` <span class='badge badge-notification clicks' title='${title}'>${number(
-              lc.clicks
-            )}</span>`
-          );
+          const $onebox = $link.closest(".onebox");
+          if (
+            $onebox.length === 0 ||
+            (bestElements[$onebox[0]] && bestElements[$onebox[0]] === $link[0])
+          ) {
+            const title = I18n.t("topic_map.clicks", { count: lc.clicks });
+            $link.append(
+              ` <span class='badge badge-notification clicks' title='${title}'>${number(
+                lc.clicks
+              )}</span>`
+            );
+          }
         }
       });
     });
diff --git a/app/assets/javascripts/discourse/tests/integration/widgets/post-test.js b/app/assets/javascripts/discourse/tests/integration/widgets/post-test.js
index 4598e48..5f09aa7 100644
--- a/app/assets/javascripts/discourse/tests/integration/widgets/post-test.js
+++ b/app/assets/javascripts/discourse/tests/integration/widgets/post-test.js
@@ -47,6 +47,35 @@ discourseModule("Integration | Component | Widget | post", function (hooks) {
     },
   });
 
+  componentTest("post - onebox links", {
+    template: hbs`{{mount-widget widget="post-contents" args=args}}`,
+    beforeEach() {
+      this.set("args", {
+        cooked: `
+        <p><a href="https://example.com">Other URL</a></p>
+
+        <aside class="onebox twitterstatus" data-onebox-src="https://twitter.com/codinghorror">
+          <header class="source">
+             <a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">twitter.com</a>
+          </header>
+          <article class="onebox-body">
+             <h4><a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">Jeff Atwood</a></h4>
+             <div class="twitter-screen-name"><a href="https://twitter.com/codinghorror" target="_blank" rel="noopener">@codinghorror</a></div>
+          </article>
+        </aside>`,
+        linkCounts: [
+          { url: "https://example.com", clicks: 1 },
+          { url: "https://twitter.com/codinghorror", clicks: 2 },
+        ],
+      });
+    },
+    async test(assert) {
+      assert.equal(queryAll(".badge.clicks").length, 2);
+      assert.equal(queryAll(".badge.clicks:nth(0)").text(), "1");
+      assert.equal(queryAll(".badge.clicks:nth(1)").text(), "2");
+    },
+  });
+
   componentTest("wiki", {
     template: hbs`
       {{mount-widget widget="post" args=args showHistory=showHistory}}

GitHub sha: 15aa213a618005317fa872d0066b2d1fd1feae69

This commit appears in #13444 which was approved by CvX. It was merged by nbianca.