@davmash/bygone 0.8.6 → 0.8.8
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/CHANGELOG.md +11 -0
- package/README.md +6 -0
- package/cli/present.js +26 -0
- package/docs/present.md +32 -0
- package/docs/product-surface.md +1 -0
- package/media/webview.css +1 -1
- package/media/webview.js +36 -36
- package/out/standalone-main.js +316 -9
- package/out/standalone-preload.js +2 -0
- package/package.json +1 -1
- package/standalone/index.html +13 -5
- package/web/index.html +41 -5
- package/web/presenter.css +136 -0
- package/web/web-host.js +5 -5
package/out/standalone-main.js
CHANGED
|
@@ -8772,6 +8772,20 @@ var require_present = __commonJS({
|
|
|
8772
8772
|
let presenterIndexTemplate;
|
|
8773
8773
|
const server = createServer((request, response) => {
|
|
8774
8774
|
const requestUrl = new URL(request.url || "/", "http://127.0.0.1");
|
|
8775
|
+
if (requestUrl.pathname === "/narration/claim") {
|
|
8776
|
+
if (request.method !== "POST") {
|
|
8777
|
+
respond(response, 405, "Method not allowed");
|
|
8778
|
+
return;
|
|
8779
|
+
}
|
|
8780
|
+
if (!isSameOriginLoopbackRequest(request)) {
|
|
8781
|
+
respond(response, 403, "Forbidden");
|
|
8782
|
+
return;
|
|
8783
|
+
}
|
|
8784
|
+
options.onNarrationClaim?.();
|
|
8785
|
+
response.writeHead(204, { "Cache-Control": "no-store" });
|
|
8786
|
+
response.end();
|
|
8787
|
+
return;
|
|
8788
|
+
}
|
|
8775
8789
|
if (requestUrl.pathname === "/tour.json") {
|
|
8776
8790
|
response.writeHead(200, {
|
|
8777
8791
|
"Content-Type": "application/json; charset=utf-8",
|
|
@@ -8897,6 +8911,17 @@ var require_present = __commonJS({
|
|
|
8897
8911
|
}
|
|
8898
8912
|
response.end(message);
|
|
8899
8913
|
}
|
|
8914
|
+
function isSameOriginLoopbackRequest(request) {
|
|
8915
|
+
const origin = request.headers.origin;
|
|
8916
|
+
const host = request.headers.host;
|
|
8917
|
+
if (typeof origin !== "string" || typeof host !== "string") return false;
|
|
8918
|
+
try {
|
|
8919
|
+
const parsed = new URL(origin);
|
|
8920
|
+
return parsed.protocol === "http:" && parsed.hostname === "127.0.0.1" && parsed.host === host;
|
|
8921
|
+
} catch {
|
|
8922
|
+
return false;
|
|
8923
|
+
}
|
|
8924
|
+
}
|
|
8900
8925
|
function escapeHtml(text) {
|
|
8901
8926
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
8902
8927
|
}
|
|
@@ -8951,6 +8976,116 @@ var require_launchArgs = __commonJS({
|
|
|
8951
8976
|
}
|
|
8952
8977
|
});
|
|
8953
8978
|
|
|
8979
|
+
// standalone/windowState.js
|
|
8980
|
+
var require_windowState = __commonJS({
|
|
8981
|
+
"standalone/windowState.js"(exports2, module2) {
|
|
8982
|
+
"use strict";
|
|
8983
|
+
var fs8 = require("fs");
|
|
8984
|
+
var path9 = require("path");
|
|
8985
|
+
var WINDOW_STATE_VERSION = 1;
|
|
8986
|
+
function readWindowState2(filePath) {
|
|
8987
|
+
try {
|
|
8988
|
+
return normalizeWindowState(JSON.parse(fs8.readFileSync(filePath, "utf8")));
|
|
8989
|
+
} catch {
|
|
8990
|
+
return null;
|
|
8991
|
+
}
|
|
8992
|
+
}
|
|
8993
|
+
function writeWindowState2(filePath, state) {
|
|
8994
|
+
const normalized = normalizeWindowState(state);
|
|
8995
|
+
if (!normalized) {
|
|
8996
|
+
throw new Error("Cannot save invalid Bygone window state.");
|
|
8997
|
+
}
|
|
8998
|
+
fs8.mkdirSync(path9.dirname(filePath), { recursive: true });
|
|
8999
|
+
const temporaryPath = `${filePath}.${process.pid}.tmp`;
|
|
9000
|
+
try {
|
|
9001
|
+
fs8.writeFileSync(temporaryPath, `${JSON.stringify(normalized, null, 2)}
|
|
9002
|
+
`, "utf8");
|
|
9003
|
+
fs8.renameSync(temporaryPath, filePath);
|
|
9004
|
+
} finally {
|
|
9005
|
+
try {
|
|
9006
|
+
fs8.unlinkSync(temporaryPath);
|
|
9007
|
+
} catch {
|
|
9008
|
+
}
|
|
9009
|
+
}
|
|
9010
|
+
}
|
|
9011
|
+
function normalizeWindowState(value) {
|
|
9012
|
+
if (!value || typeof value !== "object" || value.version !== WINDOW_STATE_VERSION) {
|
|
9013
|
+
return null;
|
|
9014
|
+
}
|
|
9015
|
+
const mainSource = value.main === null ? null : normalizeSessionSource(value.main?.source);
|
|
9016
|
+
if (value.main !== null && !mainSource) {
|
|
9017
|
+
return null;
|
|
9018
|
+
}
|
|
9019
|
+
if (!Array.isArray(value.tours)) {
|
|
9020
|
+
return null;
|
|
9021
|
+
}
|
|
9022
|
+
const tours = value.tours.map(normalizeTourLaunch).filter(Boolean);
|
|
9023
|
+
if (tours.length !== value.tours.length) {
|
|
9024
|
+
return null;
|
|
9025
|
+
}
|
|
9026
|
+
return {
|
|
9027
|
+
version: WINDOW_STATE_VERSION,
|
|
9028
|
+
main: mainSource ? { source: mainSource } : null,
|
|
9029
|
+
tours
|
|
9030
|
+
};
|
|
9031
|
+
}
|
|
9032
|
+
function normalizeSessionSource(source) {
|
|
9033
|
+
if (!source || typeof source !== "object" || typeof source.kind !== "string") {
|
|
9034
|
+
return null;
|
|
9035
|
+
}
|
|
9036
|
+
if (source.kind === "blank") {
|
|
9037
|
+
return { kind: "blank" };
|
|
9038
|
+
}
|
|
9039
|
+
if (source.kind === "files" || source.kind === "directories") {
|
|
9040
|
+
if (!isStringArray(source.paths) || source.paths.length === 0) return null;
|
|
9041
|
+
return {
|
|
9042
|
+
kind: source.kind,
|
|
9043
|
+
paths: [...source.paths],
|
|
9044
|
+
...source.kind === "directories" && isStringArray(source.labels) ? { labels: [...source.labels] } : {}
|
|
9045
|
+
};
|
|
9046
|
+
}
|
|
9047
|
+
if (source.kind === "file-history" || source.kind === "directory-history") {
|
|
9048
|
+
if (typeof source.path !== "string" || source.path.length === 0) return null;
|
|
9049
|
+
return {
|
|
9050
|
+
kind: source.kind,
|
|
9051
|
+
path: source.path,
|
|
9052
|
+
includeStaged: Boolean(source.includeStaged),
|
|
9053
|
+
skipUnchanged: Boolean(source.skipUnchanged)
|
|
9054
|
+
};
|
|
9055
|
+
}
|
|
9056
|
+
if (source.kind === "git-refs") {
|
|
9057
|
+
if (typeof source.repoRoot !== "string" || !isStringArray(source.refs) || source.refs.length < 2) return null;
|
|
9058
|
+
return { kind: source.kind, repoRoot: source.repoRoot, refs: [...source.refs] };
|
|
9059
|
+
}
|
|
9060
|
+
if (source.kind === "branch-review") {
|
|
9061
|
+
if (typeof source.repoRoot !== "string" || typeof source.headRef !== "string") return null;
|
|
9062
|
+
return {
|
|
9063
|
+
kind: source.kind,
|
|
9064
|
+
repoRoot: source.repoRoot,
|
|
9065
|
+
headRef: source.headRef,
|
|
9066
|
+
...typeof source.baseRef === "string" ? { baseRef: source.baseRef } : {}
|
|
9067
|
+
};
|
|
9068
|
+
}
|
|
9069
|
+
return null;
|
|
9070
|
+
}
|
|
9071
|
+
function normalizeTourLaunch(value) {
|
|
9072
|
+
if (!value || typeof value !== "object" || !isStringArray(value.args) || typeof value.cwd !== "string") {
|
|
9073
|
+
return null;
|
|
9074
|
+
}
|
|
9075
|
+
return { args: [...value.args], cwd: value.cwd };
|
|
9076
|
+
}
|
|
9077
|
+
function isStringArray(value) {
|
|
9078
|
+
return Array.isArray(value) && value.every((item) => typeof item === "string");
|
|
9079
|
+
}
|
|
9080
|
+
module2.exports = {
|
|
9081
|
+
WINDOW_STATE_VERSION,
|
|
9082
|
+
normalizeWindowState,
|
|
9083
|
+
readWindowState: readWindowState2,
|
|
9084
|
+
writeWindowState: writeWindowState2
|
|
9085
|
+
};
|
|
9086
|
+
}
|
|
9087
|
+
});
|
|
9088
|
+
|
|
8954
9089
|
// src/windowTitle.ts
|
|
8955
9090
|
var windowTitle_exports = {};
|
|
8956
9091
|
__export(windowTitle_exports, {
|
|
@@ -9075,7 +9210,7 @@ var require_package = __commonJS({
|
|
|
9075
9210
|
displayName: "Bygone",
|
|
9076
9211
|
desktopName: "com.davidmashburn.bygone.desktop",
|
|
9077
9212
|
description: "See how change happened. Visual diff and file history for VS Code.",
|
|
9078
|
-
version: "0.8.
|
|
9213
|
+
version: "0.8.8",
|
|
9079
9214
|
author: "David Mashburn",
|
|
9080
9215
|
license: "MIT",
|
|
9081
9216
|
private: false,
|
|
@@ -9263,7 +9398,7 @@ var require_package = __commonJS({
|
|
|
9263
9398
|
"icons:generate": "node ./scripts/generate-icons.mjs",
|
|
9264
9399
|
"package:vsix": "node ./scripts/check-vsix-contents.mjs && vsce package",
|
|
9265
9400
|
"standalone:start": "npm run compile && node ./scripts/run-electron.mjs ./out/standalone-main.js",
|
|
9266
|
-
"standalone:smoke": "npm run compile && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test-multi && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test-directory",
|
|
9401
|
+
"standalone:smoke": "npm run compile && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test-multi && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test-directory && node ./scripts/run-electron.mjs ./out/standalone-main.js --smoke-test-directory-history",
|
|
9267
9402
|
"walkthrough:refresh": "node ./scripts/refresh-walkthrough-screenshots.mjs",
|
|
9268
9403
|
"web:start": "npm run compile && node ./scripts/web-server.mjs",
|
|
9269
9404
|
"package:desktop": "npm run package:desktop:mac",
|
|
@@ -22324,6 +22459,7 @@ var { tokenMatches, tokensFor } = require_commandSpec();
|
|
|
22324
22459
|
var { startPresentation } = require_present();
|
|
22325
22460
|
var { resolveWorkingDirectory } = require_workingDirectory();
|
|
22326
22461
|
var { getCliArgsFromArgv, getForwardedLaunchArgs } = require_launchArgs();
|
|
22462
|
+
var { readWindowState, writeWindowState } = require_windowState();
|
|
22327
22463
|
var {
|
|
22328
22464
|
buildHistoryTitle: buildHistoryTitle2,
|
|
22329
22465
|
buildStandaloneSessionTitle: buildStandaloneSessionTitle2,
|
|
@@ -22343,13 +22479,15 @@ var parsedDirectoryHistoryCacheSize = Number.parseInt(process.env.BYGONE_DIR_HIS
|
|
|
22343
22479
|
var DIRECTORY_HISTORY_CACHE_SIZE = Number.isFinite(parsedDirectoryHistoryCacheSize) && parsedDirectoryHistoryCacheSize > 0 ? parsedDirectoryHistoryCacheSize : DEFAULT_DIRECTORY_HISTORY_CACHE_SIZE;
|
|
22344
22480
|
var commandLineToolPath = process.platform === "win32" ? path8.join(process.env.LOCALAPPDATA || os.homedir(), "Microsoft", "WindowsApps", "bygone.cmd") : "/usr/local/bin/bygone";
|
|
22345
22481
|
var gitHistoryService = new GitHistoryService2();
|
|
22346
|
-
var
|
|
22347
|
-
var
|
|
22482
|
+
var initialCliArgs = getCliArgs();
|
|
22483
|
+
var launchArguments = parseLaunchArgs(initialCliArgs);
|
|
22484
|
+
var smokeTestMode = launchArguments.kind === "smoke" || launchArguments.kind === "smoke-multi" || launchArguments.kind === "smoke-directory" || launchArguments.kind === "smoke-directory-history";
|
|
22348
22485
|
var captureOutputPath = launchArguments.capturePath ? path8.resolve(launchArguments.capturePath) : null;
|
|
22349
22486
|
var captureMode = Boolean(captureOutputPath);
|
|
22350
22487
|
var launchWindowWidth = Number.isFinite(launchArguments.windowWidth) ? launchArguments.windowWidth : 1500;
|
|
22351
22488
|
var launchWindowHeight = Number.isFinite(launchArguments.windowHeight) ? launchArguments.windowHeight : 960;
|
|
22352
22489
|
var shouldUseSingleInstanceLock = app.isPackaged && !smokeTestMode && !captureMode;
|
|
22490
|
+
var shouldRestoreWindowState = initialCliArgs.length === 0 && !smokeTestMode && !captureMode;
|
|
22353
22491
|
app.setName(APP_NAME);
|
|
22354
22492
|
if (typeof app.setAppUserModelId === "function") {
|
|
22355
22493
|
app.setAppUserModelId("com.davidmashburn.bygone");
|
|
@@ -22365,6 +22503,7 @@ var closingForSave = false;
|
|
|
22365
22503
|
var fileWatchers = [];
|
|
22366
22504
|
var session = createEmptySession();
|
|
22367
22505
|
var smokeTimeout;
|
|
22506
|
+
var directoryHistorySmokeDrilldownStarted = false;
|
|
22368
22507
|
var pendingOpenPaths = [];
|
|
22369
22508
|
var historyIncludeStagedPreference = false;
|
|
22370
22509
|
var historySkipUnchangedPreference = false;
|
|
@@ -22383,6 +22522,8 @@ var wordWrapEnabled = false;
|
|
|
22383
22522
|
var wordWrapAvailable = false;
|
|
22384
22523
|
var repositorySearch = null;
|
|
22385
22524
|
var lastRepositoryReplacement = null;
|
|
22525
|
+
var appIsQuitting = false;
|
|
22526
|
+
var restoringWindowState = false;
|
|
22386
22527
|
if (!singleInstanceLock) {
|
|
22387
22528
|
app.quit();
|
|
22388
22529
|
}
|
|
@@ -22399,6 +22540,10 @@ app.on("window-all-closed", () => {
|
|
|
22399
22540
|
app.quit();
|
|
22400
22541
|
}
|
|
22401
22542
|
});
|
|
22543
|
+
app.on("before-quit", () => {
|
|
22544
|
+
appIsQuitting = true;
|
|
22545
|
+
persistOpenWindowState();
|
|
22546
|
+
});
|
|
22402
22547
|
app.on("will-quit", () => {
|
|
22403
22548
|
repositorySearch?.handle?.cancel();
|
|
22404
22549
|
for (const server of [...activeTourServers]) {
|
|
@@ -22548,6 +22693,9 @@ function createMainWindow({ show = !smokeTestMode } = {}) {
|
|
|
22548
22693
|
smokeTimeout = void 0;
|
|
22549
22694
|
captureScheduled = false;
|
|
22550
22695
|
captureRenderReady = false;
|
|
22696
|
+
if (!appIsQuitting && (process.platform === "darwin" || BrowserWindow.getAllWindows().length > 0)) {
|
|
22697
|
+
persistOpenWindowState();
|
|
22698
|
+
}
|
|
22551
22699
|
});
|
|
22552
22700
|
}
|
|
22553
22701
|
function ensureMainWindow() {
|
|
@@ -22557,13 +22705,18 @@ function ensureMainWindow() {
|
|
|
22557
22705
|
}
|
|
22558
22706
|
}
|
|
22559
22707
|
async function openTourPresentation(args, cwd) {
|
|
22708
|
+
let ownerWindow = null;
|
|
22560
22709
|
const presentation = await startPresentation(args, cwd, packageRoot, {
|
|
22561
22710
|
announce: false,
|
|
22562
|
-
open: false
|
|
22711
|
+
open: false,
|
|
22712
|
+
onNarrationClaim: () => claimTourNarration(ownerWindow)
|
|
22563
22713
|
});
|
|
22564
22714
|
activeTourServers.add(presentation.server);
|
|
22565
22715
|
try {
|
|
22566
|
-
await showTourWindow(presentation.url, presentation.server, presentation.manifest
|
|
22716
|
+
ownerWindow = await showTourWindow(presentation.url, presentation.server, presentation.manifest, {
|
|
22717
|
+
args: [...args],
|
|
22718
|
+
cwd: path8.resolve(cwd)
|
|
22719
|
+
});
|
|
22567
22720
|
} catch (error) {
|
|
22568
22721
|
closeTourServer(presentation.server);
|
|
22569
22722
|
throw error;
|
|
@@ -22573,7 +22726,7 @@ async function openAuthoredTourDocument(sourcePath) {
|
|
|
22573
22726
|
const document2 = discoverAuthoredTourDocument2(sourcePath);
|
|
22574
22727
|
await openTourPresentation(["--tour", document2.documentPath], document2.repoRoot);
|
|
22575
22728
|
}
|
|
22576
|
-
async function showTourWindow(url, server, manifest) {
|
|
22729
|
+
async function showTourWindow(url, server, manifest, launch) {
|
|
22577
22730
|
const parsedUrl = new URL(url);
|
|
22578
22731
|
if (parsedUrl.protocol !== "http:" || parsedUrl.hostname !== "127.0.0.1") {
|
|
22579
22732
|
throw new Error("Tour presenter URL must use the local Bygone server.");
|
|
@@ -22595,7 +22748,8 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22595
22748
|
}
|
|
22596
22749
|
});
|
|
22597
22750
|
latestTourWindow = tourWindow;
|
|
22598
|
-
tourPresentations.set(tourWindow, { server, origin: tourOrigin });
|
|
22751
|
+
tourPresentations.set(tourWindow, { server, origin: tourOrigin, launch });
|
|
22752
|
+
installApplicationMenu();
|
|
22599
22753
|
tourWindow.webContents.setWindowOpenHandler(({ url: externalUrl }) => {
|
|
22600
22754
|
if (/^https?:\/\//i.test(externalUrl)) {
|
|
22601
22755
|
void shell.openExternal(externalUrl);
|
|
@@ -22622,6 +22776,10 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22622
22776
|
if (latestTourWindow === tourWindow) {
|
|
22623
22777
|
latestTourWindow = getLatestTourWindow();
|
|
22624
22778
|
}
|
|
22779
|
+
installApplicationMenu();
|
|
22780
|
+
if (!appIsQuitting && (process.platform === "darwin" || BrowserWindow.getAllWindows().length > 0)) {
|
|
22781
|
+
persistOpenWindowState();
|
|
22782
|
+
}
|
|
22625
22783
|
});
|
|
22626
22784
|
const tourWindowTitle = buildTourWindowTitle2(manifest, APP_NAME);
|
|
22627
22785
|
const applyTourWindowTitle = () => {
|
|
@@ -22643,11 +22801,30 @@ async function showTourWindow(url, server, manifest) {
|
|
|
22643
22801
|
applyTourWindowTitle();
|
|
22644
22802
|
tourWindow.show();
|
|
22645
22803
|
tourWindow.focus();
|
|
22804
|
+
persistOpenWindowState();
|
|
22646
22805
|
return tourWindow;
|
|
22647
22806
|
}
|
|
22648
22807
|
function getLatestTourWindow() {
|
|
22649
22808
|
return [...tourPresentations.keys()].reverse().find((window2) => !window2.isDestroyed());
|
|
22650
22809
|
}
|
|
22810
|
+
function claimTourNarration(ownerWindow) {
|
|
22811
|
+
if (!ownerWindow || ownerWindow.isDestroyed()) return;
|
|
22812
|
+
for (const tourWindow of tourPresentations.keys()) {
|
|
22813
|
+
if (tourWindow !== ownerWindow && !tourWindow.isDestroyed()) {
|
|
22814
|
+
dispatchTourPresenterCommand(tourWindow, "pauseNarration");
|
|
22815
|
+
}
|
|
22816
|
+
}
|
|
22817
|
+
}
|
|
22818
|
+
function dispatchTourPresenterCommand(tourWindow, command) {
|
|
22819
|
+
if (!tourWindow || tourWindow.isDestroyed()) return;
|
|
22820
|
+
const script = `window.dispatchEvent(new CustomEvent('bygone:tour-command', { detail: ${JSON.stringify(command)} }))`;
|
|
22821
|
+
void tourWindow.webContents.executeJavaScript(script).catch(() => {
|
|
22822
|
+
});
|
|
22823
|
+
}
|
|
22824
|
+
function toggleLatestTourNarration() {
|
|
22825
|
+
const tourWindow = getLatestTourWindow();
|
|
22826
|
+
if (tourWindow) dispatchTourPresenterCommand(tourWindow, "toggleNarration");
|
|
22827
|
+
}
|
|
22651
22828
|
function closeTourServer(server) {
|
|
22652
22829
|
if (!server || !activeTourServers.delete(server)) {
|
|
22653
22830
|
return;
|
|
@@ -22962,6 +23139,12 @@ ${HELP_URL}`,
|
|
|
22962
23139
|
click: () => {
|
|
22963
23140
|
void openAuthoredTourDialog().catch((error) => showError(`Could not open Bygone presentation: ${getErrorMessage(error)}`));
|
|
22964
23141
|
}
|
|
23142
|
+
},
|
|
23143
|
+
{ type: "separator" },
|
|
23144
|
+
{
|
|
23145
|
+
label: "Listen to Tour",
|
|
23146
|
+
enabled: Boolean(getLatestTourWindow()),
|
|
23147
|
+
click: toggleLatestTourNarration
|
|
22965
23148
|
}
|
|
22966
23149
|
]
|
|
22967
23150
|
},
|
|
@@ -23320,8 +23503,73 @@ async function openInitialLaunchTarget() {
|
|
|
23320
23503
|
await routePendingOpenPaths();
|
|
23321
23504
|
return;
|
|
23322
23505
|
}
|
|
23506
|
+
if (shouldRestoreWindowState && await restoreOpenWindowState()) {
|
|
23507
|
+
return;
|
|
23508
|
+
}
|
|
23323
23509
|
await routeLaunchTarget(launchArguments);
|
|
23324
23510
|
}
|
|
23511
|
+
async function restoreOpenWindowState() {
|
|
23512
|
+
const savedState = readWindowState(getWindowStatePath());
|
|
23513
|
+
if (!savedState || !savedState.main && savedState.tours.length === 0) {
|
|
23514
|
+
return false;
|
|
23515
|
+
}
|
|
23516
|
+
let restoredAnyWindow = false;
|
|
23517
|
+
restoringWindowState = true;
|
|
23518
|
+
try {
|
|
23519
|
+
if (savedState.main) {
|
|
23520
|
+
ensureMainWindow();
|
|
23521
|
+
try {
|
|
23522
|
+
await restoreMainSession(savedState.main.source);
|
|
23523
|
+
} catch (error) {
|
|
23524
|
+
console.error(`Could not restore the previous Bygone session: ${getErrorMessage(error)}`);
|
|
23525
|
+
await openBlankDiff();
|
|
23526
|
+
}
|
|
23527
|
+
restoredAnyWindow = true;
|
|
23528
|
+
}
|
|
23529
|
+
for (const tour of savedState.tours) {
|
|
23530
|
+
try {
|
|
23531
|
+
await openTourPresentation(tour.args, tour.cwd);
|
|
23532
|
+
restoredAnyWindow = true;
|
|
23533
|
+
} catch (error) {
|
|
23534
|
+
console.error(`Could not restore a previous Bygone tour: ${getErrorMessage(error)}`);
|
|
23535
|
+
}
|
|
23536
|
+
}
|
|
23537
|
+
} finally {
|
|
23538
|
+
restoringWindowState = false;
|
|
23539
|
+
persistOpenWindowState();
|
|
23540
|
+
}
|
|
23541
|
+
return restoredAnyWindow;
|
|
23542
|
+
}
|
|
23543
|
+
async function restoreMainSession(source) {
|
|
23544
|
+
if (source.kind === "blank") {
|
|
23545
|
+
await openBlankDiff();
|
|
23546
|
+
return;
|
|
23547
|
+
}
|
|
23548
|
+
session = buildSessionFromSource(source);
|
|
23549
|
+
historyIncludeStagedPreference = Boolean(source.includeStaged ?? historyIncludeStagedPreference);
|
|
23550
|
+
historySkipUnchangedPreference = Boolean(source.skipUnchanged ?? historySkipUnchangedPreference);
|
|
23551
|
+
clearWatchers();
|
|
23552
|
+
updateWatchers();
|
|
23553
|
+
await sendCurrentSession();
|
|
23554
|
+
}
|
|
23555
|
+
function persistOpenWindowState() {
|
|
23556
|
+
if (restoringWindowState || !app.isReady()) return;
|
|
23557
|
+
const hasMainWindow = Boolean(mainWindow && !mainWindow.isDestroyed());
|
|
23558
|
+
const mainSource = hasMainWindow && (isRefreshableSource(session.source) || session.source?.kind === "blank") ? cloneSessionSource(session.source) : hasMainWindow ? { kind: "blank" } : null;
|
|
23559
|
+
const tours = [...tourPresentations.entries()].filter(([window2, presentation]) => !window2.isDestroyed() && presentation.launch).map(([, presentation]) => presentation.launch);
|
|
23560
|
+
try {
|
|
23561
|
+
writeWindowState(getWindowStatePath(), {
|
|
23562
|
+
version: 1,
|
|
23563
|
+
main: mainSource ? { source: mainSource } : null,
|
|
23564
|
+
tours
|
|
23565
|
+
});
|
|
23566
|
+
} catch (error) {
|
|
23567
|
+
console.error(`Could not save Bygone window state: ${getErrorMessage(error)}`);
|
|
23568
|
+
}
|
|
23569
|
+
}
|
|
23570
|
+
function getWindowStatePath() {
|
|
23571
|
+
return path8.join(app.getPath("userData"), "open-windows.json");
|
|
23572
|
+
}
|
|
23325
23573
|
async function routeLaunchTarget(launchTarget) {
|
|
23326
23574
|
if (launchTarget.kind === "unsupported-launch-intent") {
|
|
23327
23575
|
ensureMainWindow();
|
|
@@ -23397,6 +23645,10 @@ async function routeLaunchTarget(launchTarget) {
|
|
|
23397
23645
|
}
|
|
23398
23646
|
if (launchTarget.kind === "smoke-directory") {
|
|
23399
23647
|
await compareDirectoryTestFiles();
|
|
23648
|
+
return;
|
|
23649
|
+
}
|
|
23650
|
+
if (launchTarget.kind === "smoke-directory-history") {
|
|
23651
|
+
await compareDirectoryHistoryTestFiles();
|
|
23400
23652
|
}
|
|
23401
23653
|
}
|
|
23402
23654
|
function sourceForLaunchTarget(launchTarget) {
|
|
@@ -23535,6 +23787,9 @@ function parseLaunchArgs(args) {
|
|
|
23535
23787
|
if (filteredArgs[0] === "--smoke-test-directory") {
|
|
23536
23788
|
return { kind: "smoke-directory", capturePath, windowWidth, windowHeight };
|
|
23537
23789
|
}
|
|
23790
|
+
if (filteredArgs[0] === "--smoke-test-directory-history") {
|
|
23791
|
+
return { kind: "smoke-directory-history", capturePath, windowWidth, windowHeight };
|
|
23792
|
+
}
|
|
23538
23793
|
if (filteredArgs.length >= 1 && !filteredArgs[0].startsWith("--")) {
|
|
23539
23794
|
const resolvedPaths = filteredArgs.map((candidate) => resolveLaunchPath(candidate, cwd));
|
|
23540
23795
|
const tourSelection = classifyAuthoredTourPaths2(resolvedPaths);
|
|
@@ -24481,6 +24736,9 @@ async function sendCurrentDirectoryHistoryEntry() {
|
|
|
24481
24736
|
canReturnToDirectory: true
|
|
24482
24737
|
});
|
|
24483
24738
|
refreshSessionWindowTitle();
|
|
24739
|
+
if (launchArguments.kind === "smoke-directory-history") {
|
|
24740
|
+
pollDirectoryHistoryDrilldownSmoke();
|
|
24741
|
+
}
|
|
24484
24742
|
scheduleCaptureIfNeeded();
|
|
24485
24743
|
return;
|
|
24486
24744
|
}
|
|
@@ -24505,6 +24763,12 @@ async function sendCurrentDirectoryHistoryEntry() {
|
|
|
24505
24763
|
canMutate: true
|
|
24506
24764
|
});
|
|
24507
24765
|
refreshSessionWindowTitle();
|
|
24766
|
+
if (launchArguments.kind === "smoke-directory-history" && !directoryHistorySmokeDrilldownStarted && mainWindow && !mainWindow.isDestroyed()) {
|
|
24767
|
+
directoryHistorySmokeDrilldownStarted = true;
|
|
24768
|
+
setTimeout(() => {
|
|
24769
|
+
void mainWindow.webContents.executeJavaScript(`document.querySelector('.dir-entry[data-is-dir="false"]')?.click()`);
|
|
24770
|
+
}, 250);
|
|
24771
|
+
}
|
|
24508
24772
|
scheduleCaptureIfNeeded();
|
|
24509
24773
|
}
|
|
24510
24774
|
function buildDirectoryHistoryViewState(dirHistory, entry) {
|
|
@@ -25682,6 +25946,10 @@ async function sendCurrentMultiDiff() {
|
|
|
25682
25946
|
fileInfo: document.getElementById('file-info')?.textContent,
|
|
25683
25947
|
panelCount: document.querySelectorAll('.multi-pane').length,
|
|
25684
25948
|
gutterCount: document.querySelectorAll('.multi-gutter').length,
|
|
25949
|
+
changePosition: document.getElementById('change-position')?.textContent,
|
|
25950
|
+
panelPositions: [...document.querySelectorAll('.multi-pane-position')].map((element) => element.textContent),
|
|
25951
|
+
decoratedLineCount: document.querySelectorAll('.bygone-paired-line, .bygone-one-sided-line').length,
|
|
25952
|
+
diffWorkerUrl: window.__BYGONE_HOST__?.diffWorkerUrl,
|
|
25685
25953
|
activeDiffCount: document.querySelectorAll('.bygone-active-diff').length,
|
|
25686
25954
|
adjacentEdgeCount: document.querySelectorAll('.bygone-paired-edge-left, .bygone-one-sided-edge-left').length,
|
|
25687
25955
|
inlineAdjacentEdgeCount: document.querySelectorAll('.view-line span.bygone-paired-edge-left, .view-line span.bygone-one-sided-edge-left').length
|
|
@@ -25780,6 +26048,44 @@ async function compareDirectoryTestFiles() {
|
|
|
25780
26048
|
fs7.writeFileSync(path8.join(right, "b.txt"), "right b\n", "utf8");
|
|
25781
26049
|
await openDirectories([left, right], { source: { kind: "synthetic" } });
|
|
25782
26050
|
}
|
|
26051
|
+
async function compareDirectoryHistoryTestFiles() {
|
|
26052
|
+
const root = fs7.mkdtempSync(path8.join(os.tmpdir(), "bygone-directory-history-smoke-"));
|
|
26053
|
+
const filePath = path8.join(root, "history-smoke.js");
|
|
26054
|
+
runGit(["init"], root);
|
|
26055
|
+
runGit(["config", "user.name", "Bygone Smoke Test"], root);
|
|
26056
|
+
runGit(["config", "user.email", "bygone-smoke@example.invalid"], root);
|
|
26057
|
+
fs7.writeFileSync(filePath, "const alpha = 1;\nconst stable = true;\n", "utf8");
|
|
26058
|
+
runGit(["add", "history-smoke.js"], root);
|
|
26059
|
+
runGit(["commit", "-m", "initial"], root);
|
|
26060
|
+
fs7.writeFileSync(filePath, "const alpha = 2;\nconst stable = false;\n", "utf8");
|
|
26061
|
+
runGit(["add", "history-smoke.js"], root);
|
|
26062
|
+
runGit(["commit", "-m", "change history smoke fixture"], root);
|
|
26063
|
+
await openDirectoryHistory(root, false, { skipConfirm: true, source: { kind: "synthetic" } });
|
|
26064
|
+
}
|
|
26065
|
+
function pollDirectoryHistoryDrilldownSmoke() {
|
|
26066
|
+
if (!mainWindow || mainWindow.isDestroyed()) {
|
|
26067
|
+
return;
|
|
26068
|
+
}
|
|
26069
|
+
void mainWindow.webContents.executeJavaScript(`(() => ({
|
|
26070
|
+
directoryHistoryDrilldown: true,
|
|
26071
|
+
fileInfo: document.getElementById('file-info')?.textContent,
|
|
26072
|
+
changePosition: document.getElementById('change-position')?.textContent,
|
|
26073
|
+
panelPositions: [...document.querySelectorAll('.multi-pane-position')].map((element) => element.textContent),
|
|
26074
|
+
decoratedLineCount: document.querySelectorAll('.bygone-paired-line, .bygone-one-sided-line').length,
|
|
26075
|
+
diffWorkerUrl: window.__BYGONE_HOST__?.diffWorkerUrl
|
|
26076
|
+
}))()`).then((snapshot) => {
|
|
26077
|
+
const ready = /^1 \/ [1-9]\d*$/.test(snapshot.changePosition) && snapshot.panelPositions.some((position) => /^1 \/ [1-9]\d*$/.test(position)) && snapshot.decoratedLineCount > 0;
|
|
26078
|
+
if (ready) {
|
|
26079
|
+
finalizeSmokeTest(snapshot);
|
|
26080
|
+
return;
|
|
26081
|
+
}
|
|
26082
|
+
setTimeout(pollDirectoryHistoryDrilldownSmoke, 100);
|
|
26083
|
+
}).catch((error) => {
|
|
26084
|
+
console.error(`Bygone directory history smoke test failed: ${getErrorMessage(error)}`);
|
|
26085
|
+
process.exitCode = 1;
|
|
26086
|
+
app.exit(1);
|
|
26087
|
+
});
|
|
26088
|
+
}
|
|
25783
26089
|
async function sendCurrentDiff() {
|
|
25784
26090
|
if (session.mode !== "diff") {
|
|
25785
26091
|
return;
|
|
@@ -26928,6 +27234,7 @@ async function refreshSession(options = {}) {
|
|
|
26928
27234
|
function postOrQueue(message) {
|
|
26929
27235
|
installApplicationMenu();
|
|
26930
27236
|
if (message && typeof message === "object" && typeof message.type === "string" && message.type.startsWith("show")) {
|
|
27237
|
+
persistOpenWindowState();
|
|
26931
27238
|
if (!refreshInProgress) {
|
|
26932
27239
|
refreshFailure = null;
|
|
26933
27240
|
}
|
|
@@ -27150,7 +27457,7 @@ function shellQuote(value) {
|
|
|
27150
27457
|
function finalizeSmokeTest(snapshot) {
|
|
27151
27458
|
clearTimeout(smokeTimeout);
|
|
27152
27459
|
smokeTimeout = void 0;
|
|
27153
|
-
const passed = Boolean(snapshot && (snapshot.fileInfo === "Comparing test-file-1.js and test-file-2.js" && snapshot.file1 === "test-file-1.js" && snapshot.file2 === "test-file-2.js" && /^1 \/ \d+$/.test(snapshot.changePosition) && snapshot.pairedLineCount > 0 && snapshot.oneSidedLineCount > 0 && snapshot.inlineHighlightCount > 0 && snapshot.activeDiffCount === 0 && isVisibleBackground(snapshot.pairedLineBackground) && isVisibleBackground(snapshot.inlineHighlightBackground) && snapshot.pairedLineBackground !== snapshot.inlineHighlightBackground || snapshot.fileInfo === `Comparing ${snapshot.panelCount} files` && snapshot.panelCount >= 2 && snapshot.gutterCount === snapshot.panelCount - 1 && snapshot.activeDiffCount === 0 && snapshot.adjacentEdgeCount === 0 && snapshot.inlineAdjacentEdgeCount === 0 || snapshot.directoryRailVisible === true && snapshot.directoryRailItemCount === 2 && snapshot.directoryReturnVisible === true && snapshot.directorySidebarToggleVisible === true && snapshot.directorySidebarToggleWorked === true && snapshot.nextFileEnabled === true));
|
|
27460
|
+
const passed = Boolean(snapshot && (snapshot.fileInfo === "Comparing test-file-1.js and test-file-2.js" && snapshot.file1 === "test-file-1.js" && snapshot.file2 === "test-file-2.js" && /^1 \/ \d+$/.test(snapshot.changePosition) && snapshot.pairedLineCount > 0 && snapshot.oneSidedLineCount > 0 && snapshot.inlineHighlightCount > 0 && snapshot.activeDiffCount === 0 && isVisibleBackground(snapshot.pairedLineBackground) && isVisibleBackground(snapshot.inlineHighlightBackground) && snapshot.pairedLineBackground !== snapshot.inlineHighlightBackground || snapshot.fileInfo === `Comparing ${snapshot.panelCount} files` && snapshot.panelCount >= 2 && snapshot.gutterCount === snapshot.panelCount - 1 && /^1 \/ [1-9]\d*$/.test(snapshot.changePosition) && snapshot.panelPositions.some((position) => /^1 \/ [1-9]\d*$/.test(position)) && snapshot.decoratedLineCount > 0 && /\/media\/diff\.worker\.js$/.test(snapshot.diffWorkerUrl) && snapshot.activeDiffCount === 0 && snapshot.adjacentEdgeCount === 0 && snapshot.inlineAdjacentEdgeCount === 0 || snapshot.directoryRailVisible === true && snapshot.directoryRailItemCount === 2 && snapshot.directoryReturnVisible === true && snapshot.directorySidebarToggleVisible === true && snapshot.directorySidebarToggleWorked === true && snapshot.nextFileEnabled === true || snapshot.directoryHistoryDrilldown === true && snapshot.fileInfo === "Comparing 2 files" && /^1 \/ [1-9]\d*$/.test(snapshot.changePosition) && snapshot.panelPositions.some((position) => /^1 \/ [1-9]\d*$/.test(position)) && snapshot.decoratedLineCount > 0 && /\/media\/diff\.worker\.js$/.test(snapshot.diffWorkerUrl)));
|
|
27154
27461
|
if (!passed) {
|
|
27155
27462
|
console.error(`Bygone smoke test failed: unexpected diff DOM snapshot ${JSON.stringify(snapshot)}`);
|
|
27156
27463
|
process.exitCode = 1;
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// standalone/preload.js
|
|
4
4
|
var { contextBridge, ipcRenderer, webUtils } = require("electron");
|
|
5
5
|
var editorWorkerUrl = new URL("../media/editor.worker.js", window.location.href).toString();
|
|
6
|
+
var diffWorkerUrl = new URL("../media/diff.worker.js", window.location.href).toString();
|
|
6
7
|
ipcRenderer.on("bygone:host-message", (_event, payload) => {
|
|
7
8
|
window.postMessage({
|
|
8
9
|
__bygoneHostMessage: payload
|
|
@@ -11,6 +12,7 @@ ipcRenderer.on("bygone:host-message", (_event, payload) => {
|
|
|
11
12
|
contextBridge.exposeInMainWorld("__BYGONE_HOST__", {
|
|
12
13
|
environment: "standalone",
|
|
13
14
|
editorWorkerUrl,
|
|
15
|
+
diffWorkerUrl,
|
|
14
16
|
getPathForFile(file) {
|
|
15
17
|
return webUtils.getPathForFile(file);
|
|
16
18
|
},
|
package/package.json
CHANGED
package/standalone/index.html
CHANGED
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
<div id="change-toolbar" class="change-toolbar header-align-diff" hidden>
|
|
31
31
|
<div class="change-toolbar-main">
|
|
32
32
|
<div class="change-toolbar-nav">
|
|
33
|
-
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" aria-label="Previous file">
|
|
33
|
+
<button id="previous-file" class="change-button icon-button" type="button" title="Open previous file" data-tooltip="Open previous file" aria-label="Previous file">
|
|
34
34
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
35
35
|
<path d="M17 11l-5-5-5 5"></path>
|
|
36
36
|
<path d="M17 18l-5-5-5 5" opacity="0.7"></path>
|
|
37
37
|
</svg>
|
|
38
38
|
</button>
|
|
39
|
-
<button id="next-file" class="change-button change-button-primary icon-button" type="button" title="Open next file" aria-label="Next file">
|
|
39
|
+
<button id="next-file" class="change-button change-button-primary icon-button" type="button" title="Open next file" data-tooltip="Open next file" aria-label="Next file">
|
|
40
40
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
41
41
|
<path d="M7 13l5 5 5-5"></path>
|
|
42
42
|
<path d="M7 6l5 5 5-5" opacity="0.7"></path>
|
|
@@ -72,8 +72,15 @@
|
|
|
72
72
|
</svg>
|
|
73
73
|
</button>
|
|
74
74
|
</div>
|
|
75
|
+
<div class="change-toolbar-actions">
|
|
75
76
|
<button id="toggle-word-wrap" class="change-button icon-button" type="button" title="Enable line wrapping (Alt+Z)" aria-label="Enable line wrapping" aria-pressed="false" hidden>
|
|
76
|
-
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
77
|
+
<svg class="word-wrap-icon-off" viewBox="0 0 24 24" aria-hidden="true">
|
|
78
|
+
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
79
|
+
<path d="M12 9l-3 3 3 3"></path>
|
|
80
|
+
<path d="M4 18h8"></path>
|
|
81
|
+
<path d="M5 4l14 16"></path>
|
|
82
|
+
</svg>
|
|
83
|
+
<svg class="word-wrap-icon-on" viewBox="0 0 24 24" aria-hidden="true">
|
|
77
84
|
<path d="M4 6h13a3 3 0 0 1 0 6H9"></path>
|
|
78
85
|
<path d="M12 9l-3 3 3 3"></path>
|
|
79
86
|
<path d="M4 18h8"></path>
|
|
@@ -85,6 +92,7 @@
|
|
|
85
92
|
<path d="M20 5v6h-6"></path>
|
|
86
93
|
</svg>
|
|
87
94
|
</button>
|
|
95
|
+
</div>
|
|
88
96
|
</div>
|
|
89
97
|
<div class="change-hint">F7 / Shift+F7 · Cmd/Ctrl+Shift+Up/Down to jump.</div>
|
|
90
98
|
</div>
|
|
@@ -94,14 +102,14 @@
|
|
|
94
102
|
<div id="history-left-time" class="history-time"></div>
|
|
95
103
|
</div>
|
|
96
104
|
<div class="history-nav">
|
|
97
|
-
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit (Alt+Left)" aria-label="Older commit">
|
|
105
|
+
<button id="history-back" class="history-button icon-button" type="button" title="Open older commit (Alt+Left)" data-tooltip="Open older commit" aria-label="Older commit">
|
|
98
106
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
99
107
|
<path d="M15 18l-6-6 6-6"></path>
|
|
100
108
|
<path d="M10 18l-6-6 6-6" opacity="0.7"></path>
|
|
101
109
|
</svg>
|
|
102
110
|
</button>
|
|
103
111
|
<div id="history-position" class="history-position" role="status" aria-live="polite" aria-atomic="true"></div>
|
|
104
|
-
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit (Alt+Right)" aria-label="Newer commit">
|
|
112
|
+
<button id="history-forward" class="history-button icon-button" type="button" title="Open newer commit (Alt+Right)" data-tooltip="Open newer commit" aria-label="Newer commit">
|
|
105
113
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
106
114
|
<path d="M9 18l6-6-6-6"></path>
|
|
107
115
|
<path d="M14 18l6-6-6-6" opacity="0.7"></path>
|