|
1 | 1 | 'use strict';
|
2 | 2 |
|
3 |
| -const util = require('util'); |
4 |
| - |
5 |
| -const stringifyEntity = require('@bem/naming').stringify; |
6 |
| -const deprecate = require('depd')(require('./package.json').name); |
7 |
| - |
8 |
| -const EntityTypeError = require('./lib/entity-type-error'); |
9 |
| - |
10 |
| -/** |
11 |
| - * Enum for types of BEM entities. |
12 |
| - * |
13 |
| - * @readonly |
14 |
| - * @enum {string} |
15 |
| - */ |
16 |
| -const TYPES = { |
17 |
| - BLOCK: 'block', |
18 |
| - BLOCK_MOD: 'blockMod', |
19 |
| - ELEM: 'elem', |
20 |
| - ELEM_MOD: 'elemMod' |
21 |
| -}; |
22 |
| - |
23 |
| -class BemEntityName { |
24 |
| - /** |
25 |
| - * @param {BemSDK.EntityName.Options} obj — representation of entity name. |
26 |
| - */ |
27 |
| - constructor(obj) { |
28 |
| - if (!obj.block) { |
29 |
| - throw new EntityTypeError(obj, 'the field `block` is undefined'); |
30 |
| - } |
31 |
| - |
32 |
| - const data = this._data = { block: obj.block }; |
33 |
| - |
34 |
| - obj.elem && (data.elem = obj.elem); |
35 |
| - |
36 |
| - const modObj = obj.mod; |
37 |
| - const modName = (typeof modObj === 'string' ? modObj : modObj && modObj.name) || obj.modName; |
38 |
| - const hasModVal = modObj && modObj.hasOwnProperty('val') || obj.hasOwnProperty('modVal'); |
39 |
| - |
40 |
| - if (modName) { |
41 |
| - data.mod = { |
42 |
| - name: modName, |
43 |
| - val: hasModVal ? modObj && modObj.val || obj.modVal : true |
44 |
| - }; |
45 |
| - } else if (modObj || hasModVal) { |
46 |
| - throw new EntityTypeError(obj, 'the field `mod.name` is undefined'); |
47 |
| - } |
48 |
| - |
49 |
| - this.__isBemEntityName__ = true; |
50 |
| - } |
51 |
| - |
52 |
| - /** |
53 |
| - * Returns the name of block to which this entity belongs. |
54 |
| - * |
55 |
| - * @example |
56 |
| - * const BemEntityName = require('@bem/entity-name'); |
57 |
| - * const name = new BemEntityName({ block: 'button' }); |
58 |
| - * |
59 |
| - * name.block; // button |
60 |
| - * |
61 |
| - * @returns {string} name of entity block. |
62 |
| - */ |
63 |
| - get block() { return this._data.block; } |
64 |
| - |
65 |
| - /** |
66 |
| - * Returns the element name of this entity. |
67 |
| - * |
68 |
| - * If entity is not element or modifier of element then returns empty string. |
69 |
| - * |
70 |
| - * @example |
71 |
| - * const BemEntityName = require('@bem/entity-name'); |
72 |
| - * const name = new BemEntityName({ block: 'button', elem: 'text' }); |
73 |
| - * |
74 |
| - * name.elem; // text |
75 |
| - * |
76 |
| - * @returns {?string} - name of entity element. |
77 |
| - */ |
78 |
| - get elem() { return this._data.elem; } |
79 |
| - |
80 |
| - /** |
81 |
| - * Returns the modifier of this entity. |
82 |
| - * |
83 |
| - * Important: If entity is not a modifier then returns `undefined`. |
84 |
| - * |
85 |
| - * @example |
86 |
| - * const BemEntityName = require('@bem/entity-name'); |
87 |
| - * |
88 |
| - * const blockName = new BemEntityName({ block: 'button' }); |
89 |
| - * const modName = new BemEntityName({ block: 'button', mod: 'disabled' }); |
90 |
| - * |
91 |
| - * modName.mod; // { name: 'disabled', val: true } |
92 |
| - * blockName.mod; // undefined |
93 |
| - * |
94 |
| - * @returns {?BemSDK.EntityName.ModifierRepresentation} - entity modifier. |
95 |
| - */ |
96 |
| - get mod() { return this._data.mod; } |
97 |
| - |
98 |
| - /** |
99 |
| - * Returns the modifier name of this entity. |
100 |
| - * |
101 |
| - * If entity is not modifier then returns `undefined`. |
102 |
| - * |
103 |
| - * @returns {?string} - entity modifier name. |
104 |
| - * @deprecated use {@link BemEntityName#mod.name} |
105 |
| - */ |
106 |
| - get modName() { |
107 |
| - deprecate(`modName is kept just for compatibility and can be dropped in the future. Use mod.name instead in ${this.inspect()} at`); |
108 |
| - |
109 |
| - return this.mod && this.mod.name; |
110 |
| - } |
111 |
| - |
112 |
| - /** |
113 |
| - * Returns the modifier value of this entity. |
114 |
| - * |
115 |
| - * If entity is not modifier then returns `undefined`. |
116 |
| - * |
117 |
| - * @returns {?(string|true)} - entity modifier name. |
118 |
| - * @deprecated use {@link BemEntityName#mod.val} |
119 |
| - */ |
120 |
| - get modVal() { |
121 |
| - deprecate(`modVal is kept just for compatibility and can be dropped in the future. Use mod.val instead in ${this.inspect()} at`); |
122 |
| - |
123 |
| - return this.mod && this.mod.val; |
124 |
| - } |
125 |
| - |
126 |
| - /** |
127 |
| - * Returns id for this entity. |
128 |
| - * |
129 |
| - * Important: should only be used to determine uniqueness of entity. |
130 |
| - * |
131 |
| - * If you want to get string representation in accordance with the provisions naming convention |
132 |
| - * you should use `@bem/naming` package. |
133 |
| - * |
134 |
| - * @example |
135 |
| - * const BemEntityName = require('@bem/entity-name'); |
136 |
| - * const name = new BemEntityName({ block: 'button', mod: 'disabled' }); |
137 |
| - * |
138 |
| - * name.id; // button_disabled |
139 |
| - * |
140 |
| - * @returns {string} - id of entity. |
141 |
| - */ |
142 |
| - get id() { |
143 |
| - if (this._id) { return this._id; } |
144 |
| - |
145 |
| - this._id = stringifyEntity(this._data); |
146 |
| - |
147 |
| - return this._id; |
148 |
| - } |
149 |
| - |
150 |
| - /** |
151 |
| - * Returns type for this entity. |
152 |
| - * |
153 |
| - * @example <caption>type of element</caption> |
154 |
| - * const BemEntityName = require('@bem/entity-name'); |
155 |
| - * const name = new BemEntityName({ block: 'button', elem: 'text' }); |
156 |
| - * |
157 |
| - * name.type; // elem |
158 |
| - * |
159 |
| - * @example <caption>type of element modifier</caption> |
160 |
| - * const BemEntityName = require('@bem/entity-name'); |
161 |
| - * const name = new BemEntityName({ block: 'menu', elem: 'item', mod: 'current' }); |
162 |
| - * |
163 |
| - * name.type; // elemMod |
164 |
| - * |
165 |
| - * @returns {string} - type of entity. One of 'block', 'elem', 'blockMod', 'elemMod'. |
166 |
| - */ |
167 |
| - get type() { |
168 |
| - if (this._type) { return this._type; } |
169 |
| - |
170 |
| - const data = this._data; |
171 |
| - const isMod = data.mod; |
172 |
| - |
173 |
| - this._type = data.elem |
174 |
| - ? isMod ? TYPES.ELEM_MOD : TYPES.ELEM |
175 |
| - : isMod ? TYPES.BLOCK_MOD : TYPES.BLOCK; |
176 |
| - |
177 |
| - return this._type; |
178 |
| - } |
179 |
| - |
180 |
| - /** |
181 |
| - * Determines whether modifier simple or not |
182 |
| - * |
183 |
| - * @example <caption>simple mod</caption> |
184 |
| - * const BemEntityName = require('@bem/entity-name'); |
185 |
| - * const name = new BemEntityName({ block: 'button', mod: { name: 'theme' } }); |
186 |
| - * |
187 |
| - * name.isSimpleMod(); // true |
188 |
| - * |
189 |
| - * @example <caption>mod with value</caption> |
190 |
| - * const BemEntityName = require('@bem/entity-name'); |
191 |
| - * const name = new BemEntityName({ block: 'button', mod: { name: 'theme', val: 'normal' } }); |
192 |
| - * |
193 |
| - * name.isSimpleMod(); // false |
194 |
| - * |
195 |
| - * @example <caption>block</caption> |
196 |
| - * const BemEntityName = require('@bem/entity-name'); |
197 |
| - * const name = new BemEntityName({ block: 'button' }); |
198 |
| - * |
199 |
| - * name.isSimpleMod(); // null |
200 |
| - * |
201 |
| - * @returns {(boolean|null)} |
202 |
| - */ |
203 |
| - isSimpleMod() { |
204 |
| - return this.mod ? this.mod.val === true : null; |
205 |
| - } |
206 |
| - |
207 |
| - /** |
208 |
| - * Returns string representing the entity name. |
209 |
| - * |
210 |
| - * Important: If you want to get string representation in accordance with the provisions naming convention |
211 |
| - * you should use `@bem/naming` package. |
212 |
| - * |
213 |
| - * @example |
214 |
| - * const BemEntityName = require('@bem/entity-name'); |
215 |
| - * const name = new BemEntityName({ block: 'button', mod: 'focused' }); |
216 |
| - * |
217 |
| - * name.toString(); // button_focused |
218 |
| - * |
219 |
| - * @returns {string} |
220 |
| - */ |
221 |
| - toString() { return this.id; } |
222 |
| - |
223 |
| - /** |
224 |
| - * Returns object representing the entity name. Is needed for debug in Node.js. |
225 |
| - * |
226 |
| - * In some browsers `console.log()` calls `valueOf()` on each argument. |
227 |
| - * This method will be called to get custom string representation of the object. |
228 |
| - * |
229 |
| - * The representation object contains only `block`, `elem` and `mod` fields |
230 |
| - * without private and deprecated fields (`modName` and `modVal`). |
231 |
| - * |
232 |
| - * @example |
233 |
| - * const BemEntityName = require('@bem/entity-name'); |
234 |
| - * const name = new BemEntityName({ block: 'button', mod: 'focused' }); |
235 |
| - * |
236 |
| - * name.valueOf(); |
237 |
| - * |
238 |
| - * // ➜ { block: 'button', mod: { name: 'focused', value: true } } |
239 |
| - * |
240 |
| - * @returns {BemSDK.EntityName.StrictRepresentation} |
241 |
| - */ |
242 |
| - valueOf() { return this._data; } |
243 |
| - |
244 |
| - /** |
245 |
| - * Returns object representing the entity name. Is needed for debug in Node.js. |
246 |
| - * |
247 |
| - * In Node.js, `console.log()` calls `util.inspect()` on each argument without a formatting placeholder. |
248 |
| - * This method will be called to get custom string representation of the object. |
249 |
| - * |
250 |
| - * The representation object contains only `block`, `elem` and `mod` fields |
251 |
| - * without private and deprecated fields (`modName` and `modVal`). |
252 |
| - * |
253 |
| - * @example |
254 |
| - * const BemEntityName = require('@bem/entity-name'); |
255 |
| - * const name = new BemEntityName({ block: 'button' }); |
256 |
| - * |
257 |
| - * console.log(name); // BemEntityName { block: 'button' } |
258 |
| - * |
259 |
| - * @param {number} depth — tells inspect how many times to recurse while formatting the object. |
260 |
| - * @param {object} options — An optional `options` object may be passed |
261 |
| - * that alters certain aspects of the formatted string. |
262 |
| - * |
263 |
| - * @returns {string} |
264 |
| - */ |
265 |
| - inspect(depth, options) { |
266 |
| - const stringRepresentation = util.inspect(this._data, options); |
267 |
| - |
268 |
| - return `BemEntityName ${stringRepresentation}`; |
269 |
| - } |
270 |
| - |
271 |
| - /** |
272 |
| - * Return raw data for `JSON.stringify()`. |
273 |
| - * |
274 |
| - * @returns {BemSDK.EntityName.StrictRepresentation} |
275 |
| - */ |
276 |
| - toJSON() { |
277 |
| - return this._data; |
278 |
| - } |
279 |
| - |
280 |
| - /** |
281 |
| - * Determines whether specified entity is the deepEqual entity. |
282 |
| - * |
283 |
| - * @example |
284 |
| - * const BemEntityName = require('@bem/entity-name'); |
285 |
| - * |
286 |
| - * const inputName = new BemEntityName({ block: 'input' }); |
287 |
| - * const buttonName = new BemEntityName({ block: 'button' }); |
288 |
| - * |
289 |
| - * inputName.isEqual(buttonName); // false |
290 |
| - * buttonName.isEqual(buttonName); // true |
291 |
| - * |
292 |
| - * @param {BemEntityName} entityName - the entity to compare. |
293 |
| - * @returns {boolean} - A Boolean indicating whether or not specified entity is the deepEqual entity. |
294 |
| - */ |
295 |
| - isEqual(entityName) { |
296 |
| - return entityName && (this.id === entityName.id); |
297 |
| - } |
298 |
| - |
299 |
| - /** |
300 |
| - * Determines whether specified entity belongs to this. |
301 |
| - * |
302 |
| - * @example |
303 |
| - * const BemEntityName = require('@bem/entity-name'); |
304 |
| - * |
305 |
| - * const buttonName = new BemEntityName({ block: 'button' }); |
306 |
| - * const buttonTextName = new BemEntityName({ block: 'button', elem: 'text' }); |
307 |
| - * const buttonTextBoldName = new BemEntityName({ block: 'button', elem: 'text', mod: 'bold' }); |
308 |
| - * |
309 |
| - * buttonTextName.belongsTo(buttonName); // true |
310 |
| - * buttonName.belongsTo(buttonTextName); // false |
311 |
| - * buttonTextBoldName.belongsTo(buttonTextName); // true |
312 |
| - * buttonTextBoldName.belongsTo(buttonName); // false |
313 |
| - * |
314 |
| - * @param {BemEntityName} entityName - the entity to compare. |
315 |
| - * |
316 |
| - * @returns {boolean} |
317 |
| - */ |
318 |
| - belongsTo(entityName) { |
319 |
| - if (entityName.block !== this.block) { return false; } |
320 |
| - |
321 |
| - return entityName.type === TYPES.BLOCK && (this.type === TYPES.BLOCK_MOD || this.type === TYPES.ELEM) |
322 |
| - || entityName.elem === this.elem && (entityName.type === TYPES.ELEM && this.type === TYPES.ELEM_MOD); |
323 |
| - } |
324 |
| - |
325 |
| - /** |
326 |
| - * Determines whether specified entity is instance of BemEntityName. |
327 |
| - * |
328 |
| - * @example |
329 |
| - * const BemEntityName = require('@bem/entity-name'); |
330 |
| - * |
331 |
| - * const entityName = new BemEntityName({ block: 'input' }); |
332 |
| - * |
333 |
| - * BemEntityName.isBemEntityName(entityName); // true |
334 |
| - * BemEntityName.isBemEntityName({}); // false |
335 |
| - * |
336 |
| - * @param {*} entityName - the entity to check. |
337 |
| - * @returns {boolean} A Boolean indicating whether or not specified entity is instance of BemEntityName. |
338 |
| - */ |
339 |
| - static isBemEntityName(entityName) { |
340 |
| - return entityName && entityName.__isBemEntityName__; |
341 |
| - } |
342 |
| - |
343 |
| - /** |
344 |
| - * Creates BemEntityName instance by any object representation. |
345 |
| - * |
346 |
| - * @example |
347 |
| - * const BemEntityName = require('@bem/entity-name'); |
348 |
| - * |
349 |
| - * BemEntityName.create({ block: 'my-button', mod: 'theme', val: 'red' }); |
350 |
| - * BemEntityName.create({ block: 'my-button', modName: 'theme', modVal: 'red' }); |
351 |
| - * // → BemEntityName { block: 'my-button', mod: { name: 'theme', val: 'red' } } |
352 |
| - * |
353 |
| - * @param {(BemSDK.EntityName.NonStrictRepresentation|string)} obj — representation of entity name. |
354 |
| - * @returns {BemEntityName} An object representing entity name. |
355 |
| - */ |
356 |
| - static create(obj) { |
357 |
| - if (BemEntityName.isBemEntityName(obj)) { |
358 |
| - return obj; |
359 |
| - } |
360 |
| - |
361 |
| - if (typeof obj === 'string') { |
362 |
| - obj = { block: obj }; |
363 |
| - } |
364 |
| - |
365 |
| - const data = { block: obj.block }; |
366 |
| - const mod = obj.mod; |
367 |
| - |
368 |
| - obj.elem && (data.elem = obj.elem); |
369 |
| - |
370 |
| - if (mod || obj.modName) { |
371 |
| - const isString = typeof mod === 'string'; |
372 |
| - const modName = (isString ? mod : mod && mod.name) || obj.modName; |
373 |
| - const modObj = !isString && mod || obj; |
374 |
| - const hasModVal = modObj.hasOwnProperty('val') || obj.hasOwnProperty('modVal'); |
375 |
| - |
376 |
| - data.mod = { |
377 |
| - name: modName, |
378 |
| - val: hasModVal ? modObj.val || obj.modVal : true |
379 |
| - }; |
380 |
| - } |
381 |
| - |
382 |
| - return new BemEntityName(data); |
383 |
| - } |
384 |
| -} |
385 |
| - |
386 |
| -module.exports = BemEntityName; |
387 |
| - |
388 |
| -// TypeScript imports the `default` property for |
389 |
| -// an ES2015 default import (`import BemEntityName from '@bem/entity-name'`) |
390 |
| -// See: https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-83694181 |
391 |
| -module.exports.default = BemEntityName; |
| 3 | +module.exports = require('./lib/entity-name'); |
0 commit comments