source: trip-planner-front/node_modules/gauge/render-template.js@ b738035

Last change on this file since b738035 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.6 KB
RevLine 
[6a3a178]1'use strict'
2var align = require('wide-align')
3var validate = require('aproba')
4var objectAssign = require('object-assign')
5var wideTruncate = require('./wide-truncate')
6var error = require('./error')
7var TemplateItem = require('./template-item')
8
9function renderValueWithValues (values) {
10 return function (item) {
11 return renderValue(item, values)
12 }
13}
14
15var renderTemplate = module.exports = function (width, template, values) {
16 var items = prepareItems(width, template, values)
17 var rendered = items.map(renderValueWithValues(values)).join('')
18 return align.left(wideTruncate(rendered, width), width)
19}
20
21function preType (item) {
22 var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
23 return 'pre' + cappedTypeName
24}
25
26function postType (item) {
27 var cappedTypeName = item.type[0].toUpperCase() + item.type.slice(1)
28 return 'post' + cappedTypeName
29}
30
31function hasPreOrPost (item, values) {
32 if (!item.type) return
33 return values[preType(item)] || values[postType(item)]
34}
35
36function generatePreAndPost (baseItem, parentValues) {
37 var item = objectAssign({}, baseItem)
38 var values = Object.create(parentValues)
39 var template = []
40 var pre = preType(item)
41 var post = postType(item)
42 if (values[pre]) {
43 template.push({value: values[pre]})
44 values[pre] = null
45 }
46 item.minLength = null
47 item.length = null
48 item.maxLength = null
49 template.push(item)
50 values[item.type] = values[item.type]
51 if (values[post]) {
52 template.push({value: values[post]})
53 values[post] = null
54 }
55 return function ($1, $2, length) {
56 return renderTemplate(length, template, values)
57 }
58}
59
60function prepareItems (width, template, values) {
61 function cloneAndObjectify (item, index, arr) {
62 var cloned = new TemplateItem(item, width)
63 var type = cloned.type
64 if (cloned.value == null) {
65 if (!(type in values)) {
66 if (cloned.default == null) {
67 throw new error.MissingTemplateValue(cloned, values)
68 } else {
69 cloned.value = cloned.default
70 }
71 } else {
72 cloned.value = values[type]
73 }
74 }
75 if (cloned.value == null || cloned.value === '') return null
76 cloned.index = index
77 cloned.first = index === 0
78 cloned.last = index === arr.length - 1
79 if (hasPreOrPost(cloned, values)) cloned.value = generatePreAndPost(cloned, values)
80 return cloned
81 }
82
83 var output = template.map(cloneAndObjectify).filter(function (item) { return item != null })
84
85 var outputLength = 0
86 var remainingSpace = width
87 var variableCount = output.length
88
89 function consumeSpace (length) {
90 if (length > remainingSpace) length = remainingSpace
91 outputLength += length
92 remainingSpace -= length
93 }
94
95 function finishSizing (item, length) {
96 if (item.finished) throw new error.Internal('Tried to finish template item that was already finished')
97 if (length === Infinity) throw new error.Internal('Length of template item cannot be infinity')
98 if (length != null) item.length = length
99 item.minLength = null
100 item.maxLength = null
101 --variableCount
102 item.finished = true
103 if (item.length == null) item.length = item.getBaseLength()
104 if (item.length == null) throw new error.Internal('Finished template items must have a length')
105 consumeSpace(item.getLength())
106 }
107
108 output.forEach(function (item) {
109 if (!item.kerning) return
110 var prevPadRight = item.first ? 0 : output[item.index - 1].padRight
111 if (!item.first && prevPadRight < item.kerning) item.padLeft = item.kerning - prevPadRight
112 if (!item.last) item.padRight = item.kerning
113 })
114
115 // Finish any that have a fixed (literal or intuited) length
116 output.forEach(function (item) {
117 if (item.getBaseLength() == null) return
118 finishSizing(item)
119 })
120
121 var resized = 0
122 var resizing
123 var hunkSize
124 do {
125 resizing = false
126 hunkSize = Math.round(remainingSpace / variableCount)
127 output.forEach(function (item) {
128 if (item.finished) return
129 if (!item.maxLength) return
130 if (item.getMaxLength() < hunkSize) {
131 finishSizing(item, item.maxLength)
132 resizing = true
133 }
134 })
135 } while (resizing && resized++ < output.length)
136 if (resizing) throw new error.Internal('Resize loop iterated too many times while determining maxLength')
137
138 resized = 0
139 do {
140 resizing = false
141 hunkSize = Math.round(remainingSpace / variableCount)
142 output.forEach(function (item) {
143 if (item.finished) return
144 if (!item.minLength) return
145 if (item.getMinLength() >= hunkSize) {
146 finishSizing(item, item.minLength)
147 resizing = true
148 }
149 })
150 } while (resizing && resized++ < output.length)
151 if (resizing) throw new error.Internal('Resize loop iterated too many times while determining minLength')
152
153 hunkSize = Math.round(remainingSpace / variableCount)
154 output.forEach(function (item) {
155 if (item.finished) return
156 finishSizing(item, hunkSize)
157 })
158
159 return output
160}
161
162function renderFunction (item, values, length) {
163 validate('OON', arguments)
164 if (item.type) {
165 return item.value(values, values[item.type + 'Theme'] || {}, length)
166 } else {
167 return item.value(values, {}, length)
168 }
169}
170
171function renderValue (item, values) {
172 var length = item.getBaseLength()
173 var value = typeof item.value === 'function' ? renderFunction(item, values, length) : item.value
174 if (value == null || value === '') return ''
175 var alignWith = align[item.align] || align.left
176 var leftPadding = item.padLeft ? align.left('', item.padLeft) : ''
177 var rightPadding = item.padRight ? align.right('', item.padRight) : ''
178 var truncated = wideTruncate(String(value), length)
179 var aligned = alignWith(truncated, length)
180 return leftPadding + aligned + rightPadding
181}
Note: See TracBrowser for help on using the repository browser.