๐Ÿ“ฆ EdwonLim / node-less

๐Ÿ“„ javascript.js ยท 61 lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61(function (module) {

    var Anonymous = require('./anonymous.js'),
        Variable = require('./variable.js'),
        Quoted = require('./quoted.js'),
        jsify = require('./jsify.js');

    var JavaScript = function (string, index, escaped) {
        this.escaped = escaped;
        this.expression = string;
        this.index = index;
    };

    JavaScript.prototype = {
        type: "JavaScript",
        eval: function (env) {
            var result,
                that = this,
                context = {};

            var expression = this.expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
                return jsify(new Variable('@' + name, that.index).eval(env));
            });

            try {
                expression = new(Function)('return (' + expression + ')');
            } catch (e) {
                throw { message: "JavaScript evaluation error: `" + expression + "`" ,
                        index: this.index };
            }

            for (var k in env.frames[0].variables()) {
                context[k.slice(1)] = {
                    value: env.frames[0].variables()[k].value,
                    toJS: function () {
                        return this.value.eval(env).toCSS();
                    }
                };
            }

            try {
                result = expression.call(context);
            } catch (e) {
                throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message + "'" ,
                        index: this.index };
            }
            if (typeof(result) === 'string') {
                return new Quoted('"' + result + '"', result, this.escaped, this.index);
            } else if (Array.isArray(result)) {
                return new Anonymous(result.join(', '));
            } else {
                return new Anonymous(result);
            }
        }
    };

    module.exports = JavaScript;

})(module);