Skip to content

Commit

Permalink
Merge pull request #381 from bem/applyNext-issue-380
Browse files Browse the repository at this point in the history
applyNext() and v4.x
  • Loading branch information
miripiruni authored Nov 10, 2016
2 parents c52d518 + e0f9718 commit 771135d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 149 deletions.
24 changes: 15 additions & 9 deletions lib/bemhtml/runtime/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ function Entity(bemhtml, block, elem, templates) {

// "Fast modes"
this.def = new Match(this);
this.tag = new Match(this, 'tag');
this.attrs = new Match(this, 'attrs');
this.tag = new Match(this);
this.attrs = new Match(this);
this.mod = 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');
this.content = new Match(this, 'content');
this.js = new Match(this);
this.mix = new Match(this);
this.bem = new Match(this);
this.cls = new Match(this);
this.content = new Match(this);

// "Slow modes"
this.rest = {};
Expand Down Expand Up @@ -99,7 +99,7 @@ Entity.prototype._initRest = function _initRest(key) {
this.rest[key] = this[key];
} else {
if (!this.rest.hasOwnProperty(key))
this.rest[key] = new Match(this, key);
this.rest[key] = new Match(this);
}
};

Expand Down Expand Up @@ -151,7 +151,9 @@ Entity.prototype.run = function run(context) {
};

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

var js;
if (context.ctx.js !== false)
Expand All @@ -163,6 +165,10 @@ 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.bemhtml.render(context,
this,
tag,
Expand Down
28 changes: 15 additions & 13 deletions lib/bemhtml/runtime/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -431,11 +431,13 @@ BEMHTML.prototype.render = function render(context,
if (js === true)
js = {};

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

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

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

if (mix) {
var m = this.renderMix(entity, mix, jsParams, addJSInitClass);
if (totalMix) {
var m = this.renderMix(entity, totalMix, jsParams, addJSInitClass);
out += m.out;
jsParams = m.jsParams;
addJSInitClass = m.addJSInitClass;
Expand Down Expand Up @@ -508,15 +515,10 @@ 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
if (isObj(attrs) || isObj(ctx.attrs)) {
attrs = utils.extend(attrs, ctx.attrs);

attrs = utils.extend(attrs, ctx.attrs);
if (attrs) {
var name; // TODO: do something with OmetaJS and YUI Compressor
/* jshint forin : false */
for (name in attrs) {
Expand Down Expand Up @@ -748,7 +750,7 @@ BEMHTML.prototype.applyNext = function applyNext() {
BEMHTML.prototype.applyMode = function applyMode(mode, changes) {
var match = this.match.entity.rest[mode];
if (!match)
return this.context.ctx[mode];
return;

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

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

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

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

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

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

var oldMask = mask;
var oldMatch = this.bemhtml.match;
Expand Down
138 changes: 15 additions & 123 deletions test/runtime-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,21 @@ describe('BEMHTML compiler/Runtime', function() {
'>Title link content</div></h2></div>');
});

it('applyNext() should not return value from BEMJSON (as it works in v1.x)',
function() {
test(function() {
block('link').mix()(function() {
return [ { block: 'mix' } ].concat(applyNext() || []);
});
block('root').content()({
block: 'link',
mix: { block: 'a', elem: 'b', elemMods: { c: 'd' } }
});
},
{ block: 'root' },
'<div class="root"><div class="link mix a__b a__b_c_d"></div></div>');
});

it('should check that mix do not overwrite jsParams', function() {
test(function() {
block('b1')(
Expand Down Expand Up @@ -1144,129 +1159,6 @@ describe('BEMHTML compiler/Runtime', function() {
});
});

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').target;
});
}, { block: 'b', attrs: { target: '_blank' } },
'_blank');
});

it('apply(\'js\') from def()', function() {
test(function() {
block('b').def()(function() {
return apply('js').data;
});
}, { block: 'b', js: { data: 'test' } },
'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);
});

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>');
});

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>');
});

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>');
});
});

describe('Modes cls', function() {
it('should trim cls', function() {
compile(function() {
Expand Down

0 comments on commit 771135d

Please sign in to comment.