photosuite 0.1.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.
package/README.md ADDED
@@ -0,0 +1,244 @@
1
+ ![Sample Image](public/Wild-squirrel-feeding-interaction-with-hand-in-natural-forest.png)
2
+
3
+ # Photosuite
4
+
5
+ [Official Website](https://photosuite.lhasa.icu) • [Latest Release](https://github.com/achuanya/photosuite/releases) • [Changelog](https://github.com/achuanya/photosuite/main/Changelog.md) • [简体中文](./README.zh-CN.md)
6
+
7
+ Photosuite is a simple yet feature-rich image integration tailored for independent blogs. It modularly integrates lightbox, EXIF data, path resolution, and more into a single, zero-config package. Out of the box, no tedious configuration required—give your blog images a fresh look with just one line of code!
8
+
9
+ ## Features
10
+
11
+ * **Lightbox**: Customized and integrated GLightbox for a more minimalist and practical experience.
12
+ * **EXIF**: Integrated `exiftool-vendored.js` for fast execution and broad coverage.
13
+ * **Path Resolution**: Simply insert the filename, and it automatically resolves the absolute path.
14
+ * **Captions**: Automatically extracts the image's `alt` attribute to display as a caption.
15
+ * **Performance**: Purely static, modular features, loaded on demand.
16
+ * **Zero-Config Start**: Default settings satisfy most needs, while offering rich options for deep customization.
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pnpm add photosuite
22
+ # or
23
+ npm install photosuite
24
+ # or
25
+ yarn add photosuite
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ Integrating Photosuite with Astro is very simple, just add the following configuration to `astro.config.js`:
31
+
32
+ ```javascript
33
+ import { defineConfig } from 'astro/config';
34
+ import photosuite from 'photosuite';
35
+ import "photosuite/dist/photosuite.css";
36
+
37
+ export default defineConfig({
38
+ integrations: [
39
+ photosuite({
40
+ // [Required] Specify the CSS selector for the scope
41
+ // Recommended: Your content container to avoid affecting other parts of the site. Supports multiple selectors separated by commas.
42
+ scope: '#main',
43
+ })
44
+ ]
45
+ });
46
+ ```
47
+
48
+ Once configured, Photosuite will automatically process all images in your Markdown/MDX files.
49
+
50
+ ## Features & Configuration
51
+
52
+ ### 1. Path Resolution
53
+
54
+ Managing image paths in blog posts can be tedious. Photosuite offers flexible resolution strategies that you can configure according to your needs.
55
+
56
+ **Scenario A: All images in a single domain/directory**
57
+
58
+ ```javascript
59
+ photosuite({
60
+ scope: '#main',
61
+ imageBase: 'https://cdn.example.com/images/',
62
+ })
63
+ ```
64
+
65
+ **Markdown Usage:**
66
+ ```markdown
67
+ ![My Photo](photo.jpg)
68
+ <!-- Resolves to: https://cdn.example.com/images/photo.jpg -->
69
+ ```
70
+
71
+ **Scenario B: Separate image directory per post (Default)**
72
+
73
+ You can specify the directory name in the Frontmatter:
74
+
75
+ ```yaml
76
+ ---
77
+ title: My First GitHub PR
78
+ imageDir: "2025-11-26-my-first-github-pr"
79
+ ---
80
+
81
+ ![My Photo](photo.jpg)
82
+ <!-- Resolves to: https://cdn.example.com/images/2025-11-26-my-first-github-pr/photo.jpg -->
83
+ ```
84
+
85
+ **Scenario C: Use filename as directory**
86
+
87
+ ```javascript
88
+ photosuite({
89
+ scope: '#main',
90
+ imageBase: 'https://cdn.example.com/',
91
+ fileDir: true, // Enable this option
92
+ })
93
+ ```
94
+
95
+ If your post filename is `2025-11-26-my-first-github-pr.md`, the image path automatically resolves to:
96
+
97
+ `https://cdn.example.com/images/2025-11-26-my-first-github-pr/photo.jpg`
98
+
99
+ ### 2. EXIF Data Display
100
+
101
+ Photosuite uses `exiftool-vendored.js` to extract information at build time.
102
+
103
+ **Default Configuration:**
104
+ Default display: Camera Model, Lens Model, Focal Length, Aperture, Shutter Speed, ISO, Date Original.
105
+
106
+ > NIKON Z 30 · NIKKOR Z DX 16-50mm f/3.5-6.3 VR · 20.5 mm · ƒ/3.8 · 1/15 · ISO 1000 · 2025/12/9
107
+
108
+ **Custom Configuration:**
109
+
110
+ ```javascript
111
+ photosuite({
112
+ // ...
113
+ exif: {
114
+ enabled: true,
115
+ // Custom fields: Focal Length, Aperture, Shutter Speed, ISO
116
+ fields: ['FocalLength', 'FNumber', 'ExposureTime', 'ISO'],
117
+ // Custom separator
118
+ separator: ' · '
119
+ }
120
+ })
121
+ ```
122
+
123
+ ### 3. Lightbox & Captions
124
+
125
+ GLightbox has been customized to differ slightly from the official version.
126
+
127
+ Supports native configuration, refer to: [GLightbox](https://github.com/achuanya/glightbox)
128
+
129
+ ```javascript
130
+ photosuite({
131
+ // ...
132
+ // Disable lightbox
133
+ glightbox: false,
134
+
135
+ // Disable captions
136
+ imageAlts: false,
137
+
138
+ // Pass native GLightbox options
139
+ glightboxOptions: {
140
+ loop: true,
141
+ zoomable: true,
142
+ }
143
+ })
144
+ ```
145
+
146
+ ## Complete Configuration Reference
147
+
148
+ ### Parameter List
149
+
150
+ | Parameter | Type | Required | Default | Description |
151
+ | :--- | :--- | :---: | :--- | :--- |
152
+ | `scope` | `string` | ✅ | - | **Scope**. CSS selector, only processes images within this container. Supports multiple selectors separated by commas. |
153
+ | `selector` | `string` | ❌ | `"a.glightbox"` | **Image Selector**. Specifies which images need lightbox effect. |
154
+ | `imageBase` | `string` | ❌ | - | **Base Image URL**. Prefix used for splicing relative paths. |
155
+ | `imageDir` | `string` | ❌ | `"imageDir"` | **Directory Field Name**. Field name in Markdown Frontmatter to specify image subdirectory. |
156
+ | `fileDir` | `boolean` | ❌ | `false` | **Filename Archiving**. Whether to automatically use Markdown filename as image subdirectory. |
157
+ | `glightbox` | `boolean` | ❌ | `true` | **Enable Lightbox**. Whether to load GLightbox module. |
158
+ | `imageAlts` | `boolean` | ❌ | `true` | **Enable Captions**. Whether to display `alt` attribute as image caption. |
159
+ | `exif` | `boolean` \| `object` | ❌ | `true` | **Enable EXIF**. `false` to disable, `true` for default config, or pass object to customize via fields:[]. |
160
+ | `glightboxOptions` | `object` | ❌ | - | **Native Lightbox Config**. Configuration items passed through to GLightbox. |
161
+
162
+ ### Full Configuration Code Example
163
+
164
+ ```javascript
165
+ import photosuite from 'photosuite';
166
+ import "photosuite/dist/photosuite.css";
167
+
168
+ photosuite({
169
+ // ----------------
170
+ // Required
171
+ // ----------------
172
+ scope: '#main', // Your content container class name
173
+
174
+ // ----------------
175
+ // Optional (Values below are defaults)
176
+ // ----------------
177
+
178
+ // Basic Settings
179
+ selector: 'a.glightbox',
180
+
181
+ // Path Resolution
182
+ imageBase: '',
183
+ imageDir: 'imageDir',
184
+ fileDir: false,
185
+
186
+ // Feature Toggles
187
+ glightbox: true,
188
+ imageAlts: true,
189
+
190
+ // EXIF Detailed Configuration
191
+ exif: {
192
+ enabled: true,
193
+ fields: [
194
+ 'Model', // Camera Model
195
+ 'LensModel', // Lens Model
196
+ 'FocalLength', // Focal Length
197
+ 'FNumber', // Aperture
198
+ 'ExposureTime', // Shutter Speed
199
+ 'ISO', // ISO
200
+ 'DateTimeOriginal' // Date Original
201
+ ],
202
+ separator: ' · ' // Separator
203
+ },
204
+
205
+ // Native GLightbox Configuration
206
+ glightboxOptions: {
207
+ loop: true,
208
+ touchNavigation: true,
209
+ closeOnOutsideClick: true
210
+ }
211
+ })
212
+ ```
213
+
214
+ ## FAQ
215
+
216
+ **Q: Why isn't EXIF data showing?**
217
+ A: Please check the following:
218
+ 1. Does the image contain EXIF data? (Some compression tools strip EXIF)
219
+ 2. EXIF data is only displayed when at least the exposure triangle (Focal Length, Aperture, Shutter Speed) is present.
220
+
221
+ **Q: I only want to use Photosuite on certain images, what should I do?**
222
+ A: You can precisely control the scope via CSS selectors (comma-separated for multiple selectors). For example, only take effect inside elements with ID `#main`:
223
+
224
+ ```javascript
225
+ photosuite({
226
+ scope: '#main',
227
+ // ... other configurations
228
+ })
229
+ ```
230
+
231
+ ## Contributors
232
+
233
+ One line of code, one plugin, for independent blogs, it is insignificant, like dust.
234
+
235
+ But we insist on taking root in this soil, letting thought be free, and letting the soul rest!
236
+
237
+ [![](https://contrib.rocks/image?repo=achuanya/photosuite)](https://github.com/achuanya/photosuite/graphs/contributors)
238
+
239
+ ## Supporters
240
+ [![Stargazers repo roster for @achuanya/photosuite](https://reporoster.com/stars/achuanya/photosuite)](https://github.com/achuanya/photosuite/stargazers)
241
+
242
+ ## License
243
+
244
+ [GPL-3.0](./LICENSE)
@@ -0,0 +1,245 @@
1
+ ![示例图片](public/Wild-squirrel-feeding-interaction-with-hand-in-natural-forest.png)
2
+
3
+ # Photosuite
4
+
5
+ [官方网站](https://photosuite.lhasa.icu) • [最新版本](https://github.com/achuanya/photosuite/releases) • [更新日志](https://github.com/achuanya/photosuite/main/Changelog.md) • [English](./README.md)
6
+
7
+ Photosuite 是一款简单易用但功能丰富的图像插件,它将灯箱、EXIF、路径补全等功能,模块化整合在一个零配置的插件中。开箱即用,无需繁琐的配置,一行代码即可让您的图片焕然一新!
8
+
9
+ ## 特性
10
+
11
+ * **灯箱**:定制并集成 GLightbox 灯箱,更简约、更实用
12
+ * **EXIF**:集成 exiftool-vendored.js 执行快、覆盖广
13
+ * **路径**:只需要插入文件名,自动补全绝对路径
14
+ * **标题**:自动获取图片alt进行标题展示
15
+ * **性能**:纯静态,功能模块化,按需加载
16
+ * **零配置启动**:默认配置即可满足绝大多数需求,同时也提供丰富的选项供深度定制
17
+
18
+ ## 安装
19
+
20
+ ```bash
21
+ pnpm add photosuite
22
+ # 或
23
+ npm install photosuite
24
+ # 或
25
+ yarn add photosuite
26
+ ```
27
+
28
+ ## 快速开始
29
+
30
+ Astro 集成 Photosuite 非常简单,只需要在 `astro.config.js` 中添加以下配置:
31
+
32
+ ```javascript
33
+ import { defineConfig } from 'astro/config';
34
+ import photosuite from 'photosuite';
35
+ import "photosuite/dist/photosuite.css";
36
+
37
+ export default defineConfig({
38
+ integrations: [
39
+ photosuite({
40
+ // [必填] 指定生效范围的 CSS 选择器
41
+ // 建议指定为您的文章容器,避免影响网站其他部分。支持多个选择器,用逗号分隔
42
+ scope: '#main',
43
+ })
44
+ ]
45
+ });
46
+ ```
47
+
48
+ 配置完成后,Photosuite 会自动处理您 Markdown/MDX 中的所有图片。
49
+
50
+ ## 功能详解与配置
51
+
52
+ ### 1. 路径解析
53
+
54
+ 在写博客时,图片路径往往很麻烦。Photosuite 提供了灵活的路径解析策略,您可以根据实际情况进行配置
55
+
56
+ **场景 A:所有图片都在一个域名下**
57
+
58
+ ```javascript
59
+ photosuite({
60
+ scope: '#main',
61
+ imageBase: 'https://cdn.example.com/images/',
62
+ })
63
+ ```
64
+
65
+ **Markdown 写法:**
66
+ ```markdown
67
+ ![我的照片](photo.jpg)
68
+ <!-- 最终解析为: https://cdn.example.com/images/photo.jpg -->
69
+ ```
70
+
71
+ **场景 B:每篇文章有独立的图片目录(默认)**
72
+
73
+ 您可以在 Frontmatter 中指定目录名:
74
+
75
+ ```yaml
76
+ ---
77
+ title: 我的第一次 GitHub PR
78
+ imageDir: "2025-11-26-my-first-github-pr"
79
+ ---
80
+
81
+ ![我的照片](photo.jpg)
82
+ <!-- 最终解析为: https://cdn.example.com/images/2025-11-26-my-first-github-pr/photo.jpg -->
83
+ ```
84
+
85
+ **场景 C:以文件名为目录**
86
+
87
+ ```javascript
88
+ photosuite({
89
+ scope: '#main',
90
+ imageBase: 'https://cdn.example.com/',
91
+ fileDir: true, // 开启此选项
92
+ })
93
+ ```
94
+
95
+ 如果您的文章文件名是 `2025-11-26-my-first-github-pr.md`,图片路径会自动解析为:
96
+
97
+ `https://cdn.example.com/images/2025-11-26-my-first-github-pr/photo.jpg`
98
+
99
+ ### 2. EXIF 信息展示
100
+
101
+ Photosuite 使用 `exiftool-vendored.js` 在构建时提取信息。
102
+
103
+ **默认配置:**
104
+ 默认显示:相机型号、镜头型号、焦距、光圈、快门速度、ISO、拍摄时间。
105
+
106
+ > NIKON Z 30 · NIKKOR Z DX 16-50mm f/3.5-6.3 VR · 20.5 mm · ƒ/3.8 · 1/15 · ISO 1000 · 2025/12/9
107
+
108
+ **自定义配置:**
109
+
110
+ ```javascript
111
+ photosuite({
112
+ // ...
113
+ exif: {
114
+ enabled: true,
115
+ // 自定义显示字段:焦距、光圈、快门速度、ISO
116
+ fields: ['FocalLength', 'FNumber', 'ExposureTime', 'ISO'],
117
+ // 自定义分隔符
118
+ separator: ' · '
119
+ }
120
+ })
121
+ ```
122
+
123
+ ### 3. 灯箱与标题
124
+
125
+ GLightbox 经过我定制后,与官方版本有些许差异
126
+
127
+ 支持原生配置,可参考:[GLightbox](https://github.com/achuanya/glightbox)
128
+
129
+ ```javascript
130
+ photosuite({
131
+ // ...
132
+ // 关闭灯箱功能
133
+ glightbox: false,
134
+
135
+ // 关闭图片标题
136
+ imageAlts: false,
137
+
138
+ // GLightbox 原生配置传递
139
+ glightboxOptions: {
140
+ loop: true,
141
+ zoomable: true,
142
+ }
143
+ })
144
+ ```
145
+
146
+ ## 完整配置参考
147
+
148
+ ### 参数列表
149
+
150
+ | 参数 | 类型 | 必填 | 默认值 | 说明 |
151
+ | :--- | :--- | :---: | :--- | :--- |
152
+ | `scope` | `string` | ✅ | - | **生效范围**。CSS 选择器,仅处理该容器内的图片,可包含多个选择器,用逗号分隔 |
153
+ | `selector` | `string` | ❌ | `"a.glightbox"` | **图片选择器**。指定哪些图片需要启用灯箱效果 |
154
+ | `imageBase` | `string` | ❌ | - | **图片基础 URL**。用于拼接相对路径的前缀 |
155
+ | `imageDir` | `string` | ❌ | `"imageDir"` | **目录字段名**。在 Markdown Frontmatter 中指定图片目录的字段名称 |
156
+ | `fileDir` | `boolean` | ❌ | `false` | **文件名归档**。是否自动使用 Markdown 文件名作为图片子目录 |
157
+ | `glightbox` | `boolean` | ❌ | `true` | **启用灯箱**。是否加载 GLightbox 模块 |
158
+ | `imageAlts` | `boolean` | ❌ | `true` | **启用标题**。是否将 `alt` 属性显示为图片标题 |
159
+ | `exif` | `boolean` \| `object` | ❌ | `true` | **启用 EXIF**。可通过 fields:[] 配置显示选项 |
160
+ | `glightboxOptions` | `object` | ❌ | - | **灯箱原生配置**。透传给 GLightbox 的配置项 |
161
+
162
+ ### 全部配置代码示例
163
+
164
+ ```javascript
165
+ import photosuite from 'photosuite';
166
+ import "photosuite/dist/photosuite.css";
167
+
168
+ photosuite({
169
+ // ----------------
170
+ // 必填项
171
+ // ----------------
172
+ scope: '#main', // 您的文章容器类名
173
+
174
+ // ----------------
175
+ // 选填项 (以下均为默认值)
176
+ // ----------------
177
+
178
+ // 基础设置
179
+ selector: 'a.glightbox',
180
+
181
+ // 路径解析
182
+ imageBase: '',
183
+ imageDir: 'imageDir',
184
+ fileDir: false,
185
+
186
+ // 功能开关
187
+ glightbox: true,
188
+ imageAlts: true,
189
+
190
+ // EXIF 详细配置
191
+ exif: {
192
+ enabled: true,
193
+ fields: [
194
+ 'Model', // 相机型号
195
+ 'LensModel', // 镜头型号
196
+ 'FocalLength', // 焦距
197
+ 'FNumber', // 光圈
198
+ 'ExposureTime', // 快门速度
199
+ 'ISO', // 感光度
200
+ 'DateTimeOriginal' // 拍摄时间
201
+ ],
202
+ separator: ' · ' // 分隔符
203
+ },
204
+
205
+ // GLightbox 原生配置
206
+ glightboxOptions: {
207
+ loop: true,
208
+ touchNavigation: true,
209
+ closeOnOutsideClick: true
210
+ }
211
+ })
212
+ ```
213
+
214
+ ## 常见问题
215
+
216
+ **1.为什么 EXIF 信息没有显示?**
217
+ A: 请检查以下几点:
218
+
219
+ 1. 图片是否包含 EXIF 信息(某些压缩工具会去除 EXIF)
220
+ 2. EXIF 信息至少有曝光三要素(焦距、光圈、快门速度)时,才会显示
221
+
222
+ **2.我想只在某些图片上使用 Photosuite,怎么办?**
223
+ A: 您可以通过 CSS 选择器精确控制范围(多个选择器用逗号分隔)例如,只在类名为 `'#main` 的元素内部生效:
224
+
225
+ ```javascript
226
+ photosuite({
227
+ scope: '#main',
228
+ // ... 其他配置
229
+ })
230
+ ```
231
+
232
+ ## 贡献者们
233
+
234
+ 一行代码,一个插件,对于独立博客而言,微不足道,如同尘埃。
235
+
236
+ 但我们偏要在这片土壤中扎根,让思想自由,让灵魂安放!
237
+
238
+ [![](https://contrib.rocks/image?repo=achuanya/photosuite)](https://github.com/achuanya/photosuite/graphs/contributors)
239
+
240
+ ## 支持者们
241
+ [![Stargazers repo roster for @achuanya/photosuite](https://reporoster.com/stars/achuanya/photosuite)](https://github.com/achuanya/photosuite/stargazers)
242
+
243
+ ## 开源许可协议
244
+
245
+ [GPL-3.0](./LICENSE)
package/dist/demo.d.ts ADDED
File without changes
@@ -0,0 +1,36 @@
1
+ function ensurePhotosuiteContainer(e) {
2
+ let t = e.parentElement;
3
+ if (!t) return e;
4
+ let n = e;
5
+ e.tagName.toLowerCase() === "img" && t && t.tagName.toLowerCase() === "a" && t.classList.contains("glightbox") && (n = t);
6
+ let r = n.parentElement;
7
+ if (r && r.classList.contains("photosuite-item")) return r;
8
+ let i = document.createElement("div");
9
+ i.className = "photosuite-item";
10
+ let a = n.parentElement;
11
+ return a ? (a.replaceChild(i, n), i.appendChild(n), i) : i;
12
+ }
13
+ function processMedia(t, n, r) {
14
+ let i = /* @__PURE__ */ new Set(), a = (t) => {
15
+ let n = ensurePhotosuiteContainer(t);
16
+ i.has(n) || n.querySelector("img") && (r(n), i.add(n));
17
+ };
18
+ document.querySelectorAll(t).forEach((e) => {
19
+ e.querySelectorAll(n).forEach(a), e.querySelectorAll("img").forEach(a);
20
+ });
21
+ }
22
+ function ensureCaption(e) {
23
+ if (e.querySelector(".photosuite-caption")) return;
24
+ let t = e.querySelector("img");
25
+ if (!t) return;
26
+ let n = String(t.getAttribute("alt") || "").trim();
27
+ if (!n) return;
28
+ let r = document.createElement("div");
29
+ r.className = "photosuite-caption", r.textContent = n, e.appendChild(r);
30
+ }
31
+ function ensureExif(e) {
32
+ if (e.querySelector(".photosuite-exif")) return;
33
+ let t = document.createElement("div");
34
+ t.className = "photosuite-exif", e.appendChild(t);
35
+ }
36
+ export { ensureExif as n, processMedia as r, ensureCaption as t };
@@ -0,0 +1 @@
1
+ function e(e){let t=e.parentElement;if(!t)return e;let n=e;e.tagName.toLowerCase()===`img`&&t&&t.tagName.toLowerCase()===`a`&&t.classList.contains(`glightbox`)&&(n=t);let r=n.parentElement;if(r&&r.classList.contains(`photosuite-item`))return r;let i=document.createElement(`div`);i.className=`photosuite-item`;let a=n.parentElement;return a?(a.replaceChild(i,n),i.appendChild(n),i):i}function t(t,n,r){let i=new Set,a=t=>{let n=e(t);i.has(n)||n.querySelector(`img`)&&(r(n),i.add(n))};document.querySelectorAll(t).forEach(e=>{e.querySelectorAll(n).forEach(a),e.querySelectorAll(`img`).forEach(a)})}function n(e){if(e.querySelector(`.photosuite-caption`))return;let t=e.querySelector(`img`);if(!t)return;let n=String(t.getAttribute(`alt`)||``).trim();if(!n)return;let r=document.createElement(`div`);r.className=`photosuite-caption`,r.textContent=n,e.appendChild(r)}function r(e){if(e.querySelector(`.photosuite-exif`))return;let t=document.createElement(`div`);t.className=`photosuite-exif`,e.appendChild(t)}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return t}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return n}});
@@ -0,0 +1 @@
1
+ const e=require(`./dom-DMZsb49p.cjs`);async function t(t,n){await Promise.resolve().then(()=>require(`./exif-DwHkZ3YD.cjs`)),e.r(t,n,t=>{e.n(t)})}exports.enableExif=t;
@@ -0,0 +1,7 @@
1
+ import { n as ensureExif, r as processMedia } from "./dom-CDvVCbvk.js";
2
+ async function enableExif(n, r) {
3
+ await Promise.resolve({ }), processMedia(n, r, (t) => {
4
+ ensureExif(t);
5
+ });
6
+ }
7
+ export { enableExif };
@@ -0,0 +1,44 @@
1
+ function wrap(e, t) {
2
+ let n = e.currentSrc || e.src || "";
3
+ if (!n) return;
4
+ let r = String(e.getAttribute("alt") || "").trim(), i = document.createElement("a");
5
+ i.href = n, i.className = "glightbox", i.dataset.gallery = t, r && (i.dataset.title = r), e.parentElement.replaceChild(i, e), i.appendChild(e);
6
+ }
7
+ function sync(e, t) {
8
+ let n = e.querySelector("img");
9
+ if (!n) return;
10
+ let r = n.currentSrc || n.src;
11
+ r && e.getAttribute("href") !== r && e.setAttribute("href", r);
12
+ let i = n.getAttribute("alt");
13
+ i && !e.dataset.title && (e.dataset.title = i), e.dataset.gallery || (e.dataset.gallery = t);
14
+ }
15
+ function loadCss(e) {
16
+ if (!e || document.querySelector(`link[href="${e}"]`)) return;
17
+ let t = document.createElement("link");
18
+ t.rel = "stylesheet", t.href = e, document.head.appendChild(t);
19
+ }
20
+ function loadJs(e) {
21
+ return new Promise((t) => {
22
+ if (!e || typeof window.GLightbox == "function") return t();
23
+ let n = document.createElement("script");
24
+ n.src = e, n.onload = () => t(), document.head.appendChild(n);
25
+ });
26
+ }
27
+ async function initGlightboxModule(i) {
28
+ let a = i.selector, o = i.scope, s = i.gallery, c = i.cssUrl || "https://cos.lhasa.icu/dist/glightbox/glightbox.min.css", l = i.jsUrl || "https://cos.lhasa.icu/dist/glightbox/glightbox.min.js", u = /* @__PURE__ */ new Set(), d = /* @__PURE__ */ new Set();
29
+ document.querySelectorAll(o).forEach((e) => {
30
+ e.querySelectorAll("img").forEach((e) => u.add(e)), e.querySelectorAll(a).forEach((e) => d.add(e));
31
+ }), u.forEach((t) => {
32
+ let n = t.parentElement, r = n && n.tagName.toLowerCase() === "a", i = r && n.classList.contains("glightbox");
33
+ (!r || !i) && wrap(t, s);
34
+ }), d.forEach((e) => sync(e, s)), loadCss(c), await loadJs(l), (() => {
35
+ let e = window.GLightbox;
36
+ if (typeof e == "function") {
37
+ let t = window.__glightboxInstance;
38
+ t && t.destroy && t.destroy();
39
+ let n = Object.assign({}, i.options || {}, { selector: a });
40
+ window.__glightboxInstance = e(n);
41
+ }
42
+ })();
43
+ }
44
+ export { initGlightboxModule };
@@ -0,0 +1 @@
1
+ function e(e,t){let n=e.currentSrc||e.src||``;if(!n)return;let r=String(e.getAttribute(`alt`)||``).trim(),i=document.createElement(`a`);i.href=n,i.className=`glightbox`,i.dataset.gallery=t,r&&(i.dataset.title=r),e.parentElement.replaceChild(i,e),i.appendChild(e)}function t(e,t){let n=e.querySelector(`img`);if(!n)return;let r=n.currentSrc||n.src;r&&e.getAttribute(`href`)!==r&&e.setAttribute(`href`,r);let i=n.getAttribute(`alt`);i&&!e.dataset.title&&(e.dataset.title=i),e.dataset.gallery||(e.dataset.gallery=t)}function n(e){if(!e||document.querySelector(`link[href="${e}"]`))return;let t=document.createElement(`link`);t.rel=`stylesheet`,t.href=e,document.head.appendChild(t)}function r(e){return new Promise(t=>{if(!e||typeof window.GLightbox==`function`)return t();let n=document.createElement(`script`);n.src=e,n.onload=()=>t(),document.head.appendChild(n)})}async function i(i){let a=i.selector,o=i.scope,s=i.gallery,c=i.cssUrl||`https://cos.lhasa.icu/dist/glightbox/glightbox.min.css`,l=i.jsUrl||`https://cos.lhasa.icu/dist/glightbox/glightbox.min.js`,u=new Set,d=new Set;document.querySelectorAll(o).forEach(e=>{e.querySelectorAll(`img`).forEach(e=>u.add(e)),e.querySelectorAll(a).forEach(e=>d.add(e))}),u.forEach(t=>{let n=t.parentElement,r=n&&n.tagName.toLowerCase()===`a`,i=r&&n.classList.contains(`glightbox`);(!r||!i)&&e(t,s)}),d.forEach(e=>t(e,s)),n(c),await r(l),(()=>{let e=window.GLightbox;if(typeof e==`function`){let t=window.__glightboxInstance;t&&t.destroy&&t.destroy();let n=Object.assign({},i.options||{},{selector:a});window.__glightboxInstance=e(n)}})()}exports.initGlightboxModule=i;
@@ -0,0 +1,7 @@
1
+ import { r as processMedia, t as ensureCaption } from "./dom-CDvVCbvk.js";
2
+ async function enableImageAlts(n, r) {
3
+ await Promise.resolve({ }), processMedia(n, r, (e) => {
4
+ ensureCaption(e);
5
+ });
6
+ }
7
+ export { enableImageAlts };
@@ -0,0 +1 @@
1
+ const e=require(`./dom-DMZsb49p.cjs`);async function t(t,n){await Promise.resolve().then(()=>require(`./image-alts-D2zawu5U.cjs`)),e.r(t,n,t=>{e.t(t)})}exports.enableImageAlts=t;
@@ -0,0 +1,10 @@
1
+ import { PhotosuiteOptions } from './types';
2
+ /**
3
+ * 初始化 Photosuite
4
+ *
5
+ * 根据配置项动态加载并初始化各个功能模块(GLightbox, ImageAlts, Exif)
6
+ *
7
+ * @param opts - Photosuite 配置项
8
+ */
9
+ export declare function photosuite(opts: PhotosuiteOptions): void;
10
+ export type { PhotosuiteOptions, ImageUrlOptions } from './types';
@@ -0,0 +1,18 @@
1
+ import { PhotosuiteOptions } from './types';
2
+ /**
3
+ * Astro 集成默认导出
4
+ *
5
+ * 提供给 Astro 框架使用的集成配置。
6
+ *
7
+ * @param options - Photosuite 配置项
8
+ * @returns Astro 集成对象
9
+ */
10
+ export default function astroPhotosuite(options: PhotosuiteOptions): {
11
+ name: string;
12
+ hooks: {
13
+ "astro:config:setup": ({ injectScript, updateConfig }: any) => void;
14
+ };
15
+ };
16
+ export { imageUrl } from './remark/imageUrl';
17
+ export { exiftoolVendored } from './rehype/exiftoolVendored';
18
+ export type { PhotosuiteOptions, ImageUrlOptions } from './types';
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @file dom.ts
3
+ * @description 提供 DOM 操作相关的辅助函数,用于处理图片容器、标题和 EXIF 元素的创建与管理
4
+ */
5
+ /**
6
+ * 确保元素被包裹在 photosuite-item 容器中
7
+ *
8
+ * 如果目标元素(通常是 img 或 a.glightbox)尚未被 photosuite-item 包裹
9
+ * 则创建一个新的 div.photosuite-item 并将目标元素移动到其中
10
+ *
11
+ * @param el - 需要检查或包裹的 DOM 元素
12
+ * @returns 包含该元素的 HTMLElement 容器 (.photosuite-item)
13
+ */
14
+ export declare function ensurePhotosuiteContainer(el: Element): HTMLElement;
15
+ /**
16
+ * 处理媒体元素
17
+ *
18
+ * 遍历匹配选择器的元素以及所有 img 元素,确保它们拥有统一的容器结构
19
+ * 然后对每个容器执行回调函数
20
+ *
21
+ * @param selector - 用于选择图片或链接的选择器字符串
22
+ * @param callback - 对每个处理后的容器执行的回调函数
23
+ */
24
+ export declare function processMedia(scope: string, selector: string, callback: (container: HTMLElement) => void): void;
25
+ /**
26
+ * 确保容器内存在标题元素
27
+ *
28
+ * 根据容器内图片的 alt 属性创建并插入标题元素
29
+ *
30
+ * @param container - 图片容器 (.photosuite-item)
31
+ */
32
+ export declare function ensureCaption(container: HTMLElement): void;
33
+ /**
34
+ * 确保容器内存在 EXIF 显示条
35
+ *
36
+ * 创建一个用于显示 EXIF 信息的占位元素
37
+ *
38
+ * @param container - 图片容器 (.photosuite-item)
39
+ */
40
+ export declare function ensureExif(container: HTMLElement): void;