@floegence/floe-webapp-core 0.74.0 → 0.75.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.
@@ -1,6 +1,6 @@
1
1
  function P(h) {
2
2
  const s = document, $ = 48e3, b = 240, A = () => h.scopeStorageKey ? sessionStorage.getItem(h.scopeStorageKey) ?? "" : "", g = (o) => typeof o == "string" && o.length <= 120 && !/[;{}<>\\]|url\(|var\(/i.test(o) && CSS.supports("color", o);
3
- let l, a, C = "", d;
3
+ let l, c, C = "", d;
4
4
  try {
5
5
  const o = sessionStorage.getItem(h.storageKey), e = o && o.length <= $ ? JSON.parse(o) : void 0;
6
6
  e?.version === 1 && e.scope === A() && e.width === innerWidth && e.height === innerHeight && g(e.background) && Array.isArray(e.scroll) && e.scroll.length <= 12 && e.scroll.every((r) => Array.isArray(r) && r.length === 3 && /^[a-z0-9-]{1,48}$/.test(r[0]) && r.slice(1).every((i) => typeof i == "number" && Number.isFinite(i) && i >= 0 && i <= 1e7)) && Array.isArray(e.boxes) && e.boxes.length > 0 && e.boxes.length <= b && e.boxes.every((r) => Array.isArray(r) && r.length === 7 && r.slice(0, 5).every((i) => typeof i == "number" && Number.isFinite(i) && i >= 0 && i <= 2e4) && g(r[5]) && g(r[6])) && (d = e);
@@ -17,19 +17,19 @@ function P(h) {
17
17
  pointerEvents: "none",
18
18
  contain: "strict"
19
19
  });
20
- for (const [o, e, r, i, x, m, w] of d.boxes) {
21
- const p = s.createElement("div");
22
- Object.assign(p.style, {
20
+ for (const [o, e, r, i, m, x, w] of d.boxes) {
21
+ const f = s.createElement("div");
22
+ Object.assign(f.style, {
23
23
  position: "absolute",
24
24
  left: `${o}px`,
25
25
  top: `${e}px`,
26
26
  width: `${r}px`,
27
27
  height: `${i}px`,
28
- borderRadius: `${x}px`,
29
- backgroundColor: m,
28
+ borderRadius: `${m}px`,
29
+ backgroundColor: x,
30
30
  border: `1px solid ${w}`,
31
31
  boxSizing: "border-box"
32
- }), l.append(p);
32
+ }), l.append(f);
33
33
  }
34
34
  s.body.append(l);
35
35
  }
@@ -45,53 +45,55 @@ function P(h) {
45
45
  }
46
46
  d = void 0, l?.remove(), l = void 0;
47
47
  }, N = () => {
48
- a = void 0, y();
48
+ c = void 0, y();
49
49
  try {
50
50
  sessionStorage.removeItem(h.storageKey);
51
51
  } catch {
52
52
  }
53
53
  }, O = () => {
54
- if (!a?.isConnected || l) return;
54
+ if (!c?.isConnected || l) return;
55
55
  const o = [], e = getComputedStyle(s.body).backgroundColor;
56
56
  if (!g(e)) return;
57
57
  const r = (n) => {
58
- const t = n.getBoundingClientRect(), c = getComputedStyle(n);
59
- return t.width && t.height && t.bottom > 0 && t.right > 0 && t.top < innerHeight && t.left < innerWidth && c.visibility === "visible" ? t : null;
60
- }, i = (n, t, c = "transparent", u = 3) => {
61
- if (o.length >= b || !g(t) || !g(c)) return;
62
- const f = Math.max(0, n.x), R = Math.max(0, n.y), k = Math.min(innerWidth, n.right) - f, E = Math.min(innerHeight, n.bottom) - R;
63
- k <= 0 || E <= 0 || o.push([f, R, k, E, Math.max(0, Math.min(u, 100)), t, c]);
58
+ const t = n.getBoundingClientRect(), a = getComputedStyle(n);
59
+ return t.width && t.height && t.bottom > 0 && t.right > 0 && t.top < innerHeight && t.left < innerWidth && a.visibility === "visible" ? t : null;
60
+ }, i = (n, t, a = "transparent", u = 3) => {
61
+ if (o.length >= b || !g(t) || !g(a)) return;
62
+ const p = Math.max(0, n.x), R = Math.max(0, n.y), k = Math.min(innerWidth, n.right) - p, E = Math.min(innerHeight, n.bottom) - R;
63
+ k <= 0 || E <= 0 || o.push([p, R, k, E, Math.max(0, Math.min(u, 100)), t, a]);
64
64
  };
65
- for (const n of a.querySelectorAll(C)) {
65
+ for (const n of c.querySelectorAll(C)) {
66
+ if (n.closest("[data-floe-reload-omit]")) continue;
66
67
  const t = r(n);
67
68
  if (!t) continue;
68
- const c = getComputedStyle(n);
69
- i(t, c.backgroundColor, c.borderTopStyle === "none" ? "transparent" : c.borderTopColor, parseFloat(c.borderRadius) || 0);
69
+ const a = getComputedStyle(n);
70
+ i(t, a.backgroundColor, a.borderTopStyle === "none" ? "transparent" : a.borderTopColor, parseFloat(a.borderRadius) || 0);
70
71
  }
71
- const x = getComputedStyle(a).color, m = g(x) ? `color-mix(in srgb, ${x} 9%, ${e})` : "#d4d4d4";
72
- for (const n of a.querySelectorAll("img,svg,input,textarea,canvas,video")) {
72
+ const m = getComputedStyle(c).color, x = g(m) ? `color-mix(in srgb, ${m} 9%, ${e})` : "#d4d4d4";
73
+ for (const n of c.querySelectorAll("img,svg,input,textarea,canvas,video")) {
74
+ if (n.closest("[data-floe-reload-omit]")) continue;
73
75
  const t = r(n);
74
- t && i(t, m, "transparent", Math.min(t.height / 4, 8));
76
+ t && i(t, x, "transparent", Math.min(t.height / 4, 8));
75
77
  }
76
- const w = s.createTreeWalker(a, NodeFilter.SHOW_TEXT), p = s.createRange();
78
+ const w = s.createTreeWalker(c, NodeFilter.SHOW_TEXT), f = s.createRange();
77
79
  let S, T = 0;
78
80
  for (; (S = w.nextNode()) && o.length < b && T++ < 12e3; ) {
79
81
  const n = S.parentElement;
80
- if (!(!n || n.closest('script,style,textarea,svg,[aria-hidden="true"]') || !r(n))) {
81
- p.selectNodeContents(S);
82
- for (const t of p.getClientRects())
83
- t.width < 2 || i(new DOMRect(t.x, t.y + t.height * 0.22, t.width, t.height * 0.56), m);
82
+ if (!(!n || n.closest('script,style,textarea,svg,[aria-hidden="true"],[data-floe-reload-omit]') || !r(n))) {
83
+ f.selectNodeContents(S);
84
+ for (const t of f.getClientRects())
85
+ t.width < 2 || i(new DOMRect(t.x, t.y + t.height * 0.22, t.width, t.height * 0.56), x);
84
86
  }
85
87
  }
86
88
  if (o.length)
87
89
  try {
88
90
  const n = [];
89
- for (const u of a.querySelectorAll("[data-floe-reload-scroll]")) {
90
- const f = u.getAttribute("data-floe-reload-scroll");
91
- /^[a-z0-9-]{1,48}$/.test(f) && n.length < 12 && r(u) && n.push([f, u.scrollLeft, u.scrollTop]);
91
+ for (const u of c.querySelectorAll("[data-floe-reload-scroll]")) {
92
+ const p = u.getAttribute("data-floe-reload-scroll");
93
+ /^[a-z0-9-]{1,48}$/.test(p) && n.length < 12 && r(u) && n.push([p, u.scrollLeft, u.scrollTop]);
92
94
  }
93
- const t = { version: 1, scope: A(), width: innerWidth, height: innerHeight, background: e, boxes: o, scroll: n }, c = JSON.stringify(t);
94
- c.length <= $ && sessionStorage.setItem(h.storageKey, c);
95
+ const t = { version: 1, scope: A(), width: innerWidth, height: innerHeight, background: e, boxes: o, scroll: n }, a = JSON.stringify(t);
96
+ a.length <= $ && sessionStorage.setItem(h.storageKey, a);
95
97
  } catch {
96
98
  }
97
99
  };
@@ -104,7 +106,7 @@ function P(h) {
104
106
  },
105
107
  finish: y,
106
108
  arm(o, e) {
107
- a = o, C = e;
109
+ c = o, C = e;
108
110
  },
109
111
  clear: N
110
112
  }, window.addEventListener("pagehide", O), window.addEventListener("resize", y, { once: !0 }), window.addEventListener("pageshow", (o) => {
@@ -22,11 +22,13 @@ export interface ViewportSnapshot {
22
22
  };
23
23
  safeArea: ViewportInsets;
24
24
  keyboardOpen: boolean;
25
- /** Add to client coordinates when positioning a document-level fixed element. */
25
+ /** Add to client coordinates before dividing by fixedScale for document-level fixed CSS. */
26
26
  fixedOffset: {
27
27
  left: number;
28
28
  top: number;
29
29
  };
30
+ /** Effective CSS zoom inherited by a document-body portal. Client bounds stay unscaled. */
31
+ fixedScale: number;
30
32
  }
31
33
  export interface ViewportSource {
32
34
  width: number;
@@ -35,6 +37,7 @@ export interface ViewportSource {
35
37
  left: number;
36
38
  top: number;
37
39
  };
40
+ fixedScale?: number;
38
41
  visualViewport?: {
39
42
  width: number;
40
43
  height: number;
package/dist/viewport.js CHANGED
@@ -1,90 +1,95 @@
1
- const u = (t, e) => Number.isFinite(t) && Number(t) > 0 ? Number(t) : Math.max(0, e);
1
+ const p = (t, e) => Number.isFinite(t) && Number(t) > 0 ? Number(t) : Math.max(0, e);
2
2
  function g(t) {
3
- const e = t.visualViewport, n = u(e?.width, t.width), i = u(e?.height, t.height), o = t.fixedOrigin ?? { left: 0, top: 0 }, s = Math.max(0, e?.offsetLeft || 0) + o.left, a = Math.max(0, e?.offsetTop || 0) + o.top, r = t.touch && t.editing && Math.abs((e?.scale ?? 1) - 1) < 0.01 && t.height - i > 100;
3
+ const e = t.visualViewport, o = p(e?.width, t.width), s = p(e?.height, t.height), n = t.fixedOrigin ?? { left: 0, top: 0 }, r = Math.max(0, e?.offsetLeft || 0) + n.left, a = Math.max(0, e?.offsetTop || 0) + n.top, i = t.touch && t.editing && Math.abs((e?.scale ?? 1) - 1) < 0.01 && t.height - s > 100;
4
4
  return {
5
- visible: { left: s, top: a, width: n, height: i, right: s + n, bottom: a + i },
5
+ visible: { left: r, top: a, width: o, height: s, right: r + o, bottom: a + s },
6
6
  layout: { width: t.width, height: t.height },
7
- safeArea: { ...t.safeArea, bottom: r ? 0 : t.safeArea.bottom },
8
- keyboardOpen: r,
9
- fixedOffset: { left: -o.left, top: -o.top }
7
+ safeArea: { ...t.safeArea, bottom: i ? 0 : t.safeArea.bottom },
8
+ keyboardOpen: i,
9
+ fixedOffset: { left: -n.left, top: -n.top },
10
+ fixedScale: p(t.fixedScale, 1)
10
11
  };
11
12
  }
12
- function b(t) {
13
+ function x(t) {
13
14
  let e = t.activeElement;
14
15
  for (; e?.shadowRoot?.activeElement; ) e = e.shadowRoot.activeElement;
15
16
  return !e || e.matches('[disabled], [readonly], [inputmode="none"]') ? !1 : e.matches('textarea, input:not([type]), input[type="text"], input[type="search"], input[type="email"], input[type="url"], input[type="tel"], input[type="password"], input[type="number"], [contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]');
16
17
  }
17
- function m(t) {
18
+ function b(t) {
18
19
  const e = t.document.createElement("div");
19
20
  return e.setAttribute("aria-hidden", "true"), e.style.cssText = "position:fixed;top:0;left:0;width:100%;height:100dvh;visibility:hidden;pointer-events:none;box-sizing:border-box;padding:env(safe-area-inset-top,0px) env(safe-area-inset-right,0px) env(safe-area-inset-bottom,0px) env(safe-area-inset-left,0px)", t.document.documentElement.append(e), e;
20
21
  }
21
- function l(t, e) {
22
- const n = e.getBoundingClientRect(), i = t.getComputedStyle(e), o = (s) => Math.max(0, Number.parseFloat(s) || 0);
22
+ function u(t, e) {
23
+ const o = e.getBoundingClientRect(), s = t.getComputedStyle(e), n = (i) => Math.max(0, Number.parseFloat(i) || 0), r = (i) => i ? p(Number.parseFloat(t.getComputedStyle(i).zoom), 1) : 1, a = r(t.document.documentElement);
23
24
  return g({
24
- width: n.width || t.innerWidth,
25
- height: n.height || t.innerHeight,
25
+ width: o.width || t.innerWidth,
26
+ height: o.height / a || t.innerHeight,
26
27
  visualViewport: t.visualViewport,
27
- fixedOrigin: { left: n.left, top: n.top },
28
- safeArea: { top: o(i.paddingTop), right: o(i.paddingRight), bottom: o(i.paddingBottom), left: o(i.paddingLeft) },
29
- editing: b(t.document),
28
+ fixedOrigin: { left: o.left, top: o.top },
29
+ fixedScale: a * r(t.document.body),
30
+ safeArea: { top: n(s.paddingTop), right: n(s.paddingRight), bottom: n(s.paddingBottom), left: n(s.paddingLeft) },
31
+ editing: x(t.document),
30
32
  touch: t.matchMedia?.("(any-pointer: coarse)").matches ?? !1
31
33
  });
32
34
  }
33
- const d = /* @__PURE__ */ new WeakMap();
34
- function x(t) {
35
- const e = d.get(t);
35
+ const c = /* @__PURE__ */ new WeakMap();
36
+ function y(t) {
37
+ const e = c.get(t);
36
38
  if (e) return e.snapshot;
37
- const n = m(t);
39
+ const o = b(t);
38
40
  try {
39
- return l(t, n);
41
+ return u(t, o);
40
42
  } finally {
41
- n.remove();
43
+ o.remove();
42
44
  }
43
45
  }
44
- function y(t, e) {
45
- let n = d.get(t);
46
- if (!n) {
47
- const o = m(t);
48
- let s = 0;
49
- const a = /* @__PURE__ */ new Set(), r = { snapshot: l(t, o), listeners: a, dispose: () => {
50
- } }, c = () => {
51
- s || (s = t.requestAnimationFrame(() => {
52
- s = 0, r.snapshot = l(t, o);
53
- for (const p of a) p(r.snapshot);
46
+ function S(t, e) {
47
+ let o = c.get(t);
48
+ if (!o) {
49
+ const n = b(t);
50
+ let r = 0;
51
+ const a = /* @__PURE__ */ new Set(), i = { snapshot: u(t, n), listeners: a, dispose: () => {
52
+ } }, f = () => {
53
+ r || (r = t.requestAnimationFrame(() => {
54
+ r = 0, i.snapshot = u(t, n);
55
+ for (const d of a) d(i.snapshot);
54
56
  }));
55
- }, f = [
57
+ }, l = [
56
58
  [t, "resize"],
57
59
  [t, "scroll"],
58
60
  [t, "orientationchange"],
59
61
  [t.document, "focusin"],
60
62
  [t.document, "focusout"]
61
63
  ];
62
- t.visualViewport && f.push([t.visualViewport, "resize"], [t.visualViewport, "scroll"]);
63
- for (const [p, h] of f) p.addEventListener(h, c);
64
- r.dispose = () => {
65
- for (const [p, h] of f) p.removeEventListener(h, c);
66
- s && t.cancelAnimationFrame(s), o.remove(), d.delete(t);
67
- }, d.set(t, r), n = r;
64
+ t.visualViewport && l.push([t.visualViewport, "resize"], [t.visualViewport, "scroll"]);
65
+ for (const [d, h] of l) d.addEventListener(h, f);
66
+ const m = new MutationObserver(f);
67
+ for (const d of [t.document.documentElement, t.document.body])
68
+ d && m.observe(d, { attributes: !0, attributeFilter: ["class", "style"] });
69
+ i.dispose = () => {
70
+ for (const [d, h] of l) d.removeEventListener(h, f);
71
+ m.disconnect(), r && t.cancelAnimationFrame(r), n.remove(), c.delete(t);
72
+ }, c.set(t, i), o = i;
68
73
  }
69
- n.listeners.add(e), e(n.snapshot);
70
- const i = n;
74
+ o.listeners.add(e), e(o.snapshot);
75
+ const s = o;
71
76
  return () => {
72
- i.listeners.delete(e), i.listeners.size === 0 && i.dispose();
77
+ s.listeners.delete(e), s.listeners.size === 0 && s.dispose();
73
78
  };
74
79
  }
75
- function V(t) {
76
- const { visible: e } = t;
80
+ function E(t) {
81
+ const { visible: e, fixedScale: o } = t;
77
82
  return {
78
83
  position: "fixed",
79
- left: `${e.left + t.fixedOffset.left}px`,
80
- top: `${e.top + t.fixedOffset.top}px`,
81
- width: `${e.width}px`,
82
- height: `${e.height}px`
84
+ left: `${(e.left + t.fixedOffset.left) / o}px`,
85
+ top: `${(e.top + t.fixedOffset.top) / o}px`,
86
+ width: `${e.width / o}px`,
87
+ height: `${e.height / o}px`
83
88
  };
84
89
  }
85
90
  export {
86
- y as observeViewport,
87
- x as readViewportSnapshot,
91
+ S as observeViewport,
92
+ y as readViewportSnapshot,
88
93
  g as resolveViewportSnapshot,
89
- V as viewportStyle
94
+ E as viewportStyle
90
95
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@floegence/floe-webapp-core",
3
- "version": "0.74.0",
3
+ "version": "0.75.0",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",