| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  | // CodeMirror, copyright (c) by Marijn Haverbeke and others
 | 
					
						
							| 
									
										
										
										
											2019-06-02 09:59:07 +02:00
										 |  |  | // Distributed under an MIT license: https://codemirror.net/LICENSE
 | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | (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"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |   function showTooltip(cm, e, content) { | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     var tt = document.createElement("div"); | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |     tt.className = "CodeMirror-lint-tooltip cm-s-" + cm.options.theme; | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     tt.appendChild(content.cloneNode(true)); | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |     if (cm.state.lint.options.selfContain) | 
					
						
							|  |  |  |       cm.getWrapperElement().appendChild(tt); | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |       document.body.appendChild(tt); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |   function showTooltipFor(cm, e, content, node) { | 
					
						
							|  |  |  |     var tooltip = showTooltip(cm, e, content); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     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, options, hasGutter) { | 
					
						
							|  |  |  |     this.marked = []; | 
					
						
							|  |  |  |     this.options = options; | 
					
						
							|  |  |  |     this.timeout = null; | 
					
						
							|  |  |  |     this.hasGutter = hasGutter; | 
					
						
							|  |  |  |     this.onMouseOver = function(e) { onMouseOver(cm, e); }; | 
					
						
							|  |  |  |     this.waitingFor = 0 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function parseOptions(_cm, options) { | 
					
						
							|  |  |  |     if (options instanceof Function) return {getAnnotations: options}; | 
					
						
							|  |  |  |     if (!options || options === true) options = {}; | 
					
						
							|  |  |  |     return options; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function clearMarks(cm) { | 
					
						
							|  |  |  |     var state = cm.state.lint; | 
					
						
							|  |  |  |     if (state.hasGutter) cm.clearGutter(GUTTER_ID); | 
					
						
							|  |  |  |     for (var i = 0; i < state.marked.length; ++i) | 
					
						
							|  |  |  |       state.marked[i].clear(); | 
					
						
							|  |  |  |     state.marked.length = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |   function makeMarker(cm, labels, severity, multiple, tooltips) { | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     var marker = document.createElement("div"), inner = marker; | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |     marker.className = "CodeMirror-lint-marker CodeMirror-lint-marker-" + severity; | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     if (multiple) { | 
					
						
							|  |  |  |       inner = marker.appendChild(document.createElement("div")); | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |       inner.className = "CodeMirror-lint-marker CodeMirror-lint-marker-multiple"; | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) { | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |       showTooltipFor(cm, e, labels, inner); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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"); | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |     tip.className = "CodeMirror-lint-message CodeMirror-lint-message-" + severity; | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     if (typeof ann.messageHTML != 'undefined') { | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |       tip.innerHTML = ann.messageHTML; | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |       tip.appendChild(document.createTextNode(ann.message)); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     } | 
					
						
							|  |  |  |     return tip; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function lintAsync(cm, getAnnotations, passOptions) { | 
					
						
							|  |  |  |     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)}) | 
					
						
							|  |  |  |     }, passOptions, cm); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function startLinting(cm) { | 
					
						
							|  |  |  |     var state = cm.state.lint, options = state.options; | 
					
						
							|  |  |  |     /* | 
					
						
							|  |  |  |      * Passing rules in `options` property prevents JSHint (and other linters) from complaining | 
					
						
							|  |  |  |      * about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     var passOptions = options.options || options; | 
					
						
							|  |  |  |     var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint"); | 
					
						
							|  |  |  |     if (!getAnnotations) return; | 
					
						
							|  |  |  |     if (options.async || getAnnotations.async) { | 
					
						
							|  |  |  |       lintAsync(cm, getAnnotations, passOptions) | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       var annotations = getAnnotations(cm.getValue(), passOptions, 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) { | 
					
						
							|  |  |  |     clearMarks(cm); | 
					
						
							|  |  |  |     var state = cm.state.lint, options = state.options; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var annotations = groupByLine(annotationsNotSorted); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for (var line = 0; line < annotations.length; ++line) { | 
					
						
							|  |  |  |       var anns = annotations[line]; | 
					
						
							|  |  |  |       if (!anns) continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |       // filter out duplicate messages
 | 
					
						
							|  |  |  |       var message = []; | 
					
						
							|  |  |  |       anns = anns.filter(function(item) { return message.indexOf(item.message) > -1 ? false : message.push(item.message) }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |       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, { | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |           className: "CodeMirror-lint-mark CodeMirror-lint-mark-" + severity, | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |           __annotation: ann | 
					
						
							|  |  |  |         })); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |       // use original annotations[line] to show multiple messages
 | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |       if (state.hasGutter) | 
					
						
							| 
									
										
										
										
											2021-04-06 22:16:34 +02:00
										 |  |  |         cm.setGutterMarker(line, GUTTER_ID, makeMarker(cm, tipLabel, maxSeverity, annotations[line].length > 1, | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |                                                        state.options.tooltips)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     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 || 500); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |   function popupTooltips(cm, annotations, e) { | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |     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)); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |     showTooltipFor(cm, e, tooltip, target); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-20 21:41:40 +02:00
										 |  |  |     if (annotations.length) popupTooltips(cm, annotations, e); | 
					
						
							| 
									
										
										
										
											2018-02-20 23:24:55 -05:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   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, parseOptions(cm, val), hasLintGutter); | 
					
						
							|  |  |  |       if (state.options.lintOnChange !== false) | 
					
						
							|  |  |  |         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() { | 
					
						
							|  |  |  |     if (this.state.lint) startLinting(this); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |