Preserve chronological order in gapless gallery rows

This commit is contained in:
2026-09-26 19:10:42 +01:00
parent c864e781d7
commit 00fffe703d
4 changed files with 86 additions and 14 deletions
+47
View File
@@ -1,6 +1,53 @@
require 'nokogiri'
module GalleryItems
JPEG_START_OF_FRAME = [0xC0, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7,
0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF].freeze
# Read just the dimensions from a local JPEG. The rendered gallery needs
# aspect ratios to size each chronological pair without cropping either photo.
def jpeg_dimensions(path)
File.open(path, 'rb') do |file|
return nil unless file.read(2) == "\xFF\xD8".b
while (prefix = file.read(1))
next unless prefix.getbyte(0) == 0xFF
marker = file.read(1)&.getbyte(0)
break unless marker
next if marker == 0xFF || marker == 0x01 || (0xD0..0xD7).cover?(marker)
break if marker == 0xD9 || marker == 0xDA
size = file.read(2)&.unpack1('n')
break unless size && size >= 2
if JPEG_START_OF_FRAME.include?(marker)
dimensions = file.read(5)
return nil unless dimensions&.length == 5
height, width = dimensions.byteslice(1, 4).unpack('n2')
return [width, height] if width.positive? && height.positive?
return nil
end
file.seek(size - 2, IO::SEEK_CUR)
end
end
nil
rescue Errno::ENOENT, EOFError
nil
end
def gallery_image_ratio(content)
image = Nokogiri::HTML::DocumentFragment.parse(content).at_css('img')
source = image&.[]('src')
return 1.5 unless source&.start_with?('/img/arts/')
path = File.join(File.expand_path('..', __dir__), source.delete_prefix('/'))
width, height = jpeg_dimensions(path)
return 1.5 unless width && height
(width.to_f / height).round(4)
end
# Uploaded batches share one source document, but each photo is a gallery item.
# Keeping this at render time also fixes batches that have already been published.
def gallery_items(content)