Skip to content

Commit

Permalink
compiler: add !this.elem
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Jun 12, 2013
1 parent 5bb5afe commit 8165a18
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
42 changes: 40 additions & 2 deletions lib/bemhtml/compiler.js
Expand Up @@ -249,7 +249,45 @@ Compiler.prototype.mergeMatches = function mergeMatches(ast) {
return ast;
};

Compiler.prototype.addNoElem = function predicates(predicates) {
var hasBlock = false,
hasElem = false,
hasCustom = false;

predicates.forEach(function(predicate) {
// this.block === ... || this.elem === ...
if (predicate.type === 'BinaryExpression' &&
predicate.operator === '===' &&
predicate.left.type === 'MemberExpression' &&
!predicate.left.computed &&
predicate.left.object.type === 'ThisExpression') {
var prop = predicate.left.property;
if (prop.name === 'block') hasBlock = true;
if (prop.name === 'elem') hasElem = true;
} else {
hasCustom = true;
}
});

// Add !this.elem
if (hasBlock && !hasElem && !hasCustom) {
predicates.push({
type: 'UnaryExpression',
operator: '!',
prefix: true,
argument: {
type: 'MemberExpression',
computed: false,
object: { type: 'ThisExpression' },
property: { type: 'Identifier', name: 'elem' }
}
});
}
return predicates;
};

Compiler.prototype.flatten = function flatten(expr) {
var self = this;
function dive(expr) {
// At this point only match(...)(match(...)(...), body) expressions are
// present.
Expand All @@ -264,14 +302,14 @@ Compiler.prototype.flatten = function flatten(expr) {
if (arg.bemMarked) {
dive(arg).forEach(function(t) {
res.push({
predicates: predicates.concat(t.predicates),
predicates: self.addNoElem(predicates.concat(t.predicates)),
body: t.body
});
});
} else {
// Body
res.push({
predicates: predicates,
predicates: self.addNoElem(predicates),
body: arg
});
}
Expand Down
44 changes: 38 additions & 6 deletions lib/bemhtml/runtime.js
@@ -1,6 +1,10 @@
module.exports = function() {
var __$that = this,
__$queue = [];
__$queue = [],
__$noElem = {},
__$noBlock = {},
__$hasElem = {},
__$hasBlock = {};

// Called after all matches
function __$flush() {
Expand All @@ -11,10 +15,38 @@ module.exports = function() {
if (item && item.__$children) {
// Sub-template
var subcond = conditions.concat(item.__$cond);

var noBlock = item.__$cond.some(function(c) {
return c === __$noBlock;
});
if (!noBlock) subcond = subcond.concat(__$hasBlock);
var noElem = item.__$cond.some(function(c) {
return c === __$noElem;
});
if (!noElem) subcond = subcond.concat(__$hasElem);

item.__$children.forEach(function(child) {
apply(subcond, child);
});
} else {
var hasElemCheck = false,
hasBlockCheck = false;

conditions = conditions.filter(function(c) {
if (c === __$hasBlock) {
hasBlockCheck = true;
return false;
} else if (c === __$hasElem) {
hasElemCheck = true;
return false;
}
return true;
});

if (hasBlockCheck && !hasElemCheck) {
conditions = conditions.concat(!__$that.elem);
}

// Body
template.apply(null, conditions)(item);
}
Expand Down Expand Up @@ -71,22 +103,22 @@ module.exports = function() {
};

function block(name) {
return match.call(this, __$that.block === name);
return match.call(this, __$that.block === name, __$noElem);
};

function elem(name) {
return match.call(this, __$that.elem === name);
return match.call(this, __$that.elem === name, __$noBlock);
};

function mode(name) {
return match.call(this, __$that._mode === name);
return match.call(this, __$that._mode === name, __$noElem, __$noBlock);
};

function mod(name, value) {
return match.call(this, __$that.mods, function() {
return __$that.mods[name] === value;
});
}
}, __$noElem, __$noBlock);
};

function def() { return mode.call(this, 'default'); };
function tag() { return mode.call(this, 'tag'); };
Expand Down

0 comments on commit 8165a18

Please sign in to comment.