Total Complexity | 68 |
Complexity/F | 4.53 |
Lines of Code | 284 |
Function Count | 15 |
Duplicated Lines | 66 |
Ratio | 23.24 % |
Changes | 0 |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like src/ub.strings.escape.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 | /** global: UB */ |
||
3 | UB.accentChars = ["Â", "Ã", "Ä", "À", "Á", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "Þ", "ß", "ẞ", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "ø", "ù", "ú", "û", "ü", "ý", "þ", "ÿ"]; |
||
4 | UB.accentEngChars = ["A", "A", "Ae", "A", "A", "A", "A", "C", "E", "E", "E", "E", "I", "I", "I", "I", "D", "N", "O", "O", "O", "O", "Oe", "O", "U", "U", "U", "Ue", "Y", "T", "ss", "ss", "a", "a", "a", "a", "ae", "a", "a", "c", "e", "e", "e", "e", "i", "i", "i", "i", "o", "n", "o", "o", "o", "o", "oe", "o", "u", "u", "u", "ue", "y", "t", "y"]; |
||
5 | UB.accentEngChars2 = ["A", "A", "A", "A", "A", "A", "A", "C", "E", "E", "E", "E", "I", "I", "I", "I", "D", "N", "O", "O", "O", "O", "O", "O", "U", "U", "U", "U", "Y", "T", "s", "s", "a", "a", "a", "a", "a", "a", "a", "c", "e", "e", "e", "e", "i", "i", "i", "i", "o", "n", "o", "o", "o", "o", "o", "o", "u", "u", "u", "u", "y", "t", "y"]; |
||
6 | |||
7 | UB.htmlCharNames = ["hellip", "deg", "prime", "lsaquo", "rsaquo", "frasl", "ndash", "mdash", "iexcl", "iquest", "ldquo", "rdquo", "lsquo", "rsquo", "laquo", "raquo", "cent", "copy", "divide", "micro", "middot", "para", "plusmn", "euro", "pound", "reg", "sect", "trade", "yen", "aacute", "Aacute", "agrave", "Agrave", "acirc", "Acirc", "aring", "Aring", "atilde", "Atilde", "auml", "Auml", "aelig", "AElig", "ccedil", "Ccedil", "eacute", "Eacute", "egrave", "Egrave", "ecirc", "Ecirc", "euml", "Euml", "iacute", "Iacute", "igrave", "Igrave", "icirc", "Icirc", "iuml", "ntilde", "Ntilde", "oacute", "Oacute", "ograve", "Ograve", "ocirc", "Ocirc", "oslash", "Oslash", "otilde", "Otilde", "ouml", "Ouml", "szlig", "uacute", "Uacute", "ugrave", "Ugrave", "ucirc", "Ucirc", "uuml", "Uuml", "yuml", "loz", "diams", "spades", "clubs", "hearts", "crarr", "larr", "rarr", "harr", "uarr", "darr", "lArr", "rArr", "hArr", "dArr", "uArr", "Delta", "nabla", "fnof", "pi", "plusmn", "divide", "times", "sup1", "sup2", "sup3", "frac12", "frac14", "frac34", "le", "ge", "middot", "prod", "sum", "minus", "radic", "infin", "ang", "sim", "isin", "prop", "asymp", "int", "forall", "exist", "part", "empty", "notin", "cap", "cup", "permil", "there4", "perp", "mu", "Theta", "curren"]; |
||
8 | UB.htmlCharUTF = ['…', '°', '`', '‹', '›', '⁄', '–', '—', '¡', '¿', '“', '”', '‘', '’', '«', '»', '¢', '©', '÷', 'µ', '·', '¶', '±', '€', '£', '®', '§', '™', '¥', 'á', 'Á', 'à', 'À', 'â', 'Â', 'å', 'Å', 'ã', 'Ã', 'ä', 'Ä', 'æ', 'Æ', 'ç', 'Ç', 'é', 'É', 'è', 'È', 'ê', 'Ê', 'ë', 'Ë', 'í', 'Í', 'ì', 'Ì', 'î', 'Î', 'Ï', 'ñ', 'Ñ', 'ó', 'Ó', 'ò', 'Ò', 'ô', 'Ô', 'ø', 'Ø', 'õ', 'Õ', 'ö', 'Ö', 'ß', 'ú', 'Ú', 'ù', 'Ù', 'û', 'Û', 'ü', 'Ü', 'ÿ', '◊', '♦', '♠', '♣', '♥', '↵', '←', '→', '↔', '↑', '↓', '⇐', '⇒', '⇔', '⇓', '⇑', 'Δ', '∇', 'ƒ', 'π', '±', '÷', '×', '¹', '²', '³', '½', '¼', '¾', '≤', '≥', '·', '∏', '∑', '−', '√', '∞', '∠', '∼', '∈', '∝', '≈', '∫', '∀', '∃', '∂', '∅', '∉', '∩', '∪', '‰', '∴', '⊥', 'μ', 'Θ', '¤']; |
||
9 | |||
10 | UB.htmlCharNames2 = ["apos", "amp", "quot", "lt", "gt"]; |
||
11 | UB.htmlCharUTF2 = ['\'', '&', '\'', '<', '>']; |
||
12 | |||
13 | UB.htmlCharNames3 = ["nbsp"]; |
||
14 | UB.htmlCharUTF3 = [' ']; |
||
15 | |||
16 | |||
17 | UB.escapedDict = {'n':'\n', 'r':'\r', 't':'\t', 'f':'\f', 'b':'\b', '"':'\"', "'":'\'', '\\':''}; |
||
18 | |||
19 | var arrayFuncs = { |
||
20 | |||
21 | escapeURLEncodedVars: function(varVals, forPopups = false){ |
||
22 | var varNames = this; |
||
23 | |||
24 | // combine name and values |
||
25 | var pairs = []; |
||
26 | for (var v = 0, vl = varNames.length;v<vl;v++){ |
||
27 | var arg = varVals[v].escapeURLEncoded(); |
||
28 | |||
29 | // FIX: protects from window.open() in JS |
||
30 | if (forPopups) { |
||
31 | arg = escape(arg); |
||
32 | } |
||
33 | |||
34 | pairs.push(varNames[v] + "=" + arg); |
||
35 | } |
||
36 | return pairs.join("&"); |
||
37 | }, |
||
38 | |||
39 | none:null |
||
40 | }; |
||
41 | |||
42 | // register funcs |
||
43 | UB.registerFuncs(Array.prototype, arrayFuncs); |
||
44 | |||
45 | |||
46 | var stringFuncs = { |
||
47 | |||
48 | flattenSymbols: function(){ |
||
49 | var text = this; |
||
50 | return text.split("#").join("Hash").split("@").join("At").split("%").join("Percent").split("$").join("Dollar").split("/").join("Slash").split("\\").join("Slash"); |
||
51 | }, |
||
52 | |||
53 | |||
54 | /** |
||
55 | * Convert "Café" to "Cafe" |
||
56 | * |
||
57 | * @param str |
||
58 | * @param preservePronunciation If true, converts "döppl" to "doeppl", else "doppl" |
||
59 | */ |
||
60 | flattenAccents: function(preservePronunciation = true){ |
||
61 | var str = this; |
||
62 | return str.replaceManyMany(UB.accentChars, preservePronunciation ? UB.accentEngChars : UB.accentEngChars2); |
||
63 | }, |
||
64 | |||
65 | |||
66 | |||
67 | // escaping strings |
||
68 | escapeString: function(){ |
||
69 | var str = this; |
||
70 | str = str.split("\\").join("\\\\"); // replace \ with \\ |
||
71 | str = str.split('"').join('\"'); // replace " with \" |
||
72 | str = str.split("\t").join("\\"+"t"); // replace (tab) with \t |
||
73 | str = str.split("\n").join("\\"+"n"); // replace (newline) with \n |
||
74 | str = str.split("\r").join("\\"+"r"); // replace (newline) with \r |
||
75 | return str; |
||
76 | }, |
||
77 | escapeURLEncoded: function(isFullURL = false){ |
||
78 | var txt = this; |
||
79 | // do not use escape() -- OUTDATED |
||
80 | return isFullURL ? encodeURI(txt.trim()) : encodeURIComponent(txt.trim()); |
||
81 | }, |
||
82 | unescapeURLEncoded: function(isFullURL = false){ |
||
83 | var txt = this; |
||
84 | // do not use unescape() -- OUTDATED |
||
85 | return isFullURL ? decodeURI(txt.trim()) : decodeURIComponent(txt.trim()); |
||
86 | }, |
||
87 | View Code Duplication | escapeJS: function(singleQuotes = true, doubleQuotes = true){ |
|
|
|||
88 | var txt = this; |
||
89 | |||
90 | /// C escape sequences \ ' " ? a b f n r t v |
||
91 | /// JS escape sequences \ ' " b f n r t |
||
92 | |||
93 | // process string |
||
94 | if (txt.indexOf("\\") > -1) { |
||
95 | txt = txt.split("\\").join("\\\\"); |
||
96 | } |
||
97 | if (singleQuotes && txt.indexOf("\'") > -1) { |
||
98 | txt = txt.split("\'").join("\\'"); |
||
99 | } |
||
100 | if (doubleQuotes && txt.indexOf('\"') > -1) { |
||
101 | txt = txt.split("\"").join('\\"'); |
||
102 | } |
||
103 | if (txt.indexOf("\b") > -1) { |
||
104 | txt = txt.split("\b").join("\\b"); |
||
105 | } |
||
106 | if (txt.indexOf("\f") > -1) { |
||
107 | txt = txt.split("\f").join("\\f"); |
||
108 | } |
||
109 | if (txt.indexOf("\n") > -1) { |
||
110 | txt = txt.split("\n").join("\\n"); |
||
111 | } |
||
112 | if (txt.indexOf("\r") > -1) { |
||
113 | txt = txt.split("\r").join("\\r"); |
||
114 | } |
||
115 | if (txt.indexOf("\t") > -1) { |
||
116 | txt = txt.split("\t").join("\\t"); |
||
117 | } |
||
118 | return txt; |
||
119 | }, |
||
120 | View Code Duplication | unescapeJS: function(){ |
|
121 | var txt = this; |
||
122 | |||
123 | /// C escape sequences \ ' " ? a b f n r t v |
||
124 | /// JS escape sequences \ ' " b f n r t |
||
125 | |||
126 | // process string |
||
127 | if (txt.indexOf("\\\\") > -1) { |
||
128 | txt = txt.split("\\\\").join("\\"); |
||
129 | } |
||
130 | if (txt.indexOf("\\'") > -1) { |
||
131 | txt = txt.split("\\'").join("\'"); |
||
132 | } |
||
133 | if (txt.indexOf('\\"') > -1) { |
||
134 | txt = txt.split('\\"').join("\""); |
||
135 | } |
||
136 | if (txt.indexOf("\\b") > -1) { |
||
137 | txt = txt.split("\\b").join("\b"); |
||
138 | } |
||
139 | if (txt.indexOf("\\f") > -1) { |
||
140 | txt = txt.split("\\f").join("\f"); |
||
141 | } |
||
142 | if (txt.indexOf("\\n") > -1) { |
||
143 | txt = txt.split("\\n").join("\n"); |
||
144 | } |
||
145 | if (txt.indexOf("\\r") > -1) { |
||
146 | txt = txt.split("\\r").join("\r"); |
||
147 | } |
||
148 | if (txt.indexOf("\\t") > -1) { |
||
149 | txt = txt.split("\\t").join("\t"); |
||
150 | } |
||
151 | return txt; |
||
152 | }, |
||
153 | escapeJSSimple: function(){ |
||
154 | var input = this; |
||
155 | input = input.split("\\").join("\\\\"); |
||
156 | input = input.split("\n").join("\\n"); |
||
157 | input = input.split("\r").join("\\r"); |
||
158 | input = input.split("\t").join("\\t"); |
||
159 | input = input.split("\f").join("\\f"); |
||
160 | input = input.split("\b").join("\\b"); |
||
161 | input = input.split("\"").join("\\\""); |
||
162 | return input; |
||
163 | }, |
||
164 | escapeURLStrict: function(doTrim = true){ |
||
165 | var input = this; |
||
166 | if (input != null && input.length > 0) { |
||
167 | if (doTrim) { |
||
168 | input = input.trim(); |
||
169 | } |
||
170 | input = encodeURIComponent(input); |
||
171 | var a = input.split(""); |
||
172 | for (var i = 0;i<a.length;i++){ |
||
173 | switch(a[i]) { |
||
174 | case "!": a[i] = "%21"; break; |
||
175 | case "'": a[i] = "%27"; break; |
||
176 | case "(": a[i] = "%28"; break; |
||
177 | case ")": a[i] = "%29"; break; |
||
178 | case "*": a[i] = "%2A"; break; |
||
179 | case "-": a[i] = "%2D"; break; |
||
180 | case ".": a[i] = "%2E"; break; |
||
181 | case "_": a[i] = "%5F"; break; |
||
182 | case "~": a[i] = "%7E"; break; |
||
183 | } |
||
184 | } |
||
185 | return a.join(""); |
||
186 | } |
||
187 | return ""; |
||
188 | }, |
||
189 | unescapeHTMLSimple: function(){ |
||
190 | var s = this; |
||
191 | s = s.split("&").join("&"); |
||
192 | s = s.split(" ").join(" "); |
||
193 | s = s.split("&eq;").join("="); |
||
194 | s = s.split("<").join("<"); |
||
195 | s = s.split(">").join(">"); |
||
196 | s = s.split(""").join('"'); |
||
197 | s = s.split("'").join("'"); |
||
198 | s = s.split("'").join("'"); |
||
199 | return s; |
||
200 | }, |
||
201 | escapeHTMLSimple: function(names = true){ |
||
202 | var s = this; |
||
203 | s = s.split("&").join(names ? "&" : "&"); |
||
204 | //s = s.split(" ").join(" "); |
||
205 | s = s.split("=").join(names ? "&eq;" : "="); |
||
206 | s = s.split("<").join(names ? "<" : "<"); |
||
207 | s = s.split(">").join(names ? ">" : ">"); |
||
208 | s = s.split('"').join(names ? '"' : """); |
||
209 | s = s.split("'").join("'"); /// ' is not in the HTML spec, not supported in IE7 |
||
210 | return s; |
||
211 | }, |
||
212 | escapeXML: function(){ |
||
213 | var s = this; |
||
214 | s = s.split("&").join("&"); |
||
215 | s = s.split("<").join("<") |
||
216 | s = s.split(">").join(">") |
||
217 | s = s.split('"').join("""); |
||
218 | s = s.split("'").join("'"); |
||
219 | return s; |
||
220 | }, |
||
221 | escapeHTML: function(encodeEntities = true, encodeHighUnicodeChars = true, encodeAll = false){ |
||
222 | var text = this; |
||
223 | if (text == null) { |
||
224 | return ""; |
||
225 | } |
||
226 | var sb = []; |
||
227 | var len = text.length; |
||
228 | for (var i = 0;i<len;i++){ |
||
229 | |||
230 | var charIndex; |
||
231 | if (encodeEntities) { |
||
232 | var charName = null; |
||
233 | charIndex = UB.htmlCharUTF.indexOf(text.charAt(i)); |
||
234 | if (charIndex === -1) { |
||
235 | charIndex = UB.htmlCharUTF2.indexOf(text.charAt(i)); |
||
236 | if (charIndex > -1) { |
||
237 | charName = UB.htmlCharNames2[charIndex]; |
||
238 | } |
||
239 | }else { |
||
240 | charName = UB.htmlCharNames[charIndex]; |
||
241 | } |
||
242 | if (charName){ |
||
243 | |||
244 | // add entity name if known entity |
||
245 | sb.push('&'); |
||
246 | sb.push(charName); |
||
247 | sb.push(';'); |
||
248 | continue; |
||
249 | |||
250 | } |
||
251 | |||
252 | } |
||
253 | |||
254 | if (encodeHighUnicodeChars) { |
||
255 | var charUnicode = text.charCodeAt(i); |
||
256 | if (encodeAll || charUnicode > 127) { |
||
257 | sb.push("&#" + charUnicode + ";"); |
||
258 | } else { |
||
259 | sb.push(text.charAt(i)); |
||
260 | } |
||
261 | continue; |
||
262 | } |
||
263 | } |
||
264 | return sb.join(""); |
||
265 | }, |
||
266 | |||
267 | unescapeDouble: function(){ |
||
268 | var src = this; |
||
269 | |||
270 | // try with --- 'quelques \\ncaract\\u00e8res \\r ololo\\t\\" ' + " \\'" + 'lol\\/lol\\blol\\f\\tsp\\u00e9ciaux' |
||
271 | |||
272 | var arr = src.split('\\'); |
||
273 | for (var i = 1;i<arr.length;i++){ |
||
274 | if (arr[i].charAt(0) != 'u') { |
||
275 | arr[i] = UB.escapedDict[arr[i].charAt(0)] ? UB.escapedDict[arr[i].charAt(0)] + arr[i].substr(1) : arr[i]; |
||
276 | }else { |
||
277 | arr[i] = String.fromCharCode('0x' + arr[i].slice(1, 5)) + arr[i].substr(5); |
||
278 | } |
||
279 | } |
||
280 | return arr.join(''); |
||
281 | }, |
||
282 | none:null |
||
283 | }; |
||
284 | |||
285 | // register funcs |
||
286 | UB.registerFuncs(String.prototype, stringFuncs); |
||
287 |