80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
| const singleComment = Symbol('singleComment');
 | |
| const multiComment = Symbol('multiComment');
 | |
| 
 | |
| const stripWithoutWhitespace = () => '';
 | |
| const stripWithWhitespace = (string, start, end) => string.slice(start, end).replace(/\S/g, ' ');
 | |
| 
 | |
| const isEscaped = (jsonString, quotePosition) => {
 | |
|   let index = quotePosition - 1;
 | |
|   let backslashCount = 0;
 | |
| 
 | |
|   while (jsonString[index] === '\\') {
 | |
|     index -= 1;
 | |
|     backslashCount += 1;
 | |
|   }
 | |
| 
 | |
|   return Boolean(backslashCount % 2);
 | |
| };
 | |
| 
 | |
| export default function stripJsonComments(jsonString, { whitespace = true } = {}) {
 | |
|   if (typeof jsonString !== 'string') {
 | |
|     throw new TypeError(
 | |
|       `Expected argument \`jsonString\` to be a \`string\`, got \`${typeof jsonString}\``,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   const strip = whitespace ? stripWithWhitespace : stripWithoutWhitespace;
 | |
| 
 | |
|   let isInsideString = false;
 | |
|   let isInsideComment = false;
 | |
|   let offset = 0;
 | |
|   let result = '';
 | |
| 
 | |
|   for (let index = 0; index < jsonString.length; index++) {
 | |
|     const currentCharacter = jsonString[index];
 | |
|     const nextCharacter = jsonString[index + 1];
 | |
| 
 | |
|     if (!isInsideComment && currentCharacter === '"') {
 | |
|       const escaped = isEscaped(jsonString, index);
 | |
|       if (!escaped) {
 | |
|         isInsideString = !isInsideString;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (isInsideString) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     if (!isInsideComment && currentCharacter + nextCharacter === '//') {
 | |
|       result += jsonString.slice(offset, index);
 | |
|       offset = index;
 | |
|       isInsideComment = singleComment;
 | |
|       index++;
 | |
|     } else if (isInsideComment === singleComment && currentCharacter + nextCharacter === '\r\n') {
 | |
|       index++;
 | |
|       isInsideComment = false;
 | |
|       result += strip(jsonString, offset, index);
 | |
|       offset = index;
 | |
|       continue;
 | |
|     } else if (isInsideComment === singleComment && currentCharacter === '\n') {
 | |
|       isInsideComment = false;
 | |
|       result += strip(jsonString, offset, index);
 | |
|       offset = index;
 | |
|     } else if (!isInsideComment && currentCharacter + nextCharacter === '/*') {
 | |
|       result += jsonString.slice(offset, index);
 | |
|       offset = index;
 | |
|       isInsideComment = multiComment;
 | |
|       index++;
 | |
|       continue;
 | |
|     } else if (isInsideComment === multiComment && currentCharacter + nextCharacter === '*/') {
 | |
|       index++;
 | |
|       isInsideComment = false;
 | |
|       result += strip(jsonString, offset, index + 1);
 | |
|       offset = index + 1;
 | |
|       continue;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return result + (isInsideComment ? strip(jsonString.slice(offset)) : jsonString.slice(offset));
 | |
| }
 |