abledom 0.4.0 → 0.6.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/esm/index.js CHANGED
@@ -58,7 +58,10 @@ var ValidationRule = class {
58
58
  };
59
59
 
60
60
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/ui.css
61
- var ui_default = "#abledom-report {\n bottom: 20px;\n display: flex;\n flex-direction: column;\n left: 10px;\n max-height: 80%;\n max-width: 60%;\n padding: 4px 8px;\n position: fixed;\n z-index: 100500;\n}\n\n#abledom-report :focus-visible {\n outline: 3px solid red;\n mix-blend-mode: difference;\n}\n\n#abledom-report.abledom-align-left {\n left: 10px;\n right: auto;\n}\n\n#abledom-report.abledom-align-right {\n left: auto;\n right: 10px;\n}\n\n#abledom-report.abledom-align-bottom {\n bottom: 20px;\n top: auto;\n}\n\n#abledom-report.abledom-align-top {\n /* flex-direction: column-reverse; */\n bottom: auto;\n top: 10px;\n}\n\n.abledom-menu-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-block;\n margin: 2px auto 2px 0;\n}\n\n#abledom-report.abledom-align-right .abledom-menu-container {\n margin: 2px 0 2px auto;\n}\n\n.abledom-menu {\n background-color: rgba(140, 10, 121, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n\n.abledom-menu .issues-count {\n margin: 0 8px;\n display: inline-block;\n}\n\n.abledom-menu .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-menu .align-button {\n border-right-color: rgba(0, 0, 0, 0.4);\n border-radius: 0;\n margin: 0;\n}\n\n.abledom-menu .align-button:active,\n#abledom-report .pressed {\n background: linear-gradient(\n 180deg,\n rgba(130, 130, 130, 1) 0%,\n rgba(180, 180, 180, 1) 100%\n );\n}\n\n.abledom-menu .align-button-first {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n margin-left: 8px;\n}\n.abledom-menu .align-button-last {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n border-right-color: rgba(255, 255, 255, 0.4);\n}\n\n.abledom-issues-container {\n overflow: scroll;\n max-height: calc(100vh - 100px);\n}\n\n#abledom-report.abledom-align-right .abledom-issues-container {\n text-align: right;\n}\n\n.abledom-issue-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-flex;\n margin: 2px 0;\n}\n\n.abledom-issue {\n background-color: rgba(164, 2, 2, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n.abledom-issue_warning {\n background-color: rgba(163, 82, 1, 0.7);\n}\n.abledom-issue_info {\n background-color: rgba(0, 0, 255, 0.7);\n}\n\n.abledom-issue .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-issue .button:hover {\n opacity: 0.7;\n}\n\n.abledom-issue .button.close {\n background: none;\n border-color: transparent;\n color: #fff;\n margin: 0;\n}\n\n.abledom-highlight {\n background-color: yellow;\n box-sizing: border-box;\n display: none;\n opacity: 0.6;\n position: fixed;\n z-index: 100499;\n}\n\n.abledom-highlight-border1 {\n border-top: 2px solid red;\n border-bottom: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n top: -2px;\n width: calc(100% + 20px);\n height: calc(100% + 4px);\n margin: 0 -10px;\n}\n\n.abledom-highlight-border2 {\n border-left: 2px solid red;\n border-right: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n width: calc(100% + 4px);\n left: -2px;\n height: calc(100% + 20px);\n margin: -10px 0;\n}\n";
61
+ var ui_default = "#abledom-report {\n bottom: 20px;\n display: flex;\n flex-direction: column;\n left: 10px;\n max-height: 80%;\n max-width: 60%;\n padding: 4px 8px;\n position: fixed;\n z-index: 100500;\n}\n\n#abledom-report :focus-visible {\n outline: 3px solid red;\n mix-blend-mode: difference;\n}\n\n#abledom-report.abledom-align-left {\n left: 10px;\n right: auto;\n}\n\n#abledom-report.abledom-align-right {\n left: auto;\n right: 10px;\n}\n\n#abledom-report.abledom-align-bottom {\n bottom: 20px;\n top: auto;\n}\n\n#abledom-report.abledom-align-top {\n /* flex-direction: column-reverse; */\n bottom: auto;\n top: 10px;\n}\n\n.abledom-menu-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-block;\n margin: 2px auto 2px 0;\n}\n\n#abledom-report.abledom-align-right .abledom-menu-container {\n margin: 2px 0 2px auto;\n}\n\n.abledom-menu {\n background-color: rgba(140, 10, 121, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n\n.abledom-menu .issues-count {\n margin: 0 8px;\n display: inline-block;\n}\n\n.abledom-menu .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-menu .align-button {\n border-right-color: rgba(0, 0, 0, 0.4);\n border-radius: 0;\n margin: 0;\n}\n\n.abledom-menu .align-button:active,\n#abledom-report .pressed {\n background: linear-gradient(\n 180deg,\n rgba(130, 130, 130, 1) 0%,\n rgba(180, 180, 180, 1) 100%\n );\n}\n\n.abledom-menu .align-button-first {\n border-top-left-radius: 6px;\n border-bottom-left-radius: 6px;\n margin-left: 8px;\n}\n.abledom-menu .align-button-last {\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n border-right-color: rgba(255, 255, 255, 0.4);\n}\n\n.abledom-issues-container {\n overflow: auto;\n max-height: calc(100vh - 100px);\n}\n\n#abledom-report.abledom-align-right .abledom-issues-container {\n text-align: right;\n}\n\n.abledom-issue-container {\n backdrop-filter: blur(3px);\n border-radius: 8px;\n box-shadow: 0px 0px 4px rgba(127, 127, 127, 0.5);\n display: inline-flex;\n margin: 2px 0;\n}\n\n.abledom-issue {\n background-color: rgba(164, 2, 2, 0.7);\n border-radius: 8px;\n color: white;\n display: inline flex;\n font-family: Arial, Helvetica, sans-serif;\n font-size: 16px;\n line-height: 26px;\n padding: 4px;\n}\n.abledom-issue_warning {\n background-color: rgba(163, 82, 1, 0.7);\n}\n.abledom-issue_info {\n background-color: rgba(0, 0, 255, 0.7);\n}\n\n.abledom-issue .button {\n all: unset;\n color: #000;\n cursor: pointer;\n background: linear-gradient(\n 180deg,\n rgba(255, 255, 255, 1) 0%,\n rgba(200, 200, 200, 1) 100%\n );\n border-radius: 6px;\n border: 1px solid rgba(255, 255, 255, 0.4);\n box-sizing: border-box;\n line-height: 0px;\n margin-right: 4px;\n max-height: 26px;\n padding: 2px;\n text-decoration: none;\n}\n\n.abledom-issue .button:hover {\n opacity: 0.7;\n}\n\n.abledom-issue .button.close {\n background: none;\n border-color: transparent;\n color: #fff;\n margin: 0;\n}\n";
62
+
63
+ // inline-file:/Users/marata/Documents/Work/abledom/src/ui/highlighter.css
64
+ var highlighter_default = ".abledom-highlight {\n background-color: yellow;\n box-sizing: border-box;\n display: none;\n opacity: 0.6;\n position: fixed;\n z-index: 100499;\n}\n\n.abledom-highlight-border1 {\n border-top: 2px solid red;\n border-bottom: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n top: -2px;\n width: calc(100% + 20px);\n height: calc(100% + 4px);\n margin: 0 -10px;\n}\n\n.abledom-highlight-border2 {\n border-left: 2px solid red;\n border-right: 2px solid red;\n box-sizing: border-box;\n position: absolute;\n width: calc(100% + 4px);\n left: -2px;\n height: calc(100% + 20px);\n margin: -10px 0;\n}\n";
62
65
 
