├── .bowerrc ├── .enb ├── make.js └── techs │ └── template-i18n.js ├── .gitignore ├── README.md ├── bin ├── app.js └── data.js ├── bower.json ├── configs ├── common │ ├── app.json │ └── redirects.js ├── dev │ ├── app.json │ └── borschik ├── production │ ├── app.json │ └── borschik └── testing │ ├── app.json │ └── borschik ├── docs ├── config.ru.md ├── data_compiling.ru.md ├── middleware.ru.md ├── model.ru.md └── people │ ├── avatars │ └── andrey-kuznetsov.png │ └── people.json ├── model └── index.js ├── package.json └── src ├── blocks ├── common.blocks │ ├── anchor │ │ ├── anchor.styl │ │ └── anchor.svg │ ├── author │ │ ├── __avatar │ │ │ ├── _no-image │ │ │ │ ├── author__avatar_no-image_120.png │ │ │ │ ├── author__avatar_no-image_80.png │ │ │ │ └── author__avatar_no-image_yes.styl │ │ │ ├── _size │ │ │ │ ├── author__avatar_size_large.styl │ │ │ │ ├── author__avatar_size_medium.styl │ │ │ │ └── author__avatar_size_small.styl │ │ │ ├── author__avatar.bemhtml │ │ │ ├── author__avatar.deps.yaml │ │ │ └── author__avatar.styl │ │ ├── __contact-item │ │ │ └── author__contact-item.styl │ │ ├── __contact │ │ │ └── author__contact.styl │ │ ├── __data-wrapper │ │ │ └── author__data-wrapper.styl │ │ ├── __e-mail │ │ │ ├── author__e-mail.bemhtml │ │ │ ├── author__e-mail.png │ │ │ └── author__e-mail.styl │ │ ├── __github │ │ │ ├── author__github.bemhtml │ │ │ ├── author__github.png │ │ │ └── author__github.styl │ │ ├── __info │ │ │ ├── author__info.bemhtml │ │ │ └── author__info.styl │ │ ├── __label │ │ │ └── author__label.styl │ │ ├── __name │ │ │ └── author__name.bemhtml │ │ ├── __skype │ │ │ ├── author__skype.bemhtml │ │ │ ├── author__skype.png │ │ │ └── author__skype.styl │ │ ├── __twitter │ │ │ ├── author__twitter.bemhtml │ │ │ ├── author__twitter.png │ │ │ └── author__twitter.styl │ │ ├── __value │ │ │ └── author__value.styl │ │ ├── _view │ │ │ ├── author_view_full.bemhtml │ │ │ ├── author_view_full.styl │ │ │ ├── author_view_grid-cell.bemhtml │ │ │ ├── author_view_grid-cell.styl │ │ │ ├── author_view_simple.bemhtml │ │ │ └── author_view_simple.styl │ │ ├── author.bemtree │ │ ├── author.deps.yaml │ │ └── author.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ ├── block-docs │ │ ├── __description │ │ │ ├── _inline │ │ │ │ └── block-docs__description_inline_yes.styl │ │ │ ├── block-docs__description.deps.yaml │ │ │ └── block-docs__description.styl │ │ ├── __sublevel │ │ │ └── block-docs__sublevel.styl │ │ ├── __title │ │ │ ├── block-docs__title.bemhtml │ │ │ └── mix │ │ │ │ ├── block-docs__title_mix_post-title-inline.bemhtml │ │ │ │ └── block-docs__title_mix_post-title.bemhtml │ │ ├── __value │ │ │ ├── block-docs__value.bemhtml │ │ │ └── block-docs__value.styl │ │ ├── block-docs.bemtree │ │ ├── block-docs.deps.yaml │ │ └── block-docs.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ ├── block-example │ │ ├── __anchor │ │ │ ├── block-example__anchor.bemhtml │ │ │ ├── block-example__anchor.deps.yaml │ │ │ └── block-example__anchor.styl │ │ ├── __blank │ │ │ ├── block-example__blank.bemhtml │ │ │ └── block-example__blank.deps.yaml │ │ ├── __header │ │ │ └── block-example__header.styl │ │ ├── __link │ │ │ ├── _icon │ │ │ │ ├── block-example__link_icon_blank.png │ │ │ │ ├── block-example__link_icon_blank.styl │ │ │ │ └── block-example__link_icon_source.styl │ │ │ ├── _source │ │ │ │ └── block-example__link_source_copy.styl │ │ │ ├── block-example__link.deps.yaml │ │ │ └── block-example__link.styl │ │ ├── __live-spin │ │ │ ├── block-example__live-spin.bemhtml │ │ │ ├── block-example__live-spin.deps.yaml │ │ │ └── block-example__live-spin.styl │ │ ├── __live-wrap │ │ │ └── block-example__live-wrap.styl │ │ ├── __live │ │ │ ├── block-example__live.bemhtml │ │ │ └── block-example__live.styl │ │ ├── __qr │ │ │ ├── block-example__qr.png │ │ │ └── block-example__qr.styl │ │ ├── __source-code │ │ │ ├── _view │ │ │ │ ├── block-example__source-code_view_iframe.bemhtml │ │ │ │ ├── block-example__source-code_view_iframe.styl │ │ │ │ └── block-example__source-code_view_text.bemhtml │ │ │ ├── block-example__source-code.deps.yaml │ │ │ └── block-example__source-code.styl │ │ ├── __source-copy │ │ │ ├── block-example__source-copy.bemhtml │ │ │ ├── block-example__source-copy.deps.yaml │ │ │ ├── block-example__source-copy.js │ │ │ └── block-example__source-copy.styl │ │ ├── __source-item │ │ │ └── block-example__source-item.styl │ │ ├── __source-switcher │ │ │ ├── _active │ │ │ │ └── block-example__source-switcher_active_yes.styl │ │ │ ├── block-example__source-switcher.bemhtml │ │ │ ├── block-example__source-switcher.deps.yaml │ │ │ └── block-example__source-switcher.styl │ │ ├── __source │ │ │ ├── _visible │ │ │ │ └── block-example__source_visible_yes.styl │ │ │ ├── block-example__source.deps.yaml │ │ │ └── block-example__source.styl │ │ ├── _view │ │ │ ├── block-example_view_default.bemtree │ │ │ └── block-example_view_inline.bemtree │ │ ├── block-example.bemhtml │ │ ├── block-example.bemtree │ │ ├── block-example.deps.yaml │ │ ├── block-example.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ ├── block-example.js │ │ └── block-example.styl │ ├── block-jsdoc │ │ ├── __access │ │ │ └── block-jsdoc__access.styl │ │ ├── __item │ │ │ └── block-jsdoc__item.styl │ │ ├── __selection │ │ │ ├── _color │ │ │ │ ├── block-jsdoc__selection_color_gold.styl │ │ │ │ └── block-jsdoc__selection_color_grey.styl │ │ │ ├── block-jsdoc__selection.deps.yaml │ │ │ └── block-jsdoc__selection.styl │ │ ├── __title │ │ │ ├── block-jsdoc__title.bemhtml │ │ │ ├── block-jsdoc__title.deps.yaml │ │ │ └── mix │ │ │ │ ├── block-jsdoc__title_mix_post-title-inline.bemhtml │ │ │ │ └── block-jsdoc__title_mix_post-title.bemhtml │ │ ├── __type-value │ │ │ └── block-jsdoc__type-value.bemhtml │ │ ├── __type │ │ │ ├── block-jsdoc__type.bemhtml │ │ │ └── block-jsdoc__type.styl │ │ ├── __types │ │ │ └── block-jsdoc__types.styl │ │ ├── __value │ │ │ └── block-jsdoc__value.styl │ │ ├── block-jsdoc.bemtree │ │ ├── block-jsdoc.deps.yaml │ │ └── block-jsdoc.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ ├── block │ │ ├── __header │ │ │ └── block__header.styl │ │ ├── __message │ │ │ └── block__message.styl │ │ ├── __title │ │ │ ├── block__title.bemhtml │ │ │ └── block__title.styl │ │ ├── block.bemhtml │ │ ├── block.bemtree │ │ ├── block.deps.yaml │ │ ├── block.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ ├── block.ie.styl │ │ ├── block.js │ │ └── block.styl │ ├── code │ │ └── code.styl │ ├── content-wrapper │ │ ├── content-wrapper.bemhtml │ │ ├── content-wrapper.deps.yaml │ │ ├── content-wrapper.ie.styl │ │ └── content-wrapper.styl │ ├── content │ │ ├── _view │ │ │ ├── content_view_author.bemtree │ │ │ ├── content_view_author.deps.yaml │ │ │ ├── content_view_authors.bemtree │ │ │ ├── content_view_authors.deps.yaml │ │ │ ├── content_view_block.bemtree │ │ │ ├── content_view_block.deps.yaml │ │ │ ├── content_view_post.bemtree │ │ │ ├── content_view_post.deps.yaml │ │ │ ├── content_view_post.styl │ │ │ ├── content_view_posts.bemtree │ │ │ ├── content_view_posts.deps.yaml │ │ │ ├── content_view_tags.bemtree │ │ │ └── content_view_tags.deps.yaml │ │ ├── content.deps.yaml │ │ ├── content.js │ │ └── content.styl │ ├── error-billboard │ │ ├── __logo │ │ │ ├── error-billboard__logo.styl │ │ │ └── error-billboard__logo.svg │ │ ├── error-billboard.bemhtml │ │ ├── error-billboard.deps.yaml │ │ ├── error-billboard.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ └── error-billboard.styl │ ├── flex │ │ ├── _type │ │ │ ├── flex_type_content.ie.styl │ │ │ └── flex_type_content.styl │ │ ├── flex.ie.styl │ │ └── flex.styl │ ├── font │ │ └── _face │ │ │ ├── font_face_ekibastuz.styl │ │ │ └── font_face_textbook.styl │ ├── form │ │ └── form.bemhtml │ ├── header │ │ ├── header.bemhtml │ │ ├── header.bemtree │ │ ├── header.deps.yaml │ │ ├── header.ie.styl │ │ └── header.styl │ ├── highlightjs │ │ ├── highlightjs.js │ │ └── highlightjs.styl │ ├── i-global │ │ ├── i-global.bemtree │ │ └── i-global.deps.yaml │ ├── icon │ │ ├── _action │ │ │ ├── icon_action.ie.styl │ │ │ ├── icon_action.styl │ │ │ ├── icon_action_search.png │ │ │ └── icon_action_search.svg │ │ └── _view │ │ │ ├── icon_view.styl │ │ │ ├── icon_view_desktop.svg │ │ │ ├── icon_view_github.svg │ │ │ ├── icon_view_touch-pad.svg │ │ │ ├── icon_view_touch-phone.svg │ │ │ └── icon_view_warning.svg │ ├── input │ │ └── input.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ ├── lang-switch │ │ ├── lang-switch.bemhtml │ │ ├── lang-switch.deps.yaml │ │ ├── lang-switch.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ └── lang-switch.styl │ ├── lib-switch │ │ ├── lib-switch.bemhtml │ │ ├── lib-switch.deps.yaml │ │ ├── lib-switch.ie.styl │ │ ├── lib-switch.js │ │ └── lib-switch.styl │ ├── link │ │ ├── _type │ │ │ └── link_type_block.styl │ │ ├── link.deps.yaml │ │ └── link.styl │ ├── logo │ │ ├── _type │ │ │ ├── logo_type_bem.ie.styl │ │ │ ├── logo_type_bem.png │ │ │ ├── logo_type_bem.styl │ │ │ └── logo_type_bem.svg │ │ ├── logo.bemhtml │ │ ├── logo.deps.yaml │ │ └── logo.styl │ ├── menu-list │ │ ├── __delimeter │ │ │ └── menu-list__delimeter.styl │ │ ├── __group-select │ │ │ ├── menu-list__group-select.deps.yaml │ │ │ └── menu-list__group-select.styl │ │ ├── __level-choose │ │ │ ├── menu-list__level-choose.deps.yaml │ │ │ └── menu-list__level-choose.styl │ │ ├── __level-group │ │ │ ├── _hide │ │ │ │ └── menu-list__level-group_hide_yes.styl │ │ │ └── menu-list__level-group.deps.yaml │ │ ├── __link │ │ │ ├── _size │ │ │ │ ├── menu-list__link_size_normal.styl │ │ │ │ └── menu-list__link_size_small.styl │ │ │ ├── _type │ │ │ │ └── menu-list__link_type_select.styl │ │ │ ├── menu-list__link.deps.yaml │ │ │ └── menu-list__link.styl │ │ ├── __option │ │ │ └── menu-list__option.bemhtml │ │ ├── _type │ │ │ ├── menu-list_type_default.bemtree │ │ │ ├── menu-list_type_default.ie.styl │ │ │ ├── menu-list_type_default.styl │ │ │ ├── menu-list_type_header.bemtree │ │ │ ├── menu-list_type_header.deps.yaml │ │ │ ├── menu-list_type_header.styl │ │ │ ├── menu-list_type_level.bemhtml │ │ │ ├── menu-list_type_level.bemtree │ │ │ ├── menu-list_type_level.js │ │ │ ├── menu-list_type_level.styl │ │ │ ├── menu-list_type_main.bemhtml │ │ │ ├── menu-list_type_main.bemtree │ │ │ ├── menu-list_type_main.deps.yaml │ │ │ └── menu-list_type_main.styl │ │ ├── menu-list.bemhtml │ │ ├── menu-list.deps.yaml │ │ ├── menu-list.js │ │ └── menu-list.styl │ ├── menus │ │ ├── menus.bemtree │ │ └── menus.deps.yaml │ ├── metrika │ │ └── metrika.bemhtml │ ├── page │ │ ├── __css │ │ │ └── page__css.bemtree │ │ ├── __fullscreen │ │ │ └── page__fullscreen.styl │ │ ├── __js │ │ │ └── page__js.bemtree │ │ ├── _fullscreen │ │ │ └── page_fullscreen.styl │ │ ├── _header │ │ │ ├── page_header.bemhtml │ │ │ ├── page_header.bemtree │ │ │ ├── page_header.deps.yaml │ │ │ └── page_header.styl │ │ ├── _page │ │ │ └── page_page_error.bemhtml │ │ ├── _search │ │ │ ├── page_search.deps.yaml │ │ │ └── page_search.js │ │ ├── _touch │ │ │ └── page_touch_yes.styl │ │ ├── page.bemhtml │ │ ├── page.bemtree │ │ ├── page.deps.yaml │ │ ├── page.js │ │ └── page.styl │ ├── post │ │ ├── __author │ │ │ ├── post__author.bemhtml │ │ │ ├── post__author.bemtree │ │ │ └── post__author.styl │ │ ├── __categories │ │ │ ├── post__categories.bemhtml │ │ │ ├── post__categories.deps.yaml │ │ │ └── post__categories.styl │ │ ├── __content │ │ │ ├── post__content.bemhtml │ │ │ └── post__content.styl │ │ ├── __date │ │ │ ├── post__date.bemhtml │ │ │ └── post__date.styl │ │ ├── __deps │ │ │ ├── post__deps.bemhtml │ │ │ └── post__deps.styl │ │ ├── __summary │ │ │ └── post__summary.bemhtml │ │ ├── __tags │ │ │ ├── post__tags.bemhtml │ │ │ └── post__tags.styl │ │ ├── __title-line │ │ │ ├── post__title-line.bemhtml │ │ │ ├── post__title-line.deps.yaml │ │ │ ├── post__title-line.ie.styl │ │ │ └── post__title-line.styl │ │ ├── __title │ │ │ ├── _inline │ │ │ │ └── post__title_inline_yes.styl │ │ │ ├── post__title.bemhtml │ │ │ ├── post__title.deps.yaml │ │ │ └── post__title.styl │ │ ├── __translation │ │ │ └── post__translation.styl │ │ ├── __url │ │ │ ├── post__url.bemhtml │ │ │ ├── post__url.deps.yaml │ │ │ └── post__url.styl │ │ ├── _view │ │ │ ├── post_view_full.bemhtml │ │ │ ├── post_view_full.bemtree │ │ │ ├── post_view_full.styl │ │ │ ├── post_view_list-item.bemtree │ │ │ └── post_view_list-item.styl │ │ ├── post.deps.yaml │ │ ├── post.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ └── post.styl │ ├── posts │ │ ├── __list │ │ │ ├── posts__list.bemtree │ │ │ ├── posts__list.deps.yaml │ │ │ └── posts__list.styl │ │ ├── __title │ │ │ └── posts__title.styl │ │ ├── posts.bemhtml │ │ ├── posts.bemtree │ │ └── posts.deps.yaml │ ├── search-button │ │ ├── __text │ │ │ └── search-button__text.styl │ │ ├── _active │ │ │ └── search-button_active.styl │ │ ├── _text │ │ │ ├── search-button_text.bemtree │ │ │ └── search-button_text.deps.yaml │ │ ├── search-button.bemtree │ │ ├── search-button.deps.yaml │ │ ├── search-button.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ └── search-button.styl │ ├── search-form │ │ ├── _type │ │ │ ├── search-form_type_default.bemtree │ │ │ ├── search-form_type_default.deps.yaml │ │ │ └── search-form_type_default.js │ │ ├── search-form.bemhtml │ │ ├── search-form.deps.yaml │ │ ├── search-form.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ └── search-form.styl │ ├── search-item │ │ ├── __category │ │ │ └── search-item__category.styl │ │ ├── __choose │ │ │ ├── search-item__choose.deps.yaml │ │ │ └── search-item__choose.styl │ │ ├── __description │ │ │ ├── search-item__description.bemhtml │ │ │ ├── search-item__description.deps.yaml │ │ │ └── search-item__description.styl │ │ ├── __level │ │ │ ├── _icon │ │ │ │ └── search-item__level_icon.styl │ │ │ ├── search-item__level.deps.yaml │ │ │ └── search-item__level.styl │ │ ├── __levels │ │ │ ├── search-item__levels.deps.yaml │ │ │ └── search-item__levels.styl │ │ ├── __post │ │ │ └── search-item__post.styl │ │ ├── __title │ │ │ ├── search-item__title.deps.yaml │ │ │ └── search-item__title.styl │ │ ├── _type │ │ │ ├── search-item_type_block.bemtree │ │ │ ├── search-item_type_block.styl │ │ │ ├── search-item_type_post.bemtree │ │ │ └── search-item_type_post.styl │ │ ├── search-item.bemhtml │ │ ├── search-item.deps.yaml │ │ ├── search-item.i18n │ │ │ ├── en.js │ │ │ └── ru.js │ │ ├── search-item.js │ │ └── search-item.styl │ ├── search-panel │ │ ├── __content │ │ │ ├── _loading │ │ │ │ └── search-panel__content_loading.styl │ │ │ ├── search-panel__content.deps.yaml │ │ │ └── search-panel__content.styl │ │ ├── __spin │ │ │ ├── search-panel__spin.deps.yaml │ │ │ └── search-panel__spin.styl │ │ ├── search-panel.bemhtml │ │ ├── search-panel.bemtree │ │ ├── search-panel.deps.yaml │ │ ├── search-panel.js │ │ └── search-panel.styl │ ├── search-results │ │ ├── __error-text │ │ │ └── search-results__error-text.styl │ │ ├── __error │ │ │ └── search-results__error.styl │ │ ├── search-results.bemtree │ │ └── search-results.deps.yaml │ ├── styling │ │ └── styling.styl │ ├── tabs │ │ ├── __header │ │ │ └── tabs__header.styl │ │ ├── __pane │ │ │ └── tabs__pane.styl │ │ ├── __tab │ │ │ └── tabs__tab.styl │ │ ├── _theme │ │ │ ├── tabs_theme_default.bemhtml │ │ │ ├── tabs_theme_default.ie.styl │ │ │ └── tabs_theme_default.styl │ │ ├── tabs.bemhtml │ │ ├── tabs.deps.yaml │ │ ├── tabs.js │ │ └── tabs.styl │ └── zeroclipboard │ │ └── zeroclipboard.js └── server.blocks │ ├── app-error │ ├── _type │ │ └── app-error_type_http.node.js │ ├── app-error.deps.yaml │ └── app-error.node.js │ ├── app │ ├── app.deps.yaml │ └── app.node.js │ ├── builder │ ├── builder.deps.yaml │ └── builder.node.js │ ├── config │ └── config.node.js │ ├── constants │ └── constants.node.js │ ├── helper │ ├── _type │ │ ├── helper_type_bundles.node.js │ │ └── helper_type_statics.node.js │ └── helper.deps.yaml │ ├── index │ ├── index.deps.yaml │ └── index.node.js │ ├── logger │ ├── logger.deps.yaml │ └── logger.node.js │ ├── middleware │ ├── __error │ │ ├── middleware__error.deps.yaml │ │ └── middleware__error.node.js │ ├── __html-cache │ │ ├── middleware__html-cache.deps.yaml │ │ └── middleware__html-cache.node.js │ ├── __lang-switcher │ │ └── middleware__lang-switcher.node.js │ ├── __locale │ │ ├── middleware__locale.deps.yaml │ │ └── middleware__locale.node.js │ ├── __logger │ │ ├── middleware__logger.deps.yaml │ │ └── middleware__logger.node.js │ ├── __metrika │ │ ├── middleware__metrika.deps.yaml │ │ └── middleware__metrika.node.js │ ├── __page-menu │ │ ├── middleware__page-menu.deps.yaml │ │ └── middleware__page-menu.node.js │ ├── __page-meta │ │ ├── middleware__page-meta.deps.yaml │ │ └── middleware__page-meta.node.js │ ├── __page-title │ │ ├── middleware__page-title.deps.yaml │ │ └── middleware__page-title.node.js │ ├── __page │ │ ├── middleware__page.deps.yaml │ │ └── middleware__page.node.js │ ├── __proxy-example │ │ ├── middleware__proxy-example.deps.yaml │ │ └── middleware__proxy-example.node.js │ ├── __redirect │ │ ├── middleware__redirect.deps.yaml │ │ └── middleware__redirect.node.js │ ├── __router │ │ ├── middleware__router.deps.yaml │ │ └── middleware__router.node.js │ ├── __search │ │ ├── middleware__search.deps.yaml │ │ └── middleware__search.node.js │ ├── __service │ │ ├── middleware__service.deps.yaml │ │ └── middleware__service.node.js │ ├── __slashes │ │ └── middleware__slashes.node.js │ ├── middleware.deps.yaml │ └── middleware.node.js │ ├── model │ ├── model.deps.yaml │ └── model.node.js │ ├── provider │ ├── _type │ │ ├── provider_type_disk.node.js │ │ └── provider_type_file.node.js │ └── provider.deps.yaml │ ├── template │ ├── template.deps.yaml │ └── template.node.js │ ├── updater │ ├── updater.deps.yaml │ └── updater.node.js │ └── util │ ├── util.deps.yaml │ └── util.node.js ├── bundles ├── desktop.bundles │ └── common │ │ └── common.bemdecl.js └── errors.bundles │ ├── error-404 │ └── error-404.bemjson.js │ └── error-500 │ └── error-500.bemjson.js ├── data ├── coa.js ├── commands │ ├── development.js │ ├── production.js │ └── testing.js ├── common.js ├── config.js ├── constants.js ├── logger.js ├── make │ ├── add_dynamic_nodes.js │ ├── add_library_nodes.js │ ├── index.js │ ├── load-sources.js │ ├── load_libraries.js │ ├── load_people.js │ ├── override-links.js │ ├── save.js │ └── sitemapXML.js ├── model │ ├── base.js │ ├── block.js │ ├── dynamic.js │ ├── index.js │ ├── level.js │ ├── person.js │ ├── post.js │ ├── search │ │ ├── block.js │ │ ├── index.js │ │ ├── level.js │ │ ├── library.js │ │ └── version.js │ ├── tag.js │ └── version.js ├── providers │ ├── index.js │ ├── provider-file.js │ ├── provider-gh-api.js │ ├── provider-gh-https.js │ └── provider-ya-disk.js ├── renderer.js └── util.js └── www ├── ZeroClipboard.swf ├── favicon.ico ├── humans.txt └── robots.txt /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "libs" 3 | } -------------------------------------------------------------------------------- /.enb/techs/template-i18n.js: -------------------------------------------------------------------------------- 1 | var vow = require('vow'), 2 | vfs = require('enb/lib/fs/async-fs'); 3 | 4 | module.exports = require('enb/lib/build-flow').create() 5 | .name('i18n-all') 6 | .target('target', '?.template.i18n.js') 7 | .useSourceListFilenames('langTargets', []) 8 | .useSourceText('sourceTarget', '?.template.js') 9 | .builder(function (langFilenames, source) { 10 | return vow.all( 11 | langFilenames.map(function (filename) { 12 | return vfs.read(filename); 13 | }) 14 | ).then(function (langResults) { 15 | return langResults.join('\n') + source; 16 | }); 17 | }) 18 | .createTech(); 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | .settings 4 | .project 5 | .borschik 6 | .bower.json 7 | 8 | configs/current 9 | 10 | node_modules 11 | npm-debug.log 12 | logs 13 | libs 14 | backups 15 | cache 16 | 17 | .enb/tmp 18 | src/bundles/*.bundles/*/*.* 19 | !src/bundles/desktop.bundles/*/*.bemdecl.js 20 | !src/bundles/errors.bundles/*/*.bemjson.js 21 | src/www/freeze 22 | 23 | *.deb 24 | *.build 25 | *.changes 26 | *.upload 27 | *.dsc 28 | *.tar.gz 29 | 30 | .githooks 31 | .jshint-groups.js 32 | .jscsrc 33 | -------------------------------------------------------------------------------- /bin/app.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | fs = require('fs'); 3 | 4 | var p = path.join(process.cwd(), 'src/bundles/desktop.bundles/common/common.node.js'); 5 | fs.exists(p, function(exists) { 6 | if(!exists) { 7 | console.error('Error! Bundle node.js file is not exist yet'); 8 | console.error('You must compile bundles before launch application'); 9 | return; 10 | } 11 | 12 | require('../src/bundles/desktop.bundles/common/common.node.js'); 13 | }); 14 | -------------------------------------------------------------------------------- /bin/data.js: -------------------------------------------------------------------------------- 1 | require('../src/data/coa').run(); 2 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bem-site-engine", 3 | "description": "BEM CMS based on Express framework", 4 | "version": "1.1.0", 5 | "private": true, 6 | "dependencies": { 7 | "bem-core": "2.5.1", 8 | "bem-components": "git://github.com/bem/bem-components.git#v2.0.0" 9 | }, 10 | "ignore": [ 11 | "node_modules", 12 | "configs/current", 13 | ".enb/tmp" 14 | ], 15 | "resolutions": { 16 | "bem-core": "2.5.1", 17 | "bem-components": "v2.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /configs/common/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "languages": ["en", "ru"], 3 | "defaultLanguage": "ru", 4 | "port": 3016, 5 | "statics": "/src", 6 | "title": { 7 | "en": "Your application title", 8 | "ru": "Название приложения" 9 | }, 10 | "update": { 11 | "enable": true, 12 | "cron": "0 */1 * * * *" 13 | }, 14 | "logger": { 15 | "level": "debug", 16 | "stdout": "logs/output.log", 17 | "stderr": "logs/errors.log" 18 | }, 19 | "yandexApi": { 20 | "login": "", 21 | "password": "" 22 | }, 23 | "model": { 24 | "dir": "backups" 25 | }, 26 | "github": { 27 | "libraries": { 28 | "type": "public", 29 | "user": "bem", 30 | "repo": "bem-info-libs", 31 | "ref": "master", 32 | "pattern": "https://raw.githubusercontent.com/%s/%s/%s%s" 33 | }, 34 | "public": { 35 | "host": "api.github.com", 36 | "auth": "57e4fb0c83d3337ffe991d8b61e09c54288c2d7e" 37 | }, 38 | "people": "https://github.com/bem/bem-site-engine/blob/dev/docs/people/people.json" 39 | }, 40 | "hosts": { 41 | "en": "http://you-site-host-en", 42 | "ru": "http://you-site-host-ru" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /configs/common/redirects.js: -------------------------------------------------------------------------------- 1 | module.exports = []; 2 | -------------------------------------------------------------------------------- /configs/dev/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "NODE_ENV": "development" 3 | } 4 | -------------------------------------------------------------------------------- /configs/dev/borschik: -------------------------------------------------------------------------------- 1 | { 2 | "paths" : { 3 | "./": "/www/", 4 | "src/www/freeze/": "/www/freeze/" 5 | }, 6 | "freeze_paths" : { 7 | "./**": "src/www/freeze/" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /configs/production/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "NODE_ENV": "production" 3 | } 4 | -------------------------------------------------------------------------------- /configs/production/borschik: -------------------------------------------------------------------------------- 1 | { 2 | "paths" : { 3 | "./": "/www/", 4 | "src/www/freeze/": "/www/freeze/" 5 | }, 6 | "freeze_paths" : { 7 | "./**": "src/www/freeze/" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /configs/testing/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "NODE_ENV": "testing" 3 | } 4 | -------------------------------------------------------------------------------- /configs/testing/borschik: -------------------------------------------------------------------------------- 1 | { 2 | "paths" : { 3 | "./": "/www/", 4 | "src/www/freeze/": "/www/freeze/" 5 | }, 6 | "freeze_paths" : { 7 | "./**": "src/www/freeze/" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /docs/people/avatars/andrey-kuznetsov.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/docs/people/avatars/andrey-kuznetsov.png -------------------------------------------------------------------------------- /docs/people/people.json: -------------------------------------------------------------------------------- 1 | { 2 | "kuznetsov-andrey": { 3 | "en": { 4 | "firstName": "Kuznetsov", 5 | "lastName": "Andrey", 6 | "avatar": "https://raw.githubusercontent.com/bem/bem-site-engine/dev/docs/people/avatars/andrey-kuznetsov.png", 7 | "github": "tormozz48", 8 | "email": [], 9 | "twitter": "kuznetsov48", 10 | "skype": "boomer4848", 11 | "info": "Frontend developer at Yandex" 12 | }, 13 | "ru": { 14 | "firstName": "Кузнецов", 15 | "lastName": "Андрей", 16 | "avatar": "https://raw.githubusercontent.com/bem/bem-site-engine/dev/docs/people/avatars/andrey-kuznetsov.png", 17 | "github": "tormozz48", 18 | "email": [], 19 | "twitter": "kuznetsov48", 20 | "skype": "boomer4848", 21 | "info": "Разработчик интерфейсов в Яндексе" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/anchor/anchor.styl: -------------------------------------------------------------------------------- 1 | $size = 20px 2 | 3 | .anchor 4 | { 5 | opacity: 0 6 | position: absolute 7 | top: 50% 8 | left: -25px 9 | margin-top: -10px 10 | width: ($size + 5) 11 | height: $size 12 | background: url('anchor.svg') no-repeat top left 13 | background-size: $size 14 | } 15 | 16 | h2, 17 | h3, 18 | h4, 19 | h5, 20 | h6 21 | { 22 | &:hover 23 | { 24 | .anchor 25 | { 26 | opacity: 1 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/anchor/anchor.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_no-image/author__avatar_no-image_120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__avatar/_no-image/author__avatar_no-image_120.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_no-image/author__avatar_no-image_80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__avatar/_no-image/author__avatar_no-image_80.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_no-image/author__avatar_no-image_yes.styl: -------------------------------------------------------------------------------- 1 | .author__avatar_no-image_yes 2 | { 3 | margin: auto; 4 | 5 | &.author__avatar_size 6 | { 7 | &_medium 8 | { 9 | background: url('author__avatar_no-image_120.png') no-repeat; 10 | } 11 | 12 | &_small 13 | { 14 | background: url('author__avatar_no-image_80.png') no-repeat; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_size/author__avatar_size_large.styl: -------------------------------------------------------------------------------- 1 | .author__avatar_size_large 2 | { 3 | width: 200px; 4 | height: 200px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_size/author__avatar_size_medium.styl: -------------------------------------------------------------------------------- 1 | .author__avatar_size_medium 2 | { 3 | width: 120px; 4 | height: 120px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/_size/author__avatar_size_small.styl: -------------------------------------------------------------------------------- 1 | .author__avatar_size_small 2 | { 3 | width: 80px; 4 | height: 80px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/author__avatar.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('avatar')( 2 | match(function () { 3 | var c = this.ctx.content; 4 | 5 | return c && c.avatar; 6 | })( 7 | tag()('img'), 8 | attrs()(function () { 9 | var content = this.ctx.content; 10 | 11 | return { 12 | src: content.avatar, 13 | alt: content.slug 14 | }; 15 | }) 16 | ) 17 | ); 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/author__avatar.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | size: [small, medium, large] 3 | no-image: 'yes' 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__avatar/author__avatar.styl: -------------------------------------------------------------------------------- 1 | .author__avatar 2 | { 3 | padding: 4px; 4 | 5 | transition: border-color .4s; 6 | 7 | border: 3px solid #fde27d; 8 | border-radius: 2px; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__contact-item/author__contact-item.styl: -------------------------------------------------------------------------------- 1 | .author__contact-item 2 | { 3 | padding: 2px 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__contact/author__contact.styl: -------------------------------------------------------------------------------- 1 | .author__contact 2 | { 3 | margin-top: 10px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__data-wrapper/author__data-wrapper.styl: -------------------------------------------------------------------------------- 1 | .author__data-wrapper 2 | { 3 | padding: 0 15px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__e-mail/author__e-mail.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('e-mail')( 2 | 3 | def().match(function () { 4 | var c = this.ctx.content; 5 | return !c || !c.length; 6 | })(false), 7 | 8 | content()(function () { 9 | return [ 10 | { 11 | block: 'author', 12 | elem: 'label', 13 | content: '' 14 | }, 15 | apply('transformation') 16 | ]; 17 | }), 18 | 19 | mode('transformation')(function () { 20 | return this.ctx.content.map(function (item) { 21 | return { 22 | block: 'author', 23 | elem: 'value', 24 | content: [ 25 | { 26 | block: 'link', 27 | url: 'mailto:' + item, 28 | content: item 29 | } 30 | ] 31 | }; 32 | }); 33 | }) 34 | ); 35 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__e-mail/author__e-mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__e-mail/author__e-mail.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__e-mail/author__e-mail.styl: -------------------------------------------------------------------------------- 1 | .author__e-mail .author__label 2 | { 3 | background: url('author__e-mail.png') no-repeat; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__github/author__github.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('github')( 2 | def().match(function () { return !this.ctx.content; })(false), 3 | 4 | content()(function () { 5 | return [ 6 | { 7 | block: 'author', 8 | elem: 'label' 9 | }, 10 | { 11 | block: 'author', 12 | elem: 'value', 13 | content: [ 14 | { 15 | block: 'link', 16 | url: apply('url'), 17 | content: this.ctx.content 18 | } 19 | ] 20 | } 21 | ]; 22 | }), 23 | 24 | mode('url')(function () { 25 | var GITHUB_URL = 'https://github.com/', 26 | content = this.ctx.content; 27 | 28 | return content.indexOf(GITHUB_URL) > -1 ? content : (GITHUB_URL + content); 29 | }) 30 | ); 31 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__github/author__github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__github/author__github.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__github/author__github.styl: -------------------------------------------------------------------------------- 1 | .author__github > .author__label 2 | { 3 | background: url('author__github.png') no-repeat; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__info/author__info.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('info')( 2 | match(function () { return !this.ctx.content; }).def()(false) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__info/author__info.styl: -------------------------------------------------------------------------------- 1 | .author__info 2 | { 3 | padding-top: 15px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__label/author__label.styl: -------------------------------------------------------------------------------- 1 | .author__label 2 | { 3 | display: inline-block; 4 | 5 | width: 24px; 6 | height: 24px; 7 | } 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__name/author__name.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('name')( 2 | 3 | def().match(function () { return !this.ctx.content; })(false), 4 | 5 | tag()('span'), 6 | 7 | content()( 8 | match(function () { return this.ctx.content.lastName; })(function () { 9 | return this.ctx.content.lastName; 10 | }), 11 | 12 | match(function () { 13 | var c = this.ctx.content; 14 | return c.firstName && c.lastName; 15 | })(function () { 16 | var c = this.ctx.content; 17 | return [c.firstName, ' ', c.lastName]; 18 | }) 19 | ) 20 | ); 21 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__skype/author__skype.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('skype')( 2 | 3 | def()(match(function () { return !this.ctx.content; })(false)), 4 | 5 | content()(function () { 6 | return [ 7 | { 8 | block: 'author', 9 | elem: 'label' 10 | }, 11 | { 12 | block: 'author', 13 | elem: 'value', 14 | content: this.ctx.content 15 | } 16 | ]; 17 | }) 18 | ); 19 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__skype/author__skype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__skype/author__skype.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__skype/author__skype.styl: -------------------------------------------------------------------------------- 1 | .author__skype > .author__label 2 | { 3 | background: url('author__skype.png') no-repeat; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__twitter/author__twitter.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').elem('twitter')( 2 | def().match(function () { return !this.ctx.content; })(false), 3 | 4 | content()(function () { 5 | var content = this.ctx.content; 6 | 7 | return [ 8 | { 9 | block: 'author', 10 | elem: 'label' 11 | }, 12 | { 13 | block: 'author', 14 | elem: 'value', 15 | content: [ 16 | { 17 | block: 'link', 18 | url: 'https://twitter.com/' + content, 19 | content: '@' + content 20 | } 21 | ] 22 | } 23 | ]; 24 | }) 25 | ); 26 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__twitter/author__twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/author/__twitter/author__twitter.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__twitter/author__twitter.styl: -------------------------------------------------------------------------------- 1 | .author__twitter > .author__label 2 | { 3 | background: url('author__twitter.png') no-repeat; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/__value/author__value.styl: -------------------------------------------------------------------------------- 1 | .author__value 2 | { 3 | line-height: 23px; 4 | 5 | display: inline-block; 6 | 7 | padding-left: 10px; 8 | 9 | vertical-align: top; 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/_view/author_view_full.styl: -------------------------------------------------------------------------------- 1 | .author_view_full 2 | { 3 | display: table; 4 | 5 | margin: 10px 20px; 6 | 7 | .author 8 | { 9 | &__avatar-wrapper, 10 | &__data-wrapper 11 | { 12 | display: table-cell; 13 | 14 | vertical-align: middle; 15 | } 16 | 17 | &__avatar 18 | { 19 | padding: 5px; 20 | } 21 | 22 | &__name 23 | { 24 | font-size: 17px; 25 | font-weight: bold; 26 | 27 | margin-bottom: 10px; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/_view/author_view_grid-cell.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').mod('view', 'grid-cell')( 2 | 3 | tag()('a'), 4 | 5 | attrs()(function () { 6 | return { href: this.ctx.content.url }; 7 | }), 8 | 9 | content()(function () { 10 | var content = this.ctx.content; 11 | 12 | return [ 13 | { 14 | block: 'author', 15 | elem: 'avatar', 16 | elemMods: { size: 'medium', 'no-image': !content.avatar && 'yes' }, 17 | content: content 18 | }, 19 | { 20 | block: 'author', 21 | elem: 'name', 22 | content: content 23 | } 24 | ]; 25 | }) 26 | ); 27 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/_view/author_view_grid-cell.styl: -------------------------------------------------------------------------------- 1 | .author_view_grid-cell 2 | { 3 | display: inline-block; 4 | 5 | width: 160px; 6 | margin-top: 20px; 7 | margin-left: 20px; 8 | padding: 10px 5px 5px; 9 | 10 | text-align: center; 11 | vertical-align: top; 12 | text-decoration: none; 13 | 14 | color: #333; 15 | 16 | &:hover .author__avatar 17 | { 18 | border-color: #ffc900; 19 | } 20 | 21 | .author__name 22 | { 23 | display: block; 24 | 25 | margin-top: 10px; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/_view/author_view_simple.bemhtml: -------------------------------------------------------------------------------- 1 | block('author').mod('view', 'simple')( 2 | 3 | tag()('a'), 4 | 5 | mix()({ block: 'link' }), 6 | 7 | attrs()(function () { 8 | return { href: this.ctx.content.url }; 9 | }), 10 | 11 | content()(function () { 12 | return { 13 | block: 'author', 14 | elem: 'name', 15 | content: this.ctx.content 16 | }; 17 | }), 18 | 19 | match(function () { 20 | return this.isSimple(this.ctx.content); 21 | }).content()(function () { 22 | return this.ctx.content; 23 | }) 24 | ); 25 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/_view/author_view_simple.styl: -------------------------------------------------------------------------------- 1 | .author_view_simple 2 | { 3 | opacity: .7; 4 | 5 | &.link 6 | { 7 | color: $link; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/author.bemtree: -------------------------------------------------------------------------------- 1 | block('author')( 2 | content()(function () { 3 | var data = this.data, 4 | id = this.ctx.id, 5 | author = data.people[id][data.lang] || id; 6 | return this.extend(author, { url: data.peopleUrls[id] }); 7 | }) 8 | ); 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/author.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | view: [full, simple, grid-cell] 3 | 4 | - elems: 5 | - avatar 6 | - contact 7 | - contact-item 8 | - data-wrapper 9 | - e-mail 10 | - github 11 | - info 12 | - label 13 | - name 14 | - skype 15 | - twitter 16 | - value 17 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/author.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "author": { 3 | "title": "AUTHOR INFO", 4 | "name": "Name", 5 | "e-mail": "E-mail", 6 | "github": "GitHub", 7 | "twitter": "Twitter", 8 | "skype": "Skype", 9 | "info": "Info" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/author/author.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "author": { 3 | "title": "ИНФОРМАЦИЯ ОБ АВТОРЕ", 4 | "name": "Имя", 5 | "e-mail": "E-mail", 6 | "github": "GitHub", 7 | "twitter": "Twitter", 8 | "skype": "Skype", 9 | "info": "Дополнительная информация" 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__description/_inline/block-docs__description_inline_yes.styl: -------------------------------------------------------------------------------- 1 | .block-docs__description_inline_yes 2 | { 3 | display: inline-block; 4 | 5 | margin-left: 10px; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__description/block-docs__description.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | inline: yes 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__description/block-docs__description.styl: -------------------------------------------------------------------------------- 1 | .block-docs__description 2 | { 3 | margin-bottom: 10px; 4 | 5 | /* Поддержать блок b-text из bem.sets */ 6 | .b-text 7 | { 8 | &__p 9 | { 10 | margin-bottom: 20px; 11 | } 12 | 13 | &__h3 14 | { 15 | font-size: 22px; 16 | 17 | margin: 0 0 .5em 0; 18 | 19 | color: #000; 20 | } 21 | 22 | &__ul 23 | { 24 | margin: .5em 0 1em 3.2em; 25 | padding: 0; 26 | } 27 | 28 | &__li 29 | { 30 | margin: .35em 0; 31 | padding: 0; 32 | 33 | &:before 34 | { 35 | position: absolute; 36 | 37 | margin: 0 0 0 -1.5em; 38 | 39 | content: '\2014\a0'; 40 | } 41 | } 42 | } 43 | 44 | .b-link 45 | { 46 | display: inline-block; 47 | } 48 | } 49 | /* (END) Поддержать блок b-text из bem.sets */ 50 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__sublevel/block-docs__sublevel.styl: -------------------------------------------------------------------------------- 1 | .block-docs__sublevel 2 | { 3 | margin-left: 20px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__title/block-docs__title.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-docs').elem('title').match(function () { 2 | return this.ctx.elemMods; 3 | }).tag()(function () { 4 | return 'h' + this.ctx.elemMods.h || 1; 5 | }); 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__title/mix/block-docs__title_mix_post-title-inline.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-docs').elem('title').elemMod('mix', 'post-title-inline')( 2 | mix()([{ block: 'post', elem: 'title', elemMods: { inline: 'yes' } }]) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__title/mix/block-docs__title_mix_post-title.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-docs').elem('title').elemMod('mix', 'post-title')( 2 | mix()([{ block: 'post', elem: 'title' }]) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__value/block-docs__value.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-docs').elem('value')( 2 | tag()('code') 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/__value/block-docs__value.styl: -------------------------------------------------------------------------------- 1 | .block-docs__value 2 | { 3 | display: inline-block; 4 | 5 | margin-bottom: 5px; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/block-docs.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elem: i18n 4 | 5 | - elems: [description, sublevel, value, title] 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/block-docs.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-docs": { 3 | "mods": "List of _mods", 4 | "elems": "List of __elems" 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-docs/block-docs.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-docs": { 3 | "mods": "Список _модификаторов", 4 | "elems": "Список __элементов" 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__anchor/block-example__anchor.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('anchor').content()(function () { 2 | return { 3 | block: 'link', 4 | url: this.ctx.url, 5 | mix: { block: 'anchor' } 6 | }; 7 | }); 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__anchor/block-example__anchor.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: anchor 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__anchor/block-example__anchor.styl: -------------------------------------------------------------------------------- 1 | .block-example__anchor .anchor 2 | { 3 | left: -23px; 4 | 5 | width: 24px; 6 | height: 16px; 7 | 8 | //hack for Fx which doesn't work well with opacity in this case 9 | display: none; 10 | 11 | opacity: 1; 12 | 13 | .block-example__header:hover & 14 | { 15 | display: block; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__blank/block-example__blank.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('blank')( 2 | def()(function () { 3 | var ctx = this.ctx; 4 | 5 | return applyCtx({ 6 | block: 'link', 7 | url: ctx.url, 8 | attrs: { 9 | target: '_blank', 10 | title: BEM.I18N('block-example', 'example-title') 11 | }, 12 | mix: { 13 | block: this.block, 14 | elem: 'link', 15 | elemMods: { icon: 'blank' } 16 | }, 17 | content: ctx.content 18 | }); 19 | }) 20 | ); 21 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__blank/block-example__blank.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__header/block-example__header.styl: -------------------------------------------------------------------------------- 1 | .block-example__header 2 | { 3 | position: relative; 4 | 5 | display: inline-block; 6 | 7 | height: 32px; 8 | 9 | border-style: solid; 10 | border-color: $grey; 11 | border-width: 1px 0 0 1px; 12 | } 13 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/_icon/block-example__link_icon_blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/block-example/__link/_icon/block-example__link_icon_blank.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/_icon/block-example__link_icon_blank.styl: -------------------------------------------------------------------------------- 1 | .block-example__link_icon_blank:after 2 | { 3 | position: relative; 4 | top: 5px; 5 | left: 4px; 6 | 7 | background-image: url(block-example__link_icon_blank.png); 8 | background-size: 12px auto; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/_icon/block-example__link_icon_source.styl: -------------------------------------------------------------------------------- 1 | .block-example__link_icon_source:after 2 | { 3 | background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20baseProfile%3D%22tiny%22%20height%3D%2224px%22%20id%3D%22Layer_1%22%20version%3D%221.2%22%20viewBox%3D%220%200%2024%2024%22%20width%3D%2224px%22%20xml%3Aspace%3D%22preserve%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3Cg%3E%3Cg%3E%3Cpath%20d%3D%22M8.171%2C18c-0.512%2C0-1.023-0.195-1.414-0.586L2.343%2C13l4.414-4.414c0.781-0.781%2C2.049-0.781%2C2.828%2C0%20%20%20%20c0.781%2C0.781%2C0.781%2C2.047%2C0%2C2.828L8%2C13l1.585%2C1.586c0.781%2C0.781%2C0.781%2C2.047%2C0%2C2.828C9.195%2C17.805%2C8.683%2C18%2C8.171%2C18z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3Cg%3E%3Cg%3E%3Cpath%20d%3D%22M15.829%2C18c-0.512%2C0-1.024-0.195-1.414-0.586c-0.781-0.781-0.781-2.047%2C0-2.828L16%2C13l-1.585-1.586%20%20%20%20c-0.781-0.781-0.781-2.047%2C0-2.828c0.779-0.781%2C2.047-0.781%2C2.828%2C0L21.657%2C13l-4.414%2C4.414C16.853%2C17.805%2C16.341%2C18%2C15.829%2C18z%22%2F%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E'); 4 | background-size: 20px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/_source/block-example__link_source_copy.styl: -------------------------------------------------------------------------------- 1 | .block-example__link_source_copy 2 | { 3 | display: block; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/block-example__link.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | icon: [blank, source] 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__link/block-example__link.styl: -------------------------------------------------------------------------------- 1 | .block-example__link 2 | { 3 | font-size: 14px; 4 | line-height: 1; 5 | 6 | position: relative; 7 | 8 | display: inline-block; 9 | 10 | padding: 5px 8px 3px; 11 | 12 | color: #8f8f8f; 13 | border-right: 1px solid $grey; 14 | 15 | &:after 16 | { 17 | display: inline-block; 18 | 19 | width: 24px; 20 | height: 24px; 21 | margin-left: 3px; 22 | 23 | content: ''; 24 | vertical-align: middle; 25 | 26 | opacity: .6; 27 | background-repeat: no-repeat; 28 | } 29 | 30 | &:hover, 31 | &:hover .link 32 | { 33 | color: #000; 34 | 35 | &:after 36 | { 37 | opacity: 1; 38 | } 39 | } 40 | 41 | & .link, 42 | &:visited 43 | { 44 | color: #8f8f8f; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live-spin/block-example__live-spin.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('live-spin')( 2 | content()(function () { 3 | return { 4 | block: 'spin', 5 | mods: { theme: 'islands', size: 'm' } 6 | }; 7 | }) 8 | ); 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live-spin/block-example__live-spin.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: spin 2 | mods: { theme: islands } 3 | required: true 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live-spin/block-example__live-spin.styl: -------------------------------------------------------------------------------- 1 | .block-example__live-spin 2 | { 3 | position: absolute; 4 | 5 | width: 100%; 6 | height: 100%; 7 | 8 | .spin_size_m 9 | { 10 | position: absolute; 11 | top: 50%; 12 | left: 50%; 13 | 14 | margin: -14px 0 0 -14px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live-wrap/block-example__live-wrap.styl: -------------------------------------------------------------------------------- 1 | .block-example__live-wrap 2 | { 3 | line-height: 1; 4 | 5 | position: relative; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live/block-example__live.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('live')( 2 | tag()('iframe'), 3 | attrs()(function () { 4 | return { 'data-url': this.ctx.url, height: 50 }; 5 | }) 6 | ); 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__live/block-example__live.styl: -------------------------------------------------------------------------------- 1 | .block-example__live 2 | { 3 | position: relative; 4 | z-index: 1; 5 | 6 | width: 100%; 7 | min-height: 50px; 8 | 9 | border: 1px solid #e6e6e6; 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__qr/block-example__qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/block-example/__qr/block-example__qr.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__qr/block-example__qr.styl: -------------------------------------------------------------------------------- 1 | .block-example__qr 2 | { 3 | &:hover 4 | { 5 | cursor: pointer; 6 | } 7 | 8 | &:after 9 | { 10 | display: none; 11 | } 12 | 13 | .link:after 14 | { 15 | display: inline-block; 16 | 17 | width: 24px; 18 | height: 24px; 19 | margin-left: 3px; 20 | 21 | content: ''; 22 | vertical-align: middle; 23 | 24 | opacity: .6; 25 | background-repeat: no-repeat; 26 | background: url(block-example__qr.png) no-repeat; 27 | background-position: 3px 3px; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-code/_view/block-example__source-code_view_iframe.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('source-code').elemMod('view', 'iframe')( 2 | tag()('iframe') 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-code/_view/block-example__source-code_view_iframe.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-code_view_iframe 2 | { 3 | border: none; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-code/_view/block-example__source-code_view_text.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('source-code').elemMod('view', 'text')( 2 | tag()('code') 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-code/block-example__source-code.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: code 2 | - mods: { view: [text, iframe] } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-code/block-example__source-code.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-code 2 | { 3 | box-sizing: border-box; 4 | width: 100%; 5 | 6 | white-space: pre-wrap; 7 | 8 | background-color: #f7f7f9; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-copy/block-example__source-copy.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('source-copy')( 2 | def()(function () { 3 | return applyCtx({ 4 | block: 'link', 5 | mods: { pseudo: true }, 6 | attrs: { title: BEM.I18N('block-example', 'copy') }, 7 | mix: { 8 | block: this.block, 9 | elem: this.elem, 10 | js: this.ctx.js 11 | } 12 | }); 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-copy/block-example__source-copy.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link 2 | - block: zeroclipboard 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-copy/block-example__source-copy.js: -------------------------------------------------------------------------------- 1 | modules.define('i-bem__dom', ['jquery', 'zeroclipboard'], function (provide, $, zeroclipboard, BEMDOM) { 2 | 3 | BEMDOM.decl('block-example', { 4 | 5 | onSetMod: { 6 | 'js': { 7 | 'inited': function () { 8 | this.__base(); 9 | 10 | this.setToClipboard(); 11 | } 12 | } 13 | }, 14 | 15 | setToClipboard: function () { 16 | var _this = this, 17 | copy; 18 | 19 | /* jshint ignore:start */ 20 | ZeroClipboard.config({ 21 | hoverClass: _this.params.copyHoverClass 22 | }); 23 | 24 | copy = new ZeroClipboard(_this.elem('source-copy')); 25 | /* jshint ignore:end */ 26 | 27 | copy.on('load', function (client) { 28 | 29 | client.on('dataRequested', function (client) { 30 | _this.getData(client); 31 | }); 32 | 33 | client.on('complete', function () { 34 | _this.setMod(_this.elem('source-copy'), 'complete', 'yes'); 35 | setTimeout(function () { 36 | _this.delMod(_this.elem('source-copy'), 'complete'); 37 | }, 1000); 38 | }); 39 | 40 | }); 41 | 42 | copy.on('noFlash wrongFlash', function () { 43 | _this.elem('source-copy').remove(); 44 | }); 45 | }, 46 | 47 | getData: function (client) { 48 | var elemParams = this.elemParams('source-copy'), 49 | inlineBemjson = elemParams.inlineBemjson; 50 | 51 | if (inlineBemjson) { 52 | client.setText(inlineBemjson); 53 | } else { 54 | $.ajax({ 55 | url: elemParams.urlBemjson, 56 | success: function (content) { 57 | client.setText(content); 58 | }, 59 | async: false 60 | }); 61 | } 62 | } 63 | 64 | }); 65 | 66 | provide(BEMDOM); 67 | 68 | }); 69 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-copy/block-example__source-copy.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-copy 2 | { 3 | font-size: 9px; 4 | 5 | position: absolute; 6 | top: 15px; 7 | right: 15px; 8 | 9 | padding: 2px 7px; 10 | 11 | cursor: pointer; 12 | text-transform: uppercase; 13 | 14 | border: 1px solid #8f8f8f; 15 | border-radius: 2px; 16 | } 17 | 18 | /* For zeroclipboard module */ 19 | .source-copy-hover 20 | { 21 | color: #333; 22 | border-color: #000; 23 | background-color: #fff; 24 | } 25 | 26 | .block-example__source-copy_complete_yes 27 | { 28 | color: #333; 29 | border-color: #000; 30 | background-color: #ffd94d; 31 | } 32 | /* END For zeroclipboard module */ 33 | 34 | .block-example__source-copy:before 35 | { 36 | display: block; 37 | 38 | width: 24px; 39 | height: 24px; 40 | 41 | content: ''; 42 | 43 | opacity: .6; 44 | background: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20baseProfile%3D%22tiny%22%20height%3D%2224px%22%20id%3D%22Layer_1%22%20version%3D%221.2%22%20viewBox%3D%220%200%2024%2024%22%20width%3D%2224px%22%20xml%3Aspace%3D%22preserve%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20xmlns%3Axlink%3D%22http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink%22%3E%3Cpath%20d%3D%22M18%2C4H8C6.896%2C4%2C6%2C4.896%2C6%2C6v2H5c-1.104%2C0-2%2C0.896-2%2C2v9c0%2C1.104%2C0.896%2C2%2C2%2C2h9c1.104%2C0%2C2-0.896%2C2-2v-1h2%20%20c1.104%2C0%2C2-0.896%2C2-2V6C20%2C4.896%2C19.104%2C4%2C18%2C4z%20M5%2C19v-9h3h5.5c0.275%2C0%2C0.5%2C0.225%2C0.5%2C0.5V16v3H5z%20M18%2C16h-3v-5.5%20%20C15%2C9.673%2C14.327%2C9%2C13.5%2C9H8V8V6h10V16z%22%2F%3E%3C%2Fsvg%3E'); 45 | background-repeat: no-repeat; 46 | background-position: center top; 47 | background-size: 24px; 48 | } 49 | 50 | .block-example__source-copy:hover:before 51 | { 52 | opacity: 1; 53 | } 54 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-item/block-example__source-item.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-item 2 | { 3 | display: none; 4 | 5 | &_visible 6 | { 7 | display: block; 8 | 9 | margin-bottom: 20px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-switcher/_active/block-example__source-switcher_active_yes.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-switcher_active_yes 2 | { 3 | color: #000; 4 | 5 | &:after 6 | { 7 | opacity: 1; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-switcher/block-example__source-switcher.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example').elem('source-switcher')( 2 | mix()(function () { 3 | return { 4 | block: this.block, 5 | elem: 'link', 6 | elemMods: { icon: 'source' } 7 | }; 8 | }) 9 | ); 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-switcher/block-example__source-switcher.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | active: yes 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source-switcher/block-example__source-switcher.styl: -------------------------------------------------------------------------------- 1 | .block-example__source-switcher 2 | { 3 | cursor: pointer; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source/_visible/block-example__source_visible_yes.styl: -------------------------------------------------------------------------------- 1 | .block-example__source_visible_yes 2 | { 3 | display: block; 4 | 5 | margin-bottom: 15px; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source/block-example__source.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | visible: yes 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/__source/block-example__source.styl: -------------------------------------------------------------------------------- 1 | .block-example__source 2 | { 3 | position: relative; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/_view/block-example_view_default.bemtree: -------------------------------------------------------------------------------- 1 | block('block-example').mod('view', 'default')( 2 | elem('source')( 3 | content()(function () { 4 | return { 5 | elem: 'source-item', 6 | elemMods: { type: 'bemjson' }, 7 | content: [ 8 | { 9 | elem: 'source-code', 10 | elemMods: { view: 'iframe' }, 11 | attrs: { 'data-url': this._bemjson } 12 | }, 13 | { 14 | elem: 'source-copy', 15 | js: { urlBemjson: this._bemjson } 16 | } 17 | ] 18 | }; 19 | }) 20 | ) 21 | ); 22 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/_view/block-example_view_inline.bemtree: -------------------------------------------------------------------------------- 1 | block('block-example').mod('view', 'inline')( 2 | elem('header')( 3 | content()(function () { 4 | return [ 5 | applyNext(), 6 | { 7 | elem: 'source-switcher', 8 | elemMods: { type: 'html' }, 9 | js: { urlBemhtml: this._urlBemhtml }, 10 | content: 'html' 11 | } 12 | ]; 13 | }) 14 | ), 15 | 16 | elem('source')( 17 | content()(function () { 18 | return [ 19 | { 20 | elem: 'source-item', 21 | elemMods: { type: 'bemjson' }, 22 | content: [ 23 | { 24 | elem: 'source-code', 25 | elemMods: { view: 'text' }, 26 | content: this._bemjson 27 | }, 28 | { 29 | elem: 'source-copy', 30 | js: { inlineBemjson: this._bemjson } 31 | } 32 | ] 33 | }, 34 | { 35 | elem: 'source-item', 36 | elemMods: { type: 'html' }, 37 | content: { 38 | elem: 'source-code', 39 | elemMods: { view: 'text', type: 'html' }, 40 | content: ' ' 41 | } 42 | } 43 | ]; 44 | }) 45 | ), 46 | 47 | elem('blank').content()(false) 48 | ); 49 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/block-example.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-example')( 2 | js()({ 3 | copyHoverClass: 'source-copy-hover' 4 | }) 5 | ); 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/block-example.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elem: i18n 4 | 5 | - block: dropdown 6 | mods: { switcher: link, theme: islands } 7 | 8 | - block: link 9 | mods: { pseudo: true, theme: islands } 10 | 11 | - block: image 12 | 13 | - elems: 14 | - anchor 15 | - blank 16 | - header 17 | - link 18 | - live 19 | - live-spin 20 | - live-wrap 21 | - source 22 | - source-code 23 | - source-copy 24 | - source-item 25 | - source-switcher 26 | - qr 27 | 28 | - mods: { view: [inline, default] } 29 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/block-example.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-example": { 3 | "examples-title": "Examples", 4 | "example-link": "Open in new tab", 5 | "copy": "Copy" 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/block-example.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-example": { 3 | "examples-title": "Примеры", 4 | "example-link": "Открыть в новой вкладке", 5 | "copy": "Копировать" 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-example/block-example.styl: -------------------------------------------------------------------------------- 1 | .block-example 2 | { 3 | margin-bottom: 20px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__access/block-jsdoc__access.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__access 2 | { 3 | font-size: 12px; 4 | 5 | display: inline-block; 6 | 7 | margin-left: 10px; 8 | 9 | text-transform: uppercase; 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__item/block-jsdoc__item.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__item 2 | { 3 | margin-bottom: 20px; 4 | 5 | &:after 6 | { 7 | display: block; 8 | 9 | width: 100%; 10 | height: 2px; 11 | margin-top: 15px; 12 | 13 | content: ''; 14 | 15 | background: linear-gradient(to right, #e6e6e6 0%,rgba(115,115,115,0) 100%,rgba(229,229,229,0) 100%); 16 | } 17 | 18 | &:last-child:after 19 | { 20 | background: none; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__selection/_color/block-jsdoc__selection_color_gold.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__selection_color_gold 2 | { 3 | border-color: #ffd94d; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__selection/_color/block-jsdoc__selection_color_grey.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__selection_color_grey 2 | { 3 | border-color: #e6e6e6; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__selection/block-jsdoc__selection.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | color: [gold, grey] 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__selection/block-jsdoc__selection.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__selection 2 | { 3 | display: inline-block; 4 | 5 | padding: 2px 10px; 6 | 7 | border: 1px solid; 8 | border-radius: 2px; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__title/block-jsdoc__title.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-jsdoc').elem('title').match(function () { 2 | return this.ctx.elemMods; 3 | }).tag()(function () { 4 | return 'h' + this.ctx.elemMods.h || 2; 5 | }); 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__title/block-jsdoc__title.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: post 2 | elem: title 3 | inline: yes 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__title/mix/block-jsdoc__title_mix_post-title-inline.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-jsdoc').elem('title').elemMod('mix', 'post-title-inline')( 2 | mix()([{ block: 'post', elem: 'title', elemMods: { inline: 'yes' } }]) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__title/mix/block-jsdoc__title_mix_post-title.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-jsdoc').elem('title').elemMod('mix', 'post-title')( 2 | mix()([{ block: 'post', elem: 'title' }]) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__type-value/block-jsdoc__type-value.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-jsdoc').elem('type-value')( 2 | content()(function () { 3 | return this.xmlEscape(applyNext()); 4 | }) 5 | ); 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__type/block-jsdoc__type.bemhtml: -------------------------------------------------------------------------------- 1 | block('block-jsdoc').elem('type')( 2 | tag()('code') 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__type/block-jsdoc__type.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__type 2 | { 3 | display: inline-block; 4 | 5 | margin-left: 5px; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__types/block-jsdoc__types.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__types 2 | { 3 | display: inline-block; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/__value/block-jsdoc__value.styl: -------------------------------------------------------------------------------- 1 | .block-jsdoc__value 2 | { 3 | font-family: monospace; 4 | font-size: 12px; 5 | line-height: 1.6; 6 | 7 | margin-bottom: 10px; 8 | padding: 0 6px; 9 | 10 | border-color: #e6e5e3; 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/block-jsdoc.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: [item, selection, value, title, access, types, type, type-value, title] 2 | 3 | - block: i-bem 4 | required: true 5 | elem: i18n 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/block-jsdoc.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-jsdoc": { 3 | "description-title": "Description", 4 | "methods-title": "Methods", 5 | "params": "Params", 6 | "returns": "Returns", 7 | "events-title": "Events" 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block-jsdoc/block-jsdoc.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block-jsdoc": { 3 | "description-title": "Описание", 4 | "methods-title": "Методы", 5 | "params": "Параметры", 6 | "returns": "Возвращаемое значение", 7 | "events-title": "События" 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/__header/block__header.styl: -------------------------------------------------------------------------------- 1 | .block__header 2 | { 3 | margin-bottom: 20px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/__message/block__message.styl: -------------------------------------------------------------------------------- 1 | .block__message 2 | { 3 | padding: 0 30px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/__title/block__title.bemhtml: -------------------------------------------------------------------------------- 1 | block('block').elem('title').tag()('h1'); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/__title/block__title.styl: -------------------------------------------------------------------------------- 1 | .block__title 2 | { 3 | margin-top: 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.bemhtml: -------------------------------------------------------------------------------- 1 | block('block').js()(true); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - header 3 | - title 4 | - message 5 | 6 | - block: i-bem 7 | required: true 8 | elem: i18n 9 | 10 | - block: tabs 11 | mods: 12 | theme: default 13 | 14 | - block: block-docs 15 | - block: block-jsdoc 16 | - block: block-example 17 | 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block": { 3 | "static-title": "Block", 4 | "docs": "Docs", 5 | "jsdoc": "Javascript API", 6 | "examples": "Examples", 7 | "warning-title": "No documentation", 8 | "warning-text": "At the moment the translation of the documentation is in the plans." 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "block": { 3 | "static-title": "Блок", 4 | "docs": "Документация", 5 | "jsdoc": "Javascript API", 6 | "examples": "Примеры", 7 | "warning-title": "Документация отсутствует", 8 | "warning-text": "В данный момент перевод документации отсутствует, в планах." 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.ie.styl: -------------------------------------------------------------------------------- 1 | .block .tabs__content 2 | { 3 | padding-top: 0; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/block/block.styl: -------------------------------------------------------------------------------- 1 | .block 2 | { 3 | .tabs__header 4 | { 5 | padding: 0 30px; 6 | } 7 | 8 | .tabs__content 9 | { 10 | padding: 40px 30px 20px; 11 | } 12 | 13 | .post__content 14 | { 15 | max-width: 100%; 16 | padding: 0; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/code/code.styl: -------------------------------------------------------------------------------- 1 | $bg-color = #f6f5f3; 2 | $border-color = #e6e5e3; 3 | 4 | .code, 5 | code 6 | { 7 | font-family: monospace; 8 | font-size: 12px; 9 | line-height: 1.6; 10 | 11 | display: inline-block; 12 | 13 | margin: 0 2px 0; 14 | padding: 0 6px; 15 | 16 | border-radius: 2px; 17 | background-color: $bg-color; 18 | } 19 | 20 | li 21 | { 22 | .code, 23 | code 24 | { 25 | margin-bottom: 5px; 26 | } 27 | } 28 | 29 | pre code 30 | { 31 | font-family: Consolas, 'Liberation Mono', Courier, monospace; 32 | 33 | display: block; 34 | overflow: auto; 35 | 36 | padding: 8px 10px; 37 | 38 | white-space: pre; 39 | 40 | border-radius: 1px; 41 | background-color: $bg-color; 42 | } 43 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content-wrapper/content-wrapper.bemhtml: -------------------------------------------------------------------------------- 1 | block('content-wrapper')( 2 | mix()({ block: 'flex', mods: { type: 'content' } }) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content-wrapper/content-wrapper.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: flex 2 | mods: { type: content } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content-wrapper/content-wrapper.ie.styl: -------------------------------------------------------------------------------- 1 | .content-wrapper 2 | { 3 | overflow: hidden; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content-wrapper/content-wrapper.styl: -------------------------------------------------------------------------------- 1 | .content-wrapper 2 | { 3 | overflow-x: hidden; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_author.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'author').content()(function () { 2 | var data = this.data; 3 | 4 | return [ 5 | { 6 | block: 'author', 7 | mods: { view: 'full' }, 8 | id: data.req.params.id 9 | }, 10 | { 11 | block: this.block, 12 | elem: 'author-posts', 13 | content: data.posts.map(function (node) { 14 | return { 15 | block: 'posts', 16 | title: node.title, 17 | node: node 18 | }; 19 | }) 20 | } 21 | ]; 22 | }); 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_author.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: author 2 | - block: posts -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_authors.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'authors').content()(function () { 2 | return this.data.authors.map(function (author) { 3 | return { 4 | block: 'author', 5 | mods: { view: 'grid-cell' }, 6 | id: author 7 | }; 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_authors.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: author -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_block.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'block').content()({ block: 'block' }); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_block.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: block 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_post.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'post').content()({ 2 | block: 'post', 3 | mods: { view: 'full' } 4 | }); 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_post.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: post -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_post.styl: -------------------------------------------------------------------------------- 1 | .content_view_post 2 | { 3 | padding-left: 25px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_posts.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'posts').content()(function () { 2 | return { 3 | block: 'posts', 4 | node: this.data.node 5 | }; 6 | }); 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_posts.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: posts -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_tags.bemtree: -------------------------------------------------------------------------------- 1 | block('content').mod('view', 'tags') 2 | .content()(function () { 3 | return { 4 | block: this.block, 5 | elem: 'tag-posts', 6 | content: this.data.posts.map(function (node) { 7 | return { 8 | block: 'posts', 9 | title: node.title, 10 | node: node 11 | }; 12 | }) 13 | }; 14 | }); 15 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/_view/content_view_tags.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: posts -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/content.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elems: [dom, html, tree] 4 | 5 | - block: code 6 | 7 | - mods: 8 | view: [post, posts, index, authors, author, block, tags] 9 | 10 | - elems: [fullscreen] 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/content.js: -------------------------------------------------------------------------------- 1 | modules.define('content', ['i-bem__dom', 'jquery'], function (provide, BEMDOM, $) { 2 | 3 | provide(BEMDOM.decl(this.name, { 4 | 5 | onSetMod: { 6 | js: { 7 | inited: function () { 8 | this.countExamples = this.findBlocksInside('block-example').length; 9 | this.count = 0; 10 | } 11 | } 12 | }, 13 | 14 | _hasAnchorUrl: function () { 15 | return /\w*#\w+/.test(window.location.href); 16 | }, 17 | 18 | _scrollToExample: function () { 19 | var _this = this, 20 | anchor = window.location.hash, 21 | examplePosTop = $(anchor).position().top, 22 | tabsHeight = this.findBlockInside('tabs').elem('header').height(); 23 | 24 | // hack for skipping default browser actions with anchor 25 | setTimeout(function () { 26 | _this.domElem.scrollTop(examplePosTop - tabsHeight); 27 | }, 500); 28 | }, 29 | 30 | _iframesLoaded: function () { 31 | this.count++; 32 | if (this.countExamples === this.count) { 33 | this._scrollToExample(); 34 | } 35 | } 36 | 37 | }, { 38 | live: function () { 39 | var ptp = this.prototype; 40 | 41 | if (ptp._hasAnchorUrl()) { 42 | this.liveInitOnBlockInsideEvent('iframeLoaded', 'block-example', ptp._iframesLoaded); 43 | } 44 | 45 | return false; 46 | } 47 | })); 48 | 49 | }); 50 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/content/content.styl: -------------------------------------------------------------------------------- 1 | .content 2 | { 3 | position: relative; 4 | 5 | overflow-y: auto; 6 | 7 | box-sizing: border-box; 8 | /* Don`t remove! Fix danced column width */ 9 | width: 100%; 10 | 11 | -webkit-overflow-scrolling: touch; 12 | flex: auto; 13 | } 14 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/__logo/error-billboard__logo.styl: -------------------------------------------------------------------------------- 1 | .error-billboard__logo 2 | { 3 | width: 500px; 4 | height: 300px; 5 | margin: 0 auto; 6 | 7 | background: url('error-billboard__logo.svg') no-repeat center; 8 | background-size: auto 300px; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/__logo/error-billboard__logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/error-billboard.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elems: [html, tree] 4 | - block: i-global 5 | required: true 6 | 7 | - elem: logo 8 | - block: link 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/error-billboard.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "error-billboard": { 3 | "title": "Error", 4 | "description": "Error occured", 5 | "description404": "Resource not found", 6 | "description500": "Error occured on server", 7 | "report": "You can report this issue to: ", 8 | "sitemap": "sitemap" 9 | } 10 | }; -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/error-billboard.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "error-billboard": { 3 | "title": "Ошибка", 4 | "description": "Произошла ошибка", 5 | "description404": "Запрашиваемый ресурс не найден", 6 | "description500": "Произошла ошибка на сервере", 7 | "report": "Вы может сообщить о этой ошибке по адресу: ", 8 | "sitemap": "карта сайта" 9 | } 10 | }; -------------------------------------------------------------------------------- /src/blocks/common.blocks/error-billboard/error-billboard.styl: -------------------------------------------------------------------------------- 1 | .error-billboard 2 | { 3 | margin: 0 auto; 4 | padding-top: 50px; 5 | 6 | &__panel 7 | { 8 | width: 50%; 9 | margin: 100px auto; 10 | } 11 | 12 | &__title, 13 | &__description, 14 | &__report, 15 | &__sitemap 16 | { 17 | text-align: center; 18 | } 19 | 20 | &__sitemap 21 | { 22 | font-size: 20px; 23 | 24 | margin-top: 50px; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/flex/_type/flex_type_content.ie.styl: -------------------------------------------------------------------------------- 1 | .flex_type_content 2 | { 3 | height: 100%; 4 | 5 | .content, 6 | .menu-list 7 | { 8 | display: table-cell; 9 | 10 | vertical-align: top; 11 | } 12 | 13 | .menu-list__group-select 14 | { 15 | width: 230px; 16 | 17 | .menu-list__select 18 | { 19 | position: relative; 20 | top: 5px; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/flex/_type/flex_type_content.styl: -------------------------------------------------------------------------------- 1 | .flex_type_content 2 | { 3 | flex: 1; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/flex/flex.ie.styl: -------------------------------------------------------------------------------- 1 | .flex 2 | { 3 | display: table; 4 | 5 | width: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/flex/flex.styl: -------------------------------------------------------------------------------- 1 | .flex 2 | { 3 | position: relative; 4 | 5 | display: flex; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/form/form.bemhtml: -------------------------------------------------------------------------------- 1 | block('form').tag()('form'); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/header/header.bemhtml: -------------------------------------------------------------------------------- 1 | block('header').mix()({ block: 'flex' }); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/header/header.bemtree: -------------------------------------------------------------------------------- 1 | block('header')( 2 | match(function () { return this.ctx.content.items; }).content()(function () { 3 | 4 | var items = this.ctx.content.items.filter(function (item, idx) { 5 | return idx > 0; 6 | }); 7 | 8 | return [ 9 | { 10 | block: 'logo', 11 | mods: { type: 'bem' }, 12 | url: '/' 13 | }, 14 | { 15 | block: 'menu-list', 16 | mods: { type: 'header' }, 17 | content: items 18 | }, 19 | { 20 | block: 'lang-switch', 21 | url: this.data.langSwitch 22 | }, 23 | { 24 | block: 'search-button' 25 | } 26 | ]; 27 | }) 28 | ); 29 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/header/header.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logo 2 | mods: { type: bem } 3 | 4 | - block: menu-list 5 | mods: { type: header } 6 | 7 | - block: search-button 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/header/header.ie.styl: -------------------------------------------------------------------------------- 1 | .header > * 2 | { 3 | display: table-cell; 4 | 5 | vertical-align: middle; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/header/header.styl: -------------------------------------------------------------------------------- 1 | .header 2 | { 3 | align-items: center 4 | 5 | position: relative; 6 | z-index: 1000; //for bem-forum loader 7 | 8 | background-color: #000; 9 | 10 | .logo_type_bem 11 | { 12 | width: 61px; 13 | height: 38px; 14 | margin: 12px auto 4px 12px; 15 | 16 | background-size: 38px; 17 | } 18 | 19 | .search-button 20 | { 21 | margin-right: 20px; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/highlightjs/highlightjs.styl: -------------------------------------------------------------------------------- 1 | .hljs-comment, 2 | .hljs-template_comment, 3 | .diff .hljs-header, 4 | .hljs-javadoc 5 | { 6 | font-style: italic; 7 | 8 | color: #998; 9 | } 10 | 11 | .css .rule .hljs-keyword, 12 | .hljs-winutils, 13 | .javascript .hljs-title, 14 | .nginx .hljs-title, 15 | .hljs-subst, 16 | .hljs-request, 17 | .hljs-status 18 | { 19 | color: #333; 20 | } 21 | 22 | .hljs-number, 23 | .hljs-hexcolor, 24 | .ruby .hljs-constant 25 | { 26 | color: #099; 27 | } 28 | 29 | .hljs-string, 30 | .hljs-tag .hljs-value, 31 | .hljs-phpdoc, 32 | .tex .hljs-formula 33 | { 34 | color: #d14; 35 | } 36 | 37 | .hljs-title, 38 | .hljs-id, 39 | .coffeescript .hljs-params, 40 | .scss .hljs-preprocessor 41 | { 42 | color: #900; 43 | } 44 | 45 | .javascript .hljs-title, 46 | .lisp .hljs-title, 47 | .clojure .hljs-title, 48 | .hljs-subst 49 | { 50 | font-weight: normal; 51 | } 52 | 53 | .hljs-class .hljs-title, 54 | .haskell .hljs-type, 55 | .vhdl .hljs-literal, 56 | .tex .hljs-command 57 | { 58 | color: #458; 59 | } 60 | 61 | .hljs-symbol, 62 | .ruby .hljs-symbol .hljs-string, 63 | .lisp .hljs-keyword, 64 | .tex .hljs-special, 65 | .hljs-prompt 66 | { 67 | color: #990073; 68 | } 69 | 70 | .hljs-deletion 71 | { 72 | background: #fdd; 73 | } 74 | 75 | .hljs-addition 76 | { 77 | background: #dfd; 78 | } 79 | 80 | .diff .hljs-change 81 | { 82 | background: #0086b3; 83 | } 84 | 85 | .hljs-chunk 86 | { 87 | color: #aaa; 88 | } 89 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/i-global/i-global.bemtree: -------------------------------------------------------------------------------- 1 | block('i-global')( 2 | def()(function () { 3 | this.data = this.ctx; 4 | 5 | return apply('', { ctx: [ 6 | { block: 'page', mods: { theme: 'white' } } 7 | ] }); 8 | }), 9 | 10 | match(BEM && BEM.I18N)(function () { 11 | BEM.I18N.lang(this.ctx.lang); 12 | return applyNext(); 13 | }), 14 | 15 | match(function () { return this.isArray(this.ctx); })(function () { 16 | return applyNext({ ctx: this.ctx[0] }); 17 | }) 18 | ); 19 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/i-global/i-global.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elems: [tree] 4 | 5 | - block: page 6 | mods: { theme: white } -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_action/icon_action.ie.styl: -------------------------------------------------------------------------------- 1 | .icon_action_search 2 | { 3 | background-image: url('icon_action_search.png'); 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_action/icon_action.styl: -------------------------------------------------------------------------------- 1 | $icon-size = 24px; 2 | 3 | .icon_action_search 4 | { 5 | width: $icon-size; 6 | height: $icon-size; 7 | 8 | background: url('icon_action_search.svg'); 9 | background-size: $icon-size; 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_action/icon_action_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/icon/_action/icon_action_search.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_action/icon_action_search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view.styl: -------------------------------------------------------------------------------- 1 | .icon_view 2 | { 3 | &_github 4 | { 5 | background-image: url('icon_view_github.svg'); 6 | } 7 | 8 | &_desktop 9 | { 10 | background-image: url('icon_view_desktop.svg'); 11 | } 12 | 13 | &_touch-pad 14 | { 15 | background-image: url('icon_view_touch-pad.svg'); 16 | } 17 | 18 | &_touch-phone 19 | { 20 | background-image: url('icon_view_touch-phone.svg'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view_desktop.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view_github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view_touch-pad.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view_touch-phone.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/icon/_view/icon_view_warning.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/input/input.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "input": { 3 | "placeholder": "Search" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/input/input.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "input": { 3 | "placeholder": "Поиск" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lang-switch/lang-switch.bemhtml: -------------------------------------------------------------------------------- 1 | block('lang-switch')( 2 | content()(function () { 3 | return { 4 | block: 'link', 5 | url: this.ctx.url, 6 | content: BEM.I18N('lang-switch', 'name') 7 | }; 8 | }) 9 | ); 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lang-switch/lang-switch.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link -------------------------------------------------------------------------------- /src/blocks/common.blocks/lang-switch/lang-switch.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "lang-switch": { 3 | "name": "RU" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lang-switch/lang-switch.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "lang-switch": { 3 | "name": "EN" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lang-switch/lang-switch.styl: -------------------------------------------------------------------------------- 1 | .lang-switch 2 | { 3 | margin-left: 30px; 4 | margin-right: 40px; 5 | 6 | .link 7 | { 8 | letter-spacing: 1px; 9 | 10 | color: #fff; 11 | 12 | &:hover 13 | { 14 | color: #ffd94d; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lib-switch/lib-switch.bemhtml: -------------------------------------------------------------------------------- 1 | block('lib-switch').js()(true); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lib-switch/lib-switch.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: select 2 | mods: { theme: islands, mode: radio } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lib-switch/lib-switch.ie.styl: -------------------------------------------------------------------------------- 1 | .lib-switch 2 | { 3 | .menu-list__link_type_select 4 | { 5 | display: inline-block; 6 | } 7 | 8 | .select 9 | { 10 | float: right; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lib-switch/lib-switch.js: -------------------------------------------------------------------------------- 1 | modules.define('lib-switch', ['i-bem__dom'], function (provide, BEMDOM) { 2 | 3 | 'use strict'; 4 | 5 | provide(BEMDOM.decl(this.name, { 6 | onSetMod: { 7 | js: { 8 | inited: function () { 9 | this._select = this.findBlockInside('select'); 10 | 11 | this._setLinkVal(); 12 | this._select.on('change', this._onChange, this); 13 | } 14 | } 15 | }, 16 | 17 | _setLinkVal: function () { 18 | this.findBlockInside('link').domElem.attr('href', this._select.getVal()); 19 | 20 | return this; 21 | }, 22 | 23 | _onChange: function () { 24 | this._openLibPage(this._select.getVal()); 25 | }, 26 | 27 | _openLibPage: function (url) { 28 | var loc = window.location; 29 | 30 | loc.href = (loc.origin || loc.protocol + '//' + loc.hostname + (loc.port ? ':' + loc.port : '')) + url; 31 | 32 | return this; 33 | } 34 | })); 35 | }); 36 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/lib-switch/lib-switch.styl: -------------------------------------------------------------------------------- 1 | .lib-switch 2 | { 3 | display: flex; 4 | align-items: center; 5 | 6 | .select 7 | { 8 | margin: 2px 5px; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/link/_type/link_type_block.styl: -------------------------------------------------------------------------------- 1 | .link_type_block 2 | { 3 | display: block; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/link/link.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elems: [html] 4 | 5 | - mods: { type: block } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/link/link.styl: -------------------------------------------------------------------------------- 1 | .page 2 | { 3 | :link 4 | { 5 | transition: all $transition-delay; 6 | text-decoration: none; 7 | 8 | color: $link; 9 | 10 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 11 | } 12 | 13 | :visited 14 | { 15 | color: $linkVisited; 16 | } 17 | 18 | :link:hover, 19 | :visited:hover 20 | { 21 | color: $linkHover; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/_type/logo_type_bem.ie.styl: -------------------------------------------------------------------------------- 1 | .logo_type_bem 2 | { 3 | background-image: url('logo_type_bem.png'); 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/_type/logo_type_bem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/blocks/common.blocks/logo/_type/logo_type_bem.png -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/_type/logo_type_bem.styl: -------------------------------------------------------------------------------- 1 | .logo_type_bem 2 | { 3 | height: 50px; 4 | margin: 0 0 20px 30px; 5 | 6 | background-image: url('logo_type_bem.svg'); 7 | background-repeat: no-repeat; 8 | } 9 | 10 | @media screen and (max-height:700px) 11 | { 12 | .logo_type_bem 13 | { 14 | height: 20px; 15 | 16 | background-size: contain; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/_type/logo_type_bem.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/logo.bemhtml: -------------------------------------------------------------------------------- 1 | block('logo').match(function () { return this.ctx.url; })( 2 | tag()('a'), 3 | attrs()(function () { 4 | return { href: this.ctx.url }; 5 | }) 6 | ); 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/logo.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { type: bem } 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/logo/logo.styl: -------------------------------------------------------------------------------- 1 | .logo 2 | { 3 | display: block; 4 | 5 | background-repeat: no-repeat; 6 | 7 | &:hover 8 | { 9 | opacity: .9; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__delimeter/menu-list__delimeter.styl: -------------------------------------------------------------------------------- 1 | .menu-list__delimeter 2 | { 3 | height: 1px; 4 | margin: 10px 20px; 5 | padding: 0; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__group-select/menu-list__group-select.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: lib-switch 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__group-select/menu-list__group-select.styl: -------------------------------------------------------------------------------- 1 | .menu-list__group-select 2 | { 3 | position: relative; 4 | align-items: center; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__level-choose/menu-list__level-choose.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: select 2 | mods: { theme: islands, mode: radio, width: available } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__level-choose/menu-list__level-choose.styl: -------------------------------------------------------------------------------- 1 | .menu-list__level-choose 2 | { 3 | margin: 3px 12px 2px 12px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__level-group/_hide/menu-list__level-group_hide_yes.styl: -------------------------------------------------------------------------------- 1 | .menu-list__level-group_hide_yes 2 | { 3 | display: none; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__level-group/menu-list__level-group.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { hide: 'yes' } 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__link/_size/menu-list__link_size_normal.styl: -------------------------------------------------------------------------------- 1 | .menu-list__link_size_normal 2 | { 3 | font-size: 17px; 4 | line-height: 1.4em; 5 | } 6 | 7 | @media screen and (max-height:700px) 8 | { 9 | .menu-list__link_size_normal 10 | { 11 | font-size: 15px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__link/_size/menu-list__link_size_small.styl: -------------------------------------------------------------------------------- 1 | .menu-list__link_size_small 2 | { 3 | font-size: 13px; 4 | } 5 | 6 | @media screen and (max-height:700px) 7 | { 8 | .menu-list__link_size_small 9 | { 10 | font-size: 12px; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__link/_type/menu-list__link_type_select.styl: -------------------------------------------------------------------------------- 1 | .menu-list__link_type_select 2 | { 3 | margin-right: auto; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__link/menu-list__link.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__link/menu-list__link.styl: -------------------------------------------------------------------------------- 1 | .menu-list__link 2 | { 3 | font-size: 13px; 4 | 5 | display: block; 6 | 7 | text-decoration: none; 8 | } 9 | 10 | @media screen and (max-height:700px) 11 | { 12 | .menu-list__link 13 | { 14 | font-size: 12px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/__option/menu-list__option.bemhtml: -------------------------------------------------------------------------------- 1 | block('menu-list').elem('option')( 2 | tag()('option') 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_default.ie.styl: -------------------------------------------------------------------------------- 1 | .menu-list_type_default .menu-list__title:before, 2 | .menu-list_type_default .menu-list__delimeter 3 | { 4 | border-top: 1px solid #b7b7b7; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_header.bemtree: -------------------------------------------------------------------------------- 1 | block('menu-list').mod('type', 'header')( 2 | match(function () { return this.ctx.content; }).content()(function () { 3 | var menu = this.ctx.content; 4 | 5 | return menu.map(function (menuItem) { 6 | return { 7 | block: 'link', 8 | url: menuItem.url, 9 | mix: [{ 10 | block: 'menu-list', 11 | elem: 'link', 12 | elemMods: { 13 | active: menuItem.active, 14 | type: menuItem.type, 15 | size: menuItem.size 16 | } 17 | }], 18 | content: menuItem.title 19 | }; 20 | }); 21 | }) 22 | ); 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_header.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: font 2 | mods: { face: ekibastuz } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_header.styl: -------------------------------------------------------------------------------- 1 | .menu-list_type_header 2 | { 3 | overflow: hidden; 4 | 5 | margin-left: 10px; 6 | 7 | border-right: none; 8 | 9 | align-self: center; 10 | 11 | .menu-list__link 12 | { 13 | font-size: 15px; 14 | line-height: 1.5; 15 | 16 | display: inline-block; 17 | 18 | margin-right: 20px; 19 | 20 | transition: $transition-delay; 21 | vertical-align: middle; 22 | 23 | color: $white; 24 | 25 | &:hover, 26 | &_active 27 | { 28 | color: $yellow; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_level.bemhtml: -------------------------------------------------------------------------------- 1 | block('menu-list').mod('type', 'level').mix()(function () { 2 | return { mods: { type: 'default' } }; 3 | }); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_level.styl: -------------------------------------------------------------------------------- 1 | .menu-list_type_level .menu-list__select 2 | { 3 | width: 85%; 4 | margin: 8px 12px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_main.bemhtml: -------------------------------------------------------------------------------- 1 | block('menu-list').mod('type', 'main').tag()('nav'); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/_type/menu-list_type_main.deps.yaml: -------------------------------------------------------------------------------- 1 | - elem: delimeter 2 | 3 | - block: logo 4 | - block: lang-switch 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/menu-list.bemhtml: -------------------------------------------------------------------------------- 1 | block('menu-list').js()(true); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/menu-list.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - level-group 3 | - group-select 4 | - level-choose 5 | - option 6 | 7 | - elem: link 8 | mods: { type: [delimeter, select], size: [small, normal] } 9 | 10 | - mods: { type: [main, default, header, level] } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/menu-list.js: -------------------------------------------------------------------------------- 1 | modules.define('i-bem__dom', ['jquery', 'next-tick'], function (provide, $, nextTick, BEMDOM) { 2 | 3 | BEMDOM.decl('menu-list', { 4 | onSetMod: { 5 | js: { 6 | inited: function () { 7 | var _this = this; 8 | 9 | /* In the case when a bem block menu-list has a filter by levels 10 | * and you must wait until the document is loaded completely, 11 | * to calculate the height of the menu after their hide 12 | */ 13 | nextTick(function () { 14 | _this._setPosActiveElem(); 15 | }); 16 | } 17 | } 18 | }, 19 | 20 | /** 21 | * @private 22 | * [Shows the active menu item is visible to the viewport] 23 | */ 24 | _setPosActiveElem: function () { 25 | var el = this.elem('link', 'active', true); 26 | 27 | if (!this.hasMod(el, 'active', true)) { 28 | return; 29 | } 30 | 31 | var elPosTop = el.offset().top, 32 | elHeight = el.outerHeight(true), 33 | 34 | viewportHeight = BEMDOM.doc.outerHeight(true) - elHeight, 35 | viewportCenter = Math.round((viewportHeight / 2) - elHeight); 36 | 37 | if (elPosTop >= viewportHeight) { 38 | var menuScrollTop = (elPosTop - viewportHeight) + viewportCenter; 39 | 40 | this.domElem.scrollTop(menuScrollTop); 41 | } 42 | } 43 | }); 44 | 45 | provide(BEMDOM); 46 | 47 | }); 48 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menu-list/menu-list.styl: -------------------------------------------------------------------------------- 1 | .menu-list 2 | { 3 | position: relative; 4 | 5 | display: block; 6 | overflow-y: auto; 7 | 8 | box-sizing: border-box; 9 | 10 | border-right: 1px solid #cbcbcb; 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menus/menus.bemtree: -------------------------------------------------------------------------------- 1 | block('menus')( 2 | def().match(function () { return this.data.menu; })(function () { 3 | return applyCtx([ 4 | this.data.menu.map(function (column) { 5 | return { 6 | block: 'menu-list', 7 | content: column.items, 8 | mods: { type: column.type } 9 | }; 10 | }), 11 | this.data.menu.length > 1 ? { 12 | block: 'page', 13 | elem: 'fullscreen' 14 | } : '' 15 | ]); 16 | }) 17 | ); 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/menus/menus.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: menu-list 2 | mods: 3 | theme: [main, default] 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/metrika/metrika.bemhtml: -------------------------------------------------------------------------------- 1 | block('metrika')( 2 | match()(function () { return !this.ctx.id; }).def()(false), 3 | 4 | content()(function () { 5 | var counterId = this.ctx.id; 6 | 7 | return ''; 16 | }) 17 | ); 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/__css/page__css.bemtree: -------------------------------------------------------------------------------- 1 | block('page').elem('css')( 2 | def()(function () { 3 | var elem = this.elem; 4 | 5 | return [ 6 | { elem: elem, url: this._pathToBundle + '.css' + '?v=' + (+(new Date())), ie: false }, 7 | { elem: elem, url: this._pathToBundle + '.ie.css' + '?v=' + (+(new Date())), ie: 'lte IE 9' } 8 | ]; 9 | }) 10 | ); 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/__js/page__js.bemtree: -------------------------------------------------------------------------------- 1 | block('page').elem('js')( 2 | def()(function () { 3 | var elem = this.elem; 4 | 5 | return [ 6 | '', 9 | { elem: elem, url: '//yastatic.net/jquery/1.10.2/jquery.min.js' }, 10 | { elem: elem, url: this._pathToBundle + '.js' + '?v=' + (+(new Date())) } 11 | ]; 12 | }) 13 | ); 14 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_fullscreen/page_fullscreen.styl: -------------------------------------------------------------------------------- 1 | .page_fullscreen .menu-list_type_default 2 | { 3 | display: none; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_header/page_header.bemhtml: -------------------------------------------------------------------------------- 1 | block('page').mod('header', true)( 2 | mix()({ mods: { search: true } }) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_header/page_header.bemtree: -------------------------------------------------------------------------------- 1 | block('page').mod('header', true)( 2 | content()(function () { 3 | var data = this.data; 4 | 5 | return [ 6 | { 7 | block: 'header', 8 | content: data.menu.shift() 9 | }, 10 | { 11 | block: 'content-wrapper', 12 | content: [ 13 | { block: 'menus' }, 14 | { block: 'content', mods: { view: data.node.view }, js: true }, 15 | { block: 'search-panel' } 16 | ] 17 | }, 18 | { block: 'metrika', id: req.metrika }, 19 | { elem: 'js' } 20 | ]; 21 | }) 22 | ); 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_header/page_header.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { search: true } 2 | 3 | - block: header 4 | - block: content-wrapper 5 | - block: search-panel 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_header/page_header.styl: -------------------------------------------------------------------------------- 1 | .page_header 2 | { 3 | flex-direction: column; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_page/page_page_error.bemhtml: -------------------------------------------------------------------------------- 1 | block('page').mod('page', 'error')( 2 | def()(function () { 3 | return applyNext({ isErrorPage: true }); 4 | }) 5 | ); 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_search/page_search.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: jquery 2 | - block: keyboard 3 | elem: codes 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_search/page_search.js: -------------------------------------------------------------------------------- 1 | modules.define('page', ['jquery', 'keyboard__codes'], function (provide, $, keyboard, Page) { 2 | provide(Page.decl({ modName: 'search', modVal: true }, { 3 | onSetMod: { 4 | js: { 5 | inited: function () { 6 | this.__base.apply(this, arguments); 7 | 8 | var _this = this; 9 | this._searchButton = this.findBlockInside('search-button'); 10 | this._searchPanel = this.findBlockInside('search-panel'); 11 | this._contentWrapper = this.findBlockInside('content-wrapper'); 12 | 13 | this.bindToDoc('click keyup', function (e) { 14 | var target = $(e.target); 15 | 16 | _this._toggleSearch(e, target); 17 | }); 18 | } 19 | } 20 | }, 21 | 22 | _toggleSearch: function (e, target) { 23 | if (e.type === 'keyup' && e.which === keyboard.ESC) { 24 | this._searchPanel.delMod('state'); 25 | 26 | return false; 27 | } 28 | 29 | if (this._searchButton.containsDomElem(target) || this._searchPanel.containsDomElem(target)) { 30 | this._searchPanel.setMod('state', 'open'); 31 | this._searchButton.setMod('active', true); 32 | } else if (this._contentWrapper.containsDomElem(target)) { 33 | this._searchPanel.delMod('state'); 34 | this._searchButton.delMod('active'); 35 | } 36 | } 37 | })); 38 | }); 39 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/_touch/page_touch_yes.styl: -------------------------------------------------------------------------------- 1 | .page_touch_yes 2 | { 3 | .page__fullscreen 4 | { 5 | opacity: .6; 6 | background-size: 24px; 7 | } 8 | 9 | .content_view_post 10 | { 11 | padding-left: 29px; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/page.bemhtml: -------------------------------------------------------------------------------- 1 | block('page').js()(true); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/page.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: [css, js, fullscreen] 2 | - mods: { page: error, touch: yes, fullscreen: true, search: true } 3 | 4 | - block: styling 5 | required: true 6 | 7 | - block: i-bem 8 | required: true 9 | elems: [dom, html, tree] 10 | 11 | - block: jquery 12 | elem: event 13 | mods: { type: pointer } 14 | 15 | - block: link 16 | - block: menus 17 | - block: content 18 | - block: metrika 19 | - block: highlightjs 20 | - block: search-panel 21 | - block: search-button 22 | - block: content-wrapper 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/page.js: -------------------------------------------------------------------------------- 1 | modules.define('page', ['i-bem__dom', 'jquery', 'highlightjs'], function (provide, BEMDOM, $, hljs) { 2 | 3 | provide(BEMDOM.decl(this.name, { 4 | onSetMod: { 5 | js: { 6 | inited: function () { 7 | 8 | var userAgent = navigator.userAgent; 9 | 10 | if (userAgent.indexOf('MSIE 8') > -1 || userAgent.indexOf('MSIE 9') > -1) { 11 | window.legacyIE = true; 12 | } 13 | 14 | if (!window.legacyIE) { 15 | $('pre code').each(function (idx, el) { 16 | hljs.highlightBlock(el); 17 | }); 18 | } 19 | 20 | this._isTouch() && this.setMod('touch', 'yes'); 21 | } 22 | } 23 | }, 24 | 25 | _onClick: function () { 26 | this.toggleMod('fullscreen'); 27 | }, 28 | 29 | /* 30 | * Проверка тач-устройств (при обнаружении добавляется модификатор _touch_yes) 31 | * @private 32 | * @returns {Boolean} 33 | */ 34 | _isTouch: function () { 35 | /* Touch detection idea by Modernizr */ 36 | /* jshint ignore:start */ 37 | if (('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch) { 38 | return true; 39 | } 40 | /* jshint ignore:end */ 41 | 42 | return false; 43 | } 44 | }, 45 | { 46 | live: function () { 47 | this.liveBindTo('fullscreen', 'pointerclick', function () { 48 | this._onClick(); 49 | }); 50 | 51 | return false; 52 | } 53 | })); 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/page/page.styl: -------------------------------------------------------------------------------- 1 | body, 2 | html 3 | { 4 | height: 100%; 5 | padding: 0; 6 | } 7 | 8 | .page 9 | { 10 | font: 13px Arial, Helvetica, sans-serif; 11 | 12 | position: relative; 13 | z-index: 0; 14 | 15 | display: flex; 16 | 17 | min-width: 1000px; 18 | margin: 0; 19 | padding: 0; 20 | 21 | &_page_tags, 22 | &_page_authors 23 | { 24 | & .page__fullscreen 25 | { 26 | display: none; 27 | } 28 | } 29 | } 30 | 31 | /* Fix for iframe from yandex metrika */ 32 | iframe[src="//yastatic.net/share/metrika.html"] { 33 | top: 0; 34 | } 35 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__author/post__author.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('author').def().match(function () { 2 | return !(this.ctx.content || []).length; 3 | })(false); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__author/post__author.bemtree: -------------------------------------------------------------------------------- 1 | block('post') 2 | .elem('author') 3 | .match(function () {return this.isArray(this.ctx.authors); }) 4 | .content()(function () { 5 | var buf = [], 6 | _this = this, 7 | ctx = this.ctx, 8 | translators = ctx.translators, 9 | splitter = { 10 | tag: 'span', 11 | content: ', ' 12 | }; 13 | 14 | ctx.authors.forEach(function (item, index) { 15 | index++ > 0 && buf.push(splitter); 16 | 17 | buf.push({ 18 | block: 'author', 19 | mods: { view: 'simple' }, 20 | id: item 21 | }); 22 | 23 | }); 24 | 25 | this.isArray(translators) && translators.filter(function (item) { 26 | return _this.ctx.authors.indexOf(item) === -1; 27 | }).forEach(function (item) { 28 | buf.push(splitter, { 29 | block: 'author', 30 | mods: { view: 'simple' }, 31 | id: item 32 | }); 33 | }); 34 | 35 | return buf; 36 | }); 37 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__author/post__author.styl: -------------------------------------------------------------------------------- 1 | .post__author 2 | { 3 | font-size: 12px; 4 | 5 | .post_view_full & 6 | { 7 | line-height: 20px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__categories/post__categories.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('categories')( 2 | match(function () { return !(this.ctx.breadcrumbs && this.ctx.breadcrumbs.length > 1); }) 3 | .def()(function () { 4 | return false; 5 | }), 6 | 7 | match(function () { return this.isArray(this.ctx.breadcrumbs); }).content()(function () { 8 | var breadcrumbs = this.ctx.breadcrumbs, 9 | length = breadcrumbs.length - 1, 10 | buf = []; 11 | 12 | breadcrumbs.forEach(function (item, index) { 13 | if (!item.title) return; 14 | 15 | var crumb = { block: 'link', content: item.title[this.ctx.lang] }; 16 | 17 | if (index > 0) { 18 | buf.push({ 19 | tag: 'span', 20 | content: ' → ' 21 | }); 22 | } 23 | 24 | if (index === length) { 25 | crumb.mods = { pseudo: true }; 26 | } else { 27 | crumb.url = item.url; 28 | } 29 | 30 | buf.push(crumb); 31 | 32 | }, this); 33 | 34 | return buf; 35 | }) 36 | ); 37 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__categories/post__categories.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link 2 | mods: { pseudo: true } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__categories/post__categories.styl: -------------------------------------------------------------------------------- 1 | .post__categories 2 | { 3 | padding-top: 10px; 4 | 5 | opacity: .7; 6 | 7 | &:visited 8 | { 9 | color: $link; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__content/post__content.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('content').match(function () { 2 | return !(this.ctx.content || []).length; 3 | }).content()(function () { 4 | return { 5 | block: 'plug', 6 | content: [ 7 | BEM.I18N('post', 'plug'), 8 | { 9 | block: 'link', 10 | url: this.ctx.url, 11 | content: BEM.I18N('post', 'plugLink') 12 | } 13 | ] 14 | }; 15 | }); 16 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__date/post__date.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('date')( 2 | 3 | match(function () { return !this.ctx.createDate && !this.ctx.editDate; })( 4 | def()(false)), 5 | 6 | content()(function () { 7 | var ctx = this.ctx, 8 | actionType = ctx.editDate ? 'editDate' : 'createDate'; 9 | 10 | function format(postDate) { 11 | var date = new Date(); 12 | date.setTime(postDate); 13 | 14 | var d = date.getDate(), 15 | m = date.getMonth(), 16 | y = date.getFullYear(); 17 | 18 | return d + ' ' + BEM.I18N('post', 'month' + m) + ' ' + y; 19 | } 20 | 21 | return [ 22 | BEM.I18N('post', actionType), 23 | ' ', 24 | format(ctx[actionType]) 25 | ]; 26 | }) 27 | ); 28 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__date/post__date.styl: -------------------------------------------------------------------------------- 1 | .post__date 2 | { 3 | .post_view_full & 4 | { 5 | font-size: 12px; 6 | line-height: 20px; 7 | 8 | display: inline-block; 9 | 10 | margin-right: 10px; 11 | 12 | color: #333; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__deps/post__deps.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('deps')( 2 | match(function () { return !(this.ctx && this.ctx.content); }).def()(false), 3 | 4 | content()(function () { 5 | var libs = this.ctx.content; 6 | 7 | return [{ 8 | block: 'post', 9 | elem: 'title', 10 | elemMods: { level: '3' }, 11 | content: BEM.I18N('post', 'deps') 12 | }].concat(Object.keys(libs).map(function (lib) { 13 | var libUrl = libs[lib], 14 | hashIndex = libUrl.indexOf('#'), 15 | isFullPath = hashIndex > -1, 16 | version = isFullPath ? '@' + libUrl.substr(hashIndex + 1) : '', 17 | text = lib + version; 18 | 19 | return { 20 | content: [ 21 | '— ', 22 | isFullPath ? { 23 | block: 'link', 24 | url: libUrl.replace('git:', 'https:'), 25 | attrs: { target: '_blank' }, 26 | content: text 27 | } : text 28 | ] 29 | }; 30 | }) 31 | ); 32 | }) 33 | ); 34 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__deps/post__deps.styl: -------------------------------------------------------------------------------- 1 | .post__deps 2 | { 3 | margin: 20px 0; 4 | 5 | .link 6 | { 7 | display: inline-block; 8 | 9 | margin-bottom: 5px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__summary/post__summary.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('summary').def().match(function () { 2 | return !this.ctx.content; 3 | })(false); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__tags/post__tags.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('tags')( 2 | def().match(function () { 3 | return !(this.ctx.content || []).length; 4 | })(false), 5 | 6 | content()(function () { 7 | return this.ctx.content.map(function (item) { 8 | return [ 9 | { 10 | block: 'link', 11 | url: '/tags/' + item, 12 | content: item 13 | }, 14 | { 15 | tag: 'span', 16 | content: ' ' 17 | } 18 | ]; 19 | }); 20 | }) 21 | ); 22 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__tags/post__tags.styl: -------------------------------------------------------------------------------- 1 | .post__tags 2 | { 3 | font-size: 12px; 4 | 5 | .link 6 | { 7 | display: inline-block; 8 | 9 | margin: 0 2px 4px 0; 10 | padding: 4px 10px; 11 | 12 | white-space: nowrap; 13 | 14 | opacity: .5; 15 | color: #000; 16 | border-radius: 2px; 17 | background-color: #eee; 18 | 19 | &:hover 20 | { 21 | opacity: 1; 22 | } 23 | } 24 | 25 | .post_view_full & 26 | { 27 | line-height: 20px; 28 | 29 | margin-left: 20px; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title-line/post__title-line.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('title-line').mix()({ block: 'flex' }); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title-line/post__title-line.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: flex 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title-line/post__title-line.ie.styl: -------------------------------------------------------------------------------- 1 | .post__title-line 2 | { 3 | .post__title, 4 | .post__tags 5 | { 6 | display: inline-block; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title-line/post__title-line.styl: -------------------------------------------------------------------------------- 1 | .post__title-line 2 | { 3 | align-items: center; 4 | 5 | .post__tags 6 | { 7 | margin-top: 10px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title/_inline/post__title_inline_yes.styl: -------------------------------------------------------------------------------- 1 | .post__title_inline_yes 2 | { 3 | display: inline-block; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title/post__title.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('title')( 2 | def().match(function () { 3 | return !this.ctx.content || this.ctx.content.length === 0; 4 | })(false), 5 | 6 | match(function () { 7 | var mods = this.ctx.elemMods; 8 | 9 | return mods && mods.level; 10 | }).tag()(function () { 11 | return 'h' + this.ctx.elemMods.level; 12 | }), 13 | 14 | match(function () { 15 | return this.ctx.url; 16 | }).content()(function () { 17 | var ctx = this.ctx; 18 | 19 | return { 20 | block: 'link', 21 | url: ctx.url, 22 | content: ctx.content 23 | }; 24 | }) 25 | 26 | ); 27 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title/post__title.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { inline: 'yes' } 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__title/post__title.styl: -------------------------------------------------------------------------------- 1 | .post__title 2 | { 3 | font-size: 19px; 4 | 5 | margin: 10px 0; 6 | } 7 | 8 | h1.post__title 9 | { 10 | font-size: 28px; 11 | line-height: 1; 12 | } 13 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__translation/post__translation.styl: -------------------------------------------------------------------------------- 1 | .post__translation 2 | { 3 | margin-top: 10px; 4 | margin-left: 20px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__url/post__url.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').elem('url')( 2 | match(function () { 3 | return !(this.ctx.content || []).length; } 4 | ).def()(false), 5 | 6 | content()(function () { 7 | return { 8 | block: 'link', 9 | url: this.ctx.content, 10 | attrs: { target: '_blank' }, 11 | content: [ 12 | { 13 | block: 'icon', 14 | mods: { view: 'github' } 15 | }, 16 | BEM.I18N('post', 'url') 17 | ] 18 | }; 19 | }) 20 | ); 21 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__url/post__url.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: icon 2 | mods: { view: github } 3 | required: true 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/__url/post__url.styl: -------------------------------------------------------------------------------- 1 | .post__url 2 | { 3 | margin: 12px 20px 12px auto; 4 | 5 | .link 6 | { 7 | display: inline-block; 8 | } 9 | 10 | .icon_view_github 11 | { 12 | $icon-size = 24px; 13 | 14 | width: $icon-size; 15 | height: $icon-size; 16 | margin-right: 5px; 17 | 18 | vertical-align: super; 19 | 20 | background-size: $icon-size; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/_view/post_view_full.bemhtml: -------------------------------------------------------------------------------- 1 | block('post').mod('view', 'full')( 2 | js()(true) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/_view/post_view_full.styl: -------------------------------------------------------------------------------- 1 | .post_view_full 2 | { 3 | margin-bottom: 10px; 4 | padding: 10px 10px 5px 0; 5 | 6 | .post__author, 7 | .post__translator, 8 | .post__tags 9 | { 10 | display: inline-block; 11 | } 12 | 13 | h1.post__title 14 | { 15 | margin-top: 20px; 16 | } 17 | 18 | .post__issueLink 19 | { 20 | color: #333; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/_view/post_view_list-item.bemtree: -------------------------------------------------------------------------------- 1 | block('post').mod('view', 'list-item')( 2 | 3 | content()(function () { 4 | var node = this.ctx.node, 5 | source = node.source && node.source[this.data.lang]; 6 | 7 | return [ 8 | apply('author', { ctx: { 9 | authors: source.authors, 10 | translators: source.translators 11 | } }), 12 | 13 | apply('tags', { 'ctx.content': source.tags }), 14 | 15 | apply('title', { ctx: { 16 | node: node, 17 | content: source 18 | } }), 19 | 20 | apply('summary', { 'ctx.content': source.summary }) 21 | ]; 22 | }), 23 | 24 | // authors of post 25 | mode('author')(function () { 26 | return { 27 | elem: 'author', 28 | authors: this.ctx.authors, 29 | translators: this.ctx.translators 30 | }; 31 | }), 32 | 33 | // tags array of post 34 | mode('tags')(function () { 35 | return { 36 | elem: 'tags', 37 | content: this.ctx.content 38 | }; 39 | }), 40 | 41 | // title of post 42 | mode('title')(function () { 43 | return { 44 | elem: 'title', 45 | url: this.ctx.node.url, 46 | content: this.ctx.content.longTitle || this.ctx.content.title 47 | }; 48 | }), 49 | 50 | // summary of post 51 | mode('summary')(function () { 52 | return { 53 | elem: 'summary', 54 | content: this.ctx.content 55 | }; 56 | }) 57 | ); 58 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/_view/post_view_list-item.styl: -------------------------------------------------------------------------------- 1 | .post_view_list-item 2 | { 3 | padding: 15px 5px 20px 25px; 4 | 5 | .post__date, 6 | .post__author, 7 | .post__translator, 8 | .post__tags 9 | { 10 | font-size: 12px; 11 | 12 | display: inline-block; 13 | 14 | padding-right: 10px; 15 | } 16 | 17 | .post 18 | { 19 | &__title 20 | { 21 | margin-top: 0; 22 | } 23 | 24 | &__summary 25 | { 26 | font-size: 14px; 27 | line-height: 1.7; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/post.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: i-bem 2 | required: true 3 | elems: [i18n] 4 | 5 | - block: anchor 6 | - block: author 7 | mods: { view: [full, menu-item, simple, avatar-only] } 8 | 9 | - mods: { view: [full, list-item] } 10 | - mods: { fullscreen: yes } 11 | 12 | - elem: title 13 | - elem: date 14 | - elem: summary 15 | - elem: tags 16 | - elem: categories 17 | - elem: author 18 | - elem: type 19 | - elem: content 20 | - elem: title-line 21 | - elem: url 22 | - elem: deps 23 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/post.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "post": { 3 | "fullscreen": "Reveal the article window", 4 | "author": "Author", 5 | "authors": "Authors", 6 | "translator": "Translator", 7 | "translators": "Translators", 8 | "createDate": "published", 9 | "editDate": "changed", 10 | "tags": "Tags", 11 | "summary": "Summary", 12 | "translation": "Russian version", 13 | "plug": "This post is available only in ", 14 | "plugLink": "russian language", 15 | 16 | "tools": "Tools", 17 | "libs": "Libraries", 18 | "articles": "Articles", 19 | "method": "Methodology", 20 | "news": "News", 21 | 22 | "month0": "january", 23 | "month1": "febuary", 24 | "month2": "march", 25 | "month3": "april", 26 | "month4": "may", 27 | "month5": "june", 28 | "month6": "july", 29 | "month7": "august", 30 | "month8": "september", 31 | "month9": "october", 32 | "month10": "november", 33 | "month11": "december", 34 | 35 | "translate": "translate", 36 | 37 | "repo-text": "If you've spotted a typo or a mistake, or wish to add something on, you could ", 38 | "repo-on-github": " on GitHub", 39 | "repo-alternative": ", either ", 40 | "repo-with-prose": " with prose.io.", 41 | "repo-issue": "write about this", 42 | "repo-prose": "edit this article", 43 | 44 | "url": "View it on Github", 45 | "deps": "Dependencies:" 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/post.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "post": { 3 | "fullscreen": "Раскрыть на все окно", 4 | "author": "Автор", 5 | "authors": "Авторы", 6 | "translator": "Переводчик", 7 | "translators": "Переводчики", 8 | "createDate": "опубликовано", 9 | "editDate": "изменено", 10 | "tags": "Тэги", 11 | "summary": "Краткое описание", 12 | "translation": "Английская версия", 13 | "plug": "Данная статья доступна только на ", 14 | "plugLink": "английском языке", 15 | 16 | "tools": "Инструменты", 17 | "libs": "Библиотеки", 18 | "articles": "Статьи", 19 | "method": "Методология", 20 | "news": "Новости", 21 | 22 | "month0": "января", 23 | "month1": "февраля", 24 | "month2": "марта", 25 | "month3": "апреля", 26 | "month4": "мая", 27 | "month5": "июня", 28 | "month6": "июля", 29 | "month7": "августа", 30 | "month8": "сентября", 31 | "month9": "октября", 32 | "month10": "ноября", 33 | "month11": "декабря", 34 | 35 | "translate": "перевод", 36 | 37 | "repo-text": "Если вы заметили ошибку или хотите чем-то дополнить статью, вы всегда можете ", 38 | "repo-on-github": " на Гитхабе", 39 | "repo-alternative": ", или ", 40 | "repo-with-prose": " с помощью prose.io.", 41 | "repo-issue": "написать об этом", 42 | "repo-prose": "поправить статью", 43 | 44 | "url": "Посмотреть на Github", 45 | "deps": "Зависимости:" 46 | } 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/post/post.styl: -------------------------------------------------------------------------------- 1 | .post 2 | { 3 | padding: 10px 10px 5px 10px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/__list/posts__list.bemtree: -------------------------------------------------------------------------------- 1 | block('posts').elem('list').match(function () { 2 | return this.isArray(this.ctx.content); 3 | }).content()(function () { 4 | var data = this.data; 5 | 6 | return this.ctx.content.map(function (item) { 7 | if (!item.source || !item.source[data.lang]) { 8 | return ''; 9 | } 10 | 11 | return { 12 | block: 'post', 13 | mods: { view: 'list-item' }, 14 | node: item 15 | }; 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/__list/posts__list.deps.yaml: -------------------------------------------------------------------------------- 1 | - post 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/__list/posts__list.styl: -------------------------------------------------------------------------------- 1 | .posts__list > .post 2 | { 3 | transition: background .4s ease; 4 | 5 | &:hover 6 | { 7 | background: rgba(255,235,160,.35); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/__title/posts__title.styl: -------------------------------------------------------------------------------- 1 | .posts__title 2 | { 3 | font-size: 12px; 4 | 5 | margin: 0; 6 | padding: 10px 0 10px 20px; 7 | 8 | text-transform: uppercase; 9 | 10 | color: #333; 11 | background: #eee; 12 | } 13 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/posts.bemhtml: -------------------------------------------------------------------------------- 1 | block('posts')( 2 | def().match(function () { 3 | var content = this.ctx.content; 4 | 5 | return content && content.length === 0; 6 | })(false), 7 | match(function () { 8 | return this.ctx.title; 9 | })( 10 | content()(function () { 11 | return [ 12 | { 13 | elem: 'title', 14 | content: this.ctx.title 15 | }, 16 | applyNext() 17 | ]; 18 | }) 19 | ) 20 | ); 21 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/posts.bemtree: -------------------------------------------------------------------------------- 1 | block('posts').content()(function () { 2 | var items = this.ctx.node && this.ctx.node.items; 3 | 4 | return items ? { 5 | elem: 'list', 6 | content: items 7 | } : []; 8 | }); 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/posts/posts.deps.yaml: -------------------------------------------------------------------------------- 1 | - elem: list 2 | - elem: title 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/__text/search-button__text.styl: -------------------------------------------------------------------------------- 1 | .search-button__text 2 | { 3 | margin-left: 5px; 4 | font-size: 15px; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/_active/search-button_active.styl: -------------------------------------------------------------------------------- 1 | .search-button_active 2 | { 3 | opacity: 1; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/_text/search-button_text.bemtree: -------------------------------------------------------------------------------- 1 | block('search-button').mod('text', true)( 2 | content()(function () { 3 | return [ 4 | applyNext(), 5 | { 6 | elem: 'text', 7 | content: BEM.I18N('search-button', 'title') 8 | } 9 | ]; 10 | }) 11 | ); 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/_text/search-button_text.deps.yaml: -------------------------------------------------------------------------------- 1 | - elem: text 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/search-button.bemtree: -------------------------------------------------------------------------------- 1 | block('search-button')( 2 | content()(function () { 3 | return { 4 | block: 'icon', 5 | mods: { action: 'search' }, 6 | attrs: { title: BEM.I18N('search-button', 'title') } 7 | }; 8 | }) 9 | ); 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/search-button.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: icon 2 | mods: { action: 'search' } 3 | 4 | - mods: { active: true, text: true } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/search-button.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-button": { 3 | "title": "Search" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/search-button.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-button": { 3 | "title": "Поиск" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-button/search-button.styl: -------------------------------------------------------------------------------- 1 | .search-button 2 | { 3 | display: flex; 4 | 5 | cursor: pointer; 6 | 7 | opacity: .8; 8 | 9 | align-self: center; 10 | align-items: center; 11 | 12 | &:hover 13 | { 14 | opacity: 1; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/_type/search-form_type_default.bemtree: -------------------------------------------------------------------------------- 1 | block('search-form').mod('type', 'default')( 2 | content()(function () { 3 | return { 4 | block: 'input', 5 | mods: { 6 | theme: 'islands', 7 | size: 'l', 8 | type: 'search', 9 | 'has-clear': true 10 | }, 11 | placeholder: BEM.I18N('search-form', 'placeholder') 12 | }; 13 | }) 14 | ); 15 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/_type/search-form_type_default.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: input 2 | mods: { theme: islands, size: l, autofocus: true, 'has-clear': true } 3 | 4 | - block: functions 5 | elem: debounce 6 | 7 | - block: events 8 | elem: channels 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/_type/search-form_type_default.js: -------------------------------------------------------------------------------- 1 | modules.define( 2 | 'search-form', 3 | ['i-bem__dom', 'functions__debounce', 'events__channels'], 4 | function (provide, BEMDOM, debounce, channels) { 5 | 6 | provide(BEMDOM.decl({ block: this.name, modName: 'type', modVal: 'default' }, { 7 | onSetMod: { 8 | js: { 9 | inited: function () { 10 | this._input = this.findBlockInside('input'); 11 | 12 | this._freezeVal(); 13 | this._debounceChange = debounce(this._checkChange, 500, this); 14 | this._input.bindTo('keyup', this._doChange.bind(this)); 15 | 16 | this.bindTo('submit', function (e) { 17 | e.preventDefault(); 18 | }); 19 | } 20 | } 21 | }, 22 | 23 | activate: function () { 24 | var _this = this; 25 | 26 | setTimeout(function () { 27 | _this._input.setMod('focused', true); 28 | }, 500); 29 | }, 30 | 31 | _doChange: function (needDebounce) { 32 | needDebounce ? this._debounceChange() : this._checkChange(); 33 | }, 34 | 35 | _onChange: function (currentVal) { 36 | channels('search').emit('change:input', { text: currentVal }); 37 | }, 38 | 39 | _freezeVal: function () { 40 | this._val = this._input.getVal(); 41 | }, 42 | 43 | _checkChange: function () { 44 | var currentValue = this._input.getVal(); 45 | 46 | if (currentValue.length > 1 && this._val !== currentValue) { 47 | this._freezeVal(); 48 | this._onChange(currentValue); 49 | } 50 | } 51 | })); 52 | 53 | }); 54 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/search-form.bemhtml: -------------------------------------------------------------------------------- 1 | block('search-form')( 2 | tag()('form'), 3 | js()(true) 4 | ); 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/search-form.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { type: default } 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/search-form.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-form": { 3 | "placeholder": "Name of block or key word(tag)" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/search-form.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-form": { 3 | "placeholder": "Имя блока или ключевое слово (тег)" 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-form/search-form.styl: -------------------------------------------------------------------------------- 1 | .search-form .input 2 | { 3 | width: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__category/search-item__category.styl: -------------------------------------------------------------------------------- 1 | .search-item__category 2 | { 3 | font-size: 14px; 4 | 5 | margin-bottom: .3em; 6 | 7 | color: #999; 8 | } 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__choose/search-item__choose.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: select 2 | mods: { theme: islands, mode: radio } 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__choose/search-item__choose.styl: -------------------------------------------------------------------------------- 1 | .search-item__choose 2 | { 3 | display: flex; 4 | 5 | align-items: center; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__description/search-item__description.bemhtml: -------------------------------------------------------------------------------- 1 | block('search-item').mod('type', 'block').elem('description')( 2 | content()(function () { 3 | return { 4 | tag: 'p', 5 | content: applyNext() 6 | }; 7 | }) 8 | ); 9 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__description/search-item__description.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: text 2 | required: true 3 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__description/search-item__description.styl: -------------------------------------------------------------------------------- 1 | .search-item__description 2 | { 3 | font-size: 13px; 4 | line-height: 1.6; 5 | 6 | color: #303030; 7 | 8 | p 9 | { 10 | margin: 0; 11 | } 12 | 13 | code 14 | { 15 | display: inline; 16 | 17 | background-color: transparent; 18 | border: 1px solid $border-color; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__level/_icon/search-item__level_icon.styl: -------------------------------------------------------------------------------- 1 | $size = 20px; 2 | 3 | .search-item__level .icon 4 | { 5 | width: $size; 6 | height: $size; 7 | 8 | background-size: $size * 2; 9 | } 10 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__level/search-item__level.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link 2 | required: true 3 | 4 | - block: icon 5 | mods: { view: [desktop, touch-pad, touch-phone] } 6 | 7 | - mods: { icon: [desktop, touch-pad, touch-phone] } 8 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__level/search-item__level.styl: -------------------------------------------------------------------------------- 1 | .search-item__level 2 | { 3 | display: inline-block; 4 | 5 | margin-left: 7px; 6 | 7 | transition: opacity .15s ease-out; 8 | 9 | opacity: .5; 10 | 11 | &:hover 12 | { 13 | opacity: inherit; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__levels/search-item__levels.deps.yaml: -------------------------------------------------------------------------------- 1 | - elem: level 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__levels/search-item__levels.styl: -------------------------------------------------------------------------------- 1 | .search-item__levels 2 | { 3 | min-width: 85px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__post/search-item__post.styl: -------------------------------------------------------------------------------- 1 | .search-item__post 2 | { 3 | margin-top: 15px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__title/search-item__title.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: link 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/__title/search-item__title.styl: -------------------------------------------------------------------------------- 1 | .search-item__title:link 2 | .search-item__title:visited 3 | { 4 | color: #444; 5 | font-size: 24px; 6 | 7 | display: inline-block; 8 | 9 | margin: 0 0 .3em; 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/_type/search-item_type_block.styl: -------------------------------------------------------------------------------- 1 | .search-item_type_block 2 | { 3 | .search-item__description 4 | { 5 | margin-top: 10px; 6 | padding-top: 10px; 7 | 8 | border-top: 5px solid #fff; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/_type/search-item_type_post.bemtree: -------------------------------------------------------------------------------- 1 | block('search-item').mod('type', 'post')( 2 | content()(function () { 3 | var _this = this, 4 | content = applyNext(); 5 | 6 | return [ 7 | { 8 | elem: 'category', 9 | content: content.category 10 | }, 11 | content.items.map(function (item) { 12 | var source = item.source && item.source[req.lang]; 13 | 14 | return source ? { 15 | elem: 'post', 16 | content: [ 17 | { 18 | block: 'link', 19 | url: item.url, 20 | attrs: { target: '_blank', title: source.title }, 21 | mix: { block: _this.block, elem: 'title' }, 22 | content: source.title 23 | }, 24 | source.summary ? { 25 | elem: 'description', 26 | content: source.summary 27 | } : undefined 28 | ] 29 | } : { 30 | elem: 'post', 31 | content: { 32 | block: 'link', 33 | url: item.url, 34 | attrs: { target: '_blank', title: item.title[req.lang] }, 35 | mix: { block: _this.block, elem: 'title' }, 36 | content: item.title[req.lang] 37 | } 38 | }; 39 | }) 40 | ]; 41 | }) 42 | ); 43 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/_type/search-item_type_post.styl: -------------------------------------------------------------------------------- 1 | .search-item_type_post 2 | { 3 | .search-item 4 | { 5 | &__title 6 | { 7 | font-size: 18px; 8 | display: block; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.bemhtml: -------------------------------------------------------------------------------- 1 | block('search-item')( 2 | js()(true) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - choose 3 | - description 4 | - levels 5 | - post 6 | - category 7 | - lib 8 | - title 9 | 10 | - mods: { type: [block, post] } 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.i18n/en.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-item": { 3 | "currentVersionTitle": 'Current version' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.i18n/ru.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "search-item": { 3 | "currentVersionTitle": 'Текущая версия' 4 | } 5 | }; 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.js: -------------------------------------------------------------------------------- 1 | modules.define('search-item', ['i-bem__dom', 'jquery'], function (provide, BEMDOM, $) { 2 | provide(BEMDOM.decl(this.name, { 3 | onSetMod: { 4 | js: { 5 | inited: function () { 6 | this._select = this.findBlockInside('select'); 7 | 8 | this._select && this._select.on('change', this._onSelectChange, this); 9 | this._setDescription(); 10 | } 11 | } 12 | }, 13 | 14 | _onSelectChange: function () { 15 | var val = this._select.getVal(); 16 | 17 | this._replaceLevelsUrl(val); 18 | }, 19 | 20 | _replaceLevelsUrl: function (newVersion) { 21 | this.elem('level').each(function (idx, level) { 22 | var $level = $(level), 23 | url = $level.attr('href'), 24 | // Match on the version /libs/bem-components/[v2.0.0]/desktop/button/ 25 | oldVersion = url.match(/^\/.+?\/.+?\/(.+?)\//)[1], 26 | newUrl; 27 | 28 | newUrl = url.replace(oldVersion, newVersion); 29 | $level.attr('href', newUrl); 30 | }); 31 | }, 32 | 33 | _setDescription: function () { 34 | var $desc = this.elem('description'), 35 | $paragraphs = $desc.find('p'); 36 | 37 | $paragraphs.each(function (idx, paragraph) { 38 | var paragraphInner = $(paragraph).html().trim(); 39 | 40 | if (paragraphInner !== '') { 41 | $desc.html(paragraphInner); 42 | 43 | return false; 44 | } 45 | }); 46 | 47 | if ($desc.text() === '') $desc.remove(); 48 | } 49 | })); 50 | }); 51 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-item/search-item.styl: -------------------------------------------------------------------------------- 1 | .search-item 2 | { 3 | position: relative; 4 | padding: 15px 0; 5 | 6 | &:before 7 | { 8 | position: absolute; 9 | top: 0; 10 | right: 0; 11 | left: 0; 12 | 13 | height: 2px; 14 | 15 | content: ''; 16 | 17 | background: linear-gradient(to left, #ffeba0 15%, #000 100%); 18 | } 19 | 20 | &:first-child 21 | { 22 | &:before 23 | { 24 | display: none; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/__content/_loading/search-panel__content_loading.styl: -------------------------------------------------------------------------------- 1 | .search-panel__content_loading 2 | { 3 | opacity: .3; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/__content/search-panel__content.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: { loading: true } 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/__content/search-panel__content.styl: -------------------------------------------------------------------------------- 1 | .search-panel__content 2 | { 3 | transition: opacity .5s; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/__spin/search-panel__spin.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: spin 2 | mods: { theme: islands } 3 | required: true 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/__spin/search-panel__spin.styl: -------------------------------------------------------------------------------- 1 | .search-panel__spin 2 | { 3 | &.spin_visible 4 | { 5 | position: absolute; 6 | top: 50%; 7 | left: 50%; 8 | 9 | margin: auto; 10 | } 11 | 12 | &.spin_visible.spin_size_xl 13 | { 14 | margin-top: -16px; 15 | margin-left: -16px; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/search-panel.bemhtml: -------------------------------------------------------------------------------- 1 | block('search-panel')( 2 | js()(true) 3 | ); 4 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/search-panel.bemtree: -------------------------------------------------------------------------------- 1 | block('search-panel')( 2 | content()(function () { 3 | return [ 4 | { block: 'search-form', mods: { type: 'default' } }, 5 | { 6 | block: 'spin', 7 | mods: { theme: 'islands', size: 'xl' }, 8 | mix: { block: this.block, elem: 'spin' } 9 | }, 10 | { elem: 'content' } 11 | ]; 12 | }) 13 | ); 14 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/search-panel.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - content 3 | - spin 4 | 5 | - block: search-results 6 | - block: search-form 7 | - block: events 8 | elem: channels 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/search-panel.js: -------------------------------------------------------------------------------- 1 | modules.define('search-panel', ['i-bem__dom', 'jquery', 'events__channels'], function (provide, BEMDOM, $, channels) { 2 | provide(BEMDOM.decl(this.name, { 3 | onSetMod: { 4 | js: { 5 | inited: function () { 6 | this._spin = this.findBlockInside('spin', 'spin'); 7 | this._form = this.findBlockInside({ block: 'search-form', modName: 'type', modVal: 'default' }); 8 | 9 | channels('search').on('change:input', this._sendRequest, this); 10 | } 11 | }, 12 | 13 | loading: function (modName, modVal) { 14 | this._spin.setMod('visible', modVal); 15 | this.setMod(this.elem('content'), 'loading', modVal); 16 | }, 17 | 18 | state: { 19 | open: function () { 20 | this._form.activate(); 21 | } 22 | } 23 | }, 24 | 25 | _toggle: function () { 26 | this.setMod('state', 'open'); 27 | }, 28 | 29 | _sendRequest: function (e, data) { 30 | this._abortRequest(); 31 | this.setMod('loading'); 32 | 33 | this._xhr = $.ajax({ 34 | type: 'GET', 35 | dataType: 'html', 36 | url: '/search?text=' + data.text, 37 | context: this, 38 | success: this._onSuccess 39 | }); 40 | }, 41 | 42 | _abortRequest: function () { 43 | this._xhr && this._xhr.abort(); 44 | }, 45 | 46 | _onSuccess: function (result) { 47 | this._updateContent(result); 48 | this.delMod('loading'); 49 | }, 50 | 51 | _updateContent: function (html) { 52 | BEMDOM.update(this.elem('content'), html); 53 | } 54 | })); 55 | }); 56 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-panel/search-panel.styl: -------------------------------------------------------------------------------- 1 | .search-panel 2 | { 3 | position: absolute; 4 | z-index: 1001; 5 | top: 0; 6 | right: -350px; 7 | 8 | overflow-y: auto; 9 | 10 | box-sizing: border-box; 11 | width: 350px; 12 | height: 100%; 13 | padding: 20px; 14 | 15 | transition: right .3s ease-out; 16 | 17 | background-color: #fafafa; 18 | box-shadow: 0 0 2px 0 rgba(0,0,0,.3); 19 | 20 | &_state_open 21 | { 22 | right: 0; 23 | } 24 | 25 | .search-form 26 | { 27 | margin-bottom: 10px; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-results/__error-text/search-results__error-text.styl: -------------------------------------------------------------------------------- 1 | .search-results__error-text 2 | { 3 | margin-bottom: 10px; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-results/__error/search-results__error.styl: -------------------------------------------------------------------------------- 1 | .search-results__error 2 | { 3 | margin-top: 15px; 4 | text-align: center; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-results/search-results.bemtree: -------------------------------------------------------------------------------- 1 | block('search-results')( 2 | match(function () { return this.ctx.text.length < 2; }).content()(function () { 3 | return { 4 | elem: 'error', 5 | content: 'Нужно ввести минимум 2 буквы' 6 | }; 7 | }), 8 | 9 | match(function () { return !this.ctx.data.length && this.ctx.text.length > 1; }).content()(function () { 10 | return { 11 | elem: 'error', 12 | content: 'По запросу ' + this.ctx.text + ' ничего не найдено.' 13 | }; 14 | }), 15 | 16 | match(function () { return this.ctx.data.length; }).content()(function () { 17 | return this.ctx.data.map(function (item) { 18 | return { 19 | block: 'search-item', 20 | mods: { type: item.class }, 21 | content: item 22 | }; 23 | }); 24 | }) 25 | ); 26 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/search-results/search-results.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: search-item 2 | 3 | - elems: 4 | - error 5 | - error-text 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/styling/styling.styl: -------------------------------------------------------------------------------- 1 | /* 2 | Desc: Common styling variables bem-site-engine 3 | 4 | Note: The code of this block must be above all other stylus files. 5 | Usage: We connect it in page block deps with 'required option' 6 | */ 7 | 8 | $link = #01b 9 | $linkVisited = #551a8b 10 | $linkHover = #000 11 | 12 | $transition-delay = .3s ease-out 13 | 14 | /* Colors */ 15 | $black = #000 16 | $brown = #473e09 17 | $white = #fff 18 | $yellow = #ffd94d 19 | $grey = #e5e5e5 20 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/__header/tabs__header.styl: -------------------------------------------------------------------------------- 1 | .tabs__header 2 | { 3 | margin: 0; 4 | padding: 0; 5 | } 6 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/__pane/tabs__pane.styl: -------------------------------------------------------------------------------- 1 | .tabs__pane 2 | { 3 | display: none; 4 | 5 | padding-top: 20px; 6 | 7 | &_state_current 8 | { 9 | display: block; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/__tab/tabs__tab.styl: -------------------------------------------------------------------------------- 1 | .tabs__tab 2 | { 3 | position: relative; 4 | 5 | display: inline-block; 6 | 7 | cursor: pointer; 8 | user-select: none; 9 | 10 | -webkit-tap-highlight-color: rgba(0, 0, 0, 0); 11 | } 12 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/_theme/tabs_theme_default.bemhtml: -------------------------------------------------------------------------------- 1 | block('tabs').mod('theme', 'default')( 2 | elem('header').tag()('ul'), 3 | elem('tab').tag()('li') 4 | ); 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/_theme/tabs_theme_default.ie.styl: -------------------------------------------------------------------------------- 1 | .tabs_theme_default .tabs__header 2 | { 3 | position: relative; 4 | 5 | display: block; 6 | } 7 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/_theme/tabs_theme_default.styl: -------------------------------------------------------------------------------- 1 | .tabs_theme_default .tabs 2 | { 3 | /* Верхняя черта */ 4 | &__header 5 | { 6 | position: fixed; 7 | 8 | z-index: 99; 9 | 10 | background: #fff; 11 | 12 | width: 100%; 13 | 14 | opacity: 0.9; 15 | 16 | line-height: 34px; 17 | 18 | list-style: none outside none; 19 | 20 | border-bottom: 1px solid $grey; 21 | } 22 | 23 | /* Цвет и отступы отдельного таба */ 24 | &__tab 25 | { 26 | margin-right: 15px; 27 | 28 | color: #999; 29 | 30 | &:after 31 | { 32 | position: absolute; 33 | right: 0; 34 | bottom: -1px; 35 | left: 0; 36 | 37 | content: ''; 38 | } 39 | 40 | &:hover:after 41 | { 42 | border-bottom: 2px solid #000; 43 | } 44 | 45 | &_state_current 46 | { 47 | color: #000; 48 | 49 | /* Верхнее выделение таба */ 50 | &:after 51 | { 52 | border-bottom: 3px solid !important; 53 | } 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/tabs.bemhtml: -------------------------------------------------------------------------------- 1 | block('tabs').js()(true); 2 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/tabs.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - header 3 | - tab 4 | - pane 5 | -------------------------------------------------------------------------------- /src/blocks/common.blocks/tabs/tabs.styl: -------------------------------------------------------------------------------- 1 | .tabs 2 | { 3 | position: relative; 4 | } 5 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/app-error/_type/app-error_type_http.node.js: -------------------------------------------------------------------------------- 1 | var Terror = require('terror'); 2 | 3 | modules.define('httpError', function (provide) { 4 | 5 | provide(Terror.create('HttpError', { 6 | NOT_FOUND: [404, 'Resource not found'], 7 | INTERNAL_SERVER_ERROR: [500, 'Error occured on server'] 8 | })); 9 | }); 10 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/app-error/app-error.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | type: [http] 3 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/app-error/app-error.node.js: -------------------------------------------------------------------------------- 1 | modules.define('appError', ['httpError'], function (provide, httpError) { 2 | provide({ 3 | HttpError: httpError 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/app/app.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: provider 4 | - block: model 5 | - block: util 6 | - block: middleware 7 | - block: updater 8 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/builder/builder.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: util 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/builder/builder.node.js: -------------------------------------------------------------------------------- 1 | var vow = require('vow'); 2 | 3 | modules.define('builder', ['util'], function (provide, util) { 4 | var enbBuilder; 5 | 6 | provide({ 7 | build: function (targets) { 8 | 9 | if (!util.isDev()) { 10 | return vow.resolve(); 11 | } 12 | 13 | var serverMiddleware = require('enb/lib/server/server-middleware'), 14 | dropRequireCache = require('enb/lib/fs/drop-require-cache'); 15 | 16 | enbBuilder = enbBuilder || serverMiddleware.createBuilder({ 17 | cdir: process.cwd(), 18 | noLog: false 19 | }); 20 | 21 | return vow.all( 22 | targets.map(function (target) { 23 | return enbBuilder(target).then(function () { 24 | dropRequireCache(require, target); 25 | return target; 26 | }); 27 | }) 28 | ); 29 | } 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/config/config.node.js: -------------------------------------------------------------------------------- 1 | var nconf = require('nconf'), 2 | path = require('path'); 3 | 4 | modules.define('config', function (provide) { 5 | 6 | nconf 7 | .argv() 8 | .env(); 9 | 10 | [ 11 | 'current/common', 12 | 'current/app', 13 | 'common/common', 14 | 'common/app' 15 | ].forEach(function (item) { 16 | nconf.add(item, { 17 | type: 'file', 18 | file: path.resolve(process.cwd(), 'configs', (item + '.json')) 19 | }); 20 | }); 21 | 22 | provide(nconf); 23 | }); 24 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/constants/constants.node.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | modules.define('constants', function (provide) { 4 | 5 | provide({ 6 | ROUTE: { 7 | NAME: 'name', 8 | CONDITIONS: 'conditions', 9 | DEFAULTS: 'defaults', 10 | DATA: 'data' 11 | }, 12 | DIRS: { 13 | CACHE: 'cache', 14 | BRANCH: 'branch', 15 | TAG: 'tag' 16 | }, 17 | MENU: { 18 | DEFAULT: 'default', 19 | MAIN: 'main', 20 | LEVEL: 'level' 21 | }, 22 | SITEMAP: 'sitemap.xml', 23 | PAGE_CACHE: path.join(process.cwd(), 'cache', 'page') 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/helper/_type/helper_type_bundles.node.js: -------------------------------------------------------------------------------- 1 | modules.define('bundles', function (provide) { 2 | var PATH = require('path'), 3 | LOD_DIR = 'bundles', 4 | LOD_SUFFIX = '.bundles'; 5 | 6 | function Bundles(settings) { 7 | this._rootPath = (settings && settings.root) || '/'; 8 | this._defaultLOD = (settings && settings.defaultLOD) || 'common'; 9 | } 10 | 11 | Bundles.prototype.getBundlePath = function (name, LOD) { 12 | LOD || (LOD = this._defaultLOD); 13 | 14 | return PATH.join(this._rootPath, LOD_DIR, LOD + LOD_SUFFIX, name); 15 | }; 16 | 17 | provide({ 18 | Bundles: Bundles 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/helper/_type/helper_type_statics.node.js: -------------------------------------------------------------------------------- 1 | var url = require('url'); 2 | 3 | modules.define('statics', function (provide) { 4 | function Statics(baseUrl) { 5 | this._url = (typeof baseUrl === 'object') ? url.format(baseUrl) : baseUrl; 6 | this._parsedUrl = url.parse(this._url); 7 | } 8 | 9 | Statics.prototype.getUrl = function (localPath) { 10 | return this._url + localPath; 11 | }; 12 | 13 | provide({ 14 | Statics: Statics 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/helper/helper.deps.yaml: -------------------------------------------------------------------------------- 1 | - mods: 2 | type: [bundles, statics] 3 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/index/index.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: app 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/index/index.node.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | fs = require('fs'); 3 | 4 | modules.require(['app'], function (app) { 5 | var p = '../../../../bundles/desktop.bundles/common/common.node.js'; 6 | fs.exists(path.join(module.filename, p), function (exists) { 7 | exists && app.init(); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/logger/logger.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: config 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/logger/logger.node.js: -------------------------------------------------------------------------------- 1 | var intel = require('intel'); 2 | 3 | modules.define('logger', ['config'], function (provide, config) { 4 | 5 | // set logger verbosity level from configuration file 6 | intel.setLevel(config.get('logger:level') || 'debug'); 7 | 8 | // add console logger handler 9 | intel.addHandler( 10 | new intel.handlers.Console({ 11 | level: intel.VERBOSE, 12 | formatter: new intel.Formatter({ 13 | format: '[%(date)s] %(levelname)s %(name)s: %(message)s', 14 | colorize: true 15 | }) 16 | }) 17 | ); 18 | 19 | // add file logger handler 20 | intel.addHandler( 21 | new intel.handlers.File({ 22 | file: config.get('logger:stdout'), 23 | level: intel.DEBUG, 24 | formatter: new intel.Formatter({ 25 | format: '[%(date)s] %(levelname)s %(name)s: %(message)s', 26 | colorize: true 27 | }) 28 | }) 29 | ); 30 | 31 | provide(function (module) { 32 | var name = module ? module.filename.split('/').slice(-2).join('/') : ''; 33 | return intel.getLogger(name); 34 | }); 35 | }); 36 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__error/middleware__error.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: util 4 | - block: builder 5 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__html-cache/middleware__html-cache.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: constants 3 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__html-cache/middleware__html-cache.node.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'), 2 | zlib = require('zlib'), 3 | path = require('path'); 4 | 5 | modules.define('middleware__html-cache', ['logger', 'constants'], function (provide, logger, constants) { 6 | logger = logger(module); 7 | 8 | provide(function () { 9 | return function (req, res, next) { 10 | var pagePath = path.join(constants.PAGE_CACHE, req.__data.node.url, (req.lang + '.html.gzip')); 11 | 12 | fs.exists(pagePath, function (exists) { 13 | if (!exists) { 14 | return next(); 15 | } 16 | 17 | logger.debug('load page from cache: %s', pagePath); 18 | 19 | var raw = fs.createReadStream(pagePath); 20 | var acceptEncoding = req.headers['accept-encoding']; 21 | if (!acceptEncoding) { 22 | acceptEncoding = ''; 23 | } 24 | 25 | if (acceptEncoding.match(/\bgzip\b/)) { 26 | res.writeHead(200, { 'content-encoding': 'gzip' }); 27 | raw.pipe(res); 28 | } else if (acceptEncoding.match(/\bdeflate\b/)) { 29 | res.writeHead(200, { 'content-encoding': 'deflate' }); 30 | raw.pipe(res); 31 | } else { 32 | res.writeHead(200, {}); 33 | raw.pipe(zlib.createGunzip()).pipe(res); 34 | } 35 | }); 36 | }; 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__lang-switcher/middleware__lang-switcher.node.js: -------------------------------------------------------------------------------- 1 | var u = require('util'); 2 | 3 | modules.define('middleware__lang-switcher', function (provide) { 4 | 5 | provide(function () { 6 | return function (req, res, next) { 7 | var node = req.__data.node, 8 | lang = { 9 | en: 'ru', 10 | ru: 'en' 11 | }[req.lang], 12 | host = req.headers.host.replace(u.format('%s.', req.lang), ''), 13 | url = u.format('//%s.%s%s', lang, host, node.hidden[lang] ? '/' : req.path); 14 | 15 | req.__data.langSwitch = url; 16 | return next(); 17 | }; 18 | }); 19 | }); 20 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__locale/middleware__locale.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: util 3 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__locale/middleware__locale.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__locale', ['logger', 'util'], function (provide, logger, util) { 2 | 3 | logger = logger(module); 4 | 5 | var languages, 6 | defaultLanguage; 7 | 8 | /** 9 | * Middleware for lang detection by subdomain 10 | * @returns {Function} 11 | */ 12 | provide(function () { 13 | languages = util.getLanguages(); 14 | defaultLanguage = util.getDefaultLanguage(); 15 | 16 | return function (req, res, next) { 17 | // TODO Here you can implement your own lang detection mechanism 18 | 19 | req.lang = defaultLanguage; 20 | logger.debug('request locale was set to %s', req.lang); 21 | return next(); 22 | }; 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__logger/middleware__logger.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__logger/middleware__logger.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__logger', ['logger'], function (provide, logger) { 2 | logger = logger(module); 3 | 4 | provide(function () { 5 | return function (req, res, next) { 6 | logger.info('request method: %s url: %s locale: %s', req.method, decodeURIComponent(req.url), req.lang); 7 | return next(); 8 | }; 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__metrika/middleware__metrika.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: config 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__metrika/middleware__metrika.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__metrika', ['config'], function (provide, config) { 2 | /** 3 | * Middleware for set Yandex Metrika counter from config 4 | * @returns {Function} 5 | */ 6 | provide(function () { 7 | return function (req, res, next) { 8 | req.metrika = config.get('metrika'); 9 | 10 | return next(); 11 | }; 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page-menu/middleware__page-menu.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: constants 3 | - block: model 4 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page-meta/middleware__page-meta.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page-meta/middleware__page-meta.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__page-meta', ['logger'], function (provide, logger) { 2 | logger = logger(module); 3 | 4 | provide(function () { 5 | 6 | /** 7 | * Retrieves meta-information for request by request 8 | * @param req - {Object} http request object 9 | * Sets meta object with fields: 10 | * description - {String} meta-description attribute 11 | * ogDescription - {String} og:description attribute 12 | * keywords - {String} keywords for source 13 | * ogKeywords - {String} keywords for source, og:keywords attribute 14 | * ogType - {String} type of source 15 | * ogUrl - {String} url of source 16 | */ 17 | return function (req, res, next) { 18 | logger.debug('get meta by request %s', req.url); 19 | 20 | var node = req.__data.node, 21 | source = node.source && node.source[req.lang], 22 | meta = { 23 | description: node.title ? node.title[req.lang] : '', 24 | ogUrl: req.url 25 | }; 26 | 27 | if (source) { 28 | meta.description = meta.ogDescription = source.title; 29 | meta.keywords = meta.ogKeywords = source.tags ? source.tags.join(', ') : ''; 30 | meta.ogType = 'article'; 31 | } 32 | 33 | req.__data.meta = meta; 34 | return next(); 35 | }; 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page-title/middleware__page-title.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: config 2 | - block: logger 3 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page-title/middleware__page-title.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__page-title', ['config', 'logger'], function (provide, config, logger) { 2 | 3 | logger = logger(module); 4 | 5 | provide({ 6 | run: function () { 7 | var _this = this; 8 | 9 | return function (req, res, next) { 10 | logger.debug('get title by request %s', req.url); 11 | 12 | var node = req.__data.node, 13 | titles = [], 14 | traverseTreeNodes = function (node) { 15 | node.url && node.title && titles.push(node.title[req.lang]); 16 | node.parent && traverseTreeNodes(node.parent); 17 | }; 18 | 19 | if (_this.hasExceptions(req, node)) return next(); 20 | 21 | traverseTreeNodes(node); 22 | 23 | // add common suffix from application configuration 24 | titles.push(config.get('title')[req.lang]); 25 | 26 | req.__data.title = titles.join(' / '); 27 | return next(); 28 | }; 29 | }, 30 | 31 | hasExceptions: function (req, node) { 32 | if (req.url === '/') { 33 | req.__data.title = node.title[req.lang]; 34 | return true; 35 | } 36 | } 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__page/middleware__page.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: config 2 | - block: logger 3 | - block: model 4 | - block: constants 5 | - block: template 6 | - block: provider 7 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__proxy-example/middleware__proxy-example.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: config 2 | - block: constants 3 | - block: logger 4 | - block: util 5 | - block: provider 6 | - block: model 7 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__redirect/middleware__redirect.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: util 3 | - block: model 4 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__redirect/middleware__redirect.node.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | 3 | modules.define('middleware__redirect', ['logger', 'util', 'model'], function (provide, logger, util, model) { 4 | 5 | logger = logger(module); 6 | 7 | var redirects = []; 8 | 9 | /** 10 | * Middleware for old url redirects 11 | * @returns {Function} 12 | */ 13 | provide({ 14 | init: function () { 15 | try { 16 | redirects = require(path.join(process.cwd(), 'configs/common/redirects.js')); 17 | } catch (err) { 18 | logger.warn('redirects.js file was not found in configs/common directory'); 19 | } 20 | redirects = redirects.concat(model.getRedirects()); 21 | }, 22 | 23 | run: function () { 24 | this.init(); 25 | 26 | return function (req, res, next) { 27 | var url = req.path, 28 | redirect = redirects.filter(function (item) { 29 | return item[0].exec(url); 30 | })[0]; 31 | 32 | if (!redirect) { 33 | return next(); 34 | } 35 | 36 | var match = url.match(redirect[0]), 37 | target = redirect[1]; 38 | 39 | for (var i = 1; i < match.length; i++) { 40 | target = target.replace('$' + i, match[i]); 41 | } 42 | return res.redirect(target); 43 | }; 44 | } 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__router/middleware__router.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: model 4 | - block: app-error 5 | 6 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__search/middleware__search.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: model 4 | - block: template 5 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__service/middleware__service.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: updater 4 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__service/middleware__service.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__service', ['config', 'logger', 'updater'], 2 | function (provide, config, logger, updater) { 3 | logger = logger(module); 4 | 5 | provide(function () { 6 | return function (req, res, next) { 7 | var url = req.path; 8 | if (url.indexOf('/__service') === -1) { 9 | return next(); 10 | } 11 | logger.info('Service request has been received'); 12 | 13 | var result = { 14 | config: { 15 | NODE_ENV: config.get('NODE_ENV'), 16 | port: config.get('port'), 17 | statics: config.get('statics'), 18 | logger: { 19 | out: config.get('logger:stdout'), 20 | err: config.get('logger:stderr') 21 | } 22 | }, 23 | marker: updater.getMarker() 24 | }; 25 | 26 | return res.json(result); 27 | }; 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/__slashes/middleware__slashes.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware__slashes', function (provide) { 2 | provide(require('connect-slashes')); 3 | }); 4 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/middleware.deps.yaml: -------------------------------------------------------------------------------- 1 | - elems: 2 | - lang-switcher 3 | - locale 4 | - logger 5 | - error 6 | - page 7 | - page-title 8 | - page-meta 9 | - page-menu 10 | - proxy-example 11 | - search 12 | - router 13 | - html-cache 14 | - slashes 15 | - redirect 16 | - service 17 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/middleware/middleware.node.js: -------------------------------------------------------------------------------- 1 | modules.define('middleware', [ 2 | 'middleware__locale', 3 | 'middleware__logger', 4 | 'middleware__service', 5 | 'middleware__proxy-example', 6 | 'middleware__search', 7 | 'middleware__slashes', 8 | 'middleware__redirect', 9 | 'middleware__router', 10 | 'middleware__html-cache', 11 | 'middleware__page-title', 12 | 'middleware__page-meta', 13 | 'middleware__page-menu', 14 | 'middleware__lang-switcher', 15 | 'middleware__page', 16 | 'middleware__error' 17 | ], 18 | function (provide, locale, logger, service, proxyExample, search, slashes, redirect, router, 19 | htmlCache, pageTitle, pageMeta, pageMenu, langSwitcher, page, error) { 20 | 21 | return provide(function () { 22 | return [ 23 | locale, 24 | logger, 25 | service, 26 | proxyExample, 27 | search, 28 | slashes, 29 | redirect, 30 | router, 31 | htmlCache, 32 | pageTitle, 33 | pageMeta, 34 | pageMenu, 35 | langSwitcher, 36 | page, 37 | error 38 | ]; 39 | }); 40 | } 41 | ); 42 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/model/model.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: util 4 | - block: provider 5 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/provider/_type/provider_type_disk.node.js: -------------------------------------------------------------------------------- 1 | var YandexDisk = require('yandex-disk'), 2 | vow = require('vow'); 3 | 4 | modules.define('providerDisk', ['logger', 'config', 'util'], function (provide, logger, config, util) { 5 | 6 | logger = logger(module); 7 | 8 | var disk; 9 | 10 | provide({ 11 | init: function () { 12 | disk = new YandexDisk.YandexDisk( 13 | config.get('yandexApi:login'), 14 | config.get('yandexApi:password') 15 | ); 16 | }, 17 | 18 | /** 19 | * Reads file from yandex disk 20 | * @param options - {Object} object with fields 21 | * - path {String} path to file 22 | * @returns {*} 23 | */ 24 | load: function (options) { 25 | logger.debug('read file %s from yandex disk', options.path); 26 | 27 | var def = vow.defer(); 28 | disk.readFile(options.path, 'utf8', function (err, content) { 29 | if (err || !content) { 30 | def.reject(err); 31 | } 32 | def.resolve(options.archive ? util.unzip(content) : content); 33 | }); 34 | return def.promise(); 35 | }, 36 | 37 | /** 38 | * Downloads file from yandex disk to local filesystem 39 | * @param options - {Object} with fields 40 | * - source {String} source path on Yandex Disk 41 | * - target {String} target path on local filesystem 42 | * @returns {*} 43 | */ 44 | downloadFile: function (options) { 45 | logger.debug('read file %s from yandex disk to %s', options.source, options.target); 46 | var def = vow.defer(); 47 | disk.downloadFile(options.source, options.target, function (err) { 48 | err ? def.reject(err) : def.resolve(); 49 | }); 50 | return def.promise(); 51 | } 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/provider/provider.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: util 4 | - mods: 5 | type: [file, disk] 6 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/template/template.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: util 4 | - block: builder 5 | - block: helper 6 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/updater/updater.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: config 3 | - block: provider 4 | - block: model 5 | - block: util 6 | - block: middleware 7 | -------------------------------------------------------------------------------- /src/blocks/server.blocks/util/util.deps.yaml: -------------------------------------------------------------------------------- 1 | - block: logger 2 | - block: constants 3 | - block: config 4 | - block: provider 5 | 6 | -------------------------------------------------------------------------------- /src/bundles/desktop.bundles/common/common.bemdecl.js: -------------------------------------------------------------------------------- 1 | exports.blocks = [ 2 | { "name": "error" }, 3 | { "name": "i-global" }, 4 | { "name": "page" }, 5 | 6 | { "name": "index"} 7 | ]; 8 | -------------------------------------------------------------------------------- /src/bundles/errors.bundles/error-404/error-404.bemjson.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "block": "page", 3 | "title": "Error / BEM", 4 | "head": [ 5 | [ 6 | { 7 | "elem": "css", 8 | "url": "{STATICS_HOST}/bundles/errors.bundles/error-404/error-404.min.css", 9 | "ie": false 10 | }, 11 | { 12 | "elem": "css", 13 | "url": "{STATICS_HOST}/bundles/errors.bundles/error-404/error-404.min", 14 | "ie": true 15 | } 16 | ], 17 | { 18 | "elem": "meta", 19 | "attrs": { 20 | "property": "og:title", 21 | "content": "Error / BEM" 22 | } 23 | }, 24 | { 25 | "elem": "meta", 26 | "attrs": { 27 | "property": "og:type", 28 | "content": "article" 29 | } 30 | }, 31 | { 32 | "elem": "meta", 33 | "attrs": { 34 | "property": "og:url", 35 | "content": "http://bem.info/404/" 36 | } 37 | } 38 | ], 39 | "content": [ 40 | { 41 | "block": "error-billboard", 42 | "code": 404, 43 | "content": 404 44 | }, 45 | { 46 | "block": "metrika" 47 | } 48 | ] 49 | }) -------------------------------------------------------------------------------- /src/bundles/errors.bundles/error-500/error-500.bemjson.js: -------------------------------------------------------------------------------- 1 | ({ 2 | "block": "page", 3 | "title": "Error / BEM", 4 | "head": [ 5 | [ 6 | { 7 | "elem": "css", 8 | "url": "{STATICS_HOST}/bundles/errors.bundles/error-500/error-500.min.css", 9 | "ie": false 10 | }, 11 | { 12 | "elem": "css", 13 | "url": "{STATICS_HOST}/bundles/errors.bundles/error-500/error-500.min", 14 | "ie": true 15 | } 16 | ], 17 | { 18 | "elem": "meta", 19 | "attrs": { 20 | "property": "og:title", 21 | "content": "Error / BEM" 22 | } 23 | }, 24 | { 25 | "elem": "meta", 26 | "attrs": { 27 | "property": "og:type", 28 | "content": "article" 29 | } 30 | }, 31 | { 32 | "elem": "meta", 33 | "attrs": { 34 | "property": "og:url", 35 | "content": "http://bem.info/500/" 36 | } 37 | } 38 | ], 39 | "content": [ 40 | { 41 | "block": "error-billboard", 42 | "code": 500, 43 | "content": 500 44 | }, 45 | { 46 | "block": "metrika" 47 | } 48 | ] 49 | }) -------------------------------------------------------------------------------- /src/data/coa.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('coa').Cmd() 4 | .name(process.argv[1]) 5 | .title('Bem-Site engine data builder') 6 | .helpful() 7 | .cmd().name('development').apply(require('./commands/development')).end() 8 | .cmd().name('testing').apply(require('./commands/testing')).end() 9 | .cmd().name('production').apply(require('./commands/production')).end() 10 | .completable(); 11 | -------------------------------------------------------------------------------- /src/data/config.js: -------------------------------------------------------------------------------- 1 | var nconf = require('nconf'), 2 | path = require('path'); 3 | 4 | nconf.env(); 5 | 6 | ['current/app', 'common/app'].forEach(function (item) { 7 | nconf.add(item, { 8 | type: 'file', 9 | file: path.resolve(process.cwd(), 'configs', (item + '.json')) 10 | }); 11 | }); 12 | 13 | module.exports = nconf; 14 | -------------------------------------------------------------------------------- /src/data/constants.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ROUTE: { 3 | NAME: 'name', 4 | CONDITIONS: 'conditions', 5 | DEFAULTS: 'defaults', 6 | DATA: 'data' 7 | }, 8 | FILES: [ 9 | 'data.json', 10 | 'sitemap.xml', 11 | 'search_libraries.json', 12 | 'search_blocks.json', 13 | 'marker.json' 14 | ] 15 | }; 16 | -------------------------------------------------------------------------------- /src/data/logger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var intel = require('intel'); 4 | 5 | intel.setLevel('debug'); 6 | intel.addHandler( 7 | new intel.handlers.Console({ 8 | level: intel.VERBOSE, 9 | formatter: new intel.Formatter({ 10 | format: '[%(date)s] %(levelname)s %(name)s: %(message)s', 11 | colorize: true 12 | }) 13 | }) 14 | ); 15 | 16 | /** 17 | * Returns logger by it name 18 | * If first arguments is module then add part of module file path to log string 19 | * @param {Object} module 20 | * @returns {*} 21 | */ 22 | function getLogger(module) { 23 | return intel.getLogger(module ? module.filename.split('/').slice(-2).join('/') : ''); 24 | } 25 | 26 | /** 27 | * Alias for logging verbose messages 28 | * @param {String} str (string) for logging 29 | * @param {Object} module object 30 | * @returns {*} 31 | */ 32 | exports.verbose = function (str, module) { 33 | return getLogger(module).verbose(str); 34 | }; 35 | 36 | /** 37 | * Alias for logging debug messages 38 | * @param {String} str (string) for logging 39 | * @param {Object} module object 40 | * @returns {*} 41 | */ 42 | exports.debug = function (str, module) { 43 | return getLogger(module).debug(str); 44 | }; 45 | 46 | /** 47 | * Alias for logging info messages 48 | * @param {String} str (string) for logging 49 | * @param {Object} module object 50 | * @returns {*} 51 | */ 52 | exports.info = function (str, module) { 53 | return getLogger(module).info(str); 54 | }; 55 | 56 | /** 57 | * Alias for logging warn messages 58 | * @param {String} str (string) for logging 59 | * @param {Object} module object 60 | * @returns {*} 61 | */ 62 | exports.warn = function (str, module) { 63 | return getLogger(module).warn(str); 64 | }; 65 | 66 | /** 67 | * Alias for logging error messages 68 | * @param {String} str (string) for logging 69 | * @param {Object} module object 70 | * @returns {*} 71 | */ 72 | exports.error = function (str, module) { 73 | return getLogger(module).error(str); 74 | }; 75 | -------------------------------------------------------------------------------- /src/data/make/sitemapXML.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'), 2 | js2xml = require('js2xmlparser'), 3 | 4 | logger = require('../logger'), 5 | config = require('../config'), 6 | utility = require('../util'); 7 | 8 | module.exports = function (obj) { 9 | logger.info('Start to build "sitemap.xml" file', module); 10 | 11 | var hosts = config.get('hosts') || {}, 12 | nodes = utility 13 | .findNodesByCriteria(obj.sitemap, function () { 14 | return this.hidden && _.isString(this.url) && !/^(https?:)?\/\//.test(this.url); 15 | }, false) 16 | .map(function (item) { 17 | return _.pick(item, 'url', 'hidden', 'search'); 18 | }), 19 | map = nodes.reduce(function (prev, item) { 20 | Object.keys(hosts).forEach(function (lang) { 21 | if (!item.hidden[lang]) { 22 | prev.push(_.extend({ loc: hosts[lang] + item.url }, item.search)); 23 | } 24 | }); 25 | return prev; 26 | }, []); 27 | 28 | obj.sitemapXml = js2xml('urlset', { url: map }); 29 | logger.info('File "sitemap.xml" has been constructed successfully', module); 30 | return obj; 31 | }; 32 | -------------------------------------------------------------------------------- /src/data/model/index.js: -------------------------------------------------------------------------------- 1 | exports.base = require('./base'); 2 | exports.dynamic = require('./dynamic'); 3 | exports.tag = require('./tag'); 4 | exports.block = require('./block'); 5 | exports.post = require('./post'); 6 | exports.level = require('./level'); 7 | exports.person = require('./person'); 8 | exports.version = require('./version'); 9 | 10 | exports.search = require('./search'); 11 | -------------------------------------------------------------------------------- /src/data/model/person.js: -------------------------------------------------------------------------------- 1 | var util = require('util'), 2 | utility = require('../util'), 3 | DynamicNode = require('./dynamic').DynamicNode; 4 | 5 | /** 6 | * Subclass of dynamic nodes which describe person 7 | * @param parent - {BaseNode} parent node 8 | * @param routes - {Object} application routes hash 9 | * @param key - {String} person data 10 | * @param people - {Object} people data 11 | * @constructor 12 | */ 13 | var PersonNode = function (parent, routes, key, people) { 14 | this 15 | .setTitle(people[key]) 16 | .processRoute(routes, parent, { 17 | conditions: { 18 | id: key 19 | } 20 | }) 21 | .init(parent); 22 | 23 | }; 24 | 25 | PersonNode.prototype = Object.create(DynamicNode.prototype); 26 | 27 | /** 28 | * Sets title for node 29 | * @param person - {Object} object data for person 30 | * @returns {PersonNode} 31 | */ 32 | PersonNode.prototype.setTitle = function (person) { 33 | this.title = utility.getLanguages().reduce(function (prev, lang) { 34 | prev[lang] = util.format('%s %s', person[lang]['firstName'], person[lang]['lastName']); 35 | return prev; 36 | }, {}); 37 | return this; 38 | }; 39 | 40 | /** 41 | * Sets view for node 42 | * @returns {PersonNode} 43 | */ 44 | PersonNode.prototype.setView = function () { 45 | this.view = this.VIEW.AUTHOR; 46 | return this; 47 | }; 48 | 49 | /** 50 | * Sets class for node 51 | * @returns {PersonNode} 52 | */ 53 | PersonNode.prototype.setClass = function () { 54 | this.class = 'person'; 55 | return this; 56 | }; 57 | 58 | exports.PersonNode = PersonNode; 59 | -------------------------------------------------------------------------------- /src/data/model/post.js: -------------------------------------------------------------------------------- 1 | var utility = require('../util'), 2 | nodes = require('./index'); 3 | 4 | /** 5 | * Subclass of dynamic nodes which describe post of library 6 | * @param parent - {VersionNode} parent node object 7 | * @param routes - {Object} application routes hash 8 | * @param version - {Object} library version object 9 | * @param doc - {Object} doc object 10 | * @param id - {String} key of doc 11 | * @constructor 12 | */ 13 | var PostNode = function (parent, routes, version, doc, id) { 14 | this.setTitle(doc) 15 | .setSource(doc) 16 | .processRoute(routes, parent, { 17 | conditions: { 18 | lib: version.repo, 19 | version: version.ref, 20 | id: id 21 | } 22 | }) 23 | .init(parent) 24 | .createBreadcrumbs(); 25 | }; 26 | 27 | PostNode.prototype = Object.create(nodes.dynamic.DynamicNode.prototype); 28 | 29 | /** 30 | * Sets title for node 31 | * @param doc - {Object} doc object 32 | * @returns {PostNode} 33 | */ 34 | PostNode.prototype.setTitle = function (doc) { 35 | this.title = doc.title; 36 | return this; 37 | }; 38 | 39 | /** 40 | * Sets source for node 41 | * @param doc - {Object} doc object 42 | * @returns {PostNode} 43 | */ 44 | PostNode.prototype.setSource = function (doc) { 45 | this.source = utility.getLanguages().reduce(function (prev, lang) { 46 | prev[lang] = { 47 | title: doc.title[lang], 48 | content: doc.content[lang] 49 | }; 50 | return prev; 51 | }, {}); 52 | 53 | return this; 54 | }; 55 | 56 | /** 57 | * Sets class for node 58 | * @returns {PostNode} 59 | */ 60 | PostNode.prototype.setClass = function () { 61 | this.class = 'post'; 62 | return this; 63 | }; 64 | 65 | exports.PostNode = PostNode; 66 | -------------------------------------------------------------------------------- /src/data/model/search/index.js: -------------------------------------------------------------------------------- 1 | exports.Library = require('./library'); 2 | exports.Version = require('./version'); 3 | exports.Level = require('./level'); 4 | exports.Block = require('./block'); 5 | -------------------------------------------------------------------------------- /src/data/model/search/level.js: -------------------------------------------------------------------------------- 1 | var Level = function (name) { 2 | return this.init(name); 3 | }; 4 | 5 | Level.prototype = { 6 | 7 | name: null, 8 | blocks: null, 9 | 10 | /** 11 | * Initialize level object 12 | * @param name - {String} level name 13 | */ 14 | init: function (name) { 15 | this.name = name.replace(/\.(sets|blocks)/, ''); 16 | this.blocks = []; 17 | }, 18 | 19 | /** 20 | * Add block to library search item 21 | * @param block - {String} name of block 22 | * @returns {Level} 23 | */ 24 | addBlock: function (block) { 25 | this.blocks.push(block); 26 | return this; 27 | } 28 | }; 29 | 30 | module.exports = Level; 31 | -------------------------------------------------------------------------------- /src/data/model/search/library.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | 3 | var Library = function (name) { 4 | return this.init(name); 5 | }; 6 | 7 | Library.prototype = { 8 | 9 | name: null, 10 | versions: null, 11 | 12 | /** 13 | * Initialize search library object 14 | * @param name - {String} name of library 15 | * @returns {Library} 16 | */ 17 | init: function (name) { 18 | this.name = name; 19 | this.versions = []; 20 | 21 | return this; 22 | }, 23 | 24 | /** 25 | * Add version to library search item 26 | * @param version - {String} version of library 27 | * @returns {Library} 28 | */ 29 | addVersion: function (version) { 30 | this.versions.push(version); 31 | return this; 32 | }, 33 | 34 | /** 35 | * Finds version of library by it name 36 | * @param name - {String} name of library version 37 | * @returns {Version} 38 | */ 39 | getVersion: function (name) { 40 | return _.find(this.versions, function (item) { 41 | return item.name && item.name === name; 42 | }); 43 | } 44 | }; 45 | 46 | module.exports = Library; 47 | -------------------------------------------------------------------------------- /src/data/model/search/version.js: -------------------------------------------------------------------------------- 1 | var _ = require('lodash'); 2 | 3 | var Version = function (name, link, doc, current) { 4 | return this.init(name, link, doc, current); 5 | }; 6 | 7 | Version.prototype = { 8 | 9 | name: null, 10 | current: false, 11 | doc: null, 12 | link: null, 13 | levels: [], 14 | 15 | /** 16 | * Initialize library version search object 17 | * @param name - {String} name of library version 18 | * @param link - {String} readme string representation 19 | * @param readme - {String} url 20 | * @param current - {Boolean} indicates that this library version is current 21 | * @returns {Version} 22 | */ 23 | init: function (name, link, readme, current) { 24 | this.name = name; 25 | this.link = link; 26 | this.doc = readme; 27 | this.current = current; 28 | this.levels = []; 29 | return this; 30 | }, 31 | 32 | /** 33 | * Add level to library search item 34 | * @param level - {Level} level object 35 | * @returns {Version} 36 | */ 37 | addLevel: function (level) { 38 | this.levels.push(level); 39 | return this; 40 | }, 41 | 42 | /** 43 | * Returns level object by it name 44 | * @param name - {String} name of level 45 | * @returns {Level} 46 | */ 47 | getLevel: function (name) { 48 | return _.find(this.levels, function (item) { 49 | return item.name && name.indexOf(item.name) > -1; 50 | }); 51 | } 52 | }; 53 | 54 | module.exports = Version; 55 | -------------------------------------------------------------------------------- /src/data/model/tag.js: -------------------------------------------------------------------------------- 1 | var utility = require('../util'), 2 | DynamicNode = require('./dynamic').DynamicNode; 3 | 4 | /** 5 | * Subclass of dynamic nodes which describe tag of post 6 | * @param parent - {BaseNode} parent node 7 | * @param routes - {Object} application routes hash 8 | * @param tagKey - {String} tag 9 | * @constructor 10 | */ 11 | var TagNode = function (parent, routes, tagKey) { 12 | this.setTitle(tagKey) 13 | .processRoute(routes, parent, { 14 | conditions: { 15 | id: tagKey 16 | } 17 | }) 18 | .init(parent); 19 | }; 20 | 21 | TagNode.prototype = Object.create(DynamicNode.prototype); 22 | 23 | /** 24 | * Sets title for node 25 | * @param tagKey - {String} tag key 26 | * @returns {TagNode} 27 | */ 28 | TagNode.prototype.setTitle = function (tagKey) { 29 | this.title = utility.getLanguages().reduce(function (prev, lang) { 30 | prev[lang] = tagKey; 31 | return prev; 32 | }, {}); 33 | return this; 34 | }; 35 | 36 | /** 37 | * Sets view for node 38 | * @returns {TagNode} 39 | */ 40 | TagNode.prototype.setView = function () { 41 | this.view = this.VIEW.TAGS; 42 | return this; 43 | }; 44 | 45 | /** 46 | * Sets class for node 47 | * @returns {TagNode} 48 | */ 49 | TagNode.prototype.setClass = function () { 50 | this.class = 'tag'; 51 | return this; 52 | }; 53 | 54 | exports.TagNode = TagNode; 55 | -------------------------------------------------------------------------------- /src/data/providers/index.js: -------------------------------------------------------------------------------- 1 | var GhApiProvider = require('./provider-gh-api').GhApiProvider, 2 | FileProvider = require('./provider-file').FileProvider, 3 | GhHttpsProvider = require('./provider-gh-https').GhHttpsProvider, 4 | YaDiskProvider = require('./provider-ya-disk').YaDiskProvider; 5 | 6 | var providerFile, 7 | providerGhApi, 8 | providerGhHttps, 9 | providerYaDisk; 10 | 11 | module.exports = { 12 | 13 | /** 14 | * Returns module which provide all operations with files on local filesystem 15 | * @returns {*|FileProvider} 16 | */ 17 | getProviderFile: function () { 18 | providerFile = providerFile || new FileProvider(); 19 | return providerFile; 20 | }, 21 | 22 | /** 23 | * Returns module which provide all operations via github API 24 | * @returns {*|GhApiProvider} 25 | */ 26 | getProviderGhApi: function () { 27 | providerGhApi = providerGhApi || new GhApiProvider(); 28 | return providerGhApi; 29 | }, 30 | 31 | /** 32 | * Returns module which provides operations via https protocol 33 | * @returns {*|GhHttpsProvider} 34 | */ 35 | getProviderGhHttps: function () { 36 | providerGhHttps = providerGhHttps || new GhHttpsProvider(); 37 | return providerGhHttps; 38 | }, 39 | 40 | /** 41 | * Returns module which provides operations via Yandex Disk API 42 | * @returns {*|YaDiskProvider} 43 | */ 44 | getProviderYaDisk: function () { 45 | providerYaDisk = providerYaDisk || new YaDiskProvider(); 46 | return providerYaDisk; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /src/www/ZeroClipboard.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/www/ZeroClipboard.swf -------------------------------------------------------------------------------- /src/www/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bem-archive/bem-site-engine/05d6e6542daf6c1bade8af51c8d1863e610e983a/src/www/favicon.ico -------------------------------------------------------------------------------- /src/www/humans.txt: -------------------------------------------------------------------------------- 1 | /* TEAM */ 2 | Maintainer: Andrey Kuznecov 3 | Contact: bemer at yandex -team.ru 4 | From: Simferopol, Crimea, Ukraine 5 | 6 | Chef: Vitaly Harisov 7 | Contact: bem at bem.info 8 | From: Simferopol, Crimea, Ukraine 9 | 10 | Team leader: Vladimir Grinenko 11 | From: Simferopol, Crimea, Ukraine 12 | 13 | Consultant: Vladimir Varankin 14 | From: Moscow, Russia 15 | 16 | UI developer: Alexandra Nekhaeva 17 | From: Simferopol, Crimea, Ukraine 18 | 19 | Web designer: Danil Kovchiy 20 | From: Moscow, Russia 21 | 22 | /* SITE */ 23 | Language: English / Russian 24 | Doctype: HTML5 25 | IDE: Sublime Text, MC 26 | -------------------------------------------------------------------------------- /src/www/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Allow: /libs/bem-core/1.0.0/ 3 | Disallow: /libs/bem-core/ 4 | Disallow: /tags/ 5 | Disallow: /tools/optimizers/borschik/borschik/ 6 | --------------------------------------------------------------------------------