Git Product home page Git Product logo

bh's People

Contributors

awinogradov avatar dab avatar dfilatov avatar f0rmat1k avatar floatdrop avatar greyevil avatar ikokostya avatar innabelaya avatar mdevils avatar megatolya avatar mishanga avatar mursya avatar sameoldmadness avatar sipayrt avatar tadatuta avatar tarmolov avatar tormozz48 avatar yeti-or avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bh's Issues

Wrong require path if building BH tech with ENB

Trying to use "BH" for building HTML examples in my library https://github.com/toivonen/bouwdoos/tree/v1

I get files like desktop.sets/page/page.examples/myexample.bh.js and inside there is

var BH = require("../../node_modules/bh/lib/bh.js");

As if it tries to look for "node_modules" folder into "desktop.sets" folder, not in a root.

However I run enb not in the root but like this

varya-2:bouwdoos toivonen$ cd desktop.sets/
varya-2:desktop.sets toivonen$ ../node_modules/enb/bin/enb make
21:36:04.980 - build started
...

I did this to store .bem/enb-make.js file into desktop.sets folder because I might have more than one set and different configs for them.

Looks like BH + ENB works properly only if run from the root.

Should I rewrite my configs so that I will use only one? Or this can be fixed here?

Increase code coverage

=============================== Coverage summary ===============================
Statements   : 89.41% ( 346/387 )
Branches     : 80.84% ( 270/334 )
Functions    : 85% ( 34/40 )
Lines        : 89.53% ( 342/382 )
================================================================================

Should be 100%.

ctx.js(): extend `js` from bemjson

it('should not override user js', function() {
    bh.match('button', function(ctx) {
        ctx.js({ a: 2 });
    });
    bh.apply({ block: 'button', js: { x: 1 } })
        .should.equal('<div class="button i-bem" onclick="return {&quot;button&quot;:{&quot;a&quot;:2,&quot;x&quot;:1}}"></div>');
});

processBemJsonAsync

Тест в котором реализована асинхронная шаблонизация delfrrr@4e19ef8

После разговора с mdevils@ добавил applyBaseAsync и возможность изменять json дерево в асинхронных матчерах

Если в целом ок, то впиливаю в bh.js и делаю пул риквест

Move enb techs into separate `enb-bh` package

Сейчас пакет требует enb, а еще подключает пакеты, которые используются только в коде enb-технологий.

Есть несколько случаев, когда такие зависимости будут лишними:

  • Использовать bh, напрямую, без какого бы то ни было инструмента для сборки.
  • Использовать bh вместе с иными инструментами для сборки (bem-tools, gulp, grunt и т.д.), написав для этих инструментов технологий/плагинов, в которых будет требоваться bh-пакет.

Strange behaviour or I'm doing it wrong

https://gist.github.com/xdghcnt/1253e5f518215577fe22
As you can see, I want my test-block contained two logical sections that don't appear in the output, and it works as I planned:
a1 a2 a3 b1 b2 b3
Then I try to append some more elements in next level of defenition:
https://gist.github.com/xdghcnt/013d17c183e60a897e64
And I get this:
b1 b2 b3 a2 a3 b1 b2 b3 b4 b5 b6

So I have to use workaround like this for now:
https://gist.github.com/xdghcnt/cb688b5d0751cc27eeae
(First I used ctx._somekey to pass value to next level and it was really ugly, but now it seems not bad and may be even better than construction that producing described bug or smth.)

Also, this example works ok:
https://gist.github.com/xdghcnt/4aeb2d2f4c3c7d63d5b9

isFirst() is not working correctly

I have an bemjson object, it contains an array which first element is false or undefined

{ 
    block: 'button', 
    content: [
        false, // can olso be undefined
        { elem: 'inner' },
        { elem: 'inner' },
        { elem: 'inner' }
    ]
}

and matcher

bh.match('button__inner', function(ctx) {
    if (ctx.isFirst()) {
        ctx.mod('first', 'yes');
    }
    if (ctx.isLast()) {
        ctx.mod('last', 'yes');
    }
});

when I apply matcher to the bemjson getting

<div class="button">
  <div class="button__inner"></div>
  <div class="button__inner"></div>
  <div class="button__inner button__inner_last_yes"></div>
</div>

instead of expected

<div class="button">
  <div class="button__inner button__inner_first_yes"></div>
  <div class="button__inner"></div>
  <div class="button__inner button__inner_last_yes"></div>
