2019-05-29 09:00:25 +08:00
|
|
|
// add image to array if src has an upload
|
|
|
|
function addImage(uploads, token) {
|
|
|
|
if (token.attrs) {
|
|
|
|
for (let i = 0; i < token.attrs.length; i++) {
|
|
|
|
if (token.attrs[i][1].indexOf("upload://") === 0) {
|
|
|
|
uploads.push([token, i]);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function rule(state) {
|
|
|
|
let uploads = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < state.tokens.length; i++) {
|
|
|
|
let blockToken = state.tokens[i];
|
|
|
|
|
|
|
|
if (blockToken.tag === "img" || blockToken.tag === "a") {
|
|
|
|
addImage(uploads, blockToken);
|
|
|
|
}
|
|
|
|
|
2019-11-13 04:32:37 +08:00
|
|
|
if (!blockToken.children) continue;
|
2019-05-29 09:00:25 +08:00
|
|
|
|
|
|
|
for (let j = 0; j < blockToken.children.length; j++) {
|
|
|
|
let token = blockToken.children[j];
|
2019-11-13 04:32:37 +08:00
|
|
|
|
|
|
|
if (token.tag === "img" || token.tag === "a") addImage(uploads, token);
|
2019-05-29 09:00:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (uploads.length > 0) {
|
|
|
|
let srcList = uploads.map(([token, srcIndex]) => token.attrs[srcIndex][1]);
|
|
|
|
let lookup = state.md.options.discourse.lookupUploadUrls;
|
|
|
|
let longUrls = (lookup && lookup(srcList)) || {};
|
|
|
|
|
|
|
|
uploads.forEach(([token, srcIndex]) => {
|
|
|
|
let origSrc = token.attrs[srcIndex][1];
|
|
|
|
let mapped = longUrls[origSrc];
|
|
|
|
|
|
|
|
switch (token.tag) {
|
|
|
|
case "img":
|
|
|
|
if (mapped) {
|
|
|
|
token.attrs[srcIndex][1] = mapped.url;
|
2019-06-11 09:15:45 +08:00
|
|
|
token.attrs.push(["data-base62-sha1", mapped.base62_sha1]);
|
2019-05-29 09:00:25 +08:00
|
|
|
} else {
|
2020-01-23 07:41:39 +08:00
|
|
|
// no point putting a transparent .png for audio/video
|
|
|
|
if (token.content.match(/\|video|\|audio/)) {
|
|
|
|
token.attrs[srcIndex][1] = state.md.options.discourse.getURL(
|
|
|
|
"/404"
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
token.attrs[srcIndex][1] = state.md.options.discourse.getURL(
|
|
|
|
"/images/transparent.png"
|
|
|
|
);
|
|
|
|
}
|
2019-05-29 09:00:25 +08:00
|
|
|
|
|
|
|
token.attrs.push(["data-orig-src", origSrc]);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case "a":
|
|
|
|
if (mapped) {
|
2020-03-04 07:11:08 +08:00
|
|
|
// when secure media is enabled we want the full /secure-media-uploads/
|
|
|
|
// url to take advantage of access control security
|
|
|
|
if (
|
|
|
|
state.md.options.discourse.limitedSiteSettings.secureMedia &&
|
|
|
|
mapped.url.indexOf("secure-media-uploads") > -1
|
|
|
|
) {
|
|
|
|
token.attrs[srcIndex][1] = mapped.url;
|
|
|
|
} else {
|
|
|
|
token.attrs[srcIndex][1] = mapped.short_path;
|
|
|
|
}
|
2019-05-29 09:00:25 +08:00
|
|
|
} else {
|
|
|
|
token.attrs[srcIndex][1] = state.md.options.discourse.getURL(
|
|
|
|
"/404"
|
|
|
|
);
|
|
|
|
|
|
|
|
token.attrs.push(["data-orig-href", origSrc]);
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function setup(helper) {
|
|
|
|
const opts = helper.getOptions();
|
|
|
|
if (opts.previewing) helper.whiteList(["img.resizable"]);
|
2019-06-11 09:15:45 +08:00
|
|
|
|
|
|
|
helper.whiteList([
|
|
|
|
"img[data-orig-src]",
|
|
|
|
"img[data-base62-sha1]",
|
|
|
|
"a[data-orig-href]"
|
|
|
|
]);
|
2019-05-29 09:00:25 +08:00
|
|
|
|
|
|
|
helper.registerPlugin(md => {
|
|
|
|
md.core.ruler.push("upload-protocol", rule);
|
|
|
|
});
|
|
|
|
}
|