@marko/language-server 1.0.20 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -25,7 +25,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
  // src/index.ts
26
26
  var import_util2 = require("util");
27
27
  var import_node = require("vscode-languageserver/node");
28
- var import_language_tools16 = require("@marko/language-tools");
28
+ var import_language_tools17 = require("@marko/language-tools");
29
29
 
30
30
  // src/utils/file.ts
31
31
  var import_path = __toESM(require("path"));
@@ -144,67 +144,65 @@ function exists(uri) {
144
144
  function isOpen(doc) {
145
145
  return openDocs.has(doc);
146
146
  }
147
- function setup(connection4) {
148
- connection4.onDidOpenTextDocument((params) => {
149
- const ref = params.textDocument;
150
- const existingDoc = docs.get(ref.uri);
147
+ function doOpen(params) {
148
+ const ref = params.textDocument;
149
+ const existingDoc = docs.get(ref.uri);
150
+ projectVersion++;
151
+ if (existingDoc) {
152
+ if (existingDoc.version === ref.version) {
153
+ openDocs.add(existingDoc);
154
+ return;
155
+ }
156
+ openDocs.delete(existingDoc);
157
+ docs.delete(ref.uri);
158
+ }
159
+ const newDoc = import_vscode_languageserver_textdocument.TextDocument.create(
160
+ ref.uri,
161
+ ref.languageId,
162
+ ref.version,
163
+ ref.text
164
+ );
165
+ openDocs.add(newDoc);
166
+ fileExists.set(ref.uri, true);
167
+ docs.set(ref.uri, newDoc);
168
+ }
169
+ function doChange(params) {
170
+ const ref = params.textDocument;
171
+ const changes = params.contentChanges;
172
+ const doc = docs.get(ref.uri);
173
+ if (changes.length > 0 && ref.version != null && doc) {
174
+ import_vscode_languageserver_textdocument.TextDocument.update(doc, changes, ref.version);
175
+ emitFileChange(doc);
176
+ }
177
+ }
178
+ function doClose(params) {
179
+ const ref = params.textDocument;
180
+ const doc = docs.get(ref.uri);
181
+ if (doc) {
151
182
  projectVersion++;
152
- if (existingDoc) {
153
- if (existingDoc.version === ref.version) {
154
- openDocs.add(existingDoc);
155
- return;
156
- }
157
- openDocs.delete(existingDoc);
183
+ openDocs.delete(doc);
184
+ if (import_vscode_uri2.URI.parse(ref.uri).scheme !== "file") {
158
185
  docs.delete(ref.uri);
159
186
  }
160
- const newDoc = import_vscode_languageserver_textdocument.TextDocument.create(
161
- ref.uri,
162
- ref.languageId,
163
- ref.version,
164
- ref.text
165
- );
166
- openDocs.add(newDoc);
167
- fileExists.set(ref.uri, true);
168
- docs.set(ref.uri, newDoc);
169
- });
170
- connection4.onDidChangeTextDocument((params) => {
171
- const ref = params.textDocument;
172
- const changes = params.contentChanges;
173
- const doc = docs.get(ref.uri);
174
- if (changes.length > 0 && ref.version != null && doc) {
175
- import_vscode_languageserver_textdocument.TextDocument.update(doc, changes, ref.version);
176
- emitFileChange(doc);
177
- }
178
- });
179
- connection4.onDidCloseTextDocument((params) => {
180
- const ref = params.textDocument;
181
- const doc = docs.get(ref.uri);
182
- if (doc) {
183
- projectVersion++;
184
- openDocs.delete(doc);
185
- if (import_vscode_uri2.URI.parse(ref.uri).scheme !== "file") {
186
- docs.delete(ref.uri);
187
- }
188
- }
189
- });
190
- connection4.onDidChangeWatchedFiles(async (params) => {
191
- for (const change of params.changes) {
192
- switch (change.type) {
193
- case import_vscode_languageserver.FileChangeType.Created:
194
- fileExists.set(change.uri, true);
195
- break;
196
- case import_vscode_languageserver.FileChangeType.Deleted:
197
- case import_vscode_languageserver.FileChangeType.Changed: {
198
- fileExists.set(change.uri, change.type === import_vscode_languageserver.FileChangeType.Changed);
199
- const doc = docs.get(change.uri);
200
- if (doc && !openDocs.has(doc)) {
201
- docs.delete(change.uri);
202
- }
187
+ }
188
+ }
189
+ function doChangeWatchedFiles(params) {
190
+ for (const change of params.changes) {
191
+ switch (change.type) {
192
+ case import_vscode_languageserver.FileChangeType.Created:
193
+ fileExists.set(change.uri, true);
194
+ break;
195
+ case import_vscode_languageserver.FileChangeType.Deleted:
196
+ case import_vscode_languageserver.FileChangeType.Changed: {
197
+ fileExists.set(change.uri, change.type === import_vscode_languageserver.FileChangeType.Changed);
198
+ const doc = docs.get(change.uri);
199
+ if (doc && !openDocs.has(doc)) {
200
+ docs.delete(change.uri);
203
201
  }
204
202
  }
205
203
  }
206
- emitFileChange(void 0);
207
- });
204
+ }
205
+ emitFileChange(void 0);
208
206
  }
209
207
  function getLanguageId(uri) {
210
208
  const ext = uri.slice(uri.lastIndexOf(".") + 1);
@@ -229,6 +227,7 @@ function emitFileChange(doc) {
229
227
  }
230
228
 
231
229
  // src/utils/workspace.ts
230
+ var isInitialized = false;
232
231
  var connection;
233
232
  var configChangeHandlers = /* @__PURE__ */ new Set();
234
233
  var settingsCache = /* @__PURE__ */ new Map();
@@ -246,11 +245,15 @@ async function getConfig(section) {
246
245
  function onConfigChange(handler) {
247
246
  configChangeHandlers.add(handler);
248
247
  }
249
- function setup2(_) {
248
+ function setup(_) {
250
249
  connection = _;
251
250
  connection.onDidChangeConfiguration(() => {
252
- settingsCache.clear();
253
- emitConfigChange();
251
+ if (isInitialized) {
252
+ settingsCache.clear();
253
+ emitConfigChange();
254
+ } else {
255
+ isInitialized = true;
256
+ }
254
257
  });
255
258
  }
256
259
  function emitConfigChange() {
@@ -263,7 +266,7 @@ function emitConfigChange() {
263
266
  var import_util = require("util");
264
267
  var connection2;
265
268
  var previousMessagesByType = /* @__PURE__ */ new Map();
266
- function setup3(_) {
269
+ function setup2(_) {
267
270
  connection2 = _;
268
271
  }
269
272
  function displayError(data) {
@@ -288,8 +291,752 @@ function display(type, data) {
288
291
  // src/service/index.ts
289
292
  var import_vscode_languageserver12 = require("vscode-languageserver");
290
293
 
294
+ // src/service/html/index.ts
295
+ var import_axe_core = __toESM(require("axe-core"));
296
+ var import_language_tools2 = require("@marko/language-tools");
297
+ var import_jsdom = require("jsdom");
298
+
299
+ // src/service/html/axe-rules/axe-rules.ts
300
+ var keyboard = {
301
+ /**
302
+ * - Ensures every accesskey attribute value is unique
303
+ * - accesskey attribute value should be unique ([url](https://dequeuniversity.com/rules/axe/4.4/accesskeys?application=axeAPI))
304
+ */
305
+ accesskeys: "accesskeys",
306
+ /**
307
+ * - Ensures each page has at least one mechanism for a user to bypass navigation and jump straight to the content
308
+ * - Page must have means to bypass repeated blocks ([url](https://dequeuniversity.com/rules/axe/4.4/bypass?application=axeAPI))
309
+ */
310
+ bypass: "bypass",
311
+ /**
312
+ * - Ensures elements in the focus order have a role appropriate for interactive content
313
+ * - Elements in the focus order should have an appropriate role ([url](https://dequeuniversity.com/rules/axe/4.4/focus-order-semantics?application=axeAPI))
314
+ */
315
+ focusOrderSemantics: "focus-order-semantics",
316
+ /**
317
+ * - Ensures `<frame>` and `<iframe>` elements with focusable content do not have tabindex=-1
318
+ * - Frames with focusable content must not have tabindex=-1 ([url](https://dequeuniversity.com/rules/axe/4.4/frame-focusable-content?application=axeAPI))
319
+ */
320
+ frameFocusableContent: "frame-focusable-content",
321
+ /**
322
+ * - Ensures interactive controls are not nested as they are not always announced by screen readers or can cause focus problems for assistive technologies
323
+ * - Interactive controls must not be nested ([url](https://dequeuniversity.com/rules/axe/4.4/nested-interactive?application=axeAPI))
324
+ */
325
+ nestedInteractive: "nested-interactive",
326
+ /**
327
+ * - Ensures all page content is contained by landmarks
328
+ * - All page content should be contained by landmarks ([url](https://dequeuniversity.com/rules/axe/4.4/region?application=axeAPI))
329
+ */
330
+ region: "region",
331
+ /**
332
+ * - Ensure elements that have scrollable content are accessible by keyboard
333
+ * - Scrollable region must have keyboard access ([url](https://dequeuniversity.com/rules/axe/4.4/scrollable-region-focusable?application=axeAPI))
334
+ */
335
+ scrollableRegionFocusable: "scrollable-region-focusable",
336
+ /**
337
+ * - Ensure all skip links have a focusable target
338
+ * - The skip-link target should exist and be focusable ([url](https://dequeuniversity.com/rules/axe/4.4/skip-link?application=axeAPI))
339
+ */
340
+ skipLink: "skip-link",
341
+ /**
342
+ * - Ensures tabindex attribute values are not greater than 0
343
+ * - Elements should not have tabindex greater than zero ([url](https://dequeuniversity.com/rules/axe/4.4/tabindex?application=axeAPI))
344
+ */
345
+ tabindex: "tabindex"
346
+ };
347
+ var textAlternatives = {
348
+ /**
349
+ * - Ensures `<area>` elements of image maps have alternate text
350
+ * - Active `<area>` elements must have alternate text ([url](https://dequeuniversity.com/rules/axe/4.4/area-alt?application=axeAPI))
351
+ */
352
+ areaAlt: "area-alt",
353
+ /**
354
+ * - Ensures each HTML document contains a non-empty `<title>` element
355
+ * - Documents must have `<title>` element to aid in navigation ([url](https://dequeuniversity.com/rules/axe/4.4/document-title?application=axeAPI))
356
+ */
357
+ documentTitle: "document-title",
358
+ /**
359
+ * - Ensures `<iframe>` and `<frame>` elements contain a unique title attribute
360
+ * - Frames should have a unique title attribute ([url](https://dequeuniversity.com/rules/axe/4.4/frame-title-unique?application=axeAPI))
361
+ */
362
+ frameTitleUnique: "frame-title-unique",
363
+ /**
364
+ * - Ensures `<iframe>` and `<frame>` elements have an accessible name
365
+ * - Frames must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/frame-title?application=axeAPI))
366
+ */
367
+ frameTitle: "frame-title",
368
+ /**
369
+ * - Ensures `<img>` elements have alternate text or a role of none or presentation
370
+ * - Images must have alternate text ([url](https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axeAPI))
371
+ */
372
+ imageAlt: "image-alt",
373
+ /**
374
+ * - Ensure image alternative is not repeated as text
375
+ * - Alternative text of images should not be repeated as text ([url](https://dequeuniversity.com/rules/axe/4.4/image-redundant-alt?application=axeAPI))
376
+ */
377
+ imageRedundantAlt: "image-redundant-alt",
378
+ /**
379
+ * - Ensures `<input type="image">` elements have alternate text
380
+ * - Image buttons must have alternate text ([url](https://dequeuniversity.com/rules/axe/4.4/input-image-alt?application=axeAPI))
381
+ */
382
+ inputImageAlt: "input-image-alt",
383
+ /**
384
+ * - Ensures `<object>` elements have alternate text
385
+ * - `<object>` elements must have alternate text ([url](https://dequeuniversity.com/rules/axe/4.4/object-alt?application=axeAPI))
386
+ */
387
+ objectAlt: "object-alt",
388
+ /**
389
+ * - Ensures [role='img'] elements have alternate text
390
+ * - [role='img'] elements must have an alternative text ([url](https://dequeuniversity.com/rules/axe/4.4/role-img-alt?application=axeAPI))
391
+ */
392
+ roleImgAlt: "role-img-alt",
393
+ /**
394
+ * - Ensures that server-side image maps are not used
395
+ * - Server-side image maps must not be used ([url](https://dequeuniversity.com/rules/axe/4.4/server-side-image-map?application=axeAPI))
396
+ */
397
+ serverSideImageMap: "server-side-image-map",
398
+ /**
399
+ * - Ensures `<svg>` elements with an img, graphics-document or graphics-symbol role have an accessible text
400
+ * - `<svg>` elements with an img role must have an alternative text ([url](https://dequeuniversity.com/rules/axe/4.4/svg-img-alt?application=axeAPI))
401
+ */
402
+ svgImgAlt: "svg-img-alt",
403
+ /**
404
+ * - Ensures `<video>` elements have captions
405
+ * - `<video>` elements must have captions ([url](https://dequeuniversity.com/rules/axe/4.4/video-caption?application=axeAPI))
406
+ */
407
+ videoCaption: "video-caption"
408
+ };
409
+ var aria = {
410
+ /**
411
+ * - Ensures ARIA attributes are allowed for an element's role
412
+ * - Elements must only use allowed ARIA attributes ([url](https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axeAPI))
413
+ */
414
+ ariaAllowedAttr: "aria-allowed-attr",
415
+ /**
416
+ * - Ensures role attribute has an appropriate value for the element
417
+ * - ARIA role should be appropriate for the element ([url](https://dequeuniversity.com/rules/axe/4.4/aria-allowed-role?application=axeAPI))
418
+ */
419
+ ariaAllowedRole: "aria-allowed-role",
420
+ /**
421
+ * - Ensures every ARIA button, link and menuitem has an accessible name
422
+ * - ARIA commands must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-command-name?application=axeAPI))
423
+ */
424
+ ariaCommandName: "aria-command-name",
425
+ /**
426
+ * - Ensures every ARIA dialog and alertdialog node has an accessible name
427
+ * - ARIA dialog and alertdialog nodes should have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-dialog-name?application=axeAPI))
428
+ */
429
+ ariaDialogName: "aria-dialog-name",
430
+ /**
431
+ * - Ensures aria-hidden='true' is not present on the document body.
432
+ * - aria-hidden='true' must not be present on the document body ([url](https://dequeuniversity.com/rules/axe/4.4/aria-hidden-body?application=axeAPI))
433
+ */
434
+ ariaHiddenBody: "aria-hidden-body",
435
+ /**
436
+ * - Ensures every ARIA input field has an accessible name
437
+ * - ARIA input fields must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-input-field-name?application=axeAPI))
438
+ */
439
+ ariaInputFieldName: "aria-input-field-name",
440
+ /**
441
+ * - Ensures every ARIA meter node has an accessible name
442
+ * - ARIA meter nodes must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-meter-name?application=axeAPI))
443
+ */
444
+ ariaMeterName: "aria-meter-name",
445
+ /**
446
+ * - Ensures every ARIA progressbar node has an accessible name
447
+ * - ARIA progressbar nodes must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-progressbar-name?application=axeAPI))
448
+ */
449
+ ariaProgressbarName: "aria-progressbar-name",
450
+ /**
451
+ * - Ensures elements with ARIA roles have all required ARIA attributes
452
+ * - Required ARIA attributes must be provided ([url](https://dequeuniversity.com/rules/axe/4.4/aria-required-attr?application=axeAPI))
453
+ */
454
+ ariaRequiredAttr: "aria-required-attr",
455
+ /**
456
+ * - Ensures elements with an ARIA role that require child roles contain them
457
+ * - Certain ARIA roles must contain particular children ([url](https://dequeuniversity.com/rules/axe/4.4/aria-required-children?application=axeAPI))
458
+ */
459
+ ariaRequiredChildren: "aria-required-children",
460
+ /**
461
+ * - Ensures elements with an ARIA role that require parent roles are contained by them
462
+ * - Certain ARIA roles must be contained by particular parents ([url](https://dequeuniversity.com/rules/axe/4.4/aria-required-parent?application=axeAPI))
463
+ */
464
+ ariaRequiredParent: "aria-required-parent",
465
+ /**
466
+ * - Ensure aria-roledescription is only used on elements with an implicit or explicit role
467
+ * - aria-roledescription must be on elements with a semantic role ([url](https://dequeuniversity.com/rules/axe/4.4/aria-roledescription?application=axeAPI))
468
+ */
469
+ ariaRoledescription: "aria-roledescription",
470
+ /**
471
+ * - Ensures all elements with a role attribute use a valid value
472
+ * - ARIA roles used must conform to valid values ([url](https://dequeuniversity.com/rules/axe/4.4/aria-roles?application=axeAPI))
473
+ */
474
+ ariaRoles: "aria-roles",
475
+ /**
476
+ * - Ensures "role=text" is used on elements with no focusable descendants
477
+ * - "role=text" should have no focusable descendants ([url](https://dequeuniversity.com/rules/axe/4.4/aria-text?application=axeAPI))
478
+ */
479
+ ariaText: "aria-text",
480
+ /**
481
+ * - Ensures every ARIA toggle field has an accessible name
482
+ * - ARIA toggle fields must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-toggle-field-name?application=axeAPI))
483
+ */
484
+ ariaToggleFieldName: "aria-toggle-field-name",
485
+ /**
486
+ * - Ensures every ARIA tooltip node has an accessible name
487
+ * - ARIA tooltip nodes must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-tooltip-name?application=axeAPI))
488
+ */
489
+ ariaTooltipName: "aria-tooltip-name",
490
+ /**
491
+ * - Ensures every ARIA treeitem node has an accessible name
492
+ * - ARIA treeitem nodes should have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/aria-treeitem-name?application=axeAPI))
493
+ */
494
+ ariaTreeitemName: "aria-treeitem-name",
495
+ /**
496
+ * - Ensures all ARIA attributes have valid values
497
+ * - ARIA attributes must conform to valid values ([url](https://dequeuniversity.com/rules/axe/4.4/aria-valid-attr-value?application=axeAPI))
498
+ */
499
+ ariaValidAttrValue: "aria-valid-attr-value",
500
+ /**
501
+ * - Ensures attributes that begin with aria- are valid ARIA attributes
502
+ * - ARIA attributes must conform to valid names ([url](https://dequeuniversity.com/rules/axe/4.4/aria-valid-attr?application=axeAPI))
503
+ */
504
+ ariaValidAttr: "aria-valid-attr",
505
+ /**
506
+ * - Ensures table headers have discernible text
507
+ * - Table header text must not be empty ([url](https://dequeuniversity.com/rules/axe/4.4/empty-table-header?application=axeAPI))
508
+ */
509
+ emptyTableHeader: "empty-table-header",
510
+ /**
511
+ * - Flags elements whose role is none or presentation and which cause the role conflict resolution to trigger.
512
+ * - Elements of role none or presentation should be flagged ([url](https://dequeuniversity.com/rules/axe/4.4/presentation-role-conflict?application=axeAPI))
513
+ */
514
+ presentationRoleConflict: "presentation-role-conflict"
515
+ };
516
+ var nameRoleValue = {
517
+ /**
518
+ * - Ensures aria-hidden elements are not focusable nor contain focusable elements
519
+ * - ARIA hidden element must not be focusable or contain focusable elements ([url](https://dequeuniversity.com/rules/axe/4.4/aria-hidden-focus?application=axeAPI))
520
+ */
521
+ ariaHiddenFocus: "aria-hidden-focus",
522
+ /**
523
+ * - Ensures buttons have discernible text
524
+ * - Buttons must have discernible text ([url](https://dequeuniversity.com/rules/axe/4.4/button-name?application=axeAPI))
525
+ */
526
+ buttonName: "button-name",
527
+ /**
528
+ * - Ensures headings have discernible text
529
+ * - Headings should not be empty ([url](https://dequeuniversity.com/rules/axe/4.4/empty-heading?application=axeAPI))
530
+ */
531
+ emptyHeading: "empty-heading",
532
+ /**
533
+ * - Ensures input buttons have discernible text
534
+ * - Input buttons must have discernible text ([url](https://dequeuniversity.com/rules/axe/4.4/input-button-name?application=axeAPI))
535
+ */
536
+ inputButtonName: "input-button-name",
537
+ /**
538
+ * - Ensures links have discernible text
539
+ * - Links must have discernible text ([url](https://dequeuniversity.com/rules/axe/4.4/link-name?application=axeAPI))
540
+ */
541
+ linkName: "link-name"
542
+ };
543
+ var timeAndMedia = {
544
+ /**
545
+ * - Ensures `<audio>` elements have captions
546
+ * - `<audio>` elements must have a captions track ([url](https://dequeuniversity.com/rules/axe/4.4/audio-caption?application=axeAPI))
547
+ */
548
+ audioCaption: "audio-caption",
549
+ /**
550
+ * - Ensures `<blink>` elements are not used
551
+ * - `<blink>` elements are deprecated and must not be used ([url](https://dequeuniversity.com/rules/axe/4.4/blink?application=axeAPI))
552
+ */
553
+ blink: "blink",
554
+ /**
555
+ * - Ensures `<meta http-equiv="refresh">` is not used
556
+ * - Timed refresh must not exist ([url](https://dequeuniversity.com/rules/axe/4.4/meta-refresh?application=axeAPI))
557
+ */
558
+ metaRefresh: "meta-refresh",
559
+ /**
560
+ * - Ensures `<video>` or `<audio>` elements do not autoplay audio for more than 3 seconds without a control mechanism to stop or mute the audio
561
+ * - `<video>` or `<audio>` elements must not play automatically ([url](https://dequeuniversity.com/rules/axe/4.4/no-autoplay-audio?application=axeAPI))
562
+ */
563
+ noAutoplayAudio: "no-autoplay-audio"
564
+ };
565
+ var forms = {
566
+ /**
567
+ * - Ensure the autocomplete attribute is correct and suitable for the form field
568
+ * - autocomplete attribute must be used correctly ([url](https://dequeuniversity.com/rules/axe/4.4/autocomplete-valid?application=axeAPI))
569
+ */
570
+ autocompleteValid: "autocomplete-valid",
571
+ /**
572
+ * - Ensures form field does not have multiple label elements
573
+ * - Form field must not have multiple label elements ([url](https://dequeuniversity.com/rules/axe/4.4/form-field-multiple-labels?application=axeAPI))
574
+ */
575
+ formFieldMultipleLabels: "form-field-multiple-labels",
576
+ /**
577
+ * - Ensures that every form element has a visible label and is not solely labeled using hidden labels, or the title or aria-describedby attributes
578
+ * - Form elements should have a visible label ([url](https://dequeuniversity.com/rules/axe/4.4/label-title-only?application=axeAPI))
579
+ */
580
+ labelTitleOnly: "label-title-only",
581
+ /**
582
+ * - Ensures every form element has a label
583
+ * - Form elements must have labels ([url](https://dequeuniversity.com/rules/axe/4.4/label?application=axeAPI))
584
+ */
585
+ label: "label",
586
+ /**
587
+ * - Ensures select element has an accessible name
588
+ * - Select element must have an accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/select-name?application=axeAPI))
589
+ */
590
+ selectName: "select-name"
591
+ };
592
+ var structure = {
593
+ /**
594
+ * - Ensure that text spacing set through style attributes can be adjusted with custom stylesheets
595
+ * - Inline text spacing must be adjustable with custom stylesheets ([url](https://dequeuniversity.com/rules/axe/4.4/avoid-inline-spacing?application=axeAPI))
596
+ */
597
+ avoidInlineSpacing: "avoid-inline-spacing",
598
+ /**
599
+ * - Ensures content is not locked to any specific display orientation, and the content is operable in all display orientations
600
+ * - CSS Media queries must not lock display orientation ([url](https://dequeuniversity.com/rules/axe/4.4/css-orientation-lock?application=axeAPI))
601
+ */
602
+ cssOrientationLock: "css-orientation-lock",
603
+ /**
604
+ * - Ensures `<dl>` elements are structured correctly
605
+ * - `<dl>` elements must only directly contain properly-ordered `<dt>` and `<dd>` groups, `<script>`, `<template>` or `<div>` elements ([url](https://dequeuniversity.com/rules/axe/4.4/definition-list?application=axeAPI))
606
+ */
607
+ definitionList: "definition-list",
608
+ /**
609
+ * - Ensures `<dt>` and `<dd>` elements are contained by a `<dl>`
610
+ * - `<dt>` and `<dd>` elements must be contained by a `<dl>` ([url](https://dequeuniversity.com/rules/axe/4.4/dlitem?application=axeAPI))
611
+ */
612
+ dlitem: "dlitem",
613
+ /**
614
+ * - Ensures `<iframe>` and `<frame>` elements contain the axe-core script
615
+ * - Frames should be tested with axe-core ([url](https://dequeuniversity.com/rules/axe/4.4/frame-tested?application=axeAPI))
616
+ */
617
+ frameTested: "frame-tested",
618
+ /**
619
+ * - Informs users about hidden content.
620
+ * - Hidden content on the page should be analyzed ([url](https://dequeuniversity.com/rules/axe/4.4/hidden-content?application=axeAPI))
621
+ */
622
+ hiddenContent: "hidden-content",
623
+ /**
624
+ * - Ensures that lists are structured correctly
625
+ * - `<ul>` and `<ol>` must only directly contain `<li>`, `<script>` or `<template>` elements ([url](https://dequeuniversity.com/rules/axe/4.4/list?application=axeAPI))
626
+ */
627
+ list: "list",
628
+ /**
629
+ * - Ensures `<li>` elements are used semantically
630
+ * - `<li>` elements must be contained in a `<ul>` or `<ol>` ([url](https://dequeuniversity.com/rules/axe/4.4/listitem?application=axeAPI))
631
+ */
632
+ listitem: "listitem"
633
+ };
634
+ var parsing = {
635
+ /**
636
+ * - Ensures every id attribute value of active elements is unique
637
+ * - IDs of active elements must be unique ([url](https://dequeuniversity.com/rules/axe/4.4/duplicate-id-active?application=axeAPI))
638
+ */
639
+ duplicateIdActive: "duplicate-id-active",
640
+ /**
641
+ * - Ensures every id attribute value used in ARIA and in labels is unique
642
+ * - IDs used in ARIA and labels must be unique ([url](https://dequeuniversity.com/rules/axe/4.4/duplicate-id-aria?application=axeAPI))
643
+ */
644
+ duplicateIdAria: "duplicate-id-aria",
645
+ /**
646
+ * - Ensures every id attribute value is unique
647
+ * - id attribute value must be unique ([url](https://dequeuniversity.com/rules/axe/4.4/duplicate-id?application=axeAPI))
648
+ */
649
+ duplicateId: "duplicate-id",
650
+ /**
651
+ * - Ensures `<marquee>` elements are not used
652
+ * - `<marquee>` elements are deprecated and must not be used ([url](https://dequeuniversity.com/rules/axe/4.4/marquee?application=axeAPI))
653
+ */
654
+ marquee: "marquee"
655
+ };
656
+ var semantics = {
657
+ /**
658
+ * - Ensures the order of headings is semantically correct
659
+ * - Heading levels should only increase by one ([url](https://dequeuniversity.com/rules/axe/4.4/heading-order?application=axeAPI))
660
+ */
661
+ headingOrder: "heading-order",
662
+ /**
663
+ * - Ensure that links with the same accessible name serve a similar purpose
664
+ * - Links with the same name must have a similar purpose ([url](https://dequeuniversity.com/rules/axe/4.4/identical-links-same-purpose?application=axeAPI))
665
+ */
666
+ identicalLinksSamePurpose: "identical-links-same-purpose",
667
+ /**
668
+ * - Ensures that elements labelled through their content must have their visible text as part of their accessible name
669
+ * - Elements must have their visible text as part of their accessible name ([url](https://dequeuniversity.com/rules/axe/4.4/label-content-name-mismatch?application=axeAPI))
670
+ */
671
+ labelContentNameMismatch: "label-content-name-mismatch",
672
+ /**
673
+ * - Ensures the banner landmark is at top level
674
+ * - Banner landmark should not be contained in another landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-banner-is-top-level?application=axeAPI))
675
+ */
676
+ landmarkBannerIsTopLevel: "landmark-banner-is-top-level",
677
+ /**
678
+ * - Ensures the complementary landmark or aside is at top level
679
+ * - Aside should not be contained in another landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-complementary-is-top-level?application=axeAPI))
680
+ */
681
+ landmarkComplementaryIsTopLevel: "landmark-complementary-is-top-level",
682
+ /**
683
+ * - Ensures the contentinfo landmark is at top level
684
+ * - Contentinfo landmark should not be contained in another landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-contentinfo-is-top-level?application=axeAPI))
685
+ */
686
+ landmarkContentinfoIsTopLevel: "landmark-contentinfo-is-top-level",
687
+ /**
688
+ * - Ensures the main landmark is at top level
689
+ * - Main landmark should not be contained in another landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-main-is-top-level?application=axeAPI))
690
+ */
691
+ landmarkMainIsTopLevel: "landmark-main-is-top-level",
692
+ /**
693
+ * - Ensures the document has at most one banner landmark
694
+ * - Document should not have more than one banner landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-no-duplicate-banner?application=axeAPI))
695
+ */
696
+ landmarkNoDuplicateBanner: "landmark-no-duplicate-banner",
697
+ /**
698
+ * - Ensures the document has at most one contentinfo landmark
699
+ * - Document should not have more than one contentinfo landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-no-duplicate-contentinfo?application=axeAPI))
700
+ */
701
+ landmarkNoDuplicateContentinfo: "landmark-no-duplicate-contentinfo",
702
+ /**
703
+ * - Ensures the document has at most one main landmark
704
+ * - Document should not have more than one main landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-no-duplicate-main?application=axeAPI))
705
+ */
706
+ landmarkNoDuplicateMain: "landmark-no-duplicate-main",
707
+ /**
708
+ * - Ensures the document has a main landmark
709
+ * - Document should have one main landmark ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-one-main?application=axeAPI))
710
+ */
711
+ landmarkOneMain: "landmark-one-main",
712
+ /**
713
+ * - Landmarks should have a unique role or role/label/title (i.e. accessible name) combination
714
+ * - Ensures landmarks are unique ([url](https://dequeuniversity.com/rules/axe/4.4/landmark-unique?application=axeAPI))
715
+ */
716
+ landmarkUnique: "landmark-unique",
717
+ /**
718
+ * - Ensure bold, italic text and font-size is not used to style `<p>` elements as a heading
719
+ * - Styled `<p>` elements must not be used as headings ([url](https://dequeuniversity.com/rules/axe/4.4/p-as-heading?application=axeAPI))
720
+ */
721
+ pAsHeading: "p-as-heading",
722
+ /**
723
+ * - Ensure that the page, or at least one of its frames contains a level-one heading
724
+ * - Page should contain a level-one heading ([url](https://dequeuniversity.com/rules/axe/4.4/page-has-heading-one?application=axeAPI))
725
+ */
726
+ pageHasHeadingOne: "page-has-heading-one"
727
+ };
728
+ var language = {
729
+ /**
730
+ * - Ensures every HTML document has a lang attribute
731
+ * - `<html>` element must have a lang attribute ([url](https://dequeuniversity.com/rules/axe/4.4/html-has-lang?application=axeAPI))
732
+ */
733
+ htmlHasLang: "html-has-lang",
734
+ /**
735
+ * - Ensures the lang attribute of the `<html>` element has a valid value
736
+ * - `<html>` element must have a valid value for the lang attribute ([url](https://dequeuniversity.com/rules/axe/4.4/html-lang-valid?application=axeAPI))
737
+ */
738
+ htmlLangValid: "html-lang-valid",
739
+ /**
740
+ * - Ensure that HTML elements with both valid lang and xml:lang attributes agree on the base language of the page
741
+ * - HTML elements with lang and xml:lang must have the same base language ([url](https://dequeuniversity.com/rules/axe/4.4/html-xml-lang-mismatch?application=axeAPI))
742
+ */
743
+ htmlXmlLangMismatch: "html-xml-lang-mismatch",
744
+ /**
745
+ * - Ensures lang attributes have valid values
746
+ * - lang attribute must have a valid value ([url](https://dequeuniversity.com/rules/axe/4.4/valid-lang?application=axeAPI))
747
+ */
748
+ validLang: "valid-lang"
749
+ };
750
+ var sensoryAndVisualCues = {
751
+ /**
752
+ * - Ensures `<meta name="viewport">` can scale a significant amount
753
+ * - Users should be able to zoom and scale the text up to 500% ([url](https://dequeuniversity.com/rules/axe/4.4/meta-viewport-large?application=axeAPI))
754
+ */
755
+ metaViewportLarge: "meta-viewport-large",
756
+ /**
757
+ * - Ensures `<meta name="viewport">` does not disable text scaling and zooming
758
+ * - Zooming and scaling should not be disabled ([url](https://dequeuniversity.com/rules/axe/4.4/meta-viewport?application=axeAPI))
759
+ */
760
+ metaViewport: "meta-viewport"
761
+ };
762
+ var tables = {
763
+ /**
764
+ * - Ensures the scope attribute is used correctly on tables
765
+ * - scope attribute should be used correctly ([url](https://dequeuniversity.com/rules/axe/4.4/scope-attr-valid?application=axeAPI))
766
+ */
767
+ scopeAttrValid: "scope-attr-valid",
768
+ /**
769
+ * - Ensure the `<caption>` element does not contain the same text as the summary attribute
770
+ * - tables should not have the same summary and caption ([url](https://dequeuniversity.com/rules/axe/4.4/table-duplicate-name?application=axeAPI))
771
+ */
772
+ tableDuplicateName: "table-duplicate-name",
773
+ /**
774
+ * - Ensure that tables with a caption use the `<caption>` element.
775
+ * - Data or header cells must not be used to give caption to a data table. ([url](https://dequeuniversity.com/rules/axe/4.4/table-fake-caption?application=axeAPI))
776
+ */
777
+ tableFakeCaption: "table-fake-caption",
778
+ /**
779
+ * - Ensure that each non-empty data cell in a `<table>` larger than 3 by 3 has one or more table headers
780
+ * - Non-empty `<td>` elements in larger `<table>` must have an associated table header ([url](https://dequeuniversity.com/rules/axe/4.4/td-has-header?application=axeAPI))
781
+ */
782
+ tdHasHeader: "td-has-header",
783
+ /**
784
+ * - Ensure that each cell in a table that uses the headers attribute refers only to other cells in that table
785
+ * - Table cells that use the headers attribute must only refer to cells in the same table ([url](https://dequeuniversity.com/rules/axe/4.4/td-headers-attr?application=axeAPI))
786
+ */
787
+ tdHeadersAttr: "td-headers-attr",
788
+ /**
789
+ * - Ensure that `<th>` elements and elements with role=columnheader/rowheader have data cells they describe
790
+ * - Table headers in a data table must refer to data cells ([url](https://dequeuniversity.com/rules/axe/4.4/th-has-data-cells?application=axeAPI))
791
+ */
792
+ thHasDataCells: "th-has-data-cells"
793
+ };
794
+
795
+ // src/service/html/axe-rules/separated-rules.ts
796
+ var rules = {
797
+ /**
798
+ * These rules can be evaluated against any component.
799
+ */
800
+ alwaysAllowed: [
801
+ aria.ariaAllowedAttr,
802
+ aria.ariaAllowedRole,
803
+ aria.ariaHiddenBody,
804
+ aria.ariaRoledescription,
805
+ aria.ariaRoles,
806
+ aria.presentationRoleConflict,
807
+ forms.autocompleteValid,
808
+ forms.formFieldMultipleLabels,
809
+ // Could not find error state
810
+ keyboard.accesskeys,
811
+ keyboard.focusOrderSemantics,
812
+ keyboard.tabindex,
813
+ language.htmlLangValid,
814
+ language.htmlXmlLangMismatch,
815
+ language.validLang,
816
+ nameRoleValue.ariaHiddenFocus,
817
+ // Could not find error state
818
+ nameRoleValue.emptyHeading,
819
+ parsing.duplicateIdActive,
820
+ parsing.duplicateIdAria,
821
+ parsing.marquee,
822
+ semantics.identicalLinksSamePurpose,
823
+ // Could not find error state
824
+ semantics.landmarkNoDuplicateBanner,
825
+ semantics.landmarkNoDuplicateContentinfo,
826
+ semantics.landmarkNoDuplicateMain,
827
+ semantics.landmarkUnique,
828
+ sensoryAndVisualCues.metaViewportLarge,
829
+ // Could not find error state
830
+ sensoryAndVisualCues.metaViewport,
831
+ // Could not find error state
832
+ tables.scopeAttrValid,
833
+ // Could not find error state
834
+ textAlternatives.serverSideImageMap,
835
+ // Could not find error state
836
+ timeAndMedia.blink,
837
+ timeAndMedia.metaRefresh,
838
+ // Could not find error state
839
+ timeAndMedia.noAutoplayAudio
840
+ // Could not find error state
841
+ ],
842
+ /**
843
+ * These rules can't be resolved with a spread operator
844
+ * in the node's attributes
845
+ */
846
+ requiresAttrs: [
847
+ aria.ariaRequiredAttr,
848
+ language.htmlHasLang,
849
+ textAlternatives.areaAlt,
850
+ textAlternatives.imageAlt,
851
+ textAlternatives.imageRedundantAlt,
852
+ textAlternatives.inputImageAlt,
853
+ textAlternatives.objectAlt,
854
+ textAlternatives.roleImgAlt,
855
+ textAlternatives.svgImgAlt
856
+ ],
857
+ /**
858
+ * These rules can't be resolved with dynamic content
859
+ * in the body of the node
860
+ */
861
+ requiresChildren: [
862
+ aria.ariaRequiredChildren,
863
+ aria.ariaText,
864
+ aria.ariaValidAttrValue,
865
+ aria.emptyTableHeader,
866
+ keyboard.frameFocusableContent,
867
+ keyboard.skipLink,
868
+ nameRoleValue.ariaHiddenFocus,
869
+ semantics.labelContentNameMismatch,
870
+ structure.definitionList,
871
+ structure.list,
872
+ tables.tableDuplicateName,
873
+ tables.tableFakeCaption,
874
+ tables.thHasDataCells,
875
+ textAlternatives.documentTitle,
876
+ textAlternatives.frameTitleUnique,
877
+ textAlternatives.frameTitle,
878
+ textAlternatives.videoCaption,
879
+ timeAndMedia.audioCaption
880
+ ],
881
+ /**
882
+ * These rules can be resolved by changing content in
883
+ * either the node body or its attributes
884
+ */
885
+ requiresAttrsOrChildren: [
886
+ aria.ariaCommandName,
887
+ aria.ariaDialogName,
888
+ aria.ariaInputFieldName,
889
+ aria.ariaMeterName,
890
+ aria.ariaProgressbarName,
891
+ aria.ariaToggleFieldName,
892
+ aria.ariaTooltipName,
893
+ aria.ariaTreeitemName,
894
+ nameRoleValue.inputButtonName,
895
+ nameRoleValue.linkName
896
+ ],
897
+ /**
898
+ * These rules cannot be supported until multiple files
899
+ * are analyzed at once. For now they are ignored.
900
+ */
901
+ requiresParent: [
902
+ aria.ariaRequiredParent,
903
+ forms.label,
904
+ forms.labelTitleOnly,
905
+ forms.selectName,
906
+ keyboard.bypass,
907
+ keyboard.nestedInteractive,
908
+ keyboard.region,
909
+ semantics.headingOrder,
910
+ semantics.landmarkBannerIsTopLevel,
911
+ semantics.landmarkComplementaryIsTopLevel,
912
+ semantics.landmarkContentinfoIsTopLevel,
913
+ semantics.landmarkMainIsTopLevel,
914
+ semantics.landmarkOneMain,
915
+ semantics.pageHasHeadingOne,
916
+ structure.dlitem,
917
+ structure.listitem,
918
+ tables.tdHasHeader,
919
+ tables.tdHeadersAttr
920
+ ],
921
+ /**
922
+ * These rules should not be enforced to all users of
923
+ * the official Marko language server.
924
+ */
925
+ blacklist: [structure.frameTested, parsing.duplicateId],
926
+ /**
927
+ * These are rules that cannot currently be validated, either
928
+ * because of limitations with JSDom + axe-core or with the
929
+ * current implementation of the language server.
930
+ */
931
+ cannotValidate: [
932
+ keyboard.scrollableRegionFocusable,
933
+ semantics.pAsHeading,
934
+ structure.avoidInlineSpacing,
935
+ structure.cssOrientationLock,
936
+ structure.hiddenContent
937
+ ]
938
+ };
939
+ var separated_rules_default = rules;
940
+
941
+ // src/service/html/index.ts
942
+ var extractCache = /* @__PURE__ */ new WeakMap();
943
+ var HTMLService = {
944
+ commands: {
945
+ "$/showHtmlOutput": async (uri) => {
946
+ const doc = get(uri);
947
+ if (!doc)
948
+ return;
949
+ const { extracted } = extract(doc);
950
+ return {
951
+ language: "html",
952
+ content: extracted.toString()
953
+ };
954
+ }
955
+ },
956
+ async doValidate(doc) {
957
+ const { extracted, nodeDetails } = extract(doc);
958
+ const jsdom = new import_jsdom.JSDOM(extracted.toString(), {
959
+ includeNodeLocations: true
960
+ });
961
+ const { documentElement } = jsdom.window.document;
962
+ const getViolationNodes = async (runOnly) => (await import_axe_core.default.run(documentElement, {
963
+ runOnly,
964
+ rules: {
965
+ "color-contrast": { enabled: false }
966
+ },
967
+ resultTypes: ["violations"],
968
+ elementRef: true
969
+ })).violations.flatMap(
970
+ ({ nodes, id }) => nodes.map((node) => ({ ...node, ruleId: id }))
971
+ );
972
+ const release = await acquireMutexLock();
973
+ const violations = await getViolationNodes(separated_rules_default.alwaysAllowed);
974
+ const requiresAttrs = await getViolationNodes(separated_rules_default.requiresAttrs);
975
+ const requiresChildren = await getViolationNodes(separated_rules_default.requiresChildren);
976
+ const requiresAttrsOrChildren = await getViolationNodes(
977
+ separated_rules_default.requiresAttrsOrChildren
978
+ );
979
+ release();
980
+ violations.push(
981
+ ...requiresAttrs.filter(
982
+ ({ element }) => (element == null ? void 0 : element.dataset.markoNodeId) && !nodeDetails[element.dataset.markoNodeId].hasDynamicAttrs
983
+ )
984
+ );
985
+ violations.push(
986
+ ...requiresChildren.filter(
987
+ ({ element }) => (element == null ? void 0 : element.dataset.markoNodeId) && !nodeDetails[element.dataset.markoNodeId].hasDynamicBody
988
+ )
989
+ );
990
+ violations.push(
991
+ ...requiresAttrsOrChildren.filter(
992
+ ({ element }) => (element == null ? void 0 : element.dataset.markoNodeId) && !nodeDetails[element.dataset.markoNodeId].hasDynamicAttrs && !nodeDetails[element.dataset.markoNodeId].hasDynamicBody
993
+ )
994
+ );
995
+ return violations.flatMap((result) => {
996
+ const { element } = result;
997
+ if (!element)
998
+ return [];
999
+ const generatedLoc = jsdom.nodeLocation(element);
1000
+ if (!generatedLoc)
1001
+ return [];
1002
+ const sourceRange = extracted.sourceLocationAt(
1003
+ generatedLoc.startOffset + 1,
1004
+ generatedLoc.startOffset + 1 + element.tagName.length
1005
+ );
1006
+ if (!sourceRange)
1007
+ return [];
1008
+ return [
1009
+ {
1010
+ range: sourceRange,
1011
+ severity: 3,
1012
+ source: `axe-core(${result.ruleId})`,
1013
+ message: result.failureSummary ?? "unknown accessibility issue"
1014
+ }
1015
+ ];
1016
+ });
1017
+ }
1018
+ };
1019
+ function extract(doc) {
1020
+ const { parsed } = getMarkoFile(doc);
1021
+ let cached = extractCache.get(parsed);
1022
+ if (!cached) {
1023
+ cached = (0, import_language_tools2.extractHTML)(parsed);
1024
+ extractCache.set(parsed, cached);
1025
+ }
1026
+ return cached;
1027
+ }
1028
+ var lock;
1029
+ async function acquireMutexLock() {
1030
+ const currLock = lock;
1031
+ let resolve;
1032
+ lock = new Promise((_) => resolve = _);
1033
+ await currLock;
1034
+ return resolve;
1035
+ }
1036
+ var html_default = HTMLService;
1037
+
291
1038
  // src/service/marko/complete/index.ts
292
- var import_language_tools5 = require("@marko/language-tools");
1039
+ var import_language_tools6 = require("@marko/language-tools");
293
1040
 
294
1041
  // src/service/marko/complete/AttrName.ts
295
1042
  var import_vscode_languageserver2 = require("vscode-languageserver");
@@ -397,7 +1144,7 @@ var import_path2 = __toESM(require("path"));
397
1144
  var import_vscode_languageserver3 = require("vscode-languageserver");
398
1145
 
399
1146
  // src/service/marko/util/is-document-link-attr.ts
400
- var import_language_tools2 = require("@marko/language-tools");
1147
+ var import_language_tools3 = require("@marko/language-tools");
401
1148
  var linkedAttrs = /* @__PURE__ */ new Map([
402
1149
  [
403
1150
  "src",
@@ -419,7 +1166,7 @@ var linkedAttrs = /* @__PURE__ */ new Map([
419
1166
  ]);
420
1167
  function isDocumentLinkAttr(code, tag, attr) {
421
1168
  var _a, _b;
422
- return tag.nameText && attr.type === import_language_tools2.NodeType.AttrNamed && ((_a = attr.value) == null ? void 0 : _a.type) === import_language_tools2.NodeType.AttrValue && /^['"]$/.test(code[attr.value.value.start]) && ((_b = linkedAttrs.get(code.slice(attr.name.start, attr.name.end))) == null ? void 0 : _b.has(tag.nameText)) || false;
1169
+ return tag.nameText && attr.type === import_language_tools3.NodeType.AttrNamed && ((_a = attr.value) == null ? void 0 : _a.type) === import_language_tools3.NodeType.AttrValue && /^['"]$/.test(code[attr.value.value.start]) && ((_b = linkedAttrs.get(code.slice(attr.name.start, attr.name.end))) == null ? void 0 : _b.has(tag.nameText)) || false;
423
1170
  }
424
1171
 
425
1172
  // src/utils/file-system.ts
@@ -625,7 +1372,7 @@ function Import({
625
1372
  }
626
1373
 
627
1374
  // src/service/marko/complete/OpenTagName.ts
628
- var import_language_tools3 = require("@marko/language-tools");
1375
+ var import_language_tools4 = require("@marko/language-tools");
629
1376
  function OpenTagName({
630
1377
  node,
631
1378
  file: { parsed, filename, lookup }
@@ -633,11 +1380,11 @@ function OpenTagName({
633
1380
  var _a;
634
1381
  const tag = node.parent;
635
1382
  const range = parsed.locationAt(node);
636
- const isAttrTag = tag.type === import_language_tools3.NodeType.AttrTag;
1383
+ const isAttrTag = tag.type === import_language_tools4.NodeType.AttrTag;
637
1384
  const result = [];
638
1385
  if (isAttrTag) {
639
1386
  let parentTag = tag.owner;
640
- while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools3.NodeType.AttrTag)
1387
+ while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools4.NodeType.AttrTag)
641
1388
  parentTag = parentTag.owner;
642
1389
  const parentTagDef = parentTag && parentTag.nameText && lookup.getTag(parentTag.nameText);
643
1390
  if (parentTagDef) {
@@ -657,7 +1404,7 @@ function OpenTagName({
657
1404
  }
658
1405
  }
659
1406
  } else {
660
- const skipStatements = !(tag.concise && tag.parent.type === import_language_tools3.NodeType.Program);
1407
+ const skipStatements = !(tag.concise && tag.parent.type === import_language_tools4.NodeType.Program);
661
1408
  for (const tag2 of lookup.getTagsSorted()) {
662
1409
  if (!(tag2.name === "*" || tag2.isNestedTag || skipStatements && ((_a = tag2.parseOptions) == null ? void 0 : _a.statement) || tag2.name[0] === "_" && /^@?marko[/-]|[\\/]node_modules[\\/]/.test(tag2.filePath))) {
663
1410
  const completion = getTagNameCompletion({
@@ -676,14 +1423,14 @@ function OpenTagName({
676
1423
 
677
1424
  // src/service/marko/complete/Tag.ts
678
1425
  var import_vscode_languageserver6 = require("vscode-languageserver");
679
- var import_language_tools4 = require("@marko/language-tools");
1426
+ var import_language_tools5 = require("@marko/language-tools");
680
1427
  var partialCloseTagReg = /<\/(?:[^><]*>)?/iy;
681
1428
  function Tag({
682
1429
  node,
683
1430
  offset,
684
1431
  file: { parsed, code }
685
1432
  }) {
686
- const isClosed = node.end !== import_language_tools4.UNFINISHED;
1433
+ const isClosed = node.end !== import_language_tools5.UNFINISHED;
687
1434
  if (isClosed || node.concise)
688
1435
  return;
689
1436
  const closingTagStr = `</${node.nameText || ""}>`;
@@ -734,7 +1481,7 @@ var doComplete = async (doc, params) => {
734
1481
  const offset = doc.offsetAt(params.position);
735
1482
  const node = file.parsed.nodeAt(offset);
736
1483
  return {
737
- items: await ((_a = handlers[import_language_tools5.NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
1484
+ items: await ((_a = handlers[import_language_tools6.NodeType[node.type]]) == null ? void 0 : _a.call(handlers, {
738
1485
  file,
739
1486
  params,
740
1487
  offset,
@@ -746,7 +1493,7 @@ var doComplete = async (doc, params) => {
746
1493
 
747
1494
  // src/service/marko/validate.ts
748
1495
  var import_path4 = __toESM(require("path"));
749
- var import_language_tools6 = require("@marko/language-tools");
1496
+ var import_language_tools7 = require("@marko/language-tools");
750
1497
  var import_vscode_languageserver7 = require("vscode-languageserver");
751
1498
  var import_babel_utils = require("@marko/babel-utils");
752
1499
  var markoErrorRegExp = /^(.+?)\.marko(?:\((\d+)(?:\s*,\s*(\d+))?\))?: (.*)$/gm;
@@ -754,7 +1501,7 @@ var doValidate = (doc) => {
754
1501
  const filename = getFSPath(doc);
755
1502
  const diagnostics = [];
756
1503
  try {
757
- const { meta } = import_language_tools6.Project.getCompiler(
1504
+ const { meta } = import_language_tools7.Project.getCompiler(
758
1505
  filename && import_path4.default.dirname(filename)
759
1506
  ).compileSync(doc.getText(), filename || "untitled.marko", {
760
1507
  code: false,
@@ -886,7 +1633,7 @@ function isErrorWithLoc(err) {
886
1633
  }
887
1634
 
888
1635
  // src/service/marko/hover/index.ts
889
- var import_language_tools7 = require("@marko/language-tools");
1636
+ var import_language_tools8 = require("@marko/language-tools");
890
1637
 
891
1638
  // src/utils/constants.ts
892
1639
  var START_POSITION = {
@@ -930,7 +1677,7 @@ var doHover = async (doc, params) => {
930
1677
  const file = getMarkoFile(doc);
931
1678
  const offset = doc.offsetAt(params.position);
932
1679
  const node = file.parsed.nodeAt(offset);
933
- return await ((_a = handlers2[import_language_tools7.NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
1680
+ return await ((_a = handlers2[import_language_tools8.NodeType[node.type]]) == null ? void 0 : _a.call(handlers2, {
934
1681
  file,
935
1682
  params,
936
1683
  offset,
@@ -939,12 +1686,12 @@ var doHover = async (doc, params) => {
939
1686
  };
940
1687
 
941
1688
  // src/service/marko/definition/index.ts
942
- var import_language_tools10 = require("@marko/language-tools");
1689
+ var import_language_tools11 = require("@marko/language-tools");
943
1690
 
944
1691
  // src/service/marko/definition/AttrName.ts
945
1692
  var import_fs2 = __toESM(require("fs"));
946
1693
  var import_vscode_uri4 = require("vscode-uri");
947
- var import_language_tools8 = require("@marko/language-tools");
1694
+ var import_language_tools9 = require("@marko/language-tools");
948
1695
 
949
1696
  // src/utils/regexp-builder.ts
950
1697
  function RegExpBuilder(strings, ...expressions) {
@@ -993,8 +1740,8 @@ function AttrName2({
993
1740
  tagDefSource
994
1741
  );
995
1742
  if (match && match.index) {
996
- range = (0, import_language_tools8.getLocation)(
997
- (0, import_language_tools8.getLines)(tagDefSource),
1743
+ range = (0, import_language_tools9.getLocation)(
1744
+ (0, import_language_tools9.getLines)(tagDefSource),
998
1745
  match.index,
999
1746
  match.index + match[0].length
1000
1747
  );
@@ -1014,7 +1761,7 @@ function AttrName2({
1014
1761
  var import_fs3 = __toESM(require("fs"));
1015
1762
  var import_path5 = __toESM(require("path"));
1016
1763
  var import_vscode_uri5 = require("vscode-uri");
1017
- var import_language_tools9 = require("@marko/language-tools");
1764
+ var import_language_tools10 = require("@marko/language-tools");
1018
1765
  function OpenTagName3({
1019
1766
  node,
1020
1767
  file: { parsed, lookup }
@@ -1022,9 +1769,9 @@ function OpenTagName3({
1022
1769
  const tag = node.parent;
1023
1770
  let tagDef;
1024
1771
  let range = START_LOCATION;
1025
- if (tag.type === import_language_tools9.NodeType.AttrTag) {
1772
+ if (tag.type === import_language_tools10.NodeType.AttrTag) {
1026
1773
  let parentTag = tag.owner;
1027
- while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools9.NodeType.AttrTag)
1774
+ while ((parentTag == null ? void 0 : parentTag.type) === import_language_tools10.NodeType.AttrTag)
1028
1775
  parentTag = parentTag.owner;
1029
1776
  tagDef = parentTag && parentTag.nameText ? lookup.getTag(parentTag.nameText) : void 0;
1030
1777
  } else {
@@ -1043,8 +1790,8 @@ function OpenTagName3({
1043
1790
  tagDefSource
1044
1791
  );
1045
1792
  if (match && match.index) {
1046
- range = (0, import_language_tools9.getLocation)(
1047
- (0, import_language_tools9.getLines)(tagDefSource),
1793
+ range = (0, import_language_tools10.getLocation)(
1794
+ (0, import_language_tools10.getLines)(tagDefSource),
1048
1795
  match.index,
1049
1796
  match.index + match[0].length
1050
1797
  );
@@ -1070,7 +1817,7 @@ var findDefinition = async (doc, params) => {
1070
1817
  const file = getMarkoFile(doc);
1071
1818
  const offset = doc.offsetAt(params.position);
1072
1819
  const node = file.parsed.nodeAt(offset);
1073
- return await ((_a = handlers3[import_language_tools10.NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1820
+ return await ((_a = handlers3[import_language_tools11.NodeType[node.type]]) == null ? void 0 : _a.call(handlers3, {
1074
1821
  file,
1075
1822
  params,
1076
1823
  offset,
@@ -1079,7 +1826,7 @@ var findDefinition = async (doc, params) => {
1079
1826
  };
1080
1827
 
1081
1828
  // src/service/marko/document-links.ts
1082
- var import_language_tools11 = require("@marko/language-tools");
1829
+ var import_language_tools12 = require("@marko/language-tools");
1083
1830
  var importTagReg2 = /(['"])<((?:[^\1\\>]+|\\.)*)>?\1/g;
1084
1831
  var findDocumentLinks = async (doc) => {
1085
1832
  return processDoc(doc, extractDocumentLinks);
@@ -1098,14 +1845,14 @@ function extractDocumentLinks({
1098
1845
  const { program, read } = parsed;
1099
1846
  const visit = (node) => {
1100
1847
  switch (node.type) {
1101
- case import_language_tools11.NodeType.AttrTag:
1848
+ case import_language_tools12.NodeType.AttrTag:
1102
1849
  if (node.body) {
1103
1850
  for (const child of node.body) {
1104
1851
  visit(child);
1105
1852
  }
1106
1853
  }
1107
1854
  break;
1108
- case import_language_tools11.NodeType.Tag:
1855
+ case import_language_tools12.NodeType.Tag:
1109
1856
  if (node.attrs && node.nameText) {
1110
1857
  for (const attr of node.attrs) {
1111
1858
  if (isDocumentLinkAttr(code, node, attr)) {
@@ -1131,7 +1878,7 @@ function extractDocumentLinks({
1131
1878
  }
1132
1879
  };
1133
1880
  for (const node of program.static) {
1134
- if (node.type === import_language_tools11.NodeType.Import) {
1881
+ if (node.type === import_language_tools12.NodeType.Import) {
1135
1882
  importTagReg2.lastIndex = 0;
1136
1883
  const value = parsed.read(node);
1137
1884
  const match = importTagReg2.exec(value);
@@ -1159,7 +1906,7 @@ function extractDocumentLinks({
1159
1906
 
1160
1907
  // src/service/marko/document-symbols.ts
1161
1908
  var import_vscode_languageserver8 = require("vscode-languageserver");
1162
- var import_language_tools12 = require("@marko/language-tools");
1909
+ var import_language_tools13 = require("@marko/language-tools");
1163
1910
  var findDocumentSymbols = async (doc) => processDoc(doc, extractDocumentSymbols);
1164
1911
  function extractDocumentSymbols({
1165
1912
  uri,
@@ -1175,10 +1922,10 @@ function extractDocumentSymbols({
1175
1922
  const visit = (node) => {
1176
1923
  var _a, _b;
1177
1924
  switch (node.type) {
1178
- case import_language_tools12.NodeType.Tag:
1179
- case import_language_tools12.NodeType.AttrTag:
1925
+ case import_language_tools13.NodeType.Tag:
1926
+ case import_language_tools13.NodeType.AttrTag:
1180
1927
  symbols.push({
1181
- name: (node.type === import_language_tools12.NodeType.AttrTag ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>",
1928
+ name: (node.type === import_language_tools13.NodeType.AttrTag ? (_a = node.nameText) == null ? void 0 : _a.slice(node.nameText.indexOf("@")) : node.nameText) || "<${...}>",
1182
1929
  kind: node.nameText && ((_b = lookup.getTag(node.nameText)) == null ? void 0 : _b.html) && import_vscode_languageserver8.SymbolKind.Property || import_vscode_languageserver8.SymbolKind.Class,
1183
1930
  location: {
1184
1931
  uri,
@@ -1252,20 +1999,20 @@ var import_tsserverlibrary = __toESM(require("typescript/lib/tsserverlibrary"));
1252
1999
  var import_vscode_languageserver10 = require("vscode-languageserver");
1253
2000
  var import_vscode_uri6 = require("vscode-uri");
1254
2001
  var prettier2 = __toESM(require("prettier"));
1255
- var import_language_tools14 = require("@marko/language-tools");
2002
+ var import_language_tools15 = require("@marko/language-tools");
1256
2003
 
1257
2004
  // src/ts-plugin/host.ts
1258
2005
  var import_path6 = __toESM(require("path"));
1259
- var import_language_tools13 = require("@marko/language-tools");
2006
+ var import_language_tools14 = require("@marko/language-tools");
1260
2007
  var fsPathReg = /^(?:[./\\]|[A-Z]:)/i;
1261
2008
  var modulePartsReg = /^((?:@(?:[^/]+)\/)?(?:[^/]+))(.*)$/;
1262
- import_language_tools13.Project.setDefaultTypePaths({
2009
+ import_language_tools14.Project.setDefaultTypePaths({
1263
2010
  internalTypesFile: import_path6.default.join(__dirname, "marko.internal.d.ts"),
1264
2011
  markoTypesFile: import_path6.default.join(__dirname, "marko.runtime.d.ts")
1265
2012
  });
1266
- function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
2013
+ function patch(ts2, configFile, extractCache3, resolutionCache, host, ps) {
1267
2014
  var _a, _b, _c;
1268
- const processors = import_language_tools13.Processors.create({
2015
+ const processors = import_language_tools14.Processors.create({
1269
2016
  ts: ts2,
1270
2017
  host,
1271
2018
  configFile
@@ -1302,7 +2049,7 @@ function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
1302
2049
  host.getScriptSnapshot = (fileName) => {
1303
2050
  const processor = getProcessor(fileName);
1304
2051
  if (processor) {
1305
- let cached = extractCache2.get(fileName);
2052
+ let cached = extractCache3.get(fileName);
1306
2053
  if (!cached) {
1307
2054
  const code = host.readFile(fileName, "utf-8") || "";
1308
2055
  try {
@@ -1312,7 +2059,7 @@ function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
1312
2059
  cached = { snapshot: ts2.ScriptSnapshot.fromString("") };
1313
2060
  }
1314
2061
  trackFile(fileName);
1315
- extractCache2.set(fileName, cached);
2062
+ extractCache3.set(fileName, cached);
1316
2063
  }
1317
2064
  return cached.snapshot;
1318
2065
  }
@@ -1332,7 +2079,7 @@ function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
1332
2079
  host.readDirectory = (path8, extensions, exclude, include, depth) => {
1333
2080
  return readDirectory2(
1334
2081
  path8,
1335
- extensions == null ? void 0 : extensions.concat(import_language_tools13.Processors.extensions),
2082
+ extensions == null ? void 0 : extensions.concat(import_language_tools14.Processors.extensions),
1336
2083
  exclude,
1337
2084
  include,
1338
2085
  depth
@@ -1379,12 +2126,12 @@ function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
1379
2126
  }
1380
2127
  }
1381
2128
  if (resolvedFileName) {
1382
- if ((0, import_language_tools13.isDefinitionFile)(resolvedFileName)) {
2129
+ if ((0, import_language_tools14.isDefinitionFile)(resolvedFileName)) {
1383
2130
  if (!host.fileExists(resolvedFileName)) {
1384
2131
  resolvedFileName = void 0;
1385
2132
  }
1386
2133
  } else {
1387
- const ext = (0, import_language_tools13.getExt)(resolvedFileName);
2134
+ const ext = (0, import_language_tools14.getExt)(resolvedFileName);
1388
2135
  const definitionFile = `${resolvedFileName.slice(
1389
2136
  0,
1390
2137
  -ext.length
@@ -1432,7 +2179,7 @@ function patch(ts2, configFile, extractCache2, resolutionCache, host, ps) {
1432
2179
  }
1433
2180
  return host;
1434
2181
  function getProcessor(fileName) {
1435
- const ext = (0, import_language_tools13.getExt)(fileName);
2182
+ const ext = (0, import_language_tools14.getExt)(fileName);
1436
2183
  return ext ? processors[ext] : void 0;
1437
2184
  }
1438
2185
  }
@@ -1589,7 +2336,7 @@ function escapeBackTicks(text) {
1589
2336
 
1590
2337
  // src/service/script/index.ts
1591
2338
  var IGNORE_DIAG_REG = /^(?:(?:Expression|Identifier|['"][^\w]['"]) expected|Invalid character)\b/i;
1592
- var extractCache = /* @__PURE__ */ new Map();
2339
+ var extractCache2 = /* @__PURE__ */ new Map();
1593
2340
  var snapshotCache = /* @__PURE__ */ new Map();
1594
2341
  var insertModuleStatementLocCache = /* @__PURE__ */ new WeakMap();
1595
2342
  var markoFileReg = /\.marko$/;
@@ -1638,7 +2385,7 @@ var ScriptService = {
1638
2385
  return;
1639
2386
  const tsProject = getTSProject(filename);
1640
2387
  const extracted = processScript(doc, tsProject);
1641
- const lang = import_language_tools14.Project.getScriptLang(
2388
+ const lang = import_language_tools15.Project.getScriptLang(
1642
2389
  filename,
1643
2390
  tsProject.markoScriptLang,
1644
2391
  import_tsserverlibrary.default,
@@ -1648,14 +2395,14 @@ var ScriptService = {
1648
2395
  const content = (() => {
1649
2396
  try {
1650
2397
  return prettier2.format(generated, {
1651
- parser: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "babel"
2398
+ parser: lang === import_language_tools15.ScriptLang.ts ? "typescript" : "babel"
1652
2399
  });
1653
2400
  } catch {
1654
2401
  return generated;
1655
2402
  }
1656
2403
  })();
1657
2404
  return {
1658
- language: lang === import_language_tools14.ScriptLang.ts ? "typescript" : "javascript",
2405
+ language: lang === import_language_tools15.ScriptLang.ts ? "typescript" : "javascript",
1659
2406
  content
1660
2407
  };
1661
2408
  }
@@ -1667,10 +2414,10 @@ var ScriptService = {
1667
2414
  onFileChange((doc) => {
1668
2415
  if (doc) {
1669
2416
  const filename = getFSPath(doc);
1670
- extractCache.delete(filename);
2417
+ extractCache2.delete(filename);
1671
2418
  snapshotCache.delete(filename);
1672
2419
  } else {
1673
- extractCache.clear();
2420
+ extractCache2.clear();
1674
2421
  snapshotCache.clear();
1675
2422
  }
1676
2423
  });
@@ -2018,12 +2765,12 @@ function processScript(doc, tsProject) {
2018
2765
  return processDoc(doc, ({ filename, parsed, lookup }) => {
2019
2766
  var _a;
2020
2767
  const { host, markoScriptLang } = tsProject;
2021
- return (0, import_language_tools14.extractScript)({
2768
+ return (0, import_language_tools15.extractScript)({
2022
2769
  ts: import_tsserverlibrary.default,
2023
2770
  parsed,
2024
2771
  lookup,
2025
- scriptLang: import_language_tools14.Project.getScriptLang(filename, markoScriptLang, import_tsserverlibrary.default, host),
2026
- runtimeTypesCode: (_a = import_language_tools14.Project.getTypeLibs(tsProject.rootDir, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode
2772
+ scriptLang: import_language_tools15.Project.getScriptLang(filename, markoScriptLang, import_tsserverlibrary.default, host),
2773
+ runtimeTypesCode: (_a = import_language_tools15.Project.getTypeLibs(tsProject.rootDir, import_tsserverlibrary.default, host)) == null ? void 0 : _a.markoTypesCode
2027
2774
  });
2028
2775
  });
2029
2776
  }
@@ -2034,9 +2781,9 @@ function getInsertModuleStatementOffset(parsed) {
2034
2781
  let lastImport;
2035
2782
  for (const node of program.static) {
2036
2783
  switch (node.type) {
2037
- case import_language_tools14.NodeType.Export:
2784
+ case import_language_tools15.NodeType.Export:
2038
2785
  return node.start;
2039
- case import_language_tools14.NodeType.Import:
2786
+ case import_language_tools15.NodeType.Import:
2040
2787
  lastImport = node;
2041
2788
  break;
2042
2789
  }
@@ -2077,7 +2824,7 @@ function docLocationAtTextSpan(doc, { start, length }) {
2077
2824
  function getTSProject(docFsPath) {
2078
2825
  var _a;
2079
2826
  let configFile;
2080
- let markoScriptLang = import_language_tools14.ScriptLang.js;
2827
+ let markoScriptLang = import_language_tools15.ScriptLang.js;
2081
2828
  if (docFsPath) {
2082
2829
  configFile = import_tsserverlibrary.default.findConfigFile(
2083
2830
  docFsPath,
@@ -2085,7 +2832,7 @@ function getTSProject(docFsPath) {
2085
2832
  "tsconfig.json"
2086
2833
  );
2087
2834
  if (configFile) {
2088
- markoScriptLang = import_language_tools14.ScriptLang.ts;
2835
+ markoScriptLang = import_language_tools15.ScriptLang.ts;
2089
2836
  } else {
2090
2837
  configFile = import_tsserverlibrary.default.findConfigFile(
2091
2838
  docFsPath,
@@ -2095,7 +2842,7 @@ function getTSProject(docFsPath) {
2095
2842
  }
2096
2843
  }
2097
2844
  const rootDir = configFile && import_path7.default.dirname(configFile) || process.cwd();
2098
- const cache = import_language_tools14.Project.getCache(configFile && rootDir);
2845
+ const cache = import_language_tools15.Project.getCache(configFile && rootDir);
2099
2846
  let projectCache = cache.get(getTSProject);
2100
2847
  let cached;
2101
2848
  if (projectCache) {
@@ -2132,7 +2879,7 @@ function getTSProject(docFsPath) {
2132
2879
  const host = patch(
2133
2880
  import_tsserverlibrary.default,
2134
2881
  configFile,
2135
- extractCache,
2882
+ extractCache2,
2136
2883
  resolutionCache,
2137
2884
  {
2138
2885
  getNewLine() {
@@ -2234,7 +2981,7 @@ function filenameToURI(filename) {
2234
2981
  }
2235
2982
  async function getPreferences(scriptLang) {
2236
2983
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2237
- const configName = scriptLang === import_language_tools14.ScriptLang.js ? "javascript" : "typescript";
2984
+ const configName = scriptLang === import_language_tools15.ScriptLang.js ? "javascript" : "typescript";
2238
2985
  const [preferencesConfig, suggestConfig, inlayHintsConfig] = await Promise.all([
2239
2986
  getConfig(`${configName}.preferences`),
2240
2987
  getConfig(`${configName}.suggest`),
@@ -2391,7 +3138,7 @@ function getCanonicalFileName(fileName) {
2391
3138
  var import_vscode_css_languageservice2 = require("vscode-css-languageservice");
2392
3139
  var import_vscode_languageserver11 = require("vscode-languageserver");
2393
3140
  var import_vscode_languageserver_textdocument2 = require("vscode-languageserver-textdocument");
2394
- var import_language_tools15 = require("@marko/language-tools");
3141
+ var import_language_tools16 = require("@marko/language-tools");
2395
3142
  var services = {
2396
3143
  ".css": import_vscode_css_languageservice2.getCSSLanguageService,
2397
3144
  ".less": import_vscode_css_languageservice2.getLESSLanguageService,
@@ -2698,7 +3445,7 @@ function processStyle(doc) {
2698
3445
  return processDoc(doc, ({ uri, version, parsed, lookup }) => {
2699
3446
  var _a;
2700
3447
  const result = [];
2701
- for (const [ext, extracted] of (0, import_language_tools15.extractStyle)({
3448
+ for (const [ext, extracted] of (0, import_language_tools16.extractStyle)({
2702
3449
  parsed,
2703
3450
  lookup
2704
3451
  })) {
@@ -2782,7 +3529,7 @@ function isTextEdit(edit) {
2782
3529
 
2783
3530
  // src/service/index.ts
2784
3531
  var REG_MARKDOWN_CHARS = /[\\`*_{}[\]<>()#+.!|-]/g;
2785
- var plugins = [marko_default, ScriptService, StyleSheetService];
3532
+ var plugins = [marko_default, ScriptService, StyleSheetService, html_default];
2786
3533
  var service = {
2787
3534
  commands: Object.assign({}, ...plugins.map(({ commands }) => commands)),
2788
3535
  async initialize(params) {
@@ -3125,7 +3872,7 @@ console.error = (...args) => {
3125
3872
  process.on("uncaughtException", console.error);
3126
3873
  process.on("unhandledRejection", console.error);
3127
3874
  connection3.onInitialize(async (params) => {
3128
- setup3(connection3);
3875
+ setup2(connection3);
3129
3876
  await service.initialize(params);
3130
3877
  return {
3131
3878
  capabilities: {
@@ -3167,9 +3914,23 @@ connection3.onInitialize(async (params) => {
3167
3914
  }
3168
3915
  };
3169
3916
  });
3170
- setup2(connection3);
3171
- onConfigChange(validateDocs);
3172
3917
  setup(connection3);
3918
+ onConfigChange(validateDocs);
3919
+ connection3.onDidOpenTextDocument(async (params) => {
3920
+ doOpen(params);
3921
+ const doc = get(params.textDocument.uri);
3922
+ if (doc) {
3923
+ const diagnostics = await service.doValidate(doc) || [];
3924
+ prevDiags.set(doc, diagnostics);
3925
+ connection3.sendDiagnostics({
3926
+ uri: doc.uri,
3927
+ diagnostics
3928
+ });
3929
+ }
3930
+ });
3931
+ connection3.onDidChangeTextDocument(doChange);
3932
+ connection3.onDidCloseTextDocument(doClose);
3933
+ connection3.onDidChangeWatchedFiles(doChangeWatchedFiles);
3173
3934
  onFileChange((changeDoc) => {
3174
3935
  if (changeDoc) {
3175
3936
  queueDiagnostic();
@@ -3270,7 +4031,7 @@ for (const command in service.commands) {
3270
4031
  }
3271
4032
  function validateDocs() {
3272
4033
  queueDiagnostic();
3273
- import_language_tools16.Project.clearCaches();
4034
+ import_language_tools17.Project.clearCaches();
3274
4035
  }
3275
4036
  function queueDiagnostic() {
3276
4037
  clearTimeout(diagnosticTimeout);