Class: Bidi2pdf::Bidi::NetworkEventFormatters::NetworkEventHtmlFormatter
- Inherits:
-
Object
- Object
- Bidi2pdf::Bidi::NetworkEventFormatters::NetworkEventHtmlFormatter
- Includes:
- NetworkEventFormatterUtils
- Defined in:
- lib/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rb
Instance Method Summary collapse
- #render(events) ⇒ Object
-
#render_event(event, index) ⇒ Object
rubocop: disable Metrics/AbcSize.
-
#render_timing_bars(timing) ⇒ Object
rubocop: enable Metrics/AbcSize.
- #toc_entry(event, index) ⇒ Object
Methods included from NetworkEventFormatterUtils
#format_bytes, #format_timestamp, #parse_timing, #shorten_url
Instance Method Details
#render(events) ⇒ Object
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 |
# File 'lib/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rb', line 9 def render(events) return unless Bidi2pdf.network_events_logger.info? " <!DOCTYPE html>\n <html lang=\"en\" data-bs-theme=\"light\">\n <head>\n <meta charset=\"UTF-8\">\n <title>Network Events</title>\n <link href=\"https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css\" rel=\"stylesheet\">\n <style>\n body { font-family: monospace; padding: 2rem; }\n .event { background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); padding: 1rem; margin-bottom: 2rem; border-radius: .5rem; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }\n .bar-container { position: relative; height: 20px; background: var(--bs-secondary-bg); border-radius: 4px; }\n .bar { position: absolute; top: 0; height: 100%; background-color: #0d6efd; opacity: 0.8; }\n .toc a { text-decoration: none; display: block; margin-bottom: 0.5rem; }\n\n @media print {\n .no-break {\n page-break-inside: avoid;\n }\n \#{\" \"}\n \#{\" \"}\n .form-select, .form-label, #theme-select {\n display: none !important; /* Hide theme selector when printing */\n }\n }\n\n .event {\n word-break: break-word;\n overflow-wrap: anywhere;\n }\n </style>\n <script>\n function toggleTheme(value) {\n document.documentElement.setAttribute('data-bs-theme', value);\n }\n </script>\n </head>\n <body>\n <h1>Network Events</h1>\n <div class=\"mb-4\">\n <label for=\"theme-select\" class=\"form-label\">Theme:</label>\n <select id=\"theme-select\" class=\"form-select w-auto d-inline-block\" onchange=\"toggleTheme(this.value)\">\n <option value=\"light\">Light</option>\n <option value=\"dark\">Dark</option>\n </select>\n </div>\n\n <h2>Index</h2>\n <div class=\"toc mb-4\">\n \#{events.map.with_index { |e, i| toc_entry(e, i) }.join(\"\\n\")}\n </div>\n\n \#{events.map.with_index { |e, i| render_event(e, i) }.join(\"\\n\")}\n </body>\n </html>\n HTML\nend\n" |
#render_event(event, index) ⇒ Object
rubocop: disable Metrics/AbcSize
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rb', line 74 def render_event(event, index) timing = parse_timing(event) duration = event.duration_seconds || 0 duration_str = event.in_progress? ? "in progress" : "#{duration}s" status = event.http_status_code || "?" method = event.http_method || "?" start = (event.) finish = event. ? (event.) : "..." bytes = event.bytes_received ? format_bytes(event.bytes_received) : "N/A" = (timing) displayed_url = shorten_url(event.url) " <div class=\"event no-break\" id=\"event-\#{index}\">\n <div><strong>Request:</strong> \#{method} \#{displayed_url}</div>\n <div><strong>Status:</strong> HTTP \#{status}</div>\n <div><strong>State:</strong> \#{event.state}</div>\n <div><strong>Start:</strong> \#{start}</div>\n <div><strong>End:</strong> \#{finish}</div>\n <div><strong>Duration:</strong> \#{duration_str}</div>\n <div><strong>Received:</strong> \#{bytes}</div>\n \#{bars}\n </div>\n HTML\nend\n" |
#render_timing_bars(timing) ⇒ Object
rubocop: enable Metrics/AbcSize
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rb', line 102 def (timing) return "" if timing.empty? max_ms = timing.map { |t| t[:ms] }.max scale = max_ms.zero? ? 0 : 100.0 / max_ms = timing.map do |t| width = (t[:ms] * scale).clamp(1, 100).round(2) " <div>\n <small>\#{t[:label]} (\#{t[:ms]} ms)</small>\n <div class=\"bar-container mb-2\">\n <div class=\"bar\" style=\"width: \#{width}%\"></div>\n </div>\n </div>\n HTML\n end\n\n \"<div class=\\\"mt-3\\\"><strong>Timing Waterfall</strong>\#{bars.join}</div>\"\nend\n" |
#toc_entry(event, index) ⇒ Object
69 70 71 |
# File 'lib/bidi2pdf/bidi/network_event_formatters/network_event_html_formatter.rb', line 69 def toc_entry(event, index) "<a href=\"#event-#{index}\">[#{index + 1}] #{event.http_method} #{event.url}</a>" end |