Войти с помощью github

Написал небольшое дополнение к официальной документации project-stub. Опубликовал на Яндекс.Диск: https://yadi.sk/i/Sj3R7SCriAXyM

Я пока встречал примеры проектов на БЭМ которые на состоят только из статичного html. А как этот инструментарий bem tools работает с фреймворками php ? Ну например yii и laravel.

Я запускаю Gemini внутри gulp вот так:

.pipe(shell([
'./node_modules/gemini/bin/gemini test --reporter html --reporter flat ./tests/gemini-test.js'
])

shell — это плагин gulp-shell, но это не важно, потому что с run и exec то же самое.

Тесты проходят, в консоль есть вывод:

Total: 192 Passed: 136 Failed: 56 Skipped: 0

А вот для html-репорта показывает вот это: https://img-fotki.yandex.ru/get/3812/14441195.34/0_93389_de3023ad_orig При этом все нужные картинки сняты и диффы правильные.

Как мне это починить?

/cc @sevinf @arikon

Вот так выглядит тред если по каким-то причинам не подгрузилась аватарка (кстати, по каким?) https://img-fotki.yandex.ru/get/3712/14441195.34/0_93388_d499523_orig

Всем доброе утро!

Есть примерно следующая ситуация.

  1. Существует меню.
{
    block: 'navigation',
    content:[
        {
            elem: 'item',
            content: {
                block: 'link',
                url :'http://first-menu-link.com',
                content: 'Home',
                mix: {block: 'navigation', elem: 'link'}
            }
        },
        {
            elem: 'item',
            content: {
                block: 'link',
                url :'http://second-menu-link.com',
                content: 'Diensleitstungen',
                mix: {block: 'navigation', elem: 'link'}
            }
        }
    ]
}
  1. У некоторых элементов меню может быть второй уровень. Что бы понять к какому элементу первого уровня относиться второй уровень, введена переменная connectTo, значение которой будет равно элементу поля content из первого уровня.
{
    block: 'navigation-level-2',
    js: { connectTo: 'Diensleitstungen' },
    content: {...}
}
  1. При клике на любой из элементов меню 1-го уровня, создается кастомное событие showSubLevel с названием элемента меню, по которому был клик.
modules.define('navigation', ['i-bem__dom', 'jquery' ], function(provide, BEMDOM, $ ){
    provide(BEMDOM.decl(this.name,
        {
            onSetMod: {
                'js': {
                    'inited' : function() {
                        this.bindTo('link', 'click', function(e) {
                            this.emit('showSubLevel', $(e.target).text());
                        });
                    }
                }
            }
        }
    ));
});
  1. Меню второго уровня подписано на события showSubLevel
modules.define('navigation-level-2', ['i-bem__dom','jquery','navigation'], function(provide, BEMDOM, $, nav){
    provide(BEMDOM.decl(this.name,
        {
            onSetMod: {
                'js': {
                    'inited' : function() {
                        nav.on('showSubLevel', function(e, title) {

                            // Here I need a loop that iterates through all the 'navigation-level-2' blocks
                            if (this.params.connectTo === title) {
                                // Show sub navigation
                            }
                           // Loop ending

                        });
                    }
                }
            }
        }
    ));
});

Подскажите, как можно создать цикл, который пройдет по всем блокам, которые есть на странице и проверит у каждого свойство .params.connectTo?

Добрый день, насколько рационально использовать bem для небольших проектов 1-5 страниц верстки. Очень хотелось бы использовать готовую библиотеку блоков но есть несколько нюансов

Например если у блока переопределить css то в скомпилированном css будет несколько блоков например

.input {
font-size:14px;
}

И в переопределенный стиль

.input {
font-size:30px;
}

Или я неправильно что-то понимаю? Нет ли возможности при использовании блока из библиотеку сразу копировать его в папку проекта а не переопределять его поведение?

И возможно ли собрать проект например так:

js/
   script.js
css/
   style.css
html/
   index.html
   innerPage.html

И т.д.

Всем привет! Начал разбираться с i-bem.js и возникли некоторые вопросы. В качестве тестового примера взял статью на вашем форуме https://ru.bem.info/tutorials/quick-start-static/

Создал блок с произвольным названием taskmanager, здесь код BEMJSON-блока taskmanager https://github.com/Sergei-b84/test/blob/master/1.bemjson Динамическую функциональность данного блока описал в taskmanager.js файле https://github.com/Sergei-b84/test/blob/master/taskmanager.js Файловое размещение стандартное, поэтому описывать его не стал. В общем все отработало хорошо.

Теперь я хочу усложнить структуру моего блока taskmanager и сделать ее такой https://github.com/Sergei-b84/test/blob/master/2.bemjson А вот как переписать мой taskmanager.js файл не знаю. Помогите пожалуйста. Как искать элементы, если появились вложенные дополнительные блоки, как описать эти блоки? Жду ответа. Спасибо.

https://img-fotki.yandex.ru/get/6708/14441195.34/0_93358_f3167daf_orig

Снимаю полный скриншот этой страницы http://varya.me/styleguide/#/section/2.3 Хочу проигнорировать первый столбец списка, в котором меняется цвет фона. Для этого я использую suite.ignoreElements('.recent-posts__item .badge'); Но это игнорирует только первый элемент, подходящий под селектор. Скриншот получается вот такой https://img-fotki.yandex.ru/get/6708/14441195.34/0_93358_f3167daf_orig Как проигнорировать все подобные элементы?

/cc @arikon @sevinf

Здравствуйте! Есть проблема с подключением библиотек. Если конкретно bem-grid. Насколько я понял из руководств чтобы подключить библиотеку необходимо выполнить следующее:

  1. Прописать библиотеку в bower.json
  2. bower-npm-install для установки и подтягивания всех зависимостей
  3. Прописать уровень в make.js сборщика { path: 'libs/bem-grid/common.blocks', check: false }
  4. Запустить сервер

В результате стили не подтягиваются. Подскажите пожалуйста что я упустил. Пользуюсь enb. И еще один вопрос. Как можно подключить библиотеку на enb, если весь проект на bem-tools?

Здравствуйте. Допустим есть следующий блок в index.bemjson файле.

{
    block: 'my-block',
    myName: 'Jonny',
    content: ' '
}

В документации нашел как получить атрибут "myName" в технологии .bemhtml.


Как получить атрибут "myName" в технологии my-block.js?

modules.define('my-block', ['i-bem__dom'], function(provide, BEMDOM){
    provide(BEMDOM.decl(this.name,
        {
            onSetMod: {
                'js': {
                    'inited' : function() {
                       // how can I get my variable here [myName]?
                    }
                }
            }
        },
        {

        }
    ));
});

Проблема странная, причины мне не понятны, описываю как есть.

Использую Gemini вместе с PhantomJS, так что может этого его проблема. Но поскольку PhantomJS в рекомендациях на странице — все равно надо обратить внимание.

В общем, если снимать скриншоты с ряда страниц, и снимать их не с localhost, а с удаленного сервера, то всегда проблемы со снятием 1го скриншота. От страницы не зависит — проблемы с любой страницей, если она первая в списке. Если снимать те же самые скриншоты с localhost, такой проблемы нет.

Проблема решается добавлением в список "ненужной" первой страницы и использованием на ней skip():

var gemini = require('gemini');

var examples = [
  '1.2-1',
  '1.1',
  '2.1'
];

var pages = [];
pages.push({
  'name': 'index',
  url: '/styleguide/#'
});
examples.forEach(function(example) {
  pages.push({
    'name': example,
    url: '/styleguide/#/section/' + example + '/fullscreen'
  });
});

pages.forEach(function(page) {

  gemini.suite(page.name, function(suite) {
      if (page.name === 'index') {
        suite.skip();
      }
      suite.setUrl(page.url)
          .setCaptureElements('body')
          .capture('plain', function(actions, find){

              actions.waitForElementToShow('shadow-dom', 7000);


          });
  });

});

/cc @arikon @sevinf

Может немного не в тему.. На главной странице Яндекса, увидел именование блока, которое не соответствует классическому БЭМ. Например: b-regioniconsicon http://i.imgur.com/OnYlwVt.png Процитирую Виталия Харисова: "классы типа blockelemelem___elem говорят о том, что верстальщик ничего не понял."

Кто-нибудь может объяснить этот диссонанс?

Всем привет! Такой у меня вопрос:

Есть блок aside, он располагается сбоку и в общем случае выглядит вот так: ссылка на картинку Логотип вынесен в отдельный блок logo, у него есть текстовые элементы logo__bold, logo__thin и logo__desc. У aside есть модификатор --collapsed, который делает его узким: ещё ссылка на картинку

Как тут можно грамотно распространить влияние модификатора aside--collapsed на элементы блока logo? Как .aside--collapsed .logo__desc { display: none; }, но в контексте БЭМ.

Делаю скриншоты нескольких страниц (условия одинаковые). Скриншоты делаются везде, кроме одной страницы. Чтобы понять почему, я бы хотела видеть картинку: что видно после timeout. Поскольку дебажить нормально пока нельзя, я хоть какую-то информацию из этого получу. Это как-то возможно сделать? /cc @arikon @sevinf

Стоит задача - обернуть вендорный js в ymodules.

При этом, это должно быть технологией. Т.к. вендорный JS используется не только для самого приложения, но и в тестах. В общем применение банальной нотации борщика в исходнике не подходит - нужен промежуточное состояние.

Нужно из ?.vendor.js превратить в ?.js.

Внутри ?.vendor.js

Будет что-то типа такого:

(function(name, ctx, define) {
    var module = define.call(ctx, ctx);
    typeof modules === 'object'?
        modules.define(name, function(provide) { provide(module); }) :
        (ctx[name] = module);
}('backbone', this, function(global) {
    /*vendorof:../../../libs/backbone/backbone.js*/;
    return global.Backbone;
}));

modules.define('backbone', function (provide, Backbone) {
    'use strict';

    Backbone.prototype.someMethod = replaceMethod;
    provide(Backbone.noConflict());
});

Все текущие примеры собирают код в конечный продукт. Мне же нужен промежуточный ?.js который будет содержать в себе код вендора.

А уже потом собираться с остальным js.

Вот в этой ветке https://ru.bem.info/forum/-439/ @tadatuta сказал:

Кроме того, BEMTREE асинхронный, что позволяет во время выполнения шаблона сходить за данными

1) Сходить куда? Например в базу данных или к HTTP API? 2) Можно ли где-нибудь почитать код, примеры как это лучше применять на практике?

