jekyll-imgflow 0.2.0 โ†’ 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b95efe6605d712e14895c4152a68b4b751eea6954416e428acbe96518bd4284
4
- data.tar.gz: 434fc1985138599142a94d32dda9c986c63893c4acfc587e085d8e3486d700d4
3
+ metadata.gz: d37c208e7250fe6da8291bfab933d5df7391347d0ce95492e32e1d94e54df7a8
4
+ data.tar.gz: cd222c0e6dbdcffe168ec0919a12d53c57324a277cb9efeecb5173a98c4c5b04
5
5
  SHA512:
6
- metadata.gz: f588617884137bcf8054e2a1bce6489b9aebfe4829ce9a279bb65654871dd13d41df6e6f0e0a15ddeb7fb39b9f4f9776206a2f6ff16b83db6e11c82b76dd78ef
7
- data.tar.gz: 480ba9208f2952793bff054b24b8f7e79a47de1b83d322d0f0f261242cbd8d01f4e532b0571397d4f0efb18c31f27867546ba987f51add3a664fb5b7049bcfb1
6
+ metadata.gz: 2f566b0e2d70993a209a5353cf1b91d54e3b3f3143397146f58bbbcf19428eab9797ed5def60efdd3d8f926f214fa2ec6670d47ccfd6c000fe2f9c35b2bac00c
7
+ data.tar.gz: 0b601aea8c16d71133816f034b4277e399e6108569af169c0984416ef6e5d90edc30490d17af254f736f2897eae5c6b55d515888a4b71af35dd8020b63f37a88
@@ -20,11 +20,12 @@ module JekyllImgFlow
20
20
  # Format used for the <img> fallback in <picture> elements.
21
21
  # All other formats in `formats` get <source> tags for browsers that support them.
22
22
  DEFAULT_FALLBACK_FORMAT = "jpg"
23
+ DEFAULT_IMAGE_MODAL = true
23
24
 
24
25
  attr_reader :site, :originals, :output, :input_formats, :sizes, :formats,
25
26
  :quality, :backend_priority, :imgproxy_url,
26
27
  :weserv_url, :flyimg_url,
27
- :optimize_qualities, :fallback_format
28
+ :optimize_qualities, :fallback_format, :image_modal
28
29
 
29
30
  def initialize(site)
30
31
  shared = site.config["shared_images_configs"] || {}
@@ -40,6 +41,7 @@ module JekyllImgFlow
40
41
  @quality = cfg["quality"] || DEFAULT_QUALITY
41
42
  @backend_priority = cfg["backend_priority"] || DEFAULT_BACKEND_PRIORITY
42
43
  @fallback_format = cfg["fallback_format"] || DEFAULT_FALLBACK_FORMAT
44
+ @image_modal = cfg.fetch("image_modal", DEFAULT_IMAGE_MODAL)
43
45
 
44
46
  @imgproxy_url = cfg["imgproxy_url"]
45
47
  @weserv_url = cfg["weserv_url"]
@@ -47,6 +47,13 @@ module JekyllImgFlow
47
47
  end
48
48
  end
49
49
 
50
+ # Inject modal CSS/JS into pages that contain data-imgflow-modal triggers
51
+ %i[pages documents].each do |type|
52
+ Jekyll::Hooks.register type, :post_render do |doc|
53
+ doc.output = ModalAssets.inject(doc.output) if doc.output
54
+ end
55
+ end
56
+
50
57
  def self.cleanup_orphaned_images(site, manifest = nil)
51
58
  Jekyll.logger.info "๐Ÿงน ImgFlow: Checking for orphaned specialized images..."
52
59
 
@@ -4,6 +4,8 @@ module JekyllImgFlow
4
4
  # Unified HTML Generator for all markup formats
5
5
  # Supports Picture Tag compatibility with multiple markup formats and attributes
6
6
  class HtmlGenerator
7
+ include ModalWrapper
8
+
7
9
  # Generate HTML based on markup format and attributes
8
10
  # @param results [Array<String>] Processed image paths
9
11
  # @param attributes [Hash] HTML attributes by element
@@ -47,6 +49,9 @@ module JekyllImgFlow
47
49
  # Wrap in link if specified
