From 15aa213a618005317fa872d0066b2d1fd1feae69 Mon Sep 17 00:00:00 2001 From: Bianca Nenciu Date: Mon, 21 Jun 2021 19:14:57 +0300 Subject: [PATCH] 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. --- .../discourse/app/widgets/post-cooked.js | 39 ++++++++++++++++--- .../tests/integration/widgets/post-test.js | 29 ++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/discourse/app/widgets/post-cooked.js b/app/assets/javascripts/discourse/app/widgets/post-cooked.js index 5a41b1d9dc3..eb870d31c85 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 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( - ` ${number( - lc.clicks - )}` - ); + 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( + ` ${number( + lc.clicks + )}` + ); + } } }); }); 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 4598e485795..5f09aa7ea67 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: ` +

Other URL

+ + `, + 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}}