From fad15d2796497d3bcf66d036e515ffcc1daf02f5 Mon Sep 17 00:00:00 2001 From: miripiruni Date: Mon, 30 Oct 2017 17:40:02 +0300 Subject: [PATCH] BEMXJST: modifier templates should apply before def() (fix #482) --- docs/en/5-templates-syntax.md | 2 +- docs/ru/5-templates-syntax.md | 2 +- lib/bemhtml/entity.js | 3 --- lib/bemtree/entity.js | 3 --- lib/bemxjst/entity.js | 8 +++++++ test/modes-def-test.js | 42 +++++++++++++++++++++++++++++++++++ 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/docs/en/5-templates-syntax.md b/docs/en/5-templates-syntax.md index 89c1d84e..79e5a376 100644 --- a/docs/en/5-templates-syntax.md +++ b/docs/en/5-templates-syntax.md @@ -350,7 +350,7 @@ def()(value) The `def` mode (short for "default") has a special status. It is responsible for generating the result as a whole. This mode defines the list of other modes and the order to go through them, as well as the build procedure for getting the final representation of the HTML element or BEMJSON from the parts generated in the other modes. -This is a special mode that shouldn’t be used unless truly necessary. A user-defined template that redefines `def` disables calls of the other modes by default. +This is a special mode that shouldn’t be used unless truly necessary. A user-defined template that redefines `def` disables calls of the other modes by default, except `mods`, `elemMods`, `addMods` and `addElemMods`. #### tag diff --git a/docs/ru/5-templates-syntax.md b/docs/ru/5-templates-syntax.md index cb10b5a0..48010e7a 100644 --- a/docs/ru/5-templates-syntax.md +++ b/docs/ru/5-templates-syntax.md @@ -347,7 +347,7 @@ def()(value) Особый статус имеет режим `def` (сокращение от default), который отвечает за генерацию результата в целом. В рамках этого режима задан набор и порядок прохождения остальных режимов, а также определена процедура сборки финального представления HTML-элемента или BEMJSON из фрагментов, сгенерированных в остальных режимах. -Режим является особым и не стоит использовать его без особой надобности. Пользовательский шаблон, переопределяющий `def`, отключает вызовы остальных режимов по умолчанию. +Режим является особым и не стоит использовать его без особой надобности. Пользовательский шаблон, переопределяющий `def`, отключает вызовы остальных режимов по умолчанию, кроме `mods`, `elemMods`, `addMods` и `addElemMods`, которые выполняются до `def`. #### tag diff --git a/lib/bemhtml/entity.js b/lib/bemhtml/entity.js index c64baba1..efc1c970 100644 --- a/lib/bemhtml/entity.js +++ b/lib/bemhtml/entity.js @@ -47,9 +47,6 @@ Entity.prototype._keys = { }; Entity.prototype.defaultBody = function(context) { - context.mods = this.mods.exec(context); - if (context.ctx.elem) context.elemMods = this.elemMods.exec(context); - return this.bemxjst.render(context, this, this.tag.exec(context), diff --git a/lib/bemtree/entity.js b/lib/bemtree/entity.js index f03235ee..b458a537 100644 --- a/lib/bemtree/entity.js +++ b/lib/bemtree/entity.js @@ -9,9 +9,6 @@ inherits(Entity, BemxjstEntity); exports.Entity = Entity; Entity.prototype.defaultBody = function(context) { - context.mods = this.mods.exec(context); - if (context.ctx.elem) context.elemMods = this.elemMods.exec(context); - return this.bemxjst.render(context, this, this.content.exec(context), diff --git a/lib/bemxjst/entity.js b/lib/bemxjst/entity.js index 2bd5a543..971e75b3 100644 --- a/lib/bemxjst/entity.js +++ b/lib/bemxjst/entity.js @@ -117,6 +117,14 @@ Entity.prototype.prepend = function(other) { // NOTE: This could be potentially compiled into inlined invokations Entity.prototype.run = function(context) { + if (this.mods.count !== 0) { + context.mods = this.mods.exec(context); + } + + if (context.ctx.elem && this.elemMods.count !== 0) { + context.elemMods = this.elemMods.exec(context); + } + if (this.def.count !== 0) return this.def.exec(context); diff --git a/test/modes-def-test.js b/test/modes-def-test.js index f9d30a01..68e50013 100644 --- a/test/modes-def-test.js +++ b/test/modes-def-test.js @@ -1,5 +1,7 @@ var assert = require('assert'); var bemhtml = require('./fixtures')('bemhtml'); +var fixtures = require('./fixtures')('bemhtml'); +var test = fixtures.test; describe('Modes def', function() { it('should throw error when args passed to def mode', function() { @@ -9,4 +11,44 @@ describe('Modes def', function() { }); }); }); + + it('mods() templates should apply', function() { + test(function() { + block('a').def()('NO'); + block('a').mods()({ m: true }); + block('a').mod('m').def()('YES'); + }, + { block: 'a' }, + 'YES'); + }); + + it('addMods() templates should apply', function() { + test(function() { + block('a').def()('NO'); + block('a').addMods()({ m: true }); + block('a').mod('m').def()('YES'); + }, + { block: 'a' }, + 'YES'); + }); + + it('elemMods() templates should apply', function() { + test(function() { + block('a').elem('e').def()('NO'); + block('a').elem('e').elemMods()({ m: true }); + block('a').elem('e').elemMod('m').def()('YES'); + }, + { block: 'a', elem: 'e' }, + 'YES'); + }); + + it('addEemMods() templates should apply', function() { + test(function() { + block('a').elem('e').def()('NO'); + block('a').elem('e').addElemMods()({ m: true }); + block('a').elem('e').elemMod('m').def()('YES'); + }, + { block: 'a', elem: 'e' }, + 'YES'); + }); });