Completed
Push — master ( f65d8f...4f3de5 )
by Pavel
04:14 queued 01:54
created

docstemplate/utils/handlebars_helper.js   D

Complexity

Total Complexity 68
Complexity/F 2.19

Size

Lines of Code 340
Function Count 31

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 0
nc 48
dl 0
loc 340
rs 4.2608
c 1
b 0
f 1
wmc 68
mnd 3
bc 49
fnc 31
bpm 1.5806
cpm 2.1934
noi 26

How to fix   Complexity   

Complexity

Complex classes like docstemplate/utils/handlebars_helper.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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