"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.assign = void 0; var _postcss = _interopRequireDefault(require("postcss")); var _postcss_plugin = _interopRequireDefault(require("../../helpers/postcss_plugin")); var _plugin = _interopRequireDefault(require("../../plugin")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** @module */ const uniqKeyChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; const uniqKeyCharsLength = uniqKeyChars.length; const generateScopeAttr = uniqKey => `data-marpit-scope-${uniqKey}`; const generateUniqKey = (length = 8) => { let ret = ''; for (let i = 0; i < length; i += 1) ret += uniqKeyChars[Math.floor(Math.random() * uniqKeyCharsLength)]; return ret; }; const injectScopePostCSSplugin = (0, _postcss_plugin.default)('marpit-style-assign-postcss-inject-scope', (key, keyframeSet) => css => css.each(function inject(node) { const { type, name } = node; if (type === 'atrule') { if (name === 'keyframes' && node.params) { keyframeSet.add(node.params); node.params += `-${key}`; } else if (name === 'media' || name === 'supports') { node.each(inject); } } else if (type === 'rule') { node.selectors = node.selectors.map(selector => { const injectSelector = /^section(?![\w-])/.test(selector) ? selector.slice(7) : ` ${selector}`; return `section[${generateScopeAttr(key)}]${injectSelector}`; }); } })); const scopeKeyframesPostCSSPlugin = (0, _postcss_plugin.default)('marpit-style-assign-postcss-scope-keyframes', (key, keyframeSet) => css => { if (keyframeSet.size === 0) return; const keyframeMatcher = new RegExp(`\\b(${[...keyframeSet.values()].map(kf => kf.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&')).join('|')})(?!\\()\\b`); css.walkDecls(/^animation(-name)?$/, decl => { decl.value = decl.value.replace(keyframeMatcher, kf => `${kf}-${key}`); }); }); /** * Marpit style assign plugin. * * Assign style global directive and parsed styles to Marpit instance's * `lastStyles' property. * * @function assign * @param {MarkdownIt} md markdown-it instance. */ function _assign(md) { const { marpit } = md; md.core.ruler.after('marpit_slide', 'marpit_style_assign', state => { if (state.inlineMode) return; const directives = marpit.lastGlobalDirectives || {}; marpit.lastStyles = directives.style ? [directives.style] : []; let current; for (const token of state.tokens) { if (token.meta && token.meta.marpitSlideElement === 1) { current = token; } else if (token.meta && token.meta.marpitSlideElement === -1) { if (current.meta && current.meta.marpitStyleScoped) { const { key, keyframeSet, styles } = current.meta.marpitStyleScoped; // Rewrite keyframes name in animation decls const processor = (0, _postcss.default)([scopeKeyframesPostCSSPlugin(key, keyframeSet)]); current.meta.marpitStyleScoped.styles = styles.map(style => { try { return processor.process(style).css; } catch { return style; } }); // Assign scoped styles marpit.lastStyles.push(...current.meta.marpitStyleScoped.styles); } current = undefined; } else if (token.type === 'marpit_style') { const { content } = token; // Scoped style const { marpitStyleScoped } = token.meta || {}; if (current && marpitStyleScoped) { current.meta = current.meta || {}; current.meta.marpitStyleScoped = current.meta.marpitStyleScoped || {}; let { key } = current.meta.marpitStyleScoped; if (!key) { key = generateUniqKey(); current.meta.marpitStyleScoped.key = key; current.attrSet(generateScopeAttr(key), ''); } current.meta.marpitStyleScoped.styles = current.meta.marpitStyleScoped.styles || []; current.meta.marpitStyleScoped.keyframeSet = current.meta.marpitStyleScoped.keyframeSet || new Set(); const processor = (0, _postcss.default)([injectScopePostCSSplugin(key, current.meta.marpitStyleScoped.keyframeSet)]); try { current.meta.marpitStyleScoped.styles.push(processor.process(content).css); } catch { // No ops } } else if (content) { // Global style marpit.lastStyles.push(content); } } } }); } const assign = exports.assign = (0, _plugin.default)(_assign); var _default = exports.default = assign;