FEATURE: Allow dismissing tooltips by clicking their button (#26668)
Also: fixes typos, updates tests, and moves the tooltip element into document.body
This commit is contained in:
parent
285acf0b86
commit
27d9b53bac
|
@ -29,47 +29,49 @@ function applyInlineFootnotes(elem) {
|
|||
}
|
||||
|
||||
function buildTooltip() {
|
||||
let html = `
|
||||
const template = document.createElement("template");
|
||||
template.innerHTML = `
|
||||
<div id="footnote-tooltip" role="tooltip">
|
||||
<div class="footnote-tooltip-content"></div>
|
||||
<div id="arrow" data-popper-arrow></div>
|
||||
</div>
|
||||
`;
|
||||
`.trim();
|
||||
|
||||
let template = document.createElement("template");
|
||||
html = html.trim();
|
||||
template.innerHTML = html;
|
||||
return template.content.firstChild;
|
||||
}
|
||||
|
||||
function footNoteEventHandler(event) {
|
||||
inlineFootnotePopper?.destroy();
|
||||
|
||||
function footnoteEventHandler(event) {
|
||||
const tooltip = document.getElementById("footnote-tooltip");
|
||||
const displayedFootnoteId = tooltip?.dataset.footnoteId;
|
||||
const expandableFootnote = event.target;
|
||||
const footnoteId = expandableFootnote.dataset.footnoteId;
|
||||
|
||||
// reset state by hidding tooltip, it handles "click outside"
|
||||
// allowing to hide the tooltip when you click anywhere else
|
||||
inlineFootnotePopper?.destroy();
|
||||
tooltip?.removeAttribute("data-show");
|
||||
tooltip?.removeAttribute("data-footnote-id");
|
||||
|
||||
// if we didn't actually click a footnote button, exit early
|
||||
if (!event.target.classList.contains("expand-footnote")) {
|
||||
// dismissing the tooltip by clicking outside
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// append footnote to tooltip body
|
||||
const expandableFootnote = event.target;
|
||||
const cooked = expandableFootnote.closest(".cooked");
|
||||
const footnoteId = expandableFootnote.dataset.footnoteId;
|
||||
const footnoteContent = tooltip.querySelector(".footnote-tooltip-content");
|
||||
let newContent = cooked.querySelector(footnoteId);
|
||||
if (displayedFootnoteId === footnoteId) {
|
||||
// dismissing the tooltip by clicking the footnote button
|
||||
return;
|
||||
}
|
||||
|
||||
// append footnote to tooltip body
|
||||
const footnoteContent = tooltip.querySelector(".footnote-tooltip-content");
|
||||
const cooked = expandableFootnote.closest(".cooked");
|
||||
const newContent = cooked.querySelector(footnoteId);
|
||||
footnoteContent.innerHTML = newContent.innerHTML;
|
||||
|
||||
// display tooltip
|
||||
tooltip.dataset.show = "";
|
||||
tooltip.dataset.footnoteId = footnoteId;
|
||||
|
||||
// setup popper
|
||||
inlineFootnotePopper?.destroy();
|
||||
|
@ -104,9 +106,8 @@ export default {
|
|||
return;
|
||||
}
|
||||
|
||||
document.documentElement.append(buildTooltip());
|
||||
|
||||
window.addEventListener("click", footNoteEventHandler);
|
||||
document.body.append(buildTooltip());
|
||||
window.addEventListener("click", footnoteEventHandler);
|
||||
|
||||
withPluginApi("0.8.9", (api) => {
|
||||
api.decorateCookedElement((elem) => applyInlineFootnotes(elem), {
|
||||
|
@ -115,16 +116,18 @@ export default {
|
|||
});
|
||||
|
||||
api.onPageChange(() => {
|
||||
document
|
||||
.getElementById("footnote-tooltip")
|
||||
?.removeAttribute("data-show");
|
||||
inlineFootnotePopper?.destroy();
|
||||
|
||||
const tooltip = document.getElementById("footnote-tooltip");
|
||||
tooltip?.removeAttribute("data-show");
|
||||
tooltip?.removeAttribute("data-footnote-id");
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
teardown() {
|
||||
inlineFootnotePopper?.destroy();
|
||||
window.removeEventListener("click", footNoteEventHandler);
|
||||
window.removeEventListener("click", footnoteEventHandler);
|
||||
document.getElementById("footnote-tooltip")?.remove();
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import { click, visit } from "@ember/test-helpers";
|
||||
import { test } from "qunit";
|
||||
import topicFixtures from "discourse/tests/fixtures/topic";
|
||||
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
|
||||
import { acceptance } from "discourse/tests/helpers/qunit-helpers";
|
||||
import { cloneJSON } from "discourse-common/lib/object";
|
||||
|
||||
acceptance("Discourse Foonote Plugin", function (needs) {
|
||||
needs.user();
|
||||
|
||||
acceptance("Discourse Footnote Plugin", function (needs) {
|
||||
needs.settings({
|
||||
display_footnotes_inline: true,
|
||||
});
|
||||
|
@ -28,30 +26,47 @@ acceptance("Discourse Foonote Plugin", function (needs) {
|
|||
});
|
||||
});
|
||||
|
||||
test("displays the foonote on click", async function (assert) {
|
||||
await visit("/t/45");
|
||||
test("displays the footnote on click", async function (assert) {
|
||||
await visit("/t/-/45");
|
||||
|
||||
const tooltip = document.getElementById("footnote-tooltip");
|
||||
assert.ok(exists(tooltip));
|
||||
assert.dom("#footnote-tooltip", document.body).exists();
|
||||
|
||||
// open
|
||||
await click(".expand-footnote");
|
||||
assert.equal(
|
||||
tooltip.querySelector(".footnote-tooltip-content").textContent.trim(),
|
||||
"consectetur adipiscing elit ↩︎"
|
||||
);
|
||||
assert
|
||||
.dom(".footnote-tooltip-content", document.body)
|
||||
.hasText("consectetur adipiscing elit ↩︎");
|
||||
assert.dom("#footnote-tooltip", document.body).hasAttribute("data-show");
|
||||
|
||||
// close by clicking outside
|
||||
await click(document.body);
|
||||
assert
|
||||
.dom("#footnote-tooltip", document.body)
|
||||
.doesNotHaveAttribute("data-show");
|
||||
|
||||
// open again
|
||||
await click(".expand-footnote");
|
||||
assert
|
||||
.dom(".footnote-tooltip-content", document.body)
|
||||
.hasText("consectetur adipiscing elit ↩︎");
|
||||
assert.dom("#footnote-tooltip", document.body).hasAttribute("data-show");
|
||||
|
||||
// close by clicking the button
|
||||
await click(".expand-footnote");
|
||||
assert
|
||||
.dom("#footnote-tooltip", document.body)
|
||||
.doesNotHaveAttribute("data-show");
|
||||
});
|
||||
|
||||
test("clicking a second footnote with same name works", async function (assert) {
|
||||
await visit("/t/45");
|
||||
await visit("/t/-/45");
|
||||
|
||||
const tooltip = document.getElementById("footnote-tooltip");
|
||||
assert.ok(exists(tooltip));
|
||||
assert.dom("#footnote-tooltip", document.body).exists();
|
||||
|
||||
await click(".second .expand-footnote");
|
||||
|
||||
assert.equal(
|
||||
tooltip.querySelector(".footnote-tooltip-content").textContent.trim(),
|
||||
"consectetur adipiscing elit ↩︎"
|
||||
);
|
||||
assert
|
||||
.dom(".footnote-tooltip-content", document.body)
|
||||
.hasText("consectetur adipiscing elit ↩︎");
|
||||
assert.dom("#footnote-tooltip", document.body).hasAttribute("data-show");
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue