all files / liquidjs/src/ tag.js

100% Statements 38/38
100% Branches 4/4
100% Functions 7/7
100% Lines 37/37
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    292× 292× 292× 292× 82× 82× 82×   292×     135×   135×   292× 292× 292×   288×     311× 311× 311×   311× 311× 305× 305× 290×         2022×     311× 311× 287×     10×     135×            
'use strict'
const lexical = require('./lexical.js')
const Syntax = require('./syntax.js')
const assert = require('./util/assert.js')
 
function hash (markup, scope) {
  let obj = {}
  let match
  lexical.hashCapture.lastIndex = 0
  while ((match = lexical.hashCapture.exec(markup))) {
    let k = match[1]
    let v = match[2]
    obj[k] = Syntax.evalValue(v, scope)
  }
  return obj
}
 
module.exports = function () {
  let tagImpls = {}
 
  let _tagInstance = {
    render: function (scope) {
      let obj = hash(this.token.args, scope)
      let impl = this.tagImpl
      if (typeof impl.render !== 'function') {
        return Promise.resolve('')
      }
      return Promise.resolve().then(() => impl.render(scope, obj))
    },
    parse: function (token, tokens) {
      this.type = 'tag'
      this.token = token
      this.name = token.name
 
      let tagImpl = tagImpls[this.name]
      assert(tagImpl, `tag ${this.name} not found`)
      this.tagImpl = Object.create(tagImpl)
      if (this.tagImpl.parse) {
        this.tagImpl.parse(token, tokens)
      }
    }
  }
 
  function register (name, tag) {
    tagImpls[name] = tag
  }
 
  function construct (token, tokens) {
    let instance = Object.create(_tagInstance)
    instance.parse(token, tokens)
    return instance
  }
 
  function clear () {
    tagImpls = {}
  }
 
  return {
    construct,
    register,
    clear
  }
}