Repository: bem/bh (js)

Issue:
Bug with ctx.js()
```js
// ({block: 'block'})

bh.match('block', function(ctx) {
    ctx.js(false);
    ctx.js(true);
});

// <div class="block i-bem" data-bem='{"block":{}}'></div>
```

After the second call to `ctx.js(true)` the value of `js` is true. Should be `false`.

`js()` implementation in BH: https://github.com/bem/bh/blob/master/lib/bh.js#L437-L445
It seems that after the first call `json.js` stays `undefined`.
On the second call this happens: `this.extend(undefined, true)`
And then returns this: https://github.com/bem/bh/blob/master/lib/bh.js#L92


Pull request description:
Fix bug with `ctx.js()`
fix #160

Patch:
diff --git a/lib/bh.js b/lib/bh.js
index cc85b81..0fb968f 100644
--- a/lib/bh.js
+++ b/lib/bh.js
@@ -435,12 +435,10 @@ function BH() {
          * @returns {Boolean|Object|Ctx}
          */
         js: function(js, force) {
-            if (js === undefined) {
-                return this.ctx.js;
-            }
-            this.ctx.js = force ?
-                (js === true ? {} : js) :
-                js ? this.extend(this.ctx.js, js) : this.ctx.js;
+            var ctx = this.ctx;
+            if (js === undefined) return ctx.js;
+            if (force || ctx.js === undefined) ctx.js = js;
+            else if (ctx.js !== false) this.extend(ctx.js, js);
             return this;
         },
         /**


Test patch:
diff --git a/test/test.js.js b/test/test.js.js
index 3bcf2b3..422033a 100644
--- a/test/test.js.js
+++ b/test/test.js.js
@@ -28,6 +28,13 @@ describe('ctx.js()', function() {
         bh.apply({ block: 'button' }).should.equal('<div class="button"></div>');
     });
 
+    it('should not override user declarations', function() {
+        bh.match('button', function(ctx) {
+            ctx.js(true);
+        });
+        bh.apply({ block: 'button', js: false }).should.equal('<div class="button"></div>');
+    });
+
     it('should extend user js', function() {
         bh.match('button', function(ctx) {
             ctx.js({ a: 2 });
@@ -36,7 +43,7 @@ describe('ctx.js()', function() {
             .should.equal('<div class="button i-bem" onclick=\'return {"button":{"x":1,"a":2}}\'></div>');
     });
 
-    it('should not override later declarations', function() {
+    it('should not override later declarations #1', function() {
         bh.match('button', function(ctx) {
             ctx.js(false);
         });
@@ -46,6 +53,16 @@ describe('ctx.js()', function() {
         bh.apply({ block: 'button' }).should.equal('<div class="button i-bem" onclick=\'return {"button":{}}\'></div>');
     });
 
+    it('should not override later declarations #2', function() {
+        bh.match('button', function(ctx) {
+            ctx.js(true);
+        });
+        bh.match('button', function(ctx) {
+            ctx.js(false);
+        });
+        bh.apply({ block: 'button' }).should.equal('<div class="button"></div>');
+    });
+
     it('should override later declarations with force flag', function() {
         bh.match('button', function(ctx) {
             ctx.js(true, true);