All files escape-js.ts

100% Statements 72/72
100% Branches 25/25
100% Functions 1/1
100% Lines 72/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 1121x 1x                                                                       1x 13x 13x 100x 100x   100x 10x 10x 3x 3x 3x 10x 1x 1x 1x 10x 1x 1x 1x 10x 1x 1x 1x 10x 1x 1x 1x 10x 1x 1x 1x 10x 1x 1x 1x 10x 1x 1x 10x 100x 71x 71x 5x 5x 5x 71x 1x 1x 1x 71x 1x 1x 1x 71x   64x 64x 71x 90x 1x 19x   6x 18x 6x 6x 6x 6x 6x 100x   13x 13x  
import { build } from './build.ts';
import { oct, u4, uu, x2 } from './escape.ts';
 
// cspell:ignore unnnn
/**
 * Escape a string for use in Javascript
 *
 * | Character          | Hex                  | Escape Sequence      |
 * | ------------------ | -------------------- | -------------------- |
 * | NUL                | 0x00                 | \\0 or \\x00[^1]     |
 * | Backspace          | 0x08                 | \\b                  |
 * | Tab                | 0x09                 | \\t                  |
 * | Newline            | 0x0a                 | \\n                  |
 * | Vertical Tab       | 0x0b                 | \\v                  |
 * | Form Feed          | 0x0c                 | \\f                  |
 * | Carriage Return    | 0x0d                 | \\r                  |
 * | Double Quote       | 0x22                 | \\"                  |
 * | Single Quote       | 0x27                 | \\'                  |
 * | Backslash          | 0x5c                 | \\\\                 |
 * | Control Characters | 0x00-0x1f, 0x7f-0x9f | \\xnn                |
 * | BMP                | 0x0100-0xffff    | \\unnnn              |
 * | Astral             | 0x10000-0x10ffff   | \\u\{nnn...\}        |
 *
 * [^1]: The sequence \\0 must not be followed by a octal digit (0-7) to avoid being interpreted
 * as a different character, \\x00 will be used to avoid ambiguity.
 * @param input - The string to escape
 * @returns Sting escaped for Javascript
 * @example
 * ```typescript
 * escapeJS('Hello\nWorld'); // "Hello\\nWorld"
 * escapeJS('"\\');          // "\\\"\\\\"
 * escapeJS('\b');           // "\\b"
 * escapeJS('\u20ac');       // "\\u20ac"
 * ```
 * @group Programming
 * @category Escaping
 */
export function escapeJS(input: string): string {
  const output: string[] = [];
  for (let i = 0; i < input.length; ++i) {
    const u0 = input.codePointAt(i)!;
    const u1 = input.codePointAt(i + 1);
 
    if (u0 < 0x00000020) {
      switch (u0) {
        case 0x00000000: {
          output.push(oct(u1) ? '\\x00' : '\\0');
          break;
        }
        case 0x00000008: {
          output.push('\\b');
          break;
        }
        case 0x00000009: {
          output.push('\\t');
          break;
        }
        case 0x0000000a: {
          output.push('\\n');
          break;
        }
        case 0x0000000b: {
          output.push('\\v');
          break;
        }
        case 0x0000000c: {
          output.push('\\f');
          break;
        }
        case 0x0000000d: {
          output.push('\\r');
          break;
        }
        default: {
          output.push(x2(u0));
        }
      }
    } else if (u0 < 0x0000007f) {
      switch (u0) {
        case 0x00000022: {
          output.push('\\"');
          break;
        }
        case 0x00000027: {
          output.push("\\'");
          break;
        }
        case 0x0000005c: {
          output.push('\\\\');
          break;
        }
        default: {
          // eslint-disable-next-line unicorn/prefer-code-point
          output.push(String.fromCharCode(u0));
        }
      }
    } else if (u0 < 0x000000a1) {
      output.push(x2(u0));
    } else if (u0 < 0x00000100) {
      // eslint-disable-next-line unicorn/prefer-code-point
      output.push(String.fromCharCode(u0));
    } else if (u0 < 0x00010000) {
      output.push(u4(u0));
    } else {
      ++i;
      output.push(uu(u0));
    }
  }
 
  return build(output);
}