mirror of
https://github.com/discourse/discourse.git
synced 2025-02-11 22:04:58 +00:00
* FEATURE: Bundle discourse-spoiler-alert plugin into core
Formerly https://github.com/discourse/discourse-spoiler-alert
* DEV: Switch to new addComposerToolbarPopupMenuOption plugin API
`api.addToolbarPopupMenuOptionsCallback` has been deprecated in 913fd3a7b392b492f6344102577960a6eada00ce
This commit was just added to the plugin, so adding it here.
49f86ba72e
102 lines
2.3 KiB
JavaScript
102 lines
2.3 KiB
JavaScript
import I18n from "discourse-i18n";
|
|
|
|
const INTERACTIVE_SELECTOR = [
|
|
"a",
|
|
"area",
|
|
"audio",
|
|
"button",
|
|
"details",
|
|
"embed",
|
|
"iframe",
|
|
"img.animated",
|
|
"input",
|
|
"map",
|
|
"object",
|
|
"option",
|
|
"portal",
|
|
"select",
|
|
"textarea",
|
|
"track",
|
|
"video",
|
|
".lightbox",
|
|
].join(", ");
|
|
|
|
function isInteractive(event) {
|
|
return event.defaultPrevented || event.target.closest(INTERACTIVE_SELECTOR);
|
|
}
|
|
|
|
function noTextSelected() {
|
|
return window.getSelection() + "" === "";
|
|
}
|
|
|
|
function setAttributes(element, attributes) {
|
|
Object.entries(attributes).forEach(([key, value]) => {
|
|
if (value === null) {
|
|
element.removeAttribute(key);
|
|
} else {
|
|
element.setAttribute(key, value);
|
|
}
|
|
});
|
|
}
|
|
|
|
function _setSpoilerHidden(element) {
|
|
const spoilerHiddenAttributes = {
|
|
role: "button",
|
|
tabindex: "0",
|
|
"data-spoiler-state": "blurred",
|
|
"aria-expanded": false,
|
|
"aria-label": I18n.t("spoiler.label.show"),
|
|
"aria-live": "polite",
|
|
};
|
|
|
|
// Set default attributes & classes on spoiler
|
|
setAttributes(element, spoilerHiddenAttributes);
|
|
element.classList.add("spoiler-blurred");
|
|
|
|
// Set aria-hidden for all children of the spoiler
|
|
Array.from(element.children).forEach((e) => {
|
|
e.setAttribute("aria-hidden", true);
|
|
});
|
|
}
|
|
|
|
function _setSpoilerVisible(element) {
|
|
const spoilerVisibleAttributes = {
|
|
"data-spoiler-state": "revealed",
|
|
"aria-expanded": true,
|
|
"aria-label": null,
|
|
role: null,
|
|
};
|
|
|
|
// Set attributes & classes for when spoiler is visible
|
|
setAttributes(element, spoilerVisibleAttributes);
|
|
element.classList.remove("spoiler-blurred");
|
|
|
|
// Remove aria-hidden for all children of the spoiler when visible
|
|
Array.from(element.children).forEach((e) => {
|
|
e.removeAttribute("aria-hidden");
|
|
});
|
|
}
|
|
|
|
function toggleSpoiler(event, element) {
|
|
if (element.getAttribute("data-spoiler-state") === "blurred") {
|
|
_setSpoilerVisible(element);
|
|
event.preventDefault();
|
|
} else if (!isInteractive(event) && noTextSelected()) {
|
|
_setSpoilerHidden(element);
|
|
}
|
|
}
|
|
|
|
export default function applySpoiler(element) {
|
|
_setSpoilerHidden(element);
|
|
|
|
element.addEventListener("click", (event) => {
|
|
toggleSpoiler(event, element);
|
|
});
|
|
|
|
element.addEventListener("keydown", (event) => {
|
|
if (event.key === "Enter") {
|
|
toggleSpoiler(event, element);
|
|
}
|
|
});
|
|
}
|