checkpoint-cli 0.3.8 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1189
- package/dist/tracking-script-minimal.js +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -79,1194 +79,6 @@ function requireAuth() {
|
|
|
79
79
|
process.exit(1);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
|
-
/* ── Checkpoint Tracking Script (injected into HTML responses) ── */
|
|
83
|
-
function trackingScript() {
|
|
84
|
-
return `
|
|
85
|
-
<script data-checkpoint-script="1">
|
|
86
|
-
(function(){
|
|
87
|
-
var lastPath='';
|
|
88
|
-
var pickMode=false;
|
|
89
|
-
var pickClickHandler=null;
|
|
90
|
-
var pickEscHandler=null;
|
|
91
|
-
var pickMoveHandler=null;
|
|
92
|
-
var pickInspectBox=null;
|
|
93
|
-
var pickInspectLabel=null;
|
|
94
|
-
var pickPointerDownHandler=null;
|
|
95
|
-
var pickHoverRaf=0;
|
|
96
|
-
var pickLastMouseX=0;
|
|
97
|
-
var pickLastMouseY=0;
|
|
98
|
-
|
|
99
|
-
function getMetrics(){
|
|
100
|
-
var de=document.documentElement;
|
|
101
|
-
return {
|
|
102
|
-
scrollX:window.scrollX||window.pageXOffset||0,
|
|
103
|
-
scrollY:window.scrollY||window.pageYOffset||0,
|
|
104
|
-
docWidth:de.scrollWidth||0,
|
|
105
|
-
docHeight:de.scrollHeight||0,
|
|
106
|
-
viewWidth:de.clientWidth||window.innerWidth||0,
|
|
107
|
-
viewHeight:de.clientHeight||window.innerHeight||0
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function clampPercent(v){
|
|
112
|
-
if(v<0) return 0;
|
|
113
|
-
if(v>100) return 100;
|
|
114
|
-
return v;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function cssEscape(value){
|
|
118
|
-
try{
|
|
119
|
-
if(window.CSS&&typeof window.CSS.escape==='function'){
|
|
120
|
-
return window.CSS.escape(value);
|
|
121
|
-
}
|
|
122
|
-
}catch(e){}
|
|
123
|
-
return String(value).replace(/[^a-zA-Z0-9_-]/g,'\\\\$&');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function shortText(value){
|
|
127
|
-
if(!value) return '';
|
|
128
|
-
return String(value).replace(/\\s+/g,' ').trim().slice(0,120);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function getFileLeaf(path){
|
|
132
|
-
if(!path) return '';
|
|
133
|
-
try{
|
|
134
|
-
var raw=String(path);
|
|
135
|
-
var parts=raw.split(/[\\\\/]/);
|
|
136
|
-
return parts[parts.length-1]||raw;
|
|
137
|
-
}catch(e){}
|
|
138
|
-
return '';
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
function getInspectElementLabel(el){
|
|
142
|
-
if(!el||!el.tagName) return '(unknown)';
|
|
143
|
-
var tag=String(el.tagName).toLowerCase();
|
|
144
|
-
var id=el.id?('#'+el.id):'';
|
|
145
|
-
var classes='';
|
|
146
|
-
try{
|
|
147
|
-
var cls=(el.className&&typeof el.className==='string')
|
|
148
|
-
? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,3)
|
|
149
|
-
: [];
|
|
150
|
-
if(cls.length>0){
|
|
151
|
-
classes='.'+cls.join('.');
|
|
152
|
-
}
|
|
153
|
-
}catch(e){}
|
|
154
|
-
return shortText(tag+id+classes);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
function ensurePickInspectUi(){
|
|
158
|
-
if(!document.body) return;
|
|
159
|
-
if(!pickInspectBox){
|
|
160
|
-
pickInspectBox=document.createElement('div');
|
|
161
|
-
pickInspectBox.setAttribute('data-checkpoint-inspect','box');
|
|
162
|
-
pickInspectBox.style.position='fixed';
|
|
163
|
-
pickInspectBox.style.left='0';
|
|
164
|
-
pickInspectBox.style.top='0';
|
|
165
|
-
pickInspectBox.style.width='0';
|
|
166
|
-
pickInspectBox.style.height='0';
|
|
167
|
-
pickInspectBox.style.border='2px solid #6366f1';
|
|
168
|
-
pickInspectBox.style.background='rgba(99,102,241,0.12)';
|
|
169
|
-
pickInspectBox.style.boxSizing='border-box';
|
|
170
|
-
pickInspectBox.style.borderRadius='4px';
|
|
171
|
-
pickInspectBox.style.pointerEvents='none';
|
|
172
|
-
pickInspectBox.style.zIndex='2147483646';
|
|
173
|
-
pickInspectBox.style.display='none';
|
|
174
|
-
document.body.appendChild(pickInspectBox);
|
|
175
|
-
}
|
|
176
|
-
if(!pickInspectLabel){
|
|
177
|
-
pickInspectLabel=document.createElement('div');
|
|
178
|
-
pickInspectLabel.setAttribute('data-checkpoint-inspect','label');
|
|
179
|
-
pickInspectLabel.style.position='fixed';
|
|
180
|
-
pickInspectLabel.style.left='0';
|
|
181
|
-
pickInspectLabel.style.top='0';
|
|
182
|
-
pickInspectLabel.style.maxWidth='380px';
|
|
183
|
-
pickInspectLabel.style.padding='6px 8px';
|
|
184
|
-
pickInspectLabel.style.borderRadius='8px';
|
|
185
|
-
pickInspectLabel.style.border='1px solid rgba(148,163,184,0.45)';
|
|
186
|
-
pickInspectLabel.style.background='rgba(15,23,42,0.96)';
|
|
187
|
-
pickInspectLabel.style.color='#e2e8f0';
|
|
188
|
-
pickInspectLabel.style.font='12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace';
|
|
189
|
-
pickInspectLabel.style.whiteSpace='pre-line';
|
|
190
|
-
pickInspectLabel.style.wordBreak='break-word';
|
|
191
|
-
pickInspectLabel.style.pointerEvents='none';
|
|
192
|
-
pickInspectLabel.style.zIndex='2147483647';
|
|
193
|
-
pickInspectLabel.style.display='none';
|
|
194
|
-
pickInspectLabel.style.boxShadow='0 6px 20px rgba(0,0,0,0.35)';
|
|
195
|
-
document.body.appendChild(pickInspectLabel);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function hidePickInspectUi(){
|
|
200
|
-
if(pickInspectBox) pickInspectBox.style.display='none';
|
|
201
|
-
if(pickInspectLabel) pickInspectLabel.style.display='none';
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
function renderPickInspect(target,mouseX,mouseY){
|
|
205
|
-
ensurePickInspectUi();
|
|
206
|
-
if(!pickInspectBox||!pickInspectLabel||!target||target.nodeType!==1){
|
|
207
|
-
hidePickInspectUi();
|
|
208
|
-
return;
|
|
209
|
-
}
|
|
210
|
-
var sourceTarget=findBestSourceAnchorTarget(target);
|
|
211
|
-
var anchorEl=sourceTarget.element||target;
|
|
212
|
-
var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl);
|
|
213
|
-
var rect=target.getBoundingClientRect?target.getBoundingClientRect():null;
|
|
214
|
-
if(!rect||rect.width<1||rect.height<1){
|
|
215
|
-
hidePickInspectUi();
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
pickInspectBox.style.display='block';
|
|
220
|
-
pickInspectBox.style.left=Math.max(0,rect.left)+'px';
|
|
221
|
-
pickInspectBox.style.top=Math.max(0,rect.top)+'px';
|
|
222
|
-
pickInspectBox.style.width=Math.max(1,rect.width)+'px';
|
|
223
|
-
pickInspectBox.style.height=Math.max(1,rect.height)+'px';
|
|
224
|
-
|
|
225
|
-
var primary=getInspectElementLabel(anchorEl);
|
|
226
|
-
var sourceLabel='(no source metadata)';
|
|
227
|
-
if(sourceAnchor){
|
|
228
|
-
var leaf=getFileLeaf(sourceAnchor.source_file);
|
|
229
|
-
if(leaf&&typeof sourceAnchor.source_line==='number'){
|
|
230
|
-
sourceLabel=leaf+':'+sourceAnchor.source_line;
|
|
231
|
-
}else if(leaf){
|
|
232
|
-
sourceLabel=leaf;
|
|
233
|
-
}else if(sourceAnchor.component_name){
|
|
234
|
-
sourceLabel=sourceAnchor.component_name;
|
|
235
|
-
}
|
|
236
|
-
if(sourceAnchor.explicit_id){
|
|
237
|
-
sourceLabel=sourceLabel+' · #'+sourceAnchor.explicit_id;
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
pickInspectLabel.textContent=primary+'\\n'+sourceLabel;
|
|
241
|
-
pickInspectLabel.style.display='block';
|
|
242
|
-
|
|
243
|
-
var viewW=window.innerWidth||document.documentElement.clientWidth||0;
|
|
244
|
-
var viewH=window.innerHeight||document.documentElement.clientHeight||0;
|
|
245
|
-
var labelRect=pickInspectLabel.getBoundingClientRect();
|
|
246
|
-
var left=mouseX+14;
|
|
247
|
-
var top=mouseY+14;
|
|
248
|
-
if(left+labelRect.width>viewW-8){
|
|
249
|
-
left=Math.max(8,mouseX-labelRect.width-14);
|
|
250
|
-
}
|
|
251
|
-
if(top+labelRect.height>viewH-8){
|
|
252
|
-
top=Math.max(8,mouseY-labelRect.height-14);
|
|
253
|
-
}
|
|
254
|
-
pickInspectLabel.style.left=left+'px';
|
|
255
|
-
pickInspectLabel.style.top=top+'px';
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
function getEventElement(ev){
|
|
259
|
-
if(!ev) return null;
|
|
260
|
-
try{
|
|
261
|
-
if(typeof ev.composedPath==='function'){
|
|
262
|
-
var path=ev.composedPath();
|
|
263
|
-
if(path&&path.length>0){
|
|
264
|
-
var first=path[0];
|
|
265
|
-
if(first&&first.nodeType===1) return first;
|
|
266
|
-
if(first&&first.nodeType===3&&first.parentElement) return first.parentElement;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
}catch(e){}
|
|
270
|
-
var target=ev.target||null;
|
|
271
|
-
if(target&&target.nodeType===1){
|
|
272
|
-
return target;
|
|
273
|
-
}
|
|
274
|
-
if(target&&target.nodeType===3&&target.parentElement){
|
|
275
|
-
return target.parentElement;
|
|
276
|
-
}
|
|
277
|
-
try{
|
|
278
|
-
if(typeof ev.clientX==='number'&&typeof ev.clientY==='number'&&document.elementFromPoint){
|
|
279
|
-
var node=document.elementFromPoint(ev.clientX,ev.clientY);
|
|
280
|
-
if(node&&node.nodeType===1){
|
|
281
|
-
return node;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}catch(e){}
|
|
285
|
-
return null;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
function getElementAtPoint(x,y){
|
|
289
|
-
try{
|
|
290
|
-
if(typeof x==='number'&&typeof y==='number'&&document.elementFromPoint){
|
|
291
|
-
var node=document.elementFromPoint(x,y);
|
|
292
|
-
if(node&&node.nodeType===1){
|
|
293
|
-
return node;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}catch(e){}
|
|
297
|
-
return null;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function elementSelector(el){
|
|
301
|
-
if(!el||!el.tagName) return '';
|
|
302
|
-
var tag=el.tagName.toLowerCase();
|
|
303
|
-
if(el.id) return '#'+cssEscape(el.id);
|
|
304
|
-
var cls=(el.className&&typeof el.className==='string')
|
|
305
|
-
? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,3)
|
|
306
|
-
: [];
|
|
307
|
-
if(cls.length>0) return tag+'.'+cls.map(cssEscape).join('.');
|
|
308
|
-
return tag;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
function getSelectorChain(el){
|
|
312
|
-
var out=[];
|
|
313
|
-
var seen={};
|
|
314
|
-
function push(selector,score){
|
|
315
|
-
if(!selector||seen[selector]) return;
|
|
316
|
-
seen[selector]=true;
|
|
317
|
-
out.push({selector:selector,score:score});
|
|
318
|
-
}
|
|
319
|
-
var current=el;
|
|
320
|
-
var depth=0;
|
|
321
|
-
while(current&¤t.nodeType===1&&depth<5){
|
|
322
|
-
var sel=elementSelector(current);
|
|
323
|
-
if(sel){
|
|
324
|
-
var score=Math.max(0.2,1-(depth*0.18));
|
|
325
|
-
push(sel,score);
|
|
326
|
-
}
|
|
327
|
-
if(current.parentElement){
|
|
328
|
-
var parentSel=elementSelector(current.parentElement);
|
|
329
|
-
if(parentSel&&sel){
|
|
330
|
-
push(parentSel+' > '+sel,Math.max(0.2,0.88-(depth*0.15)));
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
current=current.parentElement;
|
|
334
|
-
depth++;
|
|
335
|
-
}
|
|
336
|
-
return out.slice(0,10);
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
function getSiblingPath(el){
|
|
340
|
-
var path=[];
|
|
341
|
-
var current=el;
|
|
342
|
-
var steps=0;
|
|
343
|
-
while(current&¤t.parentElement&&steps<8){
|
|
344
|
-
var parent=current.parentElement;
|
|
345
|
-
var index=0;
|
|
346
|
-
var children=parent.children;
|
|
347
|
-
for(var i=0;i<children.length;i++){
|
|
348
|
-
if(children[i]===current){
|
|
349
|
-
index=i;
|
|
350
|
-
break;
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
path.unshift(index);
|
|
354
|
-
current=parent;
|
|
355
|
-
steps++;
|
|
356
|
-
}
|
|
357
|
-
return path;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
function getDomFingerprint(el){
|
|
361
|
-
if(!el||!el.tagName) return null;
|
|
362
|
-
var classes=(el.className&&typeof el.className==='string')
|
|
363
|
-
? el.className.trim().split(/\\s+/).filter(Boolean).slice(0,6)
|
|
364
|
-
: [];
|
|
365
|
-
return {
|
|
366
|
-
tag:el.tagName.toLowerCase(),
|
|
367
|
-
id:el.id||null,
|
|
368
|
-
classes:classes,
|
|
369
|
-
sibling_path:getSiblingPath(el)
|
|
370
|
-
};
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function getContainerHint(el){
|
|
374
|
-
if(!el||typeof el.closest!=='function') return null;
|
|
375
|
-
var container=el.closest('main,article,section,form,nav,[role="main"],[data-testid],[id]');
|
|
376
|
-
if(!container||!container.tagName) return null;
|
|
377
|
-
var classes=(container.className&&typeof container.className==='string')
|
|
378
|
-
? container.className.trim().split(/\\s+/).filter(Boolean).slice(0,4)
|
|
379
|
-
: [];
|
|
380
|
-
return {
|
|
381
|
-
selector:elementSelector(container),
|
|
382
|
-
tag:container.tagName.toLowerCase(),
|
|
383
|
-
id:container.id||null,
|
|
384
|
-
classes:classes
|
|
385
|
-
};
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
function parseZIndex(value){
|
|
389
|
-
var n=parseInt(String(value||''),10);
|
|
390
|
-
return isNaN(n)?0:n;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function detectTransientKind(el){
|
|
394
|
-
if(!el||!el.tagName) return 'unknown';
|
|
395
|
-
try{
|
|
396
|
-
var role=(el.getAttribute&&el.getAttribute('role')||'').toLowerCase();
|
|
397
|
-
var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
|
|
398
|
-
var id=(el.id||'').toLowerCase();
|
|
399
|
-
var label=(role+' '+classes+' '+id).trim();
|
|
400
|
-
if(role==='dialog'||el.getAttribute('aria-modal')==='true'||label.indexOf('modal')>=0||label.indexOf('dialog')>=0){
|
|
401
|
-
return 'dialog';
|
|
402
|
-
}
|
|
403
|
-
if(label.indexOf('drawer')>=0||label.indexOf('sheet')>=0||label.indexOf('sidebar')>=0){
|
|
404
|
-
return 'drawer';
|
|
405
|
-
}
|
|
406
|
-
if(label.indexOf('popover')>=0) return 'popover';
|
|
407
|
-
if(role==='menu'||label.indexOf('menu')>=0||label.indexOf('dropdown')>=0) return 'menu';
|
|
408
|
-
if(role==='tooltip'||label.indexOf('tooltip')>=0) return 'tooltip';
|
|
409
|
-
}catch(e){}
|
|
410
|
-
return 'unknown';
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
function isTransientRootCandidate(el){
|
|
414
|
-
if(!el||!el.tagName) return false;
|
|
415
|
-
try{
|
|
416
|
-
var role=(el.getAttribute&&el.getAttribute('role')||'').toLowerCase();
|
|
417
|
-
var ariaModal=(el.getAttribute&&el.getAttribute('aria-modal')||'').toLowerCase();
|
|
418
|
-
var dataState=(el.getAttribute&&el.getAttribute('data-state')||'').toLowerCase();
|
|
419
|
-
var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
|
|
420
|
-
var id=(el.id||'').toLowerCase();
|
|
421
|
-
var style=window.getComputedStyle?window.getComputedStyle(el):null;
|
|
422
|
-
var position=style?style.position:'';
|
|
423
|
-
var zIndex=parseZIndex(style?style.zIndex:0);
|
|
424
|
-
if(role==='dialog'||role==='menu'||role==='tooltip') return true;
|
|
425
|
-
if(ariaModal==='true') return true;
|
|
426
|
-
if(dataState==='open'&&(classes.indexOf('modal')>=0||classes.indexOf('popover')>=0||classes.indexOf('drawer')>=0)) return true;
|
|
427
|
-
if(classes.indexOf('modal')>=0||classes.indexOf('dialog')>=0||classes.indexOf('drawer')>=0||classes.indexOf('popover')>=0||classes.indexOf('tooltip')>=0||classes.indexOf('dropdown')>=0) return true;
|
|
428
|
-
if(id.indexOf('modal')>=0||id.indexOf('dialog')>=0||id.indexOf('drawer')>=0||id.indexOf('popover')>=0) return true;
|
|
429
|
-
if((position==='fixed'||position==='sticky')&&zIndex>=100) return true;
|
|
430
|
-
}catch(e){}
|
|
431
|
-
return false;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
function isLikelyPortaled(el){
|
|
435
|
-
if(!el||!el.parentElement) return false;
|
|
436
|
-
try{
|
|
437
|
-
var root=el;
|
|
438
|
-
var steps=0;
|
|
439
|
-
while(root&&root.parentElement&&steps<8){
|
|
440
|
-
root=root.parentElement;
|
|
441
|
-
steps++;
|
|
442
|
-
}
|
|
443
|
-
if(!root||!root.parentElement) return false;
|
|
444
|
-
if(root===document.body) return true;
|
|
445
|
-
if(el.parentElement===document.body) return true;
|
|
446
|
-
if(el.parentElement&&el.parentElement.id&&String(el.parentElement.id).toLowerCase().indexOf('portal')>=0) return true;
|
|
447
|
-
var classes=(el.className&&typeof el.className==='string'?el.className:'').toLowerCase();
|
|
448
|
-
if(classes.indexOf('portal')>=0) return true;
|
|
449
|
-
}catch(e){}
|
|
450
|
-
return false;
|
|
451
|
-
}
|
|
452
|
-
|
|
453
|
-
function getOpenerCandidates(){
|
|
454
|
-
var out=[];
|
|
455
|
-
var seen={};
|
|
456
|
-
var selectors=[
|
|
457
|
-
'[aria-haspopup=\"dialog\"]',
|
|
458
|
-
'[aria-controls]',
|
|
459
|
-
'[data-modal-trigger]',
|
|
460
|
-
'[data-dialog-trigger]',
|
|
461
|
-
'button',
|
|
462
|
-
'[role=\"button\"]',
|
|
463
|
-
'a'
|
|
464
|
-
];
|
|
465
|
-
for(var s=0;s<selectors.length;s++){
|
|
466
|
-
var selector=selectors[s];
|
|
467
|
-
try{
|
|
468
|
-
var nodes=document.querySelectorAll(selector);
|
|
469
|
-
for(var i=0;i<nodes.length&&out.length<8;i++){
|
|
470
|
-
var node=nodes[i];
|
|
471
|
-
if(!node||node.nodeType!==1) continue;
|
|
472
|
-
var sel=elementSelector(node);
|
|
473
|
-
if(!sel||seen[sel]) continue;
|
|
474
|
-
seen[sel]=true;
|
|
475
|
-
var score=0.3;
|
|
476
|
-
var label=(node.getAttribute&&node.getAttribute('aria-label')||'').toLowerCase();
|
|
477
|
-
var text=shortText(node.textContent).toLowerCase();
|
|
478
|
-
if(label.indexOf('setting')>=0||text.indexOf('setting')>=0) score=0.9;
|
|
479
|
-
else if(label.indexOf('open')>=0||text.indexOf('open')>=0) score=0.7;
|
|
480
|
-
out.push({selector:sel,score:score});
|
|
481
|
-
}
|
|
482
|
-
}catch(e){}
|
|
483
|
-
}
|
|
484
|
-
out.sort(function(a,b){ return b.score-a.score; });
|
|
485
|
-
return out.slice(0,6);
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
function getTransientContext(el){
|
|
489
|
-
if(!el||typeof el.closest!=='function') return null;
|
|
490
|
-
var current=el;
|
|
491
|
-
var depth=0;
|
|
492
|
-
while(current&¤t.nodeType===1&&depth<8){
|
|
493
|
-
if(isTransientRootCandidate(current)){
|
|
494
|
-
var style=window.getComputedStyle?window.getComputedStyle(current):null;
|
|
495
|
-
return {
|
|
496
|
-
kind:detectTransientKind(current),
|
|
497
|
-
root_selector_chain:getSelectorChain(current),
|
|
498
|
-
root_fingerprint:getDomFingerprint(current),
|
|
499
|
-
is_portaled:isLikelyPortaled(current),
|
|
500
|
-
z_index:parseZIndex(style?style.zIndex:0),
|
|
501
|
-
is_fixed:style?style.position==='fixed':false,
|
|
502
|
-
opener_candidates:getOpenerCandidates()
|
|
503
|
-
};
|
|
504
|
-
}
|
|
505
|
-
current=current.parentElement;
|
|
506
|
-
depth++;
|
|
507
|
-
}
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
|
|
511
|
-
function getVisibleText(node){
|
|
512
|
-
try{
|
|
513
|
-
if(!node||!node.textContent) return '';
|
|
514
|
-
return shortText(String(node.textContent).replace(/\\s+/g,' ').trim()).toLowerCase();
|
|
515
|
-
}catch(e){}
|
|
516
|
-
return '';
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
function getSourceDebugInfo(fiber){
|
|
520
|
-
var current=fiber;
|
|
521
|
-
var steps=0;
|
|
522
|
-
while(current&&steps<24){
|
|
523
|
-
if(current._debugSource){
|
|
524
|
-
return current._debugSource;
|
|
525
|
-
}
|
|
526
|
-
current=current.return||null;
|
|
527
|
-
steps++;
|
|
528
|
-
}
|
|
529
|
-
return null;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
function buildCoordFallback(clientX,clientY,metrics){
|
|
533
|
-
var safeViewW=metrics.viewWidth||1;
|
|
534
|
-
var safeViewH=metrics.viewHeight||1;
|
|
535
|
-
var docX=clientX+metrics.scrollX;
|
|
536
|
-
var docY=clientY+metrics.scrollY;
|
|
537
|
-
return {
|
|
538
|
-
x_percent:clampPercent((clientX/safeViewW)*100),
|
|
539
|
-
y_percent:clampPercent((clientY/safeViewH)*100),
|
|
540
|
-
scroll_x:metrics.scrollX,
|
|
541
|
-
scroll_y:metrics.scrollY,
|
|
542
|
-
viewport_width:safeViewW,
|
|
543
|
-
viewport_height:safeViewH,
|
|
544
|
-
doc_width:metrics.docWidth||safeViewW,
|
|
545
|
-
doc_height:metrics.docHeight||safeViewH,
|
|
546
|
-
doc_x_percent:clampPercent((docX/(metrics.docWidth||safeViewW))*100),
|
|
547
|
-
doc_y_percent:clampPercent((docY/(metrics.docHeight||safeViewH))*100)
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
|
|
551
|
-
function buildAnchorPayload(el,clientX,clientY){
|
|
552
|
-
var sourceTarget=findBestSourceAnchorTarget(el);
|
|
553
|
-
var anchorEl=sourceTarget.element||el;
|
|
554
|
-
var sourceAnchor=sourceTarget.sourceAnchor||getSourceAnchor(anchorEl)||null;
|
|
555
|
-
var metrics=getMetrics();
|
|
556
|
-
var textSelf='';
|
|
557
|
-
var textParent='';
|
|
558
|
-
try{
|
|
559
|
-
textSelf=shortText(el&&el.textContent);
|
|
560
|
-
textParent=shortText(el&&el.parentElement&&el.parentElement.textContent);
|
|
561
|
-
}catch(e){}
|
|
562
|
-
var fallback=buildCoordFallback(clientX,clientY,metrics);
|
|
563
|
-
try{
|
|
564
|
-
var rect=anchorEl&&anchorEl.getBoundingClientRect?anchorEl.getBoundingClientRect():null;
|
|
565
|
-
if(rect){
|
|
566
|
-
var safeW=Math.max(1,rect.width||1);
|
|
567
|
-
var safeH=Math.max(1,rect.height||1);
|
|
568
|
-
fallback.element_x_percent=clampPercent(((clientX-rect.left)/safeW)*100);
|
|
569
|
-
fallback.element_y_percent=clampPercent(((clientY-rect.top)/safeH)*100);
|
|
570
|
-
}
|
|
571
|
-
}catch(e){}
|
|
572
|
-
return {
|
|
573
|
-
selector_chain:[],
|
|
574
|
-
dom_fingerprint:null,
|
|
575
|
-
text_context:{
|
|
576
|
-
self:textSelf,
|
|
577
|
-
parent:textParent
|
|
578
|
-
},
|
|
579
|
-
container_hint:null,
|
|
580
|
-
transient_context:getTransientContext(el),
|
|
581
|
-
source_anchor:sourceAnchor,
|
|
582
|
-
coord_fallback:fallback
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
|
|
586
|
-
function getTargetDocPoint(payload,metrics){
|
|
587
|
-
var fallback=payload&&payload.coord_fallback;
|
|
588
|
-
if(!fallback||typeof fallback!=='object') return null;
|
|
589
|
-
var docW=(typeof fallback.doc_width==='number'&&fallback.doc_width>0)
|
|
590
|
-
? fallback.doc_width
|
|
591
|
-
: (metrics.docWidth||metrics.viewWidth||1);
|
|
592
|
-
var docH=(typeof fallback.doc_height==='number'&&fallback.doc_height>0)
|
|
593
|
-
? fallback.doc_height
|
|
594
|
-
: (metrics.docHeight||metrics.viewHeight||1);
|
|
595
|
-
if(typeof fallback.doc_x_percent==='number'&&typeof fallback.doc_y_percent==='number'){
|
|
596
|
-
return {
|
|
597
|
-
x:(fallback.doc_x_percent/100)*docW,
|
|
598
|
-
y:(fallback.doc_y_percent/100)*docH
|
|
599
|
-
};
|
|
600
|
-
}
|
|
601
|
-
if(typeof fallback.x_percent==='number'&&typeof fallback.y_percent==='number'){
|
|
602
|
-
var viewW=(typeof fallback.viewport_width==='number'&&fallback.viewport_width>0)
|
|
603
|
-
? fallback.viewport_width
|
|
604
|
-
: (metrics.viewWidth||1);
|
|
605
|
-
var viewH=(typeof fallback.viewport_height==='number'&&fallback.viewport_height>0)
|
|
606
|
-
? fallback.viewport_height
|
|
607
|
-
: (metrics.viewHeight||1);
|
|
608
|
-
var scrollX=typeof fallback.scroll_x==='number'?fallback.scroll_x:metrics.scrollX;
|
|
609
|
-
var scrollY=typeof fallback.scroll_y==='number'?fallback.scroll_y:metrics.scrollY;
|
|
610
|
-
return {
|
|
611
|
-
x:(fallback.x_percent/100)*viewW+scrollX,
|
|
612
|
-
y:(fallback.y_percent/100)*viewH+scrollY
|
|
613
|
-
};
|
|
614
|
-
}
|
|
615
|
-
return null;
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
function getAnchorClientPoint(el,payload){
|
|
619
|
-
var rect=el.getBoundingClientRect();
|
|
620
|
-
var safeW=Math.max(2,rect.width||2);
|
|
621
|
-
var safeH=Math.max(2,rect.height||2);
|
|
622
|
-
var relX=0.5;
|
|
623
|
-
var relY=0.5;
|
|
624
|
-
var fallback=payload&&payload.coord_fallback;
|
|
625
|
-
if(fallback&&typeof fallback.element_x_percent==='number'){
|
|
626
|
-
relX=clampPercent(fallback.element_x_percent)/100;
|
|
627
|
-
}
|
|
628
|
-
if(fallback&&typeof fallback.element_y_percent==='number'){
|
|
629
|
-
relY=clampPercent(fallback.element_y_percent)/100;
|
|
630
|
-
}
|
|
631
|
-
return {
|
|
632
|
-
clientX:rect.left+Math.max(1,Math.min(safeW-1,safeW*relX)),
|
|
633
|
-
clientY:rect.top+Math.max(1,Math.min(safeH-1,safeH*relY))
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
function siblingPathDistance(el,path){
|
|
638
|
-
if(!Array.isArray(path)||path.length===0) return 0;
|
|
639
|
-
var current=getSiblingPath(el);
|
|
640
|
-
var maxLen=Math.max(current.length,path.length);
|
|
641
|
-
var dist=Math.abs(current.length-path.length)*5;
|
|
642
|
-
var cOffset=maxLen-current.length;
|
|
643
|
-
var pOffset=maxLen-path.length;
|
|
644
|
-
for(var i=0;i<maxLen;i++){
|
|
645
|
-
var cVal=current[i-cOffset];
|
|
646
|
-
var pVal=path[i-pOffset];
|
|
647
|
-
if(typeof cVal==='number'&&typeof pVal==='number'){
|
|
648
|
-
dist+=Math.abs(cVal-pVal);
|
|
649
|
-
}else{
|
|
650
|
-
dist+=2;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
return dist;
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
function getReactFiberNode(el){
|
|
657
|
-
if(!el||typeof el!=='object') return null;
|
|
658
|
-
try{
|
|
659
|
-
var keys=Object.keys(el);
|
|
660
|
-
for(var i=0;i<keys.length;i++){
|
|
661
|
-
var key=keys[i];
|
|
662
|
-
if(key.indexOf('__reactFiber$')===0||key.indexOf('__reactInternalInstance$')===0){
|
|
663
|
-
return el[key];
|
|
664
|
-
}
|
|
665
|
-
}
|
|
666
|
-
}catch(e){}
|
|
667
|
-
return null;
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
function getReactFiberName(fiber){
|
|
671
|
-
try{
|
|
672
|
-
if(!fiber) return '';
|
|
673
|
-
var t=fiber.type||fiber.elementType;
|
|
674
|
-
if(typeof t==='string') return t;
|
|
675
|
-
if(t&&typeof t.displayName==='string'&&t.displayName) return t.displayName;
|
|
676
|
-
if(t&&typeof t.name==='string'&&t.name) return t.name;
|
|
677
|
-
}catch(e){}
|
|
678
|
-
return '';
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
function getReactOwnerPath(el){
|
|
682
|
-
var fiber=getReactFiberNode(el);
|
|
683
|
-
if(!fiber) return [];
|
|
684
|
-
var path=[];
|
|
685
|
-
var current=fiber;
|
|
686
|
-
var steps=0;
|
|
687
|
-
while(current&&steps<24){
|
|
688
|
-
var name=getReactFiberName(current);
|
|
689
|
-
if(name){
|
|
690
|
-
var keyVal=current.key!=null?String(current.key):'';
|
|
691
|
-
path.push(keyVal?name+'#'+keyVal:name);
|
|
692
|
-
}
|
|
693
|
-
current=current.return||null;
|
|
694
|
-
steps++;
|
|
695
|
-
}
|
|
696
|
-
path.reverse();
|
|
697
|
-
if(path.length>12){
|
|
698
|
-
path=path.slice(path.length-12);
|
|
699
|
-
}
|
|
700
|
-
return path;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
function getExplicitAnchorId(el){
|
|
704
|
-
if(!el||typeof el.closest!=='function') return '';
|
|
705
|
-
var holder=el.closest('[data-checkpoint-anchor]');
|
|
706
|
-
if(!holder||!holder.getAttribute) return '';
|
|
707
|
-
return holder.getAttribute('data-checkpoint-anchor')||'';
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
function getSourceAnchor(el){
|
|
711
|
-
var fiber=getReactFiberNode(el);
|
|
712
|
-
var ownerPath=getReactOwnerPath(el);
|
|
713
|
-
var source=getSourceDebugInfo(fiber);
|
|
714
|
-
var component=getReactFiberName(fiber);
|
|
715
|
-
var explicitId=getExplicitAnchorId(el);
|
|
716
|
-
var reactKey=fiber&&fiber.key!=null?String(fiber.key):'';
|
|
717
|
-
var hasData=!!(explicitId||component||ownerPath.length>0||source||reactKey);
|
|
718
|
-
if(!hasData) return null;
|
|
719
|
-
return {
|
|
720
|
-
explicit_id:explicitId||undefined,
|
|
721
|
-
component_name:component||undefined,
|
|
722
|
-
owner_path:ownerPath,
|
|
723
|
-
source_file:source&&source.fileName?String(source.fileName):undefined,
|
|
724
|
-
source_line:source&&typeof source.lineNumber==='number'?source.lineNumber:undefined,
|
|
725
|
-
source_column:source&&typeof source.columnNumber==='number'?source.columnNumber:undefined,
|
|
726
|
-
react_key:reactKey||undefined,
|
|
727
|
-
host_tag:el&&el.tagName?String(el.tagName).toLowerCase():undefined
|
|
728
|
-
};
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
function getSourceAnchorStrength(anchor){
|
|
732
|
-
if(!anchor||typeof anchor!=='object') return 0;
|
|
733
|
-
var score=0;
|
|
734
|
-
if(anchor.explicit_id) score+=2000;
|
|
735
|
-
if(anchor.react_key) score+=400;
|
|
736
|
-
if(anchor.source_file) score+=420;
|
|
737
|
-
if(typeof anchor.source_line==='number') score+=260;
|
|
738
|
-
if(anchor.component_name) score+=160;
|
|
739
|
-
if(Array.isArray(anchor.owner_path)&&anchor.owner_path.length>0){
|
|
740
|
-
score+=Math.min(220,anchor.owner_path.length*28);
|
|
741
|
-
}
|
|
742
|
-
return score;
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
function findBestSourceAnchorTarget(el){
|
|
746
|
-
if(!el||el.nodeType!==1) return { element:el, sourceAnchor:null };
|
|
747
|
-
var current=el;
|
|
748
|
-
var bestEl=el;
|
|
749
|
-
var bestAnchor=null;
|
|
750
|
-
var bestScore=0;
|
|
751
|
-
var depth=0;
|
|
752
|
-
while(current&¤t.nodeType===1&&depth<12){
|
|
753
|
-
var anchor=getSourceAnchor(current);
|
|
754
|
-
var score=getSourceAnchorStrength(anchor);
|
|
755
|
-
if(score>bestScore){
|
|
756
|
-
bestScore=score;
|
|
757
|
-
bestAnchor=anchor;
|
|
758
|
-
bestEl=current;
|
|
759
|
-
}
|
|
760
|
-
if(anchor&&anchor.explicit_id){
|
|
761
|
-
return { element:current, sourceAnchor:anchor };
|
|
762
|
-
}
|
|
763
|
-
current=current.parentElement;
|
|
764
|
-
depth++;
|
|
765
|
-
}
|
|
766
|
-
return { element:bestEl, sourceAnchor:bestAnchor };
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
function ownerPathSuffixMatches(current,expected){
|
|
770
|
-
if(!Array.isArray(current)||!Array.isArray(expected)||current.length===0||expected.length===0) return 0;
|
|
771
|
-
var i=current.length-1;
|
|
772
|
-
var j=expected.length-1;
|
|
773
|
-
var matches=0;
|
|
774
|
-
while(i>=0&&j>=0){
|
|
775
|
-
if(current[i]!==expected[j]) break;
|
|
776
|
-
matches++;
|
|
777
|
-
i--;
|
|
778
|
-
j--;
|
|
779
|
-
}
|
|
780
|
-
return matches;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
function sourceMatchScore(node,sourceAnchor){
|
|
784
|
-
if(!sourceAnchor||typeof sourceAnchor!=='object') return 0;
|
|
785
|
-
var score=0;
|
|
786
|
-
var explicit=getExplicitAnchorId(node);
|
|
787
|
-
if(sourceAnchor.explicit_id){
|
|
788
|
-
if(explicit===sourceAnchor.explicit_id) score+=1400;
|
|
789
|
-
else if(explicit) score-=300;
|
|
790
|
-
}
|
|
791
|
-
var fiber=getReactFiberNode(node);
|
|
792
|
-
if(fiber){
|
|
793
|
-
var component=getReactFiberName(fiber);
|
|
794
|
-
if(sourceAnchor.component_name&&component===sourceAnchor.component_name){
|
|
795
|
-
score+=180;
|
|
796
|
-
}
|
|
797
|
-
if(sourceAnchor.react_key&&fiber.key!=null&&String(fiber.key)===sourceAnchor.react_key){
|
|
798
|
-
score+=260;
|
|
799
|
-
}
|
|
800
|
-
var currentPath=getReactOwnerPath(node);
|
|
801
|
-
var suffix=ownerPathSuffixMatches(currentPath,sourceAnchor.owner_path);
|
|
802
|
-
if(suffix>0){
|
|
803
|
-
score+=suffix*80;
|
|
804
|
-
}
|
|
805
|
-
var source=getSourceDebugInfo(fiber);
|
|
806
|
-
if(source&&sourceAnchor.source_file){
|
|
807
|
-
var currentFile=String(source.fileName||'');
|
|
808
|
-
var targetFile=String(sourceAnchor.source_file||'');
|
|
809
|
-
if(currentFile===targetFile){
|
|
810
|
-
score+=260;
|
|
811
|
-
if(typeof sourceAnchor.source_line==='number'&&source.lineNumber===sourceAnchor.source_line){
|
|
812
|
-
score+=280;
|
|
813
|
-
}
|
|
814
|
-
if(typeof sourceAnchor.source_column==='number'&&source.columnNumber===sourceAnchor.source_column){
|
|
815
|
-
score+=60;
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
}
|
|
820
|
-
if(sourceAnchor.host_tag&&node&&node.tagName&&String(node.tagName).toLowerCase()===sourceAnchor.host_tag){
|
|
821
|
-
score+=35;
|
|
822
|
-
}
|
|
823
|
-
return score;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
function textMatchScore(node,payload){
|
|
827
|
-
if(!payload||!payload.text_context) return 0;
|
|
828
|
-
var tc=payload.text_context;
|
|
829
|
-
var selfText=getVisibleText(node);
|
|
830
|
-
var parentText=node.parentElement?getVisibleText(node.parentElement):'';
|
|
831
|
-
var bonus=0;
|
|
832
|
-
if(tc.self&&selfText&&tc.self.length>2){
|
|
833
|
-
if(selfText===tc.self.toLowerCase()) bonus+=200;
|
|
834
|
-
else if(selfText.indexOf(tc.self.toLowerCase())>=0||tc.self.toLowerCase().indexOf(selfText)>=0) bonus+=80;
|
|
835
|
-
}
|
|
836
|
-
if(tc.parent&&parentText&&tc.parent.length>2){
|
|
837
|
-
if(parentText===tc.parent.toLowerCase()) bonus+=100;
|
|
838
|
-
else if(parentText.indexOf(tc.parent.toLowerCase())>=0||tc.parent.toLowerCase().indexOf(parentText)>=0) bonus+=40;
|
|
839
|
-
}
|
|
840
|
-
return bonus;
|
|
841
|
-
}
|
|
842
|
-
|
|
843
|
-
function pickBestElement(nodes,payload,metrics,fingerprintPath){
|
|
844
|
-
if(!nodes||nodes.length===0) return { element:null, bestScore:Infinity };
|
|
845
|
-
var target=getTargetDocPoint(payload,metrics);
|
|
846
|
-
var best=null;
|
|
847
|
-
var bestScore=Infinity;
|
|
848
|
-
for(var i=0;i<nodes.length;i++){
|
|
849
|
-
var node=nodes[i];
|
|
850
|
-
if(!node||node.nodeType!==1) continue;
|
|
851
|
-
var anchorPoint=getAnchorClientPoint(node,payload);
|
|
852
|
-
var docX=anchorPoint.clientX+metrics.scrollX;
|
|
853
|
-
var docY=anchorPoint.clientY+metrics.scrollY;
|
|
854
|
-
var score=0;
|
|
855
|
-
if(target){
|
|
856
|
-
var dx=docX-target.x;
|
|
857
|
-
var dy=docY-target.y;
|
|
858
|
-
score+=Math.sqrt(dx*dx+dy*dy);
|
|
859
|
-
}
|
|
860
|
-
if(Array.isArray(fingerprintPath)&&fingerprintPath.length>0){
|
|
861
|
-
score+=siblingPathDistance(node,fingerprintPath)*40;
|
|
862
|
-
}
|
|
863
|
-
var tBonus=textMatchScore(node,payload);
|
|
864
|
-
score=Math.max(0,score-tBonus);
|
|
865
|
-
if(score<bestScore){
|
|
866
|
-
best=node;
|
|
867
|
-
bestScore=score;
|
|
868
|
-
}
|
|
869
|
-
}
|
|
870
|
-
if(!best) return { element:null, bestScore:Infinity };
|
|
871
|
-
return { element:best, bestScore:bestScore };
|
|
872
|
-
}
|
|
873
|
-
|
|
874
|
-
function querySelectorAllSafe(scope,selector){
|
|
875
|
-
if(!scope||!selector) return [];
|
|
876
|
-
try{
|
|
877
|
-
var nodeList=scope.querySelectorAll(selector);
|
|
878
|
-
return nodeList?Array.prototype.slice.call(nodeList):[];
|
|
879
|
-
}catch(e){}
|
|
880
|
-
return [];
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
function resolveFromFingerprint(fingerprint,payload,metrics,scope){
|
|
884
|
-
if(!fingerprint) return { element:null, bestScore:Infinity };
|
|
885
|
-
var searchScope=scope||document;
|
|
886
|
-
if(fingerprint.id){
|
|
887
|
-
var byId=searchScope.getElementById?searchScope.getElementById(fingerprint.id):null;
|
|
888
|
-
if(!byId&&searchScope.querySelector){
|
|
889
|
-
try{ byId=searchScope.querySelector('#'+cssEscape(fingerprint.id)); }catch(e){}
|
|
890
|
-
}
|
|
891
|
-
if(byId) return { element:byId, bestScore:0 };
|
|
892
|
-
}
|
|
893
|
-
var tag=fingerprint.tag||'*';
|
|
894
|
-
var selector=tag;
|
|
895
|
-
if(Array.isArray(fingerprint.classes)&&fingerprint.classes.length>0){
|
|
896
|
-
selector+= '.'+fingerprint.classes.map(cssEscape).join('.');
|
|
897
|
-
}
|
|
898
|
-
var nodes=querySelectorAllSafe(searchScope,selector);
|
|
899
|
-
return pickBestElement(nodes,payload,metrics,fingerprint.sibling_path);
|
|
900
|
-
}
|
|
901
|
-
|
|
902
|
-
function resolveFromSourceAnchor(sourceAnchor,payload,metrics,scope){
|
|
903
|
-
if(!sourceAnchor||typeof sourceAnchor!=='object'){
|
|
904
|
-
return { element:null, score:0 };
|
|
905
|
-
}
|
|
906
|
-
var searchScope=scope||document;
|
|
907
|
-
var best=null;
|
|
908
|
-
var bestScore=0;
|
|
909
|
-
var target=getTargetDocPoint(payload,metrics);
|
|
910
|
-
|
|
911
|
-
function consider(nodes){
|
|
912
|
-
for(var i=0;i<nodes.length;i++){
|
|
913
|
-
var node=nodes[i];
|
|
914
|
-
if(!node||node.nodeType!==1) continue;
|
|
915
|
-
var score=sourceMatchScore(node,sourceAnchor);
|
|
916
|
-
if(score<=0) continue;
|
|
917
|
-
if(target){
|
|
918
|
-
var point=getAnchorClientPoint(node,payload);
|
|
919
|
-
var dx=(point.clientX+metrics.scrollX)-target.x;
|
|
920
|
-
var dy=(point.clientY+metrics.scrollY)-target.y;
|
|
921
|
-
var dist=Math.sqrt(dx*dx+dy*dy);
|
|
922
|
-
score-=Math.min(280,dist*0.7);
|
|
923
|
-
}
|
|
924
|
-
if(score>bestScore){
|
|
925
|
-
best=node;
|
|
926
|
-
bestScore=score;
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
}
|
|
930
|
-
|
|
931
|
-
if(sourceAnchor.explicit_id){
|
|
932
|
-
var explicitNodes=querySelectorAllSafe(searchScope,'[data-checkpoint-anchor=\"'+cssEscape(sourceAnchor.explicit_id)+'\"]');
|
|
933
|
-
consider(explicitNodes);
|
|
934
|
-
if(!best&&searchScope!==document){
|
|
935
|
-
consider(querySelectorAllSafe(document,'[data-checkpoint-anchor=\"'+cssEscape(sourceAnchor.explicit_id)+'\"]'));
|
|
936
|
-
}
|
|
937
|
-
if(best){
|
|
938
|
-
return { element:best, score:bestScore };
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
var tag=sourceAnchor.host_tag||((payload.dom_fingerprint&&payload.dom_fingerprint.tag)||'*');
|
|
943
|
-
var nodes=querySelectorAllSafe(searchScope,tag);
|
|
944
|
-
if(nodes.length>1800){
|
|
945
|
-
nodes=nodes.slice(0,1800);
|
|
946
|
-
}
|
|
947
|
-
consider(nodes);
|
|
948
|
-
if(!best&&searchScope!==document){
|
|
949
|
-
var docNodes=querySelectorAllSafe(document,tag);
|
|
950
|
-
if(docNodes.length>1800){
|
|
951
|
-
docNodes=docNodes.slice(0,1800);
|
|
952
|
-
}
|
|
953
|
-
consider(docNodes);
|
|
954
|
-
}
|
|
955
|
-
var minScore=160;
|
|
956
|
-
if(sourceAnchor.explicit_id) minScore=900;
|
|
957
|
-
else if(sourceAnchor.source_file) minScore=260;
|
|
958
|
-
if(bestScore<minScore){
|
|
959
|
-
return { element:null, score:bestScore };
|
|
960
|
-
}
|
|
961
|
-
return { element:best, score:bestScore };
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
function isStrongContainerHint(hint){
|
|
965
|
-
if(!hint||typeof hint!=='object') return false;
|
|
966
|
-
if(typeof hint.id==='string'&&hint.id.length>0) return true;
|
|
967
|
-
if(typeof hint.selector==='string'){
|
|
968
|
-
if(hint.selector.indexOf('#')===0) return true;
|
|
969
|
-
if(hint.selector.indexOf('[data-testid')>=0) return true;
|
|
970
|
-
if(hint.selector.indexOf('[role=')>=0) return true;
|
|
971
|
-
}
|
|
972
|
-
return false;
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
function resolveTransientRoot(payload,metrics){
|
|
976
|
-
var transient=payload&&payload.transient_context;
|
|
977
|
-
if(!transient||typeof transient!=='object') return null;
|
|
978
|
-
var root=null;
|
|
979
|
-
if(Array.isArray(transient.root_selector_chain)){
|
|
980
|
-
for(var i=0;i<transient.root_selector_chain.length;i++){
|
|
981
|
-
var candidate=transient.root_selector_chain[i];
|
|
982
|
-
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
983
|
-
var nodes=querySelectorAllSafe(document,candidate.selector);
|
|
984
|
-
var rootMatch=pickBestElement(nodes,payload,metrics,transient.root_fingerprint&&transient.root_fingerprint.sibling_path);
|
|
985
|
-
root=rootMatch.element;
|
|
986
|
-
if(root) return root;
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document).element;
|
|
990
|
-
return root;
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
function resolveAnchor(payload){
|
|
994
|
-
if(!payload||typeof payload!=='object') return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
995
|
-
var metrics=getMetrics();
|
|
996
|
-
var transientRoot=null;
|
|
997
|
-
var hasTransientContext=!!(payload.transient_context&&typeof payload.transient_context==='object');
|
|
998
|
-
if(hasTransientContext){
|
|
999
|
-
transientRoot=resolveTransientRoot(payload,metrics);
|
|
1000
|
-
if(!transientRoot){
|
|
1001
|
-
return {coordFallback:null,strategy:'transient_missing',matchedSelector:null,status:'transient_missing'};
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
|
|
1005
|
-
if(!payload.source_anchor){
|
|
1006
|
-
if(payload.coord_fallback){
|
|
1007
|
-
return {
|
|
1008
|
-
coordFallback:payload.coord_fallback,
|
|
1009
|
-
strategy:'fallback',
|
|
1010
|
-
matchedSelector:'legacy_coord_fallback',
|
|
1011
|
-
status:'fallback_only'
|
|
1012
|
-
};
|
|
1013
|
-
}
|
|
1014
|
-
return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
1015
|
-
}
|
|
1016
|
-
|
|
1017
|
-
var sourceScope=transientRoot||document;
|
|
1018
|
-
var sourceMatch=resolveFromSourceAnchor(payload.source_anchor,payload,metrics,sourceScope);
|
|
1019
|
-
if(!sourceMatch||!sourceMatch.element){
|
|
1020
|
-
return {coordFallback:null,strategy:'fallback',matchedSelector:'source_anchor_miss',status:'fallback_only'};
|
|
1021
|
-
}
|
|
1022
|
-
var point=getAnchorClientPoint(sourceMatch.element,payload);
|
|
1023
|
-
var clientX=point.clientX;
|
|
1024
|
-
var clientY=point.clientY;
|
|
1025
|
-
return {
|
|
1026
|
-
coordFallback:buildCoordFallback(clientX,clientY,metrics),
|
|
1027
|
-
strategy:'source',
|
|
1028
|
-
matchedSelector:'source_anchor',
|
|
1029
|
-
status:'resolved'
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
|
|
1033
|
-
function setPickMode(enabled){
|
|
1034
|
-
var next=!!enabled;
|
|
1035
|
-
if(pickMode===next) return;
|
|
1036
|
-
pickMode=next;
|
|
1037
|
-
document.documentElement.style.cursor=pickMode?'crosshair':'';
|
|
1038
|
-
if(document.body){
|
|
1039
|
-
document.body.style.cursor=pickMode?'crosshair':'';
|
|
1040
|
-
}
|
|
1041
|
-
if(!pickMode){
|
|
1042
|
-
if(pickClickHandler){
|
|
1043
|
-
window.removeEventListener('click',pickClickHandler,true);
|
|
1044
|
-
pickClickHandler=null;
|
|
1045
|
-
}
|
|
1046
|
-
if(pickPointerDownHandler){
|
|
1047
|
-
window.removeEventListener('pointerdown',pickPointerDownHandler,true);
|
|
1048
|
-
pickPointerDownHandler=null;
|
|
1049
|
-
}
|
|
1050
|
-
if(pickMoveHandler){
|
|
1051
|
-
document.removeEventListener('mousemove',pickMoveHandler,true);
|
|
1052
|
-
pickMoveHandler=null;
|
|
1053
|
-
}
|
|
1054
|
-
if(pickEscHandler){
|
|
1055
|
-
window.removeEventListener('keydown',pickEscHandler,true);
|
|
1056
|
-
pickEscHandler=null;
|
|
1057
|
-
}
|
|
1058
|
-
if(pickHoverRaf){
|
|
1059
|
-
cancelAnimationFrame(pickHoverRaf);
|
|
1060
|
-
pickHoverRaf=0;
|
|
1061
|
-
}
|
|
1062
|
-
hidePickInspectUi();
|
|
1063
|
-
return;
|
|
1064
|
-
}
|
|
1065
|
-
pickMoveHandler=function(ev){
|
|
1066
|
-
if(!pickMode) return;
|
|
1067
|
-
pickLastMouseX=ev.clientX;
|
|
1068
|
-
pickLastMouseY=ev.clientY;
|
|
1069
|
-
if(pickHoverRaf) return;
|
|
1070
|
-
pickHoverRaf=requestAnimationFrame(function(){
|
|
1071
|
-
pickHoverRaf=0;
|
|
1072
|
-
var target=getElementAtPoint(pickLastMouseX,pickLastMouseY)||getEventElement(ev);
|
|
1073
|
-
renderPickInspect(target,pickLastMouseX,pickLastMouseY);
|
|
1074
|
-
});
|
|
1075
|
-
};
|
|
1076
|
-
pickPointerDownHandler=function(ev){
|
|
1077
|
-
if(!pickMode) return;
|
|
1078
|
-
var target=getElementAtPoint(ev.clientX,ev.clientY)||getEventElement(ev);
|
|
1079
|
-
if(!target) return;
|
|
1080
|
-
ev.preventDefault();
|
|
1081
|
-
ev.stopPropagation();
|
|
1082
|
-
if(typeof ev.stopImmediatePropagation==='function'){
|
|
1083
|
-
ev.stopImmediatePropagation();
|
|
1084
|
-
}
|
|
1085
|
-
try{
|
|
1086
|
-
var payload=buildAnchorPayload(target,ev.clientX,ev.clientY);
|
|
1087
|
-
window.parent.postMessage({
|
|
1088
|
-
type:'checkpoint:pickResult',
|
|
1089
|
-
path:location.pathname+location.search+location.hash,
|
|
1090
|
-
anchorPayload:payload,
|
|
1091
|
-
point:{
|
|
1092
|
-
xPercent:payload.coord_fallback&&typeof payload.coord_fallback.x_percent==='number'?payload.coord_fallback.x_percent:50,
|
|
1093
|
-
yPercent:payload.coord_fallback&&typeof payload.coord_fallback.y_percent==='number'?payload.coord_fallback.y_percent:50,
|
|
1094
|
-
scrollY:payload.coord_fallback&&typeof payload.coord_fallback.scroll_y==='number'?payload.coord_fallback.scroll_y:0,
|
|
1095
|
-
viewHeight:payload.coord_fallback&&typeof payload.coord_fallback.viewport_height==='number'?payload.coord_fallback.viewport_height:0
|
|
1096
|
-
}
|
|
1097
|
-
},'*');
|
|
1098
|
-
}catch(e){}
|
|
1099
|
-
setPickMode(false);
|
|
1100
|
-
};
|
|
1101
|
-
pickClickHandler=function(ev){
|
|
1102
|
-
try{
|
|
1103
|
-
if(!pickMode) return;
|
|
1104
|
-
ev.preventDefault();
|
|
1105
|
-
ev.stopPropagation();
|
|
1106
|
-
if(typeof ev.stopImmediatePropagation==='function'){
|
|
1107
|
-
ev.stopImmediatePropagation();
|
|
1108
|
-
}
|
|
1109
|
-
var target=getEventElement(ev);
|
|
1110
|
-
if(!target) return;
|
|
1111
|
-
var payload=buildAnchorPayload(target,ev.clientX,ev.clientY);
|
|
1112
|
-
window.parent.postMessage({
|
|
1113
|
-
type:'checkpoint:pickResult',
|
|
1114
|
-
path:location.pathname+location.search+location.hash,
|
|
1115
|
-
anchorPayload:payload,
|
|
1116
|
-
point:{
|
|
1117
|
-
xPercent:payload.coord_fallback&&typeof payload.coord_fallback.x_percent==='number'?payload.coord_fallback.x_percent:50,
|
|
1118
|
-
yPercent:payload.coord_fallback&&typeof payload.coord_fallback.y_percent==='number'?payload.coord_fallback.y_percent:50,
|
|
1119
|
-
scrollY:payload.coord_fallback&&typeof payload.coord_fallback.scroll_y==='number'?payload.coord_fallback.scroll_y:0,
|
|
1120
|
-
viewHeight:payload.coord_fallback&&typeof payload.coord_fallback.viewport_height==='number'?payload.coord_fallback.viewport_height:0
|
|
1121
|
-
}
|
|
1122
|
-
},'*');
|
|
1123
|
-
}catch(e){}
|
|
1124
|
-
setPickMode(false);
|
|
1125
|
-
};
|
|
1126
|
-
pickEscHandler=function(ev){
|
|
1127
|
-
if(ev.key==='Escape'){
|
|
1128
|
-
setPickMode(false);
|
|
1129
|
-
}
|
|
1130
|
-
};
|
|
1131
|
-
document.addEventListener('mousemove',pickMoveHandler,true);
|
|
1132
|
-
window.addEventListener('pointerdown',pickPointerDownHandler,true);
|
|
1133
|
-
window.addEventListener('click',pickClickHandler,true);
|
|
1134
|
-
window.addEventListener('keydown',pickEscHandler,true);
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
function reportNav(){
|
|
1138
|
-
try{
|
|
1139
|
-
var p=location.pathname+location.search+location.hash;
|
|
1140
|
-
if(p!==lastPath){
|
|
1141
|
-
lastPath=p;
|
|
1142
|
-
window.parent.postMessage({
|
|
1143
|
-
type:'checkpoint:navigate',
|
|
1144
|
-
path:p
|
|
1145
|
-
},'*');
|
|
1146
|
-
reportScroll();
|
|
1147
|
-
}
|
|
1148
|
-
}catch(e){}
|
|
1149
|
-
}
|
|
1150
|
-
var scrollTick=false;
|
|
1151
|
-
function reportScroll(){
|
|
1152
|
-
try{
|
|
1153
|
-
var metrics=getMetrics();
|
|
1154
|
-
window.parent.postMessage({
|
|
1155
|
-
type:'checkpoint:scroll',
|
|
1156
|
-
scrollX:metrics.scrollX,
|
|
1157
|
-
scrollY:metrics.scrollY,
|
|
1158
|
-
docWidth:metrics.docWidth,
|
|
1159
|
-
docHeight:metrics.docHeight,
|
|
1160
|
-
viewWidth:metrics.viewWidth,
|
|
1161
|
-
viewHeight:metrics.viewHeight
|
|
1162
|
-
},'*');
|
|
1163
|
-
}catch(e){}
|
|
1164
|
-
}
|
|
1165
|
-
function onScroll(){
|
|
1166
|
-
if(!scrollTick){
|
|
1167
|
-
scrollTick=true;
|
|
1168
|
-
requestAnimationFrame(function(){
|
|
1169
|
-
reportScroll();
|
|
1170
|
-
scrollTick=false;
|
|
1171
|
-
});
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
var mutationTick=false;
|
|
1176
|
-
function reportDomMutation(reason){
|
|
1177
|
-
try{
|
|
1178
|
-
window.parent.postMessage({
|
|
1179
|
-
type:'checkpoint:domMutation',
|
|
1180
|
-
reason:reason||'mutation',
|
|
1181
|
-
path:location.pathname+location.search+location.hash
|
|
1182
|
-
},'*');
|
|
1183
|
-
}catch(e){}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1186
|
-
function onMutation(){
|
|
1187
|
-
if(mutationTick) return;
|
|
1188
|
-
mutationTick=true;
|
|
1189
|
-
requestAnimationFrame(function(){
|
|
1190
|
-
mutationTick=false;
|
|
1191
|
-
reportScroll();
|
|
1192
|
-
reportDomMutation('mutation');
|
|
1193
|
-
});
|
|
1194
|
-
}
|
|
1195
|
-
|
|
1196
|
-
function setupMutationObserver(){
|
|
1197
|
-
try{
|
|
1198
|
-
if(!window.MutationObserver||!document.documentElement) return;
|
|
1199
|
-
var observer=new MutationObserver(function(mutations){
|
|
1200
|
-
for(var i=0;i<mutations.length;i++){
|
|
1201
|
-
var m=mutations[i];
|
|
1202
|
-
if(m.type==='childList'){
|
|
1203
|
-
if((m.addedNodes&&m.addedNodes.length>0)||(m.removedNodes&&m.removedNodes.length>0)){
|
|
1204
|
-
onMutation();
|
|
1205
|
-
return;
|
|
1206
|
-
}
|
|
1207
|
-
}
|
|
1208
|
-
if(m.type==='attributes'){
|
|
1209
|
-
onMutation();
|
|
1210
|
-
return;
|
|
1211
|
-
}
|
|
1212
|
-
}
|
|
1213
|
-
});
|
|
1214
|
-
observer.observe(document.documentElement,{
|
|
1215
|
-
childList:true,
|
|
1216
|
-
subtree:true,
|
|
1217
|
-
attributes:true,
|
|
1218
|
-
attributeFilter:['class','style','aria-hidden','aria-modal','data-state','open']
|
|
1219
|
-
});
|
|
1220
|
-
window.addEventListener('beforeunload',function(){ try{observer.disconnect();}catch(e){}; });
|
|
1221
|
-
}catch(e){}
|
|
1222
|
-
}
|
|
1223
|
-
|
|
1224
|
-
reportNav();
|
|
1225
|
-
reportScroll();
|
|
1226
|
-
setupMutationObserver();
|
|
1227
|
-
var _ps=history.pushState,_rs=history.replaceState;
|
|
1228
|
-
history.pushState=function(){_ps.apply(this,arguments);reportNav();};
|
|
1229
|
-
history.replaceState=function(){_rs.apply(this,arguments);reportNav();};
|
|
1230
|
-
window.addEventListener('popstate',reportNav);
|
|
1231
|
-
window.addEventListener('hashchange',reportNav);
|
|
1232
|
-
window.addEventListener('scroll',onScroll,{passive:true});
|
|
1233
|
-
document.addEventListener('scroll',onScroll,true);
|
|
1234
|
-
window.addEventListener('resize',reportScroll);
|
|
1235
|
-
window.addEventListener('message',function(e){
|
|
1236
|
-
try{
|
|
1237
|
-
if(e.data&&e.data.type==='checkpoint:scrollTo'&&typeof e.data.y==='number'){
|
|
1238
|
-
window.scrollTo({top:e.data.y,behavior:'smooth'});
|
|
1239
|
-
}
|
|
1240
|
-
if(e.data&&e.data.type==='checkpoint:pickMode'){
|
|
1241
|
-
setPickMode(!!e.data.enabled);
|
|
1242
|
-
}
|
|
1243
|
-
if(e.data&&e.data.type==='checkpoint:resolveAnchors'&&Array.isArray(e.data.items)){
|
|
1244
|
-
var positions=[];
|
|
1245
|
-
for(var i=0;i<e.data.items.length;i++){
|
|
1246
|
-
var item=e.data.items[i];
|
|
1247
|
-
if(!item||typeof item.id!=='string') continue;
|
|
1248
|
-
var result=resolveAnchor(item.anchorPayload);
|
|
1249
|
-
positions.push({
|
|
1250
|
-
id:item.id,
|
|
1251
|
-
found:!!result.coordFallback,
|
|
1252
|
-
status:result.status||'none',
|
|
1253
|
-
strategy:result.strategy,
|
|
1254
|
-
matchedSelector:result.matchedSelector,
|
|
1255
|
-
coordFallback:result.coordFallback||null
|
|
1256
|
-
});
|
|
1257
|
-
}
|
|
1258
|
-
window.parent.postMessage({
|
|
1259
|
-
type:'checkpoint:anchorsResolved',
|
|
1260
|
-
path:location.pathname+location.search+location.hash,
|
|
1261
|
-
positions:positions
|
|
1262
|
-
},'*');
|
|
1263
|
-
}
|
|
1264
|
-
}catch(ex){}
|
|
1265
|
-
});
|
|
1266
|
-
setInterval(reportNav,500);
|
|
1267
|
-
})();
|
|
1268
|
-
</script>`.trim();
|
|
1269
|
-
}
|
|
1270
82
|
/* ── Injection Proxy ── */
|
|
1271
83
|
function startInjectionProxy(targetPort) {
|
|
1272
84
|
const scriptBody = (0, tracking_script_minimal_js_1.buildMinimalTrackingScript)().replace(/<\/script/gi, '<\\/script');
|
|
@@ -1606,7 +418,7 @@ const program = new commander_1.Command();
|
|
|
1606
418
|
program
|
|
1607
419
|
.name('checkpoint')
|
|
1608
420
|
.description('Share your localhost with reviewers — get visual feedback directly on the page')
|
|
1609
|
-
.version('0.3.
|
|
421
|
+
.version('0.3.9');
|
|
1610
422
|
// ── checkpoint login ──
|
|
1611
423
|
program
|
|
1612
424
|
.command('login')
|
|
@@ -484,10 +484,10 @@ function buildMinimalTrackingScript() {
|
|
|
484
484
|
inspectBox.style.top='0';
|
|
485
485
|
inspectBox.style.width='0';
|
|
486
486
|
inspectBox.style.height='0';
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
487
|
+
inspectBox.style.border='2px solid #F26522';
|
|
488
|
+
inspectBox.style.background='rgba(242,101,34,0.12)';
|
|
489
|
+
inspectBox.style.boxSizing='border-box';
|
|
490
|
+
inspectBox.style.borderRadius='0';
|
|
491
491
|
inspectBox.style.pointerEvents='none';
|
|
492
492
|
inspectBox.style.zIndex='2147483646';
|
|
493
493
|
inspectBox.style.display='none';
|