jekyll-imgflow 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/jekyll-imgflow/html_generator.rb +4 -2
- data/lib/jekyll-imgflow/imgflow_tag.rb +43 -1
- data/lib/jekyll-imgflow/modal_assets.rb +71 -10
- data/lib/jekyll-imgflow/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa56ff31b7cfe312dfe202726e049c99db5511dc35b2e82d721abde41c76488e
|
|
4
|
+
data.tar.gz: 88ff3c89e44a1dfe0fe022a016bbeba79185c137bca201c4e2c66c9d06cc5a92
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c1f92e12c629652780356a972969ee435992b29dd62dea03ea263582084e8b512b35eb25e8bb1845c111834a5506cd1c3ffd5c9b4c5392ff6e17e20d3ea5c4ae
|
|
7
|
+
data.tar.gz: 92b73297116fd7dd7d38a5aeb349c81aeab97709f3a85886469dc0443e3fa9e5e35c2c971b1c01bd6682db2c59776c54112682a31e3610c64a6254b3d4067441
|
|
@@ -83,7 +83,8 @@ module JekyllImgFlow
|
|
|
83
83
|
parent: attributes[:parent] || {},
|
|
84
84
|
alt: attributes[:alt],
|
|
85
85
|
link: attributes[:link],
|
|
86
|
-
modal: attributes[:modal]
|
|
86
|
+
modal: attributes[:modal],
|
|
87
|
+
modal_results: attributes[:modal_results] || []
|
|
87
88
|
}
|
|
88
89
|
end
|
|
89
90
|
|
|
@@ -96,7 +97,8 @@ module JekyllImgFlow
|
|
|
96
97
|
parent: {},
|
|
97
98
|
alt: nil,
|
|
98
99
|
link: nil,
|
|
99
|
-
modal: nil
|
|
100
|
+
modal: nil,
|
|
101
|
+
modal_results: []
|
|
100
102
|
}
|
|
101
103
|
end
|
|
102
104
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "shellwords"
|
|
4
|
+
require "fastimage"
|
|
4
5
|
|
|
5
6
|
module Jekyll
|
|
6
7
|
class ImgflowTag < Liquid::Tag
|
|
@@ -99,11 +100,51 @@ module Jekyll
|
|
|
99
100
|
page_path)
|
|
100
101
|
end
|
|
101
102
|
|
|
103
|
+
modal_results = if operations.empty?
|
|
104
|
+
[]
|
|
105
|
+
else
|
|
106
|
+
process_modal_variants(components, operations.first, parsed, original_name,
|
|
107
|
+
input_path, page_path)
|
|
108
|
+
end
|
|
102
109
|
relative_results = results.uniq.map { |result| relative_result_path(result, site) }
|
|
110
|
+
relative_modal_results = modal_results.uniq.map do |result|
|
|
111
|
+
relative_result_path(result, site)
|
|
112
|
+
end
|
|
103
113
|
parsed = parsed.merge(markup_format: "picture") if relative_results.length > 1
|
|
114
|
+
parsed = parsed.merge(modal_results: relative_modal_results)
|
|
104
115
|
generate_html(relative_results, parsed, context)
|
|
105
116
|
end
|
|
106
117
|
|
|
118
|
+
def process_modal_variants(components, operation, parsed, original_name, input_path, page_path)
|
|
119
|
+
config = components[:config]
|
|
120
|
+
return [] unless modal_requested?(parsed, config)
|
|
121
|
+
|
|
122
|
+
original_width = FastImage.size(input_path)&.first
|
|
123
|
+
return [] unless original_width
|
|
124
|
+
|
|
125
|
+
params = operation[:params].dup
|
|
126
|
+
formats = Array(params.delete(:formats) || params[:format])
|
|
127
|
+
formats = config.formats if formats.empty?
|
|
128
|
+
modal_width = [original_width, config.sizes.values.max].min
|
|
129
|
+
|
|
130
|
+
formats.map do |format|
|
|
131
|
+
modal_params = params.merge(width: modal_width, format: format)
|
|
132
|
+
process_variant(components, operation, modal_params, original_name, input_path, page_path)
|
|
133
|
+
end
|
|
134
|
+
rescue FastImage::ImageFetchError, FastImage::UnknownImageType
|
|
135
|
+
[]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def modal_requested?(parsed, config)
|
|
139
|
+
return false if %w[direct_url naked_srcset].include?(parsed[:markup_format])
|
|
140
|
+
|
|
141
|
+
attrs = parsed[:html_attributes] || {}
|
|
142
|
+
return false if attrs[:link]
|
|
143
|
+
|
|
144
|
+
modal = attrs[:modal]
|
|
145
|
+
modal.nil? ? (config.respond_to?(:image_modal) && config.image_modal) : modal.to_s == "true"
|
|
146
|
+
end
|
|
147
|
+
|
|
107
148
|
def process_variants(components, operation, original_name, input_path, page_path)
|
|
108
149
|
params = operation[:params].dup
|
|
109
150
|
formats = Array(params.delete(:formats) || params[:format])
|
|
@@ -195,7 +236,8 @@ module Jekyll
|
|
|
195
236
|
parent: extract_prefixed_attrs(base_attrs, "parent-"),
|
|
196
237
|
alt: base_attrs[:alt],
|
|
197
238
|
link: base_attrs[:link],
|
|
198
|
-
modal: base_attrs[:modal]
|
|
239
|
+
modal: base_attrs[:modal],
|
|
240
|
+
modal_results: parsed[:modal_results] || []
|
|
199
241
|
}
|
|
200
242
|
end
|
|
201
243
|
|
|
@@ -20,15 +20,24 @@ module JekyllImgFlow
|
|
|
20
20
|
|
|
21
21
|
JS = <<~JS
|
|
22
22
|
(function(){
|
|
23
|
-
function openModal(
|
|
23
|
+
function openModal(trigger,alt){
|
|
24
24
|
var o=document.createElement('div');
|
|
25
25
|
o.className='imgflow-modal-overlay';
|
|
26
|
+
var p=document.createElement('picture');
|
|
27
|
+
var href=trigger.getAttribute('href');
|
|
28
|
+
var types={avif:'image/avif',webp:'image/webp',png:'image/png',jpg:'image/jpeg',jpeg:'image/jpeg'};
|
|
29
|
+
var formats=(trigger.getAttribute('data-imgflow-modal-formats')||'').split(',');
|
|
30
|
+
formats.forEach(function(format){
|
|
31
|
+
if(!format)return;
|
|
32
|
+
var s=document.createElement('source');
|
|
33
|
+
s.srcset=href.replace(/.[^.]+$/,'.'+format);s.type=types[format];p.appendChild(s);});
|
|
26
34
|
var i=document.createElement('img');
|
|
27
|
-
i.src=
|
|
35
|
+
i.src=href;
|
|
36
|
+
i.alt=alt||'';i.className='imgflow-modal-image';p.appendChild(i);
|
|
28
37
|
var b=document.createElement('button');
|
|
29
38
|
b.className='imgflow-modal-close';b.setAttribute('aria-label','Close');
|
|
30
39
|
b.innerHTML='×';
|
|
31
|
-
o.appendChild(b);o.appendChild(
|
|
40
|
+
o.appendChild(b);o.appendChild(p);document.body.appendChild(o);
|
|
32
41
|
function c(){document.body.removeChild(o);
|
|
33
42
|
document.removeEventListener('keydown',k);}
|
|
34
43
|
function k(e){if(e.key==='Escape')c();}
|
|
@@ -38,7 +47,7 @@ module JekyllImgFlow
|
|
|
38
47
|
document.addEventListener('click',function(e){
|
|
39
48
|
var t=e.target.closest('[data-imgflow-modal]');
|
|
40
49
|
if(!t)return;e.preventDefault();
|
|
41
|
-
openModal(t
|
|
50
|
+
openModal(t,t.getAttribute('data-imgflow-alt'));});
|
|
42
51
|
})();
|
|
43
52
|
JS
|
|
44
53
|
|
|
@@ -84,20 +93,72 @@ module JekyllImgFlow
|
|
|
84
93
|
@config&.image_modal ? true : false
|
|
85
94
|
end
|
|
86
95
|
|
|
87
|
-
# Pick the
|
|
88
|
-
# (e.g. jpg) for maximum browser compatibility
|
|
96
|
+
# Pick the largest existing fallback-format variant for the modal.
|
|
89
97
|
def modal_image_path
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
variants = modal_variants
|
|
99
|
+
variants[modal_fallback_format] || @results.last
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def modal_variants
|
|
103
|
+
candidates = @attributes[:modal_results] + @results + generated_modal_results
|
|
104
|
+
max_width = modal_max_width
|
|
105
|
+
|
|
106
|
+
candidates.each_with_object({}) do |result, variants|
|
|
107
|
+
parsed = JekyllImgFlow::FilenameGenerator.new.parse_filename(File.basename(result))
|
|
108
|
+
next if parsed.empty? || (max_width && parsed[:width] > max_width)
|
|
109
|
+
next if variants[parsed[:format]] && modal_width(variants[parsed[:format]]) >= parsed[:width]
|
|
110
|
+
|
|
111
|
+
variants[parsed[:format]] = result
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def modal_fallback_format
|
|
116
|
+
@config&.fallback_format.to_s
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def modal_max_width
|
|
120
|
+
return unless @config.respond_to?(:sizes)
|
|
121
|
+
|
|
122
|
+
@config.sizes.values.max
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def generated_modal_results
|
|
126
|
+
return [] unless @config && @context&.registers&.key?(:site)
|
|
127
|
+
|
|
128
|
+
result = @results.first
|
|
129
|
+
parsed = JekyllImgFlow::FilenameGenerator.new.parse_filename(File.basename(result))
|
|
130
|
+
return [] if parsed.empty?
|
|
131
|
+
|
|
132
|
+
site = @context.registers[:site]
|
|
133
|
+
directory = File.join(site.source, File.dirname(result.delete_prefix("/")))
|
|
134
|
+
return [] unless File.directory?(directory)
|
|
135
|
+
|
|
136
|
+
max_width = @config.sizes.values.max
|
|
137
|
+
Dir.children(directory).filter_map do |filename|
|
|
138
|
+
candidate = JekyllImgFlow::FilenameGenerator.new.parse_filename(filename)
|
|
139
|
+
next unless candidate[:base_name] == parsed[:base_name]
|
|
140
|
+
next unless candidate[:hash] == parsed[:hash]
|
|
141
|
+
next if max_width && candidate[:width] > max_width
|
|
142
|
+
|
|
143
|
+
File.join(File.dirname(result), filename)
|
|
144
|
+
end
|
|
145
|
+
rescue Errno::ENOENT
|
|
146
|
+
[]
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def modal_width(result)
|
|
150
|
+
JekyllImgFlow::FilenameGenerator.new.parse_filename(File.basename(result))[:width] || 0
|
|
93
151
|
end
|
|
94
152
|
|
|
95
153
|
# Wrap HTML in modal trigger anchor
|
|
96
154
|
def wrap_with_modal(html)
|
|
97
|
-
|
|
155
|
+
variants = modal_variants
|
|
156
|
+
modal_href = html_path(variants[modal_fallback_format] || @results.last)
|
|
98
157
|
return html unless modal_href
|
|
99
158
|
|
|
159
|
+
source_formats = variants.keys.reject { |format| format == modal_fallback_format }
|
|
100
160
|
data_attrs = " data-imgflow-modal"
|
|
161
|
+
data_attrs += " data-imgflow-modal-formats=\"#{source_formats.join(',')}\"" unless source_formats.empty?
|
|
101
162
|
alt = @attributes[:alt]
|
|
102
163
|
data_attrs += " data-imgflow-alt=\"#{escape_attr_value(alt)}\"" if alt
|
|
103
164
|
|