WIP: Allow kbd tag chat
This commit is contained in:
parent
88a972c61b
commit
6a0669e316
@ -7,9 +7,11 @@ const ALLOWLIST_REGEX = /([^\[]+)(\[([^=]+)(=(.*))?\])?/;
|
||||
export default class AllowLister {
|
||||
constructor(options) {
|
||||
this._enabled = { default: true };
|
||||
this._allowedHrefSchemes = (options && options.allowedHrefSchemes) || [];
|
||||
this._allowedIframes = (options && options.allowedIframes) || [];
|
||||
this._rawFeatures = [["default", DEFAULT_LIST]];
|
||||
this._allowedHrefSchemes = options?.allowedHrefSchemes || [];
|
||||
this._allowedIframes = options?.allowedIframes || [];
|
||||
this._rawFeatures = [
|
||||
["default", options?.htmlInlineAllowListOverride || DEFAULT_LIST],
|
||||
];
|
||||
|
||||
this._cache = null;
|
||||
|
||||
|
||||
@ -323,6 +323,16 @@ function buildCustomMarkdownCookFunction(engineOpts, defaultEngineOpts) {
|
||||
if (engineOpts.featuresOverride !== undefined) {
|
||||
overrideMarkdownFeatures(featureConfig, engineOpts.featuresOverride);
|
||||
}
|
||||
|
||||
// since the AllowLister is what decides which inline HTML to allow,
|
||||
// we need to completely recreate the sanitizer with a new AllowLister
|
||||
// with the override for this to work
|
||||
if (engineOpts.htmlInlineAllowListOverride !== undefined) {
|
||||
newOpts.discourse.htmlInlineAllowListOverride =
|
||||
engineOpts.htmlInlineAllowListOverride;
|
||||
newOpts.sanitizer = createSanitizer(newOpts);
|
||||
}
|
||||
|
||||
newOpts.discourse.features = featureConfig;
|
||||
|
||||
const markdownitOpts = {
|
||||
@ -401,18 +411,22 @@ function setupMarkdownEngine(opts, featureConfig) {
|
||||
opts.setup = true;
|
||||
|
||||
if (!opts.discourse.sanitizer || !opts.sanitizer) {
|
||||
const allowLister = new AllowLister(opts.discourse);
|
||||
|
||||
opts.allowListed.forEach(([feature, info]) => {
|
||||
allowLister.allowListFeature(feature, info);
|
||||
});
|
||||
|
||||
opts.sanitizer = opts.discourse.sanitizer = !!opts.discourse.sanitize
|
||||
? (a) => sanitize(a, allowLister)
|
||||
: (a) => a;
|
||||
opts.sanitizer = createSanitizer(opts);
|
||||
}
|
||||
}
|
||||
|
||||
function createSanitizer(opts) {
|
||||
const allowLister = new AllowLister(opts.discourse);
|
||||
|
||||
opts.allowListed.forEach(([feature, info]) => {
|
||||
allowLister.allowListFeature(feature, info);
|
||||
});
|
||||
|
||||
return (opts.discourse.sanitizer = !!opts.discourse.sanitize
|
||||
? (a) => sanitize(a, allowLister)
|
||||
: (a) => a);
|
||||
}
|
||||
|
||||
function unhoistForCooked(hoisted, cooked) {
|
||||
const keys = Object.keys(hoisted);
|
||||
if (keys.length) {
|
||||
|
||||
@ -49,6 +49,7 @@ export function buildOptions(state) {
|
||||
hashtagTypesInPriorityOrder,
|
||||
hashtagIcons,
|
||||
hashtagLookup,
|
||||
htmlInlineAllowListOverride,
|
||||
} = state;
|
||||
|
||||
let features = {};
|
||||
@ -94,6 +95,7 @@ export function buildOptions(state) {
|
||||
hashtagTypesInPriorityOrder,
|
||||
hashtagIcons,
|
||||
hashtagLookup,
|
||||
htmlInlineAllowListOverride,
|
||||
};
|
||||
|
||||
// note, this will mutate options due to the way the API is designed
|
||||
|
||||
@ -211,6 +211,10 @@ module PrettyText
|
||||
|
||||
buffer << "__optInput.topicId = #{opts[:topic_id].to_i};\n" if opts[:topic_id]
|
||||
|
||||
if opts[:html_inline_allow_list_override]
|
||||
buffer << "__optInput.htmlInlineAllowListOverride = #{opts[:html_inline_allow_list_override].to_json};\n"
|
||||
end
|
||||
|
||||
if opts[:force_quote_link]
|
||||
buffer << "__optInput.forceQuoteLink = #{opts[:force_quote_link]};\n"
|
||||
end
|
||||
|
||||
@ -144,6 +144,8 @@ class ChatMessage < ActiveRecord::Base
|
||||
where("cooked_version <> ? or cooked_version IS NULL", BAKED_VERSION)
|
||||
end
|
||||
|
||||
HTML_INLINE_ALLOW_LIST_OVERRIDE = %w[kbd]
|
||||
|
||||
MARKDOWN_FEATURES = %w[
|
||||
anchor
|
||||
bbcode-block
|
||||
@ -183,6 +185,7 @@ class ChatMessage < ActiveRecord::Base
|
||||
strikethrough
|
||||
blockquote
|
||||
emphasis
|
||||
html_inline
|
||||
]
|
||||
|
||||
def self.cook(message, opts = {})
|
||||
@ -200,6 +203,7 @@ class ChatMessage < ActiveRecord::Base
|
||||
force_quote_link: true,
|
||||
user_id: opts[:user_id],
|
||||
hashtag_context: "chat-composer",
|
||||
html_inline_allow_list_override: HTML_INLINE_ALLOW_LIST_OVERRIDE,
|
||||
)
|
||||
|
||||
result =
|
||||
|
||||
@ -251,6 +251,8 @@ export function setup(helper) {
|
||||
hashtagTypesInPriorityOrder:
|
||||
chatAdditionalOpts.hashtag_configurations["chat-composer"],
|
||||
hashtagIcons: opts.discourse.hashtagIcons,
|
||||
htmlInlineAllowListOverride:
|
||||
chatAdditionalOpts.html_inline_allow_list_override,
|
||||
},
|
||||
(customCookFn) => {
|
||||
customMarkdownCookFn = customCookFn;
|
||||
|
||||
@ -739,6 +739,7 @@ after_initialize do
|
||||
limited_pretty_text_features: ChatMessage::MARKDOWN_FEATURES,
|
||||
limited_pretty_text_markdown_rules: ChatMessage::MARKDOWN_IT_RULES,
|
||||
hashtag_configurations: HashtagAutocompleteService.contexts_with_ordered_types,
|
||||
html_inline_allow_list_override: ChatMessage::HTML_INLINE_ALLOW_LIST_OVERRIDE,
|
||||
}
|
||||
|
||||
register_user_destroyer_on_content_deletion_callback(
|
||||
|
||||
Reference in New Issue
Block a user