data-preview 1.0.4 → 1.0.6

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 CHANGED
@@ -10,7 +10,7 @@ AI-native semantic preview runtime for modern web.
10
10
 
11
11
  - Zero Dependency
12
12
  - Framework Agnostic
13
- - Hover Preview(PC)/ Long Press Preview(Mobile)
13
+ - Hover Preview(PC)/ Tap Preview(Mobile)
14
14
  - Smart Positioning — 自动适应窗口边界与图片比例
15
15
  - SPA Compatible — 内置 `destroy()` 支持路由卸载
16
16
  - Auto Dark Mode
@@ -181,14 +181,14 @@ DataPreview.init()
181
181
  | `imgPad` | `8` | 预览框内边距 px |
182
182
  | `maxWRatio` | `0.9` | 预览框最大宽度占窗口比例 |
183
183
  | `maxHRatio` | `0.85` | 预览框最大高度占窗口比例 |
184
- | `delayHide` | `120` | 鼠标离开后隐藏延迟 ms |
185
- | `longPressDuration` | `480` | 移动端长按触发时长 ms |
184
+ | `delayHide` | `150` | 鼠标离开后隐藏延迟 ms |
185
+ | `badgeOffset` | `6` | 预览图标距右上角偏移 px |
186
186
 
187
187
  ------
188
188
 
189
189
  ## Mobile
190
190
 
191
- 移动端通过 `(pointer: coarse)` 自动识别触摸设备,采用长按触发预览,点击遮罩或右上角 ✕ 关闭。无需额外配置。
191
+ 移动端通过 `(pointer: coarse)` 自动识别触摸设备,采用点击触发预览,点击遮罩或右上角 ✕ 关闭。无需额外配置。
192
192
 
193
193
  ------
194
194
 
