#554 newsfoot.js and css are included in the page
These changes are the bare minimum required to get footnotes to appear and function on the article page. * The newsfoot.js script now wraps everything in an IIFE to prevent bleed to other scripts * Stylesheets are included in the main stylesheet, with the colors extracted out into separate selectors Currently missing the arrow pointing to the footnote link, and no consideration exists for mobile presentation beyond a max-width: 100vh on the footnote popover.
This commit is contained in:
parent
20f8fe91df
commit
5fea81971b
@ -3,6 +3,7 @@
|
||||
<style>
|
||||
</style>
|
||||
<script src="main.js"></script>
|
||||
<script src="newsfoot.js" async="async"></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
|
@ -181,3 +181,51 @@ img[src*="feedblitz"],
|
||||
img[src*="share-buttons"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
/* Newsfoot specific styles. Structural styles come first, theme styles second */
|
||||
.newsfoot-footnote-container {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
.newsfoot-footnote-popover {
|
||||
position: absolute;
|
||||
display: block;
|
||||
padding: 0em 1em;
|
||||
margin: 1em;
|
||||
left: -11em;
|
||||
right: -11em;
|
||||
max-width: none;
|
||||
border-radius: 0.3em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
a.footnote {
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
padding: 0.05em 0.75em;
|
||||
border-radius: 1em;
|
||||
min-width: 1em;
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
line-height: 1em;
|
||||
position:relative;
|
||||
top: -0.1em;
|
||||
}
|
||||
|
||||
/* light / default */
|
||||
.newsfoot-footnote-popover {
|
||||
background: #fafafa;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.5);
|
||||
color: black;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
body a.footnote,
|
||||
body a.footnote:visited {
|
||||
background: #aaa;
|
||||
color: white;
|
||||
transition: background-color 200ms ease-out;
|
||||
}
|
||||
a.footnote:hover {
|
||||
background: #666;
|
||||
transition: background-color 200ms ease-out;
|
||||
}
|
||||
|
@ -1,22 +1,22 @@
|
||||
(function () {
|
||||
// @ts-check
|
||||
/** @param {Node | null} el */
|
||||
const remove = (el) => { if (el) el.parentElement.removeChild(el) };
|
||||
|
||||
// @ts-check
|
||||
/** @param {Node | null} el */
|
||||
const remove = (el) => { if (el) el.parentElement.removeChild(el) };
|
||||
const stripPx = (s) => +s.slice(0, -2);
|
||||
|
||||
const stripPx = (s) => +s.slice(0, -2);
|
||||
|
||||
/** @param {string} tag
|
||||
/** @param {string} tag
|
||||
* @param {string} cls
|
||||
* @returns HTMLElement
|
||||
*/
|
||||
function newEl(tag, cls) {
|
||||
function newEl(tag, cls) {
|
||||
const el = document.createElement(tag);
|
||||
el.classList.add(cls);
|
||||
return el;
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {<T extends any[]>(fn: (...args: T) => void, t: number) => ((...args: T) => void)} */
|
||||
function debounce(f, ms) {
|
||||
/** @type {<T extends any[]>(fn: (...args: T) => void, t: number) => ((...args: T) => void)} */
|
||||
function debounce(f, ms) {
|
||||
let t = Date.now();
|
||||
return (...args) => {
|
||||
const now = Date.now();
|
||||
@ -24,23 +24,23 @@ function debounce(f, ms) {
|
||||
t = now;
|
||||
f(...args);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const clsPrefix = "newsfoot-footnote-";
|
||||
const CONTAINER_CLS = `${clsPrefix}container`;
|
||||
const POPOVER_CLS = `${clsPrefix}popover`;
|
||||
const clsPrefix = "newsfoot-footnote-";
|
||||
const CONTAINER_CLS = `${clsPrefix}container`;
|
||||
const POPOVER_CLS = `${clsPrefix}popover`;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @param {Node} content
|
||||
* @returns {HTMLElement}
|
||||
*/
|
||||
function footnoteMarkup(content) {
|
||||
function footnoteMarkup(content) {
|
||||
const popover = newEl("div", POPOVER_CLS);
|
||||
popover.appendChild(content);
|
||||
return popover;
|
||||
}
|
||||
}
|
||||
|
||||
class Footnote {
|
||||
class Footnote {
|
||||
/**
|
||||
* @param {Node} content
|
||||
* @param {Element} fnref
|
||||
@ -89,31 +89,34 @@ class Footnote {
|
||||
}
|
||||
this.popover.style.transform = `translate(${offset}px)`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {Node} n */
|
||||
function fragFromContents(n) {
|
||||
/** @param {Node} n */
|
||||
function fragFromContents(n) {
|
||||
const frag = document.createDocumentFragment();
|
||||
n.childNodes.forEach((ch) => frag.appendChild(ch));
|
||||
return frag;
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {HTMLAnchorElement} a */
|
||||
function installContainer(a) {
|
||||
/** @param {HTMLAnchorElement} a */
|
||||
function installContainer(a) {
|
||||
if (!a.parentElement.matches(`.${CONTAINER_CLS}`)) {
|
||||
const container = newEl("div", CONTAINER_CLS);
|
||||
a.parentElement.insertBefore(container, a);
|
||||
container.appendChild(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("click", (ev) => {
|
||||
document.addEventListener("click", (ev) => {
|
||||
if (!(ev.target && ev.target instanceof HTMLAnchorElement)) return;
|
||||
if (!ev.target.matches(".footnote")) return;
|
||||
ev.preventDefault();
|
||||
|
||||
const content = document.querySelector(`[id='${ev.target.hash.substring(1)}']`).cloneNode(true);
|
||||
if (content instanceof HTMLElement) remove(content.querySelector(".reversefootnote"));
|
||||
if (content instanceof HTMLElement) {
|
||||
remove(content.querySelector(".reversefootnote"));
|
||||
}
|
||||
installContainer(ev.target);
|
||||
void new Footnote(fragFromContents(content), ev.target);
|
||||
});
|
||||
}());
|
||||
|
Loading…
x
Reference in New Issue
Block a user