@rr0/cms
Version:
RR0 Content Management System (CMS)
154 lines (153 loc) • 6.45 kB
JavaScript
import path from "path";
import assert from "assert";
/**
* Insert content in context file, according to data found in .json files aside of it.
*/
export class DataContentVisitor {
constructor(service, eventRenderer, timeElementFactory) {
this.service = service;
this.eventRenderer = eventRenderer;
this.timeElementFactory = timeElementFactory;
}
async visit(context) {
const dirName = path.dirname(context.file.name);
const dataList = await this.service.getFromDir(dirName, ["people", "case", "sighting", "api", "product", "org"], ["index.json", "case.json", "people.json", "api.json", "org.json"]);
if (dataList.length > 0) {
for (const data of dataList) {
switch (data.type) {
case "people":
context.people = data;
break;
}
await this.process(context, data);
}
}
}
async process(context, data) {
this.processTitle(context, data);
this.processURL(context, data);
const events = data.events.sort((event1, event2) => event1.time ? event2.time ? event1.time.isBefore(event2.time) ? -1 : 1 : -1 : 1);
for (const event of events) {
await this.processEvent(context, event, data);
}
context.file.contents = context.file.serialize();
}
async processEvent(context, event, data) {
switch (event.eventType) {
case "birth":
await this.processBirth(context, event, data);
break;
case "book":
await this.processBook(context, event);
break;
case "image":
await this.processImage(context, event);
break;
case "death":
await this.processDeath(context, event, data);
break;
default:
const { eventP, timeEl } = this.timeParagraph(context, event);
await this.eventRenderer.render(context, event, eventP);
context.file.document.append(eventP);
}
}
timeParagraph(context, event) {
const container = context.file.document.createElement("p");
const eventContext = context.clone();
const eventTime = eventContext.time.date = event.time;
assert.ok(eventTime, `Event of type "${event.type}" has no time for paragraph`);
container.dataset.time = eventTime.toString();
const timeEl = this.timeElementFactory.create(eventContext, context);
return { eventP: container, timeEl };
}
async processImage(context, imageData) {
const doc = context.file.document;
const contents = doc.querySelector(".contents");
if (contents) {
const imgEl = contents.querySelector("img");
const caption = imageData.name;
const src = imageData.url;
if ((imgEl === null || imgEl === void 0 ? void 0 : imgEl.src) !== src) {
const imgEl = doc.createElement("img");
imgEl.src = src;
imgEl.alt = imageData.title;
const figcaptionEl = doc.createElement("figcaption");
figcaptionEl.innerHTML = caption;
await this.eventRenderer.renderEnd(context, imageData, figcaptionEl);
const figureEl = doc.createElement("figure");
figureEl.append(imgEl);
figureEl.append(figcaptionEl);
const insertEl = contents.querySelector("*");
contents.insertBefore(figureEl, insertEl);
}
}
}
async processBirth(context, event, entity) {
const parentEl = context.file.document.querySelector(".contents");
if (parentEl) {
const { eventP, timeEl } = this.timeParagraph(context, event);
const name = entity.surname ? `"${entity.surname}"` : entity.name || entity.title;
eventP.append(name);
eventP.append(context.messages[entity.type].birth);
eventP.append(timeEl);
const eventPlace = event.place;
if (eventPlace) {
eventP.append(" à ");
eventP.append(this.eventRenderer.placeElement(context, eventPlace));
}
await this.eventRenderer.renderEnd(context, event, eventP);
const insertEl = parentEl.firstElementChild;
parentEl.insertBefore(eventP, insertEl);
}
else {
context.warn("no .content in", context.file.name);
}
}
async processDeath(context, event, entity) {
const { eventP, timeEl } = this.timeParagraph(context, event);
const name = entity.name;
eventP.append(name);
eventP.append(context.messages[entity.type].death);
eventP.append(timeEl);
if (event.place) {
eventP.append(" à ");
const birthPlace = this.eventRenderer.placeElement(context, event.place);
eventP.append(birthPlace);
}
await this.eventRenderer.renderEnd(context, event, eventP);
const insertEl = context.file.document.querySelector(".contents > p:last-of-type");
if (insertEl) {
insertEl.parentNode.append(eventP);
}
}
async processBook(context, bookData) {
const doc = context.file.document;
const parentEl = doc.querySelector(".contents");
if (parentEl) {
const bookEl = doc.createElement("p");
const people = context.people;
const birthContext = context.clone();
const bookDateEl = this.timeElementFactory.create(birthContext, context);
bookEl.append(bookDateEl, " ");
bookEl.append((people.gender === "female" ? "elle" : "il") + " écrit un livre");
await this.eventRenderer.renderEnd(context, bookData, bookEl);
parentEl.append(bookEl);
}
else {
context.warn("no .content in " + context.file.name);
}
}
processTitle(context, data) {
const doc = context.file.document;
if (!doc.title) {
context.file.title = doc.title = data.title;
}
}
processURL(context, data) {
const url = data.url;
if (url && !context.file.meta.url) {
context.file.meta.url = url;
}
}
}