Passed
Push — master ( 7e07d9...30706c )
by Ron
02:08 queued 12s
created

plugin.js ➔ parseCurrentLine   F

Complexity

Conditions 28
Paths 1348

Size

Total Lines 81
Code Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 66
nc 1348
nop 3
dl 0
loc 81
c 0
b 0
f 0
cc 28
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

Complex classes like plugin.js ➔ parseCurrentLine 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
(function () {
2
var autolink = (function () {
0 ignored issues
show
Unused Code introduced by
The variable autolink seems to be never used. Consider removing it.
Loading history...
3
    'use strict';
4
5
    var global = tinymce.util.Tools.resolve('tinymce.PluginManager');
0 ignored issues
show
Bug introduced by
The variable tinymce seems to be never declared. If this is a global, consider adding a /** global: tinymce */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
6
7
    var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
8
9
    var getAutoLinkPattern = function (editor) {
10
      return editor.getParam('autolink_pattern', /^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i);
11
    };
12
    var getDefaultLinkTarget = function (editor) {
13
      return editor.getParam('default_link_target', '');
14
    };
15
    var Settings = {
16
      getAutoLinkPattern: getAutoLinkPattern,
17
      getDefaultLinkTarget: getDefaultLinkTarget
18
    };
19
20
    var rangeEqualsDelimiterOrSpace = function (rangeString, delimiter) {
21
      return rangeString === delimiter || rangeString === ' ' || rangeString.charCodeAt(0) === 160;
22
    };
23
    var handleEclipse = function (editor) {
24
      parseCurrentLine(editor, -1, '(');
25
    };
26
    var handleSpacebar = function (editor) {
27
      parseCurrentLine(editor, 0, '');
28
    };
29
    var handleEnter = function (editor) {
30
      parseCurrentLine(editor, -1, '');
31
    };
32
    var scopeIndex = function (container, index) {
33
      if (index < 0) {
34
        index = 0;
35
      }
36
      if (container.nodeType === 3) {
37
        var len = container.data.length;
38
        if (index > len) {
39
          index = len;
40
        }
41
      }
42
      return index;
43
    };
44
    var setStart = function (rng, container, offset) {
45
      if (container.nodeType !== 1 || container.hasChildNodes()) {
46
        rng.setStart(container, scopeIndex(container, offset));
47
      } else {
48
        rng.setStartBefore(container);
49
      }
50
    };
51
    var setEnd = function (rng, container, offset) {
52
      if (container.nodeType !== 1 || container.hasChildNodes()) {
53
        rng.setEnd(container, scopeIndex(container, offset));
54
      } else {
55
        rng.setEndAfter(container);
56
      }
57
    };
58
    var parseCurrentLine = function (editor, endOffset, delimiter) {
59
      var rng, end, start, endContainer, bookmark, text, matches, prev, len, rngText;
60
      var autoLinkPattern = Settings.getAutoLinkPattern(editor);
61
      var defaultLinkTarget = Settings.getDefaultLinkTarget(editor);
62
      if (editor.selection.getNode().tagName === 'A') {
63
        return;
64
      }
65
      rng = editor.selection.getRng(true).cloneRange();
66
      if (rng.startOffset < 5) {
67
        prev = rng.endContainer.previousSibling;
68
        if (!prev) {
69
          if (!rng.endContainer.firstChild || !rng.endContainer.firstChild.nextSibling) {
70
            return;
71
          }
72
          prev = rng.endContainer.firstChild.nextSibling;
73
        }
74
        len = prev.length;
75
        setStart(rng, prev, len);
76
        setEnd(rng, prev, len);
77
        if (rng.endOffset < 5) {
78
          return;
79
        }
80
        end = rng.endOffset;
81
        endContainer = prev;
82
      } else {
83
        endContainer = rng.endContainer;
84
        if (endContainer.nodeType !== 3 && endContainer.firstChild) {
85
          while (endContainer.nodeType !== 3 && endContainer.firstChild) {
86
            endContainer = endContainer.firstChild;
87
          }
88
          if (endContainer.nodeType === 3) {
89
            setStart(rng, endContainer, 0);
90
            setEnd(rng, endContainer, endContainer.nodeValue.length);
91
          }
92
        }
93
        if (rng.endOffset === 1) {
94
          end = 2;
95
        } else {
96
          end = rng.endOffset - 1 - endOffset;
97
        }
98
      }
99
      start = end;
100
      do {
101
        setStart(rng, endContainer, end >= 2 ? end - 2 : 0);
102
        setEnd(rng, endContainer, end >= 1 ? end - 1 : 0);
103
        end -= 1;
104
        rngText = rng.toString();
105
      } while (rngText !== ' ' && rngText !== '' && rngText.charCodeAt(0) !== 160 && end - 2 >= 0 && rngText !== delimiter);
106
      if (rangeEqualsDelimiterOrSpace(rng.toString(), delimiter)) {
107
        setStart(rng, endContainer, end);
108
        setEnd(rng, endContainer, start);
109
        end += 1;
0 ignored issues
show
Unused Code introduced by
The assignment to variable end seems to be never used. Consider removing it.
Loading history...
110
      } else if (rng.startOffset === 0) {
111
        setStart(rng, endContainer, 0);
112
        setEnd(rng, endContainer, start);
113
      } else {
114
        setStart(rng, endContainer, end);
115
        setEnd(rng, endContainer, start);
116
      }
117
      text = rng.toString();
118
      if (text.charAt(text.length - 1) === '.') {
119
        setEnd(rng, endContainer, start - 1);
120
      }
121
      text = rng.toString().trim();
122
      matches = text.match(autoLinkPattern);
123
      if (matches) {
124
        if (matches[1] === 'www.') {
125
          matches[1] = 'http://www.';
126
        } else if (/@$/.test(matches[1]) && !/^mailto:/.test(matches[1])) {
127
          matches[1] = 'mailto:' + matches[1];
128
        }
129
        bookmark = editor.selection.getBookmark();
130
        editor.selection.setRng(rng);
131
        editor.execCommand('createlink', false, matches[1] + matches[2]);
132
        if (defaultLinkTarget) {
133
          editor.dom.setAttrib(editor.selection.getNode(), 'target', defaultLinkTarget);
134
        }
135
        editor.selection.moveToBookmark(bookmark);
136
        editor.nodeChanged();
137
      }
138
    };
139
    var setup = function (editor) {
140
      var autoUrlDetectState;
141
      editor.on('keydown', function (e) {
142
        if (e.keyCode === 13) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if e.keyCode === 13 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
143
          return handleEnter(editor);
144
        }
145
      });
146
      if (global$1.ie) {
147
        editor.on('focus', function () {
148
          if (!autoUrlDetectState) {
149
            autoUrlDetectState = true;
150
            try {
151
              editor.execCommand('AutoUrlDetect', false, true);
152
            } catch (ex) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
153
            }
154
          }
155
        });
156
        return;
157
      }
158
      editor.on('keypress', function (e) {
159
        if (e.keyCode === 41) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if e.keyCode === 41 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
160
          return handleEclipse(editor);
161
        }
162
      });
163
      editor.on('keyup', function (e) {
164
        if (e.keyCode === 32) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if e.keyCode === 32 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
165
          return handleSpacebar(editor);
166
        }
167
      });
168
    };
169
    var Keys = { setup: setup };
170
171
    global.add('autolink', function (editor) {
172
      Keys.setup(editor);
173
    });
174
    function Plugin () {
175
    }
176
177
    return Plugin;
178
179
}());
180
})();
181