123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
-
- /**
- * Module dependencies.
- */
-
- var visit = require('rework-visit');
-
- /**
- * Define custom function.
- */
-
- module.exports = function(functions, args) {
- if (!functions) throw new Error('functions object required');
- return function(style){
- var functionMatcher = functionMatcherBuilder(Object.keys(functions).join('|'));
-
- visit(style, function(declarations){
- func(declarations, functions, functionMatcher, args);
- });
- }
- };
-
- /**
- * Visit declarations and apply functions.
- *
- * @param {Array} declarations
- * @param {Object} functions
- * @param {RegExp} functionMatcher
- * @param {Boolean} [parseArgs]
- * @api private
- */
-
- function func(declarations, functions, functionMatcher, parseArgs) {
- if (!declarations) return;
- if (false !== parseArgs) parseArgs = true;
-
- declarations.forEach(function(decl){
- if ('comment' == decl.type) return;
- var generatedFuncs = [], result, generatedFunc;
-
- while (decl.value.match(functionMatcher)) {
- decl.value = decl.value.replace(functionMatcher, function(_, name, args){
- if (parseArgs) {
- args = args.split(/\s*,\s*/).map(strip);
- } else {
- args = [strip(args)];
- }
- // Ensure result is string
- result = '' + functions[name].apply(decl, args);
-
- // Prevent fall into infinite loop like this:
- //
- // {
- // url: function(path) {
- // return 'url(' + '/some/prefix' + path + ')'
- // }
- // }
- //
- generatedFunc = {from: name, to: name + getRandomString()};
- result = result.replace(functionMatcherBuilder(name), generatedFunc.to + '($2)');
- generatedFuncs.push(generatedFunc);
- return result;
- });
- }
-
- generatedFuncs.forEach(function(func) {
- decl.value = decl.value.replace(func.to, func.from);
- })
- });
- }
-
- /**
- * Build function regexp
- *
- * @param {String} name
- * @api private
- */
-
- function functionMatcherBuilder(name) {
- // /(?!\W+)(\w+)\(([^()]+)\)/
- return new RegExp("(?!\\W+)(" + name + ")\\(([^\(\)]+)\\)");
- }
-
- /**
- * get random string
- *
- * @api private
- */
-
- function getRandomString() {
- return Math.random().toString(36).slice(2);
- }
-
- /**
- * strip quotes from string
- * @api private
- */
-
- function strip(str) {
- if ('"' == str[0] || "'" == str[0]) return str.slice(1, -1);
- return str;
- }
|