FIX: Replace links to removed uploads from reviewables with a placeholder (#10180)

This commit is contained in:
Bianca Nenciu 2020-07-10 17:57:06 +03:00 committed by GitHub
parent 4b0d86d8d3
commit 275b748016
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 61 additions and 16 deletions

View File

@ -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);
}
});

View File

@ -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>

View File

@ -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
);

View File

@ -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..."