Completed
Pull Request — master (#81)
by
unknown
02:10
created

prepare.js ➔ getAbeAttributeData   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
c 0
b 0
f 0
nc 2
nop 4
dl 0
loc 23
rs 9.0856
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
export function addHasAbeAttr(text) {
32
  return text.replace('}}', ' has-abe=1}}')
33
}
34
35
export function getAbeAttributeData(match, text, htmlAttribute, abeTag) {
36
  var valueOfAttritube
37
  var key = cmsData.regex.getAttr(match, 'key')
38
  var res
39
40
  if (cmsData.regex.isSingleAbe(match, text)) {
41
    valueOfAttritube = key.replace(/\./g, '-')
42
    key = cmsData.regex.validDataAbe(valueOfAttritube)
43
    key = key.replace(/\./g, '-')
44
    res = ' data-abe-attr-' + valueOfAttritube + '="'  + htmlAttribute + '"' + ' data-abe-' + valueOfAttritube + '="'  + key + '"' + abeTag
45
  }else {
46
    valueOfAttritube = key.split('.')
47
    var parentKey = valueOfAttritube.shift()
48
    valueOfAttritube = `${parentKey}[index].${valueOfAttritube[0]}`
49
    var valueOfAttritubeIndexed = valueOfAttritube.replace(/\[index\]/, '{{@index}}')
50
    key = cmsData.regex.validDataAbe(valueOfAttritube)
51
52
    res = ` data-abe-attr-${valueOfAttritube}="${htmlAttribute}"  data-abe-${valueOfAttritube}="${key}"`
53
    + ` data-abe-attr-${valueOfAttritubeIndexed}="${htmlAttribute}" data-abe-${valueOfAttritubeIndexed}="${key}"${abeTag}`
54
  }
55
56
  return res
57
}
58
59
/**
60
 *
61
 * IF ABE TAG SINGLE (NOT ABE EACH STATEMENT)
62
 * 
63
 * THIS:
64
<img src="{{abe type='image' key='image_key' tab='default'}}" alt="">
65
66
 * BECOME:
67
<img data-abe-attr-image_key="src" data-abe-image_key="image_key" data-abe-attr-image_key="src"
68
data-abe-image_key="image_key" src="{{abe type='image' key='image_key' tab='default' has-abe=1 has-abe=1}}" alt="">
69
70
 *
71
 * IF ABE EACH TAG
72
 * THIS:
73
{{#each test}}
74
  <img src="{{abe type='image' key='test.img' desc='test_img' tab='default'}}" alt="">
75
{{/each}}
76
77
 * BECOME:
78
{{#each test}}
79
  <img data-abe-attr-test[index].img="src" data-abe-test[index].img="test[index].img" src="{{abe type='image' key='test.img' desc='test_img' tab='default' has-abe=1}}" alt="">
80
{{/each}}
81
82
 * @param {[type]} template [description]
83
 */
84
export function addAbeDataAttrForHtmlAttributes(template) {
85
  var text = template.replace(/<([A-Za-z]+)/g, '\nABE_SPLIT<$1')
86
  let abeTagIntoAttribute = text.match(cmsData.regex.abeAsAttributePattern)
87
88
  if (abeTagIntoAttribute != null) {
89
    Array.prototype.forEach.call(abeTagIntoAttribute, (abeIntoTag) => {
90
      let matchAbeTag = /({{abe.*?[\s\S].*?}})/g.exec(abeIntoTag)
91
92
      if(matchAbeTag != null && matchAbeTag[1] != null) {
93
        var toReplace = cmsTemplates.prepare.getAbeAttributeData(matchAbeTag[1], text, (abeIntoTag.split('=')[0]).trim(), abeIntoTag)
94
95
        toReplace = toReplace.replace(
96
          cmsData.regex.escapeTextToRegex(matchAbeTag[1]),
97
          cmsTemplates.prepare.addHasAbeAttr(matchAbeTag[1])
98
        )
99
100
        text = text.replace(
101
          cmsData.regex.escapeTextToRegex(abeIntoTag),
102
          toReplace
103
        )
104
      }
105
    })
106
  }
107
  text = text.replace(/\nABE_SPLIT</g, '<')
108
109
  return text
110
}
111
112
/**
113
 * Example:
114
 *
115
 *
116
 * THIS:
117
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
118
119
{{#each data_key}}
120
  {{title}}
121
{{/each}}
122
123
 *
124
 * BECOME THIS
125
126
{{abe type='data' key='data_key' source='select title from article' display='title' editable='true' tab='default'}}
127
128
{{#each data_key}}
129
  {{title}}
130
{{/each}}<!-- [[data_key]] %7B%7B%23each%20data_key%7D%7D%0A%09%7B%7Btitle%7D%7D%0A%7B%7B/each%7D%7D -->
131
132
 * @param {[type]} template [description]
133
 * @param {[type]} json     [description]
134
 */
135
export function addAbeSourceComment(template, json) {
136
  
137
  // Don't know what it does...
138
  if(typeof json.abe_source !== 'undefined' && json.abe_source !== null) {
139
    var keys = Object.keys(json.abe_source)
140
    
141
    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...
142
      var replaceEach = new RegExp(`<!-- \\[\\[${keys[i]}\\]\\][\\s\\S]*?-->`, 'g')
143
      template = template.replace(replaceEach, '')
144
145
      var patAttrSource = new RegExp(' ([A-Za-z0-9\-\_]+)=["|\'].*?({{' + keys[i] + '}}).*?["|\']', 'g')
146
      var patAttrSourceMatch = template.match(patAttrSource)
147
148
      if(patAttrSourceMatch != null) {
149
        let checkEscapedRegex = /["|'](.*?)["|']/
150
        let patAttrSourceInside = new RegExp('(\\S+)=["\']?((?:.(?!["\']?\\s+(?:\\S+)=|[>"\']))+.)["\']?({{' + keys[i] + '}}).*?["|\']', 'g')
151
        Array.prototype.forEach.call(patAttrSourceMatch, (pat) => {
152
          let patAttrSourceCheck = patAttrSourceInside.exec(pat)
153
          if(patAttrSourceCheck != null) {
154
            
155
            let checkEscaped = checkEscapedRegex.exec(patAttrSourceCheck[0])
156
            if(checkEscaped != null && checkEscaped.length > 0) {
157
              checkEscaped = escape(checkEscaped[1])
158
              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 143. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
159
                patAttrSourceCheck[0],
160
                ` 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 141. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
161
              )
162
            }
163
          }
164
        })
165
      }
166
167
      var eachSource = new RegExp(`({{#each ${keys[i]}}[\\s\\S a-z]*?{{\/each}})`, 'g')
168
      var matches = template.match(eachSource)
169
      if(typeof matches !== 'undefined' && matches !== null) {
170
        Array.prototype.forEach.call(matches, (match) => {
171
          template = template.replace(match, `${match}<!-- [[${keys[i]}]] ${cmsTemplates.encodeAbeTagAsComment(match)} -->`)
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 143. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
introduced by
The variable i is changed by the for-each loop on line 141. Only the value of the last iteration will be visible in this function if it is called outside of the loop.
Loading history...
172
        })
173
      }
174
    }
175
  }
176
177
  return template
178
}
179
180
/**
181
 * THIS:
182
<span>{{abe type='text' key='text_visible'}}</span>
183
184
 * BECOME:
185
<span><abe>{{abe type='text' key='text_visible'}}</abe></span>
186
187
 * @param {[type]} template [description]
188
 */
189
export function addAbeHtmlTagBetweenAbeTags(template) {
190
  var match
191
  while (match = cmsData.regex.abePattern.exec(template)) {
192
    template = template.replace(cmsData.regex.escapeTextToRegex(match[1], 'g'), '<abe>' + match[1].trim() + '</abe>')
193
  }
194
195
  return template
196
}
197
198
/**
199
 * THIS:
200
[index].
201
202
 * BECOME:
203
{{@index}}-
204
205
 *  @param  {[type]} template [description]
206
 * @return {[type]}          [description]
207
 */
208
export function replaceAbeEachIndex(template) {
209
  return template.replace(/\[index\]\./g, '{{@index}}-')
210
}
211
212
export function removeHiddenAbeTag(template) {
213
  return template.replace(/(\{\{abe.*visible=[\'|\"]false.*\}\})/g, '')
214
}
215
216
/**
217
 * Remove {{abe type=*}} from html if attribute visible="false"
218
 * @param  {[type]} template [description]
219
 * @return {[type]}          [description]
220
 */
221
export function removeHandlebarsRawFromHtml(template) {
222
  return template.replace(/\{\{\{\{\/?raw\}\}\}\}/g, '')
223
}
224
225
/**
226
 * split {{#each}}...{{/each}} into an array
227
 * 
228
 * @param  {[type]} template [description]
229
 * @return {[type]}          [description]
230
 */
231
export function splitEachBlocks(template) {
232
  var block
233
  var blocks = []
234
235
  while (block = cmsData.regex.blockPattern.exec(template)) {
236
    blocks.push(block[1])
237
  }
238
239
  return blocks
240
}
241
242
export function indexEachBlocks(template, onlyHtml) {
243
  // create an array of {{each}} blocks
244
  var blocks = cmsTemplates.prepare.splitEachBlocks(template)
245
246
  Array.prototype.forEach.call(blocks, (block) => {
247
    var key = block.match(/#each (.*)\}\}/)[1]
248
    var match
249
250
    if(!onlyHtml) {
251
252
      var voidData = {}
253
      voidData[key] = [{}]
254
      var blockCompiled = Handlebars.compile(block.replace(/{{abe (.*?)}}/g, '[[abe $1]]').replace(new RegExp(`\\.\\.\/${config.meta.name}`, 'g'), config.meta.name))
255
      var blockHtml = blockCompiled(voidData, {data: {intl: config.intlData}}).replace(/\[\[abe (.*?)\]\]/g, '{{abe $1}}')
256
257
      // je rajoute un data-abe-block avec index sur tous les tags html du bloc each
258
      var textEachWithIndex = block.replace(/(<(?![\/])[A-Za-z0-9!-]*)/g, '$1 data-abe-block="' + key + '{{@index}}"')
259
260
      // je remplace le block dans le texte par ça
261
      template = template.replace(block, textEachWithIndex + `<!-- [[${key}]] ${cmsTemplates.encodeAbeTagAsComment(blockHtml)} -->`)
262
    }
263
264
    // Pour chaque tag Abe
265
    while (match = cmsData.regex.abeTag.exec(block)) {
266
      // template = cmsTemplates.prepare.insertAbeEach(template, match, key, cmsData.regex.eachBlockPattern.lastIndex - block.length, onlyHtml)
267
      template = cmsTemplates.prepare.addAbeDictionnary(template, match[0], key)
0 ignored issues
show
Bug introduced by
The variable template is changed as part of the while loop for example by cmsTemplates.prepare.add...template, match.0, key) on line 267. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
268
    } 
269
  })
270
271
  return template
272
}
273
274
/**
275
 * split {{#each}}...{{/each}} into an array
276
 *
277
 * THIS:
278
  {{abe type='text' key='test.title' desc='test title' tab='default'}}
279
280
 * BECOME THIS:
281
  {{abe dictionnary='test' type='text' key='test.title' desc='test title' tab='default'}}
282
283
 * 
284
 * @param  {[type]} template [description]
285
 * @return {[type]}          [description]
286
 */
287
export function addAbeDictionnary(template, match, key) {
288
  if(cmsData.regex.isEachStatement(match)) 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...
289
290
  if(cmsData.regex.isBlockAbe(match)){
291
    var abeDictionnary = match.replace(new RegExp('(key=[\'|"])' + key + '.', 'g'), '$1' + key + '[index].')
292
                               .replace(/\{\{abe/, '{{abe dictionnary=\'' + key + '\'')
293
294
    template = template.replace(match, abeDictionnary)
295
  }
296
297
  return template
298
}