Skip to content

Commit

Permalink
apply(modeName) must return values from this.ctx if no other temp…
Browse files Browse the repository at this point in the history
…lates
  • Loading branch information
miripiruni committed Jun 27, 2016
1 parent 0b96bac commit 9d230c5
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 41 deletions.
20 changes: 7 additions & 13 deletions lib/bemhtml/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ function Entity(bemxjst) {
this.jsClass = null;

// "Fast modes"
this.tag = new Match(this);
this.attrs = new Match(this);
this.tag = new Match(this, 'tag');
this.attrs = new Match(this, 'attrs');
this.mod = new Match(this);
this.js = new Match(this);
this.mix = new Match(this);
this.bem = new Match(this);
this.cls = new Match(this);
this.js = new Match(this, 'js');
this.mix = new Match(this, 'mix');
this.bem = new Match(this, 'bem');
this.cls = new Match(this, 'cls');

BemxjstEntity.apply(this, arguments);
}
Expand Down Expand Up @@ -50,14 +50,12 @@ Entity.prototype._initRest = function _initRest(key) {
this.rest[key] = this[key];
} else {
if (!this.rest.hasOwnProperty(key))
this.rest[key] = new Match(this);
this.rest[key] = new Match(this, key);
}
};

Entity.prototype.defaultBody = function defaultBody(context) {
var tag = this.tag.exec(context);
if (tag === undefined)
tag = context.ctx.tag;

var js;
if (context.ctx.js !== false)
Expand All @@ -69,10 +67,6 @@ Entity.prototype.defaultBody = function defaultBody(context) {
var attrs = this.attrs.exec(context);
var content = this.content.exec(context);

// Default content
if (this.content.count === 0 && content === undefined)
content = context.ctx.content;

return this.bemxjst.render(context,
this,
tag,
Expand Down
27 changes: 12 additions & 15 deletions lib/bemhtml/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,11 @@ BEMHTML.prototype.render = function render(context,
if (js === true)
js = {};

if (js) {
if (js && js !== ctx.js) {
if (ctxJS !== true)
js = utils.extend(ctxJS, js);
} else if (ctxJS === true) {
js = {};
} else {
js = ctxJS;
}
}

Expand Down Expand Up @@ -114,16 +112,11 @@ BEMHTML.prototype.render = function render(context,
out += entity.jsClass;
out += this.buildModsClasses(entity.block, entity.elem, mods);

var totalMix = mix;
if (ctx.mix) {
if (totalMix)
totalMix = [].concat(totalMix, ctx.mix);
else
totalMix = ctx.mix;
}
if (ctx.mix && mix && mix !== ctx.mix)
mix = [].concat(mix, ctx.mix);

if (totalMix) {
var m = this.renderMix(entity, totalMix, jsParams, addJSInitClass);
if (mix) {
var m = this.renderMix(entity, mix, jsParams, addJSInitClass);
out += m.out;
jsParams = m.jsParams;
addJSInitClass = m.addJSInitClass;
Expand Down Expand Up @@ -156,11 +149,15 @@ BEMHTML.prototype.renderClose = function renderClose(prefix,
ctx,
content) {
var out = prefix;
var isObj = function isObj(val) {
return val && typeof val === 'object' && !Array.isArray(val) &&
val !== null;
};

// NOTE: maybe we need to make an array for quicker serialization
attrs = utils.extend(attrs, ctx.attrs);
if (attrs && typeof attrs === 'object' && !Array.isArray(attrs) &&
attrs !== null) {
if (isObj(attrs) || isObj(ctx.attrs)) {
attrs = utils.extend(attrs, ctx.attrs);

/* jshint forin : false */
for (var name in attrs) {
var attr = attrs[name];
Expand Down
10 changes: 2 additions & 8 deletions lib/bemtree/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,10 @@ Entity.prototype._initRest = function _initRest(key) {
this.rest[key] = this[key];
} else {
if (!this.rest.hasOwnProperty(key))
this.rest[key] = new Match(this);
this.rest[key] = new Match(this, key);
}
};

Entity.prototype.defaultBody = function defaultBody(context) {
var content = this.content.exec(context);

// Default content
if (this.content.count === 0 && content === undefined)
content = context.ctx.content;

return this.bemxjst.render(context, this, content);
return this.bemxjst.render(context, this, this.content.exec(context));
};
2 changes: 1 addition & 1 deletion lib/bemxjst/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ function Entity(bemxjst, block, elem, templates) {

// "Fast modes"
this.def = new Match(this);
this.content = new Match(this);
this.content = new Match(this, 'content');

// "Slow modes"
this.rest = {};
Expand Down
2 changes: 1 addition & 1 deletion lib/bemxjst/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ BEMXJST.prototype.applyNext = function applyNext() {
BEMXJST.prototype.applyMode = function applyMode(mode, changes) {
var match = this.match.entity.rest[mode];
if (!match)
return;
return this.context.ctx[mode];

if (!changes)
return match.exec(this.context);
Expand Down
7 changes: 4 additions & 3 deletions lib/bemxjst/match.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,9 @@ function MatchTemplate(mode, template) {
}
exports.MatchTemplate = MatchTemplate;

function Match(entity) {
function Match(entity, modeName) {
this.entity = entity;
this.modeName = modeName;
this.bemxjst = this.entity.bemxjst;
this.templates = [];

Expand All @@ -135,7 +136,7 @@ function Match(entity) {
exports.Match = Match;

Match.prototype.clone = function clone(entity) {
var res = new Match(entity);
var res = new Match(entity, this.modeName);

res.templates = this.templates.slice();
res.mask = this.mask.slice();
Expand Down Expand Up @@ -206,7 +207,7 @@ Match.prototype.exec = function exec(context) {
}

if (i === this.count)
return undefined;
return context.ctx[this.modeName];

var oldMask = mask;
var oldMatch = this.bemxjst.match;
Expand Down
8 changes: 8 additions & 0 deletions test/modes-attrs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,12 @@ describe('Modes attrs', function() {
},
'<div class="button" type="link" name="button"></div>');
});

it('should merge attrs from templates and from bemjson', function() {
test(function() {
block('b').attrs()({ templ: '1' });
},
{ block: 'b', attrs: { bemjson: '2' } },
'<div class="b" templ="1" bemjson="2"></div>');
});
});
9 changes: 9 additions & 0 deletions test/modes-js-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,13 @@ describe('Modes js', function() {
'<div class="b__e i-bem" data-bem=\'{"b__e":{}}\'></div>',
{ elemJsInstances: true });
});

it('should merge js from templates and js from bemjson', function() {
test(function() {
block('b').js()({ templ: '1' });
},
{ block: 'b', js: { bemjson: '2' } },
'<div class="b i-bem" data-bem=\'{"b":{"bemjson":' +
'"2","templ":"1"}}\'></div>');
});
});
11 changes: 11 additions & 0 deletions test/modes-mix-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,4 +150,15 @@ describe('Modes mix', function() {
elem: 'elem'
}, '<div class="b1__elem b2__elem"></div>');
});

it('should concat mix from templates with mix from bemjson', function() {
test(function() {
block('b1')(
mix()({ block: 'template' })
);
}, {
block: 'b1',
mix: { block: 'bemjson' }
}, '<div class="b1 template bemjson"></div>');
});
});
97 changes: 97 additions & 0 deletions test/runtime-apply-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
var fixtures = require('./fixtures')('bemhtml');
var test = fixtures.test;

describe('Runtime apply()', function() {
it('apply(\'content\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('content');
});
}, { block: 'b', content: 'test' },
'test');
});

it('apply(\'mix\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('mix');
});
}, { block: 'b', mix: 'test' },
'test');
});

it('apply(\'tag\') from tag()', function() {
test(function() {
block('b').tag()(function() {
return 'span';
});
block('b').tag()(function() {
return apply('tag');
});
}, { block: 'b', tag: 'a' },
'<span class="b"></span>');
});

it('apply(\'tag\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('tag');
});
}, { block: 'b', tag: 'a' },
'a');
});

it('apply(\'bem\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('bem');
});
}, { block: 'b', bem: false },
false);
});

it('apply(\'cls\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('cls');
});
}, { block: 'b', cls: 'test' },
'test');
});

it('apply(\'attrs\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('attrs');
});
}, { block: 'b', attrs: { target: '_blank' } },
{ target: '_blank' });
});

it('apply(\'js\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('js');
});
}, { block: 'b', js: { data: 'test' } },
{ data: 'test' });
});

it('apply(\'usermode\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('usermode');
});
}, { block: 'b', usermode: 'test' },
'test');
});

it('apply(\'undefusermode\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('undefusermode');
});
}, { block: 'b' },
undefined);
});
});

0 comments on commit 9d230c5

Please sign in to comment.