Completed
Push — master ( 3b3ae1...61dd3f )
by greg
01:50
created

src/cli/cms/data/regex-helper.js   B

Complexity

Total Complexity 37
Complexity/F 2.85

Size

Lines of Code 183
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 183
rs 8.6
noi 5
wmc 37
mnd 2
bc 25
fnc 13
bpm 1.923
cpm 2.8461

5 Functions

Rating   Name   Duplication   Size   Complexity  
A regex-helper.js ➔ getEnclosingTags 0 15 1
B regex-helper.js ➔ querySelectorTags 0 43 2
A regex-helper.js ➔ escapeTextToRegex 0 4 1
A regex-helper.js ➔ isInsideOtherTag 0 19 1
B regex-helper.js ➔ explodeTag 0 32 2
1
2
export function getAttr (str, attr) {
3
  var rex = new RegExp(attr + '=["|\']([\\S\\s]*?)["|\']( +[a-zA-Z0-9-]*?=|}})')
4
  var res = rex.exec(str)
5
  res = (typeof res !== null && res !== null && res.length > 1) ? res[1] : ''
6
  return res
7
}
8
9
/**
10
 * Return array of tag found into html text
11
 * 
12
 * @param  {String} text html
13
 * @param  {String} tag name
14
 * @return {Array}  array of tags
15
 *
16
 * if a tag is inside a tag
17
 *
18
 * <div>
19
 *   <div></div>
20
 * <div>
21
 *
22
 * Will return the whole div (use querySelectorTags for that)
23
 */
24
function explodeTag(text, tag) {
25
  var startWithTags = false
0 ignored issues
show
Unused Code introduced by
The variable startWithTags seems to be never used. Consider removing it.
Loading history...
26
  if(text.indexOf('<' + tag) === 0) {
27
    startWithTags = true
28
  }
29
  var tags = text.split('<' + tag)
30
31
  var i = 0
32
  var reconstruct = []
33
  var wait = ''
34
35
  reconstruct.push(tags.shift())
36
  Array.prototype.forEach.call(tags, function(ele) {
37
    i++
38
    var matches = ele.match(escapeTextToRegex('</' + tag, 'g'))
39
    if(typeof matches !== 'undefined' && matches !== null && matches.length > 0) {
40
      Array.prototype.forEach.call(matches, function(match) {
0 ignored issues
show
Unused Code introduced by
The parameter match is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
41
        i--
42
      })
43
44
      if(i === 0) {
45
        reconstruct.push(wait + '<' + tag + ele)
46
        wait = ''
47
      }else {
48
        wait += '<' + tag + ele
49
      }
50
    }else {
51
      wait += '<' + tag + ele
52
    }
53
  })
54
  return reconstruct
55
}
56
57
/**
58
 * Return all tags inside text html
59
 * 
60
 * @param  {String}   text html
61
 * @param  {String}   tag name
62
 * @return {Array}    array of tags
63
 *
64
 * Exemple
65
 *
66
 * <div class="cl-1">
67
 *   <div class="cl-2"></div>
68
 * <div>
69
 *
70
 * will return an array with 2
71
 *
72
 * [
73
 *   '<div class="cl-1">
74
 *     <div class="cl-2"></div>
75
 *    <div>',
76
 *    
77
 *    '<div class="cl-2"></div>'
78
 * ]
79
 * 
80
 */
81
function querySelectorTags(text, tag) {
82
  var res = []
83
  var finalRes = []
84
85
  while(text !== ''){
86
    var checkTags = explodeTag(text, tag)
87
    text = ''
88
    Array.prototype.forEach.call(checkTags, function(ele) {
89
      res.push(ele)
90
91
      var matches = ele.match(escapeTextToRegex('<' + tag, 'g'))
92
      if(typeof matches !== 'undefined' && matches !== null && matches.length > 1) {
93
        var tagLength = '<' + tag
94
        tagLength = tagLength.length
95
96
        // remove first tag
97
        var start = ele.indexOf('<' + tag)
98
        ele = ele.substring(start + tagLength)
99
100
        // remove end tag
101
        var end = ele.lastIndexOf('</' + tag)
102
        ele = ele.substring(0, end)
103
104
        text += ele
0 ignored issues
show
Bug introduced by
The variable text is changed as part of the while loop for example by "" on line 87. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
105
      }
106
    })
107
  }
108
  
109
  Array.prototype.forEach.call(res, function(ele) {
110
    var matches = ele.match(escapeTextToRegex('<' + tag, 'g'))
111
    if(typeof matches !== 'undefined' && matches !== null && matches.length > 0) {
112
      var finalEleReg = new RegExp('<' + tag + '([\\s\\S]*?)<\\/' + tag + '>(?![\\s\\S]*<\/' + tag + '>)')
113
      finalEleReg = finalEleReg.exec(ele)
114
      if(typeof finalEleReg !== 'undefined' && finalEleReg !== null && finalEleReg.length > 0) {
115
        finalRes.push(finalEleReg[0])
116
      }else {
117
        finalRes.push(ele)
118
      }
119
    }
120
  })
121
122
  return finalRes
123
}
124
125
/**
126
 * Check if an html tag wrap an other tag and return only the deepest one
127
 * 
128
 * @param  {Array}    arr of tags
129
 * @return {Boolean}  true|false
130
 */
131
function isInsideOtherTag(arr) {
132
  var res = []
0 ignored issues
show
Unused Code introduced by
The variable res seems to be never used. Consider removing it.
Loading history...
133
134
  arr = arr.reverse()
135
136
  var uniq = arr.reduce(function(a, b) {
137
    var isUniq = true
138
    Array.prototype.forEach.call(arr, function(c) {
139
      if(c !== b && b.indexOf(c) !== -1) {
140
        isUniq = false
141
      }
142
    })
143
    if(isUniq) a.push(b)
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...
144
145
    return a
146
  },[])
147
148
  return uniq
149
}
150
151
/**
152
 * return html tags that enclose a string
153
 * 
154
 * @param  {String} text  html
155
 * @param  {String} match string to match
156
 * @param  {String} tag   html tag name
157
 * @return {Array} array of matches
158
 */
159
export function getEnclosingTags(text, match, tag) {
160
  var res = []
161
  var tags = querySelectorTags(text, tag)
162
  
163
  Array.prototype.forEach.call(tags, function(tag) {
164
    var matches = tag.match(escapeTextToRegex(match, 'g'))
165
    if(typeof matches !== 'undefined' && matches !== null && matches.length > 0) {
166
      res.push(tag)
167
    }
168
  })
169
170
  res = isInsideOtherTag(res)
171
172
  return res
173
}
174
175
/**
176
 * escape a regex
177
 * @param  {String} str
178
 * @param  {String} params g,m,i
179
 * @return {Object} RegExp
180
 */
181
export function escapeTextToRegex(str, params) {
182
  str = str.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')
183
  return new RegExp(str, params)
184
}