-
Notifications
You must be signed in to change notification settings - Fork 0
/
motley.js
151 lines (135 loc) · 4.29 KB
/
motley.js
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
/*!
* Motley CSS (https://github.com/aasierra/Motley-CSS)
* Copyright (c) 2014 Anthony A Sierra
* Licensed under MIT (https://github.com/aasierra/Motley-CSS/LICENSE)
*/
/*
The motley global object takes in the following options
{
fileName:'',
limit:4000,
diagnostics:false,
callback:Function,
compress:false
}
*/
var other = require('line-by-line');
module.exports = function (options) {
if (!options.fileName) {
console.log("'fileName' NOT FOUND NEED FILENAME FOR FILE TO PARSE");
}
//Get the line by line library
var lbl = require('line-by-line');
//Get the file to start parsing line by line.
var lr = new lbl(options.fileName);
//A flag during parse to know when we are in the middle of parsing a comment
var inComment = false;
//A count of the amount of comments in the file.
var commentCount = 0;
//The files that will be created at the end.
var files = [];
//The file output string for each file that will be altered throughout the algorithm.
var fileOutput = "";
//An selector count to keep track of while iterating the file.
var selectorCount = 0;
//A total selector count for diagnostics at the end.
var totalSelectorCount = 0;
//The IE8 limit that is imposed on CSS files.
var selectorLimit = (options.limit) ? options.limit : 4095;
//A flag to be used while parsing to know whether we are about to create a new file or not.
var nextClear = false;
//An amount that lets us know how many nests we are entering so we can leave them before cutting the file off.
var contextCount = 0;
var selectorBuffer = "";
if (options.diagnostics) {
console.log("Starting");
}
lr.on("error", function (error) {
console.log("Operation could not be completed : " + error);
});
lr.on("line", function (line) {
if (line.indexOf("/*") >= 0) {
inComment = true;
commentCount++;
}
if (!inComment) {
selectorBuffer += (options.compress) ? line : "\n" + line;
if(line.indexOf("{") >= 0) {
//If we find any commas because the selector being a multi line selector or possibly
//This bracket is on a new line then we need to go back and count the commas.
//If there was no commas then this is a single selector
if (selectorBuffer.indexOf("@media") < 0 && contextCount == 0 && selectorBuffer.split(",") && selectorBuffer.split(",").length) {
selectorCount += selectorBuffer.split(',').length;
} else if (selectorBuffer.indexOf('@media') >= 0 && contextCount == 1) {
var afterQuery = selectorBuffer.substring(selectorBuffer.indexOf("{"), selectorBuffer.length);
selectorCount += afterQuery.split(",").length;
} else {
selectorCount++;
}
contextCount++;
if (selectorCount >= selectorLimit) {
nextClear = true;
}
}
if (line.indexOf("}") >= 0) {
contextCount--;
if (contextCount == 0) {
fileOutput += "\n" + selectorBuffer;
selectorBuffer = "";
}
if (nextClear && contextCount == 0) {
files.push(fileOutput);
fileOutput = "";
totalSelectorCount += selectorCount;
selectorCount = 0;
nextClear = false;
}
}
}
if (line.indexOf("*/") >= 0) {
inComment = false;
}
});
lr.on("end", function () {
var fs = require("fs");
files.push(fileOutput);
totalSelectorCount += selectorCount;
for (var i = 0; i < files.length; i++) {
var fileName = options.fileName;
if (i > 0) {
fileName = fileName.substring(0, fileName.indexOf(".css")) + i + ".css";
}
var importName = "";
if (i + 1 < files.length) {
if (fileName.match("/").length) {
var parts = options.fileName.split("/");
if (parts.length) {
var toSubString = parts[parts.length-1];
importName = toSubString.substring(0, toSubString.indexOf(".css")) + (i + 1) + ".css";
}
} else {
importName = fileName.substring(0, options.fileName.indexOf(".css")) + (i + 1) + ".css";
}
}
var importText = "";
if (importName) {
importText = "@import url('" + importName + "');\n";
}
var outputPrint = function (error) {
if (error) {
console.log(error);
} else {
console.log("File was created.");
}
};
fs.writeFile(fileName, importText + files[i], outputPrint);
}
if (options.diagnostics) {
console.log("Comments : " + commentCount);
console.log("Selectors : " + totalSelectorCount);
}
if(options.callback) {
options.callback();
}
});
}