48
50
  html = wrap_with_link(html) if @attributes[:link]
49
51
 
52
+ # Wrap in modal trigger if enabled (only for HTML elements, not raw URLs)
53
+ html = wrap_with_modal(html) if modal_enabled? && html_element?
54
+
50
55
  # Wrap in parent container if specified
51
56
  html = wrap_with_parent(html) if @attributes[:parent]&.any?
52
57
 
@@ -77,7 +82,8 @@ module JekyllImgFlow
77
82
  a: attributes[:a] || {},
78
83
  parent: attributes[:parent] || {},
79
84
  alt: attributes[:alt],
80
- link: attributes[:link]
85
+ link: attributes[:link],
86
+ modal: attributes[:modal]
81
87
  }
82
88
  end
83
89
 
@@ -89,7 +95,8 @@ module JekyllImgFlow
89
95
  a: {},
90
96
  parent: {},
91
97
  alt: nil,
92
- link: nil
98
+ link: nil,
99
+ modal: nil
93
100
  }
94
101
  end
95
102
 
@@ -193,7 +193,8 @@ module Jekyll
193
193
  a: extract_prefixed_attrs(base_attrs, "a-"),
194
194
  parent: extract_prefixed_attrs(base_attrs, "parent-"),
195
195
  alt: base_attrs[:alt],
196
- link: base_attrs[:link]
196
+ link: base_attrs[:link],
197
+ modal: base_attrs[:modal]
197
198
  }
198
199
  end
199
200
 
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ module JekyllImgFlow
4
+ # Inline CSS and JS for the image modal/lightbox feature.
5
+ # Injected by hooks.rb into pages that contain data-imgflow-modal triggers.
6
+ module ModalAssets
7
+ CSS = <<~CSS
8
+ .imgflow-modal-overlay{position:fixed;inset:0;background:rgba(0,0,0,.85);
9
+ display:flex;align-items:center;justify-content:center;z-index:9999;
10
+ cursor:pointer;animation:imgflow-fade .15s ease-out}
11
+ .imgflow-modal-image{max-width:90vw;max-height:90vh;object-fit:contain;
12
+ cursor:auto;border-radius:4px;box-shadow:0 4px 30px rgba(0,0,0,.5)}
13
+ .imgflow-modal-close{position:absolute;top:1rem;right:1rem;
14
+ background:rgba(255,255,255,.2);border:none;color:#fff;font-size:2rem;
15
+ width:3rem;height:3rem;border-radius:50%;cursor:pointer;
16
+ display:flex;align-items:center;justify-content:center;line-height:1}
17
+ .imgflow-modal-close:hover{background:rgba(255,255,255,.4)}
18
+ @keyframes imgflow-fade{from{opacity:0}to{opacity:1}}
19
+ CSS
20
+
21
+ JS = <<~JS
22
+ (function(){
23
+ function openModal(src,alt){
24
+ var o=document.createElement('div');
25
+ o.className='imgflow-modal-overlay';
26
+ var i=document.createElement('img');
27
+ i.src=src;i.alt=alt||'';i.className='imgflow-modal-image';
28
+ var b=document.createElement('button');
29
+ b.className='imgflow-modal-close';b.setAttribute('aria-label','Close');
30
+ b.innerHTML='&times;';
31
+ o.appendChild(b);o.appendChild(i);document.body.appendChild(o);
32
+ function c(){document.body.removeChild(o);
33
+ document.removeEventListener('keydown',k);}
34
+ function k(e){if(e.key==='Escape')c();}
35
+ o.addEventListener('click',function(e){
36
+ if(e.target===o||e.target===b)c();});
37
+ document.addEventListener('keydown',k);}
38
+ document.addEventListener('click',function(e){
39
+ var t=e.target.closest('[data-imgflow-modal]');
40
+ if(!t)return;e.preventDefault();
41
+ openModal(t.getAttribute('href'),t.getAttribute('data-imgflow-alt'));});
42
+ })();
43
+ JS
44
+
45
+ def self.inject(html)
46
+ return html unless html&.include?("data-imgflow-modal")
47
+
48
+ style_tag = "<style>\n#{CSS}</style>"
49
+ script_tag = "<script>\n#{JS}</script>"
50
+
51
+ if html.include?("</head>")
52
+ html = html.sub("</head>", "#{style_tag}\n</head>")
53
+ html = html.sub("</body>", "#{script_tag}\n</body>") if html.include?("</body>")
54
+ elsif html.include?("</body>")
55
+ html = html.sub("</body>", "#{style_tag}\n#{script_tag}\n</body>")
56
+ else
57
+ html = "#{html}\n#{style_tag}\n#{script_tag}"
58
+ end
59
+
60
+ html
61
+ end
62
+ end
63
+
64
+ # Modal wrapping logic for HtmlGenerator โ€” extracted to keep HtmlGenerator
65
+ # under the RuboCop class length limit.
66
+ module ModalWrapper
67
+ # Formats that produce raw URLs/srcsets (not wrappable HTML elements)
68
+ NON_HTML_FORMATS = %w[direct_url naked_srcset].freeze
69
+
70
+ # Check if the current markup format produces an HTML element
71
+ def html_element?
72
+ !NON_HTML_FORMATS.include?(@markup_format)
73
+ end
74
+
75
+ # Determine if modal behavior is enabled for this image
76
+ # Per-image modal:true/false overrides config default
77
+ # Modal is skipped when an explicit link is set
78
+ def modal_enabled?
79
+ return false if @attributes[:link]
80
+
81
+ modal_attr = @attributes[:modal]
82
+ return modal_attr.to_s == "true" if modal_attr
83
+
84
+ @config&.image_modal ? true : false
85
+ end
86
+
87
+ # Pick the best image path for the modal โ€” prefer the fallback format
88
+ # (e.g. jpg) for maximum browser compatibility
89
+ def modal_image_path
90
+ fallback_ext = @config&.fallback_format ? ".#{@config.fallback_format}" : ".jpg"
91
+ fallback = @results.find { |r| File.extname(r).downcase == fallback_ext }
92
+ fallback || @results.last
93
+ end
94
+
95
+ # Wrap HTML in modal trigger anchor
96
+ def wrap_with_modal(html)
97
+ modal_href = html_path(modal_image_path)
98
+ return html unless modal_href
99
+
100
+ data_attrs = " data-imgflow-modal"
101
+ alt = @attributes[:alt]
102
+ data_attrs += " data-imgflow-alt=\"#{escape_attr_value(alt)}\"" if alt
103
+
104
+ "<a href=\"#{modal_href}\"#{data_attrs}>#{html}</a>"
105
+ end
106
+ end
107
+ end
@@ -9,7 +9,7 @@ module JekyllImgFlow
9
9
  # Define valid operation parameters and attribute types
