mirror of
https://github.com/hanzoai/postcss.git
synced 2026-09-24 17:01:56 +00:00
206 lines
7.9 KiB
JavaScript
206 lines
7.9 KiB
JavaScript
import LazyResult from './lazy-result';
|
||
|
||
/**
|
||
* Contains plugins to process CSS. Create one `Processor` instance,
|
||
* initialize its plugins, and then use that instance on numerous CSS files.
|
||
*
|
||
* @example
|
||
* const processor = postcss([autoprefixer, precss]);
|
||
* processor.process(css1).then(result => console.log(result.css));
|
||
* processor.process(css2).then(result => console.log(result.css));
|
||
*/
|
||
class Processor {
|
||
|
||
/**
|
||
* @param {Array.<Plugin|pluginFunction>|Processor} plugins - PostCSS
|
||
* plugins. See {@link Processor#use} for plugin format.
|
||
*/
|
||
constructor(plugins = []) {
|
||
/**
|
||
* @member {string} - Current PostCSS version.
|
||
*
|
||
* @example
|
||
* if ( result.processor.version.split('.')[0] !== '6' ) {
|
||
* throw new Error('This plugin works only with PostCSS 6');
|
||
* }
|
||
*/
|
||
this.version = '6.0.6';
|
||
/**
|
||
* @member {pluginFunction[]} - Plugins added to this processor.
|
||
*
|
||
* @example
|
||
* const processor = postcss([autoprefixer, precss]);
|
||
* processor.plugins.length //=> 2
|
||
*/
|
||
this.plugins = this.normalize(plugins);
|
||
}
|
||
|
||
/**
|
||
* Adds a plugin to be used as a CSS processor.
|
||
*
|
||
* PostCSS plugin can be in 4 formats:
|
||
* * A plugin created by {@link postcss.plugin} method.
|
||
* * A function. PostCSS will pass the function a @{link Root}
|
||
* as the first argument and current {@link Result} instance
|
||
* as the second.
|
||
* * An object with a `postcss` method. PostCSS will use that method
|
||
* as described in #2.
|
||
* * Another {@link Processor} instance. PostCSS will copy plugins
|
||
* from that instance into this one.
|
||
*
|
||
* Plugins can also be added by passing them as arguments when creating
|
||
* a `postcss` instance (see [`postcss(plugins)`]).
|
||
*
|
||
* Asynchronous plugins should return a `Promise` instance.
|
||
*
|
||
* @param {Plugin|pluginFunction|Processor} plugin - PostCSS plugin
|
||
* or {@link Processor}
|
||
* with plugins
|
||
*
|
||
* @example
|
||
* const processor = postcss()
|
||
* .use(autoprefixer)
|
||
* .use(precss);
|
||
*
|
||
* @return {Processes} current processor to make methods chain
|
||
*/
|
||
use(plugin) {
|
||
this.plugins = this.plugins.concat(this.normalize([plugin]));
|
||
return this;
|
||
}
|
||
|
||
/**
|
||
* Parses source CSS and returns a {@link LazyResult} Promise proxy.
|
||
* Because some plugins can be asynchronous it doesn’t make
|
||
* any transformations. Transformations will be applied
|
||
* in the {@link LazyResult} methods.
|
||
*
|
||
* @param {string|toString|Result} css - String with input CSS or
|
||
* any object with a `toString()`
|
||
* method, like a Buffer.
|
||
* Optionally, send a {@link Result}
|
||
* instance and the processor will
|
||
* take the {@link Root} from it.
|
||
* @param {processOptions} [opts] - options
|
||
*
|
||
* @return {LazyResult} Promise proxy
|
||
*
|
||
* @example
|
||
* processor.process(css, { from: 'a.css', to: 'a.out.css' })
|
||
* .then(result => {
|
||
* console.log(result.css);
|
||
* });
|
||
*/
|
||
process(css, opts = { }) {
|
||
return new LazyResult(this, css, opts);
|
||
}
|
||
|
||
normalize(plugins) {
|
||
let normalized = [];
|
||
for ( let i of plugins ) {
|
||
if ( i.postcss ) i = i.postcss;
|
||
|
||
if ( typeof i === 'object' && Array.isArray(i.plugins) ) {
|
||
normalized = normalized.concat(i.plugins);
|
||
} else if ( typeof i === 'function' ) {
|
||
normalized.push(i);
|
||
} else if ( typeof i === 'object' && (i.parse || i.stringify) ) {
|
||
throw new Error('PostCSS syntaxes cannot be used as plugins. ' +
|
||
'Instead, please use one of the ' +
|
||
'syntax/parser/stringifier options as ' +
|
||
'outlined in your PostCSS ' +
|
||
'runner documentation.');
|
||
} else {
|
||
throw new Error(i + ' is not a PostCSS plugin');
|
||
}
|
||
}
|
||
return normalized;
|
||
}
|
||
|
||
}
|
||
|
||
export default Processor;
|
||
|
||
/**
|
||
* @callback builder
|
||
* @param {string} part - part of generated CSS connected to this node
|
||
* @param {Node} node - AST node
|
||
* @param {"start"|"end"} [type] - node’s part type
|
||
*/
|
||
|
||
/**
|
||
* @callback parser
|
||
*
|
||
* @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
|
||
*/
|
||
|
||
/**
|
||
* @callback stringifier
|
||
*
|
||
* @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}
|
||
*/
|
||
|
||
/**
|
||
* @typedef {object} syntax
|
||
* @property {parser} parse - function to generate AST by string
|
||
* @property {stringifier} stringify - function to generate string by AST
|
||
*/
|
||
|
||
/**
|
||
* @typedef {object} toString
|
||
* @property {function} toString
|
||
*/
|
||
|
||
/**
|
||
* @callback pluginFunction
|
||
* @param {Root} root - parsed input CSS
|
||
* @param {Result} result - result to set warnings or check other plugins
|
||
*/
|
||
|
||
/**
|
||
* @typedef {object} Plugin
|
||
* @property {function} postcss - PostCSS plugin function
|
||
*/
|
||
|
||
/**
|
||
* @typedef {object} processOptions
|
||
* @property {string} from - the path of the CSS source file.
|
||
* You should always set `from`,
|
||
* because it is used in source map
|
||
* generation and syntax error messages.
|
||
* @property {string} to - the path where you’ll put the output
|
||
* CSS file. You should always set `to`
|
||
* to generate correct source maps.
|
||
* @property {parser} parser - function to generate AST by string
|
||
* @property {stringifier} stringifier - class to generate string by AST
|
||
* @property {syntax} syntax - object with `parse` and `stringify`
|
||
* @property {object} map - source map options
|
||
* @property {boolean} map.inline - does source map should
|
||
* be embedded in the output
|
||
* CSS as a base64-encoded
|
||
* comment
|
||
* @property {string|object|false|function} map.prev - source map content
|
||
* from a previous
|
||
* processing step
|
||
* (for example, Sass).
|
||
* PostCSS will try to find
|
||
* previous map
|
||
* automatically, so you
|
||
* could disable it by
|
||
* `false` value.
|
||
* @property {boolean} map.sourcesContent - does PostCSS should set
|
||
* the origin content to map
|
||
* @property {string|false} map.annotation - does PostCSS should set
|
||
* annotation comment to map
|
||
* @property {string} map.from - override `from` in map’s
|
||
* `sources`
|
||
*/
|