</div>

TypeError when using elemMod matcher

module.exports = function (bh) {
    bh.match("test-block", function (ctx) {
        ctx.content([
            {
                elem:    'test-elem'
            },
            {
                elem:    'test-elem',
                elemMods:    {
                    mod: 'val'
                }
            }
        ]);
    });
    bh.match("test-block__test-elem", function (ctx) {
        ctx.content('test');
    });
    bh.match("test-block__test-elem_mod_val", function (ctx) {
        ctx.content('test');
    });
};

TypeError: Cannot read property 'mod' of undefined

Version is "3.1.2"
Ok in "2.2.0"

Xml escaping

http://nda.ya.ru/3QTRGF

bemjson
{ content: '<script>&amp;</script>' }

expected
<div>&lt;script&gt;&amp;amp;&lt;/script&gt;</div>

actual
<div><script>&amp;</script></div>

mix works inconsistently

mix mix classes and not tags, attrs and other mixes and it's a consistency problem.

tags

I want to use link block as mixin and not to hack it every time, so I want to write this way, but it's not working:

{
    block: 'media',
    elem: 'link',
    mix: [{ block: 'link', url: 'http://github.com/' }],
    content: [
        {
            elem: 'icon',
            url: 'duck.png'
        },
        {
            elem: 'title',
            content: 'comment'
        }
    ]
}

So I have to write this ugly code:

{
    block: 'link',
    mix: [{ block: 'media', elem: 'link' }],
    url: 'http://github.com/',
    content: [
        {
            block: 'media', elem: 'icon',
            url: 'duck.png'
        },
        {
            block: 'media', elem: 'title',
            content: 'comment'
        },
    ]
}

attrs

Then, I want to use one block for analytics tracking, and it have onclick attrs and goal option. I want to mix it and expect to see onclick attr on parent block like this way:

i-track.bh.js:

bh.match('i-track', function (ctx, json) {
    ctx.attr('onclick', 'track("' + json.goal + '")');
});

and use it like this:

{   
    block: 'link',
    mix: [{ block: 'i-track', goal: 'clck_goal' }],
    url: 'http://github.com/',
    content: 'Tracking link'
}

But it's not working too.

other mixes

I want to use custom font on my site. So I have one block i-face with mods for each custom font, but in reality only one font is being used in project, so it's reasonable to create shortcut block textbook, which have it's own mix with concrete textbook font.

In other words, I don't want to write mix: [{ block: 'i-font', mods: { face: 'textbook' }}] every time, because it's hard to remember and want to short it to this: mix: [{ block: 'textbook' }], where textbook block have such bh file:

bh.match('textbook', function (ctx, json) {
    ctx.mix([{ block: 'i-font', mods: { face: 'textbook' }}]);
});

And finally it's not working at all.

Разное поведение BH.apply и BEMHTML.apply, в случае отсутствия аргумента

Если в метод apply передать undefined, то BH и BEMHTML ведут себя по разному.
BEMHTML возвращает пустую строку, BH падает с ошибкой.
Замечено при переписывании модуля slider на клиенте - https://github.yandex-team.ru/lego/islands-components/blob/dev/common.blocks/slider/__ui/slider__ui.js#L324

Not working elemMods in mix

{ block: 'foo', mix: [{ elem: 'bar', elemMods: { baz: 'ololo' } }] }

rendered to:

"<div class="foo foo__bar"></div>"

Пусть ctx.mix() принимает на вход не только массив, но и один объект

Сейчас работает так:
ctx.mix([{
block: 'y-user',
userPic: userPic,
userLogin: userLogin
}]);

Если миксумая сущность одна, хочется передавать её объектом
ctx.mix({
block: 'y-user',
userPic: userPic,
userLogin: userLogin
});

То же самое в bemjson:
return {
block: 'y-user',
mix: {block: 'y-head', elem: 'user'}
}

Ignore empty nodes when counting position

    it('should ignore empty array items', function() {
        bh.match('button', function(ctx) {
            ctx.isFirst() && ctx.mod('pos', 'first');
            ctx.isLast() && ctx.mod('pos', 'last');
        });
        bh.apply([
            false,
            { block: 'button' },
            { block: 'button' },
            { block: 'button' },
            []
        ]).should.equal(
            '<div class="button button_pos_first"></div>' +
            '<div class="button"></div>' +
            '<div class="button button_pos_last"></div>'
        );
    });

