@@ -164,6 +164,14 @@ let activeEntEl = null;
164164let cardPinned = false ;
165165let cardHideTimer = 0 ;
166166
167+ const ATOMIC_KINDS = new Set ( [
168+ "ip" ,
169+ "url" ,
170+ "email" ,
171+ "uuid" ,
172+ "phone" ,
173+ ] ) ;
174+
167175const fmtDuration = ( ms ) => {
168176 const n = Number ( ms ) ;
169177 if ( ! Number . isFinite ( n ) || n < 0 ) return "" ;
@@ -311,14 +319,14 @@ const groupByStart = (entities) => {
311319 groups . push ( arr ) ;
312320
313321 // For annotation:
314- // - Prefer a non-quantity match when available (so "ip"/" url"/etc. is
315- // visibly matched) .
316- // - Otherwise, show the smallest match to avoid hiding inner groups .
317- const displayPool = arr . some ( ( e ) => e . kind !== "quantity" )
318- ? arr . filter ( ( e ) => e . kind !== "quantity" )
319- : arr ;
320-
321- const chosen = [ ...displayPool ] . sort ( ( a , b ) =>
322+ // - Prefer "atomic" entities (ip/ url/email/uuid/phone) so they look like
323+ // they matched.
324+ // - Otherwise, pick the shortest match to surface useful sub-spans (e.g .
325+ // CC groups), without trying to render overlapping spans.
326+ const atomic = arr . filter ( ( e ) => ATOMIC_KINDS . has ( e . kind ) ) ;
327+ const pool = atomic . length ? atomic : arr ;
328+
329+ const chosen = [ ...pool ] . sort ( ( a , b ) =>
322330 ( a . end - a . start ) - ( b . end - b . start ) ||
323331 ( a . end - b . end ) ||
324332 String ( a . kind ) . localeCompare ( b . kind )
@@ -488,10 +496,26 @@ const annotateHtml = (text, entities, limit, countsByStart) => {
488496 return parts . join ( "" ) ;
489497} ;
490498
499+ const suppressInnerQuantities = ( displayEntities , allEntities ) => {
500+ const atomicSpans = allEntities
501+ . filter ( ( e ) => e && ATOMIC_KINDS . has ( e . kind ) )
502+ . map ( ( e ) => ( { start : e . start , end : e . end } ) ) ;
503+
504+ if ( ! atomicSpans . length ) return displayEntities ;
505+
506+ return displayEntities . filter ( ( e ) => {
507+ if ( ! e || e . kind !== "quantity" ) return true ;
508+ for ( const a of atomicSpans ) {
509+ if ( e . start >= a . start && e . end <= a . end ) return false ;
510+ }
511+ return true ;
512+ } ) ;
513+ } ;
514+
491515const renderAnnotated = ( text , entities , limit ) => {
492516 const grouped = groupByStart ( entities ) ;
493517 lastGroupsByStart = grouped . map ;
494- lastDisplayEntities = grouped . display ;
518+ lastDisplayEntities = suppressInnerQuantities ( grouped . display , entities ) ;
495519
496520 const counts = new Map ( ) ;
497521 for ( const [ start , arr ] of lastGroupsByStart . entries ( ) ) {
0 commit comments