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

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

Complexity

Total Complexity 34
Complexity/F 2.62

Size

Lines of Code 259
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 259
rs 9.2
wmc 34
mnd 5
bc 28
fnc 13
bpm 2.1538
cpm 2.6153
noi 9

10 Functions

Rating   Name   Duplication   Size   Complexity  
A prepare.js ➔ addAbeDataAttrForHtmlTag 0 12 2
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
B prepare.js ➔ addAbeDataAttrForHtmlAttributes 0 30 3
A prepare.js ➔ splitEachBlocks 0 10 2
A prepare.js ➔ replaceAbeEachIndex 0 3 1
B prepare.js ➔ indexEachBlocks 0 36 1
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
  template = template.replace(/<([A-Za-z]+)/g, '\nABE_SPLIT<$1')
44
  var match
45
  while (match = cmsData.regex.abeAsAttributePattern.exec(template)) { // While regexp match {{attribut}}, ex: link, image ...
46
    if(cmsData.regex.isSingleAbe(match[2], template)){
47
      var more_attr = ''
0 ignored issues
show
Unused Code introduced by
The variable more_attr seems to be never used. Consider removing it.
Loading history...
48
      var getattr = cmsData.regex.getAttr(match, 'key').replace(/\./g, '-')
49
      var toReplace = match[0].replace(
50
        new RegExp(match[1]),
51
        ' data-abe-attr-' + cmsData.regex.validDataAbe(getattr) + '="'  + (match[0].split('=')[0]).trim() + '"' +
52
        ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="'  + getattr + '"' + match[1])
53
54
      toReplace = toReplace.replace(
55
        new RegExp(match[2]),
56
        match[2].replace('}}', ' has-abe=1}}')
57
      )
58
59
      console.log('* * * * * * * * * * * * * * * * * * * * * * * * * * * * *')
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
60
      console.log('toReplace', toReplace)
61
62
      template = template.replace(
63
        new RegExp(match[0]),
64
        toReplace
65
      )
66
    }
67
  }
68
  template = template.replace(/\nABE_SPLIT</g, '<')
69
70
  return template
71
}
72
73
/**
74
 * Example:
75
 *
76
 *
77
 * THIS:
78
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
79
80
{{#each data_key}}
81
  {{title}}
82
{{/each}}
83
84
 *
85
 * BECOME THIS
86
87
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
88
89
{{#each data_key}}
90
  {{title}}
91
{{/each}}<!-- [[data_key]] %7B%7B%23each%20data_key%7D%7D%0A%09%7B%7Btitle%7D%7D%0A%7B%7B/each%7D%7D -->
92
93
 * @param {[type]} template [description]
94
 * @param {[type]} json     [description]
95
 */
