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() {
|
function buildTooltip() {
|
||||||
let html = `
|
const template = document.createElement("template");
|
||||||
|
template.innerHTML = `
|
||||||
<div id="footnote-tooltip" role="tooltip">
|
<div id="footnote-tooltip" role="tooltip">
|
||||||
<div class="footnote-tooltip-content"></div>
|
<div class="footnote-tooltip-content"></div>
|
||||||
<div id="arrow" data-popper-arrow></div>
|
<div id="arrow" data-popper-arrow></div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`.trim();
|
||||||
|
|
||||||
let template = document.createElement("template");
|
|
||||||
html = html.trim();
|
|
||||||
template.innerHTML = html;
|
|
||||||
return template.content.firstChild;
|
return template.content.firstChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
function footNoteEventHandler(event) {
|
function footnoteEventHandler(event) {
|
||||||
inlineFootnotePopper?.destroy();
|
|
||||||
|
|
||||||
const tooltip = document.getElementById("footnote-tooltip");
|
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"
|
inlineFootnotePopper?.destroy();
|
||||||
// allowing to hide the tooltip when you click anywhere else
|
|
||||||
tooltip?.removeAttribute("data-show");
|
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")) {
|
if (!event.target.classList.contains("expand-footnote")) {
|
||||||
|
// dismissing the tooltip by clicking outside
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
// append footnote to tooltip body
|
if (displayedFootnoteId === footnoteId) {
|
||||||
const expandableFootnote = event.target;
|
// dismissing the tooltip by clicking the footnote button
|
||||||
const cooked = expandableFootnote.closest(".cooked");
|
return;
|
||||||
const footnoteId = expandableFootnote.dataset.footnoteId;
|
}
|
||||||
const footnoteContent = tooltip.querySelector(".footnote-tooltip-content");
|
|
||||||
let newContent = cooked.querySelector(footnoteId);
|
|
||||||
|
|
||||||
|
// 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;
|
footnoteContent.innerHTML = newContent.innerHTML;
|
||||||
|
|
||||||
// display tooltip
|
// display tooltip
|
||||||
tooltip.dataset.show = "";
|
tooltip.dataset.show = "";
|
||||||
|
tooltip.dataset.footnoteId = footnoteId;
|
||||||
|
|
||||||
// setup popper
|
// setup popper
|
||||||
inlineFootnotePopper?.destroy();
|
inlineFootnotePopper?.destroy();
|
||||||
|
@ -104,9 +106,8 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
document.documentElement.append(buildTooltip());
|
document.body.append(buildTooltip());
|
||||||
|
window.addEventListener("click", footnoteEventHandler);
|
||||||
window.addEventListener("click", footNoteEventHandler);
|
|
||||||
|
|
||||||
withPluginApi("0.8.9", (api) => {
|
withPluginApi("0.8.9", (api) => {
|
||||||
api.decorateCookedElement((elem) => applyInlineFootnotes(elem), {
|
api.decorateCookedElement((elem) => applyInlineFootnotes(elem), {
|
||||||
|
@ -115,16 +116,18 @@ export default {
|
||||||
});
|
});
|
||||||
|
|
||||||
api.onPageChange(() => {
|
api.onPageChange(() => {
|
||||||
document
|
inlineFootnotePopper?.destroy();
|
||||||
.getElementById("footnote-tooltip")
|
|
||||||
?.removeAttribute("data-show");
|
const tooltip = document.getElementById("footnote-tooltip");
|
||||||
|
tooltip?.removeAttribute("data-show");
|
||||||
|
tooltip?.removeAttribute("data-footnote-id");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
teardown() {
|
teardown() {
|
||||||
inlineFootnotePopper?.destroy();
|
inlineFootnotePopper?.destroy();
|
||||||
window.removeEventListener("click", footNoteEventHandler);
|
window.removeEventListener("click", footnoteEventHandler);
|
||||||
document.getElementById("footnote-tooltip")?.remove();
|
document.getElementById("footnote-tooltip")?.remove();
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
import { click, visit } from "@ember/test-helpers";
|
import { click, visit } from "@ember/test-helpers";
|
||||||
import { test } from "qunit";
|
import { test } from "qunit";
|
||||||
import topicFixtures from "discourse/tests/fixtures/topic";
|
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";
|
import { cloneJSON } from "discourse-common/lib/object";
|
||||||
|
|
||||||
acceptance("Discourse Foonote Plugin", function (needs) {
|
acceptance("Discourse Footnote Plugin", function (needs) {
|
||||||
needs.user();
|
|
||||||
|
|
||||||
needs.settings({
|
needs.settings({
|
||||||
display_footnotes_inline: true,
|
display_footnotes_inline: true,
|
||||||
});
|
});
|
||||||
|
@ -28,30 +26,47 @@ acceptance("Discourse Foonote Plugin", function (needs) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test("displays the foonote on click", async function (assert) {
|
test("displays the footnote on click", async function (assert) {
|
||||||
await visit("/t/45");
|
await visit("/t/-/45");
|
||||||
|
|
||||||
const tooltip = document.getElementById("footnote-tooltip");
|
assert.dom("#footnote-tooltip", document.body).exists();
|
||||||
assert.ok(exists(tooltip));
|
|
||||||
|
|
||||||
|
// open
|
||||||
await click(".expand-footnote");
|
await click(".expand-footnote");
|
||||||
assert.equal(
|
assert
|
||||||
tooltip.querySelector(".footnote-tooltip-content").textContent.trim(),
|
.dom(".footnote-tooltip-content", document.body)
|
||||||
"consectetur adipiscing elit ↩︎"
|
.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) {
|
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.dom("#footnote-tooltip", document.body).exists();
|
||||||
assert.ok(exists(tooltip));
|
|
||||||
|
|
||||||
await click(".second .expand-footnote");
|
await click(".second .expand-footnote");
|
||||||
|
assert
|
||||||
assert.equal(
|
.dom(".footnote-tooltip-content", document.body)
|
||||||
tooltip.querySelector(".footnote-tooltip-content").textContent.trim(),
|
.hasText("consectetur adipiscing elit ↩︎");
|
||||||
"consectetur adipiscing elit ↩︎"
|
assert.dom("#footnote-tooltip", document.body).hasAttribute("data-show");
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue