From 7b5dbf434e7443c42b1dc4d77ef8994ca4365245 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Mon, 22 Mar 2021 00:02:53 +0900 Subject: [PATCH 1/4] Upgrade PostCSS to 8 --- package.json | 4 +- src/helpers/postcss_plugin.js | 29 +++++++++ src/markdown/style/assign.js | 5 +- src/postcss/advanced_background.js | 4 +- src/postcss/import/parse.js | 8 +-- src/postcss/import/replace.js | 64 +++++++++--------- src/postcss/import/rollup.js | 4 +- src/postcss/import/suppress.js | 7 +- src/postcss/meta.js | 14 ++-- src/postcss/pagination.js | 4 +- src/postcss/printable.js | 6 +- src/postcss/pseudo_selector/prepend.js | 4 +- src/postcss/pseudo_selector/replace.js | 4 +- src/postcss/root/font_size.js | 76 ++++++++++++---------- src/postcss/root/increasing_specificity.js | 4 +- src/postcss/root/rem.js | 4 +- src/postcss/root/replace.js | 4 +- src/postcss/section_size.js | 10 +-- src/theme_set.js | 16 ++++- yarn.lock | 43 +++++++++++- 20 files changed, 199 insertions(+), 115 deletions(-) create mode 100644 src/helpers/postcss_plugin.js diff --git a/package.json b/package.json index 1540d195..6b3e7f9c 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "@babel/cli": "^7.12.13", "@babel/core": "^7.12.13", "@babel/preset-env": "^7.12.13", - "autoprefixer": "^9.8.6", + "autoprefixer": "^10.2.5", "babel-eslint": "^10.1.0", "cheerio": "^1.0.0-rc.5", "chokidar": "^3.5.1", @@ -95,7 +95,7 @@ "lodash.kebabcase": "^4.1.1", "markdown-it": "^12.0.4", "markdown-it-front-matter": "^0.2.3", - "postcss": "^7.0.32" + "postcss": "^8.2.8" }, "publishConfig": { "access": "public" diff --git a/src/helpers/postcss_plugin.js b/src/helpers/postcss_plugin.js new file mode 100644 index 00000000..b72e09f9 --- /dev/null +++ b/src/helpers/postcss_plugin.js @@ -0,0 +1,29 @@ +/** @module */ + +/** + * Generate PostCSS plugin. + * + * This is a glue code generator to migrate existed plugins to support + * PostCSS 8. + * + * @param {string} name Plugin name. + * @param {(Function|Object)} func Function with PostCSS plugin interface. + * @returns {Function} A PostCSS plugin. + */ +function plugin(name, func) { + return Object.defineProperty( + function intrface(...args) { + const retFunc = func.apply(this, args) + + return Object.defineProperty( + typeof retFunc === 'function' ? { Once: retFunc } : retFunc, + 'postcssPlugin', + { value: name } + ) + }, + 'postcss', + { value: true } + ) +} + +export default plugin diff --git a/src/markdown/style/assign.js b/src/markdown/style/assign.js index bc3994f1..c8294e09 100644 --- a/src/markdown/style/assign.js +++ b/src/markdown/style/assign.js @@ -1,5 +1,6 @@ /** @module */ import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' import marpitPlugin from '../../plugin' const uniqKeyChars = @@ -17,7 +18,7 @@ const generateUniqKey = (length = 8) => { return ret } -const injectScopePostCSSplugin = postcss.plugin( +const injectScopePostCSSplugin = postcssPlugin( 'marpit-style-assign-postcss-inject-scope', (key, keyframeSet) => (css) => css.each(function inject(node) { @@ -42,7 +43,7 @@ const injectScopePostCSSplugin = postcss.plugin( }) ) -const scopeKeyframesPostCSSPlugin = postcss.plugin( +const scopeKeyframesPostCSSPlugin = postcssPlugin( 'marpit-style-assign-postcss-scope-keyframes', (key, keyframeSet) => (css) => { if (keyframeSet.size === 0) return diff --git a/src/postcss/advanced_background.js b/src/postcss/advanced_background.js index cede4ea5..36e438f5 100644 --- a/src/postcss/advanced_background.js +++ b/src/postcss/advanced_background.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../helpers/postcss_plugin' /** * Marpit PostCSS advanced background plugin. @@ -8,7 +8,7 @@ import postcss from 'postcss' * * @alias module:postcss/advanced_background */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-advanced-background', () => (css) => { css.last.after( diff --git a/src/postcss/import/parse.js b/src/postcss/import/parse.js index c922c45e..386b38b0 100644 --- a/src/postcss/import/parse.js +++ b/src/postcss/import/parse.js @@ -1,6 +1,6 @@ /* eslint consistent-return: 0 */ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' /** * @typedef {object} ImportMeta @@ -26,9 +26,9 @@ import postcss from 'postcss' * * @alias module:postcss/import/parse */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-import-parse', - () => (css, ret) => { + () => (css, { result }) => { const imports = { import: [], importTheme: [] } let allowImport = true @@ -70,7 +70,7 @@ const plugin = postcss.plugin( } }) - ret.marpitImport = [...imports.importTheme, ...imports.import] + result.marpitImport = [...imports.importTheme, ...imports.import] } ) diff --git a/src/postcss/import/replace.js b/src/postcss/import/replace.js index d1b71804..586abc55 100644 --- a/src/postcss/import/replace.js +++ b/src/postcss/import/replace.js @@ -1,5 +1,6 @@ /** @module */ import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' import postcssImportParse from './parse' /** @@ -13,41 +14,38 @@ import postcssImportParse from './parse' * @alias module:postcss/import/replace * @param {ThemeSet} themeSet ThemeSet instance. */ -const plugin = postcss.plugin( - 'marpit-postcss-import-replace', - (themeSet, importedThemes = []) => - postcss([ - postcssImportParse, - (css) => { - const prepends = [] - - css.walk((node) => { - const name = node.marpitImportParse - - if (name) { - const theme = themeSet.get(name) - - if (theme) { - if (importedThemes.includes(name)) - throw new Error(`Circular "${name}" theme import is detected.`) - - const processed = postcss([ - plugin(themeSet, [...importedThemes, name]), - ]).process(theme.css) - - if (node.name === 'import') { - node.replaceWith(processed.root) - } else { - node.remove() - prepends.unshift(processed.root) - } +const plugin = (themeSet, importedThemes = []) => + postcss([ + postcssImportParse, + postcssPlugin('marpit-postcss-import-replace', () => (css) => { + const prepends = [] + + css.walk((node) => { + const name = node.marpitImportParse + + if (name) { + const theme = themeSet.get(name) + + if (theme) { + if (importedThemes.includes(name)) + throw new Error(`Circular "${name}" theme import is detected.`) + + const processed = postcss([ + plugin(themeSet, [...importedThemes, name]), + ]).process(theme.css) + + if (node.name === 'import') { + node.replaceWith(processed.root) + } else { + node.remove() + prepends.unshift(processed.root) } } - }) + } + }) - for (const root of prepends) css.first.before(root) - }, - ]) -) + for (const root of prepends) css.first.before(root) + }), + ]) export default plugin diff --git a/src/postcss/import/rollup.js b/src/postcss/import/rollup.js index 0816b353..acd2e336 100644 --- a/src/postcss/import/rollup.js +++ b/src/postcss/import/rollup.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' /** * Marpit PostCSS import rollup plugin. @@ -12,7 +12,7 @@ import postcss from 'postcss' * * @alias module:postcss/import/rollup */ -const plugin = postcss.plugin('marpit-postcss-import-rollup', () => (css) => { +const plugin = postcssPlugin('marpit-postcss-import-rollup', () => (css) => { const rolluped = { charset: undefined, imports: [], diff --git a/src/postcss/import/suppress.js b/src/postcss/import/suppress.js index a19dfe3f..7c82f518 100644 --- a/src/postcss/import/suppress.js +++ b/src/postcss/import/suppress.js @@ -1,5 +1,6 @@ /** @module */ import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' import postcssImportParse from './parse' /** @@ -13,15 +14,15 @@ import postcssImportParse from './parse' * @alias module:postcss/import/suppress * @param {ThemeSet} themeSet ThemeSet instance. */ -const plugin = postcss.plugin('marpit-postcss-import-suppress', (themeSet) => +const plugin = postcssPlugin('marpit-postcss-import-suppress', (themeSet) => postcss([ postcssImportParse, - (css) => { + postcssPlugin('marpit-postcss-import-suppress', () => (css) => { css.walk((node) => { if (node.marpitImportParse && themeSet.has(node.marpitImportParse)) node.replaceWith(`${node.raw('before')}/* ${node.toString()}; */`) }) - }, + }), ]) ) diff --git a/src/postcss/meta.js b/src/postcss/meta.js index 8e4c5fa1..320a275c 100644 --- a/src/postcss/meta.js +++ b/src/postcss/meta.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../helpers/postcss_plugin' /** * Marpit PostCSS meta plugin. @@ -10,12 +10,12 @@ import postcss from 'postcss' * @param {Object} [opts.metaType] An object for defined types for metadata. * @alias module:postcss/meta */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-meta', - (opts = {}) => (css, ret) => { + (opts = {}) => (css, { result }) => { const metaType = opts.metaType || {} - ret.marpitMeta = ret.marpitMeta || {} + result.marpitMeta = result.marpitMeta || {} css.walkComments((comment) => { comment.text @@ -23,13 +23,13 @@ const plugin = postcss.plugin( .replace(/^[*!\s]*@([\w-]+)\s+(.+)$/gim, (_, metaName, value) => { if (metaType[metaName] === Array) { // Array meta - ret.marpitMeta[metaName] = [ - ...(ret.marpitMeta[metaName] || []), + result.marpitMeta[metaName] = [ + ...(result.marpitMeta[metaName] || []), value, ] } else { // String meta (default) - ret.marpitMeta[metaName] = value + result.marpitMeta[metaName] = value } }) }) diff --git a/src/postcss/pagination.js b/src/postcss/pagination.js index ab374bee..8e87c9ec 100644 --- a/src/postcss/pagination.js +++ b/src/postcss/pagination.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../helpers/postcss_plugin' /** * Marpit PostCSS pagination plugin. @@ -13,7 +13,7 @@ import postcss from 'postcss' * * @alias module:postcss/pagination */ -const plugin = postcss.plugin('marpit-postcss-pagination', () => (css) => { +const plugin = postcssPlugin('marpit-postcss-pagination', () => (css) => { css.walkRules((rule) => { if ( rule.selectors.some((selector) => diff --git a/src/postcss/printable.js b/src/postcss/printable.js index dffa03c9..37458753 100644 --- a/src/postcss/printable.js +++ b/src/postcss/printable.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../helpers/postcss_plugin' const marpitPrintContainerStyle = ` html, body { @@ -20,7 +20,7 @@ html, body { * @param {string} opts.height * @alias module:postcss/printable */ -const plugin = postcss.plugin('marpit-postcss-printable', (opts) => (css) => { +const plugin = postcssPlugin('marpit-postcss-printable', (opts) => (css) => { css.walkAtRules('media', (rule) => { if (rule.params === 'marpit-print') rule.remove() }) @@ -61,7 +61,7 @@ const plugin = postcss.plugin('marpit-postcss-printable', (opts) => (css) => { * * @alias module:postcss/printable.postprocess */ -export const postprocess = postcss.plugin( +export const postprocess = postcssPlugin( 'marpit-postcss-printable-postprocess', () => (css) => css.walkAtRules('media', (rule) => { diff --git a/src/postcss/pseudo_selector/prepend.js b/src/postcss/pseudo_selector/prepend.js index 0b5bf0a7..96b012e2 100644 --- a/src/postcss/pseudo_selector/prepend.js +++ b/src/postcss/pseudo_selector/prepend.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' /** * Marpit PostCSS pseudo selector prepending plugin. @@ -9,7 +9,7 @@ import postcss from 'postcss' * * @alias module:postcss/pseudo_selector/prepend */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-pseudo-selector-prepend', () => (css) => css.walkRules((rule) => { diff --git a/src/postcss/pseudo_selector/replace.js b/src/postcss/pseudo_selector/replace.js index 390ca78c..66e83443 100644 --- a/src/postcss/pseudo_selector/replace.js +++ b/src/postcss/pseudo_selector/replace.js @@ -1,6 +1,6 @@ /** @module */ import cssesc from 'cssesc' -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' import wrapArray from '../../helpers/wrap_array' const buildSelector = (elms) => @@ -28,7 +28,7 @@ const buildSelector = (elms) => * @param {Element|Element[]} [elements] Container elements * @param {Element|Element[]} [slideElements={ tag: 'section' }] Slide elements */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-pseudo-selector-replace', (elements, slideElements = { tag: 'section' }) => { const container = buildSelector([...wrapArray(elements)]) diff --git a/src/postcss/root/font_size.js b/src/postcss/root/font_size.js index a8501b86..39e3acfa 100644 --- a/src/postcss/root/font_size.js +++ b/src/postcss/root/font_size.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' export const rootFontSizeCustomProp = '--marpit-root-font-size' @@ -11,46 +11,50 @@ export const rootFontSizeCustomProp = '--marpit-root-font-size' * * @alias module:postcss/root/font_size */ -const plugin = postcss.plugin('marpit-postcss-root-font-size', () => (css) => - css.walkRules((rule) => { - const injectSelector = new Set() - - for (const selector of rule.selectors) { - // Detect whether the selector is targeted to section - const parentSelectors = selector.split(/(\s+|\s*[>~+]\s*)/) - const targetSelector = parentSelectors.pop() - const delimiterMatched = targetSelector.match(/[.:#[]/) - const target = delimiterMatched - ? targetSelector.slice(0, delimiterMatched.index) - : targetSelector - - if (target === 'section' || target.endsWith('*') || target === '') { - // Generate selector for injection - injectSelector.add( - [ - ...parentSelectors, - target === 'section' - ? 'section' - : ':marpit-container > :marpit-slide section', // Universal selector is targeted to the children `section` of root `section` - delimiterMatched - ? targetSelector.slice(delimiterMatched.index) - : '', - ].join('') - ) +const plugin = postcssPlugin( + 'marpit-postcss-root-font-size', + () => (css, postcss) => + css.walkRules((rule) => { + const injectSelector = new Set() + + for (const selector of rule.selectors) { + // Detect whether the selector is targeted to section + const parentSelectors = selector.split(/(\s+|\s*[>~+]\s*)/) + const targetSelector = parentSelectors.pop() + const delimiterMatched = targetSelector.match(/[.:#[]/) + const target = delimiterMatched + ? targetSelector.slice(0, delimiterMatched.index) + : targetSelector + + if (target === 'section' || target.endsWith('*') || target === '') { + // Generate selector for injection + injectSelector.add( + [ + ...parentSelectors, + target === 'section' + ? 'section' + : ':marpit-container > :marpit-slide section', // Universal selector is targeted to the children `section` of root `section` + delimiterMatched + ? targetSelector.slice(delimiterMatched.index) + : '', + ].join('') + ) + } } - } - if (injectSelector.size === 0) return + if (injectSelector.size === 0) return - // Inject CSS variable - const injectRule = postcss.rule({ selectors: [...injectSelector.values()] }) + // Inject CSS variable + const injectRule = postcss.rule({ + selectors: [...injectSelector.values()], + }) - rule.walkDecls('font-size', (decl) => { - injectRule.append(decl.clone({ prop: rootFontSizeCustomProp })) - }) + rule.walkDecls('font-size', (decl) => { + injectRule.append(decl.clone({ prop: rootFontSizeCustomProp })) + }) - if (injectRule.nodes.length > 0) rule.parent.insertAfter(rule, injectRule) - }) + if (injectRule.nodes.length > 0) rule.parent.insertAfter(rule, injectRule) + }) ) export default plugin diff --git a/src/postcss/root/increasing_specificity.js b/src/postcss/root/increasing_specificity.js index 471532a0..77b1862c 100644 --- a/src/postcss/root/increasing_specificity.js +++ b/src/postcss/root/increasing_specificity.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' export const pseudoClass = ':marpit-root' @@ -13,7 +13,7 @@ const matcher = new RegExp(`\\b${pseudoClass}\\b`, 'g') * * @alias module:postcss/root/increasing_specificity */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-root-increasing-specificity', () => (css) => css.walkRules((rule) => { diff --git a/src/postcss/root/rem.js b/src/postcss/root/rem.js index f1056d41..1b668226 100644 --- a/src/postcss/root/rem.js +++ b/src/postcss/root/rem.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' import { rootFontSizeCustomProp } from './font_size' const skipParsingMatcher = /("[^"]*"|'[^']*'|(?:attr|url|var)\([^)]*\))/g @@ -11,7 +11,7 @@ const skipParsingMatcher = /("[^"]*"|'[^']*'|(?:attr|url|var)\([^)]*\))/g * * @alias module:postcss/root/rem */ -const plugin = postcss.plugin('marpit-postcss-rem', () => (css) => +const plugin = postcssPlugin('marpit-postcss-rem', () => (css) => css.walkDecls((decl) => { decl.value = decl.value .split(skipParsingMatcher) diff --git a/src/postcss/root/replace.js b/src/postcss/root/replace.js index 10f54f19..68c73967 100644 --- a/src/postcss/root/replace.js +++ b/src/postcss/root/replace.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../../helpers/postcss_plugin' /** * Marpit PostCSS root replace plugin. @@ -8,7 +8,7 @@ import postcss from 'postcss' * * @alias module:postcss/root/replace */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-root-replace', ({ pseudoClass } = {}) => (css) => css.walkRules((rule) => { diff --git a/src/postcss/section_size.js b/src/postcss/section_size.js index cf4a6f2d..ba68eee1 100644 --- a/src/postcss/section_size.js +++ b/src/postcss/section_size.js @@ -1,5 +1,5 @@ /** @module */ -import postcss from 'postcss' +import postcssPlugin from '../helpers/postcss_plugin' /** * Marpit PostCSS section size plugin. @@ -8,15 +8,15 @@ import postcss from 'postcss' * * @alias module:postcss/section_size */ -const plugin = postcss.plugin( +const plugin = postcssPlugin( 'marpit-postcss-section-size', ({ pseudoClass } = {}) => { const rootSectionMatcher = new RegExp( `^(?:section|\\*?:root)${pseudoClass ? `(?:${pseudoClass})?` : ''}$` ) - return (css, ret) => { - ret.marpitSectionSize = ret.marpitSectionSize || {} + return (css, { result }) => { + result.marpitSectionSize = result.marpitSectionSize || {} css.walkRules((rule) => { if (rule.selectors.some((s) => rootSectionMatcher.test(s))) { @@ -24,7 +24,7 @@ const plugin = postcss.plugin( const { prop } = decl const value = decl.value.trim() - ret.marpitSectionSize[prop] = value + result.marpitSectionSize[prop] = value }) } }) diff --git a/src/theme_set.js b/src/theme_set.js index 07222f1c..427eaef2 100644 --- a/src/theme_set.js +++ b/src/theme_set.js @@ -1,4 +1,5 @@ import postcss from 'postcss' +import postcssPlugin from './helpers/postcss_plugin' import postcssAdvancedBackground from './postcss/advanced_background' import postcssImportReplace from './postcss/import/replace' import postcssImportRollup from './postcss/import/rollup' @@ -261,8 +262,14 @@ class ThemeSet { const packer = postcss( [ - before && ((css) => css.first.before(before)), - after && ((css) => css.last.after(after)), + before && + postcssPlugin('marpit-pack-before', () => (css) => + css.first.before(before) + ), + after && + postcssPlugin('marpit-pack-after', () => (css) => + css.first.after(after) + ), postcssImportRollup, postcssImportReplace(this), opts.printable && @@ -270,7 +277,10 @@ class ThemeSet { width: this.getThemeProp(theme, 'width'), height: this.getThemeProp(theme, 'height'), }), - theme !== scaffold && ((css) => css.first.before(scaffold.css)), + theme !== scaffold && + postcssPlugin('marpit-pack-scaffold', () => (css) => + css.first.before(scaffold.css) + ), opts.inlineSVG && postcssAdvancedBackground, postcssPagination, postcssRootReplace({ pseudoClass }), diff --git a/yarn.lock b/yarn.lock index 3e49c013..d91dc047 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1467,6 +1467,18 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +autoprefixer@^10.2.5: + version "10.2.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.5.tgz#096a0337dbc96c0873526d7fef5de4428d05382d" + integrity sha512-7H4AJZXvSsn62SqZyJCP+1AWwOuoYpUfK6ot9vm0e87XD6mT8lDywc9D9OTJPMULyGcvmIxzTAMeG2Cc+YX+fA== + dependencies: + browserslist "^4.16.3" + caniuse-lite "^1.0.30001196" + colorette "^1.2.2" + fraction.js "^4.0.13" + normalize-range "^0.1.2" + postcss-value-parser "^4.1.0" + autoprefixer@^9.8.6: version "9.8.6" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.6.tgz#3b73594ca1bf9266320c5acf1588d74dea74210f" @@ -1656,7 +1668,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.1, browserslist@^4.16.3: version "4.16.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.3.tgz#340aa46940d7db878748567c5dea24a48ddf3717" integrity sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw== @@ -1765,6 +1777,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001181: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz#3482a407d261da04393e2f0d61eefbc53be43b95" integrity sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg== +caniuse-lite@^1.0.30001196: + version "1.0.30001203" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001203.tgz#a7a34df21a387d9deffcd56c000b8cf5ab540580" + integrity sha512-/I9tvnzU/PHMH7wBPrfDMSuecDeUKerjCPX7D0xBbaJZPxoT9m+yYxt0zCTkcijCkjTdim3H56Zm0i5Adxch4w== + capture-exit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" @@ -1979,6 +1996,11 @@ colorette@^1.2.1: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94" + integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -2976,6 +2998,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +fraction.js@^4.0.13: + version "4.0.13" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.0.13.tgz#3c1c315fa16b35c85fffa95725a36fa729c69dfe" + integrity sha512-E1fz2Xs9ltlUp+qbiyx9wmt2n9dRzPsS11Jtdb8D2o+cC7wr9xkkKsVKJuBX0ST+LVS+LhLO+SbLJNtfWcJvXA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -4778,6 +4805,11 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +nanoid@^3.1.20: + version "3.1.22" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.22.tgz#b35f8fb7d151990a8aebd5aa5015c03cf726f844" + integrity sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -5612,6 +5644,15 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.21 source-map "^0.6.1" supports-color "^6.1.0" +postcss@^8.2.8: + version "8.2.8" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.8.tgz#0b90f9382efda424c4f0f69a2ead6f6830d08ece" + integrity sha512-1F0Xb2T21xET7oQV9eKuctbM9S7BC0fetoHCc4H13z0PT6haiRLP4T0ZY4XWh7iLP0usgqykT6p9B2RtOf4FPw== + dependencies: + colorette "^1.2.2" + nanoid "^3.1.20" + source-map "^0.6.1" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" From b0232c28c846ee5e76c4aaf19865078b1c525201 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Mon, 22 Mar 2021 00:57:16 +0900 Subject: [PATCH 2/4] Prevent using imported PostCSS instance in plugins --- src/postcss/import/replace.js | 68 ++++++++++++++++++---------------- src/postcss/import/suppress.js | 13 +++---- 2 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/postcss/import/replace.js b/src/postcss/import/replace.js index 586abc55..66f32b04 100644 --- a/src/postcss/import/replace.js +++ b/src/postcss/import/replace.js @@ -1,5 +1,4 @@ /** @module */ -import postcss from 'postcss' import postcssPlugin from '../../helpers/postcss_plugin' import postcssImportParse from './parse' @@ -15,37 +14,44 @@ import postcssImportParse from './parse' * @param {ThemeSet} themeSet ThemeSet instance. */ const plugin = (themeSet, importedThemes = []) => - postcss([ - postcssImportParse, - postcssPlugin('marpit-postcss-import-replace', () => (css) => { - const prepends = [] - - css.walk((node) => { - const name = node.marpitImportParse - - if (name) { - const theme = themeSet.get(name) - - if (theme) { - if (importedThemes.includes(name)) - throw new Error(`Circular "${name}" theme import is detected.`) - - const processed = postcss([ - plugin(themeSet, [...importedThemes, name]), - ]).process(theme.css) - - if (node.name === 'import') { - node.replaceWith(processed.root) - } else { - node.remove() - prepends.unshift(processed.root) + postcssPlugin('marpit-postcss-import-replace', () => ({ + plugins: [ + postcssImportParse(), + postcssPlugin( + 'marpit-postcss-import-replace-processor', + () => (css, { postcss }) => { + const prepends = [] + + css.walk((node) => { + const name = node.marpitImportParse + + if (name) { + const theme = themeSet.get(name) + + if (theme) { + if (importedThemes.includes(name)) + throw new Error( + `Circular "${name}" theme import is detected.` + ) + + const processed = postcss([ + plugin(themeSet, [...importedThemes, name]), + ]).process(theme.css) + + if (node.name === 'import') { + node.replaceWith(processed.root) + } else { + node.remove() + prepends.unshift(processed.root) + } + } } - } - } - }) + }) - for (const root of prepends) css.first.before(root) - }), - ]) + for (const root of prepends) css.first.before(root) + } + )(), + ], + })) export default plugin diff --git a/src/postcss/import/suppress.js b/src/postcss/import/suppress.js index 7c82f518..5f03b1d8 100644 --- a/src/postcss/import/suppress.js +++ b/src/postcss/import/suppress.js @@ -1,5 +1,4 @@ /** @module */ -import postcss from 'postcss' import postcssPlugin from '../../helpers/postcss_plugin' import postcssImportParse from './parse' @@ -14,16 +13,16 @@ import postcssImportParse from './parse' * @alias module:postcss/import/suppress * @param {ThemeSet} themeSet ThemeSet instance. */ -const plugin = postcssPlugin('marpit-postcss-import-suppress', (themeSet) => - postcss([ - postcssImportParse, +const plugin = postcssPlugin('marpit-postcss-import-suppress', (themeSet) => ({ + plugins: [ + postcssImportParse(), postcssPlugin('marpit-postcss-import-suppress', () => (css) => { css.walk((node) => { if (node.marpitImportParse && themeSet.has(node.marpitImportParse)) node.replaceWith(`${node.raw('before')}/* ${node.toString()}; */`) }) - }), - ]) -) + })(), + ], +})) export default plugin From 65dea616453924780947145b636a4bc7d6e21b98 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Mon, 22 Mar 2021 01:06:49 +0900 Subject: [PATCH 3/4] Requires Node >= 10 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 6b3e7f9c..6b4bee0d 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "url": "https://github.com/marp-team/marpit" }, "engines": { - "node": ">=8" + "node": ">=10" }, "main": "lib/index.js", "types": "index.d.ts", From 6377d91151ea0c6353d9b0f605b72a78e735add1 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Fri, 26 Mar 2021 00:13:47 +0900 Subject: [PATCH 4/4] [ci skip] Update CHANGELOG.md --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 63353fe4..48680dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## [Unreleased] +### Breaking + +- Marpit requires Node.js >= 10 to install ([#284](https://github.com/marp-team/marpit/pull/284)) + +### Changed + +- Upgrade to PostCSS 8 ([#260](https://github.com/marp-team/marpit/issues/260), [#284](https://github.com/marp-team/marpit/pull/284)) + ## v1.6.4 - 2021-02-06 ### Fixed