All files / src json-syntax.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 561x                                                                                                              
window.customElements.define('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 {outline: 1px solid #ccc; padding: 5px; }
        .string { color: green; }
        .number { color: darkorange; }
        .boolean { color: blue; }
        .null { color: magenta; }
        .key { color: red; }
      </style>
      <pre></pre>
    `
    return template
  }
 
  render(source) {
    this.$pre.innerHTML = this._syntaxHighlight(source)
  }
 
  _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)
  }
 
})