Multiple fixes to styles and polyfills

This commit is contained in:
Ludwig Schubert
2017-10-23 11:10:03 -07:00
parent 1a4cd694cd
commit c742b36be6
27 changed files with 339 additions and 151 deletions
+78 -41
View File
@@ -1,54 +1,91 @@
/* Flag that we're being loaded */
if (window.distillLoaded) {
throw new Error('Distill Template is getting loaded more than once, aborting!');
} else {
window.distillLoaded = true;
}
import { Controller } from './controller';
/* Static styles and other modules */
import { makeStyleTag } from './styles/styles';
makeStyleTag(document);
/* Transforms */
import { makeStyleTag } from './styles/styles';
import { Polyfills, polyfills } from './helpers/polyfills';
/* Components */
import { Abstract } from './components/d-abstract';
import { Appendix } from './components/d-appendix';
import { Article } from './components/d-article';
import { Bibliography } from './components/d-bibliography';
import { Byline } from './components/d-byline';
import { Cite } from './components/d-cite';
import { CitationList } from './components/d-citation-list';
import { Code } from './components/d-code';
import { Footnote } from './components/d-footnote';
import { FootnoteList } from './components/d-footnote-list';
import { FrontMatter } from './components/d-front-matter';
import { Title } from './components/d-title';
import { DMath } from './components/d-math';
import { References } from './components/d-references';
import { TOC } from './components/d-toc';
import { Figure } from './components/d-figure';
import { Interstitial } from './components/d-interstitial';
import { Slider } from './ui/d-slider';
const components = [
Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
Footnote, FootnoteList, FrontMatter, Title, DMath, References, TOC, Figure,
Slider, Interstitial
];
import { Abstract } from './components/d-abstract';
import { Appendix } from './components/d-appendix';
import { Article } from './components/d-article';
import { Bibliography } from './components/d-bibliography';
import { Byline } from './components/d-byline';
import { Cite } from './components/d-cite';
import { CitationList } from './components/d-citation-list';
import { Code } from './components/d-code';
import { Footnote } from './components/d-footnote';
import { FootnoteList } from './components/d-footnote-list';
import { FrontMatter } from './components/d-front-matter';
import { Title } from './components/d-title';
import { DMath } from './components/d-math';
import { References } from './components/d-references';
import { TOC } from './components/d-toc';
import { Figure } from './components/d-figure';
import { Interstitial } from './components/d-interstitial';
import { Slider } from './ui/d-slider';
/* Distill website specific components */
import { DistillHeader } from './distill-components/distill-header';
import { DistillHeader } from './distill-components/distill-header';
import { DistillAppendix } from './distill-components/distill-appendix';
import { DistillFooter } from './distill-components/distill-footer';
import { DistillFooter } from './distill-components/distill-footer';
const distillComponents = [
DistillHeader, DistillAppendix, DistillFooter,
];
const distillMain = function() {
function defineComponents() {
if (window.distillRunlevel < 1) {
throw new Error('Insufficient Runlevel for Distill Template!');
}
/* 1. Flag that we're being loaded */
if ('distillTemplateIsLoading' in window && window.distillTemplateIsLoading) {
throw new Error('Runlevel 1: Distill Template is getting loaded more than once, aborting!');
} else {
window.distillTemplateIsLoading = true;
console.info('Runlevel 1: Distill Template has started loading.');
}
/* 2. Add styles if they weren't added during prerendering */
makeStyleTag(document);
console.info('Runlevel 1: Static Distill styles have been added.');
console.info('Runlevel 1->2.');
window.distillRunlevel = 2;
/* 3. Register components */
/* Article will register controller which takes control from there */
const components = [
Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
Footnote, FootnoteList, FrontMatter, Title, DMath, References, TOC, Figure,
Slider, Interstitial
];
const distillComponents = [
DistillHeader, DistillAppendix, DistillFooter,
];
if (window.distillRunlevel < 2) {
throw new Error('Insufficient Runlevel for adding custom elements!');
}
const allComponents = components.concat(distillComponents);
for (const component of allComponents) {
console.info('Runlevel 2: Registering custom element: ' + component.is);
customElements.define(component.is, component);
}
}
defineComponents();
console.info('Runlevel 2: Distill Template finished registering custom elements.');
console.info('Runlevel 2->3.');
window.distillRunlevel = 3;
console.info('Distill Template initialisation complete.');
Controller.listeners.DOMContentLoaded();
};
window.distillRunlevel = 0;
/* 0. Check browser feature support; synchronously polyfill if needed */
if (Polyfills.browserSupportsAllFeatures()) {
console.info('Runlevel 0: No need for polyfills.');
console.info('Runlevel 0->1.');
window.distillRunlevel = 1;
distillMain();
} else {
console.info('Runlevel 0: Distill Template is loading polyfills.');
Polyfills.load(distillMain);
}
-1
View File
@@ -4,7 +4,6 @@ import { body } from '../helpers/layout';
const T = Template('d-abstract', `
<style>
:host {
display: block;
font-size: 1.25rem;
line-height: 1.6em;
color: rgba(0, 0, 0, 0.7);
+8 -2
View File
@@ -30,8 +30,14 @@ d-appendix h3 + * {
}
d-appendix ol {
padding: 0 0 0 30px;
margin-left: -30px;
padding: 0 0 0 15px;
}
@media (min-width: 768px) {
d-appendix ol {
padding: 0 0 0 30px;
margin-left: -30px;
}
}
d-appendix li {
+6
View File
@@ -31,6 +31,12 @@ export class Article extends HTMLElement {
}
connectedCallback() {
document.onreadystatechange = function () {
console.log("onreadystatechange:");
console.log(document.readyState);
};
console.info('Article tag connected, we can now listen to controller events.');
console.info('Runlevel 3->4.');
for (const [functionName, callback] of Object.entries(Controller.listeners)) {
if (typeof callback === 'function') {
document.addEventListener(functionName, callback);
+2
View File
@@ -11,6 +11,8 @@ export function parseBibliography(element) {
} else {
console.warn('Unsupported bibliography script tag type: ' + scriptTag.type);
}
} else {
console.warn('Bibliography did not have any script tag.');
}
}
+12 -14
View File
@@ -1,4 +1,4 @@
import style from '../styles/d-byline.css';
// import style from '../styles/d-byline.css';
export function bylineTemplate(frontMatter) {
return `
@@ -7,31 +7,29 @@ export function bylineTemplate(frontMatter) {
<h3>Authors</h3>
<h3>Affiliations</h3>
${frontMatter.authors.map(author => `
<p>
${author.personalURL
? `<a class="name" href="${author.personalURL}">${author.name}</a>`
: `<div class="name">${author.name}</div>`
}
<p class="author">
${author.personalURL ? `
<a class="name" href="${author.personalURL}">${author.name}</a>` : `
<div class="name">${author.name}</div>`}
</p>
<p>
${author.affiliationURL
? `<a class="affiliation" href="${author.affiliationURL}">${author.affiliation}</a>`
: `<div class="affiliation">${author.affiliation}</div>`
}
<p class="affiliation">
${author.affiliationURL ? `
<a class="affiliation" href="${author.affiliationURL}">${author.affiliation}</a>` : `
<div class="affiliation">${author.affiliation}</div>`}
</p>
`).join("")}
`).join('')}
</div>
<div>
<h3>Published</h3>
${frontMatter.publishedDate ? `
<p>${frontMatter.publishedMonth}. ${frontMatter.publishedDay} ${frontMatter.publishedYear}</p> ` : `
<p><em>Not yet published</em></p>`}
<p><em>Not published yet.</em></p>`}
</div>
<div>
<h3>DOI</h3>
${frontMatter.doi ? `
<p>${frontMatter.doi}</p>` : `
<p><em>No DOI yet</em></p>`}
<p><em>No DOI yet.</em></p>`}
</div>
</div>
`;
+27 -19
View File
@@ -1,9 +1,6 @@
import { Template } from '../mixins/template';
import { bibliography_cite } from '../helpers/citation';
const T = Template('d-citation-list', `
<style>
const styles = `
d-citation-list {
contain: content;
overflow: hidden;
@@ -16,21 +13,32 @@ d-citation-list .references {
d-citation-list .references .title {
font-weight: 500;
}
`;
</style>
<h3>References</h3>
<ol class='references' id='references-list'></ol>
`, false);
export function renderCitationList(element, entries) {
export function renderCitationList(element, entries, dom=document) {
if (entries.size > 0) {
element.style.display = '';
const list = document.getElementById('references-list');
list.innerHTML = '';
let list = element.querySelector('.references');
if (list) {
list.innerHTML = '';
} else {
const stylesTag = dom.createElement('style');
stylesTag.innerHTML = styles;
element.appendChild(stylesTag);
const heading = dom.createElement('h3');
heading.id = 'references';
heading.textContent = 'References';
element.appendChild(heading);
list = dom.createElement('ol');
list.id = 'references-list';
list.className = 'references';
element.appendChild(list);
}
for (const [key, entry] of entries) {
const listItem = document.createElement('li');
const listItem = dom.createElement('li');
listItem.id = key;
listItem.innerHTML = bibliography_cite(entry);
list.appendChild(listItem);
@@ -40,16 +48,16 @@ export function renderCitationList(element, entries) {
}
}
export class CitationList extends T(HTMLElement) {
export class CitationList extends HTMLElement {
static get is() { return 'd-citation-list'; }
connectedCallback() {
super.connectedCallback();
this.root.style.display = 'none';
this.style.display = 'none';
}
set citations(citations) {
renderCitationList(this.root, citations);
renderCitationList(this, citations);
}
}
+3 -1
View File
@@ -10,6 +10,7 @@ const T = Template('d-cite', `
}
.citation {
display: inline-block;
color: hsla(206, 90%, 20%, 0.7);
}
@@ -39,6 +40,7 @@ figcaption .citation-number {
width: 100%;
left: 0;
z-index: 10000;
margin-top: 2em;
}
.dt-hover-box {
@@ -59,7 +61,7 @@ figcaption .citation-number {
<div id="hover-box" class="dt-hover-box"></div>
</div>
<span id="citation-" class="citation"><slot></slot><span class="citation-number"></span></span>
<div id="citation-" class="citation"><slot></slot><span class="citation-number"></span></div>
`);
export class Cite extends T(HTMLElement) {
+9 -6
View File
@@ -33,8 +33,7 @@ export class Figure extends HTMLElement {
static runReadyQueue() {
// console.log("Checking to run readyQueue, length: " + Figure.readyQueue.length + ", scrolling: " + Figure.isScrolling);
if (Figure.isScrolling) return;
// if (Figure.isScrolling) return;
// console.log("Running ready Queue");
const figure = Figure.readyQueue
.sort((a,b) => a._seenOnScreen - b._seenOnScreen )
@@ -56,6 +55,7 @@ export class Figure extends HTMLElement {
}
connectedCallback() {
this.loadsWhileScrolling = this.hasAttribute('loadsWhileScrolling');
Figure.marginObserver.observe(this);
Figure.directObserver.observe(this);
}
@@ -71,12 +71,15 @@ export class Figure extends HTMLElement {
static get marginObserver() {
if (!Figure._marginObserver) {
// if (!('IntersectionObserver' in window)) {
// throw new Error('no interscetionobbserver!');
// }
const viewportHeight = window.innerHeight;
const margin = Math.floor(2 * viewportHeight);
Figure._marginObserver = new IntersectionObserver(
Figure.didObserveMarginIntersection, {
rootMargin: margin + 'px 0px ' + margin + 'px 0px', threshold: 0.01,
});
const options = {rootMargin: margin + 'px 0px ' + margin + 'px 0px', threshold: 0.01};
const callback = Figure.didObserveMarginIntersection;
const observer = new IntersectionObserver(callback, options);
Figure._marginObserver = observer;
}
return Figure._marginObserver;
}
+36 -4
View File
@@ -26,14 +26,18 @@ const T = Template('d-interstitial', `
.container {
position: relative;
left: 25%;
width: 50%;
margin-left: auto;
margin-right: auto;
max-width: 420px;
padding: 2em;
}
h1 {
text-decoration: underline;
text-decoration-color: hsl(0,100%,40%);
-webkit-text-decoration-color: hsl(0,100%,40%);
margin-bottom: 1em;
line-height: 1.5em;
}
input[type="password"] {
@@ -71,12 +75,31 @@ p small {
color: #888;
}
.logo {
position: relative;
font-size: 1.5em;
margin-bottom: 3em;
}
.logo svg {
width: 36px;
position: relative;
top: 6px;
margin-right: 2px;
}
.logo svg path {
fill: none;
stroke: black;
stroke-width: 2px;
}
</style>
<div class="overlay">
<div class="container">
<h1>This article is in review.</h1>
<p>Do not share this URL, or the contents of this article. Thank you!</p>
<p>Do not share this URL or the contents of this article. Thank you!</p>
<input id="interstitial-password-input" type="password" name="password" autofocus/>
<p><small>Enter the password we shared with you as part of the review process to view the article.</small></p>
</div>
@@ -88,14 +111,23 @@ export class Interstitial extends T(HTMLElement) {
connectedCallback() {
const passwordInput = this.root.querySelector('#interstitial-password-input');
passwordInput.oninput = (event) => this.passwordChanged(event);
if (typeof(Storage) !== 'undefined') {
if (localStorage.getItem('distill-interstitial-password-correct') === 'true') {
console.log('Loaded that correct password was entered before; skipping interstitial.');
this.parentElement.removeChild(this);
}
}
}
passwordChanged(event) {
const entered = event.target.value;
if (entered === this.password) {
console.log('Correct password entered.');
event.target.classList.add('correct');
this.parentElement.removeChild(this);
if (typeof(Storage) !== 'undefined') {
console.log('Saved that correct password was entered.');
localStorage.setItem('distill-interstitial-password-correct', 'true');
}
}
}
+7 -3
View File
@@ -33,15 +33,19 @@ export class DMath extends Mutating(T(HTMLElement)) {
static set katexOptions(options) {
DMath._katexOptions = options;
if (DMath.katexOptions.delimiters && !DMath.katexAdded) {
DMath.addKatex();
if (DMath.katexOptions.delimiters) {
if (!DMath.katexAdded) {
DMath.addKatex();
} else {
DMath.katexLoadedCallback();
}
}
}
static get katexOptions() {
if (!DMath._katexOptions) {
DMath._katexOptions = {
delimiters: [ { 'left':'$', 'right':'$', 'display':true } ]
delimiters: [ { 'left':'$$', 'right':'$$', 'display': false } ]
};
}
return DMath._katexOptions;
+13 -1
View File
@@ -71,6 +71,7 @@ export const Controller = {
},
onBibliographyChanged(event) {
console.info('BibliographyChanged');
const citationListTag = document.querySelector('d-citation-list');
const bibliography = event.detail;
@@ -136,7 +137,12 @@ export const Controller = {
},
DOMContentLoaded() {
// console.debug('DOMContentLoaded.');
if (Controller.loaded || ['interactive', 'complete'].indexOf(document.readyState) === -1) {
return;
} else {
Controller.loaded = true;
console.log('Controller running DOMContentLoaded')
}
const frontMatterTag = document.querySelector('d-front-matter');
const data = parseFrontmatter(frontMatterTag);
@@ -149,6 +155,12 @@ export const Controller = {
waitingCallback();
}
if (frontMatter.bibliographyParsed) {
for (const waitingCallback of Controller.waitingOn.bibliography.slice()) {
waitingCallback();
}
}
const footnotesList = document.querySelector('d-footnote-list');
if (footnotesList) {
const footnotes = document.querySelectorAll('d-footnote');
+6 -1
View File
@@ -35,7 +35,12 @@ export function appendixTemplate(frontMatter) {
if (typeof frontMatter.githubUrl !== 'undefined') {
html += `
<h3 id="updates-and-corrections">Updates and Corrections</h3>
<p><a href="">View all changes</a> to this article since it was first published. If you see mistakes or want to suggest changes, please <a href="${frontMatter.githubUrl + '/issues/new'}">create an issue on GitHub</a>. </p>
<p>`;
if (frontMatter.githubCompareUpdatesUrl) {
html += `<a href="${frontMatter.githubCompareUpdatesUrl}">View all changes</a> to this article since it was first published.`;
}
html += `
If you see mistakes or want to suggest changes, please <a href="${frontMatter.githubUrl + '/issues/new'}">create an issue on GitHub</a>. </p>
`;
}
-1
View File
@@ -5,7 +5,6 @@ const T = Template('distill-footer', `
<style>
:host {
display: block;
color: rgba(255, 255, 255, 0.5);
font-weight: 300;
padding: 60px 0;
+15
View File
@@ -1,3 +1,5 @@
import { parseBibtex } from '../helpers/bibtex';
import fs from 'fs';
import { parseBibliography } from '../components/d-bibliography';
export default function(dom, data) {
@@ -6,5 +8,18 @@ export default function(dom, data) {
console.warn('No bibliography tag found!');
return;
}
const src = bibliographyTag.getAttribute('src');
if (src) {
const path = data.inputDirectory + '/' + src;
const text = fs.readFileSync(path, 'utf-8');
const bibliography = parseBibtex(text);
const scriptTag = dom.createElement('script');
scriptTag.type = 'text/json';
scriptTag.textContent = JSON.stringify([...bibliography]);
bibliographyTag.appendChild(scriptTag);
bibliographyTag.removeAttribute('src');
}
data.bibliography = parseBibliography(bibliographyTag);
}
+2 -2
View File
@@ -41,7 +41,7 @@ export class HoverBox {
this.stopTimeout();
});
this.div.addEventListener('mouseout', () => {
this.extendTimeout(250);
this.extendTimeout(500);
});
// Don't trigger body touchstart event when touching within box
this.div.addEventListener('touchstart', (event) => {
@@ -62,7 +62,7 @@ export class HoverBox {
});
node.addEventListener('mouseout', () => {
this.extendTimeout(250);
this.extendTimeout(500);
});
node.addEventListener('touchstart', (event) => {
+68
View File
@@ -0,0 +1,68 @@
export function addPolyfill(polyfill, polyfillLoadedCallback) {
console.info('Runlevel 0: Polyfill required: ' + polyfill.name);
const script = document.createElement('script');
script.src = polyfill.url;
script.async = false;
if (polyfillLoadedCallback) {
script.onload = function() { polyfillLoadedCallback(polyfill); };
}
script.onerror = function() {
new Error('Runlevel 0: Polyfills failed to load script ' + polyfill.name);
};
document.head.appendChild(script);
}
export const polyfills = [
{
name: 'WebComponents',
support: function() {
return 'customElements' in window &&
'attachShadow' in Element.prototype &&
'getRootNode' in Element.prototype &&
'content' in document.createElement('template') &&
'Promise' in window &&
'from' in Array;
},
url: 'https://distill.pub/third-party/polyfills/webcomponents-lite.js'
}, {
name: 'IntersectionObserver',
support: function() {
return 'IntersectionObserver' in window &&
'IntersectionObserverEntry' in window;
},
url: 'https://distill.pub/third-party/polyfills/intersection-observer.js'
},
];
export class Polyfills {
static browserSupportsAllFeatures() {
return polyfills.every((poly) => poly.support());
}
static load(callback) {
// Define an intermediate callback that checks if all is loaded.
const polyfillLoaded = function(polyfill) {
polyfill.loaded = true;
console.info('Runlevel 0: Polyfill has finished loading: ' + polyfill.name);
// console.info(window[polyfill.name]);
if (Polyfills.neededPolyfills.every((poly) => poly.loaded)) {
console.info('Runlevel 0: All required polyfills have finished loading.');
console.info('Runlevel 0->1.');
window.distillRunlevel = 1;
callback();
}
};
// Add polyfill script tags
for (const polyfill of Polyfills.neededPolyfills) {
addPolyfill(polyfill, polyfillLoaded);
}
}
static get neededPolyfills() {
if (!Polyfills._neededPolyfills) {
Polyfills._neededPolyfills = polyfills.filter((poly) => !poly.support());
}
return Polyfills._neededPolyfills;
}
}
+2 -2
View File
@@ -71,8 +71,8 @@ d-article h3 {
font-weight: 700;
font-size: 18px;
line-height: 1.4em;
margin-bottom: 24px;
margin-top: 0;
margin-bottom: 1em;
margin-top: 2em;
}
@media(min-width: 1024px) {
+3 -2
View File
@@ -41,9 +41,10 @@ d-article d-byline a:hover {
border-bottom: none;
}
d-byline .authors p {
font-weight: 600;
d-byline p.author {
font-weight: 500;
}
d-byline .affiliations {
}
+1 -1
View File
@@ -1,7 +1,7 @@
span.katex-display {
text-align: left;
padding: 8px 0 8px 0;
margin: 0 0 1.7em 1em;
margin: 0.5em 0 0.5em 1em;
}
span.katex {
+6 -1
View File
@@ -83,7 +83,12 @@ sub {
figure {
position: relative;
margin-bottom: 1.5rem;
margin-bottom: 2.5em;
margin-top: 2.5em;
}
figcaption+figure {
}
figure img {
+2 -1
View File
@@ -17,7 +17,8 @@ export function makeStyleTag(dom) {
styleTag.type = 'text/css';
const cssTextTag = dom.createTextNode(styles);
styleTag.appendChild(cssTextTag);
dom.head.insertBefore(styleTag, dom.head.firstChild);
const firstScriptTag = dom.head.querySelector('script');
dom.head.insertBefore(styleTag, firstScriptTag);
}
}
+4 -4
View File
@@ -16,26 +16,26 @@ const extractors = new Map([
/* Transforms */
import HTML from './transforms/html';
import Byline from './transforms/byline';
import Polyfills from './transforms/polyfills';
import OptionalComponents from './transforms/optional-components';
import Mathematics from './transforms/mathematics';
import Meta from './transforms/meta';
import { makeStyleTag } from './styles/styles';
import TOC from './transforms/toc';
import Typeset from './transforms/typeset';
import Bibliography from './transforms/bibliography';
import Polyfills from './transforms/polyfills';
import CitationList from './transforms/citation-list';
const transforms = new Map([
['HTML', HTML],
['makeStyleTag', makeStyleTag],
['Polyfills', Polyfills],
['OptionalComponents', OptionalComponents],
['TOC', TOC],
['Byline', Byline],
['Mathematics', Mathematics],
['Meta', Meta],
['Typeset', Typeset],
['Bibliography', Bibliography],
['Polyfills', Polyfills],
['CitationList', CitationList],
]);
/* Distill Transforms */
-39
View File
@@ -1,39 +0,0 @@
// import { renderBibliography, templateString } from '../components/d-bibliography';
import { parseBibtex } from '../helpers/bibtex';
import fs from 'fs';
export default function(dom, data) {
const bibliographyTag = dom.querySelector('d-bibliography');
if (!bibliographyTag) {
console.warn('No bibliography tag present!');
return;
}
const src = bibliographyTag.getAttribute('src');
if (src) {
const path = data.inputDirectory + '/' + src;
const text = fs.readFileSync(path, 'utf-8');
const bibliography = parseBibtex(text);
const scriptTag = dom.createElement('script');
scriptTag.type = 'text/json';
scriptTag.textContent = JSON.stringify([...bibliography]);
bibliographyTag.appendChild(scriptTag);
bibliographyTag.removeAttribute('src');
}
// const bibliographyEntries = new Map(data.citations.map( citationKey => {
// const entry = data.bibliography.get(citationKey);
// return [citationKey, entry];
// }));
//
// const prerenderedBibliography = dom.createElement('d-bibliography-prerendered');
//
// const template = dom.createElement('template');
// template.innerHTML = templateString;
// const clone = dom.importNode(template.content, true);
// prerenderedBibliography.innerHTML = template.content;
// renderBibliography(prerenderedBibliography, bibliographyEntries, dom);
//
// bibliographyTag.parentElement.insertBefore(bibliographyTag, prerenderedBibliography);
// bibliographyTag.parentElement.removeChild(bibliographyTag);
}
+11
View File
@@ -0,0 +1,11 @@
import { renderCitationList } from '../components/d-citation-list'; // (element, entries)
export default function(dom, data) {
const citationListTag = dom.querySelector('d-citation-list');
if (citationListTag) {
const entries = new Map(data.citations.map( citationKey => {
return [citationKey, data.bibliography.get(citationKey)];
}));
renderCitationList(citationListTag, entries, dom);
}
}
+16 -4
View File
@@ -14,16 +14,28 @@ export default function(dom, data) {
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
<link rel="icon" type="image/png" href="data:image/png;base64,${favicon}">
<link href="/rss.xml" rel="alternate" type="application/rss+xml" title="Articles from Distill">
<link rel="canonical" href="${data.url}">
<title>${data.title}</title>
`);
appendHead(`
if (data.url) {
appendHead(`
<link rel="canonical" href="${data.url}">
`);
}
if (data.title) {
appendHead(`
<title>${data.title}</title>
`);
}
if (data.publishedDate){
appendHead(`
<!-- https://schema.org/Article -->
<meta property="article:published" itemprop="datePublished" content="${data.publishedYear}-${data.publishedMonthPadded}-${data.publishedDayPadded}" />
<meta property="article:created" itemprop="dateCreated" content="${data.publishedDate}" />
<meta property="article:modified" itemprop="dateModified" content="${data.updatedDate}" />
`);
`);
}
(data.authors || []).forEach((a) => {
appendHtml(head, `
+2 -1
View File
@@ -42,5 +42,6 @@ export default function render(dom) {
polyfillScriptTag.id = 'polyfills';
// insert at appropriate position--before any other script tag
dom.head.insertBefore(polyfillScriptTag, dom.head.firstChild);
const firstScriptTag = dom.head.querySelector('script');
dom.head.insertBefore(polyfillScriptTag, firstScriptTag);
}