checkpoint-cli 0.1.7 → 0.1.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 +238 -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
|
}
|
|
@@ -451,14 +587,35 @@ function trackingScript() {
|
|
|
451
587
|
return dist;
|
|
452
588
|
}
|
|
453
589
|
|
|
590
|
+
function textMatchScore(node,payload){
|
|
591
|
+
if(!payload||!payload.text_context) return 0;
|
|
592
|
+
var tc=payload.text_context;
|
|
593
|
+
var selfText=getVisibleText(node);
|
|
594
|
+
var parentText=node.parentElement?getVisibleText(node.parentElement):'';
|
|
595
|
+
var bonus=0;
|
|
596
|
+
if(tc.self&&selfText&&tc.self.length>2){
|
|
597
|
+
if(selfText===tc.self.toLowerCase()) bonus+=200;
|
|
598
|
+
else if(selfText.indexOf(tc.self.toLowerCase())>=0||tc.self.toLowerCase().indexOf(selfText)>=0) bonus+=80;
|
|
599
|
+
}
|
|
600
|
+
if(tc.parent&&parentText&&tc.parent.length>2){
|
|
601
|
+
if(parentText===tc.parent.toLowerCase()) bonus+=100;
|
|
602
|
+
else if(parentText.indexOf(tc.parent.toLowerCase())>=0||tc.parent.toLowerCase().indexOf(parentText)>=0) bonus+=40;
|
|
603
|
+
}
|
|
604
|
+
return bonus;
|
|
605
|
+
}
|
|
606
|
+
|
|
454
607
|
function pickBestElement(nodes,payload,metrics,fingerprintPath){
|
|
455
|
-
if(!nodes||nodes.length===0) return null;
|
|
608
|
+
if(!nodes||nodes.length===0) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
456
609
|
var target=getTargetDocPoint(payload,metrics);
|
|
457
610
|
var best=null;
|
|
458
611
|
var bestScore=Infinity;
|
|
612
|
+
var secondScore=Infinity;
|
|
613
|
+
var matchCount=0;
|
|
614
|
+
var bestTextBonus=0;
|
|
459
615
|
for(var i=0;i<nodes.length;i++){
|
|
460
616
|
var node=nodes[i];
|
|
461
617
|
if(!node||node.nodeType!==1) continue;
|
|
618
|
+
matchCount++;
|
|
462
619
|
var anchorPoint=getAnchorClientPoint(node,payload);
|
|
463
620
|
var docX=anchorPoint.clientX+metrics.scrollX;
|
|
464
621
|
var docY=anchorPoint.clientY+metrics.scrollY;
|
|
@@ -471,12 +628,27 @@ function trackingScript() {
|
|
|
471
628
|
if(Array.isArray(fingerprintPath)&&fingerprintPath.length>0){
|
|
472
629
|
score+=siblingPathDistance(node,fingerprintPath)*40;
|
|
473
630
|
}
|
|
631
|
+
var tBonus=textMatchScore(node,payload);
|
|
632
|
+
score=Math.max(0,score-tBonus);
|
|
474
633
|
if(score<bestScore){
|
|
634
|
+
secondScore=bestScore;
|
|
475
635
|
best=node;
|
|
476
636
|
bestScore=score;
|
|
637
|
+
bestTextBonus=tBonus;
|
|
638
|
+
}else if(score<secondScore){
|
|
639
|
+
secondScore=score;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if(!best) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
643
|
+
var ambiguous=false;
|
|
644
|
+
if(matchCount>1){
|
|
645
|
+
if(!target&&bestTextBonus===0){
|
|
646
|
+
ambiguous=true;
|
|
647
|
+
}else if((secondScore-bestScore)<30&&bestTextBonus<80){
|
|
648
|
+
ambiguous=true;
|
|
477
649
|
}
|
|
478
650
|
}
|
|
479
|
-
return best;
|
|
651
|
+
return { element:best, ambiguous:ambiguous, bestScore:bestScore };
|
|
480
652
|
}
|
|
481
653
|
|
|
482
654
|
function querySelectorAllSafe(scope,selector){
|
|
@@ -489,14 +661,14 @@ function trackingScript() {
|
|
|
489
661
|
}
|
|
490
662
|
|
|
491
663
|
function resolveFromFingerprint(fingerprint,payload,metrics,scope){
|
|
492
|
-
if(!fingerprint) return null;
|
|
664
|
+
if(!fingerprint) return { element:null, ambiguous:false, bestScore:Infinity };
|
|
493
665
|
var searchScope=scope||document;
|
|
494
666
|
if(fingerprint.id){
|
|
495
667
|
var byId=searchScope.getElementById?searchScope.getElementById(fingerprint.id):null;
|
|
496
668
|
if(!byId&&searchScope.querySelector){
|
|
497
669
|
try{ byId=searchScope.querySelector('#'+cssEscape(fingerprint.id)); }catch(e){}
|
|
498
670
|
}
|
|
499
|
-
if(byId) return byId;
|
|
671
|
+
if(byId) return { element:byId, ambiguous:false, bestScore:0 };
|
|
500
672
|
}
|
|
501
673
|
var tag=fingerprint.tag||'*';
|
|
502
674
|
var selector=tag;
|
|
@@ -527,20 +699,30 @@ function trackingScript() {
|
|
|
527
699
|
var candidate=transient.root_selector_chain[i];
|
|
528
700
|
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
529
701
|
var nodes=querySelectorAllSafe(document,candidate.selector);
|
|
530
|
-
|
|
702
|
+
var rootMatch=pickBestElement(nodes,payload,metrics,transient.root_fingerprint&&transient.root_fingerprint.sibling_path);
|
|
703
|
+
root=rootMatch.element;
|
|
531
704
|
if(root) return root;
|
|
532
705
|
}
|
|
533
706
|
}
|
|
534
|
-
root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document);
|
|
707
|
+
root=resolveFromFingerprint(transient.root_fingerprint,payload,metrics,document).element;
|
|
535
708
|
return root;
|
|
536
709
|
}
|
|
537
710
|
|
|
538
711
|
function resolveAnchor(payload){
|
|
539
712
|
if(!payload||typeof payload!=='object') return {coordFallback:null,strategy:'none',matchedSelector:null,status:'none'};
|
|
713
|
+
if(!viewContextMatches(payload.view_context)){
|
|
714
|
+
return {
|
|
715
|
+
coordFallback:payload.coord_fallback||null,
|
|
716
|
+
strategy:'context_mismatch',
|
|
717
|
+
matchedSelector:null,
|
|
718
|
+
status:'context_mismatch'
|
|
719
|
+
};
|
|
720
|
+
}
|
|
540
721
|
var element=null;
|
|
541
722
|
var strategy='none';
|
|
542
723
|
var matchedSelector=null;
|
|
543
724
|
var metrics=getMetrics();
|
|
725
|
+
var ambiguous=false;
|
|
544
726
|
var transientRoot=null;
|
|
545
727
|
var hasTransientContext=!!(payload.transient_context&&typeof payload.transient_context==='object');
|
|
546
728
|
if(hasTransientContext){
|
|
@@ -557,8 +739,9 @@ function trackingScript() {
|
|
|
557
739
|
if(!candidate||typeof candidate.selector!=='string') continue;
|
|
558
740
|
var nodes=querySelectorAllSafe(scope,candidate.selector);
|
|
559
741
|
var found=pickBestElement(nodes,payload,metrics,null);
|
|
560
|
-
if(found){
|
|
561
|
-
element=found;
|
|
742
|
+
if(found&&found.element){
|
|
743
|
+
element=found.element;
|
|
744
|
+
ambiguous=!!found.ambiguous;
|
|
562
745
|
strategy='selector';
|
|
563
746
|
matchedSelector=(scopeTag?scopeTag+': ':'')+candidate.selector;
|
|
564
747
|
return true;
|
|
@@ -581,28 +764,64 @@ function trackingScript() {
|
|
|
581
764
|
isStrongContainerHint(payload.container_hint)
|
|
582
765
|
){
|
|
583
766
|
var containerNodesInRoot=transientRoot?querySelectorAllSafe(transientRoot,payload.container_hint.selector):[];
|
|
584
|
-
var
|
|
585
|
-
if(!
|
|
767
|
+
var containerMatch=pickBestElement(containerNodesInRoot,payload,metrics,null);
|
|
768
|
+
if(!containerMatch.element){
|
|
586
769
|
var containerNodes=querySelectorAllSafe(document,payload.container_hint.selector);
|
|
587
|
-
|
|
770
|
+
containerMatch=pickBestElement(containerNodes,payload,metrics,null);
|
|
588
771
|
}
|
|
589
|
-
if(
|
|
590
|
-
element=
|
|
772
|
+
if(containerMatch.element){
|
|
773
|
+
element=containerMatch.element;
|
|
774
|
+
ambiguous=!!containerMatch.ambiguous;
|
|
591
775
|
strategy='container';
|
|
592
776
|
matchedSelector=payload.container_hint.selector;
|
|
593
777
|
}
|
|
594
778
|
}
|
|
595
779
|
if(!element){
|
|
596
|
-
var
|
|
597
|
-
if(!
|
|
598
|
-
|
|
780
|
+
var fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,transientRoot||undefined);
|
|
781
|
+
if(!fpMatch.element){
|
|
782
|
+
fpMatch=resolveFromFingerprint(payload.dom_fingerprint,payload,metrics,document);
|
|
599
783
|
}
|
|
600
|
-
if(
|
|
601
|
-
element=
|
|
784
|
+
if(fpMatch.element){
|
|
785
|
+
element=fpMatch.element;
|
|
786
|
+
ambiguous=!!fpMatch.ambiguous;
|
|
602
787
|
strategy='fingerprint';
|
|
603
788
|
}
|
|
604
789
|
}
|
|
790
|
+
if(!element&&payload.scroll_context){
|
|
791
|
+
var fromContainer=getPointFromScrollContext(payload.scroll_context);
|
|
792
|
+
if(fromContainer){
|
|
793
|
+
return {
|
|
794
|
+
coordFallback:buildCoordFallback(fromContainer.clientX,fromContainer.clientY,metrics),
|
|
795
|
+
strategy:'scroll_container',
|
|
796
|
+
matchedSelector:null,
|
|
797
|
+
status:'resolved'
|
|
798
|
+
};
|
|
799
|
+
}
|
|
800
|
+
}
|
|
605
801
|
if(!element) return {coordFallback:null,strategy:'fallback',matchedSelector:null,status:'fallback_only'};
|
|
802
|
+
if(ambiguous){
|
|
803
|
+
return {
|
|
804
|
+
coordFallback:payload.coord_fallback||null,
|
|
805
|
+
strategy:'ambiguous',
|
|
806
|
+
matchedSelector:matchedSelector,
|
|
807
|
+
status:'ambiguous'
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
var target=getTargetDocPoint(payload,metrics);
|
|
811
|
+
if(target){
|
|
812
|
+
var anchorPoint=getAnchorClientPoint(element,payload);
|
|
813
|
+
var distX=(anchorPoint.clientX+metrics.scrollX)-target.x;
|
|
814
|
+
var distY=(anchorPoint.clientY+metrics.scrollY)-target.y;
|
|
815
|
+
var dist=Math.sqrt(distX*distX+distY*distY);
|
|
816
|
+
if(dist>220){
|
|
817
|
+
return {
|
|
818
|
+
coordFallback:payload.coord_fallback||null,
|
|
819
|
+
strategy:'ambiguous',
|
|
820
|
+
matchedSelector:matchedSelector,
|
|
821
|
+
status:'ambiguous'
|
|
822
|
+
};
|
|
823
|
+
}
|
|
824
|
+
}
|
|
606
825
|
var point=getAnchorClientPoint(element,payload);
|
|
607
826
|
var clientX=point.clientX;
|
|
608
827
|
var clientY=point.clientY;
|
|
@@ -758,6 +977,7 @@ function trackingScript() {
|
|
|
758
977
|
window.addEventListener('popstate',reportNav);
|
|
759
978
|
window.addEventListener('hashchange',reportNav);
|
|
760
979
|
window.addEventListener('scroll',onScroll,{passive:true});
|
|
980
|
+
document.addEventListener('scroll',onScroll,true);
|
|
761
981
|
window.addEventListener('resize',reportScroll);
|
|
762
982
|
window.addEventListener('message',function(e){
|
|
763
983
|
try{
|