Skip to content

Commit

Permalink
Merge 3bdf92d into de78b58
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Abramov committed Nov 8, 2014
2 parents de78b58 + 3bdf92d commit 8761570
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 29 deletions.
36 changes: 34 additions & 2 deletions README.md
Expand Up @@ -10,7 +10,7 @@ This tool allows getting information about BEM entity using [string](#string-rep

String representation
---------------------
To define BEM-entities we often use a special string format that allows us 100% define what entity exactly is represented.
To define BEM entities we often use a special string format that allows us 100% define what entity exactly is represented.

According to original BEM-naming convention it looks like the following:

Expand Down Expand Up @@ -45,7 +45,7 @@ Also there is no such BEM entity as a modifier and an element modifier simultane
BEM-naming
----------

BEM-entities can be defined with a help of js-object with the following fields:
BEM entities can be defined with a help of js-object with the following fields:

* `block` — a block name. The field is required because only a block exists as an independent BEM entity
* `elem` — an element name.
Expand Down Expand Up @@ -103,6 +103,8 @@ API
* [`validate(str)`](#validatestr)
* [`parse(str)`](#parsestr)
* [`stringify(obj)`](#stringifyobj)
* [`typeOf(str)`](#typeofstr)
* [`typeOf(obj)`](#typeofobj)
* [`isBlock(str)`](#isblockstr)
* [`isBlock(obj)`](#isblockobj)
* [`isBlockMod(str)`](#isblockmodstr)
Expand Down Expand Up @@ -153,6 +155,36 @@ bemNaming.stringify({

<hr/>

### `typeOf(str)`

Returns a string indicating the type of the BEM entity.

Example:

```js
bemNaming.typeOf('block'); // block
bemNaming.typeOf('block_mod'); // blockMod
bemNaming.typeOf('block__elem'); // elem
bemNaming.typeOf('block__elem_mod'); // elemMod
```

<hr/>

### `typeOf(obj)`

Returns a string indicating the type of the BEM entity.

Example:

```js
bemNaming.isBlock({ block: 'block' }); // block
bemNaming.isBlock({ block: 'block', modName: 'mod' }); // blockMod
bemNaming.isBlock({ block: 'block', elem: 'elem' }); // elem
bemNaming.isBlock({ block: 'block', elem: 'elem' }); // elemMod
```

<hr/>

### `isBlock(str)`

Checks whether string `str` is a block.
Expand Down
32 changes: 32 additions & 0 deletions README.ru.md
Expand Up @@ -103,6 +103,8 @@ API
* [`validate(str)`](#validatestr)
* [`parse(str)`](#parsestr)
* [`stringify(obj)`](#stringifyobj)
* [`typeOf(str)`](#typeofstr)
* [`typeOf(obj)`](#typeofobj)
* [`isBlock(str)`](#isblockstr)
* [`isBlock(obj)`](#isblockobj)
* [`isBlockMod(str)`](#isblockmodstr)
Expand Down Expand Up @@ -153,6 +155,36 @@ bemNaming.stringify({

<hr/>

### `typeOf(str)`

Возвращает строку, указывающую тип БЭМ-сущности.

Пример:

```js
bemNaming.typeOf('block'); // block
bemNaming.typeOf('block_mod'); // blockMod
bemNaming.typeOf('block__elem'); // elem
bemNaming.typeOf('block__elem_mod'); // elemMod
```

<hr/>

### `typeOf(obj)`

Возвращает строку, указывающую тип БЭМ-сущности.

Пример:

```js
bemNaming.isBlock({ block: 'block' }); // block
bemNaming.isBlock({ block: 'block', modName: 'mod' }); // blockMod
bemNaming.isBlock({ block: 'block', elem: 'elem' }); // elem
bemNaming.isBlock({ block: 'block', elem: 'elem' }); // elemMod
```

<hr/>

### `isBlock(str)`

Проверяет обозначает ли строка `str` блок.
Expand Down
74 changes: 47 additions & 27 deletions lib/bem-naming.js
@@ -1,6 +1,6 @@
(function (global) {
/**
* BEMNaming allows getting information about BEM-entity using string as well as forming string
* BEMNaming allows getting information about BEM entity using string as well as forming string
* representation based on BEM-naming.
*
* @param {Object} [options]
Expand All @@ -26,65 +26,92 @@ var BEMNaming = function (options) {
/**
* Checks a string to be valid BEM notation.
*
* @param {String} str String representation of BEM-entity.
* @param {String} str String representation of BEM entity.
* @returns {Boolean}
*/
BEMNaming.prototype.validate = function (str) {
return this._regex.test(str);
};

/**
* Returns a string indicating the type of the BEM entity.
*
* @param {Object|String} obj BEM-naming object or string representation of BEM entity.
* @returns {String}
*/
BEMNaming.prototype.typeOf = function (obj) {
if (typeof obj === 'string') {
obj = this.parse(obj);
}

if (!obj || !obj.block) { return; }

var hasModVal = obj.hasOwnProperty('modVal'),
isMod = obj.modName && (!hasModVal || obj.modVal);

if (obj.elem) {
if (isMod) {
return 'elemMod';
}

if (!hasModVal) {
return 'elem';
}
}

if (isMod) {
return 'blockMod';
}

if (!hasModVal) {
return 'block';
}
};

/**
* Checks whether BEM-naming object or string is a block.
*
* @param {Object|String} obj BEM-naming object or string representation of BEM-entity.
* @param {Object|String} obj BEM-naming object or string representation of BEM entity.
* @returns {Boolean}
*/
BEMNaming.prototype.isBlock = function (obj) {
obj = this._parse(obj);

return !!obj.block && !obj.modName && !obj.elem;
return this.typeOf(obj) === 'block';
};

/**
* Checks whether BEM-naming object or string is modifier of a block.
*
* @param {Object|String} obj BEM-naming object or string representation of BEM-entity.
* @param {Object|String} obj BEM-naming object or string representation of BEM entity.
* @returns {Boolean}
*/
BEMNaming.prototype.isBlockMod = function (obj) {
obj = this._parse(obj);

return !!(obj.block && obj.modName && (!obj.hasOwnProperty('modVal') || obj.modVal)) && !obj.elem;
return this.typeOf(obj) === 'blockMod';
};

/**
* Checks whether BEM-naming object or string is element of a block.
*
* @param {Object|String} obj BEM-naming object or string representation of BEM-entity.
* @param {Object|String} obj BEM-naming object or string representation of BEM entity.
* @returns {Boolean}
*/
BEMNaming.prototype.isElem = function (obj) {
obj = this._parse(obj);

return !!(obj.block && obj.elem) && !obj.modName;
return this.typeOf(obj) === 'elem';
};

/**
* Checks whether BEM-naming object or string is element of a block.
*
* @param {Object|String} obj BEM-naming object or string representation of BEM-entity.
* @param {Object|String} obj BEM-naming object or string representation of BEM entity.
* @returns {Boolean}
*/
BEMNaming.prototype.isElemMod = function (obj) {
obj = this._parse(obj);

return !!(obj.block && obj.elem && obj.modName && (!obj.hasOwnProperty('modVal') || obj.modVal));
return this.typeOf(obj) === 'elemMod';
};

/**
* Parses string into BEM-naming.
*
* @param {String} str String representation of BEM-entity.
* @param {String} str String representation of BEM entity.
* @returns {Object|undefined}
*/
BEMNaming.prototype.parse = function (str) {
Expand Down Expand Up @@ -152,14 +179,6 @@ BEMNaming.prototype._buildRegex = function () {
this._regex = new RegExp(['^', block, mod, mod, '$|^', block, elem, mod, mod, '$'].join(''));
};

BEMNaming.prototype._parse = function (obj) {
if (typeof obj === 'string') {
obj = this.parse(obj);
}

return obj || {};
};

var defineAsGlobal = true,
originalNaming = new BEMNaming(),
bemNaming = function (options) {
Expand All @@ -170,6 +189,7 @@ bemNaming.BEMNaming = BEMNaming;
bemNaming.validate = function () { return originalNaming.validate.apply(originalNaming, arguments); };
bemNaming.parse = function () { return originalNaming.parse.apply(originalNaming, arguments); };
bemNaming.stringify = function () { return originalNaming.stringify.apply(originalNaming, arguments); };
bemNaming.typeOf = function () { return originalNaming.typeOf.apply(originalNaming, arguments); };
bemNaming.isBlock = function () { return originalNaming.isBlock.apply(originalNaming, arguments); };
bemNaming.isElem = function () { return originalNaming.isElem.apply(originalNaming, arguments); };
bemNaming.isBlockMod = function () { return originalNaming.isBlockMod.apply(originalNaming, arguments); };
Expand Down
90 changes: 90 additions & 0 deletions test/harry-roberts/typeOf.test.js
@@ -0,0 +1,90 @@
var demand = require('should'),
naming = require('../../lib/bem-naming')({ elem: '__', mod: '--' });

describe('harry roberts', function () {
describe('typeOf', function () {
it('should not determine undefined', function () {
var type = naming.typeOf(undefined);

demand(type).be.undefined;
});

it('should not determine empty object', function () {
var type = naming.typeOf({});

demand(type).be.undefined;
});

it('should not determine not valid string', function () {
var type = naming.typeOf('(*)_(*)');

demand(type).be.undefined;
});

it('should not determine not valid object', function () {
var type = naming.typeOf({ elem: 'elem' });

demand(type).be.undefined;
});

it('should determine block by string', function () {
naming.typeOf('block').should.equal('block');
});

it('should determine block by object', function () {
var notation = { block: 'block' };

naming.typeOf(notation).should.equal('block');
});

it('should determine mod of block by string', function () {
naming.typeOf('block--mod--val').should.equal('blockMod');
});

it('should determine mod of block by object', function () {
var notation = { block: 'block', modName: 'mod', modVal: 'val' };

naming.typeOf(notation).should.equal('blockMod');
});

it('should determine boolean mod of block by string', function () {
naming.typeOf('block--mod').should.equal('blockMod');
});

it('should determine boolean mod of block by object', function () {
var notation = { block: 'block', modName: 'mod', modVal: true };

naming.typeOf(notation).should.equal('blockMod');
});

it('should determine elem by string', function () {
naming.typeOf('block__elem').should.equal('elem');
});

it('should determine elem by object', function () {
var notation = { block: 'block', elem: 'elem' };

naming.typeOf(notation).should.equal('elem');
});

it('should determine mod of elem by string', function () {
naming.typeOf('block__elem--mod--value').should.equal('elemMod');
});

it('should determine mod of elem by object', function () {
var notation = { block: 'block', elem: 'elem', modName: 'mod', modVal: 'val' };

naming.typeOf(notation).should.equal('elemMod');
});

it('should determine boolean mod of elem by string', function () {
naming.typeOf('block__elem--mod').should.equal('elemMod');
});

it('should determine boolean mod of elem by object', function () {
var notation = { block: 'block', elem: 'elem', modName: 'mod', modVal: true };

naming.typeOf(notation).should.equal('elemMod');
});
});
});

0 comments on commit 8761570

Please sign in to comment.