mirror of
https://github.com/wassname/template.git
synced 2026-06-27 22:54:13 +08:00
204 lines
6.8 KiB
JavaScript
204 lines
6.8 KiB
JavaScript
// Copyright 2018 The Distill Template Authors
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import { FrontMatter, mergeFromYMLFrontmatter } from './front-matter';
|
|
import { DMath } from './components/d-math';
|
|
import { collect_citations } from './helpers/citation.js';
|
|
import { parseFrontmatter } from './components/d-front-matter';
|
|
import optionalComponents from './transforms/optional-components';
|
|
|
|
const frontMatter = new FrontMatter();
|
|
|
|
function domContentLoaded() {
|
|
return ['interactive', 'complete'].indexOf(document.readyState) !== -1;
|
|
}
|
|
|
|
export const Controller = {
|
|
|
|
frontMatter: frontMatter,
|
|
waitingOn: {
|
|
bibliography: [],
|
|
citations: [],
|
|
},
|
|
listeners: {
|
|
|
|
onCiteKeyCreated(event) {
|
|
const [citeTag, keys] = event.detail;
|
|
|
|
// ensure we have citations
|
|
if (!frontMatter.citationsCollected) {
|
|
// 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.bibliographyParsed) {
|
|
// 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() {
|
|
// const [citeTag, keys] = event.detail;
|
|
|
|
// update citations
|
|
frontMatter.citations = collect_citations();
|
|
frontMatter.citationsCollected = true;
|
|
for (const waitingCallback of Controller.waitingOn.citations.slice()) {
|
|
waitingCallback();
|
|
}
|
|
|
|
// update bibliography
|
|
const citationListTag = document.querySelector('d-citation-list');
|
|
const bibliographyEntries = new Map(frontMatter.citations.map( citationKey => {
|
|
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
|
}));
|
|
citationListTag.citations = 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;
|
|
}
|
|
|
|
},
|
|
|
|
onCiteKeyRemoved(event) {
|
|
Controller.listeners.onCiteKeyChanged(event);
|
|
},
|
|
|
|
onBibliographyChanged(event) {
|
|
const citationListTag = document.querySelector('d-citation-list');
|
|
|
|
const bibliography = event.detail;
|
|
|
|
frontMatter.bibliography = bibliography;
|
|
frontMatter.bibliographyParsed = true;
|
|
for (const waitingCallback of Controller.waitingOn.bibliography.slice()) {
|
|
waitingCallback();
|
|
}
|
|
|
|
// ensure we have citations
|
|
if (!frontMatter.citationsCollected) {
|
|
Controller.waitingOn.citations.push( function() {
|
|
Controller.listeners.onBibliographyChanged({target: event.target, detail: event.detail});
|
|
});
|
|
return;
|
|
}
|
|
|
|
|
|
if (citationListTag.hasAttribute('distill-prerendered')) {
|
|
console.info('Citation list was prerendered; not updating it.');
|
|
} else {
|
|
const entries = new Map(frontMatter.citations.map( citationKey => {
|
|
return [citationKey, frontMatter.bibliography.get(citationKey)];
|
|
}));
|
|
citationListTag.citations = entries;
|
|
}
|
|
},
|
|
|
|
onFootnoteChanged() {
|
|
// 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;
|
|
mergeFromYMLFrontmatter(frontMatter, data);
|
|
|
|
const interstitial = document.querySelector('d-interstitial');
|
|
if (interstitial) {
|
|
if (typeof frontMatter.password !== 'undefined') {
|
|
interstitial.password = frontMatter.password;
|
|
} else {
|
|
interstitial.parentElement.removeChild(interstitial);
|
|
}
|
|
}
|
|
|
|
const prerendered = document.body.hasAttribute('distill-prerendered');
|
|
if (!prerendered && domContentLoaded()) {
|
|
optionalComponents(document, frontMatter);
|
|
|
|
const appendix = document.querySelector('distill-appendix');
|
|
if (appendix) {
|
|
appendix.frontMatter = frontMatter;
|
|
}
|
|
|
|
const byline = document.querySelector('d-byline');
|
|
if (byline) {
|
|
byline.frontMatter = frontMatter;
|
|
}
|
|
|
|
if (data.katex) {
|
|
DMath.katexOptions = data.katex;
|
|
}
|
|
}
|
|
|
|
},
|
|
|
|
DOMContentLoaded() {
|
|
if (Controller.loaded) {
|
|
console.warn('Controller received DOMContentLoaded but was already loaded!');
|
|
return;
|
|
} else if (!domContentLoaded()) {
|
|
console.warn('Controller received DOMContentLoaded before appropriate document.readyState!');
|
|
return;
|
|
} else {
|
|
Controller.loaded = true;
|
|
console.log('Runlevel 4: Controller running DOMContentLoaded');
|
|
}
|
|
|
|
const frontMatterTag = document.querySelector('d-front-matter');
|
|
const data = parseFrontmatter(frontMatterTag);
|
|
Controller.listeners.onFrontMatterChanged({detail: data});
|
|
|
|
// Resolving "citations" dependency due to initial DOM load
|
|
frontMatter.citations = collect_citations();
|
|
frontMatter.citationsCollected = true;
|
|
for (const waitingCallback of Controller.waitingOn.citations.slice()) {
|
|
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');
|
|
footnotesList.footnotes = footnotes;
|
|
}
|
|
}
|
|
|
|
}, // listeners
|
|
|
|
}; // Controller
|