forked from cory/tildefriends
		
	Add/enable codemirror's javascript-lint using jshint, and fix a few things.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4248 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
		
							
								
								
									
										66
									
								
								deps/codemirror/javascript-lint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								deps/codemirror/javascript-lint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | ||||
| // CodeMirror, copyright (c) by Marijn Haverbeke and others | ||||
| // Distributed under an MIT license: https://codemirror.net/5/LICENSE | ||||
|  | ||||
| // Depends on jshint.js from https://github.com/jshint/jshint | ||||
|  | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   "use strict"; | ||||
|   // declare global: JSHINT | ||||
|  | ||||
|   function validator(text, options) { | ||||
|     if (!window.JSHINT) { | ||||
|       if (window.console) { | ||||
|         window.console.error("Error: window.JSHINT not defined, CodeMirror JavaScript linting cannot run."); | ||||
|       } | ||||
|       return []; | ||||
|     } | ||||
|     if (!options.indent) // JSHint error.character actually is a column index, this fixes underlining on lines using tabs for indentation | ||||
|       options.indent = 1; // JSHint default value is 4 | ||||
|     JSHINT(text, options, options.globals); | ||||
|     var errors = JSHINT.data().errors, result = []; | ||||
|     if (errors) parseErrors(errors, result); | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   CodeMirror.registerHelper("lint", "javascript", validator); | ||||
|  | ||||
|   function parseErrors(errors, output) { | ||||
|     for ( var i = 0; i < errors.length; i++) { | ||||
|       var error = errors[i]; | ||||
|       if (error) { | ||||
|         if (error.line <= 0) { | ||||
|           if (window.console) { | ||||
|             window.console.warn("Cannot display JSHint error (invalid line " + error.line + ")", error); | ||||
|           } | ||||
|           continue; | ||||
|         } | ||||
|  | ||||
|         var start = error.character - 1, end = start + 1; | ||||
|         if (error.evidence) { | ||||
|           var index = error.evidence.substring(start).search(/.\b/); | ||||
|           if (index > -1) { | ||||
|             end += index; | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         // Convert to format expected by validation service | ||||
|         var hint = { | ||||
|           message: error.reason, | ||||
|           severity: error.code ? (error.code.startsWith('W') ? "warning" : "error") : "error", | ||||
|           from: CodeMirror.Pos(error.line - 1, start), | ||||
|           to: CodeMirror.Pos(error.line - 1, end) | ||||
|         }; | ||||
|  | ||||
|         output.push(hint); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| }); | ||||
|  | ||||
							
								
								
									
										32076
									
								
								deps/codemirror/jshint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										32076
									
								
								deps/codemirror/jshint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										80
									
								
								deps/codemirror/lint.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								deps/codemirror/lint.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | ||||
| /* The lint marker gutter */ | ||||
| .CodeMirror-lint-markers { | ||||
|   width: 16px; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-tooltip { | ||||
|   background-color: #ffd; | ||||
|   border: 1px solid black; | ||||
|   border-radius: 4px 4px 4px 4px; | ||||
|   color: black; | ||||
|   font-family: monospace; | ||||
|   font-size: 10pt; | ||||
|   overflow: hidden; | ||||
|   padding: 2px 5px; | ||||
|   position: fixed; | ||||
|   white-space: pre; | ||||
|   white-space: pre-wrap; | ||||
|   z-index: 100; | ||||
|   max-width: 600px; | ||||
|   opacity: 0; | ||||
|   transition: opacity .4s; | ||||
|   -moz-transition: opacity .4s; | ||||
|   -webkit-transition: opacity .4s; | ||||
|   -o-transition: opacity .4s; | ||||
|   -ms-transition: opacity .4s; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-mark { | ||||
|   background-position: left bottom; | ||||
|   background-repeat: repeat-x; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-mark-warning { | ||||
|   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJFhQXEbhTg7YAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAMklEQVQI12NkgIIvJ3QXMjAwdDN+OaEbysDA4MPAwNDNwMCwiOHLCd1zX07o6kBVGQEAKBANtobskNMAAAAASUVORK5CYII="); | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-mark-error { | ||||
|   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAADCAYAAAC09K7GAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sJDw4cOCW1/KIAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAHElEQVQI12NggIL/DAz/GdA5/xkY/qPKMDAwAADLZwf5rvm+LQAAAABJRU5ErkJggg=="); | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-marker { | ||||
|   background-position: center center; | ||||
|   background-repeat: no-repeat; | ||||
|   cursor: pointer; | ||||
|   display: inline-block; | ||||
|   height: 16px; | ||||
|   width: 16px; | ||||
|   vertical-align: middle; | ||||
|   position: relative; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-message { | ||||
|   padding-left: 18px; | ||||
|   background-position: top left; | ||||
|   background-repeat: no-repeat; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-marker-warning, .CodeMirror-lint-message-warning { | ||||
|   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAANlBMVEX/uwDvrwD/uwD/uwD/uwD/uwD/uwD/uwD/uwD6twD/uwAAAADurwD2tQD7uAD+ugAAAAD/uwDhmeTRAAAADHRSTlMJ8mN1EYcbmiixgACm7WbuAAAAVklEQVR42n3PUQqAIBBFUU1LLc3u/jdbOJoW1P08DA9Gba8+YWJ6gNJoNYIBzAA2chBth5kLmG9YUoG0NHAUwFXwO9LuBQL1giCQb8gC9Oro2vp5rncCIY8L8uEx5ZkAAAAASUVORK5CYII="); | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-marker-error, .CodeMirror-lint-message-error { | ||||
|   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAHlBMVEW7AAC7AACxAAC7AAC7AAAAAAC4AAC5AAD///+7AAAUdclpAAAABnRSTlMXnORSiwCK0ZKSAAAATUlEQVR42mWPOQ7AQAgDuQLx/z8csYRmPRIFIwRGnosRrpamvkKi0FTIiMASR3hhKW+hAN6/tIWhu9PDWiTGNEkTtIOucA5Oyr9ckPgAWm0GPBog6v4AAAAASUVORK5CYII="); | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-marker-multiple { | ||||
|   background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAMAAADzjKfhAAAACVBMVEUAAAAAAAC/v7914kyHAAAAAXRSTlMAQObYZgAAACNJREFUeNo1ioEJAAAIwmz/H90iFFSGJgFMe3gaLZ0od+9/AQZ0ADosbYraAAAAAElFTkSuQmCC"); | ||||
|   background-repeat: no-repeat; | ||||
|   background-position: right bottom; | ||||
|   width: 100%; height: 100%; | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-line-error { | ||||
|   background-color: rgba(183, 76, 81, 0.08); | ||||
| } | ||||
|  | ||||
| .CodeMirror-lint-line-warning { | ||||
|   background-color: rgba(255, 211, 0, 0.1); | ||||
| } | ||||
|  | ||||
							
								
								
									
										292
									
								
								deps/codemirror/lint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										292
									
								
								deps/codemirror/lint.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,292 @@ | ||||
| // CodeMirror, copyright (c) by Marijn Haverbeke and others | ||||
| // Distributed under an MIT license: https://codemirror.net/5/LICENSE | ||||
|  | ||||
| (function(mod) { | ||||
|   if (typeof exports == "object" && typeof module == "object") // CommonJS | ||||
|     mod(require("../../lib/codemirror")); | ||||
|   else if (typeof define == "function" && define.amd) // AMD | ||||
|     define(["../../lib/codemirror"], mod); | ||||
|   else // Plain browser env | ||||
|     mod(CodeMirror); | ||||
| })(function(CodeMirror) { | ||||
|   "use strict"; | ||||
|   var GUTTER_ID = "CodeMirror-lint-markers"; | ||||
|   var LINT_LINE_ID = "CodeMirror-lint-line-"; | ||||
|  | ||||
|   function showTooltip(cm, e, content) { | ||||
|     var tt = document.createElement("div"); | ||||
|     tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme; | ||||
|     tt.appendChild(content.cloneNode(true)); | ||||
|     if (cm.state.lint.options.selfContain) | ||||
|       cm.getWrapperElement().appendChild(tt); | ||||
|     else | ||||
|       document.body.appendChild(tt); | ||||
|  | ||||
|     function position(e) { | ||||
|       if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position); | ||||
|       tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px"; | ||||
|       tt.style.left = (e.clientX + 5) + "px"; | ||||
|     } | ||||
|     CodeMirror.on(document, "mousemove", position); | ||||
|     position(e); | ||||
|     if (tt.style.opacity != null) tt.style.opacity = 1; | ||||
|     return tt; | ||||
|   } | ||||
|   function rm(elt) { | ||||
|     if (elt.parentNode) elt.parentNode.removeChild(elt); | ||||
|   } | ||||
|   function hideTooltip(tt) { | ||||
|     if (!tt.parentNode) return; | ||||
|     if (tt.style.opacity == null) rm(tt); | ||||
|     tt.style.opacity = 0; | ||||
|     setTimeout(function() { rm(tt); }, 600); | ||||
|   } | ||||
|  | ||||
|   function showTooltipFor(cm, e, content, node) { | ||||
|     var tooltip = showTooltip(cm, e, content); | ||||
|     function hide() { | ||||
|       CodeMirror.off(node, "mouseout", hide); | ||||
|       if (tooltip) { hideTooltip(tooltip); tooltip = null; } | ||||
|     } | ||||
|     var poll = setInterval(function() { | ||||
|       if (tooltip) for (var n = node;; n = n.parentNode) { | ||||
|         if (n && n.nodeType == 11) n = n.host; | ||||
|         if (n == document.body) return; | ||||
|         if (!n) { hide(); break; } | ||||
|       } | ||||
|       if (!tooltip) return clearInterval(poll); | ||||
|     }, 400); | ||||
|     CodeMirror.on(node, "mouseout", hide); | ||||
|   } | ||||
|  | ||||
|   function LintState(cm, conf, hasGutter) { | ||||
|     this.marked = []; | ||||
|     if (conf instanceof Function) conf = {getAnnotations: conf}; | ||||
|     if (!conf || conf === true) conf = {}; | ||||
|     this.options = {}; | ||||
|     this.linterOptions = conf.options || {}; | ||||
|     for (var prop in defaults) this.options[prop] = defaults[prop]; | ||||
|     for (var prop in conf) { | ||||
|       if (defaults.hasOwnProperty(prop)) { | ||||
|         if (conf[prop] != null) this.options[prop] = conf[prop]; | ||||
|       } else if (!conf.options) { | ||||
|         this.linterOptions[prop] = conf[prop]; | ||||
|       } | ||||
|     } | ||||
|     this.timeout = null; | ||||
|     this.hasGutter = hasGutter; | ||||
|     this.onMouseOver = function(e) { onMouseOver(cm, e); }; | ||||
|     this.waitingFor = 0 | ||||
|   } | ||||
|  | ||||
|   var defaults = { | ||||
|     highlightLines: false, | ||||
|     tooltips: true, | ||||
|     delay: 500, | ||||
|     lintOnChange: true, | ||||
|     getAnnotations: null, | ||||
|     async: false, | ||||
|     selfContain: null, | ||||
|     formatAnnotation: null, | ||||
|     onUpdateLinting: null | ||||
|   } | ||||
|  | ||||
|   function clearMarks(cm) { | ||||
|     var state = cm.state.lint; | ||||
|     if (state.hasGutter) cm.clearGutter(GUTTER_ID); | ||||
|     if (state.options.highlightLines) clearErrorLines(cm); | ||||
|     for (var i = 0; i < state.marked.length; ++i) | ||||
|       state.marked[i].clear(); | ||||
|     state.marked.length = 0; | ||||
|   } | ||||
|  | ||||
|   function clearErrorLines(cm) { | ||||
|     cm.eachLine(function(line) { | ||||
|       var has = line.wrapClass && /\bCodeMirror-lint-line-\w+\b/.exec(line.wrapClass); | ||||
|       if (has) cm.removeLineClass(line, "wrap", has[0]); | ||||
|     }) | ||||
|   } | ||||
|  | ||||
|   function makeMarker(cm, labels, severity, multiple, tooltips) { | ||||
|     var marker = document.createElement("div"), inner = marker; | ||||
|     marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity; | ||||
|     if (multiple) { | ||||
|       inner = marker.appendChild(document.createElement("div")); | ||||
|       inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple"; | ||||
|     } | ||||
|  | ||||
|     if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { | ||||
|       showTooltipFor(cm, e, labels, inner); | ||||
|     }); | ||||
|  | ||||
|     return marker; | ||||
|   } | ||||
|  | ||||
|   function getMaxSeverity(a, b) { | ||||
|     if (a == "error") return a; | ||||
|     else return b; | ||||
|   } | ||||
|  | ||||
|   function groupByLine(annotations) { | ||||
|     var lines = []; | ||||
|     for (var i = 0; i < annotations.length; ++i) { | ||||
|       var ann = annotations[i], line = ann.from.line; | ||||
|       (lines[line] || (lines[line] = [])).push(ann); | ||||
|     } | ||||
|     return lines; | ||||
|   } | ||||
|  | ||||
|   function annotationTooltip(ann) { | ||||
|     var severity = ann.severity; | ||||
|     if (!severity) severity = "error"; | ||||
|     var tip = document.createElement("div"); | ||||
|     tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity; | ||||
|     if (typeof ann.messageHTML != 'undefined') { | ||||
|       tip.innerHTML = ann.messageHTML; | ||||
|     } else { | ||||
|       tip.appendChild(document.createTextNode(ann.message)); | ||||
|     } | ||||
|     return tip; | ||||
|   } | ||||
|  | ||||
|   function lintAsync(cm, getAnnotations) { | ||||
|     var state = cm.state.lint | ||||
|     var id = ++state.waitingFor | ||||
|     function abort() { | ||||
|       id = -1 | ||||
|       cm.off("change", abort) | ||||
|     } | ||||
|     cm.on("change", abort) | ||||
|     getAnnotations(cm.getValue(), function(annotations, arg2) { | ||||
|       cm.off("change", abort) | ||||
|       if (state.waitingFor != id) return | ||||
|       if (arg2 && annotations instanceof CodeMirror) annotations = arg2 | ||||
|       cm.operation(function() {updateLinting(cm, annotations)}) | ||||
|     }, state.linterOptions, cm); | ||||
|   } | ||||
|  | ||||
|   function startLinting(cm) { | ||||
|     var state = cm.state.lint; | ||||
|     if (!state) return; | ||||
|     var options = state.options; | ||||
|     /* | ||||
|      * Passing rules in `options` property prevents JSHint (and other linters) from complaining | ||||
|      * about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc. | ||||
|      */ | ||||
|     var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); | ||||
|     if (!getAnnotations) return; | ||||
|     if (options.async || getAnnotations.async) { | ||||
|       lintAsync(cm, getAnnotations) | ||||
|     } else { | ||||
|       var annotations = getAnnotations(cm.getValue(), state.linterOptions, cm); | ||||
|       if (!annotations) return; | ||||
|       if (annotations.then) annotations.then(function(issues) { | ||||
|         cm.operation(function() {updateLinting(cm, issues)}) | ||||
|       }); | ||||
|       else cm.operation(function() {updateLinting(cm, annotations)}) | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   function updateLinting(cm, annotationsNotSorted) { | ||||
|     var state = cm.state.lint; | ||||
|     if (!state) return; | ||||
|     var options = state.options; | ||||
|     clearMarks(cm); | ||||
|  | ||||
|     var annotations = groupByLine(annotationsNotSorted); | ||||
|  | ||||
|     for (var line = 0; line < annotations.length; ++line) { | ||||
|       var anns = annotations[line]; | ||||
|       if (!anns) continue; | ||||
|  | ||||
|       // filter out duplicate messages | ||||
|       var message = []; | ||||
|       anns = anns.filter(function(item) { return message.indexOf(item.message) > -1 ? false : message.push(item.message) }); | ||||
|  | ||||
|       var maxSeverity = null; | ||||
|       var tipLabel = state.hasGutter && document.createDocumentFragment(); | ||||
|  | ||||
|       for (var i = 0; i < anns.length; ++i) { | ||||
|         var ann = anns[i]; | ||||
|         var severity = ann.severity; | ||||
|         if (!severity) severity = "error"; | ||||
|         maxSeverity = getMaxSeverity(maxSeverity, severity); | ||||
|  | ||||
|         if (options.formatAnnotation) ann = options.formatAnnotation(ann); | ||||
|         if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann)); | ||||
|  | ||||
|         if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, { | ||||
|           className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity, | ||||
|           __annotation: ann | ||||
|         })); | ||||
|       } | ||||
|       // use original annotations[line] to show multiple messages | ||||
|       if (state.hasGutter) | ||||
|         cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, annotations[line].length > 1, | ||||
|                                                        options.tooltips)); | ||||
|  | ||||
|       if (options.highlightLines) | ||||
|         cm.addLineClass(line, "wrap", LINT_LINE_ID + maxSeverity); | ||||
|     } | ||||
|     if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm); | ||||
|   } | ||||
|  | ||||
|   function onChange(cm) { | ||||
|     var state = cm.state.lint; | ||||
|     if (!state) return; | ||||
|     clearTimeout(state.timeout); | ||||
|     state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay); | ||||
|   } | ||||
|  | ||||
|   function popupTooltips(cm, annotations, e) { | ||||
|     var target = e.target || e.srcElement; | ||||
|     var tooltip = document.createDocumentFragment(); | ||||
|     for (var i = 0; i < annotations.length; i++) { | ||||
|       var ann = annotations[i]; | ||||
|       tooltip.appendChild(annotationTooltip(ann)); | ||||
|     } | ||||
|     showTooltipFor(cm, e, tooltip, target); | ||||
|   } | ||||
|  | ||||
|   function onMouseOver(cm, e) { | ||||
|     var target = e.target || e.srcElement; | ||||
|     if (!/\bCodeMirror-lint-mark-/.test(target.className)) return; | ||||
|     var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2; | ||||
|     var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client")); | ||||
|  | ||||
|     var annotations = []; | ||||
|     for (var i = 0; i < spans.length; ++i) { | ||||
|       var ann = spans[i].__annotation; | ||||
|       if (ann) annotations.push(ann); | ||||
|     } | ||||
|     if (annotations.length) popupTooltips(cm, annotations, e); | ||||
|   } | ||||
|  | ||||
|   CodeMirror.defineOption("lint", false, function(cm, val, old) { | ||||
|     if (old && old != CodeMirror.Init) { | ||||
|       clearMarks(cm); | ||||
|       if (cm.state.lint.options.lintOnChange !== false) | ||||
|         cm.off("change", onChange); | ||||
|       CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver); | ||||
|       clearTimeout(cm.state.lint.timeout); | ||||
|       delete cm.state.lint; | ||||
|     } | ||||
|  | ||||
|     if (val) { | ||||
|       var gutters = cm.getOption("gutters"), hasLintGutter = false; | ||||
|       for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true; | ||||
|       var state = cm.state.lint = new LintState(cm, val, hasLintGutter); | ||||
|       if (state.options.lintOnChange) | ||||
|         cm.on("change", onChange); | ||||
|       if (state.options.tooltips != false && state.options.tooltips != "gutter") | ||||
|         CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver); | ||||
|  | ||||
|       startLinting(cm); | ||||
|     } | ||||
|   }); | ||||
|  | ||||
|   CodeMirror.defineExtension("performLint", function() { | ||||
|     startLinting(this); | ||||
|   }); | ||||
| }); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user