@@ -1,211 +1,200 @@
1
- const te = (() => {
2
- const b = {
1
+ const oe = (() => {
2
+ const m = {
3
3
  imgPad: 8,
4
4
  maxWRatio: 0.9,
5
5
  maxHRatio: 0.85,
6
- delayHide: 120,
7
- longPressDuration: 480,
6
+ delayHide: 150,
8
7
  badgeOffset: 6
9
- }, y = 16, g = 12;
10
- let h, i, L, u, m, p, r, M = null, T = null, k = null, P = null, _ = 0, l = null, v = null;
11
- const w = /* @__PURE__ */ new Map();
12
- let x = window.matchMedia("(pointer: coarse)").matches;
13
- const z = window.matchMedia("(prefers-color-scheme: dark)");
14
- window.matchMedia("(pointer: coarse)").addEventListener("change", (e) => {
15
- x = e.matches;
16
- });
17
- function K() {
18
- h || (h = H("div", {
19
- style: "position:fixed;inset:0;z-index:99999;pointer-events:none;"
20
- }), r = H("div", {
21
- style: `
22
- position:fixed;
23
- width:24px;height:24px;
24
- border-radius:6px;
25
- background:rgba(0,0,0,0.45);
26
- color:#fff;font-size:13px;
27
- display:flex;align-items:center;justify-content:center;
28
- cursor:pointer;
29
- opacity:0;
30
- transition:opacity 0.15s;
31
- pointer-events:none;
32
- z-index:100001;
33
- user-select:none;
34
- backdrop-filter:blur(4px);
35
- `
36
- }), r.textContent = "🖼️", i = H("div", {
37
- style: `
38
- position:fixed;
39
- border-radius:12px;
40
- overflow:hidden;
41
- opacity:0;
42
- transform:scale(0.95);
43
- transition:opacity 0.15s,transform 0.15s;
44
- pointer-events:none;
45
- z-index:100000;
46
- will-change:transform,opacity;
47
- `
48
- }), p = H("button", {
49
- style: `
50
- position:absolute;top:6px;right:6px;
51
- width:26px;height:26px;
52
- border-radius:50%;border:none;cursor:pointer;
53
- display:flex;align-items:center;justify-content:center;
54
- font-size:13px;line-height:1;z-index:1;
55
- opacity:0;transition:opacity 0.15s;
56
- `
57
- }), p.textContent = "✕", p.setAttribute("aria-label", "关闭预览"), p.addEventListener("click", (e) => {
58
- e.stopPropagation(), D();
59
- }), p.addEventListener("touchend", (e) => {
60
- e.stopPropagation(), D();
61
- }), L = H("div", { style: "position:relative;" }), u = H("img", { style: "display:block;", alt: "preview" }), m = H("div", { style: "font-size:11px;padding:5px 10px;white-space:nowrap;" }), L.append(u, p), i.append(L, m), h.append(r, i), document.body.appendChild(h), r.addEventListener("mouseenter", () => {
62
- if (clearTimeout(M), clearTimeout(T), !l) return;
63
- const e = R(l), n = N(l);
64
- e && Q(e, n);
65
- }), r.addEventListener("mouseleave", () => {
66
- i.style.opacity !== "1" && O();
67
- }), r.addEventListener("click", () => {
68
- i.style.opacity === "1" && D();
8
+ }, h = 16, w = 12;
9
+ let g, i, M, l, v, f, s, L = null, T = null, E = null, W = 0, u = null, b = null, B = "[data-preview]";
10
+ const x = /* @__PURE__ */ new Map();
11
+ let y = window.matchMedia("(pointer: coarse)").matches;
12
+ const A = window.matchMedia("(prefers-color-scheme: dark)"), _ = window.matchMedia("(pointer: coarse)"), q = (e) => {
13
+ y = e.matches;
14
+ };
15
+ _.addEventListener("change", q);
16
+ let C = !1;
17
+ function V() {
18
+ g || (g = H("div", {
19
+ style: "position:fixed; inset:0; z-index:99999; pointer-events:none; will-change:transform;"
20
+ }), s = H("div", {
21
+ style: "position:fixed; width:24px; height:24px; border-radius:6px; background:rgba(0,0,0,0.45); color:#fff; font-size:13px; display:flex; align-items:center; justify-content:center; cursor:pointer; opacity:0; transition:opacity 0.15s, background 0.15s; pointer-events:none; z-index:100001; user-select:none; backdrop-filter:blur(4px);"
22
+ }), s.textContent = "🖼️", i = H("div", {
23
+ style: "position:fixed; border-radius:12px; overflow:hidden; opacity:0; transform:scale(0.95); transition:opacity 0.15s, transform 0.15s; pointer-events:none; z-index:100000; will-change:transform, opacity;"
24
+ }), f = H("button", {
25
+ style: "position:absolute; top:6px; right:6px; width:26px; height:26px; border-radius:50%; border:none; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:13px; line-height:1; z-index:1; opacity:0; transition:opacity 0.15s;"
26
+ }), f.textContent = "✕", f.setAttribute("aria-label", "关闭预览"), M = H("div", { style: "position:relative;" }), l = H("img", { style: "display:block; max-width:none; max-height:none;", alt: "preview" }), v = H("div", { style: "font-size:11px; padding:5px 10px; white-space:nowrap; height:22px; box-sizing:border-box;" }), M.append(l, f), i.append(M, v), g.append(s, i), document.body.appendChild(g), s.addEventListener("mouseenter", () => {
27
+ if (y || !u) return;
28
+ clearTimeout(L), clearTimeout(T);
29
+ const e = $(u);
30
+ e && Y(e, G(u));
31
+ }), s.addEventListener("mouseleave", () => {
32
+ y || i.style.opacity === "1" || z();
33
+ }), s.addEventListener("click", (e) => {
34
+ e.stopPropagation(), i.style.opacity === "1" && P();
69
35
  }), i.addEventListener("mouseenter", () => {
70
- clearTimeout(M), clearTimeout(T), x || (p.style.opacity = "1");
71
- }), i.addEventListener("mouseleave", () => {
72
- x || (p.style.opacity = "0"), O();
73
- }), A(), z.addEventListener("change", A));
74
- }
75
- function A() {
76
- const e = z.matches;
77
- i.style.background = e ? "#1c1c1e" : "#ffffff", i.style.border = e ? "1px solid rgba(255,255,255,.12)" : "1px solid rgba(0,0,0,.1)", i.style.boxShadow = e ? "0 12px 40px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.3)" : "0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08)", m.style.background = e ? "rgba(255,255,255,.06)" : "rgba(0,0,0,.04)", m.style.color = e ? "rgba(255,255,255,.4)" : "rgba(0,0,0,.4)", m.style.borderTop = e ? "1px solid rgba(255,255,255,.08)" : "1px solid rgba(0,0,0,.06)", p.style.background = e ? "rgba(255,255,255,.15)" : "rgba(0,0,0,.15)", p.style.color = e ? "rgba(255,255,255,.8)" : "rgba(0,0,0,.6)";
78
- }
79
- function j(e) {
80
- const n = e.getBoundingClientRect(), t = b.badgeOffset;
81
- r.style.left = n.right - 24 - t + "px", r.style.top = n.top + t + "px";
82
- }
83
- function q(e, n) {
84
- const t = b.imgPad * 2, o = m.offsetHeight || 22, s = Math.floor(window.innerWidth * b.maxWRatio) - t, d = Math.floor(window.innerHeight * b.maxHRatio) - t - o, f = e / n;
85
- let a, c;
86
- return f >= 1 ? (a = Math.min(s, e), c = a / f, c > d && (c = d, a = c * f)) : (c = Math.min(d, n), a = c * f, a > s && (a = s, c = a / f)), { pw: Math.round(a), ph: Math.round(c) };
87
- }
88
- function U(e, n) {
89
- if (!l) return;
90
- const t = l.getBoundingClientRect(), o = b.imgPad, s = m.offsetHeight || 22, { pw: d, ph: f } = q(e, n), a = d + o * 2, c = f + o * 2 + s, S = window.innerWidth, J = window.innerHeight;
91
- let W;
92
- t.left - g >= a + y ? W = t.left - g - a : S - t.right - g >= a + y ? W = t.right + g : W = C(t.left + (t.width - a) / 2, y, S - a - y);
93
- let B;
94
- J - t.bottom - g >= c + y ? B = t.bottom + g : t.top - g >= c + y ? B = t.top - g - c : B = C(t.top + (t.height - c) / 2, y, J - c - y), i.style.left = W + "px", i.style.top = B + "px", i.style.width = a + "px", L.style.padding = o + "px", u.style.width = d + "px", u.style.height = f + "px";
95
- }
96
- function V(e, n) {
97
- const t = b.imgPad, o = m.offsetHeight || 22, { pw: s, ph: d } = q(e, n), f = s + t * 2, a = d + t * 2 + o, c = window.innerWidth, S = window.innerHeight;
98
- i.style.left = C((c - f) / 2, y, c - f - y) + "px", i.style.top = C((S - a) / 2, y, S - a - y) + "px", i.style.width = f + "px", L.style.padding = t + "px", u.style.width = s + "px", u.style.height = d + "px";
36
+ y || (clearTimeout(L), clearTimeout(T), f.style.opacity = "1");
37
+ }), i.addEventListener("mouseleave", (e) => {
38
+ y || (f.style.opacity = "0", e.relatedTarget !== s && z());
39
+ }), f.addEventListener("click", (e) => {
40
+ e.stopPropagation(), P();
41
+ }), f.addEventListener("touchend", (e) => {
42
+ e.stopPropagation(), e.preventDefault(), P();
43
+ }), document.addEventListener("click", (e) => {
44
+ i && i.style.opacity === "1" && !i.contains(e.target) && !s.contains(e.target) && P();
45
+ }, { passive: !0 }), O(), A.addEventListener("change", O));
46
+ }
47
+ function O() {
48
+ if (!i) return;
49
+ const e = A.matches;
50
+ i.style.background = e ? "#1c1c1e" : "#ffffff", i.style.border = e ? "1px solid rgba(255,255,255,.12)" : "1px solid rgba(0,0,0,.1)", i.style.boxShadow = e ? "0 12px 40px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.3)" : "0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08)", v.style.background = e ? "rgba(255,255,255,.06)" : "rgba(0,0,0,.04)", v.style.color = e ? "rgba(255,255,255,.4)" : "rgba(0,0,0,.4)", v.style.borderTop = e ? "1px solid rgba(255,255,255,.08)" : "1px solid rgba(0,0,0,.06)", f.style.background = e ? "rgba(255,255,255,.15)" : "rgba(0,0,0,.15)", f.style.color = e ? "rgba(255,255,255,.8)" : "rgba(0,0,0,.6)";
51
+ }
52
+ function R(e) {
53
+ const n = e.getBoundingClientRect();
54
+ s.style.left = `${n.right - 24 - m.badgeOffset}px`, s.style.top = `${n.top + m.badgeOffset}px`;
55
+ }
56
+ function j(e, n) {
57
+ const t = m.imgPad * 2, r = 22, o = Math.floor(window.innerWidth * m.maxWRatio) - t, a = Math.floor(window.innerHeight * m.maxHRatio) - t - r, c = e / n;
58
+ let d, p;
59
+ return c >= 1 ? (d = Math.min(o, e), p = d / c, p > a && (p = a, d = p * c)) : (p = Math.min(a, n), d = p * c, d > o && (d = o, p = d / c)), { pw: Math.round(d), ph: Math.round(p) };
60
+ }
61
+ function D(e, n) {
62
+ if (!u) return;
63
+ const t = u.getBoundingClientRect(), r = m.imgPad, o = 22, { pw: a, ph: c } = j(e, n), d = a + r * 2, p = c + r * 2 + o, K = window.innerWidth, U = window.innerHeight;
64
+ let ne = t.left - w >= d + h ? t.left - w - d : K - t.right - w >= d + h ? t.right + w : S(t.left + (t.width - d) / 2, h, K - d - h), ie = U - t.bottom - w >= p + h ? t.bottom + w : t.top - w >= p + h ? t.top - w - p : S(t.top + (t.height - p) / 2, h, U - p - h);
65
+ i.style.left = `${ne}px`, i.style.top = `${ie}px`, i.style.width = `${d}px`, M.style.padding = `${r}px`, l.style.width = `${a}px`, l.style.height = `${c}px`;
66
+ }
67
+ function F(e, n) {
68
+ const t = m.imgPad, r = 22, { pw: o, ph: a } = j(e, n), c = o + t * 2, d = a + t * 2 + r;
69
+ i.style.left = `${S((window.innerWidth - c) / 2, h, window.innerWidth - c - h)}px`, i.style.top = `${S((window.innerHeight - d) / 2, h, window.innerHeight - d - h)}px`, i.style.width = `${c}px`, M.style.padding = `${t}px`, l.style.width = `${o}px`, l.style.height = `${a}px`;
99
70
  }
100
71
  function X(e) {
101
- v !== e && (clearTimeout(T), !(l === e && r.style.opacity === "1") && (l = e, j(e), r.style.opacity = "1", r.style.pointerEvents = "auto", h.style.pointerEvents = "auto"));
102
- }
103
- function Q(e, n) {
104
- if (v && l === v) return;
105
- const t = ++_;
106
- m.textContent = n || "";
107
- function o(s, d) {
108
- t === _ && (x ? V(s, d) : U(s, d), i.style.opacity = "1", i.style.transform = "scale(1)", i.style.pointerEvents = "auto", x && (p.style.opacity = "1"), r.textContent = "✕", r.style.background = "rgba(220,60,60,0.75)", m.textContent = n || s + " × " + d);
72
+ b !== e && (clearTimeout(T), u = e, R(e), s.style.opacity = "1", s.style.pointerEvents = y ? "none" : "auto");
73
+ }
74
+ function Y(e, n) {
75
+ if (!e) return;
76
+ const t = ++W;
77
+ function r(a, c) {
78
+ t !== W || !u || (y ? F(a, c) : D(a, c), i.style.opacity = "1", i.style.transform = "scale(1)", i.style.pointerEvents = "auto", g.style.pointerEvents = "auto", f.style.opacity = "1", s.textContent = "✕", s.style.background = "rgba(220,60,60,0.75)", s.style.pointerEvents = "auto", v.textContent = n || `${a} × ${c}`);
109
79
  }
110
- if (w.get(e) === "loaded" && u.src === e) {
111
- o(u.naturalWidth, u.naturalHeight);
80
+ const o = x.get(e);
81
+ if (o && o.status === "loaded") {
82
+ l.src !== e && (l.onload = l.onerror = null, l.src = e), r(o.w, o.h);
112
83
  return;
113
84
  }
114
- u.src = e, u.onload = () => {
115
- w.set(e, "loaded"), o(u.naturalWidth, u.naturalHeight);
116
- }, u.onerror = () => {
117
- w.set(e, "error");
118
- };
119
- }
120
- function O() {
121
- clearTimeout(M), M = setTimeout(() => {
122
- i.style.opacity = "0", i.style.transform = "scale(0.95)", i.style.pointerEvents = "none", r.style.opacity = "0", r.style.pointerEvents = "none", r.textContent = "🖼️", r.style.background = "rgba(0,0,0,0.45)", h.style.pointerEvents = "none", p.style.opacity = "0", l = null;
123
- }, b.delayHide);
85
+ l.onload = l.onerror = null, l.onload = () => {
86
+ x.set(e, { status: "loaded", w: l.naturalWidth, h: l.naturalHeight }), r(l.naturalWidth, l.naturalHeight);
87
+ }, l.onerror = () => {
88
+ x.set(e, { status: "error", w: 0, h: 0 });
89
+ }, l.src = e;
90
+ }
91
+ function z() {
92
+ clearTimeout(L), L = setTimeout(() => {
93
+ I();
94
+ }, m.delayHide);
95
+ }
96
+ function P() {
97
+ if (clearTimeout(L), clearTimeout(T), u) {
98
+ const e = u;
99
+ b = e, setTimeout(() => {
100
+ b === e && (b = null);
101
+ }, 300);
102
+ }
103
+ I();
124
104
  }
125
- function D() {
126
- clearTimeout(M), clearTimeout(T), ++_, l && (v = l), i.style.opacity = "0", i.style.transform = "scale(0.95)", i.style.pointerEvents = "none", r.style.opacity = "0", r.style.pointerEvents = "none", r.textContent = "🖼️", r.style.background = "rgba(0,0,0,0.45)", h.style.pointerEvents = "none", p.style.opacity = "0", l = null;
105
+ function I() {
106
+ W++, i && (i.style.opacity = "0", i.style.transform = "scale(0.95)", i.style.pointerEvents = "none", s.style.opacity = "0", s.style.pointerEvents = "none", f.style.opacity = "0", s.textContent = "🖼️", s.style.background = "rgba(0,0,0,0.45)", g.style.pointerEvents = "none", u = null);
127
107
  }
128
- function F(e) {
129
- if (!e || w.has(e)) return;
130
- w.set(e, "loading");
108
+ function N(e) {
109
+ if (!e || x.has(e)) return;
110
+ x.set(e, { status: "loading", w: 0, h: 0 });
131
111
  const n = new Image();
132
- n.onload = () => w.set(e, "loaded"), n.onerror = () => w.set(e, "error"), n.src = e;
133
- }
134
- function I() {
135
- l && r.style.opacity === "1" && j(l);
112
+ n.onload = () => {
113
+ x.set(e, { status: "loaded", w: n.naturalWidth, h: n.naturalHeight });
114
+ }, n.onerror = () => {
115
+ x.set(e, { status: "error", w: 0, h: 0 });
116
+ }, n.src = e;
117
+ }
118
+ function Q() {
119
+ !u || C || (C = !0, requestAnimationFrame(() => {
120
+ if (u && s && s.style.opacity === "1") {
121
+ R(u);
122
+ const e = x.get($(u));
123
+ i && i.style.opacity === "1" && e && e.status === "loaded" && (y ? F(e.w, e.h) : D(e.w, e.h));
124
+ }
125
+ C = !1;
126
+ }));
136
127
  }
137
- function R(e) {
128
+ function $(e) {
138
129
  var n;
139
130
  return e.dataset.previewSrc || e.src || e.currentSrc || ((n = e.querySelector("img")) == null ? void 0 : n.src) || null;
140
131
  }
141
- function N(e) {
132
+ function G(e) {
142
133
  return e.dataset.previewLabel || e.alt || e.title || null;
143
134
  }
144
- function E(e) {
135
+ function k(e) {
145
136
  if (e._dpBound) return;
146
- const n = {
137
+ let n = 0, t = 0;
138
+ const r = {
147
139
  mouseenter() {
148
- x || v !== e && (clearTimeout(T), !(l === e && r.style.opacity === "1") && (F(R(e)), X(e)));
149
- },
150
- mouseleave(t) {
151
- x || e.contains(t.relatedTarget) || (v === e && (v = null), T = setTimeout(() => {
152
- l === e && O();
153
- }, b.delayHide));
140
+ y || b === e || (clearTimeout(T), N($(e)), X(e));
154
141
  },
155
- touchstart(t) {
156
- if (!x) return;
157
- const o = R(e);
158
- o && (F(o), k = setTimeout(() => {
159
- l = e, Q(o, N(e));
160
- }, b.longPressDuration));
142
+ mouseleave(o) {
143
+ y || e.contains(o.relatedTarget) || (b === e && (b = null), T = setTimeout(() => {
144
+ u === e && z();
145
+ }, m.delayHide));
161
146
  },
162
- touchend() {
163
- clearTimeout(k);
147
+ touchstart(o) {
148
+ if (!y) return;
149
+ const a = o.touches[0];
150
+ n = a.clientX, t = a.clientY, N($(e));
164
151
  },
165
- touchmove() {
166
- clearTimeout(k);
167
- },
168
- touchcancel() {
169
- clearTimeout(k);
170
- },
171
- contextmenu(t) {
172
- x && t.preventDefault();
152
+ touchend(o) {
153
+ if (!y || b === e) return;
154
+ const a = o.changedTouches[0];
155
+ if (Math.abs(a.clientX - n) < 10 && Math.abs(a.clientY - t) < 10) {
156
+ X(e);
157
+ const c = $(e);
158
+ c && Y(c, G(e));
159
+ }
173
160
  }
174
161
  };
175
- Object.entries(n).forEach(([t, o]) => e.addEventListener(t, o)), e._dpBound = !0, e._dpHandlers = n;
162
+ Object.entries(r).forEach(([o, a]) => {
163
+ e.addEventListener(o, a, o.startsWith("touch") && o !== "touchend" ? { passive: !0 } : !1);
164
+ }), e._dpBound = !0, e._dpHandlers = r;
176
165
  }
177
- function G(e) {
178
- e._dpBound && (Object.entries(e._dpHandlers).forEach(
179
- ([n, t]) => e.removeEventListener(n, t)
180
- ), e._dpBound = !1, e._dpHandlers = null, e._dpMoveTimer = null);
166
+ function J(e) {
167
+ !e || !e._dpBound || (Object.entries(e._dpHandlers || {}).forEach(([n, t]) => {
168
+ e.removeEventListener(n, t);
169
+ }), delete e._dpBound, delete e._dpHandlers);
181
170
  }
182
- function Y(e) {
183
- document.querySelectorAll(e).forEach((n) => E(n));
171
+ function Z(e) {
172
+ document.querySelectorAll(e).forEach(k);
184
173
  }
185
- function Z(e = "[data-preview]") {
186
- K(), document.querySelectorAll(e).forEach((n) => E(n)), window.addEventListener("scroll", I, !0), P = new MutationObserver((n) => {
174
+ function ee(e = "[data-preview]") {
175
+ B = e, V(), document.querySelectorAll(e).forEach(k), window.addEventListener("scroll", Q, { capture: !0, passive: !0 }), E = new MutationObserver((n) => {
187
176
  n.forEach((t) => {
188
- t.addedNodes.forEach((o) => {
189
- var s, d;
190
- o.nodeType === 1 && ((s = o.matches) != null && s.call(o, e) && E(o), (d = o.querySelectorAll) == null || d.call(o, e).forEach((f) => E(f)));
177
+ t.addedNodes.forEach((r) => {
178
+ var o, a;
179
+ r.nodeType === 1 && ((o = r.matches) != null && o.call(r, e) && k(r), (a = r.querySelectorAll) == null || a.call(r, e).forEach(k));
191
180
  });
192
181
  });
193
- }), P.observe(document.body, { childList: !0, subtree: !0 });
182
+ }), E.observe(document.body, { childList: !0, subtree: !0 });
194
183
  }
195
- function $() {
196
- P == null || P.disconnect(), P = null, document.querySelectorAll("[data-preview]").forEach((e) => G(e)), window.removeEventListener("scroll", I, !0), z.removeEventListener("change", A), h == null || h.remove(), h = i = L = u = m = p = r = null, w.clear(), clearTimeout(M), clearTimeout(T), clearTimeout(k), v = null;
184
+ function te() {
185
+ E == null || E.disconnect(), E = null, document.querySelectorAll(B).forEach(J), window.removeEventListener("scroll", Q, { capture: !0, passive: !0 }), A.removeEventListener("change", O), _.removeEventListener("change", q), g == null || g.remove(), g = null, i = null, M = null, l = null, v = null, f = null, s = null, x.clear(), clearTimeout(L), clearTimeout(T), b = null, u = null;
197
186
  }
198
187
  function H(e, n = {}) {
199
188
  const t = document.createElement(e);
200
- return Object.entries(n).forEach(([o, s]) => {
201
- o === "style" ? t.style.cssText = s : t[o] = s;
189
+ return Object.entries(n).forEach(([r, o]) => {
190
+ r === "style" ? t.style.cssText = o : r.startsWith("aria-") ? t.setAttribute(r, o) : t[r] = o;
202
191
  }), t;
203
192
  }
204
- function C(e, n, t) {
193
+ function S(e, n, t) {
205
194
  return Math.max(n, Math.min(e, t));
206
195
  }
207
- return { init: Z, bind: E, unbind: G, bindAll: Y, destroy: $, config: b };
196
+ return { init: ee, bind: k, unbind: J, bindAll: Z, destroy: te, config: m };
208
197
  })();
209
198
  export {
210
- te as default
199
+ oe as default
211
200
  };
@@ -1,32 +1 @@
1
- (function(C,p){typeof exports=="object"&&typeof module<"u"?module.exports=p():typeof define=="function"&&define.amd?define(p):(C=typeof globalThis<"u"?globalThis:C||self,C.DataPreview=p())})(this,(function(){"use strict";return(()=>{const p={imgPad:8,maxWRatio:.9,maxHRatio:.85,delayHide:120,longPressDuration:480,badgeOffset:6},h=16,g=12;let m,o,P,u,b,f,r,L=null,T=null,k=null,M=null,z=0,l=null,v=null;const w=new Map;let x=window.matchMedia("(pointer: coarse)").matches;const A=window.matchMedia("(prefers-color-scheme: dark)");window.matchMedia("(pointer: coarse)").addEventListener("change",e=>{x=e.matches});function U(){m||(m=H("div",{style:"position:fixed;inset:0;z-index:99999;pointer-events:none;"}),r=H("div",{style:`
2
- position:fixed;
3
- width:24px;height:24px;
4
- border-radius:6px;
5
- background:rgba(0,0,0,0.45);
6
- color:#fff;font-size:13px;
7
- display:flex;align-items:center;justify-content:center;
8
- cursor:pointer;
9
- opacity:0;
10
- transition:opacity 0.15s;
11
- pointer-events:none;
12
- z-index:100001;
13
- user-select:none;
14
- backdrop-filter:blur(4px);
15
- `}),r.textContent="🖼️",o=H("div",{style:`
16
- position:fixed;
17
- border-radius:12px;
18
- overflow:hidden;
19
- opacity:0;
20
- transform:scale(0.95);
21
- transition:opacity 0.15s,transform 0.15s;
22
- pointer-events:none;
23
- z-index:100000;
24
- will-change:transform,opacity;
25
- `}),f=H("button",{style:`
26
- position:absolute;top:6px;right:6px;
27
- width:26px;height:26px;
28
- border-radius:50%;border:none;cursor:pointer;
29
- display:flex;align-items:center;justify-content:center;
30
- font-size:13px;line-height:1;z-index:1;
31
- opacity:0;transition:opacity 0.15s;
32
- `}),f.textContent="✕",f.setAttribute("aria-label","关闭预览"),f.addEventListener("click",e=>{e.stopPropagation(),j()}),f.addEventListener("touchend",e=>{e.stopPropagation(),j()}),P=H("div",{style:"position:relative;"}),u=H("img",{style:"display:block;",alt:"preview"}),b=H("div",{style:"font-size:11px;padding:5px 10px;white-space:nowrap;"}),P.append(u,f),o.append(P,b),m.append(r,o),document.body.appendChild(m),r.addEventListener("mouseenter",()=>{if(clearTimeout(L),clearTimeout(T),!l)return;const e=R(l),n=G(l);e&&F(e,n)}),r.addEventListener("mouseleave",()=>{o.style.opacity!=="1"&&O()}),r.addEventListener("click",()=>{o.style.opacity==="1"&&j()}),o.addEventListener("mouseenter",()=>{clearTimeout(L),clearTimeout(T),x||(f.style.opacity="1")}),o.addEventListener("mouseleave",()=>{x||(f.style.opacity="0"),O()}),D(),A.addEventListener("change",D))}function D(){const e=A.matches;o.style.background=e?"#1c1c1e":"#ffffff",o.style.border=e?"1px solid rgba(255,255,255,.12)":"1px solid rgba(0,0,0,.1)",o.style.boxShadow=e?"0 12px 40px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.3)":"0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08)",b.style.background=e?"rgba(255,255,255,.06)":"rgba(0,0,0,.04)",b.style.color=e?"rgba(255,255,255,.4)":"rgba(0,0,0,.4)",b.style.borderTop=e?"1px solid rgba(255,255,255,.08)":"1px solid rgba(0,0,0,.06)",f.style.background=e?"rgba(255,255,255,.15)":"rgba(0,0,0,.15)",f.style.color=e?"rgba(255,255,255,.8)":"rgba(0,0,0,.6)"}function q(e){const n=e.getBoundingClientRect(),t=p.badgeOffset;r.style.left=n.right-24-t+"px",r.style.top=n.top+t+"px"}function Q(e,n){const t=p.imgPad*2,i=b.offsetHeight||22,s=Math.floor(window.innerWidth*p.maxWRatio)-t,d=Math.floor(window.innerHeight*p.maxHRatio)-t-i,y=e/n;let a,c;return y>=1?(a=Math.min(s,e),c=a/y,c>d&&(c=d,a=c*y)):(c=Math.min(d,n),a=c*y,a>s&&(a=s,c=a/y)),{pw:Math.round(a),ph:Math.round(c)}}function V(e,n){if(!l)return;const t=l.getBoundingClientRect(),i=p.imgPad,s=b.offsetHeight||22,{pw:d,ph:y}=Q(e,n),a=d+i*2,c=y+i*2+s,S=window.innerWidth,K=window.innerHeight;let B;t.left-g>=a+h?B=t.left-g-a:S-t.right-g>=a+h?B=t.right+g:B=W(t.left+(t.width-a)/2,h,S-a-h);let _;K-t.bottom-g>=c+h?_=t.bottom+g:t.top-g>=c+h?_=t.top-g-c:_=W(t.top+(t.height-c)/2,h,K-c-h),o.style.left=B+"px",o.style.top=_+"px",o.style.width=a+"px",P.style.padding=i+"px",u.style.width=d+"px",u.style.height=y+"px"}function X(e,n){const t=p.imgPad,i=b.offsetHeight||22,{pw:s,ph:d}=Q(e,n),y=s+t*2,a=d+t*2+i,c=window.innerWidth,S=window.innerHeight;o.style.left=W((c-y)/2,h,c-y-h)+"px",o.style.top=W((S-a)/2,h,S-a-h)+"px",o.style.width=y+"px",P.style.padding=t+"px",u.style.width=s+"px",u.style.height=d+"px"}function Y(e){v!==e&&(clearTimeout(T),!(l===e&&r.style.opacity==="1")&&(l=e,q(e),r.style.opacity="1",r.style.pointerEvents="auto",m.style.pointerEvents="auto"))}function F(e,n){if(v&&l===v)return;const t=++z;b.textContent=n||"";function i(s,d){t===z&&(x?X(s,d):V(s,d),o.style.opacity="1",o.style.transform="scale(1)",o.style.pointerEvents="auto",x&&(f.style.opacity="1"),r.textContent="✕",r.style.background="rgba(220,60,60,0.75)",b.textContent=n||s+" × "+d)}if(w.get(e)==="loaded"&&u.src===e){i(u.naturalWidth,u.naturalHeight);return}u.src=e,u.onload=()=>{w.set(e,"loaded"),i(u.naturalWidth,u.naturalHeight)},u.onerror=()=>{w.set(e,"error")}}function O(){clearTimeout(L),L=setTimeout(()=>{o.style.opacity="0",o.style.transform="scale(0.95)",o.style.pointerEvents="none",r.style.opacity="0",r.style.pointerEvents="none",r.textContent="🖼️",r.style.background="rgba(0,0,0,0.45)",m.style.pointerEvents="none",f.style.opacity="0",l=null},p.delayHide)}function j(){clearTimeout(L),clearTimeout(T),++z,l&&(v=l),o.style.opacity="0",o.style.transform="scale(0.95)",o.style.pointerEvents="none",r.style.opacity="0",r.style.pointerEvents="none",r.textContent="🖼️",r.style.background="rgba(0,0,0,0.45)",m.style.pointerEvents="none",f.style.opacity="0",l=null}function I(e){if(!e||w.has(e))return;w.set(e,"loading");const n=new Image;n.onload=()=>w.set(e,"loaded"),n.onerror=()=>w.set(e,"error"),n.src=e}function N(){l&&r.style.opacity==="1"&&q(l)}function R(e){var n;return e.dataset.previewSrc||e.src||e.currentSrc||((n=e.querySelector("img"))==null?void 0:n.src)||null}function G(e){return e.dataset.previewLabel||e.alt||e.title||null}function E(e){if(e._dpBound)return;const n={mouseenter(){x||v!==e&&(clearTimeout(T),!(l===e&&r.style.opacity==="1")&&(I(R(e)),Y(e)))},mouseleave(t){x||e.contains(t.relatedTarget)||(v===e&&(v=null),T=setTimeout(()=>{l===e&&O()},p.delayHide))},touchstart(t){if(!x)return;const i=R(e);i&&(I(i),k=setTimeout(()=>{l=e,F(i,G(e))},p.longPressDuration))},touchend(){clearTimeout(k)},touchmove(){clearTimeout(k)},touchcancel(){clearTimeout(k)},contextmenu(t){x&&t.preventDefault()}};Object.entries(n).forEach(([t,i])=>e.addEventListener(t,i)),e._dpBound=!0,e._dpHandlers=n}function J(e){e._dpBound&&(Object.entries(e._dpHandlers).forEach(([n,t])=>e.removeEventListener(n,t)),e._dpBound=!1,e._dpHandlers=null,e._dpMoveTimer=null)}function Z(e){document.querySelectorAll(e).forEach(n=>E(n))}function $(e="[data-preview]"){U(),document.querySelectorAll(e).forEach(n=>E(n)),window.addEventListener("scroll",N,!0),M=new MutationObserver(n=>{n.forEach(t=>{t.addedNodes.forEach(i=>{var s,d;i.nodeType===1&&((s=i.matches)!=null&&s.call(i,e)&&E(i),(d=i.querySelectorAll)==null||d.call(i,e).forEach(y=>E(y)))})})}),M.observe(document.body,{childList:!0,subtree:!0})}function ee(){M==null||M.disconnect(),M=null,document.querySelectorAll("[data-preview]").forEach(e=>J(e)),window.removeEventListener("scroll",N,!0),A.removeEventListener("change",D),m==null||m.remove(),m=o=P=u=b=f=r=null,w.clear(),clearTimeout(L),clearTimeout(T),clearTimeout(k),v=null}function H(e,n={}){const t=document.createElement(e);return Object.entries(n).forEach(([i,s])=>{i==="style"?t.style.cssText=s:t[i]=s}),t}function W(e,n,t){return Math.max(n,Math.min(e,t))}return{init:$,bind:E,unbind:J,bindAll:Z,destroy:ee,config:p}})()}));
1
+ (function(k,p){typeof exports=="object"&&typeof module<"u"?module.exports=p():typeof define=="function"&&define.amd?define(p):(k=typeof globalThis<"u"?globalThis:k||self,k.DataPreview=p())})(this,(function(){"use strict";return(()=>{const p={imgPad:8,maxWRatio:.9,maxHRatio:.85,delayHide:150,badgeOffset:6},y=16,w=12;let b,i,M,l,v,h,a,L=null,T=null,P=null,A=0,u=null,g=null,_="[data-preview]";const x=new Map;let m=window.matchMedia("(pointer: coarse)").matches;const C=window.matchMedia("(prefers-color-scheme: dark)"),D=window.matchMedia("(pointer: coarse)"),j=e=>{m=e.matches};D.addEventListener("change",j);let O=!1;function Z(){b||(b=H("div",{style:"position:fixed; inset:0; z-index:99999; pointer-events:none; will-change:transform;"}),a=H("div",{style:"position:fixed; width:24px; height:24px; border-radius:6px; background:rgba(0,0,0,0.45); color:#fff; font-size:13px; display:flex; align-items:center; justify-content:center; cursor:pointer; opacity:0; transition:opacity 0.15s, background 0.15s; pointer-events:none; z-index:100001; user-select:none; backdrop-filter:blur(4px);"}),a.textContent="🖼️",i=H("div",{style:"position:fixed; border-radius:12px; overflow:hidden; opacity:0; transform:scale(0.95); transition:opacity 0.15s, transform 0.15s; pointer-events:none; z-index:100000; will-change:transform, opacity;"}),h=H("button",{style:"position:absolute; top:6px; right:6px; width:26px; height:26px; border-radius:50%; border:none; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:13px; line-height:1; z-index:1; opacity:0; transition:opacity 0.15s;"}),h.textContent="✕",h.setAttribute("aria-label","关闭预览"),M=H("div",{style:"position:relative;"}),l=H("img",{style:"display:block; max-width:none; max-height:none;",alt:"preview"}),v=H("div",{style:"font-size:11px; padding:5px 10px; white-space:nowrap; height:22px; box-sizing:border-box;"}),M.append(l,h),i.append(M,v),b.append(a,i),document.body.appendChild(b),a.addEventListener("mouseenter",()=>{if(m||!u)return;clearTimeout(L),clearTimeout(T);const e=E(u);e&&I(e,J(u))}),a.addEventListener("mouseleave",()=>{m||i.style.opacity==="1"||B()}),a.addEventListener("click",e=>{e.stopPropagation(),i.style.opacity==="1"&&S()}),i.addEventListener("mouseenter",()=>{m||(clearTimeout(L),clearTimeout(T),h.style.opacity="1")}),i.addEventListener("mouseleave",e=>{m||(h.style.opacity="0",e.relatedTarget!==a&&B())}),h.addEventListener("click",e=>{e.stopPropagation(),S()}),h.addEventListener("touchend",e=>{e.stopPropagation(),e.preventDefault(),S()}),document.addEventListener("click",e=>{i&&i.style.opacity==="1"&&!i.contains(e.target)&&!a.contains(e.target)&&S()},{passive:!0}),z(),C.addEventListener("change",z))}function z(){if(!i)return;const e=C.matches;i.style.background=e?"#1c1c1e":"#ffffff",i.style.border=e?"1px solid rgba(255,255,255,.12)":"1px solid rgba(0,0,0,.1)",i.style.boxShadow=e?"0 12px 40px rgba(0,0,0,.55),0 2px 8px rgba(0,0,0,.3)":"0 8px 32px rgba(0,0,0,.18),0 2px 8px rgba(0,0,0,.08)",v.style.background=e?"rgba(255,255,255,.06)":"rgba(0,0,0,.04)",v.style.color=e?"rgba(255,255,255,.4)":"rgba(0,0,0,.4)",v.style.borderTop=e?"1px solid rgba(255,255,255,.08)":"1px solid rgba(0,0,0,.06)",h.style.background=e?"rgba(255,255,255,.15)":"rgba(0,0,0,.15)",h.style.color=e?"rgba(255,255,255,.8)":"rgba(0,0,0,.6)"}function q(e){const n=e.getBoundingClientRect();a.style.left=`${n.right-24-p.badgeOffset}px`,a.style.top=`${n.top+p.badgeOffset}px`}function R(e,n){const t=p.imgPad*2,r=22,o=Math.floor(window.innerWidth*p.maxWRatio)-t,s=Math.floor(window.innerHeight*p.maxHRatio)-t-r,c=e/n;let d,f;return c>=1?(d=Math.min(o,e),f=d/c,f>s&&(f=s,d=f*c)):(f=Math.min(s,n),d=f*c,d>o&&(d=o,f=d/c)),{pw:Math.round(d),ph:Math.round(f)}}function F(e,n){if(!u)return;const t=u.getBoundingClientRect(),r=p.imgPad,o=22,{pw:s,ph:c}=R(e,n),d=s+r*2,f=c+r*2+o,U=window.innerWidth,V=window.innerHeight;let ie=t.left-w>=d+y?t.left-w-d:U-t.right-w>=d+y?t.right+w:W(t.left+(t.width-d)/2,y,U-d-y),oe=V-t.bottom-w>=f+y?t.bottom+w:t.top-w>=f+y?t.top-w-f:W(t.top+(t.height-f)/2,y,V-f-y);i.style.left=`${ie}px`,i.style.top=`${oe}px`,i.style.width=`${d}px`,M.style.padding=`${r}px`,l.style.width=`${s}px`,l.style.height=`${c}px`}function X(e,n){const t=p.imgPad,r=22,{pw:o,ph:s}=R(e,n),c=o+t*2,d=s+t*2+r;i.style.left=`${W((window.innerWidth-c)/2,y,window.innerWidth-c-y)}px`,i.style.top=`${W((window.innerHeight-d)/2,y,window.innerHeight-d-y)}px`,i.style.width=`${c}px`,M.style.padding=`${t}px`,l.style.width=`${o}px`,l.style.height=`${s}px`}function Y(e){g!==e&&(clearTimeout(T),u=e,q(e),a.style.opacity="1",a.style.pointerEvents=m?"none":"auto")}function I(e,n){if(!e)return;const t=++A;function r(s,c){t!==A||!u||(m?X(s,c):F(s,c),i.style.opacity="1",i.style.transform="scale(1)",i.style.pointerEvents="auto",b.style.pointerEvents="auto",h.style.opacity="1",a.textContent="✕",a.style.background="rgba(220,60,60,0.75)",a.style.pointerEvents="auto",v.textContent=n||`${s} × ${c}`)}const o=x.get(e);if(o&&o.status==="loaded"){l.src!==e&&(l.onload=l.onerror=null,l.src=e),r(o.w,o.h);return}l.onload=l.onerror=null,l.onload=()=>{x.set(e,{status:"loaded",w:l.naturalWidth,h:l.naturalHeight}),r(l.naturalWidth,l.naturalHeight)},l.onerror=()=>{x.set(e,{status:"error",w:0,h:0})},l.src=e}function B(){clearTimeout(L),L=setTimeout(()=>{N()},p.delayHide)}function S(){if(clearTimeout(L),clearTimeout(T),u){const e=u;g=e,setTimeout(()=>{g===e&&(g=null)},300)}N()}function N(){A++,i&&(i.style.opacity="0",i.style.transform="scale(0.95)",i.style.pointerEvents="none",a.style.opacity="0",a.style.pointerEvents="none",h.style.opacity="0",a.textContent="🖼️",a.style.background="rgba(0,0,0,0.45)",b.style.pointerEvents="none",u=null)}function Q(e){if(!e||x.has(e))return;x.set(e,{status:"loading",w:0,h:0});const n=new Image;n.onload=()=>{x.set(e,{status:"loaded",w:n.naturalWidth,h:n.naturalHeight})},n.onerror=()=>{x.set(e,{status:"error",w:0,h:0})},n.src=e}function G(){!u||O||(O=!0,requestAnimationFrame(()=>{if(u&&a&&a.style.opacity==="1"){q(u);const e=x.get(E(u));i&&i.style.opacity==="1"&&e&&e.status==="loaded"&&(m?X(e.w,e.h):F(e.w,e.h))}O=!1}))}function E(e){var n;return e.dataset.previewSrc||e.src||e.currentSrc||((n=e.querySelector("img"))==null?void 0:n.src)||null}function J(e){return e.dataset.previewLabel||e.alt||e.title||null}function $(e){if(e._dpBound)return;let n=0,t=0;const r={mouseenter(){m||g===e||(clearTimeout(T),Q(E(e)),Y(e))},mouseleave(o){m||e.contains(o.relatedTarget)||(g===e&&(g=null),T=setTimeout(()=>{u===e&&B()},p.delayHide))},touchstart(o){if(!m)return;const s=o.touches[0];n=s.clientX,t=s.clientY,Q(E(e))},touchend(o){if(!m||g===e)return;const s=o.changedTouches[0];if(Math.abs(s.clientX-n)<10&&Math.abs(s.clientY-t)<10){Y(e);const c=E(e);c&&I(c,J(e))}}};Object.entries(r).forEach(([o,s])=>{e.addEventListener(o,s,o.startsWith("touch")&&o!=="touchend"?{passive:!0}:!1)}),e._dpBound=!0,e._dpHandlers=r}function K(e){!e||!e._dpBound||(Object.entries(e._dpHandlers||{}).forEach(([n,t])=>{e.removeEventListener(n,t)}),delete e._dpBound,delete e._dpHandlers)}function ee(e){document.querySelectorAll(e).forEach($)}function te(e="[data-preview]"){_=e,Z(),document.querySelectorAll(e).forEach($),window.addEventListener("scroll",G,{capture:!0,passive:!0}),P=new MutationObserver(n=>{n.forEach(t=>{t.addedNodes.forEach(r=>{var o,s;r.nodeType===1&&((o=r.matches)!=null&&o.call(r,e)&&$(r),(s=r.querySelectorAll)==null||s.call(r,e).forEach($))})})}),P.observe(document.body,{childList:!0,subtree:!0})}function ne(){P==null||P.disconnect(),P=null,document.querySelectorAll(_).forEach(K),window.removeEventListener("scroll",G,{capture:!0,passive:!0}),C.removeEventListener("change",z),D.removeEventListener("change",j),b==null||b.remove(),b=null,i=null,M=null,l=null,v=null,h=null,a=null,x.clear(),clearTimeout(L),clearTimeout(T),g=null,u=null}function H(e,n={}){const t=document.createElement(e);return Object.entries(n).forEach(([r,o])=>{r==="style"?t.style.cssText=o:r.startsWith("aria-")?t.setAttribute(r,o):t[r]=o}),t}function W(e,n,t){return Math.max(n,Math.min(e,t))}return{init:te,bind:$,unbind:K,bindAll:ee,destroy:ne,config:p}})()}));
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "data-preview",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "AI-native semantic preview runtime for modern web.",
5
5
  "keywords": ["image preview", "big image", "semantic protocol", "ai-native","data preview protocol"],
6
6
  "type": "module",
7
7
 
8
8
  "main": "./dist/data-preview.umd.js",
9
- "module": "./dist/data-preview.js",
9
+ "module": "./dist/data-preview.es.js",
10
10
 
11
11
  "exports": {
12
12
  ".": {
13
- "import": "./dist/data-preview.js",
13
+ "import": "./dist/data-preview.es.js",
14
14
  "default": "./dist/data-preview.umd.js"
15
15
  }
16
16
  },
@@ -34,7 +34,7 @@
34
34
  "type": "git",
35
35
  "url": "https://github.com/doc-war/data-preview"
36
36
  },
37
- "homepage": "https://doc-war.com/data-preview",
37
+ "homepage": "https://doc-war.com",
38
38
 
39
39
  "license": "MIT"
40
40
  }