При миграции на bem-core больше нельзя указать контекст для поиска элемента строкой. Нужно обязательно передать jQuery-объект. Ну да, лучше так вообще не делать ;)

https://github.com/bem/bem-bl/blob/support/2.x/blocks-common/i-bem/__dom/i-bem__dom.js#L791 vs https://github.com/bem/bem-core/blob/v2/common.blocks/i-bem/__dom/i-bem__dom.js#L725

Было:

var nestedElem = this.findElem('parent-elem', 'nested-elem');

Стало:

var nestedElem = this.findElem(this.findElem('parent-elem'), 'nested-elem'),
    oneMoreElem = this.findElem(this.elem('another-elem'), 'nested-elem');

https://github.com/enb-bem/enb-magic-platform

Верно ли понимаю, что это таск менеджер?

И можно с помощью него запускать сборки разных mode одной командой enb?

Из описания https://ru.bem.info/method/faq/#Почему-нельзя-делать-общий-сброс-стилей-reset человеку не знакомому с БЭМ непонятно - почему нельзя делать общий сброс (или нормализацию). Впрочем, мне, как знакомому - непонятно тоже. Как я догадываюсь, речь идет о том, что библиотека блоков Яндекса (bem-bl) расчитана на определенные дефолтные стили у html-элементов , а reset собьёт их, поэтому css reset в Яндексе нельзя. Но ведь это личное дело Яндекса какие у него базовые стили? Опять-таки если мы говорим о надежности и универсальности - то в блоке должны быть прописаны все нужные стили, исходя из того что может быть reset. Или, если проще, то только те, которые отличаются от Normalize, который сейчас стандарт де-факто.

