<template>
  <div class="sv-code-item" :style="codeItemStyle"></div>
</template>

<script>
  export default {
    name: 'svCodeItem',
    data () {
      return {
        codeItemStyle: {
          textIndent: `${16 * this.level}px`
        }
      }
    },
    props: {
      code: {
        type: String,
        default: ''
      },
      level: {
        type: Number,
        default: 1
      }
    },
    methods: {
      strToDOM (str) {
        let element = document.createElement("div")
        element.innerHTML = str
        return element.childNodes[0]
      },
      processAttributes (codeString, codeDOM) {
        if (!codeDOM) return codeString
        let attribute
        Object.keys(codeDOM.attributes).forEach(key => {
          attribute = codeDOM.attributes[key]
          codeString = codeString
            .replace(attribute.nodeName, `<w sv-cls="sv-code-attribute-name">${attribute.nodeName}</w>`)
            .replace(`"${attribute.nodeValue}"`, `<w sv-cls="sv-code-attribute-value">"${attribute.nodeValue}"</w>`)
        })
        return codeString
      },
      processNode (str, codeDOM) {
        let nodeName
        if (!codeDOM && str.startsWith('</')) {
          nodeName = str.substring(str.indexOf('</') + 2, str.length - 1)
          return str.replace(new RegExp(nodeName, 'gm'), `<w sv-cls="sv-code-element">${nodeName}</w>`)
        }

        nodeName = codeDOM.localName
        return str.replace(new RegExp(nodeName, 'gm'), `<w sv-cls="sv-code-element">${nodeName}</w>`)
      },

    },
    mounted () {
      let codeString = this.code
      let codeDOM = this.strToDOM(codeString)

      codeString = this.processNode(codeString, codeDOM)

      codeString = codeString.replace(new RegExp('<(?!(w|/))', 'gm'), '&lt')
      codeString = codeString.replace(new RegExp('</(?=<)', 'gm'), '&lt;/')

      codeString = this.processAttributes(codeString, codeDOM)

      codeString = codeString.replace(/sv-cls/img, 'class')

      codeString = codeString.replace(/d\{/g, '{{').replace(/d}/g, '}}')
      // 处理element
      this.$el.innerHTML = codeString
    }
  }
</script>

<style lang="scss" rel="stylesheet/scss">
  .sv-code{
    .sv-code-item{
      .sv-code-element{
        color:#63a35c;
      }
      .sv-code-attribute-name{
        color:#795da3;
      }
      .sv-code-attribute-value{
        color:#df5000;
      }
    }
  }
</style>
