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 & 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 <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>