Я задавал аналогичный вопрос пару лет назад тут: http://clubs.ya.ru/bem/replies.xml?item_no=1777, мне кажется сказали что у Яндекса просто свой normalize. Увы это сейчас нельзя открыть и найти поиском на новом форуме тоже.

В процессе миграции на bem-core обнаружил, что метод liveBindTo больше не принимает объект с ключом elemName, а ожидает строго elem. В руководстве по миграции об этом не указано, к сожалению.

Пишу отдельным топиком, тк это уже подтема — написание тестов.

Меня интересует как сделать так, чтобы скриншот был снят только после какого-то события (например, на объекте window). Это важно для тестирование SPA, они не сразу отрисовываются, а из JavaScript.

Для простоты я пока не пользуюсь своим кастомным событием, а просто проверяю, работает ли с load. Я не нашла в документации возможности реагировать на события, поэтому пытаюсь пользоваться флагом и функциями executeJS и waitForJSCondition.

Текст теста вот такой:

var gemini = require('gemini');

var examples = [
  '1.1',
  '1.2-1',
  '2.1'
];

examples.forEach(function(example) {

  gemini.suite(example, function(suite) {
      suite.setUrl('/styleguide/#/section/' + example + '/fullscreen')
          .setCaptureElements('body')
          .capture('plain', function(actions, find){
              actions.executeJS(function(window) {

                  window.addEventListener('load', function() {
                      window.doTake = true;
                  });

              })
              actions.waitForJSCondition(function(window) {
                  return window.doTake;
              }, 3000);
          });
  });

});

