All files / shared/src escapeHtml.ts

100% Statements 30/30
100% Branches 16/16
100% Functions 4/4
100% Lines 30/30

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 65180x     761x 761x   761x 709x     52x     52x 52x 426x   18x 18x   10x 10x   2x 2x   48x 48x   46x 46x   302x     124x 83x     124x 124x     52x       180x     18x       180x           30x 42x      
const escapeRE = /["'&<>]/
 
export function escapeHtml(string: unknown): string {
  const str = '' + string
  const match = escapeRE.exec(str)
 
  if (!match) {
    return str
  }
 
  let html = ''
  let escaped: string
  let index: number
  let lastIndex = 0
  for (index = match.index; index < str.length; index++) {
    switch (str.charCodeAt(index)) {
      case 34: // "
        escaped = '&quot;'
        break
      case 38: // &
        escaped = '&amp;'
        break
      case 39: // '
        escaped = '&#39;'
        break
      case 60: // <
        escaped = '&lt;'
        break
      case 62: // >
        escaped = '&gt;'
        break
      default:
        continue
    }
 
    if (lastIndex !== index) {
      html += str.slice(lastIndex, index)
    }
 
    lastIndex = index + 1
    html += escaped
  }
 
  return lastIndex !== index ? html + str.slice(lastIndex, index) : html
}
 
// https://www.w3.org/TR/html52/syntax.html#comments
const commentStripRE = /^-?>|<!--|-->|--!>|<!-$/g
 
export function escapeHtmlComment(src: string): string {
  return src.replace(commentStripRE, '')
}
 
export const cssVarNameEscapeSymbolsRE: RegExp =
  /[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g
 
export function getEscapedCssVarName(
  key: string,
  doubleEscape: boolean,
): string {
  return key.replace(cssVarNameEscapeSymbolsRE, s =>
    doubleEscape ? (s === '"' ? '\\\\\\"' : `\\\\${s}`) : `\\${s}`,
  )
}