import Declaration from './declaration'; import Processor from './processor'; import stringify from './stringify'; import Comment from './comment'; import AtRule from './at-rule'; import vendor from './vendor'; import parse from './parse'; import list from './list'; import Rule from './rule'; import Root from './root'; /** * Create a new {@link Processor} instance that will apply `plugins` * as CSS processors. * * @param {Array.|Processor} plugins - PostCSS * plugins. See {@link Processor#use} for plugin format. * * @return {Processor} Processor to process multiple CSS * * @example * import postcss from 'postcss'; * * postcss(plugins).process(css, { from, to }).then(result => { * console.log(result.css); * }); * * @namespace postcss */ function postcss(...plugins) { if ( plugins.length === 1 && Array.isArray(plugins[0]) ) { plugins = plugins[0]; } return new Processor(plugins); } /** * Creates a PostCSS plugin with a standard API. * * The newly-wrapped function will provide both the name and PostCSS * version of the plugin. * * ```js * const processor = postcss([replace]); * processor.plugins[0].postcssPlugin //=> 'postcss-replace' * processor.plugins[0].postcssVersion //=> '5.1.0' * ``` * * The plugin function receives 2 arguments: {@link Root} * and {@link Result} instance. The function should mutate the provided * `Root` node. Alternatively, you can create a new `Root` node * and override the `result.root` property. * * ```js * const cleaner = postcss.plugin('postcss-cleaner', () => { * return (root, result) => { * result.root = postcss.root(); * }; * }); * ``` * * As a convenience, plugins also expose a `process` method so that you can use * them as standalone tools. * * ```js * cleaner.process(css, options); * // This is equivalent to: * postcss([ cleaner(options) ]).process(css); * ``` * * Asynchronous plugins should return a `Promise` instance. * * ```js * postcss.plugin('postcss-import', () => { * return (root, result) => { * return new Promise( (resolve, reject) => { * fs.readFile('base.css', (base) => { * root.prepend(base); * resolve(); * }); * }); * }; * }); * ``` * * Add warnings using the {@link Node#warn} method. * Send data to other plugins using the {@link Result#messages} array. * * ```js * postcss.plugin('postcss-caniuse-test', () => { * return (root, result) => { * css.walkDecls(decl => { * if ( !caniuse.support(decl.prop) ) { * decl.warn(result, 'Some browsers do not support ' + decl.prop); * } * }); * }; * }); * ``` * * @param {string} name - PostCSS plugin name. Same as in `name` * property in `package.json`. It will be saved * in `plugin.postcssPlugin` property. * @param {function} initializer - will receive plugin options * and should return {@link pluginFunction} * * @return {Plugin} PostCSS plugin */ postcss.plugin = function plugin(name, initializer) { let creator = function (...args) { let transformer = initializer(...args); transformer.postcssPlugin = name; transformer.postcssVersion = (new Processor()).version; return transformer; }; let cache; Object.defineProperty(creator, 'postcss', { get() { if ( !cache ) cache = creator(); return cache; } }); creator.process = function (root, opts) { return postcss([ creator(opts) ]).process(root, opts); }; return creator; }; /** * Default function to convert a node tree into a CSS string. * * @param {Node} node - start node for stringifing. Usually {@link Root}. * @param {builder} builder - function to concatenate CSS from node’s parts * or generate string and source map * * @return {void} * * @function */ postcss.stringify = stringify; /** * Parses source css and returns a new {@link Root} node, * which contains the source CSS nodes. * * @param {string|toString} css - string with input CSS or any object * with toString() method, like a Buffer * @param {processOptions} [opts] - options with only `from` and `map` keys * * @return {Root} PostCSS AST * * @example * // Simple CSS concatenation with source map support * const root1 = postcss.parse(css1, { from: file1 }); * const root2 = postcss.parse(css2, { from: file2 }); * root1.append(root2).toResult().css; * * @function */ postcss.parse = parse; /** * @member {vendor} - Contains the {@link vendor} module. * * @example * postcss.vendor.unprefixed('-moz-tab') //=> ['tab'] */ postcss.vendor = vendor; /** * @member {list} - Contains the {@link list} module. * * @example * postcss.list.space('5px calc(10% + 5px)') //=> ['5px', 'calc(10% + 5px)'] */ postcss.list = list; /** * Creates a new {@link Comment} node. * * @param {object} [defaults] - properties for the new node. * * @return {Comment} new Comment node * * @example * postcss.comment({ text: 'test' }) */ postcss.comment = defaults => new Comment(defaults); /** * Creates a new {@link AtRule} node. * * @param {object} [defaults] - properties for the new node. * * @return {AtRule} new AtRule node * * @example * postcss.atRule({ name: 'charset' }).toString() //=> "@charset" */ postcss.atRule = defaults => new AtRule(defaults); /** * Creates a new {@link Declaration} node. * * @param {object} [defaults] - properties for the new node. * * @return {Declaration} new Declaration node * * @example * postcss.decl({ prop: 'color', value: 'red' }).toString() //=> "color: red" */ postcss.decl = defaults => new Declaration(defaults); /** * Creates a new {@link Rule} node. * * @param {object} [defaults] - properties for the new node. * * @return {AtRule} new Rule node * * @example * postcss.rule({ selector: 'a' }).toString() //=> "a {\n}" */ postcss.rule = defaults => new Rule(defaults); /** * Creates a new {@link Root} node. * * @param {object} [defaults] - properties for the new node. * * @return {Root} new Root node * * @example * postcss.root({ after: '\n' }).toString() //=> "\n" */ postcss.root = defaults => new Root(defaults); export default postcss;