FIX: Replace links to removed uploads from reviewables with a placeholder (#10180)
This commit is contained in:
parent
4b0d86d8d3
commit
275b748016
|
@ -1,8 +1,8 @@
|
|||
import Component from "@ember/component";
|
||||
import { cookAsync } from "discourse/lib/text";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { resolveAllShortUrls } from "pretty-text/upload-short-url";
|
||||
import { afterRender } from "discourse-common/utils/decorators";
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
import { cookAsync } from "discourse/lib/text";
|
||||
import { resolveAllShortUrls } from "pretty-text/upload-short-url";
|
||||
|
||||
const CookText = Component.extend({
|
||||
cooked: null,
|
||||
|
@ -17,7 +17,7 @@ const CookText = Component.extend({
|
|||
|
||||
@afterRender
|
||||
_resolveUrls() {
|
||||
resolveAllShortUrls(ajax, this.siteSettings, this.element);
|
||||
resolveAllShortUrls(ajax, this.siteSettings, this.element, this.opts);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -18,9 +18,7 @@
|
|||
<div class="post-contents">
|
||||
{{reviewable-post-header reviewable=reviewable createdBy=reviewable.created_by tagName=""}}
|
||||
|
||||
<div class="post-body">
|
||||
{{cook-text reviewable.payload.raw}}
|
||||
</div>
|
||||
{{cook-text reviewable.payload.raw class="post-body" opts=(hash removeMissing=true)}}
|
||||
|
||||
{{yield}}
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { debounce } from "@ember/runloop";
|
||||
import I18n from "I18n";
|
||||
|
||||
let _cache = {};
|
||||
|
||||
export function lookupCachedUploadUrl(shortUrl) {
|
||||
|
@ -43,7 +45,13 @@ export function resetCache() {
|
|||
_cache = {};
|
||||
}
|
||||
|
||||
function retrieveCachedUrl(upload, siteSettings, dataAttribute, callback) {
|
||||
function retrieveCachedUrl(
|
||||
upload,
|
||||
siteSettings,
|
||||
dataAttribute,
|
||||
opts,
|
||||
callback
|
||||
) {
|
||||
const cachedUpload = lookupCachedUploadUrl(
|
||||
upload.getAttribute(`data-${dataAttribute}`)
|
||||
);
|
||||
|
@ -53,6 +61,42 @@ function retrieveCachedUrl(upload, siteSettings, dataAttribute, callback) {
|
|||
upload.removeAttribute(`data-${dataAttribute}`);
|
||||
if (url !== MISSING) {
|
||||
callback(url);
|
||||
} else if (opts && opts.removeMissing) {
|
||||
const style = getComputedStyle(document.body);
|
||||
const canvas = document.createElement("canvas");
|
||||
canvas.width = upload.width;
|
||||
canvas.height = upload.height;
|
||||
|
||||
const context = canvas.getContext("2d");
|
||||
|
||||
// Draw background
|
||||
context.fillStyle = getComputedStyle(document.body).backgroundColor;
|
||||
context.strokeRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
// Draw border
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = getComputedStyle(document.body).color;
|
||||
context.strokeRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
let fontSize = 25;
|
||||
const text = I18n.t("image_removed");
|
||||
|
||||
// Fill text size to fit the canvas
|
||||
let textSize;
|
||||
do {
|
||||
--fontSize;
|
||||
context.font = `${fontSize}px ${style.fontFamily}`;
|
||||
textSize = context.measureText(text);
|
||||
} while (textSize.width > canvas.width);
|
||||
|
||||
context.fillStyle = getComputedStyle(document.body).color;
|
||||
context.fillText(
|
||||
text,
|
||||
(canvas.width - textSize.width) / 2,
|
||||
(canvas.height + fontSize) / 2
|
||||
);
|
||||
|
||||
upload.parentNode.replaceChild(canvas, upload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,23 +123,23 @@ function getAttributeBasedUrl(dataAttribute, cachedUpload, siteSettings) {
|
|||
return cachedUpload.short_path;
|
||||
}
|
||||
|
||||
function _loadCachedShortUrls(uploadElements, siteSettings) {
|
||||
function _loadCachedShortUrls(uploadElements, siteSettings, opts) {
|
||||
uploadElements.forEach(upload => {
|
||||
switch (upload.tagName) {
|
||||
case "A":
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-href", url => {
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-href", opts, url => {
|
||||
upload.href = url;
|
||||
});
|
||||
|
||||
break;
|
||||
case "IMG":
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-src", url => {
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-src", opts, url => {
|
||||
upload.src = url;
|
||||
});
|
||||
|
||||
break;
|
||||
case "SOURCE": // video/audio tag > source tag
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-src", url => {
|
||||
retrieveCachedUrl(upload, siteSettings, "orig-src", opts, url => {
|
||||
if (url.startsWith(`//${window.location.host}`)) {
|
||||
let hostRegex = new RegExp("//" + window.location.host, "g");
|
||||
url = url.replace(hostRegex, "");
|
||||
|
@ -120,7 +164,7 @@ function _loadCachedShortUrls(uploadElements, siteSettings) {
|
|||
});
|
||||
}
|
||||
|
||||
function _loadShortUrls(uploads, ajax, siteSettings) {
|
||||
function _loadShortUrls(uploads, ajax, siteSettings, opts) {
|
||||
let urls = [...uploads].map(upload => {
|
||||
return (
|
||||
upload.getAttribute("data-orig-src") ||
|
||||
|
@ -129,17 +173,17 @@ function _loadShortUrls(uploads, ajax, siteSettings) {
|
|||
});
|
||||
|
||||
return lookupUncachedUploadUrls(urls, ajax).then(() =>
|
||||
_loadCachedShortUrls(uploads, siteSettings)
|
||||
_loadCachedShortUrls(uploads, siteSettings, opts)
|
||||
);
|
||||
}
|
||||
|
||||
export function resolveAllShortUrls(ajax, siteSettings, scope) {
|
||||
export function resolveAllShortUrls(ajax, siteSettings, scope, opts) {
|
||||
const attributes =
|
||||
"img[data-orig-src], a[data-orig-href], source[data-orig-src]";
|
||||
let shortUploadElements = scope.querySelectorAll(attributes);
|
||||
|
||||
if (shortUploadElements.length > 0) {
|
||||
_loadCachedShortUrls(shortUploadElements, siteSettings);
|
||||
_loadCachedShortUrls(shortUploadElements, siteSettings, opts);
|
||||
|
||||
shortUploadElements = scope.querySelectorAll(attributes);
|
||||
if (shortUploadElements.length > 0) {
|
||||
|
@ -150,6 +194,7 @@ export function resolveAllShortUrls(ajax, siteSettings, scope) {
|
|||
shortUploadElements,
|
||||
ajax,
|
||||
siteSettings,
|
||||
opts,
|
||||
450,
|
||||
true
|
||||
);
|
||||
|
|
|
@ -3401,6 +3401,8 @@ en:
|
|||
safe_mode:
|
||||
enabled: "Safe mode is enabled, to exit safe mode close this browser window"
|
||||
|
||||
image_removed: "(image removed)"
|
||||
|
||||
# This section is exported to the javascript for i18n in the admin section
|
||||
admin_js:
|
||||
type_to_filter: "type to filter..."
|
||||
|
|
Loading…
Reference in New Issue