gutterpress 0.10.0 → 0.10.1-beta.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.
Files changed (54) hide show
  1. package/README.md +3 -16
  2. package/dist/api/index.d.ts +10 -19
  3. package/dist/api/index.js +8 -64
  4. package/dist/{audit-cvarpa72.js → audit-7a37g51p.js} +5 -5
  5. package/dist/{build-6r502chw.js → build-kdaet3pd.js} +5 -5
  6. package/dist/checks/source/index.d.ts +1 -0
  7. package/dist/checks/source/merge-markers.d.ts +3 -0
  8. package/dist/{cli-zfcryxg8.js → cli-ak1tagkr.js} +94 -57
  9. package/dist/{cli-eq5naw4m.js → cli-df7gcyns.js} +370 -1249
  10. package/dist/{cli-149edp6b.js → cli-dx6sxj2t.js} +1 -1
  11. package/dist/{cli-cqtggsng.js → cli-mcb484g3.js} +2 -47
  12. package/dist/{cli-k1065rkg.js → cli-w692g6dx.js} +75 -29
  13. package/dist/cli.js +14 -15
  14. package/dist/{doctor-akvxbtjb.js → doctor-vajd5h45.js} +2 -2
  15. package/dist/{engine-b159tbns.js → engine-0nt35svz.js} +2 -2
  16. package/dist/{engine-ft4cr3ep.js → engine-gkcqdye5.js} +1 -1
  17. package/dist/{gutterpress-viewer-te8g5grx.js → gutterpress-viewer-tma1qwz2.js} +57 -15
  18. package/dist/{index-ge7q9xj3.js → index-6g72h2n1.js} +771 -1482
  19. package/dist/{index-ycpvr0am.js → index-b2rqw41a.js} +1 -1
  20. package/dist/{index-mdefp0y5.js → index-dtrftayr.js} +75 -27
  21. package/dist/{index-wq3r5pj7.js → index-kvgq4q3q.js} +94 -57
  22. package/dist/index.js +9 -65
  23. package/dist/lib/git-fs.d.ts +43 -0
  24. package/dist/lib/host-policy.d.ts +14 -2
  25. package/dist/lib/remote-auth/clone.d.ts +0 -21
  26. package/dist/lib/remote-auth/converge-merge.d.ts +24 -7
  27. package/dist/lib/remote-auth/generic-auth.d.ts +0 -22
  28. package/dist/lib/remote-auth/git-http.d.ts +1 -1
  29. package/dist/lib/remote-auth/github-auth.d.ts +2 -22
  30. package/dist/lib/remote-auth/operation-log.d.ts +4 -9
  31. package/dist/lib/remote-auth/sync-messages.d.ts +35 -12
  32. package/dist/lib/remote-auth/sync-types.d.ts +30 -101
  33. package/dist/lib/remote-auth/sync.d.ts +19 -21
  34. package/dist/lib/remote-auth/token-store.d.ts +0 -10
  35. package/dist/lib/remote-auth/transport.d.ts +42 -40
  36. package/dist/lib/source-provider.d.ts +12 -0
  37. package/dist/{lint-p2sw53d9.js → lint-p6a4bkvh.js} +5 -5
  38. package/dist/{new-hvq0x91q.js → new-4cdzfbsj.js} +5 -5
  39. package/dist/{plugin-pssmk0dx.js → plugin-a89tqspy.js} +5 -5
  40. package/dist/{preflight-4j00yd0g.js → preflight-r4y3f8f9.js} +5 -5
  41. package/dist/{preview-d4s6gk6p.js → preview-k8n2kew7.js} +5 -5
  42. package/dist/{publish-tkc26en7.js → publish-jnhjp2vd.js} +5 -5
  43. package/dist/{source-provider-3tcj6qg2.js → source-provider-2j5x2hyw.js} +1 -1
  44. package/dist/{source-provider-vanafrt9.js → source-provider-kn41jmbs.js} +1 -1
  45. package/dist/{validate-w9vfefrw.js → validate-prnybpkx.js} +5 -5
  46. package/package.json +1 -1
  47. package/dist/lib/app-heartbeat.d.ts +0 -102
  48. package/dist/lib/remote-auth/image-clash.d.ts +0 -17
  49. package/dist/lib/remote-auth/recovery/classify.d.ts +0 -97
  50. package/dist/lib/remote-auth/recovery/inspect.d.ts +0 -75
  51. package/dist/lib/remote-auth/recovery/locks.d.ts +0 -20
  52. package/dist/lib/remote-auth/recovery/repair.d.ts +0 -29
  53. package/dist/lib/remote-auth/recovery/types.d.ts +0 -39
  54. package/dist/repair-2va4w12t.js +0 -137
