xtralab 0.15.0 → 0.15.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 (228) hide show
  1. package/README.md +10 -0
  2. package/lib/about/icons.d.ts +0 -5
  3. package/lib/about/icons.js +0 -5
  4. package/lib/about/index.d.ts +4 -8
  5. package/lib/about/index.js +6 -17
  6. package/lib/agentSessions.d.ts +9 -29
  7. package/lib/agentSessions.js +2 -7
  8. package/lib/askAgent/editorSelection.d.ts +20 -26
  9. package/lib/askAgent/editorSelection.js +11 -26
  10. package/lib/askAgent/icons.d.ts +2 -3
  11. package/lib/askAgent/icons.js +2 -3
  12. package/lib/askAgent/index.d.ts +4 -26
  13. package/lib/askAgent/index.js +54 -158
  14. package/lib/askAgent/popup.d.ts +12 -16
  15. package/lib/askAgent/popup.js +18 -37
  16. package/lib/askAgent/prompt.d.ts +3 -5
  17. package/lib/askAgent/prompt.js +6 -19
  18. package/lib/askAgent/queue.d.ts +11 -21
  19. package/lib/askAgent/queue.js +9 -19
  20. package/lib/askAgent/queuePanel.d.ts +13 -18
  21. package/lib/askAgent/queuePanel.js +15 -37
  22. package/lib/askAgent/targetPicker.d.ts +2 -9
  23. package/lib/askAgent/targetPicker.js +6 -11
  24. package/lib/askAgent/tokens.d.ts +32 -46
  25. package/lib/askAgent/tokens.js +4 -6
  26. package/lib/commandBar/index.d.ts +4 -13
  27. package/lib/commandBar/index.js +21 -39
  28. package/lib/customPanel/index.js +15 -0
  29. package/lib/editorBreadcrumbs/index.d.ts +3 -6
  30. package/lib/editorBreadcrumbs/index.js +10 -6
  31. package/lib/editorBreadcrumbs/widget.d.ts +17 -4
  32. package/lib/editorBreadcrumbs/widget.js +11 -17
  33. package/lib/editorIndent/index.d.ts +4 -12
  34. package/lib/editorIndent/index.js +8 -23
  35. package/lib/fileBrowser/commands.d.ts +28 -19
  36. package/lib/fileBrowser/commands.js +39 -98
  37. package/lib/fileBrowser/contents.d.ts +3 -0
  38. package/lib/fileBrowser/dragAndDrop.d.ts +17 -4
  39. package/lib/fileBrowser/dragAndDrop.js +2 -7
  40. package/lib/fileBrowser/fileBrowser.d.ts +19 -9
  41. package/lib/fileBrowser/fileBrowser.js +68 -216
  42. package/lib/fileBrowser/gitStatus.d.ts +4 -9
  43. package/lib/fileBrowser/gitStatus.js +7 -17
  44. package/lib/fileBrowser/gitignore.d.ts +4 -17
  45. package/lib/fileBrowser/gitignore.js +4 -25
  46. package/lib/fileBrowser/icons.d.ts +7 -17
  47. package/lib/fileBrowser/icons.js +25 -80
  48. package/lib/fileBrowser/index.js +2 -4
  49. package/lib/fileBrowser/widget.d.ts +126 -48
  50. package/lib/fileBrowser/widget.js +89 -4
  51. package/lib/fileTypeIcons/index.js +0 -10
  52. package/lib/git/api.d.ts +5 -13
  53. package/lib/git/api.js +10 -36
  54. package/lib/git/askRequest.d.ts +4 -8
  55. package/lib/git/askRequest.js +6 -20
  56. package/lib/git/commands.d.ts +40 -5
  57. package/lib/git/commands.js +16 -10
  58. package/lib/git/diffModel.js +4 -0
  59. package/lib/git/diffSurface.d.ts +41 -55
  60. package/lib/git/diffSurface.js +42 -117
  61. package/lib/git/diffWidget.d.ts +81 -2
  62. package/lib/git/diffWidget.js +62 -12
  63. package/lib/git/imageDiff.d.ts +5 -6
  64. package/lib/git/imageDiff.js +18 -48
  65. package/lib/git/index.d.ts +0 -3
  66. package/lib/git/index.js +3 -8
  67. package/lib/git/notebookDiff.d.ts +110 -33
  68. package/lib/git/notebookDiff.js +52 -195
  69. package/lib/git/tokens.d.ts +73 -31
  70. package/lib/git/tokens.js +2 -3
  71. package/lib/highlight/index.d.ts +4 -10
  72. package/lib/highlight/index.js +10 -41
  73. package/lib/index.d.ts +0 -9
  74. package/lib/index.js +0 -9
  75. package/lib/launcher/agents.d.ts +55 -51
  76. package/lib/launcher/agents.js +15 -57
  77. package/lib/launcher/availability.d.ts +3 -9
  78. package/lib/launcher/availability.js +3 -9
  79. package/lib/launcher/commands.d.ts +7 -32
  80. package/lib/launcher/commands.js +14 -45
  81. package/lib/launcher/dashboard.d.ts +19 -24
  82. package/lib/launcher/dashboard.js +21 -67
  83. package/lib/launcher/editorRegistry.d.ts +10 -22
  84. package/lib/launcher/editorRegistry.js +14 -18
  85. package/lib/launcher/editors.d.ts +39 -45
  86. package/lib/launcher/editors.js +8 -34
  87. package/lib/launcher/icons.d.ts +0 -12
  88. package/lib/launcher/icons.js +5 -39
  89. package/lib/launcher/index.js +12 -55
  90. package/lib/launcher/invocation.d.ts +4 -10
  91. package/lib/launcher/invocation.js +7 -22
  92. package/lib/launcher/registry.d.ts +9 -7
  93. package/lib/launcher/registry.js +9 -7
  94. package/lib/launcher/tokens.d.ts +10 -22
  95. package/lib/launcher/tokens.js +5 -8
  96. package/lib/menuBar/index.d.ts +3 -10
  97. package/lib/menuBar/index.js +11 -28
  98. package/lib/menus/index.d.ts +3 -9
  99. package/lib/menus/index.js +14 -30
  100. package/lib/omnibox/files.d.ts +2 -4
  101. package/lib/omnibox/files.js +5 -11
  102. package/lib/omnibox/index.d.ts +4 -14
  103. package/lib/omnibox/index.js +9 -27
  104. package/lib/omnibox/model.d.ts +38 -10
  105. package/lib/omnibox/model.js +15 -33
  106. package/lib/omnibox/recents.d.ts +15 -17
  107. package/lib/omnibox/recents.js +12 -17
  108. package/lib/omnibox/tokens.d.ts +5 -10
  109. package/lib/omnibox/tokens.js +2 -6
  110. package/lib/omnibox/widget.d.ts +11 -7
  111. package/lib/omnibox/widget.js +8 -16
  112. package/lib/searchReplace/index.d.ts +4 -20
  113. package/lib/searchReplace/index.js +7 -27
  114. package/lib/showOutput/index.d.ts +3 -12
  115. package/lib/showOutput/index.js +6 -22
  116. package/lib/sidebar/index.d.ts +4 -7
  117. package/lib/sidebar/index.js +5 -12
  118. package/lib/terminalNotifications/index.d.ts +4 -10
  119. package/lib/terminalNotifications/index.js +6 -20
  120. package/lib/terminals/agentTerminals.d.ts +12 -5
  121. package/lib/terminals/agentTerminals.js +25 -44
  122. package/lib/terminals/detection.d.ts +4 -8
  123. package/lib/terminals/detection.js +4 -8
  124. package/lib/terminals/index.d.ts +0 -35
  125. package/lib/terminals/index.js +12 -101
  126. package/lib/terminals/model.d.ts +64 -139
  127. package/lib/terminals/model.js +80 -220
  128. package/lib/terminals/tokens.d.ts +11 -22
  129. package/lib/terminals/tokens.js +2 -2
  130. package/lib/terminals/widget.d.ts +43 -13
  131. package/lib/terminals/widget.js +33 -18
  132. package/lib/topBar/icons.d.ts +3 -8
  133. package/lib/topBar/icons.js +3 -8
  134. package/lib/topBar/index.d.ts +4 -11
  135. package/lib/topBar/index.js +10 -38
  136. package/lib/walkthrough/index.d.ts +4 -9
  137. package/lib/walkthrough/index.js +6 -20
  138. package/lib/walkthrough/panel.d.ts +40 -9
  139. package/lib/walkthrough/panel.js +4 -10
  140. package/package.json +2 -2
  141. package/src/about/icons.ts +0 -5
  142. package/src/about/index.tsx +6 -17
  143. package/src/agentSessions.ts +9 -29
  144. package/src/askAgent/editorSelection.ts +22 -29
  145. package/src/askAgent/icons.ts +2 -3
  146. package/src/askAgent/index.ts +54 -158
  147. package/src/askAgent/popup.tsx +23 -45
  148. package/src/askAgent/prompt.ts +6 -19
  149. package/src/askAgent/queue.ts +13 -24
  150. package/src/askAgent/queuePanel.tsx +21 -46
  151. package/src/askAgent/targetPicker.tsx +5 -15
  152. package/src/askAgent/tokens.ts +32 -46
  153. package/src/commandBar/index.ts +24 -39
  154. package/src/customPanel/index.ts +15 -0
  155. package/src/editorBreadcrumbs/index.ts +10 -6
  156. package/src/editorBreadcrumbs/widget.ts +23 -17
  157. package/src/editorIndent/index.ts +17 -23
  158. package/src/fileBrowser/commands.ts +57 -98
  159. package/src/fileBrowser/contents.ts +3 -0
  160. package/src/fileBrowser/dragAndDrop.ts +17 -7
  161. package/src/fileBrowser/fileBrowser.tsx +84 -223
  162. package/src/fileBrowser/gitStatus.ts +7 -17
  163. package/src/fileBrowser/gitignore.ts +4 -25
  164. package/src/fileBrowser/icons.ts +25 -80
  165. package/src/fileBrowser/index.ts +2 -4
  166. package/src/fileBrowser/widget.tsx +149 -50
  167. package/src/fileTypeIcons/index.ts +0 -10
  168. package/src/git/api.ts +10 -36
  169. package/src/git/askRequest.ts +6 -20
  170. package/src/git/commands.ts +70 -10
  171. package/src/git/diffModel.ts +25 -0
  172. package/src/git/diffSurface.tsx +71 -159
  173. package/src/git/diffWidget.tsx +104 -14
  174. package/src/git/imageDiff.tsx +45 -51
  175. package/src/git/index.ts +3 -8
  176. package/src/git/notebookDiff.tsx +211 -238
  177. package/src/git/tokens.ts +73 -31
  178. package/src/highlight/index.ts +10 -41
  179. package/src/index.ts +0 -9
  180. package/src/launcher/agents.ts +64 -95
  181. package/src/launcher/availability.ts +3 -9
  182. package/src/launcher/commands.ts +14 -51
  183. package/src/launcher/dashboard.tsx +49 -88
  184. package/src/launcher/editorRegistry.ts +21 -29
  185. package/src/launcher/editors.ts +39 -58
  186. package/src/launcher/icons.ts +5 -39
  187. package/src/launcher/index.ts +12 -55
  188. package/src/launcher/invocation.ts +7 -22
  189. package/src/launcher/registry.ts +9 -7
  190. package/src/launcher/tokens.ts +10 -22
  191. package/src/menuBar/index.ts +11 -28
  192. package/src/menus/index.ts +14 -30
  193. package/src/omnibox/files.ts +10 -14
  194. package/src/omnibox/index.ts +9 -27
  195. package/src/omnibox/model.ts +50 -38
  196. package/src/omnibox/recents.ts +17 -22
  197. package/src/omnibox/tokens.ts +5 -10
  198. package/src/omnibox/widget.tsx +14 -19
  199. package/src/searchReplace/index.ts +7 -27
  200. package/src/showOutput/index.ts +6 -22
  201. package/src/sidebar/index.ts +20 -12
  202. package/src/terminalNotifications/index.ts +42 -25
  203. package/src/terminals/agentTerminals.ts +25 -49
  204. package/src/terminals/detection.ts +4 -8
  205. package/src/terminals/index.ts +12 -101
  206. package/src/terminals/model.ts +130 -246
  207. package/src/terminals/tokens.ts +11 -22
  208. package/src/terminals/widget.tsx +48 -31
  209. package/src/topBar/icons.ts +3 -8
  210. package/src/topBar/index.ts +21 -44
  211. package/src/walkthrough/index.ts +6 -20
  212. package/src/walkthrough/panel.ts +40 -10
  213. package/style/about.css +2 -7
  214. package/style/askAgent.css +8 -40
  215. package/style/base.css +9 -45
  216. package/style/chrome.css +108 -308
  217. package/style/commandBar.css +4 -20
  218. package/style/customPanel.css +1 -4
  219. package/style/git.css +22 -184
  220. package/style/highlight.css +1 -3
  221. package/style/launcher.css +6 -70
  222. package/style/omnibox.css +2 -14
  223. package/style/showOutput.css +0 -6
  224. package/style/sidebar.css +29 -9
  225. package/style/tabs.css +5 -13
  226. package/style/terminals.css +6 -53
  227. package/style/topBar.css +2 -22
  228. package/style/walkthrough.css +0 -8
