UNPKG

@gouvfr/dsfr-roller

Version:

Le module `dsfr-roller` permet de publier le site de documentation du Système de Design de l’État - DSFR

66 lines (54 loc) 2.28 kB
import { Renderable } from '../core/renderable.js'; import { nodeFactory } from '../node/node-factory.js'; const PERMALINK_CONTENT_REGEX = /<!--\s*NO_PERMALINK_START\s*-->\s(?<content>[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->/g; const PREVENT_PERMALINKS_REGEX = /(?<permalinks><!--\s*NO_PERMALINK_START\s*-->\s(?:[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->)/g; const HEADING_REGEX = /<h(?<level>[2-6])(?<attrs>[^>]*)>(?<content>.*?)<\/h\1>/g; const ATTRIBUTE_ID_REGEX = /\sid=["'](?<id>[^"']+)["']/; const HEADING_BUTTON_CLASS = 'fr-btn--tooltip fr-btn fr-btn--sm fr-icon-link fr-btn--tertiary-no-outline dsfr-doc-anchor-heading__button'; const injectPermaLink = (match, level, attrs, content, fragments) => { const idMatch = attrs.match(ATTRIBUTE_ID_REGEX); if (!idMatch || !idMatch.groups?.id) return match; const copied = fragments?.button?.['link-copied']; const copy = fragments?.button?.['copy-link']; const buttonId = `${idMatch.groups.id}-anchor`; const anchorButton = `<button type="button" id="${buttonId}" title="${copy}" data-label-copied="${copied}" class="${HEADING_BUTTON_CLASS}"></button>`; return `<h${level}${attrs}>${content}${anchorButton}</h${level}>`; }; class Template extends Renderable { constructor (data, hasPermaLinks = false) { super(data); this._fragments = data.fragments; nodeFactory.populate(data.fragments); this._hasPermaLinks = hasPermaLinks; this._content = nodeFactory.create({ type: 'root', children: data.nodes }); } get content () { return this._content; } get name () { return this.constructor.NAME; } async render () { const html = await this._content.render(); if (!this._hasPermaLinks) return html; return this.addPermaLinks(html); } addPermaLinks (html) { return html.split(PREVENT_PERMALINKS_REGEX).map((part) => { const match = PERMALINK_CONTENT_REGEX.exec(part); if (match && match.groups && match.groups.content) { return match.groups.content; } return part.replace(HEADING_REGEX, (match, level, attrs, content) => { return injectPermaLink(match, level, attrs, content, this._fragments); }); }).join(''); } get text () { return this._content.text; } } export { Template };