@@ -4,7 +4,7 @@ import {
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "gutterpress",
7
- version: "0.10.0",
7
+ version: "0.10.1-beta.1",
8
8
  description: "Markdown-to-PDF converter for professional print layout using a native Chromium print engine and Ghostscript.",
9
9
  author: "itlackey",
10
10
  license: "MPL-2.0",
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "./cli-149edp6b.js";
3
+ } from "./cli-dx6sxj2t.js";
4
4
  import {
5
5
  execCapture,
6
6
  findTool,
@@ -307,27 +307,6 @@ async function convertToPdfxCmyk(inputPdf, outPdf, config) {
307
307
  import { chmod, mkdir, readFile as readFile2, rename as rename2, writeFile as writeFile2 } from "node:fs/promises";
308
308
  import os from "node:os";
309
309
  import path from "node:path";
310
- function credentialHostKey(hostOrUrl) {
311
- const trimmed = String(hostOrUrl ?? "").trim();
312
- if (!trimmed)
313
- return "";
314
- const scp = /^[\w.-]+@([\w.][\w.-]*):/.exec(trimmed);
315
- if (scp)
316
- return stripWww(scp[1].toLowerCase());
317
- const candidate = /^[a-z][a-z0-9+.-]*:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
318
- try {
319
- const url = new URL(candidate);
320
- if (!url.hostname)
321
- return "";
322
- const host = url.port ? `${url.hostname}:${url.port}`.toLowerCase() : url.hostname.toLowerCase();
323
- return stripWww(host);
324
- } catch {
325
- return "";
326
- }
327
- }
328
- function stripWww(host) {
329
- return host.startsWith("www.") && host.length > 4 ? host.slice(4) : host;
330
- }
331
310
  function defaultConfigDir() {
332
311
  const override = process.env.GUTTERPRESS_CONFIG_DIR?.trim();
333
312
  if (override)
@@ -422,30 +401,6 @@ class FileTokenStore {
422
401
  function normalizeHost(host) {
423
402
  return host.trim().toLowerCase();
424
403
  }
425
- function extractUrlCredential(url) {
426
- let parsed;
427
- try {
428
- parsed = new URL(url);
429
- } catch {
430
- return { cleanUrl: url };
431
- }
432
- if (!/^https?:$/.test(parsed.protocol))
433
- return { cleanUrl: url };
434
- if (!parsed.username && !parsed.password)
435
- return { cleanUrl: url };
436
- const token = parsed.password ? decodeURIComponent(parsed.password) : decodeURIComponent(parsed.username);
437
- const username = parsed.password ? decodeURIComponent(parsed.username) : undefined;
438
- parsed.username = "";
439
- parsed.password = "";
440
- const credential = {
441
- host: credentialHostKey(parsed.toString()),
442
- kind: "token",
443
- token,
444
- ...username ? { username } : {},
445
- createdAt: Date.now()
446
- };
447
- return { cleanUrl: parsed.toString(), credential };
448
- }
449
404
 
450
405
  // src/lib/diagnostics.ts
451
406
  import { platform, arch, release } from "node:os";
@@ -559,4 +514,4 @@ async function getSystemDiagnostics() {
559
514
  };
560
515
  }
561
516
 
562
- export { setLogLevel, debug, info, warn, error, log, resolveGhostscript, hasLiveTransparency, stripAnnotations, stampCreator, convertToPdfxCmyk, PACKAGE_META, PACKAGE_VERSION, credentialHostKey, defaultConfigDir, FileTokenStore, extractUrlCredential, getSystemDiagnostics };
517
+ export { setLogLevel, debug, info, warn, error, log, resolveGhostscript, hasLiveTransparency, stripAnnotations, stampCreator, convertToPdfxCmyk, PACKAGE_META, PACKAGE_VERSION, defaultConfigDir, FileTokenStore, getSystemDiagnostics };
@@ -4,8 +4,59 @@ import {
4
4
  findEnclosingRepoDir
5
5
  } from "./cli-v5mp7a6q.js";
6
6
 
7
+ // src/lib/git-fs.ts
8
+ import * as nodeFs from "node:fs";
9
+ var MUTABLE_GIT_METADATA = /(?:^|[\\/])\.git[\\/](?:index|HEAD|packed-refs|refs[\\/].+)$/;
10
+ function needsAtomicWrite(file) {
11
+ return typeof file === "string" && MUTABLE_GIT_METADATA.test(file);
12
+ }
13
+ var tempCounter = 0;
14
+ function tempPathFor(file) {
15
+ return `${file}.gp${process.pid.toString(36)}-${(tempCounter++).toString(36)}.tmp`;
16
+ }
17
+ function writeFile2(file, data, options, callback) {
18
+ const cb = typeof options === "function" ? options : callback;
19
+ const opts = typeof options === "function" ? undefined : options;
20
+ if (!needsAtomicWrite(file)) {
21
+ nodeFs.writeFile(file, data, opts, cb);
22
+ return;
23
+ }
24
+ const temp = tempPathFor(file);
25
+ const failed = (err) => nodeFs.unlink(temp, () => cb(err));
26
+ nodeFs.writeFile(temp, data, opts, (writeErr) => {
27
+ if (writeErr)
28
+ return failed(writeErr);
29
+ nodeFs.rename(temp, file, (renameErr) => {
30
+ if (renameErr)
31
+ return failed(renameErr);
32
+ cb(null);
33
+ });
34
+ });
35
+ }
36
+ async function writeFilePromise(file, data, options) {
37
+ if (!needsAtomicWrite(file)) {
38
+ return nodeFs.promises.writeFile(file, data, options);
39
+ }
40
+ const temp = tempPathFor(file);
41
+ try {
42
+ await nodeFs.promises.writeFile(temp, data, options);
43
+ await nodeFs.promises.rename(temp, file);
44
+ } catch (err) {
45
+ await nodeFs.promises.unlink(temp).catch(() => {});
46
+ throw err;
47
+ }
48
+ }
49
+ var promises2 = {
50
+ ...nodeFs.promises,
51
+ writeFile: writeFilePromise
52
+ };
53
+ var gitFs = {
54
+ ...nodeFs,
55
+ writeFile: writeFile2,
56
+ promises: promises2
57
+ };
58
+
7
59
  // src/lib/source-provider.ts
8
- import * as fs from "node:fs";
9
60
  import path2 from "node:path";
10
61
  import git from "isomorphic-git";
11
62
 
@@ -43,11 +94,6 @@ function createFileLogger(logFile, operation, minLevel = "debug") {
43
94
  error: (step, message, data) => write("error", step, message, data)
44
95
  };
45
96
  }
46
- function resolveLogger(logFile, operation) {
47
- if (!logFile)
48
- return noop;
49
- return createFileLogger(logFile, operation);
50
- }
51
97
  function formatData(data) {
52
98
  if (!data)
53
99
  return "";
@@ -83,7 +129,7 @@ var repoQueues = new Map;
83
129
  function repoLockKey(projectDir) {
84
130
  const resolved = path2.resolve(projectDir);
85
131
  try {
86
- return fs.realpathSync(resolved);
132
+ return gitFs.realpathSync(resolved);
87
133
  } catch {
88
134
  return resolved;
89
135
  }
@@ -114,10 +160,10 @@ function gitAuthor(name, email) {
114
160
  }
115
161
  async function readGitAuthor(dir) {
116
162
  const [name, email] = await Promise.all([
117
- git.getConfig({ fs, dir, path: "user.name" }).catch(() => {
163
+ git.getConfig({ fs: gitFs, dir, path: "user.name" }).catch(() => {
118
164
  return;
119
165
  }),
120
- git.getConfig({ fs, dir, path: "user.email" }).catch(() => {
166
+ git.getConfig({ fs: gitFs, dir, path: "user.email" }).catch(() => {
121
167
  return;
122
168
  })
123
169
  ]);
@@ -134,14 +180,14 @@ async function listWorkdirChanges(dir, cache = {}) {
134
180
  const adds = [];
135
181
  const removes = [];
136
182
  await git.walk({
137
- fs,
183
+ fs: gitFs,
138
184
  dir,
139
185
  cache,
140
186
  trees: [git.WORKDIR(), git.STAGE()],
141
187
  map: async (filepath, [workdir, stage]) => {
142
188
  if (filepath === ".")
143
189
  return;
144
- if (!stage && workdir && await git.isIgnored({ fs, dir, filepath })) {
190
+ if (!stage && workdir && (filepath.startsWith(".git-damaged") || await git.isIgnored({ fs: gitFs, dir, filepath }))) {
145
191
  return null;
146
192
  }
147
193
  const [wType, sType] = await Promise.all([
@@ -165,7 +211,7 @@ async function listWorkdirChanges(dir, cache = {}) {
165
211
  if (workdirOid !== stageOid) {
166
212
  adds.push(filepath);
167
213
  } else {
168
- const fileBytes = await fs.promises.readFile(path2.join(dir, filepath));
214
+ const fileBytes = await gitFs.promises.readFile(path2.join(dir, filepath));
169
215
  const { oid: actualOid } = await git.hashBlob({ object: fileBytes });
170
216
  if (actualOid !== stageOid)
171
217
  adds.push(filepath);
@@ -178,10 +224,10 @@ async function listWorkdirChanges(dir, cache = {}) {
178
224
  }
179
225
  async function stageChanges(dir, changes, cache) {
180
226
  if (changes.adds.length > 0) {
181
- await git.add({ fs, dir, cache, filepath: changes.adds });
227
+ await git.add({ fs: gitFs, dir, cache, filepath: changes.adds });
182
228
  }
183
229
  for (const filepath of changes.removes) {
184
- await git.remove({ fs, dir, cache, filepath });
230
+ await git.remove({ fs: gitFs, dir, cache, filepath });
185
231
  }
186
232
  }
187
233
  async function hasPendingChanges(dir, cache = {}) {
@@ -196,13 +242,13 @@ async function hasUncommittedChanges(dir, cache = {}) {
196
242
  async function stageMatchesHead(dir, cache) {
197
243
  let headOid;
198
244
  try {
199
- headOid = await git.resolveRef({ fs, dir, ref: "HEAD" });
245
+ headOid = await git.resolveRef({ fs: gitFs, dir, ref: "HEAD" });
200
246
  } catch {
201
247
  return false;
202
248
  }
203
249
  let differs = false;
204
250
  await git.walk({
205
- fs,
251
+ fs: gitFs,
206
252
  dir,
207
253
  cache,
208
254
  trees: [git.TREE({ ref: headOid }), git.STAGE()],
@@ -244,10 +290,10 @@ class LocalFolderSourceProvider {
244
290
  }
245
291
  return withRepoLock(dir, async () => {
246
292
  const cache = {};
247
- await git.init({ fs, dir, defaultBranch: DEFAULT_BRANCH });
293
+ await git.init({ fs: gitFs, dir, defaultBranch: DEFAULT_BRANCH });
248
294
  await stageChanges(dir, await listWorkdirChanges(dir, cache), cache);
249
295
  await git.commit({
250
- fs,
296
+ fs: gitFs,
251
297
  dir,
252
298
  cache,
253
299
  message: options.initialMessage?.trim() || "Created project",
@@ -316,7 +362,7 @@ class LocalGitSourceProvider {
316
362
  let commits;
317
363
  try {
318
364
  commits = await git.log({
319
- fs,
365
+ fs: gitFs,
320
366
  dir,
321
367
  cache: {},
322
368
  depth: limit + 2,
@@ -353,7 +399,7 @@ class LocalGitSourceProvider {
353
399
  }
354
400
  async restoreUnlocked(options) {
355
401
  await git.checkout({
356
- fs,
402
+ fs: gitFs,
357
403
  dir: this.dir,
358
404
  cache: {},
359
405
  ref: options.id,
@@ -365,9 +411,9 @@ class LocalGitSourceProvider {
365
411
  async function snapshotWorkingTreeUnlocked(options) {
366
412
  const dir = options.repoRoot ?? options.projectDir;
367
413
  const logger = options.logFile ? createFileLogger(options.logFile, "snapshot") : noopLogger;
368
- const cache = {};
414
+ const cache = options.cache ?? {};
369
415
  const stagingMarker = snapshotStagingMarkerPath(dir);
370
- const staleStaging = fs.existsSync(stagingMarker);
416
+ const staleStaging = gitFs.existsSync(stagingMarker);
371
417
  const changes = await listWorkdirChanges(dir, cache);
372
418
  const workdirClean = changes.adds.length === 0 && changes.removes.length === 0;
373
419
  if (workdirClean && !staleStaging) {
@@ -376,8 +422,8 @@ async function snapshotWorkingTreeUnlocked(options) {
376
422
  }
377
423
  if (workdirClean && staleStaging && await stageMatchesHead(dir, cache)) {
378
424
  logger.debug("snapshot", "stale marker outlived a completed commit — clearing, not recommitting");
379
- fs.rmSync(stagingMarker, { force: true });
380
- const [head2] = await git.log({ fs, dir, cache, depth: 1 });
425
+ gitFs.rmSync(stagingMarker, { force: true });
426
+ const [head2] = await git.log({ fs: gitFs, dir, cache, depth: 1 });
381
427
  return {
382
428
  id: head2.oid,
383
429
  message: head2.commit.message.trim(),
@@ -390,18 +436,18 @@ async function snapshotWorkingTreeUnlocked(options) {
390
436
  removes: changes.removes.length,
391
437
  ...staleStaging ? { recoveredStaleStaging: true } : {}
392
438
  });
393
- fs.writeFileSync(stagingMarker, "");
439
+ gitFs.writeFileSync(stagingMarker, "");
394
440
  await stageChanges(dir, changes, cache);
395
441
  const author = await resolveGitAuthor(dir, options.authorName, options.authorEmail);
396
442
  const id = await git.commit({
397
- fs,
443
+ fs: gitFs,
398
444
  dir,
399
445
  cache,
400
446
  message: options.message,
401
447
  author
402
448
  });
403
- fs.rmSync(stagingMarker, { force: true });
404
- const [head] = await git.log({ fs, dir, cache, depth: 1 });
449
+ gitFs.rmSync(stagingMarker, { force: true });
450
+ const [head] = await git.log({ fs: gitFs, dir, cache, depth: 1 });
405
451
  return {
406
452
  id,
407
453
  message: options.message,
@@ -458,4 +504,4 @@ async function restoreVersionWithBackup(options) {
458
504
  });
459
505
  }
460
506
 
461
- export { resolveLogger, gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup };
507
+ export { gitScopeFor, HISTORY_PAGE_LIMIT, withRepoLock, __repoLockQueueSizeForTests, resolveGitAuthor, listWorkdirChanges, stageChanges, hasPendingChanges, hasUncommittedChanges, snapshotWorkingTreeUnlocked, isNoChangesError, providerFor, gitDirFor, snapshotStagingMarkerPath, RESTORE_BACKUP_MESSAGE, AUTO_SNAPSHOT_MESSAGE, restoreVersionWithBackup };
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  UsageError,
7
7
  package_default,
8
8
  rejectUnknownFlags
9
- } from "./cli-149edp6b.js";
9
+ } from "./cli-dx6sxj2t.js";
10
10
  import {
11
11
  EXIT_CODES
12
12
  } from "./cli-46ycxe6r.js";
@@ -18,17 +18,16 @@ import {
18
18
  import { defineCommand, parseArgs, runMain } from "citty";
19
19
  import { statSync } from "node:fs";
20
20
  var SUBCOMMANDS = {
21
- new: () => import("./new-hvq0x91q.js").then((m) => m.default),
22
- preview: () => import("./preview-d4s6gk6p.js").then((m) => m.default),
23
- build: () => import("./build-6r502chw.js").then((m) => m.default),
24
- publish: () => import("./publish-tkc26en7.js").then((m) => m.default),
25
- lint: () => import("./lint-p2sw53d9.js").then((m) => m.default),
26
- validate: () => import("./validate-w9vfefrw.js").then((m) => m.default),
27
- audit: () => import("./audit-cvarpa72.js").then((m) => m.default),
28
- preflight: () => import("./preflight-4j00yd0g.js").then((m) => m.default),
29
- repair: () => import("./repair-2va4w12t.js").then((m) => m.default),
30
- doctor: () => import("./doctor-akvxbtjb.js").then((m) => m.default),
31
- plugin: () => import("./plugin-pssmk0dx.js").then((m) => m.default)
21
+ new: () => import("./new-4cdzfbsj.js").then((m) => m.default),
22
+ preview: () => import("./preview-k8n2kew7.js").then((m) => m.default),
23
+ build: () => import("./build-kdaet3pd.js").then((m) => m.default),
24
+ publish: () => import("./publish-jnhjp2vd.js").then((m) => m.default),
25
+ lint: () => import("./lint-p6a4bkvh.js").then((m) => m.default),
26
+ validate: () => import("./validate-prnybpkx.js").then((m) => m.default),
27
+ audit: () => import("./audit-7a37g51p.js").then((m) => m.default),
28
+ preflight: () => import("./preflight-r4y3f8f9.js").then((m) => m.default),
29
+ doctor: () => import("./doctor-vajd5h45.js").then((m) => m.default),
30
+ plugin: () => import("./plugin-a89tqspy.js").then((m) => m.default)
32
31
  };
33
32
  var VERSION = package_default.version;
34
33
  var main = defineCommand({
@@ -53,7 +52,7 @@ async function preflightRequiredInvocations(rawArgs) {
53
52
  const [command, ...commandArgs] = rawArgs;
54
53
  try {
55
54
  if (command === "new") {
56
- const { newArgs } = await import("./new-hvq0x91q.js");
55
+ const { newArgs } = await import("./new-4cdzfbsj.js");
57
56
  rejectUnknownFlags(commandArgs, newArgs, "new");
58
57
  const parsed2 = parseArgs(commandArgs, {
59
58
  ...newArgs,
@@ -65,7 +64,7 @@ async function preflightRequiredInvocations(rawArgs) {
65
64
  return;
66
65
  }
67
66
  if (command === "preflight") {
68
- const { preflightArgs } = await import("./preflight-4j00yd0g.js");
67
+ const { preflightArgs } = await import("./preflight-r4y3f8f9.js");
69
68
  rejectUnknownFlags(commandArgs, preflightArgs, "preflight");
70
69
  const parsed2 = parseArgs(commandArgs, {
71
70
  ...preflightArgs,
@@ -89,7 +88,7 @@ async function preflightRequiredInvocations(rawArgs) {
89
88
  if (subcommand !== "add") {
90
89
  throw new UsageError(`gutterpress plugin: unknown command "${subcommand}"`);
91
90
  }
92
- const { pluginAddArgs } = await import("./plugin-pssmk0dx.js");
91
+ const { pluginAddArgs } = await import("./plugin-a89tqspy.js");
93
92
  rejectUnknownFlags(subcommandArgs, pluginAddArgs, "plugin add");
94
93
  const parsed = parseArgs(subcommandArgs, {
95
94
  ...pluginAddArgs,
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  getSystemDiagnostics,
3
3
  log
4
- } from "./cli-cqtggsng.js";
4
+ } from "./cli-mcb484g3.js";
5
5
  import {
6
6
  UsageError,
7
7
  rejectExtraPositionals,
8
8
  rejectUnknownFlags
9
- } from "./cli-149edp6b.js";
9
+ } from "./cli-dx6sxj2t.js";
10
10
  import"./cli-c41yr7he.js";
11
11
  import"./cli-46ycxe6r.js";
12
12
  import"./cli-37x76zdn.js";
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  build
3
- } from "./index-wq3r5pj7.js";
3
+ } from "./index-kvgq4q3q.js";
4
4
  import {
5
5
  BuildError,
6
6
  RENDER_TIMEOUT_MS,
7
7
  assertMilestone,
8
8
  connectChromium,
9
9
  getBrowser
10
- } from "./index-ycpvr0am.js";
10
+ } from "./index-b2rqw41a.js";
11
11
  import"./index-37x76zdn.js";
12
12
 
13
13
  // src/lib/engine.ts
@@ -4,7 +4,7 @@ import {
4
4
  build,
5
5
  connectChromium,
6
6
  getBrowser
7
- } from "./cli-zfcryxg8.js";
7
+ } from "./cli-ak1tagkr.js";
8
8
  import"./cli-c41yr7he.js";
9
9
  import {
10
10
  BuildError
@@ -29,11 +29,11 @@
29
29
  pageRangeOf: () => pageRangeOf,
30
30
  pageOf: () => pageOf,
31
31
  measure: () => measure,
32
+ makeOverflowFragmentable: () => makeOverflowFragmentable,
32
33
  loadStyleSources: () => loadStyleSources,
33
34
  injectViewerCss: () => injectViewerCss,
34
35
  injectBreakMapping: () => injectBreakMapping,
35
36
  fragmentDocument: () => fragmentDocument,
36
- forcedColumnBreaksSupported: () => forcedColumnBreaksSupported,
37
37
  contentEdgeRect: () => contentEdgeRect,
38
38
  compensateTrailingMarginsBeforeAvoids: () => compensateTrailingMarginsBeforeAvoids,
39
39
  compensateRepeatedHeaders: () => compensateRepeatedHeaders,
@@ -1048,15 +1048,10 @@
1048
1048
  doc.getElementById("gp-break-mapping")?.remove();
1049
1049
  return "";
1050
1050
  }
1051
- function forcedColumnBreaksSupported() {
1052
- return typeof CSS !== "undefined" && typeof CSS.supports === "function" && CSS.supports("break-before", "column") && CSS.supports("break-after", "column");
1053
- }
1054
1051
  var FRAGMENT_EPSILON_PX = 1;
1055
1052
  function contentEdgeRect(site, atEnd) {
1056
1053
  const rects = Array.from(site.getClientRects());
1057
- const solid = rects.filter((r) => r.height >= FRAGMENT_EPSILON_PX);
1058
- const pool = solid.length ? solid : rects;
1059
- return atEnd ? pool.at(-1) : pool[0];
1054
+ return atEnd ? rects.at(-1) : rects[0];
1060
1055
  }
1061
1056
  function columnReserve(offset, columnHeight) {
1062
1057
  const remaining = columnHeight - offset;
@@ -1116,13 +1111,12 @@
1116
1111
  continue;
1117
1112
  const stripTop = strip.getBoundingClientRect().top;
1118
1113
  const edge = prop === "break-after" ? rect.bottom : rect.top;
1119
- const reserve = columnReserve((edge - stripTop) / cssZoomOf(strip), strip.clientHeight);
1120
- if (reserve === null)
1114
+ if (columnReserve((edge - stripTop) / cssZoomOf(strip), strip.clientHeight) === null)
1121
1115
  continue;
1122
1116
  const spacer = document.createElement("div");
1123
1117
  spacer.className = "gp-column-break-spacer";
1124
1118
  spacer.setAttribute("aria-hidden", "true");
1125
- spacer.style.cssText = `height:${reserve}px;margin:0;padding:0;border:0;`;
1119
+ spacer.style.cssText = `${prop}: column; height:0; margin:0; padding:0; border:0;`;
1126
1120
  if (prop === "break-after")
1127
1121
  el.after(spacer);
1128
1122
  else
@@ -1280,6 +1274,47 @@
1280
1274
  delete el.dataset.gpLeadingPageRootDisplayPriority;
1281
1275
  }
1282
1276
  }
1277
+ var SCROLLABLE = /^(auto|scroll|hidden)$/;
1278
+ function makeOverflowFragmentable(strips) {
1279
+ const todo = [];
1280
+ for (const strip of strips) {
1281
+ for (const el of Array.from(strip.el.querySelectorAll("*"))) {
1282
+ const cs = getComputedStyle(el);
1283
+ const x = SCROLLABLE.test(cs.overflowX);
1284
+ const y = SCROLLABLE.test(cs.overflowY);
1285
+ if (x || y)
1286
+ todo.push({ el, x, y });
1287
+ }
1288
+ }
1289
+ for (const { el, x, y } of todo) {
1290
+ el.dataset.gpOverflow = "clipped";
1291
+ el.dataset.gpOverflowX = el.style.getPropertyValue("overflow-x");
1292
+ el.dataset.gpOverflowY = el.style.getPropertyValue("overflow-y");
1293
+ el.dataset.gpOverflowXPriority = el.style.getPropertyPriority("overflow-x");
1294
+ el.dataset.gpOverflowYPriority = el.style.getPropertyPriority("overflow-y");
1295
+ if (x)
1296
+ el.style.setProperty("overflow-x", "clip");
1297
+ if (y)
1298
+ el.style.setProperty("overflow-y", "clip");
1299
+ }
1300
+ }
1301
+ function restoreScrollContainers(doc = document) {
1302
+ for (const el of Array.from(doc.querySelectorAll('[data-gp-overflow="clipped"]'))) {
1303
+ for (const axis of ["x", "y"]) {
1304
+ const value = axis === "x" ? el.dataset.gpOverflowX : el.dataset.gpOverflowY;
1305
+ const priority = axis === "x" ? el.dataset.gpOverflowXPriority : el.dataset.gpOverflowYPriority;
1306
+ if (value)
1307
+ el.style.setProperty(`overflow-${axis}`, value, priority || "");
1308
+ else
1309
+ el.style.removeProperty(`overflow-${axis}`);
1310
+ }
1311
+ delete el.dataset.gpOverflow;
1312
+ delete el.dataset.gpOverflowX;
1313
+ delete el.dataset.gpOverflowY;
1314
+ delete el.dataset.gpOverflowXPriority;
1315
+ delete el.dataset.gpOverflowYPriority;
1316
+ }
1317
+ }
1283
1318
  function compensateTrailingMarginsBeforeAvoids(model, strips) {
1284
1319
  const candidates = new Set;
1285
1320
  for (const decl of model.breaks) {
@@ -1555,11 +1590,15 @@
1555
1590
  for (const [i, site] of sites.entries()) {
1556
1591
  if (!plan[i])
1557
1592
  continue;
1558
- const spacer = document.createElement("div");
1559
- spacer.className = "gp-recto-spacer";
1560
- spacer.setAttribute("aria-hidden", "true");
1561
- spacer.style.cssText = "break-before: column; break-after: column; height: 0; margin: 0; padding: 0; border: 0;";
1562
- site.el.before(spacer);
1593
+ const leading = site.el.previousElementSibling;
1594
+ const need = leading?.classList.contains("gp-column-break-spacer") ? 1 : 2;
1595
+ for (let n = 0;n < need; n++) {
1596
+ const spacer = document.createElement("div");
1597
+ spacer.className = "gp-recto-spacer";
1598
+ spacer.setAttribute("aria-hidden", "true");
1599
+ spacer.style.cssText = "break-before: column; height: 0; margin: 0; padding: 0; border: 0;";
1600
+ site.el.before(spacer);
1601
+ }
1563
1602
  inserted++;
1564
1603
  }
1565
1604
  return inserted;
@@ -1713,6 +1752,7 @@
1713
1752
  const authoring = [];
1714
1753
  const strips = buildStrips(model, opts, authoring);
1715
1754
  await layoutReady;
1755
+ makeOverflowFragmentable(strips);
1716
1756
  stabilizeFullHeightPageRoots(model, strips);
1717
1757
  compensateTrailingMarginsBeforeAvoids(model, strips);
1718
1758
  synthesizeColumnBreaks(model);
@@ -1735,12 +1775,14 @@
1735
1775
  relayout: () => {
1736
1776
  restoreFullHeightPageRoots();
1737
1777
  restoreTrailingMargins();
1778
+ restoreScrollContainers();
1738
1779
  unwrapStrips(strips);
1739
1780
  for (const spacer of Array.from(document.querySelectorAll(".gp-recto-spacer")))
1740
1781
  spacer.remove();
1741
1782
  const rebuilt = buildStrips(model, opts, authoring);
1742
1783
  strips.length = 0;
1743
1784
  strips.push(...rebuilt);
1785
+ makeOverflowFragmentable(strips);
1744
1786
  stabilizeFullHeightPageRoots(model, strips);
1745
1787
  compensateTrailingMarginsBeforeAvoids(model, strips);
1746
1788
  synthesizeColumnBreaks(model);