import type { ProjectListingInfo } from 'src/views/project/project' import { getFormattedPeriod } from 'src/utilities/dom' /** * Queries for description list nodes and inflates them with extra functionality * @param _window the reference to the window */ export const inflateDescriptionListEmbeds = (_projectInfo?: ProjectListingInfo) => { document.querySelectorAll('dl:not(.no-inflate)').forEach((_element) => { new DescriptionListElement(_element as HTMLDListElement, _projectInfo) }) } /** * Inflates description list elements with extra functionality, namely tags and time period */ export class DescriptionListElement { element: HTMLDListElement constructor(_element: HTMLDListElement, _projectInfo?: ProjectListingInfo) { this.element = _element if (!!_projectInfo) { this._inflatePeriod(_projectInfo) } this._inflateTags() } /** * Searches for the presence of a .period element wrapping around
and
, * and inflates the inner
element by replacing the first instance of $PERIOD with formatted period * @param _projectInfo the project info in which the project's time period is defined. */ _inflatePeriod = (_projectInfo: ProjectListingInfo) => { const periodWrapper = this.element.querySelector('.period') if (!!periodWrapper) { if (!!_projectInfo.period) { const periodDescriptionElement = periodWrapper.querySelector('dd') if (!!periodDescriptionElement) { periodDescriptionElement.innerHTML = periodDescriptionElement.innerHTML.replace('$PERIOD', getFormattedPeriod(_projectInfo.period)) } else { console.warn('Found a .period element but not an inner dd element to format on. The .period class should be on a div wrapping around
and
') } } else { console.warn('Found a .period element but the project information is missing a period.') } } } /** * Searches for the presence of a .tags element wrapping around
and
, * and inflates the inner
element by replacing the inner key-value JSON object with an array of span elements, * where the span's inner text corresponds to the keys of the JSON object, * and the span's class corresponds to the values of the JSON object. */ _inflateTags = () => { const tagsWrapper = this.element.querySelector('.tags') if (!!tagsWrapper) { let originalContent: { [key: string]: string } = { } try { const tagsDescriptionElement = tagsWrapper.querySelector('dd') if (!!tagsDescriptionElement) { originalContent = JSON.parse(tagsDescriptionElement.innerHTML) const formattedText = Object.keys(originalContent).map((key) => ( `${key}` )).join('') tagsDescriptionElement.innerHTML = formattedText } else { console.warn('Found a .tags element but not an inner dd element to format on. The .tags class should be on a div wrapping around
and
.') } } catch (err) { console.error('Found a .tags element but the inner dd element was improperly formatted. The
element should contain a valid JSON object.') console.error(originalContent) console.error(err) } } } }