mirror of
https://github.com/less/less.js.git
synced 2026-01-22 13:48:03 -05:00
113 lines
5.0 KiB
JavaScript
113 lines
5.0 KiB
JavaScript
// Split the input into chunks.
|
|
module.exports = function (input, fail) {
|
|
var len = input.length, level = 0, parenLevel = 0,
|
|
lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace,
|
|
chunks = [], emitFrom = 0,
|
|
chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched;
|
|
|
|
function emitChunk(force) {
|
|
var len = chunkerCurrentIndex - emitFrom;
|
|
if (((len < 512) && !force) || !len) {
|
|
return;
|
|
}
|
|
chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
|
|
emitFrom = chunkerCurrentIndex + 1;
|
|
}
|
|
|
|
for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
cc = input.charCodeAt(chunkerCurrentIndex);
|
|
if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
|
|
// a-z or whitespace
|
|
continue;
|
|
}
|
|
|
|
switch (cc) {
|
|
case 40: // (
|
|
parenLevel++;
|
|
lastOpeningParen = chunkerCurrentIndex;
|
|
continue;
|
|
case 41: // )
|
|
if (--parenLevel < 0) {
|
|
return fail("missing opening `(`", chunkerCurrentIndex);
|
|
}
|
|
continue;
|
|
case 59: // ;
|
|
if (!parenLevel) { emitChunk(); }
|
|
continue;
|
|
case 123: // {
|
|
level++;
|
|
lastOpening = chunkerCurrentIndex;
|
|
continue;
|
|
case 125: // }
|
|
if (--level < 0) {
|
|
return fail("missing opening `{`", chunkerCurrentIndex);
|
|
}
|
|
if (!level && !parenLevel) { emitChunk(); }
|
|
continue;
|
|
case 92: // \
|
|
if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
|
|
return fail("unescaped `\\`", chunkerCurrentIndex);
|
|
case 34:
|
|
case 39:
|
|
case 96: // ", ' and `
|
|
matched = 0;
|
|
currentChunkStartIndex = chunkerCurrentIndex;
|
|
for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
if (cc2 > 96) { continue; }
|
|
if (cc2 == cc) { matched = 1; break; }
|
|
if (cc2 == 92) { // \
|
|
if (chunkerCurrentIndex == len - 1) {
|
|
return fail("unescaped `\\`", chunkerCurrentIndex);
|
|
}
|
|
chunkerCurrentIndex++;
|
|
}
|
|
}
|
|
if (matched) { continue; }
|
|
return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
|
|
case 47: // /, check for comment
|
|
if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
|
|
cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
|
|
if (cc2 == 47) {
|
|
// //, find lnfeed
|
|
for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
|
|
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }
|
|
}
|
|
} else if (cc2 == 42) {
|
|
// /*, find */
|
|
lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
|
|
for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
|
|
cc2 = input.charCodeAt(chunkerCurrentIndex);
|
|
if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }
|
|
if (cc2 != 42) { continue; }
|
|
if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
|
|
}
|
|
if (chunkerCurrentIndex == len - 1) {
|
|
return fail("missing closing `*/`", currentChunkStartIndex);
|
|
}
|
|
chunkerCurrentIndex++;
|
|
}
|
|
continue;
|
|
case 42: // *, check for unmatched */
|
|
if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
|
|
return fail("unmatched `/*`", chunkerCurrentIndex);
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (level !== 0) {
|
|
if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
|
|
return fail("missing closing `}` or `*/`", lastOpening);
|
|
} else {
|
|
return fail("missing closing `}`", lastOpening);
|
|
}
|
|
} else if (parenLevel !== 0) {
|
|
return fail("missing closing `)`", lastOpeningParen);
|
|
}
|
|
|
|
emitChunk(true);
|
|
return chunks;
|
|
};
|