pro-visu 0.3.0 → 0.3.1

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/dist/cli/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { cac } from "cac";
5
5
 
6
6
  // src/version.ts
7
- var TOOL_VERSION = true ? "0.3.0" : "0.0.0-dev";
7
+ var TOOL_VERSION = true ? "0.3.1" : "0.0.0-dev";
8
8
 
9
9
  // src/cli/update-check.ts
10
10
  import updateNotifier from "update-notifier";
@@ -1044,7 +1044,8 @@ async function detectSectionOffsets(args) {
1044
1044
  continue;
1045
1045
  }
1046
1046
  if (!args.selector && rect.height < minH) continue;
1047
- const top = docTarget ? rect.top + curScroll : rect.top - containerTop + curScroll;
1047
+ const rawTop = docTarget ? rect.top + curScroll : rect.top - containerTop + curScroll;
1048
+ const top = rawTop - (args.headerInsetPx ?? 0);
1048
1049
  const y = Math.max(0, Math.min(distance, top));
1049
1050
  offsets.push(y / distance);
1050
1051
  }
@@ -1102,7 +1103,8 @@ async function measureNormalizedOffsets(args) {
1102
1103
  }
1103
1104
  if (!el) return null;
1104
1105
  const rect = el.getBoundingClientRect();
1105
- const offsetTop = docTarget ? rect.top + curScroll : rect.top - containerTop + curScroll;
1106
+ const rawTop = docTarget ? rect.top + curScroll : rect.top - containerTop + curScroll;
1107
+ const offsetTop = rawTop - (args.headerInsetPx ?? 0);
1106
1108
  const y = Math.max(0, Math.min(distance, offsetTop));
1107
1109
  return distance > 0 ? y / distance : 0;
1108
1110
  });
@@ -1138,6 +1140,79 @@ async function measureNormalizedOffsets(args) {
1138
1140
  return Math.max(0, t.scrollHeight - t.clientHeight);
1139
1141
  }
1140
1142
  }
1143
+ async function measureTopInset(args) {
1144
+ const target = findScrollTarget(document, getComputedStyle);
1145
+ const vh = window.innerHeight || document.documentElement.clientHeight || 0;
1146
+ const vw = window.innerWidth || document.documentElement.clientWidth || 0;
1147
+ const maxFraction = args.maxFraction ?? 0.4;
1148
+ const distance = maxScrollOf(target);
1149
+ const cur = isDocTarget(target) ? window.pageYOffset || document.documentElement.scrollTop || 0 : target.scrollTop;
1150
+ scrollTargetTo(target, Math.min(cur + vh, distance));
1151
+ await new Promise((resolve) => requestAnimationFrame(() => resolve()));
1152
+ let inset = 0;
1153
+ try {
1154
+ const all = document.querySelectorAll("body *");
1155
+ for (let i = 0; i < all.length; i++) {
1156
+ const el = all[i];
1157
+ let position = "";
1158
+ try {
1159
+ position = getComputedStyle(el).position;
1160
+ } catch {
1161
+ continue;
1162
+ }
1163
+ if (position !== "fixed" && position !== "sticky") continue;
1164
+ let r;
1165
+ try {
1166
+ r = el.getBoundingClientRect();
1167
+ } catch {
1168
+ continue;
1169
+ }
1170
+ if (r.top <= 2 && r.width >= vw * 0.6 && r.height > 0 && r.bottom > inset && r.bottom <= vh * maxFraction) {
1171
+ inset = r.bottom;
1172
+ }
1173
+ }
1174
+ } catch {
1175
+ }
1176
+ scrollTargetTo(target, cur);
1177
+ await new Promise((resolve) => requestAnimationFrame(() => resolve()));
1178
+ return inset;
1179
+ function findScrollTarget(doc, gcs) {
1180
+ const se = doc.scrollingElement || doc.documentElement;
1181
+ if (se && se.scrollHeight - se.clientHeight > 1) return se;
1182
+ let best = null;
1183
+ let bestArea = 0;
1184
+ const all = doc.querySelectorAll("*");
1185
+ for (let i = 0; i < all.length; i++) {
1186
+ const el = all[i];
1187
+ let oy = "";
1188
+ try {
1189
+ oy = gcs(el).overflowY;
1190
+ } catch {
1191
+ oy = "";
1192
+ }
1193
+ const scrollable = oy === "auto" || oy === "scroll" || oy === "overlay";
1194
+ if (scrollable && el.scrollHeight - el.clientHeight > 1) {
1195
+ const area = el.clientWidth * el.clientHeight;
1196
+ if (area > bestArea) {
1197
+ bestArea = area;
1198
+ best = el;
1199
+ }
1200
+ }
1201
+ }
1202
+ return best || se;
1203
+ }
1204
+ function isDocTarget(t) {
1205
+ return t === (document.scrollingElement || document.documentElement) || t === document.documentElement || t === document.body;
1206
+ }
1207
+ function scrollTargetTo(t, y) {
1208
+ if (isDocTarget(t)) window.scrollTo({ top: y, left: 0, behavior: "instant" });
1209
+ else if (t.scrollTo) t.scrollTo({ top: y, left: 0, behavior: "instant" });
1210
+ else t.scrollTop = y;
1211
+ }
1212
+ function maxScrollOf(t) {
1213
+ return Math.max(0, t.scrollHeight - t.clientHeight);
1214
+ }
1215
+ }
1141
1216
  async function settleInView() {
1142
1217
  try {
1143
1218
  await (document.fonts?.ready ?? Promise.resolve());
@@ -1848,7 +1923,8 @@ async function buildScrollTimeline(page, options, totalSeconds, logger) {
1848
1923
  const finalize = (spec) => resolveTimeline(options.loop === "boomerang" ? boomerangSpec(spec) : spec, totalSeconds);
1849
1924
  if (steps && steps.length > 0) {
1850
1925
  const selectors = steps.map((s) => s.to).filter((to) => typeof to === "string" && !to.trim().endsWith("%"));
1851
- const measured = selectors.length > 0 ? await page.evaluate(measureNormalizedOffsets, { selectors }) : [];
1926
+ const headerInsetPx = selectors.length > 0 ? await page.evaluate(measureTopInset, {}) : 0;
1927
+ const measured = selectors.length > 0 ? await page.evaluate(measureNormalizedOffsets, { selectors, headerInsetPx }) : [];
1852
1928
  let mi = 0;
1853
1929
  let prevY = 0;
1854
1930
  const resolved = steps.map((s) => {
@@ -1884,10 +1960,12 @@ async function buildScrollTimeline(page, options, totalSeconds, logger) {
1884
1960
  }
1885
1961
  if (options.autoSections) {
1886
1962
  const cfg = options.autoSections === true ? {} : options.autoSections;
1963
+ const headerInsetPx = await page.evaluate(measureTopInset, {});
1887
1964
  const offsets = await page.evaluate(detectSectionOffsets, {
1888
1965
  minHeightFraction: cfg.minHeightFraction ?? DEFAULT_AUTO_MIN_HEIGHT_FRACTION,
1889
1966
  selector: cfg.selector ?? null,
1890
- maxSections: cfg.maxSections ?? DEFAULT_AUTO_MAX_SECTIONS
1967
+ maxSections: cfg.maxSections ?? DEFAULT_AUTO_MAX_SECTIONS,
1968
+ headerInsetPx
1891
1969
  });
1892
1970
  const autoSteps = autoSectionSteps({
1893
1971
  offsets,