From 05dda755edeb789f198a5e82839d7dc7c0a04612 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Mon, 25 Oct 2021 10:24:37 +0200 Subject: [PATCH] DEV: removes jquery usage from linkSeenMentions codepath (#14695) --- .../app/components/composer-editor.js | 4 +- .../discourse/app/components/d-editor.js | 2 +- .../discourse/app/lib/link-mentions.js | 39 ++++++++++++------- .../tests/unit/lib/link-mentions-test.js | 32 +++++++++------ 4 files changed, 47 insertions(+), 30 deletions(-) diff --git a/app/assets/javascripts/discourse/app/components/composer-editor.js b/app/assets/javascripts/discourse/app/components/composer-editor.js index b6c3d3456a0..1e01a57b27d 100644 --- a/app/assets/javascripts/discourse/app/components/composer-editor.js +++ b/app/assets/javascripts/discourse/app/components/composer-editor.js @@ -503,7 +503,7 @@ export default Component.extend(ComposerUpload, { // 'Create a New Topic' scenario is not supported (per conversation with codinghorror) // https://meta.discourse.org/t/taking-another-1-7-release-task/51986/7 fetchUnseenMentions(unseen, this.get("composer.topic.id")).then(() => { - linkSeenMentions($preview, this.siteSettings); + linkSeenMentions($preview[0], this.siteSettings); this._warnMentionedGroups($preview); this._warnCannotSeeMention($preview); }); @@ -734,7 +734,7 @@ export default Component.extend(ComposerUpload, { previewUpdated($preview) { // Paint mentions - const unseenMentions = linkSeenMentions($preview, this.siteSettings); + const unseenMentions = linkSeenMentions($preview[0], this.siteSettings); if (unseenMentions.length) { discourseDebounce( this, diff --git a/app/assets/javascripts/discourse/app/components/d-editor.js b/app/assets/javascripts/discourse/app/components/d-editor.js index a7a879d5b49..312c0719a18 100644 --- a/app/assets/javascripts/discourse/app/components/d-editor.js +++ b/app/assets/javascripts/discourse/app/components/d-editor.js @@ -395,7 +395,7 @@ export default Component.extend(TextareaTextManipulation, { cookedElement.innerHTML = cooked; linkSeenHashtags($(cookedElement)); - linkSeenMentions($(cookedElement), this.siteSettings); + linkSeenMentions(cookedElement, this.siteSettings); resolveCachedShortUrls(this.siteSettings, cookedElement); loadOneboxes( cookedElement, diff --git a/app/assets/javascripts/discourse/app/lib/link-mentions.js b/app/assets/javascripts/discourse/app/lib/link-mentions.js index e7cd5c29de3..ab9aca48118 100644 --- a/app/assets/javascripts/discourse/app/lib/link-mentions.js +++ b/app/assets/javascripts/discourse/app/lib/link-mentions.js @@ -1,3 +1,4 @@ +import deprecated from "discourse-common/lib/deprecated"; import { ajax } from "discourse/lib/ajax"; import { formatUsername } from "discourse/lib/utilities"; import getURL from "discourse-common/lib/get-url"; @@ -5,10 +6,9 @@ import { userPath } from "discourse/lib/url"; let maxGroupMention; -function replaceSpan($e, username, opts) { +function replaceSpan(element, username, opts) { let extra = {}; let extraClass = []; - const element = $e[0]; const a = document.createElement("a"); if (opts && opts.group) { @@ -48,30 +48,39 @@ const mentionableGroups = {}; const checked = {}; const cannotSee = []; -function updateFound($mentions, usernames) { - $mentions.each((i, e) => { - const $e = $(e); - const username = usernames[i]; +function updateFound(mentions, usernames) { + mentions.forEach((mention, index) => { + const username = usernames[index]; if (found[username.toLowerCase()]) { - replaceSpan($e, username, { cannot_see: cannotSee[username] }); + replaceSpan(mention, username, { cannot_see: cannotSee[username] }); } else if (mentionableGroups[username]) { - replaceSpan($e, username, { + replaceSpan(mention, username, { group: true, mentionable: mentionableGroups[username], }); } else if (foundGroups[username]) { - replaceSpan($e, username, { group: true }); + replaceSpan(mention, username, { group: true }); } else if (checked[username]) { - $e.addClass("mention-tested"); + mention.classList.add("mention-tested"); } }); } -export function linkSeenMentions($elem, siteSettings) { - const $mentions = $("span.mention:not(.mention-tested)", $elem); - if ($mentions.length) { - const usernames = [...$mentions.map((_, e) => $(e).text().substr(1))]; - updateFound($mentions, usernames); +export function linkSeenMentions(elem, siteSettings) { + if (elem instanceof jQuery) { + elem = elem[0]; + + deprecated("linkSeenMentions now expects a DOM node as first parameter", { + since: "2.8.0.beta7", + }); + } + + const mentions = [ + ...elem.querySelectorAll("span.mention:not(.mention-tested)"), + ]; + if (mentions.length) { + const usernames = mentions.map((m) => m.innerText.substr(1)); + updateFound(mentions, usernames); return usernames .uniq() .filter( diff --git a/app/assets/javascripts/discourse/tests/unit/lib/link-mentions-test.js b/app/assets/javascripts/discourse/tests/unit/lib/link-mentions-test.js index 53c072bdc95..c18887b6e6a 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/link-mentions-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/link-mentions-test.js @@ -32,31 +32,39 @@ module("Unit | Utility | link-mentions", function () { "invalid", ]); - let $root = $(` + let html = `
- @invalid - @valid_user - @valid_group - @mentionable_group + @invalid + @valid_user + @valid_group + @mentionable_group
- `); + `; - await linkSeenMentions($root); + let template = document.createElement("template"); + html = html.trim(); + template.innerHTML = html; + const root = template.content.firstChild; + + await linkSeenMentions(root); // Ember.Test.registerWaiter is not available here, so we are implementing // our own await new Promise((resolve) => { const interval = setInterval(() => { - if ($("a", $root).length > 0) { + if (root.querySelectorAll("a").length > 0) { clearInterval(interval); resolve(); } }, 500); }); - assert.equal($("a", $root)[0].text, "@valid_user"); - assert.equal($("a", $root)[1].text, "@valid_group"); - assert.equal($("a.notify", $root).text(), "@mentionable_group"); - assert.equal($("span.mention", $root)[0].innerHTML, "@invalid"); + assert.equal(root.querySelector("a").innerText, "@valid_user"); + assert.equal(root.querySelectorAll("a")[1].innerText, "@valid_group"); + assert.equal( + root.querySelector("a.notify").innerText, + "@mentionable_group" + ); + assert.equal(root.querySelector("span.mention").innerHTML, "@invalid"); }); });