110 lines
3.0 KiB
JavaScript
110 lines
3.0 KiB
JavaScript
import PrettyText, { buildOptions } from "pretty-text/pretty-text";
|
|
import { buildEmojiUrl, performEmojiUnescape } from "pretty-text/emoji";
|
|
import AllowLister from "pretty-text/allow-lister";
|
|
import { Promise } from "rsvp";
|
|
import Session from "discourse/models/session";
|
|
import { formatUsername } from "discourse/lib/utilities";
|
|
import { getURLWithCDN } from "discourse-common/lib/get-url";
|
|
import { helperContext } from "discourse-common/lib/helpers";
|
|
import { htmlSafe } from "@ember/template";
|
|
import loadScript from "discourse/lib/load-script";
|
|
import { sanitize as textSanitize } from "pretty-text/sanitizer";
|
|
|
|
function getOpts(opts) {
|
|
let context = helperContext();
|
|
|
|
opts = Object.assign(
|
|
{
|
|
getURL: getURLWithCDN,
|
|
currentUser: context.currentUser,
|
|
censoredRegexp: context.site.censored_regexp,
|
|
customEmojiTranslation: context.site.custom_emoji_translation,
|
|
siteSettings: context.siteSettings,
|
|
formatUsername,
|
|
},
|
|
opts
|
|
);
|
|
|
|
return buildOptions(opts);
|
|
}
|
|
|
|
// Use this to easily create a pretty text instance with proper options
|
|
export function cook(text, options) {
|
|
return htmlSafe(createPrettyText(options).cook(text));
|
|
}
|
|
|
|
// everything should eventually move to async API and this should be renamed
|
|
// cook
|
|
export function cookAsync(text, options) {
|
|
return loadMarkdownIt().then(() => cook(text, options));
|
|
}
|
|
|
|
// Warm up pretty text with a set of options and return a function
|
|
// which can be used to cook without rebuilding prettytext every time
|
|
export function generateCookFunction(options) {
|
|
return loadMarkdownIt().then(() => {
|
|
const prettyText = createPrettyText(options);
|
|
return (text) => prettyText.cook(text);
|
|
});
|
|
}
|
|
|
|
export function sanitize(text, options) {
|
|
return textSanitize(text, new AllowLister(options));
|
|
}
|
|
|
|
export function sanitizeAsync(text, options) {
|
|
return loadMarkdownIt().then(() => {
|
|
return createPrettyText(options).sanitize(text);
|
|
});
|
|
}
|
|
|
|
function loadMarkdownIt() {
|
|
return new Promise((resolve) => {
|
|
let markdownItURL = Session.currentProp("markdownItURL");
|
|
if (markdownItURL) {
|
|
loadScript(markdownItURL)
|
|
.then(() => resolve())
|
|
.catch((e) => {
|
|
// eslint-disable-next-line no-console
|
|
console.error(e);
|
|
});
|
|
} else {
|
|
resolve();
|
|
}
|
|
});
|
|
}
|
|
|
|
function createPrettyText(options) {
|
|
return new PrettyText(getOpts(options));
|
|
}
|
|
|
|
function emojiOptions() {
|
|
let siteSettings = helperContext().siteSettings;
|
|
if (!siteSettings.enable_emoji) {
|
|
return;
|
|
}
|
|
|
|
return {
|
|
getURL: (url) => getURLWithCDN(url),
|
|
emojiSet: siteSettings.emoji_set,
|
|
enableEmojiShortcuts: siteSettings.enable_emoji_shortcuts,
|
|
inlineEmoji: siteSettings.enable_inline_emoji_translation,
|
|
};
|
|
}
|
|
|
|
export function emojiUnescape(string, options) {
|
|
const opts = emojiOptions();
|
|
if (opts) {
|
|
return performEmojiUnescape(string, Object.assign(opts, options || {}));
|
|
} else {
|
|
return string;
|
|
}
|
|
}
|
|
|
|
export function emojiUrlFor(code) {
|
|
const opts = emojiOptions();
|
|
if (opts) {
|
|
return buildEmojiUrl(code, opts);
|
|
}
|
|
}
|