diff --git a/.gitignore b/.gitignore index 28d0c77..e53ba5a 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,8 @@ jspm_packages # Yarn Integrity file .yarn-integrity + +# Copied fonts +examples/fonts +dist/examples/fonts +dist/fonts diff --git a/components.js b/components.js index 1dbfa8a..e5e627a 100644 --- a/components.js +++ b/components.js @@ -1,32 +1,42 @@ -// load `webcomponent` polyfills asynchronously -// import "webcomponents.js/webcomponents-loader.js"; +/* Static styles and other modules */ +import * as Styles from './components/styles'; -import * as frontMatter from "./components/d-front-matter"; -import * as title from "./components/d-title"; -import * as byline from "./components/d-byline"; -import * as article from "./components/d-article"; -import * as abstract from "./components/d-abstract"; -import * as toc from "./components/d-toc"; -import * as styles from "./components/styles"; -import * as appendix from "./components/d-appendix"; -import * as distillAppendix from "./components/distill-appendix"; -import * as bibliography from "./components/d-bibliography"; -import * as references from "./components/d-references"; -import * as code from "./components/d-code"; -import * as math from "./components/d-math"; -import * as footnote from "./components/d-footnote"; -import * as footnoteList from "./components/d-footnote-list"; -import * as acknowledgements from "./components/d-acknowledgements"; -import * as cite from "./components/d-cite"; +/* Components */ +import { Abstract } from './components/d-abstract'; +import { Acknowledgements } from './components/d-acknowledgements'; +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 { 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 { DMath } from './components/d-math'; +import { References } from './components/d-references'; +import { Title } from './components/d-title'; +import { TOC } from './components/d-toc'; -// let codeStyle = document.createElement("style"); -// codeStyle.textContent = codeCss; -// document.querySelector("head").appendChild(codeStyle); +const components = [ + Abstract, Acknowledgements, Appendix, Article, Bibliography, + Byline, Cite, Code, Footnote, FootnoteList, FrontMatter, DMath, + References, Title, TOC, +]; -document.addEventListener("DOMContentLoaded", function() { - // Render byline with authors list. +/* Distill website specific components */ +import { DistillHeader } from "./distill-components/distill-header"; +import { DistillAppendix } from "./distill-components/distill-appendix"; - // Render distill appendix with distill journal data. - // document.querySelector("distill-appendix").render([]); +const distillComponents = [ + DistillHeader, DistillAppendix, +]; -}) +function defineComponents() { + const allComponents = components.concat(distillComponents); + for (const component of allComponents) { + customElements.define(component.is, component); + } +} + +defineComponents(); diff --git a/components/controller.js b/components/controller.js new file mode 100644 index 0000000..9d1391e --- /dev/null +++ b/components/controller.js @@ -0,0 +1,145 @@ +import { FrontMatter } from '../transforms/data'; +import { collectCitations } from './d-cite'; + +const frontMatter = new FrontMatter(); + +// set up global controller object +/* functions whose names start with 'on' will be registered as listeners on d-article */ +export const Controller = { + + frontMatter: frontMatter, + waitingOn: { + bibliography: [], + citations: [], + }, + listeners: { + + onCiteKeyCreated(event) { + const [citeTag, keys] = event.detail; + + // ensure we have citations + if (frontMatter.citations.length === 0) { + console.debug('onCiteKeyCreated, but unresolved dependency ("citations"). Enqueing.'); + Controller.waitingOn.citations.push(() => Controller.listeners.onCiteKeyCreated(event)); + return; + } + + // ensure we have a loaded bibliography + if (frontMatter.bibliography.size === 0) { + console.debug('onCiteKeyCreated, but unresolved dependency ("bibliography"). Enqueing.'); + Controller.waitingOn.bibliography.push(() => Controller.listeners.onCiteKeyCreated(event)); + return; + } + + const numbers = keys.map( key => frontMatter.citations.indexOf(key) ); + citeTag.numbers = numbers; + const entries = keys.map( key => frontMatter.bibliography.get(key) ); + citeTag.entries = entries; + }, + + onCiteKeyChanged(event) { + const [citeTag, keys] = event.detail; + + // update citations + frontMatter.citations = collectCitations(); + for (const waitingCallback of Controller.waitingOn.citations) { + waitingCallback(); + } + + // update bibliography + const bibliographyTag = document.querySelector('d-bibliography'); + const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => { + return [citationKey, frontMatter.bibliography.get(citationKey)]; + })); + bibliographyTag.entries = bibliographyEntries; + + const citeTags = document.querySelectorAll('d-cite'); + for (const citeTag of citeTags) { + const keys = citeTag.keys; + const numbers = keys.map( key => frontMatter.citations.indexOf(key) ); + citeTag.numbers = numbers; + const entries = keys.map( key => frontMatter.bibliography.get(key) ); + citeTag.entries = entries; + } + + const numbers = keys.map( key => frontMatter.citations.indexOf(key) ); + citeTag.numbers = numbers; + const entries = keys.map( key => frontMatter.bibliography.get(key) ); + citeTag.entries = entries; + }, + + onBibliographyChanged(event) { + const bibliographyTag = event.target; + const bibliography = event.detail; + + frontMatter.bibliography = bibliography; + for (const waitingCallback of Controller.waitingOn.bibliography) { + waitingCallback(); + } + + // ensure we have citations + if (frontMatter.citations.length === 0) { + console.debug('onBibliographyChanged, but unresolved dependency ("citations"). Enqueing.'); + Controller.waitingOn.citations.push(() => Controller.listeners.onBibliographyChanged(event)); + return; + } + + const entries = new Map(frontMatter.citations.map( citationKey => { + return [citationKey, frontMatter.bibliography.get(citationKey)]; + })); + bibliographyTag.entries = entries; + }, + + onFootnoteChanged(event) { + const footnote = event.detail; + //TODO: optimize to only update current footnote + const footnotesList = document.querySelector('d-footnote-list'); + if (footnotesList) { + const footnotes = document.querySelectorAll('d-footnote'); + footnotesList.footnotes = footnotes; + } + }, + + onFrontMatterChanged(event) { + const data = event.detail; + frontMatter.mergeFromYMLFrontmatter(data); + + const appendix = document.querySelector('distill-appendix'); + appendix.frontMatter = frontMatter; + }, + + DOMContentLoaded(event) { + console.debug('DOMContentLoaded.'); + + const frontMatterTag = document.querySelector('d-front-matter'); + const data = frontMatterTag.parse(); + frontMatter.mergeFromYMLFrontmatter(data); + const appendix = document.querySelector('distill-appendix'); + appendix.frontMatter = frontMatter; + + console.debug('Resolving "citations" dependency due to initial DOM load.'); + frontMatter.citations = collectCitations(); + for (const waitingCallback of Controller.waitingOn.citations) { + waitingCallback(); + } + + const footnotesList = document.querySelector('d-footnote-list'); + if (footnotesList) { + const footnotes = document.querySelectorAll('d-footnote'); + footnotesList.footnotes = footnotes; + } + + } + + }, // listeners + + update: { + cite(element) { + + }, + footnoteList(element) { + + } + } + +} // Controller diff --git a/components/d-abstract.js b/components/d-abstract.js index 1a11edc..3b83f17 100644 --- a/components/d-abstract.js +++ b/components/d-abstract.js @@ -1,5 +1,5 @@ -import {Template} from "../mixins/template"; -import {body} from "./layout"; +import { Template } from "../mixins/template"; +import { body } from "./layout"; const T = Template("d-abstract", ` `, false); -export default class Abstract extends T(HTMLElement) { - static get is() { return "d-abstract"; } -} +export class Abstract extends T(HTMLElement) { -customElements.define(Abstract.is, Abstract); +} diff --git a/components/d-acknowledgements.js b/components/d-acknowledgements.js index 5aab8d7..4ef2d4b 100644 --- a/components/d-acknowledgements.js +++ b/components/d-acknowledgements.js @@ -1,8 +1,6 @@ import { Template } from "../mixins/template"; -const name = 'd-acknowledgements'; - -const T = Template(name, ` +const T = Template('d-acknowledgements', ` +const T = Template('d-article', ` + `, false); -export default class Article extends T(HTMLElement) { - static get is() { return "d-article"; } -} -customElements.define(Article.is, Article); + +export class Article extends T(HTMLElement) { + + // constructor() { + // super(); + // } + + connectedCallback() { + for (const [functionName, callback] of Object.entries(Controller.listeners)) { + if (typeof callback === 'function') { + document.addEventListener(functionName, callback); + } else { + console.error('Controller listeners need to be functions!') + } + } + } + +} diff --git a/components/d-bibliography.js b/components/d-bibliography.js index f1b3606..f7001c7 100644 --- a/components/d-bibliography.js +++ b/components/d-bibliography.js @@ -1,9 +1,10 @@ -import bibtexParse from "bibtex-parse-js"; import { Template } from "../mixins/template"; +import { Mutating } from "../mixins/mutating"; +import { collectCitations } from './d-cite' +import bibtexParse from "bibtex-parse-js"; import { bibliography_cite } from "./citation"; -const name = 'd-bibliography'; -const T = Template(name, ` +const T = Template('d-bibliography', ` -