PageSourceSearch

https://my.reigate-banstead.gov.uk/libraries/js/template.js

js reigate-banstead.gov.uk collected 2026-09-24 09:41:11 UTC 13,153 bytes, 406 lines download raw bytes

1(function(root, factory) {
2    var _ = root._ || require('lodash');
3    var dependencies = ['dustjs-linkedin', 'bluebird', 'lodash', 'jquery'];
4
5    if (typeof define === 'function' && define.amd) {
6        define(dependencies, factory);
7    } else if (typeof exports === 'object') {
8        module.exports = factory.apply(this, _.map(dependencies, require));
9    } else {
10        root.FS = root.FS || {};
11        root.FS.Template = factory(root.dust, root.Promise, root._, root.jQuery);
12    }
13}(this, function(dust, Promise, _, $) {
14    if(!dust || !dust.helpers) throw new Error('Dust.js is not available');
15    if(!Promise) throw new Error('Bluebird.js is not available');
16    if(!_) throw new Error('Underscore.js is not available');
17    if(!$) throw new Error('jQuery.js is not available');
18
19    // A unique incrementing ID for use by the dust.js @apib helper below
20    var appLoadingId = 0;
21
22    dust.iter = function(chk, ctx, bodies, params) {
23        var self = this;
24        var obj = ctx.current();
25        var keys = [];
26
27        params = _.map(params || {}, function(param) {
28          return dust.helpers.tap(param, chk, ctx);
29        });
30
31        for (var k in obj) {
32            if(obj.hasOwnProperty(k)) keys.push(k);
33        }
34        if(params.sort){
35            var by = params.by || 'name';
36            keys = keys.sort(function(ka, kb) {
37                var a = new String(obj[ka][by]).toLowerCase(),
38                    b = new String(obj[kb][by]).toLowerCase();
39                if(a > b) return 1;
40                if(a < b) return -1;
41                return 0;
42            })
43        }
44        var l = keys.length;
45        for (var k in keys) {
46            var key = keys[k];
47            chk = chk.render(bodies.block, ctx.push({
48                iter: arguments.callee,
49                key: key,
50                value: obj[key],
51                index: k,
52                length: l
53            }));
54        }
55        return chk;
56    };
57
58    var uuids = {};
59    _.extend(dust.helpers, {
60      /**
61       * {@ifAuthenticated}
62       *    User is authenticated
63       * {:else}
64       *    User is anonymous
65       * {/ifAuthenticated}
66       */
67      ifAuthenticated: function(chunk, context, bodies, params) {
68        if(bodies.block) {
69          return chunk.map(function(chunk) {
70            FS.Auth.isLoggedIn()
71              .then(
72                function() {
73                  chunk.render(bodies.block, context).end();
74                },
75                function() {
76                  if(bodies['else']) {
77                    chunk.render(bodies['else'], context).end();
78                  }
79                }
80              );
81          });
82        }
83          return chunk;
84      },
85
86      /**
87       * {@ifHasRole role="Petitions Admin"}
88       *    User has the Petitions Admin role
89       * {:else}
90       *    User does NOT have the Petitions Admin role
91       * {/ifAuthenticated}
92       */
93      ifHasRole: function(chunk, context, bodies, params) {
94        params = params || {};
95
96        if(!params.role || !params.module || !params.product) {
97          console.warn('Did not specify role | module | product');
98          return chunk;
99        }
100
101        if(bodies.block) {
102          return chunk.map(function(chunk) {
103            FS.SecurityManager.hasRole(params.product, params.module, params.role)
104              .then(function() {
105                chunk.render(bodies.block, context).end();
106              })
107              .caught(function(error) {
108                if(bodies['else']) {
109                  chunk.render(bodies['else'], context).end();
110                }
111              });
112
113          });
114        }
115          return chunk;
116      },
117
118      /**
119       * {@formUrl formID="sdfhksdfj" /}
120       */
121      formUrl: function(chunk, context, bodies, params) {
122        params = params || {};
123
124        var formID = params.formID,
125            returnModule = params.returnModule,
126            showMsg = params.showMsg,
127            engine = params.engine || 'FS2',
128            serviceName = params.oldFormName || params.oldProcessName || null;
129
130        return chunk.map(function(chunk) {
131          Promise.resolve(FS.Forms.getUrl(formID, params, engine, showMsg, returnModule, serviceName, null, null, params.returnUrls))
132            .then(
133              function(formUrl) {
134                chunk.write(formUrl).end();
135              },
136              function() {
137                chunk.write(params.failUrl || '#').end();
138              }
139            );
140        });
141      },
142
143      /**
144      * {@apib name="Account_CTAX" type="html"} {.|s} {:else} ERROR! {/apib}
145      */
146      apib: function(chunk, context, bodies, params, transform) {
147        params = params || {};
148
149        if(!params.name) {
150          console.warn('Must specify an API name');
151          return chunk;
152        }
153        var api = params.name;
154        delete params.name;
155
156        var dataType = 'json';
157        if(params.type) {
158          dataType = params.type;
159          delete params.type;
160        }
161
162        var cache = false;
163        if(params.cache) {
164          cache = params.cache;
165          delete params.cache;
166        }
167
168        var loadingHtml = '<span class="muted">Loading&hellip;</span>';
169        if(params.loadingText) {
170          loadingHtml = dust.escapeHtml(params.loadingText);
171          delete params.loadingText;
172        } else if(params.loadingHtml) {
173          loadingHtml = params.loadingHtml;
174          delete params.loadingHtml;
175        }
176
177        if(bodies.block) {
178          var id = ++appLoadingId,
179            placeholderContainer = $('<div><div data-fs-load="'+id+'">'+loadingHtml+'</div></div>'),
180            onrender = function(data, block) {
181              var locator = $('[data-fs-load="'+id+'"]'),
182                output;
183
184              if(!_.isFunction(bodies[block])) {
185                console.error('Trying to load non-existant block', block, bodies);
186              } else {
187                var localContext = context.push(data);
188                // TODO: Seems like a hack. Probably is a hack. Shouldn't be a hack
189                if(localContext && localContext.stack && localContext.stack.tail && localContext.stack.tail.head) {
190                  _.extend(localContext.stack.head, localContext.stack.tail.head);
191                }
192                chunk.capture(bodies[block], localContext, function(output) {
193                  setTimeout(function() { locator.html(output); }, 0);
194                });
195              }
196            };
197
198          FS.API.get(api, params, undefined, dataType)
199            .then(
200              function(data) {
201                var outputContext = {};
202                if(_.isFunction(transform)) {
203                  outputContext.transformed = transform(data);
204                  outputContext.raw = data;
205                } else {
206                  outputContext = data;
207                }
208                onrender(outputContext, 'block');
209              },
210              function(error) {
211                onrender(error, 'error');
212              }
213            );
214          return chunk.write(placeholderContainer.html());
215        }
216          return chunk;
217      },
218
219      /**
220       * {@limData api="CapitaLIMTest"}
221       *   {#transformed} ... {/transformed}
222       * {/limData}
223       */
224      limData: function(chunk, context, bodies, params) {
225        return dust.helpers.apib(chunk, context, bodies, params, function(input) {
226          return _.map(input, function(row) {
227            return _.object(
228              _.flattenDeep(_.map(row, _.keys)),
229              _.flattenDeep(_.map(row, _.values))
230            );
231          });
232        });
233      },
234
235      /**
236       * {@sort input="arrayOfObjects" by="id"}
237       *    arrayOfObjects is sorted by ID here
238       * {/sort}
239       */
240      sort: function(chunk, context, bodies, params) {
241        params = params || {};
242        if(!params.input || !_.isArray(params.input)) {
243          console.warn('Input parameter to @sort must be an array of objects.');
244        }
245
246        if(bodies.block) {
247          var sortedOutput = params.input;
248          if(params.by) {
249            sortedOutput = sortObjects(sortedOutput, params.by, !!params.reverse);
250          }
251          chunk.render(bodies.block, context.push({sorted: sortedOutput}));
252        }
253        chunk.end();
254        return chunk;
255      },
256
257      /**
258       * {@objectKeys input=someObject}
259       *    {key}: {value}<br />
260       * {/objectKeys}
261       */
262      objectKeys: function(chunk, context, bodies, params) {
263        params = params || {};
264        if(!$.isPlainObject(params.input)) {
265          console.warn('Input parameter to @objectKeys must be a plain object');
266        }
267
268        var isEmpty = true;
269        if(bodies.block) {
270          for(var key in params.input) {
271            isEmpty = false;
272            var localContext = context.push({key: key, value: params.input[key]});
273            // TODO: Seems like a hack. Probably is a hack. Shouldn't be a hack
274            if(localContext && localContext.stack && localContext.stack.tail && localContext.stack.tail.head) {
275              localContext = localContext.push(localContext.stack.tail.head);
276            }
277            chunk.render(bodies.block, localContext);
278          }
279        }
280        if(isEmpty && bodies.empty) {
281          chunk.render(bodies.empty, context);
282        }
283        return chunk;
284      },
285
286      /**
287       * {@uuid /}
288       * {@uuid id="formID" /}
289       */
290      uuid: function(chunk, context, bodies, params) {
291        params = params || {};
292        var ID = params.id,
293          UUID;
294        if(ID && uuids[ID]) {
295          UUID = uuids[ID];
296        }
297        if(!UUID) {
298          UUID = uuid();
299          if(ID) {
300            uuids[ID] = UUID;
301          }
302        }
303        return chunk.write(UUID);
304      },
305
306      /**
307       * {@regex pat="([0-9]+)" mod="g" src="asdfh342342jfks"}{matches[1]}{/regex}
308       */
309      regex: function(chunk, context, bodies, params) {
310        params = params || {};
311        if(!params.pat) {
312          console.warn('No pattern supplied to @regex');
313        }
314        if(!params.src) {
315          console.warn('No src supplied to @regex');
316        }
317        var regex = new RegExp(params.pat, params.mod || '');
318        var localContext = context.push({matches: regex.exec(params.src)});
319        chunk.render(bodies.block, localContext);
320        return chunk;
321      }
322    });
323
324    var TemplatePromise = function TemplatePromise() {
325        Promise.apply(this, arguments);
326    };
327
328    TemplatePromise.prototype = Object.create(Promise.prototype);
329    TemplatePromise.prototype.constructor = TemplatePromise;
330
331    TemplatePromise.prototype.set = function(method, selector) {
332        return this
333        .then(function(output) {
334            return $(selector)[method](output);
335        });
336    };
337
338    TemplatePromise.prototype.methods = {
339        into: 'html',
340        append: 'append',
341        prepend: 'prepend',
342        after: 'after',
343        before: 'before',
344        replace: 'replaceWith'
345    };
346
347    _.each(TemplatePromise.prototype.methods, function(jQueryMethod, templateMethod) {
348        TemplatePromise.prototype[templateMethod] = function(selector) {
349            return this.set(jQueryMethod, selector);
350        };
351    });
352
353    var TemplateManager = function(dust) {
354        this.dust = dust;
355    };
356
357    TemplateManager.prototype.has = function(name) {
358        if(!name) throw new Error('No name supplied to FS.Template().has');
359        return !!this.dust.cache[name];
360    };
361
362    TemplateManager.prototype.add = function(source, name) {
363        if(!source) throw new Error('No source supplied to FS.Template().add');
364        if(!name) throw new Error('No name supplied to FS.Template().add');
365        return this.dust.loadSource(this.dust.compile(source, name));
366    };
367
368    var TemplateFactory = function(dust) {
369        this.dust = dust;
370        this.local = _.bind(this.local, this);
371        this.server = _.bind(this.server, this);
372        this._render = Promise.promisify(this.dust.render);
373
374        return _.bind(this.render, this);
375    };
376
377    TemplateFactory.prototype.local = function(template, context) {
378        return this._render(template, context);
379    };
380
381    TemplateFactory.prototype.server = function(template, context) {
382        if(!FS.API.appName.match(/(AchieveForms|AF-Renderer)/)) return this.local(template, context);
383
384        return FS.API.post('CreateTemplate', { template: template }, context)
385        .then(function(ret){
386          if(ret.error) throw new Error(ret.error);
387          return ret.html;
388        }).caught(function(err){
389          throw new Error(err.error || err);
390        })
391    };
392
393    TemplateFactory.prototype.render = function(template, context, server) {
394        if(!template) return new TemplateManager(this.dust);
395        /*if(root.IE && root.IEVersion <= 7) server = true;*/
396
397        var _this = this;
398        return new TemplatePromise(function (resolve, reject) {
399            return (server === true ? _this.server : _this.local)
400                (template, context || {}).then(resolve, reject);
401        });
402    };
403
404    var root = this;
405    return new TemplateFactory(dust);
406}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.