al_img_tools 1.0.0 → 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6f6550e1c0bb52d5441af3ff5694fe09b246860aaab960b27dffe8465d60a5d3
4
- data.tar.gz: 797301afab6ee75d003251f6bbe9500863c87a0eb1f33df7f5375dd3c634f8f7
3
+ metadata.gz: d0b1285b1603c7d9106f5ad809554097f58c763bd7ae8efbfbfc0b2214a8d37e
4
+ data.tar.gz: 1a956fb012c2407646cc2a0d96d77f425ae939a0feee0f1608d46e54e58eb31e
5
5
  SHA512:
6
- metadata.gz: 7dfcadad0d3e1d810e559f4e5cfa201cef6bd96584a40aff6bd5378fd486ef24a0067dc7d4285647f9a8b6fb634024eb98e941fc106826c429b8f05b95dd782d
7
- data.tar.gz: 782ff6c34c4f358063421e707afe9635b82f0b667099c8138b1f3f6587c945335fb8bd578660ba7c322c2fe83b2fafb573f158309901fdc27fb04ecf7cdc44a2
6
+ metadata.gz: 7cd648a5aa7bc2f888453696ebed3bd551a20d16016bfdff92abdf7e41fa03fefaf7763230888ed1545095494ce532af9551910ea88dc5645e6e06d5a59a8241
7
+ data.tar.gz: 3a70c2754a6a415ac50be057efce129a546ce8743afba7dc3b646aab708a8b5450ec10cbcd48c7dc9107cf89697e5514ec4cdf1959d16a8528b782704b52ac19
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.2 - 2026-02-17
4
+
5
+ - Finalized plugin-owned lightbox runtime by shipping a vanilla Lightbox2-compatible adapter path.
6
+ - Ensured static asset generator picks up all plugin runtime assets under `lib/assets/al_img_tools/**`.
7
+ - Added test coverage for adapter CSS/JS packaging contracts.
8
+ - Reduced noisy static-file logging by treating unchanged asset copies as debug-level skips.
9
+
10
+ ## 1.0.1 - 2026-02-17
11
+
12
+ - Replaced Lightbox2 CDN runtime dependency with a plugin-owned vanilla lightbox adapter.
13
+ - Added plugin-owned lightbox adapter CSS/JS assets and static asset registration.
14
+ - Removed jQuery dependency from medium zoom initialization.
15
+
3
16
  ## 0.1.0 - 2026-02-07
4
17
 
5
18
  - Initial gem release.
data/README.md CHANGED
@@ -5,7 +5,7 @@ A Jekyll plugin that provides various image manipulation features for al-folio s
5
5
  ## Features
6
6
 
7
7
  - Image comparison sliders
8
- - Lightbox galleries
8
+ - Lightbox-style galleries (vanilla adapter for `data-lightbox` markup)
9
9
  - Medium zoom
10
10
  - Image sliders
11
11
  - PhotoSwipe galleries
@@ -42,7 +42,7 @@ plugins:
42
42
  layout: page
43
43
  title: Gallery
44
44
  images:
45
- lightbox2: true # Enable Lightbox2 gallery (or use `gallery: true`)
45
+ lightbox2: true # Enable lightbox adapter (or use `gallery: true`)
46
46
  compare: true # Enable image comparison slider
47
47
  slider: true # Enable image slider
48
48
  photoswipe: true # Enable PhotoSwipe gallery
data/lib/al_img_tools.rb CHANGED
@@ -4,8 +4,8 @@ module AlImgTools
4
4
  # Directory structure constants
5
5
  PLUGIN_NAME = 'al_img_tools'
6
6
  ASSETS_DIR = 'assets'
7
+ CSS_DIR = 'css'
7
8
  JS_DIR = 'js'
8
- JS_FILES = ['zoom.js', 'venobox-setup.js'].freeze
9
9
 
10
10
  # Custom StaticFile class to track when files are written
11
11
  class PluginStaticFile < Jekyll::StaticFile
@@ -15,7 +15,7 @@ module AlImgTools
15
15
  if result
16
16
  Jekyll.logger.info("AlImgTools:", "Successfully copied #{name} from #{path} to #{destination(dest)}")
17
17
  else
18
- Jekyll.logger.error("AlImgTools:", "Failed to copy #{name} from #{path}")
18
+ Jekyll.logger.debug("AlImgTools:", "Skipped unchanged asset #{name} from #{path}")
19
19
  end
20
20
  end
21
21
  end
