From 68a000750355263da55511f4524c867331c2e8f7 Mon Sep 17 00:00:00 2001 From: Ludwig Schubert Date: Wed, 18 Oct 2017 11:50:12 -0700 Subject: [PATCH 1/3] WIP --- examples/article.html | 1 - src/components/d-appendix.js | 5 +- src/components/d-byline.js | 2 +- src/distill-components/distill-footer.js | 4 +- src/distill-transforms/distill-appendix.js | 5 +- src/front-matter.js | 71 +++++++++++++++++++++- src/styles/d-article.css | 2 +- src/transforms.js | 6 +- test/transforms.js | 4 +- 9 files changed, 86 insertions(+), 14 deletions(-) diff --git a/examples/article.html b/examples/article.html index ddb993e..6f2f262 100644 --- a/examples/article.html +++ b/examples/article.html @@ -125,7 +125,6 @@

Some text with links describing who reviewed the article.

- diff --git a/src/components/d-appendix.js b/src/components/d-appendix.js index 3e84aa3..d9e4eaa 100644 --- a/src/components/d-appendix.js +++ b/src/components/d-appendix.js @@ -8,10 +8,11 @@ d-appendix { contain: content; font-size: 0.8em; line-height: 1.7em; + margin-top: 60px; margin-bottom: 0; - border-top: 1px solid rgba(0,0,0,0.1); + border-top: 1px solid rgba(0, 0, 0, 0.1); color: rgba(0,0,0,0.5); - padding-top: 36px; + padding-top: 60px; padding-bottom: 48px; } diff --git a/src/components/d-byline.js b/src/components/d-byline.js index 7bead09..b1d4687 100644 --- a/src/components/d-byline.js +++ b/src/components/d-byline.js @@ -27,7 +27,7 @@ export function bylineTemplate(frontMatter) {

Published

- ${frontMatter.published ? ` + ${frontMatter.publishedDate ? `

${frontMatter.publishedMonth}. ${frontMatter.publishedDay} ${frontMatter.publishedYear}

` : `

Not yet published

`}
diff --git a/src/distill-components/distill-footer.js b/src/distill-components/distill-footer.js index 87a5226..f27660d 100644 --- a/src/distill-components/distill-footer.js +++ b/src/distill-components/distill-footer.js @@ -6,9 +6,9 @@ const T = Template('distill-footer', ` :host { display: block; - color: rgba(255, 255, 255, 0.4); + color: rgba(255, 255, 255, 0.5); font-weight: 300; - padding: 40px 0; + padding: 60px 0; border-top: 1px solid rgba(0, 0, 0, 0.1); background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/ text-align: left; diff --git a/src/distill-transforms/distill-appendix.js b/src/distill-transforms/distill-appendix.js index 2fb639b..1dd3584 100644 --- a/src/distill-transforms/distill-appendix.js +++ b/src/distill-transforms/distill-appendix.js @@ -1,4 +1,6 @@ -export default function(dom) { +import { appendixTemplate } from '../distill-components/distill-appendix'; + +export default function(dom, data) { const appendixTag = dom.querySelector('d-appendix'); if (!appendixTag) { @@ -9,6 +11,7 @@ export default function(dom) { if (!distillAppendixTag) { const distillAppendix = dom.createElement('distill-appendix'); appendixTag.appendChild(distillAppendix); + distillAppendix.innerHTML = appendixTemplate(data); } } diff --git a/src/front-matter.js b/src/front-matter.js index 81766fa..a450b04 100644 --- a/src/front-matter.js +++ b/src/front-matter.js @@ -13,6 +13,23 @@ const RFC = function(date) { return `${day}, ${paddedDate} ${month} ${year} ${hours}:${minutes}:${seconds} Z`; }; +const objectFromMap = function(map) { + const object = Array.from(map).reduce((object, [key, value]) => ( + Object.assign(object, { [key]: value }) // Be careful! Maps can have non-String keys; object literals can't. + ), {}); + return object; +}; + +const mapFromObject = function(object) { + const map = new Map(); + for (var property in object) { + if (object.hasOwnProperty(property)) { + map.set(property, object[property]); + } + } + return map; +}; + class Author { // constructor(name='', personalURL='', affiliation='', affiliationURL='') { @@ -44,7 +61,20 @@ class Author { export function mergeFromYMLFrontmatter(target, source) { target.title = source.title; - target.publishedDate = new Date(source.published); + if (source.published) { + if (source.published instanceof Date) { + target.publishedDate = source.published; + } else if (source.published.constructor === String) { + target.publishedDate = new Date(source.published); + } + } + if (source.publishedDate) { + if (source.publishedDate instanceof Date) { + target.publishedDate = source.publishedDate; + } else if (source.publishedDate.constructor === String) { + target.publishedDate = new Date(source.publishedDate); + } + } target.description = source.description; target.authors = source.authors.map( (authorObject) => new Author(authorObject)); target.katex = source.katex; @@ -103,7 +133,6 @@ export class FrontMatter { // } // volume: 1, // issue: 9, - this.publishedDate = new Date(); this.katex = {}; @@ -230,4 +259,42 @@ export class FrontMatter { })); } + set bibliography(bibliography) { + if (bibliography instanceof Map) { + this._bibliography = bibliography; + } else if (typeof bibliography === 'object') { + this._bibliography = mapFromObject(bibliography); + } + } + + get bibliography() { + return this._bibliography; + } + + static fromObject(source) { + const frontMatter = new FrontMatter(); + Object.assign(frontMatter, source); + return frontMatter; + } + + assignToObject(target) { + Object.assign(target, this); + target.bibliography = objectFromMap(this.bibliographyEntries); + target.url = this.url; + target.githubUrl = this.githubUrl; + target.previewURL = this.previewURL; + target.volume = this.volume; + target.issue = this.issue; + target.publishedDateRFC = this.publishedDateRFC; + target.publishedYear = this.publishedYear; + target.publishedMonth = this.publishedMonth; + target.publishedDay = this.publishedDay; + target.publishedMonthPadded = this.publishedMonthPadded; + target.publishedDayPadded = this.publishedDayPadded; + target.updatedDateRFC = this.updatedDateRFC; + target.concatenatedAuthors = this.concatenatedAuthors; + target.bibtexAuthors = this.bibtexAuthors; + target.slug = this.slug; + } + } diff --git a/src/styles/d-article.css b/src/styles/d-article.css index cc0351b..8bcd056 100644 --- a/src/styles/d-article.css +++ b/src/styles/d-article.css @@ -145,7 +145,7 @@ d-article hr { grid-column: screen; width: 100%; border: none; - border-bottom: 1px solid rgba(0, 0, 0, 0.2); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); margin-top: 60px; margin-bottom: 60px; } diff --git a/src/transforms.js b/src/transforms.js index 8de90bc..dcc5125 100644 --- a/src/transforms.js +++ b/src/transforms.js @@ -52,19 +52,21 @@ const distillTransforms = new Map([ /* Exported functions */ export function render(dom, data, verbose=true) { + const frontMatter = FrontMatter.fromObject(data); // first, we collect static data from the dom for (const [name, extract] of extractors.entries()) { if (verbose) console.warn('Running extractor: ' + name); - extract(dom, data, verbose); + extract(dom, frontMatter, verbose); } // secondly we use it to transform parts of the dom for (const [name, transform] of transforms.entries()) { if (verbose) console.warn('Running transform: ' + name); // console.warn('Running transform: ', transform); - transform(dom, data, verbose); + transform(dom, frontMatter, verbose); } dom.body.setAttribute('distill-prerendered', ''); // the function calling us can now use the transformed dom and filled data object + frontMatter.assignToObject(data); } export function distillify(dom, data, verbose=true) { diff --git a/test/transforms.js b/test/transforms.js index 7d568b3..73c67a0 100644 --- a/test/transforms.js +++ b/test/transforms.js @@ -196,7 +196,7 @@ describe('Distill V2 (transforms)', function() { expect(content).to.not.include('journal'); }); - it('given only a DOM, it should add Google scholar references information', function() { + it('given only a DOM (and publish data), it should add Google scholar references information', function() { const dom = new JSDOM(` sth @@ -215,7 +215,7 @@ describe('Distill V2 (transforms)', function() { `, options); - const data = {}; + const data = { publishedDate: new Date(), updatedDate: new Date() }; distill.render(dom.window.document, data, false); const metaTags = [].slice.call(dom.window.document.querySelectorAll('meta[name="citation_reference"]')); expect(metaTags).to.not.be.empty; From 1a4cd694cd7fa6d99076558ef69fd0c9ffddf066 Mon Sep 17 00:00:00 2001 From: Ludwig Schubert Date: Thu, 19 Oct 2017 13:44:56 -0700 Subject: [PATCH 2/3] Fix interstitial on localhost, distill-appendix crash on unpublished articles --- src/components.js | 10 +- src/components/d-article.js | 3 - src/components/d-bibliography.js | 13 ++- src/components/d-figure.js | 1 - src/distill-components/distill-appendix.js | 37 +++++--- src/distill-components/distill-header.js | 105 +++++++++++---------- src/front-matter.js | 8 +- src/styles/styles-base.css | 11 +++ src/transforms.js | 13 ++- src/transforms/optional-components.js | 16 ++-- 10 files changed, 134 insertions(+), 83 deletions(-) diff --git a/src/components.js b/src/components.js index 32eb8f0..c8937a1 100644 --- a/src/components.js +++ b/src/components.js @@ -1,3 +1,10 @@ +/* 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; +} + /* Static styles and other modules */ import { makeStyleTag } from './styles/styles'; makeStyleTag(document); @@ -20,8 +27,7 @@ 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'; +import { Slider } from './ui/d-slider'; const components = [ Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code, diff --git a/src/components/d-article.js b/src/components/d-article.js index 5085868..d228079 100644 --- a/src/components/d-article.js +++ b/src/components/d-article.js @@ -14,9 +14,6 @@ export class Article extends HTMLElement { for (const mutation of mutations) { for (const addedNode of mutation.addedNodes) { switch (addedNode.nodeName) { - // case 'HR': - // console.warn('Use of
tags in distill articles is discouraged as they interfere with layout! To separate sections, please just use h2 or h3 tags.'); - // break; case '#text': { // usually text nodes are only linebreaks. const text = addedNode.nodeValue; if (!isOnlyWhitespace.test(text)) { diff --git a/src/components/d-bibliography.js b/src/components/d-bibliography.js index 6b6135e..f88bbad 100644 --- a/src/components/d-bibliography.js +++ b/src/components/d-bibliography.js @@ -1,9 +1,16 @@ import { parseBibtex } from '../helpers/bibtex'; export function parseBibliography(element) { - if (element.firstElementChild && element.firstElementChild.tagName === 'SCRIPT') { - const bibtex = element.firstElementChild.textContent; - return parseBibtex(bibtex); + const scriptTag = element.firstElementChild; + if (scriptTag && scriptTag.tagName === 'SCRIPT') { + if (scriptTag.type == 'text/bibtex') { + const bibtex = element.firstElementChild.textContent; + return parseBibtex(bibtex); + } else if (scriptTag.type == 'text/json') { + return new Map(JSON.parse(scriptTag.textContent)); + } else { + console.warn('Unsupported bibliography script tag type: ' + scriptTag.type); + } } } diff --git a/src/components/d-figure.js b/src/components/d-figure.js index 2df9302..a3e1c47 100644 --- a/src/components/d-figure.js +++ b/src/components/d-figure.js @@ -166,7 +166,6 @@ if (typeof window !== 'undefined') { clearTimeout(timeout); timeout = setTimeout(() => { Figure.isScrolling = false; - console.log('Stopped Scrolling') Figure.runReadyQueue(); }, 500); }; diff --git a/src/distill-components/distill-appendix.js b/src/distill-components/distill-appendix.js index 6770b0e..924dedc 100644 --- a/src/distill-components/distill-appendix.js +++ b/src/distill-components/distill-appendix.js @@ -30,21 +30,34 @@ const styles = ` `; export function appendixTemplate(frontMatter) { - return ` - ${styles} + let html = styles; -

Updates and Corrections

-

View all changes to this article since it was first published. If you see mistakes or want to suggest changes, please create an issue on GitHub.

+ if (typeof frontMatter.githubUrl !== 'undefined') { + html += ` +

Updates and Corrections

+

View all changes to this article since it was first published. If you see mistakes or want to suggest changes, please create an issue on GitHub.

+ `; + } -

Reuse

-

Diagrams and text are licensed under Creative Commons Attribution CC-BY 4.0 with the source available on GitHub, unless noted otherwise. The figures that have been reused from other sources don’t fall under this license and can be recognized by a note in their caption: “Figure from …”.

+ const journal = frontMatter.journal; + if (typeof journal !== 'undefined' && journal.title === 'Distill') { + html += ` +

Reuse

+

Diagrams and text are licensed under Creative Commons Attribution CC-BY 4.0 with the source available on GitHub, unless noted otherwise. The figures that have been reused from other sources don’t fall under this license and can be recognized by a note in their caption: “Figure from …”.

+ `; + } -

Citation

-

For attribution in academic contexts, please cite this work as

-
${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.
-

BibTeX citation

-
${serializeFrontmatterToBibtex(frontMatter)}
- `; + if (typeof frontMatter.publishedDate !== 'undefined') { + html += ` +

Citation

+

For attribution in academic contexts, please cite this work as

+
${frontMatter.concatenatedAuthors}, "${frontMatter.title}", Distill, ${frontMatter.publishedYear}.
+

BibTeX citation

+
${serializeFrontmatterToBibtex(frontMatter)}
+ `; + } + + return html; } export class DistillAppendix extends HTMLElement { diff --git a/src/distill-components/distill-header.js b/src/distill-components/distill-header.js index e312543..8e4cb2a 100644 --- a/src/distill-components/distill-header.js +++ b/src/distill-components/distill-header.js @@ -4,80 +4,81 @@ import logo from '../assets/distill-logo.svg'; const T = Template('distill-header', ` - -
+
-
Distill + + - Latest - About - Prize - Submit
-`); +`, false); // - +
`); export class Cite extends T(HTMLElement) { diff --git a/src/components/d-figure.js b/src/components/d-figure.js index a3e1c47..7fc880f 100644 --- a/src/components/d-figure.js +++ b/src/components/d-figure.js @@ -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; } diff --git a/src/components/d-interstitial.js b/src/components/d-interstitial.js index c980424..e214f66 100644 --- a/src/components/d-interstitial.js +++ b/src/components/d-interstitial.js @@ -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; +} +

This article is in review.

-

Do not share this URL, or the contents of this article. Thank you!

+

Do not share this URL or the contents of this article. Thank you!

Enter the password we shared with you as part of the review process to view the article.

@@ -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'); + } } } diff --git a/src/components/d-math.js b/src/components/d-math.js index 3b4ad76..25c99fb 100644 --- a/src/components/d-math.js +++ b/src/components/d-math.js @@ -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; diff --git a/src/controller.js b/src/controller.js index a0567ec..3a93f02 100644 --- a/src/controller.js +++ b/src/controller.js @@ -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'); diff --git a/src/distill-components/distill-appendix.js b/src/distill-components/distill-appendix.js index 924dedc..f219a1b 100644 --- a/src/distill-components/distill-appendix.js +++ b/src/distill-components/distill-appendix.js @@ -35,7 +35,12 @@ export function appendixTemplate(frontMatter) { if (typeof frontMatter.githubUrl !== 'undefined') { html += `

Updates and Corrections

-

View all changes to this article since it was first published. If you see mistakes or want to suggest changes, please create an issue on GitHub.

+

`; + if (frontMatter.githubCompareUpdatesUrl) { + html += `View all changes to this article since it was first published.`; + } + html += ` + If you see mistakes or want to suggest changes, please create an issue on GitHub.

`; } diff --git a/src/distill-components/distill-footer.js b/src/distill-components/distill-footer.js index f27660d..04ce57a 100644 --- a/src/distill-components/distill-footer.js +++ b/src/distill-components/distill-footer.js @@ -5,7 +5,6 @@ const T = Template('distill-footer', `