This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6
Joffrey JAFFEUX e28a2735bc
FIX: correctly defines data-attributes used by local-dates (#14418)
This was previously relying on data-* being allowed by other initialisers which could cause bugs if local dates ends up being used in other contexts.
2021-09-22 16:49:45 +02:00

175 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { parseBBCodeTag } from "pretty-text/engines/discourse-markdown/bbcode-block";
const timezoneNames = moment.tz.names();
function addLocalDate(buffer, matches, state) {
let token;
let config = {
date: null,
time: null,
timezone: null,
format: null,
timezones: null,
displayedTimezone: null,
countdown: null,
};
const matchString = matches[1].replace(/||„|“|«|»|”/g, '"');
let parsed = parseBBCodeTag(
"[date date" + matchString + "]",
0,
matchString.length + 11
);
config.date = parsed.attrs.date;
config.format = parsed.attrs.format;
config.calendar = parsed.attrs.calendar;
config.time = parsed.attrs.time;
config.timezone = (parsed.attrs.timezone || "").trim();
config.recurring = parsed.attrs.recurring;
config.timezones = parsed.attrs.timezones;
config.displayedTimezone = parsed.attrs.displayedTimezone;
config.countdown = parsed.attrs.countdown;
token = new state.Token("span_open", "span", 1);
token.attrs = [["data-date", state.md.utils.escapeHtml(config.date)]];
if (!config.date.match(/\d{4}-\d{2}-\d{2}/)) {
closeBuffer(buffer, state, moment.invalid().format());
return;
}
if (config.time && !config.time.match(/\d{2}:\d{2}(?::\d{2})?/)) {
closeBuffer(buffer, state, moment.invalid().format());
return;
}
let dateTime = config.date;
if (config.time) {
token.attrs.push(["data-time", state.md.utils.escapeHtml(config.time)]);
dateTime = `${dateTime} ${config.time}`;
}
if (!moment(dateTime).isValid()) {
closeBuffer(buffer, state, moment.invalid().format());
return;
}
token.attrs.push(["class", "discourse-local-date"]);
if (config.format) {
token.attrs.push(["data-format", state.md.utils.escapeHtml(config.format)]);
}
if (config.countdown) {
token.attrs.push([
"data-countdown",
state.md.utils.escapeHtml(config.countdown),
]);
}
if (config.calendar) {
token.attrs.push([
"data-calendar",
state.md.utils.escapeHtml(config.calendar),
]);
}
if (
config.displayedTimezone &&
timezoneNames.includes(config.displayedTimezone)
) {
token.attrs.push([
"data-displayed-timezone",
state.md.utils.escapeHtml(config.displayedTimezone),
]);
}
if (config.timezones) {
const timezones = config.timezones.split("|").filter((timezone) => {
return timezoneNames.includes(timezone);
});
token.attrs.push([
"data-timezones",
state.md.utils.escapeHtml(timezones.join("|")),
]);
}
if (config.timezone && timezoneNames.includes(config.timezone)) {
token.attrs.push([
"data-timezone",
state.md.utils.escapeHtml(config.timezone),
]);
dateTime = moment.tz(dateTime, config.timezone);
} else {
dateTime = moment.utc(dateTime);
}
if (config.recurring) {
token.attrs.push([
"data-recurring",
state.md.utils.escapeHtml(config.recurring),
]);
}
buffer.push(token);
const formattedDateTime = dateTime
.tz("Etc/UTC")
.format(
state.md.options.discourse.datesEmailFormat || moment.defaultFormat
);
token.attrs.push(["data-email-preview", `${formattedDateTime} UTC`]);
closeBuffer(buffer, state, dateTime.utc().format(config.format));
}
function closeBuffer(buffer, state, text) {
let token;
token = new state.Token("text", "", 0);
token.content = text;
buffer.push(token);
token = new state.Token("span_close", "span", -1);
buffer.push(token);
}
export function setup(helper) {
helper.allowList([
"span.discourse-local-date",
"span[aria-label]",
"span[data-date]",
"span[data-time]",
"span[data-format]",
"span[data-countdown]",
"span[data-calendar]",
"span[data-displayed-timezone]",
"span[data-timezone]",
"span[data-timezones]",
"span[data-recurring]",
"span[data-email-preview]",
]);
helper.registerOptions((opts, siteSettings) => {
opts.datesEmailFormat = siteSettings.discourse_local_dates_email_format;
opts.features[
"discourse-local-dates"
] = !!siteSettings.discourse_local_dates_enabled;
});
helper.registerPlugin((md) => {
const rule = {
matcher: /\[date(=.+?)\]/,
onMatch: addLocalDate,
};
md.core.textPostProcess.ruler.push("discourse-local-dates", rule);
});
}