/
runtime.js
142 lines (126 loc) · 3.55 KB
/
runtime.js
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
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
module.exports = function() {
var __$that = this,
__$queue = [];
// Called after all matches
function __$flush() {
__$queue.filter(function(item) {
return !item.__$parent;
}).forEach(function(item) {
function apply(conditions, item) {
if (item && item.__$children) {
// Sub-template
var subcond = conditions.concat(item.__$cond);
item.__$children.forEach(function(child) {
apply(subcond, child);
});
} else {
// Body
template.apply(null, conditions)(item);
}
}
apply([], item);
});
};
// Matching
function match() {
function fn() {
var args = Array.prototype.slice.call(arguments);
args.forEach(function(arg) {
if (arg && arg.__$children) {
// Sub-template
arg.__$parent = fn;
}
fn.__$children.push(arg);
});
// Handle match().match()
var res = fn;
while (res.__$parent) res = res.__$parent;
return res;
};
__$queue.push(fn);
fn.__$children = [];
fn.__$parent = null;
fn.__$cond = Array.prototype.slice.call(arguments);
fn.match = match;
fn.block = block;
fn.elem = elem;
fn.mode = mode;
fn.mod = mod;
fn.def = def;
fn.tag = tag;
fn.attrs = attrs;
fn.cls = cls;
fn.js = js;
fn.jsAttr = jsAttr;
fn.bem = bem;
fn.mix = mix;
fn.content = content;
// match().match()
if (this && this.__$children) {
this.__$children.push(fn);
fn.__$parent = this;
}
return fn;
};
function block(name) {
return match.call(this, __$that.block === name);
};
function elem(name) {
return match.call(this, __$that.elem === name);
};
function mode(name) {
return match.call(this, __$that._mode === name);
};
function mod(name, value) {
return match.call(this, __$that.mods, __$that.mods[name] === value);
}
function def() { return mode.call(this, 'default'); };
function tag() { return mode.call(this, 'tag'); };
function attrs() { return mode.call(this,'attrs'); };
function cls() { return mode.call(this, 'cls'); };
function js() { return mode.call(this, 'js'); };
function jsAttr() { return mode.call(this, 'jsAttr'); };
function bem() { return mode.call(this, 'bem'); };
function mix() { return mode.call(this, 'mix'); };
function content() { return mode.call(this, 'content'); };
// Apply by mode, local by mode and applyCtx
apply = function(apply) {
return function bemApply() {
var args = Array.prototype.map.call(arguments, function(arg) {
if (typeof arg === 'string') {
return { _mode: arg };
} else {
return arg;
}
});
return apply.apply(null, args);
};
}(apply);
applyNext = function(applyNext) {
return function bemApplyNext() {
var args = Array.prototype.map.call(arguments, function(arg) {
if (typeof arg === 'string') {
return { _mode: arg };
} else {
return arg;
}
});
return applyNext.apply(null, args);
};
}(applyNext);
local = function(local) {
return function bemLocal() {
var args = Array.prototype.map.call(arguments, function(arg) {
if (typeof arg === 'string') {
return { _mode: arg };
} else {
return arg;
}
});
return local.apply(null, args);
};
}(local);
function applyCtx(context) {
return applyNext({ _mode: '', ctx: context });
};
}.toString().replace(/^function\s*\(\)\s*{|}$/g, '');