544 adds and positions the arrow on the popover bubble

An arrow element is now inserted into the dom to orient the bubble to the fnref
element that opened it. This is offset in the opposite direction to the bubble
if the bubble overhangs one side or the other.

Additionally, if both sides overhang then no positioning takes place. This
is the first step towards supporting more narrow windows and mobile clients.
This commit is contained in:
Andrew Brehaut 2019-09-23 20:25:00 +12:00
parent af5d510c80
commit 4c54d2c4ff
2 changed files with 57 additions and 8 deletions

View File

@ -195,10 +195,36 @@ img[src*="share-buttons"] {
margin: 1em;
left: -11em;
right: -11em;
top: 0.75em;
max-width: none;
border-radius: 0.3em;
box-sizing: border-box;
}
.newsfoot-footnote-popover-arrow {
content: '';
display: block;
width: 1em;
position: absolute;
top: -0.5em;
left: calc(50% - 0.5em);
height: 1em !important;
transform: rotate(45deg);
z-index:0;
}
.newsfoot-footnote-popover-inner {
border-radius: calc(0.3em - 1px);
padding: 1em;
position: relative;
z-index: 1;
}
.newsfoot-footnote-popover-inner :first-child {
margin-top: 0;
}
.newsfoot-footnote-popover-inner :last-child {
margin-bottom: 0;
}
.newsfoot-footnote-popover .reversefootnote {
display: none;
}
@ -217,18 +243,27 @@ a.footnote {
/* light / default */
.newsfoot-footnote-popover {
background: #fafafa;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
background: #ccc;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5), 0 3px 6px rgba(0, 0, 0, 0.25);
color: black;
padding: 1px;
}
.newsfoot-footnote-popover-arrow {
background: #fafafa;
border: 1px solid #ccc;
}
.newsfoot-footnote-popover-inner {
background: #fafafa;
}
body a.footnote,
body a.footnote:visited {
body a.footnote:visited,
.newsfoot-footnote-popover + a.footnote:hover {
background: #aaa;
color: white;
transition: background-color 200ms ease-out;
}
a.footnote:hover {
a.footnote:hover,
.newsfoot-footnote-popover + a.footnote {
background: #666;
transition: background-color 200ms ease-out;
}

View File

@ -29,6 +29,8 @@
const clsPrefix = "newsfoot-footnote-";
const CONTAINER_CLS = `${clsPrefix}container`;
const POPOVER_CLS = `${clsPrefix}popover`;
const POPOVER_INNER_CLS = `${clsPrefix}popover-inner`;
const POPOVER_ARROW_CLS = `${clsPrefix}popover-arrow`;
/**
* @param {Node} content
@ -36,7 +38,11 @@
*/
function footnoteMarkup(content) {
const popover = newEl("div", POPOVER_CLS);
popover.appendChild(content);
const arrow = newEl("div", POPOVER_ARROW_CLS);
const inner = newEl("div", POPOVER_INNER_CLS);
popover.appendChild(inner);
popover.appendChild(arrow);
inner.appendChild(content);
return popover;
}
@ -49,13 +55,17 @@
this.popover = footnoteMarkup(content);
this.style = window.getComputedStyle(this.popover);
this.fnref = fnref;
this.fnref.closest(`.${CONTAINER_CLS}`).appendChild(this.popover);
this.fnref.closest(`.${CONTAINER_CLS}`).insertBefore(this.popover, fnref);
this.reposition();
/** @type {(ev:MouseEvent) => void} */
this.clickoutHandler = (ev) => {
if (!(ev.target instanceof Element)) return;
if (ev.target.closest(`.${POPOVER_CLS}`) === this.popover) return;
if (ev.target === this.fnref) {
ev.stopPropagation();
ev.preventDefault();
}
this.cleanup();
}
document.addEventListener("click", this.clickoutHandler, {capture: true});
@ -80,14 +90,18 @@
const marginLeft = stripPx(this.style.marginLeft);
const marginRight = stripPx(this.style.marginRight);
const rightOverhang = center + popoverHalfWidth + marginRight > window.innerWidth;
const leftOverhang = center - (popoverHalfWidth + marginLeft) < 0;
let offset = 0;
if (center + popoverHalfWidth + marginRight > window.innerWidth) {
if (leftOverhang && !rightOverhang) {
offset = -((center + popoverHalfWidth + marginRight) - window.innerWidth);
}
else if (center - (popoverHalfWidth + marginLeft) < 0) {
else if (rightOverhang && !leftOverhang) {
offset = (popoverHalfWidth + marginLeft) - center;
}
this.popover.style.transform = `translate(${offset}px)`;
this.popover.querySelector(`.${POPOVER_ARROW_CLS}`).style.transform = `translate(${-offset}px) rotate(45deg)`;
}
}