@@ -3407,10 +3407,27 @@ async function loadBaselineAnnotations(
34073407 if ( ! annotationMap . has ( def . id ) ) {
34083408 annotationMap . set ( def . id , { def, elements : [ ] } ) ;
34093409 }
3410+ } else if ( ann . annotationType !== 20 ) {
3411+ // Widget (type 20) is expected to be skipped; anything else we
3412+ // don't import will still be painted by page.render() onto the
3413+ // canvas as unselectable pixels. Log so we can diagnose
3414+ // "ghost annotations" (visible but not in panel, not clickable).
3415+ log . info (
3416+ `[WARN] Baseline: skipped PDF annotation on page ${ pageNum } ` ,
3417+ `type=${ ann . annotationType } ` ,
3418+ `subtype=${ ann . subtype ?? "?" } ` ,
3419+ `name=${ ann . name ?? "?" } ` ,
3420+ `rect=${ ann . rect ? JSON . stringify ( ann . rect ) : "none" } ` ,
3421+ ) ;
34103422 }
34113423 }
3412- } catch {
3413- // Skip pages that fail to load annotations
3424+ } catch ( err ) {
3425+ // Log the error — a thrown import for one annotation silently
3426+ // drops the REST of that page's annotations too.
3427+ log . info (
3428+ `[WARN] Baseline: page ${ pageNum } annotation import failed:` ,
3429+ err ,
3430+ ) ;
34143431 }
34153432 }
34163433 log . info (
@@ -5376,6 +5393,62 @@ app.connect().then(() => {
53765393 updateAnnotationsBadge ( ) ;
53775394} ) ;
53785395
5396+ // Debug helper: dump all annotation state. Run in DevTools console as
5397+ // `__pdfDebug()` to diagnose ghost annotations (visible on canvas but not
5398+ // in panel / not selectable). Returns a copy-pasteable JSON object.
5399+ ( window as unknown as { __pdfDebug : ( ) => unknown } ) . __pdfDebug = ( ) => {
5400+ const out = {
5401+ annotationMap : [ ...annotationMap . entries ( ) ] . map ( ( [ id , t ] ) => ( {
5402+ id,
5403+ type : t . def . type ,
5404+ page : t . def . page ,
5405+ hasElements : t . elements . length ,
5406+ // Trim imageData — can be megabytes of base64
5407+ def :
5408+ t . def . type === "image"
5409+ ? { ...t . def , imageData : t . def . imageData ? "<omitted>" : undefined }
5410+ : t . def ,
5411+ } ) ) ,
5412+ pdfBaselineAnnotations : pdfBaselineAnnotations . map ( ( d ) => ( {
5413+ id : d . id ,
5414+ type : d . type ,
5415+ page : d . page ,
5416+ } ) ) ,
5417+ annotationLayerChildren : [ ...annotationLayerEl . children ] . map ( ( el ) => ( {
5418+ tag : el . tagName ,
5419+ class : el . className ,
5420+ } ) ) ,
5421+ formLayerChildren : [ ...formLayerEl . children ] . map ( ( el ) => ( {
5422+ tag : el . tagName ,
5423+ class : el . className ,
5424+ } ) ) ,
5425+ localStorageKey : annotationStorageKey ( ) ,
5426+ localStorageRaw : ( ( ) => {
5427+ const k = annotationStorageKey ( ) ;
5428+ if ( ! k ) return null ;
5429+ const raw = localStorage . getItem ( k ) ;
5430+ if ( ! raw ) return null ;
5431+ // Parse and trim imageData
5432+ try {
5433+ const d = JSON . parse ( raw ) ;
5434+ if ( Array . isArray ( d . added ) ) {
5435+ d . added = d . added . map ( ( a : { imageData ?: string } ) =>
5436+ a . imageData ? { ...a , imageData : "<omitted>" } : a ,
5437+ ) ;
5438+ }
5439+ return d ;
5440+ } catch {
5441+ return { parseError : true , length : raw . length } ;
5442+ }
5443+ } ) ( ) ,
5444+ currentPage,
5445+ isDirty,
5446+ panelOpen : annotationPanelOpen ,
5447+ } ;
5448+ console . log ( JSON . stringify ( out , null , 2 ) ) ;
5449+ return out ;
5450+ } ;
5451+
53795452// =============================================================================
53805453// Image from File (shared by drag-drop and paste)
53815454// =============================================================================
0 commit comments