File size: 3,076 Bytes
99c7c9f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
 * Pulpie WebUI - UI Renderer
 *
 * Renders extraction results, stats, Markdown, Reader preview, and block inspection elements.
 */

import { marked } from 'marked';
import DOMPurify from 'dompurify';

/**
 * Display extraction results and statistics in the UI.
 *
 * @param {Object} data - Extraction results payload
 * @param {Object} elements - References to DOM elements
 */
export function displayResults(data, elements) {
  elements.resultsCard.style.display = 'block';

  elements.pageTitleDisplay.textContent = data.title;
  elements.sourceUrlDisplay.textContent = data.sourceUrl ? `Source: ${data.sourceUrl}` : '';

  // Calculate statistics
  const totalBlocks = data.blocks.length;
  const keptCount = data.rawPredictions.filter((p) => p === 1).length;
  const retentionPct = totalBlocks > 0 ? ((keptCount / totalBlocks) * 100).toFixed(1) : 0;

  elements.statKeptBlocks.textContent = `${keptCount} / ${totalBlocks}`;
  elements.statRetention.textContent = `${retentionPct}%`;
  elements.statTokens.textContent = data.totalTokens.toLocaleString();
  if (elements.statTimeLabel) {
    elements.statTimeLabel.textContent = data.provider === 'wasm' ? 'WASM Time' : 'WebGPU Time';
  }
  elements.statGpuTime.textContent = `${data.inferenceTimeMs} ms`;

  // Reader View (Sanitized HTML)
  const renderedHtml = DOMPurify.sanitize(marked.parse(data.markdown));
  elements.readerContent.innerHTML = renderedHtml;

  // Raw Markdown & Clean HTML
  elements.markdownContent.textContent = data.markdown;
  elements.htmlContent.textContent = data.cleanHtml;

  // Render individual inspected blocks
  renderBlockInspector(data.blocks, data.itemIds, data.labels, elements.blockInspectorList);

  // Smooth scroll
  elements.resultsCard.scrollIntoView({ behavior: 'smooth', block: 'start' });
}

/**
 * Populate individual block inspection cards in the Block Inspector tab.
 *
 * @param {string[]} blocks - Raw block HTML snippets
 * @param {string[]} itemIds - Array of _item_id strings
 * @param {Record<string, 'main' | 'other'>} labels - Mapping of item_id -> predicted label
 * @param {HTMLElement} container - DOM container for block items
 */
export function renderBlockInspector(blocks, itemIds, labels, container) {
  container.innerHTML = '';
  for (let i = 0; i < blocks.length; i++) {
    const id = itemIds[i];
    const isMain = labels[id] === 'main';

    const itemEl = document.createElement('div');
    itemEl.className = `inspector-item ${isMain ? 'is-main' : 'is-other'}`;

    const header = document.createElement('div');
    header.className = 'inspector-header';
    header.innerHTML = `
      <span>Block #${id}</span>
      <span class="inspector-badge ${isMain ? 'badge-main' : 'badge-other'}">
        ${isMain ? 'MAIN CONTENT' : 'BOILERPLATE'}
      </span>
    `;

    const code = document.createElement('div');
    code.className = 'inspector-code';
    code.textContent = blocks[i].slice(0, 300) + (blocks[i].length > 300 ? '...' : '');

    itemEl.appendChild(header);
    itemEl.appendChild(code);
    container.appendChild(itemEl);
  }
}