forked from cyyjs/scss2css-vscode
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathextension.js
More file actions
218 lines (190 loc) · 7.64 KB
/
extension.js
File metadata and controls
218 lines (190 loc) · 7.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
var vscode = require('vscode');
var fs = require('fs');
var compileSass = require('./lib/sass.node.spk.js');
var pathModule = require('path');
var CompileSassExtension = function () {
// Private fields ---------------------------------------------------------
var outputChannel;
// Constructor ------------------------------------------------------------
outputChannel = vscode.window.createOutputChannel("Scss2Css");
// Private functions ------------------------------------------------------
// Processes result of css file generation.
function handleResult(outputPath, result) {
if (result.status == 0) {
try {
fs.writeFileSync(outputPath, result.text, { flags: "w" });
} catch (e) {
outputChannel.appendLine("Failed to generate CSS: " + e);
}
outputChannel.appendLine("Successfully generated CSS: " + outputPath);
} else {
if (result.formatted) {
outputChannel.appendLine(result.formatted);
} else if (result.message) {
outputChannel.appendLine(result.message);
} else {
outputChannel.appendLine("Failed to generate CSS from SASS, but the error is unknown.");
}
vscode.window.showErrorMessage('Scss2Css: could not generate CSS file. See Output panel for details.');
}
}
// Generates source path for searching scss/sass files for the CompileAll command, based on the sourceDir setting.
// The current workspace folder is used as root.
// The given path is appended to the dir found in the settings.
function generateSourcePath(path) {
var configuration = vscode.workspace.getConfiguration('Scss2Css'), sourceDir = '';
if (configuration.sourceDir != undefined && configuration.sourceDir.length > 0) {
sourceDir = configuration.sourceDir;
}
return pathModule.join(sourceDir, path);
}
// Generates target path for scss/sass file basing on its path
// and Scss2Css.targetDir setting. If the setting specifies
// relative path, current workspace folder is used as root.
function generateTargetPath(path) {
var configuration = vscode.workspace.getConfiguration('Scss2Css');
var targetDir = pathModule.dirname(path);
var filename = pathModule.basename(path);
if (configuration.targetDir != undefined && configuration.targetDir.length > 0) {
if (pathModule.isAbsolute(configuration.targetDir)) {
targetDir = configuration.targetDir;
} else {
var folder = vscode.workspace.rootPath;
if (folder == undefined) {
throw "Path specified in Scss2Css.targetDir is relative, but there is no open folder in VS Code!";
}
targetDir = pathModule.join(folder, configuration.targetDir);
}
}
return {
targetDir: targetDir,
filename: filename
};
}
// Compiles single scss/sass file.
function compileFile(path) {
var configuration = vscode.workspace.getConfiguration('Scss2Css');
outputChannel.appendLine("Scss2Css: compileFile(" + path + ")");
var outputPathData = generateTargetPath(path);
var format, style;
// Iterate through formats from configuration
if (configuration.formats.length == 0) {
throw "No formats are specified. Define Scss2Css.formats setting (or remove to use defaults)";
}
for (var i = 0; i < configuration.formats.length; i++) {
format = configuration.formats[i];
// Evaluate style for sass generator
switch (format.format) {
case "nested":
style = compileSass.Sass.style.nested;
break;
case "compact":
style = compileSass.Sass.style.compact;
break;
case "expanded":
style = compileSass.Sass.style.expanded;
break;
case "compressed":
style = compileSass.Sass.style.compressed;
break;
default:
throw "Invalid format specified for Scss2Css.formats[" + i + "]. Look at setting's hint for available formats.";
}
// Check target extension
if (format.extension == undefined || format.extension.length == 0) {
throw "No extension specified for Scss2Css.formats[" + i + "].";
}
var fileName = outputPathData.filename.substring(0, outputPathData.filename.lastIndexOf('.'));
let mainFile = configuration.mainFile;
if (mainFile) {
path = path.substring(0, path.lastIndexOf('/')) + '/' + mainFile;
fileName = mainFile.substring(0, mainFile.lastIndexOf('.'));
}
var targetPath = pathModule.join(outputPathData.targetDir, fileName + format.extension);
// Using closure to properly pass local variables to callback
(function (path_, targetPath_, style_) {
// Run the compilation process
compileSass(path_, { style: style_ }, function (result) {
handleResult(targetPath_, result);
});
})(path, targetPath, style);
}
}
// Checks whether the file matches the exclude regular expression
function checkExclude(filename) {
var configuration = vscode.workspace.getConfiguration('Scss2Css');
return configuration.excludeRegex.length > 0 && new RegExp(configuration.excludeRegex).test(filename);
}
// Checks wether the path matches the exclude directory regular expression
function checkExcludeDir(path) {
var configuration = vscode.workspace.getConfiguration('Scss2Css');
return configuration.excludeDirRegex.length > 0 && new RegExp(configuration.excludeDirRegex).test(path);
}
function compileAll() {
outputChannel.appendLine("Scss2Css: Compiling all");
// var configuration = vscode.workspace.getConfiguration('Scss2Css');
var sourcePath = generateSourcePath("**/*.s[ac]ss");
outputChannel.appendLine("Scss2Css: sourcePath: " + sourcePath);
vscode.workspace.findFiles(sourcePath).then(function (files) {
var i, filename;
outputChannel.appendLine("Scss2Css: found " + files.length + " files in sourcePath");
for (i = 0; i < files.length; i++) {
outputChannel.appendLine("Scss2Css: filepath: " + files[i].fsPath);
if (checkExcludeDir(files[i].fsPath)) {
outputChannel.appendLine("File " + files[i].fsPath + " is in a directory excluded from building to CSS. Check Scss2Css.excludeDirRegex setting.");
continue;
}
filename = pathModule.basename(files[i].fsPath);
if (checkExclude(filename)) {
outputChannel.appendLine("File " + files[i].fsPath + " is excluded from building to CSS. Check Scss2Css.excludeRegex setting.");
continue;
}
try {
compileFile(files[i].fsPath);
} catch (e) {
vscode.window.showErrorMessage('Scss2Css: could not generate CSS file: ' + e);
}
}
});
}
// Public -----------------------------------------------------------------
return {
OnSave: function (document) {
outputChannel.clear();
outputChannel.show(true);
try {
var configuration = vscode.workspace.getConfiguration('Scss2Css');
var filename = pathModule.basename(document.fileName);
if (configuration.compileAfterSave) {
if (document.fileName.toLowerCase().endsWith('.scss') || document.fileName.toLowerCase().endsWith('.sass')) {
if (!checkExclude(filename)) {
compileFile(document.fileName);
} else if (configuration.compileAllAfterSaveExcluded) {
compileAll();
} else {
outputChannel.appendLine("File " + document.fileName + " is excluded from building to CSS. Check Scss2Css.excludeRegex setting.");
}
}
}
} catch (e) {
vscode.window.showErrorMessage('Scss2Css: could not generate CSS file: ' + e);
}
},
CompileAll: function () {
outputChannel.clear();
outputChannel.show(true);
compileAll();
}
};
};
function activate(context) {
var extension = CompileSassExtension();
vscode.workspace.onDidSaveTextDocument(function (document) { extension.OnSave(document) });
var disposable = vscode.commands.registerCommand('Scss2Css.compileAll', function () {
extension.CompileAll();
});
context.subscriptions.push(disposable);
}
function deactivate() { }
exports.activate = activate;
exports.deactivate = deactivate;