Fix css, js, json, and images browsing views

Seto Elkahfi committed Jun 17, 2026 at 09:53 UTC 3933a8867ac2d3875810f4b356b4e388f861a9b6
3 files changed +30 -6
app/controllers/blobs_controller.rb
+21 -2
index 2c33acf..234dfc0 100644 --- a/app/controllers/blobs_controller.rb +++ b/app/controllers/blobs_controller.rb @@ -3,6 +3,19 @@ class BlobsController < ApplicationController before_action :load_repository before_action :ensure_can_read! + # Raster image types served inline from the raw endpoint with their real + # content type. SVG is intentionally excluded — serving it inline could + # execute embedded scripts on direct navigation. + RAW_IMAGE_TYPES = { + "png" => "image/png", "jpg" => "image/jpeg", "jpeg" => "image/jpeg", + "gif" => "image/gif", "webp" => "image/webp", "avif" => "image/avif", + "bmp" => "image/bmp", "ico" => "image/x-icon" + }.freeze + + # Types previewed in the blob view via a data URI. SVG is safe here because it + # is loaded through an <img> tag, which browsers sandbox. + PREVIEW_IMAGE_TYPES = RAW_IMAGE_TYPES.merge("svg" => "image/svg+xml").freeze + def show # A file path like ".../app.js" or "...style.css" makes Rails negotiate a # non-HTML format from the trailing extension — which has no template (→ @@ -30,7 +43,12 @@ class BlobsController < ApplicationController @is_binary = content.encoding != Encoding::UTF_8 || !content.valid_encoding? || binary_content?(content) @file_size = content.bytesize - unless @is_binary + @image_type = PREVIEW_IMAGE_TYPES[@extension.downcase] + if @image_type + # Embed the image inline as a data URI so it previews without a second + # request. <img>-loaded content is sandboxed, so this is safe for SVG too. + @image_data_uri = "data:#{@image_type};base64,#{[ content ].pack('m0')}" + elsif !@is_binary @highlighted_lines = highlight_lines(content, @filename) @line_count = content.lines.count end @@ -48,8 +66,9 @@ class BlobsController < ApplicationController return end + ext = File.extname(@file_path).delete_prefix(".").downcase send_data content, - type: "text/plain; charset=utf-8", + type: RAW_IMAGE_TYPES[ext] || "text/plain; charset=utf-8", disposition: "inline", filename: File.basename(@file_path) end
app/views/blobs/show.html.erb
+7 -2
index c449572..356848e 100644 --- a/app/views/blobs/show.html.erb +++ b/app/views/blobs/show.html.erb @@ -50,7 +50,7 @@ <div class="px-4 py-2.5 border-b border-surface-600 flex items-center justify-between bg-surface-600"> <div class="flex items-center gap-3 text-xs text-gray-400"> <span class="font-mono badge-gray"><%= @extension.presence || "text" %></span> - <% unless @is_binary %> + <% if @line_count %> <span><%= number_with_delimiter(@line_count) %> lines</span> <% end %> <span><%= number_to_human_size(@file_size) %></span> @@ -61,7 +61,12 @@ </div> </div> - <% if @is_binary %> + <% if @image_type %> + <div class="px-6 py-10 flex justify-center bg-surface-800"> + <img src="<%= @image_data_uri %>" alt="<%= @filename %>" + class="max-w-full h-auto rounded border border-surface-600" /> + </div> + <% elsif @is_binary %> <div class="px-6 py-10 text-center text-sm text-gray-400"> Binary file — <%= number_to_human_size(@file_size) %> </div>
app/views/layouts/application.html.erb
+2 -2
index bba5e9d..2c5936f 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -39,8 +39,8 @@ <div class="max-w-6xl mx-auto px-4 sm:px-6 py-8 flex items-center justify-between text-xs text-gray-500"> <span> Get <a href="https://getsigit.5mb.app/" class="hover:text-gray-300 transition-colors" target="_blank" rel="noopener noreferrer">siGit Code &amp; Deploy</a></span> - <div class="flex items-center gap-4"> - Runs on <a href="https://smbcloud.xyz/" class="hover:text-gray-300 transition-colors" target="_blank" rel="noopener noreferrer">smbCloud</a> + <div class="flex items-center"> + Auth and Mail by&nbsp;<a href="https://smbcloud.xyz/" class="hover:text-gray-300 transition-colors" target="_blank" rel="noopener noreferrer">smbCloud Platform</a> </div> <%= render "shared/dev_panel" if Rails.env.development? %> </div>