UNPKG

3.59 kBJavaScriptView Raw
1'use strict';
2
3var PATH = require('./path'),
4 INHERIT = require('inherit'),
5 bemUtil = require('./util'),
6 createTech = require('./tech').createTech,
7 isRequireable = bemUtil.isRequireable;
8
9exports.Context = INHERIT({
10
11 __constructor: function(level, opts) {
12 var levels = opts.level;
13 this.level = level;
14 this.levels = !levels? [] : Array.isArray(levels)? levels : [levels];
15 this.opts = opts || {};
16 this.techs = this.initOptsTechs();
17 this._techsCache = {};
18 },
19
20 initOptsTechs: function() {
21 var opts = this.opts,
22 techs = {},
23 pathToName = function(techIdent) {
24 var techPath = this.resolveTech(techIdent),
25 techName = bemUtil.isPath(techIdent)?
26 createTech(techPath, null, this.getLevel()).getTechName() :
27 techIdent;
28 techs[techName] = techPath;
29 return techName;
30 };
31 opts.forceTech && (opts.forceTech = opts.forceTech.map(pathToName, this));
32 opts.addTech && (opts.addTech = opts.addTech.map(pathToName, this));
33 opts.noTech && (opts.noTech = opts.noTech.map(pathToName, this));
34 opts.tech && (opts.tech = opts.tech.map(pathToName, this));
35 return techs;
36 },
37
38 getTech: function(name, path) {
39 if(!this._techsCache.hasOwnProperty(name)) {
40 this._techsCache[name] = this.createTech(name, path || name);
41 }
42 return this._techsCache[name];
43 },
44
45 createTech: function(name, path) {
46 return createTech(this.resolveTech(path || name), name, this.getLevel()).setContext(this);
47 },
48
49 resolveTech: function(techIdent) {
50 return (bemUtil.isPath(techIdent) && this.resolveTechPath(techIdent)) ||
51 this.resolveTechName(techIdent) ||
52 bemUtil.getBemTechPath(techIdent);
53 },
54
55 resolveTechName: function(techIdent) {
56 // NOTE: this.techs has not been initialized when resolveTechName() called
57 // from initOptsTechs(). It is not so good as it could be, need to rethink.
58 var techPath = this.techs? this.techs[techIdent] : null;
59 if(techPath || !this.getLevel()) return techPath;
60 return this.getLevel().resolveTechName(techIdent);
61 },
62
63 /* jshint -W109 */
64 resolveTechPath: function(techPath) {
65 // Относительный или абсолютный путь
66 techPath = PATH.absolute(techPath);
67 if(isRequireable(techPath)) {
68 return techPath;
69 }
70
71 throw new Error("Tech module on path '" + techPath + "' not found");
72 },
73 /* jshint +W109 */
74
75 getTechs: function() {
76 return this.opts.tech;
77 },
78
79 getDefaultTechs: function() {
80 // Список технологий по умолчанию с последнего уровня переопределения
81 var defaultTechs = (!this.opts.forceTech && this.getLevel())?
82 this.getLevel().getDefaultTechs() : [],
83 opts = this.opts;
84
85 opts.forceTech && defaultTechs.push.apply(defaultTechs, opts.forceTech);
86 opts.addTech && defaultTechs.push.apply(defaultTechs, opts.addTech);
87 defaultTechs = bemUtil.arrayUnique(defaultTechs);
88 opts.noTech && opts.noTech.forEach(function(t) {
89 defaultTechs.splice(defaultTechs.indexOf(t), 1);
90 });
91
92 return defaultTechs;
93 },
94
95 getLevels: function() {
96 return this.levels;
97 },
98
99 getLevel: function() {
100 return this.level;
101 }
102
103});