96
export function addAbeSourceComment(template, json) {
97
  
98
  // Don't know what it does...
99
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
100
    var keys = Object.keys(json.abe_source)
101
    
102
    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...
103
      var replaceEach = new RegExp(`<!-- \\[\\[${keys[i]}\\]\\][\\s\\S]*?-->`, 'g')
104
      template = template.replace(replaceEach, '')
105
106
      var patAttrSource = new RegExp(' ([A-Za-z0-9\-\_]+)=["|\'].*?({{' + keys[i] + '}}).*?["|\']', 'g')
107
      var patAttrSourceMatch = template.match(patAttrSource)
108
109
      if(patAttrSourceMatch != null) {
110
        let checkEscapedRegex = /["|'](.*?)["|']/
111
        let patAttrSourceInside = new RegExp('(\\S+)=["\']?((?:.(?!["\']?\\s+(?:\\S+)=|[>"\']))+.)["\']?({{' + keys[i] + '}}).*?["|\']', 'g')
112
        Array.prototype.forEach.call(patAttrSourceMatch, (pat) => {
113
          let patAttrSourceCheck = patAttrSourceInside.exec(pat)
114
          if(patAttrSourceCheck != null) {
115
            
116
            let checkEscaped = checkEscapedRegex.exec(patAttrSourceCheck[0])
117
            if(checkEscaped != null && checkEscaped.length > 0) {
118
              checkEscaped = escape(checkEscaped[1])
119
              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 104. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
120
                patAttrSourceCheck[0],
121
                ` 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 102. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
122
              )
123
            }
124
          }
125
        })
126
      }
127
128
      var eachSource = new RegExp(`({{#each ${keys[i]}}[\\s\\S a-z]*?{{\/each}})`, 'g')
129
      var matches = template.match(eachSource)
130
      if(typeof matches !== 'undefined' && matches !== null) {
131
        Array.prototype.forEach.call(matches, (match) => {
132
          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 102. 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 104. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
133
        })
134
      }
135
    }
136
  }
137
138
  return template
139
}
140
141
/**
142
 * THIS:
143
<span>{{abe type='text' key='text_visible'}}</span>
144
145
 * BECOME:
146
<span><abe>{{abe type='text' key='text_visible'}}</abe></span>
147
148
 * @param {[type]} template [description]
149
 */
150
export function addAbeHtmlTagBetweenAbeTags(template) {
151
  var match
152
  while (match = cmsData.regex.abePattern.exec(template)) {
153
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
154
  }
155
156
  return template
157
}
158
159
/**
160
 * THIS:
161
[index].
162
163
 * BECOME:
164
{{@index}}-
165
166
 *  @param  {[type]} template [description]
167
 * @return {[type]}          [description]
168
 */
169
export function replaceAbeEachIndex(template) {
170
  return template.replace(/\[index\]\./g, '{{@index}}-')
171
}
172
173
export function removeHiddenAbeTag(template) {
174
  return template.replace(/(\{\{abe.*visible=[\'|\"]false.*\}\})/g, '')
175
}
176
177
/**
178
 * Remove {{abe type=*}} from html if attribute visible="false"
179
 * @param  {[type]} template [description]
180
 * @return {[type]}          [description]
181
 */
182
export function removeHandlebarsRawFromHtml(template) {
183
  return template.replace(/\{\{\{\{\/?raw\}\}\}\}/g, '')
184
}
185
186
/**
187
 * split {{#each}}...{{/each}} into an array
188
 * 
189
 * @param  {[type]} template [description]
190
 * @return {[type]}          [description]
191
 */
192
export function splitEachBlocks(template) {
193
  var block
194
  var blocks = []
195
196
  while (block = cmsData.regex.blockPattern.exec(template)) {
197
    blocks.push(block[1])
198
  }
199
200
  return blocks
201
}
202
203
export function indexEachBlocks(template, onlyHtml) {
204
  // create an array of {{each}} blocks
205
  var blocks = cmsTemplates.prepare.splitEachBlocks(template)
206
207
  Array.prototype.forEach.call(blocks, (block) => {
208
    var key = block.match(/#each (.*)\}\}/)
209
    key = key[1]
210
    var match
211
212
    if(!onlyHtml) {
213
214
      var voidData = {}
215
      voidData[key] = [{}]
216
      var blockCompiled = Handlebars.compile(block.replace(/{{abe (.*?)}}/g, '[[abe $1]]').replace(new RegExp(`\\.\\.\/${config.meta.name}`, 'g'), config.meta.name))
217
      var blockHtml = blockCompiled(voidData, {data: {intl: config.intlData}}).replace(/\[\[abe (.*?)\]\]/g, '{{abe $1}}')
218
219
      // je rajoute un data-abe-block avec index sur tous les tags html du bloc each
220
      var textEachWithIndex = block.replace(/(<(?![\/])[A-Za-z0-9!-]*)/g, '$1 data-abe-block="' + key + '{{@index}}"')
221
222
      // je remplace le block dans le texte par ça
223
      template = template.replace(block, textEachWithIndex + `<!-- [[${key}]] ${cmsTemplates.encodeAbeTagAsComment(blockHtml)} -->`)
224
    }
225
226
    // Pour chaque tag Abe, je mets en forme ce tag avec des data- supplémentaires
227
    while (match = cmsData.regex.abePattern.exec(block)) {
228
      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 228. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
229
    }
230
231
    // Pour chaque tag Abe attribut de HTML, je mets en forme ce tag avec des data- supplémentaires sur le tag html parent
232
    while (match = cmsData.regex.abeAsAttributePattern.exec(block)) {
233
      template = cmsTemplates.prepare.insertAbeEach(template, match, key, cmsData.regex.eachBlockPattern.lastIndex - block.length, onlyHtml)
234
    }  
235
  })
236
237
  return template
238
}
239
240
export function insertAbeEach(template, theMatch, key, lastIndex, onlyHtml) {
241
  var matchBlock = theMatch[0]
242
  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...
243
  if(cmsData.regex.isBlockAbe(matchBlock)){
244
    var matchblockattr = (matchBlock.split('=')[0]).trim()
245
    var getattr = cmsData.regex.getAttr(matchBlock, 'key').replace('.', '[index].')
246
    var newMatchBlock = ((!onlyHtml) ?
247
                          (/=[\"\']\{\{(.*?)\}\}/g.test(matchBlock) ?
248
                              ' data-abe-attr-' + cmsData.regex.validDataAbe(getattr) + '="'  + matchblockattr + '"' :
249
                              '') +
250
                          ' data-abe-' + cmsData.regex.validDataAbe(getattr) + '="' + getattr + '" ' + matchBlock :
251
                          matchBlock)
252
        .replace(new RegExp('(key=[\'|"])' + key + '.', 'g'), '$1' + key + '[index].')
253
        .replace(/\{\{abe/, '{{abe dictionnary=\'' + key + '\'')
254
255
    template = template.replace(matchBlock, newMatchBlock)
256
  }
257
258
  return template
259
}