checkpoint-cli 0.1.7 → 0.1.8
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 +218 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -331,6 +331,140 @@ function trackingScript() {
|
|
|
331
331
|
return null;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
|
+
function getVisibleText(node){
|
|
335
|
+
try{
|
|
336
|
+
if(!node||!node.textContent) return '';
|
|
337
|
+
return shortText(String(node.textContent).replace(/\\s+/g,' ').trim()).toLowerCase();
|
|
338
|
+
}catch(e){}
|
|
339
|
+
return '';
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
function getNavSignature(){
|
|
343
|
+
try{
|
|
344
|
+
var candidates=[];
|
|
345
|
+
var activeSelectors=[
|
|
346
|
+
'[aria-current=\"page\"]',
|
|
347
|
+
'[aria-selected=\"true\"]',
|
|
348
|
+
'[data-state=\"active\"]',
|
|
349
|
+
'.active',
|
|
350
|
+
'.is-active',
|
|
351
|
+
'.selected'
|
|
352
|
+
];
|
|
353
|
+
for(var i=0;i<activeSelectors.length;i++){
|
|
354
|
+
var nodes=document.querySelectorAll(activeSelectors[i]);
|
|
355
|
+
for(var j=0;j<nodes.length&&candidates.length<8;j++){
|
|
356
|
+
var text=getVisibleText(nodes[j]);
|
|
357
|
+
if(text) candidates.push(text);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if(candidates.length===0){
|
|
361
|
+
var heading=document.querySelector('main h1, [role=\"main\"] h1, h1, h2');
|
|
362
|
+
var fallbackText=getVisibleText(heading);
|
|
363
|
+
if(fallbackText) candidates.push(fallbackText);
|
|
364
|
+
}
|
|
365
|
+
if(candidates.length===0) return '';
|
|
366
|
+
return candidates.slice(0,4).join('|');
|
|
367
|
+
}catch(e){}
|
|
368
|
+
return '';
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
function getHeadingSignature(){
|
|
372
|
+
try{
|
|
373
|
+
var heading=document.querySelector('main h1, [role=\"main\"] h1, h1, h2');
|
|
374
|
+
return getVisibleText(heading);
|
|
375
|
+
}catch(e){}
|
|
376
|
+
return '';
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function getViewContext(){
|
|
380
|
+
return {
|
|
381
|
+
nav_signature:getNavSignature()||undefined,
|
|
382
|
+
heading_signature:getHeadingSignature()||undefined
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function viewContextMatches(expected){
|
|
387
|
+
if(!expected||typeof expected!=='object') return true;
|
|
388
|
+
var current=getViewContext();
|
|
389
|
+
if(expected.nav_signature&¤t.nav_signature&&expected.nav_signature!==current.nav_signature){
|
|
390
|
+
return false;
|
|
391
|
+
}
|
|
392
|
+
if(expected.heading_signature&¤t.heading_signature&&expected.heading_signature!==current.heading_signature){
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
function isScrollable(el){
|
|
399
|
+
if(!el||el.nodeType!==1||!window.getComputedStyle) return false;
|
|
400
|
+
try{
|
|
401
|
+
var style=window.getComputedStyle(el);
|
|
402
|
+
var overflowY=String(style.overflowY||'').toLowerCase();
|
|
403
|
+
var overflowX=String(style.overflowX||'').toLowerCase();
|
|
404
|
+
var canScrollY=(overflowY==='auto'||overflowY==='scroll'||overflowY==='overlay')&&(el.scrollHeight-el.clientHeight>1);
|
|
405
|
+
var canScrollX=(overflowX==='auto'||overflowX==='scroll'||overflowX==='overlay')&&(el.scrollWidth-el.clientWidth>1);
|
|
406
|
+
return !!(canScrollX||canScrollY);
|
|
407
|
+
}catch(e){}
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function getNearestScrollContainer(el){
|
|
412
|
+
if(!el) return null;
|
|
413
|
+
var current=el.parentElement;
|
|
414
|
+
var depth=0;
|
|
415
|
+
while(current&&depth<10){
|
|
416
|
+
if(current===document.body||current===document.documentElement) return null;
|
|
417
|
+
if(isScrollable(current)) return current;
|
|
418
|
+
current=current.parentElement;
|
|
419
|
+
depth++;
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function getScrollContext(el,clientX,clientY){
|
|
425
|
+
var container=getNearestScrollContainer(el);
|
|
426
|
+
if(!container) return null;
|
|
427
|
+
var rect=container.getBoundingClientRect?container.getBoundingClientRect():null;
|
|
428
|
+
if(!rect) return null;
|
|
429
|
+
var safeW=Math.max(1,rect.width||1);
|
|
430
|
+
var safeH=Math.max(1,rect.height||1);
|
|
431
|
+
return {
|
|
432
|
+
container_selector_chain:getSelectorChain(container),
|
|
433
|
+
container_fingerprint:getDomFingerprint(container),
|
|
434
|
+
container_x_percent:clampPercent(((clientX-rect.left)/safeW)*100),
|
|
435
|
+
container_y_percent:clampPercent(((clientY-rect.top)/safeH)*100)
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function getPointFromScrollContext(scrollContext){
|
|
440
|
+
if(!scrollContext||typeof scrollContext!=='object') return null;
|
|
441
|
+
var container=null;
|
|
442
|
+
if(Array.isArray(scrollContext.container_selector_chain)){
|
|
443
|
+
for(var i=0;i<scrollContext.container_selector_chain.length;i++){
|
|
444
|
+
var candidate=scrollContext.container_selector_chain[i];
|
|
445
|
+
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
446
|
+
var nodes=querySelectorAllSafe(document,candidate.selector);
|
|
447
|
+
var match=pickBestElement(nodes,{coord_fallback:null},getMetrics(),null);
|
|
448
|
+
if(match&&match.element){
|
|
449
|
+
container=match.element;
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
if(!container&&scrollContext.container_fingerprint){
|
|
455
|
+
var fp=resolveFromFingerprint(scrollContext.container_fingerprint,{coord_fallback:null},getMetrics(),document);
|
|
456
|
+
container=fp&&fp.element?fp.element:null;
|
|
457
|
+
}
|
|
458
|
+
if(!container||!container.getBoundingClientRect) return null;
|
|
459
|
+
var rect=container.getBoundingClientRect();
|
|
460
|
+
var relX=typeof scrollContext.container_x_percent==='number'?clampPercent(scrollContext.container_x_percent)/100:0.5;
|
|
461
|
+
var relY=typeof scrollContext.container_y_percent==='number'?clampPercent(scrollContext.container_y_percent)/100:0.5;
|
|
462
|
+
return {
|
|
463
|
+
clientX:rect.left+(rect.width*relX),
|
|
464
|
+
clientY:rect.top+(rect.height*relY)
|
|
465
|
+
};
|
|
466
|
+
}
|
|
467
|
+
|
|
334
468
|
function buildCoordFallback(clientX,clientY,metrics){
|
|
335
469
|
var safeViewW=metrics.viewWidth||1;
|
|
336
470
|
var safeViewH=metrics.viewHeight||1;
|
|
@@ -377,6 +511,8 @@ function trackingScript() {
|
|
|
377
511
|
},
|
|
378
512
|
container_hint:getContainerHint(el),
|
|
379
513
|
transient_context:getTransientContext(el),
|
|
514
|
+
view_context:getViewContext(),
|
|
515
|
+
scroll_context:getScrollContext(el,clientX,clientY),
|
|
380
516
|
coord_fallback:fallback
|
|
381
517
|
};
|
|
382
518
|
}
|
|
@@ -452,13 +588,16 @@ function trackingScript() {
|
|
|
452
588
|
}
|
|
453
589
|
|
|
454
590
|
function pickBestElement(nodes,payload,metrics,fingerprintPath){
|
|
455
|
-
if(!nodes||nodes.length===0) return null;
|
|
591
|
+
if(!nodes||nodes.length===0) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
456
592
|
var target=getTargetDocPoint(payload,metrics);
|
|
457
593
|
var best=null;
|
|
458
594
|
var bestScore=Infinity;
|
|
595
|
+
var secondScore=Infinity;
|
|
596
|
+
var matchCount=0;
|
|
459
597
|
for(var i=0;i<nodes.length;i++){
|
|
460
598
|
var node=nodes[i];
|
|
461
599
|
if(!node||node.nodeType!==1) continue;
|
|
600
|
+
matchCount++;
|
|
462
601
|
var anchorPoint=getAnchorClientPoint(node,payload);
|
|
463
602
|
var docX=anchorPoint.clientX+metrics.scrollX;
|
|
464
603
|
var docY=anchorPoint.clientY+metrics.scrollY;
|
|
@@ -472,11 +611,23 @@ function trackingScript() {
|
|
|
472
611
|
score+=siblingPathDistance(node,fingerprintPath)*40;
|
|
473
612
|
}
|
|
474
613
|
if(score<bestScore){
|
|
614
|
+
secondScore=bestScore;
|
|
475
615
|
best=node;
|
|
476
616
|
bestScore=score;
|
|
617
|
+
}else if(score<secondScore){
|
|
618
|
+
secondScore=score;
|
|
477
619
|
}
|
|
478
620
|
}
|
|
479
|
-
return
|
|
621
|
+
if(!best) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
622
|
+
var ambiguous=false;
|
|
623
|
+
if(matchCount>1){
|
|
624
|
+
if(!target){
|
|
625
|
+
ambiguous=true;
|
|
626
|
+
}else if((secondScore-bestScore)<18){
|
|
627
|
+
ambiguous=true;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
return { element:best, ambiguous:ambiguous, bestScore:bestScore };
|
|
480
631
|
}
|
|
481
632
|
|
|
482
633
|
function querySelectorAllSafe(scope,selector){
|
|
@@ -489,14 +640,14 @@ function trackingScript() {
|
|
|
489
640
|
}
|
|
490
641
|
|
|
491
642
|
function resolveFromFingerprint(fingerprint,payload,metrics,scope){
|
|
492
|
-
if(!fingerprint) return null;
|
|
643
|
+
if(!fingerprint) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
493
644
|
var searchScope=scope||document;
|
|
494
645
|
if(fingerprint.id){
|
|
495
646
|
var byId=searchScope.getElementById?searchScope.getElementById(fingerprint.id):null;
|
|
496
647
|
if(!byId&&searchScope.querySelector){
|
|
497
648
|
try{ byId=searchScope.querySelector('#'+cssEscape(fingerprint.id)); }catch(e){}
|
|
498
649
|
}
|
|
499
|
-
if(byId) return byId;
|
|
650
|
+
if(byId) return { element:byId, ambiguous:false, bestScore:0 };
|
|
500
651
|
}
|
|
501
652
|
var tag=fingerprint.tag||'*';
|
|
502
653
|
var selector=tag;
|
|
@@ -527,20 +678,30 @@ function trackingScript() {
|
|
|
527
678
|
var candidate=transient.root_selector_chain[i];
|
|
528
679
|
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
529
680
|
var nodes=querySelectorAllSafe(document,candidate.selector);
|
|
530
|
-
|
|
681
|
+
var rootMatch=pickBestElement(nodes,payload,metrics,transient.root_fingerprint&&transient.root_fingerprint.sibling_path);
|
|
682
|
+
root=rootMatch.element;
|
|
531
683
|
if(root) return root;
|
|
532
684
|
}
|
|
533
685
|
}
|
|
534
|
-
root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document);
|
|
686
|
+
root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document).element;
|
|
535
687
|
return root;
|
|
536
688
|
}
|
|
537
689
|
|
|
538
690
|
function resolveAnchor(payload){
|
|
539
691
|
if(!payload||typeof payload!=='object') return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
692
|
+
if(!viewContextMatches(payload.view_context)){
|
|
693
|
+
return {
|
|
694
|
+
coordFallback:payload.coord_fallback||null,
|
|
695
|
+
strategy:'context_mismatch',
|
|
696
|
+
matchedSelector:null,
|
|
697
|
+
status:'context_mismatch'
|
|
698
|
+
};
|
|
699
|
+
}
|
|
540
700
|
var element=null;
|
|
541
701
|
var strategy='none';
|
|
542
702
|
var matchedSelector=null;
|
|
543
703
|
var metrics=getMetrics();
|
|
704
|
+
var ambiguous=false;
|
|
544
705
|
var transientRoot=null;
|
|
545
706
|
var hasTransientContext=!!(payload.transient_context&&typeof payload.transient_context==='object');
|
|
546
707
|
if(hasTransientContext){
|
|
@@ -557,8 +718,9 @@ function trackingScript() {
|
|
|
557
718
|
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
558
719
|
var nodes=querySelectorAllSafe(scope,candidate.selector);
|
|
559
720
|
var found=pickBestElement(nodes,payload,metrics,null);
|
|
560
|
-
if(found){
|
|
561
|
-
element=found;
|
|
721
|
+
if(found&&found.element){
|
|
722
|
+
element=found.element;
|
|
723
|
+
ambiguous=!!found.ambiguous;
|
|
562
724
|
strategy='selector';
|
|
563
725
|
matchedSelector=(scopeTag?scopeTag+': ':'')+candidate.selector;
|
|
564
726
|
return true;
|
|
@@ -581,28 +743,64 @@ function trackingScript() {
|
|
|
581
743
|
isStrongContainerHint(payload.container_hint)
|
|
582
744
|
){
|
|
583
745
|
var containerNodesInRoot=transientRoot?querySelectorAllSafe(transientRoot,payload.container_hint.selector):[];
|
|
584
|
-
var
|
|
585
|
-
if(!
|
|
746
|
+
var containerMatch=pickBestElement(containerNodesInRoot,payload,metrics,null);
|
|
747
|
+
if(!containerMatch.element){
|
|
586
748
|
var containerNodes=querySelectorAllSafe(document,payload.container_hint.selector);
|
|
587
|
-
|
|
749
|
+
containerMatch=pickBestElement(containerNodes,payload,metrics,null);
|
|
588
750
|
}
|
|
589
|
-
if(
|
|
590
|
-
element=
|
|
751
|
+
if(containerMatch.element){
|
|
752
|
+
element=containerMatch.element;
|
|
753
|
+
ambiguous=!!containerMatch.ambiguous;
|
|
591
754
|
strategy='container';
|
|
592
755
|
matchedSelector=payload.container_hint.selector;
|
|
593
756
|
}
|
|
594
757
|
}
|
|
595
758
|
if(!element){
|
|
596
|
-
var
|
|
597
|
-
if(!
|
|
598
|
-
|
|
759
|
+
var fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,transientRoot||undefined);
|
|
760
|
+
if(!fpMatch.element){
|
|
761
|
+
fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,document);
|
|
599
762
|
}
|
|
600
|
-
if(
|
|
601
|
-
element=
|
|
763
|
+
if(fpMatch.element){
|
|
764
|
+
element=fpMatch.element;
|
|
765
|
+
ambiguous=!!fpMatch.ambiguous;
|
|
602
766
|
strategy='fingerprint';
|
|
603
767
|
}
|
|
604
768
|
}
|
|
769
|
+
if(!element&&payload.scroll_context){
|
|
770
|
+
var fromContainer=getPointFromScrollContext(payload.scroll_context);
|
|
771
|
+
if(fromContainer){
|
|
772
|
+
return {
|
|
773
|
+
coordFallback:buildCoordFallback(fromContainer.clientX,fromContainer.clientY,metrics),
|
|
774
|
+
strategy:'scroll_container',
|
|
775
|
+
matchedSelector:null,
|
|
776
|
+
status:'resolved'
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
}
|
|
605
780
|
if(!element) return {coordFallback:null,strategy:'fallback',matchedSelector:null,status:'fallback_only'};
|
|
781
|
+
if(ambiguous){
|
|
782
|
+
return {
|
|
783
|
+
coordFallback:payload.coord_fallback||null,
|
|
784
|
+
strategy:'ambiguous',
|
|
785
|
+
matchedSelector:matchedSelector,
|
|
786
|
+
status:'ambiguous'
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
var target=getTargetDocPoint(payload,metrics);
|
|
790
|
+
if(target){
|
|
791
|
+
var anchorPoint=getAnchorClientPoint(element,payload);
|
|
792
|
+
var distX=(anchorPoint.clientX+metrics.scrollX)-target.x;
|
|
793
|
+
var distY=(anchorPoint.clientY+metrics.scrollY)-target.y;
|
|
794
|
+
var dist=Math.sqrt(distX*distX+distY*distY);
|
|
795
|
+
if(dist>220){
|
|
796
|
+
return {
|
|
797
|
+
coordFallback:payload.coord_fallback||null,
|
|
798
|
+
strategy:'ambiguous',
|
|
799
|
+
matchedSelector:matchedSelector,
|
|
800
|
+
status:'ambiguous'
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
}
|
|
606
804
|
var point=getAnchorClientPoint(element,payload);
|
|
607
805
|
var clientX=point.clientX;
|
|
608
806
|
var clientY=point.clientY;
|
|
@@ -695,6 +893,7 @@ function trackingScript() {
|
|
|
695
893
|
scrollTick=true;
|
|
696
894
|
requestAnimationFrame(function(){
|
|
697
895
|
reportScroll();
|
|
896
|
+
reportDomMutation('scroll');
|
|
698
897
|
scrollTick=false;
|
|
699
898
|
});
|
|
700
899
|
}
|
|
@@ -758,6 +957,7 @@ function trackingScript() {
|
|
|
758
957
|
window.addEventListener('popstate',reportNav);
|
|
759
958
|
window.addEventListener('hashchange',reportNav);
|
|
760
959
|
window.addEventListener('scroll',onScroll,{passive:true});
|
|
960
|
+
document.addEventListener('scroll',onScroll,true);
|
|
761
961
|
window.addEventListener('resize',reportScroll);
|
|
762
962
|
window.addEventListener('message',function(e){
|
|
763
963
|
try{
|