From 4c54d2c4ffa6b384021054c053961cc898f330e2 Mon Sep 17 00:00:00 2001 From: Andrew Brehaut Date: Mon, 23 Sep 2019 20:25:00 +1200 Subject: [PATCH] 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. --- Mac/MainWindow/Detail/styleSheet.css | 43 +++++++++++++++++++++++++--- Shared/Article Rendering/newsfoot.js | 22 +++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/Mac/MainWindow/Detail/styleSheet.css b/Mac/MainWindow/Detail/styleSheet.css index e47f1255b..c71b65ea6 100644 --- a/Mac/MainWindow/Detail/styleSheet.css +++ b/Mac/MainWindow/Detail/styleSheet.css @@ -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; } diff --git a/Shared/Article Rendering/newsfoot.js b/Shared/Article Rendering/newsfoot.js index a599bb1c7..38815ab00 100644 --- a/Shared/Article Rendering/newsfoot.js +++ b/Shared/Article Rendering/newsfoot.js @@ -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)`; } }