Repository: bem/bh (js)

Issue:
jsElem
Add ability to parametrize addition of `i-bem` classname for elems with js params.

If `jsElem: true` then add `i-bem` class for blocks and elems.
If `jsElem: false` then add `i-bem` class only for blocks.

See:

* https://github.com/bem/bh/issues/119
* https://github.com/enb-bem/enb-bh/issues/26

Pull request description:
Added `jsElem` option
Resolved #146 

Patch:
diff --git a/lib/bh.js b/lib/bh.js
index 2eaea42..6fb2612 100644
--- a/lib/bh.js
+++ b/lib/bh.js
@@ -48,6 +48,7 @@ function BH() {
     this._optJsAttrName = 'onclick';
     this._optJsAttrIsJs = true;
     this._optJsCls = 'i-bem';
+    this._optJsElem = true;
     this._optEscapeContent = false;
     this._optNobaseMods = false;
     this.utils = {
@@ -564,6 +565,9 @@ BH.prototype = {
         if (options.jsCls !== undefined) {
             this._optJsCls = options.jsCls;
         }
+        if (options.hasOwnProperty('jsElem')) {
+            this._optJsElem = options.jsElem;
+        }
         if (options.clsNobaseMods) {
             this._optNobaseMods = true;
         }
@@ -1009,6 +1013,8 @@ BH.prototype = {
                     }
                 }
 
+                var addJSInitClass = this._optJsCls && (this._optJsElem || !json.elem);
+
                 var mixes = json.mix;
                 if (mixes && mixes.length) {
                     for (i = 0, l = mixes.length; i < l; i++) {
@@ -1023,6 +1029,9 @@ BH.prototype = {
                                 if (mix.js) {
                                     (jsParams = jsParams || {})[mixBase] = mix.js === true ? {} : mix.js;
                                     hasMixJsParams = true;
+                                    if (!addJSInitClass) {
+                                        addJSInitClass = mixBlock && (this._optJsCls && (this._optJsElem || !mixElem));
+                                    }
                                 }
                             }
                         }
@@ -1030,7 +1039,7 @@ BH.prototype = {
                 }
 
                 if (jsParams) {
-                    if (this._optJsCls) cls += ' ' + this._optJsCls;
+                    if (addJSInitClass) cls += ' ' + this._optJsCls;
                     var jsData = (!hasMixJsParams && json.js === true ?
                         '{"' + base + '":{}}' :
                         jsAttrEscape(JSON.stringify(jsParams)));


Test patch:
diff --git a/test/test.options.js b/test/test.options.js
index ca7d181..15ce155 100644
--- a/test/test.options.js
+++ b/test/test.options.js
@@ -61,6 +61,19 @@ describe('options', function() {
             );
         });
 
+        it('should use jsElem option', function() {
+            bh.setOptions({ jsElem: false });
+            bh.apply({ block: 'button', elem: 'box', js: true }).should.equal(
+                '<div class="button__box" onclick=\'return {"button__box":{}}\'></div>'
+            );
+        });
+
+        it('should use jsElem option for mixed element', function() {
+            bh.setOptions({ jsElem: false });
+            bh.apply({ block: 'button', elem: 'box', mix: { block: 'icon', elem: 'wrap', js: true } }).should.equal(
+                '<div class="button__box icon__wrap" onclick=\'return {"icon__wrap":{}}\'></div>');
+        });
+
         it('should use clsNobaseMods options', function() {
             bh.setOptions({ clsNobaseMods: true });
             bh.apply({
diff --git a/test/test.toHtml.js b/test/test.toHtml.js
index 4bd27b2..a4083eb 100644
--- a/test/test.toHtml.js
+++ b/test/test.toHtml.js
@@ -259,6 +259,10 @@ describe('bh.toHtml()', function() {
             bh.apply({ block: 'icon', content: 'submit', mix: { block: 'button', elem: 'control', js: true } }).should.equal(
                 '<div class="icon button__control i-bem" onclick=\'return {"button__control":{}}\'>submit</div>');
         });
+        it('should set `i-bem` class on mixed block', function() {
+            bh.apply({ block: 'button', elem: 'box', content: 'submit', mix: { block: 'icon', js: true } }).should.equal(
+                '<div class="button__box icon i-bem" onclick=\'return {"icon":{}}\'>submit</div>');
+        });
     });
 
     describe('cls', function() {