make the 🔗 button copy branch links to clipboard
to accomplish this, I generalised emoji tooltips to a shared Tooltip class. in the long run I'd like to transform all existing `title=""` tooltips into these for stylistic consistency with the rest of the website, but this is good enough for now. I also ended up cleaning up some old code from before the /b rework.
This commit is contained in:
parent
c537eb844f
commit
74baa61122
8 changed files with 208 additions and 138 deletions
|
@ -1,103 +1,21 @@
|
|||
// Emoji zoom-in functionality.
|
||||
|
||||
import { addSpell } from "treehouse/spells.js";
|
||||
import { attachTooltip, Tooltip } from "treehouse/overlay.js";
|
||||
|
||||
class EmojiTooltip extends HTMLElement {
|
||||
constructor(emoji, element, { onClosed }) {
|
||||
super();
|
||||
function createEmojiTooltip(emoji, element) {
|
||||
let tooltip = new Tooltip(element, "bottom");
|
||||
tooltip.classList.add("tooltip-emoji");
|
||||
|
||||
this.emoji = emoji;
|
||||
this.emojiElement = element;
|
||||
this.onClosed = onClosed;
|
||||
}
|
||||
let img = tooltip.appendChild(new Image());
|
||||
img.src = element.src;
|
||||
|
||||
connectedCallback() {
|
||||
this.role = "tooltip";
|
||||
let description = tooltip.appendChild(document.createElement("p"));
|
||||
description.textContent = emoji.emojiName;
|
||||
|
||||
this.image = new Image();
|
||||
this.image.src = this.emojiElement.src;
|
||||
|
||||
this.description = document.createElement("p");
|
||||
this.description.textContent = `${this.emoji.emojiName}`;
|
||||
|
||||
let emojiBoundingBox = this.emojiElement.getBoundingClientRect();
|
||||
this.style.left = `${emojiBoundingBox.left + emojiBoundingBox.width / 2}px`;
|
||||
this.style.top = `calc(${emojiBoundingBox.top}px + 1.5em)`;
|
||||
|
||||
this.fullyOpaque = false;
|
||||
this.addEventListener("transitionend", event => {
|
||||
if (event.propertyName == "opacity") {
|
||||
this.fullyOpaque = !this.fullyOpaque;
|
||||
if (!this.fullyOpaque) {
|
||||
this.onClosed();
|
||||
}
|
||||
}
|
||||
});
|
||||
// Timeout is zero because we just want to execute this later, to be definitely sure
|
||||
// the transition plays out.
|
||||
setTimeout(() => this.classList.add("transitioned-in"), 0);
|
||||
|
||||
this.appendChild(this.image);
|
||||
this.appendChild(this.description);
|
||||
}
|
||||
|
||||
close() {
|
||||
this.classList.remove("transitioned-in");
|
||||
}
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
customElements.define("th-emoji-tooltip", EmojiTooltip);
|
||||
|
||||
let emojiTooltips = null;
|
||||
|
||||
class EmojiTooltips extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.tooltips = new Set();
|
||||
this.abortController = new AbortController();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
emojiTooltips = this;
|
||||
|
||||
addEventListener(
|
||||
"wheel",
|
||||
event => emojiTooltips.closeTooltips(event),
|
||||
{ signal: this.abortController.signal },
|
||||
);
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
this.abortController.abort();
|
||||
}
|
||||
|
||||
openTooltip(emoji, element) {
|
||||
let tooltip = new EmojiTooltip(emoji, element, {
|
||||
onClosed: () => {
|
||||
this.removeChild(tooltip);
|
||||
this.tooltips.delete(tooltip);
|
||||
},
|
||||
});
|
||||
|
||||
this.appendChild(tooltip);
|
||||
this.tooltips.add(tooltip);
|
||||
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
closeTooltip(tooltip) {
|
||||
tooltip.close();
|
||||
}
|
||||
|
||||
closeTooltips() {
|
||||
for (let tooltip of this.tooltips) {
|
||||
tooltip.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("th-emoji-tooltips", EmojiTooltips);
|
||||
|
||||
class Emoji {
|
||||
constructor(element) {
|
||||
this.emojiName = element.title;
|
||||
|
@ -106,18 +24,7 @@ class Emoji {
|
|||
// so remove the title.
|
||||
element.title = "";
|
||||
|
||||
element.addEventListener("mouseenter", () => this.openTooltip(element));
|
||||
element.addEventListener("mouseleave", () => this.closeTooltip());
|
||||
element.addEventListener("scroll", () => this.closeTooltip());
|
||||
}
|
||||
|
||||
openTooltip(element) {
|
||||
this.tooltip = emojiTooltips.openTooltip(this, element);
|
||||
}
|
||||
|
||||
closeTooltip() {
|
||||
emojiTooltips.closeTooltip(this.tooltip);
|
||||
this.tooltip = null;
|
||||
attachTooltip(element, () => createEmojiTooltip(this, element)).showOnHover();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue