-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.mjs
91 lines (81 loc) · 3.24 KB
/
index.mjs
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
//
// there are SERIOUS CAVEATS to be aware of when using this code (as per README.md)
//
/**
* strip-javascript-comments.js - strips comments from javascript code
*
* Copyright (c) 2019+ Frederic Rudman
*
* Distributed under the ISC license.
*/
export default stripComments;
export function stripComments(code) {
var strippedCode = '',
pos = -1,
spacingChar = null,
inQuote = false, // becomes the quote's leading char (i.e. a 1-char string)
inEOLComment = false,
inMultilineComment = false,
mlcStartPos = -1, // start pos if in a multiline comment
backslashes = 0; // when checking for escaped-quotes AND for patho-case #1
const more = () => ++pos < code.length, // also increments to next char
cur = () => (pos < code.length) ? code[pos] : ' ',
next = () => (pos+1 < code.length) ? code[pos+1] : ' ',
prev = () => (pos-1 >= 0) ? code[pos-1] : ' ',
isSpaceChar = c => c === ' ' || c === '\n' || c === '\r' || c === '\t' || c === '\f', // other space chars?
isQuoteChar = c => c === '"' || c === "'" || c === '`',
validMLC = () => pos - 2 > mlcStartPos, // to prevent /*/ from being considered valid multiline-comment
lastKeptChar = () => strippedCode.length > 0 ? strippedCode[strippedCode.length-1] : '',
keep = c => strippedCode += c,
evenNumberOfPrecedingBackSlashes = () => backslashes % 2 === 0;
while (more()) {
const c = cur();
if (inQuote) {
keep(c);
if (c === inQuote && evenNumberOfPrecedingBackSlashes()) // checking for escaped quotes
inQuote = false;
}
else if (inEOLComment) {
if (c === '\n') {
inEOLComment = false;
spacingChar = '\n';
}
}
else if (inMultilineComment) {
if (c === '/' && prev() === '*' && validMLC()) { // /*/*/ is valid; /*/ is not
inMultilineComment = false;
spacingChar = ' ';
}
}
else if (isSpaceChar(c)) {
spacingChar = (c === '\n' || spacingChar === '\n') ? '\n' : ' ';
}
else {
// first, handle prior spacing...
if (spacingChar) { // ...if any
(lastKeptChar() !== spacingChar) && keep(spacingChar); // collapse multiple ones into single
spacingChar = null;
}
// then, consider next char...
if (isQuoteChar(c)) {
keep(c);
inQuote = c; // now in a quote (to be terminated by same char)
}
else if (c === '/') {
if (next() === '/')
inEOLComment = true;
else if (next() === '*' && evenNumberOfPrecedingBackSlashes()) { // checking for patho-case #1
inMultilineComment = true;
mlcStartPos = pos; // remember its start: a ml-comment must be at least 4 chars long (incl. /* and */)
}
else
keep(c);
}
else {
keep(c);
}
}
backslashes = (c === '\\') ? backslashes+1 : 0;
}
return strippedCode;
}