UNPKG

@extjs/sencha-cmd-linux-32

Version:

Productivity and performance optimization tool for building applications with Sencha Ext JS and Sencha Touch.

297 lines (250 loc) 11.6 kB
"use strict"; var Fashion = require('../export/Base.js'); var FunctionCall = require('../export/type/FunctionCall.js'); var Literal = require('../export/type/Literal.js'); var Declaration = require('../type/Declaration.js'); var Ruleset = require('../type/Ruleset.js'); var SelectorList = require('../type/selectors/SelectorList.js'); var Preprocessor = require('../Preprocessor.js'); var Nodes = require('../parse/ast/Nodes.js'); var ExportBuilder = require('./ExportBuilder.js'); module.exports = { init (runtime) { // helper functions for creating new exported css variables from extension functions runtime.register({ create_css_variable: function (name, value, base) { while (base && base.$previousReference) { base = base.$previousReference; } value.$referenceName = this.unbox(name); value.$referenceBase = base || value; return value; }, name_of: function(refNode) { while (refNode && refNode.$referenceBase) { refNode = refNode.$referenceBase; } return refNode && refNode.$referenceName; } }); // detect css variable exports runtime.registerProcessor({ enable: true, execute: function (obj, ctx) { var me = this, config = runtime.context.getConfig('cssVars'); if (config) { Fashion.apply(this, config); } if (me.enable) { me.ctx = ctx; ctx.exportedVariables = {}; ctx.exportRuleset = new Ruleset({ selectors: new SelectorList([ new Literal('html') ]) }); me.visit(obj); if (me.export === 'all') { me.exportAllGlobals(obj); } } }, exportAllGlobals: function(css) { var globals = runtime.getGlobalScope().getEntries(), me = this, exportRuleset = me.ctx.exportRuleset; for (var key in globals) { var entry = globals[key], value = entry; if (value && value.ast && value.$referenceName) { var name = value.$referenceName, jsName = Fashion.getJsName(name.replace(/^--/g, '$')), varName = name.replace(/^\$/, ''), dynamics = runtime._dynamics; if (dynamics[jsName] && !entry.exported && varName.indexOf('include-') !== 0) { exportRuleset.addDeclaration(new Declaration({ property: '--' + varName, value: new Literal('export') })); entry.exported = true; } } } this.visit(exportRuleset); }, declaration: function (decl) { var name = decl.property, val = decl.value, exportedVariables = this.ctx.exportedVariables; if (name.indexOf('--') == 0) { if (val && val.$isFashionLiteral) { if (val.value && val.value.trim() === 'export') { var jsName = Fashion.getJsName(name.replace(/^--/g, '$')), globals = runtime.getGlobalScope(), dynamics = runtime._dynamics, variable = globals.get(jsName), baseName = name.replace(/^--/g, ''), key = Fashion.getJsName(baseName), exported = exportedVariables[key] || { name: baseName, rulesets: [] }; if (variable) { if (!dynamics[jsName]) { Fashion.log('cannot export ' + jsName + ' because it is not dynamic'); } else { if (val) { val.visitTarget = variable.clone(); } exported.declaration = decl; exported.variable = variable; variable.exported = true; exported.rulesets.push(decl.ruleset); exportedVariables[key] = exported; } } } } } this.visit(val); } }); // update rulesets to include new declarations w/o css variable references runtime.registerProcessor({ currDecl: null, referenceNodes: null, enable: true, execute: function (obj, ctx) { var me = this, config = runtime.context.getConfig('cssVars'); if (config) { Fashion.apply(me, config); } if (me.enable) { me.ctx = ctx; me.visit(obj); var exportedVariables = me.ctx.exportedVariables; if (Object.getOwnPropertyNames(exportedVariables).length) { var exportRuleset = me.ctx.exportRuleset, builder = new ExportBuilder(exportRuleset); builder.export = me.export; var exportFn = builder.buildExportFunction(exportedVariables, runtime); if (exportRuleset.declarations.length) { obj.push(exportRuleset); me.ctx.exportRuleset = new Ruleset({ selectors: new SelectorList([ new Literal('html') ]) }); } if (exportFn) { ctx.exportFn = exportFn; } } } }, visitItem: function (item) { if (item.$referenceName) { this.referenceNodes.push(item); } else { item.doVisit(this); } }, declaration: function (decl) { this.currDecl = decl; this.referenceNodes = []; var copy = decl.clone(), refNodes = this.referenceNodes, addNewDecl = false, exportedVariables = this.ctx.exportedVariables; this.visit(copy.value); outer: for (var i = 0; i < refNodes.length; i++) { var referenceNode = refNodes[i], refNode = referenceNode, refBase; while (refNode) { if (refNode.$referenceBase) { refBase = refNode.$referenceBase; break; } refNode = refNode.$previousReference; } if (refBase) { // need to add the export declaration for this variable var base = refBase, baseName = base.$referenceName.replace(/^\$/, ''), newName, exported, visitTarget, exDecl, keyName; baseName = Fashion.getJsName(baseName); newName = refNode.$referenceName.replace(/^\$/, ''); keyName = Fashion.getJsName(newName); if (exportedVariables[baseName]) { exported = exportedVariables[baseName]; exDecl = exported.declaration; } else { exDecl = copy; } if (!exportedVariables[keyName]) { var d = new Declaration({ property: '--' + newName, value: refNode.clone() }); exportedVariables[keyName] = { declaration: d, name: newName, rulesets: [ exDecl.ruleset ], variable: { $isWrapper: true, value: d.value } }; visitTarget = exDecl.visitTarget; if (!visitTarget) { exDecl.visitTarget = visitTarget = [ // don't clone here, since we need to // preserve visitTargets new Declaration({ property: exDecl.property, important: exDecl.important, sourceInfo: exDecl.sourceInfo, value: exDecl.value }) ]; } visitTarget.push(d); } } refNode = referenceNode; inner: while (refNode) { var refName = refNode.$referenceName.replace(/^\$/, ''); var keyName = Fashion.getJsName(refName); if (exportedVariables[keyName]) { referenceNode.visitTarget = new FunctionCall('var', [ new Literal('--' + refName) ]); addNewDecl = true; break inner; } else if (refNode.$previousReference && refNode.$previousReference.$referenceName) { refNode = refNode.$previousReference; } else { refNode = null; } } } if (addNewDecl) { decl.visitTarget = [decl.clone(), copy]; } this.currDecl = null; this.referenceNodes = null; } }); } };