checkpoint-cli 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/tracking-script-minimal.js +233 -69
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -447,7 +447,7 @@ const program = new commander_1.Command();
|
|
|
447
447
|
program
|
|
448
448
|
.name('checkpoint')
|
|
449
449
|
.description('Share your localhost with reviewers — get visual feedback directly on the page.\n\nQuick start:\n 1. checkpoint login Sign in to your Checkpoint account\n 2. checkpoint start -p 3000 Start tunneling and get a share link\n\nReuse a tunnel name to keep the same share URL and preserve all comments.')
|
|
450
|
-
.version('0.
|
|
450
|
+
.version('0.5.0');
|
|
451
451
|
// ── checkpoint login ──
|
|
452
452
|
program
|
|
453
453
|
.command('login')
|
|
@@ -14,7 +14,6 @@ function buildMinimalTrackingScript() {
|
|
|
14
14
|
var lastMouseX=0;
|
|
15
15
|
var lastMouseY=0;
|
|
16
16
|
var inspectBox=null;
|
|
17
|
-
var inspectLabel=null;
|
|
18
17
|
var pickShield=null;
|
|
19
18
|
var lastPath='';
|
|
20
19
|
var mutationTick=false;
|
|
@@ -147,6 +146,214 @@ function buildMinimalTrackingScript() {
|
|
|
147
146
|
return path.slice(-12);
|
|
148
147
|
}
|
|
149
148
|
|
|
149
|
+
function withFrameworkSuffix(path,framework){
|
|
150
|
+
var safePath=Array.isArray(path)?path.slice(0):[];
|
|
151
|
+
if(framework) safePath.push('@fw:'+framework);
|
|
152
|
+
return safePath.slice(-16);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function getVueComponentFromElement(el){
|
|
156
|
+
if(!el||el.nodeType!==1) return null;
|
|
157
|
+
var current=el;
|
|
158
|
+
var depth=0;
|
|
159
|
+
while(current&&depth<8){
|
|
160
|
+
try{
|
|
161
|
+
if(current.__vueParentComponent) return current.__vueParentComponent;
|
|
162
|
+
if(current.__vue__) return current.__vue__;
|
|
163
|
+
if(current.__vnode&¤t.__vnode.component) return current.__vnode.component;
|
|
164
|
+
}catch(e){}
|
|
165
|
+
current=current.parentElement;
|
|
166
|
+
depth++;
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getVueComponentName(instance){
|
|
172
|
+
try{
|
|
173
|
+
if(!instance) return '';
|
|
174
|
+
if(instance.type){
|
|
175
|
+
var t=instance.type;
|
|
176
|
+
if(typeof t.name==='string'&&t.name) return t.name;
|
|
177
|
+
if(typeof t.__name==='string'&&t.__name) return t.__name;
|
|
178
|
+
if(typeof t.displayName==='string'&&t.displayName) return t.displayName;
|
|
179
|
+
}
|
|
180
|
+
if(instance.$options&&typeof instance.$options.name==='string'&&instance.$options.name){
|
|
181
|
+
return instance.$options.name;
|
|
182
|
+
}
|
|
183
|
+
}catch(e){}
|
|
184
|
+
return '';
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function getVueSourceFile(instance){
|
|
188
|
+
try{
|
|
189
|
+
if(!instance) return '';
|
|
190
|
+
if(instance.type&&typeof instance.type.__file==='string'&&instance.type.__file) return instance.type.__file;
|
|
191
|
+
if(instance.$options&&typeof instance.$options.__file==='string'&&instance.$options.__file) return instance.$options.__file;
|
|
192
|
+
}catch(e){}
|
|
193
|
+
return '';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function getVueOwnerPath(instance){
|
|
197
|
+
var path=[];
|
|
198
|
+
var current=instance;
|
|
199
|
+
var steps=0;
|
|
200
|
+
while(current&&steps<24){
|
|
201
|
+
var name=getVueComponentName(current);
|
|
202
|
+
var keyVal='';
|
|
203
|
+
try{
|
|
204
|
+
if(current.vnode&¤t.vnode.key!=null) keyVal=String(current.vnode.key);
|
|
205
|
+
else if(current.$vnode&¤t.$vnode.key!=null) keyVal=String(current.$vnode.key);
|
|
206
|
+
}catch(e){}
|
|
207
|
+
if(name) path.push(keyVal?name+'#'+keyVal:name);
|
|
208
|
+
current=current.parent||current.$parent||null;
|
|
209
|
+
steps++;
|
|
210
|
+
}
|
|
211
|
+
path.reverse();
|
|
212
|
+
return path.slice(-12);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function getVueInstanceKey(instance){
|
|
216
|
+
try{
|
|
217
|
+
if(!instance) return '';
|
|
218
|
+
if(instance.vnode&&instance.vnode.key!=null) return String(instance.vnode.key);
|
|
219
|
+
if(instance.$vnode&&instance.$vnode.key!=null) return String(instance.$vnode.key);
|
|
220
|
+
}catch(e){}
|
|
221
|
+
return '';
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function getSvelteMetaFromElement(el){
|
|
225
|
+
if(!el||el.nodeType!==1) return null;
|
|
226
|
+
var current=el;
|
|
227
|
+
var depth=0;
|
|
228
|
+
while(current&&depth<8){
|
|
229
|
+
try{
|
|
230
|
+
if(current.__svelte_meta) return current.__svelte_meta;
|
|
231
|
+
}catch(e){}
|
|
232
|
+
current=current.parentElement;
|
|
233
|
+
depth++;
|
|
234
|
+
}
|
|
235
|
+
return null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
function basename(path){
|
|
239
|
+
if(!path) return '';
|
|
240
|
+
try{
|
|
241
|
+
var clean=String(path).split(/[\\/]/).pop()||'';
|
|
242
|
+
return clean;
|
|
243
|
+
}catch(e){}
|
|
244
|
+
return '';
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function withoutExt(name){
|
|
248
|
+
if(!name) return '';
|
|
249
|
+
return String(name).replace(/\.[^.]+$/,'');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
function getAngularComponentFromElement(el){
|
|
253
|
+
var ngApi=null;
|
|
254
|
+
try{ ngApi=window.ng||null; }catch(e){ ngApi=null; }
|
|
255
|
+
if(!ngApi||typeof ngApi.getComponent!=='function') return null;
|
|
256
|
+
var current=el;
|
|
257
|
+
var depth=0;
|
|
258
|
+
while(current&&depth<8){
|
|
259
|
+
try{
|
|
260
|
+
var comp=ngApi.getComponent(current);
|
|
261
|
+
if(comp) return { component:comp, host:current };
|
|
262
|
+
}catch(e){}
|
|
263
|
+
current=current.parentElement;
|
|
264
|
+
depth++;
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function getAngularOwnerPath(el){
|
|
270
|
+
var ngApi=null;
|
|
271
|
+
try{ ngApi=window.ng||null; }catch(e){ ngApi=null; }
|
|
272
|
+
if(!ngApi||typeof ngApi.getComponent!=='function') return [];
|
|
273
|
+
var path=[];
|
|
274
|
+
var current=el;
|
|
275
|
+
var depth=0;
|
|
276
|
+
while(current&&depth<12){
|
|
277
|
+
try{
|
|
278
|
+
var comp=ngApi.getComponent(current);
|
|
279
|
+
if(comp&&comp.constructor&&comp.constructor.name){
|
|
280
|
+
path.push(String(comp.constructor.name));
|
|
281
|
+
}
|
|
282
|
+
}catch(e){}
|
|
283
|
+
current=current.parentElement;
|
|
284
|
+
depth++;
|
|
285
|
+
}
|
|
286
|
+
path.reverse();
|
|
287
|
+
return path.slice(-12);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
function getFrameworkContextFromElement(el){
|
|
291
|
+
if(!el||el.nodeType!==1) return null;
|
|
292
|
+
|
|
293
|
+
var fiber=getReactFiberNode(el);
|
|
294
|
+
if(fiber){
|
|
295
|
+
var reactPath=getReactOwnerPathFromFiber(fiber);
|
|
296
|
+
var reactSource=getSourceDebugInfo(fiber);
|
|
297
|
+
return {
|
|
298
|
+
framework:'react',
|
|
299
|
+
component_name:getReactFiberName(fiber)||'',
|
|
300
|
+
owner_path:withFrameworkSuffix(reactPath,'react'),
|
|
301
|
+
source_file:reactSource&&reactSource.fileName?String(reactSource.fileName):'',
|
|
302
|
+
source_line:reactSource&&typeof reactSource.lineNumber==='number'?reactSource.lineNumber:undefined,
|
|
303
|
+
source_column:reactSource&&typeof reactSource.columnNumber==='number'?reactSource.columnNumber:undefined,
|
|
304
|
+
instance_key:fiber&&fiber.key!=null?String(fiber.key):''
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
var vueInstance=getVueComponentFromElement(el);
|
|
309
|
+
if(vueInstance){
|
|
310
|
+
var vueFile=getVueSourceFile(vueInstance);
|
|
311
|
+
return {
|
|
312
|
+
framework:'vue',
|
|
313
|
+
component_name:getVueComponentName(vueInstance)||withoutExt(basename(vueFile))||'',
|
|
314
|
+
owner_path:withFrameworkSuffix(getVueOwnerPath(vueInstance),'vue'),
|
|
315
|
+
source_file:vueFile||'',
|
|
316
|
+
source_line:undefined,
|
|
317
|
+
source_column:undefined,
|
|
318
|
+
instance_key:getVueInstanceKey(vueInstance)||''
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
var svelteMeta=getSvelteMetaFromElement(el);
|
|
323
|
+
if(svelteMeta){
|
|
324
|
+
var sLoc=svelteMeta.loc||null;
|
|
325
|
+
var sFile=sLoc&&sLoc.file?String(sLoc.file):'';
|
|
326
|
+
var sName=withoutExt(basename(sFile));
|
|
327
|
+
return {
|
|
328
|
+
framework:'svelte',
|
|
329
|
+
component_name:sName||'SvelteComponent',
|
|
330
|
+
owner_path:withFrameworkSuffix(sName?[sName]:[],'svelte'),
|
|
331
|
+
source_file:sFile||'',
|
|
332
|
+
source_line:sLoc&&typeof sLoc.line==='number'?sLoc.line:undefined,
|
|
333
|
+
source_column:sLoc&&typeof sLoc.column==='number'?sLoc.column:undefined,
|
|
334
|
+
instance_key:''
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
var ngMatch=getAngularComponentFromElement(el);
|
|
339
|
+
if(ngMatch&&ngMatch.component){
|
|
340
|
+
var ngName=(ngMatch.component.constructor&&ngMatch.component.constructor.name)
|
|
341
|
+
? String(ngMatch.component.constructor.name)
|
|
342
|
+
: 'AngularComponent';
|
|
343
|
+
return {
|
|
344
|
+
framework:'angular',
|
|
345
|
+
component_name:ngName,
|
|
346
|
+
owner_path:withFrameworkSuffix(getAngularOwnerPath(el),'angular'),
|
|
347
|
+
source_file:'',
|
|
348
|
+
source_line:undefined,
|
|
349
|
+
source_column:undefined,
|
|
350
|
+
instance_key:''
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
return null;
|
|
355
|
+
}
|
|
356
|
+
|
|
150
357
|
function getExplicitAnchorId(el){
|
|
151
358
|
if(!el||typeof el.closest!=='function') return '';
|
|
152
359
|
var holder=el.closest('[data-checkpoint-anchor]');
|
|
@@ -156,22 +363,26 @@ function buildMinimalTrackingScript() {
|
|
|
156
363
|
|
|
157
364
|
function getSourceAnchorFromElement(el){
|
|
158
365
|
if(!el||el.nodeType!==1) return null;
|
|
159
|
-
var fiber=getReactFiberNode(el);
|
|
160
|
-
var ownerPath=getReactOwnerPathFromFiber(fiber);
|
|
161
|
-
var source=getSourceDebugInfo(fiber);
|
|
162
|
-
var component=getReactFiberName(fiber);
|
|
163
366
|
var explicitId=getExplicitAnchorId(el);
|
|
164
|
-
var
|
|
165
|
-
var hasData=!!(
|
|
367
|
+
var context=getFrameworkContextFromElement(el);
|
|
368
|
+
var hasData=!!(
|
|
369
|
+
explicitId||
|
|
370
|
+
(context&&(
|
|
371
|
+
context.component_name||
|
|
372
|
+
(Array.isArray(context.owner_path)&&context.owner_path.length>0)||
|
|
373
|
+
context.source_file||
|
|
374
|
+
context.instance_key
|
|
375
|
+
))
|
|
376
|
+
);
|
|
166
377
|
if(!hasData) return null;
|
|
167
378
|
return {
|
|
168
379
|
explicit_id:explicitId||undefined,
|
|
169
|
-
component_name:
|
|
170
|
-
owner_path:
|
|
171
|
-
source_file:
|
|
172
|
-
source_line:
|
|
173
|
-
source_column:
|
|
174
|
-
react_key:
|
|
380
|
+
component_name:context&&context.component_name?context.component_name:undefined,
|
|
381
|
+
owner_path:context&&Array.isArray(context.owner_path)?context.owner_path:[],
|
|
382
|
+
source_file:context&&context.source_file?context.source_file:undefined,
|
|
383
|
+
source_line:context&&typeof context.source_line==='number'?context.source_line:undefined,
|
|
384
|
+
source_column:context&&typeof context.source_column==='number'?context.source_column:undefined,
|
|
385
|
+
react_key:context&&context.instance_key?context.instance_key:undefined,
|
|
175
386
|
host_tag:el&&el.tagName?String(el.tagName).toLowerCase():undefined
|
|
176
387
|
};
|
|
177
388
|
}
|
|
@@ -249,17 +460,16 @@ function buildMinimalTrackingScript() {
|
|
|
249
460
|
if(explicit===sourceAnchor.explicit_id) score+=2400;
|
|
250
461
|
else if(explicit) score-=200;
|
|
251
462
|
}
|
|
252
|
-
var
|
|
253
|
-
var component=
|
|
254
|
-
var
|
|
255
|
-
var ownerPath=getReactOwnerPathFromFiber(fiber);
|
|
463
|
+
var context=getFrameworkContextFromElement(el);
|
|
464
|
+
var component=context&&context.component_name?context.component_name:'';
|
|
465
|
+
var ownerPath=context&&Array.isArray(context.owner_path)?context.owner_path:[];
|
|
256
466
|
if(sourceAnchor.component_name&&component===sourceAnchor.component_name) score+=240;
|
|
257
|
-
if(sourceAnchor.react_key&&
|
|
467
|
+
if(sourceAnchor.react_key&&context&&context.instance_key&&String(context.instance_key)===sourceAnchor.react_key) score+=360;
|
|
258
468
|
score+=ownerSuffixScore(ownerPath,sourceAnchor.owner_path||[]);
|
|
259
|
-
if(sourceAnchor.source_file&&
|
|
469
|
+
if(sourceAnchor.source_file&&context&&context.source_file&&String(context.source_file||'')===String(sourceAnchor.source_file)){
|
|
260
470
|
score+=420;
|
|
261
|
-
if(typeof sourceAnchor.source_line==='number'&&
|
|
262
|
-
if(typeof sourceAnchor.source_column==='number'&&
|
|
471
|
+
if(typeof sourceAnchor.source_line==='number'&&context.source_line===sourceAnchor.source_line) score+=420;
|
|
472
|
+
if(typeof sourceAnchor.source_column==='number'&&context.source_column===sourceAnchor.source_column) score+=80;
|
|
263
473
|
}
|
|
264
474
|
if(sourceAnchor.host_tag&&el.tagName&&String(el.tagName).toLowerCase()===sourceAnchor.host_tag) score+=40;
|
|
265
475
|
return score;
|
|
@@ -451,19 +661,6 @@ function buildMinimalTrackingScript() {
|
|
|
451
661
|
return { coordFallback:null, strategy:'none', matchedSelector:null, status:'none' };
|
|
452
662
|
}
|
|
453
663
|
|
|
454
|
-
function getInspectLabelText(target){
|
|
455
|
-
if(!target||!target.tagName) return '';
|
|
456
|
-
var tag=String(target.tagName).toLowerCase();
|
|
457
|
-
var id=target.id?('#'+target.id):'';
|
|
458
|
-
var cls='';
|
|
459
|
-
try{
|
|
460
|
-
var classes=(target.className&&typeof target.className==='string')
|
|
461
|
-
? target.className.trim().split(/\s+/).filter(Boolean).slice(0,3)
|
|
462
|
-
: [];
|
|
463
|
-
if(classes.length>0) cls='.'+classes.join('.');
|
|
464
|
-
}catch(e){}
|
|
465
|
-
return shortText(tag+id+cls);
|
|
466
|
-
}
|
|
467
664
|
|
|
468
665
|
function ensureInspectUi(){
|
|
469
666
|
if(!document.body) return;
|
|
@@ -483,31 +680,10 @@ inspectBox.style.border='2px solid #F26522';
|
|
|
483
680
|
inspectBox.style.display='none';
|
|
484
681
|
document.body.appendChild(inspectBox);
|
|
485
682
|
}
|
|
486
|
-
if(!inspectLabel){
|
|
487
|
-
inspectLabel=document.createElement('div');
|
|
488
|
-
inspectLabel.style.position='fixed';
|
|
489
|
-
inspectLabel.style.left='0';
|
|
490
|
-
inspectLabel.style.top='0';
|
|
491
|
-
inspectLabel.style.padding='6px 8px';
|
|
492
|
-
inspectLabel.style.maxWidth='420px';
|
|
493
|
-
inspectLabel.style.borderRadius='8px';
|
|
494
|
-
inspectLabel.style.border='1px solid rgba(148,163,184,0.45)';
|
|
495
|
-
inspectLabel.style.background='rgba(15,23,42,0.96)';
|
|
496
|
-
inspectLabel.style.color='#e2e8f0';
|
|
497
|
-
inspectLabel.style.font='12px/1.35 ui-monospace, SFMono-Regular, Menlo, monospace';
|
|
498
|
-
inspectLabel.style.whiteSpace='nowrap';
|
|
499
|
-
inspectLabel.style.wordBreak='break-word';
|
|
500
|
-
inspectLabel.style.pointerEvents='none';
|
|
501
|
-
inspectLabel.style.zIndex='2147483647';
|
|
502
|
-
inspectLabel.style.display='none';
|
|
503
|
-
inspectLabel.style.boxShadow='0 6px 20px rgba(0,0,0,0.35)';
|
|
504
|
-
document.body.appendChild(inspectLabel);
|
|
505
|
-
}
|
|
506
683
|
}
|
|
507
684
|
|
|
508
685
|
function hideInspectUi(){
|
|
509
|
-
|
|
510
|
-
if(inspectLabel) inspectLabel.style.display='none';
|
|
686
|
+
if(inspectBox) inspectBox.style.display='none';
|
|
511
687
|
}
|
|
512
688
|
|
|
513
689
|
function ensurePickShield(){
|
|
@@ -534,7 +710,7 @@ inspectBox.style.border='2px solid #F26522';
|
|
|
534
710
|
|
|
535
711
|
function renderInspectAt(x,y){
|
|
536
712
|
ensureInspectUi();
|
|
537
|
-
|
|
713
|
+
if(!inspectBox){
|
|
538
714
|
return;
|
|
539
715
|
}
|
|
540
716
|
var target=getElementAtPoint(x,y);
|
|
@@ -552,18 +728,6 @@ inspectBox.style.border='2px solid #F26522';
|
|
|
552
728
|
inspectBox.style.top=Math.max(0,rect.top)+'px';
|
|
553
729
|
inspectBox.style.width=Math.max(1,rect.width)+'px';
|
|
554
730
|
inspectBox.style.height=Math.max(1,rect.height)+'px';
|
|
555
|
-
inspectLabel.textContent=getInspectLabelText(target);
|
|
556
|
-
inspectLabel.style.display='block';
|
|
557
|
-
|
|
558
|
-
var vw=window.innerWidth||document.documentElement.clientWidth||0;
|
|
559
|
-
var vh=window.innerHeight||document.documentElement.clientHeight||0;
|
|
560
|
-
var lr=inspectLabel.getBoundingClientRect();
|
|
561
|
-
var left=x+12;
|
|
562
|
-
var top=y+12;
|
|
563
|
-
if(left+lr.width>vw-8) left=Math.max(8,x-lr.width-12);
|
|
564
|
-
if(top+lr.height>vh-8) top=Math.max(8,y-lr.height-12);
|
|
565
|
-
inspectLabel.style.left=left+'px';
|
|
566
|
-
inspectLabel.style.top=top+'px';
|
|
567
731
|
}
|
|
568
732
|
|
|
569
733
|
function postPickResult(target,clientX,clientY){
|