github.com/jancarloviray/community@v0.41.1-0.20170124221257-33a66c87cf2f/app/public/codemirror/addon/lint/javascript-lint.js (about)

     1  // CodeMirror, copyright (c) by Marijn Haverbeke and others
     2  // Distributed under an MIT license: http://codemirror.net/LICENSE
     3  
     4  (function(mod) {
     5    if (typeof exports == "object" && typeof module == "object") // CommonJS
     6      mod(require("../../lib/codemirror"));
     7    else if (typeof define == "function" && define.amd) // AMD
     8      define(["../../lib/codemirror"], mod);
     9    else // Plain browser env
    10      mod(CodeMirror);
    11  })(function(CodeMirror) {
    12    "use strict";
    13    // declare global: JSHINT
    14  
    15    var bogus = [ "Dangerous comment" ];
    16  
    17    var warnings = [ [ "Expected '{'",
    18                       "Statement body should be inside '{ }' braces." ] ];
    19  
    20    var errors = [ "Missing semicolon", "Extra comma", "Missing property name",
    21                   "Unmatched ", " and instead saw", " is not defined",
    22                   "Unclosed string", "Stopping, unable to continue" ];
    23  
    24    function validator(text, options) {
    25      if (!window.JSHINT) return [];
    26      JSHINT(text, options, options.globals);
    27      var errors = JSHINT.data().errors, result = [];
    28      if (errors) parseErrors(errors, result);
    29      return result;
    30    }
    31  
    32    CodeMirror.registerHelper("lint", "javascript", validator);
    33  
    34    function cleanup(error) {
    35      // All problems are warnings by default
    36      fixWith(error, warnings, "warning", true);
    37      fixWith(error, errors, "error");
    38  
    39      return isBogus(error) ? null : error;
    40    }
    41  
    42    function fixWith(error, fixes, severity, force) {
    43      var description, fix, find, replace, found;
    44  
    45      description = error.description;
    46  
    47      for ( var i = 0; i < fixes.length; i++) {
    48        fix = fixes[i];
    49        find = (typeof fix === "string" ? fix : fix[0]);
    50        replace = (typeof fix === "string" ? null : fix[1]);
    51        found = description.indexOf(find) !== -1;
    52  
    53        if (force || found) {
    54          error.severity = severity;
    55        }
    56        if (found && replace) {
    57          error.description = replace;
    58        }
    59      }
    60    }
    61  
    62    function isBogus(error) {
    63      var description = error.description;
    64      for ( var i = 0; i < bogus.length; i++) {
    65        if (description.indexOf(bogus[i]) !== -1) {
    66          return true;
    67        }
    68      }
    69      return false;
    70    }
    71  
    72    function parseErrors(errors, output) {
    73      for ( var i = 0; i < errors.length; i++) {
    74        var error = errors[i];
    75        if (error) {
    76          var linetabpositions, index;
    77  
    78          linetabpositions = [];
    79  
    80          // This next block is to fix a problem in jshint. Jshint
    81          // replaces
    82          // all tabs with spaces then performs some checks. The error
    83          // positions (character/space) are then reported incorrectly,
    84          // not taking the replacement step into account. Here we look
    85          // at the evidence line and try to adjust the character position
    86          // to the correct value.
    87          if (error.evidence) {
    88            // Tab positions are computed once per line and cached
    89            var tabpositions = linetabpositions[error.line];
    90            if (!tabpositions) {
    91              var evidence = error.evidence;
    92              tabpositions = [];
    93              // ugggh phantomjs does not like this
    94              // forEachChar(evidence, function(item, index) {
    95              Array.prototype.forEach.call(evidence, function(item,
    96                                                              index) {
    97                if (item === '\t') {
    98                  // First col is 1 (not 0) to match error
    99                  // positions
   100                  tabpositions.push(index + 1);
   101                }
   102              });
   103              linetabpositions[error.line] = tabpositions;
   104            }
   105            if (tabpositions.length > 0) {
   106              var pos = error.character;
   107              tabpositions.forEach(function(tabposition) {
   108                if (pos > tabposition) pos -= 1;
   109              });
   110              error.character = pos;
   111            }
   112          }
   113  
   114          var start = error.character - 1, end = start + 1;
   115          if (error.evidence) {
   116            index = error.evidence.substring(start).search(/.\b/);
   117            if (index > -1) {
   118              end += index;
   119            }
   120          }
   121  
   122          // Convert to format expected by validation service
   123          error.description = error.reason;// + "(jshint)";
   124          error.start = error.character;
   125          error.end = end;
   126          error = cleanup(error);
   127  
   128          if (error)
   129            output.push({message: error.description,
   130                         severity: error.severity,
   131                         from: CodeMirror.Pos(error.line - 1, start),
   132                         to: CodeMirror.Pos(error.line - 1, end)});
   133        }
   134      }
   135    }
   136  });