mirror of
https://github.com/discourse/discourse.git
synced 2024-11-28 18:04:38 +08:00
a1e77aa2ed
Previously, the site setting was only effective on the client side of things. Once the site setting was been reached, all oneboxes are not rendered. This commit changes it such that the site setting is respected both on the client and server side. The first N oneboxes are rendered and once the limit has been reached, subsequent oneboxes will not be rendered.
146 lines
3.5 KiB
JavaScript
146 lines
3.5 KiB
JavaScript
let timeout;
|
|
const loadingQueue = [];
|
|
let localCache = {};
|
|
let failedCache = {};
|
|
|
|
export const LOADING_ONEBOX_CSS_CLASS = "loading-onebox";
|
|
|
|
export function resetCache() {
|
|
loadingQueue.clear();
|
|
localCache = {};
|
|
failedCache = {};
|
|
}
|
|
|
|
function resolveSize(img) {
|
|
$(img).addClass("size-resolved");
|
|
|
|
if (img.width > 0 && img.width === img.height) {
|
|
$(img).addClass("onebox-avatar");
|
|
}
|
|
}
|
|
|
|
// Detect square images and apply smaller onebox-avatar class
|
|
function applySquareGenericOnebox($elem, normalizedUrl) {
|
|
if (!$elem.hasClass("whitelistedgeneric")) {
|
|
return;
|
|
}
|
|
|
|
let $img = $elem.find(".onebox-body img.thumbnail");
|
|
let img = $img[0];
|
|
|
|
// already resolved... skip
|
|
if ($img.length !== 1 || $img.hasClass("size-resolved")) {
|
|
return;
|
|
}
|
|
|
|
if (img.complete) {
|
|
resolveSize(img, $elem, normalizedUrl);
|
|
} else {
|
|
$img.on("load.onebox", () => {
|
|
resolveSize(img, $elem, normalizedUrl);
|
|
$img.off("load.onebox");
|
|
});
|
|
}
|
|
}
|
|
|
|
function loadNext(ajax) {
|
|
if (loadingQueue.length === 0) {
|
|
timeout = null;
|
|
return;
|
|
}
|
|
|
|
let timeoutMs = 150;
|
|
let removeLoading = true;
|
|
const { url, refresh, $elem, categoryId, topicId } = loadingQueue.shift();
|
|
|
|
// Retrieve the onebox
|
|
return ajax("/onebox", {
|
|
dataType: "html",
|
|
data: {
|
|
url,
|
|
refresh,
|
|
category_id: categoryId,
|
|
topic_id: topicId
|
|
},
|
|
cache: true
|
|
})
|
|
.then(
|
|
html => {
|
|
let $html = $(html);
|
|
localCache[normalize(url)] = $html;
|
|
$elem.replaceWith($html);
|
|
applySquareGenericOnebox($html, normalize(url));
|
|
},
|
|
result => {
|
|
if (result && result.jqXHR && result.jqXHR.status === 429) {
|
|
timeoutMs = 2000;
|
|
removeLoading = false;
|
|
loadingQueue.unshift({ url, refresh, $elem, categoryId, topicId });
|
|
} else {
|
|
failedCache[normalize(url)] = true;
|
|
}
|
|
}
|
|
)
|
|
.finally(() => {
|
|
timeout = Ember.run.later(() => loadNext(ajax), timeoutMs);
|
|
if (removeLoading) {
|
|
$elem.removeClass(LOADING_ONEBOX_CSS_CLASS);
|
|
$elem.data("onebox-loaded");
|
|
}
|
|
});
|
|
}
|
|
|
|
// 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,
|
|
refresh = true,
|
|
ajax,
|
|
synchronous = false,
|
|
categoryId,
|
|
topicId
|
|
}) {
|
|
const $elem = $(elem);
|
|
|
|
// If the onebox has loaded or is loading, return
|
|
if ($elem.data("onebox-loaded")) return;
|
|
if ($elem.hasClass(LOADING_ONEBOX_CSS_CLASS)) return;
|
|
|
|
const url = elem.href;
|
|
|
|
// Unless we're forcing a refresh...
|
|
if (!refresh) {
|
|
// If we have it in our cache, return it.
|
|
const cached = localCache[normalize(url)];
|
|
if (cached) return cached.prop("outerHTML");
|
|
|
|
// If the request failed, don't do anything
|
|
const failed = failedCache[normalize(url)];
|
|
if (failed) return;
|
|
}
|
|
|
|
// Add the loading CSS class
|
|
$elem.addClass(LOADING_ONEBOX_CSS_CLASS);
|
|
|
|
// Add to the loading queue
|
|
loadingQueue.push({ url, refresh, $elem, categoryId, topicId });
|
|
|
|
// Load next url in queue
|
|
if (synchronous) {
|
|
return loadNext(ajax);
|
|
} else {
|
|
timeout = timeout || Ember.run.later(() => loadNext(ajax), 150);
|
|
}
|
|
}
|
|
|
|
// Sometimes jQuery will return URLs with trailing slashes when the
|
|
// `href` didn't have them.
|
|
function normalize(url) {
|
|
return url.replace(/\/$/, "");
|
|
}
|
|
|
|
export function lookupCache(url) {
|
|
const cached = localCache[normalize(url)];
|
|
return cached && cached.prop("outerHTML");
|
|
}
|