all files / liquidjs/tags/ cycle.js

100% Statements 26/26
100% Branches 6/6
100% Functions 3/3
100% Lines 26/26
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   107×           23×         12× 12×   12× 12×   12×     12× 12× 12×   12×        
const Liquid = require('..')
const Promise = require('any-promise')
const lexical = Liquid.lexical
const groupRE = new RegExp(`^(?:(${lexical.value.source})\\s*:\\s*)?(.*)$`)
const candidatesRE = new RegExp(lexical.value.source, 'g')
const assert = require('../src/util/assert.js')
 
module.exports = function (liquid) {
  liquid.registerTag('cycle', {
 
    parse: function (tagToken, remainTokens) {
      var match = groupRE.exec(tagToken.args)
      assert(match, `illegal tag: ${tagToken.raw}`)
 
      this.group = match[1] || ''
      var candidates = match[2]
 
      this.candidates = []
 
      while ((match = candidatesRE.exec(candidates))) {
        this.candidates.push(match[0])
      }
      assert(this.candidates.length, `empty candidates: ${tagToken.raw}`)
    },
 
    render: function (scope, hash) {
      var group = Liquid.evalValue(this.group, scope)
      var fingerprint = `cycle:${group}:` + this.candidates.join(',')
 
      var groups = scope.opts.groups = scope.opts.groups || {}
      var idx = groups[fingerprint]
 
      if (idx === undefined) {
        idx = groups[fingerprint] = 0
      }
 
      var candidate = this.candidates[idx]
      idx = (idx + 1) % this.candidates.length
      groups[fingerprint] = idx
 
      return Promise.resolve(Liquid.evalValue(candidate, scope))
    }
  })
}