2 if (typeof exports
== "object" && typeof module
== "object") // CommonJS
3 mod(require("../../lib/codemirror"));
4 else if (typeof define
== "function" && define
.amd
) // AMD
5 define(["../../lib/codemirror"], mod
);
6 else // Plain browser env
8 })(function(CodeMirror
) {
10 // declare global: JSHINT
12 var bogus
= [ "Dangerous comment" ];
14 var warnings
= [ [ "Expected '{'",
15 "Statement body should be inside '{ }' braces." ] ];
17 var errors
= [ "Missing semicolon", "Extra comma", "Missing property name",
18 "Unmatched ", " and instead saw", " is not defined",
19 "Unclosed string", "Stopping, unable to continue" ];
21 function validator(text
, options
) {
22 JSHINT(text
, options
);
23 var errors
= JSHINT
.data().errors
, result
= [];
24 if (errors
) parseErrors(errors
, result
);
28 CodeMirror
.registerHelper("lint", "javascript", validator
);
30 function cleanup(error
) {
31 // All problems are warnings by default
32 fixWith(error
, warnings
, "warning", true);
33 fixWith(error
, errors
, "error");
35 return isBogus(error
) ? null : error
;
38 function fixWith(error
, fixes
, severity
, force
) {
39 var description
, fix
, find
, replace
, found
;
41 description
= error
.description
;
43 for ( var i
= 0; i
< fixes
.length
; i
++) {
45 find
= (typeof fix
=== "string" ? fix
: fix
[0]);
46 replace
= (typeof fix
=== "string" ? null : fix
[1]);
47 found
= description
.indexOf(find
) !== -1;
50 error
.severity
= severity
;
52 if (found
&& replace
) {
53 error
.description
= replace
;
58 function isBogus(error
) {
59 var description
= error
.description
;
60 for ( var i
= 0; i
< bogus
.length
; i
++) {
61 if (description
.indexOf(bogus
[i
]) !== -1) {
68 function parseErrors(errors
, output
) {
69 for ( var i
= 0; i
< errors
.length
; i
++) {
70 var error
= errors
[i
];
72 var linetabpositions
, index
;
74 linetabpositions
= [];
76 // This next block is to fix a problem in jshint. Jshint
78 // all tabs with spaces then performs some checks. The error
79 // positions (character/space) are then reported incorrectly,
80 // not taking the replacement step into account. Here we look
81 // at the evidence line and try to adjust the character position
82 // to the correct value.
84 // Tab positions are computed once per line and cached
85 var tabpositions
= linetabpositions
[error
.line
];
87 var evidence
= error
.evidence
;
89 // ugggh phantomjs does not like this
90 // forEachChar(evidence, function(item, index) {
91 Array
.prototype.forEach
.call(evidence
, function(item
,
94 // First col is 1 (not 0) to match error
96 tabpositions
.push(index
+ 1);
99 linetabpositions
[error
.line
] = tabpositions
;
101 if (tabpositions
.length
> 0) {
102 var pos
= error
.character
;
103 tabpositions
.forEach(function(tabposition
) {
104 if (pos
> tabposition
) pos
-= 1;
106 error
.character
= pos
;
110 var start
= error
.character
- 1, end
= start
+ 1;
111 if (error
.evidence
) {
112 index
= error
.evidence
.substring(start
).search(/.\b/);
118 // Convert to format expected by validation service
119 error
.description
= error
.reason
;// + "(jshint)";
120 error
.start
= error
.character
;
122 error
= cleanup(error
);
125 output
.push({message
: error
.description
,
126 severity
: error
.severity
,
127 from: CodeMirror
.Pos(error
.line
- 1, start
),
128 to
: CodeMirror
.Pos(error
.line
- 1, end
)});