UNPKG

antd-theme

Version:

Provide runtime dynamic theme for ant design.

104 lines (88 loc) 2.49 kB
const less = require('less'); const Muteable = require('../tree/muteable'); const colorPalette = require('../../lib/colorPalette'); const ReductionVisitor = require('./reductionVisitor'); const reductionVisitor = new ReductionVisitor(); class ResolveVisitor { constructor(runtimeVariableNames, variables, runtimeVariableVisitor) { this._visitor = new less.visitors.Visitor(this); this.isReplacing = true; this.lookup = new Set(); this.variables = variables; this.runtimeVariableVisitor = runtimeVariableVisitor; runtimeVariableNames.forEach( (name) => this.lookup.add(name) ); const frame = new less.tree.Ruleset( null, Object.keys(variables).map( (name) => new less.tree.Declaration( `@${name}`, this.variables[name].node ) ) ); frame.functionRegistry = less.functions.functionRegistry.inherit(); frame.functionRegistry.add( 'colorPalette', (color, index) => new less.tree.Color(colorPalette(color, index)) ); const context = new less.contexts.Eval({ math: 0 }, [frame]); this._context = context; } run(root) { const context = this._context; const value = this._visitor .visit(new less.tree.Value([root])) .eval(this._context); if (value instanceof Muteable) { const reduction = reductionVisitor.run( value.origin ); if (this.runtimeVariableVisitor.include(reduction)) { return { runtime: true, expr: reduction, node: value.value, value: value.value.toCSS(context), }; } return { runtime: false, expr: null, node: reduction, value: reduction.toCSS(context), }; } return { runtime: false, expr: null, node: value, value: value.toCSS(context), }; } visit(root) { const fn = this[`visit${root.type}`]; return fn ? fn.call(this, root) : root; } visitValue(node) { if (node.value.length === 1) { return this.visit(node.value[0]); } return node; } visitVariable(node) { const name = node.name.substr(1); if (this.lookup.has(name)) { return new Muteable( node, this.variables[name].node, node._index, node._fileInfo ); } return this.visit(this.variables[name].expr); } visitMuteable(node) { return this.visit(node.origin); } } module.exports = ResolveVisitor;