@@ -26,36 +26,14 @@ module AlImgTools
26
26
  priority :low
27
27
 
28
28
  def generate(site)
29
- # Get the plugin's assets directory path - now includes the full desired structure
30
29
  plugin_lib_path = File.expand_path('.', __dir__)
31
- Jekyll.logger.info("AlImgTools:", "Plugin lib directory: #{plugin_lib_path}")
32
-
33
- # Register each JS file
34
- JS_FILES.each do |js_file|
35
- # Construct source path - now includes the full path structure we want in the output
36
- source_path = File.join(plugin_lib_path, ASSETS_DIR, PLUGIN_NAME, JS_DIR, js_file)
37
- Jekyll.logger.info("AlImgTools:", "Looking for source file: #{source_path}")
38
-
39
- # Only add the file if it exists
40
- if File.exist?(source_path)
41
- # Create a static file with:
42
- # - site: the Jekyll site instance
43
- # - base: the base directory containing the file
44
- # - dir: the directory relative to base (used to construct the destination path)
45
- # - name: the file name
46
- static_file = PluginStaticFile.new(
47
- site,
48
- plugin_lib_path, # base directory
49
- File.join(ASSETS_DIR, PLUGIN_NAME, JS_DIR), # source dir relative to base
50
- js_file # filename
51
- )
52
-
53
- # The file will be copied to: _site/assets/al_img_tools/js/[filename]
54
- site.static_files << static_file
55
- Jekyll.logger.info("AlImgTools:", "Registered #{js_file} for copying to #{ASSETS_DIR}/#{PLUGIN_NAME}/#{JS_DIR}/")
56
- else
57
- Jekyll.logger.warn("AlImgTools:", "JavaScript file not found: #{source_path}")
58
- end
30
+ assets_root = File.join(plugin_lib_path, ASSETS_DIR, PLUGIN_NAME)
31
+
32
+ Dir.glob(File.join(assets_root, '**', '*')).sort.each do |source_path|
33
+ next if File.directory?(source_path)
34
+
35
+ relative_dir = File.dirname(source_path).sub("#{plugin_lib_path}/", '')
36
+ site.static_files << PluginStaticFile.new(site, plugin_lib_path, relative_dir, File.basename(source_path))
59
37
  end
60
38
  end
61
39
  end
@@ -75,17 +53,6 @@ module AlImgTools
75
53
  },
76
54
  'version' => '8.0.6'
77
55
  },
