sliccy 2.4.0 → 2.5.1
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/ui/assets/{anthropic-BCyIsIaq.js → anthropic-DghSut-C.js} +7 -7
- package/dist/ui/assets/azure-openai-responses-Dnfg8pba.js +1 -0
- package/dist/ui/assets/{dist-DEO1hNOZ2.js → dist-BNEtmCAc2.js} +2 -2
- package/dist/ui/assets/{dist-DhTZTSy5.js → dist-BqCqxkrA.js} +1 -1
- package/dist/ui/assets/{dist-DJK5C7yO.js → dist-CxsgJFgV.js} +1 -1
- package/dist/ui/assets/{dist-CYRMRTTO.js → dist-DPNMKo07.js} +1 -1
- package/dist/ui/assets/{dist-CWhXzJlW.js → dist-Sngeewv4.js} +1 -1
- package/dist/ui/assets/{es-6oFxNVOv.js → es-BgWSe85_.js} +1 -1
- package/dist/ui/assets/google-_zHlLVt5.js +1 -0
- package/dist/ui/assets/{google-gemini-cli-CLKrNaN2.js → google-gemini-cli-CBH9v3m0.js} +1 -1
- package/dist/ui/assets/{google-shared-Dm8eVEiI.js → google-shared-jyMmIrwc.js} +1 -1
- package/dist/ui/assets/{google-vertex-DO4sjUxJ.js → google-vertex-BrN3Tz3e.js} +1 -1
- package/dist/ui/assets/index-DP3Ol2R4.js +15796 -0
- package/dist/ui/assets/{magick-wasm-DA8eLvGf.js → magick-wasm-BtLTRPKb.js} +1 -1
- package/dist/ui/assets/{mistral-DZrYPR3L.js → mistral-DuNLtbqK.js} +2 -2
- package/dist/ui/assets/{openai-codex-responses-BtjFHbjN.js → openai-codex-responses-h0SgBqnQ.js} +1 -1
- package/dist/ui/assets/openai-completions-BPuxYxr3.js +5 -0
- package/dist/ui/assets/openai-responses-DZjAbLKt.js +1 -0
- package/dist/ui/assets/{openai-responses-shared-D0nL21GA.js → openai-responses-shared-CrweEi92.js} +1 -1
- package/dist/ui/assets/{provider-settings-BNHO2Tcv.js → provider-settings-CTKuckn7.js} +4 -4
- package/dist/ui/assets/{pyodide-3PMN6X39.js → pyodide-JXDzDQlX.js} +2 -2
- package/dist/ui/assets/{skills-DBBQyHko.js → skills-CY7rXZij.js} +1 -1
- package/dist/ui/assets/{slicc-editor-DmlPglrQ.js → slicc-editor-BXeXUUnd.js} +2 -2
- package/dist/ui/assets/{sql-wasm-yST8pDy6.js → sql-wasm-DsCCg8Gn.js} +1 -1
- package/dist/ui/index.html +10 -15
- package/dist/ui/packages/webapp/index.html +10 -15
- package/package.json +2 -2
- package/dist/ui/assets/azure-openai-responses-CSjq2stN.js +0 -1
- package/dist/ui/assets/cdp-CsCvDwW3.js +0 -880
- package/dist/ui/assets/cost-command-DBzah9S9.js +0 -1584
- package/dist/ui/assets/env-api-keys-7VVTY3n7.js +0 -1
- package/dist/ui/assets/fs-CFxFn45v.js +0 -3
- package/dist/ui/assets/google-CHyDZd_T.js +0 -1
- package/dist/ui/assets/index-BxvCGJ1l.js +0 -13332
- package/dist/ui/assets/json-parse-Dn8fsQhn.js +0 -2
- package/dist/ui/assets/openai-completions-CvOr92bY.js +0 -5
- package/dist/ui/assets/openai-responses-D1b_e2py.js +0 -1
- package/dist/ui/assets/tray-follower-status-BlQSlF6m.js +0 -1
- /package/dist/ui/assets/{__vite-browser-external-BC516C8G.js → __vite-browser-external-BotBUAC3.js} +0 -0
- /package/dist/ui/assets/{addon-fit-CnTv21Qe.js → addon-fit-B0aHsvmX.js} +0 -0
- /package/dist/ui/assets/{bsh-watchdog-BXTi5bzs.js → bsh-watchdog-DYfdvOrR.js} +0 -0
- /package/dist/ui/assets/{chat-fixture-Nts2sMME.js → chat-fixture-BWvups7M.js} +0 -0
- /package/dist/ui/assets/{constants-DdIXxN9e.js → constants-BnzYaC4L.js} +0 -0
- /package/dist/ui/assets/{db-CmHnV4DS.js → db-ybNEUfR8.js} +0 -0
- /package/dist/ui/assets/{dist-B3YOuOiy.js → dist-CPYmBmyZ.js} +0 -0
- /package/dist/ui/assets/{dist-C43FKPek.js → dist-Ct5XR8EU.js} +0 -0
- /package/dist/ui/assets/{github-copilot-headers-BNWb_OCE.js → github-copilot-headers-BxUvy78-.js} +0 -0
- /package/dist/ui/assets/{hash-CsofV07h.js → hash-BwzabXYv.js} +0 -0
- /package/dist/ui/assets/{headers-Dr-OH1-5.js → headers-BCPSYYop.js} +0 -0
- /package/dist/ui/assets/{lick-manager-proxy-CogaR9kt.js → lick-manager-proxy-BF0GrOv_.js} +0 -0
- /package/dist/ui/assets/{oauth-service-CfTUWB9P.js → oauth-service-8Xax8Fjw.js} +0 -0
- /package/dist/ui/assets/{offscreen-client-BlWuVmPl.js → offscreen-client-DGObT_O6.js} +0 -0
- /package/dist/ui/assets/{openai-CQsomflW.js → openai-CuiHR4mv.js} +0 -0
- /package/dist/ui/assets/{path-utils-CNNVZ3-O.js → path-utils-CgbXfwyO.js} +0 -0
- /package/dist/ui/assets/{pdfjs-DEEfCfSi.js → pdfjs-C_fzykJW.js} +0 -0
- /package/dist/ui/assets/{sanitize-unicode-Dw-JFaZE.js → sanitize-unicode-ncMKN_SD.js} +0 -0
- /package/dist/ui/assets/{secret-masking-Bg1u5YcF.js → secret-masking-CXZkZ8rX.js} +0 -0
- /package/dist/ui/assets/{simple-options-GPCv4BUJ.js → simple-options-DEbfD_Ko.js} +0 -0
- /package/dist/ui/assets/{src-CNgmwAf5.js → src-Cu5WM_BM.js} +0 -0
- /package/dist/ui/assets/{xterm-CAZt1iF4.js → xterm-D5M9QCcR.js} +0 -0
|
@@ -1,880 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/magick-wasm-DA8eLvGf.js","assets/chunk-jRWAZmH_.js","assets/preload-helper-D4M6sveU.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{r as e}from"./chunk-jRWAZmH_.js";import{t}from"./logger-B-No_qN_.js";import{t as n}from"./preload-helper-D4M6sveU.js";var r=t(`cdp`),i=class{ws=null;nextId=1;pending=new Map;listeners=new Map;_state=`disconnected`;get state(){return this._state}async connect(e){if(this._state!==`disconnected`)throw Error(`Cannot connect: state is ${this._state}`);if(!e?.url)throw Error(`CDPClient.connect() requires a WebSocket URL`);let{url:t,timeout:n=5e3}=e;return this._state=`connecting`,new Promise((e,i)=>{let a=setTimeout(()=>{this.cleanup(),i(Error(`CDP connection timed out after ${n}ms`))},n);try{this.ws=new WebSocket(t)}catch(e){clearTimeout(a),this._state=`disconnected`,i(e);return}this.ws.onopen=()=>{clearTimeout(a),this._state=`connected`,r.info(`Connected`,{url:t}),e()},this.ws.onerror=e=>{clearTimeout(a),this._state===`connecting`&&(r.error(`Connection failed`,{url:t}),this.cleanup(),i(Error(`CDP WebSocket connection failed`)))},this.ws.onmessage=e=>{this.handleMessage(e.data)},this.ws.onclose=()=>{this.handleClose()}})}disconnect(){this.ws&&(this.ws.onclose=null,this.ws.close()),this.cleanup(),r.info(`Disconnected`)}async send(e,t,n,i=3e4){if(this._state!==`connected`||!this.ws)throw Error(`CDP client is not connected`);let a=this.nextId++,o={id:a,method:e};return t&&(o.params=t),n&&(o.sessionId=n),r.debug(`Send`,{method:e,id:a,sessionId:n}),new Promise((t,n)=>{let r=setTimeout(()=>{this.pending.delete(a),n(Error(`CDP command timed out after ${i}ms: ${e}`))},i);this.pending.set(a,{resolve:e=>{clearTimeout(r),t(e)},reject:e=>{clearTimeout(r),n(e)}}),this.ws.send(JSON.stringify(o))})}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t=3e4){return new Promise((n,r)=>{let i=setTimeout(()=>{this.off(e,a),r(Error(`Timed out waiting for event: ${e}`))},t),a=t=>{clearTimeout(i),this.off(e,a),n(t)};this.on(e,a)})}handleMessage(e){let t;try{t=JSON.parse(e)}catch{return}if(`id`in t&&typeof t.id==`number`){let e=t;r.debug(`Response`,{id:e.id,hasError:!!e.error});let n=this.pending.get(e.id);n&&(this.pending.delete(e.id),e.error?(r.error(`Command error`,{id:e.id,code:e.error.code,message:e.error.message}),n.reject(Error(`CDP error: ${e.error.message} (${e.error.code})`))):n.resolve(e.result??{}));return}if(`method`in t){let e=t;r.debug(`Event`,{method:e.method,sessionId:e.sessionId});let n=this.listeners.get(e.method);if(n){let t=e.sessionId?{...e.params,sessionId:e.sessionId}:e.params??{};for(let e of n)try{e(t)}catch{}}}}handleClose(){r.error(`Connection closed unexpectedly`,{pendingCommands:this.pending.size});for(let[,e]of this.pending)e.reject(Error(`CDP connection closed`));this.cleanup()}cleanup(){this.ws=null,this._state=`disconnected`,this.pending.clear()}};function a(e,t=``){if(e==null)return t;if(typeof e==`string`)return e;if(typeof e==`number`||typeof e==`boolean`||typeof e==`bigint`)return String(e);try{return JSON.stringify(e)??t}catch{return String(e)}}var o=`(function() {
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
// ===== DOM Utilities =====
|
|
6
|
-
|
|
7
|
-
function parentElementOrShadowHost(element) {
|
|
8
|
-
if (element.parentElement) return element.parentElement;
|
|
9
|
-
if (!element.parentNode) return undefined;
|
|
10
|
-
if (element.parentNode.nodeType === 11 && element.parentNode.host)
|
|
11
|
-
return element.parentNode.host;
|
|
12
|
-
return undefined;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function enclosingShadowRootOrDocument(element) {
|
|
16
|
-
var node = element;
|
|
17
|
-
while (node.parentNode) node = node.parentNode;
|
|
18
|
-
if (node.nodeType === 11 || node.nodeType === 9) return node;
|
|
19
|
-
return undefined;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function closestCrossShadow(element, css) {
|
|
23
|
-
while (element) {
|
|
24
|
-
var closest = element.closest(css);
|
|
25
|
-
if (closest) return closest;
|
|
26
|
-
var parent = element;
|
|
27
|
-
while (parent.parentElement) parent = parent.parentElement;
|
|
28
|
-
element = parentElementOrShadowHost(parent);
|
|
29
|
-
}
|
|
30
|
-
return undefined;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function elementSafeTagName(element) {
|
|
34
|
-
var tagName = element.tagName;
|
|
35
|
-
if (typeof tagName === 'string') return tagName.toUpperCase();
|
|
36
|
-
if (element instanceof HTMLFormElement) return 'FORM';
|
|
37
|
-
return element.tagName.toUpperCase();
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
function getComputedStyleCached(element, pseudo) {
|
|
41
|
-
if (!element.ownerDocument || !element.ownerDocument.defaultView) return undefined;
|
|
42
|
-
return element.ownerDocument.defaultView.getComputedStyle(element, pseudo || null);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isElementStyleVisibilityVisible(element, style) {
|
|
46
|
-
style = style || getComputedStyleCached(element);
|
|
47
|
-
if (!style) return true;
|
|
48
|
-
if (typeof element.checkVisibility === 'function') {
|
|
49
|
-
if (!element.checkVisibility()) return false;
|
|
50
|
-
} else {
|
|
51
|
-
var detailsOrSummary = element.closest('details,summary');
|
|
52
|
-
if (detailsOrSummary !== element && detailsOrSummary &&
|
|
53
|
-
detailsOrSummary.nodeName === 'DETAILS' && !detailsOrSummary.open)
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
if (style.visibility !== 'visible') return false;
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
function isVisibleTextNode(node) {
|
|
61
|
-
var range = node.ownerDocument.createRange();
|
|
62
|
-
range.selectNode(node);
|
|
63
|
-
var rect = range.getBoundingClientRect();
|
|
64
|
-
return rect.width > 0 && rect.height > 0;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function isElementVisible(element) {
|
|
68
|
-
var style = getComputedStyleCached(element);
|
|
69
|
-
if (!style) return true;
|
|
70
|
-
if (style.display === 'contents') {
|
|
71
|
-
for (var child = element.firstChild; child; child = child.nextSibling) {
|
|
72
|
-
if (child.nodeType === 1 && isElementVisible(child)) return true;
|
|
73
|
-
if (child.nodeType === 3 && isVisibleTextNode(child)) return true;
|
|
74
|
-
}
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
if (!isElementStyleVisibilityVisible(element, style)) return false;
|
|
78
|
-
var rect = element.getBoundingClientRect();
|
|
79
|
-
return rect.width > 0 && rect.height > 0;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// ===== ARIA Role Utilities =====
|
|
83
|
-
|
|
84
|
-
var kAncestorPreventingLandmark = 'article:not([role]), aside:not([role]), main:not([role]), nav:not([role]), section:not([role]), [role=article], [role=complementary], [role=main], [role=navigation], [role=region]';
|
|
85
|
-
|
|
86
|
-
function hasExplicitAccessibleName(e) {
|
|
87
|
-
return e.hasAttribute('aria-label') || e.hasAttribute('aria-labelledby');
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
var kGlobalAriaAttributes = [
|
|
91
|
-
'aria-atomic', 'aria-busy', 'aria-controls', 'aria-current',
|
|
92
|
-
'aria-describedby', 'aria-details', 'aria-dropeffect', 'aria-flowto',
|
|
93
|
-
'aria-grabbed', 'aria-hidden', 'aria-keyshortcuts', 'aria-label',
|
|
94
|
-
'aria-labelledby', 'aria-live', 'aria-owns', 'aria-relevant',
|
|
95
|
-
'aria-roledescription'
|
|
96
|
-
];
|
|
97
|
-
|
|
98
|
-
function hasGlobalAriaAttribute(element) {
|
|
99
|
-
for (var i = 0; i < kGlobalAriaAttributes.length; i++) {
|
|
100
|
-
if (element.hasAttribute(kGlobalAriaAttributes[i])) return true;
|
|
101
|
-
}
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function hasTabIndex(element) {
|
|
106
|
-
return !Number.isNaN(Number(String(element.getAttribute('tabindex'))));
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function isNativelyDisabled(element) {
|
|
110
|
-
var isNativeFormControl = ['BUTTON','INPUT','SELECT','TEXTAREA','OPTION','OPTGROUP'].indexOf(elementSafeTagName(element)) >= 0;
|
|
111
|
-
return isNativeFormControl && (element.hasAttribute('disabled') || belongsToDisabledFieldSet(element));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function belongsToDisabledFieldSet(element) {
|
|
115
|
-
var fieldSet = element.closest('FIELDSET[DISABLED]');
|
|
116
|
-
if (!fieldSet) return false;
|
|
117
|
-
var legend = fieldSet.querySelector(':scope > LEGEND');
|
|
118
|
-
return !legend || !legend.contains(element);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function isFocusable(element) {
|
|
122
|
-
return !isNativelyDisabled(element) && (isNativelyFocusable(element) || hasTabIndex(element));
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function isNativelyFocusable(element) {
|
|
126
|
-
var tagName = elementSafeTagName(element);
|
|
127
|
-
if (['BUTTON','DETAILS','SELECT','TEXTAREA'].indexOf(tagName) >= 0) return true;
|
|
128
|
-
if (tagName === 'A' || tagName === 'AREA') return element.hasAttribute('href');
|
|
129
|
-
if (tagName === 'INPUT') return !element.hidden;
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function getIdRefs(element, ref) {
|
|
134
|
-
if (!ref) return [];
|
|
135
|
-
var root = enclosingShadowRootOrDocument(element);
|
|
136
|
-
if (!root) return [];
|
|
137
|
-
try {
|
|
138
|
-
var ids = ref.split(' ').filter(function(id) { return !!id; });
|
|
139
|
-
var result = [];
|
|
140
|
-
for (var i = 0; i < ids.length; i++) {
|
|
141
|
-
var el = root.querySelector('#' + CSS.escape(ids[i]));
|
|
142
|
-
if (el && result.indexOf(el) < 0) result.push(el);
|
|
143
|
-
}
|
|
144
|
-
return result;
|
|
145
|
-
} catch(e) { return []; }
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
var inputTypeToRole = {
|
|
149
|
-
'button': 'button', 'checkbox': 'checkbox', 'image': 'button',
|
|
150
|
-
'number': 'spinbutton', 'radio': 'radio', 'range': 'slider',
|
|
151
|
-
'reset': 'button', 'submit': 'button'
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
var kImplicitRoleByTagName = {
|
|
155
|
-
'A': function(e) { return e.hasAttribute('href') ? 'link' : null; },
|
|
156
|
-
'AREA': function(e) { return e.hasAttribute('href') ? 'link' : null; },
|
|
157
|
-
'ARTICLE': function() { return 'article'; },
|
|
158
|
-
'ASIDE': function() { return 'complementary'; },
|
|
159
|
-
'BLOCKQUOTE': function() { return 'blockquote'; },
|
|
160
|
-
'BUTTON': function() { return 'button'; },
|
|
161
|
-
'CAPTION': function() { return 'caption'; },
|
|
162
|
-
'CODE': function() { return 'code'; },
|
|
163
|
-
'DATALIST': function() { return 'listbox'; },
|
|
164
|
-
'DD': function() { return 'definition'; },
|
|
165
|
-
'DEL': function() { return 'deletion'; },
|
|
166
|
-
'DETAILS': function() { return 'group'; },
|
|
167
|
-
'DFN': function() { return 'term'; },
|
|
168
|
-
'DIALOG': function() { return 'dialog'; },
|
|
169
|
-
'DT': function() { return 'term'; },
|
|
170
|
-
'EM': function() { return 'emphasis'; },
|
|
171
|
-
'FIELDSET': function() { return 'group'; },
|
|
172
|
-
'FIGURE': function() { return 'figure'; },
|
|
173
|
-
'FOOTER': function(e) { return closestCrossShadow(e, kAncestorPreventingLandmark) ? null : 'contentinfo'; },
|
|
174
|
-
'FORM': function(e) { return hasExplicitAccessibleName(e) ? 'form' : null; },
|
|
175
|
-
'H1': function() { return 'heading'; },
|
|
176
|
-
'H2': function() { return 'heading'; },
|
|
177
|
-
'H3': function() { return 'heading'; },
|
|
178
|
-
'H4': function() { return 'heading'; },
|
|
179
|
-
'H5': function() { return 'heading'; },
|
|
180
|
-
'H6': function() { return 'heading'; },
|
|
181
|
-
'HEADER': function(e) { return closestCrossShadow(e, kAncestorPreventingLandmark) ? null : 'banner'; },
|
|
182
|
-
'HR': function() { return 'separator'; },
|
|
183
|
-
'HTML': function() { return 'document'; },
|
|
184
|
-
'IMG': function(e) { return (e.getAttribute('alt') === '') && !e.getAttribute('title') && !hasGlobalAriaAttribute(e) && !hasTabIndex(e) ? 'presentation' : 'img'; },
|
|
185
|
-
'INPUT': function(e) {
|
|
186
|
-
var type = (e.type || '').toLowerCase();
|
|
187
|
-
if (type === 'search') return e.hasAttribute('list') ? 'combobox' : 'searchbox';
|
|
188
|
-
if (['email','tel','text','url',''].indexOf(type) >= 0) {
|
|
189
|
-
var list = getIdRefs(e, e.getAttribute('list'))[0];
|
|
190
|
-
return (list && elementSafeTagName(list) === 'DATALIST') ? 'combobox' : 'textbox';
|
|
191
|
-
}
|
|
192
|
-
if (type === 'hidden') return null;
|
|
193
|
-
if (type === 'file') return 'button';
|
|
194
|
-
return inputTypeToRole[type] || 'textbox';
|
|
195
|
-
},
|
|
196
|
-
'INS': function() { return 'insertion'; },
|
|
197
|
-
'LI': function() { return 'listitem'; },
|
|
198
|
-
'MAIN': function() { return 'main'; },
|
|
199
|
-
'MARK': function() { return 'mark'; },
|
|
200
|
-
'MATH': function() { return 'math'; },
|
|
201
|
-
'MENU': function() { return 'list'; },
|
|
202
|
-
'METER': function() { return 'meter'; },
|
|
203
|
-
'NAV': function() { return 'navigation'; },
|
|
204
|
-
'OL': function() { return 'list'; },
|
|
205
|
-
'OPTGROUP': function() { return 'group'; },
|
|
206
|
-
'OPTION': function() { return 'option'; },
|
|
207
|
-
'OUTPUT': function() { return 'status'; },
|
|
208
|
-
'P': function() { return 'paragraph'; },
|
|
209
|
-
'PROGRESS': function() { return 'progressbar'; },
|
|
210
|
-
'SEARCH': function() { return 'search'; },
|
|
211
|
-
'SECTION': function(e) { return hasExplicitAccessibleName(e) ? 'region' : null; },
|
|
212
|
-
'SELECT': function(e) { return e.hasAttribute('multiple') || e.size > 1 ? 'listbox' : 'combobox'; },
|
|
213
|
-
'STRONG': function() { return 'strong'; },
|
|
214
|
-
'SUB': function() { return 'subscript'; },
|
|
215
|
-
'SUP': function() { return 'superscript'; },
|
|
216
|
-
'SVG': function() { return 'img'; },
|
|
217
|
-
'TABLE': function() { return 'table'; },
|
|
218
|
-
'TBODY': function() { return 'rowgroup'; },
|
|
219
|
-
'TD': function(e) {
|
|
220
|
-
var table = closestCrossShadow(e, 'table');
|
|
221
|
-
var role = table ? getExplicitAriaRole(table) : '';
|
|
222
|
-
return (role === 'grid' || role === 'treegrid') ? 'gridcell' : 'cell';
|
|
223
|
-
},
|
|
224
|
-
'TEXTAREA': function() { return 'textbox'; },
|
|
225
|
-
'TFOOT': function() { return 'rowgroup'; },
|
|
226
|
-
'TH': function(e) {
|
|
227
|
-
var scope = e.getAttribute('scope');
|
|
228
|
-
if (scope === 'col' || scope === 'colgroup') return 'columnheader';
|
|
229
|
-
if (scope === 'row' || scope === 'rowgroup') return 'rowheader';
|
|
230
|
-
return 'columnheader';
|
|
231
|
-
},
|
|
232
|
-
'THEAD': function() { return 'rowgroup'; },
|
|
233
|
-
'TIME': function() { return 'time'; },
|
|
234
|
-
'TR': function() { return 'row'; },
|
|
235
|
-
'UL': function() { return 'list'; }
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
var validRoles = ['alert','alertdialog','application','article','banner','blockquote','button','caption','cell','checkbox','code','columnheader','combobox','complementary','contentinfo','definition','deletion','dialog','directory','document','emphasis','feed','figure','form','generic','grid','gridcell','group','heading','img','insertion','link','list','listbox','listitem','log','main','mark','marquee','math','meter','menu','menubar','menuitem','menuitemcheckbox','menuitemradio','navigation','none','note','option','paragraph','presentation','progressbar','radio','radiogroup','region','row','rowgroup','rowheader','scrollbar','search','searchbox','separator','slider','spinbutton','status','strong','subscript','superscript','switch','tab','table','tablist','tabpanel','term','textbox','time','timer','toolbar','tooltip','tree','treegrid','treeitem'];
|
|
239
|
-
|
|
240
|
-
function getExplicitAriaRole(element) {
|
|
241
|
-
var roles = (element.getAttribute('role') || '').split(' ').map(function(r) { return r.trim(); });
|
|
242
|
-
for (var i = 0; i < roles.length; i++) {
|
|
243
|
-
if (validRoles.indexOf(roles[i]) >= 0) return roles[i];
|
|
244
|
-
}
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
var kPresentationInheritanceParents = {
|
|
249
|
-
'DD': ['DL','DIV'], 'DIV': ['DL'], 'DT': ['DL','DIV'], 'LI': ['OL','UL'],
|
|
250
|
-
'TBODY': ['TABLE'], 'TD': ['TR'], 'TFOOT': ['TABLE'], 'TH': ['TR'],
|
|
251
|
-
'THEAD': ['TABLE'], 'TR': ['THEAD','TBODY','TFOOT','TABLE']
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
function hasPresentationConflictResolution(element, role) {
|
|
255
|
-
return hasGlobalAriaAttribute(element) || isFocusable(element);
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function getImplicitAriaRole(element) {
|
|
259
|
-
var fn = kImplicitRoleByTagName[elementSafeTagName(element)];
|
|
260
|
-
var implicitRole = fn ? fn(element) : '';
|
|
261
|
-
if (!implicitRole) return null;
|
|
262
|
-
var ancestor = element;
|
|
263
|
-
while (ancestor) {
|
|
264
|
-
var parent = parentElementOrShadowHost(ancestor);
|
|
265
|
-
var parents = kPresentationInheritanceParents[elementSafeTagName(ancestor)];
|
|
266
|
-
if (!parents || !parent || parents.indexOf(elementSafeTagName(parent)) < 0) break;
|
|
267
|
-
var parentExplicitRole = getExplicitAriaRole(parent);
|
|
268
|
-
if ((parentExplicitRole === 'none' || parentExplicitRole === 'presentation') &&
|
|
269
|
-
!hasPresentationConflictResolution(parent, parentExplicitRole))
|
|
270
|
-
return parentExplicitRole;
|
|
271
|
-
ancestor = parent;
|
|
272
|
-
}
|
|
273
|
-
return implicitRole;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
function getAriaRole(element) {
|
|
277
|
-
var explicitRole = getExplicitAriaRole(element);
|
|
278
|
-
if (!explicitRole) return getImplicitAriaRole(element);
|
|
279
|
-
if (explicitRole === 'none' || explicitRole === 'presentation') {
|
|
280
|
-
var implicitRole = getImplicitAriaRole(element);
|
|
281
|
-
if (hasPresentationConflictResolution(element, implicitRole)) return implicitRole;
|
|
282
|
-
}
|
|
283
|
-
return explicitRole;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// ===== Visibility / Hidden for ARIA =====
|
|
287
|
-
|
|
288
|
-
function isElementIgnoredForAria(element) {
|
|
289
|
-
return ['STYLE','SCRIPT','NOSCRIPT','TEMPLATE'].indexOf(elementSafeTagName(element)) >= 0;
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
function getAriaBoolean(attr) {
|
|
293
|
-
return attr === null ? undefined : attr.toLowerCase() === 'true';
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
function belongsToDisplayNoneOrAriaHidden(element) {
|
|
297
|
-
var style = getComputedStyleCached(element);
|
|
298
|
-
if (!style || style.display === 'none' || getAriaBoolean(element.getAttribute('aria-hidden')) === true)
|
|
299
|
-
return true;
|
|
300
|
-
if (element.parentElement && element.parentElement.shadowRoot && !element.assignedSlot)
|
|
301
|
-
return true;
|
|
302
|
-
var parent = parentElementOrShadowHost(element);
|
|
303
|
-
if (parent) return belongsToDisplayNoneOrAriaHidden(parent);
|
|
304
|
-
return false;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
function isElementHiddenForAria(element) {
|
|
308
|
-
if (isElementIgnoredForAria(element)) return true;
|
|
309
|
-
var style = getComputedStyleCached(element);
|
|
310
|
-
var isSlot = element.nodeName === 'SLOT';
|
|
311
|
-
if (style && style.display === 'contents' && !isSlot) {
|
|
312
|
-
for (var child = element.firstChild; child; child = child.nextSibling) {
|
|
313
|
-
if (child.nodeType === 1 && !isElementHiddenForAria(child)) return false;
|
|
314
|
-
if (child.nodeType === 3 && isVisibleTextNode(child)) return false;
|
|
315
|
-
}
|
|
316
|
-
return true;
|
|
317
|
-
}
|
|
318
|
-
var isOptionInsideSelect = element.nodeName === 'OPTION' && !!element.closest('select');
|
|
319
|
-
if (!isOptionInsideSelect && !isSlot && !isElementStyleVisibilityVisible(element, style))
|
|
320
|
-
return true;
|
|
321
|
-
return belongsToDisplayNoneOrAriaHidden(element);
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// ===== Accessible Name Computation (WAI-ARIA accname) =====
|
|
325
|
-
|
|
326
|
-
function trimFlatString(s) { return s.trim(); }
|
|
327
|
-
|
|
328
|
-
function asFlatString(s) {
|
|
329
|
-
return s.replace(/\\r\\n/g, '\\n').replace(/[\\u200b\\u00ad]/g, '').replace(/\\s\\s*/g, ' ').trim();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
function normalizeWhiteSpace(s) {
|
|
333
|
-
if (!s) return '';
|
|
334
|
-
return s.replace(/\\s+/g, ' ').trim();
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
function allowsNameFromContent(role, targetDescendant) {
|
|
338
|
-
var always = ['button','cell','checkbox','columnheader','gridcell','heading','link','menuitem','menuitemcheckbox','menuitemradio','option','radio','row','rowheader','switch','tab','tooltip','treeitem'];
|
|
339
|
-
if (always.indexOf(role) >= 0) return true;
|
|
340
|
-
if (targetDescendant) {
|
|
341
|
-
var descendant = ['','caption','code','contentinfo','definition','deletion','emphasis','insertion','list','listitem','mark','none','paragraph','presentation','region','row','rowgroup','section','strong','subscript','superscript','table','term','time'];
|
|
342
|
-
if (descendant.indexOf(role) >= 0) return true;
|
|
343
|
-
}
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
function getAriaLabelledByElements(element) {
|
|
348
|
-
var ref = element.getAttribute('aria-labelledby');
|
|
349
|
-
if (ref === null) return null;
|
|
350
|
-
var refs = getIdRefs(element, ref);
|
|
351
|
-
return refs.length ? refs : null;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
function queryInAriaOwned(element, selector) {
|
|
355
|
-
var result = Array.from(element.querySelectorAll(selector));
|
|
356
|
-
var owned = getIdRefs(element, element.getAttribute('aria-owns'));
|
|
357
|
-
for (var i = 0; i < owned.length; i++) {
|
|
358
|
-
if (owned[i].matches(selector)) result.push(owned[i]);
|
|
359
|
-
result.push.apply(result, Array.from(owned[i].querySelectorAll(selector)));
|
|
360
|
-
}
|
|
361
|
-
return result;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
function getCSSContent(element, pseudo) {
|
|
365
|
-
var style = getComputedStyleCached(element, pseudo);
|
|
366
|
-
if (!style) return undefined;
|
|
367
|
-
var contentValue = style.content;
|
|
368
|
-
if (!contentValue || contentValue === 'none' || contentValue === 'normal') return undefined;
|
|
369
|
-
if (style.display === 'none' || style.visibility === 'hidden') return undefined;
|
|
370
|
-
// Simple string content parsing - handles "text" and 'text'
|
|
371
|
-
var match = contentValue.match(/^["'](.*)["']$/);
|
|
372
|
-
if (match) {
|
|
373
|
-
var content = match[1];
|
|
374
|
-
if (pseudo) {
|
|
375
|
-
var display = style.display || 'inline';
|
|
376
|
-
if (display !== 'inline') content = ' ' + content + ' ';
|
|
377
|
-
}
|
|
378
|
-
return content;
|
|
379
|
-
}
|
|
380
|
-
return undefined;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function getTextAlternativeInternal(element, options) {
|
|
384
|
-
if (options.visitedElements.has(element)) return '';
|
|
385
|
-
|
|
386
|
-
var childOptions = Object.assign({}, options);
|
|
387
|
-
childOptions.embeddedInTargetElement = options.embeddedInTargetElement === 'self' ? 'descendant' : options.embeddedInTargetElement;
|
|
388
|
-
|
|
389
|
-
// Step 2a: Hidden not referenced
|
|
390
|
-
if (!options.includeHidden) {
|
|
391
|
-
var isEmbeddedInHiddenRef =
|
|
392
|
-
(options.embeddedInLabelledBy && options.embeddedInLabelledBy.hidden) ||
|
|
393
|
-
(options.embeddedInLabel && options.embeddedInLabel.hidden) ||
|
|
394
|
-
(options.embeddedInNativeTextAlternative && options.embeddedInNativeTextAlternative.hidden);
|
|
395
|
-
if (isElementIgnoredForAria(element) || (!isEmbeddedInHiddenRef && isElementHiddenForAria(element))) {
|
|
396
|
-
options.visitedElements.add(element);
|
|
397
|
-
return '';
|
|
398
|
-
}
|
|
399
|
-
}
|
|
400
|
-
|
|
401
|
-
var labelledBy = getAriaLabelledByElements(element);
|
|
402
|
-
|
|
403
|
-
// Step 2b: aria-labelledby
|
|
404
|
-
if (!options.embeddedInLabelledBy && labelledBy) {
|
|
405
|
-
var accessibleName = labelledBy.map(function(ref) {
|
|
406
|
-
return getTextAlternativeInternal(ref, {
|
|
407
|
-
includeHidden: options.includeHidden,
|
|
408
|
-
visitedElements: options.visitedElements,
|
|
409
|
-
embeddedInLabelledBy: { element: ref, hidden: isElementHiddenForAria(ref) }
|
|
410
|
-
});
|
|
411
|
-
}).join(' ');
|
|
412
|
-
if (accessibleName) return accessibleName;
|
|
413
|
-
}
|
|
414
|
-
|
|
415
|
-
var role = getAriaRole(element) || '';
|
|
416
|
-
var tagName = elementSafeTagName(element);
|
|
417
|
-
|
|
418
|
-
// Step 2c/2d: Embedded controls
|
|
419
|
-
if (options.embeddedInLabel || options.embeddedInLabelledBy || options.embeddedInTargetElement === 'descendant') {
|
|
420
|
-
var labels = element.labels || [];
|
|
421
|
-
var isOwnLabel = Array.from(labels).indexOf(element) >= 0;
|
|
422
|
-
var isOwnLabelledBy = (labelledBy || []).indexOf(element) >= 0;
|
|
423
|
-
if (!isOwnLabel && !isOwnLabelledBy) {
|
|
424
|
-
if (role === 'textbox') {
|
|
425
|
-
options.visitedElements.add(element);
|
|
426
|
-
if (tagName === 'INPUT' || tagName === 'TEXTAREA') return element.value;
|
|
427
|
-
return element.textContent || '';
|
|
428
|
-
}
|
|
429
|
-
if (role === 'combobox' || role === 'listbox') {
|
|
430
|
-
options.visitedElements.add(element);
|
|
431
|
-
var selectedOptions;
|
|
432
|
-
if (tagName === 'SELECT') {
|
|
433
|
-
selectedOptions = Array.from(element.selectedOptions);
|
|
434
|
-
if (!selectedOptions.length && element.options.length)
|
|
435
|
-
selectedOptions.push(element.options[0]);
|
|
436
|
-
} else {
|
|
437
|
-
var listbox = role === 'combobox' ? queryInAriaOwned(element, '*').find(function(e) { return getAriaRole(e) === 'listbox'; }) : element;
|
|
438
|
-
selectedOptions = listbox ? queryInAriaOwned(listbox, '[aria-selected="true"]').filter(function(e) { return getAriaRole(e) === 'option'; }) : [];
|
|
439
|
-
}
|
|
440
|
-
if (!selectedOptions.length && tagName === 'INPUT') return element.value;
|
|
441
|
-
return selectedOptions.map(function(opt) { return getTextAlternativeInternal(opt, childOptions); }).join(' ');
|
|
442
|
-
}
|
|
443
|
-
if (['progressbar','scrollbar','slider','spinbutton','meter'].indexOf(role) >= 0) {
|
|
444
|
-
options.visitedElements.add(element);
|
|
445
|
-
if (element.hasAttribute('aria-valuetext')) return element.getAttribute('aria-valuetext') || '';
|
|
446
|
-
if (element.hasAttribute('aria-valuenow')) return element.getAttribute('aria-valuenow') || '';
|
|
447
|
-
return element.getAttribute('value') || '';
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
// Step 2d: aria-label
|
|
453
|
-
var ariaLabel = element.getAttribute('aria-label') || '';
|
|
454
|
-
if (trimFlatString(ariaLabel)) {
|
|
455
|
-
options.visitedElements.add(element);
|
|
456
|
-
return ariaLabel;
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Step 2e: Native text alternatives
|
|
460
|
-
if (['presentation','none'].indexOf(role) < 0) {
|
|
461
|
-
if (tagName === 'INPUT' && ['button','submit','reset'].indexOf(element.type) >= 0) {
|
|
462
|
-
options.visitedElements.add(element);
|
|
463
|
-
var val = element.value || '';
|
|
464
|
-
if (trimFlatString(val)) return val;
|
|
465
|
-
if (element.type === 'submit') return 'Submit';
|
|
466
|
-
if (element.type === 'reset') return 'Reset';
|
|
467
|
-
return element.getAttribute('title') || '';
|
|
468
|
-
}
|
|
469
|
-
if (tagName === 'INPUT' && element.type === 'image') {
|
|
470
|
-
options.visitedElements.add(element);
|
|
471
|
-
var alt = element.getAttribute('alt') || '';
|
|
472
|
-
if (trimFlatString(alt)) return alt;
|
|
473
|
-
var title = element.getAttribute('title') || '';
|
|
474
|
-
if (trimFlatString(title)) return title;
|
|
475
|
-
return 'Submit';
|
|
476
|
-
}
|
|
477
|
-
if (!labelledBy && (tagName === 'TEXTAREA' || tagName === 'SELECT' || tagName === 'INPUT')) {
|
|
478
|
-
options.visitedElements.add(element);
|
|
479
|
-
var elLabels = element.labels || [];
|
|
480
|
-
if (elLabels.length) {
|
|
481
|
-
return Array.from(elLabels).map(function(label) {
|
|
482
|
-
return getTextAlternativeInternal(label, Object.assign({}, childOptions, {
|
|
483
|
-
embeddedInLabel: { element: label, hidden: isElementHiddenForAria(label) }
|
|
484
|
-
}));
|
|
485
|
-
}).filter(function(n) { return !!n; }).join(' ');
|
|
486
|
-
}
|
|
487
|
-
var usePlaceholder = (tagName === 'INPUT' && ['text','password','search','tel','email','url'].indexOf(element.type) >= 0) || tagName === 'TEXTAREA';
|
|
488
|
-
var placeholder = element.getAttribute('placeholder') || '';
|
|
489
|
-
var elTitle = element.getAttribute('title') || '';
|
|
490
|
-
if (!usePlaceholder || elTitle) return elTitle;
|
|
491
|
-
return placeholder;
|
|
492
|
-
}
|
|
493
|
-
if (!labelledBy && tagName === 'FIELDSET') {
|
|
494
|
-
options.visitedElements.add(element);
|
|
495
|
-
for (var child = element.firstElementChild; child; child = child.nextElementSibling) {
|
|
496
|
-
if (elementSafeTagName(child) === 'LEGEND') {
|
|
497
|
-
return getTextAlternativeInternal(child, Object.assign({}, childOptions, {
|
|
498
|
-
embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) }
|
|
499
|
-
}));
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
return element.getAttribute('title') || '';
|
|
503
|
-
}
|
|
504
|
-
if (!labelledBy && tagName === 'FIGURE') {
|
|
505
|
-
options.visitedElements.add(element);
|
|
506
|
-
for (var child = element.firstElementChild; child; child = child.nextElementSibling) {
|
|
507
|
-
if (elementSafeTagName(child) === 'FIGCAPTION') {
|
|
508
|
-
return getTextAlternativeInternal(child, Object.assign({}, childOptions, {
|
|
509
|
-
embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) }
|
|
510
|
-
}));
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
return element.getAttribute('title') || '';
|
|
514
|
-
}
|
|
515
|
-
if (tagName === 'IMG') {
|
|
516
|
-
options.visitedElements.add(element);
|
|
517
|
-
var imgAlt = element.getAttribute('alt') || '';
|
|
518
|
-
if (trimFlatString(imgAlt)) return imgAlt;
|
|
519
|
-
return element.getAttribute('title') || '';
|
|
520
|
-
}
|
|
521
|
-
if (tagName === 'TABLE') {
|
|
522
|
-
options.visitedElements.add(element);
|
|
523
|
-
for (var child = element.firstElementChild; child; child = child.nextElementSibling) {
|
|
524
|
-
if (elementSafeTagName(child) === 'CAPTION') {
|
|
525
|
-
return getTextAlternativeInternal(child, Object.assign({}, childOptions, {
|
|
526
|
-
embeddedInNativeTextAlternative: { element: child, hidden: isElementHiddenForAria(child) }
|
|
527
|
-
}));
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
var summary = element.getAttribute('summary') || '';
|
|
531
|
-
if (summary) return summary;
|
|
532
|
-
}
|
|
533
|
-
if (tagName === 'AREA') {
|
|
534
|
-
options.visitedElements.add(element);
|
|
535
|
-
var areaAlt = element.getAttribute('alt') || '';
|
|
536
|
-
if (trimFlatString(areaAlt)) return areaAlt;
|
|
537
|
-
return element.getAttribute('title') || '';
|
|
538
|
-
}
|
|
539
|
-
if (tagName === 'SVG' || element.ownerSVGElement) {
|
|
540
|
-
options.visitedElements.add(element);
|
|
541
|
-
for (var child = element.firstElementChild; child; child = child.nextElementSibling) {
|
|
542
|
-
if (elementSafeTagName(child) === 'TITLE' && child.ownerSVGElement) {
|
|
543
|
-
return getTextAlternativeInternal(child, Object.assign({}, childOptions, {
|
|
544
|
-
embeddedInLabelledBy: { element: child, hidden: isElementHiddenForAria(child) }
|
|
545
|
-
}));
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
// Step 2f + 2h: Name from content
|
|
552
|
-
var shouldNameFromContentForSummary = tagName === 'SUMMARY' && ['presentation','none'].indexOf(role) < 0;
|
|
553
|
-
if (allowsNameFromContent(role, options.embeddedInTargetElement === 'descendant') ||
|
|
554
|
-
shouldNameFromContentForSummary ||
|
|
555
|
-
options.embeddedInLabelledBy || options.embeddedInLabel ||
|
|
556
|
-
options.embeddedInNativeTextAlternative) {
|
|
557
|
-
options.visitedElements.add(element);
|
|
558
|
-
var accName = innerAccumulatedElementText(element, childOptions);
|
|
559
|
-
var maybeTrimmed = options.embeddedInTargetElement === 'self' ? trimFlatString(accName) : accName;
|
|
560
|
-
if (maybeTrimmed) return accName;
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// Step 2i: title attribute
|
|
564
|
-
if (['presentation','none'].indexOf(role) < 0 || tagName === 'IFRAME') {
|
|
565
|
-
options.visitedElements.add(element);
|
|
566
|
-
var titleAttr = element.getAttribute('title') || '';
|
|
567
|
-
if (trimFlatString(titleAttr)) return titleAttr;
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
options.visitedElements.add(element);
|
|
571
|
-
return '';
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
function innerAccumulatedElementText(element, options) {
|
|
575
|
-
var tokens = [];
|
|
576
|
-
var visit = function(node, skipSlotted) {
|
|
577
|
-
if (skipSlotted && node.assignedSlot) return;
|
|
578
|
-
if (node.nodeType === 1) {
|
|
579
|
-
var display = (getComputedStyleCached(node) || {}).display || 'inline';
|
|
580
|
-
var token = getTextAlternativeInternal(node, options);
|
|
581
|
-
if (display !== 'inline' || node.nodeName === 'BR') token = ' ' + token + ' ';
|
|
582
|
-
tokens.push(token);
|
|
583
|
-
} else if (node.nodeType === 3) {
|
|
584
|
-
tokens.push(node.textContent || '');
|
|
585
|
-
}
|
|
586
|
-
};
|
|
587
|
-
tokens.push(getCSSContent(element, '::before') || '');
|
|
588
|
-
var assignedNodes = element.nodeName === 'SLOT' ? element.assignedNodes() : [];
|
|
589
|
-
if (assignedNodes.length) {
|
|
590
|
-
for (var i = 0; i < assignedNodes.length; i++) visit(assignedNodes[i], false);
|
|
591
|
-
} else {
|
|
592
|
-
for (var child = element.firstChild; child; child = child.nextSibling) visit(child, true);
|
|
593
|
-
if (element.shadowRoot) {
|
|
594
|
-
for (var child = element.shadowRoot.firstChild; child; child = child.nextSibling) visit(child, true);
|
|
595
|
-
}
|
|
596
|
-
var owned = getIdRefs(element, element.getAttribute('aria-owns'));
|
|
597
|
-
for (var i = 0; i < owned.length; i++) visit(owned[i], true);
|
|
598
|
-
}
|
|
599
|
-
tokens.push(getCSSContent(element, '::after') || '');
|
|
600
|
-
return tokens.join('');
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
function getElementAccessibleName(element, includeHidden) {
|
|
604
|
-
var elementProhibitsNaming = ['caption','code','definition','deletion','emphasis','generic','insertion','mark','paragraph','presentation','strong','subscript','suggestion','superscript','term','time'].indexOf(getAriaRole(element) || '') >= 0;
|
|
605
|
-
if (elementProhibitsNaming) return '';
|
|
606
|
-
return asFlatString(getTextAlternativeInternal(element, {
|
|
607
|
-
includeHidden: includeHidden,
|
|
608
|
-
visitedElements: new Set(),
|
|
609
|
-
embeddedInTargetElement: 'self'
|
|
610
|
-
}));
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
// ===== ARIA State Helpers =====
|
|
614
|
-
|
|
615
|
-
var kAriaCheckedRoles = ['checkbox','menuitemcheckbox','option','radio','switch','menuitemradio','treeitem'];
|
|
616
|
-
var kAriaDisabledRoles = ['application','button','composite','gridcell','group','input','link','menuitem','scrollbar','separator','tab','checkbox','columnheader','combobox','grid','listbox','menu','menubar','menuitemcheckbox','menuitemradio','option','radio','radiogroup','row','rowheader','searchbox','select','slider','spinbutton','switch','tablist','textbox','toolbar','tree','treegrid','treeitem'];
|
|
617
|
-
var kAriaExpandedRoles = ['application','button','checkbox','combobox','gridcell','link','listbox','menuitem','row','rowheader','tab','treeitem','columnheader','menuitemcheckbox','menuitemradio','switch'];
|
|
618
|
-
var kAriaLevelRoles = ['heading','listitem','row','treeitem'];
|
|
619
|
-
var kAriaPressedRoles = ['button'];
|
|
620
|
-
var kAriaSelectedRoles = ['gridcell','option','row','tab','rowheader','columnheader','treeitem'];
|
|
621
|
-
|
|
622
|
-
function getAriaChecked(element) {
|
|
623
|
-
var tagName = elementSafeTagName(element);
|
|
624
|
-
if (tagName === 'INPUT' && element.indeterminate) return 'mixed';
|
|
625
|
-
if (tagName === 'INPUT' && ['checkbox','radio'].indexOf(element.type) >= 0) return element.checked;
|
|
626
|
-
if (kAriaCheckedRoles.indexOf(getAriaRole(element) || '') >= 0) {
|
|
627
|
-
var checked = element.getAttribute('aria-checked');
|
|
628
|
-
if (checked === 'true') return true;
|
|
629
|
-
if (checked === 'mixed') return 'mixed';
|
|
630
|
-
return false;
|
|
631
|
-
}
|
|
632
|
-
return false;
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function getAriaDisabled(element) {
|
|
636
|
-
if (isNativelyDisabled(element)) return true;
|
|
637
|
-
var e = element;
|
|
638
|
-
while (e) {
|
|
639
|
-
if (kAriaDisabledRoles.indexOf(getAriaRole(e) || '') >= 0 || e !== element) {
|
|
640
|
-
var attr = (e.getAttribute('aria-disabled') || '').toLowerCase();
|
|
641
|
-
if (attr === 'true') return true;
|
|
642
|
-
if (attr === 'false') return false;
|
|
643
|
-
}
|
|
644
|
-
e = parentElementOrShadowHost(e);
|
|
645
|
-
}
|
|
646
|
-
return false;
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
function getAriaExpanded(element) {
|
|
650
|
-
if (elementSafeTagName(element) === 'DETAILS') return element.open;
|
|
651
|
-
if (kAriaExpandedRoles.indexOf(getAriaRole(element) || '') >= 0) {
|
|
652
|
-
var expanded = element.getAttribute('aria-expanded');
|
|
653
|
-
if (expanded === null) return undefined;
|
|
654
|
-
if (expanded === 'true') return true;
|
|
655
|
-
return false;
|
|
656
|
-
}
|
|
657
|
-
return undefined;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
function getAriaLevel(element) {
|
|
661
|
-
var native = { 'H1': 1, 'H2': 2, 'H3': 3, 'H4': 4, 'H5': 5, 'H6': 6 }[elementSafeTagName(element)];
|
|
662
|
-
if (native) return native;
|
|
663
|
-
if (kAriaLevelRoles.indexOf(getAriaRole(element) || '') >= 0) {
|
|
664
|
-
var attr = element.getAttribute('aria-level');
|
|
665
|
-
var value = attr === null ? NaN : Number(attr);
|
|
666
|
-
if (Number.isInteger(value) && value >= 1) return value;
|
|
667
|
-
}
|
|
668
|
-
return 0;
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
function getAriaPressed(element) {
|
|
672
|
-
if (kAriaPressedRoles.indexOf(getAriaRole(element) || '') >= 0) {
|
|
673
|
-
var pressed = element.getAttribute('aria-pressed');
|
|
674
|
-
if (pressed === 'true') return true;
|
|
675
|
-
if (pressed === 'mixed') return 'mixed';
|
|
676
|
-
}
|
|
677
|
-
return false;
|
|
678
|
-
}
|
|
679
|
-
|
|
680
|
-
function getAriaSelected(element) {
|
|
681
|
-
if (elementSafeTagName(element) === 'OPTION') return element.selected;
|
|
682
|
-
if (kAriaSelectedRoles.indexOf(getAriaRole(element) || '') >= 0)
|
|
683
|
-
return getAriaBoolean(element.getAttribute('aria-selected')) === true;
|
|
684
|
-
return false;
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
// ===== Tree Generation (from ariaSnapshot.ts) =====
|
|
688
|
-
|
|
689
|
-
function generateAriaTree(rootElement) {
|
|
690
|
-
var visited = new Set();
|
|
691
|
-
var root = { role: 'RootWebArea', name: '', children: [] };
|
|
692
|
-
|
|
693
|
-
function visit(ariaNode, node, parentElementVisible) {
|
|
694
|
-
if (visited.has(node)) return;
|
|
695
|
-
visited.add(node);
|
|
696
|
-
|
|
697
|
-
if (node.nodeType === 3 && node.nodeValue) {
|
|
698
|
-
if (!parentElementVisible) return;
|
|
699
|
-
var text = node.nodeValue;
|
|
700
|
-
if (ariaNode.role !== 'textbox' && text) ariaNode.children.push(text);
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
if (node.nodeType !== 1) return;
|
|
704
|
-
|
|
705
|
-
var element = node;
|
|
706
|
-
var visible = !isElementHiddenForAria(element);
|
|
707
|
-
|
|
708
|
-
// If not visible for aria, skip entirely (including children)
|
|
709
|
-
if (!visible) return;
|
|
710
|
-
|
|
711
|
-
// Emit placeholder for iframes/frames — don't recurse into their document
|
|
712
|
-
if (element.nodeName === 'IFRAME' || element.nodeName === 'FRAME') {
|
|
713
|
-
var iframeNode = {
|
|
714
|
-
role: 'iframe',
|
|
715
|
-
name: element.getAttribute('title') || element.getAttribute('name') || '',
|
|
716
|
-
children: [],
|
|
717
|
-
value: element.getAttribute('src') || ''
|
|
718
|
-
};
|
|
719
|
-
ariaNode.children.push(iframeNode);
|
|
720
|
-
return;
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
var ariaChildren = [];
|
|
724
|
-
if (element.hasAttribute('aria-owns')) {
|
|
725
|
-
var ids = element.getAttribute('aria-owns').split(/\\s+/);
|
|
726
|
-
for (var i = 0; i < ids.length; i++) {
|
|
727
|
-
var ownedElement = rootElement.ownerDocument.getElementById(ids[i]);
|
|
728
|
-
if (ownedElement) ariaChildren.push(ownedElement);
|
|
729
|
-
}
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
var childAriaNode = toAriaNode(element);
|
|
733
|
-
if (childAriaNode) ariaNode.children.push(childAriaNode);
|
|
734
|
-
processElement(childAriaNode || ariaNode, element, ariaChildren, visible);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
function processElement(ariaNode, element, ariaChildren, parentElementVisible) {
|
|
738
|
-
var display = (getComputedStyleCached(element) || {}).display || 'inline';
|
|
739
|
-
var treatAsBlock = (display !== 'inline' || element.nodeName === 'BR') ? ' ' : '';
|
|
740
|
-
if (treatAsBlock) ariaNode.children.push(treatAsBlock);
|
|
741
|
-
|
|
742
|
-
ariaNode.children.push(getCSSContent(element, '::before') || '');
|
|
743
|
-
var assignedNodes = element.nodeName === 'SLOT' ? element.assignedNodes() : [];
|
|
744
|
-
if (assignedNodes.length) {
|
|
745
|
-
for (var i = 0; i < assignedNodes.length; i++) visit(ariaNode, assignedNodes[i], parentElementVisible);
|
|
746
|
-
} else {
|
|
747
|
-
for (var child = element.firstChild; child; child = child.nextSibling) {
|
|
748
|
-
if (!child.assignedSlot) visit(ariaNode, child, parentElementVisible);
|
|
749
|
-
}
|
|
750
|
-
if (element.shadowRoot) {
|
|
751
|
-
for (var child = element.shadowRoot.firstChild; child; child = child.nextSibling)
|
|
752
|
-
visit(ariaNode, child, parentElementVisible);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
for (var i = 0; i < ariaChildren.length; i++) visit(ariaNode, ariaChildren[i], parentElementVisible);
|
|
756
|
-
ariaNode.children.push(getCSSContent(element, '::after') || '');
|
|
757
|
-
if (treatAsBlock) ariaNode.children.push(treatAsBlock);
|
|
758
|
-
|
|
759
|
-
// Remove redundant child when it equals the node name
|
|
760
|
-
if (ariaNode.children.length === 1 && ariaNode.name === ariaNode.children[0])
|
|
761
|
-
ariaNode.children = [];
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
function toAriaNode(element) {
|
|
765
|
-
var role = getAriaRole(element);
|
|
766
|
-
if (!role || role === 'presentation' || role === 'none') return null;
|
|
767
|
-
|
|
768
|
-
var name = normalizeWhiteSpace(getElementAccessibleName(element, false));
|
|
769
|
-
var result = { role: role, name: name, children: [] };
|
|
770
|
-
|
|
771
|
-
if (kAriaCheckedRoles.indexOf(role) >= 0) {
|
|
772
|
-
var checked = getAriaChecked(element);
|
|
773
|
-
if (checked === true) result.checked = true;
|
|
774
|
-
else if (checked === 'mixed') result.checked = 'mixed';
|
|
775
|
-
}
|
|
776
|
-
if (kAriaDisabledRoles.indexOf(role) >= 0 && getAriaDisabled(element))
|
|
777
|
-
result.disabled = true;
|
|
778
|
-
if (kAriaExpandedRoles.indexOf(role) >= 0) {
|
|
779
|
-
var expanded = getAriaExpanded(element);
|
|
780
|
-
if (expanded !== undefined) result.expanded = expanded;
|
|
781
|
-
}
|
|
782
|
-
if (kAriaLevelRoles.indexOf(role) >= 0) {
|
|
783
|
-
var level = getAriaLevel(element);
|
|
784
|
-
if (level) result.level = level;
|
|
785
|
-
}
|
|
786
|
-
if (kAriaPressedRoles.indexOf(role) >= 0) {
|
|
787
|
-
var pressed = getAriaPressed(element);
|
|
788
|
-
if (pressed === true) result.pressed = true;
|
|
789
|
-
else if (pressed === 'mixed') result.pressed = 'mixed';
|
|
790
|
-
}
|
|
791
|
-
if (kAriaSelectedRoles.indexOf(role) >= 0 && getAriaSelected(element))
|
|
792
|
-
result.selected = true;
|
|
793
|
-
|
|
794
|
-
// Value for form controls
|
|
795
|
-
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {
|
|
796
|
-
if (['checkbox','radio','file'].indexOf(element.type) < 0)
|
|
797
|
-
result.value = element.value;
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
return result;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
visit(root, rootElement, true);
|
|
804
|
-
normalizeStringChildren(root);
|
|
805
|
-
return root;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
function normalizeStringChildren(ariaNode) {
|
|
809
|
-
var normalizedChildren = [];
|
|
810
|
-
var buffer = [];
|
|
811
|
-
for (var i = 0; i < (ariaNode.children || []).length; i++) {
|
|
812
|
-
var child = ariaNode.children[i];
|
|
813
|
-
if (typeof child === 'string') {
|
|
814
|
-
buffer.push(child);
|
|
815
|
-
} else {
|
|
816
|
-
if (buffer.length) {
|
|
817
|
-
var text = normalizeWhiteSpace(buffer.join(''));
|
|
818
|
-
if (text) normalizedChildren.push(text);
|
|
819
|
-
buffer = [];
|
|
820
|
-
}
|
|
821
|
-
normalizeStringChildren(child);
|
|
822
|
-
normalizedChildren.push(child);
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
if (buffer.length) {
|
|
826
|
-
var text = normalizeWhiteSpace(buffer.join(''));
|
|
827
|
-
if (text) normalizedChildren.push(text);
|
|
828
|
-
}
|
|
829
|
-
ariaNode.children = normalizedChildren.length ? normalizedChildren : [];
|
|
830
|
-
if (ariaNode.children.length === 1 && ariaNode.children[0] === ariaNode.name)
|
|
831
|
-
ariaNode.children = [];
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// ===== Convert to AccessibilityNode format =====
|
|
835
|
-
|
|
836
|
-
function toAccessibilityNode(ariaNode) {
|
|
837
|
-
var result = { role: ariaNode.role, name: ariaNode.name || '' };
|
|
838
|
-
if (ariaNode.value) result.value = String(ariaNode.value);
|
|
839
|
-
var descParts = [];
|
|
840
|
-
if (ariaNode.checked === true) descParts.push('checked');
|
|
841
|
-
else if (ariaNode.checked === 'mixed') descParts.push('checked=mixed');
|
|
842
|
-
if (ariaNode.disabled) descParts.push('disabled');
|
|
843
|
-
if (ariaNode.expanded === true) descParts.push('expanded');
|
|
844
|
-
else if (ariaNode.expanded === false) descParts.push('collapsed');
|
|
845
|
-
if (ariaNode.level) descParts.push('level=' + ariaNode.level);
|
|
846
|
-
if (ariaNode.pressed === true) descParts.push('pressed');
|
|
847
|
-
else if (ariaNode.pressed === 'mixed') descParts.push('pressed=mixed');
|
|
848
|
-
if (ariaNode.selected) descParts.push('selected');
|
|
849
|
-
if (descParts.length) result.description = descParts.join(', ');
|
|
850
|
-
|
|
851
|
-
if (ariaNode.children && ariaNode.children.length) {
|
|
852
|
-
result.children = [];
|
|
853
|
-
for (var i = 0; i < ariaNode.children.length; i++) {
|
|
854
|
-
var child = ariaNode.children[i];
|
|
855
|
-
if (typeof child === 'string') {
|
|
856
|
-
result.children.push({ role: 'text', name: child });
|
|
857
|
-
} else {
|
|
858
|
-
result.children.push(toAccessibilityNode(child));
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
return result;
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
// ===== Main =====
|
|
866
|
-
try {
|
|
867
|
-
var root = generateAriaTree(document.body || document.documentElement);
|
|
868
|
-
return toAccessibilityNode(root);
|
|
869
|
-
} catch(e) {
|
|
870
|
-
return { role: 'RootWebArea', name: '', description: 'Error: ' + (e.message || String(e)) };
|
|
871
|
-
}
|
|
872
|
-
})()`,s=`ws://localhost:5710/cdp`,c=t(`browser-api`);function l(e=typeof window<`u`?window.location:null){return e?.host?`${e.protocol===`https:`?`wss:`:`ws:`}//${e.host}/cdp`:s}var u=class{client;localClient;sessionId=null;attachedTargetId=null;trayTargetProvider=null;remoteTargetInfo=null;_frameContextCache=new Map;_tabLock=Promise.resolve();_onSessionChange;handleJavaScriptDialogOpening=async e=>{let t=typeof e.sessionId==`string`?e.sessionId:this.sessionId;if(t)try{await this.client.send(`Page.handleJavaScriptDialog`,{accept:!1},t,5e3),c.warn(`Auto-dismissed unexpected JavaScript dialog`,{sessionId:t,type:e.type,message:e.message,url:e.url})}catch(e){c.warn(`Failed to auto-dismiss JavaScript dialog`,{sessionId:t,error:e instanceof Error?e.message:String(e)})}};constructor(e){this.client=e??new i,this.localClient=this.client,this.addDialogListener(this.client)}getTransport(){return this.client}setSessionChangeCallback(e){this._onSessionChange=e}getSessionId(){return this.sessionId}getAttachedTargetId(){return this.attachedTargetId}async withTab(e,t){let n,r=new Promise(e=>{n=e}),i=this._tabLock;this._tabLock=r,await i;try{return await t(await this.attachToPage(e))}finally{n()}}setTrayTargetProvider(e){this.trayTargetProvider=e}async listAllTargets(){let e=await this.listPages();if(!this.trayTargetProvider)return e;let t=!this.remoteTargetInfo,n=new Set(e.map(e=>e.targetId)),r=this.trayTargetProvider.getTargets().filter(e=>!t||!(e.runtimeId===`leader`&&n.has(e.localTargetId))).map(e=>({targetId:e.targetId,title:e.title,url:e.url}));return[...e,...r]}async connect(e){await this.client.connect({url:e?.url??l(),timeout:e?.timeout})}async createPage(e){return await this.ensureConnected(),await this.ensureLocalConnected(),(await this.localClient.send(`Target.createTarget`,{url:e??`about:blank`,background:!0})).targetId}async createRemotePage(e,t){if(!this.trayTargetProvider?.openRemoteTab)throw Error(`Remote tab opening not available (no tray target provider)`);return this.trayTargetProvider.openRemoteTab(e,t??`about:blank`)}async closePage(e){if(await this.ensureConnected(),this.trayTargetProvider?.createRemoteTransport&&e.includes(`:`)){let t=e.indexOf(`:`),n=e.substring(0,t),r=e.substring(t+1);{let t=this.trayTargetProvider.createRemoteTransport(n,r);try{await t.send(`Target.closeTarget`,{targetId:r})}finally{this.trayTargetProvider.removeRemoteTransport&&this.trayTargetProvider.removeRemoteTransport(n,r)}this.attachedTargetId===e&&(this.remoteTargetInfo&&=(this.setClient(this.localClient),null),this.sessionId=null,this.attachedTargetId=null);return}}await this.localClient.send(`Target.closeTarget`,{targetId:e}),this.attachedTargetId===e&&(this.sessionId=null,this.attachedTargetId=null)}disconnect(){this.sessionId=null,this.attachedTargetId=null,this.client.disconnect()}async listPages(){return await this.ensureConnected(),await this.ensureLocalConnected(),((await this.localClient.send(`Target.getTargets`)).targetInfos??[]).filter(e=>e.type===`page`).map(e=>({targetId:e.targetId,title:e.title,url:e.url,...e.active?{active:!0}:{}}))}async attachToPage(e){if(await this.ensureConnected(),this.sessionId&&this.attachedTargetId===e)return this.sessionId;if(this._frameContextCache.clear(),this.trayTargetProvider?.createRemoteTransport&&e.includes(`:`)){let t=e.indexOf(`:`),n=e.substring(0,t),r=e.substring(t+1);{let t=this.trayTargetProvider.createRemoteTransport(n,r);this.setClient(t),this.remoteTargetInfo={runtimeId:n,localTargetId:r};let i=await this.client.send(`Target.attachToTarget`,{targetId:r,flatten:!0});return this.sessionId=i.sessionId,this.attachedTargetId=e,await this.client.send(`Page.enable`,{},this.sessionId),this._onSessionChange?.(this.sessionId,this.client),this.sessionId}}this.remoteTargetInfo&&=(this.trayTargetProvider?.removeRemoteTransport&&this.trayTargetProvider.removeRemoteTransport(this.remoteTargetInfo.runtimeId,this.remoteTargetInfo.localTargetId),this.setClient(this.localClient),null),await this.ensureLocalConnected();let t=await this.localClient.send(`Target.attachToTarget`,{targetId:e,flatten:!0});return this.sessionId=t.sessionId,this.attachedTargetId=e,await this.localClient.send(`Page.enable`,{},this.sessionId),this._onSessionChange?.(this.sessionId,this.localClient),this.sessionId}async detach(){if(this.sessionId){try{await this.client.send(`Target.detachFromTarget`,{sessionId:this.sessionId})}catch{}this.remoteTargetInfo&&this.trayTargetProvider?.removeRemoteTransport&&(this.trayTargetProvider.removeRemoteTransport(this.remoteTargetInfo.runtimeId,this.remoteTargetInfo.localTargetId),this.setClient(this.localClient),this.remoteTargetInfo=null),this.sessionId=null,this.attachedTargetId=null}}async navigate(e){await this.ensureConnected(),this.ensureAttached(),await this.client.send(`Page.enable`,{},this.sessionId);let t=this.client.once(`Page.loadEventFired`);await this.client.send(`Page.navigate`,{url:e},this.sessionId),await t}async screenshot(e){await this.ensureConnected(),this.ensureAttached();try{let t={format:e?.format??`png`,captureBeyondViewport:!0};if(e?.quality!==void 0&&(t.quality=e.quality),e?.clip||e?.fullPage){let n=0,r=0;try{await this.client.send(`Runtime.enable`,{},this.sessionId);let e=await this.client.send(`Runtime.evaluate`,{expression:`JSON.stringify({ w: window.innerWidth, h: document.documentElement.scrollHeight })`,returnByValue:!0},this.sessionId),t=JSON.parse(e.result?.value??`{}`);n=t.w??0,r=t.h??0}catch{}e?.clip?t.clip={...e.clip,scale:e.clip.scale??1}:t.clip={x:0,y:0,width:n||1280,height:r||800,scale:1}}let r;try{r=await this.client.send(`Page.captureScreenshot`,t,this.sessionId)}catch{await this.client.send(`Page.bringToFront`,{},this.sessionId),r=await this.client.send(`Page.captureScreenshot`,t,this.sessionId)}let i=r.data;if(e?.maxWidth)try{let{getMagick:t}=await n(async()=>{let{getMagick:e}=await import(`./magick-wasm-DA8eLvGf.js`).then(e=>e.n);return{getMagick:e}},__vite__mapDeps([0,1,2])),r=await t(),a=atob(i),o=new Uint8Array(a.length);for(let e=0;e<a.length;e++)o[e]=a.charCodeAt(e);let s=8e3,c=!1;await r.ImageMagick.read(o,async t=>{let n=Math.min(e.maxWidth,s),r=Math.max(t.width,t.height);if(t.width>n||r>s){let e=Math.min(n/t.width,s/r);t.resize(Math.round(t.width*e),Math.round(t.height*e)),c=!0}c&&t.write(`PNG`,e=>{let t=``;for(let n=0;n<e.length;n++)t+=String.fromCharCode(e[n]);i=btoa(t)})})}catch(e){console.warn(`[browser-api] Screenshot maxWidth resize failed, returning original`,e)}return i}finally{}}async evaluate(e,t){await this.ensureConnected(),this.ensureAttached(),await this.client.send(`Runtime.enable`,{},this.sessionId);let n=await this.client.send(`Runtime.evaluate`,{expression:e,awaitPromise:t?.awaitPromise??!0,returnByValue:t?.returnByValue??!0},this.sessionId),r=n.exceptionDetails;if(r){let e=r.exception?.description??r.text;throw Error(`Evaluation failed: ${e}`)}return n.result.value}async click(e){await this.ensureConnected(),this.ensureAttached();let t=await this.boundingBox(e);if(!t)throw Error(`Element not found: ${e}`);let n=t.x+t.width/2,r=t.y+t.height/2;await this.client.send(`Input.dispatchMouseEvent`,{type:`mousePressed`,x:n,y:r,button:`left`,clickCount:1},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseReleased`,x:n,y:r,button:`left`,clickCount:1},this.sessionId)}async type(e){await this.ensureConnected(),this.ensureAttached();for(let t of e)await this.client.send(`Input.dispatchKeyEvent`,{type:`keyDown`,text:t},this.sessionId),await this.client.send(`Input.dispatchKeyEvent`,{type:`keyUp`,text:t},this.sessionId)}async waitForSelector(e,t){await this.ensureConnected(),this.ensureAttached();let n=t?.timeout??3e4,r=t?.interval??100,i=Date.now();for(;Date.now()-i<n;){if(await this.evaluate(`!!document.querySelector(${JSON.stringify(e)})`))return;await new Promise(e=>setTimeout(e,r))}throw Error(`waitForSelector timed out after ${n}ms: ${e}`)}async getAccessibilityTree(){await this.ensureConnected(),this.ensureAttached();let e=await this.evaluate(o,{awaitPromise:!1,returnByValue:!0});return!e||typeof e!=`object`?{role:`RootWebArea`,name:``}:d(e)}async clickByBackendNodeId(e){await this.ensureConnected(),this.ensureAttached(),await this.client.send(`DOM.enable`,{},this.sessionId),await this.client.send(`Runtime.enable`,{},this.sessionId);let t=(await this.client.send(`DOM.resolveNode`,{backendNodeId:e},this.sessionId)).object;if(!t?.objectId)throw Error(`Could not resolve backend node ${e} to a DOM element`);let n=(await this.client.send(`Runtime.callFunctionOn`,{objectId:t.objectId,functionDeclaration:`function() {
|
|
873
|
-
this.scrollIntoView({ block: 'center', inline: 'center' });
|
|
874
|
-
const r = this.getBoundingClientRect();
|
|
875
|
-
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
876
|
-
}`,returnByValue:!0},this.sessionId)).result?.value;if(!n||n.width===0||n.height===0){await this.client.send(`Runtime.callFunctionOn`,{objectId:t.objectId,functionDeclaration:`function() { this.click(); }`},this.sessionId);return}let r=n.x+n.width/2,i=n.y+n.height/2;await this.client.send(`Input.dispatchMouseEvent`,{type:`mousePressed`,x:r,y:i,button:`left`,clickCount:1},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseReleased`,x:r,y:i,button:`left`,clickCount:1},this.sessionId)}async dblclickByBackendNodeId(e,t=`left`){await this.ensureConnected(),this.ensureAttached();let{x:n,y:r}=await this.resolveNodeCenter(e);await this.client.send(`Input.dispatchMouseEvent`,{type:`mousePressed`,x:n,y:r,button:t,clickCount:1},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseReleased`,x:n,y:r,button:t,clickCount:1},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mousePressed`,x:n,y:r,button:t,clickCount:2},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseReleased`,x:n,y:r,button:t,clickCount:2},this.sessionId)}async hoverByBackendNodeId(e){await this.ensureConnected(),this.ensureAttached();let{x:t,y:n}=await this.resolveNodeCenter(e);await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseMoved`,x:t,y:n},this.sessionId)}async selectByBackendNodeId(e,t){await this.ensureConnected(),this.ensureAttached();let n=await this.resolveNodeObjectId(e);await this.client.send(`Runtime.callFunctionOn`,{objectId:n,functionDeclaration:`function(val) { this.value = val; this.dispatchEvent(new Event('change', { bubbles: true })); }`,arguments:[{value:t}],returnByValue:!0},this.sessionId)}async setCheckedByBackendNodeId(e,t){await this.ensureConnected(),this.ensureAttached();let n=await this.resolveNodeObjectId(e);return(await this.client.send(`Runtime.callFunctionOn`,{objectId:n,functionDeclaration:`function() { return this.checked; }`,returnByValue:!0},this.sessionId)).result?.value===t?`already`:(await this.clickByBackendNodeId(e),`toggled`)}async dragByBackendNodeIds(e,t){await this.ensureConnected(),this.ensureAttached();let n=await this.resolveNodeCenter(e),r=await this.resolveNodeCenter(t);await this.client.send(`Input.dispatchMouseEvent`,{type:`mousePressed`,x:n.x,y:n.y,button:`left`,clickCount:1},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseMoved`,x:r.x,y:r.y},this.sessionId),await this.client.send(`Input.dispatchMouseEvent`,{type:`mouseReleased`,x:r.x,y:r.y,button:`left`,clickCount:1},this.sessionId)}async getFrameTree(){await this.ensureConnected(),this.ensureAttached(),await this.client.send(`Page.enable`,{},this.sessionId);let e=(await this.client.send(`Page.getFrameTree`,{},this.sessionId)).frameTree,t=[],n=e=>{if(t.push({frameId:e.frame.id,parentFrameId:e.frame.parentId,url:e.frame.url,name:e.frame.name??``,securityOrigin:e.frame.securityOrigin}),Array.isArray(e.childFrames))for(let t of e.childFrames)n(t)};return n(e),t}async evaluateInFrame(e,t,n){await this.ensureConnected(),this.ensureAttached();let r=e=>{let t=e instanceof Error?e.message:String(e);return t.includes(`Cannot find context with specified id`)||t.includes(`Execution context was destroyed`)},i=async()=>{let t=(await this.client.send(`Page.createIsolatedWorld`,{frameId:e,worldName:`__slicc_iframe`},this.sessionId)).executionContextId;return this._frameContextCache.set(e,t),t},a=this._frameContextCache.get(e);if(a===void 0)try{a=await i()}catch(t){throw Error(`Failed to create isolated world for frame ${e}: ${t instanceof Error?t.message:String(t)}`)}await this.client.send(`Runtime.enable`,{},this.sessionId);let o={expression:t,contextId:a,awaitPromise:n?.awaitPromise??!0,returnByValue:n?.returnByValue??!0},s;try{s=await this.client.send(`Runtime.evaluate`,o,this.sessionId)}catch(t){if(r(t))this._frameContextCache.delete(e),a=await i(),s=await this.client.send(`Runtime.evaluate`,{...o,contextId:a},this.sessionId);else throw t}let c=s.exceptionDetails;if(c){let t=c.exception?.description??c.text;if(r(Error(t))){this._frameContextCache.delete(e),a=await i();let t=await this.client.send(`Runtime.evaluate`,{...o,contextId:a},this.sessionId),n=t.exceptionDetails;if(n){let t=n.exception?.description??n.text;throw Error(`Evaluation in frame ${e} failed: ${t}`)}return t.result.value}throw this._frameContextCache.delete(e),Error(`Evaluation in frame ${e} failed: ${t}`)}return s.result.value}async getAccessibilityTreeForFrame(e){if(!e)return this.getAccessibilityTree();await this.ensureConnected(),this.ensureAttached();let t=await this.evaluateInFrame(e,o,{awaitPromise:!1,returnByValue:!0});return!t||typeof t!=`object`?{role:`RootWebArea`,name:``}:d(t)}async sendCDP(e,t={}){return await this.ensureConnected(),this.ensureAttached(),await this.client.send(e,t,this.sessionId)}async resolveNodeObjectId(e){await this.client.send(`DOM.enable`,{},this.sessionId),await this.client.send(`Runtime.enable`,{},this.sessionId);let t=(await this.client.send(`DOM.resolveNode`,{backendNodeId:e},this.sessionId)).object;if(!t?.objectId)throw Error(`Could not resolve backend node ${e} to a DOM element`);return t.objectId}async resolveNodeCenter(e){let t=await this.resolveNodeObjectId(e),n=(await this.client.send(`Runtime.callFunctionOn`,{objectId:t,functionDeclaration:`function() {
|
|
877
|
-
this.scrollIntoView({ block: 'center', inline: 'center' });
|
|
878
|
-
const r = this.getBoundingClientRect();
|
|
879
|
-
return { x: r.x, y: r.y, width: r.width, height: r.height };
|
|
880
|
-
}`,returnByValue:!0},this.sessionId)).result?.value;if(!n||n.width===0||n.height===0)throw Error(`Element with backend node ${e} has no dimensions`);return{x:n.x+n.width/2,y:n.y+n.height/2}}async ensureLocalConnected(){this.localClient.state===`disconnected`&&await this.localClient.connect({url:l()})}async ensureConnected(){this.client.state===`disconnected`&&(this.remoteTargetInfo&&this.trayTargetProvider?.removeRemoteTransport&&(this.trayTargetProvider.removeRemoteTransport(this.remoteTargetInfo.runtimeId,this.remoteTargetInfo.localTargetId),this.setClient(this.localClient),this.remoteTargetInfo=null),this.sessionId=null,this.attachedTargetId=null,this.client.state===`disconnected`&&await this.connect())}ensureAttached(){if(!this.sessionId)throw Error(`Not attached to a page. Call attachToPage(targetId) first.`)}addDialogListener(e){e.on(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}removeDialogListener(e){e.off(`Page.javascriptDialogOpening`,this.handleJavaScriptDialogOpening)}setClient(e){this.client!==e&&(this.removeDialogListener(this.client),this.client=e,this.addDialogListener(this.client))}async boundingBox(e){await this.client.send(`DOM.enable`,{},this.sessionId);let t=(await this.client.send(`DOM.getDocument`,{depth:0},this.sessionId)).root.nodeId,n;try{n=(await this.client.send(`DOM.querySelector`,{nodeId:t,selector:e},this.sessionId)).nodeId}catch{return null}if(!n)return null;let r=(await this.client.send(`DOM.getBoxModel`,{nodeId:n},this.sessionId)).model;if(!r)return null;let i=r.content;return{x:i[0],y:i[1],width:r.width,height:r.height}}};function d(e){let t={role:a(e.role,`unknown`),name:a(e.name)},n=a(e.value);n!==``&&(t.value=n);let r=a(e.description);return r!==``&&(t.description=r),Array.isArray(e.children)&&e.children.length>0&&(t.children=e.children.map(e=>d(e)).filter(e=>e.role!==`unknown`)),t}t(`cdp:debugger`);var f=class{_state=`disconnected`;nextCommandId=1;listeners=new Map;pendingCommands=new Map;messageHandler=null;get state(){return this._state}async connect(e){if(this._state!==`disconnected`)throw Error(`Cannot connect: state is ${this._state}`);this.messageHandler=e=>{try{if(!p(e))return;let t=e;t.source===`offscreen`&&t.payload.type===`panel-cdp-response`&&this.handleCdpResponse(t.payload),t.source===`service-worker`&&t.payload.type===`cdp-event`&&this.handleCdpEvent(t.payload)}catch(e){console.error(`[panel-cdp-proxy] Error in message handler:`,e)}},chrome.runtime.onMessage.addListener(this.messageHandler),this._state=`connected`}disconnect(){this.messageHandler&&=(chrome.runtime.onMessage.removeListener(this.messageHandler),null);for(let[,e]of this.pendingCommands)clearTimeout(e.timer),e.reject(Error(`Panel CDP proxy disconnected`));this.pendingCommands.clear(),this.listeners.clear(),this._state=`disconnected`}async send(e,t,n,r=3e4){if(this._state!==`connected`)throw Error(`PanelCdpProxy is not connected`);let i=this.nextCommandId++,a={type:`panel-cdp-command`,id:i,method:e,params:t,sessionId:n};return new Promise((t,n)=>{let o=!1,s=setTimeout(()=>{o||(o=!0,this.pendingCommands.delete(i),n(Error(`CDP command timed out after ${r}ms: ${e}`)))},r);this.pendingCommands.set(i,{resolve:t,reject:n,timer:s}),chrome.runtime.sendMessage({source:`panel`,payload:a}).catch(e=>{o||(o=!0,this.pendingCommands.delete(i),clearTimeout(s),n(Error(`Failed to send CDP command: ${e instanceof Error?e.message:String(e)}`)))})})}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){let n=this.listeners.get(e);n&&(n.delete(t),n.size===0&&this.listeners.delete(e))}once(e,t=3e4){return new Promise((n,r)=>{let i=setTimeout(()=>{this.off(e,a),r(Error(`Timed out waiting for event: ${e}`))},t),a=t=>{clearTimeout(i),this.off(e,a),n(t)};this.on(e,a)})}handleCdpResponse(e){let t=this.pendingCommands.get(e.id);if(!t){console.warn(`[panel-cdp-proxy] Ignoring CDP response with unknown id ${e.id}`);return}this.pendingCommands.delete(e.id),clearTimeout(t.timer),e.error?t.reject(Error(e.error)):t.resolve(e.result??{})}handleCdpEvent(e){let t=this.listeners.get(e.method);if(t)for(let n of t)try{n(e.params??{})}catch(t){console.error(`[panel-cdp-proxy] Listener error for event "${e.method}":`,t)}}};function p(e){return typeof e==`object`&&!!e&&`source`in e&&`payload`in e}var m=t(`har-recorder`),h=class{recordings=new Map;client;fs;eventCleanup=new Map;constructor(e,t){this.client=e,this.fs=t}async startRecording(e,t,n){let r=`rec-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;await this.client.send(`Network.enable`,{},t),await this.client.send(`Page.enable`,{},t);let i=(await this.client.send(`Runtime.evaluate`,{expression:`location.href`,returnByValue:!0},t)).result?.value??`about:blank`,a={id:r,targetId:e,sessionId:t,filterCode:n,pendingRequests:new Map,entries:[],startTime:Date.now(),currentUrl:i,snapshotCount:0};return this.recordings.set(r,a),this.setupEventListeners(a),await this.ensureDir(`/recordings/${r}`),m.debug(`Started recording`,{recordingId:r,targetId:e,currentUrl:i}),r}setupEventListeners(e){let{sessionId:t,id:n}=e,r=n=>{n.sessionId===t&&this.handleRequestWillBeSent(e,n)},i=n=>{n.sessionId===t&&this.handleResponseReceived(e,n)},a=n=>{n.sessionId===t&&this.handleLoadingFinished(e,n)},o=n=>{n.sessionId===t&&this.handleLoadingFailed(e,n)},s=r=>{if(r.sessionId!==t)return;let i=r.frame;if(!i?.parentId&&i?.url){let t=[...e.entries],r=e.currentUrl;e.currentUrl=i.url,e.entries=[],e.pendingRequests.clear(),this.saveSnapshotWithEntries(e,`navigation`,t,r).catch(e=>{m.error(`Failed to save navigation snapshot`,{recordingId:n,error:e instanceof Error?e.message:String(e)})})}};this.client.on(`Network.requestWillBeSent`,r),this.client.on(`Network.responseReceived`,i),this.client.on(`Network.loadingFinished`,a),this.client.on(`Network.loadingFailed`,o),this.client.on(`Page.frameNavigated`,s),this.eventCleanup.set(n,()=>{this.client.off(`Network.requestWillBeSent`,r),this.client.off(`Network.responseReceived`,i),this.client.off(`Network.loadingFinished`,a),this.client.off(`Network.loadingFailed`,o),this.client.off(`Page.frameNavigated`,s)})}handleRequestWillBeSent(e,t){let n=t.requestId,r=t.request,i=t.timestamp;e.pendingRequests.set(n,{requestId:n,startTime:i*1e3,request:{method:r.method,url:r.url,headers:r.headers,postData:r.postData}})}handleResponseReceived(e,t){let n=t.requestId,r=t.response,i=e.pendingRequests.get(n);i&&(i.response={status:r.status,statusText:r.statusText,headers:r.headers,mimeType:r.mimeType},i.timing=r.timing)}async handleLoadingFinished(e,t){let n=t.requestId,r=t.timestamp,i=e.pendingRequests.get(n);if(!i)return;i.endTime=r*1e3;try{let t=await this.client.send(`Network.getResponseBody`,{requestId:n},e.sessionId);i.responseBody=t.body,i.responseBodyBase64=t.base64Encoded}catch{}let a=this.buildHarEntry(i);a&&e.entries.push(a),e.pendingRequests.delete(n)}handleLoadingFailed(e,t){let n=t.requestId;e.pendingRequests.delete(n)}buildHarEntry(e){if(!e.response)return null;let{request:t,response:n,timing:r,startTime:i,endTime:a,responseBody:o,responseBodyBase64:s}=e,c=a?a-i:0,l=[];try{let e=new URL(t.url);l=Array.from(e.searchParams.entries()).map(([e,t])=>({name:e,value:t}))}catch{}let u=r?(()=>{let e=(e,t)=>{if(e==null||t==null||e<0||t<0)return-1;let n=t-e;return n>=0?n:-1},t=r.dnsStart>=0?r.dnsStart:r.connectStart>=0?r.connectStart:0;return{blocked:t>0?t:-1,dns:e(r.dnsStart,r.dnsEnd),connect:e(r.connectStart,r.connectEnd),ssl:e(r.sslStart,r.sslEnd),send:e(r.sendStart,r.sendEnd),wait:e(r.sendEnd,r.receiveHeadersStart),receive:e(r.receiveHeadersStart,r.receiveHeadersEnd)}})():{blocked:-1,dns:-1,connect:-1,ssl:-1,send:0,wait:c,receive:0},d={size:o?.length??0,mimeType:n.mimeType??`application/octet-stream`};o&&(d.text=o,s&&(d.encoding=`base64`));let f;return t.postData&&(f={mimeType:t.headers[`content-type`]??t.headers[`Content-Type`]??`text/plain`,text:t.postData}),{startedDateTime:new Date(i).toISOString(),time:c,request:{method:t.method,url:t.url,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(t.headers).map(([e,t])=>({name:e,value:t})),queryString:l,postData:f,headersSize:-1,bodySize:t.postData?.length??0},response:{status:n.status,statusText:n.statusText,httpVersion:`HTTP/1.1`,cookies:[],headers:Object.entries(n.headers).map(([e,t])=>({name:e,value:t})),content:d,redirectURL:n.headers.location??n.headers.Location??``,headersSize:-1,bodySize:d.size},cache:{},timings:u}}async saveSnapshot(e,t){return this.saveSnapshotWithEntries(e,t,e.entries,e.currentUrl)}async applyFilter(e,t){if(typeof chrome<`u`&&chrome?.runtime?.id)try{let n=document.querySelector(`iframe[data-js-tool]`);n||(n=document.createElement(`iframe`),n.style.display=`none`,n.dataset.jsTool=`true`,n.src=chrome.runtime.getURL(`sandbox.html`),document.body.appendChild(n),await Promise.race([new Promise(e=>{n.addEventListener(`load`,()=>e(),{once:!0})}),new Promise((e,t)=>{setTimeout(()=>t(Error(`Sandbox iframe failed to load`)),5e3)})]));let r=`har-filter-${Date.now()}-${Math.random().toString(36).slice(2)}`;return await new Promise((i,a)=>{let o=setTimeout(()=>{window.removeEventListener(`message`,s),a(Error(`HAR filter sandbox timeout`))},1e4),s=e=>{e.data?.type===`har_filter_result`&&e.data.id===r&&(window.removeEventListener(`message`,s),clearTimeout(o),e.data.error?a(Error(e.data.error)):i(e.data.entries))};window.addEventListener(`message`,s),n.contentWindow.postMessage({type:`har_filter`,id:r,entries:e,filterCode:t},`*`)})}catch(t){return m.error(`HAR filter sandbox error, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}else try{let n=Function(`entry`,`return (${t})(entry);`),r=[];for(let t of e)try{let e=n(t);if(e===!1)continue;typeof e==`object`&&e?r.push(e):r.push(t)}catch(e){m.error(`Filter function error on entry, keeping it`,{error:e instanceof Error?e.message:String(e)}),r.push(t)}return r}catch(t){return m.error(`Failed to compile filter, returning unfiltered`,{error:t instanceof Error?t.message:String(t)}),e}}async saveSnapshotWithEntries(e,t,n,r){if(n.length===0)return m.debug(`No entries to save`,{recordingId:e.id,trigger:t}),null;let i=e.filterCode?await this.applyFilter(n,e.filterCode):n;if(i.length===0)return m.debug(`All entries filtered out`,{recordingId:e.id,trigger:t}),null;e.snapshotCount++;let a=new Date().toISOString().replace(/[:.]/g,`-`),o=this.urlToSlug(r),s=`${e.snapshotCount.toString().padStart(3,`0`)}-${a}-${t}-${o}.har`,c=`/recordings/${e.id}/${s}`,l={log:{version:`1.2`,creator:{name:`SLICC HAR Recorder`,version:`1.0.0`},entries:i}};return await this.fs.writeFile(c,JSON.stringify(l,null,2)),m.debug(`Saved HAR snapshot`,{recordingId:e.id,path:c,entryCount:i.length}),c}urlToSlug(e){try{let t=new URL(e);return`${t.hostname}${t.pathname}`.replace(/[^a-zA-Z0-9]/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``).slice(0,50)||`page`}catch{return`page`}}async stopRecording(e){let t=this.recordings.get(e);if(!t)throw Error(`Recording not found: ${e}`);await this.saveSnapshot(t,`close`);let n=this.eventCleanup.get(e);n&&(n(),this.eventCleanup.delete(e));try{await this.client.send(`Network.disable`,{},t.sessionId)}catch{}this.recordings.delete(e);let r=`/recordings/${e}`;return m.debug(`Stopped recording`,{recordingId:e,snapshotCount:t.snapshotCount}),r}getRecording(e){return this.recordings.get(e)}getRecordingByTarget(e){for(let[t,n]of this.recordings)if(n.targetId===e)return t}async ensureDir(e){await this.fs.mkdir(e,{recursive:!0})}},g=t(`navigation-watcher`);function _(e){try{return decodeURIComponent(e)}catch{return e}}function v(e){if(!e)return null;for(let[t,n]of Object.entries(e))if(t.toLowerCase()===`x-slicc`&&typeof n==`string`&&n.length>0)return _(n);return null}var y=class{transport;onEvent;sessions=new Map;started=!1;onAttachedToTarget=e=>{this.handleAttachedToTarget(e)};onDetachedFromTarget=e=>{let t=e.sessionId;t&&this.sessions.delete(t)};onTargetInfoChanged=e=>{let t=e.targetInfo;if(t?.targetId)for(let e of this.sessions.values())e.targetId===t.targetId&&(typeof t.title==`string`&&(e.title=t.title),typeof t.url==`string`&&(e.url=t.url))};onFrameNavigated=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n)return;let r=e.frame;r?.id&&(r.parentId||(n.rootFrameId=r.id,typeof r.url==`string`&&(n.url=r.url)))};onResponseReceived=e=>{let t=e.sessionId;if(!t)return;let n=this.sessions.get(t);if(!n||e.type!==`Document`)return;let r=e.frameId;if(!r||r!==n.rootFrameId)return;let i=e.response;if(!i)return;let a=v(i.headers);if(!a)return;let o=typeof i.url==`string`&&i.url.length>0?i.url:n.url;o&&this.onEvent({url:o,sliccHeader:a,title:n.title,targetId:n.targetId})};constructor(e,t){this.transport=e,this.onEvent=t}async start(){if(!this.started){this.transport.on(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.on(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.on(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.on(`Page.frameNavigated`,this.onFrameNavigated),this.transport.on(`Network.responseReceived`,this.onResponseReceived);try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!0}),await this.transport.send(`Target.setAutoAttach`,{autoAttach:!0,waitForDebuggerOnStart:!1,flatten:!0})}catch(e){g.error(`Failed to enable target discovery`,{error:e instanceof Error?e.message:String(e)}),this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived);return}this.started=!0;try{let e=(await this.transport.send(`Target.getTargets`)).targetInfos??[];for(let t of e){if(t.type!==`page`)continue;let e=t.attached===!0,n=t.targetId;if(!(e||typeof n!=`string`))try{await this.transport.send(`Target.attachToTarget`,{targetId:n,flatten:!0})}catch(e){g.debug(`Failed to attach to preexisting target`,{targetId:n,error:e instanceof Error?e.message:String(e)})}}}catch(e){g.debug(`Failed to enumerate preexisting targets`,{error:e instanceof Error?e.message:String(e)})}}}async stop(){if(this.started){this.started=!1,this.transport.off(`Target.attachedToTarget`,this.onAttachedToTarget),this.transport.off(`Target.detachedFromTarget`,this.onDetachedFromTarget),this.transport.off(`Target.targetInfoChanged`,this.onTargetInfoChanged),this.transport.off(`Page.frameNavigated`,this.onFrameNavigated),this.transport.off(`Network.responseReceived`,this.onResponseReceived),this.sessions.clear();try{await this.transport.send(`Target.setAutoAttach`,{autoAttach:!1,waitForDebuggerOnStart:!1,flatten:!0})}catch(e){g.debug(`Failed to disable auto-attach on stop`,{error:e instanceof Error?e.message:String(e)})}try{await this.transport.send(`Target.setDiscoverTargets`,{discover:!1})}catch(e){g.debug(`Failed to disable target discovery on stop`,{error:e instanceof Error?e.message:String(e)})}}}async handleAttachedToTarget(e){let t=e.sessionId,n=e.targetInfo;if(!(!t||!n||n.type!==`page`||typeof n.targetId!=`string`)){this.sessions.set(t,{targetId:n.targetId,rootFrameId:null,title:n.title,url:n.url});try{await this.transport.send(`Page.enable`,{},t),await this.transport.send(`Network.enable`,{},t);let e=(await this.transport.send(`Page.getFrameTree`,{},t)).frameTree?.frame;if(e?.id&&typeof e.id==`string`){let n=this.sessions.get(t);n&&(n.rootFrameId=e.id)}}catch(e){g.debug(`Failed to enable Page/Network on attached target`,{sessionId:t,error:e instanceof Error?e.message:String(e)})}}}},b=t(`tray-sync`),x=32*1024;function S(e,t,n,r){if(r||!n)return e.send({type:`cdp.response`,requestId:t,result:n,error:r});let i=JSON.stringify(n);if(i.length<=65536)return e.send({type:`cdp.response`,requestId:t,result:n});let a=Math.ceil(i.length/x),o=!0;for(let n=0;n<a;n++){let r=i.slice(n*x,(n+1)*x);if(!e.send({type:`cdp.response`,requestId:t,chunkData:r,chunkIndex:n,totalChunks:a})){o=!1,e.send({type:`cdp.response`,requestId:t,error:`Failed to send CDP response chunk ${n}/${a} (response was ${i.length} bytes)`});break}}return o}function C(e,t){if(t.chunkIndex===void 0||t.totalChunks===void 0)return{result:t.result,error:t.error};if(t.error)return e.delete(t.requestId),{error:t.error};let n=t.requestId,r=e.get(n);if(r||(r={chunks:Array(t.totalChunks),received:0,totalChunks:t.totalChunks},e.set(n,r)),r.chunks[t.chunkIndex]||(r.chunks[t.chunkIndex]=t.chunkData,r.received++),r.received>=r.totalChunks){e.delete(n);try{return{result:JSON.parse(r.chunks.join(``))}}catch(e){return{error:`Failed to reassemble CDP response: ${e instanceof Error?e.message:String(e)}`}}}return null}var w=32*1024;function T(e,t,n){let r=JSON.stringify({messages:t,scoopJid:n});if(r.length<=65536)return e.send({type:`snapshot`,messages:t,scoopJid:n});let i=Math.ceil(r.length/w),a=!0;for(let t=0;t<i;t++){let o=r.slice(t*w,(t+1)*w);if(!e.send({type:`snapshot_chunk`,chunkData:o,chunkIndex:t,totalChunks:i,scoopJid:n})){a=!1,b.error(`Failed to send snapshot chunk`,{chunkIndex:t,totalChunks:i,totalSize:r.length});break}}return b.debug(`Snapshot sent in chunks`,{totalChunks:i,totalSize:r.length}),a}function E(e,t){if(e||={chunks:Array(t.totalChunks),received:0,totalChunks:t.totalChunks},e.chunks[t.chunkIndex]||(e.chunks[t.chunkIndex]=t.chunkData,e.received++),e.received>=e.totalChunks)try{return{result:JSON.parse(e.chunks.join(``)),buffer:null}}catch(e){return b.error(`Failed to reassemble snapshot`,{error:e instanceof Error?e.message:String(e)}),{result:{messages:[],scoopJid:t.scoopJid},buffer:null}}return{result:null,buffer:e}}var D=class{listeners=[];closed=!1;constructor(e){this.channel=e,this.channel.addEventListener(`message`,e=>{if(!this.closed)try{let t=JSON.parse(e.data);for(let e of this.listeners)e(t)}catch(e){b.warn(`Failed to parse tray sync message`,{error:e instanceof Error?e.message:String(e)})}})}send(e){if(this.closed)return!1;try{return this.channel.send(JSON.stringify(e)),!0}catch(t){return b.error(`Failed to send tray sync message`,{type:e.type,error:t instanceof Error?t.message:String(t)}),!1}}onMessage(e){return this.listeners.push(e),()=>{let t=this.listeners.indexOf(e);t>=0&&this.listeners.splice(t,1)}}close(){this.closed=!0,this.listeners.length=0,this.channel.close()}get isOpen(){return!this.closed&&this.channel.readyState===`open`}};function O(e){return new D(e)}function k(e){return new D(e)}var A=class{pending=new Map;eventListeners=new Map;chunkBuffers=new Map;_state=`connected`;requestCounter=0;constructor(e,t=3e4){this.sender=e,this.timeoutMs=t}get state(){return this._state}async connect(){}disconnect(){this._state=`disconnected`;for(let[,{reject:e,timer:t}]of this.pending)clearTimeout(t),e(Error(`Transport disconnected`));this.pending.clear()}async send(e,t,n,r){if(this._state===`disconnected`)throw Error(`Transport disconnected`);let i=`remote-${++this.requestCounter}-${Date.now()}`,a=r??this.timeoutMs;return new Promise((r,o)=>{let s=setTimeout(()=>{this.pending.delete(i),o(Error(`Remote CDP request timed out after ${a}ms: ${e}`))},a);this.pending.set(i,{resolve:r,reject:o,timer:s}),this.sender.sendCDPRequest(i,e,t,n)})}on(e,t){let n=this.eventListeners.get(e);n||(n=new Set,this.eventListeners.set(e,n)),n.add(t)}off(e,t){this.eventListeners.get(e)?.delete(t)}once(e,t){return new Promise((n,r)=>{let i=t??this.timeoutMs,a=setTimeout(()=>{this.off(e,o),r(Error(`Remote CDP event timed out: ${e}`))},i),o=t=>{clearTimeout(a),this.off(e,o),n(t)};this.on(e,o)})}handleResponse(e,t,n,r,i,a){let o=this.pending.get(e);if(!o)return;let s=C(this.chunkBuffers,{type:`cdp.response`,requestId:e,result:t,error:n,chunkData:r,chunkIndex:i,totalChunks:a});s&&(this.pending.delete(e),clearTimeout(o.timer),s.error?o.reject(Error(s.error)):o.resolve(s.result??{}))}handleEvent(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)e(t)}},j=e({BrowserAPI:()=>u,PanelCdpProxy:()=>f});export{C as a,T as c,u as d,a as f,O as i,y as l,A as n,E as o,k as r,S as s,j as t,h as u};
|