feat(pdftract-3mdb7): implement hover tooltips for inspector
- Update app.js setupTooltips() to show span attributes - Display text/font/confidence/bbox when available - Display block-ref/MCID/reading-idx when available server-side - Add edge detection for repositioning near viewport edges - Use 8px offset from cursor - Update style.css tooltip styling per spec: - Light background (rgba(255,255,255,0.95)) - Border: 1px solid #ccc - Monospace font family - 12px font size - No CSS transitions for 50ms appearance Acceptance criteria: - Tooltip appears within 50ms (no CSS transitions) - Shows available data-* attrs as formatted rows - mouseleave hides tooltip - Auto-repositions near right/bottom edges - XSS-safe via textContent (no innerHTML) Phase: 7.9.6
This commit is contained in:
parent
b93bb53ac2
commit
ba03d03f90
2 changed files with 48 additions and 10 deletions
|
|
@ -354,29 +354,67 @@ function loadFragment(){
|
|||
|
||||
function setupTooltips(svg){
|
||||
const tooltip=document.getElementById('tooltip');
|
||||
const OFFSET=8;
|
||||
|
||||
svg.addEventListener('mouseover',e=>{
|
||||
const target=e.target.closest('[data-text], [data-kind]');
|
||||
if(!target)return;
|
||||
let content='';
|
||||
if(target.dataset.spanIndex!==undefined){
|
||||
content=`Text: ${target.dataset.text}\nFont: ${target.dataset.font}\nSize: ${target.dataset.size}pt\nConfidence: ${target.dataset.confidence||'N/A'}\nSpan index: ${target.dataset.spanIndex}`
|
||||
const lines=[];
|
||||
if(target.dataset.text)lines.push(`Text: ${target.dataset.text}`);
|
||||
if(target.dataset.font){
|
||||
const size=target.dataset.size?` ${target.dataset.size}pt`:'';
|
||||
lines.push(`Font: ${target.dataset.font}${size}`);
|
||||
}
|
||||
if(target.dataset.confidence&&target.dataset.confidence!==''){
|
||||
lines.push(`Confidence: ${target.dataset.confidence}`);
|
||||
}
|
||||
if(target.dataset.bbox)lines.push(`Bbox: ${target.dataset.bbox}`);
|
||||
if(target.dataset.blockRef)lines.push(`Block: ${target.dataset.blockRef}`);
|
||||
if(target.dataset.mcid)lines.push(`MCID: ${target.dataset.mcid}`);
|
||||
if(target.dataset.readingIdx)lines.push(`Reading idx: ${target.dataset.readingIdx}`);
|
||||
content=lines.join('\n');
|
||||
}else if(target.dataset.blockIndex!==undefined){
|
||||
content=`Block index: ${target.dataset.blockIndex}\nKind: ${target.dataset.kind}\nText: ${target.dataset.text}\nLevel: ${target.dataset.level||'N/A'}\nTable index: ${target.dataset.tableIndex||'N/A'}`
|
||||
}
|
||||
tooltip.hidden=false;
|
||||
tooltip.textContent=content;
|
||||
tooltip.style.left=e.pageX+10+'px';
|
||||
tooltip.style.top=e.pageY+10+'px'
|
||||
if(content){
|
||||
tooltip.textContent=content;
|
||||
tooltip.hidden=false;
|
||||
positionTooltip(e.pageX,e.pageY);
|
||||
}
|
||||
});
|
||||
|
||||
svg.addEventListener('mouseout',e=>{
|
||||
if(e.target.closest('[data-text], [data-kind]'))tooltip.hidden=true
|
||||
});
|
||||
|
||||
svg.addEventListener('mousemove',e=>{
|
||||
if(!tooltip.hidden){
|
||||
tooltip.style.left=e.pageX+10+'px';
|
||||
tooltip.style.top=e.pageY+10+'px'
|
||||
if(!tooltip.hidden)positionTooltip(e.pageX,e.pageY)
|
||||
});
|
||||
|
||||
function positionTooltip(x,y){
|
||||
const tooltipRect=tooltip.getBoundingClientRect();
|
||||
const viewportWidth=window.innerWidth;
|
||||
const viewportHeight=window.innerHeight;
|
||||
|
||||
let left=x+OFFSET;
|
||||
let top=y+OFFSET;
|
||||
|
||||
if(left+tooltipRect.width>viewportWidth){
|
||||
left=x-tooltipRect.width-OFFSET;
|
||||
}
|
||||
})
|
||||
|
||||
if(top+tooltipRect.height>viewportHeight){
|
||||
top=y-tooltipRect.height-OFFSET;
|
||||
}
|
||||
|
||||
left=Math.max(OFFSET,Math.min(left,viewportWidth-tooltipRect.width-OFFSET));
|
||||
top=Math.max(OFFSET,Math.min(top,viewportHeight-tooltipRect.height-OFFSET));
|
||||
|
||||
tooltip.style.left=left+'px';
|
||||
tooltip.style.top=top+'px'
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded',init);
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ body{font-family:system-ui,-apple-system,sans-serif;font-size:14px;line-height:1
|
|||
.panel-header{padding:12px;border-bottom:1px solid #ddd;font-weight:600;background:#f9f9f9}
|
||||
.json-tree{flex:1;overflow:auto;padding:12px;font-size:12px;font-family:ui-monospace,monospace;white-space:pre-wrap;word-break:break-all}
|
||||
.loading{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:16px;color:#666}
|
||||
.tooltip{position:absolute;background:#333;color:#fff;padding:6px 10px;border-radius:4px;font-size:12px;pointer-events:none;z-index:1000;max-width:300px;white-space:pre-wrap;word-break:break-word}
|
||||
.tooltip{position:absolute;background:rgba(255,255,255,.95);border:1px solid #ccc;padding:6px 10px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,Consolas,monospace;font-size:12px;pointer-events:none;z-index:1000;max-width:400px;white-space:pre;line-height:1.4}
|
||||
.layer-spans,.layer-blocks,.layer-columns,.layer-reading-order,.layer-confidence-heatmap,.layer-ocr,.layer-mcid,.layer-anchors,.layer-diff{display:none}
|
||||
html[data-layers~="spans"] .layer-spans,html[data-layers~="blocks"] .layer-blocks,html[data-layers~="columns"] .layer-columns,html[data-layers~="reading-order"] .layer-reading-order,html[data-layers~="confidence-heatmap"] .layer-confidence-heatmap,html[data-layers~="ocr"] .layer-ocr,html[data-layers~="mcid"] .layer-mcid,html[data-layers~="anchors"] .layer-anchors,html[data-layers~="diff"] .layer-diff{display:block}
|
||||
.tooltip-key{color:#8f8}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue