all files / liquidjs/src/ filter.js

100% Statements 43/43
100% Branches 8/8
100% Functions 6/6
100% Lines 41/41
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 65 66 67     114× 114×   114×   123× 123× 123×     131× 131×   130× 130× 130× 130×       126× 126× 91× 91× 91×     126× 126× 126×   126×       131× 131×     4577×     16×     114×        
const lexical = require('./lexical.js')
const Syntax = require('./syntax.js')
const assert = require('./util/assert.js')
const _ = require('./util/underscore.js')
 
var valueRE = new RegExp(`${lexical.value.source}`, 'g')
 
module.exports = function (options) {
  options = _.assign({}, options)
  var filters = {}
 
  var _filterInstance = {
    render: function (output, scope) {
      var args = this.args.map(arg => Syntax.evalValue(arg, scope))
      args.unshift(output)
      return this.filter.apply(null, args)
    },
    parse: function (str) {
      var match = lexical.filterLine.exec(str)
      assert(match, 'illegal filter: ' + str)
 
      var name = match[1]
      var argList = match[2] || ''
      var filter = filters[name]
      if (typeof filter !== 'function') {
        if (options.strict_filters) {
          throw new TypeError(`undefined filter: ${name}`)
        }
        this.name = name
        this.filter = x => x
        this.args = []
        return this
      }
 
      var args = []
      while ((match = valueRE.exec(argList.trim()))) {
        var v = match[0]
        var re = new RegExp(`${v}\\s*:`, 'g')
        re.test(match.input) ? args.push(`'${v}'`) : args.push(v)
      }
 
      this.name = name
      this.filter = filter
      this.args = args
 
      return this
    }
  }
 
  function construct (str) {
    var instance = Object.create(_filterInstance)
    return instance.parse(str)
  }
 
  function register (name, filter) {
    filters[name] = filter
  }
 
  function clear () {
    filters = {}
  }
 
  return {
    construct, register, clear
  }
}