1 | 'use strict';
|
2 |
|
3 | var PATH = require('./path'),
|
4 | INHERIT = require('inherit'),
|
5 | bemUtil = require('./util'),
|
6 | createTech = require('./tech').createTech,
|
7 | isRequireable = bemUtil.isRequireable;
|
8 |
|
9 | exports.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 |
|
57 |
|
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 |
|
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 |
|
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 | });
|