@skippr/live-agent-sdk 0.103.0 → 0.105.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/README.md +0 -1
- package/dist/esm/lib-exports.js +111 -8
- package/dist/skippr-sdk.js +128 -128
- package/dist/types/capture/a11yUtils.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -56,7 +56,6 @@ The widget opens with a picker of your active modules — the user chooses which
|
|
|
56
56
|
|
|
57
57
|
```tsx
|
|
58
58
|
import { LiveAgent } from '@skippr/live-agent-sdk';
|
|
59
|
-
import '@skippr/live-agent-sdk/styles';
|
|
60
59
|
|
|
61
60
|
function App() {
|
|
62
61
|
return <LiveAgent appKey="pk_live_your_key" />;
|
package/dist/esm/lib-exports.js
CHANGED
|
@@ -5089,6 +5089,21 @@ var ROLE_BY_TAG = {
|
|
|
5089
5089
|
embed: "embed",
|
|
5090
5090
|
object: "object"
|
|
5091
5091
|
};
|
|
5092
|
+
var REACT_PROPS_KEY_PREFIX = "__reactProps$";
|
|
5093
|
+
var POINTER_HANDLER_PROPS = ["onClick", "onMouseDown", "onMouseUp", "onPointerDown"];
|
|
5094
|
+
function hasFrameworkPointerHandler(element) {
|
|
5095
|
+
try {
|
|
5096
|
+
const propsKey = Object.keys(element).find((key) => key.startsWith(REACT_PROPS_KEY_PREFIX));
|
|
5097
|
+
if (!propsKey)
|
|
5098
|
+
return false;
|
|
5099
|
+
const props = element[propsKey];
|
|
5100
|
+
if (!props || typeof props !== "object")
|
|
5101
|
+
return false;
|
|
5102
|
+
return POINTER_HANDLER_PROPS.some((handler) => typeof props[handler] === "function");
|
|
5103
|
+
} catch {
|
|
5104
|
+
return false;
|
|
5105
|
+
}
|
|
5106
|
+
}
|
|
5092
5107
|
function inferRole(element) {
|
|
5093
5108
|
const explicitRole = element.getAttribute("role");
|
|
5094
5109
|
if (explicitRole)
|
|
@@ -5246,6 +5261,56 @@ function isCursorClickable(element, rect) {
|
|
|
5246
5261
|
return false;
|
|
5247
5262
|
return true;
|
|
5248
5263
|
}
|
|
5264
|
+
var KEYSTROKE_TRAP_MAX_EDGE_PX = 8;
|
|
5265
|
+
function isKeystrokeTrap(rect) {
|
|
5266
|
+
return rect.width < KEYSTROKE_TRAP_MAX_EDGE_PX || rect.height < KEYSTROKE_TRAP_MAX_EDGE_PX;
|
|
5267
|
+
}
|
|
5268
|
+
var CONTAINED_CONTROL_SELECTOR = "input, select, textarea, button, a[href]";
|
|
5269
|
+
function isLayoutContainer(element) {
|
|
5270
|
+
if (element.querySelectorAll(CONTAINED_CONTROL_SELECTOR).length > 1)
|
|
5271
|
+
return true;
|
|
5272
|
+
return element.querySelector("h1, h2, h3, h4, h5, h6") !== null;
|
|
5273
|
+
}
|
|
5274
|
+
var MENU_MIN_OPTION_ROWS = 2;
|
|
5275
|
+
function optionRowsOf(element) {
|
|
5276
|
+
const children = Array.from(element.children);
|
|
5277
|
+
if (children.length < MENU_MIN_OPTION_ROWS)
|
|
5278
|
+
return [];
|
|
5279
|
+
const rects = children.map((child) => child.getBoundingClientRect());
|
|
5280
|
+
const everyChildIsALabelledLeaf = children.every((child, index2) => child.children.length === 0 && normalizeText(child.textContent).length > 0 && !isVisuallyEmpty(rects[index2]));
|
|
5281
|
+
return everyChildIsALabelledLeaf && areStackedVertically(rects) ? children : [];
|
|
5282
|
+
}
|
|
5283
|
+
function isVisuallyEmpty(rect) {
|
|
5284
|
+
return rect.width <= 0 || rect.height <= 0;
|
|
5285
|
+
}
|
|
5286
|
+
function areStackedVertically(rects) {
|
|
5287
|
+
for (let index2 = 1;index2 < rects.length; index2++) {
|
|
5288
|
+
const previous = rects[index2 - 1];
|
|
5289
|
+
const current = rects[index2];
|
|
5290
|
+
if (current.top < previous.bottom)
|
|
5291
|
+
return false;
|
|
5292
|
+
}
|
|
5293
|
+
return true;
|
|
5294
|
+
}
|
|
5295
|
+
var WIDGET_NESTING_SEARCH_DEPTH = 4;
|
|
5296
|
+
function isInsideHandlerOwningWidget(element) {
|
|
5297
|
+
let ancestor = element.parentElement;
|
|
5298
|
+
for (let depth = 0;depth < WIDGET_NESTING_SEARCH_DEPTH && ancestor; depth++) {
|
|
5299
|
+
if (hasFrameworkPointerHandler(ancestor) && !isLayoutContainer(ancestor))
|
|
5300
|
+
return true;
|
|
5301
|
+
ancestor = ancestor.parentElement;
|
|
5302
|
+
}
|
|
5303
|
+
return false;
|
|
5304
|
+
}
|
|
5305
|
+
function isFrameworkClickable(element, rect) {
|
|
5306
|
+
if (!intersectsViewport(rect, window.innerWidth, window.innerHeight))
|
|
5307
|
+
return false;
|
|
5308
|
+
if (!hasFrameworkPointerHandler(element))
|
|
5309
|
+
return false;
|
|
5310
|
+
if (isLayoutContainer(element))
|
|
5311
|
+
return false;
|
|
5312
|
+
return !isInsideHandlerOwningWidget(element);
|
|
5313
|
+
}
|
|
5249
5314
|
function isBlindRegion(role) {
|
|
5250
5315
|
return role === "video" || role === "iframe" || role === "canvas" || role === "audio" || role === "embed" || role === "object";
|
|
5251
5316
|
}
|
|
@@ -5570,6 +5635,19 @@ function collectTableRowAsSingleEntry(row, depth, rect, entries) {
|
|
|
5570
5635
|
}
|
|
5571
5636
|
return true;
|
|
5572
5637
|
}
|
|
5638
|
+
function collectOptionRows(rows, depth, entries) {
|
|
5639
|
+
for (const row of rows) {
|
|
5640
|
+
const rect = row.getBoundingClientRect();
|
|
5641
|
+
entries.push({
|
|
5642
|
+
depth,
|
|
5643
|
+
role: "option",
|
|
5644
|
+
name: normalizeText(row.textContent).slice(0, NAME_MAX_CHARS),
|
|
5645
|
+
ref: ensureStableRef(row),
|
|
5646
|
+
attrs: [],
|
|
5647
|
+
area: rect.width * rect.height
|
|
5648
|
+
});
|
|
5649
|
+
}
|
|
5650
|
+
}
|
|
5573
5651
|
function walkAndCollect(element, depth, entries, suppressTextLeaves = false) {
|
|
5574
5652
|
if (shouldSkipSubtree(element))
|
|
5575
5653
|
return;
|
|
@@ -5580,7 +5658,18 @@ function walkAndCollect(element, depth, entries, suppressTextLeaves = false) {
|
|
|
5580
5658
|
if (collectTableRowAsSingleEntry(element, depth, rect, entries))
|
|
5581
5659
|
return;
|
|
5582
5660
|
}
|
|
5583
|
-
|
|
5661
|
+
if (element.tagName === "INPUT" && isKeystrokeTrap(rect))
|
|
5662
|
+
return;
|
|
5663
|
+
const markupRole = inferRole(element);
|
|
5664
|
+
const isFrameworkControl = markupRole === null && isFrameworkClickable(element, rect);
|
|
5665
|
+
if (isFrameworkControl && isVisible(element, rect)) {
|
|
5666
|
+
const optionRows = optionRowsOf(element);
|
|
5667
|
+
if (optionRows.length > 0) {
|
|
5668
|
+
collectOptionRows(optionRows, depth, entries);
|
|
5669
|
+
return;
|
|
5670
|
+
}
|
|
5671
|
+
}
|
|
5672
|
+
const role = markupRole ?? (isCursorClickable(element, rect) || isFrameworkControl ? "button" : null);
|
|
5584
5673
|
const isVisibleAndEmittable = role !== null && isVisible(element, rect) && shouldEmitElement(element, role);
|
|
5585
5674
|
let childDepth = depth;
|
|
5586
5675
|
let childSuppressTextLeaves = suppressTextLeaves;
|
|
@@ -7219,6 +7308,7 @@ function performSelect(element, value) {
|
|
|
7219
7308
|
element.click();
|
|
7220
7309
|
}
|
|
7221
7310
|
}
|
|
7311
|
+
var NATIVELY_ACTIVATABLE_SELECTOR = "a[href], button, input, select, textarea, label, summary";
|
|
7222
7312
|
var INTERACTIVE_SELECTOR = 'button, a[href], [role="button"], [role="link"], input, select, [onclick]';
|
|
7223
7313
|
function resolveClickTarget(element) {
|
|
7224
7314
|
if (element.matches(INTERACTIVE_SELECTOR))
|
|
@@ -7230,23 +7320,36 @@ function resolveClickTarget(element) {
|
|
|
7230
7320
|
const onlyDescendant = descendants.length === 1 ? descendants[0] : null;
|
|
7231
7321
|
return onlyDescendant ?? element;
|
|
7232
7322
|
}
|
|
7323
|
+
function deepestElementAt(fallback, clientX, clientY) {
|
|
7324
|
+
const topmost = document.elementFromPoint(clientX, clientY);
|
|
7325
|
+
if (!(topmost instanceof HTMLElement))
|
|
7326
|
+
return fallback;
|
|
7327
|
+
if (!fallback.contains(topmost))
|
|
7328
|
+
return fallback;
|
|
7329
|
+
return isActionBlocked(topmost) ? fallback : topmost;
|
|
7330
|
+
}
|
|
7233
7331
|
function performClick(element) {
|
|
7234
7332
|
const rect = element.getBoundingClientRect();
|
|
7235
7333
|
const clientX = rect.left + rect.width / 2;
|
|
7236
7334
|
const clientY = rect.top + rect.height / 2;
|
|
7237
7335
|
const base = { bubbles: true, cancelable: true, composed: true, clientX, clientY, button: 0 };
|
|
7238
|
-
|
|
7336
|
+
const hitTarget = deepestElementAt(element, clientX, clientY);
|
|
7337
|
+
if (typeof hitTarget.focus === "function") {
|
|
7239
7338
|
try {
|
|
7240
|
-
|
|
7339
|
+
hitTarget.focus({ preventScroll: true });
|
|
7241
7340
|
} catch {}
|
|
7242
7341
|
}
|
|
7243
7342
|
try {
|
|
7244
|
-
|
|
7245
|
-
|
|
7246
|
-
|
|
7247
|
-
|
|
7343
|
+
hitTarget.dispatchEvent(new PointerEvent("pointerdown", { ...base, pointerId: 1, isPrimary: true }));
|
|
7344
|
+
hitTarget.dispatchEvent(new MouseEvent("mousedown", base));
|
|
7345
|
+
hitTarget.dispatchEvent(new PointerEvent("pointerup", { ...base, pointerId: 1, isPrimary: true }));
|
|
7346
|
+
hitTarget.dispatchEvent(new MouseEvent("mouseup", base));
|
|
7347
|
+
if (hitTarget.matches(NATIVELY_ACTIVATABLE_SELECTOR)) {
|
|
7348
|
+
hitTarget.click();
|
|
7349
|
+
} else {
|
|
7350
|
+
hitTarget.dispatchEvent(new MouseEvent("click", base));
|
|
7351
|
+
}
|
|
7248
7352
|
} catch {}
|
|
7249
|
-
element.click();
|
|
7250
7353
|
}
|
|
7251
7354
|
function performHover(element) {
|
|
7252
7355
|
const rect = element.getBoundingClientRect();
|