@@ -14,22 +14,44 @@ export { DIFF_WIDGET_CSS_CLASS };
14
14
  * `Git.Diff.IModel` plus optional xtralab-only metadata.
15
15
  */
16
16
  export interface IXtralabDiffModel extends Git.Diff.IModel {
17
+ /**
18
+ * Whether the file is binary, so no text contents are fetched.
19
+ */
17
20
  isBinary?: boolean;
21
+ /**
22
+ * Whether hunks may be discarded; when absent, a working-tree heuristic decides.
23
+ */
18
24
  canDiscard?: boolean;
25
+ /**
26
+ * The old-side path when the diff represents a rename.
27
+ */
19
28
  oldFilename?: string;
20
29
  }
21
30
  /**
22
31
  * Application-level services the diff model does not carry.
23
32
  */
24
33
  export interface IXtralabDiffContext {
34
+ /**
35
+ * The contents manager used to save hunk-discard results.
36
+ */
25
37
  contentsManager: Contents.IManager;
38
+ /**
39
+ * The rendermime registry for rendered notebook diffs, or `null` to
40
+ * force the textual fallback.
41
+ */
26
42
  rendermime: IRenderMimeRegistry | null;
43
+ /**
44
+ * The theme manager used to track theme changes, or `null` to watch
45
+ * the body attribute instead.
46
+ */
27
47
  themeManager: IThemeManager | null;
28
48
  /**
29
- * The ask-agent popup; when available, diff line selections get an
30
- * "ask an agent about these lines" gutter button.
49
+ * When available, diff line selections get an "ask an agent" gutter button.
31
50
  */
32
51
  askAgent: IAskAgent | null;
52
+ /**
53
+ * The application translation bundle.
54
+ */
33
55
  trans: TranslationBundle;
34
56
  }
