source: Dev/branches/rest-dojo-ui/client/util/less/tree/mixin.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

  • Property svn:executable set to *
File size: 4.2 KB
Line 
1(function (tree) {
2
3tree.mixin = {};
4tree.mixin.Call = function (elements, args, index) {
5    this.selector = new(tree.Selector)(elements);
6    this.arguments = args;
7    this.index = index;
8};
9tree.mixin.Call.prototype = {
10    eval: function (env) {
11        var mixins, args, rules = [], match = false;
12
13        for (var i = 0; i < env.frames.length; i++) {
14            if ((mixins = env.frames[i].find(this.selector)).length > 0) {
15                args = this.arguments && this.arguments.map(function (a) { return a.eval(env) });
16                for (var m = 0; m < mixins.length; m++) {
17                    if (mixins[m].match(args, env)) {
18                        try {
19                            Array.prototype.push.apply(
20                                  rules, mixins[m].eval(env, this.arguments).rules);
21                            match = true;
22                        } catch (e) {
23                            throw { message: e.message, index: e.index, stack: e.stack, call: this.index };
24                        }
25                    }
26                }
27                if (match) {
28                    return rules;
29                } else {
30                    throw { message: 'No matching definition was found for `' +
31                                      this.selector.toCSS().trim() + '('      +
32                                      this.arguments.map(function (a) {
33                                          return a.toCSS();
34                                      }).join(', ') + ")`",
35                            index:   this.index };
36                }
37            }
38        }
39        throw { message: this.selector.toCSS().trim() + " is undefined",
40                index: this.index };
41    }
42};
43
44tree.mixin.Definition = function (name, params, rules) {
45    this.name = name;
46    this.selectors = [new(tree.Selector)([new(tree.Element)(null, name)])];
47    this.params = params;
48    this.arity = params.length;
49    this.rules = rules;
50    this._lookups = {};
51    this.required = params.reduce(function (count, p) {
52        if (!p.name || (p.name && !p.value)) { return count + 1 }
53        else                                 { return count }
54    }, 0);
55    this.parent = tree.Ruleset.prototype;
56    this.frames = [];
57};
58tree.mixin.Definition.prototype = {
59    toCSS:     function ()     { return "" },
60    variable:  function (name) { return this.parent.variable.call(this, name) },
61    variables: function ()     { return this.parent.variables.call(this) },
62    find:      function ()     { return this.parent.find.apply(this, arguments) },
63    rulesets:  function ()     { return this.parent.rulesets.apply(this) },
64
65    eval: function (env, args) {
66        var frame = new(tree.Ruleset)(null, []), context, _arguments = [];
67
68        for (var i = 0, val; i < this.params.length; i++) {
69            if (this.params[i].name) {
70                if (val = (args && args[i]) || this.params[i].value) {
71                    frame.rules.unshift(new(tree.Rule)(this.params[i].name, val.eval(env)));
72                } else {
73                    throw { message: "wrong number of arguments for " + this.name +
74                            ' (' + args.length + ' for ' + this.arity + ')' };
75                }
76            }
77        }
78        for (var i = 0; i < Math.max(this.params.length, args && args.length); i++) {
79            _arguments.push(args[i] || this.params[i].value);
80        }
81        frame.rules.unshift(new(tree.Rule)('@arguments', new(tree.Expression)(_arguments).eval(env)));
82
83        return new(tree.Ruleset)(null, this.rules.slice(0)).eval({
84            frames: [this, frame].concat(this.frames, env.frames)
85        });
86    },
87    match: function (args, env) {
88        var argsLength = (args && args.length) || 0, len;
89
90        if (argsLength < this.required)                               { return false }
91        if ((this.required > 0) && (argsLength > this.params.length)) { return false }
92
93        len = Math.min(argsLength, this.arity);
94
95        for (var i = 0; i < len; i++) {
96            if (!this.params[i].name) {
97                if (args[i].eval(env).toCSS() != this.params[i].value.eval(env).toCSS()) {
98                    return false;
99                }
100            }
101        }
102        return true;
103    }
104};
105
106})(require('less/tree'));
Note: See TracBrowser for help on using the repository browser.