All files / json-syntax index.js

4.35% Statements 1/23
0% Branches 0/8
0% Functions 0/6
4.35% Lines 1/23

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 651x                                                                                                                                
window.customElements.define('h-json-syntax', class extends HTMLElement {
 
  constructor() {
    super()
    const shadowRoot = this.attachShadow({ mode: 'open' })
    shadowRoot.appendChild(this._generateTemplate().content.cloneNode(true))
    this.$pre = this.shadowRoot.querySelector('pre')
  }
 
  _generateTemplate() {
    const template = document.createElement('template')
    template.innerHTML = `
      <style>
        pre { overflow: auto; font-weight: bold; }
        .string { color: #de5b4c; }
        .number { color: darkorange; }
        .boolean { color: #6071f6	; }
        .null { color: magenta; }
        .key { color: #8e3693; }
      </style>
      <pre></pre>
    `
    return template
  }
 
  render(source) {
    this.$pre.innerHTML = this._syntaxHighlight(source)
  }
 
  /*
    1st Capturing Group = "(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?
      Gets unicode values with optional colon
    " matches the character " literally (case sensitive)
    2nd Capturing Group = \b(true|false|null)\b
      word boundary for boolean or null value
    3th Capturing Group = -?\d+(?:\.\d*)?(?:[eE][+]?\d+)?
      all numeric type values
  */
  _syntaxHighlight(source) {
    let json = this._formatJSON(source)
    json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
    return json.replace(/("(\\u[a-zA-Z0-9]{4}|\\[^u]|[^\\"])*"(\s*:)?|\b(true|false|null)\b|-?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)/g, (match) => {
      let cls = 'number'
      if (/^"/.test(match)) {
        if (/:$/.test(match)) {
          cls = 'key'
        } else {
          cls = 'string'
        }
      } else if (/true|false/.test(match)) {
        cls = 'boolean'
      } else if (/null/.test(match)) {
        cls = 'null'
      }
      return `<span class="${cls}">${match}</span>`
    })
  }
 
  _formatJSON(obj) {
    return JSON.stringify(obj, undefined, 2)
  }
 
})