Completed
Pull Request — master (#67)
by
unknown
02:05
created

src/cli/cms/templates/prepare.js   A

Complexity

Total Complexity 34
Complexity/F 2.62

Size

Lines of Code 246
Function Count 13

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
c 1
b 0
f 0
nc 1
dl 0
loc 246
rs 9.2
wmc 34
mnd 5
bc 28
fnc 13
bpm 2.1538
cpm 2.6153
noi 7

10 Functions

Rating   Name   Duplication   Size   Complexity  
A prepare.js ➔ removeHiddenAbeTag 0 3 1
C prepare.js ➔ addAbeSourceComment 0 44 7
A prepare.js ➔ addAbeHtmlTagBetweenAbeTags 0 8 2
A prepare.js ➔ removeHandlebarsRawFromHtml 0 3 1
B prepare.js ➔ insertAbeEach 0 20 5
A prepare.js ➔ addAbeDataAttrForHtmlAttributes 0 17 3
A prepare.js ➔ splitEachBlocks 0 10 2
A prepare.js ➔ replaceAbeEachIndex 0 3 1
B prepare.js ➔ indexEachBlocks 0 36 1
A prepare.js ➔ addAbeDataAttrForHtmlTag 0 12 2
1
import Handlebars from 'handlebars'
2
3
import {
4
  cmsData
5
  ,config
6
  ,cmsTemplates
7
} from '../../'
8
9
/**
10
 * THIS:
11
<span>{{abe type='text' key='text_visible'}}</span>
12
13
 * BECOME:
14
<span data-abe-text_visible="text_visible" >{{abe type='text' key='text_visible'}}</span>
15
16
 * @param {[type]} template [description]
17
 */
18
export function addAbeDataAttrForHtmlTag(template) {
19
  var match
20
  while (match = cmsData.regex.abePattern.exec(template)) {
21
    var getattr = cmsData.regex.getAttr(match, 'key').replace(/\./g, '-')
22
    template = template.replace(
23
      cmsData.regex.escapeTextToRegex(match[0], 'g'),
24
      ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="'  + getattr + '" ' + match[0]
25
    )
26
  }
27
28
  return template
29
}
30
31
/**
32
 * 
33
 * THIS:
34
<img src="{{abe type='image' key='image_key' tab='default'}}" alt="">
35
36
 * BECOME:
37
<img data-abe-attr-image_key="src" data-abe-image_key="image_key" data-abe-attr-image_key="src"
38
data-abe-image_key="image_key" src="{{abe type='image' key='image_key' tab='default' has-abe=1 has-abe=1}}" alt="">
39
40
 * @param {[type]} template [description]
41
 */
42
export function addAbeDataAttrForHtmlAttributes(template) {
43
  var match
44
  while (match = cmsData.regex.abeAsAttributePattern.exec(template)) { // While regexp match {{attribut}}, ex: link, image ...
45
    if(cmsData.regex.isSingleAbe(match[0], template)){
46
      var more_attr = ''
47
      var getattr = cmsData.regex.getAttr(match, 'key').replace(/\./g, '-')
48
      template = template.replace(
49
        new RegExp(match[0]),
50
        ' data-abe-attr-' + cmsData.regex.validDataAbe(getattr) + '="'  + (match[0].split('=')[0]).trim() + '"' +
51
        ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="'  + getattr + '"' +
52
        more_attr + match[0].replace('}}', ' has-abe=1}}')
53
      )
54
    }
55
  }
56
57
  return template
58
}
59
60
/**
61
 * Example:
62
 *
63
 *
64
 * THIS:
65
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
66
67
{{#each data_key}}
68
  {{title}}
69
{{/each}}
70
71
 *
72
 * BECOME THIS
73
74
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
75
76
{{#each data_key}}
77
  {{title}}
78
{{/each}}<!-- [[data_key]] %7B%7B%23each%20data_key%7D%7D%0A%09%7B%7Btitle%7D%7D%0A%7B%7B/each%7D%7D -->
79
80
 * @param {[type]} template [description]
81
 * @param {[type]} json     [description]
82
 */
83
export function addAbeSourceComment(template, json) {
84
  
85
  // Don't know what it does...
86
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
87
    var keys = Object.keys(json.abe_source)
88
    
89
    for(var i in keys) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
90
      var replaceEach = new RegExp(`<!-- \\[\\[${keys[i]}\\]\\][\\s\\S]*?-->`, 'g')
91
      template = template.replace(replaceEach, '')
92
93
      var patAttrSource = new RegExp(' ([A-Za-z0-9\-\_]+)=["|\'].*?({{' + keys[i] + '}}).*?["|\']', 'g')
94
      var patAttrSourceMatch = template.match(patAttrSource)
95
96
      if(patAttrSourceMatch != null) {
97
        let checkEscapedRegex = /["|'](.*?)["|']/
98
        let patAttrSourceInside = new RegExp('(\\S+)=["\']?((?:.(?!["\']?\\s+(?:\\S+)=|[>"\']))+.)["\']?({{' + keys[i] + '}}).*?["|\']', 'g')
99
        Array.prototype.forEach.call(patAttrSourceMatch, (pat) => {
100
          let patAttrSourceCheck = patAttrSourceInside.exec(pat)
101
          if(patAttrSourceCheck != null) {
102
            
103
            let checkEscaped = checkEscapedRegex.exec(patAttrSourceCheck[0])
104
            if(checkEscaped != null && checkEscaped.length > 0) {
105
              checkEscaped = escape(checkEscaped[1])
106
              template = template.replace(
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 91. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
107
                patAttrSourceCheck[0],
108
                ` data-abe-attr="${patAttrSourceCheck[1]}" data-abe-attr-escaped="${checkEscaped}" data-abe="${keys[i]}" ${patAttrSourceCheck[0]}`
0 ignored issues
show
introduced by
The variable i is changed by the for-each loop on line 89. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
109
              )
110
            }
111
          }
112
        })
113
      }
114
115
      var eachSource = new RegExp(`({{#each ${keys[i]}}[\\s\\S a-z]*?{{\/each}})`, 'g')
116
      var matches = template.match(eachSource)
117
      if(typeof matches !== 'undefined' && matches !== null) {
118
        Array.prototype.forEach.call(matches, (match) => {
119
          template = template.replace(match, `${match}<!-- [[${keys[i]}]] ${cmsTemplates.encodeAbeTagAsComment(match)} -->`)
0 ignored issues
show
introduced by
The variable i is changed by the for-each loop on line 89. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
Bug introduced by
The variable template is changed as part of the for-each loop for example by template.replace(replaceEach, "") on line 91. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
120
        })
121
      }
122
    }
123
  }
124
125
  return template
126
}
127
128
/**
129
 * THIS:
130
<span>{{abe type='text' key='text_visible'}}</span>
131
132
 * BECOME:
133
<span><abe>{{abe type='text' key='text_visible'}}</abe></span>
134
135
 * @param {[type]} template [description]
136
 */
