NaturalCycles/js-lib

View on GitHub
src/string/escape.ts

Summary

Maintainability
C
7 hrs
Test Coverage
A
100%
/*

Vendored:
https://github.com/sindresorhus/escape-goat

(c) Sindre Sorhus

Reasons:
1. Stable enough to be included in "core" js-lib
2. ESM-only

 */

// Multiple `.replace()` calls are actually faster than using replacer functions
function _htmlEscape(s: string): string {
  return s
    .replaceAll('&', '&') // Must happen first or else it will escape other just-escaped characters.
    .replaceAll('"', '"')
    .replaceAll("'", ''')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
}

function _htmlUnescape(html: string): string {
  return html
    .replaceAll('&gt;', '>')
    .replaceAll('&lt;', '<')
    .replaceAll(/&#0?39;/g, "'")
    .replaceAll('&quot;', '"')
    .replaceAll('&amp;', '&') // Must happen last or else it will unescape other characters in the wrong order.
}

export function htmlEscape(strings: string | TemplateStringsArray, ...values: any[]): string {
  if (typeof strings === 'string') {
    return _htmlEscape(strings)
  }

  let output = strings[0]!
  for (const [index, value] of values.entries()) {
    output = output + _htmlEscape(String(value)) + strings[index + 1]
  }

  return output
}

export function htmlUnescape(strings: string | TemplateStringsArray, ...values: any[]): string {
  if (typeof strings === 'string') {
    return _htmlUnescape(strings)
  }

  let output = strings[0]!
  for (const [index, value] of values.entries()) {
    output = output + _htmlUnescape(String(value)) + strings[index + 1]
  }

  return output
}