diff --git a/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6 b/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6
index 53d8d04dcc4..108fae47934 100644
--- a/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6
+++ b/plugins/discourse-local-dates/assets/javascripts/initializers/discourse-local-dates.js.es6
@@ -1,10 +1,72 @@
+import deprecated from "discourse-common/lib/deprecated";
+import { getOwner } from "discourse-common/lib/get-owner";
+import { hidePopover, showPopover } from "discourse/lib/d-popover";
import LocalDateBuilder from "../lib/local-date-builder";
-import showModal from "discourse/lib/show-modal";
import { withPluginApi } from "discourse/lib/plugin-api";
+import showModal from "discourse/lib/show-modal";
+
+export function applyLocalDates(dates, siteSettings) {
+ if (!siteSettings.discourse_local_dates_enabled) {
+ return;
+ }
+
+ const currentUserTZ = moment.tz.guess();
+
+ dates.forEach((element) => {
+ const opts = buildOptionsFromElement(element, siteSettings);
+
+ const localDateBuilder = new LocalDateBuilder(opts, currentUserTZ).build();
+ element.innerText = "";
+ element.insertAdjacentHTML(
+ "beforeend",
+ `
+
+ ${localDateBuilder.formated}
+ `
+ );
+ element.setAttribute("aria-label", localDateBuilder.textPreview);
+
+ const classes = ["cooked-date"];
+ if (localDateBuilder.pastEvent) {
+ classes.push("past");
+ }
+ element.classList.add(...classes);
+ });
+}
+
+function buildOptionsFromElement(element, siteSettings) {
+ const opts = {};
+ const dataset = element.dataset;
+ opts.time = dataset.time;
+ opts.date = dataset.date;
+ opts.recurring = dataset.recurring;
+ opts.timezones = (
+ dataset.timezones ||
+ siteSettings.discourse_local_dates_default_timezones ||
+ "Etc/UTC"
+ )
+ .split("|")
+ .filter(Boolean);
+ opts.timezone = dataset.timezone;
+ opts.calendar = (dataset.calendar || "on") === "on";
+ opts.displayedTimezone = dataset.displayedTimezone;
+ opts.format = dataset.format || (opts.time ? "LLL" : "LL");
+ opts.countdown = dataset.countdown;
+ return opts;
+}
function initializeDiscourseLocalDates(api) {
- api.decorateCooked(
- ($elem) => $(".discourse-local-date", $elem).applyLocalDates(),
+ const siteSettings = api.container.lookup("site-settings:main");
+
+ api.decorateCookedElement(
+ (elem) => {
+ applyLocalDates(
+ elem.querySelectorAll(".discourse-local-date"),
+ siteSettings
+ );
+ },
{ id: "discourse-local-date" }
);
@@ -30,87 +92,84 @@ function initializeDiscourseLocalDates(api) {
});
}
+function buildHtmlPreview(element, siteSettings) {
+ const opts = buildOptionsFromElement(element, siteSettings);
+ const localDateBuilder = new LocalDateBuilder(
+ opts,
+ moment.tz.guess()
+ ).build();
+
+ const htmlPreviews = localDateBuilder.previews.map((preview) => {
+ const previewNode = document.createElement("div");
+ previewNode.classList.add("preview");
+ if (preview.current) {
+ previewNode.classList.add("current");
+ }
+
+ const timezoneNode = document.createElement("span");
+ timezoneNode.classList.add("timezone");
+ timezoneNode.innerText = preview.timezone;
+ previewNode.appendChild(timezoneNode);
+
+ const dateTimeNode = document.createElement("span");
+ dateTimeNode.classList.add("date-time");
+ dateTimeNode.innerText = preview.formated;
+ previewNode.appendChild(dateTimeNode);
+
+ return previewNode;
+ });
+
+ const previewsNode = document.createElement("div");
+ previewsNode.classList.add("locale-dates-previews");
+ htmlPreviews.forEach((htmlPreview) => previewsNode.appendChild(htmlPreview));
+
+ return previewsNode.outerHTML;
+}
+
export default {
name: "discourse-local-dates",
+ showDatePopover(event) {
+ const siteSettings = getOwner(this).lookup("site-settings:main");
+
+ if (event?.target?.classList?.contains("discourse-local-date")) {
+ showPopover(event, {
+ htmlContent: buildHtmlPreview(event.target, siteSettings),
+ });
+ }
+ },
+
+ hideDatePopover(event) {
+ if (event?.target?.classList?.contains("discourse-local-date")) {
+ hidePopover(event);
+ }
+ },
+
initialize(container) {
+ const router = container.lookup("router:main");
+ router.on("routeWillChange", hidePopover);
+
+ window.addEventListener("click", this.showDatePopover);
+ window.addEventListener("mouseover", this.showDatePopover);
+ window.addEventListener("mouseout", this.hideDatePopover);
+
const siteSettings = container.lookup("site-settings:main");
if (siteSettings.discourse_local_dates_enabled) {
- const currentUserTZ = moment.tz.guess();
-
$.fn.applyLocalDates = function () {
- return this.each(function () {
- const opts = {};
- const dataset = this.dataset;
- opts.time = dataset.time;
- opts.date = dataset.date;
- opts.recurring = dataset.recurring;
- opts.timezones = (
- dataset.timezones ||
- siteSettings.discourse_local_dates_default_timezones ||
- "Etc/UTC"
- )
- .split("|")
- .filter(Boolean);
- opts.timezone = dataset.timezone;
- opts.calendar = (dataset.calendar || "on") === "on";
- opts.displayedTimezone = dataset.displayedTimezone;
- opts.format = dataset.format || (opts.time ? "LLL" : "LL");
- opts.countdown = dataset.countdown;
+ deprecated(
+ "`$.applyLocalDates()` is deprecated, import and use `applyLocalDates()` instead."
+ );
- const localDateBuilder = new LocalDateBuilder(
- opts,
- currentUserTZ
- ).build();
-
- const htmlPreviews = localDateBuilder.previews.map((preview) => {
- const previewNode = document.createElement("div");
- previewNode.classList.add("preview");
- if (preview.current) {
- previewNode.classList.add("current");
- }
-
- const timezoneNode = document.createElement("span");
- timezoneNode.classList.add("timezone");
- timezoneNode.innerText = preview.timezone;
- previewNode.appendChild(timezoneNode);
-
- const dateTimeNode = document.createElement("span");
- dateTimeNode.classList.add("date-time");
- dateTimeNode.innerText = preview.formated;
- previewNode.appendChild(dateTimeNode);
-
- return previewNode;
- });
-
- const previewsNode = document.createElement("div");
- previewsNode.classList.add("locale-dates-previews");
- htmlPreviews.forEach((htmlPreview) =>
- previewsNode.appendChild(htmlPreview)
- );
-
- this.innerText = "";
- this.insertAdjacentHTML(
- "beforeend",
- `
-
- ${localDateBuilder.formated}
- `
- );
- this.setAttribute("aria-label", localDateBuilder.textPreview);
- this.dataset.htmlTooltip = previewsNode.outerHTML;
-
- const classes = ["cooked-date"];
- if (localDateBuilder.pastEvent) {
- classes.push("past");
- }
- this.classList.add(...classes);
- });
+ return applyLocalDates(this.toArray(), siteSettings);
};
withPluginApi("0.8.8", initializeDiscourseLocalDates);
}
},
+
+ teardown() {
+ window.removeEventListener("click", this.showDatePopover);
+ window.removeEventListener("mouseover", this.showDatePopover);
+ window.removeEventListener("mouseout", this.hideDatePopover);
+ },
};
diff --git a/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6 b/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6
index 69ecd7f75a4..7dee925e88f 100644
--- a/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6
+++ b/plugins/discourse-local-dates/assets/javascripts/lib/discourse-markdown/discourse-local-dates.js.es6
@@ -140,11 +140,7 @@ function closeBuffer(buffer, state, text) {
}
export function setup(helper) {
- helper.allowList([
- "span.discourse-local-date",
- "span[data-*]",
- "span[aria-label]",
- ]);
+ helper.allowList(["span.discourse-local-date", "span[aria-label]"]);
helper.registerOptions((opts, siteSettings) => {
opts.datesEmailFormat = siteSettings.discourse_local_dates_email_format;
diff --git a/plugins/discourse-local-dates/assets/stylesheets/common/discourse-local-dates.scss b/plugins/discourse-local-dates/assets/stylesheets/common/discourse-local-dates.scss
index 08436eb090b..3c7db2310ae 100644
--- a/plugins/discourse-local-dates/assets/stylesheets/common/discourse-local-dates.scss
+++ b/plugins/discourse-local-dates/assets/stylesheets/common/discourse-local-dates.scss
@@ -1,4 +1,8 @@
.discourse-local-date {
+ > * {
+ pointer-events: none;
+ }
+
&.cooked-date {
color: var(--primary);
cursor: pointer;