137
export function addAbeHtmlTagBetweenAbeTags(template) {
138
  var match
139
  while (match = cmsData.regex.abePattern.exec(template)) {
140
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
141
  }
142
143
  return template
144
}
145
146
/**
147
 * THIS:
148
[index].
149
150
 * BECOME:
151
{{@index}}-
152
153
 *  @param  {[type]} template [description]
154
 * @return {[type]}          [description]
155
 */
156
export function replaceAbeEachIndex(template) {
157
  return template.replace(/\[index\]\./g, '{{@index}}-')
158
}
159
160
export function removeHiddenAbeTag(template) {
161
  return template.replace(/(\{\{abe.*visible=[\'|\"]false.*\}\})/g, '')
162
}
163
164
/**
165
 * Remove {{abe type=*}} from html if attribute visible="false"
166
 * @param  {[type]} template [description]
167
 * @return {[type]}          [description]
168
 */
169
export function removeHandlebarsRawFromHtml(template) {
170
  return template.replace(/\{\{\{\{\/?raw\}\}\}\}/g, '')
171
}
172
173
/**
174
 * split {{#each}}...{{/each}} into an array
175
 * 
176
 * @param  {[type]} template [description]
177
 * @return {[type]}          [description]
178
 */
179
export function splitEachBlocks(template) {
180
  var block
181
  var blocks = []
182
183
  while (block = cmsData.regex.blockPattern.exec(template)) {
184
    blocks.push(block[1])
185
  }
186
187
  return blocks
188
}
189
190
export function indexEachBlocks(template, onlyHtml) {
191
  // create an array of {{each}} blocks
192
  var blocks = cmsTemplates.prepare.splitEachBlocks(template)
193
194
  Array.prototype.forEach.call(blocks, (block) => {
195
    var key = block.match(/#each (.*)\}\}/)
196
    key = key[1]
197
    var match
198
199
    if(!onlyHtml) {
200
201
      var voidData = {}
202
      voidData[key] = [{}]
203
      var blockCompiled = Handlebars.compile(block.replace(/{{abe (.*?)}}/g, '[[abe $1]]').replace(new RegExp(`\\.\\.\/${config.meta.name}`, 'g'), config.meta.name))
204
      var blockHtml = blockCompiled(voidData, {data: {intl: config.intlData}}).replace(/\[\[abe (.*?)\]\]/g, '{{abe $1}}')
205
206
      // je rajoute un data-abe-block avec index sur tous les tags html du bloc each
207
      var textEachWithIndex = block.replace(/(<(?![\/])[A-Za-z0-9!-]*)/g, '$1 data-abe-block="' + key + '{{@index}}"')
208
209
      // je remplace le block dans le texte par ça
210
      template = template.replace(block, textEachWithIndex + `<!-- [[${key}]] ${cmsTemplates.encodeAbeTagAsComment(blockHtml)} -->`)
211
    }
212
213
    // Pour chaque tag Abe, je mets en forme ce tag avec des data- supplémentaires
214
    while (match = cmsData.regex.abePattern.exec(block)) {
215
      template = cmsTemplates.prepare.insertAbeEach(template, match, key, cmsData.regex.eachBlockPattern.lastIndex - block.length, onlyHtml)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the while loop for example by cmsTemplates.prepare.ins...block.length, onlyHtml) on line 215. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
216
    }
217
218
    // Pour chaque tag Abe attribut de HTML, je mets en forme ce tag avec des data- supplémentaires sur le tag html parent
219
    while (match = cmsData.regex.abeAsAttributePattern.exec(block)) {
220
      template = cmsTemplates.prepare.insertAbeEach(template, match, key, cmsData.regex.eachBlockPattern.lastIndex - block.length, onlyHtml)
221
    }  
222
  })
223
224
  return template
225
}
226
227
export function insertAbeEach(template, theMatch, key, lastIndex, onlyHtml) {
228
  var matchBlock = theMatch[0]
229
  if(cmsData.regex.isEachStatement(matchBlock)) return
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
230
  if(cmsData.regex.isBlockAbe(matchBlock)){
231
    var matchblockattr = (matchBlock.split('=')[0]).trim()
232
    var getattr = cmsData.regex.getAttr(matchBlock, 'key').replace('.', '[index].')
233
    var newMatchBlock = ((!onlyHtml) ?
234
                          (/=[\"\']\{\{(.*?)\}\}/g.test(matchBlock) ?
235
                              ' data-abe-attr-' + cmsData.regex.validDataAbe(getattr) + '="'  + matchblockattr + '"' :
236
                              '') +
237
                          ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="' + getattr + '" ' + matchBlock :
238
                          matchBlock)
239
        .replace(new RegExp('(key=[\'|"])' + key + '.', 'g'), '$1' + key + '[index].')
240
        .replace(/\{\{abe/, '{{abe dictionnary=\'' + key + '\'')
241
242
    template = template.replace(matchBlock, newMatchBlock)
243
  }
244
245
  return template
246
}