PageSourceSearch

https://pasvik-inari.net/js/vendor/codemirror/addon/lint/lint.js?v=4.9.4

js pasvik-inari.net collected 2026-09-25 08:37:41 UTC 8,610 bytes, 252 lines download raw bytes

1// CodeMirror, copyright (c) by Marijn Haverbeke and others
2// Distributed under an MIT license: https://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  var GUTTER_ID = "CodeMirror-lint-markers";
14
15  function showTooltip(e, content) {
16    var tt = document.createElement("div");
17    tt.className = "CodeMirror-lint-tooltip";
18    tt.appendChild(content.cloneNode(true));
19    document.body.appendChild(tt);
20
21    function position(e) {
22      if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
23      tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
24      tt.style.left = (e.clientX + 5) + "px";
25    }
26    CodeMirror.on(document, "mousemove", position);
27    position(e);
28    if (tt.style.opacity != null) tt.style.opacity = 1;
29    return tt;
30  }
31  function rm(elt) {
32    if (elt.parentNode) elt.parentNode.removeChild(elt);
33  }
34  function hideTooltip(tt) {
35    if (!tt.parentNode) return;
36    if (tt.style.opacity == null) rm(tt);
37    tt.style.opacity = 0;
38    setTimeout(function() { rm(tt); }, 600);
39  }
40
41  function showTooltipFor(e, content, node) {
42    var tooltip = showTooltip(e, content);
43    function hide() {
44      CodeMirror.off(node, "mouseout", hide);
45      if (tooltip) { hideTooltip(tooltip); tooltip = null; }
46    }
47    var poll = setInterval(function() {
48      if (tooltip) for (var n = node;; n = n.parentNode) {
49        if (n && n.nodeType == 11) n = n.host;
50        if (n == document.body) return;
51        if (!n) { hide(); break; }
52      }
53      if (!tooltip) return clearInterval(poll);
54    }, 400);
55    CodeMirror.on(node, "mouseout", hide);
56  }
57
58  function LintState(cm, options, hasGutter) {
59    this.marked = [];
60    this.options = options;
61    this.timeout = null;
62    this.hasGutter = hasGutter;
63    this.onMouseOver = function(e) { onMouseOver(cm, e); };
64    this.waitingFor = 0
65  }
66
67  function parseOptions(_cm, options) {
68    if (options instanceof Function) return {getAnnotations: options};
69    if (!options || options === true) options = {};
70    return options;
71  }
72
73  function clearMarks(cm) {
74    var state = cm.state.lint;
75    if (state.hasGutter) cm.clearGutter(GUTTER_ID);
76    for (var i = 0; i < state.marked.length; ++i)
77      state.marked[i].clear();
78    state.marked.length = 0;
79  }
80
81  function makeMarker(labels, severity, multiple, tooltips) {
82    var marker = document.createElement("div"), inner = marker;
83    marker.className = "CodeMirror-lint-marker-" + severity;
84    if (multiple) {
85      inner = marker.appendChild(document.createElement("div"));
86      inner.className = "CodeMirror-lint-marker-multiple";
87    }
88
89    if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
90      showTooltipFor(e, labels, inner);
91    });
92
93    return marker;
94  }
95
96  function getMaxSeverity(a, b) {
97    if (a == "error") return a;
98    else return b;
99  }
100
101  function groupByLine(annotations) {
102    var lines = [];
103    for (var i = 0; i < annotations.length; ++i) {
104      var ann = annotations[i], line = ann.from.line;
105      (lines[line] || (lines[line] = [])).push(ann);
106    }
107    return lines;
108  }
109
110  function annotationTooltip(ann) {
111    var severity = ann.severity;
112    if (!severity) severity = "error";
113    var tip = document.createElement("div");
114    tip.className = "CodeMirror-lint-message-" + severity;
115    if (typeof ann.messageHTML != 'undefined') {
116        tip.innerHTML = ann.messageHTML;
117    } else {
118        tip.appendChild(document.createTextNode(ann.message));
119    }
120    return tip;
121  }
122
123  function lintAsync(cm, getAnnotations, passOptions) {
124    var state = cm.state.lint
125    var id = ++state.waitingFor
126    function abort() {
127      id = -1
128      cm.off("change", abort)
129    }
130    cm.on("change", abort)
131    getAnnotations(cm.getValue(), function(annotations, arg2) {
132      cm.off("change", abort)
133      if (state.waitingFor != id) return
134      if (arg2 && annotations instanceof CodeMirror) annotations = arg2
135      cm.operation(function() {updateLinting(cm, annotations)})
136    }, passOptions, cm);
137  }
138
139  function startLinting(cm) {
140    var state = cm.state.lint, options = state.options;
141    /*
142     * Passing rules in `options` property prevents JSHint (and other linters) from complaining
143     * about unrecognized rules like `onUpdateLinting`, `delay`, `lintOnChange`, etc.
144     */
145    var passOptions = options.options || options;
146    var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
147    if (!getAnnotations) return;
148    if (options.async || getAnnotations.async) {
149      lintAsync(cm, getAnnotations, passOptions)
150    } else {
151      var annotations = getAnnotations(cm.getValue(), passOptions, cm);
152      if (!annotations) return;
153      if (annotations.then) annotations.then(function(issues) {
154        cm.operation(function() {updateLinting(cm, issues)})
155      });
156      else cm.operation(function() {updateLinting(cm, annotations)})
157    }
158  }
159
160  function updateLinting(cm, annotationsNotSorted) {
161    clearMarks(cm);
162    var state = cm.state.lint, options = state.options;
163
164    var annotations = groupByLine(annotationsNotSorted);
165
166    for (var line = 0; line < annotations.length; ++line) {
167      var anns = annotations[line];
168      if (!anns) continue;
169
170      var maxSeverity = null;
171      var tipLabel = state.hasGutter && document.createDocumentFragment();
172
173      for (var i = 0; i < anns.length; ++i) {
174        var ann = anns[i];
175        var severity = ann.severity;
176        if (!severity) severity = "error";
177        maxSeverity = getMaxSeverity(maxSeverity, severity);
178
179        if (options.formatAnnotation) ann = options.formatAnnotation(ann);
180        if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
181
182        if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
183          className: "CodeMirror-lint-mark-" + severity,
184          __annotation: ann
185        }));
186      }
187
188      if (state.hasGutter)
189        cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
190                                                       state.options.tooltips));
191    }
192    if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
193  }
194
195  function onChange(cm) {
196    var state = cm.state.lint;
197    if (!state) return;
198    clearTimeout(state.timeout);
199    state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
200  }
201
202  function popupTooltips(annotations, e) {
203    var target = e.target || e.srcElement;
204    var tooltip = document.createDocumentFragment();
205    for (var i = 0; i < annotations.length; i++) {
206      var ann = annotations[i];
207      tooltip.appendChild(annotationTooltip(ann));
208    }
209    showTooltipFor(e, tooltip, target);
210  }
211
212  function onMouseOver(cm, e) {
213    var target = e.target || e.srcElement;
214    if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
215    var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
216    var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
217
218    var annotations = [];
219    for (var i = 0; i < spans.length; ++i) {
220      var ann = spans[i].__annotation;
221      if (ann) annotations.push(ann);
222    }
223    if (annotations.length) popupTooltips(annotations, e);
224  }
225
226  CodeMirror.defineOption("lint", false, function(cm, val, old) {
227    if (old && old != CodeMirror.Init) {
228      clearMarks(cm);
229      if (cm.state.lint.options.lintOnChange !== false)
230        cm.off("change", onChange);
231      CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
232      clearTimeout(cm.state.lint.timeout);
233      delete cm.state.lint;
234    }
235
236    if (val) {
237      var gutters = cm.getOption("gutters"), hasLintGutter = false;
238      for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
239      var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
240      if (state.options.lintOnChange !== false)
241        cm.on("change", onChange);
242      if (state.options.tooltips != false && state.options.tooltips != "gutter")
243        CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
244
245      startLinting(cm);
246    }
247  });
248
249  CodeMirror.defineExtension("performLint", function() {
250    if (this.state.lint) startLinting(this);
251  });
252});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.