Но ничего не получается, на снятии скриншотов получаю отлуп "Condition was not met in 3000ms".

Важно отметить, что если я просто пользуюсь actions.wait(3000), то все скриншоты снимаются как надо.

Теперь вопросы:

  • Правильно ли я делаю ожидание события на window или может быть есть какой-то более простой путь?
  • Почему не работает?
  • Как дебажить тесты? Я хочу писать console.log и видеть, что там происходит.

/cc @arikon @sevinf

В руководстве по миграции https://ru.bem.info/libs/bem-core/v2.6.0/migration/#Деструктор написано, что «Вызывать base для того, чтобы у блоков работал базовый деструктор, определенный в i-bemdom, больше не нужно.»

Однако в блоке input в bem-components родительский деструктор вызывается явно. https://github.com/bem/bem-components/blob/v2/desktop.blocks/input/input.js#L49-L57

Вопрос — когда такое делать необходимо?

Привет!

Продолжаю пытаться начать работать с Gemini, есть несколько вопросов. Я прочла https://ru.bem.info/forum/396/ но там вроде моих вопросов нет. Так что вот.

  1. Я хочу сравнивать интерфейс на моём localhost с продакшеном. Какова последовательность действий?
  2. Если запускать ./node_modules/gemini/bin/gemini test --reporter html tests/gemini-test.js, то ничего не происходит. Это от того что все тесты проходят? (Опция --flat показывает их пройденными). Как посмотреть html-отчет даже в случае пройденных тестов?
  3. Тот же тест через gemini-ui даёт такую картину: https://img-fotki.yandex.ru/get/34/14441195.34/0_92c3d_f85a7e6e_orig Мне не понятен этот интерфейс. Что с чем сравнивается? Я ожидала увидеть 2 скриншота для каждого браузера: эталонный и снятый сейчас. На кнопки я нажимала, меняется только фон. В gemini-report я просмотрела, что есть файлы chrome~ref.png, но в визуальном интерфейсе не понятно, где что.
  4. После того как я сняла идеальные скриншоты с продакшена, я хочу сравнить их с "испорченной" локальной копией. В конфиге я указала локальный сайт: https://github.com/varya/varya.github.com/blob/features/gemini/.gemini.yml И изменила фон у блока, теперь он выглядит вот так https://img-fotki.yandex.ru/get/4423/14441195.34/0_92c3e_54e46af6_orig То есть разница должна быть. Однако мой тест всё равно проходит. Что я делаю не так? Если что, вот ветка с моим сайтом: https://github.com/varya/varya.github.com/tree/features/gemini Чтобы запустить сайт, надо сделать docpad run. UPD: проблема в том, что после каждого изменения надо перезапускать PhantomJS
  5. Как попроще указать большой список страниц для тестирования, если на них не предполагается делать никаких действий?
  6. Можно ли писать исполняемый JavaScript в файлах тестов? Например, чтобы сформировать похожие тесты динамически.
  7. Как в конфиге указать, что нужно протестировать в нескольких windowSize?
  8. Зачем отдельно запускать phantomjs? Вот этот инструмент https://github.com/BBC-News/wraith не требует такого. Нельзя сделать так же?
  9. Если в Gemini нельзя сделать так чтобы не запускать PhantomJS в соседнем окне, то как это могу сделать я? Например, в своих gulp тасках. где я вызываю Gemini. В идеале я хочу, чтобы мои разработчики запускали в одном окне что-то вроде gulp gemini-test, и всё работало. Могу оформить в пакет :-)

Спасибо!

Привет!

Пробую Gemini. Сначала решила снять эталонные скриншоты со своего блога. Снимаю блок .social-ico, сайт http://varya.me/ Вот какие скриншоты он мне генерирует: https://img-fotki.yandex.ru/get/4702/14441195.33/0_92bd0_deca9d4f_orig

Почему на скриншоте блок горизонтальный? У меня же на сайте вертикально расположено.

Текст теста вот такой:

var gemini = require('gemini');

gemini.suite('varya', function(suite) {
    suite.setUrl('/')
        .setCaptureElements('.social-ico')
        .capture('plain');
});

Всем привет. Собираю БЭМ-проект по описанию zxqfox https://ru.bem.info/forum/175/ Далее запускаю сервер с помощью ENB: Проверяю результат по ссылке http://lookingschools.com:8080/desktop.bundles/index/index.html Открывается страница с примерами блоков библиотеки. Только вот селекты какие-то кривые. При нажатии страница мерцает. Подскажите, что не так и где править? Если делаю так: git clone https://github.com/bem/project-stub.git --depth 1 --branch v1.0.0 start-project cd start-project npm install , то все отрабатывает отлично. Но так как у меня php проект, пользуюсь описанием zxqfox.

Привет всем!

Начинаю изучать БЭМ. Есть тестовый проект с одним блоком и одним элементом в нем. Пытаюсь собрать. Безуспешно, категорически не могу получить html. Хотя сборка вроде бы проходит без ошибок.

Структура проекта до сборки:

├── common.block
│.....└── b-head
│.............├── b-head.bemhtml
│.............├── b-head.css
│.............└── __title
│....................├── b-head__title.bemhtml
│....................└── b-head__title.css
└── pages.bundles
 ......└── index
 ..............└── index.bemjson.js

"Проект" принципиально сделан с нуля, без использования bem-components - чтобы понять как создаются блоки, как из bemhtml получается просто html, как собирается весь проект.

Контент файлов: ---------------- b-head.bemhtml -----------

block('b-head')(
   tag()('h1'),
   content()(
      {elem : 'title', content : 'Yo!'}
   ) 
)

-------------- b-head__title.bemhtml --------------

block('b-head').elem('title').tag()('i')

-------------- index.bemjson.js ----------------------

({
    block: 'b-head',
    content: [
        { elem: 'title', content: 'H' },
    ]
})

