Showing preview only (1,394K chars total). Download the full file or copy to clipboard to get everything.
Repository: bem/bem-core
Branch: v5
Commit: 7a9e9327a56d
Files: 318
Total size: 1.2 MB
Directory structure:
gitextract_z09_3irc/
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .husky/
│ └── pre-commit
├── .nvmrc
├── CHANGELOG.md
├── CHANGELOG.ru.md
├── CLA.md
├── CONTRIBUTING.md
├── CONTRIBUTING.ru.md
├── LICENSE.txt
├── MIGRATION.md
├── MIGRATION.ru.md
├── PLAN.md
├── README.md
├── README.ru.md
├── SUMMARY.md
├── build/
│ ├── platforms/
│ │ ├── desktop.js
│ │ └── touch.js
│ ├── plugins/
│ │ ├── vite-plugin-bem-levels.js
│ │ └── vite-plugin-bem-levels.test.js
│ ├── vite.config.js
│ └── vite.test.config.js
├── common.blocks/
│ ├── clearfix/
│ │ ├── clearfix.css
│ │ ├── clearfix.en.md
│ │ ├── clearfix.en.title.txt
│ │ ├── clearfix.ru.md
│ │ └── clearfix.ru.title.txt
│ ├── cookie/
│ │ ├── cookie.en.md
│ │ ├── cookie.js
│ │ ├── cookie.ru.md
│ │ └── cookie.spec.js
│ ├── dom/
│ │ ├── dom.deps.js
│ │ ├── dom.en.md
│ │ ├── dom.js
│ │ ├── dom.ru.md
│ │ └── dom.spec.js
│ ├── events/
│ │ ├── __channels/
│ │ │ ├── events__channels.deps.js
│ │ │ ├── events__channels.en.md
│ │ │ ├── events__channels.ru.md
│ │ │ └── events__channels.vanilla.js
│ │ ├── __observable/
│ │ │ ├── _type/
│ │ │ │ ├── events__observable_type_bem-dom.deps.js
│ │ │ │ ├── events__observable_type_bem-dom.js
│ │ │ │ └── events__observable_type_bem-dom.spec.js
│ │ │ ├── events__observable.deps.js
│ │ │ ├── events__observable.js
│ │ │ └── events__observable.spec.js
│ │ ├── events.deps.js
│ │ ├── events.en.md
│ │ ├── events.ru.md
│ │ ├── events.spec.js
│ │ └── events.vanilla.js
│ ├── functions/
│ │ ├── __debounce/
│ │ │ ├── functions__debounce.spec.js
│ │ │ └── functions__debounce.vanilla.js
│ │ ├── __throttle/
│ │ │ ├── functions__throttle.spec.js
│ │ │ └── functions__throttle.vanilla.js
│ │ ├── functions.en.md
│ │ ├── functions.ru.md
│ │ ├── functions.spec.js
│ │ └── functions.vanilla.js
│ ├── i-bem/
│ │ ├── __collection/
│ │ │ ├── i-bem__collection.js
│ │ │ └── i-bem__collection.spec.js
│ │ ├── __internal/
│ │ │ ├── i-bem__internal.ru.title.txt
│ │ │ ├── i-bem__internal.spec.js
│ │ │ └── i-bem__internal.vanilla.js
│ │ ├── i-bem.deps.js
│ │ ├── i-bem.en.md
│ │ ├── i-bem.en.title.txt
│ │ ├── i-bem.ru.md
│ │ ├── i-bem.ru.title.txt
│ │ ├── i-bem.spec.js
│ │ └── i-bem.vanilla.js
│ ├── i-bem-dom/
│ │ ├── __collection/
│ │ │ ├── i-bem-dom__collection.deps.js
│ │ │ ├── i-bem-dom__collection.js
│ │ │ └── i-bem-dom__collection.spec.js
│ │ ├── __events/
│ │ │ ├── _type/
│ │ │ │ ├── i-bem-dom__events_type_bem.deps.js
│ │ │ │ ├── i-bem-dom__events_type_bem.js
│ │ │ │ ├── i-bem-dom__events_type_bem.spec.js
│ │ │ │ ├── i-bem-dom__events_type_dom.deps.js
│ │ │ │ ├── i-bem-dom__events_type_dom.js
│ │ │ │ └── i-bem-dom__events_type_dom.spec.js
│ │ │ ├── i-bem-dom__events.deps.js
│ │ │ └── i-bem-dom__events.js
│ │ ├── __init/
│ │ │ ├── _auto/
│ │ │ │ ├── i-bem-dom__init_auto.deps.js
│ │ │ │ └── i-bem-dom__init_auto.js
│ │ │ ├── i-bem-dom__init.deps.js
│ │ │ ├── i-bem-dom__init.js
│ │ │ └── i-bem-dom__init.spec.js
│ │ ├── i-bem-dom.deps.js
│ │ ├── i-bem-dom.en.md
│ │ ├── i-bem-dom.js
│ │ ├── i-bem-dom.ru.md
│ │ ├── i-bem-dom.spec.js
│ │ └── i-bem-dom.tests/
│ │ ├── benchmarks.bemjson.js
│ │ └── benchmarks.blocks/
│ │ ├── b1/
│ │ │ ├── b1.deps.js
│ │ │ └── b1.js
│ │ ├── b2/
│ │ │ ├── b2.deps.js
│ │ │ └── b2.js
│ │ └── page/
│ │ ├── page.deps.js
│ │ └── page.js
│ ├── i18n/
│ │ ├── i18n.deps.js
│ │ ├── i18n.en.md
│ │ ├── i18n.i18n.js
│ │ ├── i18n.ru.md
│ │ ├── i18n.test.js
│ │ ├── i18n.tests/
│ │ │ ├── blocks/
│ │ │ │ ├── logo/
│ │ │ │ │ ├── logo.bemhtml.js
│ │ │ │ │ ├── logo.bh.js
│ │ │ │ │ ├── logo.deps.js
│ │ │ │ │ ├── logo.i18n/
│ │ │ │ │ │ ├── en.js
│ │ │ │ │ │ └── ru.js
│ │ │ │ │ ├── logo.i18n.js
│ │ │ │ │ └── logo.js
│ │ │ │ └── page/
│ │ │ │ ├── __js/
│ │ │ │ │ ├── page__js.bemhtml.js
│ │ │ │ │ └── page__js.bh.js
│ │ │ │ └── page.i18n/
│ │ │ │ ├── en.js
│ │ │ │ └── ru.js
│ │ │ └── simple.bemjson.js
│ │ └── i18n.tmpl-specs/
│ │ ├── 10-simple.bemjson.js
│ │ ├── 10-simple.html
│ │ └── blocks/
│ │ └── greeting-card/
│ │ ├── greeting-card.bemhtml.js
│ │ ├── greeting-card.bh.js
│ │ └── greeting-card.deps.js
│ ├── identify/
│ │ ├── identify.en.md
│ │ ├── identify.ru.md
│ │ ├── identify.spec.js
│ │ └── identify.vanilla.js
│ ├── idle/
│ │ ├── _start/
│ │ │ └── idle_start_auto.js
│ │ ├── idle.deps.js
│ │ ├── idle.en.md
│ │ ├── idle.js
│ │ └── idle.ru.md
│ ├── inherit/
│ │ ├── inherit.en.md
│ │ ├── inherit.ru.md
│ │ ├── inherit.spec.js
│ │ └── inherit.vanilla.js
│ ├── jquery/
│ │ ├── __config/
│ │ │ ├── jquery__config.js
│ │ │ └── jquery__config.ru.md
│ │ ├── jquery.deps.js
│ │ ├── jquery.en.md
│ │ ├── jquery.js
│ │ ├── jquery.ru.md
│ │ └── jquery.ru.title.txt
│ ├── keyboard/
│ │ ├── __codes/
│ │ │ └── keyboard__codes.js
│ │ ├── keyboard.en.md
│ │ └── keyboard.ru.md
│ ├── loader/
│ │ ├── _type/
│ │ │ ├── loader_type_bundle.js
│ │ │ ├── loader_type_js.js
│ │ │ └── loader_type_js.spec.js
│ │ ├── loader.en.md
│ │ └── loader.ru.md
│ ├── next-tick/
│ │ ├── next-tick.en.md
│ │ ├── next-tick.ru.md
│ │ ├── next-tick.spec.js
│ │ └── next-tick.vanilla.js
│ ├── objects/
│ │ ├── objects.en.md
│ │ ├── objects.ru.md
│ │ ├── objects.spec.js
│ │ └── objects.vanilla.js
│ ├── page/
│ │ ├── __css/
│ │ │ ├── page__css.bemhtml.js
│ │ │ └── page__css.bh.js
│ │ ├── __js/
│ │ │ ├── page__js.bemhtml.js
│ │ │ └── page__js.bh.js
│ │ ├── page.bemhtml.js
│ │ ├── page.bh.js
│ │ ├── page.deps.js
│ │ ├── page.en.md
│ │ ├── page.en.title.txt
│ │ ├── page.examples/
│ │ │ ├── .bem/
│ │ │ │ └── level.js
│ │ │ ├── 10-simple.bemjson.js
│ │ │ ├── 10-simple.ru.title.txt
│ │ │ ├── 10-simple.ru.wiki
│ │ │ ├── 20-doctype.bemjson.js
│ │ │ └── 20-doctype.ru.title.txt
│ │ ├── page.ru.md
│ │ ├── page.ru.title.txt
│ │ └── page.tmpl-specs/
│ │ ├── 00-empty.bemjson.js
│ │ ├── 00-empty.html
│ │ ├── 10-simple.bemjson.js
│ │ ├── 10-simple.html
│ │ ├── 20-style.bemjson.js
│ │ ├── 20-style.html
│ │ ├── 25-styles.bemjson.js
│ │ ├── 25-styles.html
│ │ ├── 30-scripts.bemjson.js
│ │ ├── 30-scripts.html
│ │ ├── 40-nonce.bemjson.js
│ │ ├── 40-nonce.html
│ │ ├── 60-x-ua-compatible.bemjson.js
│ │ ├── 60-x-ua-compatible.html
│ │ ├── 70-lang.bemjson.js
│ │ └── 70-lang.html
│ ├── strings/
│ │ ├── __escape/
│ │ │ ├── strings__escape.spec.js
│ │ │ └── strings__escape.vanilla.js
│ │ ├── strings.en.md
│ │ └── strings.ru.md
│ ├── tick/
│ │ ├── _start/
│ │ │ └── tick_start_auto.vanilla.js
│ │ ├── tick.deps.js
│ │ ├── tick.en.md
│ │ ├── tick.ru.md
│ │ ├── tick.spec.js
│ │ └── tick.vanilla.js
│ ├── ua/
│ │ ├── __svg/
│ │ │ ├── ua__svg.bemhtml.js
│ │ │ ├── ua__svg.bh.js
│ │ │ ├── ua__svg.deps.js
│ │ │ ├── ua__svg.en.title.txt
│ │ │ ├── ua__svg.ru.title.txt
│ │ │ └── ua__svg.tmpl-specs/
│ │ │ ├── 00-simple.bemjson.js
│ │ │ └── 00-simple.html
│ │ ├── ua.bemhtml.js
│ │ ├── ua.bh.js
│ │ ├── ua.en.md
│ │ ├── ua.en.title.txt
│ │ ├── ua.ru.md
│ │ ├── ua.ru.title.txt
│ │ └── ua.tmpl-specs/
│ │ ├── 00-simple.bemjson.js
│ │ └── 00-simple.html
│ └── uri/
│ ├── __querystring/
│ │ ├── uri__querystring.deps.js
│ │ ├── uri__querystring.spec.js
│ │ └── uri__querystring.vanilla.js
│ ├── uri.en.md
│ ├── uri.ru.md
│ ├── uri.spec.js
│ └── uri.vanilla.js
├── common.bundles/
│ └── index/
│ ├── blocks/
│ │ └── square/
│ │ ├── _color/
│ │ │ └── square_color_green.css
│ │ ├── square.css
│ │ ├── square.deps.js
│ │ └── square.js
│ └── index.bemjson.js
├── common.docs/
│ ├── bemjson/
│ │ ├── bemjson.en.md
│ │ └── bemjson.ru.md
│ └── i-bem-js/
│ ├── i-bem-js-collections.en.md
│ ├── i-bem-js-collections.ru.md
│ ├── i-bem-js-common.en.md
│ ├── i-bem-js-common.ru.md
│ ├── i-bem-js-context.en.md
│ ├── i-bem-js-context.ru.md
│ ├── i-bem-js-decl.en.md
│ ├── i-bem-js-decl.ru.md
│ ├── i-bem-js-dom.en.md
│ ├── i-bem-js-dom.ru.md
│ ├── i-bem-js-events.en.md
│ ├── i-bem-js-events.ru.md
│ ├── i-bem-js-extras.en.md
│ ├── i-bem-js-extras.ru.md
│ ├── i-bem-js-html-binding.en.md
│ ├── i-bem-js-html-binding.ru.md
│ ├── i-bem-js-init.en.md
│ ├── i-bem-js-init.ru.md
│ ├── i-bem-js-interact.en.md
│ ├── i-bem-js-interact.ru.md
│ ├── i-bem-js-params.en.md
│ ├── i-bem-js-params.ru.md
│ ├── i-bem-js-states.en.md
│ ├── i-bem-js-states.ru.md
│ ├── i-bem-js.en.md
│ └── i-bem-js.ru.md
├── desktop.blocks/
│ ├── jquery/
│ │ ├── __config/
│ │ │ ├── jquery__config.deps.js
│ │ │ └── jquery__config.js
│ │ └── __event/
│ │ └── _type/
│ │ ├── jquery__event_type_winresize.deps.js
│ │ └── jquery__event_type_winresize.js
│ ├── page/
│ │ ├── __conditional-comment/
│ │ │ ├── page__conditional-comment.bemhtml.js
│ │ │ ├── page__conditional-comment.bh.js
│ │ │ └── page__conditional-comment.ru.md
│ │ ├── page.deps.js
│ │ ├── page.examples/
│ │ │ ├── .bem/
│ │ │ │ └── level.js
│ │ │ ├── 40-es5-shims.bemjson.js
│ │ │ └── 40-es5-shims.ru.title.txt
│ │ ├── page.ru.md
│ │ └── page.tmpl-specs/
│ │ ├── 50-conditions.bemjson.js
│ │ ├── 50-conditions.html
│ │ ├── 60-conditional-comments.bemjson.js
│ │ ├── 60-conditional-comments.html
│ │ ├── 70-custom-x-ua-compatible.bemjson.js
│ │ └── 70-custom-x-ua-compatible.html
│ └── ua/
│ ├── ua.js
│ └── ua.ru.md
├── eslint.config.js
├── jsdoc.config.json
├── package.json
├── playwright.config.js
├── test/
│ ├── browser/
│ │ ├── bemhtml-shim.js
│ │ ├── entry.js
│ │ ├── index.html
│ │ └── modules-shim.js
│ ├── browser.spec.js
│ └── dist/
│ ├── assets/
│ │ └── test.html
│ ├── build-fixtures.js
│ ├── config.js
│ └── fixtures/
│ ├── chai.js
│ ├── desktop.html
│ ├── mocha.css
│ ├── mocha.js
│ ├── sinon-chai.js
│ ├── sinon.js
│ └── touch.html
└── touch.blocks/
├── page/
│ ├── __icon/
│ │ ├── page__icon.bemhtml.js
│ │ └── page__icon.bh.js
│ ├── page.bemhtml.js
│ ├── page.bh.js
│ ├── page.deps.js
│ ├── page.ru.md
│ └── page.tmpl-specs/
│ ├── 00-empty.html
│ ├── 10-simple.html
│ ├── 20-style.html
│ ├── 25-styles.html
│ ├── 30-scripts.html
│ ├── 40-nonce.html
│ ├── 60-x-ua-compatible.html
│ ├── 70-lang.html
│ ├── 70-zoom.bemjson.js
│ └── 70-zoom.html
└── ua/
├── __dom/
│ ├── ua__dom.deps.js
│ ├── ua__dom.js
│ └── ua__dom.ru.md
├── ua.bemhtml.js
├── ua.bh.js
├── ua.deps.js
├── ua.js
└── ua.ru.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/ci.yml
================================================
name: CI
on:
push:
branches: [master, v*]
pull_request:
branches: [master, v5]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: npm
- run: npm ci
- run: npm test
test-browser:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npm run test:browser
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run docs
- uses: actions/upload-artifact@v4
with:
name: jsdoc
path: docs/jsdoc/
================================================
FILE: .gitignore
================================================
.project
.settings
.bem/cache
.bem/snapshots
.enb/tmp
libs
node_modules
coverage.json
/coverage
*.bundles/*/*
!*.bundles/.bem/*
!*.bundles/*/blocks
!*.bundles/*/*.bemjson.js
/dist
/docs/jsdoc
/test-results
/*desktop.docs
/*touch.docs
/*.examples
/*.specs
/*.tmpl-specs
/*.tests
/*.sets
_book
================================================
FILE: .husky/pre-commit
================================================
npx lint-staged
================================================
FILE: .nvmrc
================================================
24
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## 5.0.0
### Breaking changes
- **ESM-only**: The entire codebase has been migrated from the `ym` module system (`modules.define`/`modules.require`) to native ES modules (`import`/`export`). The `ym` runtime dependency has been removed.
- **Vite build system**: ENB and all 17+ associated packages have been replaced with [Vite](https://vite.dev/). A custom `vite-plugin-bem-levels` plugin handles BEM level scanning, `bem:*` virtual module resolution, and redefinition chain barrel generation.
- **jQuery 4.0**: The `jquery` peer dependency has been upgraded from `^3.x` to `^4.0.0`. Notable API change: `$.unique()` has been removed — use `$.uniqueSort()` instead.
- **Node.js 20+**: The minimum supported Node.js version is now 20 (was 8).
- **Native Promises**: `vow` has been removed. All code now uses native `Promise`.
- **Native test runner**: Server-side tests now use `node:test` and `node:assert` instead of `mocha`/`chai`.
- **Playwright**: Browser tests now use [Playwright](https://playwright.dev/) instead of `mocha-phantomjs` (PhantomJS is dead).
- **ESLint 10**: Linting has been migrated from `jshint`/`jscs` to ESLint 10 with flat config (`eslint.config.js`).
- **GitHub Actions CI**: Travis CI has been replaced with GitHub Actions.
- **Husky + lint-staged**: `git-hooks` has been replaced with `husky` and `lint-staged`.
### Notable changes
- All `.vanilla.js` and `.js` source files have been converted to ES modules with `import`/`export` syntax.
- Module redefinition chains (e.g., `jquery` with pointer event extensions) are now handled via auto-generated barrel files by `vite-plugin-bem-levels`.
- The `i18n` block retains its API but uses native ES modules internally.
- Browser spec tests (28 spec files, 500+ test cases) run via Vite dev server + Playwright.
- Vite produces platform-specific builds (`desktop`, `touch`) with jQuery as an external dependency.
### Removed packages
- **Build**: `enb`, `enb-bem-techs`, `enb-magic-factory`, `enb-magic-platform`, `enb-bemxjst`, `enb-bemxjst-6x`, `enb-bemxjst-7x`, `enb-bemxjst-i18n`, `enb-bh`, `enb-bh-i18n`, `enb-borschik`, `enb-css`, `enb-js`, `enb-bem-docs`, `enb-bem-examples`, `enb-bem-specs`, `enb-bem-tmpl-specs`, `enb-bem-i18n`, `borschik`
- **Linting**: `jscs`, `jscs-bem`, `jshint`, `jshint-groups`
- **Testing**: `mocha-phantomjs`, `istanbul`, `chai-as-promised`
- **Other**: `ym`, `vow`, `bower`, `git-hooks`, `gitbook-api`, `bem-naming`, `bem-walk`
### Removed config files
- `.enb/` directory (ENB build config)
- `.jshintrc`, `.jscs.json`, `.jshint-groups.js` (linting configs)
- `.bowerrc`, `bower.json` (Bower configs)
- `.travis.yml` (Travis CI config)
- `.githooks/` directory (git-hooks config)
## 4.3.1
### Bug fixes
- Reverted change that led to error when `lazyInit` in `declMod` was used ([#1594](https://github.com/bem/bem-core/pull/1594)).
## 4.3.0
### Notable changes
- `jQuery` was updated to 3.2.1 and 1.12.4 ([#1587](https://github.com/bem/bem-core/pull/1587)).
### Bug fixes
- Possibility to force `lazy` initialization from markup was fixed ([#1579](https://github.com/bem/bem-core/pull/1579)).
- Possibility to declare entities with mixins was fixed ([#1550](https://github.com/bem/bem-core/pull/1550)).
- Now `lazyInit` in `declMod` will throw an error ([#1579](https://github.com/bem/bem-core/pull/1579)).
- With bug in `isFunction` method of `functions` block, which works wrong for special functions ([#1577](https://github.com/bem/bem-core/pull/1577)).
### Other changes
- `.bemrc` config was added ([#1568](https://github.com/bem/bem-core/pull/1568)).
- `vow` was updated to 0.4.17 ([#1565](https://github.com/bem/bem-core/pull/1565)).
- `inherit` was updated to 2.2.6 ([#1519](https://github.com/bem/bem-core/pull/1519)).
- Private `_delInitedMod` method of `i-bem` block was removed ([#1523](https://github.com/bem/bem-core/pull/1523)).
- Removed code for old `bem-tools` (https://github.com/bem/bem-core/commit/e57678b2d64a3b976a53af4a7fa09bf918685821).
- npm dependencies were updated ([#1589](https://github.com/bem/bem-core/pull/1589)).
- Now tests are executed also on Node.js 8 (https://github.com/bem/bem-core/commit/dd7e5344a64ad1595eab28febb2242134fcedbb3).
- More specs for `i-bem-dom` were added ([#1517](https://github.com/bem/bem-core/pull/1517)).
- `gitbook` was added ([#1569](https://github.com/bem/bem-core/pull/1569)).
- JSDoc was fixed.
- Documentation updates.
## 4.2.1
### Bug fixes
- Fixed an issue with elems cache invalidation on DOM modifications ([#1487](https://github.com/bem/bem-core/issues/1487)).
- Fixed an issue in `i-bem-dom__events` when event's data was not passed to handler ([#1509](https://github.com/bem/bem-core/pull/1509)).
- Fixed method `isEditable` of `dom` module. Missing editable input types were added ([#1502](https://github.com/bem/bem-core/pull/1502)).
### Other changes
- Fixed syntax error in `i-bem-dom` JSDoc.
- Minor documentation updates.
- [CLA](https://github.com/bem/bem-core/blob/v4/CLA.md) introduced.
## 4.2.0
### Notable changes
- `bem-xjst 8.x` support was introduced in BEMHTML templates ([#1486](https://github.com/bem/bem-core/issues/1485)).
### Bug fixes
- `concat()` method was fixed in `i-bem-dom__collection` ([#1488](https://github.com/bem/bem-core/issues/1488)).
- An issue in `ua__dom` was fix ([#1479](https://github.com/bem/bem-core/issues/1478)).
- dist: `i-bem-dom__init_auto` was removed from `no-autoinit` bundle ([#1482](https://github.com/bem/bem-core/issues/1481)).
### Other changes
- Now `findChildBlock`, `findChildBlocks`, `findParentBlock`, `findParentBlocks`, `findMixedBlock` and `findMixedBlocks` methods throw an error if block is given as String ([#1469](https://github.com/bem/bem-core/pull/1469/)).
- `buildClassName` function was optimized ([#1404](https://github.com/bem/bem-core/pull/1404)).
- Docs: English translations were added ([#1483](https://github.com/bem/bem-core/pull/1483), [#1476](https://github.com/bem/bem-core/pull/1476), [#1475](https://github.com/bem/bem-core/pull/1475)).
- Migration: Added notes about bemTarget ([#1491](https://github.com/bem/bem-core/issues/1472)).
- Migration: added info about template options ([#1467](https://github.com/bem/bem-core/issues/1467)).
- Fixed issues in docs.
## 4.1.1
### Bug fixes
— Fixed a bug in `ua` block on `touch.blocks` level ([#1460](https://github.com/bem/bem-core/pull/1460)).
## 4.1.0
### Bug fixes
- Fixed a bug in `identify` returning different result on each call for `document` ([#1441](https://github.com/bem/bem-core/issues/1441)).
- `modules.define` recursion problem was fixed ([#1446](https://github.com/bem/bem-core/issues/1446)).
- Support for escaping in `ua` block was fixed ([#1435](https://github.com/bem/bem-core/issues/1435)).
- Workaround for `Array.prototype.push` bug in `Opera 41` was implemented.
- An issue with pointer events on iOS devices was fixed ([#1253](https://github.com/bem/bem-core/issues/1253)).
- An issue in `i-bem-dom__events` was fixed. Method `once()` was broken in some cases ([#1452](https://github.com/bem/bem-core/issues/1452)).
### Other changes
- Ability to specify `html@lang` attribute was added to `page` block ([#751](https://github.com/bem/bem-core/issues/751)).
## 4.0.0
### Breaking changes
- Changes in the `i-bem` block. See [MIGRATION.md](MIGRATION.md#changes-in-the-i-bem-block).
- Changes in the `querystring`. See [MIGRATION.md](MIGRATION.md#changes-in-the-querystring-block).
- The optional parameter `onlyGet` was removed from the `identify` module ([#1028](https://github.com/bem/bem-core/issues/1028)).
- All static methods were removed from the `events` module ([#1024](https://github.com/bem/bem-core/issues/1024)).
- The `result` field in `Event` class of `events` module was removed ([#1023](https://github.com/bem/bem-core/issues/1023)).
- The `css` element of the `page` block does not support auto insertion of conditional comments for IE ([#379](https://github.com/bem/bem-core/issues/379)).
## 3.2.0
### Bug fixes
- `modules.define` recursion problem was fixed ([#1446](https://github.com/bem/bem-core/issues/1446)).
- Support for escaping in `ua` block was fixed ([#1435](https://github.com/bem/bem-core/issues/1435)).
- Workaround for `Array.prototype.push` bug in `Opera 41` was implemented.
### Other changes
- Ability to specify `html@lang` attribute was added to `page` block ([#751](https://github.com/bem/bem-core/issues/751)).
## 3.1.0
### Bug fixes
- An issue in `getMods()` method of `i-bem` was fixed ([#1379](https://github.com/bem/bem-core/issues/1379)).
### Notable changes
- Templates: support for escaped mode was introduced ([#1406](https://github.com/bem/bem-core/issues/1406)).
### Other changes
- Minor documentation updates.
## 3.0.1
### Bug fixes
- An issue with pointer events on iOS devices was fixed ([#1253](https://github.com/bem/bem-core/issues/1253)).
## 3.0.0
### Breaking changes
- Base templates for `BEMHTML` and `BEMTREE` were removed ([#1258](https://github.com/bem/bem-core/issues/1258)). `bem-xjst` 6.3.0+ should be used instead.
- File extentions of BEMHTML templates were renamed from `*.bemhtml` to `*.bemhtml.js` ([#984](https://github.com/bem/bem-core/issues/984)). Please check that new extention is supported in you build config.
- `i-bem__i18n` element was removed ([#1304](https://github.com/bem/bem-core/issues/1304)). Please use `i18n` block for internationalization.
- `jquery__events_type_pointerclick` is not using [FastClick](https://github.com/ftlabs/fastclick) anymore ([#1088](https://github.com/bem/bem-core/issues/1088)).
### Notable changes
- `jQuery` was updated to 2.2.3 and 1.12.3 ([#1260](https://github.com/bem/bem-core/issues/1260)).
### Bug fixes
- An issue in `page` was fixed. `<meta name=viewport>` had wrong `user-scalable` value on the touch level ([#1294](https://github.com/bem/bem-core/issues/1294)).
- An issue in `jquery__event_type_pointernative` which led to JS error in IE8 was fixed ([1317](https://github.com/bem/bem-core/issues/1317)).
### Other changes
- dist: Autoinitialisation of blocks is optional now ([#1271](https://github.com/bem/bem-core/issues/1271)).
## 2.9.0
### Notable changes
- `jQuery` was updated to 2.2.0 and 1.12.0 ([#1249](https://github.com/bem/bem-core/issues/1249)).
### Bug fixes
- Fixed bug in BEMHTML 1.x which leads to drop of `this.mods` in `reapply()` ([#97](https://github.com/bem/bem-xjst/issues/97)).
### Other changes
- `jquery__event_type_pointerpressrelease` now exposes `originalEvent` ([#1254](https://github.com/bem/bem-core/issues/1254)).
- dist: Support for `i18n` was added to dist ([#1212](https://github.com/bem/bem-core/issues/1212)).
- `page__css.bemhtml` template was updated to support new `bem-xjst` versions ([#1228](https://github.com/bem/bem-core/issues/1228)).
## 2.8.0
### Notable changes
- New [i18n](https://github.com/bem/bem-core/tree/v2/common.blocks/i18n) block was introduced, providing support for internationalization ([#1074](https://github.com/bem/bem-core/issues/1074)).
- Now jQuery is included via `https` by default ([#1202](https://github.com/bem/bem-core/issues/1202)).
- Dependency on `bemhtml-compat` was dropped ([#1186](https://github.com/bem/bem-core/issues/1186)). Users of `bem-tools` need to run `npm i bemhtml-compat --save` to install it on their projects.
### Bug fixes
- Bug with undefined handler call in `loader_type_js` was fixed ([#1159](https://github.com/bem/bem-core/pull/1159)).
### Other changes
- BH bundles in `dist` now mimic to BEMHTML ([#1210](https://github.com/bem/bem-core/issues/1210)).
- `bem create` templates for `bemhtml`, `bemtree`, `vanilla.js` and `browser.js` were improved ([#1183](https://github.com/bem/bem-core/issues/1183)).
- `vow` was updated to `0.4.10` ([#1056](https://github.com/bem/bem-core/issues/1056)).
## 2.7.0
### Notable changes
- New `detach` method was added to `i-bem__dom` ([#1102](https://github.com/bem/bem-core/issues/1102)).
- `i-bem.bemhtml` now supports nested mixes as objects ([873](https://github.com/bem/bem-core/issues/873)).
- Some minor attribute escaping optimizations were added to `i-bem.bemhtml` ([#961](https://github.com/bem/bem-core/issues/961)), ([#980](https://github.com/bem/bem-core/issues/980)) and ([#982](https://github.com/bem/bem-core/issues/982)).
- Support for [bem-xjst](https://github.com/bem/bem-xjst) 2.x was added to BEMHTML templates ([#1021](https://github.com/bem/bem-core/issues/1021)).
- `clearfix` was optimized to work properly in supported IE browsers ([#722](https://github.com/bem/bem-core/issues/722)).
- `jquery` was updated to 2.1.4 and 1.11.3 ([#999](https://github.com/bem/bem-core/issues/999)).
### Bug fixes
- An issue in `i-bem__dom` was fixed. `findElem` didn't update cache of elements that
had been found previously ([#583](https://github.com/bem/bem-core/issues/583)).
- An issue in `i-bem__dom` was fixed. `dropElemCache` worked incorrectly in some edge cases ([#1037](https://github.com/bem/bem-core/issues/1037)).
- An issue in `i-bem__dom` was fixed. `setMod` didn't add CSS classes if blocks on the same DOM node had
overlapping end parts in their names ([#1090](https://github.com/bem/bem-core/issues/1090)).
- An issue in `page` was fixed. `zoom` attribute of the block didn't work for touch levels ([#1020](https://github.com/bem/bem-core/issues/1020)).
- An issue in `keyboard__codes` was fixed. `insert` and `delete` keys had wrong key codes ([#1002](https://github.com/bem/bem-core/issues/1002)).
- An issue in `i-bem.bemhtml` was fixed. `applyNext` calls were skipped in nested templates ([b1dc50c](https://github.com/bem/bem-core/commit/b1dc50c621b5659cff33daa4dd3f210b67cf25e1)).
- An issue in `jquery__events_type_pointernative` was fixed to work properly in IE 11/Edge ([#1066](https://github.com/bem/bem-core/issues/1066)).
### Other changes
- Russian documentation for every blocks was reworked. Please visit https://ru.bem.info/libs/bem-core/ for new documentation.
- Other minor improvements of the documentation.
## 2.6.0
### Notable changes
- Since now `i-bem__dom` provides module after DOM is ready ([#859](https://github.com/bem/bem-core/issues/859)).
- Since now `setMod` and `hasMod` methods of `i-bem__dom` convert their `modVal` argument to string in case
it is not of type string or boolean ([#890](https://github.com/bem/bem-core/issues/890)).
- An ability to pass `nonce` attribute was added to `page`, to support related parts of Content Security Policy
specification ([#882](https://github.com/bem/bem-core/issues/882)).
- New `page__conditional-comment` template was added ([#551](https://github.com/bem/bem-core/issues/511)).
- `vow` was updated to 0.4.8 ([#837](https://github.com/bem/bem-core/issues/837)).
### Bug fixes
- An issue in `i-bem.bemhtml` was fixed. Block CSS class repeated in case of mix with the same
block ([#792](https://github.com/bem/bem-core/issues/792)).
- An issue in `loader_type_bundle` was fixed. Success callback might be applied after timeout
error ([67ff55f](https://github.com/bem/bem-core/commit/da5fdb9923e7e83e3ef9cd31aefc3967ff55fd3c)).
- An issue in `i-bem__dom` was fixed. `append`, `prepend` and other similar methods won't properly work with strings
in some cases ([#852](https://github.com/bem/bem-core/issues/852)).
- An issue in `jquery__event_type_winresize` was fixed. MSIE wasn't detected properly ([#862](https://github.com/bem/bem-core/issues/862)).
- An issue in `object` was fixed to proper handle `null` value as `target` argument in `extend` method ([#910](https://github.com/bem/bem-core/issues/910)).
- An issue in `page` was fixed. There was no way to disable `x-ua-compatible` meta tag from BEMJSON ([#794](https://github.com/bem/bem-core/issues/794)).
### Other changes
- Timeout in `loader_type_bundle` module was increased to 30000 ms ([4e27422](https://github.com/bem/bem-core/commit/000c6af02bfae4506fa460168de16d4e27422393)).
- Russian documentation for several blocks was fixed.
## 2.5.1
### Bug fixes
- An issue in `jquery__pointerpress` and `jquery__pointerrelease` was fixed. Events work now in
Internet Explorer 8 ([#792](https://github.com/bem/bem-core/issues/792)).
- An issue in `jquery__pointernative` was fixed. `pointerenter` and `pointerleave` events have bubbled up
to the document root, while they shouldn't ([#801](https://github.com/bem/bem-core/issues/801)).
- An issue in `loader_type_bundle` was fixed. CSS bundle has been always added to the top of the HTML `<head>`, so CSS rules
from the bundle might not work properly ([#808](https://github.com/bem/bem-core/issues/808)).
- Issues in BH templates for `ua` were fixed. There was no possibility to pass the content of the block from
BEMJSON ([#734](https://github.com/bem/bem-core/pull/734)).
- An issue in `page` was fixed. There was a problem with conditional comments for Internet Explorer in the BH template
of the block ([#781](https://github.com/bem/bem-core/pull/781)).
### Other changes
- `jquery` was updated to the 2.1.3 and 1.11.2 ([#778](https://github.com/bem/bem-core/pull/788)).
- Russian documentation for modules: `clearfix`, `cookie`, `identify`, `idle`, `inherit`, `keyboard`, `loader`, `next-tick`,
`string` and `tick` was added.
- Russian documentation for `i-bem.js` was updated.
- English guides to BEMHTM and BEMJSON were updated.
## 2.5.0
### Notable changes
- bem-core in now published under the [MPL 2.0](https://www.mozilla.org/MPL/2.0/) license ([#443](https://github.com/bem/bem-core/issues/443)).
- An ability to specify error handler was added to `loader_type_js` ([#672](https://github.com/bem/bem-core/issues/672)).
- `BEMContext` class was added to `oninit` export context in `i-bem.bemtree` ([#602](https://github.com/bem/bem-core/issues/602)).
- `reapply` static method was added to BEMContext class of BEMTREE ([#706](https://github.com/bem/bem-core/pull/706)).
- bh templates for block `page` were added to touch level ([#689](https://github.com/bem/bem-core/pull/689)).
- [bem-xjst](https://github.com/bem/bem-xjst) was updated to 0.9.0 ([#709](https://github.com/bem/bem-core/pull/709)).
### Bug fixes
- An issue in `i-bem__dom` was fixed. `findBlocksInside` could return blocks which weren't inited ([#699](https://github.com/bem/bem-core/issues/699)).
- An issue in `tick` was fixed. Timer was not removed by `Tick#stop()` ([#694](https://github.com/bem/bem-core/issues/694)).
- An issue in `i-bem.bemhtml` was fixed. `i-bem` CSS class was added to elements by mistake ([#633](https://github.com/bem/bem-core/issues/633)).
- `html-from-bemtree` tech was fixed to expose `vow`, `console`, `setTimeout` inside BEMTREE template context ([#438ebb8](https://github.com/bem/bem-core/commit/438ebb8f828e26977592e26511e8aad15176d7a4)).
### Other changes
- English guide to BEMJSON was added.
- Russian documentation for `querystring` module was added.
- Russian documentation for `i-bem.js` was fixed to satisfy current API.
- Documentation for BEMHML/BEMTREE for both languages was updated.
## 2.4.0
### Notable changes
- [bem-xjst](https://github.com/bem/bem-xjst) was updated to 0.8.0; [bemhtml-compat](https://github.com/bem/bemhtml-compat) was updated to 0.0.11.
### Bug fixes
- An issue in `jquery__event_type_pointerpressrelease` was fixed. `pointerpress`/`pointerrelease` events fired for any press/release
of mouse button ([#607](https://github.com/bem/bem-core/issues/607)).
- An issue in `i-bem__dom.js` was fixed. Base `live` method was not properly called in some edge cases ([#608](https://github.com/bem/bem-core/issues/608)).
### Other changes
- English documentation for JS-syntax of BEMHTML was added.
## 2.3.0
### Notable changes
- New implementation of pointer events was added. Based on pointer events polyfills from [Polymer](http://www.polymer-project.org/) ([#567](https://github.com/bem/bem-core/pull/567)).
- Ability to specify additional data for event was added to `bindTo*` methods of `i-bem__dom.js` ([#568](https://github.com/bem/bem-core/issues/568)).
### Other changes
- An issue in `i-bem.bemhtml` was fixed. There was an error when mix was used as an object (not an array) in BEMJSON and BEMHTML simultaneously ([#555](https://github.com/bem/bem-core/issues/555)).
- An issue in `page` was fixed. There was no possibility to apply standard modes to `page` in BEMHTML template and touch template was broken ([516](https://github.com/bem/bem-core/issues/516)).
## 2.2.4
### Bug fixes
- An issue in `i-bem.js` was fixed. Modifier change event has been emitted even if `beforeSetMod` handler
had prevented change ([#546](https://github.com/bem/bem-core/pull/546)).
- String decoding process of `querystring__uri` module was fixed to return original string
if decode failed ([#554](https://github.com/bem/bem-core/pull/554)).
## 2.2.3
### Bug fixes
- Destruction process of blocks was fixed to prevent unexpected block reinitialization ([#540](https://github.com/bem/bem-core/issues/540)).
- An issue in `jquery__event_type_pointer` was fixed. Native mouse events were replaced with pointer events
in unexpected cases ([#534](https://github.com/bem/bem-core/issues/534)).
- `unbindFrom*` methods of `i-bem__dom` now support multiple events to be passed in arguments ([#533](https://github.com/bem/bem-core/issues/533)).
- Lost `functions` dependency in `events` module was restored ([#532](https://github.com/bem/bem-core/issues/532)).
## 2.2.2
### Bug fixes
- An issue with block reinitialization on the DOM node, that has been processed with destructor, was fixed
in `i-bem__dom` ([#518](https://github.com/bem/bem-core/issues/518)).
- An issue in mod events subscription was fixed in `i-bem`. `false` could be used as `modVal` ([#529](https://github.com/bem/bem-core/issues/529)).
- `jquery` was updated to the latest minor releases 2.1.1 and 1.11.1 ([#515](https://github.com/bem/bem-core/issues/515)).
## 2.2.1
- An issue in `jquery__event_type_pointerpressrelease` was fixed. `pointerpress` event has been triggered twice on each mousedown
in IE10 ([#505](https://github.com/bem/bem-core/issues/505)).
## 2.2.0
### Notable changes
- New `keyboard__codes` module has been added ([#431](https://github.com/bem/bem-core/issues/431)).
- `BEMContext` class was added to oninit export context in `i-bem.bemhtml` ([#485](https://github.com/bem/bem-core/pull/485)).
- Ability to declare elements with block class has been added ([#481](https://github.com/bem/bem-core/issues/481)).
- Behaviour of `isSimple` method of `BEMContext` was fixed in `i-bem.bemhtml` ([#432](https://github.com/bem/bem-core/pull/432)).
- An issue with `liveUnbindFrom` method of `BEMDOM` was fixed in `i-bem__dom` ([#476](https://github.com/bem/bem-core/pull/476)).
- An issue with `isFocusable` method of `dom` module was fixed for cases where `domElem` is a link with `tabindex` attribute,
but without `href` ([#501](https://github.com/bem/bem-core/issues/501)).
- Short way of module declaration was fixed for `i-bem__dom_elem-instances` ([#479](https://github.com/bem/bem-core/issues/479)).
- A workaround for rendering performance of blocks initialisation in Chrome-based browsers was added
to `i-bem__dom_init_auto` ([#486](https://github.com/bem/bem-core/issues/486)).
- `vow.js` module has been moved to `vow.vanilla.js` ([#412](https://github.com/bem/bem-core/issues/412)).
### Other changes
- `vow` module has been updated to 0.4.3 ([#504](https://github.com/bem/bem-core/pull/504)).
- Russian documentation about BEMTREE technology was added ([#500](https://github.com/bem/bem-core/pull/500)).
- Russian documentation for JS-syntax of BEMHTML was updated ([#471](https://github.com/bem/bem-core/pull/471)).
- API references for JS-modules has been added as a separate branch `v2-jsdoc` ([#478](https://github.com/bem/bem-core/pull/478)).
## 2.1.0
### Notable changes
- An issue in `i-bem.js` when modifiers change event had been emitted before `onSetMod` handlers have been called was fixed ([#454](https://github.com/bem/bem-core/issues/454)).
- An issue in `i-bem.bemhtml` was fixed. Since now `this.mods` and `this.ctx.mods` use the same object ([#441](https://github.com/bem/bem-core/issues/441)).
- Error in modular declaration of element modifiers was fixed in `i-bem__dom_elem-instances` ([#447](https://github.com/bem/bem-core/issues/447)).
- [inherit](https://github.com/dfilatov/inherit) module was updated to 2.2.1 ([#466](https://github.com/bem/bem-core/issues/466)).
- An order of tags in `head` section of `page.bemhtml` was fixed ([#465](https://github.com/bem/bem-core/pull/465)).
### Other changes
- `baseMix` field description of `i-bem.js` was added to russian docs ([#461](https://github.com/bem/bem-core/pull/461)).
- CDN host was changed to `yastatic.net` ([#444](https://github.com/bem/bem-core/issues/444)).
Previous CDN host `yandex.st` is still accessible. Physically they both are the same web servers. DNS records is the only difference.
- BEMHTML template for `bem create` command was added ([#277](https://github.com/bem/bem-core/issues/277)).
- We do not support autobuilding of our tests with Node.js 0.8 in [Travis CI](http://travis-ci.com) any longer ([#455](https://github.com/bem/bem-core/issues/455)).
- Travis's build status badge [was changed to SVG version](http://blog.travis-ci.com/2014-03-20-build-status-badges-support-svg/) :)
## 2.0.0
### Breaking changes
- All deprecated methods have been removed from `i-bem.js` and `i-bem__dom.js` ([#318](https://github.com/bem/bem-core/issues/318)).
The following methods were removed:
* `destruct`, use `onSetMod js ''`;
* `extractParams`, use `elemParams`;
* `trigger`, use `emit`;
* `afterCurrentEvent`, use `next-tick` module;
* `channel`, use `events__channels` module;
* `changeThis`, use native `Function.prototype.bind`.
- `init` and `destruct` events have been removed from `i-bem.js` in favor of modifiers changes events (see "Notable changes" section below).
- `ecma` was moved to [separate repo](http://github.com/bem/es5-shims); ES5-shims should be used
for IE < 9 ([#230](https://github.com/bem/bem-core/issues/230)).
- `vow` module has been updated to 0.4.1 ([#350](https://github.com/bem/bem-core/issues/350)).
See [Vow's changelog](https://github.com/dfilatov/vow/blob/0.4.1/CHANGELOG.md) for changes.
- Support for vow@0.4 has been added to `i-bem.bemhtml` ([#385](https://github.com/bem/bem-core/issues/385)).
### Notable changes
- Support for defining BEMDOM-blocks as [ym](https://github.com/ymaps/modules) modules has been added ([#382](https://github.com/bem/bem-core/issues/382)).
- Events for modifiers changes have been added to `i-bem.js` ([#357](https://github.com/bem/bem-core/issues/357)).
- Support for passing string values has been added to `BEMDOM.init`
([#419](https://github.com/bem/bem-core/issues/419)).
and `BEMDOM.update` methods ([#420](https://github.com/bem/bem-core/issues/420)).
- DOM helpers from `i-bem__dom.js` `replace`, `append`, `prepend`, `before`, `after` now return new context and `update` returns
updated context as a jQuery object ([#410](https://github.com/bem/bem-core/issues/410)).
- New `loader_type_bundle` has been added ([#358](https://github.com/bem/bem-core/issues/358)).
- Default jQuery versions were updated to 2.1.0 and to 1.11.0, for IE < 9 ([#356](https://github.com/bem/bem-core/issues/356)).
### Other changes
- `i-bem.bemhtml` now uses strings concatination instead of pushing to buffer in it's internals ([#401](https://github.com/bem/bem-core/issues/401)).
- jQuery no longer removes itself from global scope if it exists ([#349](https://github.com/bem/bem-core/issues/349)).
- `jquery__event_type_pointerclick.js` has been moved from touch level to common ([#393](https://github.com/bem/bem-core/issues/393)).
- Modifiers `i-bem_elem-instances_yes` and `i-bem__dom_elem-instances_yes` were renamed to boolean style ([#352](https://github.com/bem/bem-core/issues/352)).
- Runtime error in `page` template in development mode has been fixed ([#417](https://github.com/bem/bem-core/issues/417)).
- Usage of `Function.prototype.bind` has been droped from `i-bem.js` internals in favor of support
for Android 2.3 ([#404](https://github.com/bem/bem-core/issues/404)).
- Some bugs in `browser-js+bemhtml` tech have been fixed ([#392](https://github.com/bem/bem-core/issues/392)).
- Up to [ym@0.0.15](https://github.com/ymaps/modules/releases) ([#414](https://github.com/bem/bem-core/issues/414)).
## 1.2.0
### Notable changes
- BEM-blocks are emit `destruct` event on destructing ([#370](https://github.com/bem/bem-core/issues/370)).
- Improvements of `pointerevents` polyfills ([#354](https://github.com/bem/bem-core/pull/354)).
### Other changes
- All JSDocs were fixed so [bem-jsd](github.com/bem/bem-jsd) could parse them ([#335](https://github.com/bem/bem-core/issues/335)).
- Russian version of BEMHTML reference was actualized to JavaScript syntax ([#355](https://github.com/bem/bem-core/pull/355)).
- Use [bower](http://bower.io) for dependency management ([#367](https://github.com/bem/bem-core/issues/367)).
## 1.1.0
### Notable changes
- `jquery__config` uses jQuery 2.x by default for modern browsers ([#319](https://github.com/bem/bem-core/issues/319)).
- Add ability to use any BEMJSON as value of attributes in BEMHTML templates ([#290](https://github.com/bem/bem-core/issues/290)).
- Fix dependencies in `i-bem__collection` ([#292](https://github.com/bem/bem-core/issues/292)).
- Remove `page` block touch styles ([#306](https://github.com/bem/bem-core/issues/306)).
- Fix `page` BEMHTML wrapping in production mode ([#309](https://github.com/bem/bem-core/issues/309)).
- Fix possible JavaScript error in script injection in IE<9 in `next-tick` ([#324](https://github.com/bem/bem-core/issues/324)).
- Fix `FastClick` initialisation in `jquery__event_type_pointerclick` of `touch.blocks` ([#332](https://github.com/bem/bem-core/issues/332)).
- Fix `node.js` tech bug on Windows systems ([#274](https://github.com/bem/bem-core/issues/274)).
- Fix `i-bem__dom_elem-instances` bug with `onElemSetMod` ([#340](https://github.com/bem/bem-core/issues/340)).
- Use bemhtml from [bem-xjst](https://github.com/bem/bem-xjst) ([#329](https://github.com/bem/bem-core/issues/329)).
### Other changes
- [ym](https://github.com/ymaps/modules) was updated to 0.0.12 ([#326](https://github.com/bem/bem-core/issues/326)).
- Do not flood `console` with messages if `i-bem__i18n` is not in debug mode ([#285](https://github.com/bem/bem-core/issues/285)).
- Fix jsdoc for `dropElemCache()` method of `i-bem__dom` module ([#296](https://github.com/bem/bem-core/issues/296)).
- Development infrastructure was updated to
[bem-pr@v0.5.x](https://github.com/narqo/bem-pr/blob/0.5.3/HISTORY.md) ([#323](https://github.com/bem/bem-core/issues/323)).
- Russian documentation for `i-bem.js` was updated.
- [List of supported browsers](https://github.com/bem/bem-core/blob/v1/README.md#supported-browsers)
was specified in project README.
## 1.0.0
### Breaking changes
- Starts using modular system [ym](https://github.com/ymaps/modules).
- Removes all deprecated methods from `i-bem` and `i-bem__dom`.
- `i-bem` now has no dependency on jQuery. `i-bem__dom` still depends on jQuery.
- BEMHTML-template can be written with [JS-syntax](https://gist.github.com/veged/6150760).
- Introduces new tech `bemtree` (based on [bem-xjst](https://github.com/bem/bem-xjst))
for describing dynamic generation of BEM-tree.
- Introduces new tech `vanilla.js` for JS-implementations that does not depend on particular JS-engine.
- Introduces new techs `browser.js` and `node.js` for JS-implementations targeted corresponding engines.
For backward compatibility we assume that `.js`-files contains `browser.js` implementation.
- Introduces polyfill (`jquery__event_type_pointer` and `jquery__event_type_pointerclick` as a jQuery-plugins)
for universalize desktop and touch pointer events.
- Introduces system for unit testing and blocks examples generation.
- Introduces "simple" modifiers (modifiers without value) support in `i-bem` and BEMHTML.
### Other changes
- Gets rid of prefixes in all block names (except `i-bem`).
- Block `i-bem__dom` becomes a module (in terms of [ym](https://github.com/ymaps/modules))
and all `BEM.DOM`-block must define additions to `i-bem__dom` ([example](https://github.com/bem/bem-core/blob/v1/common.bundles/index/blocks/b-square/b-square.js)).
- Method for blocks declaration (`.decl()`) does not accept object with `name` field as first parameter.
Required form with `block` field: `BEM.decl({ block: 'b1', modName: 'm', modVal: 'v' }, ...)`.
- Introduces `nextTick` method as replacement for `afterCurrentEvent` method
for ensure of block existence in callback invocation time.
`BEM.afterCurrentEvent` is **deprecated**.
- Introduces new `channels` module instead of `BEM.channel`. `BEM.channel` is **deprecated**.
- `changeThis` is **deprecated**. Use native `bind` instead.
- Removes `del` method from `i-bem` block.
- Removes `getWindowSize` method from `i-bem__dom` block. Use `BEMDOM.win.width()` and `BEMDOM.win.height()`.
- Introduces `jquery` module-wrapper for providing jQuery.
If jQuery already included into the page module-wrapper provides it. Otherwise it loads jQuery (version 1.10.1) on its own.
- `$.observable` becomes `events` module and not longer depends on jQuery.
- `$.inherit` becomes `inherit` module and not longer depends on jQuery.
- `$.identify` becomes `identify` module and not longer depends on jQuery.
- `$.throttle` splits into two modules: `functions__throttle` and `functions__debounce`, they both not longer depend on jQuery.
- `$.decodeURI`, `$.decodeURIComponent` moves to `querystring__uri` module and not longer depends on jQuery.
- `$.cookie` becomes `cookie` module and not longer depends on jQuery.
- Introduces `ua` module instead of `$.browser` (with same interface).
- Use `pointerclick` instead of `leftclick`. It provides by `jquery__event_type_pointerclick` polyfill.
- `i-system` block splits into two modules: `idle` and `tick`.
- Triggers for modifiers changes now splitted into two groups:
before setting new value (`beforeSetMod` and `beforeElemSetMod`)
and after the value has been set (`onSetMod` and `onElemSetMod`).
Cancellation of modifiers change is possible only from `before*`-triggers.
- Using of `{ onSetMod : { js : function() { ... } } }` is **deprecated**, use `onSetMod: { js : { inited : ... } } }`.
- `destruct` method from `i-bem` block is **deprecated**.
Use supplementary trigger for `_js` modifiers:
`onSetMod: { js : { inited : ... } } }` — `{ onSetMod : { js : { '' : ... } } }`.
- `exractParams` method from `i-bem__dom` block is **deprecated**.
Use `elemParams` method for access to elements params.
- `trigger` method from `i-bem` block is **deprecated** in flavor of `emit` method.
- `onFirst` method from `i-bem` block is **deprecated** in flavor of `once` method.
- **Deprecated** field `e.block` that provided block-target of BEM-events was removed. Use `e.target` field instead.
- Field `e.data.domElem` that provided DOM-element of block in DOM-events was removed. Use `$(e.currentTarget)` (provided by jQuery).
- Introduces parameter for `findElem` method that allows to search elements
of particular block instance (in case of nested blocks with same name).
- Introduces possibility to point particular function in `unbindFrom*` methods.
- Introduces `objects` module for work with JS-objects. It contains methods: `extend`, `isEmpty`, `each`.
- Introduces `functions` module for work with JS-functions. It contains methods: `isFunction`, `noop`.
- Introduces `dom` module for work with DOM-tree.
- Introduces `querystring` module for work with URL-based strings.
- Introduces `loader_type_js` module for JS loading.
- Introduces `vow` module for Promises/A+.
- Introduces `next-tick` module as polyfill for `nextTick`, `setImmediate`, `setTimeout(0, ...` and etc.
- Introduces `strings__escape` module for XML, HTML and attributes escaping.
- `inherit` module now supports mixins.
- Introduces `invokeAsap` parameter for `functions__throttle` module that allows to delay first invocation.
================================================
FILE: CHANGELOG.ru.md
================================================
# История изменений
## 5.0.0
### Несовместимые изменения
- **Только ESM**: Вся кодовая база мигрирована с модульной системы `ym` (`modules.define`/`modules.require`) на нативные ES-модули (`import`/`export`). Зависимость `ym` удалена.
- **Сборка через Vite**: ENB и все 17+ связанных пакетов заменены на [Vite](https://vite.dev/). Кастомный плагин `vite-plugin-bem-levels` обеспечивает сканирование BEM-уровней, разрешение виртуальных модулей `bem:*` и генерацию barrel-файлов для цепочек переопределений.
- **jQuery 4.0**: Peer-зависимость `jquery` обновлена с `^3.x` до `^4.0.0`. Основное изменение API: `$.unique()` удалён — используйте `$.uniqueSort()`.
- **Node.js 20+**: Минимальная поддерживаемая версия Node.js — 20 (было 8).
- **Нативные промисы**: `vow` удалён. Весь код использует нативный `Promise`.
- **Нативный тест-раннер**: Серверные тесты используют `node:test` и `node:assert` вместо `mocha`/`chai`.
- **Playwright**: Браузерные тесты используют [Playwright](https://playwright.dev/) вместо `mocha-phantomjs` (PhantomJS мёртв).
- **ESLint 10**: Линтинг мигрирован с `jshint`/`jscs` на ESLint 10 с flat-конфигурацией (`eslint.config.js`).
- **GitHub Actions CI**: Travis CI заменён на GitHub Actions.
- **Husky + lint-staged**: `git-hooks` заменён на `husky` и `lint-staged`.
### Крупные изменения
- Все `.vanilla.js` и `.js` файлы конвертированы в ES-модули с синтаксисом `import`/`export`.
- Цепочки переопределений модулей (напр., `jquery` с расширениями pointer-событий) обрабатываются автоматически сгенерированными barrel-файлами через `vite-plugin-bem-levels`.
- Блок `i18n` сохраняет свой API, но использует нативные ES-модули внутри.
- Браузерные спек-тесты (28 файлов, 500+ тестов) запускаются через Vite dev server + Playwright.
- Vite генерирует платформенно-специфичные сборки (`desktop`, `touch`) с jQuery как внешней зависимостью.
### Удалённые пакеты
- **Сборка**: `enb`, `enb-bem-techs`, `enb-magic-factory`, `enb-magic-platform`, `enb-bemxjst`, `enb-bemxjst-6x`, `enb-bemxjst-7x`, `enb-bemxjst-i18n`, `enb-bh`, `enb-bh-i18n`, `enb-borschik`, `enb-css`, `enb-js`, `enb-bem-docs`, `enb-bem-examples`, `enb-bem-specs`, `enb-bem-tmpl-specs`, `enb-bem-i18n`, `borschik`
- **Линтинг**: `jscs`, `jscs-bem`, `jshint`, `jshint-groups`
- **Тестирование**: `mocha-phantomjs`, `istanbul`, `chai-as-promised`
- **Прочие**: `ym`, `vow`, `bower`, `git-hooks`, `gitbook-api`, `bem-naming`, `bem-walk`
### Удалённые конфигурационные файлы
- `.enb/` (конфигурация сборки ENB)
- `.jshintrc`, `.jscs.json`, `.jshint-groups.js` (конфигурация линтинга)
- `.bowerrc`, `bower.json` (конфигурация Bower)
- `.travis.yml` (конфигурация Travis CI)
- `.githooks/` (конфигурация git-hooks)
## 4.3.1
### В релиз вошли следующие исправления ошибок
- Откатили изменение, из-за которого при попытке использования `lazyInit` при деклации модификатора выбрасывалось исключение ([#1594](https://github.com/bem/bem-core/pull/1594)).
## 4.3.0
### Крупные изменения
- `jQuery` была обновлена до 3.2.1 и 1.12.4 ([#1587](https://github.com/bem/bem-core/pull/1587)).
### В релиз вошли следующие исправления ошибок
- Исправлена возможность форсировать lazy-инициализацию из разметки ([#1579](https://github.com/bem/bem-core/pull/1579)).
- Исправлена возможность декларировать сущности с миксинами ([#1550](https://github.com/bem/bem-core/pull/1550)).
- Теперь при попытке использования `lazyInit` при деклации модификатора будет выбрасываться исключение ([#1579](https://github.com/bem/bem-core/pull/1579)).
- Исправлен баг в методе `isFunction` блока `functions`, который неправильно определял сложные функции ([#1577](https://github.com/bem/bem-core/pull/1577)).
### Также в релиз вошли следующие изменения
- Добавлен конфиг `.bemrc` ([#1568](https://github.com/bem/bem-core/pull/1568)).
- Блок `vow` обновлен до версии 0.4.17 ([#1565](https://github.com/bem/bem-core/pull/1565)).
- Блок `inherit` обновлен до версии 2.2.6 ([#1519](https://github.com/bem/bem-core/pull/1519)).
- Удален приватный метод `_delInitedMod` блока `i-bem` ([#1523](https://github.com/bem/bem-core/pull/1523)).
- Удален код, относящийся к старой версии `bem-tools` (https://github.com/bem/bem-core/commit/e57678b2d64a3b976a53af4a7fa09bf918685821).
- Обновлены npm-зависимости ([#1589](https://github.com/bem/bem-core/pull/1589)).
- Теперь тесты в CI запускаются и под Node.js 8 (https://github.com/bem/bem-core/commit/dd7e5344a64ad1595eab28febb2242134fcedbb3).
- Добавлены недостающие тесты для блока `i-bem-dom` ([#1517](https://github.com/bem/bem-core/pull/1517)).
- Добавлен gitbook ([#1569](https://github.com/bem/bem-core/pull/1569)).
- Исправления JSDoc.
- Исправления документации.
## 4.2.1
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка с инвалидацией кеша элементов при изменении DOM ([#1487](https://github.com/bem/bem-core/issues/1487)).
- Исправлена ошибка в `i-bem-dom__events`, приводившая к тому, что данные события не передавались в обработчик ([#1509](https://github.com/bem/bem-core/pull/1509)).
- Исправлен метод `isEditable` модуля `dom`. Добавлены недостающие типы ([#1502](https://github.com/bem/bem-core/pull/1502)).
### Также в релиз вошли следующие изменения
- Исправлены синтаксические ошибки в JSDoc блока `i-bem-dom`.
- Незначительные исправления документации.
- Добавлено [CLA](https://github.com/bem/bem-core/blob/v4/CLA.md).
## 4.2.0
### Крупные изменения
- В BEMHTML-шаблонах реализована поддержка `bem-xjst 8.x` ([#1486](https://github.com/bem/bem-core/issues/1485)).
### В релиз вошли следующие исправления ошибок
- Исправлена работа метода `concat()` в i-bem-dom__collection ([#1488](https://github.com/bem/bem-core/issues/1488)).
- Исправлена опечатка в `ua__dom`, приводящая к runtime-ошибке при использовании touch-уровня ([#1479](https://github.com/bem/bem-core/issues/1478)).
- dist: Исправлена ошибка, при которой `i-bem-dom__init_auto` подключался в `no-autoinit`-бандл ([#1482](https://github.com/bem/bem-core/issues/1481)).
### Также в релиз вошли следующие изменения
- Теперь методы `findChildBlock`, `findChildBlocks`, `findParentBlock`, `findParentBlocks`, `findMixedBlock` и `findMixedBlocks` выбрасывают исключение, если блок передан строкой ([#1469](https://github.com/bem/bem-core/pull/1469/)).
- Оптимизирована функция построения имен классов ([#1404](https://github.com/bem/bem-core/pull/1404)).
- Добавлены переводы на английский ([#1483](https://github.com/bem/bem-core/pull/1483), [#1476](https://github.com/bem/bem-core/pull/1476), [#1475](https://github.com/bem/bem-core/pull/1475)).
- Миграционный гайд: добавлено примечание о `bemTarget` ([#1491](https://github.com/bem/bem-core/issues/1472)).
- Миграционный гайд: добавлено примечание о необходимых опциях для шаблонизаторов ([#1467](https://github.com/bem/bem-core/issues/1467)).
- Исправлены ошибки в документации.
## 4.1.1
### В релиз вошли следующие исправления ошибок
— Исправлена ошибка в блоке `ua` на уровне `touch.blocks`, которая приводила к невозможности предоставить ym-зависимости ([#1460](https://github.com/bem/bem-core/pull/1460)).
## 4.1.0
### В релиз вошли следующие исправления ошибок
- Исправлена проблема в `identify` с возвращением разного результата при вызове для `document` ([#1441](https://github.com/bem/bem-core/issues/1441)).
- Исправлена проблема с переполнением глубины стека вызовов `modules.define` ([#1446](https://github.com/bem/bem-core/issues/1446)).
- Исправлена поддержка эскейпинга в блоке `ua` ([#1435](https://github.com/bem/bem-core/issues/1435)).
- Реализован обход бага в `Array.prototype.push` в `Opera 41`.
- Исправлены pointer-события на iOS-устройствах ([#1253](https://github.com/bem/bem-core/issues/1253)).
- Исправлена ошибка в `i-bem-dom__events`, приводящая к неправильной работе метода `once()` в некоторых случаях ([#1452](https://github.com/bem/bem-core/issues/1452)).
### Также в релиз вошли следующие изменения
- Реализована возможность задавать атрибут `lang` для `<html>` в блоке `page` ([#751](https://github.com/bem/bem-core/issues/751)).
## 4.0.0
### Изменения, ломающие обратную совместимость
- Изменения в блоке `i-bem`. Подробнее в [MIGRATION.ru.md](MIGRATION.ru.md#Изменения-в-блоке-i-bem).
- Изменения в блоке `querystring`. Подробнее в [MIGRATION.ru.md](MIGRATION.ru.md#Изменения-в-блоке-querystring).
- Из модуля `identify` удален опциональный параметр `onlyGet` ([#1028](https://github.com/bem/bem-core/issues/1028)).
- Из модуля `events` удалены все статические методы ([#1024](https://github.com/bem/bem-core/issues/1024)).
- В классе `Event` модуля `events` удалено поле `result` ([#1023](https://github.com/bem/bem-core/issues/1023)).
- Элемент `css` блока `page` больше не поддерживает автоматическое добавление условных комментариев для IE ([#379](https://github.com/bem/bem-core/issues/379)).
## 3.2.0
### В релиз вошли следующие исправления ошибок
- Исправлена проблема с переполнением глубины стека вызовов `modules.define` ([#1446](https://github.com/bem/bem-core/issues/1446)).
- Исправлена поддержка эскейпинга в блоке `ua` ([#1435](https://github.com/bem/bem-core/issues/1435)).
- Реализован обход бага в `Array.prototype.push` в `Opera 41`.
### Также в релиз вошли следующие изменения
- Реализована возможность задавать атрибут `lang` для `<html>` в блоке `page` ([#751](https://github.com/bem/bem-core/issues/751)).
## 3.1.0
### В релиз вошли следующие исправления ошибок
- Исправлен баг в методе `getMods()` блока `i-bem` ([#1379](https://github.com/bem/bem-core/issues/1379)).
### Крупные изменения
- Шаблоны: реализована поддержка режима экранирования ([#1406](https://github.com/bem/bem-core/issues/1406)).
### Также в релиз вошли следующие изменения
- Мелкие исправления документации.
## 3.0.1
### В релиз вошли следующие исправления ошибок
- Исправлены pointer-события на iOS-устройствах ([#1253](https://github.com/bem/bem-core/issues/1253)).
## 3.0.0
### Изменения, ломающие обратную совместимость
- Удалены базовые шаблоны и документация для `BEMHTML` и `BEMTREE` ([#1258](https://github.com/bem/bem-core/issues/1258)). Следует использовать версию `bem-xjst` не ниже 6.3.0.
- Расширения файлов BEMHTML-шаблонов переименованы с `*.bemhtml` на `*.bemhtml.js` ([#984](https://github.com/bem/bem-core/issues/984)). Необходимо убедиться, что в конфиге сборки поддерживается новое расширение.
- Удален элемент `i-bem__i18n` ([#1304](https://github.com/bem/bem-core/issues/1304)). Для интернационализации следует использовать блок `i18n`.
- `jquery__events_type_pointerclick` больше не использует библиотеку [FastClick](https://github.com/ftlabs/fastclick) ([#1088](https://github.com/bem/bem-core/issues/1088)).
### Крупные изменения
- `jQuery` была обновлена до 2.2.3 и 1.12.3 ([#1260](https://github.com/bem/bem-core/issues/1260)).
### В релиз вошли следующие исправления ошибок
- В блоке `page` на уровне `blocks.touch` исправлена ошибка с невалидным значением `user-scalable=0` для `<meta name=viewport>` ([#1294](https://github.com/bem/bem-core/issues/1294)).
- Исправлена ошибка в `jquery__event_type_pointernative`, которая приводила к возникновению JS ошибки в IE8 ([1317](https://github.com/bem/bem-core/issues/1317)).
### Также в релиз вошли следующие изменения
- dist: Автоматическая инициализация блоков теперь опциональна ([#1271](https://github.com/bem/bem-core/issues/1271)).
## 2.9.0
### Крупные изменения
- `jQuery` была обновлена до 2.2.0 и 1.12.0 ([#1249](https://github.com/bem/bem-core/issues/1249)).
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `BEMHTML 1.x`, которая приводила к потере `this.mods` в `reapply()` ([#97](https://github.com/bem/bem-xjst/issues/97)).
### Также в релиз вошли следующие изменения
- Теперь `jquery__event_type_pointerpressrelease` предоставляет `originalEvent` ([#1254](https://github.com/bem/bem-core/issues/1254)).
- dist: Поддержка `i18n` добавлена в dist ([#1212](https://github.com/bem/bem-core/issues/1212)).
- Шаблон `page__css.bemhtml` был обновлен для поддержки новых версий `bem-xjst` ([#1228](https://github.com/bem/bem-core/issues/1228)).
## 2.8.0
### Крупные изменения
- Реализован новый блок [i18n](https://github.com/bem/bem-core/tree/v2/common.blocks/i18n), реализующий интернационализацию проектов на bem-core ([#1074](https://github.com/bem/bem-core/issues/1074)).
- Теперь `jQuery` по умолчанию подключается через `https` ([#1202](https://github.com/bem/bem-core/issues/1202)).
- Удалена зависимость от `bemhtml-compat` ([#1186](https://github.com/bem/bem-core/issues/1186)). Пользователям `bem-tools` необходимо выполнить `npm i bemhtml-compat --save` для установки пакета на уровне проекта.
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `loader_type_js`, допускавшая вызовы неопределенного обработчика ([#1159](https://github.com/bem/bem-core/pull/1159)).
### Также в релиз вошли следующие изменения
- BH-бандлы в `dist` теперь мимикрируют под BEMHTML ([#1210](https://github.com/bem/bem-core/issues/1210)).
- Улучшены шаблоны `bem create` для `bemhtml`, `bemtree`, `vanilla.js` и `browser.js` ([#1183](https://github.com/bem/bem-core/issues/1183)).
- `vow` обновлена до `0.4.10` ([#1056](https://github.com/bem/bem-core/issues/1056)).
## 2.7.0
### Крупные изменения
- В `i-bem__dom` добавлен новый метод `detach` ([#1102](https://github.com/bem/bem-core/issues/1102)).
- В `i-bem.bemhtml` добавлена поддержка вложенных миксов ([873](https://github.com/bem/bem-core/issues/873)).
- В `i-bem.bemhtml` добавлены незначительные оптимизации, связанные с эскейпингом аттрибутов ([#961](https://github.com/bem/bem-core/issues/961)), ([#980](https://github.com/bem/bem-core/issues/980)) и ([#982](https://github.com/bem/bem-core/issues/982)).
- В BEMHTML-шаблоны добавлена поддержка [bem-xjst](https://github.com/bem/bem-xjst) 2.x ([#1021](https://github.com/bem/bem-core/issues/1021)).
- `clearfix` оптимизирован для работы в поддерживаемых библиотекой браузерах IE ([#722](https://github.com/bem/bem-core/issues/722)).
- `jquery` обновлен до версий 2.1.4 и 1.11.3 ([#999](https://github.com/bem/bem-core/issues/999)).
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `i-bem__dom`, из-за которой метод `findElem` не обновлял кэш ранее найденных
элементов ([#583](https://github.com/bem/bem-core/issues/583)).
- Исправлена ошибка в `i-bem__dom`, приводящая к неправильной работе метода `dropElemCache` в некоторых граничных
случаях ([#1037](https://github.com/bem/bem-core/issues/1037)).
- Исправлена ошибка в `i-bem__dom`, из-за которой вызов метода `setMod` не выставлял CSS-классы блоку в случае, если
на DOM-узеле был подмешан блок с пересекающимся окончанием в имени ([#1090](https://github.com/bem/bem-core/issues/1090)).
- Исправлена ошибка в `page`, из-за которой на touch-уровнях не работало специализированное поле `zoom` ([#1020](https://github.com/bem/bem-core/issues/1020)).
- Исправлена ошибка в `keyboard__codes`. Клавиши `insert` и `delete` были описаны неправильными
кодами ([#1002](https://github.com/bem/bem-core/issues/1002)).
- Исправлена ошибка в `i-bem.bemhtml`, из-за которой неверно интерпретировались вложенные вызовы `applyNext` ([b1dc50c](https://github.com/bem/bem-core/commit/b1dc50c621b5659cff33daa4dd3f210b67cf25e1)).
- Исправлена ошибка в `jquery__events_type_pointernative`, из-за которой события работали некорректно
в браузерах IE 11 и Edge ([#1066](https://github.com/bem/bem-core/issues/1066)).
### Также в релиз вошли следующие изменения
- Обновлена русская докуметация для всех блоков библиотеки. Документация доступна по адресу https://ru.bem.info/libs/bem-core/.
- Прочие улучшения в документации к библиотеке.
## 2.6.0
### Крупные изменения
- Предоставление модуля `i-bem__dom` теперь происходит после наступления события DOM ready ([#859](https://github.com/bem/bem-core/issues/859)).
- Методы `setMod` и `hasMod` модуля `i-bem__dom` теперь явно преобразуют параметр `modVal` к строке,
если переданное значение не типа string или boolean ([#890](https://github.com/bem/bem-core/issues/890)).
- В блок `page` добавлена возможность прокидывать атрибут `nonce`, для корректной работы инлайн-скриптов, в соответствии
со спецификацией Content Security Policy ([#882](https://github.com/bem/bem-core/issues/882)).
- Добавлены шаблоны `page__conditional-comment` ([#551](https://github.com/bem/bem-core/issues/511)).
- Модуль `vow` обновлен до версии 0.4.8 ([#837](https://github.com/bem/bem-core/issues/837)).
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `i-bem.bemhtml`, из-за которой CSS-класс блока дублировался, в случае микса с этим же блоком
([#792](https://github.com/bem/bem-core/issues/792)).
- Исправлена ошибка в `loader_type_bundle`, из-за которой функция-обработчик успешного результата могла выполняться
после наступления таймаута ([67ff55f](https://github.com/bem/bem-core/commit/da5fdb9923e7e83e3ef9cd31aefc3967ff55fd3c)).
- Исправлена ошибка в `i-bem__dom`, в некоторых случаях, приводящая к неправильной интерпретации строковых аргументов
в методах `append`, `prepend` и др. ([#852](https://github.com/bem/bem-core/issues/852)).
- Исправлена ошибка в `jquery__event_type_winresize`, из-за которой неправильно определятся браузер MSIE ([#862](https://github.com/bem/bem-core/issues/862)).
- Исправлена ошибка в `object`, из-за которой метод `extend` неправильно обрабатывал `null` в качестве значения
аргумента `target` ([#910](https://github.com/bem/bem-core/issues/910)).
- Исправлена ошибка в `page`. Из BEMJSON было невозможно отключить добавление meta-тега `x-ua-compatible` ([#794](https://github.com/bem/bem-core/issues/794)).
### Также в релиз вошли следующие изменения
- Таймаут в `loader_type_bundle` увеличен до 30000 мс ([4e27422](https://github.com/bem/bem-core/commit/000c6af02bfae4506fa460168de16d4e27422393)).
- Исправлены незначительные ошибки в русской документации блоков.
## 2.5.1
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `jquery__pointerpress` и `jquery__pointerrelease` из-за которой события не работали в браузере
Internet Explorer 8 ([#792](https://github.com/bem/bem-core/issues/792)).
- Исправлена ошибка в `jquery__pointernative`. События `pointerenter` и `pointerleave` не должны всплывать
по DOM-дереву ([#801](https://github.com/bem/bem-core/issues/801)).
- Исправлена ошибка в `loader_type_bundle`. После загрузки, CSS-бандл добавлялся в самый верх HTML-тега `<head>`, из-за чего
CSS-правила из содержимого бандла могли работать не корректно ([#808](https://github.com/bem/bem-core/issues/808)).
- Исправлена ошибка в BH-шаблоне `ua`. Шаблон не позволял вставить содержимое блока из входного
BEMJSON ([#734](https://github.com/bem/bem-core/pull/734)).
- Исправлена ошибка в `page`, приводящая к неработоспособности добавленных на страницу условных комментариев для браузера
Internet Explorer ([#781](https://github.com/bem/bem-core/pull/781)).
### Также в релиз вошли следующие изменения
- `jquery` обновлен до версий 2.1.3 и 1.11.2 ([#778](https://github.com/bem/bem-core/pull/788)).
- Добавлена документация на русском языке для модулей: `clearfix`, `cookie`, `identify`, `idle`, `inherit`, `keyboard`,
`loader`, `next-tick`, `string` and `tick`.
- Исправлена документация на русском языке для `i-bem.js`.
- Обновлено руководство на английском языке по технологиям BEMHTML и BEMJSON.
## 2.5.0
### Крупные изменения
- Код библиотеки переведен на использование лицензии [MPL 2.0](https://www.mozilla.org/MPL/2.0/) ([#443](https://github.com/bem/bem-core/issues/443)).
- В модуль `loader_type_js` добавлена возможность указывать функцию-обработчик ошибок ([#672](https://github.com/bem/bem-core/issues/672)).
- Класс `BEMContext` добавлен в export-параметры функции `oninit` в базовых шаблонах `i-bem.bemtree` ([#602](https://github.com/bem/bem-core/issues/602)).
- В `BEMContext` BEMTREE добавлен статический метод `reapply` по аналогии с BEMHTML ([#706](https://github.com/bem/bem-core/pull/706)).
- Добавлены bh-шаблоны блока `page` для уровней touch ([#689](https://github.com/bem/bem-core/pull/689)).
- npm-модуль [bem-xjst](https://github.com/bem/bem-xjst) обновлен до версии 0.9.0 ([#709](https://github.com/bem/bem-core/pull/709)).
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `i-bem__dom`, из-за которой метод `findBlocksInside` мог возвращать блоки, которые еще не были
инициализированы ([#699](https://github.com/bem/bem-core/issues/699)).
- Исправлена ошибка в `tick`, позволявшая вызвать метод `stop` без освобождения внутреннего таймера ([#694](https://github.com/bem/bem-core/issues/694)).
- Исправлена ошибка в `i-bem.bemhtml`, из-за которой на элементы блока добавлялся CSS-класс `i-bem` ([#633](https://github.com/bem/bem-core/issues/633)).
- Исправлена ошибка в технологии `html-from-bemtree`, из-за которой в контексте BEMTREE-шаблонов не было глобальных объектов
`vow`, `console`, `setTimeout` ([#438ebb8](https://github.com/bem/bem-core/commit/438ebb8f828e26977592e26511e8aad15176d7a4)).
### Также в релиз вошли следующие изменения
- Добавлено английское руководство по технологии BEMJSON.
- Обновлена русская документация для i-bem.js. Теперь документация соответсвует текущему API библиотеки.
- Обновлена документация для технологий BEMHTML/BEMTREE.
## 2.4.0
### Крупные изменения
- npm-модуль [bem-xjst](https://github.com/bem/bem-xjst) обновлен до версии 0.8.0; [bemhtml-compat](https://github.com/bem/bemhtml-compat)
обновлен до 0.0.11.
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `jquery__event_type_pointerpressrelease`, из-за которой события `pointerpress` / `pointerrelease` генерировались
на нажатие любой кнопки мыши ([#607](https://github.com/bem/bem-core/issues/607)).
- Исправлена ошибка в `i-bem__dom.js`, из-за которой в некоторых случаях не происходил вызов базового метода
`live` ([#608](https://github.com/bem/bem-core/issues/608)).
### Также в релиз вошли следующие изменения
- Добавлена английская документация на JS-синтаксис BEMHTML.
## 2.3.0
### Крупные изменения
- Добавлена новая реализация pointer-событий на основе полифилов из [Polymer](http://www.polymer-project.org/) ([#567](https://github.com/bem/bem-core/pull/567)).
- Добавлена возможность в `i-bem__dom.js` указывать дополнительные данные о событии в методах `bindTo*` ([#568](https://github.com/bem/bem-core/issues/568)).
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `i-bem.bemhtml`, из-за которой было невозможно использовать микс в виде одного объекта (не массива) одновременно в BEMJSON и BEMHTML ([#555](https://github.com/bem/bem-core/issues/555)).
- Исправлена ошибка в BEMHTML-шаблоне блока `page`, из-за которой не выполнялись стандартные моды, и исправлена регрессия в шаблоне на touch-уровне ([516](https://github.com/bem/bem-core/issues/516)).
## 2.2.4
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в `i-bem.js`, из-за которой событие об изменении модификатора генерировалось,
даже если обработчик `beforeSetMod` предотвращал изменение ([#546](https://github.com/bem/bem-core/pull/546)).
- В случае возникновения ошибки в процессе декодирования строки, модуль `querystring__uri` теперь возвращает
оригинальную строку ([#554](https://github.com/bem/bem-core/pull/554)).
## 2.2.3
### В релиз вошли следующие исправления ошибок
- В модуле `i-bem__dom` был исправлен процесс удаления блока для предотвращения нежелательной повторной
инициализации блока ([#540](https://github.com/bem/bem-core/issues/540)).
- Исправлена ошибка в модуле `jquery__event_type_pointer`, из-за которой нативные события мыши ошибочно замещались
на pointer-события ([#534](https://github.com/bem/bem-core/issues/534)).
- `unbindFrom*`-методы в модуле `i-bem__dom` теперь поддерживают отписывание от нескольких событий
за вызов ([#533](https://github.com/bem/bem-core/issues/533)).
- Добавлена недостающая зависимость от модуля `functions` в модуле `events` ([#532](https://github.com/bem/bem-core/issues/532)).
## 2.2.2
### В релиз вошли следующие исправления ошибок
- Исправлена ошибка в модуле `i-bem__dom` приводящая к повторной инициализации блока на DOM-узле, отмеченном как
удаленный ([#518](https://github.com/bem/bem-core/issues/518)).
- Исправлена ошибка в модуле `i-bem`, из-за которой невозможно было подписаться на событие о выставлении модификатора в
значение `false` ([#529](https://github.com/bem/bem-core/issues/529)).
- Модуль `jquery` обновлен до версий 2.1.1 и 1.11.1 ([#515](https://github.com/bem/bem-core/issues/515)).
## 2.2.1
- Исправлена ошибка в модуле `jquery__event_type_pointerpressrelease`, из-за которой событие `pointerpress` генерировалось
дважды на каждое событие `mousedown` в IE10 ([#505](https://github.com/bem/bem-core/issues/505)).
## 2.2.0
### Крупные изменения
- Добавлен новый модуль `keyboard__codes` ([#431](https://github.com/bem/bem-core/issues/431)).
- Класс `BEMContext` добавлен в export-параметры функции `oninit` в базовых шаблонах `i-bem.bemhtml` ([#485](https://github.com/bem/bem-core/pull/485)).
- Добавлена возможность декларировать инстанс элемента используя класс блока ([#481](https://github.com/bem/bem-core/issues/481)).
- Исправлено поведение метода `isSimple` класса BEMContext в в базовых шаблонах `i-bem.bemhtml` ([#432](https://github.com/bem/bem-core/pull/432)).
- Исправлена ошибка в методе `liveUnbindFrom` модуля `BEMDOM` ([#476](https://github.com/bem/bem-core/pull/476)).
- Исправлена ошибка в методе `isFocusable` модуля `dom`, возникающая если переданный `domElem` является ссылкой
с атрибутом `tabindex`, но без атрибута `href` ([#501](https://github.com/bem/bem-core/issues/501)).
- Исправлена ошибка возникающая в процессе декларации БЭМ-блока как модуля, если был подключен
модуль `i-bem__dom_elem-instances` ([#479](https://github.com/bem/bem-core/issues/479)).
- В модуле `i-bem__dom_init_auto` добавлено временное решение для проблем с производительностью ренедеринга при инициализации блоков
в Chrome-браузерах ([#486](https://github.com/bem/bem-core/issues/486)).
- Модуль `vow.js` перенесен в `vow.vanilla.js` ([#412](https://github.com/bem/bem-core/issues/412)).
### Также в релиз вошли следующие изменения
- Модуль `vow` обновлен до версии 0.4.3 ([#504](https://github.com/bem/bem-core/pull/504)).
- Добавлена русская документация на технологию BEMTREE ([#500](https://github.com/bem/bem-core/pull/500)).
- Обновлена русская документация на JavaScript-синтаксис BEMHTML ([#471](https://github.com/bem/bem-core/pull/471)).
- Добавлен референс на API JavaScript-модулей. См. ветку `v2-jsdoc` ([#478](https://github.com/bem/bem-core/pull/478)).
## 2.1.0
### Крупные изменения
- Исправлена ошибка в `i-bem.js`, из-за которой событие об изменении модификатора происходило до того, как будет
вызван обработчик реакции на изменение этого модификатора в `onSetMod` ([#454](https://github.com/bem/bem-core/issues/454)).
- Свойства `this.mods` и `this.ctx.mods` базового шаблона `i-bem.bemhtml` теперь используют
один и тот же объект ([#441](https://github.com/bem/bem-core/issues/441)).
- Модуль [inherit](https://github.com/dfilatov/inherit) обновлен до версии 2.2.1 ([#466](https://github.com/bem/bem-core/issues/466)).
- Исправлен порядок тегов секции `head` в шаблоне `page.bemhtml` ([#465](https://github.com/bem/bem-core/pull/465)).
### Также в релиз вошли следующие изменения
- В русскую документацию к `i-bem.js` добавлено описание поля `baseMix` ([#461](https://github.com/bem/bem-core/pull/461)).
- CDN-хост внешних ресурсов изменен на `yastatic.net` ([#444](https://github.com/bem/bem-core/issues/444)).
Все ресурсы все так же доступны с хоста `yandex.st`. Физически `yandex.st` и `yastatic.net` находятся на
одних и тех же серверах. Различие только в DNS-записях.
- Добавлен базовый BEMHTML-шаблон для команды `bem create` технологии `bemhtml` ([#277](https://github.com/bem/bem-core/issues/277)).
- Прекращен автоматический запуск тестов под Node.js 0.8 в [Travis CI](http://travis-ci.com) ([#455](https://github.com/bem/bem-core/issues/455)).
- Иконка статуса автосборки Travis [заменена на SVG](http://blog.travis-ci.com/2014-03-20-build-status-badges-support-svg/) :)
## 2.0.0
### Изменения, ломающие обратную совместимость
- Из `i-bem.js` и `i-bem__dom.js` удалены все **deprecated** методы ([#318](https://github.com/bem/bem-core/issues/318)):
* `destruct`, используйте `onSetMod js ''`;
* `extractParams`, используйте `elemParams`;
* `trigger`, используйте `emit`;
* `afterCurrentEvent`, используйте модуль `next-tick`;
* `channel`, используйте модуль `events__channels`;
* `changeThis`, используйте нативный `Function.prototype.bind`.
- Из `i-bem.js` убраны события `init` и `destruct`. Вместо них следует использовать события об изменении модификатора
(см. «Крупные изменения»).
- Блок `ecma` перенесен [в отдельный репозиторий](http://github.com/bem/es5-shims); ES5-shims следует использовать
для IE < 9 ([#230](https://github.com/bem/bem-core/issues/230)).
- Модуль `vow` обновлен до мажорной версии 0.4.1 ([#350](https://github.com/bem/bem-core/issues/350)).
См. [изменения в Vow](https://github.com/dfilatov/vow/blob/0.4.1/CHANGELOG.md).
- В `i-bem.bemhtml` добавлена поддержка vow@0.4 ([#385](https://github.com/bem/bem-core/issues/385)).
### Крупные изменения
- Добавлена возможность декларировать BEMDOM-блоки как модули [ym](https://github.com/ymaps/modules) ([#382](https://github.com/bem/bem-core/issues/382)).
- В `i-bem.js` добавлены события об изменении модификатора ([#357](https://github.com/bem/bem-core/issues/357)).
- Добавлена поддержка использования строковых значений в качестве аргумента в методах `BEMDOM.init` ([#419](https://github.com/bem/bem-core/issues/419))
и `BEMDOM.update` ([#420](https://github.com/bem/bem-core/issues/420)).
- Методы `i-bem__dom.js` `replace`, `append`, `prepend`, `before`, `after` теперь возвращают новый контекст,
а `update` – изменённый ([#410](https://github.com/bem/bem-core/issues/410)).
- В `loader` добавлен модификатор `_type_bundle` ([#358](https://github.com/bem/bem-core/issues/358)).
- jQuery обновлен до версии 2.1.0. Для IE < 9 — до версии 1.11.0 ([#356](https://github.com/bem/bem-core/issues/356)).
### Также в релиз вошли следующие изменения
- Базовые шаблоны в `i-bem.bemhtml` используют конкатенацию строк вместо наполнения внутреннего буфера ([#401](https://github.com/bem/bem-core/issues/401)).
- jQuery больше не удаляет себя из глобальной области видимости, если присутствует на странице ([#349](https://github.com/bem/bem-core/issues/349)).
- `jquery__event_type_pointerclick.js` перемещен с уровня `touch.blocks` на уровень `common.blocks` ([#393](https://github.com/bem/bem-core/issues/393)).
- Модификаторы `i-bem_elem-instances_yes` и `i-bem__dom_elem-instances_yes` приведены к булевому стилю ([#352](https://github.com/bem/bem-core/issues/352)).
- Исправлена ошибка в шаблоне блока `page`, возникающая при использовании development-режима BEMHTML ([#417](https://github.com/bem/bem-core/issues/417)).
- Для поддержки Android 2.3 внутри `i-bem.js` отказались от использований `Function.prototype.bind` ([#404](https://github.com/bem/bem-core/issues/404)).
- Исправлены ошибки в модуле технологии `browser-js+bemhtml` ([#392](https://github.com/bem/bem-core/issues/392)).
- NPM-модуль `ym` обновлен до версии [0.0.15](https://github.com/ymaps/modules/releases) ([#414](https://github.com/bem/bem-core/issues/414)).
## 1.2.0
### Крупные изменения
- BEM-блоки инициируют событие `destruct` в процессе удаления ([#370](https://github.com/bem/bem-core/issues/370)).
- Исправлены полифилы для `pointerevents` ([#354](https://github.com/bem/bem-core/pull/354)).
### Также в релиз вошли следующие изменения
- JSDoc блоков исправлен в соответствии с поддержкой [bem-jsd](github.com/bem/bem-jsd) ([#335](https://github.com/bem/bem-core/issues/335)).
- Референс на BEMHTML обновлен для соответствия JavaScript-синтаксису шаблонизатора ([#355](https://github.com/bem/bem-core/pull/355)).
- Переход на менеджер зависимостей [bower](http://bower.io) ([#367](https://github.com/bem/bem-core/issues/367)).
## 1.1.0
### Крупные изменения
- Для современных браузеров `jquery__config` подключает jQuery 2.x ([#319](https://github.com/bem/bem-core/issues/319)).
- Добавлена возможность использовать произвольный BEMJSON в качестве значения атрибутов в BEMHTML ([#290](https://github.com/bem/bem-core/issues/290)).
- Исправлены зависимости в `i-bem__collection` ([#292](https://github.com/bem/bem-core/issues/292)).
- Удалены CSS-стили блока `page` из уровня `touch.blocks` ([#306](https://github.com/bem/bem-core/issues/306)).
- Исправлена ошибка в BEMHTML-шаблоне блока `page`, приводящая к зацикливанию шаблонизатора
в production-режиме ([#309](https://github.com/bem/bem-core/issues/309)).
- Исправлена возможная ошибка в `next-tick`, возникающая при вставке скрипта в DOM в IE<9 ([#324](https://github.com/bem/bem-core/issues/324)).
- Исправлена ошибка в инициализации плагина `FastClick` в модуле `jquery__event_type_pointerclick`
на уровне `touch.blocks` ([#332](https://github.com/bem/bem-core/issues/332)).
- Исправлена ошибка в технологии `node.js` в Windows ([#274](https://github.com/bem/bem-core/issues/274)).
- Исправлена ошибка в `onElemSetMod` в `i-bem__dom_elem-instances` ([#340](https://github.com/bem/bem-core/issues/340)).
- В технологии `bemhtml` используется [bem-xjst](https://github.com/bem/bem-xjst) ([#329](https://github.com/bem/bem-core/issues/329)).
### Также в релиз вошли следующие изменения
- Модуль [ym](https://github.com/ymaps/modules) обновлен до версии 0.0.12 ([#326](https://github.com/bem/bem-core/issues/326)).
- В ядре локализации `i-bem__i18n` отключен вывод сообщений о неизвестных ключах, если не включен
debug-режим ([#285](https://github.com/bem/bem-core/issues/285)).
- Инфраструктура сборки тестов и примеров переведена
на [bem-pr@v0.5.x](https://github.com/narqo/bem-pr/blob/0.5.3/HISTORY.md) ([#323](https://github.com/bem/bem-core/issues/323)).
- Исправлен jsdoc для метода `dropElemCache()` в `i-bem__dom` ([#296](https://github.com/bem/bem-core/issues/296)).
- Доработана документация для блока `i-bem.js` на русском языке.
- В README проекта добавлен [список поддерживаемых браузеров](https://github.com/bem/bem-core/blob/v1/README.ru.md#%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D0%B5%D0%BC%D1%8B%D0%B5-%D0%B1%D1%80%D0%B0%D1%83%D0%B7%D0%B5%D1%80%D1%8B).
## 1.0.0
### Крупные изменения
- Переход на модульную систему [ym](https://github.com/ymaps/modules).
- Из `i-bem`, `i-bem__dom` убраны все deprecated-методы.
- `i-bem` больше не зависит от jQuery. `i-bem__dom` продолжает зависеть от jQuery.
- BEMHTML-шаблоны можно писать с использованием [JS-синтаксиса](https://gist.github.com/veged/6150760).
- Новая технология `bemtree` (на базе [bem-xjst](https://github.com/bem/bem-xjst)) для описания процесса
динамического построения БЭМ-дерева.
- Новая технология `vanilla.js` для описания JS-реализации модулей, не зависящей от конкретного JavaScript движка.
- Новые технологии `browser.js` и `node.js` для описания JS-реализаций модулей (блоков) в соответствующих движках.
Для совместимости с существующим кодом считаем, что файлы с расширением `.js` содержат реализацию блоков
в технологии `browser.js`.
- Система модульного тестирования и примеров для блоков в библиотеке.
- Появились полифилы (`jquery__event_type_pointer` и `jquery__event_type_pointerclick` как jQuery-плагины),
позволяющие использовать универсальные события для десктопных и тач-интерфейсов.
- Плагин для jQuery, позволяющий навешивать обработчик события на нажатие левой кнопки мыши, становится модулем `jquery__pointerclick`.
- В `i-bem` и BEMHTML добавлена поддержка простых модификаторов (модификаторов без значений).
### Также в релиз вошли следующие изменения
- Все блоки-модули, кроме `i-bem`, избавились от префиксов.
- Блок `i-bem__dom` становится модулем `i-bem__dom`. Все BEM.DOM-блоки должны теперь доопределять
этот модуль ([пример](https://github.com/bem/bem-core/blob/v1/common.bundles/index/blocks/b-square/b-square.js)).
- Метод для декларации блоков (`.decl()`) больше не принимает первым параметром объект с полем `name`.
Теперь обязательная форма записи с полем `block`: `BEM.decl({ block: 'b1', modName: 'm', modVal: 'v' }, ...)`.
- Вместо метода `afterCurrentEvent` у блоков появился метод `nextTick`, который проверят существование блока в момент исполнения колбэка. `BEM.afterCurrentEvent` теперь **deprecated**.
- Вместо `BEM.channel` появился отдельный модуль `channels`. `BEM.channel` теперь **deprecated**.
- Метод `changeThis` помечен как **deprecated**. Используйте нативный `bind`.
- Метод `del` удален из блока `i-bem`.
- Метод `getWindowSize` удален из блока `i-bem__dom`. Используйте `BEMDOM.win.width()` и `BEMDOM.win.height()`.
- Добавлен модуль-обертка `jquery`, предоставляющий jQuery. Модуль либо предоставляет jQuery, уже присутствующий на странице, либо сам его загружает (версию 1.10.1).
- `$.observable` становится модулем `events` и больше не зависит от jQuery.
- `$.inherit` становится модулем `inherit` и больше не зависит от jQuery.
- `$.identify` становится модулем `identify` и больше не зависит от jQuery.
- `$.throttle` разбивается на два модуля: `functions__throttle` и `functions__debounce`, которые больше не зависят от jQuery.
- `$.decodeURI`, `$.decodeURIComponent` переезжают в модуль `querystring__uri` и больше не зависят от jQuery.
- `$.cookie` становится модулем `cookie` и больше не зависит от jQuery.
- Вместо `$.browser` появился модуль `ua` с аналогичным интерфейсом.
- Блок `i-system` разбит на 2 модуля: `idle` и `tick`.
- Вместо события `leftclick` следует использовать `pointerclick` (предоставляемый полифилом `jquery__event_type_pointerclick`).
- Триггеры на установку модификаторов теперь разделены на две группы: до установки модификатора (`beforeSetMod` и `beforeElemSetMod`) и после (`onSetMod` и `onElemSetMod`). Отмена установки модификатора теперь возможна только из триггеров первой группы.
- Использовать конструкцию `{ onSetMod : { js : function() { ... } } }` в качестве конструктора теперь **deprecated**, необходимо использовать `onSetMod: { js : { inited : ... } } }`.
- Вместо метода `destruct` в `i-bem` появился зеркальный метод
для `onSetMod: { js : { inited : ... } } }` — `{ onSetMod : { js : { '' : ... } } }`.
Метод `destruct` теперь **deprecated**.
- Метод `exractParams` в `i-bem__dom` теперь **deprecated**, для доступа к параметрам элементов нужно использовать метод `elemParams`.
- Метод `trigger` в `i-bem` теперь **deprecated**, нужно использовать `emit`.
- Метод `onFirst` в `i-bem` теперь **deprecated**, нужно использовать `once`.
- Удалено **deprecated** поле `e.block`, представляющее блок-источник события для BEM-событий. Вместо него следует использовать поле `e.target`.
- Для доступа к DOM-элементу блока в обработчике DOM-событий теперь нужно использовать поле `currentTarget`, предоставляемое jQuery. Вместо `e.data.domElem`нужно писать `$(e.currentTarget)`.
- В методе `findElem` добавлен параметр, позволяющий находить элемента блока с учетом вложенных блоков.
- Добавлена возможность указывать конкретную функцию для отписки от событий в методах `unbindFrom*`.
- Добавлен модуль `objects` для работы с JS-объектами (содержит методы `extend`, `isEmpty`, `each`).
- Добавлен модуль `functions` для работы с JS-функциями (содержит методы `isFunction`, `noop`).
- Добавлен модуль `dom` для хелперов при работе с DOM.
- Добавлен модуль `querystring` для работы с урлами.
- Добавлен модуль `loader_type_js` для загрузки JS.
- Добавлен модуль `vow` для работы с промисами.
- Добавлен модуль `next-tick` для полифила `nextTick`, `setImmediate`, `setTimeout(0, ...` и т.п..
- Добавлен модуль `strings__escape`, содержащий методы для эскейпинга XML, HTML и атрибутов.
- Модуль `inherit` теперь поддерживает миксины.
- В модуле `functions__throttle` добавлен параметр `invokeAsap`, позволяющий отложить первое исполнение.
================================================
FILE: CLA.md
================================================
# Notice to external contributors
## General info
Hello! In order for us (YANDEX LLC) to accept patches and other contributions from you, you will have to adopt our Yandex Contributor License Agreement (the “**CLA**”). The current version of the CLA you may find here:
1) https://yandex.ru/legal/cla/?lang=en (in English) and
2) https://yandex.ru/legal/cla/?lang=ru (in Russian).
By adopting the CLA, you state the following:
* You obviously wish and are willingly licensing your contributions to us for our open source projects under the terms of the CLA,
* You has read the terms and conditions of the CLA and agree with them in full,
* You are legally able to provide and license your contributions as stated,
* We may use your contributions for our open source projects and for any other our project too,
* We rely on your assurances concerning the rights of third parties in relation to your contributes.
If you agree with these principles, please read and adopt our CLA. By providing us your contributions, you hereby declare that you has already read and adopt our CLA, and we may freely merge your contributions with our corresponding open source project and use it in further in accordance with terms and conditions of the CLA.
## Provide contributions
If you have already adopted terms and conditions of the CLA, you are able to provide your contributes. When you submit your pull request, please add the following information into it:
```
I hereby agree to the terms of the CLA available at: [link].
```
Replace the bracketed text as follows:
* `[link]` is the link at the current version of the CLA (you may add here a link https://yandex.ru/legal/cla/?lang=en (in English) or a link https://yandex.ru/legal/cla/?lang=ru (in Russian).
It is enough to provide us such notification at once.
## Other questions
If you have any questions, please mail us at opensource@yandex-team.ru.
================================================
FILE: CONTRIBUTING.md
================================================
# How to contribute
1. [Create an issue](https://github.com/bem/bem-core/issues/new) with a proper description.
2. Decide which version needs your changes.
3. Create a feature-branch with an issue number and a version (`issues/<issue_number>@v<version_number>`) based on a version branch.
For example, for an issue #42 and a version #1: `git checkout -b issues/42@v1 v1`.
If you need changes for several versions, each of them has to have a feature branch.
4. Commit changes accordingly to [CLA](CLA.md) and `push`. Rebase your branch on a corresponding version branch if it's needed.
5. Create a pull-request from your feature branch; or several pull-requests if you changed several versions.
6. Link your pull request with an issue number any way you like. A comment will work perfectly.
7. Wait for your pull request and the issue to be closed ;-)
## Contributors
The list of contributors is available at https://github.com/bem/bem-core/graphs/contributors. You may also get it with `git log --pretty=format:"%an <%ae>" | sort -u`.
================================================
FILE: CONTRIBUTING.ru.md
================================================
# Внесение изменений
1. [Создать issue](https://github.com/bem/bem-core/issues/new) с описанием сути изменений.
2. Определить в какую версию необходимо внести изменения.
3. Сделать feature-branch с указанием номера issue и версии (`issues/<номер_issue>@v<номер_версии>`) на основе ветки версии.
Например, для issue с номером 42 и версией 1: `git checkout -b issues/42@v1 v1`. Если изменения нужно внести в несколько версий,
то для каждой из версий создаётся отдельная ветка.
4. Сделать изменения, закоммитить согласно с [CLA](CLA.md) и сделать push. Если это необходимо, то нужно сделать rebase от базовой ветки версии.
5. Создать pull-request на основе созданной ветки (или несколько pull-request-ов для случая изменений в нескольких версиях).
6. Любым способом связать pull-request и issue (например, c помощью комментария).
7. Ждать закрытия pull-request и issue ;-)
## Контрибьюторы
Список контрибьютеров данного проекта доступен по ссылке https://github.com/bem/bem-core/graphs/contributors. Вы так же можете получить его с помощью команды `git log --pretty=format:"%an <%ae>" | sort -u`.
================================================
FILE: LICENSE.txt
================================================
© YANDEX LLC, 2012
The Source Code called `bem-core` available at https://github.com/bem/bem-core is subject to the terms of the Mozilla Public License, v. 2.0 (hereinafter - MPL). The text of MPL is the following:
Mozilla Public License, version 2.0
1. Definitions
1.1. "Contributor"
means each individual or legal entity that creates, contributes to the
creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used by a
Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached the
notice in Exhibit A, the Executable Form of such Source Code Form, and
Modifications of such Source Code Form, in each case including portions
thereof.
1.5. "Incompatible With Secondary Licenses"
means
a. that the initial Contributor has attached the notice described in
Exhibit B to the Covered Software; or
b. that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the terms of
a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in a
separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible, whether
at the time of the initial grant or subsequently, any and all of the
rights conveyed by this License.
1.10. "Modifications"
means any of the following:
a. any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered Software; or
b. any new file in Source Code Form that contains any Covered Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the License,
by the making, using, selling, offering for sale, having made, import,
or transfer of either its Contributions or its Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU Lesser
General Public License, Version 2.1, the GNU Affero General Public
License, Version 3.0, or any later versions of those licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that controls, is
controlled by, or is under common control with You. For purposes of this
definition, "control" means (a) the power, direct or indirect, to cause
the direction or management of such entity, whether by contract or
otherwise, or (b) ownership of more than fifty percent (50%) of the
outstanding shares or beneficial ownership of such entity.
2. License Grants and Conditions
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
a. under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
b. under Patent Claims of such Contributor to make, use, sell, offer for
sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
a. for any code that a Contributor has removed from Covered Software; or
b. for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
c. under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights to
grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
Section 2.1.
3. Responsibilities
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
a. such Covered Software must also be made available in Source Code Form,
as described in Section 3.1, and You must inform recipients of the
Executable Form how they can obtain a copy of such Source Code Form by
reasonable means in a timely manner, at a charge no more than the cost
of distribution to the recipient; and
b. You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter the
recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty, or
limitations of liability) contained within the Source Code Form of the
Covered Software, except that You may alter any license notices to the
extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
If it is impossible for You to comply with any of the terms of this License
with respect to some or all of the Covered Software due to statute,
judicial order, or regulation then You must: (a) comply with the terms of
this License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be placed in a
text file included with all distributions of the Covered Software under
this License. Except to the extent prohibited by statute or regulation,
such description must be sufficiently detailed for a recipient of ordinary
skill to be able to understand it.
5. Termination
5.1. The rights granted under this License will terminate automatically if You
fail to comply with any of its terms. However, if You become compliant,
then the rights granted under this License from a particular Contributor
are reinstated (a) provisionally, unless and until such Contributor
explicitly and finally terminates Your grants, and (b) on an ongoing
basis, if such Contributor fails to notify You of the non-compliance by
some reasonable means prior to 60 days after You have come back into
compliance. Moreover, Your grants from a particular Contributor are
reinstated on an ongoing basis if such Contributor notifies You of the
non-compliance by some reasonable means, this is the first time You have
received notice of non-compliance with this License from such
Contributor, and You become compliant prior to 30 days after Your receipt
of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
license agreements (excluding distributors and resellers) which have been
validly granted by You or Your distributors under this License prior to
termination shall survive termination.
6. Disclaimer of Warranty
Covered Software is provided under this License on an "as is" basis,
without warranty of any kind, either expressed, implied, or statutory,
including, without limitation, warranties that the Covered Software is free
of defects, merchantable, fit for a particular purpose or non-infringing.
The entire risk as to the quality and performance of the Covered Software
is with You. Should any Covered Software prove defective in any respect,
You (not any Contributor) assume the cost of any necessary servicing,
repair, or correction. This disclaimer of warranty constitutes an essential
part of this License. No use of any Covered Software is authorized under
this License except under this disclaimer.
7. Limitation of Liability
Under no circumstances and under no legal theory, whether tort (including
negligence), contract, or otherwise, shall any Contributor, or anyone who
distributes Covered Software as permitted above, be liable to You for any
direct, indirect, special, incidental, or consequential damages of any
character including, without limitation, damages for lost profits, loss of
goodwill, work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses, even if such party shall have been
informed of the possibility of such damages. This limitation of liability
shall not apply to liability for death or personal injury resulting from
such party's negligence to the extent applicable law prohibits such
limitation. Some jurisdictions do not allow the exclusion or limitation of
incidental or consequential damages, so this exclusion and limitation may
not apply to You.
8. Litigation
Any litigation relating to this License may be brought only in the courts
of a jurisdiction where the defendant maintains its principal place of
business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions. Nothing
in this Section shall prevent a party's ability to bring cross-claims or
counter-claims.
9. Miscellaneous
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides that
the language of a contract shall be construed against the drafter shall not
be used to construe this License against a Contributor.
10. Versions of the License
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses If You choose to distribute Source Code Form that is
Incompatible With Secondary Licenses under the terms of this version of
the License, the notice described in Exhibit B of this License must be
attached.
Exhibit A - Source Code Form License Notice
This Source Code Form is subject to the
terms of the Mozilla Public License, v.
2.0. If a copy of the MPL was not
distributed with this file, You can
obtain one at
http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file,
then You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a
notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
This Source Code Form is "Incompatible
With Secondary Licenses", as defined by
the Mozilla Public License, v. 2.0.
A copy of the MPL is also available at http://mozilla.org/MPL/2.0/.
================================================
FILE: MIGRATION.md
================================================
# Migration
## 5.0.0
### ym → ES modules
The `ym` module system (`modules.define`/`modules.require`) has been replaced with native ES modules.
Before:
```js
modules.define('my-block', ['i-bem-dom', 'events'], function(provide, bemDom, events) {
provide(bemDom.declBlock(this.name, { /* ... */ }));
});
```
After:
```js
import bemDom from 'bem:i-bem-dom';
import events from 'bem:events';
export default bemDom.declBlock('my-block', { /* ... */ });
```
All `bem:*` imports are resolved at build time by `vite-plugin-bem-levels` to the actual file paths, respecting platform-specific level priorities.
### Module redefinitions
Module redefinitions that previously used `modules.define` with a callback receiving the previous module value are now handled via barrel files generated by the Vite plugin.
Before (ym redefinition):
```js
modules.define('jquery', function(provide, $) {
$.event.special.pointerclick = { /* ... */ };
provide($);
});
```
After (side-effect import in barrel):
```js
// The barrel file auto-generated by vite-plugin-bem-levels:
import $ from '../../common.blocks/jquery/jquery.js';
import '../../common.blocks/jquery/__event/_type/jquery__event_type_pointerclick.js';
export default $;
```
### jQuery 3 → 4
The `jquery` peer dependency is now `^4.0.0`.
Key breaking changes in jQuery 4:
- `$.unique()` has been removed. Use `$.uniqueSort()`.
- Several deprecated methods have been removed. See [jQuery 4.0 upgrade guide](https://jquery.com/upgrade-guide/4.0/).
### vow → native Promise
The `vow` dependency has been removed. All asynchronous code now uses native `Promise`.
Before:
```js
var vow = require('vow');
var promise = vow.resolve(value);
```
After:
```js
const promise = Promise.resolve(value);
```
### Build system: ENB → Vite
The entire ENB toolchain has been replaced with Vite.
Before:
```bash
./node_modules/.bin/enb make
```
After:
```bash
npm run build # both platforms
npm run build:desktop # desktop only
npm run build:touch # touch only
```
The Vite config is in `build/vite.config.js`. The custom `vite-plugin-bem-levels` plugin in `build/plugins/` handles BEM level scanning and module resolution.
### Node.js 20+
The minimum supported Node.js version is now 20 (was 8). Update your `.nvmrc` or CI configuration accordingly.
### Linting: jshint/jscs → ESLint 10
Replace any custom `.jshintrc` or `.jscs.json` rules with ESLint flat config (`eslint.config.js`).
### Testing
- **Server-side tests**: `mocha`/`chai` have been replaced with `node:test`/`node:assert`.
- **Browser tests**: `mocha-phantomjs` has been replaced with Playwright. Run with `npm run test:browser`.
- **All tests**: `npm run test:all` runs both server-side and browser tests.
### CI/CD: Travis → GitHub Actions
Replace `.travis.yml` with `.github/workflows/ci.yml`. The new CI runs lint, test, test:browser, and build jobs.
### Git hooks: git-hooks → husky
Replace `.githooks/` with husky configuration. The `prepare` script in `package.json` sets up husky automatically on `npm install`.
## 4.0.0
### Changes in the `i-bem` block
#### Separate `i-bem-dom` block
The `dom` element of the `i-bem` block was moved to a separate `i-bem-dom` block.
Before:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
/* ... */
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
/* ... */
});
```
The `i-bem` and `i-bem-dom` blocks are no longer classes. They are modules with methods for declaring BEM entities, links to classes of BEM entities, and some additional helpers. These methods are no longer class methods for the corresponding blocks.
Issue: [#413](https://github.com/bem/bem-core/issues/413).
#### Declaration
#### Block declaration
Instead of the `decl()` method, use the `declBlock()` method to declare a block.
Before:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }));
});
```
#### Modifier declaration
Instead of the static `decl()` method, use the static `declMod()` method to declare a modifier.
Before:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'my-val' }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : 'myVal' }, { /* ... */ }));
});
```
#### Boolean modifier declaration
Before:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'true' }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod' }, { /* ... */ }));
});
```
Issue: [#1374](https://github.com/bem/bem-core/issues/1374).
#### Declaration for a modifier with any value
Before:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod' }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : '*' }, { /* ... */ }));
});
```
Issue: [#1376](https://github.com/bem/bem-core/pull/1376).
#### Block redefinition
Instead of the `decl()` method for a block class, use the `declBlock()` method for the `i-bem-dom` module.
Before:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom, MyDomBlock) {
provide(bemDom.declBlock(MyDomBlock, { /* ... */ }));
});
```
#### Inherited block declaration
Before:
```js
modules.define('my-dom-block', ['i-bem__dom', 'my-base-dom-block'], function(provide, BEMDOM, MyBaseDomBlock) {
provide(BEMDOM.decl({ block : this.name, baseBlock : MyBaseDomBlock }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom', 'my-base-dom-block'], function(provide, bemDom, MyBaseDomBlock) {
provide(bemDom.declBlock(this.name, MyBaseDomBlock, { /* ... */ }));
});
```
#### Mix declaration
The `declMix` method has been renamed to `declMixin`. This clarifies the concept of [mixes of multiple BEM entities on a single DOM node](https://en.bem.info/methodology/key-concepts/#Mix) as opposed to JS-level mixins.
Before:
```js
modules.define('my-mix-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.declMix(this.name, { /* ... */ }));
});
```
After:
```js
modules.define('my-mixin-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declMixin({ /* ... */ }));
});
```
#### Mixing a mixin
Before:
```js
modules.define('my-dom-block', ['i-bem__dom', 'my-mix-1', 'my-mix-2'], function(provide, BEMDOM) {
provide(BEMDOM.decl({ block : this.name, baseMix : ['my-mix-1', 'my-mix-2']}, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom', 'my-mixin-1', 'my-mixin-2'], function(provide, bemDom, MyMixin1, MyMixin2) {
provide(bemDom.declBlock(this.name, [MyMixin1, MyMixin2], { /* ... */ }));
});
```
#### Triggers for changing modifiers
When declaring a specific modifier (for example, `_my-mod_my-val`), it wasn't possible to declare the behavior for deleting this modifier. We had to make two declarations.
Before:
```js
//
modules.define('my-dom-block', function(provide, MyDomBlock) {
MyDomBlock.decl({
onSetMod : {
'my-mod' : {
'' : function() { /* ... */ } // declaration for deleting the _my-mod_my-val modifier
}
}
});
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'my-val' }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : 'my-val' }, {
onSetMod : {
'mod1' : {
'' : function() { /* ... */ } // declaration for deleting the _my-mod_my-val modifier
}
}
}));
});
```
Issue: [#1025](https://github.com/bem/bem-core/issues/1025).
Shorthand syntax is now available for declaring behaviors for changing modifiers.
Before:
```js
onSetMod : {
'my-mod' : {
'*' : function(modName, modVal, prevModVal) {
if(prevModVal === 'my-val') {
/* ... */ // declaration for changing _my-mod_my-val to any other value
}
}
}
}
```
After:
```js
onSetMod : {
'my-mod' : {
'~my-val' : function() { /* ... */ } // declaration for changing the my-mod value from my-val to any other value
}
}
}
```
Before:
```js
onSetMod : {
'my-mod' : {
'*' : function(modName, modVal) {
if(modVal !== 'my-val') {
/* ... */ // declaration for changing my-mod to any value other than my-val
}
}
}
}
```
After:
```js
onSetMod : {
'my-mod' : {
'!my-val' : function() { /* ... */ } // declaration for changing my-mod to any value other than my-val
}
}
}
```
Issue: [#1072](https://github.com/bem/bem-core/issues/1072).
#### Lazy initialization
The functionality of the `live` field has been divided into two parts: the `lazyInit` field and the `onInit()` method.
Before:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : true
}));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
lazyInit : true
}));
});
```
Before:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
/* ... */
}
}));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
lazyInit : true,
onInit : function() {
/* ... */
}
}));
});
```
Before:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
/* ... */
return false;
}
}));
});
```
After:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
onInit : function() {
/* ... */
}
}));
});
```
Before:
```js
{
block : 'b1',
js : { live : false }
}
```
After:
```js
{
block : 'b1',
js : { lazyInit : false }
}
```
Issue: [#877](https://github.com/bem/bem-core/issues/877).
#### Instances for elements
Deleted the `elem-instances` element of the `i-bem` block and the `elem-instances` modifier of the `dom` element in the `i-bem` block.
Now the corresponding functionality is incorporated into `i-bem` and `i-bem-dom`.
Before:
```js
modules.define('my-dom-block__my-elem', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl({ block : 'my-dom-block', elem : 'my-elem' }, { /* ... */ }));
});
```
After:
```js
modules.define('my-dom-block__my-elem', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declElem('my-dom-block', 'my-elem', { /* ... */ }));
});
```
Now the `_elem(elemName)` method of the block instance (previously `elem(elemName)`) returns an instance of the element's class, instead of a jQuery object with all the elements named `elemName`.
To get a collection of instances of the element's class, use the `_elems()` method.
Now the caches for elements with JS implementation found with `_elem()` and `_elems()` are invalidated automatically when the DOM is modified.
Issue: [#1352](https://github.com/bem/bem-core/issues/1352).
Note: When this methods are used for elements without JS implementation you still need to use `_dropElemCache()` in cases of dynamically DOM update.
Note: don't forget to switch on support for elements instances in template engine.
For `bem-xjst` please refer to https://github.com/bem/bem-xjst/blob/master/docs/en/3-api.md#support-js-instances-for-elements-bem-core-v4 or for `BH` see https://github.com/bem/bh#jselem.
##### Ways to work with elements
Before:
```js
this.setMod(this.elem('my-elem'), 'my-mod', 'my-val');
```
After:
```js
this._elem('my-elem').setMod('my-mod', 'my-val');
```
The same is true for the methods `getMod()`, `hasMod()`, `toggleMod()`, and `delMod()`.
##### Deleted methods and fields
The following methods were deleted from the block API: `elemify()`, `elemParams()`, and the `onElemSetMod` field. The corresponding functionality is provided in instances of elements.
Also see the changes for [search methods](#Search-methods).
Issue: [#581](https://github.com/bem/bem-core/issues/581).
#### Search methods
Renamed the following methods:
- `findBlockInside()` to `findChildBlock()`
- `findBlocksInside()` to `findChildBlocks()`
- `findBlockOutside()` to `findParentBlock()`
- `findBlocksOutside()` to `findParentBlocks()`
- `findBlockOn()` to `findMixedBlock()`
- `findBlocksOn()` to `findMixedBlocks()`
The optional first parameter about the element has been removed from these methods.
Added the following methods: `findChildElem()`, `findChildElems()`, `findParentElem()`, `findParentElems()`, `findMixedElem()`, `findMixedElems()`.
Before:
```js
this.findBlockInside(this.elem('my-elem'), 'my-block-2');
```
After:
```js
this.findChildElem('my-elem').findChildBlock(MyBlock2);
```
Deleted the following methods: `findElem()`, `closestElem()`. Use the `findChildElem()` and `findParentElem()` elements, instead.
The methods `findChildBlocks()`, `findParentBlocks()`, `findMixedBlocks()`, `findChildElems()`, `findParentElems()`, and `findMixedElems()` return [collections of BEM entities](#Collections).
The `findChildElem()` and `findChildElems()` methods (unlike the previous equivalent `findElem`) don't search on their own DOM nodes of the instance.
Before:
```js
this.findElem('my-elem');
```
After:
```js
this.findChildElems('my-elem').concat(this.findMixedElems('my-elem'));
```
However, consider whether you really need both searches. In most cases, you can just use either `this.findChildElems('my-elem')` or `this.findMixedElems('my-elem')`.
##### Checking for nesting
In place of the deleted `containsDomElem()` method, use the `containsEntity()` method.
Before:
```js
this.containsDomElem(someElem);
```
After:
```js
this.containsEntity(someElem);
```
#### Collections
The functionality of the `collection` element of the `i-bem` block is no longer optional.
All methods that return an array of BEM entities now return collections.
Before:
```js
this.findBlocksInside('my-block-2')[0].setMod('my-mod', 'my-val');
```
After:
```js
this.findChildBlocks(MyBlock2).get(0).setMod('my-mod', 'my-val');
```
Before:
```js
this.findBlocksInside('my-block-2').forEach(function(myBlock2) {
return myBlock2.setMod('my-mod', 'my-val');
});
```
After:
```js
this.findChildBlocks(MyBlock2).setMod('my-mod', 'my-val');
```
Issue: [#582](https://github.com/bem/bem-core/issues/582).
#### Events
The events API has been simplified. Deleted the following block instance methods: `on()`, `un()`, `once()`, `bindTo()`, `unbindFrom()`, `bindToDoc()`, `bindToWin()`, `unbindFromDoc()`, `unbindFromWin()`, and class methods: `liveBindTo()`, `liveUnbindFrom()`, `on()`, `un()`, `once()`, `liveInitOnBlockEvent()`, `liveInitOnBlockInsideEvent()`.
They have been replaced with the new `_domEvents()` and `_events()` methods, which return an instance of the events manager class with the `on()`, `un()` and `once()` methods.
##### DOM events on instances
Before:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindTo('click', this._onClick);
}
}
}
});
```
After:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents().on('click', this._onClick);
}
}
}
});
```
Before:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindToDoc('click', this._onDocClick);
}
}
}
});
```
After:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents(bemDom.doc).on('click', this._onDocClick);
}
}
}
});
```
Before:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindToWin('resize', this._onWinResize);
}
}
}
});
```
After:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents(bemDom.win).on('resize', this._onWinResize);
}
}
}
});
```
##### Link to instance
If an event was fired on BEM instance the event object will contain a link to an instance:
```js
this._domEvents('my-elem').on('click', function(e) {
e.bemTarget // refers to `my-elem` instance
});
```
##### BEM events on instances
Before:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.findBlockOutside('my-block-2').on('my-event', this._onMyBlock2MyEvent, this);
},
'' : function() {
this.findBlockOutside('my-block-2').un('my-event', this._onMyBlock2MyEvent, this);
}
}
}
});
```
After:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._events(this.findParentBlock('my-block-2')).on('my-event', this._onMyBlock2MyEvent);
}
}
}
});
```
Note that unsubscribing from events is now automatic when the instance is destroyed.
##### Delegated DOM events
Before:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveBindTo('click', this.prototype._onClick);
}
});
```
After:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._domEvents().on('click', this.prototype._onClick);
}
});
```
Before:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveBindTo('my-elem', 'click', this.prototype._onMyElemClick);
}
});
```
After:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._domEvents('my-elem').on('click', this.prototype._onMyElemClick);
}
});
```
##### Delegated BEM events
Before:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveInitOnBlockInsideEvent('my-event', 'my-block-2', this.prototype._onMyBlock2MyEvent);
}
});
```
After:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._events(MyBlock2).on('my-event', this.prototype._onMyBlock2MyEvent);
}
});
```
Note that the parameter with the event handler function is now required.
Before:
```js
modules.define('my-block', ['i-bem__dom', 'my-block-2'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
this.liveInitOnBlockInsideEvent('my-event', 'my-block-2');
}
}));
});
```
After:
```js
modules.define('my-block', ['i-bem-dom', 'my-block-2', 'functions'], function(provide, bemDom, MyBlock2, functions) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
onInit : function() {
this._events(MyBlock2).on('my-event', functions.noop);
}
}));
});
```
Before:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
MyBlock2.on(this.domElem, 'my-event', this._onMyBlock2MyEvent, this);
},
'' : function() {
MyBlock2.un(this.domElem, 'my-event', this._onMyBlock2MyEvent, this);
}
}
}
});
```
After:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._events(MyBlock2).on('my-event', this._onMyBlock2MyEvent);
}
}
}
});
```
Note that unsubscribing from events is now automatic when the instance is destroyed.
#### External code accessing BEM blocks
##### Getting an instance of a BEM block
Now the `bem()` method of a jQuery object accepts a BEM class instead of a string.
Before:
```js
modules.require(['jquery', 'i-bem__dom'], function($, BEMDOM) {
var myBlock = $('.my-block').bem('my-block');
});
```
After:
```js
modules.require(['jquery', 'my-block'], function($, MyBlock) {
var myBlock = $('.my-block').bem(MyBlock);
});
```
##### Subscribing to BEM events from external code
Before:
```js
modules.require(['jquery', 'i-bem__dom'], function($, BEMDOM) {
$('.my-block').bem('my-block').on('my-event', function() { /* ... */ });
});
```
After:
```js
modules.require(['jquery', 'my-block', 'events__observable'], function($, MyBlock, observable) {
observable($('.my-block').bem(MyBlock))
.on('my-event', function() { /* ... */ });
});
```
In addition, you must add `{ block : 'events', elem : 'observable', mods : { type : 'bem-dom' } }` to the dependency.
Issue: [#394](https://github.com/bem/bem-core/issues/394).
#### Names of protected methods begin with `_`
Renamed the protected methods:
- `emit()` to `_emit()`
- `elem()` to `_elem()`
- `dropElemCache()` to `_dropElemCache()`
- `buildClass()` to `_buildClassName()`
- `buildSelector()` to `_buildSelector()`
- `getDefaultParams()` to `_getDefaultParams()`
Issues: [#586](https://github.com/bem/bem-core/issues/586) and [#1359](https://github.com/bem/bem-core/issues/1359).
#### Deleted methods
Deleted the `getMods()` method.
### Changes in the `querystring` block
The `querystring__uri` element is now the `uri` block. The `querystring` block is now the `uri__querystring` element.
Issue: [#967](https://github.com/bem/bem-core/issues/967).
### Changes in the `page` block
The `page__css` element does not support `ie` field. Use the `page__conditional-comment` element instead.
Before:
```
{
block : 'page',
head : [
{ elem : 'css', url : 'my-css.css', ie : false },
{ elem : 'css', url : 'my-css', ie : true }
],
content : 'Page content'
}
```
After:
```
{
block : 'page',
head : [
{
elem : 'conditional-comment',
condition : '! IE',
content : { elem : 'css', url : 'my-css.css' }
},
{
elem : 'conditional-comment',
condition : '> IE 8',
content : { elem : 'css', url : 'my-css.ie.css' }
}
// and so on for needed IE versions
],
content : 'Page content'
}
```
Issue: [#379](https://github.com/bem/bem-core/issues/379).
## 3.0.0
To migrate to version 3.0.0, review the [history of changes](https://en.bem.info/libs/bem-core/v3/changelog/#300).
## 2.0.0
To migrate to version 2.0.0, review the [history of changes](https://en.bem.info/libs/bem-core/v2/changelog/#200).
## 1.0.0
For version 1.0.0, migrating requires switching from using [bem-bl](https://github.com/bem/bem-bl/) to using [bem-core](https://github.com/bem/bem-core/).
### Modules
The entire code is now written in terms of the modular system https://github.com/ymaps/modules.
All dependencies must be explicitly stated in the code. Minimize or eliminate use of global variables, if possible.
Example:
```js
modules.define(
'my-module', // module name
['module-from-library', 'my-another-module'], // module dependencies
function(provide, moduleFromLibrary, myAnotherModule) { // module declaration, called when all dependencies are resolved
// module representation
provide({
myModuleMethod : function() {}
});
});
```
TODO: Add information about the build process (usage of special technologies for JS and instructions for custom builders).
### jQuery and jQuery plugins
jQuery is represented by a `jquery` wrapper module that uses the global jQuery object if it already exists on the page, or loads it otherwise.
jQuery is now used only for operations directly related to the DOM (searching for elements, binding listeners to events, setting and getting attribute values, and so on).
All other operations have corresponding modules that provide the same functionality without depending on jQuery:
* The `objects` module for operating on objects (with the `extend`, `isEmpty`, and `each` methods).
* The `functions` module for operating on functions (with the `isFunction` and `noop` methods).
In addition, all the jQuery plugins that aren't directly related to jQuery (`$.observable`, `$.inherit`, `$.cookie`, `$.identify`, `$.throttle`) are now modules:
* The `events` module replaces `$.observable` for working with events. It provides the "classes" `EventsEmitter` and `Event`.
* The `inherit` module instead of `$.inherit` for working with "classes" and inheritance.
* The `cookie` module instead of `$.cookie`.
* The `identify` module instead of `$.identify`.
* The `functions__throttle` and `functions__debounce` modules instead of `$.throttle` and `$.debounce`.
Before:
```js
// block code
$.throttle()
// block code
```
After:
```js
module.define('my-module', ['functions__throttle'], function(provide, throttle) {
// module code
throttle()
// module code
});
```
### BEM.DOM blocks
#### Declaration
Instead of a declaration via BEM.DOM.decl, you need to extend the `i-bem__dom` module.
Before:
```js
BEM.DOM.decl('block', /* ... */);
```
After:
```js
modules.define('i-bem__dom', function(provide, BEMDOM) {
BEMDOM.decl('block', /* ... */);
provide(BEMDOM);
});
```
#### Constructor
You must use full notation for the handler for setting the `js` modifier to `inited`.
Before:
```js
onSetMod : {
js : function() {
// constructor code
}
}
```
After:
```js
onSetMod : {
'js' : {
'inited' : function() {
// constructor code
}
}
}
```
#### Desctructor
Instead of the `destruct` method, you need to use the handler for setting the `js` modifier to an empty value (remove the modifier).
You no longer need to call `__base` in order to run the base destructor defined in `i-bem__dom` on blocks.
Before:
```js
destruct : function() {
this.__base.apply(this, arguments);
// destructor code
}
```
After:
```js
onSetMod : {
js : {
'' : function() {
// destructor code
}
}
}
```
#### `changeThis` method
Instead of the `changeThis` method, use either the corresponding parameter, or the native `bind` method if there isn't a parameter.
Before:
```js
// block code
obj.on('event', this.changeThis(this._method));
// block code
```
After:
```js
obj.on('event', this._method.bind(this));
// or better
obj.on('event', this._method, this);
```
#### `afterCurrentEvent` method
Instead of the `afterCurrentEvent` method, use the `nextTick` method, which guarantees that the block still exists during the callback (if the block has already been destroyed by this time, the callback isn't executed).
Before:
```js
BEM.DOM.decl('block', {
method : function() {
this.afterCurrentEvent(function() {
/* ... */
})
}
});
```
After:
```js
modules.define('i-bem__dom', function(provide, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
this.nextTick(function() {
/* ... */
});
}
});
});
```
#### `findElem` method
The context for finding an element is no longer set as a string. Instead, pass a jQuery object.
Before:
```js
var nestedElem = this.findElem('parent-elem', 'nested-elem');
```
After:
```js
var nestedElem = this.findElem(this.findElem('parent-elem'), 'nested-elem'),
oneMoreElem = this.findElem(this.elem('another-elem'), 'nested-elem');
```
#### `liveBindTo` method
The `liveBindTo` method no longer supports the `elemName` field for passing the element name. Use the `elem` field instead.
#### Access to a DOM element in an event handler
A DOM element that had an event handler bound to it is now accessed as `$(e.currentTarget)` instead of `e.data.domElem`.
Before:
```js
onClick : function(e) {
e.data.domElem.attr(/* ... */);
}
```
After:
```js
onClick : function(e) {
$(e.currentTarget).attr(/* ... */);
}
```
#### Channels
Channels are no longer an integral part of BEM. Now they are separate `events__channels` modules.
Before:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('channel-name').on(/* ... */);
}
});
```
After:
```js
modules.define('i-bem__dom', ['events__channels'], function(provide, channels, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
channels('channel-name').on(/* ... */);
}
});
});
```
#### The `i-system` block and the `sys` channel for the `tick`, `idle`, and `wakeup` events
This block and channel no longer exist. They have been replaced with separate modules: `tick` with the "tick" event, and `idle` with the "idle" and "wakeup" events.
Before:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('sys').on('tick', /* ... */);
}
});
```
After:
```js
modules.define('i-bem__dom', ['tick'], function(provide, tick, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
tick.on('tick', /* ... */);
}
});
});
```
Before:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('sys').on('wakeup', /* ... */);
}
});
```
After:
```js
modules.define('i-bem__dom', ['idle'], function(provide, idle, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
idle.on('wakeup', /* ... */);
}
});
});
```
### BEM blocks
BEM blocks that were used as storage for some methods but that didn't use the BEM methodology in any way can now be written as modules.
Before:
```js
BEM.decl('i-router', {
route : function() { /* ... */ }
});
```
After:
```js
modules.define('router', function(provide) {
provide({
route : function() { /* ... */ }
});
});
```
If for some reason you need BEM blocks (not BEM.DOM blocks), you can declare them by extending the `i-bem` module.
Before:
```js
BEM.decl('my-block', { /* ... */ });
```
After:
```js
modules.define('i-bem', function(provide, BEM) {
BEM.decl('my-block', { /* ... */ });
provide(BEM);
});
```
#### Refactoring using the `b-spin` block example
Before:
```js
BEM.DOM.decl('b-spin', {
onSetMod : {
'js' : function() {
this._size = this.getMod('size') || /[\d]+/.exec(this.getMod('theme'))[0];
this._bgProp = 'background-position';
this._posPrefix = '0 -';
if (this.elem('icon').css('background-position-y')) { /* In IE, you can't get the background-position property. You can only get background-position-y, so use this workaround */
this._bgProp = 'background-position-y';
this._posPrefix = '-';
}
this._curFrame = 0;
this.hasMod('progress') && this.channel('sys').on('tick', this._onTick, this);
},
'progress' : {
'yes' : function() {
this.channel('sys').on('tick', this._onTick, this);
},
'' : function() {
this.channel('sys').un('tick', this._onTick, this);
}
}
},
_onTick: function(){
var y = ++this._curFrame * this._size;
(y >= this._size * 36) && (this._curFrame = y = 0);
this.elem('icon').css(this._bgProp, this._posPrefix + y +'px');
},
destruct : function() {
this.channel('sys').un('tick', this._onTick, this);
this.__base.apply(this, arguments);
}
});
```
After:
```js
modules.define(
'i-bem__dom',
['tick'],
function(provide, tick, BEMDOM) {
var FRAME_COUNT = 36;
BEMDOM.decl('b-spin', {
onSetMod : {
'js' : {
'inited' : function() { // constructor
var hasBackgroundPositionY = !!this.elem('icon').css('background-position-y')); /* In IE we can't get the background-position property, only background-position-y */
this._bgProp = hasBackgroundPositionY? 'background-position-y' : 'background-position';
this._posPrefix = hasBackgroundPositionY? '-' : '0 -';
this._curFrame = 0;
this._size = Number(this.getMod('size') || /[\d]+/.exec(this.getMod('theme'))[0]);
this.hasMod('progress') && this._bindToTick();
},
'' : function() { // destructor
this._unbindFromTick();
}
},
'progress' : {
'true' : function() {
this._bindToTick();
},
'' : function() {
this._unbindFromTick();
}
}
},
_bindToTick : function() {
tick.on('tick', this._onTick, this);
},
_unbindFromTick : function() {
tick.un('tick', this._onTick, this);
},
_onTick : function() {
var offset;
this._curFrame++ >= FRAME_COUNT?
offset = this._curFrame * this._size :
this._curFrame = offset = 0;
this.elem('icon').css(this._bgProp, this._posPrefix + offset + 'px');
}
});
provide(BEMDOM);
});
```
================================================
FILE: MIGRATION.ru.md
================================================
# Миграция
## 5.0.0
### ym → ES-модули
Модульная система `ym` (`modules.define`/`modules.require`) заменена на нативные ES-модули.
Было:
```js
modules.define('my-block', ['i-bem-dom', 'events'], function(provide, bemDom, events) {
provide(bemDom.declBlock(this.name, { /* ... */ }));
});
```
Стало:
```js
import bemDom from 'bem:i-bem-dom';
import events from 'bem:events';
export default bemDom.declBlock('my-block', { /* ... */ });
```
Все `bem:*` импорты разрешаются на этапе сборки плагином `vite-plugin-bem-levels` в реальные пути файлов с учётом приоритетов уровней для конкретной платформы.
### Переопределения модулей
Переопределения модулей, которые ранее использовали `modules.define` с колбэком, получающим предыдущее значение модуля, теперь обрабатываются через barrel-файлы, генерируемые Vite-плагином.
Было (переопределение ym):
```js
modules.define('jquery', function(provide, $) {
$.event.special.pointerclick = { /* ... */ };
provide($);
});
```
Стало (side-effect импорт в barrel-файле):
```js
// Barrel-файл автоматически сгенерирован vite-plugin-bem-levels:
import $ from '../../common.blocks/jquery/jquery.js';
import '../../common.blocks/jquery/__event/_type/jquery__event_type_pointerclick.js';
export default $;
```
### jQuery 3 → 4
Peer-зависимость `jquery` теперь `^4.0.0`.
Основные несовместимые изменения в jQuery 4:
- `$.unique()` удалён. Используйте `$.uniqueSort()`.
- Ряд устаревших методов удалён. См. [руководство по обновлению jQuery 4.0](https://jquery.com/upgrade-guide/4.0/).
### vow → нативный Promise
Зависимость `vow` удалена. Весь асинхронный код теперь использует нативный `Promise`.
Было:
```js
var vow = require('vow');
var promise = vow.resolve(value);
```
Стало:
```js
const promise = Promise.resolve(value);
```
### Система сборки: ENB → Vite
Весь инструментарий ENB заменён на Vite.
Было:
```bash
./node_modules/.bin/enb make
```
Стало:
```bash
npm run build # обе платформы
npm run build:desktop # только desktop
npm run build:touch # только touch
```
Конфигурация Vite находится в `build/vite.config.js`. Кастомный плагин `vite-plugin-bem-levels` в `build/plugins/` обеспечивает сканирование BEM-уровней и разрешение модулей.
### Node.js 20+
Минимальная поддерживаемая версия Node.js — 20 (было 8). Обновите `.nvmrc` или конфигурацию CI.
### Линтинг: jshint/jscs → ESLint 10
Замените кастомные `.jshintrc` или `.jscs.json` правила на flat-конфигурацию ESLint (`eslint.config.js`).
### Тестирование
- **Серверные тесты**: `mocha`/`chai` заменены на `node:test`/`node:assert`.
- **Браузерные тесты**: `mocha-phantomjs` заменён на Playwright. Запуск: `npm run test:browser`.
- **Все тесты**: `npm run test:all` запускает серверные и браузерные тесты.
### CI/CD: Travis → GitHub Actions
Замените `.travis.yml` на `.github/workflows/ci.yml`. Новый CI запускает задачи lint, test, test:browser и build.
### Git-хуки: git-hooks → husky
Замените `.githooks/` на конфигурацию husky. Скрипт `prepare` в `package.json` автоматически настраивает husky при `npm install`.
## 4.0.0
### Изменения в блоке `i-bem`
#### Отдельный блок `i-bem-dom`
Элемент `dom` блока `i-bem` был перенесён в отдельный блок `i-bem-dom`.
Было:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
/* ... */
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
/* ... */
});
```
Блоки `i-bem` и `i-bem-dom` больше не являются классами, представляя собой модули с методами для декларации
БЭМ-сущностей, ссылками на классы БЭМ-сущностей и некоторыми дополнительными хелперами. Эти методы больше не являются методами класса для соответсвующих блоков.
Задача: [#413](https://github.com/bem/bem-core/issues/413).
#### Декларация
#### Декларация блока
Для декларации блока, вместо метода `decl()`, следует использовать метод `declBlock()`.
Было:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }));
});
```
#### Декларация модификатора
Для декларации модификатора, вместо статического метода `decl()`, следует использовать статический метод `declMod()`.
Было:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'my-val' }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : 'myVal' }, { /* ... */ }));
});
```
#### Декларация булевого модификатора
Было:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'true' }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod' }, { /* ... */ }));
});
```
Задача: [#1374](https://github.com/bem/bem-core/issues/1374).
#### Декларация для модификатора с любым значением
Было:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ modName : 'my-mod' }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : '*' }, { /* ... */ }));
});
```
Задача: [#1376](https://github.com/bem/bem-core/pull/1376).
#### Доопределение блока
Вместо метода `decl()` класса блока следует использовать метод `declBlock()` модуля `i-bem-dom`.
Было:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.decl({ /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom, MyDomBlock) {
provide(bemDom.declBlock(MyDomBlock, { /* ... */ }));
});
```
#### Декларация наследуемого блока
Было:
```js
modules.define('my-dom-block', ['i-bem__dom', 'my-base-dom-block'], function(provide, BEMDOM, MyBaseDomBlock) {
provide(BEMDOM.decl({ block : this.name, baseBlock : MyBaseDomBlock }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom', 'my-base-dom-block'], function(provide, bemDom, MyBaseDomBlock) {
provide(bemDom.declBlock(this.name, MyBaseDomBlock, { /* ... */ }));
});
```
#### Декларация миксина
Метод `declMix` переименован в `declMixin`, чтобы отделить понятие
[миксов нескольких БЭМ-сущностей на одном DOM-узле](https://ru.bem.info/methodology/key-concepts/#Микс) от миксинов на уровне JS.
Было:
```js
modules.define('my-mix-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.declMix(this.name, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-mixin-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declMixin({ /* ... */ }));
});
```
#### Примешивание миксина
Было:
```js
modules.define('my-dom-block', ['i-bem__dom', 'my-mix-1', 'my-mix-2'], function(provide, BEMDOM) {
provide(BEMDOM.decl({ block : this.name, baseMix : ['my-mix-1', 'my-mix-2']}, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom', 'my-mixin-1', 'my-mixin-2'], function(provide, bemDom, MyMixin1, MyMixin2) {
provide(bemDom.declBlock(this.name, [MyMixin1, MyMixin2], { /* ... */ }));
});
```
#### Триггеры для изменения модификаторов
При декларации определённого модификатора (например, `_my-mod_my-val`) невозможно было задекларировать поведение
на удаление этого модификатора. Приходилось делать две декларации.
Было:
```js
// my-dom-block_my-mod_my-val.js
modules.define('my-dom-block', function(provide, MyDomBlock) {
MyDomBlock.decl({
onSetMod : {
'my-mod' : {
'' : function() { /* ... */ } // декларация для удаления модификатора _my-mod_my-val
}
}
});
provide(MyDomBlock.decl({ modName : 'my-mod', modVal : 'my-val' }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block', function(provide, MyDomBlock) {
provide(MyDomBlock.declMod({ modName : 'my-mod', modVal : 'my-val' }, {
onSetMod : {
'mod1' : {
'' : function() { /* ... */ } // декларация для удаления модификатора _my-mod_my-val
}
}
}));
});
```
Задача: [#1025](https://github.com/bem/bem-core/issues/1025).
Появился сокращённый синтаксис для декларации поведения на изменение модификатора.
Было:
```js
onSetMod : {
'my-mod' : {
'*' : function(modName, modVal, prevModVal) {
if(prevModVal === 'my-val') {
/* ... */ // декларация для изменения _my-mod_my-val в любое другое значение
}
}
}
}
```
Стало:
```js
onSetMod : {
'my-mod' : {
'~my-val' : function() { /* ... */ } // декларация для изменения значения my-mod из my-val в любое другое значение
}
}
}
```
Было:
```js
onSetMod : {
'my-mod' : {
'*' : function(modName, modVal) {
if(modVal !== 'my-val') {
/* ... */ // декларация для изменения my-mod в любое значение, кроме my-val
}
}
}
}
```
Стало:
```js
onSetMod : {
'my-mod' : {
'!my-val' : function() { /* ... */ } // декларация для изменения my-mod в любое значение, кроме my-val
}
}
}
```
Задача: [#1072](https://github.com/bem/bem-core/issues/1072).
#### Ленивая инициализация
Функциональность поля `live` была разделена на две части: поле `lazyInit` и метод `onInit()`.
Было:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : true
}));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
lazyInit : true
}));
});
```
Было:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
/* ... */
}
}));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
lazyInit : true,
onInit : function() {
/* ... */
}
}));
});
```
Было:
```js
modules.define('my-dom-block', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
/* ... */
return false;
}
}));
});
```
Стало:
```js
modules.define('my-dom-block', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
onInit : function() {
/* ... */
}
}));
});
```
Было:
```js
{
block : 'b1',
js : { live : false }
}
```
Стало:
```js
{
block : 'b1',
js : { lazyInit : false }
}
```
Задача: [#877](https://github.com/bem/bem-core/issues/877).
#### Экземпляры для элементов
Удалены элемент `elem-instances` блока `i-bem` и модификатор `elem-instances` элемента `dom` блока `i-bem`.
Теперь соответствующая функциональность является частью `i-bem` и `i-bem-dom`.
Было:
```js
modules.define('my-dom-block__my-elem', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM.decl({ block : 'my-dom-block', elem : 'my-elem' }, { /* ... */ }));
});
```
Стало:
```js
modules.define('my-dom-block__my-elem', ['i-bem-dom'], function(provide, bemDom) {
provide(bemDom.declElem('my-dom-block', 'my-elem', { /* ... */ }));
});
```
Теперь метод `_elem(elemName)` экземпляра блока (бывший `elem(elemName)`) возвращает не jQuery-объект со всеми элементами
с именем `elemName`, а экземпляр класса элемента.
Для того, чтобы получить коллекцию экземпляров класса элемента, используйте метод `_elems()`.
Теперь кэш для элементов с JS-реализацией найденных через `_elem()` и `_elems()` инвалидируется автоматически при DOM модификациях.
Задача: [#1352](https://github.com/bem/bem-core/issues/1352).
Когда эти методы используются для элементов без JS-реализации необходимо использовать `_dropElemCache()` при динамическом обновлении DOM.
Не забудьте включить поддержку экземплятор для элементов в шаблонизаторе.
Опция [elemJsInstances](https://github.com/bem/bem-xjst/blob/master/docs/ru/3-api.md#%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%BA%D0%B0-js-%D1%8D%D0%BA%D0%B7%D0%B5%D0%BC%D0%BF%D0%BB%D1%8F%D1%80%D0%BE%D0%B2-%D0%B4%D0%BB%D1%8F-%D1%8D%D0%BB%D0%B5%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2-bem-core-v4) для `bem-xjst` или [jsElem](https://github.com/bem/bh#jselem) для `BH`.
##### Cпособы взаимодействия с элементами
Было:
```js
this.setMod(this.elem('my-elem'), 'my-mod', 'my-val');
```
Стало:
```js
this._elem('my-elem').setMod('my-mod', 'my-val');
```
Аналогично для методов `getMod()`, `hasMod()`, `toggleMod()`, `delMod()`.
##### Удалённые методы и поля
Из API блока удалены методы: `elemify()`, `elemParams()` и поле `onElemSetMod`. Соответствующая
им функциональность выражается через экземпляры элементов .
См. также изменения про [методы поиска](#Методы-поиска).
Задача: [#581](https://github.com/bem/bem-core/issues/581).
#### Методы поиска
Переименованы следующие методы:
- `findBlockInside()` в `findChildBlock()`
- `findBlocksInside()` в `findChildBlocks()`
- `findBlockOutside()` в `findParentBlock()`
- `findBlocksOutside()` в `findParentBlocks()`
- `findBlockOn()` в `findMixedBlock()`
- `findBlocksOn()` в `findMixedBlocks()`
Из этих методов удален опциональный первый параметр про элемент.
Добавлены методы: `findChildElem()`, `findChildElems()`, `findParentElem()`, `findParentElems()`, `findMixedElem()`, `findMixedElems()`.
Было:
```js
this.findBlockInside(this.elem('my-elem'), 'my-block-2');
```
Стало:
```js
this.findChildElem('my-elem').findChildBlock(MyBlock2);
```
Удалены методы: `findElem()`, `closestElem()`, вместо них следует использовать методы `findChildElem()`
и `findParentElem()`, соответсвенно.
Методы `findChildBlocks()`, `findParentBlocks()`, `findMixedBlocks()`, `findChildElems()`, `findParentElems()`,
`findMixedElems()` возвращают [коллекции БЭМ-сущностей](#Коллекции).
Методы `findChildElem()` и `findChildElems()` (в отличие от предыдущего аналога `findElem`) не выполняют поиск на собственных DOM-узлах экземпляра.
Было:
```js
this.findElem('my-elem');
```
Стало:
```js
this.findChildElems('my-elem').concat(this.findMixedElems('my-elem'));
```
Но рекомендуется обратить внимание, действительно ли необходимы оба поиска:
в большинстве случаев достаточно использовать или `this.findChildElems('my-elem')` или `this.findMixedElems('my-elem')`.
##### Проверка вложенности
Вместо удаленного метода `containsDomElem()`, следует использовать метод `containsEntity()`.
Было:
```js
this.containsDomElem(someElem);
```
Стало:
```js
this.containsEntity(someElem);
```
#### Коллекции
Функциональность элемента `collection` блока `i-bem` перестала быть опциональной.
Все методы возвращавшие массив БЭМ-сущностей, теперь возвращают коллекции.
Было:
```js
this.findBlocksInside('my-block-2')[0].setMod('my-mod', 'my-val');
```
Стало:
```js
this.findChildBlocks(MyBlock2).get(0).setMod('my-mod', 'my-val');
```
Было:
```js
this.findBlocksInside('my-block-2').forEach(function(myBlock2) {
return myBlock2.setMod('my-mod', 'my-val');
});
```
Стало:
```js
this.findChildBlocks(MyBlock2).setMod('my-mod', 'my-val');
```
Задача: [#582](https://github.com/bem/bem-core/issues/582).
#### События
API работы с событиями значильно упрощено. Удалены методы экземпляра блока: `on()`, `un()`, `once()`, `bindTo()`,
`unbindFrom()`, `bindToDoc()`, `bindToWin()`, `unbindFromDoc()`, `unbindFromWin()` и методы класса: `liveBindTo()`,
`liveUnbindFrom()`, `on()`, `un()`, `once()`, `liveInitOnBlockEvent()`, `liveInitOnBlockInsideEvent()`.
Вместо них добавлены методы `_domEvents()` и `_events()`, возвращающие экземпляр класса менеджера событий, с методами
`on()`, `un()` и `once()`;
##### DOM-события на экземплярах
Было:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindTo('click', this._onClick);
}
}
}
});
```
Стало:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents().on('click', this._onClick);
}
}
}
});
```
Было:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindToDoc('click', this._onDocClick);
}
}
}
});
```
Стало:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents(bemDom.doc).on('click', this._onDocClick);
}
}
}
});
```
Было:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.bindToWin('resize', this._onWinResize);
}
}
}
});
```
Стало:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._domEvents(bemDom.win).on('resize', this._onWinResize);
}
}
}
});
```
##### Ссылка на экземпляр
Если событие произошло на БЭМ-экземпляре, в объект события будет добавлено поле, ссылающееся на экземпляр:
```js
this._domEvents('my-elem').on('click', function(e) {
e.bemTarget // ссылается на экземпляр `my-elem`
});
```
##### БЭМ-события на экземплярах
Было:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this.findBlockOutside('my-block-2').on('my-event', this._onMyBlock2MyEvent, this);
},
'' : function() {
this.findBlockOutside('my-block-2').un('my-event', this._onMyBlock2MyEvent, this);
}
}
}
});
```
Стало:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._events(this.findParentBlock('my-block-2')).on('my-event', this._onMyBlock2MyEvent);
}
}
}
});
```
Следует обратить внимание, что теперь, отписка от событий происходит автоматически во время уничтожения экземпляра.
##### Делегированные DOM-события
Было:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveBindTo('click', this.prototype._onClick);
}
});
```
Стало:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._domEvents().on('click', this.prototype._onClick);
}
});
```
Было:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveBindTo('my-elem', 'click', this.prototype._onMyElemClick);
}
});
```
Стало:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._domEvents('my-elem').on('click', this.prototype._onMyElemClick);
}
});
```
##### Делегированные БЭМ-события
Было:
```js
BEMDOM.decl('my-block', { /* ... */ }, {
live : function() {
this.liveInitOnBlockInsideEvent('my-event', 'my-block-2', this.prototype._onMyBlock2MyEvent);
}
});
```
Стало:
```js
bemDom.declBlock('my-block', { /* ... */ }, {
onInit : function() {
this._events(MyBlock2).on('my-event', this.prototype._onMyBlock2MyEvent);
}
});
```
Следует обратить внимание, что параметр с функцией обработчиком события теперь обязательный.
Было:
```js
modules.define('my-block', ['i-bem__dom', 'my-block-2'], function(provide, BEMDOM) {
provide(BEMDOM.decl(this.name, { /* ... */ }, {
live : function() {
this.liveInitOnBlockInsideEvent('my-event', 'my-block-2');
}
}));
});
```
Стало:
```js
modules.define('my-block', ['i-bem-dom', 'my-block-2', 'functions'], function(provide, bemDom, MyBlock2, functions) {
provide(bemDom.declBlock(this.name, { /* ... */ }, {
onInit : function() {
this._events(MyBlock2).on('my-event', functions.noop);
}
}));
});
```
Было:
```js
BEMDOM.decl('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
MyBlock2.on(this.domElem, 'my-event', this._onMyBlock2MyEvent, this);
},
'' : function() {
MyBlock2.un(this.domElem, 'my-event', this._onMyBlock2MyEvent, this);
}
}
}
});
```
Стало:
```js
bemDom.declBlock('my-block', {
onSetMod : {
'js' : {
'inited' : function() {
this._events(MyBlock2).on('my-event', this._onMyBlock2MyEvent);
}
}
}
});
```
Следует обратить внимание, что теперь, отписка от событий происходит автоматически во время уничтожения экземпляра.
#### Взаимодействие стороннего кода с БЭМ-блоками
##### Получение экземпляра БЭМ-блока
Теперь, метод jQuery-объекта `bem()` принимает БЭМ-класс, вместо строки.
Было:
```js
modules.require(['jquery', 'i-bem__dom'], function($, BEMDOM) {
var myBlock = $('.my-block').bem('my-block');
});
```
Стало:
```js
modules.require(['jquery', 'my-block'], function($, MyBlock) {
var myBlock = $('.my-block').bem(MyBlock);
});
```
##### Подписка на БЭМ-события из стороннего кода
Было:
```js
modules.require(['jquery', 'i-bem__dom'], function($, BEMDOM) {
$('.my-block').bem('my-block').on('my-event', function() { /* ... */ });
});
```
Стало:
```js
modules.require(['jquery', 'my-block', 'events__observable'], function($, MyBlock, observable) {
observable($('.my-block').bem(MyBlock))
.on('my-event', function() { /* ... */ });
});
```
При этом в зависимости нужно добавить `{ block : 'events', elem : 'observable', mods : { type : 'bem-dom' } }`.
Задача: [#394](https://github.com/bem/bem-core/issues/394).
#### Имена protected-методов начинаются с `_`
Переименованы protected-методы:
- `emit()` в `_emit()`
- `elem()` в `_elem()`
- `dropElemCache()` в `_dropElemCache()`
- `buildClass()` в `_buildClassName()`
- `buildSelector()` в `_buildSelector()`
- `getDefaultParams()` в `_getDefaultParams()`
Задачи: [#586](https://github.com/bem/bem-core/issues/586), [#1359](https://github.com/bem/bem-core/issues/1359).
#### Удалённые методы
Удалён метод `getMods()`.
### Изменения в блоке `querystring`
Элемент `querystring__uri` стал блоком `uri`. Блок `querystring` стал элементом `uri__querystring`.
Задача: [#967](https://github.com/bem/bem-core/issues/967).
### Изменения в блоке `page`
Элемент `page__css` больше не поддреживает поле `ie`. Используйте элемент `page__conditional-comment`.
Было:
```
{
block : 'page',
head : [
{ elem : 'css', url : 'my-css.css', ie : false },
{ elem : 'css', url : 'my-css', ie : true }
],
content : 'Page content'
}
```
Стало:
```
{
block : 'page',
head : [
{
elem : 'conditional-comment',
condition : '! IE',
content : { elem : 'css', url : 'my-css.css' }
},
{
elem : 'conditional-comment',
condition : '> IE 8',
content : { elem : 'css', url : 'my-css.ie.css' }
}
// и т.д. для других нужных версий IE
],
content : 'Page content'
}
```
Задача: [#379](https://github.com/bem/bem-core/issues/379).
## 3.0.0
Для миграции на версию 3.0.0 достаточно ознакомиться с [историей изменений](https://ru.bem.info/libs/bem-core/v3/changelog/#300).
## 2.0.0
Для миграции на версию 2.0.0 достаточно ознакомиться с [историей изменений](https://ru.bem.info/libs/bem-core/v2/changelog/#200).
## 1.0.0
Для версии 1.0.0 миграция подразумевается с использования [bem-bl](https://github.com/bem/bem-bl/) на использование [bem-core](https://github.com/bem/bem-core/).
### Модули
Весь код теперь пишется в терминах модульной системы https://github.com/ymaps/modules.
Все зависимости должны явно указываться в коде, обращения к глобальным объектам необходимо минимизировать, а, по возможности, и полностью исключить.
Пример:
```js
modules.define(
'my-module', // имя модуля
['module-from-library', 'my-another-module'], // зависимости модуля
function(provide, moduleFromLibrary, myAnotherModule) { // декларация модуля, вызывается когда все зависимости "разрезолвлены"
// предоставление модуля
provide({
myModuleMethod : function() {}
});
});
```
TODO: дописать про изменение сборки (использование специальных технологий для js и как быть с кастомными сборщиками)
### jQuery и jQuery-плагины
jQuery представлен модулем-оберткой `jquery`, который использует глобальный объект jQuery,
в случае если он уже присутствует на странице, в противном случае загружая его самостоятельно.
jQuery теперь используется только для операций, связанных непосредственно с DOM
(поиск элементов, подписка на события, установка/получение атрибутов элементов, и т.д.).
Для всех остальных операций написаны соответствующие модули,
предоставляющие аналогичный функционал, но, при этом, не зависящие от jQuery:
* модуль `objects` для работы с объектами (с методами `extend`, `isEmpty`, `each`)
* модуль `functions` для работы с функциями (с методами `isFunction` и `noop`)
Также, все jQuery-плагины, не связанные непосредственно с jQuery
(`$.observable`, `$.inherit`, `$.cookie`, `$.identify`, `$.throttle`) стали модулями:
* модуль `events` вместо `$.observable` для работы с событиями, предоставляющий "классы" `EventsEmitter` и `Event`
* модуль `inherit` вместо `$.inherit` для работы с "классами" и наследованием
* модуль `cookie` вместо `$.cookie`
* модуль `identify` вместо `$.identify`
* модули `functions__throttle`, `functions__debounce` вместо `$.throttle` и `$.debounce`, соответственно
Было:
```js
// код блока
$.throttle()
// код блока
```
Стало:
```js
module.define('my-module', ['functions__throttle'], function(provide, throttle) {
// код модуля
throttle()
// код модуля
});
```
### BEM.DOM-блоки
#### Декларация
Вместо декларации через BEM.DOM.decl необходимо доопределять модуль `i-bem__dom`.
Было:
```js
BEM.DOM.decl('block', /* ... */);
```
Стало:
```js
modules.define('i-bem__dom', function(provide, BEMDOM) {
BEMDOM.decl('block', /* ... */);
provide(BEMDOM);
});
```
#### Конструктор
Необходимо использовать полную нотацию для обработчика установки модификатора `js` в значение `inited`.
Было:
```js
onSetMod : {
js : function() {
// код конструктора
}
}
```
Стало:
```js
onSetMod : {
'js' : {
'inited' : function() {
// код конструктора
}
}
}
```
#### Деструктор
Вместо метода `destruct` необходимо использовать обработчик установки модификатора `js` в пустое значение (удаление модификатора).
Вызывать `__base` для того, чтобы у блоков работал базовый деструктор, определенный в `i-bem__dom`, больше не нужно.
Было:
```js
destruct : function() {
this.__base.apply(this, arguments);
// код деструктора
}
```
Стало:
```js
onSetMod : {
js : {
'' : function() {
// код деструктора
}
}
}
```
#### Метод `changeThis`
Вместо метода `changeThis` необходимо использовать либо соответствующий параметр, либо нативный метод `bind`, если такой параметр отсутствует.
Было:
```js
// код блока
obj.on('event', this.changeThis(this._method));
// код блока
```
Стало:
```js
obj.on('event', this._method.bind(this));
// или лучше
obj.on('event', this._method, this);
```
#### Метод `afterCurrentEvent`
Вместо метода `afterCurrentEvent` необходимо использовать метод `nextTick`,
который гарантирует, что блок еще существует в момент исполнения callback'а
(если блок уже уничтожен к этому моменту, то callback не исполняется).
Было:
```js
BEM.DOM.decl('block', {
method : function() {
this.afterCurrentEvent(function() {
/* ... */
});
}
});
```
Стало:
```js
modules.define('i-bem__dom', function(provide, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
this.nextTick(function() {
/* ... */
});
}
});
});
```
#### Метод `findElem`
Контекст для поиска элемента больше не задается строкой, вместо нее следует передавать jQuery-объект.
Было:
```js
var nestedElem = this.findElem('parent-elem', 'nested-elem');
```
Стало:
```js
var nestedElem = this.findElem(this.findElem('parent-elem'), 'nested-elem'),
oneMoreElem = this.findElem(this.elem('another-elem'), 'nested-elem');
```
#### Метод `liveBindTo`
Метод `liveBindTo` больше не поддерживает поле `elemName` для передачи имени элемента. Вместо него следует использовать поле `elem`.
#### Доступ до DOM-элемента в обработчике события
DOM-элемент, к которому был подвешен обработчик события теперь доступен
как `$(e.currentTarget)`вместо `e.data.domElem`.
Было:
```js
onClick : function(e) {
e.data.domElem.attr(/* ... */);
}
```
Стало:
```js
onClick : function(e) {
$(e.currentTarget).attr(/* ... */);
}
```
#### Каналы (channels)
Каналы больше не являются встроенными в BEM, теперь они являются самостоятельным модулем `events__channels`.
Было:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('channel-name').on(/* ... */);
}
});
```
Стало:
```js
modules.define('i-bem__dom', ['events__channels'], function(provide, channels, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
channels('channel-name').on(/* ... */);
}
});
});
```
#### Блок `i-system` и канал `sys` событий `tick`, `idle`, `wakeup`
Этот блок и канал перестали существовать, вместо них появились отдельные модули: `tick` с событием tick и `idle` с событиями idle и wakeup.
Было:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('sys').on('tick', /* ... */);
}
});
```
Стало:
```js
modules.define('i-bem__dom', ['tick'], function(provide, tick, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
tick.on('tick', /* ... */);
}
});
});
```
Было:
```js
BEM.DOM.decl('block', {
method : function() {
BEM.channel('sys').on('wakeup', /* ... */);
}
});
```
Стало:
```js
modules.define('i-bem__dom', ['idle'], function(provide, idle, BEMDOM) {
BEMDOM.decl('block', {
method : function() {
idle.on('wakeup', /* ... */);
}
});
});
```
### BEM-блоки
Те BEM-блоки, которые использовались как хранилище для каких-то методов, при этом никак не использующие BEM-методологию, теперь
могут быть написаны как модули.
Было:
```js
BEM.decl('i-router', {
route : function() { /* ... */ }
});
```
Стало:
```js
modules.define('router', function(provide) {
provide({
route : function() { /* ... */ }
});
});
```
Если же, по каким-то причинам, нужны именно BEM-блоки (не BEM.DOM-блоки), то их можно объявлять, доопределяя модуль `i-bem`.
Было:
```js
BEM.decl('my-block', { /* ... */ });
```
Стало:
```js
modules.define('i-bem', function(provide, BEM) {
BEM.decl('my-block', { /* ... */ });
provide(BEM);
});
```
#### Рефакторинг на примере блока `b-spin`
Было:
```js
BEM.DOM.decl('b-spin', {
onSetMod : {
'js' : function() {
this._size = this.getMod('size') || /[\d]+/.exec(this.getMod('theme'))[0];
this._bgProp = 'background-position';
this._posPrefix = '0 -';
if (this.elem('icon').css('background-position-y')) { /* В IE нельзя получить свойство background-position, только background-position-y, поэтому костыляем */
this._bgProp = 'background-position-y';
this._posPrefix = '-';
}
this._curFrame = 0;
this.hasMod('progress') && this.channel('sys').on('tick', this._onTick, this);
},
'progress' : {
'yes' : function() {
this.channel('sys').on('tick', this._onTick, this);
},
'' : function() {
this.channel('sys').un('tick', this._onTick, this);
}
}
},
_onTick: function(){
var y = ++this._curFrame * this._size;
(y >= this._size * 36) && (this._curFrame = y = 0);
this.elem('icon').css(this._bgProp, this._posPrefix + y +'px');
},
destruct : function() {
this.channel('sys').un('tick', this._onTick, this);
this.__base.apply(this, arguments);
}
});
```
Стало:
```js
modules.define(
'i-bem__dom',
['tick'],
function(provide, tick, BEMDOM) {
var FRAME_COUNT = 36;
BEMDOM.decl('b-spin', {
onSetMod : {
'js' : {
'inited' : function() { // конструктор
var hasBackgroundPositionY = !!this.elem('icon').css('background-position-y')); /* В IE нельзя получить свойство background-position, только background-position-y */
this._bgProp = hasBackgroundPositionY? 'background-position-y' : 'background-position';
this._posPrefix = hasBackgroundPositionY? '-' : '0 -';
this._curFrame = 0;
this._size = Number(this.getMod('size') || /[\d]+/.exec(this.getMod('theme'))[0]);
this.hasMod('progress') && this._bindToTick();
},
'' : function() { // деструктор
this._unbindFromTick();
}
},
'progress' : {
'true' : function() {
this._bindToTick();
},
'' : function() {
this._unbindFromTick();
}
}
},
_bindToTick : function() {
tick.on('tick', this._onTick, this);
},
_unbindFromTick : function() {
tick.un('tick', this._onTick, this);
},
_onTick : function() {
var offset;
this._curFrame++ >= FRAME_COUNT?
offset = this._curFrame * this._size :
this._curFrame = offset = 0;
this.elem('icon').css(this._bgProp, this._posPrefix + offset + 'px');
}
});
provide(BEMDOM);
});
```
================================================
FILE: PLAN.md
================================================
# Plan: Modernization of bem-core Dependencies
## Current State Analysis
### Runtime Environment
| Component | Current | Target | Status |
|-----------|---------|--------|--------|
| Node.js | 8 | 24 LTS (Krypton, v24.13.1) | 16 major versions behind |
| npm | 5-6 (lockfile v1) | 11+ (lockfile v3) | Needs regeneration |
### Dependencies — Current vs Latest
#### Production (`dependencies`)
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `ym` | ^0.1.2 | 0.1.2 | ancient | **Abandoned**. BEM module system. No updates for years. |
#### Dev Dependencies (`devDependencies`)
**Build System (ENB) — ALL ABANDONED:**
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `enb` | ^1.2.0 | 1.5.1 | 2017-11 | **Abandoned** |
| `enb-bem-techs` | ^2.2.2 | 2.2.2 | 2017-12 | **Abandoned** |
| `enb-magic-factory` | ^0.6.0 | 0.6.0 | 2018-02 | **Abandoned** |
| `enb-magic-platform` | 0.7.0 | 0.7.0 | 2016-04 | **Abandoned** |
| `enb-bemxjst` | ^8.10.2 | 8.10.6 | ~2018 | **Abandoned** |
| `enb-bemxjst-6x` | ^6.5.3 | — | — | **Abandoned** |
| `enb-bemxjst-7x` | ^7.3.1 | — | — | **Abandoned** |
| `enb-bemxjst-i18n` | 1.0.0-beta3 | — | — | **Abandoned** |
| `enb-bh` | ^1.2.1 | — | — | **Abandoned** |
| `enb-bh-i18n` | 1.0.0-beta2 | — | — | **Abandoned** |
| `enb-borschik` | ^2.8.0 | — | — | **Abandoned** |
| `enb-css` | ^1.2.2 | 1.2.2 | — | **Abandoned** |
| `enb-js` | ^1.1.1 | 1.1.1 | — | **Abandoned** |
| `enb-bem-docs` | 0.14.1 | 0.15.0 | 2019-02 | **Abandoned** |
| `enb-bem-examples` | ^1.0.2 | 1.0.2 | 2016-04 | **Abandoned** |
| `enb-bem-specs` | ^0.11.0 | 0.11.0 | 2016-12 | **Abandoned** |
| `enb-bem-tmpl-specs` | ^1.3.3 | 1.3.3 | 2018-03 | **Abandoned** |
| `enb-bem-i18n` | ^1.1.1 | — | — | **Abandoned** |
**Linting — ABANDONED/OUTDATED:**
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `jscs` | ^2.11.0 | 3.0.7 | 2016-07 | **Abandoned** (merged into ESLint) |
| `jscs-bem` | ^0.2.0 | — | — | **Abandoned** |
| `jshint` | ^2.9.1 | 2.13.6 | maintained | Functional but superseded by ESLint |
| `jshint-groups` | ^0.8.0 | — | — | **Abandoned** |
**Testing — PARTIALLY ABANDONED:**
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `mocha` | ^3.3.0 | 11.7.5 | active | 8 major versions behind |
| `mocha-phantomjs` | ^4.1.0 | 4.1.0 | 2016-06 | **Abandoned** (PhantomJS is dead) |
| `chai` | ^3.2.0 | 6.2.2 | active | 3 major versions behind; v5+ is ESM-only |
| `chai-as-promised` | ^5.1.0 | — | — | Outdated |
| `istanbul` | ^0.4.3 | 0.4.5 | 2016-08 | **Abandoned** (replaced by nyc → c8) |
**BEM Tools:**
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `bem-naming` | ^1.0.1 | 1.0.1 | — | **Abandoned** |
| `bem-walk` | 1.0.0-alpha1 | 1.0.0-1 | — | **Never left alpha** |
**Other:**
| Package | Current | Latest | Last Published | Status |
|---------|---------|--------|----------------|--------|
| `borschik` | ^1.5.3 | 3.0.0 | 2021-02 | Unmaintained |
| `bower` | ^1.7.9 | 1.8.14 | 2022-03 | **Deprecated** since 2017 |
| `git-hooks` | ^1.0.2 | 1.1.10 | — | Superseded by husky |
| `gitbook-api` | ^3.0.2 | — | — | **Abandoned** |
| `jsdoc` | ^3.5.5 | 4.0.5 | active | 1 major version behind |
| `vow` | ^0.4.17 | 0.4.20 | 2019-07 | **Abandoned** (native Promises exist) |
### Configuration Files to Replace
| File | Purpose | Modern Replacement |
|------|---------|-------------------|
| `.jshintrc` | JSHint config | `eslint.config.js` (ESLint flat config) |
| `.jscs.json` | JSCS style config | `eslint.config.js` (ESLint flat config) |
| `.jshint-groups.js` | JSHint groups config | `eslint.config.js` (ESLint flat config) |
| `.bowerrc` | Bower directory config | Remove (drop Bower) |
| `bower.json` | Bower package manifest | Remove (drop Bower) |
| `.travis.yml` | Travis CI config | `.github/workflows/ci.yml` (GitHub Actions) |
| `.enb/` (entire dir) | ENB build config | New build system config |
| `.githooks/pre-commit/lint` | Pre-commit hook | `.husky/pre-commit` |
### CI/CD
| Component | Current | Target |
|-----------|---------|--------|
| CI system | Travis CI | GitHub Actions |
| Coverage | Istanbul + Coveralls | c8 + Coveralls (or Codecov) |
| Node.js in CI | 8 | 24 |
---
## Implementation Plan
### Phase 0: Preparation
1. Create feature branch `claude/update-dependencies-fWO1e`
2. Verify project builds and tests in current state (baseline)
### Phase 1: Node.js & npm Modernization
1. Add `.nvmrc` with `24`
2. Add `engines` field to `package.json`: `"node": ">=24"`, `"npm": ">=11"`
3. Delete `package-lock.json` (will regenerate with lockfile v3)
### Phase 2: Remove Abandoned/Deprecated Tools
1. **Remove Bower**: delete `bower.json`, `.bowerrc`, remove `bower i` from scripts
2. **Remove JSCS**: delete `.jscs.json`, uninstall `jscs`, `jscs-bem`
3. **Remove JSHint**: delete `.jshintrc`, `.jshint-groups.js`, uninstall `jshint`, `jshint-groups`
4. **Remove Istanbul**: uninstall `istanbul`
5. **Remove mocha-phantomjs**: uninstall `mocha-phantomjs`
6. **Remove gitbook-api**: uninstall `gitbook-api`
7. **Remove git-hooks**: delete `.githooks/` directory, uninstall `git-hooks`
### Phase 3: Linting — Migrate to ESLint 10
1. Install `eslint@^10.0.1`
2. Create `eslint.config.js` (flat config, required for ESLint 10) migrating rules from:
- `.jshintrc` rules → ESLint equivalents
- `.jscs.json` BEM preset rules → ESLint equivalents
- `.jshint-groups.js` file-group-specific overrides → ESLint flat config overrides
3. Support file extensions: `.js`, `.bemtree`, `.bemhtml`
4. Update `package.json` `lint` script: `"lint": "eslint ."`
5. Delete old config files: `.jshintrc`, `.jscs.json`, `.jshint-groups.js`
### Phase 4: Testing Modernization
1. **Upgrade Mocha**: `mocha@^11.7.5`
2. **Upgrade Chai**: `chai@^6.2.2` (ESM-only — requires `"type": "module"` or `.mjs` for test files using it)
- Alternative: stay on `chai@^4.x` (last CJS version) if ESM migration is too invasive
3. **Replace Istanbul with c8**: install `c8@^10.1.3`
4. **Replace mocha-phantomjs with Playwright**: install `playwright@^1.58.2` and `@playwright/test`
- Browser spec tests (`.spec.js` files using `modules.define`) need adaptation for Playwright
5. Update test scripts in `package.json`
### Phase 5: Build System — ENB → Vite 6 + BEM Levels Plugin
> **This is the highest-risk, highest-effort phase.** The entire ENB ecosystem (17+ packages) is abandoned.
> **Chosen approach: Vite 6** with custom `vite-plugin-bem-levels` for BEM level resolution + barrel file generation, plus dedicated plugins for BEMHTML/BH template compilation and i18n.
#### What ENB Currently Does (to be replaced)
| ENB Function | Packages | Vite Replacement |
|---|---|---|
| BEM level scanning & file resolution | `enb-bem-techs` | `vite-plugin-bem-levels` (custom) |
| JS bundling with `ym` module system | `enb-js` + `ym` | Vite native ES modules + barrel files |
| Module redefinition (`modules.define` chains) | `ym` runtime | Platform barrel files (auto-generated) |
| CSS concatenation | `enb-css` | Vite native CSS handling |
| BEMHTML template compilation | `enb-bemxjst`, `enb-bemxjst-6x`, `enb-bemxjst-7x` | `vite-plugin-bemhtml` (custom, wraps `bem-xjst`) |
| BH template compilation | `enb-bh` | `vite-plugin-bh` (custom, wraps `bh`) |
| i18n keysets processing | `enb-bem-i18n`, `enb-bemxjst-i18n`, `enb-bh-i18n` | `vite-plugin-bem-i18n` (custom) |
| Minification (borschik) | `enb-borschik`, `borschik` | Vite built-in (esbuild/terser for JS, lightningcss for CSS) |
| HTML from BEMJSON | `enb-bemxjst`, `enb-bh` | Build script using compiled templates |
| Examples/tests/specs building | `enb-bem-examples`, `enb-bem-specs`, `enb-bem-docs`, `enb-magic-*` | Vite dev server + Playwright |
#### Phase 5.0: Preparation & Coexistence
> ENB and Vite will coexist during migration. ENB stays functional until Vite fully replaces it.
1. Install Vite 6 and core dependencies:
```
npm i -D vite@^6 @anthropic-ai/vite-plugin-bem-levels
```
(Initially `vite-plugin-bem-levels` will live in `build/plugins/` as a local module)
2. Create build directory structure:
```
build/
├── plugins/
│ ├── vite-plugin-bem-levels.js — BEM level resolution + barrel generation
│ ├── vite-plugin-bemhtml.js — BEMHTML compilation
│ ├── vite-plugin-bh.js — BH compilation
│ └── vite-plugin-bem-i18n.js — i18n keysets
├── platforms/
│ ├── desktop.js — entry point for desktop platform
│ └── touch.js — entry point for touch platform
└── vite.config.js — main Vite config
```
3. Keep `.enb/` directory intact for fallback
#### Phase 5.1: `vite-plugin-bem-levels` — Core BEM Resolution Plugin
This is the central piece. The plugin:
**5.1.1. Level scanning** — scans BEM levels like ENB does:
```js
// Configuration mirrors .enb/config/levels.js
const LEVELS = {
common: ['common.blocks'],
desktop: ['common.blocks', 'desktop.blocks'],
touch: ['common.blocks', 'touch.blocks']
};
```
**5.1.2. Virtual module resolution** — resolves `bem:*` imports:
```js
// In source code:
import $ from 'bem:jquery';
import bemDom from 'bem:i-bem-dom';
// Plugin resolves 'bem:jquery' → generated barrel file
```
**5.1.3. Barrel file generation for module redefinition chains**
For each module with redefinitions, generates a platform-specific barrel file.
Based on analysis, there are exactly **5 modules with redefinitions** (8 total redefinition instances):
| Module | Files in chain | Generated barrel |
|---|---|---|
| `jquery` | base + 4 redefinitions (3 common + 1 desktop) | `@bem/desktop/jquery.js`, `@bem/touch/jquery.js` |
| `jquery__config` | base (common) + 1 redefinition (desktop) | `@bem/desktop/jquery__config.js` |
| `ua` | alternative defs (desktop vs touch) + 1 redefinition (touch) | `@bem/desktop/ua.js`, `@bem/touch/ua.js` |
| `events__observable` | base + 1 redefinition | `@bem/common/events__observable.js` |
| `i-bem-dom__init` | base + dynamic redefinition | Special handling (see below) |
Example generated barrel for `jquery` on desktop platform:
```js
// @generated by vite-plugin-bem-levels for platform: desktop
import { $ } from '../../common.blocks/jquery/jquery.js';
// Redefinition: pointer events polyfill (mutates $.event.special)
import '../../common.blocks/jquery/__event/_type/jquery__event_type_pointernative.js';
// Redefinition: pointerclick event
import '../../common.blocks/jquery/__event/_type/jquery__event_type_pointerclick.js';
// Redefinition: pointerpress/pointerrelease events
import '../../common.blocks/jquery/__event/_type/jquery__event_type_pointerpressrelease.js';
// Redefinition: IE8 window resize fix (desktop only)
import '../../desktop.blocks/jquery/__event/_type/jquery__event_type_winresize.js';
export { $ };
```
**5.1.4. Automatic redefinition detection**
The plugin scans all `.js` files in BEM levels and detects `modules.define('name', ...)` calls:
- If a module name appears in multiple files → it's a redefinition chain
- Files are ordered by level priority (common < desktop/touch)
- Within a level, element/modifier files redefine block files
**5.1.5. deps.js → import graph**
Parse existing `.deps.js` files and generate import statements:
```js
// From: { shouldDeps: [{ block: 'events' }] }
// To: import 'bem:events';
```
This runs as a build-time code generation step, not at runtime.
#### Phase 5.2: ym → ES Modules Migration
**5.2.1. Source file transformation** — Each `modules.define` file gets an ES module equivalent:
Before (ym):
```js
modules.define('jquery', ['loader_type_js', 'jquery__config'],
function(provide, loader, cfg) {
// ...
provide(jQuery);
});
```
After (ES module):
```js
import loader from 'bem:loader_type_js';
import cfg from 'bem:jquery__config';
let jQuery;
// ... loading logic ...
export default jQuery;
```
**5.2.2. Redefinition files** — become side-effect imports or wrapper modules:
Before (ym redefinition):
```js
modules.define('jquery', function(provide, $) {
$.event.special.pointerclick = { /* ... */ };
provide($);
});
```
After (ES module side-effect):
```js
import $ from 'bem:jquery'; // gets the base jquery
$.event.special.pointerclick = { /* ... */ };
// No export needed — this is a side-effect module imported by the barrel
```
**5.2.3. Scope of ym migration**
| Category | Count | Migration complexity |
|---|---|---|
| `.vanilla.js` files (never redefined) | ~13 | Low — straightforward `export default` |
| `.js` files (base definitions, no redefinition) | ~30 | Low — `import` deps + `export default` |
| `.js` files (redefinition participants) | 14 | Medium — need barrel coordination |
| `i-bem-dom__init` dynamic redefinition | 1 | High — needs architectural redesign |
**5.2.4. `i-bem-dom__init` special case**
The dynamic `modules.define` monkey-patching in `i-bem-dom.js` (lines 1141-1158) cannot be directly expressed in ES modules. Solution:
- The Vite plugin generates the `i-bem-dom__init` barrel by scanning which blocks depend on `i-bem-dom`
- This replaces the runtime monkey-patching with build-time dependency collection
- The barrel imports all BEM DOM blocks, then calls `bemDom.init()`
#### Phase 5.3: Template Engine Plugins
**5.3.1. `vite-plugin-bemhtml`**
- Handles `.bemhtml` and `.bemhtml.js` files
- Wraps `bem-xjst` compiler (keep as dependency)
- Produces compiled JS that can be imported as ES module
- Supports HMR in dev mode
**5.3.2. `vite-plugin-bh`**
- Handles `.bh.js` files
- Wraps `bh` runtime
- Produces CommonJS-compatible bundle (BH uses `module.exports`)
#### Phase 5.4: i18n Plugin
**`vite-plugin-bem-i18n`**
- Scans `*.i18n/` directories for keysets
- Generates per-language JS modules
- Supports `{lang}` placeholder pattern from current ENB config
- Integrates with BEMHTML i18n via `bem-xjst`
#### Phase 5.5: Vite Configuration
```js
// build/vite.config.js
import { defineConfig } from 'vite';
import bemLevels from './plugins/vite-plugin-bem-levels.js';
import bemhtml from './plugins/vite-plugin-bemhtml.js';
import bh from './plugins/vite-plugin-bh.js';
import bemI18n from './plugins/vite-plugin-bem-i18n.js';
export default defineConfig(({ mode }) => {
const platform = process.env.BEM_PLATFORM || 'desktop';
return {
plugins: [
bemLevels({
platform,
levels: {
common: ['common.blocks'],
desktop: ['common.blocks', 'desktop.blocks'],
touch: ['common.blocks', 'touch.blocks']
}
}),
bemhtml(),
bh({ jsAttrName: 'data-bem', jsAttrScheme: 'json' }),
bemI18n({ langs: ['ru', 'en'] })
],
build: {
lib: {
entry: `./build/platforms/${platform}.js`,
name: 'bemCore',
formats: ['es', 'umd']
},
outDir: `dist/${platform}`,
rollupOptions: {
output: {
// Reproduce ENB dist structure:
// bem-core.js, bem-core.css, bem-core.bemhtml.js, etc.
}
}
}
};
});
```
#### Phase 5.6: dist Task Replacement
ENB `dist` task currently produces these artifacts per platform:
| Artifact | dev | min | Vite equivalent |
|---|---|---|---|
| `bem-core.css` | `.dev.css` | `.css` | Vite CSS output (dev: unminified, build: minified) |
| `bem-core.js` | `.dev.js` | `.js` | Vite JS bundle (with autoinit) |
| `bem-core.no-autoinit.js` | `.dev.no-autoinit.js` | `.no-autoinit.js` | Separate entry point without `i-bem-dom__init_auto` |
| `bem-core.bemhtml.js` | `.dev.bemhtml.js` | `.bemhtml.js` | BEMHTML-only bundle via separate entry |
| `bem-core.bh.js` | `.dev.bh.js` | `.bh.js` | BH-only bundle via separate entry |
| `bem-core.js+bemhtml.js` | `.dev.js+bemhtml.js` | `.js+bemhtml.js` | Combined bundle (JS + BEMHTML) |
| `bem-core.js+bh.js` | `.dev.js+bh.js` | `.js+bh.js` | Combined bundle (JS + BH) |
Vite handles dev/production modes natively (no borschik needed).
npm scripts:
```json
{
"build": "npm run build:desktop && npm run build:touch",
"build:desktop": "BEM_PLATFORM=desktop vite build -c build/vite.config.js",
"build:touch": "BEM_PLATFORM=touch vite build -c build/vite.config.js",
"dev": "BEM_PLATFORM=desktop vite -c build/vite.config.js"
}
```
#### Phase 5.7: specs/tests/examples Migration
1. **Browser specs** (`*.spec.js`) — Currently use `enb-bem-specs` + mocha-phantomjs:
- Migrate to Playwright (already planned in Phase 4)
- Vite dev server serves spec pages instead of ENB magic nodes
- `vite-plugin-bem-levels` resolves spec level: `libs/bem-pr/spec.blocks`
2. **Examples** (`*.examples/`) — Currently use `enb-bem-examples`:
- Vite dev server with HTML plugin serves example pages
- BEMJSON → HTML conversion done via imported compiled templates
3. **Template specs** (`tmpl-specs`) — Currently use `enb-bem-tmpl-specs`:
- Run as Node.js tests with Mocha (import compiled templates, compare output)
#### Phase 5.8: Cleanup
1. Delete `.enb/` directory entirely (17 files)
2. Uninstall all ENB packages (17 packages):
```
npm rm enb enb-bem-techs enb-magic-factory enb-magic-platform \
enb-bemxjst enb-bemxjst-6x enb-bemxjst-7x enb-bemxjst-i18n \
enb-bh enb-bh-i18n enb-borschik enb-css enb-js \
enb-bem-docs enb-bem-examples enb-bem-specs enb-bem-tmpl-specs \
enb-bem-i18n
```
3. Uninstall `borschik` (replaced by Vite built-in minification)
4. Remove `ym` from production dependencies (replaced by ES modules)
5. Remove `bem-walk` and `bem-naming` if no longer used outside ENB
6. Update `package.json` scripts to use Vite commands
#### Phase 5 Sub-Phase Execution Order
```
5.0 Preparation & coexistence setup
│
├── 5.1 vite-plugin-bem-levels (CRITICAL PATH — everything depends on this)
│ ├── 5.1.1 Level scanning
│ ├── 5.1.2 Virtual module resolution (bem:* imports)
│ ├── 5.1.3 Barrel file generation
│ ├── 5.1.4 Redefinition detection
│ └── 5.1.5 deps.js parsing
│
├── 5.2 ym → ES modules migration (can start after 5.1 is functional)
│ ├── 5.2.1 .vanilla.js files (easiest, start here)
│ ├── 5.2.2 .js base definitions
│ ├── 5.2.3 .js redefinition files
│ └── 5.2.4 i-bem-dom__init special case
│
├── 5.3 Template plugins (parallel with 5.2)
│ ├── 5.3.1 vite-plugin-bemhtml
│ └── 5.3.2 vite-plugin-bh
│
├── 5.4 i18n plugin (parallel with 5.2, 5.3)
│
├── 5.5 Vite config (after 5.1-5.4 plugins exist)
│
├── 5.6 dist replacement (after 5.5)
│ └── Verify output matches ENB dist artifacts
│
├── 5.7 specs/tests/examples (after 5.6)
│
└── 5.8 Cleanup (LAST — only after full verification)
```
#### Phase 5 Risk Mitigation
| Risk | Impact | Mitigation |
|---|---|---|
| Barrel file import order matters for side-effects | High | Plugin sorts by level priority; test thoroughly |
| `i-bem-dom__init` dynamic dep collection hard to replicate | High | Build-time scanning replaces runtime monkey-patching |
| `bem-xjst` may not work as Vite plugin | Medium | Keep as Node.js pre-compilation step if needed |
| Circular dependencies between BEM blocks | Medium | Vite handles circular ESM; add cycle detection to plugin |
| Output bundle size differs from ENB | Low | Compare sizes; adjust Rollup chunking |
| Dev server HMR with BEM redefinitions | Low | Regenerate barrels on file change; full reload as fallback |
### Phase 6: Git Hooks Modernization
1. Install `husky@^9.1.7` + `lint-staged@^16.2.7`
2. Configure `.husky/pre-commit` to run `lint-staged`
3. Configure `lint-staged` in `package.json` to run ESLint on staged files
4. Delete `.githooks/` directory
### Phase 7: CI/CD — Travis CI → GitHub Actions
1. Create `.github/workflows/ci.yml`:
- Matrix: Node.js 24
- Steps: install, lint, test
- Coverage: c8 + upload to Coveralls
2. Delete `.travis.yml`
### Phase 8: Update Remaining Packages
1. `mocha` → ^11.7.5
2. `jsdoc` → ^4.0.5
3. `vow` → replace with native `Promise` where possible; remove if fully replaced
4. `borschik` → remove (replaced by Vite built-in minification in Phase 5.8)
5. `bem-naming` → remove if only used by ENB plugins; keep if used by `vite-plugin-bem-levels`
6. `bem-walk` → remove (replaced by custom level scanning in `vite-plugin-bem-levels`)
7. `ym` → remove from production deps (replaced by ES modules in Phase 5.2)
### Phase 9: Regenerate Lock File & Validate
1. Run `npm install` to generate new `package-lock.json` (lockfile v3)
2. Run `npm run lint` — fix any ESLint issues
3. Run `npm run build` — verify Vite builds succeed for both platforms
4. Run `npm run test` — verify all tests pass
5. Compare Vite dist output with archived ENB dist output (size, functionality)
6. Run examples in Vite dev server, verify they work
---
## Risk Assessment
| Risk | Impact | Mitigation |
|------|--------|------------|
| `vite-plugin-bem-levels` barrel generation order incorrect | **CRITICAL** | Comprehensive tests comparing ENB and Vite output |
| `i-bem-dom__init` dynamic monkey-patching hard to replicate statically | **HIGH** | Build-time BEM block scanning replaces runtime logic |
| `bem-xjst` (BEMHTML compiler) integration with Vite plugin | High | Keep as pre-compilation step if direct plugin fails |
| Chai 6.x ESM-only breaks test imports | Medium | Use Chai 4.x (last CJS) or add ESM wrapper |
| mocha-phantomjs removal breaks browser tests | High | Playwright migration for spec tests |
| Circular dependencies between BEM blocks in ES modules | Medium | Vite handles circular ESM natively; add cycle detection |
| BEM-specific spec files (`modules.define`) won't work without `ym` | High | Migrate spec files to ES imports as part of Phase 5.2 |
| Output bundle size/behavior differs from ENB | Medium | Comparison testing: run both builds, diff output |
| ym → ES modules migration introduces regressions | High | Phased migration with coexistence; ENB stays as reference |
## Suggested Execution Order (by priority/safety)
1. **Phase 0** — Baseline
2. **Phase 1** — Node.js 24 (needed for Vite 6 and modern tooling)
3. **Phase 2** — Remove dead packages (safe, reduces surface)
4. **Phase 3** — ESLint migration (independent, high value)
5. **Phase 6** — Git hooks (small, independent)
6. **Phase 7** — GitHub Actions (independent)
7. **Phase 8** — Update remaining packages
8. **Phase 4** — Testing modernization (Playwright needed for Phase 5.7)
9. **Phase 5** — Build system migration to Vite (largest effort):
- 5.0 → 5.1 → 5.2 + 5.3 + 5.4 (parallel) → 5.5 → 5.6 → 5.7 → 5.8
10. **Phase 9** — Final validation (verify all Vite builds match ENB output)
================================================
FILE: README.md
================================================
# bem-core library [](https://github.com/bem/bem-core/actions/workflows/ci.yml) [](https://github.com/bem/bem-core/releases)
Documentation on `bem-core` is also available at [bem.info](https://en.bem.info/libs/bem-core/). It is also available [in Russian](https://ru.bem.info/libs/bem-core/).
## What is this?
`bem-core` is a base library for web interface development.
It provides the minimal stack for coding client-side JavaScript and templating.
## Use
Install as an npm dependency:
```shell
npm install bem-core@5
```
jQuery 4 is a peer dependency — install it alongside:
```shell
npm install jquery@^4.0.0
```
## Inside
### Levels
- `common.blocks` — suited for any devices and browsers
- `desktop.blocks` — should be used for desktop browsers
- `touch.blocks` — implement some touch-platforms specifics
### Blocks
- `i-bem` — base block with helpers for JS and HTML
- `strings` — helpers for JS-strings
- `objects` — helpers for JS-objects
- `functions` — helpers for JS-functions
- `events` — JS-events
- `uri` — helpers for work with URIs and querystrings
- `tick` — global timer
- `idle` — IDLE event
- `next-tick` — polyfill for `nextTick`/`setTimeout(0, ...)`
- `inherit` — OOP helpers
- `jquery` — jQuery
- `clearfix` — CSS clearfix trick
- `identify` — identify JS-objects
- `cookie` — helpers for work with browser cookies
- `dom` — helpers for work with DOM
- `loader` — loader for JS files
- `ua` — browser features detection
- `keyboard` — keyboard helpers
- `page` — html/head/body scaffold
### Technologies
- vanilla.js + browser.js
- bemhtml
- bemtree
## API
The autogenerated JSDoc API can be found on bem.info. E.g. JSDoc for `i-bem` is here https://en.bem.info/platform/libs/bem-core/current/desktop/i-bem/#jsdoc
## Changelog
See [CHANGELOG.md](CHANGELOG.md).
## Migration
If you are upgrading from v4, see [MIGRATION.md](MIGRATION.md).
## Development
### Working copy
1. Get the source code:
```shell
git clone -b v5 git://github.com/bem/bem-core.git
cd bem-core
```
2. Install the dependencies (requires Node.js 20+):
```shell
npm install
```
3. Run linting:
```shell
npm run lint
```
4. Run tests:
```shell
npm test # server-side tests (node:test)
npm run test:browser # browser tests (Playwright)
npm run test:all # both
```
5. Build:
```shell
npm run build # desktop + touch platforms
```
### How to contribute
Please refer to [How to contribute](/CONTRIBUTING.md) guide.
## Supported browsers
- Google Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
## License
Code and documentation copyright 2012 YANDEX LLC. Code released under the [Mozilla Public License 2.0](LICENSE.txt).
================================================
FILE: README.ru.md
================================================
# Библиотека BEM Core
`bem-core` — это библиотека с открытым кодом, которая предоставляет набор блоков для разработки веб-интерфейсов. Содержит необходимый минимум для разработки клиентского JS и HTML-шаблонов.
[](https://github.com/bem/bem-core/actions/workflows/ci.yml) [](https://github.com/bem/bem-core/releases)
> **Примечание.** Информация о библиотеке в более информативном виде доступна на [bem.info](https://ru.bem.info/libs/bem-core/). This README is also available [in English](https://en.bem.info/libs/bem-core/).
## Содержание
* [Уровни](#Уровни-переопределения)
* [Блоки](#Блоки)
* [Использование](#Использование)
* [Поддерживаемые браузеры](#Поддерживаемые-браузеры)
* [Технологии](#Технологии)
* [API](#api)
* [Разработка](#Разработка)
**Дополнительная информация**
* [История изменений](CHANGELOG.ru.md)
* [Миграция на последующие версии](MIGRATION.ru.md)
## Уровни переопределения
* `common.blocks` — поддержка всех устройств и браузеров;
* `desktop.blocks` — поддержка всех десктопных браузеров;
* `touch.blocks` — реализация специфических особенностей для touch-платформ.
## Блоки
* [i-bem](common.blocks/i-bem/i-bem.ru.md) — базовый блок с хелперами для JS и HTML;
* [i-bem-dom](common.blocks/i-bem-dom/i-bem-dom.ru.md) — базовый блок с хелперами для HTML;
* [strings](common.blocks/strings/strings.ru.md) — хелперы для JS-строк;
* [objects](common.blocks/objects/objects.ru.md) — хелперы для JS-объектов;
* [functions](common.blocks/functions/functions.ru.md) — хелперы для JS-функций;
* [events](common.blocks/events/events.ru.md) — JS-события;
* [uri](common.blocks/uri/uri.ru.md) — работа с URI и строкой запроса;
* [tick](common.blocks/tick/tick.ru.md) — глобальный таймер;
* [idle](common.blocks/idle/idle.ru.md) — IDLE-событие;
* [next-tick](common.blocks/next-tick/next-tick.ru.md) — полифил для `nextTick`/`setTimeout(0, ...)`;
* [inherit](common.blocks/inherit/inherit.ru.md) — ООП-хелперы;
* [jquery](common.blocks/jquery/jquery.ru.md) — jQuery;
* [clearfix](common.blocks/clearfix/clearfix.ru.md) — CSS-трюк clearfix;
* [identify](common.blocks/identify/identify.ru.md) — идентификация JS-объектов;
* [cookie](common.blocks/cookie/cookie.ru.md) — хелперы для работы с браузерными куками;
* [dom](common.blocks/dom/dom.ru.md) — хелперы для работы с DOM;
* [loader](common.blocks/loader/loader.ru.md) — загрузчик для JS-файлов;
* [ua](common.blocks/ua/ua.ru.md) — определение возможностей браузера;
* [uri](common.blocks/uri/uri.ru.md) — декодирование строки из формата URI;
* [keyboard](common.blocks/keyboard/keyboard.ru.md) — хелперы для работы с клавиатурой;
* [page](common.blocks/page/page.ru.md) — скелет для html/head/body.
## Использование
Установите как npm-зависимость:
```shell
npm install bem-core@5
```
jQuery 4 — peer-зависимость, установите рядом:
```shell
npm install jquery@^4.0.0
```
## Поддерживаемые браузеры
* Google Chrome (последняя версия)
* Firefox (последняя версия)
* Safari (последняя версия)
* Edge (последняя версия)
## Технологии
* vanilla.js + browser.js;
* DEPS;
* bemhtml;
* bemtree.
## API
Автосгенерированную документацию на JavaScript API блоков (JSDoc) можно посмотреть на bem.info. Например, для блока `i-bem` она доступна по ссылке https://ru.bem.info/platform/libs/bem-core/current/desktop/i-bem/#jsdoc
## Разработка
### Рабочая копия
1. Получаем исходники:
```bash
git clone -b v5 git://github.com/bem/bem-core.git
cd bem-core
```
2. Устанавливаем зависимости (требуется Node.js 20+):
```bash
npm install
```
3. Запускаем линтер:
```bash
npm run lint
```
4. Запускаем тесты:
```bash
npm test # серверные тесты (node:test)
npm run test:browser # браузерные тесты (Playwright)
npm run test:all # все тесты
```
5. Собираем:
```bash
npm run build # desktop + touch платформы
```
## Команда основной разработки
* [veged](https://github.com/veged)
* [dfilatov](https://github.com/dfilatov)
* [tadatuta](https://github.com/tadatuta)
## Лицензия
© 2012 YANDEX LLC. Код лицензирован [Mozilla Public License 2.0](LICENSE.txt).
================================================
FILE: SUMMARY.md
================================================
# Summary
* [Введение](README.ru.md)
* [Общие сведения](common.docs/i-bem-js/i-bem-js-common.ru.md)
* [Привязка JS-блоков к HTML](common.docs/i-bem-js/i-bem-js-html-binding.ru.md)
* [Декларация блока](common.docs/i-bem-js/i-bem-js-decl.ru.md)
* [Передача параметров](common.docs/i-bem-js/i-bem-js-params.ru.md)
* [Работа с DOM-деревом](common.docs/i-bem-js/i-bem-js-dom.ru.md)
* [Состояния блока](common.docs/i-bem-js/i-bem-js-states.ru.md)
* [Коллекции](common.docs/i-bem-js/i-bem-js-collections.ru.md)
* [События](common.docs/i-bem-js/i-bem-js-events.ru.md)
* [Инициализация](common.docs/i-bem-js/i-bem-js-init.ru.md)
* [Взаимодействие блоков](common.docs/i-bem-js/i-bem-js-interact.ru.md)
* [Контекст](common.docs/i-bem-js/i-bem-js-context.ru.md)
* [Что дальше?](common.docs/i-bem-js/i-bem-js-extras.ru.md)
================================================
FILE: build/platforms/desktop.js
================================================
/**
* Entry point for the desktop platform build.
*
* This file imports all BEM blocks in the correct order for the desktop platform.
* The vite-plugin-bem-levels plugin resolves `bem:*` imports to actual files
* from the level chain: common.blocks → desktop.blocks
*/
// Core utilities (no dependencies)
import 'bem:identify';
import 'bem:inherit';
import 'bem:objects';
import 'bem:functions';
import 'bem:functions__throttle';
import 'bem:functions__debounce';
import 'bem:next-tick';
import 'bem:strings__escape';
// Events
gitextract_z09_3irc/
├── .github/
│ └── workflows/
│ └── ci.yml
├── .gitignore
├── .husky/
│ └── pre-commit
├── .nvmrc
├── CHANGELOG.md
├── CHANGELOG.ru.md
├── CLA.md
├── CONTRIBUTING.md
├── CONTRIBUTING.ru.md
├── LICENSE.txt
├── MIGRATION.md
├── MIGRATION.ru.md
├── PLAN.md
├── README.md
├── README.ru.md
├── SUMMARY.md
├── build/
│ ├── platforms/
│ │ ├── desktop.js
│ │ └── touch.js
│ ├── plugins/
│ │ ├── vite-plugin-bem-levels.js
│ │ └── vite-plugin-bem-levels.test.js
│ ├── vite.config.js
│ └── vite.test.config.js
├── common.blocks/
│ ├── clearfix/
│ │ ├── clearfix.css
│ │ ├── clearfix.en.md
│ │ ├── clearfix.en.title.txt
│ │ ├── clearfix.ru.md
│ │ └── clearfix.ru.title.txt
│ ├── cookie/
│ │ ├── cookie.en.md
│ │ ├── cookie.js
│ │ ├── cookie.ru.md
│ │ └── cookie.spec.js
│ ├── dom/
│ │ ├── dom.deps.js
│ │ ├── dom.en.md
│ │ ├── dom.js
│ │ ├── dom.ru.md
│ │ └── dom.spec.js
│ ├── events/
│ │ ├── __channels/
│ │ │ ├── events__channels.deps.js
│ │ │ ├── events__channels.en.md
│ │ │ ├── events__channels.ru.md
│ │ │ └── events__channels.vanilla.js
│ │ ├── __observable/
│ │ │ ├── _type/
│ │ │ │ ├── events__observable_type_bem-dom.deps.js
│ │ │ │ ├── events__observable_type_bem-dom.js
│ │ │ │ └── events__observable_type_bem-dom.spec.js
│ │ │ ├── events__observable.deps.js
│ │ │ ├── events__observable.js
│ │ │ └── events__observable.spec.js
│ │ ├── events.deps.js
│ │ ├── events.en.md
│ │ ├── events.ru.md
│ │ ├── events.spec.js
│ │ └── events.vanilla.js
│ ├── functions/
│ │ ├── __debounce/
│ │ │ ├── functions__debounce.spec.js
│ │ │ └── functions__debounce.vanilla.js
│ │ ├── __throttle/
│ │ │ ├── functions__throttle.spec.js
│ │ │ └── functions__throttle.vanilla.js
│ │ ├── functions.en.md
│ │ ├── functions.ru.md
│ │ ├── functions.spec.js
│ │ └── functions.vanilla.js
│ ├── i-bem/
│ │ ├── __collection/
│ │ │ ├── i-bem__collection.js
│ │ │ └── i-bem__collection.spec.js
│ │ ├── __internal/
│ │ │ ├── i-bem__internal.ru.title.txt
│ │ │ ├── i-bem__internal.spec.js
│ │ │ └── i-bem__internal.vanilla.js
│ │ ├── i-bem.deps.js
│ │ ├── i-bem.en.md
│ │ ├── i-bem.en.title.txt
│ │ ├── i-bem.ru.md
│ │ ├── i-bem.ru.title.txt
│ │ ├── i-bem.spec.js
│ │ └── i-bem.vanilla.js
│ ├── i-bem-dom/
│ │ ├── __collection/
│ │ │ ├── i-bem-dom__collection.deps.js
│ │ │ ├── i-bem-dom__collection.js
│ │ │ └── i-bem-dom__collection.spec.js
│ │ ├── __events/
│ │ │ ├── _type/
│ │ │ │ ├── i-bem-dom__events_type_bem.deps.js
│ │ │ │ ├── i-bem-dom__events_type_bem.js
│ │ │ │ ├── i-bem-dom__events_type_bem.spec.js
│ │ │ │ ├── i-bem-dom__events_type_dom.deps.js
│ │ │ │ ├── i-bem-dom__events_type_dom.js
│ │ │ │ └── i-bem-dom__events_type_dom.spec.js
│ │ │ ├── i-bem-dom__events.deps.js
│ │ │ └── i-bem-dom__events.js
│ │ ├── __init/
│ │ │ ├── _auto/
│ │ │ │ ├── i-bem-dom__init_auto.deps.js
│ │ │ │ └── i-bem-dom__init_auto.js
│ │ │ ├── i-bem-dom__init.deps.js
│ │ │ ├── i-bem-dom__init.js
│ │ │ └── i-bem-dom__init.spec.js
│ │ ├── i-bem-dom.deps.js
│ │ ├── i-bem-dom.en.md
│ │ ├── i-bem-dom.js
│ │ ├── i-bem-dom.ru.md
│ │ ├── i-bem-dom.spec.js
│ │ └── i-bem-dom.tests/
│ │ ├── benchmarks.bemjson.js
│ │ └── benchmarks.blocks/
│ │ ├── b1/
│ │ │ ├── b1.deps.js
│ │ │ └── b1.js
│ │ ├── b2/
│ │ │ ├── b2.deps.js
│ │ │ └── b2.js
│ │ └── page/
│ │ ├── page.deps.js
│ │ └── page.js
│ ├── i18n/
│ │ ├── i18n.deps.js
│ │ ├── i18n.en.md
│ │ ├── i18n.i18n.js
│ │ ├── i18n.ru.md
│ │ ├── i18n.test.js
│ │ ├── i18n.tests/
│ │ │ ├── blocks/
│ │ │ │ ├── logo/
│ │ │ │ │ ├── logo.bemhtml.js
│ │ │ │ │ ├── logo.bh.js
│ │ │ │ │ ├── logo.deps.js
│ │ │ │ │ ├── logo.i18n/
│ │ │ │ │ │ ├── en.js
│ │ │ │ │ │ └── ru.js
│ │ │ │ │ ├── logo.i18n.js
│ │ │ │ │ └── logo.js
│ │ │ │ └── page/
│ │ │ │ ├── __js/
│ │ │ │ │ ├── page__js.bemhtml.js
│ │ │ │ │ └── page__js.bh.js
│ │ │ │ └── page.i18n/
│ │ │ │ ├── en.js
│ │ │ │ └── ru.js
│ │ │ └── simple.bemjson.js
│ │ └── i18n.tmpl-specs/
│ │ ├── 10-simple.bemjson.js
│ │ ├── 10-simple.html
│ │ └── blocks/
│ │ └── greeting-card/
│ │ ├── greeting-card.bemhtml.js
│ │ ├── greeting-card.bh.js
│ │ └── greeting-card.deps.js
│ ├── identify/
│ │ ├── identify.en.md
│ │ ├── identify.ru.md
│ │ ├── identify.spec.js
│ │ └── identify.vanilla.js
│ ├── idle/
│ │ ├── _start/
│ │ │ └── idle_start_auto.js
│ │ ├── idle.deps.js
│ │ ├── idle.en.md
│ │ ├── idle.js
│ │ └── idle.ru.md
│ ├── inherit/
│ │ ├── inherit.en.md
│ │ ├── inherit.ru.md
│ │ ├── inherit.spec.js
│ │ └── inherit.vanilla.js
│ ├── jquery/
│ │ ├── __config/
│ │ │ ├── jquery__config.js
│ │ │ └── jquery__config.ru.md
│ │ ├── jquery.deps.js
│ │ ├── jquery.en.md
│ │ ├── jquery.js
│ │ ├── jquery.ru.md
│ │ └── jquery.ru.title.txt
│ ├── keyboard/
│ │ ├── __codes/
│ │ │ └── keyboard__codes.js
│ │ ├── keyboard.en.md
│ │ └── keyboard.ru.md
│ ├── loader/
│ │ ├── _type/
│ │ │ ├── loader_type_bundle.js
│ │ │ ├── loader_type_js.js
│ │ │ └── loader_type_js.spec.js
│ │ ├── loader.en.md
│ │ └── loader.ru.md
│ ├── next-tick/
│ │ ├── next-tick.en.md
│ │ ├── next-tick.ru.md
│ │ ├── next-tick.spec.js
│ │ └── next-tick.vanilla.js
│ ├── objects/
│ │ ├── objects.en.md
│ │ ├── objects.ru.md
│ │ ├── objects.spec.js
│ │ └── objects.vanilla.js
│ ├── page/
│ │ ├── __css/
│ │ │ ├── page__css.bemhtml.js
│ │ │ └── page__css.bh.js
│ │ ├── __js/
│ │ │ ├── page__js.bemhtml.js
│ │ │ └── page__js.bh.js
│ │ ├── page.bemhtml.js
│ │ ├── page.bh.js
│ │ ├── page.deps.js
│ │ ├── page.en.md
│ │ ├── page.en.title.txt
│ │ ├── page.examples/
│ │ │ ├── .bem/
│ │ │ │ └── level.js
│ │ │ ├── 10-simple.bemjson.js
│ │ │ ├── 10-simple.ru.title.txt
│ │ │ ├── 10-simple.ru.wiki
│ │ │ ├── 20-doctype.bemjson.js
│ │ │ └── 20-doctype.ru.title.txt
│ │ ├── page.ru.md
│ │ ├── page.ru.title.txt
│ │ └── page.tmpl-specs/
│ │ ├── 00-empty.bemjson.js
│ │ ├── 00-empty.html
│ │ ├── 10-simple.bemjson.js
│ │ ├── 10-simple.html
│ │ ├── 20-style.bemjson.js
│ │ ├── 20-style.html
│ │ ├── 25-styles.bemjson.js
│ │ ├── 25-styles.html
│ │ ├── 30-scripts.bemjson.js
│ │ ├── 30-scripts.html
│ │ ├── 40-nonce.bemjson.js
│ │ ├── 40-nonce.html
│ │ ├── 60-x-ua-compatible.bemjson.js
│ │ ├── 60-x-ua-compatible.html
│ │ ├── 70-lang.bemjson.js
│ │ └── 70-lang.html
│ ├── strings/
│ │ ├── __escape/
│ │ │ ├── strings__escape.spec.js
│ │ │ └── strings__escape.vanilla.js
│ │ ├── strings.en.md
│ │ └── strings.ru.md
│ ├── tick/
│ │ ├── _start/
│ │ │ └── tick_start_auto.vanilla.js
│ │ ├── tick.deps.js
│ │ ├── tick.en.md
│ │ ├── tick.ru.md
│ │ ├── tick.spec.js
│ │ └── tick.vanilla.js
│ ├── ua/
│ │ ├── __svg/
│ │ │ ├── ua__svg.bemhtml.js
│ │ │ ├── ua__svg.bh.js
│ │ │ ├── ua__svg.deps.js
│ │ │ ├── ua__svg.en.title.txt
│ │ │ ├── ua__svg.ru.title.txt
│ │ │ └── ua__svg.tmpl-specs/
│ │ │ ├── 00-simple.bemjson.js
│ │ │ └── 00-simple.html
│ │ ├── ua.bemhtml.js
│ │ ├── ua.bh.js
│ │ ├── ua.en.md
│ │ ├── ua.en.title.txt
│ │ ├── ua.ru.md
│ │ ├── ua.ru.title.txt
│ │ └── ua.tmpl-specs/
│ │ ├── 00-simple.bemjson.js
│ │ └── 00-simple.html
│ └── uri/
│ ├── __querystring/
│ │ ├── uri__querystring.deps.js
│ │ ├── uri__querystring.spec.js
│ │ └── uri__querystring.vanilla.js
│ ├── uri.en.md
│ ├── uri.ru.md
│ ├── uri.spec.js
│ └── uri.vanilla.js
├── common.bundles/
│ └── index/
│ ├── blocks/
│ │ └── square/
│ │ ├── _color/
│ │ │ └── square_color_green.css
│ │ ├── square.css
│ │ ├── square.deps.js
│ │ └── square.js
│ └── index.bemjson.js
├── common.docs/
│ ├── bemjson/
│ │ ├── bemjson.en.md
│ │ └── bemjson.ru.md
│ └── i-bem-js/
│ ├── i-bem-js-collections.en.md
│ ├── i-bem-js-collections.ru.md
│ ├── i-bem-js-common.en.md
│ ├── i-bem-js-common.ru.md
│ ├── i-bem-js-context.en.md
│ ├── i-bem-js-context.ru.md
│ ├── i-bem-js-decl.en.md
│ ├── i-bem-js-decl.ru.md
│ ├── i-bem-js-dom.en.md
│ ├── i-bem-js-dom.ru.md
│ ├── i-bem-js-events.en.md
│ ├── i-bem-js-events.ru.md
│ ├── i-bem-js-extras.en.md
│ ├── i-bem-js-extras.ru.md
│ ├── i-bem-js-html-binding.en.md
│ ├── i-bem-js-html-binding.ru.md
│ ├── i-bem-js-init.en.md
│ ├── i-bem-js-init.ru.md
│ ├── i-bem-js-interact.en.md
│ ├── i-bem-js-interact.ru.md
│ ├── i-bem-js-params.en.md
│ ├── i-bem-js-params.ru.md
│ ├── i-bem-js-states.en.md
│ ├── i-bem-js-states.ru.md
│ ├── i-bem-js.en.md
│ └── i-bem-js.ru.md
├── desktop.blocks/
│ ├── jquery/
│ │ ├── __config/
│ │ │ ├── jquery__config.deps.js
│ │ │ └── jquery__config.js
│ │ └── __event/
│ │ └── _type/
│ │ ├── jquery__event_type_winresize.deps.js
│ │ └── jquery__event_type_winresize.js
│ ├── page/
│ │ ├── __conditional-comment/
│ │ │ ├── page__conditional-comment.bemhtml.js
│ │ │ ├── page__conditional-comment.bh.js
│ │ │ └── page__conditional-comment.ru.md
│ │ ├── page.deps.js
│ │ ├── page.examples/
│ │ │ ├── .bem/
│ │ │ │ └── level.js
│ │ │ ├── 40-es5-shims.bemjson.js
│ │ │ └── 40-es5-shims.ru.title.txt
│ │ ├── page.ru.md
│ │ └── page.tmpl-specs/
│ │ ├── 50-conditions.bemjson.js
│ │ ├── 50-conditions.html
│ │ ├── 60-conditional-comments.bemjson.js
│ │ ├── 60-conditional-comments.html
│ │ ├── 70-custom-x-ua-compatible.bemjson.js
│ │ └── 70-custom-x-ua-compatible.html
│ └── ua/
│ ├── ua.js
│ └── ua.ru.md
├── eslint.config.js
├── jsdoc.config.json
├── package.json
├── playwright.config.js
├── test/
│ ├── browser/
│ │ ├── bemhtml-shim.js
│ │ ├── entry.js
│ │ ├── index.html
│ │ └── modules-shim.js
│ ├── browser.spec.js
│ └── dist/
│ ├── assets/
│ │ └── test.html
│ ├── build-fixtures.js
│ ├── config.js
│ └── fixtures/
│ ├── chai.js
│ ├── desktop.html
│ ├── mocha.css
│ ├── mocha.js
│ ├── sinon-chai.js
│ ├── sinon.js
│ └── touch.html
└── touch.blocks/
├── page/
│ ├── __icon/
│ │ ├── page__icon.bemhtml.js
│ │ └── page__icon.bh.js
│ ├── page.bemhtml.js
│ ├── page.bh.js
│ ├── page.deps.js
│ ├── page.ru.md
│ └── page.tmpl-specs/
│ ├── 00-empty.html
│ ├── 10-simple.html
│ ├── 20-style.html
│ ├── 25-styles.html
│ ├── 30-scripts.html
│ ├── 40-nonce.html
│ ├── 60-x-ua-compatible.html
│ ├── 70-lang.html
│ ├── 70-zoom.bemjson.js
│ └── 70-zoom.html
└── ua/
├── __dom/
│ ├── ua__dom.deps.js
│ ├── ua__dom.js
│ └── ua__dom.ru.md
├── ua.bemhtml.js
├── ua.bh.js
├── ua.deps.js
├── ua.js
└── ua.ru.md
SYMBOL INDEX (407 symbols across 34 files)
FILE: build/plugins/vite-plugin-bem-levels.js
constant BEM_PREFIX (line 3) | const BEM_PREFIX = 'bem:'
constant VIRTUAL_PREFIX (line 4) | const VIRTUAL_PREFIX = '\0bem:'
function scanLevel (line 21) | function scanLevel(levelDir) {
function scanDirectory (line 45) | function scanDirectory(dir, modules, levelDir) {
function parseModulesDefine (line 111) | function parseModulesDefine(source) {
function parseEsModule (line 168) | function parseEsModule(source, filePath, levelDir) {
function filePathToModuleName (line 197) | function filePathToModuleName(filePath, levelDir) {
function parseDepsFile (line 214) | function parseDepsFile(filePath) {
function normalizeDeps (line 231) | function normalizeDeps(raw) {
function normalizeDep (line 261) | function normalizeDep(dep) {
function bemEntityToModuleName (line 280) | function bemEntityToModuleName(entity, contextBlock) {
function expandBemEntity (line 318) | function expandBemEntity(entity, contextBlock) {
function buildRegistry (line 395) | function buildRegistry(levels, rootDir) {
function generateBarrel (line 503) | function generateBarrel(name, entries, rootDir) {
function safeIdentifier (line 533) | function safeIdentifier(name) {
function bemLevels (line 551) | function bemLevels(options = {}) {
FILE: build/plugins/vite-plugin-bem-levels.test.js
constant ROOT (line 15) | const ROOT = resolve(import.meta.dirname, '../..');
FILE: common.blocks/cookie/cookie.js
method get (line 12) | get(name) {
method set (line 35) | set(name, val, options) {
FILE: common.blocks/dom/dom.js
constant EDITABLE_INPUT_TYPES (line 8) | const EDITABLE_INPUT_TYPES = new Set([
method contains (line 29) | contains(ctx, domElem) {
method getFocused (line 48) | getFocused() {
method containsFocus (line 58) | containsFocus(domElem) {
method isFocusable (line 67) | isFocusable(domElem) {
method isEditable (line 95) | isEditable(domElem) {
FILE: common.blocks/functions/functions.vanilla.js
method isFunction (line 12) | isFunction(obj) {
method noop (line 22) | noop() {}
FILE: common.blocks/i-bem-dom/__collection/i-bem-dom__collection.js
function collectionMapMethod (line 122) | function collectionMapMethod(collection, methodName, args) {
function buildProxyMethodForOne (line 126) | function buildProxyMethodForOne(methodName) {
function buildAggregateProxyFn (line 132) | function buildAggregateProxyFn(arrayMethodName, entityMethodName) {
function buildMapProxyFn (line 139) | function buildMapProxyFn(entityMethodName) {
function buildProxyMethodForMany (line 146) | function buildProxyMethodForMany(methodName) {
FILE: common.blocks/i-bem-dom/__collection/i-bem-dom__collection.spec.js
function getEntityIds (line 133) | function getEntityIds(entities) {
FILE: common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_bem.js
constant EVENT_PREFIX (line 11) | const EVENT_PREFIX = '__bem__',
constant MOD_CHANGE_EVENT (line 11) | const EVENT_PREFIX = '__bem__',
function wrapperFn (line 49) | function wrapperFn(fn, fnCtx, fnId) {
FILE: common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_bem.spec.js
function initDom (line 52) | function initDom(bemjson) {
function initDom (line 643) | function initDom(bemjson) {
function createDomNode (line 1009) | function createDomNode(bemjson) {
FILE: common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_dom.js
function wrapperFn (line 19) | function wrapperFn(fn) {
FILE: common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_dom.spec.js
function initDom (line 781) | function initDom(bemjson) {
function createDomNode (line 1065) | function createDomNode(bemjson) {
FILE: common.blocks/i-bem-dom/__events/i-bem-dom__events.js
method __constructor (line 25) | __constructor(params, fnWrapper, eventBuilder) {
method on (line 39) | on(e, data, fn, _fnCtx, _isOnce) {
method _bindSingle (line 58) | _bindSingle(event, origEvent, data, fn, _fnCtx, _isOnce, params) {
method once (line 94) | once(e, data, fn, _fnCtx) {
method un (line 110) | un(e, fn, _fnCtx) {
method _unbindByEvent (line 143) | _unbindByEvent(fnStorage, e) {
method __constructor (line 177) | __constructor(eventManagers) {
method __constructor (line 213) | __constructor(getEntityCls) {
method getEventManager (line 226) | getEventManager(ctx, bindCtx, bindScope) {
method _buildEventManagerParams (line 267) | _buildEventManagerParams(bindCtx, bindScope, ctxSelector, ctxCls) {
method _createEventManager (line 325) | _createEventManager(ctx, params, isInstance) {
FILE: common.blocks/i-bem-dom/i-bem-dom.js
constant BEM_CLASS_NAME (line 49) | const BEM_CLASS_NAME = 'i-bem'
constant BEM_SELECTOR (line 50) | const BEM_SELECTOR = '.' + BEM_CLASS_NAME
constant BEM_PARAMS_ATTR (line 51) | const BEM_PARAMS_ATTR = 'data-bem'
constant NAME_PATTERN (line 53) | const NAME_PATTERN = bemInternal.NAME_PATTERN
constant MOD_DELIM (line 55) | const MOD_DELIM = bemInternal.MOD_DELIM
constant ELEM_DELIM (line 56) | const ELEM_DELIM = bemInternal.ELEM_DELIM
function initEntities (line 75) | function initEntities(domElem, uniqInitId, dropElemCacheQueue) {
function initEntity (line 102) | function initEntity(entityName, domElem, params, ignoreLazyInit, callbac...
function getEntityCls (line 144) | function getEntityCls(entityName) {
function processParams (line 159) | function processParams(params, entityName, uniqInitId) {
function findDomElem (line 175) | function findDomElem(ctx, selector, excludeSelf) {
function getParams (line 187) | function getParams(domNode) {
function getEntityParams (line 202) | function getEntityParams(domNode, entityName) {
function extractParams (line 212) | function extractParams(domNode) {
function removeDomNodeFromEntity (line 222) | function removeDomNodeFromEntity(entity, domNode) {
function storeDomNodeParents (line 235) | function storeDomNodeParents(domElem) {
function dropElemCacheForCtx (line 245) | function dropElemCacheForCtx(ctx, dropElemCacheQueue) {
function buildElemKey (line 264) | function buildElemKey(elem) {
function getJqueryCollection (line 284) | function getJqueryCollection(html) {
function validateBlockParam (line 295) | function validateBlockParam(Block) {
function getEntityBase (line 311) | function getEntityBase(baseCls, entityName, base) {
function getEntityFromDom (line 923) | function getEntityFromDom(domNode, BemDomEntity) {
FILE: common.blocks/i-bem-dom/i-bem-dom.spec.js
function find (line 398) | function find() {
function find (line 406) | function find() {
function find (line 445) | function find() {
function find (line 453) | function find() {
function find (line 501) | function find() {
function find (line 509) | function find() {
function find (line 548) | function find() {
function find (line 556) | function find() {
function find (line 588) | function find() {
function find (line 596) | function find() {
function find (line 617) | function find() {
function find (line 625) | function find() {
function createDomNode (line 1840) | function createDomNode(bemjson) {
function initDom (line 1844) | function initDom(bemjson) {
function getEntityIds (line 1848) | function getEntityIds(entities) {
FILE: common.blocks/i-bem/__collection/i-bem__collection.js
method __constructor (line 14) | __constructor(entities) {
method get (line 80) | get(i) {
method filter (line 123) | filter(...args) {
method has (line 148) | has(entity) {
method find (line 158) | find(fn, ctx) {
method concat (line 168) | concat(...args) {
method size (line 179) | size() {
method toArray (line 187) | toArray() {
function buildForEachEntityMethodProxyFn (line 192) | function buildForEachEntityMethodProxyFn(methodName) {
function buildEntitiesMethodProxyFn (line 201) | function buildEntitiesMethodProxyFn(methodName) {
function buildComplexProxyFn (line 208) | function buildComplexProxyFn(arrayMethodName, entityMethodName) {
FILE: common.blocks/i-bem/__internal/i-bem__internal.vanilla.js
constant MOD_DELIM (line 10) | const MOD_DELIM = '_'
constant ELEM_DELIM (line 17) | const ELEM_DELIM = '__'
constant NAME_PATTERN (line 24) | const NAME_PATTERN = '[a-zA-Z0-9-]+'
function isSimple (line 26) | function isSimple(obj) {
function buildModPostfix (line 31) | function buildModPostfix(modName, modVal) {
function buildBlockClassName (line 40) | function buildBlockClassName(name, modName, modVal) {
function buildElemClassName (line 44) | function buildElemClassName(block, name, modName, modVal) {
method buildClassName (line 66) | buildClassName(block, elem, modName, modVal) {
method buildClassNames (line 95) | buildClassNames(block, elem, mods) {
FILE: common.blocks/i-bem/i-bem.vanilla.js
constant ELEM_DELIM (line 12) | const ELEM_DELIM = bemInternal.ELEM_DELIM
function buildModFnName (line 35) | function buildModFnName(prefix, modName, modVal) {
function buildSpecialModFn (line 52) | function buildSpecialModFn(modVal, curModFn, prevModFn, condition) {
function modFnsToProps (line 80) | function modFnsToProps(prefix, modFns, props) {
function buildCheckMod (line 109) | function buildCheckMod(modName, modVal) {
function checkMod (line 128) | function checkMod(block, modName, modVal) {
function convertModHandlersToMethods (line 137) | function convertModHandlersToMethods(props) {
function declEntity (line 146) | function declEntity(baseCls, entityName, base, props, staticProps) {
method declBlock (line 557) | declBlock(blockName, base, props, staticProps) {
method declElem (line 584) | declElem(blockName, elemName, base, props, staticProps) {
method declMixin (line 618) | declMixin(props, staticProps) {
method _runInitFns (line 627) | _runInitFns() {
FILE: common.blocks/i18n/i18n.i18n.js
function i18n (line 12) | function i18n(keyset, key, params) {
FILE: common.blocks/idle/idle.js
constant IDLE_TIMEOUT (line 9) | const IDLE_TIMEOUT = 3000,
constant USER_EVENTS (line 9) | const IDLE_TIMEOUT = 3000,
FILE: common.blocks/inherit/inherit.vanilla.js
function override (line 18) | function override(base, res, add) {
function applyMixins (line 48) | function applyMixins(mixins, res) {
function inherit (line 69) | function inherit() {
FILE: common.blocks/loader/_type/loader_type_bundle.js
constant LOADING_TIMEOUT (line 6) | const LOADING_TIMEOUT = 30000
FILE: common.blocks/objects/objects.vanilla.js
method extend (line 13) | extend(target, source) {
method isEmpty (line 32) | isEmpty(obj) {
method each (line 42) | each(obj, fn, ctx) {
FILE: common.blocks/tick/tick.vanilla.js
constant TICK_INTERVAL (line 9) | const TICK_INTERVAL = 50,
FILE: common.blocks/uri/__querystring/uri__querystring.spec.js
function test (line 53) | function test(cases) {
FILE: common.blocks/uri/__querystring/uri__querystring.vanilla.js
function addParam (line 8) | function addParam(res, name, val) {
method parse (line 18) | parse(str) {
method stringify (line 59) | stringify(obj) {
FILE: common.blocks/uri/uri.vanilla.js
function convert (line 9) | function convert(str) {
function decode (line 18) | function decode(fn, str) {
method decodeURI (line 39) | decodeURI(str) {
method decodeURIComponent (line 48) | decodeURIComponent(str) {
FILE: test/browser.spec.js
constant MAX_ALLOWED_FAILURES (line 3) | const MAX_ALLOWED_FAILURES = 0;
FILE: test/browser/bemhtml-shim.js
constant BEM_JS_CLASS (line 12) | const BEM_JS_CLASS = 'i-bem';
constant BEMHTML (line 14) | const BEMHTML = {
method apply (line 15) | apply(bemjson, ctx) {
method _render (line 26) | _render(node, ctx) {
FILE: test/browser/modules-shim.js
function createModulesShim (line 12) | function createModulesShim(preRegistered) {
FILE: test/dist/build-fixtures.js
function buildHTML (line 54) | function buildHTML(platform, specs) {
FILE: test/dist/fixtures/chai.js
function require (line 1) | function require(e){var t=require.modules[e];if(!t)throw new Error('fail...
function i (line 1) | function i(e){throw new Error('failed to find latest module of "'+e+'"')}
function i (line 1) | function i(){function e(e,i){Object.keys(i).forEach(function(r){~t.index...
function r (line 1) | function r(e,t,r){var n=i("name","message","stack","constructor","toJSON...
function i (line 1) | function i(e){var t=Object.prototype.toString.call(e);return n[t]?n[t]:n...
function r (line 1) | function r(){this.tests={}}
function i (line 1) | function i(e,t,i){return r(e,t)?!0:"date"===d(e)?o(e,t):"regexp"===d(e)?...
function r (line 1) | function r(e,t){return e===t?0!==e||1/e===1/t:e!==e&&t!==t}
function n (line 1) | function n(e,t){return d(e)===d(t)}
function o (line 1) | function o(e,t){return"date"!==d(t)?!1:r(e.getTime(),t.getTime())}
function s (line 1) | function s(e,t){return"regexp"!==d(t)?!1:r(e.toString(),t.toString())}
function a (line 1) | function a(e,t,r){return"arguments"!==d(t)?!1:(e=[].slice.call(e),t=[].s...
function c (line 1) | function c(e){var t=[];for(var i in e)t.push(i);return t}
function u (line 1) | function u(e,t){if(e.length!==t.length)return!1;for(var i=0,r=!0;i<e.len...
function h (line 1) | function h(e,t){return p.isBuffer(t)?u(e,t):!1}
function l (line 1) | function l(e){return null!==e&&void 0!==e}
function f (line 1) | function f(e,t,r){if(!l(e)||!l(t))return!1;if(e.prototype!==t.prototype)...
function n (line 1) | function n(e,t,i){s(this,"ssfi",i||arguments.callee),s(this,"object",e),...
function i (line 1) | function i(e,i){i&&x(this,"message",i),e=e.toLowerCase();var r=x(this,"o...
function r (line 1) | function r(){x(this,"contains",!0)}
function n (line 1) | function n(e,i){i&&x(this,"message",i);var r=x(this,"object"),n=!1;if("a...
function o (line 1) | function o(){var e=x(this,"object"),t=Object.prototype.toString.call(e);...
function s (line 1) | function s(e,t){t&&x(this,"message",t);var i=x(this,"object");return x(t...
function a (line 1) | function a(e,i){i&&x(this,"message",i),this.assert(t.eql(e,x(this,"objec...
function c (line 1) | function c(e,t){t&&x(this,"message",t);var i=x(this,"object");if(x(this,...
function u (line 1) | function u(e,t){t&&x(this,"message",t);var i=x(this,"object");if(x(this,...
function h (line 1) | function h(e,t){t&&x(this,"message",t);var i=x(this,"object");if(x(this,...
function l (line 1) | function l(e,t){t&&x(this,"message",t);var i=x(this,"object");if(x(this,...
function f (line 1) | function f(e,i){i&&x(this,"message",i);var r=t.getName(e);this.assert(x(...
function p (line 1) | function p(e,i){i&&x(this,"message",i);var r=x(this,"object");this.asser...
function d (line 1) | function d(){x(this,"doLength",!0)}
function b (line 1) | function b(e,t){t&&x(this,"message",t);var i=x(this,"object");new j(i,t)...
function g (line 1) | function g(e){var i,r=x(this,"object"),n=!0;if(e=e instanceof Array?e:Ar...
function v (line 1) | function v(e,i,r){r&&x(this,"message",r);var n=x(this,"object");new j(n,...
function y (line 1) | function y(e,t,i){return e.every(function(e){return i?t.some(function(t)...
function i (line 1) | function i(){function e(){return this instanceof String||this instanceof...
function i (line 1) | function i(e){var t=e.replace(/\[/g,".["),i=t.match(/(\\\.|[^.]+?)+/g);r...
function r (line 1) | function r(e,t){for(var i,r=t,n=0,o=e.length;o>n;n++){var s=e[n];r?("und...
function t (line 1) | function t(e){-1===i.indexOf(e)&&i.push(e)}
function i (line 1) | function i(e,t,i,n){var o={showHidden:t,seen:[],stylize:function(e){retu...
function r (line 1) | function r(t,i,p){if(i&&"function"==typeof i.inspect&&i.inspect!==e.insp...
function n (line 1) | function n(e,t){switch(typeof t){case"undefined":return e.stylize("undef...
function o (line 1) | function o(e){return"["+Error.prototype.toString.call(e)+"]"}
function s (line 1) | function s(e,t,i,r,n){for(var o=[],s=0,c=t.length;c>s;++s)Object.prototy...
function a (line 1) | function a(e,t,i,n,o,s){var a,c;if(t.__lookupGetter__&&(t.__lookupGetter...
function c (line 1) | function c(e,t,i){var r=0,n=e.reduce(function(e,t){return r++,t.indexOf(...
function u (line 1) | function u(e){return Array.isArray(e)||"object"==typeof e&&"[object Arra...
function h (line 1) | function h(e){return"object"==typeof e&&"[object RegExp]"===p(e)}
function l (line 1) | function l(e){return"object"==typeof e&&"[object Date]"===p(e)}
function f (line 1) | function f(e){return"object"==typeof e&&"[object Error]"===p(e)}
function p (line 1) | function p(e){return Object.prototype.toString.call(e)}
FILE: test/dist/fixtures/mocha.js
function t (line 1) | function t(e){var n=t.resolve(e),r=t.modules[n];if(!r)throw new Error('f...
function e (line 1) | function e(){for(var t=(new r).getTime();f.length&&(new r).getTime()-t<1...
function t (line 1) | function t(t){return{newPos:t.newPos,components:t.components.slice(0)}}
function e (line 1) | function e(t){for(var e=[],n=0;n<t.length;n++)t[n]&&e.push(t[n]);return e}
function n (line 1) | function n(t){var e=t;return e=e.replace(/&/g,"&"),e=e.replace(/</g,...
function i (line 1) | function i(t){return t.map(function(t){return" "+t})}
function s (line 1) | function s(t,e,n){var r=l[l.length-2],o=e===l.length-2,i=e===l.length-3&...
function r (line 1) | function r(t){return"[object Array]"=={}.toString.call(t)}
function o (line 1) | function o(){}
function n (line 1) | function n(){r.removeListener(t,n),e.apply(this,arguments)}
function r (line 1) | function r(){this.percent=0,this.size(0),this.fontSize(11),this.font("he...
function r (line 1) | function r(){}
function r (line 1) | function r(t,e){i.call(this,t,e),this.type="hook"}
function o (line 1) | function o(){}
function e (line 1) | function e(t,i){var s;for(var a in t)if("function"==typeof t[a]){var u=t...
function o (line 1) | function o(t){return __dirname+"/../images/"+t+".png"}
function s (line 1) | function s(t){t=t||{},this.files=[],this.options=t,this.grep(t.grep),thi...
function r (line 1) | function r(t){var e=/^((?:\d+)?\.?\d+) *(ms|seconds?|s|minutes?|m|hours?...
function o (line 1) | function o(t){return t>=c?Math.round(t/c)+"d":t>=l?Math.round(t/l)+"h":t...
function i (line 1) | function i(t){return s(t,c,"day")||s(t,l,"hour")||s(t,u,"minute")||s(t,a...
function s (line 1) | function s(t,e,n){return e>t?void 0:1.5*e>t?Math.floor(t/e)+" "+n:Math.c...
function o (line 1) | function o(t){var e=this.stats={suites:0,tests:0,passes:0,pending:0,fail...
function s (line 1) | function s(t,e){return t=String(t),Array(e-t.length+1).join(" ")+t}
function a (line 1) | function a(t,e){var n=l(t,"WordsWithSpace",e),r=n.split("\n");if(r.lengt...
function u (line 1) | function u(t,e){function n(t){return e&&(t=c(t)),"+"===t[0]?o+f("diff ad...
function l (line 1) | function l(t,e,n){var r=n?c(t.actual):t.actual,o=n?c(t.expected):t.expec...
function c (line 1) | function c(t){return t.replace(/\t/g,"<tab>").replace(/\r/g,"<CR>").repl...
function f (line 1) | function f(t,e){return e.split("\n").map(function(e){return w(t,e)}).joi...
function p (line 1) | function p(t,e){return t=Object.prototype.toString.call(t),e=Object.prot...
function r (line 1) | function r(t){function e(){return Array(n).join(" ")}o.call(this,t);var...
function r (line 1) | function r(t){s.call(this,t);var e=this,n=(this.stats,.75*s.window.width...
function o (line 1) | function o(){}
function r (line 1) | function r(t){var e=n("jade"),r=__dirname+"/templates/coverage.jade",u=a...
function o (line 1) | function o(t){return t>=75?"high":t>=50?"medium":t>=25?"low":"terrible"}
function o (line 1) | function o(t){f.call(this,t);var e,n,r=this,o=this.stats,v=(t.total,s(m)...
function i (line 1) | function i(t){document.body.appendChild(s('<div id="mocha-error">%s</div...
function s (line 1) | function s(t){var e=arguments,n=document.createElement("div"),r=1;return...
function a (line 1) | function a(t){for(var e=document.getElementsByClassName("suite"),n=0;n<e...
function u (line 1) | function u(){for(var t=document.getElementsByClassName("suite hidden"),e...
function l (line 1) | function l(t,e){t.textContent?t.textContent=e:t.innerText=e}
function c (line 1) | function c(t,e,n){t.addEventListener?t.addEventListener(e,n,!1):t.attach...
function o (line 1) | function o(t,e){var r=this,e=1==arguments.length?!0:e;l.call(this,t);var...
function s (line 1) | function s(t){var e={instrumentation:"node-jscoverage",sloc:0,hits:0,mis...
function a (line 1) | function a(t,e){var n={filename:t,coverage:0,hits:0,misses:0,sloc:0,sour...
function u (line 1) | function u(t){return{title:t.title,fullTitle:t.fullTitle(),duration:t.du...
function r (line 1) | function r(t){s.call(this,t);var e=this,n=(this.stats,t.total);t.on("sta...
function o (line 1) | function o(t){return{title:t.title,fullTitle:t.fullTitle(),duration:t.du...
function r (line 1) | function r(t){var e=this;a.call(this,t);var n=[],r=[],s=[],u=[];t.on("te...
function o (line 1) | function o(t){return{title:t.title,fullTitle:t.fullTitle(),duration:t.du...
function s (line 1) | function s(t){var e={};return Object.getOwnPropertyNames(t).forEach(func...
function r (line 1) | function r(t){function e(){var t=Array(r).join("-");return" "+u("runway...
function o (line 1) | function o(){}
function r (line 1) | function r(t){s.call(this,t);var e=this,n=(this.stats,0);t.on("start",fu...
function o (line 1) | function o(){}
function r (line 1) | function r(t){function e(t){return Array(u).join("#")+" "+t}function n(t...
function r (line 2) | function r(t){s.call(this,t),t.on("start",function(){i.stdout.write("[2...
function o (line 2) | function o(){}
function r (line 2) | function r(t){a.call(this,t);var e=this,n=(this.stats,.75*a.window.width...
function o (line 2) | function o(t){i.stdout.write(t)}
function s (line 2) | function s(){}
function t (line 2) | function t(t,e){o(" "),o("["+t+"m"+e+"[0m"),o("\n")}
function r (line 2) | function r(t,e){s.call(this,t);var n=this,e=e||{},r=(this.stats,.5*s.win...
function o (line 2) | function o(){}
function r (line 2) | function r(t){function e(){return Array(r).join(" ")}i.call(this,t);var...
function o (line 2) | function o(){}
function r (line 2) | function r(t){i.call(this,t);var e=(this.stats,1),n=0,r=0;t.on("start",f...
function o (line 2) | function o(t){return t.fullTitle().replace(/#/g,"")}
function o (line 2) | function o(t){l.call(this,t);var e=this.stats,n=[];t.on("pending",functi...
function i (line 2) | function i(){}
function s (line 2) | function s(t){var e={classname:t.parent.fullTitle(),name:t.title,time:t....
function a (line 2) | function a(t,e,n,r){var o,i=n?"/>":">",s=[];for(var a in e)s.push(a+'="'...
function u (line 2) | function u(t){return"<![CDATA["+f(t)+"]]>"}
function o (line 2) | function o(t,e){this.title=t,this.fn=e,this.async=e&&e.length,this.sync=...
function i (line 2) | function i(){}
function e (line 2) | function e(t){i||(i=!0,s.emit("error",t||new Error("done() called multip...
function n (line 2) | function n(n){var r=s.timeout();if(!s.timedOut){if(o)return e(n||s._trac...
function r (line 2) | function r(t){var e=t.call(u);e&&"function"==typeof e.then?(s.resetTimeo...
function o (line 2) | function o(t){var e=this;this._globals=[],this._abort=!1,this.suite=t,th...
function s (line 2) | function s(){}
function a (line 2) | function a(t,e){return p(e,function(e){if(/^d+/.test(e))return!1;if(n.na...
function u (line 2) | function u(){if("object"==typeof i&&"string"==typeof i.version){var t=i....
function n (line 2) | function n(t){var o=i[t];return o?s.failures&&r.bail()?e():(s.currentRun...
function r (line 2) | function r(s){return o.suite=s,s?void o.hook(t,function(t){if(t){var s=o...
function n (line 2) | function n(t,r,o){var s=i.suite;i.suite=o?r.parent:r,i.suite?i.hookUp("a...
function r (line 2) | function r(a,u){if(i.failures&&t._bail)return e();if(i._abort)return e()...
function n (line 2) | function n(e){if(e)return e==t?r():r(e);if(i._abort)return r();var o=t.s...
function r (line 2) | function r(n){i.suite=t,i.hook("afterAll",function(){i.emit("suite end",...
function e (line 2) | function e(t){n.uncaught(t)}
function r (line 2) | function r(t,e){this.title=t;var n=function(){};n.prototype=e,this.ctx=n...
function o (line 2) | function o(){}
function r (line 2) | function r(t,e){i.call(this,t,e),this.pending=!e,this.type="test"}
function o (line 2) | function o(){}
function r (line 2) | function r(t){return!~p.indexOf(t)}
function o (line 2) | function o(t){return t.replace(/</g,"<").replace(/>/g,">").replace...
FILE: test/dist/fixtures/sinon-chai.js
function n (line 1) | function n(t){return"function"==typeof t&&"function"==typeof t.getCall&&...
function a (line 1) | function a(t){return 1===t?"once":2===t?"twice":3===t?"thrice":(t||0)+" ...
function i (line 1) | function i(t){return t&&n(t.proxy)}
function o (line 1) | function o(t){if(!n(t._obj)&&!i(t._obj))throw new TypeError(e.inspect(t....
function c (line 1) | function c(t,e,a,i,o){function c(e){return t.printf.apply(t,e)}var l=i?"...
function l (line 1) | function l(n,a,i){e.addProperty(t.Assertion.prototype,n,function(){o(thi...
function r (line 1) | function r(n,i,l){e.addMethod(t.Assertion.prototype,n,function(t){o(this...
function s (line 1) | function s(t,n,a){return function(){o(this);var i="always"+t[0].toUpperC...
function u (line 1) | function u(n,a,i){var o=s(n,a,i);e.addProperty(t.Assertion.prototype,n,o)}
function f (line 1) | function f(n,a,i,o){var c=s(a,i,o);e.addMethod(t.Assertion.prototype,n,c)}
function d (line 1) | function d(t,e,n){f(t,t,e,n)}
FILE: test/dist/fixtures/sinon.js
function define (line 1) | function define(e,t,n){"samsam"==e?samsam=t():"function"==typeof t&&0===...
function e (line 1) | function e(e){var t=e;return"number"==typeof e&&e!==t}
function t (line 1) | function t(e){return f.toString.call(e).split(/[ \]]/)[1]}
function n (line 1) | function n(e){if("Arguments"===t(e))return!0;if("object"!=typeof e||"num...
function r (line 1) | function r(e){if(!e||1!==e.nodeType||!d)return!1;try{e.appendChild(d),e....
function o (line 1) | function o(e){var t,n=[];for(t in e)f.hasOwnProperty.call(e,t)&&n.push(t...
function i (line 1) | function i(e){return"function"==typeof e.getTime&&e.getTime()==e.valueOf()}
function s (line 1) | function s(e){return 0===e&&1/e===-(1/0)}
function a (line 1) | function a(t,n){return t===n||e(t)&&e(n)?0!==t||s(t)===s(n):void 0}
function u (line 1) | function u(s,u){function l(e){return!("object"!=typeof e||null===e||e in...
function l (line 1) | function l(e,t){if(0===t.length)return!0;var n,r,o,i;for(n=0,r=e.length;...
function t (line 1) | function t(e){if(!e)return"";if(e.displayName)return e.displayName;if(e....
function n (line 1) | function n(e,n){var r,o,i=t(n&&n.constructor),a=e.excludeConstructors||s...
function r (line 1) | function r(e,t){if("object"!=typeof e)return!1;var n,r;for(n=0,r=t.lengt...
function o (line 1) | function o(t,n,i,s){if("string"==typeof n){var u=t.quoteStrings,l="boole...
function i (line 1) | function i(e){for(var t in e)this[t]=e[t]}
function o (line 1) | function o(s,a){if(!n[s]){if(!t[s]){var u="function"==typeof require&&re...
function parseTime (line 1) | function parseTime(e){if(!e)return 0;var t,n=e.split(":"),r=n.length,o=r...
function getEpoch (line 1) | function getEpoch(e){if(!e)return 0;if("function"==typeof e.getTime)retu...
function inRange (line 1) | function inRange(e,t,n){return n&&n.callAt>=e&&n.callAt<=t}
function mirrorDateProperties (line 1) | function mirrorDateProperties(e,t){var n;for(n in t)t.hasOwnProperty(n)&...
function createDate (line 1) | function createDate(){function e(t,n,r,o,i,s,a){switch(arguments.length)...
function addTimer (line 1) | function addTimer(e,t){if(void 0===t.func)throw new Error("Callback must...
function compareTimers (line 1) | function compareTimers(e,t){return e.callAt<t.callAt?-1:e.callAt>t.callA...
function firstTimerInRange (line 1) | function firstTimerInRange(e,t,n){var r,o,i=e.timers,s=null;for(r in i)i...
function callTimer (line 1) | function callTimer(clock,timer){var exception;"number"==typeof timer.int...
function uninstall (line 1) | function uninstall(e,t){var n,r,o;for(r=0,o=e.methods.length;o>r;r++)if(...
function hijackMethod (line 1) | function hijackMethod(e,t,n){var r;if(n[t].hadOwnProperty=Object.prototy...
function createClock (line 1) | function createClock(e){var t={now:getEpoch(e),timeouts:{},Date:createDa...
function detectKnownFailSituation (line 1) | function detectKnownFailSituation(e){if(!(e.indexOf("Date")<0)){if(e.ind...
function e (line 1) | function e(e,n,r){t=r.exports=e("./sinon/util/core"),e("./sinon/extend")...
function t (line 1) | function t(e){var t=!1;try{e.appendChild(l),t=l.parentNode===e}catch(n){...
function n (line 1) | function n(e){return l&&e&&1===e.nodeType&&t(e)}
function r (line 1) | function r(e){return"function"==typeof e||!!(e&&e.constructor&&e.call&&e...
function o (line 1) | function o(e){return"number"==typeof e&&isNaN(e)}
function i (line 1) | function i(e,t){for(var n in t)c.call(e,n)||(e[n]=t[n])}
function s (line 1) | function s(e){return"function"==typeof e&&"function"==typeof e.restore&&...
function a (line 1) | function a(e){return e.wrapMethod=function(t,n,o){function s(e){var t;if...
function u (line 1) | function u(e,t){a(t)}
function t (line 1) | function t(e){function t(e){var t,r,o,i=Array.prototype.slice.call(argum...
function n (line 1) | function n(e,n,r){var o=e("./util/core");r.exports=t(o)}
function t (line 1) | function t(e){function t(e){switch(e){case 1:return"once";case 2:return"...
function n (line 1) | function n(e,n,r){var o=e("./util/core");r.exports=t(o)}
function t (line 1) | function t(e){function t(e){if(null===e)return"null";if(void 0===e)retur...
function n (line 1) | function n(e,n,r){var o=e("./util/core");r.exports=t(o)}
function t (line 1) | function t(e){function t(t,n,r){var o=e.typeOf(t);if(o!==n)throw new Typ...
function n (line 1) | function n(e,n,r){var o=e("./util/core");e("./typeOf"),r.exports=t(o)}
function n (line 1) | function n(e){function n(e){return""+e}function r(){function e(){return ...
function r (line 1) | function r(e,t,r){var o=e("./util/core");r.exports=n(o)}
function t (line 1) | function t(e){function t(t,n,o){var i=e.functionName(t)+n;throw o.length...
function n (line 1) | function n(e,n,r){var o=e("./util/core");e("./match"),e("./format"),r.ex...
function makeApi (line 1) | function makeApi(sinon){function spy(e,t,n){if(!t&&"function"==typeof e)...
function loadDependencies (line 2) | function loadDependencies(e,t,n){var r=e("./util/core");e("./call"),e("....
function t (line 2) | function t(e,t){return"string"==typeof e?(this.exception=new Error(t||""...
function n (line 2) | function n(e,t){var n=e.callArgAt;if(n>=0)return t[n];var r;n===a&&(r=t)...
function r (line 2) | function r(e){function r(t,n,r){if(t.callArgAt<0){var o;return o=t.callA...
function o (line 2) | function o(e,t,n){var o=e("./util/core");e("./extend"),n.exports=r(o)}
function t (line 2) | function t(e){function t(n,r,o){if(o&&"function"!=typeof o&&"object"!=ty...
function n (line 2) | function n(e,n,r){var o=e("./util/core");e("./behavior"),e("./spy"),e("....
function t (line 2) | function t(e){function t(n){return n?t.create(n):e.expectation.create("A...
function n (line 2) | function n(e,n,r){var o=e("./util/core");e("./times_in_words"),e("./call...
function t (line 2) | function t(e){return e.fakes||(e.fakes=[]),e.fakes}
function n (line 2) | function n(e,n){for(var r=t(e),o=0,i=r.length;i>o;o+=1)"function"==typeo...
function r (line 2) | function r(e){for(var n=t(e),r=0;r<n.length;)n.splice(r,1)}
function o (line 2) | function o(e){var o={verify:function(){n(this,"verify")},restore:functio...
function i (line 2) | function i(e,t,n){var r=e("./util/core");e("./mock"),e("./spy"),e("./stu...
function e (line 2) | function e(e,t){var n="undefined"!=typeof lolex?lolex:t;e.useFakeTimers=...
function t (line 2) | function t(t,n,r,o){var i=t("./core");e(i,o),r.exports=i}
function e (line 2) | function e(e){e.Event=function(e,t,n,r){this.initEvent(e,t,n,r)},e.Event...
function t (line 2) | function t(t){var n=t("./core");e(n)}
function t (line 2) | function t(e){function t(){}function n(t,r){var o=t+" threw exception: "...
function n (line 2) | function n(e,n,r){var o=e("./util/core");r.exports=t(o)}
function t (line 2) | function t(t){function n(){this.readyState=n.UNSENT,this.requestBody=nul...
function n (line 2) | function n(e,n,r){var o=e("./core");e("../extend"),e("./event"),e("../lo...
function n (line 2) | function n(e){var t="undefined"!=typeof e.XMLHttpRequest;if(t)return e.X...
function r (line 2) | function r(){this.eventListeners={progress:[],load:[],abort:[],error:[]}}
function o (line 2) | function o(){function e(e){t.addEventListener(e,function(n){var r=t["on"...
function i (line 2) | function i(e){if(e.readyState!==o.OPENED)throw new Error("INVALID_STATE_...
function s (line 2) | function s(e,t){t=t.toLowerCase();for(var n in e)if(n.toLowerCase()===t)...
function a (line 2) | function a(e,t){if(e)for(var n=0,r=e.length;r>n;n+=1)t(e[n])}
function u (line 2) | function u(e,t){for(var n=0;n<e.length;n++)if(t(e[n])===!0)return!0;retu...
function l (line 2) | function l(e){if(e.readyState!==o.OPENED)throw new Error("INVALID_STATE_...
function c (line 2) | function c(e){if(e.readyState===o.DONE)throw new Error("Request done")}
function f (line 2) | function f(e){if(e.async&&e.readyState!==o.HEADERS_RECEIVED)throw new Er...
function d (line 2) | function d(e){if("string"!=typeof e){var t=new Error("Attempted to respo...
function h (line 2) | function h(e){e.xhr=g,e.extend(o.prototype,e.EventTarget,{async:!0,open:...
function p (line 2) | function p(e,t,n){var r=e("./core");e("../extend"),e("./event"),e("../lo...
function e (line 3) | function e(e){var t=e;if("[object Array]"!==Object.prototype.toString.ca...
function t (line 3) | function t(e,t,n){var r=e.method,o=!r||r.toLowerCase()===t.toLowerCase()...
function n (line 3) | function n(e,n){var r=n.url;if(/^https?:\/\//.test(r)&&!a.test(r)||(r=r....
function r (line 3) | function r(t){t.fakeServer={create:function(e){var n=t.create(this);retu...
function o (line 3) | function o(e,t,n){var o=e("./core");e("./fake_xdomain_request"),e("./fak...
function e (line 3) | function e(e){function t(){}t.prototype=e.fakeServer,e.fakeServerWithClo...
function t (line 3) | function t(t){var n=t("./core");t("./fake_server"),t("./fake_timers"),e(n)}
function t (line 3) | function t(e){function t(e,t,n,o){o&&(!t.injectInto||n in t.injectInto?r...
function n (line 3) | function n(e,n,r){var o=e("./util/core");e("./extend"),e("./util/fake_se...
function t (line 3) | function t(e){function t(t){function r(){var r=e.getConfig(e.config);r.i...
function n (line 3) | function n(e,n,r){var o=e("./util/core");e("./sandbox"),r.exports=t(o)}
function t (line 3) | function t(e,t,n){return function(){t&&t.apply(this,arguments);var r,o;t...
function n (line 3) | function n(e){function n(n,r){if(!n||"object"!=typeof n)throw new TypeEr...
function r (line 3) | function r(e,t,r){var o=e("./util/core");e("./test"),r.exports=n(o)}
function n (line 3) | function n(e){function n(){for(var e,t=0,r=arguments.length;r>t;++t)e=ar...
function r (line 3) | function r(e,t,r){var o=e("./util/core");e("./match"),e("./format"),r.ex...
Condensed preview — 318 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,393K chars).
[
{
"path": ".github/workflows/ci.yml",
"chars": 1580,
"preview": "name: CI\n\non:\n push:\n branches: [master, v*]\n pull_request:\n branches: [master, v5]\n\njobs:\n lint:\n runs-on: "
},
{
"path": ".gitignore",
"chars": 298,
"preview": ".project\n.settings\n\n.bem/cache\n.bem/snapshots\n.enb/tmp\n\nlibs\nnode_modules\n\ncoverage.json\n/coverage\n\n*.bundles/*/*\n!*.bun"
},
{
"path": ".husky/pre-commit",
"chars": 16,
"preview": "npx lint-staged\n"
},
{
"path": ".nvmrc",
"chars": 3,
"preview": "24\n"
},
{
"path": "CHANGELOG.md",
"chars": 36265,
"preview": "# Changelog\n\n## 5.0.0\n\n### Breaking changes\n\n- **ESM-only**: The entire codebase has been migrated from the `ym` module "
},
{
"path": "CHANGELOG.ru.md",
"chars": 40053,
"preview": "# История изменений\n\n## 5.0.0\n\n### Несовместимые изменения\n\n- **Только ESM**: Вся кодовая база мигрирована с модульной с"
},
{
"path": "CLA.md",
"chars": 1908,
"preview": "# Notice to external contributors\n\n\n## General info\n\nHello! In order for us (YANDEX LLC) to accept patches and other con"
},
{
"path": "CONTRIBUTING.md",
"chars": 1044,
"preview": "# How to contribute\n\n1. [Create an issue](https://github.com/bem/bem-core/issues/new) with a proper description.\n2. Deci"
},
{
"path": "CONTRIBUTING.ru.md",
"chars": 1104,
"preview": "# Внесение изменений\n\n1. [Создать issue](https://github.com/bem/bem-core/issues/new) с описанием сути изменений.\n2. Опре"
},
{
"path": "LICENSE.txt",
"chars": 16208,
"preview": "© YANDEX LLC, 2012\n\nThe Source Code called `bem-core` available at https://github.com/bem/bem-core is subject to the ter"
},
{
"path": "MIGRATION.md",
"chars": 33866,
"preview": "# Migration\n\n## 5.0.0\n\n### ym → ES modules\n\nThe `ym` module system (`modules.define`/`modules.require`) has been replace"
},
{
"path": "MIGRATION.ru.md",
"chars": 33979,
"preview": "# Миграция\n\n## 5.0.0\n\n### ym → ES-модули\n\nМодульная система `ym` (`modules.define`/`modules.require`) заменена на нативн"
},
{
"path": "PLAN.md",
"chars": 23017,
"preview": "# Plan: Modernization of bem-core Dependencies\n\n## Current State Analysis\n\n### Runtime Environment\n| Component | Current"
},
{
"path": "README.md",
"chars": 2957,
"preview": "# bem-core library [](https://github."
},
{
"path": "README.ru.md",
"chars": 4266,
"preview": "# Библиотека BEM Core\n\n`bem-core` — это библиотека с открытым кодом, которая предоставляет набор блоков для разработки в"
},
{
"path": "SUMMARY.md",
"chars": 859,
"preview": "# Summary\n\n* [Введение](README.ru.md)\n * [Общие сведения](common.docs/i-bem-js/i-bem-js-common.ru.md)\n * [Привязка"
},
{
"path": "build/platforms/desktop.js",
"chars": 1541,
"preview": "/**\n * Entry point for the desktop platform build.\n *\n * This file imports all BEM blocks in the correct order for the d"
},
{
"path": "build/platforms/touch.js",
"chars": 1514,
"preview": "/**\n * Entry point for the touch platform build.\n *\n * This file imports all BEM blocks in the correct order for the tou"
},
{
"path": "build/plugins/vite-plugin-bem-levels.js",
"chars": 23419,
"preview": "import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs'\nimport { join, resolve, relative, dirname, bas"
},
{
"path": "build/plugins/vite-plugin-bem-levels.test.js",
"chars": 23934,
"preview": "import { describe, it } from 'node:test';\nimport { strict as assert } from 'node:assert';\nimport { readFileSync } from '"
},
{
"path": "build/vite.config.js",
"chars": 1426,
"preview": "import { defineConfig } from 'vite';\nimport { resolve } from 'node:path';\nimport bemLevels from './plugins/vite-plugin-b"
},
{
"path": "build/vite.test.config.js",
"chars": 1269,
"preview": "import { defineConfig } from 'vite';\nimport { resolve } from 'node:path';\nimport bemLevels from './plugins/vite-plugin-b"
},
{
"path": "common.blocks/clearfix/clearfix.css",
"chars": 75,
"preview": ".clearfix:after\n{\n display: table;\n clear: both;\n\n content: '';\n}\n"
},
{
"path": "common.blocks/clearfix/clearfix.en.md",
"chars": 1883,
"preview": "# clearfix\n\nThis block provides a CSS class that implements the **clearfix** layout hack, also known as the [Easy Cleari"
},
{
"path": "common.blocks/clearfix/clearfix.en.title.txt",
"chars": 25,
"preview": "Block with floats inside\n"
},
{
"path": "common.blocks/clearfix/clearfix.ru.md",
"chars": 1885,
"preview": "# clearfix\n\nБлок предоставляет СSS-класс, реализующий прием верстки **clearfix**, также известный как [Easy Clearing Hac"
},
{
"path": "common.blocks/clearfix/clearfix.ru.title.txt",
"chars": 31,
"preview": "Блок с float элементами внутри\n"
},
{
"path": "common.blocks/cookie/cookie.en.md",
"chars": 2995,
"preview": "# cookie\n\nThis block provides an object with a set of methods for working with browser cookies (the JS `document.cookie`"
},
{
"path": "common.blocks/cookie/cookie.js",
"chars": 2176,
"preview": "/**\n * @module cookie\n * @description Inspired from $.cookie plugin by Klaus Hartl (stilbuero.de)\n */\n\nexport default {\n"
},
{
"path": "common.blocks/cookie/cookie.ru.md",
"chars": 2945,
"preview": "# cookie\n\nБлок предоставляет объект, содержащий набор методов для работы с cookie браузера (JS-свойство `document.cookie"
},
{
"path": "common.blocks/cookie/cookie.spec.js",
"chars": 1031,
"preview": "modules.define('spec', [\n 'cookie',\n 'chai'\n], function(provide,\n cookie,\n chai\n) {\n\nvar expect = chai.expec"
},
{
"path": "common.blocks/dom/dom.deps.js",
"chars": 32,
"preview": "({\n shouldDeps : 'jquery'\n})\n"
},
{
"path": "common.blocks/dom/dom.en.md",
"chars": 3944,
"preview": "# dom\n\nThis block provides an object with a set of methods for working with the DOM tree.\n\n## Overview\n\n### Object prope"
},
{
"path": "common.blocks/dom/dom.js",
"chars": 2501,
"preview": "/**\n * @module dom\n * @description some DOM utils\n */\n\nimport $ from 'bem:jquery'\n\nconst EDITABLE_INPUT_TYPES = new Set("
},
{
"path": "common.blocks/dom/dom.ru.md",
"chars": 3955,
"preview": "# dom\n\nБлок предоставляет объект, содержащий набор методов для работы с DOM-деревом.\n\n## Обзор\n\n### Свойства и методы об"
},
{
"path": "common.blocks/dom/dom.spec.js",
"chars": 6054,
"preview": "modules.define('spec', [\n 'dom',\n 'jquery'\n], function(provide,\n dom,\n $\n) {\n\ndescribe('dom', function() {\n "
},
{
"path": "common.blocks/events/__channels/events__channels.deps.js",
"chars": 31,
"preview": "({\n shouldDeps : 'events'\n})\n"
},
{
"path": "common.blocks/events/__channels/events__channels.en.md",
"chars": 1096,
"preview": "<a name=\"elems-channels\"></a>\n\n# `channels` element in the `events` block\n\nUse the `channels` element in the `events` bl"
},
{
"path": "common.blocks/events/__channels/events__channels.ru.md",
"chars": 1158,
"preview": "<a name=\"elems-channels\"></a>\n\n# Элемент `channels` блока `events`\n\nЭлемент `channels` блока `events` предназначен для р"
},
{
"path": "common.blocks/events/__channels/events__channels.vanilla.js",
"chars": 753,
"preview": "/**\n * @module events__channels\n */\n\nimport events from 'bem:events'\n\nconst channels = new Map()\n\nexport default\n /**\n "
},
{
"path": "common.blocks/events/__observable/_type/events__observable_type_bem-dom.deps.js",
"chars": 202,
"preview": "[{\n mustDeps : { elem : 'observable' },\n shouldDeps : 'i-bem-dom'\n},\n{\n tech : 'spec.js',\n mustDeps : [\n "
},
{
"path": "common.blocks/events/__observable/_type/events__observable_type_bem-dom.js",
"chars": 473,
"preview": "/**\n * @module events__observable_type_bem-dom\n */\n\nimport bemDom from 'bem:i-bem-dom';\nimport observable from 'bem:even"
},
{
"path": "common.blocks/events/__observable/_type/events__observable_type_bem-dom.spec.js",
"chars": 2463,
"preview": "modules.define('spec', [\n 'events__observable',\n 'sinon',\n 'i-bem-dom',\n 'BEMHTML'\n], function(provide,\n "
},
{
"path": "common.blocks/events/__observable/events__observable.deps.js",
"chars": 129,
"preview": "[\n { shouldDeps : 'inherit' },\n {\n tech : 'spec.js',\n shouldDeps : { block : 'events', tech : 'js' }"
},
{
"path": "common.blocks/events/__observable/events__observable.js",
"chars": 1627,
"preview": "/**\n * @module events__observable\n */\n\nimport inherit from 'bem:inherit';\n\n/**\n * @class Observable\n */\nconst Observable"
},
{
"path": "common.blocks/events/__observable/events__observable.spec.js",
"chars": 2251,
"preview": "modules.define('spec', [\n 'events__observable',\n 'sinon',\n 'events'\n], function(provide,\n observable,\n si"
},
{
"path": "common.blocks/events/events.deps.js",
"chars": 59,
"preview": "({\n shouldDeps : ['inherit', 'identify', 'functions']\n})\n"
},
{
"path": "common.blocks/events/events.en.md",
"chars": 9620,
"preview": "# events\n\nThis block provides a set of JS classes for working with events.\n\n## Overview\n\n### Classes provided by the blo"
},
{
"path": "common.blocks/events/events.ru.md",
"chars": 9901,
"preview": "# events\n\nБлок предоставляет набор JS-классов, реализующий механизмы работы с событиями.\n\n## Обзор\n\n### Классы, предоста"
},
{
"path": "common.blocks/events/events.spec.js",
"chars": 8052,
"preview": "modules.define('spec', [\n 'events',\n 'sinon'\n], function(provide,\n events,\n sinon\n) {\n\ndescribe('events', fu"
},
{
"path": "common.blocks/events/events.vanilla.js",
"chars": 7403,
"preview": "/**\n * @module events\n */\n\nimport identify from 'bem:identify'\nimport inherit from 'bem:inherit'\nimport functions from '"
},
{
"path": "common.blocks/functions/__debounce/functions__debounce.spec.js",
"chars": 1792,
"preview": "modules.define('spec', ['functions__debounce'], function(provide, debounce) {\n\ndescribe('functions__debounce', function("
},
{
"path": "common.blocks/functions/__debounce/functions__debounce.vanilla.js",
"chars": 951,
"preview": "/**\n * @module functions__debounce\n */\n\nexport default\n /**\n * Debounces given function\n * @param {Function} "
},
{
"path": "common.blocks/functions/__throttle/functions__throttle.spec.js",
"chars": 1645,
"preview": "modules.define('spec', ['functions__throttle'], function(provide, throttle) {\n\ndescribe('functions__throttle', function("
},
{
"path": "common.blocks/functions/__throttle/functions__throttle.vanilla.js",
"chars": 1345,
"preview": "/**\n * @module functions__throttle\n */\n\nexport default\n /**\n * Throttle given function\n * @param {Function} f"
},
{
"path": "common.blocks/functions/functions.en.md",
"chars": 4352,
"preview": "# functions\n\nThis block provides an object with a set of methods for working with JavaScript functions.\n\n## Overview\n\n##"
},
{
"path": "common.blocks/functions/functions.ru.md",
"chars": 4406,
"preview": "# functions\n\nБлок предоставляет объект, содержащий набор методов для работы с функциями JavaScript.\n\n## Обзор\n\n### Свойс"
},
{
"path": "common.blocks/functions/functions.spec.js",
"chars": 876,
"preview": "modules.define('spec', ['functions'], function(provide, functions) {\n\ndescribe('functions', function() {\n describe('i"
},
{
"path": "common.blocks/functions/functions.vanilla.js",
"chars": 578,
"preview": "/**\n * @module functions\n * @description A set of helpers to work with JavaScript functions\n */\n\nexport default {\n /**\n"
},
{
"path": "common.blocks/i-bem/__collection/i-bem__collection.js",
"chars": 6770,
"preview": "/**\n * @module i-bem__collection\n */\nimport inherit from 'bem:inherit'\n\n/**\n * @class BemCollection\n */\nconst BemCollect"
},
{
"path": "common.blocks/i-bem/__collection/i-bem__collection.spec.js",
"chars": 16212,
"preview": "modules.define('spec', [\n 'i-bem',\n 'i-bem__collection',\n 'sinon',\n 'chai'\n], function(provide,\n bem,\n "
},
{
"path": "common.blocks/i-bem/__internal/i-bem__internal.ru.title.txt",
"chars": 32,
"preview": "Модуль для внутренних хелперов\n\n"
},
{
"path": "common.blocks/i-bem/__internal/i-bem__internal.spec.js",
"chars": 4438,
"preview": "modules.define('spec', ['i-bem__internal'], function(provide, bemInternal) {\n\ndescribe('i-bem__internal', function() {\n "
},
{
"path": "common.blocks/i-bem/__internal/i-bem__internal.vanilla.js",
"chars": 3003,
"preview": "/**\n * @module i-bem__internal\n */\n\n/**\n * Separator for modifiers and their values\n * @const\n * @type String\n */\nconst "
},
{
"path": "common.blocks/i-bem/i-bem.deps.js",
"chars": 161,
"preview": "({\n shouldDeps : [\n { elem : 'internal' },\n 'inherit',\n 'identify',\n 'next-tick',\n "
},
{
"path": "common.blocks/i-bem/i-bem.en.md",
"chars": 275,
"preview": "# i-bem\n\nA helper block for creating other blocks.\n\nThe block is implemented as a specialized JavaScript framework for w"
},
{
"path": "common.blocks/i-bem/i-bem.en.title.txt",
"chars": 30,
"preview": "Helper to create other blocks\n"
},
{
"path": "common.blocks/i-bem/i-bem.ru.md",
"chars": 307,
"preview": "# i-bem\n\nБлок-хелпер, позволяющий создавать другие блоки.\n\nРеализация блока представляет собой специализированный JavaSc"
},
{
"path": "common.blocks/i-bem/i-bem.ru.title.txt",
"chars": 36,
"preview": "Помощник для создания других блоков\n"
},
{
"path": "common.blocks/i-bem/i-bem.spec.js",
"chars": 36556,
"preview": "modules.define('spec', [\n 'i-bem',\n 'sinon',\n 'objects'\n], function(provide,\n bem,\n sinon,\n objects\n) "
},
{
"path": "common.blocks/i-bem/i-bem.vanilla.js",
"chars": 18452,
"preview": "/**\n * @module i-bem\n */\n\nimport bemInternal from 'bem:i-bem__internal'\nimport inherit from 'bem:inherit'\nimport identif"
},
{
"path": "common.blocks/i-bem-dom/__collection/i-bem-dom__collection.deps.js",
"chars": 282,
"preview": "[{\n shouldDeps : [\n 'inherit',\n { block : 'i-bem', elem : 'collection' }\n ]\n},\n{\n tech : 'spec.js"
},
{
"path": "common.blocks/i-bem-dom/__collection/i-bem-dom__collection.js",
"chars": 5668,
"preview": "/**\n * @module i-bem-dom__collection\n */\nimport inherit from 'bem:inherit'\nimport BemCollection from 'bem:i-bem__collect"
},
{
"path": "common.blocks/i-bem-dom/__collection/i-bem-dom__collection.spec.js",
"chars": 4703,
"preview": "modules.define('spec', [\n 'i-bem',\n 'i-bem-dom',\n 'i-bem-dom__collection',\n 'objects',\n 'BEMHTML'\n], func"
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_bem.deps.js",
"chars": 411,
"preview": "[{\n shouldDeps : [\n 'inherit',\n 'jquery',\n 'events',\n { block : 'i-bem', elem : 'internal"
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_bem.js",
"chars": 4251,
"preview": "/**\n * @module i-bem-dom__events_type_bem\n */\nimport bemDomEvents from 'bem:i-bem-dom__events';\nimport bemInternal from "
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_bem.spec.js",
"chars": 37705,
"preview": "modules.define('spec', [\n 'i-bem',\n 'i-bem-dom',\n 'objects',\n 'events',\n 'jquery',\n 'chai',\n 'sinon"
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_dom.deps.js",
"chars": 168,
"preview": "[{\n shouldDeps : [\n 'identify',\n 'inherit',\n 'jquery'\n ]\n},\n{\n tech : 'spec.js',\n shoul"
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_dom.js",
"chars": 1500,
"preview": "/**\n * @module i-bem-dom__events_type_dom\n */\nimport bemDomEvents from 'bem:i-bem-dom__events';\nimport inherit from 'bem"
},
{
"path": "common.blocks/i-bem-dom/__events/_type/i-bem-dom__events_type_dom.spec.js",
"chars": 41700,
"preview": "modules.define('spec', [\n 'i-bem',\n 'i-bem-dom',\n 'objects',\n 'jquery',\n 'chai',\n 'sinon',\n 'BEMHTM"
},
{
"path": "common.blocks/i-bem-dom/__events/i-bem-dom__events.deps.js",
"chars": 208,
"preview": "({\n shouldDeps : [\n 'inherit',\n 'identify',\n 'objects',\n 'jquery',\n 'functions',\n "
},
{
"path": "common.blocks/i-bem-dom/__events/i-bem-dom__events.js",
"chars": 11349,
"preview": "/**\n * @module i-bem-dom__events\n */\nimport bemInternal from 'bem:i-bem__internal'\nimport BemDomCollection from 'bem:i-b"
},
{
"path": "common.blocks/i-bem-dom/__init/_auto/i-bem-dom__init_auto.deps.js",
"chars": 47,
"preview": "({\n shouldDeps : ['jquery', 'next-tick']\n})\n"
},
{
"path": "common.blocks/i-bem-dom/__init/_auto/i-bem-dom__init_auto.js",
"chars": 186,
"preview": "/**\n * Auto initialization on DOM ready\n */\n\nimport init from 'bem:i-bem-dom__init'\nimport $ from 'bem:jquery'\nimport ne"
},
{
"path": "common.blocks/i-bem-dom/__init/i-bem-dom__init.deps.js",
"chars": 37,
"preview": "({\n shouldDeps : ['i-bem-dom']\n})\n"
},
{
"path": "common.blocks/i-bem-dom/__init/i-bem-dom__init.js",
"chars": 318,
"preview": "/**\n * @module i-bem-dom__init\n */\n\nimport bemDom from 'bem:i-bem-dom'\n\nexport default\n /**\n * Initializes blocks"
},
{
"path": "common.blocks/i-bem-dom/__init/i-bem-dom__init.spec.js",
"chars": 507,
"preview": "modules.define('spec', ['i-bem'], function(provide, bem) {\n\ndescribe('i-bem-dom__init', function() {\n it('block shoul"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.deps.js",
"chars": 296,
"preview": "({\n shouldDeps : [\n 'inherit',\n 'jquery',\n 'objects',\n 'functions',\n 'dom',\n "
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.en.md",
"chars": 310,
"preview": "# i-bem-dom\n\nA helper block for creating other blocks that have a DOM representation.\n\nThe block is implemented as a spe"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.js",
"chars": 38123,
"preview": "/**\n * @module i-bem-dom\n */\n\nimport bem from 'bem:i-bem'\nimport bemInternal from 'bem:i-bem__internal'\nimport BemDomCol"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.ru.md",
"chars": 338,
"preview": "# i-bem-dom\n\nБлок-хелпер, позволяющий создавать другие блоки, имеющие DOM-представление.\n\nРеализация блока представляет "
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.spec.js",
"chars": 66381,
"preview": "modules.define('spec', [\n 'i-bem',\n 'i-bem-dom',\n 'i-bem-dom__collection',\n 'objects',\n 'functions',\n "
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.bemjson.js",
"chars": 506,
"preview": "({\n block : 'page',\n title : 'v3 benchmarks',\n head : {\n elem : 'js', url : 'https://yastatic.net/jquery"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/b1/b1.deps.js",
"chars": 80,
"preview": "({\n mustDeps : {\n block : 'i-bem-dom'\n },\n shouldDeps : 'b2'\n})\n"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/b1/b1.js",
"chars": 316,
"preview": "modules.define('b1', ['i-bem-dom', 'b2'], function(provide, bemDom, B2) {\n\nprovide(bemDom.declBlock(this.name, {\n onS"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/b2/b2.deps.js",
"chars": 57,
"preview": "({\n mustDeps : {\n block : 'i-bem-dom'\n }\n})\n"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/b2/b2.js",
"chars": 108,
"preview": "modules.define('b2', ['i-bem-dom'], function(provide, bemDom) {\n\nprovide(bemDom.declBlock(this.name));\n\n});\n"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/page/page.deps.js",
"chars": 233,
"preview": "({\n noDeps : {\n block : 'i-bem-dom',\n elem : 'init',\n mods : { auto : true }\n },\n shouldDe"
},
{
"path": "common.blocks/i-bem-dom/i-bem-dom.tests/benchmarks.blocks/page/page.js",
"chars": 223,
"preview": "modules.require(['i-bem-dom__init', 'jquery'], function(init, $) {\n\n$(function() {\n var timeStart = Date.now();\n i"
},
{
"path": "common.blocks/i18n/i18n.deps.js",
"chars": 66,
"preview": "({\n tech : 'tmpl-spec.js',\n shouldDeps : 'greeting-card'\n})\n"
},
{
"path": "common.blocks/i18n/i18n.en.md",
"chars": 859,
"preview": "# i18n\n\nThis block provides a function for project internationalization.\nIt can be used in a browser and in a node.js en"
},
{
"path": "common.blocks/i18n/i18n.i18n.js",
"chars": 1206,
"preview": "export default {\n i18n : {\n i18n : function() {\n let data;\n\n /**\n * @param {"
},
{
"path": "common.blocks/i18n/i18n.ru.md",
"chars": 871,
"preview": "# i18n\n\nБлок предоставляет функцию для интернационализации проекта.\nМожет быть использован в браузере и в node.js-окруже"
},
{
"path": "common.blocks/i18n/i18n.test.js",
"chars": 2205,
"preview": "import { describe, it, beforeEach } from 'node:test';\nimport assert from 'node:assert/strict';\n\nimport i18nModule from '"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.bemhtml.js",
"chars": 81,
"preview": "block('logo').content()(function() {\n return this.i18n('logo', 'yandex');\n});\n"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.bh.js",
"chars": 160,
"preview": "module.exports = function (bh) {\n bh.match('logo', function (ctx) {\n var i18n = bh.lib.i18n;\n\n ctx.cont"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.deps.js",
"chars": 102,
"preview": "({\n shouldDeps : [\n { block : 'i-bem', elems : 'dom' },\n { block : 'i18n' }\n ]\n})\n"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.i18n/en.js",
"chars": 127,
"preview": "module.exports = {\n 'yandex-service' : {\n 'Lego' : 'Lego'\n },\n 'logo' : {\n 'yandex' : 'Yandex'\n "
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.i18n/ru.js",
"chars": 127,
"preview": "module.exports = {\n 'yandex-service' : {\n 'Lego' : 'Лего'\n },\n 'logo' : {\n 'yandex' : 'Яндекс'\n "
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.i18n.js",
"chars": 197,
"preview": "module.exports = {\n 'logo' : {\n 'yandex-service' : function(serviceName, i18n) {\n return i18n('logo"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/logo/logo.js",
"chars": 465,
"preview": "modules.define('logo', ['i-bem__dom', 'i18n'], function(provide, BEMDOM, i18n) {\n\nprovide(BEMDOM.decl(this.name, {\n o"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/page/__js/page__js.bemhtml.js",
"chars": 116,
"preview": "block('page').elem('js').def()(function() {\n this.ctx.url = this.i18n('page', 'js');\n return applyNext();\n});\n"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/page/__js/page__js.bh.js",
"chars": 164,
"preview": "module.exports = function (bh) {\n bh.match('page__js', function (ctx, json) {\n var i18n = bh.lib.i18n;\n\n "
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/page/page.i18n/en.js",
"chars": 73,
"preview": "module.exports = {\n 'page' : {\n 'js' : 'simple.en.js'\n }\n};\n"
},
{
"path": "common.blocks/i18n/i18n.tests/blocks/page/page.i18n/ru.js",
"chars": 73,
"preview": "module.exports = {\n 'page' : {\n 'js' : 'simple.ru.js'\n }\n};\n"
},
{
"path": "common.blocks/i18n/i18n.tests/simple.bemjson.js",
"chars": 164,
"preview": "({\n block : 'page',\n title : 'i18n: test',\n scripts : { elem : 'js' },\n content : {\n block : 'logo',\n"
},
{
"path": "common.blocks/i18n/i18n.tmpl-specs/10-simple.bemjson.js",
"chars": 34,
"preview": "({\n block : 'greeting-card'\n})\n"
},
{
"path": "common.blocks/i18n/i18n.tmpl-specs/10-simple.html",
"chars": 55,
"preview": "<div class=\"greeting-card\">greeting-card:message</div>\n"
},
{
"path": "common.blocks/i18n/i18n.tmpl-specs/blocks/greeting-card/greeting-card.bemhtml.js",
"chars": 134,
"preview": "block('greeting-card').content()(function () {\n var i18n = this.require('i18n');\n\n return i18n('greeting-card', 'm"
},
{
"path": "common.blocks/i18n/i18n.tmpl-specs/blocks/greeting-card/greeting-card.bh.js",
"chars": 210,
"preview": "module.exports = function (bh) {\n bh.match('greeting-card', function (ctx) {\n var i18n = bh.lib.i18n,\n "
},
{
"path": "common.blocks/i18n/i18n.tmpl-specs/blocks/greeting-card/greeting-card.deps.js",
"chars": 39,
"preview": "({\n mustDeps : ['i-bem', 'i18n']\n})\n"
},
{
"path": "common.blocks/identify/identify.en.md",
"chars": 1206,
"preview": "# identify\n\nThis block provides a function for working with unique identifiers. It allows you to:\n\n* Create object ident"
},
{
"path": "common.blocks/identify/identify.ru.md",
"chars": 1257,
"preview": "# identify\n\nБлок предоставляет функцию для работы с уникальными идентификаторами, которая позволяет:\n\n* создавать иденти"
},
{
"path": "common.blocks/identify/identify.spec.js",
"chars": 1928,
"preview": "modules.define('spec', [\n 'identify',\n 'chai'\n], function(provide,\n identify,\n chai\n) {\n\nvar should = chai.s"
},
{
"path": "common.blocks/identify/identify.vanilla.js",
"chars": 900,
"preview": "/**\n * @module identify\n */\n\nlet counter = 0\nconst expando = '__' + (+new Date),\n get = () => 'uniq' + (++counter),\n i"
},
{
"path": "common.blocks/idle/_start/idle_start_auto.js",
"chars": 89,
"preview": "/**\n * Automatically starts idle module\n */\n\nimport idle from 'bem:idle';\n\nidle.start();\n"
},
{
"path": "common.blocks/idle/idle.deps.js",
"chars": 55,
"preview": "({\n shouldDeps : ['events', 'inherit', 'jquery']\n})\n"
},
{
"path": "common.blocks/idle/idle.en.md",
"chars": 2914,
"preview": "# idle\n\nThis block provides an object with a set of methods for generating an event when user activity ends (i.e. the us"
},
{
"path": "common.blocks/idle/idle.js",
"chars": 2005,
"preview": "/**\n * @module idle\n */\n\nimport inherit from 'bem:inherit'\nimport events from 'bem:events'\nimport $ from 'bem:jquery'\n\nc"
},
{
"path": "common.blocks/idle/idle.ru.md",
"chars": 3242,
"preview": "# idle\n\nБлок предоставляет объект, содержащий набор методов для генерации события в момент прекращения пользовательской "
},
{
"path": "common.blocks/inherit/inherit.en.md",
"chars": 6912,
"preview": "# inherit\n\nThis block provides a function for declaring and inheriting classes.\n\n## Overview\n\n### Usage\n\n| Use | Signatu"
},
{
"path": "common.blocks/inherit/inherit.ru.md",
"chars": 7079,
"preview": "# inherit\n\nБлок предоставляет функцию, реализующую механизмы для объявления и наследования классов.\n\n## Обзор\n\n### Спосо"
},
{
"path": "common.blocks/inherit/inherit.spec.js",
"chars": 9215,
"preview": "modules.define('spec', ['inherit'], function(provide, inherit) {\n\ndescribe('inherit', function() {\n describe('instanc"
},
{
"path": "common.blocks/inherit/inherit.vanilla.js",
"chars": 3183,
"preview": "/**\n * @module inherit\n * @version 2.2.6\n * @author Filatov Dmitry <dfilatov@yandex-team.ru>\n */\n\nconst noop = () => {},"
},
{
"path": "common.blocks/jquery/__config/jquery__config.js",
"chars": 257,
"preview": "/**\n * @module jquery__config\n * @description Configuration for jQuery.\n * jQuery is now provided via npm package (peer "
},
{
"path": "common.blocks/jquery/__config/jquery__config.ru.md",
"chars": 637,
"preview": "<a name=\"elems-config\"></a>\n\n# Элемент `config` блока `jquery`\n\nЭлемент предоставляет объект с настройками подключаемой "
},
{
"path": "common.blocks/jquery/jquery.deps.js",
"chars": 59,
"preview": "({\n shouldDeps : [\n { elem : 'config' }\n ]\n})\n"
},
{
"path": "common.blocks/jquery/jquery.en.md",
"chars": 836,
"preview": "# jquery\n\nThis block is for downloading the [jQuery](https://jquery.com) library and its extensions and enabling them on"
},
{
"path": "common.blocks/jquery/jquery.js",
"chars": 153,
"preview": "/**\n * @module jquery\n * @description Provide jQuery from npm package.\n */\n\nimport jQuery from 'jquery'\n\n/**\n * @type Fu"
},
{
"path": "common.blocks/jquery/jquery.ru.md",
"chars": 833,
"preview": "# jquery\n\nБлок служит для загрузки и подключения на страницу библиотеки [jQuery](https://jquery.com) и ее расширений.\nРа"
},
{
"path": "common.blocks/jquery/jquery.ru.title.txt",
"chars": 28,
"preview": "Блок с плагинами для jQuery\n"
},
{
"path": "common.blocks/keyboard/__codes/keyboard__codes.js",
"chars": 727,
"preview": "/**\n * @module keyboard__codes\n */\nexport default {\n /** @type {Number} */\n BACKSPACE : 8,\n /** @type {Number} "
},
{
"path": "common.blocks/keyboard/keyboard.en.md",
"chars": 2172,
"preview": "# keyboard\n\nThis block is used for working with keyboard input.\n\n## Overview\n\n### Elements of the block\n\n| Element | Usa"
},
{
"path": "common.blocks/keyboard/keyboard.ru.md",
"chars": 2122,
"preview": "# keyboard\n\nБлок предназначен для работы с клавиатурным вводом.\n\n## Обзор\n\n### Элементы блока\n\n| Элемент | Способы испол"
},
{
"path": "common.blocks/loader/_type/loader_type_bundle.js",
"chars": 2424,
"preview": "/**\n * @module loader_type_bundle\n * @description Load BEM bundle (JS+CSS) from external URL.\n */\n\nconst LOADING_TIMEOUT"
},
{
"path": "common.blocks/loader/_type/loader_type_js.js",
"chars": 1532,
"preview": "/**\n * @module loader_type_js\n * @description Load JS from external URL.\n */\n\nconst loading = new Map()\nconst loaded = n"
},
{
"path": "common.blocks/loader/_type/loader_type_js.spec.js",
"chars": 672,
"preview": "modules.define('spec', [\n 'loader_type_js',\n 'sinon'\n], function(provide,\n loader,\n sinon\n) {\n\ndescribe('loa"
},
{
"path": "common.blocks/loader/loader.en.md",
"chars": 3297,
"preview": "# loader\n\nUse the `loader` block for downloading and connecting scripts by URLs.\n\n## Overview\n\n### Block modifiers\n\n| Mo"
},
{
"path": "common.blocks/loader/loader.ru.md",
"chars": 3456,
"preview": "# loader\n\nБлок `loader` служит для загрузки и подключения скриптов по URL.\n\n## Обзор\n\n### Модификаторы блока\n\n| Модифика"
},
{
"path": "common.blocks/next-tick/next-tick.en.md",
"chars": 1483,
"preview": "# next-tick\n\nThis block provides a function that performs an asynchronous call of the callback function passed as an arg"
},
{
"path": "common.blocks/next-tick/next-tick.ru.md",
"chars": 1505,
"preview": "# next-tick\n\nБлок предоставляет функцию, производящую асинхронный вызов callback-функции, переданной аргументом, в следу"
},
{
"path": "common.blocks/next-tick/next-tick.spec.js",
"chars": 720,
"preview": "modules.define('spec', ['next-tick'], function(provide, nextTick) {\n\ndescribe('next-tick', function() {\n it('should c"
},
{
"path": "common.blocks/next-tick/next-tick.vanilla.js",
"chars": 650,
"preview": "/**\n * @module next-tick\n */\n\n/**\n * Executes given function on next tick.\n * @type Function\n * @param {Function} fn\n */"
},
{
"path": "common.blocks/objects/objects.en.md",
"chars": 2857,
"preview": "# objects\n\nThis block provides an object with a set of methods for working with JavaScript objects.\n\n## Overview\n\n### Pr"
},
{
"path": "common.blocks/objects/objects.ru.md",
"chars": 2851,
"preview": "# objects\n\nБлок предоставляет объект, содержащий набор методов для работы с объектами JavaScript.\n\n## Обзор\n\n### Свойств"
},
{
"path": "common.blocks/objects/objects.spec.js",
"chars": 3261,
"preview": "modules.define('spec', ['objects'], function(provide, objects) {\n\ndescribe('objects', function() {\n var undef;\n\n /"
},
{
"path": "common.blocks/objects/objects.vanilla.js",
"chars": 1084,
"preview": "/**\n * @module objects\n * @description A set of helpers to work with JavaScript objects\n */\n\nexport default {\n /**\n *"
},
{
"path": "common.blocks/page/__css/page__css.bemhtml.js",
"chars": 281,
"preview": "block('page').elem('css')(\n bem()(false),\n tag()('style'),\n match(function() { return this.ctx.url; })(\n "
},
{
"path": "common.blocks/page/__css/page__css.bh.js",
"chars": 328,
"preview": "module.exports = function(bh) {\n\n bh.match('page__css', function(ctx, json) {\n ctx.bem(false);\n\n if(jso"
},
{
"path": "common.blocks/page/__js/page__js.bemhtml.js",
"chars": 332,
"preview": "block('page').elem('js')(\n bem()(false),\n tag()('script'),\n attrs()(function() {\n var attrs = {};\n "
},
{
"path": "common.blocks/page/__js/page__js.bh.js",
"chars": 338,
"preview": "module.exports = function(bh) {\n\n bh.match('page__js', function(ctx, json) {\n var nonce = ctx.tParam('nonceCsp"
},
{
"path": "common.blocks/page/page.bemhtml.js",
"chars": 1943,
"preview": "block('page')(\n\n mode('doctype')(function() {\n return { html : this.ctx.doctype || '<!DOCTYPE html>' };\n })"
},
{
"path": "common.blocks/page/page.bh.js",
"chars": 1952,
"preview": "module.exports = function(bh) {\n\n bh.match('page', function(ctx, json) {\n ctx\n .tag('body')\n "
},
{
"path": "common.blocks/page/page.deps.js",
"chars": 149,
"preview": "({\n shouldDeps : [\n { block : 'i-bem-dom', elems : { elem : 'init', mods : { auto : true } } },\n { elem"
},
{
"path": "common.blocks/page/page.en.md",
"chars": 7029,
"preview": "# page\n\nThis block provides templates that create a set of top-level HTML elements for a page: `<html>`, `<head>`, and `"
},
{
"path": "common.blocks/page/page.en.title.txt",
"chars": 39,
"preview": "HTML skeleton (<html>, <head>, <body>)\n"
},
{
"path": "common.blocks/page/page.examples/.bem/level.js",
"chars": 80,
"preview": "exports.baseLevelPath = require.resolve('../../../../.bem/levels/examples.js');\n"
},
{
"path": "common.blocks/page/page.examples/10-simple.bemjson.js",
"chars": 397,
"preview": "({\n block : 'page',\n title : 'Простой пример html/head/body-обвязки страницы',\n favicon : '//bem.info/favicon.i"
},
{
"path": "common.blocks/page/page.examples/10-simple.ru.title.txt",
"chars": 46,
"preview": "Простой пример html/head/body-обвязки страницы"
},
{
"path": "common.blocks/page/page.examples/10-simple.ru.wiki",
"chars": 73,
"preview": "Пример иллюстрирует задание:\n * favicon\n * meta\n * ссылок на css и js"
},
{
"path": "common.blocks/page/page.examples/20-doctype.bemjson.js",
"chars": 246,
"preview": "({\n block : 'page',\n doctype : '<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/"
},
{
"path": "common.blocks/page/page.examples/20-doctype.ru.title.txt",
"chars": 28,
"preview": "Пример произвольного doctype"
},
{
"path": "common.blocks/page/page.ru.md",
"chars": 7101,
"preview": "# page\n\nБлок предоставляет шаблоны, создающие набор HTML-элементов верхнего уровня страницы: `<html>`, `<head>`, `<body>"
},
{
"path": "common.blocks/page/page.ru.title.txt",
"chars": 38,
"preview": "HTML-обвязка (<html>, <head>, <body>)\n"
},
{
"path": "common.blocks/page/page.tmpl-specs/00-empty.bemjson.js",
"chars": 25,
"preview": "({\n block : 'page'\n})\n"
},
{
"path": "common.blocks/page/page.tmpl-specs/00-empty.html",
"chars": 330,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compatible\" conten"
},
{
"path": "common.blocks/page/page.tmpl-specs/10-simple.bemjson.js",
"chars": 367,
"preview": "({\n block : 'page',\n title : 'Простой пример html/head/body-обвязки страницы',\n favicon : '//bem.info/favicon.i"
},
{
"path": "common.blocks/page/page.tmpl-specs/10-simple.html",
"chars": 597,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compatible\" conten"
},
{
"path": "common.blocks/page/page.tmpl-specs/20-style.bemjson.js",
"chars": 111,
"preview": "({\n block : 'page',\n head : {\n elem : 'css',\n content : '.b-blah { color: #f00 }'\n }\n})\n"
},
{
"path": "common.blocks/page/page.tmpl-specs/20-style.html",
"chars": 372,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compatible\" conten"
},
{
"path": "common.blocks/page/page.tmpl-specs/25-styles.bemjson.js",
"chars": 173,
"preview": "({\n block : 'page',\n styles : [\n { elem : 'css', content : '.b-blah { color: red }' },\n { elem : 'cs"
},
{
"path": "common.blocks/page/page.tmpl-specs/25-styles.html",
"chars": 417,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compatible\" conten"
},
{
"path": "common.blocks/page/page.tmpl-specs/30-scripts.bemjson.js",
"chars": 297,
"preview": "({\n block : 'page',\n scripts : [\n { elem : 'js', url : 'https://yastatic.net/jquery/2.1.1/jquery.min.js' },"
},
{
"path": "common.blocks/page/page.tmpl-specs/30-scripts.html",
"chars": 530,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compatible\" conten"
},
{
"path": "common.blocks/page/page.tmpl-specs/40-nonce.bemjson.js",
"chars": 368,
"preview": "({\n block : 'page',\n scripts : [\n { elem : 'js', url : 'https://yastatic.net/jquery/2.1.1/jquery.min.js' },"
},
{
"path": "common.blocks/page/page.tmpl-specs/40-nonce.html",
"chars": 589,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta content=\"IE=edge\" http-equiv=\"X-UA-"
},
{
"path": "common.blocks/page/page.tmpl-specs/60-x-ua-compatible.bemjson.js",
"chars": 89,
"preview": "({\n block : 'page',\n title : 'Remove x-ua-compatible',\n uaCompatible : false\n})\n"
},
{
"path": "common.blocks/page/page.tmpl-specs/60-x-ua-compatible.html",
"chars": 293,
"preview": "<!DOCTYPE HTML>\n<html class=\"ua_js_no\">\n<head>\n <meta charset=\"utf-8\"/>\n <title>Remove x-ua-compatible</title>\n "
},
{
"path": "common.blocks/page/page.tmpl-specs/70-lang.bemjson.js",
"chars": 45,
"preview": "({\n block : 'page',\n lang : 'en-us'\n})\n"
},
{
"path": "common.blocks/page/page.tmpl-specs/70-lang.html",
"chars": 343,
"preview": "<!DOCTYPE html>\n<html class=\"ua_js_no\" lang=\"en-us\">\n<head>\n <meta charset=\"utf-8\"/>\n <meta http-equiv=\"X-UA-Compa"
},
{
"path": "common.blocks/strings/__escape/strings__escape.spec.js",
"chars": 750,
"preview": "modules.define('spec', ['strings__escape'], function(provide, escape) {\n\ndescribe('strings__escape', function() {\n it"
},
{
"path": "common.blocks/strings/__escape/strings__escape.vanilla.js",
"chars": 829,
"preview": "/**\n * @module strings__escape\n * @description A set of string escaping functions\n */\n\nconst symbols = {\n '\"' : '&quo"
},
{
"path": "common.blocks/strings/strings.en.md",
"chars": 2667,
"preview": "# strings\n\nThis block provides helpers for manipulating string data.\n\n## Overview\n\n### Elements of the block\n\n| Element "
},
{
"path": "common.blocks/strings/strings.ru.md",
"chars": 2777,
"preview": "# strings\n\nБлок предоставляет хелперы для манипуляций с данными строчного типа.\n\n## Обзор\n\n### Элементы блока\n\n| Элемент"
},
{
"path": "common.blocks/tick/_start/tick_start_auto.vanilla.js",
"chars": 89,
"preview": "/**\n * Automatically starts tick module\n */\n\nimport tick from 'bem:tick';\n\ntick.start();\n"
},
{
"path": "common.blocks/tick/tick.deps.js",
"chars": 45,
"preview": "({\n shouldDeps : ['events', 'inherit']\n})\n"
},
{
"path": "common.blocks/tick/tick.en.md",
"chars": 2285,
"preview": "# tick\n\nThis block provides an object for working with a regularly generated `tick` event (to implement the polling patt"
},
{
"path": "common.blocks/tick/tick.ru.md",
"chars": 2333,
"preview": "# tick\n\nБлок предоставляет объект для работы с регулярно генерируемым событием `tick` (для реализации паттерна polling)."
},
{
"path": "common.blocks/tick/tick.spec.js",
"chars": 2196,
"preview": "modules.define('spec', [\n 'tick',\n 'sinon'\n], function(provide,\n tick,\n sinon\n) {\n\ndescribe('tick', function"
},
{
"path": "common.blocks/tick/tick.vanilla.js",
"chars": 1316,
"preview": "/**\n * @module tick\n * @description Helpers for polling anything\n */\n\nimport inherit from 'bem:inherit'\nimport events fr"
}
]
// ... and 118 more files (download for full content)
About this extraction
This page contains the full source code of the bem/bem-core GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 318 files (1.2 MB), approximately 322.0k tokens, and a symbol index with 407 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.