Expected:

<div class="button button_pos_first"></div>
<div class="button"></div>
<div class="button button_pos_last"></div>

Actual:

<div class="button"></div>
<div class="button"></div>
<div class="button"></div>

ctx.content(0) gives empty tag

BEMJSON

{
    block: 'score',
    content: [
        { elem: 'goals', content: 0 },
        ' : ',
        { elem: 'goals', content: 3 }
    ]
}

BH:

bh.match('score__goals', function(ctx) {
    ctx.tag('span');
});

Result HTML

<div class="score">
    <span class="score__goals"></span> : <span class="score__goals">3</span>
</div>

processBemJson method modify passed object

var test = {
    block: 'input',
    mods: {
        type: 'textarea'
    },
    content: [
        { elem: 'control' }
    ]
};

var bhResult = bh.processBemJson(test);

console.log(test === bhResult); // => true

Add ctx.attrs method similar to ctx.mods

Сейчас есть метод ctx.attr, который позволяет работать только с одним атрибутом. Хочется иметь метод, который будет работать с объектами и позволить выставлять несколько атрибутов пачкой.

template-benchmark

I got curious, how good BH performance versus some popular template engines. There is a template-benchmark in a wild, so I wrote test runner for BH (this is my first time with BH, so be gentle it's maybe not the fastest version of BEMJSON).

Also I found no way to disable html escaping in bh code, so numbers for escaped and unescaped versions are the same.

P.S. this benchmark is using obsolete versions of engines, so numbers may vary.

Rendering 100000 templates:

ECT
  Escaped   : 1399ms
  Unescaped : 84ms
  Total     : 1483ms

Dust
  Escaped   : 1674ms
  Unescaped : 278ms
  Total     : 1952ms

Hogan.js
  Escaped   : 1964ms
  Unescaped : 534ms
  Total     : 2498ms

Gaikan
  Escaped   : 1691ms
  Unescaped : 50ms
  Total     : 1741ms

Fest
  Escaped   : 1651ms
  Unescaped : 169ms
  Total     : 1820ms

EJS without `with`
  Escaped   : 3335ms
  Unescaped : 224ms
  Total     : 3559ms

doT
  Escaped   : 2230ms
  Unescaped : 46ms
  Total     : 2276ms

Swig
  Escaped   : 3882ms
  Unescaped : 310ms
  Total     : 4192ms

Underscore
  Escaped   : 2355ms
  Unescaped : 1440ms
  Total     : 3795ms

EJS
  Escaped   : 5350ms
  Unescaped : 1448ms
  Total     : 6798ms

Eco
  Escaped   : 4927ms
  Unescaped : 577ms
  Total     : 5504ms

Handlebars.js
  Escaped   : 4653ms
  Unescaped : 2049ms
  Total     : 6702ms

Jade without `with`
  Escaped   : 6867ms
  Unescaped : 2617ms
  Total     : 9484ms

CoffeeKup
  Escaped   : 2794ms
  Unescaped : 5159ms
  Total     : 7953ms

BH
  Escaped   : 6095ms
  Unescaped : 5680ms // 5299ms - for manually disabled escaping
  Total     : 11775ms

Jade
  Escaped   : 11691ms
  Unescaped : 8164ms
  Total     : 19855ms

/cc @denchistyakov

bh.mix's doesn't applying when element is mixed

I have two blocks g-media and person. g-media has such bh.js:

module.exports = function (bh) {

    bh.match('g-media', function (ctx) {
        ctx.mix([{ block: 'i-clearfix' }], true);
    });

    bh.match('g-media__content-wrap', function (ctx) {
        ctx.mix([{ block: 'i-clearfix' }], true);
    });

};

This block applied bh correctly:

{
    block: 'g-media',
    content: [
        {
            elem: 'img-wrap',
            content: 'img'
        },
        {
            elem: 'content-wrap',
            content: 'content'
        }
    ]
}

But when I mix g-media and g-media__content-wrap nothing happens (I thought that person__content-wrap should have g-media__content-wrap and i-clearfix classes):

{
    block: 'person',
    mix: [{block: 'g-media'}],
    content: [
        {
            elem: 'photo',
            mix: [{block: 'g-media', elem: 'img-wrap'}],
            content: 'img'
        },
        {
            elem: 'content-wrap',
            mix: [{block: 'g-media', elem: 'content-wrap'}],
            content: 'content'
        }
    ]
}

Strange matching rules

I have found very "strange" behavior of matching rules. Suppose I have such setup of bh:

bh.match('block__elem', function () { console.log('block__elem'); });
bh.match('block__elem_emod', function () { console.log('block__elem_emod'); });
bh.match('block__elem_mod', function () { console.log('block__elem_mod'); });
bh.match('block_mod__elem', function () { console.log('block_mod__elem'); });
bh.match('block_emod__elem', function () { console.log('block_emod__elem'); });
bh.match('block_mod__elem_emod', function () { console.log('block_mod__elem_emod'); });

And applying them with this code:

console.log(bh.apply({block: 'block', elem: 'elem', mods: { mod: true, emod: true } }));

Which gives me this HTML:

<div class="block__elem block__elem_mod block__elem_emod"></div>

As you can see, HTML contains only three classes, but output of a program is:

block_mod__elem_emod
block_emod__elem
block_mod__elem
block__elem_mod
block__elem_emod
block__elem

Which indicates, that all six matchers has been applied. Is this expected behaviour?

Ignore incorrect mix

Right now if i call ctx.mix({}) without block, elem or mods key i'll see
<div class="block block">

Allow multiple match

bh.match(
    [ 'item__mark', 'item__text' ],
    function(ctx) {
        ctx.tag('span')
    }
)

tParam should not be lost after applyBase

Result: AssertionError: expected NaN to equal 333
Expected: successfully passed.

    it('should return tParam after applyBase #2', function() {
        bh.match('select', function(ctx) {
            ctx.tParam('foo', 222);
        });
        bh.match('select__control', function(ctx) {
            (ctx.tParam('foo') + ctx.tParam('bar')).should.equal(333);
        });
        bh.match('select__control', function(ctx) {
            ctx.tParam('bar', 111);
            ctx.applyBase();
        });
        bh.apply({ block: 'select', content: { elem: 'control' } });
    });

ctx.mod VS ctx.mix({mods : ...})

Shouldn't these be equivalent?

Bh = require('bh').BH,
lo = require('lodash');

var json1 = {block : 'button', elem : 'item'},
    json2 = lo.cloneDeep(json1),

    template1 = function (bh) {
        bh.match('button__item', function(ctx, json) {
            ctx.mix({mods: {'pos': 'last'}});
        });
    },
    template2 = function (bh) {
        bh.match('button__item', function(ctx, json) {
            ctx.mod('pos', 'last');
        });
    },

    bh1 = new Bh(),
    bh2 = new Bh();

template1(bh1);
bh1.apply(json1);
<div class="button__item button_pos_last"></div>
template2(bh2);
bh2.apply(json2);
<div class="button__item button__item_pos_last"></div>

mix: Do not add block class when mix with it's own mods

E.g. bemjson:

{
    block: 'bla'
}

with template

module.exports = function(bh) {
    bh.match('bla', function(ctx, json) {
        ctx.mix({
            mods: { m1: 'v1' }
        });
    });
}

results in <div class="bla bla bla_m1_v1"> (bla is duplicated).

Do not ignore `undefined` value in BEMJSON in attrs

For example,
we have BEMJSON

{
    block : 'bla',
    attrs : { a : undefined },
    content : 'bla'
}

and BH-template

bh.match('bla', function(ctx) {
    ctx.attrs({
        a : 0,
        b : 'some'
    });
});

and HTML

<div class="bla" a="0" b="some">bla</div>

So param from BEMJSON was ignored. But we expect that parameter will not be added

BH is incompatible with BEMHTML

I need to get some BEMJSON from BH layer and then compile it to HTML with BEMHTML. But BH process this structure:

{
    "block": "input",
    "mods": {
        "type": "textarea"
    },
    "content": [
        { "elem": "control" }
    ]
}

into this:

{
    "block": "input",
    "mods": {
        "type": "textarea"
    },
    "content": [
        {
            "elem": "control",
            "block": "input",
            "blockMods": {
                "type": "textarea"
            }
        }
    ],
    "blockMods": {
        "type": "textarea"
    }
}

And the fragment

{
    "elem": "control",
    "block": "input",
    "blockMods": {
        "type": "textarea"
    }
}

is parsed wrong with BEMHTML. If it was mods instead of blockMods, BEMHTML would work as I expected.

May be it is possible to add an option for this parameter? How could I solve the problem now?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.