14a57fc757315c041c9a1f1371938355ed308c1d
[motion2.git] / apidoc / utils / handlebars_helper.js
1 define([
2     'locales',
3     'handlebars',
4     'diffMatchPatch'
5 ], function(locale, Handlebars, DiffMatchPatch) {
6
7     /**
8      * Return a text as markdown.
9      * Currently only a little helper to replace apidoc-inline Links (#Group:Name).
10      * Should be replaced with a full markdown lib.
11      * @param string text
12      */
13     Handlebars.registerHelper('markdown', function(text) {
14         if ( ! text ) {
15           return text;
16         }
17         text = text.replace(/((\[(.*?)\])?\(#)((.+?):(.+?))(\))/mg, function(match, p1, p2, p3, p4, p5, p6) {
18           var link = p3 || p5 + '/' + p6;
19           return '<a href="#api-' + p5 + '-' + p6 + '">' + link + '</a>';
20         });
21         return text;
22     });
23
24     /**
25      * set paramater type.
26      */
27     Handlebars.registerHelper("setInputType", function(text) {
28           if (text === "File") {
29             return "file";
30           }
31           return "text";
32     });
33
34     /**
35      * start/stop timer for simple performance check.
36      */
37     var timer;
38     Handlebars.registerHelper('startTimer', function(text) {
39         timer = new Date();
40         return '';
41     });
42
43     Handlebars.registerHelper('stopTimer', function(text) {
44         console.log(new Date() - timer);
45         return '';
46     });
47
48     /**
49      * Return localized Text.
50      * @param string text
51      */
52     Handlebars.registerHelper('__', function(text) {
53         return locale.__(text);
54     });
55
56     /**
57      * Console log.
58      * @param mixed obj
59      */
60     Handlebars.registerHelper('cl', function(obj) {
61         console.log(obj);
62         return '';
63     });
64
65     /**
66      * Replace underscore with space.
67      * @param string text
68      */
69     Handlebars.registerHelper('underscoreToSpace', function(text) {
70         return text.replace(/(_+)/g, ' ');
71     });
72
73     /**
74      *
75      */
76     Handlebars.registerHelper('assign', function(name) {
77         if(arguments.length > 0) {
78             var type = typeof(arguments[1]);
79             var arg = null;
80             if(type === 'string' || type === 'number' || type === 'boolean') arg = arguments[1];
81             Handlebars.registerHelper(name, function() { return arg; });
82         }
83         return '';
84     });
85
86     /**
87      *
88      */
89     Handlebars.registerHelper('nl2br', function(text) {
90         return _handlebarsNewlineToBreak(text);
91     });
92
93     /**
94      *
95      */
96     Handlebars.registerHelper('if_eq', function(context, options) {
97         var compare = context;
98         // Get length if context is an object
99         if (context instanceof Object && ! (options.hash.compare instanceof Object))
100              compare = Object.keys(context).length;
101
102         if (compare === options.hash.compare)
103             return options.fn(this);
104
105         return options.inverse(this);
106     });
107
108     /**
109      *
110      */
111     Handlebars.registerHelper('if_gt', function(context, options) {
112         var compare = context;
113         // Get length if context is an object
114         if (context instanceof Object && ! (options.hash.compare instanceof Object))
115              compare = Object.keys(context).length;
116
117         if(compare > options.hash.compare)
118             return options.fn(this);
119
120         return options.inverse(this);
121     });
122
123     /**
124      *
125      */
126     var templateCache = {};
127     Handlebars.registerHelper('subTemplate', function(name, sourceContext) {
128         if ( ! templateCache[name])
129             templateCache[name] = Handlebars.compile($('#template-' + name).html());
130
131         var template = templateCache[name];
132         var templateContext = $.extend({}, this, sourceContext.hash);
133         return new Handlebars.SafeString( template(templateContext) );
134     });
135
136     /**
137      *
138      */
139     Handlebars.registerHelper('toLowerCase', function(value) {
140         return (value && typeof value === 'string') ? value.toLowerCase() : '';
141     });
142
143     /**
144      *
145      */
146     Handlebars.registerHelper('splitFill', function(value, splitChar, fillChar) {
147         var splits = value.split(splitChar);
148         return new Array(splits.length).join(fillChar) + splits[splits.length - 1];
149     });
150
151     /**
152      * Convert Newline to HTML-Break (nl2br).
153      *
154      * @param {String} text
155      * @returns {String}
156      */
157     function _handlebarsNewlineToBreak(text) {
158         return ('' + text).replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br>' + '$2');
159     }
160
161     /**
162      *
163      */
164     Handlebars.registerHelper('each_compare_list_field', function(source, compare, options) {
165         var fieldName = options.hash.field;
166         var newSource = [];
167         if (source) {
168             source.forEach(function(entry) {
169                 var values = entry;
170                 values['key'] = entry[fieldName];
171                 newSource.push(values);
172             });
173         }
174
175         var newCompare = [];
176         if (compare) {
177             compare.forEach(function(entry) {
178                 var values = entry;
179                 values['key'] = entry[fieldName];
180                 newCompare.push(values);
181             });
182         }
183         return _handlebarsEachCompared('key', newSource, newCompare, options);
184     });
185
186     /**
187      *
188      */
189     Handlebars.registerHelper('each_compare_keys', function(source, compare, options) {
190         var newSource = [];
191         if (source) {
192             var sourceFields = Object.keys(source);
193             sourceFields.forEach(function(name) {
194                 var values = {};
195                 values['value'] = source[name];
196                 values['key'] = name;
197                 newSource.push(values);
198             });
199         }
200
201         var newCompare = [];
202         if (compare) {
203             var compareFields = Object.keys(compare);
204             compareFields.forEach(function(name) {
205                 var values = {};
206                 values['value'] = compare[name];
207                 values['key'] = name;
208                 newCompare.push(values);
209             });
210         }
211         return _handlebarsEachCompared('key', newSource, newCompare, options);
212     });
213
214     /**
215      *
216      */
217     Handlebars.registerHelper('each_compare_field', function(source, compare, options) {
218         return _handlebarsEachCompared('field', source, compare, options);
219     });
220
221     /**
222      *
223      */
224     Handlebars.registerHelper('each_compare_title', function(source, compare, options) {
225         return _handlebarsEachCompared('title', source, compare, options);
226     });
227
228     /**
229      *
230      */
231     Handlebars.registerHelper('reformat', function(source, type){
232         if (type == 'json')
233             try {
234                return JSON.stringify(JSON.parse(source.trim()),null, "    ");
235             } catch(e) {
236
237             }
238         return source
239     });
240
241     /**
242      *
243      */
244     Handlebars.registerHelper('showDiff', function(source, compare, options) {
245         var ds = '';
246         if(source === compare) {
247             ds = source;
248         } else {
249             if( ! source)
250                 return compare;
251
252             if( ! compare)
253                 return source;
254
255             var d = diffMatchPatch.diff_main(stripHtml(compare), stripHtml(source));
256             diffMatchPatch.diff_cleanupSemantic(d);
257             ds = diffMatchPatch.diff_prettyHtml(d);
258             ds = ds.replace(/&para;/gm, '');
259         }
260         if(options === 'nl2br')
261             ds = _handlebarsNewlineToBreak(ds);
262
263         return ds;
264     });
265
266     /**
267      *
268      */
269     function _handlebarsEachCompared(fieldname, source, compare, options)
270     {
271         var dataList = [];
272         var index = 0;
273         if(source) {
274             source.forEach(function(sourceEntry) {
275                 var found = false;
276                 if (compare) {
277                     compare.forEach(function(compareEntry) {
278                         if(sourceEntry[fieldname] === compareEntry[fieldname]) {
279                             var data = {
280                                 typeSame: true,
281                                 source: sourceEntry,
282                                 compare: compareEntry,
283                                 index: index
284                             };
285                             dataList.push(data);
286                             found = true;
287                             index++;
288                         }
289                     });
290                 }
291                 if ( ! found) {
292                     var data = {
293                         typeIns: true,
294                         source: sourceEntry,
295                         index: index
296                     };
297                     dataList.push(data);
298                     index++;
299                 }
300             });
301         }
302
303         if (compare) {
304             compare.forEach(function(compareEntry) {
305                 var found = false;
306                 if (source) {
307                     source.forEach(function(sourceEntry) {
308                         if(sourceEntry[fieldname] === compareEntry[fieldname])
309                             found = true;
310                     });
311                 }
312                 if ( ! found) {
313                     var data = {
314                         typeDel: true,
315                         compare: compareEntry,
316                         index: index
317                     };
318                     dataList.push(data);
319                     index++;
320                 }
321             });
322         }
323
324         var ret = '';
325         var length = dataList.length;
326         for (var index in dataList) {
327             if(index == (length - 1))
328                 dataList[index]['_last'] = true;
329             ret = ret + options.fn(dataList[index]);
330         }
331         return ret;
332     }
333
334     var diffMatchPatch = new DiffMatchPatch();
335
336     /**
337      * Overwrite Colors
338      */
339     DiffMatchPatch.prototype.diff_prettyHtml = function(diffs) {
340       var html = [];
341       var pattern_amp = /&/g;
342       var pattern_lt = /</g;
343       var pattern_gt = />/g;
344       var pattern_para = /\n/g;
345       for (var x = 0; x < diffs.length; x++) {
346         var op = diffs[x][0];    // Operation (insert, delete, equal)
347         var data = diffs[x][1];  // Text of change.
348         var text = data.replace(pattern_amp, '&amp;').replace(pattern_lt, '&lt;')
349             .replace(pattern_gt, '&gt;').replace(pattern_para, '&para;<br>');
350         switch (op) {
351           case DIFF_INSERT:
352             html[x] = '<ins>' + text + '</ins>';
353             break;
354           case DIFF_DELETE:
355             html[x] = '<del>' + text + '</del>';
356             break;
357           case DIFF_EQUAL:
358             html[x] = '<span>' + text + '</span>';
359             break;
360         }
361       }
362       return html.join('');
363     };
364
365     /**
366      * Fixes html after comparison (#506, #538, #616, #825)
367      */
368     function stripHtml(html){
369       var div = document.createElement("div");
370       div.innerHTML = html;
371       return div.textContent || div.innerText || "";
372     }
373
374     // Exports
375     return Handlebars;
376 });