CSS пока не важно, больше ничего не трогал. (код выложен на https://bitbucket.org/shbma/codepr-6_bem3)

Сборку выполняю по инструкции https://ru.bem.info/tools/bem/bem-tools/commands/

команда: bem create -l pages.bundles -b index -T bemdecl.js результат: успешно cоздается файл декларации pages.bundles/index/index.bemdecl.js

команда: bem create -l common.block -b b-head -T bemdecl.js результат: успешно создался файл декларации common.block/b-head/b-head.bemdecl.js

команда: bem build -l common.block -l pages.bandles -d pages.bundles/index/index.bemdecl.js -t deps.js -o pages.bundles/index -n index результат: успешно создался файл зависимостей pages.bundles/index/index.deps.js

команда: bem build -l common.block -l pages.bandles -d pages.bundles/index/index.deps.js -t css -o pages.bundles/index -n index результат: создался файл импорта стилей pages.bundles/index/index.css

команда: bem make результат:

22:56:32.837 - info: bem 0.9.0
22:56:33.082 - info: Graph:
== root
 all
   build
     pages.bundles*

22:56:33.090 - info: [i] Going to build 'all' [1]
22:56:33.108 - info: [t] isValid() time for "build" [1]: 1ms
22:56:33.108 - info: [*] make 'build' [1]
22:56:33.108 - info: [t] Build time for "build" [1]: 1ms
22:56:33.109 - info: [t] isValid() time for "all" [1]: 0ms
22:56:33.109 - info: [*] make 'all' [1]
22:56:33.110 - info: [t] Build time for "all" [1]: 1ms
22:56:33.111 - info: [t] Build total: 270ms

ничего не произошло - html файлов не появилось

Пробуем по-другому:

команда: bem server результат:

23:00:52.405 - info: bem 0.9.0
23:00:52.412 - info: Project root is '/home/michael/code-production/les6_bem/bem-tools-test'
23:00:52.658 - info: Graph:
== root
 all
   build
     pages.bundles*

23:00:52.668 - info: Server is listening on port 8080. Point your browser to http://localhost:8080/

На запрос http://localhost:8080/index.html отдает 404 ошибку, в консоли пишет

warn: *** HTTP error: 404, /home/michael/code-production/les6_bem/bem-tools-test/index.html

И опять-таки никаких html-файлов внутри папок проекта не образуется

Есть какие-то варианты решения проблемы?

P.S. Извиняюсь, если этот пост покажется очевидной банальностью тому, кто в теме. В БЭМ я чайник, шерстю сайт, есть отличные вебинары по сборке css и js, теория по синтаксису bemhtml (правда не нашел ничего по сборке таких вот нано-проектов), но в моей голове мозаика материалов пока не складывается. Я уперся лбом в стену и не понимаю куда копать, потому и задаю сюда вопросы.

Я тут услышал что был какой то конкурс по разработке проекта на полном стеке bem. Планируется ли в будущем ? И откуда про это можно узнать ?

Есть ли в enb server возможность использовать его не только для отдачи собранной статики, но и как api сервер? Хочется параллельно разрабатывать js и тестировать с api

Привет всем! Хочу изменить стили для одной кнопки в теме islands. Пытался добавить модификатор, который будет переопределять свойства, но так не получилось (стили из темы перекрывают стили моего модификатора). Если создаю у себя на проекте button/_theme/button_theme_islands.styl и перекрываю нужные свойства из bem-components на свои, то переопределяются свойства всех кнопок. Может есть какое-то интересное встроенное решение для выборочного переопределения стилей.

Коллеги, подскажите в i-bem.js есть замечательные методы

 block.delMod(elem, 'hidden');
 block.setMod(elem, 'visible', true);

С помощью них можно манипулировать модификаторами у элементов. Так, как элементы это обычная jquery коллекция, применив определенный фильтр по коллекции, я могу получить отфильтрованные элементы в виде jquery коллекции. Метод удаления модификатора работает замечательно с выборкой, а сеттер вершает модификатор на все элементы не обращая внимания на коллекцию что я передаю.

var blockList =  this.findBlockOutside('page').findBlockInside('abstract-section-list'),
    searchResult,
    searchReg = new RegExp(filterVal, 'i');

blockList.setMod(blockList.elem('item'), 'hidden', true);

searchResult = blockList.elem('item').filter(function() {
    return searchReg.test($(this).attr('data-month'));
});
blockList.delMod(searchResult, 'hidden'); /*работает удалет у нужных элементов*/
blockList.setMod(searchResult, 'visible', true);/*вешает на все элементы*/

Вопрос, как вешать модификатор на отфильтрованную выборку элементов?.