diff options
Diffstat (limited to 'vanilla/node_modules/css-tree/lib/generator/create.js')
| -rw-r--r-- | vanilla/node_modules/css-tree/lib/generator/create.js | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/vanilla/node_modules/css-tree/lib/generator/create.js b/vanilla/node_modules/css-tree/lib/generator/create.js new file mode 100644 index 0000000..c542f4f --- /dev/null +++ b/vanilla/node_modules/css-tree/lib/generator/create.js @@ -0,0 +1,97 @@ +import { tokenize, Delim, WhiteSpace } from '../tokenizer/index.js'; +import { generateSourceMap } from './sourceMap.js'; +import * as tokenBefore from './token-before.js'; + +const REVERSESOLIDUS = 0x005c; // U+005C REVERSE SOLIDUS (\) + +function processChildren(node, delimeter) { + if (typeof delimeter === 'function') { + let prev = null; + + node.children.forEach(node => { + if (prev !== null) { + delimeter.call(this, prev); + } + + this.node(node); + prev = node; + }); + + return; + } + + node.children.forEach(this.node, this); +} + +function processChunk(chunk) { + tokenize(chunk, (type, start, end) => { + this.token(type, chunk.slice(start, end)); + }); +} + +export function createGenerator(config) { + const types = new Map(); + + for (let [name, item] of Object.entries(config.node)) { + const fn = item.generate || item; + + if (typeof fn === 'function') { + types.set(name, item.generate || item); + } + } + + return function(node, options) { + let buffer = ''; + let prevCode = 0; + let handlers = { + node(node) { + if (types.has(node.type)) { + types.get(node.type).call(publicApi, node); + } else { + throw new Error('Unknown node type: ' + node.type); + } + }, + tokenBefore: tokenBefore.safe, + token(type, value) { + prevCode = this.tokenBefore(prevCode, type, value); + + this.emit(value, type, false); + + if (type === Delim && value.charCodeAt(0) === REVERSESOLIDUS) { + this.emit('\n', WhiteSpace, true); + } + }, + emit(value) { + buffer += value; + }, + result() { + return buffer; + } + }; + + if (options) { + if (typeof options.decorator === 'function') { + handlers = options.decorator(handlers); + } + + if (options.sourceMap) { + handlers = generateSourceMap(handlers); + } + + if (options.mode in tokenBefore) { + handlers.tokenBefore = tokenBefore[options.mode]; + } + } + + const publicApi = { + node: (node) => handlers.node(node), + children: processChildren, + token: (type, value) => handlers.token(type, value), + tokenize: processChunk + }; + + handlers.node(node); + + return handlers.result(); + }; +}; |
