xtralab 0.15.0 → 0.15.2
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 +65 -30
- package/lib/about/icons.d.ts +0 -5
- package/lib/about/icons.js +0 -5
- package/lib/about/index.d.ts +4 -8
- package/lib/about/index.js +6 -17
- package/lib/agentSessions.d.ts +9 -29
- package/lib/agentSessions.js +2 -7
- package/lib/askAgent/editorSelection.d.ts +20 -26
- package/lib/askAgent/editorSelection.js +11 -26
- package/lib/askAgent/icons.d.ts +2 -3
- package/lib/askAgent/icons.js +2 -3
- package/lib/askAgent/index.d.ts +4 -26
- package/lib/askAgent/index.js +54 -158
- package/lib/askAgent/popup.d.ts +12 -16
- package/lib/askAgent/popup.js +18 -37
- package/lib/askAgent/prompt.d.ts +3 -5
- package/lib/askAgent/prompt.js +6 -19
- package/lib/askAgent/queue.d.ts +11 -21
- package/lib/askAgent/queue.js +9 -19
- package/lib/askAgent/queuePanel.d.ts +13 -18
- package/lib/askAgent/queuePanel.js +15 -37
- package/lib/askAgent/targetPicker.d.ts +2 -9
- package/lib/askAgent/targetPicker.js +6 -11
- package/lib/askAgent/tokens.d.ts +32 -46
- package/lib/askAgent/tokens.js +4 -6
- package/lib/commandBar/index.d.ts +4 -13
- package/lib/commandBar/index.js +21 -39
- package/lib/customPanel/index.js +15 -0
- package/lib/editorBreadcrumbs/index.d.ts +3 -6
- package/lib/editorBreadcrumbs/index.js +10 -6
- package/lib/editorBreadcrumbs/widget.d.ts +17 -4
- package/lib/editorBreadcrumbs/widget.js +11 -17
- package/lib/editorIndent/index.d.ts +4 -12
- package/lib/editorIndent/index.js +8 -23
- package/lib/fileBrowser/commands.d.ts +29 -19
- package/lib/fileBrowser/commands.js +83 -97
- package/lib/fileBrowser/contents.d.ts +3 -0
- package/lib/fileBrowser/dragAndDrop.d.ts +17 -4
- package/lib/fileBrowser/dragAndDrop.js +2 -7
- package/lib/fileBrowser/fileBrowser.d.ts +19 -9
- package/lib/fileBrowser/fileBrowser.js +70 -222
- package/lib/fileBrowser/gitStatus.d.ts +16 -10
- package/lib/fileBrowser/gitStatus.js +31 -30
- package/lib/fileBrowser/gitignore.d.ts +4 -17
- package/lib/fileBrowser/gitignore.js +4 -25
- package/lib/fileBrowser/icons.d.ts +7 -17
- package/lib/fileBrowser/icons.js +25 -80
- package/lib/fileBrowser/index.js +2 -4
- package/lib/fileBrowser/widget.d.ts +141 -48
- package/lib/fileBrowser/widget.js +102 -4
- package/lib/fileTypeIcons/index.js +0 -10
- package/lib/git/api.d.ts +5 -13
- package/lib/git/api.js +10 -36
- package/lib/git/askRequest.d.ts +4 -8
- package/lib/git/askRequest.js +6 -20
- package/lib/git/commands.d.ts +45 -5
- package/lib/git/commands.js +20 -13
- package/lib/git/diffModel.js +4 -0
- package/lib/git/diffPreferences.d.ts +90 -0
- package/lib/git/diffPreferences.js +107 -0
- package/lib/git/diffProvider.js +10 -2
- package/lib/git/diffSurface.d.ts +64 -63
- package/lib/git/diffSurface.js +72 -213
- package/lib/git/diffTheme.d.ts +7 -0
- package/lib/git/diffTheme.js +23 -0
- package/lib/git/diffWidget.d.ts +70 -14
- package/lib/git/diffWidget.js +100 -94
- package/lib/git/imageDiff.d.ts +14 -6
- package/lib/git/imageDiff.js +19 -75
- package/lib/git/index.d.ts +0 -3
- package/lib/git/index.js +44 -10
- package/lib/git/notebookDiff.d.ts +110 -33
- package/lib/git/notebookDiff.js +55 -197
- package/lib/git/tokens.d.ts +73 -31
- package/lib/git/tokens.js +2 -3
- package/lib/highlight/index.d.ts +4 -10
- package/lib/highlight/index.js +10 -41
- package/lib/index.d.ts +0 -9
- package/lib/index.js +0 -9
- package/lib/launcher/agents.d.ts +55 -51
- package/lib/launcher/agents.js +15 -57
- package/lib/launcher/availability.d.ts +3 -9
- package/lib/launcher/availability.js +3 -9
- package/lib/launcher/commands.d.ts +7 -32
- package/lib/launcher/commands.js +14 -45
- package/lib/launcher/dashboard.d.ts +19 -24
- package/lib/launcher/dashboard.js +21 -67
- package/lib/launcher/editorRegistry.d.ts +10 -22
- package/lib/launcher/editorRegistry.js +14 -18
- package/lib/launcher/editors.d.ts +39 -45
- package/lib/launcher/editors.js +8 -34
- package/lib/launcher/icons.d.ts +0 -12
- package/lib/launcher/icons.js +5 -39
- package/lib/launcher/index.js +12 -55
- package/lib/launcher/invocation.d.ts +4 -10
- package/lib/launcher/invocation.js +7 -22
- package/lib/launcher/registry.d.ts +9 -7
- package/lib/launcher/registry.js +9 -7
- package/lib/launcher/tokens.d.ts +10 -22
- package/lib/launcher/tokens.js +5 -8
- package/lib/menuBar/index.d.ts +3 -10
- package/lib/menuBar/index.js +11 -28
- package/lib/menus/index.d.ts +3 -9
- package/lib/menus/index.js +14 -30
- package/lib/omnibox/files.d.ts +2 -4
- package/lib/omnibox/files.js +5 -11
- package/lib/omnibox/index.d.ts +4 -14
- package/lib/omnibox/index.js +9 -27
- package/lib/omnibox/model.d.ts +38 -10
- package/lib/omnibox/model.js +15 -33
- package/lib/omnibox/recents.d.ts +15 -17
- package/lib/omnibox/recents.js +12 -17
- package/lib/omnibox/tokens.d.ts +5 -10
- package/lib/omnibox/tokens.js +2 -6
- package/lib/omnibox/widget.d.ts +11 -7
- package/lib/omnibox/widget.js +8 -16
- package/lib/searchReplace/index.d.ts +4 -20
- package/lib/searchReplace/index.js +7 -27
- package/lib/showOutput/index.d.ts +3 -12
- package/lib/showOutput/index.js +6 -22
- package/lib/sidebar/index.d.ts +4 -7
- package/lib/sidebar/index.js +5 -12
- package/lib/terminalNotifications/index.d.ts +4 -10
- package/lib/terminalNotifications/index.js +6 -20
- package/lib/terminals/agentTerminals.d.ts +12 -5
- package/lib/terminals/agentTerminals.js +25 -44
- package/lib/terminals/detection.d.ts +4 -8
- package/lib/terminals/detection.js +4 -8
- package/lib/terminals/index.d.ts +0 -35
- package/lib/terminals/index.js +12 -101
- package/lib/terminals/model.d.ts +64 -139
- package/lib/terminals/model.js +80 -220
- package/lib/terminals/tokens.d.ts +11 -22
- package/lib/terminals/tokens.js +2 -2
- package/lib/terminals/widget.d.ts +43 -13
- package/lib/terminals/widget.js +33 -18
- package/lib/topBar/icons.d.ts +3 -8
- package/lib/topBar/icons.js +3 -8
- package/lib/topBar/index.d.ts +4 -11
- package/lib/topBar/index.js +10 -38
- package/lib/walkthrough/index.d.ts +4 -9
- package/lib/walkthrough/index.js +6 -20
- package/lib/walkthrough/panel.d.ts +40 -9
- package/lib/walkthrough/panel.js +4 -10
- package/package.json +5 -3
- package/schema/git-diff-preferences.json +42 -0
- package/src/about/icons.ts +0 -5
- package/src/about/index.tsx +6 -17
- package/src/agentSessions.ts +9 -29
- package/src/askAgent/editorSelection.ts +22 -29
- package/src/askAgent/icons.ts +2 -3
- package/src/askAgent/index.ts +54 -158
- package/src/askAgent/popup.tsx +23 -45
- package/src/askAgent/prompt.ts +6 -19
- package/src/askAgent/queue.ts +13 -24
- package/src/askAgent/queuePanel.tsx +21 -46
- package/src/askAgent/targetPicker.tsx +5 -15
- package/src/askAgent/tokens.ts +32 -46
- package/src/commandBar/index.ts +24 -39
- package/src/customPanel/index.ts +15 -0
- package/src/editorBreadcrumbs/index.ts +10 -6
- package/src/editorBreadcrumbs/widget.ts +23 -17
- package/src/editorIndent/index.ts +17 -23
- package/src/fileBrowser/commands.ts +119 -96
- package/src/fileBrowser/contents.ts +3 -0
- package/src/fileBrowser/dragAndDrop.ts +17 -7
- package/src/fileBrowser/fileBrowser.tsx +86 -230
- package/src/fileBrowser/gitStatus.ts +36 -33
- package/src/fileBrowser/gitignore.ts +4 -25
- package/src/fileBrowser/icons.ts +25 -80
- package/src/fileBrowser/index.ts +2 -4
- package/src/fileBrowser/widget.tsx +171 -50
- package/src/fileTypeIcons/index.ts +0 -10
- package/src/git/api.ts +10 -36
- package/src/git/askRequest.ts +6 -20
- package/src/git/commands.ts +83 -11
- package/src/git/diffModel.ts +25 -0
- package/src/git/diffPreferences.ts +192 -0
- package/src/git/diffProvider.tsx +11 -2
- package/src/git/diffSurface.tsx +165 -286
- package/src/git/diffTheme.ts +24 -0
- package/src/git/diffWidget.tsx +194 -134
- package/src/git/imageDiff.tsx +56 -84
- package/src/git/index.ts +54 -10
- package/src/git/notebookDiff.tsx +214 -240
- package/src/git/tokens.ts +73 -31
- package/src/highlight/index.ts +10 -41
- package/src/index.ts +0 -9
- package/src/launcher/agents.ts +64 -95
- package/src/launcher/availability.ts +3 -9
- package/src/launcher/commands.ts +14 -51
- package/src/launcher/dashboard.tsx +49 -88
- package/src/launcher/editorRegistry.ts +21 -29
- package/src/launcher/editors.ts +39 -58
- package/src/launcher/icons.ts +5 -39
- package/src/launcher/index.ts +12 -55
- package/src/launcher/invocation.ts +7 -22
- package/src/launcher/registry.ts +9 -7
- package/src/launcher/tokens.ts +10 -22
- package/src/menuBar/index.ts +11 -28
- package/src/menus/index.ts +14 -30
- package/src/omnibox/files.ts +10 -14
- package/src/omnibox/index.ts +9 -27
- package/src/omnibox/model.ts +50 -38
- package/src/omnibox/recents.ts +17 -22
- package/src/omnibox/tokens.ts +5 -10
- package/src/omnibox/widget.tsx +14 -19
- package/src/searchReplace/index.ts +7 -27
- package/src/showOutput/index.ts +6 -22
- package/src/sidebar/index.ts +20 -12
- package/src/terminalNotifications/index.ts +42 -25
- package/src/terminals/agentTerminals.ts +25 -49
- package/src/terminals/detection.ts +4 -8
- package/src/terminals/index.ts +12 -101
- package/src/terminals/model.ts +130 -246
- package/src/terminals/tokens.ts +11 -22
- package/src/terminals/widget.tsx +48 -31
- package/src/topBar/icons.ts +3 -8
- package/src/topBar/index.ts +21 -44
- package/src/walkthrough/index.ts +6 -20
- package/src/walkthrough/panel.ts +40 -10
- package/style/about.css +2 -7
- package/style/askAgent.css +8 -40
- package/style/base.css +9 -45
- package/style/chrome.css +108 -308
- package/style/commandBar.css +4 -20
- package/style/customPanel.css +1 -4
- package/style/git.css +26 -186
- package/style/highlight.css +1 -3
- package/style/launcher.css +6 -70
- package/style/omnibox.css +2 -14
- package/style/showOutput.css +0 -6
- package/style/sidebar.css +29 -9
- package/style/tabs.css +5 -13
- package/style/terminals.css +6 -53
- package/style/topBar.css +2 -22
- package/style/walkthrough.css +0 -8
package/src/git/imageDiff.tsx
CHANGED
|
@@ -2,23 +2,19 @@ import * as React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import type { TranslationBundle } from '@jupyterlab/translation';
|
|
4
4
|
|
|
5
|
+
import type { ImageDiffViewMode } from './diffPreferences';
|
|
6
|
+
|
|
5
7
|
/**
|
|
6
8
|
* xtralab's image diff, registered in place of `@jupyterlab/git:image-diff`.
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* for text. This module turns those strings into `<img>` elements and
|
|
11
|
-
* offers the 2-up / swipe / onion-skin comparison modes; no diffing library
|
|
12
|
-
* is involved (`@pierre/diffs` is text-only).
|
|
9
|
+
* Both sides arrive base64-encoded through the same `content()` getters used
|
|
10
|
+
* for text; the 2-up/swipe/onion views are hand-rolled (`@pierre/diffs` is
|
|
11
|
+
* text-only).
|
|
13
12
|
*/
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
* Raster
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* `.svg` is intentionally absent: it is XML text, so the `@pierre/diffs`
|
|
20
|
-
* text diff (the fallback provider) is more useful for it than an image
|
|
21
|
-
* comparison.
|
|
15
|
+
* Raster extensions mapped to the `data:image/<subtype>` MIME subtype.
|
|
16
|
+
* `.svg` is intentionally absent: it is XML text, so the fallback text diff
|
|
17
|
+
* is more useful than an image comparison.
|
|
22
18
|
*/
|
|
23
19
|
const IMAGE_DATA_TYPES: Record<string, string> = {
|
|
24
20
|
'.png': 'png',
|
|
@@ -30,9 +26,6 @@ const IMAGE_DATA_TYPES: Record<string, string> = {
|
|
|
30
26
|
'.ico': 'x-icon'
|
|
31
27
|
};
|
|
32
28
|
|
|
33
|
-
/**
|
|
34
|
-
* The file extensions registered as the xtralab image diff provider.
|
|
35
|
-
*/
|
|
36
29
|
export const IMAGE_DIFF_EXTENSIONS = Object.keys(IMAGE_DATA_TYPES);
|
|
37
30
|
|
|
38
31
|
/**
|
|
@@ -49,46 +42,14 @@ export function imageDataType(path: string): string | null {
|
|
|
49
42
|
}
|
|
50
43
|
|
|
51
44
|
/**
|
|
52
|
-
*
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const IMAGE_DIFF_VIEW_MODE_STORAGE_KEY = 'xtralab:image-diff-view-mode';
|
|
57
|
-
|
|
58
|
-
function readStoredImageViewMode(): ImageDiffViewMode {
|
|
59
|
-
try {
|
|
60
|
-
const raw = window.localStorage.getItem(IMAGE_DIFF_VIEW_MODE_STORAGE_KEY);
|
|
61
|
-
if (raw === '2-up' || raw === 'swipe' || raw === 'onion') {
|
|
62
|
-
return raw;
|
|
63
|
-
}
|
|
64
|
-
} catch {
|
|
65
|
-
// localStorage can throw in privacy/sandboxed contexts — 2-up is the
|
|
66
|
-
// sensible default anyway.
|
|
67
|
-
}
|
|
68
|
-
return '2-up';
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function writeStoredImageViewMode(mode: ImageDiffViewMode): void {
|
|
72
|
-
try {
|
|
73
|
-
window.localStorage.setItem(IMAGE_DIFF_VIEW_MODE_STORAGE_KEY, mode);
|
|
74
|
-
} catch {
|
|
75
|
-
// Best-effort.
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Strip whitespace from a base64 payload. Python's `base64.encodebytes`
|
|
81
|
-
* (used by the git server) inserts a newline every 76 characters; most
|
|
82
|
-
* browsers tolerate that inside a `data:` URL but some are stricter, and
|
|
83
|
-
* the cleaned length also lets us size the file accurately.
|
|
45
|
+
* Strip whitespace from a base64 payload: the server's `base64.encodebytes`
|
|
46
|
+
* inserts newlines some browsers reject in `data:` URLs, and the cleaned
|
|
47
|
+
* length sizes the file accurately.
|
|
84
48
|
*/
|
|
85
49
|
function cleanBase64(value: string): string {
|
|
86
50
|
return value.replace(/\s+/g, '');
|
|
87
51
|
}
|
|
88
52
|
|
|
89
|
-
/**
|
|
90
|
-
* Decoded byte length of a (whitespace-free) base64 string.
|
|
91
|
-
*/
|
|
92
53
|
function base64ByteLength(clean: string): number {
|
|
93
54
|
if (clean.length === 0) {
|
|
94
55
|
return 0;
|
|
@@ -111,13 +72,25 @@ function formatBytes(bytes: number): string {
|
|
|
111
72
|
return `${value.toFixed(value < 10 ? 1 : 0)} ${units[unit]}`;
|
|
112
73
|
}
|
|
113
74
|
|
|
75
|
+
/**
|
|
76
|
+
* One side of the image comparison, decoded from its base64 payload.
|
|
77
|
+
*/
|
|
114
78
|
interface IImageSide {
|
|
115
79
|
/**
|
|
116
80
|
* Cleaned base64 payload; empty string means the side does not exist.
|
|
117
81
|
*/
|
|
118
82
|
data: string;
|
|
83
|
+
/**
|
|
84
|
+
* Whether this side exists; added and deleted files lack one side.
|
|
85
|
+
*/
|
|
119
86
|
present: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* The `data:` URI for the image, or `null` when the side is absent.
|
|
89
|
+
*/
|
|
120
90
|
uri: string | null;
|
|
91
|
+
/**
|
|
92
|
+
* Decoded size of the payload in bytes.
|
|
93
|
+
*/
|
|
121
94
|
bytes: number;
|
|
122
95
|
}
|
|
123
96
|
|
|
@@ -132,6 +105,9 @@ function toSide(raw: string, fileType: string): IImageSide {
|
|
|
132
105
|
};
|
|
133
106
|
}
|
|
134
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Props for {@link ImageDiffView}.
|
|
110
|
+
*/
|
|
135
111
|
interface IImageDiffViewProps {
|
|
136
112
|
/**
|
|
137
113
|
* Base64 of the reference (old) revision; empty when added.
|
|
@@ -145,6 +121,14 @@ interface IImageDiffViewProps {
|
|
|
145
121
|
* MIME subtype from {@link imageDataType}.
|
|
146
122
|
*/
|
|
147
123
|
fileType: string;
|
|
124
|
+
/**
|
|
125
|
+
* The selected comparison mode (host-controlled).
|
|
126
|
+
*/
|
|
127
|
+
mode: ImageDiffViewMode;
|
|
128
|
+
/**
|
|
129
|
+
* Called when the user picks another comparison mode.
|
|
130
|
+
*/
|
|
131
|
+
onModeChange: (mode: ImageDiffViewMode) => void;
|
|
148
132
|
/**
|
|
149
133
|
* Translation bundle for user-facing strings.
|
|
150
134
|
*/
|
|
@@ -152,12 +136,11 @@ interface IImageDiffViewProps {
|
|
|
152
136
|
}
|
|
153
137
|
|
|
154
138
|
/**
|
|
155
|
-
* The image comparison surface: a
|
|
156
|
-
*
|
|
157
|
-
* plus the selected 2-up / swipe / onion-skin view.
|
|
139
|
+
* The image comparison surface: a mode selector (reusing the diff widget's
|
|
140
|
+
* segmented-control styling) plus the selected 2-up / swipe / onion view.
|
|
158
141
|
*/
|
|
159
142
|
export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
160
|
-
const { reference, challenger, fileType, trans } = props;
|
|
143
|
+
const { reference, challenger, fileType, mode, onModeChange, trans } = props;
|
|
161
144
|
const ref = React.useMemo(
|
|
162
145
|
() => toSide(reference, fileType),
|
|
163
146
|
[reference, fileType]
|
|
@@ -167,14 +150,6 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
167
150
|
[challenger, fileType]
|
|
168
151
|
);
|
|
169
152
|
|
|
170
|
-
const [mode, setMode] = React.useState<ImageDiffViewMode>(() =>
|
|
171
|
-
readStoredImageViewMode()
|
|
172
|
-
);
|
|
173
|
-
const changeMode = React.useCallback((next: ImageDiffViewMode) => {
|
|
174
|
-
setMode(next);
|
|
175
|
-
writeStoredImageViewMode(next);
|
|
176
|
-
}, []);
|
|
177
|
-
|
|
178
153
|
return (
|
|
179
154
|
<div className="jp-xtralab-ImageDiff">
|
|
180
155
|
<div className="jp-xtralab-ImageDiff-header">
|
|
@@ -197,7 +172,7 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
197
172
|
aria-selected={mode === value}
|
|
198
173
|
data-active={mode === value}
|
|
199
174
|
className="jp-xtralab-DiffWidget-segmentedButton"
|
|
200
|
-
onClick={() =>
|
|
175
|
+
onClick={() => onModeChange(value)}
|
|
201
176
|
>
|
|
202
177
|
{label}
|
|
203
178
|
</button>
|
|
@@ -217,9 +192,21 @@ export function ImageDiffView(props: IImageDiffViewProps): React.ReactElement {
|
|
|
217
192
|
);
|
|
218
193
|
}
|
|
219
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Props shared by the 2-up, swipe, and onion-skin views.
|
|
197
|
+
*/
|
|
220
198
|
interface ISideViewProps {
|
|
199
|
+
/**
|
|
200
|
+
* The reference (old) side.
|
|
201
|
+
*/
|
|
221
202
|
reference: IImageSide;
|
|
203
|
+
/**
|
|
204
|
+
* The challenger (new) side.
|
|
205
|
+
*/
|
|
222
206
|
challenger: IImageSide;
|
|
207
|
+
/**
|
|
208
|
+
* Translation bundle for user-facing strings.
|
|
209
|
+
*/
|
|
223
210
|
trans: TranslationBundle;
|
|
224
211
|
}
|
|
225
212
|
|
|
@@ -303,11 +290,6 @@ function TwoUp({
|
|
|
303
290
|
);
|
|
304
291
|
}
|
|
305
292
|
|
|
306
|
-
/**
|
|
307
|
-
* Range slider shared by the swipe and onion-skin views. A native
|
|
308
|
-
* `<input type="range">` (styled via CSS) keeps the bundle free of a UI
|
|
309
|
-
* component dependency.
|
|
310
|
-
*/
|
|
311
293
|
function RangeSlider(props: {
|
|
312
294
|
value: number;
|
|
313
295
|
onChange: (value: number) => void;
|
|
@@ -329,11 +311,9 @@ function RangeSlider(props: {
|
|
|
329
311
|
}
|
|
330
312
|
|
|
331
313
|
/**
|
|
332
|
-
* Fit
|
|
333
|
-
*
|
|
334
|
-
*
|
|
335
|
-
* `max-width/height: 100%; width/height: auto`. Returns the displayed pixel
|
|
336
|
-
* box, or `null` until both the image and the area have been measured.
|
|
314
|
+
* Fit an image inside an area without upscaling past its intrinsic size —
|
|
315
|
+
* the "contain, never enlarge" rule the other views get from CSS. Returns
|
|
316
|
+
* the displayed pixel box, or `null` until both sizes are measured.
|
|
337
317
|
*/
|
|
338
318
|
function containBox(
|
|
339
319
|
naturalWidth: number,
|
|
@@ -357,9 +337,6 @@ function containBox(
|
|
|
357
337
|
return { width: naturalWidth * scale, height: naturalHeight * scale };
|
|
358
338
|
}
|
|
359
339
|
|
|
360
|
-
/**
|
|
361
|
-
* Track an element's content-box size, kept current across layout changes.
|
|
362
|
-
*/
|
|
363
340
|
function useElementSize(): readonly [
|
|
364
341
|
React.RefObject<HTMLDivElement>,
|
|
365
342
|
{ width: number; height: number }
|
|
@@ -396,13 +373,9 @@ function Swipe({
|
|
|
396
373
|
const [areaRef, area] = useElementSize();
|
|
397
374
|
const frameRef = React.useRef<HTMLDivElement>(null);
|
|
398
375
|
|
|
399
|
-
//
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
// mapping (below) and each image's `clip-path` inset then all resolve
|
|
403
|
-
// against the same width, so the white line sits precisely on the seam
|
|
404
|
-
// between the two revisions at every position. A full-width frame instead
|
|
405
|
-
// let the line drift off the seam by as much as half the letterbox.
|
|
376
|
+
// Size the frame to the union box of both revisions so the divider %, the
|
|
377
|
+
// pointer mapping and the clip-paths all resolve against the same width;
|
|
378
|
+
// a full-width frame lets the line drift off the seam.
|
|
406
379
|
const naturalWidth = Math.max(refSize?.[0] ?? 0, challSize?.[0] ?? 0);
|
|
407
380
|
const naturalHeight = Math.max(refSize?.[1] ?? 0, challSize?.[1] ?? 0);
|
|
408
381
|
const box = containBox(naturalWidth, naturalHeight, area.width, area.height);
|
|
@@ -422,7 +395,6 @@ function Swipe({
|
|
|
422
395
|
|
|
423
396
|
const onPointerDown = React.useCallback(
|
|
424
397
|
(event: React.PointerEvent<HTMLDivElement>) => {
|
|
425
|
-
// Only react to the primary pointer (left click / touch / pen tip).
|
|
426
398
|
if (event.button !== 0) {
|
|
427
399
|
return;
|
|
428
400
|
}
|
package/src/git/index.ts
CHANGED
|
@@ -4,6 +4,8 @@ import {
|
|
|
4
4
|
} from '@jupyterlab/application';
|
|
5
5
|
import { IThemeManager, WidgetTracker } from '@jupyterlab/apputils';
|
|
6
6
|
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
|
|
7
|
+
import { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
8
|
+
import { IStateDB } from '@jupyterlab/statedb';
|
|
7
9
|
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
|
|
8
10
|
|
|
9
11
|
import { IAskAgent } from '../askAgent/tokens';
|
|
@@ -16,33 +18,76 @@ import {
|
|
|
16
18
|
pinnedDiffWidgetId,
|
|
17
19
|
registerGitCommands
|
|
18
20
|
} from './commands';
|
|
21
|
+
import { DiffPreferences, IDiffPreferences } from './diffPreferences';
|
|
19
22
|
import diffProviderPlugin from './diffProvider';
|
|
20
23
|
import { IFileChange } from './tokens';
|
|
21
24
|
|
|
22
25
|
const GIT_DIFF_COMMAND_PLUGIN_ID = 'xtralab:git-diff-command';
|
|
26
|
+
const GIT_DIFF_PREFERENCES_PLUGIN_ID = 'xtralab:git-diff-preferences';
|
|
23
27
|
const GIT_DIFF_TRACKER_NAMESPACE = 'xtralab-git-diff';
|
|
24
28
|
|
|
25
29
|
/**
|
|
26
|
-
* The launcher
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
* The display choices shared by the launcher diff and the Git panel diff.
|
|
31
|
+
*/
|
|
32
|
+
const diffPreferencesPlugin: JupyterFrontEndPlugin<IDiffPreferences> = {
|
|
33
|
+
id: GIT_DIFF_PREFERENCES_PLUGIN_ID,
|
|
34
|
+
description:
|
|
35
|
+
'Keeps the git diff display choices in the settings and the state database.',
|
|
36
|
+
autoStart: true,
|
|
37
|
+
provides: IDiffPreferences,
|
|
38
|
+
optional: [ISettingRegistry, IStateDB],
|
|
39
|
+
activate: (
|
|
40
|
+
app: JupyterFrontEnd,
|
|
41
|
+
settingRegistry: ISettingRegistry | null,
|
|
42
|
+
state: IStateDB | null
|
|
43
|
+
): IDiffPreferences => {
|
|
44
|
+
const preferences = new DiffPreferences();
|
|
45
|
+
if (settingRegistry !== null) {
|
|
46
|
+
settingRegistry
|
|
47
|
+
.load(GIT_DIFF_PREFERENCES_PLUGIN_ID)
|
|
48
|
+
.then(settings => preferences.connectSettings(settings))
|
|
49
|
+
.catch(reason => {
|
|
50
|
+
console.error(
|
|
51
|
+
`xtralab: failed to load settings for ${GIT_DIFF_PREFERENCES_PLUGIN_ID}`,
|
|
52
|
+
reason
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (state !== null) {
|
|
57
|
+
preferences.connectState(state).catch(reason => {
|
|
58
|
+
console.error('xtralab: failed to restore the diff split', reason);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return preferences;
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* The launcher's git diff command plugin. The upstream git panel stays
|
|
67
|
+
* enabled; this only adds `xtralab:git:open-diff` and preview/pinned-tab
|
|
68
|
+
* tracking.
|
|
30
69
|
*/
|
|
31
70
|
const diffCommandPlugin: JupyterFrontEndPlugin<void> = {
|
|
32
71
|
id: GIT_DIFF_COMMAND_PLUGIN_ID,
|
|
33
72
|
description:
|
|
34
73
|
"The launcher dashboard's side-by-side git diff command, powered by @pierre/diffs.",
|
|
35
74
|
autoStart: true,
|
|
36
|
-
optional: [
|
|
75
|
+
optional: [
|
|
76
|
+
IThemeManager,
|
|
77
|
+
IRenderMimeRegistry,
|
|
78
|
+
ITranslator,
|
|
79
|
+
IAskAgent,
|
|
80
|
+
IDiffPreferences
|
|
81
|
+
],
|
|
37
82
|
activate: (
|
|
38
83
|
app: JupyterFrontEnd,
|
|
39
84
|
themeManager: IThemeManager | null,
|
|
40
85
|
rendermime: IRenderMimeRegistry | null,
|
|
41
86
|
translator: ITranslator | null,
|
|
42
|
-
askAgent: IAskAgent | null
|
|
87
|
+
askAgent: IAskAgent | null,
|
|
88
|
+
preferences: IDiffPreferences | null
|
|
43
89
|
): void => {
|
|
44
90
|
const trans = (translator ?? nullTranslator).load('jupyterlab');
|
|
45
|
-
// Track open diffs so repeated opens reveal the existing tab.
|
|
46
91
|
const tracker = new WidgetTracker<DiffMainAreaWidget>({
|
|
47
92
|
namespace: GIT_DIFF_TRACKER_NAMESPACE
|
|
48
93
|
});
|
|
@@ -64,6 +109,7 @@ const diffCommandPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
64
109
|
contentsManager: app.serviceManager.contents,
|
|
65
110
|
rendermime,
|
|
66
111
|
askAgent,
|
|
112
|
+
preferences: preferences ?? new DiffPreferences(),
|
|
67
113
|
trans,
|
|
68
114
|
trackDiff: widget => tracker.add(widget),
|
|
69
115
|
onPinned: current => {
|
|
@@ -86,10 +132,8 @@ const diffCommandPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
86
132
|
}
|
|
87
133
|
};
|
|
88
134
|
|
|
89
|
-
/**
|
|
90
|
-
* Plugins contributed by xtralab's git integration.
|
|
91
|
-
*/
|
|
92
135
|
const plugins: JupyterFrontEndPlugin<unknown>[] = [
|
|
136
|
+
diffPreferencesPlugin,
|
|
93
137
|
diffCommandPlugin,
|
|
94
138
|
diffProviderPlugin
|
|
95
139
|
];
|