78
- 'lightbox2' => {
79
- 'integrity' => {
80
- 'css' => 'sha256-uypRbsAiJcFInM/ndyI/JHpzNe6DtUNXaWEUWEPfMGo=',
81
- 'js' => 'sha256-A6jI5V9s1JznkWwsBaRK8kSeXLgIqQfxfnvdDOZEURY='
82
- },
83
- 'url' => {
84
- 'css' => 'https://cdn.jsdelivr.net/npm/lightbox2@{{version}}/dist/css/lightbox.min.css',
85
- 'js' => 'https://cdn.jsdelivr.net/npm/lightbox2@{{version}}/dist/js/lightbox.min.js'
86
- },
87
- 'version' => '2.11.5'
88
- },
89
56
  'medium_zoom' => {
90
57
  'integrity' => {
91
58
  'js' => 'sha256-ZgMyDAIYDYGxbcpJcfUnYwNevG/xi9OHKaR/8GK+jWc='
@@ -174,8 +141,8 @@ module AlImgTools
174
141
  !!(images['lightbox2'] || images['gallery'])
175
142
  end
176
143
 
177
- def asset_url(context, file_name)
178
- "#{base_url(context)}/#{ASSETS_DIR}/#{PLUGIN_NAME}/#{JS_DIR}/#{file_name}"
144
+ def asset_url(context, file_name, dir = JS_DIR)
145
+ "#{base_url(context)}/#{ASSETS_DIR}/#{PLUGIN_NAME}/#{dir}/#{file_name}"
179
146
  end
180
147
 
181
148
  def library_url(library, asset_type)
@@ -212,12 +179,10 @@ module AlImgTools
212
179
 
213
180
  if lightbox_enabled?(images)
214
181
  output << <<~HTML
215
- <!-- Lightbox2 -->
182
+ <!-- Lightbox adapter -->
216
183
  <link
217
184
  rel="stylesheet"
218
- href="#{library_url('lightbox2', 'css')}"
219
- integrity="#{library_integrity('lightbox2', 'css')}"
220
- crossorigin="anonymous"
185
+ href="#{asset_url(context, 'lightbox2-adapter.css', CSS_DIR)}"
221
186
  >
222
187
  HTML
223
188
  end
@@ -304,12 +269,7 @@ module AlImgTools
304
269
 
305
270
  if lightbox_enabled?(images)
306
271
  output << <<~HTML
307
- <script
308
- defer
309
- src="#{library_url('lightbox2', 'js')}"
310
- integrity="#{library_integrity('lightbox2', 'js')}"
311
- crossorigin="anonymous"
312
- ></script>
272
+ <script defer src="#{asset_url(context, 'lightbox2-adapter.js')}"></script>
313
273
  HTML
314
274
  end
315
275
 
@@ -0,0 +1,68 @@
1
+ .al-lightbox-open {
2
+ overflow: hidden;
3
+ }
4
+
5
+ .al-lightbox-overlay {
6
+ position: fixed;
7
+ inset: 0;
8
+ z-index: 1200;
9
+ display: none;
10
+ align-items: center;
11
+ justify-content: center;
12
+ background: rgba(0, 0, 0, 0.88);
13
+ padding: 2rem;
14
+ }
15
+
16
+ .al-lightbox-overlay.is-open {
17
+ display: flex;
18
+ }
19
+
20
+ .al-lightbox-figure {
21
+ margin: 0;
22
+ max-width: min(90vw, 1200px);
23
+ max-height: 90vh;
24
+ text-align: center;
25
+ }
26
+
27
+ .al-lightbox-image {
28
+ max-width: 100%;
29
+ max-height: calc(90vh - 3rem);
30
+ object-fit: contain;
31
+ }
32
+
33
+ .al-lightbox-caption {
34
+ margin-top: 0.75rem;
35
+ color: #f8f8f8;
36
+ font-size: 0.95rem;
37
+ }
38
+
39
+ .al-lightbox-close,
40
+ .al-lightbox-nav {
41
+ position: absolute;
42
+ border: 0;
43
+ background: transparent;
44
+ color: #fff;
45
+ cursor: pointer;
46
+ line-height: 1;
47
+ }
48
+
49
+ .al-lightbox-close {
50
+ top: 1rem;
51
+ right: 1rem;
52
+ font-size: 2rem;
53
+ }
54
+
55
+ .al-lightbox-nav {
56
+ top: 50%;
57
+ transform: translateY(-50%);
58
+ font-size: 2.25rem;
59
+ padding: 0.5rem;
60
+ }
61
+
62
+ .al-lightbox-prev {
63
+ left: 0.75rem;
64
+ }
65
+
66
+ .al-lightbox-next {
67
+ right: 0.75rem;
68
+ }
@@ -0,0 +1,101 @@
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+ const links = Array.from(document.querySelectorAll("a[data-lightbox]"));
3
+ if (!links.length) {
4
+ return;
5
+ }
6
+
7
+ const overlay = document.createElement("div");
8
+ overlay.className = "al-lightbox-overlay";
9
+ overlay.setAttribute("role", "dialog");
10
+ overlay.setAttribute("aria-modal", "true");
11
+ overlay.setAttribute("aria-label", "Image preview");
12
+ overlay.innerHTML = `
13
+ <button type="button" class="al-lightbox-close" aria-label="Close preview">&times;</button>
14
+ <button type="button" class="al-lightbox-nav al-lightbox-prev" aria-label="Previous image">&#10094;</button>
15
+ <figure class="al-lightbox-figure">
16
+ <img class="al-lightbox-image" alt="">
17
+ <figcaption class="al-lightbox-caption"></figcaption>
18
+ </figure>
19
+ <button type="button" class="al-lightbox-nav al-lightbox-next" aria-label="Next image">&#10095;</button>
20
+ `;
21
+ document.body.appendChild(overlay);
22
+
23
+ const image = overlay.querySelector(".al-lightbox-image");
24
+ const caption = overlay.querySelector(".al-lightbox-caption");
25
+ const closeBtn = overlay.querySelector(".al-lightbox-close");
26
+ const prevBtn = overlay.querySelector(".al-lightbox-prev");
27
+ const nextBtn = overlay.querySelector(".al-lightbox-next");
28
+
29
+ let currentGroup = [];
30
+ let currentIndex = 0;
31
+
32
+ const readCaption = (link) => {
33
+ return link.getAttribute("data-title") || link.querySelector("img")?.getAttribute("alt") || "";
34
+ };
35
+
36
+ const updateView = () => {
37
+ const link = currentGroup[currentIndex];
38
+ if (!link) {
39
+ return;
40
+ }
41
+ image.src = link.href;
42
+ image.alt = readCaption(link);
43
+ caption.textContent = readCaption(link);
44
+ prevBtn.disabled = currentGroup.length <= 1;
45
+ nextBtn.disabled = currentGroup.length <= 1;
46
+ };
47
+
48
+ const open = (group, index) => {
49
+ currentGroup = group;
50
+ currentIndex = index;
51
+ updateView();
52
+ overlay.classList.add("is-open");
53
+ document.body.classList.add("al-lightbox-open");
54
+ };
55
+
56
+ const close = () => {
57
+ overlay.classList.remove("is-open");
58
+ image.src = "";
59
+ document.body.classList.remove("al-lightbox-open");
60
+ };
61
+
62
+ const step = (delta) => {
63
+ if (currentGroup.length <= 1) {
64
+ return;
65
+ }
66
+ currentIndex = (currentIndex + delta + currentGroup.length) % currentGroup.length;
67
+ updateView();
68
+ };
69
+
70
+ links.forEach((link) => {
71
+ link.addEventListener("click", (event) => {
72
+ event.preventDefault();
73
+ const groupName = link.getAttribute("data-lightbox") || "__default";
74
+ const group = links.filter((candidate) => (candidate.getAttribute("data-lightbox") || "__default") === groupName);
75
+ const index = group.indexOf(link);
76
+ open(group, index < 0 ? 0 : index);
77
+ });
78
+ });
79
+
80
+ closeBtn.addEventListener("click", close);
81
+ prevBtn.addEventListener("click", () => step(-1));
82
+ nextBtn.addEventListener("click", () => step(1));
83
+ overlay.addEventListener("click", (event) => {
84
+ if (event.target === overlay) {
85
+ close();
86
+ }
87
+ });
88
+
89
+ document.addEventListener("keydown", (event) => {
90
+ if (!overlay.classList.contains("is-open")) {
91
+ return;
92
+ }
93
+ if (event.key === "Escape") {
94
+ close();
95
+ } else if (event.key === "ArrowLeft") {
96
+ step(-1);
97
+ } else if (event.key === "ArrowRight") {
98
+ step(1);
99
+ }
100
+ });
101
+ });
@@ -1,6 +1,9 @@
1
- // Initialize medium zoom.
2
- $(document).ready(function () {
3
- medium_zoom = mediumZoom("[data-zoomable]", {
4
- background: getComputedStyle(document.documentElement).getPropertyValue("--global-bg-color") + "ee", // + 'ee' for trasparency.
1
+ document.addEventListener("DOMContentLoaded", () => {
2
+ if (typeof mediumZoom !== "function") {
3
+ return;
4
+ }
5
+ mediumZoom("[data-zoomable]", {
6
+ // Append alpha to theme background color to keep content visible under zoom.
7
+ background: `${getComputedStyle(document.documentElement).getPropertyValue("--global-bg-color")}ee`,
5
8
  });
6
- });
9
+ });
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: al_img_tools
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - al-org
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-02-16 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: jekyll
@@ -90,6 +89,8 @@ files:
90
89
  - LICENSE
91
90
  - README.md
92
91
  - lib/al_img_tools.rb
92
+ - lib/assets/al_img_tools/css/lightbox2-adapter.css
93
+ - lib/assets/al_img_tools/js/lightbox2-adapter.js
93
94
  - lib/assets/al_img_tools/js/venobox-setup.js
94
95
  - lib/assets/al_img_tools/js/zoom.js
95
96
  homepage: https://github.com/al-org-dev/al-img-tools
@@ -99,7 +100,6 @@ metadata:
99
100
  allowed_push_host: https://rubygems.org
100
101
  homepage_uri: https://github.com/al-org-dev/al-img-tools
101
102
  source_code_uri: https://github.com/al-org-dev/al-img-tools
102
- post_install_message:
103
103
  rdoc_options: []
104
104
  require_paths:
105
105
  - lib
@@ -114,8 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
114
  - !ruby/object:Gem::Version
115
115
  version: '0'
116
116
  requirements: []
117
- rubygems_version: 3.4.10
118
- signing_key:
117
+ rubygems_version: 4.0.6
119
118
  specification_version: 4
120
119
  summary: Image interaction tags and assets for Jekyll
121
120
  test_files: []