10
10
  OPERATION_PARAMS = %i[width height ratio aspect_ratio quality format formats
11
11
  optimize level watermark opacity position keep preset].freeze
12
- HTML_ATTRIBUTES = %i[alt class title loading].freeze
12
+ HTML_ATTRIBUTES = %i[alt class title loading link modal].freeze
13
13
 
14
14
  # Simple operation mappings for single-parameter operations
15
15
  SIMPLE_OPERATIONS = {
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JekyllImgFlow
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -23,6 +23,7 @@ require_relative "jekyll-imgflow/provider_registry"
23
23
  require_relative "jekyll-imgflow/build_time_processor"
24
24
  require_relative "jekyll-imgflow/parser"
25
25
  require_relative "jekyll-imgflow/tags/tag_registry"
26
+ require_relative "jekyll-imgflow/modal_assets"
26
27
  require_relative "jekyll-imgflow/html_generator"
27
28
  require_relative "jekyll-imgflow/imgflow_tag"
28
29
  require_relative "jekyll-imgflow/picture_tag_adaptor"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-imgflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Svend Gundestrup
@@ -74,6 +74,7 @@ files:
74
74
  - lib/jekyll-imgflow/html_generator.rb
75
75
  - lib/jekyll-imgflow/imgflow_tag.rb
76
76
  - lib/jekyll-imgflow/manifest_manager.rb
77
+ - lib/jekyll-imgflow/modal_assets.rb
77
78
  - lib/jekyll-imgflow/operation_processor.rb
78
79
  - lib/jekyll-imgflow/parser.rb
79
80
  - lib/jekyll-imgflow/path_resolver.rb