63
66
  // src/ui/domBuilder.ts
64
67
  var DOMBuilder = class {
@@ -116,7 +119,7 @@ var DOMBuilder = class {
116
119
  };
117
120
 
118
121
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/close.svg
119
- var close_default = function buildSVG(parent) {
122
+ var close_default = (function buildSVG(parent) {
120
123
  const builder = new DOMBuilder(parent);
121
124
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
122
125
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -127,10 +130,10 @@ var close_default = function buildSVG(parent) {
127
130
  builder.closeTag();
128
131
  builder.closeTag();
129
132
  return parent.firstElementChild;
130
- };
133
+ });
131
134
 
132
135
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/help.svg
133
- var help_default = function buildSVG2(parent) {
136
+ var help_default = (function buildSVG2(parent) {
134
137
  const builder = new DOMBuilder(parent);
135
138
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
136
139
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -141,10 +144,10 @@ var help_default = function buildSVG2(parent) {
141
144
  builder.closeTag();
142
145
  builder.closeTag();
143
146
  return parent.firstElementChild;
144
- };
147
+ });
145
148
 
146
149
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/log.svg
147
- var log_default = function buildSVG3(parent) {
150
+ var log_default = (function buildSVG3(parent) {
148
151
  const builder = new DOMBuilder(parent);
149
152
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
150
153
  builder.openTag("polyline", { "points": "4 7 9 12 4 17" }, void 0, "http://www.w3.org/2000/svg");
@@ -153,10 +156,10 @@ var log_default = function buildSVG3(parent) {
153
156
  builder.closeTag();
154
157
  builder.closeTag();
155
158
  return parent.firstElementChild;
156
- };
159
+ });
157
160
 
158
161
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/reveal.svg
159
- var reveal_default = function buildSVG4(parent) {
162
+ var reveal_default = (function buildSVG4(parent) {
160
163
  const builder = new DOMBuilder(parent);
161
164
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 24 24", "fill": "none", "stroke": "currentColor", "stroke-width": "2", "stroke-linecap": "round", "stroke-linejoin": "round", "xmlns": "http://www.w3.org/2000/svg" }, void 0, "http://www.w3.org/2000/svg");
162
165
  builder.openTag("circle", { "cx": "12", "cy": "12", "r": "10" }, void 0, "http://www.w3.org/2000/svg");
@@ -171,10 +174,10 @@ var reveal_default = function buildSVG4(parent) {
171
174
  builder.closeTag();
172
175
  builder.closeTag();
173
176
  return parent.firstElementChild;
174
- };
177
+ });
175
178
 
176
179
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/bug.svg
177
- var bug_default = function buildSVG5(parent) {
180
+ var bug_default = (function buildSVG5(parent) {
178
181
  const builder = new DOMBuilder(parent);
179
182
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
180
183
  builder.openTag("ellipse", { "cx": "10", "cy": "12", "rx": "4", "ry": "5", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -199,10 +202,10 @@ var bug_default = function buildSVG5(parent) {
199
202
  builder.closeTag();
200
203
  builder.closeTag();
201
204
  return parent.firstElementChild;
202
- };
205
+ });
203
206
 
204
207
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/hideall.svg
205
- var hideall_default = function buildSVG6(parent) {
208
+ var hideall_default = (function buildSVG6(parent) {
206
209
  const builder = new DOMBuilder(parent);
207
210
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
208
211
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -213,10 +216,10 @@ var hideall_default = function buildSVG6(parent) {
213
216
  builder.closeTag();
214
217
  builder.closeTag();
215
218
  return parent.firstElementChild;
216
- };
219
+ });
217
220
 
218
221
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/muteall.svg
219
- var muteall_default = function buildSVG7(parent) {
222
+ var muteall_default = (function buildSVG7(parent) {
220
223
  const builder = new DOMBuilder(parent);
221
224
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
222
225
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -229,10 +232,10 @@ var muteall_default = function buildSVG7(parent) {
229
232
  builder.closeTag();
230
233
  builder.closeTag();
231
234
  return parent.firstElementChild;
232
- };
235
+ });
233
236
 
234
237
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/showall.svg
235
- var showall_default = function buildSVG8(parent) {
238
+ var showall_default = (function buildSVG8(parent) {
236
239
  const builder = new DOMBuilder(parent);
237
240
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
238
241
  builder.openTag("path", { "d": "M11.44 17.5a1.67 1.67 0 0 1-2.89 0", "stroke-width": "1.5" }, void 0, "http://www.w3.org/2000/svg");
@@ -241,47 +244,47 @@ var showall_default = function buildSVG8(parent) {
241
244
  builder.closeTag();
242
245
  builder.closeTag();
243
246
  return parent.firstElementChild;
244
- };
247
+ });
245
248
 
246
249
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/aligntopleft.svg
247
- var aligntopleft_default = function buildSVG9(parent) {
250
+ var aligntopleft_default = (function buildSVG9(parent) {
248
251
  const builder = new DOMBuilder(parent);
249
252
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
250
253
  builder.openTag("rect", { "x": "3", "y": "3", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
251
254
  builder.closeTag();
252
255
  builder.closeTag();
253
256
  return parent.firstElementChild;
254
- };
257
+ });
255
258
 
256
259
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/aligntopright.svg
257
- var aligntopright_default = function buildSVG10(parent) {
260
+ var aligntopright_default = (function buildSVG10(parent) {
258
261
  const builder = new DOMBuilder(parent);
259
262
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
260
263
  builder.openTag("rect", { "x": "11", "y": "3", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
261
264
  builder.closeTag();
262
265
  builder.closeTag();
263
266
  return parent.firstElementChild;
264
- };
267
+ });
265
268
 
266
269
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/alignbottomright.svg
267
- var alignbottomright_default = function buildSVG11(parent) {
270
+ var alignbottomright_default = (function buildSVG11(parent) {
268
271
  const builder = new DOMBuilder(parent);
269
272
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
270
273
  builder.openTag("rect", { "x": "11", "y": "11", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
271
274
  builder.closeTag();
272
275
  builder.closeTag();
273
276
  return parent.firstElementChild;
274
- };
277
+ });
275
278
 
276
279
  // inline-file:/Users/marata/Documents/Work/abledom/src/ui/alignbottomleft.svg
277
- var alignbottomleft_default = function buildSVG12(parent) {
280
+ var alignbottomleft_default = (function buildSVG12(parent) {
278
281
  const builder = new DOMBuilder(parent);
279
282
  builder.openTag("svg", { "width": "20", "height": "20", "viewBox": "0 0 20 20", "fill": "none", "stroke": "currentColor" }, void 0, "http://www.w3.org/2000/svg");
280
283
  builder.openTag("rect", { "x": "3", "y": "11", "width": "6", "height": "6", "stroke-width": "2" }, void 0, "http://www.w3.org/2000/svg");
281
284
  builder.closeTag();
282
285
  builder.closeTag();
283
286
  return parent.firstElementChild;
284
- };
287
+ });
285
288
 
286
289
  // src/ui/ui.ts
287
290
  var pressedClass = "pressed";
@@ -364,8 +367,7 @@ var IssueUI = class {
364
367
  if (element2) {
365
368
  revealButton.onclick = () => {
366
369
  var _a;
367
- element2.scrollIntoView({ block: "center" });
368
- (_a = this._issuesUI) == null ? void 0 : _a.highlight(element2);
370
+ (_a = this._issuesUI) == null ? void 0 : _a.highlight(element2, true);
369
371
  };
370
372
  } else {
371
373
  revealButton.style.display = "none";
@@ -442,7 +444,8 @@ var IssueUI = class {
442
444
  }
443
445
  };
444
446
  var IssuesUI = class {
445
- constructor(win, props) {
447
+ constructor(win, getHighlighter, props) {
448
+ __publicField(this, "_win");
446
449
  __publicField(this, "_container");
447
450
  __publicField(this, "_issuesContainer");
448
451
  __publicField(this, "_menuElement");
@@ -455,9 +458,11 @@ var IssuesUI = class {
455
458
  __publicField(this, "_alignBottomRightButton");
456
459
  __publicField(this, "_isMuted", false);
457
460
  __publicField(this, "_issues", /* @__PURE__ */ new Set());
458
- __publicField(this, "_highlighter");
461
+ __publicField(this, "_getHighlighter");
459
462
  __publicField(this, "bugReport");
460
463
  __publicField(this, "headless");
464
+ this._win = win;
465
+ this._getHighlighter = getHighlighter;
461
466
  this.bugReport = props.bugReport;
462
467
  this.headless = !!props.headless;
463
468
  if (this.headless) {
@@ -578,7 +583,6 @@ var IssuesUI = class {
578
583
  }
579
584
  ).element(alignbottomright_default).closeTag().closeTag();
580
585
  doc.body.appendChild(container);
581
- this._highlighter = new ElementHighlighter(win);
582
586
  }
583
587
  setUIAlignment(alignment) {
584
588
  var _a, _b, _c, _d, _e, _f, _g, _h;
@@ -700,15 +704,15 @@ var IssuesUI = class {
700
704
  });
701
705
  this._setShowHideButtonsVisibility();
702
706
  }
703
- highlight(element) {
704
- var _a;
705
- (_a = this._highlighter) == null ? void 0 : _a.highlight(element);
707
+ highlight(element, scrollIntoView, autoHideTime) {
708
+ var _a, _b;
709
+ (_b = (_a = this._getHighlighter) == null ? void 0 : _a.call(this)) == null ? void 0 : _b.highlight(element, scrollIntoView, autoHideTime);
706
710
  }
707
711
  dispose() {
708
- var _a, _b;
709
- (_a = this._highlighter) == null ? void 0 : _a.dispose();
710
- (_b = this._container) == null ? void 0 : _b.remove();
711
- delete this._highlighter;
712
+ var _a;
713
+ (_a = this._container) == null ? void 0 : _a.remove();
714
+ delete this._win;
715
+ delete this._getHighlighter;
712
716
  delete this._container;
713
717
  delete this._issuesContainer;
714
718
  delete this._menuElement;
@@ -728,6 +732,7 @@ var ElementHighlighter = class {
728
732
  __publicField(this, "_element");
729
733
  __publicField(this, "_cancelScrollTimer");
730
734
  __publicField(this, "_intersectionObserver");
735
+ __publicField(this, "_cancelAutoHideTimer");
731
736
  __publicField(this, "_onScroll", () => {
732
737
  var _a;
733
738
  (_a = this._cancelScrollTimer) == null ? void 0 : _a.call(this);
@@ -748,10 +753,19 @@ var ElementHighlighter = class {
748
753
  const container = this._container = win.document.createElement("div");
749
754
  container.__abledomui = true;
750
755
  container.className = "abledom-highlight";
756
+ const doc = win.document;
757
+ const style = doc.createElement("style");
758
+ style.type = "text/css";
759
+ style.appendChild(doc.createTextNode(highlighter_default));
760
+ container.appendChild(style);
751
761
  new DOMBuilder(container).openTag("div", { class: "abledom-highlight-border1" }).closeTag().openTag("div", { class: "abledom-highlight-border2" }).closeTag();
752
762
  win.addEventListener("scroll", this._onScroll, true);
753
763
  }
754
- highlight(element) {
764
+ highlight(element, scrollIntoView, autoHideTime) {
765
+ var _a;
766
+ if (this._cancelAutoHideTimer && element !== this._element) {
767
+ this._cancelAutoHideTimer();
768
+ }
755
769
  if (!element) {
756
770
  delete this._element;
757
771
  this._unobserve();
@@ -764,6 +778,22 @@ var ElementHighlighter = class {
764
778
  return;
765
779
  }
766
780
  this._element = element;
781
+ if (scrollIntoView) {
782
+ element.scrollIntoView({ block: "center" });
783
+ }
784
+ if (autoHideTime) {
785
+ (_a = this._cancelAutoHideTimer) == null ? void 0 : _a.call(this);
786
+ const autoHideTimeout = win.setTimeout(() => {
787
+ if (this._cancelAutoHideTimer) {
788
+ this.highlight(null);
789
+ delete this._cancelAutoHideTimer;
790
+ }
791
+ }, autoHideTime);
792
+ this._cancelAutoHideTimer = () => {
793
+ win.clearTimeout(autoHideTimeout);
794
+ delete this._cancelAutoHideTimer;
795
+ };
796
+ }
767
797
  this._intersectionObserver = new IntersectionObserver(([entry]) => {
768
798
  if (entry) {
769
799
  const rect = entry.boundingClientRect;
@@ -782,11 +812,12 @@ var ElementHighlighter = class {
782
812
  this._intersectionObserver.observe(element);
783
813
  }
784
814
  dispose() {
785
- var _a, _b, _c;
815
+ var _a, _b, _c, _d;
786
816
  this._unobserve();
787
817
  (_a = this._cancelScrollTimer) == null ? void 0 : _a.call(this);
788
- (_b = this._window) == null ? void 0 : _b.removeEventListener("scroll", this._onScroll, true);
789
- (_c = this._container) == null ? void 0 : _c.remove();
818
+ (_b = this._cancelAutoHideTimer) == null ? void 0 : _b.call(this);
819
+ (_c = this._window) == null ? void 0 : _c.removeEventListener("scroll", this._onScroll, true);
820
+ (_d = this._container) == null ? void 0 : _d.remove();
790
821
  delete this._element;
791
822
  delete this._container;
792
823
  delete this._window;
@@ -994,6 +1025,7 @@ function getStackTrace() {
994
1025
  var AbleDOM = class {
995
1026
  constructor(win, props = {}) {
996
1027
  __publicField(this, "_win");
1028
+ __publicField(this, "_isDisposed", false);
997
1029
  __publicField(this, "_props");
998
1030
  __publicField(this, "_observer");
999
1031
  __publicField(this, "_clearValidationTimeout");
@@ -1006,8 +1038,17 @@ var AbleDOM = class {
1006
1038
  __publicField(this, "_startFunc");
1007
1039
  __publicField(this, "_isStarted", false);
1008
1040
  __publicField(this, "_issuesUI");
1041
+ __publicField(this, "_elementHighlighter");
1009
1042
  __publicField(this, "_idlePromise");
1010
1043
  __publicField(this, "_idleResolve");
1044
+ __publicField(this, "_currentAnchoredIssues", /* @__PURE__ */ new Map());
1045
+ __publicField(this, "_currentNotAnchoredIssues", []);
1046
+ __publicField(this, "_getHighlighter", () => {
1047
+ if (!this._elementHighlighter && !this._isDisposed) {
1048
+ this._elementHighlighter = new ElementHighlighter(this._win);
1049
+ }
1050
+ return this._elementHighlighter;
1051
+ });
1011
1052
  __publicField(this, "_onFocusIn", (event) => {
1012
1053
  var _a;
1013
1054
  const target = event.target;
@@ -1175,9 +1216,9 @@ var AbleDOM = class {
1175
1216
  }
1176
1217
  }
1177
1218
  _addIssue(rule, issue) {
1178
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1219
+ var _a, _b;
1179
1220
  if (!this._issuesUI) {
1180
- this._issuesUI = new IssuesUI(this._win, {
1221
+ this._issuesUI = new IssuesUI(this._win, this._getHighlighter, {
1181
1222
  bugReport: (_a = this._props) == null ? void 0 : _a.bugReport,
1182
1223
  headless: (_b = this._props) == null ? void 0 : _b.headless
1183
1224
  });
@@ -1203,26 +1244,21 @@ var AbleDOM = class {
1203
1244
  issueUI = new IssueUI(this._win, this, rule, this._issuesUI);
1204
1245
  issues.set(rule, issueUI);
1205
1246
  justUpdate = false;
1206
- (_e = (_d = (_c = this._props) == null ? void 0 : _c.callbacks) == null ? void 0 : _d.onIssueAdded) == null ? void 0 : _e.call(_d, element, rule, issue);
1247
+ this._onIssueAdded(element, rule, issue);
1207
1248
  }
1208
1249
  this._elementsWithIssues.add(element);
1209
1250
  } else {
1210
1251
  issueUI = new IssueUI(this._win, this, rule, this._issuesUI);
1211
1252
  justUpdate = false;
1212
- (_h = (_g = (_f = this._props) == null ? void 0 : _f.callbacks) == null ? void 0 : _g.onIssueAdded) == null ? void 0 : _h.call(_g, null, rule, issue);
1253
+ this._onIssueAdded(null, rule, issue);
1213
1254
  }
1214
1255
  issueUI.update(issue);
1215
- if (justUpdate) {
1216
- (_k = (_j = (_i = this._props) == null ? void 0 : _i.callbacks) == null ? void 0 : _j.onIssueUpdated) == null ? void 0 : _k.call(
1217
- _j,
1218
- rule.anchored && element ? element : null,
1219
- rule,
1220
- issue
1221
- );
1256
+ if (justUpdate && rule.anchored && element) {
1257
+ this._onIssueUpdated(element, rule, issue);
1222
1258
  }
1223
1259
  }
1224
1260
  _removeIssue(element, rule) {
1225
- var _a, _b, _c, _d;
1261
+ var _a;
1226
1262
  if (!rule.anchored) {
1227
1263
  return;
1228
1264
  }
@@ -1234,7 +1270,7 @@ var AbleDOM = class {
1234
1270
  if (issue) {
1235
1271
  issue.dispose();
1236
1272
  issues.delete(rule);
1237
- (_d = (_c = (_b = this._props) == null ? void 0 : _b.callbacks) == null ? void 0 : _c.onIssueRemoved) == null ? void 0 : _d.call(_c, element, rule);
1273
+ this._onIssueRemoved(element, rule);
1238
1274
  }
1239
1275
  if (issues.size === 0) {
1240
1276
  this._elementsWithIssues.delete(element);
@@ -1320,6 +1356,42 @@ var AbleDOM = class {
1320
1356
  this._dependantIdsByElement.set(element, dependsOnIds);
1321
1357
  }
1322
1358
  }
1359
+ _updateCurrentAnchoredIssues(element, rule, issue) {
1360
+ let issuesByElement = this._currentAnchoredIssues.get(element);
1361
+ if (!issuesByElement && issue) {
1362
+ issuesByElement = /* @__PURE__ */ new Map();
1363
+ this._currentAnchoredIssues.set(element, issuesByElement);
1364
+ }
1365
+ if (issuesByElement) {
1366
+ if (issue) {
1367
+ issuesByElement.set(rule, issue);
1368
+ } else {
1369
+ issuesByElement.delete(rule);
1370
+ if (issuesByElement.size === 0) {
1371
+ this._currentAnchoredIssues.delete(element);
1372
+ }
1373
+ }
1374
+ }
1375
+ }
1376
+ _onIssueAdded(element, rule, issue) {
1377
+ var _a, _b, _c;
1378
+ if (element) {
1379
+ this._updateCurrentAnchoredIssues(element, rule, issue);
1380
+ } else {
1381
+ this._currentNotAnchoredIssues.push(issue);
1382
+ }
1383
+ (_c = (_b = (_a = this._props) == null ? void 0 : _a.callbacks) == null ? void 0 : _b.onIssueAdded) == null ? void 0 : _c.call(_b, element, rule, issue);
1384
+ }
1385
+ _onIssueUpdated(element, rule, issue) {
1386
+ var _a, _b, _c;
1387
+ this._updateCurrentAnchoredIssues(element, rule, issue);
1388
+ (_c = (_b = (_a = this._props) == null ? void 0 : _a.callbacks) == null ? void 0 : _b.onIssueUpdated) == null ? void 0 : _c.call(_b, element, rule, issue);
1389
+ }
1390
+ _onIssueRemoved(element, rule) {
1391
+ var _a, _b, _c;
1392
+ this._updateCurrentAnchoredIssues(element, rule, null);
1393
+ (_c = (_b = (_a = this._props) == null ? void 0 : _a.callbacks) == null ? void 0 : _b.onIssueRemoved) == null ? void 0 : _c.call(_b, element, rule);
1394
+ }
1323
1395
  _remove(elements) {
1324
1396
  elements.forEach((element) => {
1325
1397
  var _a, _b;
@@ -1327,21 +1399,42 @@ var AbleDOM = class {
1327
1399
  rules.forEach((rule) => this._removeIssue(element, rule));
1328
1400
  });
1329
1401
  }
1402
+ _getCurrentIssues() {
1403
+ const issues = this._currentNotAnchoredIssues.slice(0);
1404
+ this._currentAnchoredIssues.forEach((issueByRule) => {
1405
+ issueByRule.forEach((issue) => {
1406
+ issues.push(issue);
1407
+ });
1408
+ });
1409
+ return issues;
1410
+ }
1330
1411
  idle() {
1331
1412
  if (!this._clearValidationTimeout) {
1332
- return Promise.resolve();
1413
+ return Promise.resolve(this._getCurrentIssues());
1333
1414
  }
1334
1415
  if (!this._idlePromise) {
1335
1416
  this._idlePromise = new Promise((resolve) => {
1336
1417
  this._idleResolve = () => {
1337
1418
  delete this._idlePromise;
1338
1419
  delete this._idleResolve;
1339
- resolve();
1420
+ resolve(this._getCurrentIssues());
1340
1421
  };
1341
1422
  });
1342
1423
  }
1343
1424
  return this._idlePromise;
1344
1425
  }
1426
+ clearCurrentIssues(anchored = true, notAnchored = true) {
1427
+ if (anchored) {
1428
+ this._currentAnchoredIssues.clear();
1429
+ }
1430
+ if (notAnchored) {
1431
+ this._currentNotAnchoredIssues = [];
1432
+ }
1433
+ }
1434
+ highlightElement(element, scrollIntoView, autoHideTime) {
1435
+ var _a;
1436
+ (_a = this._getHighlighter()) == null ? void 0 : _a.highlight(element, scrollIntoView, autoHideTime);
1437
+ }
1345
1438
  addRule(rule) {
1346
1439
  this._rules.push(rule);
1347
1440
  }
@@ -1368,6 +1461,7 @@ var AbleDOM = class {
1368
1461
  }
1369
1462
  dispose() {
1370
1463
  var _a, _b, _c, _d;
1464
+ this._isDisposed = true;
1371
1465
  const doc = this._win.document;
1372
1466
  doc.addEventListener("focusin", this._onFocusIn, true);
1373
1467
  doc.addEventListener("focusout", this._onFocusOut, true);
@@ -1376,6 +1470,7 @@ var AbleDOM = class {
1376
1470
  this._dependantIdsByElement.clear();
1377
1471
  this._elementsDependingOnId.clear();
1378
1472
  this._idByElement.clear();
1473
+ this.clearCurrentIssues();
1379
1474
  (_a = this._issuesUI) == null ? void 0 : _a.dispose();
1380
1475
  delete this._issuesUI;
1381
1476
  (_b = this._clearValidationTimeout) == null ? void 0 : _b.call(this);
@@ -1580,6 +1675,147 @@ var FocusableElementLabelRule = class extends ValidationRule {
1580
1675
  }
1581
1676
  };
1582
1677
 
1678
+ // src/rules/contrast.ts
1679
+ function hexToRgb(hex) {
1680
+ hex = hex.replace(/^#/, "");
1681
+ if (hex.length === 3) {
1682
+ hex = hex.split("").map((x) => x + x).join("");
1683
+ }
1684
+ if (hex.length !== 6) {
1685
+ return null;
1686
+ }
1687
+ const num = parseInt(hex, 16);
1688
+ return [num >> 16 & 255, num >> 8 & 255, num & 255];
1689
+ }
1690
+ function parseColor(color) {
1691
+ color = color.trim();
1692
+ if (color.startsWith("#")) {
1693
+ return hexToRgb(color);
1694
+ }
1695
+ const rgbMatch = color.match(
1696
+ /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)$/
1697
+ );
1698
+ if (rgbMatch) {
1699
+ return [
1700
+ parseInt(rgbMatch[1], 10),
1701
+ parseInt(rgbMatch[2], 10),
1702
+ parseInt(rgbMatch[3], 10)
1703
+ ];
1704
+ }
1705
+ return null;
1706
+ }
1707
+ function luminance([r, g, b]) {
1708
+ const a = [r, g, b].map((v) => {
1709
+ v /= 255;
1710
+ return v <= 0.03928 ? v / 12.92 : Math.pow((v + 0.055) / 1.055, 2.4);
1711
+ });
1712
+ return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
1713
+ }
1714
+ function contrastRatio(l1, l2) {
1715
+ return (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
1716
+ }
1717
+ function isTransparent(color) {
1718
+ if (!color) {
1719
+ return true;
1720
+ }
1721
+ color = color.trim();
1722
+ if (color === "transparent" || color === "rgba(0, 0, 0, 0)") {
1723
+ return true;
1724
+ }
1725
+ const rgbaMatch = color.match(/^rgba?\(\d+,\s*\d+,\s*\d+,\s*([\d.]+)\)$/);
1726
+ if (rgbaMatch && parseFloat(rgbaMatch[1]) === 0) {
1727
+ return true;
1728
+ }
1729
+ return false;
1730
+ }
1731
+ var ContrastRule = class extends ValidationRule {
1732
+ constructor() {
1733
+ super(...arguments);
1734
+ __publicField(this, "type", 1 /* Error */);
1735
+ __publicField(this, "name", "ContrastRule");
1736
+ __publicField(this, "anchored", true);
1737
+ }
1738
+ accept(element) {
1739
+ if (!isElementVisible(element)) {
1740
+ return false;
1741
+ }
1742
+ const hasDirectTextContent = Array.from(element.childNodes).some((node) => {
1743
+ var _a;
1744
+ if (node.nodeType === Node.TEXT_NODE) {
1745
+ const text = (_a = node.textContent) == null ? void 0 : _a.trim();
1746
+ return text && text.length > 0;
1747
+ }
1748
+ return false;
1749
+ });
1750
+ return hasDirectTextContent;
1751
+ }
1752
+ validate(element) {
1753
+ const win = this.window;
1754
+ if (!win) {
1755
+ return null;
1756
+ }
1757
+ const style = win.getComputedStyle(element);
1758
+ const fg = parseColor(style.color);
1759
+ if (!fg) {
1760
+ return null;
1761
+ }
1762
+ const hasChildWithDifferentColor = Array.from(element.children).some(
1763
+ (child) => {
1764
+ var _a;
1765
+ if (child instanceof HTMLElement && ((_a = child.textContent) == null ? void 0 : _a.trim())) {
1766
+ const childStyle = win.getComputedStyle(child);
1767
+ const childColor = parseColor(childStyle.color);
1768
+ if (childColor && (childColor[0] !== fg[0] || childColor[1] !== fg[1] || childColor[2] !== fg[2])) {
1769
+ return true;
1770
+ }
1771
+ }
1772
+ return false;
1773
+ }
1774
+ );
1775
+ if (hasChildWithDifferentColor) {
1776
+ return null;
1777
+ }
1778
+ let bg = null;
1779
+ let el = element;
1780
+ let depth = 0;
1781
+ const maxDepth = 50;
1782
+ while (el && depth < maxDepth) {
1783
+ const bgColor = win.getComputedStyle(el).backgroundColor;
1784
+ if (!isTransparent(bgColor)) {
1785
+ const parsedBg = parseColor(bgColor);
1786
+ if (parsedBg) {
1787
+ bg = parsedBg;
1788
+ break;
1789
+ }
1790
+ }
1791
+ el = el.parentElement;
1792
+ depth++;
1793
+ }
1794
+ if (!bg) {
1795
+ bg = [255, 255, 255];
1796
+ }
1797
+ const l1 = luminance(fg);
1798
+ const l2 = luminance(bg);
1799
+ const ratio = contrastRatio(l1, l2);
1800
+ const fontSize = parseFloat(style.fontSize);
1801
+ const fontWeight = style.fontWeight;
1802
+ const isBold = fontWeight === "bold" || fontWeight === "bolder" || parseInt(fontWeight, 10) >= 700;
1803
+ const isLarge = fontSize >= 24 || fontSize >= 18.66 && isBold;
1804
+ const minRatio = isLarge ? 3 : 4.5;
1805
+ if (ratio < minRatio) {
1806
+ return {
1807
+ issue: {
1808
+ id: "contrast",
1809
+ message: `Text contrast ratio is ${ratio.toFixed(2)}:1, which is below the minimum of ${minRatio}:1 (text: rgb(${fg.join(", ")}), background: rgb(${bg.join(", ")})) on ${element.tagName}`,
1810
+ element,
1811
+ help: "https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html"
1812
+ }
1813
+ };
1814
+ }
1815
+ return null;
1816
+ }
1817
+ };
1818
+
1583
1819
  // src/rules/existingid.ts
1584
1820
  var ExistingIdRule = class extends ValidationRule {
1585
1821
  constructor() {
@@ -1830,6 +2066,7 @@ export {
1830
2066
  AbleDOM,
1831
2067
  AtomicRule,
1832
2068
  BadFocusRule,
2069
+ ContrastRule,
1833
2070
  CustomNotifyRule,
1834
2071
  ExistingIdRule,
1835
2072
  FindElementRule,