From b3e1d7c2eee07e528790de188ddf647fe143a724 Mon Sep 17 00:00:00 2001 From: Vasiliy Loginevskiy Date: Mon, 12 Mar 2018 15:19:23 +0300 Subject: [PATCH 1/2] fix(import-notation): parsing modifiers with scope Previous decision was wrong we actually need to extract main entity Check this issue: https://github.com/bem/webpack-bem-loader/issues/64 Natural dependencies were broken --- packages/import-notation/README.md | 7 ++----- packages/import-notation/index.js | 1 + packages/import-notation/test/parse.test.js | 15 +++++++++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/import-notation/README.md b/packages/import-notation/README.md index 2e0a4bf1..469fdc9b 100644 --- a/packages/import-notation/README.md +++ b/packages/import-notation/README.md @@ -63,14 +63,11 @@ Context allows to extract portion of entities. ```js var enties = parse('m:theme=normal', { block: 'button' }); -// → [ { block: 'button', mod: { name: 'theme' } }, +// → [ { block: 'button' }, +// { block: 'button', mod: { name: 'theme' } }, // { block: 'button', mod: { name: 'theme', val: 'normal' } } ] ``` -Note that, using context exludes `{ block: 'button'}` from result. - -So `parse('m:theme=normal', { block: 'button' })` is not same as `parse('b:button m:theme=normal')` - ### stringify Parameter | Type | Description diff --git a/packages/import-notation/index.js b/packages/import-notation/index.js index 844a76ec..8f0a7ead 100644 --- a/packages/import-notation/index.js +++ b/packages/import-notation/index.js @@ -58,6 +58,7 @@ function parse(importString, ctx) { if(!main.block) { main.block = ctx.block; main.elem || ctx.elem && (main.elem = ctx.elem); + acc.add(main); } if(type === 'm') { diff --git a/packages/import-notation/test/parse.test.js b/packages/import-notation/test/parse.test.js index 31b35f87..78c5a695 100644 --- a/packages/import-notation/test/parse.test.js +++ b/packages/import-notation/test/parse.test.js @@ -70,12 +70,14 @@ describe('block', () => { describe('context is block', () => { it('should extract blockMod', () => { expect(p('m:autoclosable', { block : 'popup' })).to.eql([ + { block : 'popup' }, { block : 'popup', mod : { name : 'autoclosable' } } ]); }); it('should extract block with modifier', () => { expect(p('m:autoclosable=yes', { block : 'popup' })).to.eql([ + { block : 'popup' }, { block : 'popup', mod : { name : 'autoclosable' } }, { block : 'popup', mod : { name : 'autoclosable', val : 'yes' } } ]); @@ -83,6 +85,7 @@ describe('block', () => { it('should extract blockMod with several values', () => { expect(p('m:theme=normal|action', { block : 'popup' })).to.eql([ + { block : 'popup' }, { block : 'popup', mod : { name : 'theme' } }, { block : 'popup', mod : { name : 'theme', val : 'normal' } }, { block : 'popup', mod : { name : 'theme', val : 'action' } } @@ -91,6 +94,7 @@ describe('block', () => { it('should extract blockMod with several modifiers', () => { expect(p('m:theme m:autoclosable', { block : 'popup' })).to.eql([ + { block : 'popup' }, { block : 'popup', mod : { name : 'theme' } }, { block : 'popup', mod : { name : 'autoclosable' } } ]); @@ -98,6 +102,7 @@ describe('block', () => { it('should extract blockMods with several modifiers and several values', () => { expect(p('m:theme=normal|action m:autoclosable=yes', { block : 'popup' })).to.eql([ + { block : 'popup' }, { block : 'popup', mod : { name : 'theme' } }, { block : 'popup', mod : { name : 'theme', val : 'normal' } }, { block : 'popup', mod : { name : 'theme', val : 'action' } }, @@ -323,12 +328,14 @@ describe('elem', () => { describe('context is elem', () => { it('should extract elem with simple modifier', () => { expect(p('m:pseudo', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'pseudo' } } ]); }); it('should extract elem with modifier', () => { expect(p('m:pseudo=yes', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'pseudo' } }, { block : 'button2', elem : 'text', mod : { name : 'pseudo', val : 'yes' } } ]); @@ -336,6 +343,7 @@ describe('elem', () => { it('should extract elem with modifier and several values', () => { expect(p('m:theme=normal|action', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'theme' } }, { block : 'button2', elem : 'text', mod : { name : 'theme', val : 'normal' } }, { block : 'button2', elem : 'text', mod : { name : 'theme', val : 'action' } } @@ -344,6 +352,7 @@ describe('elem', () => { it('should extract elem with several modifiers', () => { expect(p('m:theme m:autoclosable', { block : 'popup', elem : 'tail' })).to.eql([ + { block : 'popup', elem : 'tail' }, { block : 'popup', elem : 'tail', mod : { name : 'theme' } }, { block : 'popup', elem : 'tail', mod : { name : 'autoclosable' } } ]); @@ -353,6 +362,7 @@ describe('elem', () => { expect( p('m:theme=normal|action m:autoclosable=yes', { block : 'popup', elem : 'tail' }) ).to.eql([ + { block : 'popup', elem : 'tail' }, { block : 'popup', elem : 'tail', mod : { name : 'theme' } }, { block : 'popup', elem : 'tail', mod : { name : 'theme', val : 'normal' } }, { block : 'popup', elem : 'tail', mod : { name : 'theme', val : 'action' } }, @@ -418,12 +428,14 @@ describe('elem', () => { describe('context is current elem', () => { it('should extract elem with simple modifier', () => { expect(p('e:text m:pseudo', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'pseudo' } } ]); }); it('should extract elem with modifier', () => { expect(p('e:text m:pseudo=yes', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'pseudo' } }, { block : 'button2', elem : 'text', mod : { name : 'pseudo', val : 'yes' } } ]); @@ -431,6 +443,7 @@ describe('elem', () => { it('should extract elem with modifier and several values', () => { expect(p('e:text m:theme=normal|action', { block : 'button2', elem : 'text' })).to.eql([ + { block : 'button2', elem : 'text' }, { block : 'button2', elem : 'text', mod : { name : 'theme' } }, { block : 'button2', elem : 'text', mod : { name : 'theme', val : 'normal' } }, { block : 'button2', elem : 'text', mod : { name : 'theme', val : 'action' } } @@ -439,6 +452,7 @@ describe('elem', () => { it('should extract elem with several modifiers', () => { expect(p('e:tail m:theme m:autoclosable', { block : 'popup', elem : 'tail' })).to.eql([ + { block : 'popup', elem : 'tail' }, { block : 'popup', elem : 'tail', mod : { name : 'theme' } }, { block : 'popup', elem : 'tail', mod : { name : 'autoclosable' } } ]); @@ -448,6 +462,7 @@ describe('elem', () => { expect( p('e:tail m:theme=normal|action m:autoclosable=yes', { block : 'popup', elem : 'tail' }) ).to.eql([ + { block : 'popup', elem : 'tail' }, { block : 'popup', elem : 'tail', mod : { name : 'theme' } }, { block : 'popup', elem : 'tail', mod : { name : 'theme', val : 'normal' } }, { block : 'popup', elem : 'tail', mod : { name : 'theme', val : 'action' } }, From fc3d418f9ce958e62ce97e0c0abe545d6ee18605 Mon Sep 17 00:00:00 2001 From: Vasiliy Loginevskiy Date: Wed, 28 Mar 2018 14:01:05 +0300 Subject: [PATCH 2/2] docs(import-notation): fix after review --- packages/import-notation/README.md | 10 +++++----- packages/import-notation/index.js | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/import-notation/README.md b/packages/import-notation/README.md index 469fdc9b..c2c865f3 100644 --- a/packages/import-notation/README.md +++ b/packages/import-notation/README.md @@ -36,15 +36,15 @@ parse('b:button m:theme=normal|action'); API --- -* [parse](#parsestr-ctx) +* [parse](#parsestr-scope) * [stringify](#stringify) -### parse(str, ctx) +### parse(str, [scope]) Parameter | Type | Description ----------|----------|-------------------------------------------------------- `str` | `string` | BEM import notation check [notation section](#notation) -`ctx` | `object` | BEM entity name representation. +[`scope`] | `object` | BEM entity name representation. Parses the string into BEM entities. @@ -56,7 +56,7 @@ entity.block // → 'button' entity.elem // → 'text' ``` -#### ctx +#### scope Context allows to extract portion of entities. @@ -81,7 +81,7 @@ Notation -------- This section describes all possible syntax of BEM import strings. -Examples are provided in es6 syntax. Note that [parse](#parsestr-ctx) function only works with strings. +Examples are provided in es6 syntax. Note that [parse](#parsestr-scope) function only works with strings. Right now order of fields is important, check [issue](https://github.com/bem-sdk-archive/bem-import-notation/issues/12): diff --git a/packages/import-notation/index.js b/packages/import-notation/index.js index 8f0a7ead..009ac10e 100644 --- a/packages/import-notation/index.js +++ b/packages/import-notation/index.js @@ -31,14 +31,14 @@ const BemCellSet = hashSet(cell => * * @public * @param {String} importString - string Literal from import statement - * @param {BemEntity} [ctx] - entity to restore `block` part + * @param {BemEntity} [scope] - entity to restore `block`/`elem` base name * it's needed for short syntax: `import 'e:elemOfThisBlock'` * `import 'm:modOfThisBlock` * @returns {BemCell[]} */ -function parse(importString, ctx) { +function parse(importString, scope) { const main = {}; - ctx || (ctx = {}); + scope || (scope = {}); return Array.from(importString.split(' ').reduce((acc, importToken) => { const split = importToken.split(':'), @@ -50,14 +50,14 @@ function parse(importString, ctx) { acc.add(main); } else if(type === 'e') { main.elem = tail; - if(!main.block && ctx.elem !== tail) { - main.block = ctx.block; + if(!main.block && scope.elem !== tail) { + main.block = scope.block; acc.add(main); } } else if(type === 'm' || type === 't') { if(!main.block) { - main.block = ctx.block; - main.elem || ctx.elem && (main.elem = ctx.elem); + main.block = scope.block; + main.elem || scope.elem && (main.elem = scope.elem); acc.add(main); }