35
57
  /**
@@ -37,6 +59,9 @@ export interface IXtralabDiffContext {
37
59
  */
38
60
  export declare class XtralabDiffWidget extends ReactWidget implements Git.Diff.IDiffWidget {
39
61
  constructor(model: Git.Diff.IModel, context: IXtralabDiffContext);
62
+ /**
63
+ * The git diff model being rendered.
64
+ */
40
65
  get model(): Git.Diff.IModel;
41
66
  /**
42
67
  * Swap the rendered model when the launcher reuses its preview tab.
@@ -54,30 +79,81 @@ export declare class XtralabDiffWidget extends ReactWidget implements Git.Diff.I
54
79
  * Re-pull both sides of the model and re-render.
55
80
  */
56
81
  refresh(): Promise<void>;
82
+ /**
83
+ * The current rendered-vs-JSON choice for notebook diffs.
84
+ */
57
85
  get notebookViewMode(): NotebookDiffViewMode;
86
+ /**
87
+ * Set the notebook view mode and persist it.
88
+ */
58
89
  setNotebookViewMode(mode: NotebookDiffViewMode): void;
90
+ /**
91
+ * A signal emitted when the notebook view mode changes.
92
+ */
59
93
  get notebookViewModeChanged(): ISignal<this, NotebookDiffViewMode>;
94
+ /**
95
+ * Whether a rendered notebook view is currently available.
96
+ */
60
97
  get hasNotebookView(): boolean;
98
+ /**
99
+ * Set whether a rendered notebook view is available.
100
+ */
61
101
  setHasNotebookView(value: boolean): void;
102
+ /**
103
+ * A signal emitted when rendered-notebook availability changes.
104
+ */
62
105
  get hasNotebookViewChanged(): ISignal<this, boolean>;
106
+ /**
107
+ * The current split/unified layout for textual file diffs.
108
+ */
63
109
  get diffStyle(): DiffStyle;
110
+ /**
111
+ * Set the diff style and persist it.
112
+ */
64
113
  setDiffStyle(style: DiffStyle): void;
114
+ /**
115
+ * A signal emitted when the diff style changes.
116
+ */
65
117
  get diffStyleChanged(): ISignal<this, DiffStyle>;
66
118
  /**
67
119
  * Whether the Split/Unified toolbar selector currently applies.
68
120
  */
69
121
  get fileDiffActive(): boolean;
122
+ /**
123
+ * Set whether the textual file diff is the active view.
124
+ */
70
125
  setFileDiffActive(value: boolean): void;
126
+ /**
127
+ * A signal emitted when {@link fileDiffActive} changes.
128
+ */
71
129
  get fileDiffActiveChanged(): ISignal<this, boolean>;
72
130
  /**
73
131
  * Emitted when a post-discard reload leaves the diff with no hunks.
74
132
  */
75
133
  get emptied(): ISignal<this, void>;
134
+ /**
135
+ * Emit the {@link emptied} signal.
136
+ */
76
137
  notifyEmptied(): void;
138
+ /**
139
+ * Resolve and clear the pending `refresh()` promise, if any.
140
+ */
77
141
  settleRefresh(): void;
142
+ /**
143
+ * Dispose of the resources held by the widget.
144
+ */
78
145
  dispose(): void;
146
+ /**
147
+ * A counter incremented on each `refresh()` to trigger a content re-fetch.
148
+ */
79
149
  get reloadNonce(): number;
150
+ /**
151
+ * The application-level services used by the rendered diff.
152
+ */
80
153
  get context(): IXtralabDiffContext;
154
+ /**
155
+ * Render the diff view for the current model.
156
+ */
81
157
  protected render(): React.ReactElement;
82
158
  private _model;
83
159
  private _context;
@@ -97,6 +173,9 @@ export declare class XtralabDiffWidget extends ReactWidget implements Git.Diff.I
97
173
  * Structural toolbar type shared across host package boundaries.
98
174
  */
99
175
  interface IDiffToolbar {
176
+ /**
177
+ * Add an item to the toolbar under the given name.
178
+ */
100
179
  addItem(name: string, widget: Widget): boolean;
101
180
  }
102
181
  /**
@@ -31,6 +31,9 @@ export class XtralabDiffWidget extends ReactWidget {
31
31
  this.addClass('jp-git-diff-root');
32
32
  this.addClass(DIFF_WIDGET_CSS_CLASS);
33
33
  }
34
+ /**
35
+ * The git diff model being rendered.
36
+ */
34
37
  get model() {
35
38
  return this._model;
36
39
  }
@@ -74,9 +77,15 @@ export class XtralabDiffWidget extends ReactWidget {
74
77
  this.update();
75
78
  await done.promise;
76
79
  }
80
+ /**
81
+ * The current rendered-vs-JSON choice for notebook diffs.
82
+ */
77
83
  get notebookViewMode() {
78
84
  return this._notebookViewMode;
79
85
  }
86
+ /**
87
+ * Set the notebook view mode and persist it.
88
+ */
80
89
  setNotebookViewMode(mode) {
81
90
  if (mode === this._notebookViewMode) {
82
91
  return;
@@ -85,12 +94,21 @@ export class XtralabDiffWidget extends ReactWidget {
85
94
  writeStoredNotebookViewMode(mode);
86
95
  this._notebookViewModeChanged.emit(mode);
87
96
  }
97
+ /**
98
+ * A signal emitted when the notebook view mode changes.
99
+ */
88
100
  get notebookViewModeChanged() {
89
101
  return this._notebookViewModeChanged;
90
102
  }
103
+ /**
104
+ * Whether a rendered notebook view is currently available.
105
+ */
91
106
  get hasNotebookView() {
92
107
  return this._hasNotebookView;
93
108
  }
109
+ /**
110
+ * Set whether a rendered notebook view is available.
111
+ */
94
112
  setHasNotebookView(value) {
95
113
  if (value === this._hasNotebookView) {
96
114
  return;
@@ -98,12 +116,21 @@ export class XtralabDiffWidget extends ReactWidget {
98
116
  this._hasNotebookView = value;
99
117
  this._hasNotebookViewChanged.emit(value);
100
118
  }
119
+ /**
120
+ * A signal emitted when rendered-notebook availability changes.
121
+ */
101
122
  get hasNotebookViewChanged() {
102
123
  return this._hasNotebookViewChanged;
103
124
  }
125
+ /**
126
+ * The current split/unified layout for textual file diffs.
127
+ */
104
128
  get diffStyle() {
105
129
  return this._diffStyle;
106
130
  }
131
+ /**
132
+ * Set the diff style and persist it.
133
+ */
107
134
  setDiffStyle(style) {
108
135
  if (style === this._diffStyle) {
109
136
  return;
@@ -112,6 +139,9 @@ export class XtralabDiffWidget extends ReactWidget {
112
139
  writeStoredDiffStyle(style);
113
140
  this._diffStyleChanged.emit(style);
114
141
  }
142
+ /**
143
+ * A signal emitted when the diff style changes.
144
+ */
115
145
  get diffStyleChanged() {
116
146
  return this._diffStyleChanged;
117
147
  }
@@ -121,6 +151,9 @@ export class XtralabDiffWidget extends ReactWidget {
121
151
  get fileDiffActive() {
122
152
  return this._fileDiffActive;
123
153
  }
154
+ /**
155
+ * Set whether the textual file diff is the active view.
156
+ */
124
157
  setFileDiffActive(value) {
125
158
  if (value === this._fileDiffActive) {
126
159
  return;
@@ -128,6 +161,9 @@ export class XtralabDiffWidget extends ReactWidget {
128
161
  this._fileDiffActive = value;
129
162
  this._fileDiffActiveChanged.emit(value);
130
163
  }
164
+ /**
165
+ * A signal emitted when {@link fileDiffActive} changes.
166
+ */
131
167
  get fileDiffActiveChanged() {
132
168
  return this._fileDiffActiveChanged;
133
169
  }
@@ -137,27 +173,44 @@ export class XtralabDiffWidget extends ReactWidget {
137
173
  get emptied() {
138
174
  return this._emptied;
139
175
  }
176
+ /**
177
+ * Emit the {@link emptied} signal.
178
+ */
140
179
  notifyEmptied() {
141
180
  this._emptied.emit();
142
181
  }
182
+ /**
183
+ * Resolve and clear the pending `refresh()` promise, if any.
184
+ */
143
185
  settleRefresh() {
144
186
  const pending = this._pendingRefresh;
145
187
  this._pendingRefresh = null;
146
188
  pending === null || pending === void 0 ? void 0 : pending.resolve();
147
189
  }
190
+ /**
191
+ * Dispose of the resources held by the widget.
192
+ */
148
193
  dispose() {
149
- // Release any in-flight refresh awaiter so a host that awaits refresh()
150
- // (jupyterlab-git re-shows its diff button only once it resolves) does not
151
- // hang when the widget is torn down mid-fetch.
194
+ // jupyterlab-git awaits refresh() to re-show its diff button; release any
195
+ // in-flight awaiter so it does not hang on mid-fetch teardown.
152
196
  this.settleRefresh();
153
197
  super.dispose();
154
198
  }
199
+ /**
200
+ * A counter incremented on each `refresh()` to trigger a content re-fetch.
201
+ */
155
202
  get reloadNonce() {
156
203
  return this._reloadNonce;
157
204
  }
205
+ /**
206
+ * The application-level services used by the rendered diff.
207
+ */
158
208
  get context() {
159
209
  return this._context;
160
210
  }
211
+ /**
212
+ * Render the diff view for the current model.
213
+ */
161
214
  render() {
162
215
  return React.createElement(ModelDiffView, { widget: this });
163
216
  }
@@ -174,7 +227,6 @@ function ModelDiffView(props) {
174
227
  newText: '',
175
228
  error: null
176
229
  });
177
- // Mirror toolbar-driven notebook view changes into React state.
178
230
  const [notebookViewMode, setNotebookViewMode] = React.useState(() => widget.notebookViewMode);
179
231
  React.useEffect(() => {
180
232
  const handler = (sender, mode) => {
@@ -189,7 +241,6 @@ function ModelDiffView(props) {
189
241
  const handleNotebookAvailabilityChange = React.useCallback((available) => {
190
242
  widget.setHasNotebookView(available);
191
243
  }, [widget]);
192
- // Mirror toolbar-driven diff-style changes into React state.
193
244
  const [diffStyle, setDiffStyle] = React.useState(() => widget.diffStyle);
194
245
  React.useEffect(() => {
195
246
  const handler = (sender, style) => {
@@ -226,18 +277,14 @@ function ModelDiffView(props) {
226
277
  observer.disconnect();
227
278
  };
228
279
  }, [themeManager]);
229
- // Image diffs use the server's base64 payloads; other binaries show a placeholder.
230
280
  const isImage = React.useMemo(() => imageDataType(model.filename) !== null, [model.filename]);
231
281
  const isBinary = model.isBinary === true && !isImage;
232
- // Used by the launcher to auto-close an emptied diff after discard.
233
282
  const [hunkCount, setHunkCount] = React.useState(null);
234
283
  const handleMetadataChange = React.useCallback((info) => {
235
284
  setHunkCount(info.hunkCount);
236
285
  }, []);
237
- // Fetch both sides whenever the model or reload nonce changes.
238
286
  React.useEffect(() => {
239
287
  let cancelled = false;
240
- // Non-image binaries do not need content fetches.
241
288
  if (isBinary) {
242
289
  setState({ loading: false, oldText: '', newText: '', error: null });
243
290
  // An in-flight `refresh()` still has to resolve.
@@ -276,7 +323,6 @@ function ModelDiffView(props) {
276
323
  }
277
324
  finally {
278
325
  if (!cancelled) {
279
- // Let `refresh()` settle once content has loaded.
280
326
  widget.settleRefresh();
281
327
  }
282
328
  }
@@ -295,7 +341,6 @@ function ModelDiffView(props) {
295
341
  widget.notifyEmptied();
296
342
  }
297
343
  }, [state.loading, state.error, isBinary, hunkCount, nonce, widget]);
298
- // The launcher sets `canDiscard`; jupyterlab-git models fall back to source.
299
344
  const canDiscardHunk = (_a = model.canDiscard) !== null && _a !== void 0 ? _a : (model.challenger.source === Git.Diff.SpecialRef.WORKING &&
300
345
  model.hasConflict !== true);
301
346
  const serverPath = React.useMemo(() => { var _a; return PathExt.join((_a = model.repositoryPath) !== null && _a !== void 0 ? _a : '', model.filename); }, [model.repositoryPath, model.filename]);
@@ -309,7 +354,6 @@ function ModelDiffView(props) {
309
354
  });
310
355
  },
311
356
  onAfterSave: () => {
312
- // Re-pull so the diff reflects the reverted hunk.
313
357
  void widget.refresh();
314
358
  }
315
359
  }), [canDiscardHunk, contentsManager, serverPath, widget]);
@@ -339,6 +383,9 @@ class NotebookViewModeToolbarItem extends ReactWidget {
339
383
  this._widget = widget;
340
384
  this.addClass('jp-xtralab-DiffWidget-viewModeToolbarItem');
341
385
  }
386
+ /**
387
+ * Render the Notebook/JSON toggle.
388
+ */
342
389
  render() {
343
390
  return React.createElement(NotebookViewModeToolbarControl, { widget: this._widget });
344
391
  }
@@ -375,6 +422,9 @@ class DiffStyleToolbarItem extends ReactWidget {
375
422
  this._widget = widget;
376
423
  this.addClass('jp-xtralab-DiffWidget-diffStyleToolbarItem');
377
424
  }
425
+ /**
426
+ * Render the Split/Unified toggle.
427
+ */
378
428
  render() {
379
429
  return React.createElement(DiffStyleToolbarControl, { widget: this._widget });
380
430
  }
@@ -1,14 +1,14 @@
1
1
  import * as React from 'react';
2
2
  import type { TranslationBundle } from '@jupyterlab/translation';
3
- /**
4
- * The file extensions registered as the xtralab image diff provider.
5
- */
6
3
  export declare const IMAGE_DIFF_EXTENSIONS: string[];
7
4
  /**
8
5
  * The `data:` MIME subtype for a path xtralab renders as an image, or
9
6
  * `null` when the path is not a supported raster image.
10
7
  */
11
8
  export declare function imageDataType(path: string): string | null;
9
+ /**
10
+ * Props for {@link ImageDiffView}.
11
+ */
12
12
  interface IImageDiffViewProps {
13
13
  /**
14
14
  * Base64 of the reference (old) revision; empty when added.
@@ -28,9 +28,8 @@ interface IImageDiffViewProps {
28
28
  trans: TranslationBundle;
29
29
  }
30
30
  /**
31
- * The image comparison surface: a segmented mode selector (reusing the
32
- * diff segmented-control styling so it matches the Notebook/JSON toggle)
33
- * plus the selected 2-up / swipe / onion-skin view.
31
+ * The image comparison surface: a mode selector (reusing the diff widget's
32
+ * segmented-control styling) plus the selected 2-up / swipe / onion view.
34
33
  */
35
34
  export declare function ImageDiffView(props: IImageDiffViewProps): React.ReactElement;
36
35
  export {};
@@ -1,20 +1,14 @@
1
1
  import * as React from 'react';
2
2
  /**
3
3
  * xtralab's image diff, registered in place of `@jupyterlab/git:image-diff`.
4
- *
5
- * The git server base64-encodes binary content, so both diff hosts receive
6
- * the two sides as base64 strings through the same `content()` getters used
7
- * for text. This module turns those strings into `<img>` elements and
8
- * offers the 2-up / swipe / onion-skin comparison modes; no diffing library
9
- * is involved (`@pierre/diffs` is text-only).
4
+ * Both sides arrive base64-encoded through the same `content()` getters used
5
+ * for text; the 2-up/swipe/onion views are hand-rolled (`@pierre/diffs` is
6
+ * text-only).
10
7
  */
11
8
  /**
12
- * Raster image extensions xtralab renders as an image diff, mapped to the
13
- * MIME subtype used in the `data:image/<subtype>;base64,…` URL.
14
- *
15
- * `.svg` is intentionally absent: it is XML text, so the `@pierre/diffs`
16
- * text diff (the fallback provider) is more useful for it than an image
17
- * comparison.
9
+ * Raster extensions mapped to the `data:image/<subtype>` MIME subtype.
10
+ * `.svg` is intentionally absent: it is XML text, so the fallback text diff
11
+ * is more useful than an image comparison.
18
12
  */
19
13
  const IMAGE_DATA_TYPES = {
20
14
  '.png': 'png',
@@ -25,9 +19,6 @@ const IMAGE_DATA_TYPES = {
25
19
  '.bmp': 'bmp',
26
20
  '.ico': 'x-icon'
27
21
  };
28
- /**
29
- * The file extensions registered as the xtralab image diff provider.
30
- */
31
22
  export const IMAGE_DIFF_EXTENSIONS = Object.keys(IMAGE_DATA_TYPES);
32
23
  /**
33
24
  * The `data:` MIME subtype for a path xtralab renders as an image, or
@@ -51,8 +42,7 @@ function readStoredImageViewMode() {
51
42
  }
52
43
  }
53
44
  catch (_a) {
54
- // localStorage can throw in privacy/sandboxed contexts — 2-up is the
55
- // sensible default anyway.
45
+ // localStorage can throw in privacy/sandboxed contexts.
56
46
  }
57
47
  return '2-up';
58
48
  }
@@ -65,17 +55,13 @@ function writeStoredImageViewMode(mode) {
65
55
  }
66
56
  }
67
57
  /**
68
- * Strip whitespace from a base64 payload. Python's `base64.encodebytes`
69
- * (used by the git server) inserts a newline every 76 characters; most
70
- * browsers tolerate that inside a `data:` URL but some are stricter, and
71
- * the cleaned length also lets us size the file accurately.
58
+ * Strip whitespace from a base64 payload: the server's `base64.encodebytes`
59
+ * inserts newlines some browsers reject in `data:` URLs, and the cleaned
60
+ * length sizes the file accurately.
72
61
  */
73
62
  function cleanBase64(value) {
74
63
  return value.replace(/\s+/g, '');
75
64
  }
76
- /**
77
- * Decoded byte length of a (whitespace-free) base64 string.
78
- */
79
65
  function base64ByteLength(clean) {
80
66
  if (clean.length === 0) {
81
67
  return 0;
@@ -107,9 +93,8 @@ function toSide(raw, fileType) {
107
93
  };
108
94
  }
109
95
  /**
110
- * The image comparison surface: a segmented mode selector (reusing the
111
- * diff segmented-control styling so it matches the Notebook/JSON toggle)
112
- * plus the selected 2-up / swipe / onion-skin view.
96
+ * The image comparison surface: a mode selector (reusing the diff widget's
97
+ * segmented-control styling) plus the selected 2-up / swipe / onion view.
113
98
  */
114
99
  export function ImageDiffView(props) {
115
100
  const { reference, challenger, fileType, trans } = props;
@@ -157,21 +142,14 @@ function TwoUp({ reference, challenger, trans }) {
157
142
  React.createElement("div", { className: "jp-xtralab-ImageDiff-frame", "data-side": "challenger" }, challenger.uri !== null ? (React.createElement("img", { className: "jp-xtralab-ImageDiff-img", src: challenger.uri, alt: trans.__('Challenger revision'), onLoad: onChallLoad })) : (React.createElement("div", { className: "jp-xtralab-ImageDiff-empty" }, trans.__('Deleted')))),
158
143
  React.createElement("figcaption", { className: "jp-xtralab-ImageDiff-caption" }, caption(challenger, challSize, trans.__('Deleted'))))));
159
144
  }
160
- /**
161
- * Range slider shared by the swipe and onion-skin views. A native
162
- * `<input type="range">` (styled via CSS) keeps the bundle free of a UI
163
- * component dependency.
164
- */
165
145
  function RangeSlider(props) {
166
146
  const { value, onChange, ariaLabel } = props;
167
147
  return (React.createElement("input", { className: "jp-xtralab-ImageDiff-slider", type: "range", min: 0, max: 100, step: 1, value: value, "aria-label": ariaLabel, onChange: event => onChange(Number(event.target.value)) }));
168
148
  }
169
149
  /**
170
- * Fit a `naturalWidth × naturalHeight` image inside an `areaWidth ×
171
- * areaHeight` box without upscaling past its intrinsic size — the same
172
- * "contain, never enlarge" rule the 2-up and onion views get for free from
173
- * `max-width/height: 100%; width/height: auto`. Returns the displayed pixel
174
- * box, or `null` until both the image and the area have been measured.
150
+ * Fit an image inside an area without upscaling past its intrinsic size —
151
+ * the "contain, never enlarge" rule the other views get from CSS. Returns
152
+ * the displayed pixel box, or `null` until both sizes are measured.
175
153
  */
176
154
  function containBox(naturalWidth, naturalHeight, areaWidth, areaHeight) {
177
155
  if (naturalWidth <= 0 ||
@@ -183,9 +161,6 @@ function containBox(naturalWidth, naturalHeight, areaWidth, areaHeight) {
183
161
  const scale = Math.min(areaWidth / naturalWidth, areaHeight / naturalHeight, 1);
184
162
  return { width: naturalWidth * scale, height: naturalHeight * scale };
185
163
  }
186
- /**
187
- * Track an element's content-box size, kept current across layout changes.
188
- */
189
164
  function useElementSize() {
190
165
  const ref = React.useRef(null);
191
166
  const [size, setSize] = React.useState({ width: 0, height: 0 });
@@ -214,13 +189,9 @@ function Swipe({ reference, challenger, trans }) {
214
189
  const [challSize, onChallLoad] = useNaturalSize();
215
190
  const [areaRef, area] = useElementSize();
216
191
  const frameRef = React.useRef(null);
217
- // Display both revisions in a single box — the union of their intrinsic
218
- // sizes, scaled down to fit but never enlarged — and size the frame to
219
- // exactly that box. The divider's `left: N%`, the pointer-to-percent
220
- // mapping (below) and each image's `clip-path` inset then all resolve
221
- // against the same width, so the white line sits precisely on the seam
222
- // between the two revisions at every position. A full-width frame instead
223
- // let the line drift off the seam by as much as half the letterbox.
192
+ // Size the frame to the union box of both revisions so the divider %, the
193
+ // pointer mapping and the clip-paths all resolve against the same width;
194
+ // a full-width frame lets the line drift off the seam.
224
195
  const naturalWidth = Math.max((_a = refSize === null || refSize === void 0 ? void 0 : refSize[0]) !== null && _a !== void 0 ? _a : 0, (_b = challSize === null || challSize === void 0 ? void 0 : challSize[0]) !== null && _b !== void 0 ? _b : 0);
225
196
  const naturalHeight = Math.max((_c = refSize === null || refSize === void 0 ? void 0 : refSize[1]) !== null && _c !== void 0 ? _c : 0, (_d = challSize === null || challSize === void 0 ? void 0 : challSize[1]) !== null && _d !== void 0 ? _d : 0);
226
197
  const box = containBox(naturalWidth, naturalHeight, area.width, area.height);
@@ -237,7 +208,6 @@ function Swipe({ reference, challenger, trans }) {
237
208
  setPosition(Math.max(0, Math.min(100, next)));
238
209
  }, []);
239
210
  const onPointerDown = React.useCallback((event) => {
240
- // Only react to the primary pointer (left click / touch / pen tip).
241
211
  if (event.button !== 0) {
242
212
  return;
243
213
  }
@@ -1,8 +1,5 @@
1
1
  import { JupyterFrontEndPlugin } from '@jupyterlab/application';
2
2
  import { CommandArguments, CommandIDs } from './commands';
3
- /**
4
- * Plugins contributed by xtralab's git integration.
5
- */
6
3
  declare const plugins: JupyterFrontEndPlugin<unknown>[];
7
4
  export { CommandArguments, CommandIDs };
8
5
  export default plugins;
package/lib/git/index.js CHANGED
@@ -7,10 +7,9 @@ import diffProviderPlugin from './diffProvider';
7
7
  const GIT_DIFF_COMMAND_PLUGIN_ID = 'xtralab:git-diff-command';
8
8
  const GIT_DIFF_TRACKER_NAMESPACE = 'xtralab-git-diff';
9
9
  /**
10
- * The launcher's git diff command plugin.
11
- *
12
- * The upstream git panel stays enabled; this plugin only gives the launcher
13
- * its own `xtralab:git:open-diff` command and preview/pinned-tab tracking.
10
+ * The launcher's git diff command plugin. The upstream git panel stays
11
+ * enabled; this only adds `xtralab:git:open-diff` and preview/pinned-tab
12
+ * tracking.
14
13
  */
15
14
  const diffCommandPlugin = {
16
15
  id: GIT_DIFF_COMMAND_PLUGIN_ID,
@@ -19,7 +18,6 @@ const diffCommandPlugin = {
19
18
  optional: [IThemeManager, IRenderMimeRegistry, ITranslator, IAskAgent],
20
19
  activate: (app, themeManager, rendermime, translator, askAgent) => {
21
20
  const trans = (translator !== null && translator !== void 0 ? translator : nullTranslator).load('jupyterlab');
22
- // Track open diffs so repeated opens reveal the existing tab.
23
21
  const tracker = new WidgetTracker({
24
22
  namespace: GIT_DIFF_TRACKER_NAMESPACE
25
23
  });
@@ -53,9 +51,6 @@ const diffCommandPlugin = {
53
51
  });
54
52
  }
55
53
  };
56
- /**
57
- * Plugins contributed by xtralab's git integration.
58
- */
59
54
  const plugins = [
60
55
  diffCommandPlugin,
61
56
  diffProviderPlugin