From 76a9ca99a88f7f78590b18adbf30c3d4f4e28c71 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Fri, 22 Oct 2021 13:15:46 +0200 Subject: [PATCH] DEV: removes jquery usage from onebox (#14683) --- .../discourse/app/lib/load-oneboxes.js | 2 +- .../discourse/tests/unit/lib/oneboxer-test.js | 6 +- .../pretty-text/addon/inline-oneboxer.js | 8 +-- .../pretty-text/addon/oneboxer-cache.js | 3 +- .../javascripts/pretty-text/addon/oneboxer.js | 64 ++++++++++--------- 5 files changed, 43 insertions(+), 40 deletions(-) diff --git a/app/assets/javascripts/discourse/app/lib/load-oneboxes.js b/app/assets/javascripts/discourse/app/lib/load-oneboxes.js index 0be10658ecf..24d599a61bd 100644 --- a/app/assets/javascripts/discourse/app/lib/load-oneboxes.js +++ b/app/assets/javascripts/discourse/app/lib/load-oneboxes.js @@ -21,7 +21,7 @@ export function loadOneboxes( ).length; container - .querySelectorAll(`a.onebox, a.inline-onebox-loading`) + .querySelectorAll("a.onebox, a.inline-onebox-loading") .forEach((link) => { const isInline = link.classList.contains("inline-onebox-loading"); diff --git a/app/assets/javascripts/discourse/tests/unit/lib/oneboxer-test.js b/app/assets/javascripts/discourse/tests/unit/lib/oneboxer-test.js index 7ac11a624a5..6510a5ab38e 100644 --- a/app/assets/javascripts/discourse/tests/unit/lib/oneboxer-test.js +++ b/app/assets/javascripts/discourse/tests/unit/lib/oneboxer-test.js @@ -40,9 +40,9 @@ module("Unit | Utility | oneboxer", function () { await loadOnebox(element); assert.ok( - localCache["http://somegoodurl.com"] - .prop("outerHTML") - .indexOf("Yet another collaboration tool") !== -1, + localCache["http://somegoodurl.com"].outerHTML.indexOf( + "Yet another collaboration tool" + ) !== -1, "stores the html of the onebox in a local cache" ); assert.ok( diff --git a/app/assets/javascripts/pretty-text/addon/inline-oneboxer.js b/app/assets/javascripts/pretty-text/addon/inline-oneboxer.js index 010b6a9f064..b427ce6141b 100644 --- a/app/assets/javascripts/pretty-text/addon/inline-oneboxer.js +++ b/app/assets/javascripts/pretty-text/addon/inline-oneboxer.js @@ -24,12 +24,12 @@ export function applyInlineOneboxes(inline, ajax, opts) { result["inline-oneboxes"].forEach((onebox) => { if (onebox.title) { _cache[onebox.url] = onebox; + let links = inline[onebox.url] || []; links.forEach((link) => { - $(link) - .text(onebox.title) - .addClass("inline-onebox") - .removeClass("inline-onebox-loading"); + link.innerText = onebox.title; + link.classList.add("inline-onebox"); + link.classList.remove("inline-onebox-loading"); }); } }); diff --git a/app/assets/javascripts/pretty-text/addon/oneboxer-cache.js b/app/assets/javascripts/pretty-text/addon/oneboxer-cache.js index c9a98165ce7..6b7daa5dee3 100644 --- a/app/assets/javascripts/pretty-text/addon/oneboxer-cache.js +++ b/app/assets/javascripts/pretty-text/addon/oneboxer-cache.js @@ -24,6 +24,5 @@ export function normalize(url) { } export function lookupCache(url) { - const cached = localCache[normalize(url)]; - return cached && cached.prop("outerHTML"); + return localCache[normalize(url)]?.outerHTML; } diff --git a/app/assets/javascripts/pretty-text/addon/oneboxer.js b/app/assets/javascripts/pretty-text/addon/oneboxer.js index ada1bd4d4f2..f5d0679765e 100644 --- a/app/assets/javascripts/pretty-text/addon/oneboxer.js +++ b/app/assets/javascripts/pretty-text/addon/oneboxer.js @@ -1,6 +1,6 @@ import { failedCache, - localCache, + lookupCache, normalize, resetFailedCache, resetLocalCache, @@ -21,37 +21,38 @@ export function resetCache() { } function resolveSize(img) { - $(img).addClass("size-resolved"); + img.classList.add("size-resolved"); if (img.width > 0 && img.width === img.height) { - $(img).addClass("onebox-avatar"); + img.classList.add("onebox-avatar"); } } // Detect square images and apply smaller onebox-avatar class -function applySquareGenericOnebox($elem) { - if (!$elem.hasClass("allowlistedgeneric")) { +function applySquareGenericOnebox(elem) { + if (!elem.classList.contains("allowlistedgeneric")) { return; } - let $img = $elem.find(".onebox-body img.thumbnail"); - let img = $img[0]; + let img = elem.querySelector(".onebox-body img.thumbnail"); // already resolved... skip - if ($img.length !== 1 || $img.hasClass("size-resolved")) { + if (!img || img.classList.contains("size-resolved")) { return; } if (img.complete) { resolveSize(img); } else { - $img.on("load.onebox", () => { - resolveSize(img); - $img.off("load.onebox"); - }); + img.addEventListener("load", _handleLoadingOneboxImages); } } +function _handleLoadingOneboxImages() { + resolveSize(this); + this.removeEventListener("load", _handleLoadingOneboxImages); +} + function loadNext(ajax) { if (loadingQueue.length === 0) { timeout = null; @@ -60,7 +61,7 @@ function loadNext(ajax) { let timeoutMs = 150; let removeLoading = true; - const { url, refresh, $elem, categoryId, topicId } = loadingQueue.shift(); + const { url, refresh, elem, categoryId, topicId } = loadingQueue.shift(); // Retrieve the onebox return ajax("/onebox", { @@ -74,16 +75,19 @@ function loadNext(ajax) { }) .then( (html) => { - let $html = $(html); - setLocalCache(normalize(url), $html); - $elem.replaceWith($html); - applySquareGenericOnebox($html); + let template = document.createElement("template"); + template.innerHTML = html.trim(); + const node = template.content.firstChild; + + setLocalCache(normalize(url), node); + elem.replaceWith(node); + applySquareGenericOnebox(node); }, (result) => { - if (result && result.jqXHR && result.jqXHR.status === 429) { + if (result?.jqXHR?.status === 429) { timeoutMs = 2000; removeLoading = false; - loadingQueue.unshift({ url, refresh, $elem, categoryId, topicId }); + loadingQueue.unshift({ url, refresh, elem, categoryId, topicId }); } else { setFailedCache(normalize(url), true); } @@ -92,13 +96,13 @@ function loadNext(ajax) { .finally(() => { timeout = later(() => loadNext(ajax), timeoutMs); if (removeLoading) { - $elem.removeClass(LOADING_ONEBOX_CSS_CLASS); - $elem.data("onebox-loaded"); + elem.classList.remove(LOADING_ONEBOX_CSS_CLASS); + elem.dataset.oneboxLoaded = ""; } }); } -// Perform a lookup of a onebox based an anchor $element. +// Perform a lookup of a onebox based an anchor element. // It will insert a loading indicator and remove it when the loading is complete or fails. export function load({ elem, @@ -109,13 +113,13 @@ export function load({ offline = false, synchronous = false, }) { - const $elem = $(elem); - // If the onebox has loaded or is loading, return - if ($elem.data("onebox-loaded")) { + + if (elem.dataset.oneboxLoaded) { return; } - if ($elem.hasClass(LOADING_ONEBOX_CSS_CLASS)) { + + if (elem.classList.contains(LOADING_ONEBOX_CSS_CLASS)) { return; } @@ -124,9 +128,9 @@ export function load({ // Unless we're forcing a refresh... if (!refresh) { // If we have it in our cache, return it. - const cached = localCache[normalize(url)]; + const cached = lookupCache(url); if (cached) { - return cached.prop("outerHTML"); + return cached; } // If the request failed, don't do anything @@ -141,10 +145,10 @@ export function load({ } // Add the loading CSS class - $elem.addClass(LOADING_ONEBOX_CSS_CLASS); + elem.classList.add(LOADING_ONEBOX_CSS_CLASS); // Add to the loading queue - loadingQueue.push({ url, refresh, $elem, categoryId, topicId }); + loadingQueue.push({ url, refresh, elem, categoryId, topicId }); // Load next url in queue if (synchronous) {