Skip to content

Commit

Permalink
BEMTREE: js(), mix(), mods(), elemMods() added
Browse files Browse the repository at this point in the history
  • Loading branch information
miripiruni committed Dec 7, 2016
1 parent 929b688 commit 895b5e9
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 43 deletions.
3 changes: 2 additions & 1 deletion docs/en/5-templates-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,8 @@ More information about [apply()](7-runtime.md#apply).
## BEMTREE
Only the [def](#def), [content](#content), [replace](#replace),
In BEMTREE engine only data related modes avaliable: [def](#def), [js](#js), [mix](#mix),
[mods](#mods), [elemMods](#elemMods), [content](#content), [replace](#replace),
[extend](#extend) and [wrap](#wrap) modes are used by the BEMTREE engine. User-defined modes can also be used. The other modes described in the documentation above can only be used in BEMHTML.
***
Expand Down
6 changes: 4 additions & 2 deletions docs/ru/5-templates-syntax.md
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,10 @@ block('control')(
## BEMTREE
Движком BEMTREE используются только режимы [def](#def), [content](#content) и
режимы-хелперы [replace](#replace), [extend](#extend) и [wrap](#wrap). Пользовательские режимы тоже могут быть использованы. Остальные режимы, описанные в документации выше, применимы только к BEMHTML.
В движке BEMTREE используются только режимы ориентированные на данные: [def](#def), [js](#js), [mix](#mix), [mods](#mods), [elemMods](#elemMods), [content](#content) и
режимы-хелперы [replace](#replace), [extend](#extend) и [wrap](#wrap).
Пользовательские режимы тоже могут быть использованы. Остальные режимы
ориентированные на HTML, описанные в документации выше, применимы только к BEMHTML.
***
Expand Down
28 changes: 8 additions & 20 deletions lib/bemhtml/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,9 @@ function Entity(bemxjst) {

this.jsClass = null;

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

Expand Down Expand Up @@ -73,23 +69,15 @@ Entity.prototype.defaultBody = function defaultBody(context) {

// Notice: other modes must be after context.mods/context.elemMods changes

var tag = this.tag.exec(context);
var content = this.content.exec(context);
var attrs = this.attrs.exec(context);
var mix = this.mix.exec(context);
var js = this.js.exec(context);
var bem = this.bem.exec(context);
var cls = this.cls.exec(context);

return this.bemxjst.render(context,
this,
tag,
js,
bem,
cls,
mix,
attrs,
content,
this.tag.exec(context),
this.js.exec(context),
this.bem.exec(context),
this.cls.exec(context),
this.mix.exec(context),
this.attrs.exec(context),
this.content.exec(context),
mods,
elemMods);
};
29 changes: 17 additions & 12 deletions lib/bemtree/entity.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var inherits = require('inherits');
var Match = require('../bemxjst/match').Match;
var BemxjstEntity = require('../bemxjst/entity').Entity;

function Entity() {
Expand All @@ -9,17 +8,23 @@ function Entity() {
inherits(Entity, BemxjstEntity);
exports.Entity = Entity;

Entity.prototype._initRest = function _initRest(key) {
if (key === 'default') {
this.rest[key] = this.def;
} else if (key === 'content') {
this.rest[key] = this[key];
} else {
if (!this.rest.hasOwnProperty(key))
this.rest[key] = new Match(this, key);
Entity.prototype.defaultBody = function defaultBody(context) {
var mods = this.mods.exec(context);
context.mods = mods;

var elemMods;
if (context.ctx.elem) {
elemMods = this.elemMods.exec(context);
context.elemMods = elemMods;
}
};

Entity.prototype.defaultBody = function defaultBody(context) {
return this.bemxjst.render(context, this, this.content.exec(context));
// Notice: other modes must be after context.mods/context.elemMods changes

return this.bemxjst.render(context,
this,
this.content.exec(context),
this.js.exec(context),
this.mix.exec(context),
mods,
elemMods);
};
23 changes: 19 additions & 4 deletions lib/bemtree/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var inherits = require('inherits');
var BEMXJST = require('../bemxjst');
var Entity = require('./entity').Entity;
var utils = require('../bemxjst/utils');

function BEMTREE() {
BEMXJST.apply(this, arguments);
Expand Down Expand Up @@ -39,11 +40,25 @@ BEMTREE.prototype.runMany = function runMany(arr) {
return out;
};

BEMTREE.prototype.render = function render(context, entity, content) {
var ctx = context.ctx;
var isBEM = !!(ctx.block || ctx.elem || ctx.bem); // TODO: check
BEMTREE.prototype.render = function render(context, entity, content, js, mix,
mods, elemMods) {
var ctx = utils.extend({}, context.ctx);
var isBEM = !!(ctx.block || ctx.elem || ctx.bem);

if (typeof content === 'undefined') return ctx;
if (typeof js !== 'undefined')
ctx.js = js;

if (typeof mix !== 'undefined')
ctx.mix = mix;

if (!entity.elem && mods && Object.keys(mods).length > 0)
ctx.mods = utils.extend(ctx.mods || {}, mods);

if (entity.elem && elemMods && Object.keys(elemMods).length > 0)
ctx.elemMods = utils.extend(ctx.elemMods || {}, elemMods);

if (typeof content === 'undefined')
return ctx;

ctx.content = this.renderContent(content, isBEM);

Expand Down
23 changes: 23 additions & 0 deletions lib/bemxjst/entity.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ function Entity(bemxjst, block, elem, templates) {

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

// "Slow modes"
Expand All @@ -35,6 +39,25 @@ Entity.prototype.init = function init(block, elem) {
this.elem = elem;
};

var keys = {
content: true,
mix: true,
js: true,
mods: true,
elemMods: true
};

Entity.prototype._initRest = function _initRest(key) {
if (key === 'default') {
this.rest[key] = this.def;
} else if (keys[key]) {
this.rest[key] = this[key];
} else {
if (!this.rest.hasOwnProperty(key))
this.rest[key] = new Match(this, key);
}
};

function contentMode() {
return this.ctx.content;
}
Expand Down
170 changes: 166 additions & 4 deletions test/bemtree-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ describe('BEMTREE engine tests', function() {
});

block('b1').mod('a', 'b').content()('ok');
}, { block: 'b1' }, { block: 'b1', content: 'ok' });
}, { block: 'b1' }, { block: 'b1', mods: { a: 'b' }, content: 'ok' });
});

it('should inherit mods properly', function() {
Expand Down Expand Up @@ -397,9 +397,13 @@ describe('BEMTREE engine tests', function() {
content: {
block: 'b2'
}
}, { block: 'b1', content: [
'yes', { block: 'b2' }
] });
}, {
block: 'b1',
mods: { a: 'yes' },
content: [
'yes', { block: 'b2' }
]
});
});
});

Expand Down Expand Up @@ -530,4 +534,162 @@ describe('BEMTREE engine tests', function() {
null, '', undefined, { block: 'b1' }, undefined, 0
]);
});

describe('modes', function() {
it('should support wrap() mode', function() {
test(function() {
block('b1').wrap()(function() {
return {
block: 'wrap',
content: this.ctx
};
});
},
{ block: 'b1' },
{ block: 'wrap', content: { block: 'b1' } });
});

it('should support replace() mode', function() {
test(function() {
block('b1').replace()(function() {
return { block: 'a2' };
});
},
{ block: 'b1' },
{ block: 'a2' });
});

it('should support extend() mode', function() {
test(function() {
block('b1')(
extend()(function() {
return { test: 42 };
}),
content()(function() {
return this.test;
})
);
},
{ block: 'b1' },
{ block: 'b1', content: 42 });
});

it('should support def() mode', function() {
test(function() {
block('b1').def()(function() {
return 42;
});
},
{ block: 'b1' },
42);
});

it('should support content() mode', function() {
test(function() {
block('b1').content()(function() {
return 42;
});
},
{ block: 'b1' },
{ block: 'b1', content: 42 });
});

it('should support appendContent() mode', function() {
test(function() {
block('b1').appendContent()(function() {
return 42;
});
},
{ block: 'b1', content: 1 },
{ block: 'b1', content: [ 1, 42 ] });
});

it('should support prependContent() mode', function() {
test(function() {
block('b1').prependContent()(function() {
return 42;
});
},
{ block: 'b1', content: 1 },
{ block: 'b1', content: [ 42, 1 ] });
});

it('should support js() mode', function() {
test(function() {
block('b1').js()(true);
},
{ block: 'b1' },
{ block: 'b1', js: true });
});

it('should support addJs() mode', function() {
test(function() {
block('b1').addJs()(function() {
return { more: 'sea' };
});
},
{ block: 'b1', js: { river: 'neva' } },
{ block: 'b1', js: { river: 'neva', more: 'sea' } });
});

it('should support mix() mode', function() {
test(function() {
block('b1').mix()(function() {
return { block: 'mixed' };
});
},
{ block: 'b1' },
{ block: 'b1', mix: { block: 'mixed' } });
});

it('should support addMix() mode', function() {
test(function() {
block('b1').addMix()(function() {
return { block: 'mixed' };
});
},
{ block: 'b1', mix: { block: 'i-bem' } },
{ block: 'b1', mix: [ { block: 'i-bem' }, { block: 'mixed' } ] });
});

it('should support mods() mode', function() {
test(function() {
block('b1').mods()(function() {
return { disabled: 'true' };
});
},
{ block: 'b1' },
{ block: 'b1', mods: { disabled: 'true' } });
});

it('should support addMods() mode', function() {
test(function() {
block('b1').addMods()(function() {
return { disabled: 'true' };
});
},
{ block: 'b1', mods: { size: 'm' } },
{ block: 'b1', mods: { size: 'm', disabled: 'true' } });
});

it('should support elemMods() mode', function() {
test(function() {
block('b1').elem('e').elemMods()(function() {
return { size: 'm' };
});
},
{ block: 'b1', elem: 'e' },
{ block: 'b1', elem: 'e', elemMods: { size: 'm' } });
});

it('should support addElemMods() mode', function() {
test(function() {
block('b1').elem('e').addElemMods()(function() {
return { disabled: 'true' };
});
},
{ block: 'b1', elem: 'e', elemMods: { size: 'm' } },
{ block: 'b1', elem: 'e', elemMods: { size: 'm', disabled: 'true' } });
});
});
});

0 comments on commit 895b5e9

Please sign in to comment.