@theia/scm 1.75.0-next.3 → 1.75.0-next.35

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 (83) hide show
  1. package/lib/browser/decorations/scm-navigator-decorator.d.ts.map +1 -1
  2. package/lib/browser/decorations/scm-navigator-decorator.js +1 -0
  3. package/lib/browser/decorations/scm-navigator-decorator.js.map +1 -1
  4. package/lib/browser/scm-context-key-service.d.ts +2 -0
  5. package/lib/browser/scm-context-key-service.d.ts.map +1 -1
  6. package/lib/browser/scm-context-key-service.js +4 -0
  7. package/lib/browser/scm-context-key-service.js.map +1 -1
  8. package/lib/browser/scm-context-key-service.spec.js +7 -0
  9. package/lib/browser/scm-context-key-service.spec.js.map +1 -1
  10. package/lib/browser/scm-frontend-module.d.ts.map +1 -1
  11. package/lib/browser/scm-frontend-module.js +6 -0
  12. package/lib/browser/scm-frontend-module.js.map +1 -1
  13. package/lib/browser/scm-history-graph-contribution.d.ts +44 -0
  14. package/lib/browser/scm-history-graph-contribution.d.ts.map +1 -0
  15. package/lib/browser/scm-history-graph-contribution.js +226 -0
  16. package/lib/browser/scm-history-graph-contribution.js.map +1 -0
  17. package/lib/browser/scm-history-graph-contribution.spec.d.ts +2 -0
  18. package/lib/browser/scm-history-graph-contribution.spec.d.ts.map +1 -0
  19. package/lib/browser/scm-history-graph-contribution.spec.js +66 -0
  20. package/lib/browser/scm-history-graph-contribution.spec.js.map +1 -0
  21. package/lib/browser/scm-history-graph-helpers.d.ts +34 -6
  22. package/lib/browser/scm-history-graph-helpers.d.ts.map +1 -1
  23. package/lib/browser/scm-history-graph-helpers.js +71 -5
  24. package/lib/browser/scm-history-graph-helpers.js.map +1 -1
  25. package/lib/browser/scm-history-graph-helpers.spec.d.ts +2 -0
  26. package/lib/browser/scm-history-graph-helpers.spec.d.ts.map +1 -0
  27. package/lib/browser/scm-history-graph-helpers.spec.js +96 -0
  28. package/lib/browser/scm-history-graph-helpers.spec.js.map +1 -0
  29. package/lib/browser/scm-history-graph-lanes.d.ts +19 -5
  30. package/lib/browser/scm-history-graph-lanes.d.ts.map +1 -1
  31. package/lib/browser/scm-history-graph-lanes.js +25 -9
  32. package/lib/browser/scm-history-graph-lanes.js.map +1 -1
  33. package/lib/browser/scm-history-graph-lanes.spec.js +62 -25
  34. package/lib/browser/scm-history-graph-lanes.spec.js.map +1 -1
  35. package/lib/browser/scm-history-graph-model.d.ts +52 -5
  36. package/lib/browser/scm-history-graph-model.d.ts.map +1 -1
  37. package/lib/browser/scm-history-graph-model.js +108 -10
  38. package/lib/browser/scm-history-graph-model.js.map +1 -1
  39. package/lib/browser/scm-history-graph-model.spec.js +197 -4
  40. package/lib/browser/scm-history-graph-model.spec.js.map +1 -1
  41. package/lib/browser/scm-history-graph-tooltip.d.ts +27 -2
  42. package/lib/browser/scm-history-graph-tooltip.d.ts.map +1 -1
  43. package/lib/browser/scm-history-graph-tooltip.js +113 -22
  44. package/lib/browser/scm-history-graph-tooltip.js.map +1 -1
  45. package/lib/browser/scm-history-graph-tooltip.spec.d.ts +2 -0
  46. package/lib/browser/scm-history-graph-tooltip.spec.d.ts.map +1 -0
  47. package/lib/browser/scm-history-graph-tooltip.spec.js +213 -0
  48. package/lib/browser/scm-history-graph-tooltip.spec.js.map +1 -0
  49. package/lib/browser/scm-history-graph-widget.d.ts +23 -1
  50. package/lib/browser/scm-history-graph-widget.d.ts.map +1 -1
  51. package/lib/browser/scm-history-graph-widget.js +93 -24
  52. package/lib/browser/scm-history-graph-widget.js.map +1 -1
  53. package/lib/browser/scm-history-graph-widget.spec.d.ts +2 -0
  54. package/lib/browser/scm-history-graph-widget.spec.d.ts.map +1 -0
  55. package/lib/browser/scm-history-graph-widget.spec.js +100 -0
  56. package/lib/browser/scm-history-graph-widget.spec.js.map +1 -0
  57. package/lib/browser/scm-provider.d.ts +9 -1
  58. package/lib/browser/scm-provider.d.ts.map +1 -1
  59. package/lib/browser/scm-provider.js.map +1 -1
  60. package/lib/common/scm-preferences.d.ts +3 -0
  61. package/lib/common/scm-preferences.d.ts.map +1 -1
  62. package/lib/common/scm-preferences.js +24 -0
  63. package/lib/common/scm-preferences.js.map +1 -1
  64. package/package.json +6 -6
  65. package/src/browser/decorations/scm-navigator-decorator.ts +3 -2
  66. package/src/browser/scm-context-key-service.spec.ts +9 -0
  67. package/src/browser/scm-context-key-service.ts +6 -0
  68. package/src/browser/scm-frontend-module.ts +7 -1
  69. package/src/browser/scm-history-graph-contribution.spec.ts +83 -0
  70. package/src/browser/scm-history-graph-contribution.ts +222 -0
  71. package/src/browser/scm-history-graph-helpers.spec.ts +118 -0
  72. package/src/browser/scm-history-graph-helpers.ts +81 -6
  73. package/src/browser/scm-history-graph-lanes.spec.ts +70 -25
  74. package/src/browser/scm-history-graph-lanes.ts +48 -11
  75. package/src/browser/scm-history-graph-model.spec.ts +247 -12
  76. package/src/browser/scm-history-graph-model.ts +125 -12
  77. package/src/browser/scm-history-graph-tooltip.spec.ts +254 -0
  78. package/src/browser/scm-history-graph-tooltip.ts +144 -24
  79. package/src/browser/scm-history-graph-widget.spec.ts +112 -0
  80. package/src/browser/scm-history-graph-widget.tsx +104 -35
  81. package/src/browser/scm-provider.ts +9 -1
  82. package/src/browser/style/scm-history-graph.css +43 -2
  83. package/src/common/scm-preferences.ts +27 -0
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ // *****************************************************************************
3
+ // Copyright (C) 2026 Safi Seid-Ahmad, K2view and others.
4
+ //
5
+ // This program and the accompanying materials are made available under the
6
+ // terms of the Eclipse Public License v. 2.0 which is available at
7
+ // http://www.eclipse.org/legal/epl-2.0.
8
+ //
9
+ // This Source Code may also be made available under the following Secondary
10
+ // Licenses when the conditions for such availability set forth in the Eclipse
11
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
12
+ // with the GNU Classpath Exception which is available at
13
+ // https://www.gnu.org/software/classpath/license.html.
14
+ //
15
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
16
+ // *****************************************************************************
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
19
+ const disableJSDOM = (0, jsdom_1.enableJSDOM)();
20
+ const chai_1 = require("chai");
21
+ const markdown_string_1 = require("@theia/core/lib/common/markdown-rendering/markdown-string");
22
+ const markdown_link_handler_1 = require("@theia/core/lib/browser/markdown-rendering/markdown-link-handler");
23
+ const disposable_1 = require("@theia/core/lib/common/disposable");
24
+ const scm_history_graph_tooltip_1 = require("./scm-history-graph-tooltip");
25
+ disableJSDOM();
26
+ function makeEntry(item) {
27
+ return {
28
+ item: {
29
+ id: '1a56ba96fdc9b6df3a230df7b44e22e5785e3abd',
30
+ subject: 'fix something',
31
+ parentIds: [],
32
+ ...item,
33
+ },
34
+ graphRow: { lane: 0, color: 0, topColor: 0, edges: [], hasContinuation: false, hasTopLine: false },
35
+ isCurrent: false,
36
+ };
37
+ }
38
+ const markdownRenderer = {
39
+ render: () => ({ element: document.createElement('div'), dispose: () => { } })
40
+ };
41
+ describe('buildHtmlTooltip', () => {
42
+ let restoreJSDOM;
43
+ before(() => {
44
+ restoreJSDOM = (0, jsdom_1.enableJSDOM)();
45
+ });
46
+ after(() => {
47
+ restoreJSDOM();
48
+ });
49
+ it('renders the author as a bold mailto link when the email is known', () => {
50
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ author: 'Jane Doe', authorEmail: 'jane@example.com', timestamp: 1000 }), markdownRenderer);
51
+ const link = tooltip.querySelector('a[href="mailto:jane@example.com"]');
52
+ (0, chai_1.expect)(link, 'mailto link').to.not.be.null;
53
+ (0, chai_1.expect)(link.textContent).to.contain('Jane Doe');
54
+ (0, chai_1.expect)(link.querySelector('strong'), 'bold author').to.not.be.null;
55
+ });
56
+ it('renders a plain bold author when no email is known', () => {
57
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ author: 'Jane Doe', timestamp: 1000 }), markdownRenderer);
58
+ (0, chai_1.expect)(tooltip.querySelector('a[href^="mailto:"]')).to.be.null;
59
+ const strong = tooltip.querySelector('.scm-history-tooltip-header strong');
60
+ (0, chai_1.expect)(strong).to.not.be.null;
61
+ (0, chai_1.expect)(strong.textContent).to.equal('Jane Doe');
62
+ });
63
+ it('renders the author avatar image when authorIcon is a URL', () => {
64
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ author: 'Jane Doe', authorIcon: 'https://avatars.example.com/u/1' }), markdownRenderer);
65
+ const img = tooltip.querySelector('img.scm-history-tooltip-avatar');
66
+ (0, chai_1.expect)(img, 'avatar image').to.not.be.null;
67
+ (0, chai_1.expect)(img.src).to.equal('https://avatars.example.com/u/1');
68
+ });
69
+ it('falls back to the account icon without an avatar', () => {
70
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ author: 'Jane Doe' }), markdownRenderer);
71
+ (0, chai_1.expect)(tooltip.querySelector('img.scm-history-tooltip-avatar')).to.be.null;
72
+ (0, chai_1.expect)(tooltip.querySelector('.scm-history-tooltip-header .codicon-account')).to.not.be.null;
73
+ });
74
+ it('renders an Open Commit action with the short hash', () => {
75
+ let opened = 0;
76
+ const actions = { openCommit: () => { opened++; } };
77
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ displayId: '1a56ba9' }), markdownRenderer, undefined, actions);
78
+ const action = tooltip.querySelector('[title="Open Commit"]');
79
+ (0, chai_1.expect)(action, 'open commit action').to.not.be.null;
80
+ (0, chai_1.expect)(action.textContent).to.contain('1a56ba9');
81
+ action.click();
82
+ (0, chai_1.expect)(opened).to.equal(1);
83
+ });
84
+ it('renders a Copy Commit Hash action', () => {
85
+ let copied = 0;
86
+ const actions = { copyCommitHash: () => { copied++; } };
87
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({}), markdownRenderer, undefined, actions);
88
+ const action = tooltip.querySelector('[title="Copy Commit Hash"]');
89
+ (0, chai_1.expect)(action, 'copy hash action').to.not.be.null;
90
+ action.click();
91
+ (0, chai_1.expect)(copied).to.equal(1);
92
+ });
93
+ it('shows the short hash as plain text when no actions are given', () => {
94
+ const tooltip = (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(makeEntry({ displayId: '1a56ba9' }), markdownRenderer);
95
+ (0, chai_1.expect)(tooltip.querySelector('[title="Open Commit"]')).to.be.null;
96
+ (0, chai_1.expect)(tooltip.querySelector('[title="Copy Commit Hash"]')).to.be.null;
97
+ (0, chai_1.expect)(tooltip.textContent).to.contain('1a56ba9');
98
+ });
99
+ });
100
+ describe('buildProviderTooltip', () => {
101
+ let restoreJSDOM;
102
+ let opened;
103
+ let toDispose;
104
+ /** Renders the markdown value as HTML, so that the wiring of the resulting links can be asserted. */
105
+ const htmlRenderer = {
106
+ render: (markdown) => {
107
+ const element = document.createElement('div');
108
+ element.innerHTML = markdown.value;
109
+ return { element, dispose: () => { } };
110
+ }
111
+ };
112
+ const openerService = {
113
+ getOpener: (uri) => Promise.resolve({
114
+ canHandle: () => 1,
115
+ open: () => {
116
+ // decoded, as `HttpOpenHandler` does when opening the target externally
117
+ opened.push(uri.toString(true));
118
+ return Promise.resolve(undefined);
119
+ }
120
+ })
121
+ };
122
+ /** Clicks the anchor and waits for the asynchronous opener lookup to settle. */
123
+ async function click(tooltip, selector) {
124
+ const anchor = tooltip.querySelector(selector);
125
+ (0, chai_1.expect)(anchor, selector).to.not.be.null;
126
+ anchor.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true }));
127
+ await new Promise(resolve => setTimeout(resolve, 0));
128
+ }
129
+ before(() => {
130
+ restoreJSDOM = (0, jsdom_1.enableJSDOM)();
131
+ });
132
+ after(() => {
133
+ restoreJSDOM();
134
+ });
135
+ beforeEach(() => {
136
+ opened = [];
137
+ toDispose = new disposable_1.DisposableCollection();
138
+ });
139
+ afterEach(() => {
140
+ toDispose.dispose();
141
+ });
142
+ it('renders each section in order', () => {
143
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)([new markdown_string_1.MarkdownStringImpl('<span>first</span>'), new markdown_string_1.MarkdownStringImpl('<span>second</span>')], htmlRenderer, openerService, toDispose);
144
+ (0, chai_1.expect)(tooltip, 'tooltip').to.not.be.undefined;
145
+ (0, chai_1.expect)(tooltip.textContent).to.equal('firstsecond');
146
+ });
147
+ // `vscode.git` ends its author and statistics sections with a horizontal rule of its own,
148
+ // so adding separators here would render every boundary as a double line.
149
+ it('adds no separators of its own between sections', () => {
150
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)([new markdown_string_1.MarkdownStringImpl('<span>first</span><hr>'), new markdown_string_1.MarkdownStringImpl('<span>second</span>')], htmlRenderer, openerService, toDispose);
151
+ (0, chai_1.expect)(tooltip.querySelectorAll('hr').length, 'rules').to.equal(1);
152
+ });
153
+ it('renders a plain string tooltip', () => {
154
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)('just text', htmlRenderer, openerService, toDispose);
155
+ (0, chai_1.expect)(tooltip, 'tooltip').to.not.be.undefined;
156
+ (0, chai_1.expect)(tooltip.textContent).to.equal('just text');
157
+ });
158
+ it('returns undefined when the provider supplies no usable content', () => {
159
+ (0, chai_1.expect)((0, scm_history_graph_tooltip_1.buildProviderTooltip)(' ', htmlRenderer, openerService, toDispose)).to.be.undefined;
160
+ (0, chai_1.expect)((0, scm_history_graph_tooltip_1.buildProviderTooltip)([], htmlRenderer, openerService, toDispose)).to.be.undefined;
161
+ });
162
+ it('routes an author mailto link through the opener service', async () => {
163
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)(new markdown_string_1.MarkdownStringImpl('<a href="mailto:jane@example.com">Jane Doe</a>'), htmlRenderer, openerService, toDispose);
164
+ await click(tooltip, 'a[href^="mailto:"]');
165
+ (0, chai_1.expect)(opened).to.deep.equal(['mailto:jane@example.com']);
166
+ });
167
+ it('executes a command link that the section trusts', async () => {
168
+ const section = new markdown_string_1.MarkdownStringImpl('<a href="command:git.viewCommit">Open Commit</a>');
169
+ section.isTrusted = { enabledCommands: ['git.viewCommit'] };
170
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)(section, htmlRenderer, openerService, toDispose);
171
+ await click(tooltip, 'a[href^="command:"]');
172
+ (0, chai_1.expect)(opened).to.deep.equal(['command:git.viewCommit']);
173
+ });
174
+ it('blocks a command link that the section does not trust', async () => {
175
+ const section = new markdown_string_1.MarkdownStringImpl('<a href="command:git.viewCommit">Open Commit</a>');
176
+ section.isTrusted = { enabledCommands: ['git.copyContentToClipboard'] };
177
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)(section, htmlRenderer, openerService, toDispose);
178
+ await click(tooltip, 'a[href^="command:"]');
179
+ (0, chai_1.expect)(opened).to.be.empty;
180
+ });
181
+ it('does not open a link twice when the renderer already wired it', async () => {
182
+ // The Monaco-based renderer used at runtime routes link activation through the opener
183
+ // service itself, so wiring a second handler on top would open every link twice.
184
+ const wiringRenderer = {
185
+ render: (markdown) => {
186
+ const element = document.createElement('div');
187
+ element.innerHTML = markdown.value;
188
+ (0, markdown_link_handler_1.markMarkdownLinksWired)(element);
189
+ element.addEventListener('click', event => {
190
+ event.preventDefault();
191
+ opened.push(event.target.getAttribute('href'));
192
+ });
193
+ return { element, dispose: () => { } };
194
+ }
195
+ };
196
+ const section = new markdown_string_1.MarkdownStringImpl('<a href="command:git.viewCommit">Open Commit</a>');
197
+ section.isTrusted = { enabledCommands: ['git.viewCommit'] };
198
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)(section, wiringRenderer, openerService, toDispose);
199
+ await click(tooltip, 'a[href^="command:"]');
200
+ (0, chai_1.expect)(opened).to.deep.equal(['command:git.viewCommit']);
201
+ });
202
+ it('does not let one section authorize another section\'s commands', async () => {
203
+ const untrusted = new markdown_string_1.MarkdownStringImpl('<a id="untrusted" href="command:git.viewCommit">Open Commit</a>');
204
+ const trusted = new markdown_string_1.MarkdownStringImpl('<a id="trusted" href="command:git.copyContentToClipboard">Copy</a>');
205
+ trusted.isTrusted = { enabledCommands: ['git.copyContentToClipboard'] };
206
+ const tooltip = (0, scm_history_graph_tooltip_1.buildProviderTooltip)([untrusted, trusted], htmlRenderer, openerService, toDispose);
207
+ await click(tooltip, 'a#untrusted');
208
+ (0, chai_1.expect)(opened, 'untrusted section').to.be.empty;
209
+ await click(tooltip, 'a#trusted');
210
+ (0, chai_1.expect)(opened, 'trusted section').to.deep.equal(['command:git.copyContentToClipboard']);
211
+ });
212
+ });
213
+ //# sourceMappingURL=scm-history-graph-tooltip.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scm-history-graph-tooltip.spec.js","sourceRoot":"","sources":["../../src/browser/scm-history-graph-tooltip.spec.ts"],"names":[],"mappings":"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"}
@@ -2,33 +2,42 @@ import * as React from '@theia/core/shared/react';
2
2
  import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
3
3
  import { LabelProvider } from '@theia/core/lib/browser/label-provider';
4
4
  import { HoverService } from '@theia/core/lib/browser/hover-service';
5
+ import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';
5
6
  import { MarkdownRenderer, MarkdownRendererFactory } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
6
7
  import { ScmHistoryGraphModel, HistoryGraphEntry } from './scm-history-graph-model';
7
8
  import { ScmHistoryItemRef, ScmHistoryItemChange } from './scm-provider';
8
9
  import { ScmService } from './scm-service';
9
10
  import { GraphRow } from './scm-history-graph-lanes';
10
11
  import { CancellationTokenSource } from '@theia/core/lib/common/cancellation';
12
+ import { DisposableCollection } from '@theia/core/lib/common/disposable';
13
+ import { Emitter, Event } from '@theia/core/lib/common/event';
14
+ import { DynamicToolbarWidget } from '@theia/core/lib/browser/view-container';
11
15
  import { MenuPath } from '@theia/core/lib/common/menu/menu-types';
12
16
  import { ContextMenuRenderer } from '@theia/core/lib/browser/context-menu-renderer';
13
17
  import { OpenerService } from '@theia/core/lib/browser/opener-service';
14
18
  import { ScmContextKeyService } from './scm-context-key-service';
19
+ import { ScmPreferences } from '../common/scm-preferences';
20
+ import { ILogger } from '@theia/core';
15
21
  /** Menu path matching the VS Code 'scm/history/title' contribution point (graph section toolbar). */
16
22
  export declare const SCM_HISTORY_TITLE_MENU: MenuPath;
17
23
  /** Menu path matching the VS Code 'scm/historyItem/context' contribution point (commit row context menu). */
18
24
  export declare const SCM_HISTORY_ITEM_CONTEXT_MENU: MenuPath;
19
25
  /** Menu path matching the VS Code 'scm/historyItemRef/context' contribution point (ref badge context menu). */
20
26
  export declare const SCM_HISTORY_ITEM_REF_CONTEXT_MENU: MenuPath;
21
- export declare class ScmHistoryGraphWidget extends ReactWidget {
27
+ export declare class ScmHistoryGraphWidget extends ReactWidget implements DynamicToolbarWidget {
22
28
  static readonly ID = "scm-history-graph-widget";
23
29
  static readonly LABEL: string;
24
30
  protected readonly model: ScmHistoryGraphModel;
25
31
  protected readonly hoverService: HoverService;
32
+ protected readonly clipboardService: ClipboardService;
26
33
  protected readonly markdownRendererFactory: MarkdownRendererFactory;
27
34
  protected readonly scmService: ScmService;
28
35
  protected readonly labelProvider: LabelProvider;
29
36
  protected readonly contextMenuRenderer: ContextMenuRenderer;
30
37
  protected readonly openerService: OpenerService;
31
38
  protected readonly scmContextKeys: ScmContextKeyService;
39
+ protected readonly scmPreferences: ScmPreferences;
40
+ protected readonly logger: ILogger;
32
41
  protected selectedIndex: number;
33
42
  /** Currently selected change row key (`${itemId}-${ci}`), or undefined. */
34
43
  protected selectedChangeKey: string | undefined;
@@ -38,6 +47,11 @@ export declare class ScmHistoryGraphWidget extends ReactWidget {
38
47
  protected expandedIds: Set<string>;
39
48
  /** Map from commit id → in-flight CancellationTokenSource for loadChanges. */
40
49
  protected loadChangesCts: Map<string, CancellationTokenSource>;
50
+ /** Cleanup for the content of the hover currently being shown. */
51
+ protected readonly toDisposeOnHover: DisposableCollection;
52
+ protected readonly onDidChangeToolbarItemsEmitter: Emitter<void>;
53
+ /** Re-renders the part toolbar on model changes, e.g. to reflect the toggled state of the ref filter picker. */
54
+ readonly onDidChangeToolbarItems: Event<void>;
41
55
  constructor();
42
56
  protected init(): void;
43
57
  protected updateContextKeys(): void;
@@ -47,6 +61,14 @@ export declare class ScmHistoryGraphWidget extends ReactWidget {
47
61
  protected _markdownRenderer: MarkdownRenderer | undefined;
48
62
  protected get markdownRenderer(): MarkdownRenderer;
49
63
  protected handleRowMouseEnter: (e: React.MouseEvent<HTMLDivElement>, entry: HistoryGraphEntry) => void;
64
+ /**
65
+ * Prefers the hover content supplied by the provider, so that its own links and commands
66
+ * (author `mailto:`, "Open Commit", remote actions) stay intact, and falls back to the hover
67
+ * derived from the history item's fields for providers that supply none.
68
+ */
69
+ protected buildTooltip(entry: HistoryGraphEntry): HTMLElement;
70
+ /** Selects the commit and expands its changes, closing the hover first. */
71
+ protected openCommitFromTooltip(entry: HistoryGraphEntry): void;
50
72
  protected renderChangesRows(itemId: string, svgWidth: number, graphRow: GraphRow, changes: ScmHistoryItemChange[] | 'loading' | undefined): React.ReactElement;
51
73
  protected renderChangeRow(change: ScmHistoryItemChange, ci: number, itemId: string, svgWidth: number, graphRow: GraphRow): React.ReactElement;
52
74
  protected handleChangeClick: (e: React.MouseEvent, change: ScmHistoryItemChange, changeKey: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"scm-history-graph-widget.d.ts","sourceRoot":"","sources":["../../src/browser/scm-history-graph-widget.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scm-history-graph-widget.d.ts","sourceRoot":"","sources":["../../src/browser/scm-history-graph-widget.tsx"],"names":[],"mappings":"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"}
@@ -24,17 +24,22 @@ const inversify_1 = require("@theia/core/shared/inversify");
24
24
  const react_widget_1 = require("@theia/core/lib/browser/widgets/react-widget");
25
25
  const label_provider_1 = require("@theia/core/lib/browser/label-provider");
26
26
  const hover_service_1 = require("@theia/core/lib/browser/hover-service");
27
+ const clipboard_service_1 = require("@theia/core/lib/browser/clipboard-service");
27
28
  const markdown_renderer_1 = require("@theia/core/lib/browser/markdown-rendering/markdown-renderer");
28
29
  const scm_history_graph_model_1 = require("./scm-history-graph-model");
29
30
  const scm_service_1 = require("./scm-service");
30
31
  const uri_1 = require("@theia/core/lib/common/uri");
31
32
  const nls_1 = require("@theia/core/lib/common/nls");
32
33
  const cancellation_1 = require("@theia/core/lib/common/cancellation");
34
+ const disposable_1 = require("@theia/core/lib/common/disposable");
35
+ const event_1 = require("@theia/core/lib/common/event");
33
36
  const context_menu_renderer_1 = require("@theia/core/lib/browser/context-menu-renderer");
34
37
  const opener_service_1 = require("@theia/core/lib/browser/opener-service");
35
38
  const diff_uris_1 = require("@theia/core/lib/browser/diff-uris");
36
39
  const scm_context_key_service_1 = require("./scm-context-key-service");
40
+ const scm_preferences_1 = require("../common/scm-preferences");
37
41
  const scm_history_graph_helpers_1 = require("./scm-history-graph-helpers");
42
+ const core_1 = require("@theia/core");
38
43
  const scm_history_graph_tooltip_1 = require("./scm-history-graph-tooltip");
39
44
  /** Menu path matching the VS Code 'scm/history/title' contribution point (graph section toolbar). */
40
45
  exports.SCM_HISTORY_TITLE_MENU = ['plugin_scm/history/title'];
@@ -68,14 +73,20 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
68
73
  this.expandedIds = new Set();
69
74
  /** Map from commit id → in-flight CancellationTokenSource for loadChanges. */
70
75
  this.loadChangesCts = new Map();
76
+ /** Cleanup for the content of the hover currently being shown. */
77
+ this.toDisposeOnHover = new disposable_1.DisposableCollection();
78
+ this.onDidChangeToolbarItemsEmitter = new event_1.Emitter();
79
+ /** Re-renders the part toolbar on model changes, e.g. to reflect the toggled state of the ref filter picker. */
80
+ this.onDidChangeToolbarItems = this.onDidChangeToolbarItemsEmitter.event;
71
81
  this.handleEndReached = () => {
72
82
  if (this.model.hasMore && !this.model.loading) {
73
83
  this.model.loadMore();
74
84
  }
75
85
  };
76
86
  this.handleRowMouseEnter = (e, entry) => {
87
+ this.toDisposeOnHover.dispose();
77
88
  this.hoverService.requestHover({
78
- content: (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(entry, this.markdownRenderer),
89
+ content: this.buildTooltip(entry),
79
90
  target: e.currentTarget,
80
91
  position: 'right',
81
92
  interactive: true,
@@ -167,9 +178,16 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
167
178
  this.node.tabIndex = 0;
168
179
  }
169
180
  init() {
181
+ this.toDispose.push(this.onDidChangeToolbarItemsEmitter);
170
182
  this.toDispose.push(this.model.onDidChange(() => {
171
183
  this.updateContextKeys();
172
184
  this.update();
185
+ this.onDidChangeToolbarItemsEmitter.fire();
186
+ }));
187
+ this.toDispose.push(this.scmPreferences.onPreferenceChanged(e => {
188
+ if (e.preferenceName.startsWith('scm.graph.')) {
189
+ this.update();
190
+ }
173
191
  }));
174
192
  this.toDispose.push({
175
193
  dispose: () => {
@@ -180,12 +198,15 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
180
198
  this.loadChangesCts.clear();
181
199
  }
182
200
  });
201
+ this.toDispose.push(this.toDisposeOnHover);
183
202
  this.update();
184
203
  }
185
204
  updateContextKeys() {
186
205
  const provider = this.model.provider;
187
206
  this.scmContextKeys.scmCurrentHistoryItemRefHasRemote.set(!!provider?.currentHistoryItemRemoteRef);
188
207
  this.scmContextKeys.scmCurrentHistoryItemRefHasBase.set(!!provider?.currentHistoryItemBaseRef);
208
+ // Commands like git.pullRef/git.pushRef gate their enablement on this key.
209
+ this.scmContextKeys.scmCurrentHistoryItemRefInFilter.set(!!provider?.currentHistoryItemRef && this.model.isCurrentRefInFilter());
189
210
  }
190
211
  render() {
191
212
  const { entries, hasMore, loading } = this.model;
@@ -209,15 +230,14 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
209
230
  : hasMore
210
231
  ? () => (React.createElement("div", { className: 'scm-history-load-more', onClick: this.handleLoadMore, role: 'button', tabIndex: 0, onKeyDown: this.handleLoadMoreKey }, nls_1.nls.localizeByDefault('Load more')))
211
232
  : undefined;
212
- return (React.createElement(react_virtuoso_1.Virtuoso, { className: 'scm-history-graph-list', data: entries, itemContent: (idx, entry) => this.renderRow(entry, idx, svgWidth), endReached: hasMore && !loading ? this.handleEndReached : undefined, overscan: 500, components: footer ? { Footer: footer } : {}, style: { overflowX: 'hidden' } }));
233
+ return (React.createElement(react_virtuoso_1.Virtuoso, { className: 'scm-history-graph-list', data: entries, itemContent: (idx, entry) => this.renderRow(entry, idx, svgWidth), endReached: hasMore && !loading && this.scmPreferences['scm.graph.pageOnScroll'] !== false ? this.handleEndReached : undefined, overscan: 500, components: footer ? { Footer: footer } : {}, style: { overflowX: 'hidden' } }));
213
234
  }
214
235
  renderRow(entry, idx, svgWidth) {
215
236
  const { item, graphRow } = entry;
216
237
  const isSelected = idx === this.selectedIndex;
217
238
  const isExpanded = this.expandedIds.has(item.id);
218
239
  const changes = this.expandedChanges.get(item.id);
219
- // The first commit (idx === 0) on lane 0 is treated as HEAD/current
220
- const isHead = idx === 0 && graphRow.lane === 0;
240
+ const isHead = entry.isCurrent;
221
241
  return (React.createElement(React.Fragment, { key: item.id },
222
242
  React.createElement("div", { className: `scm-history-graph-row${isSelected ? ' selected' : ''}`, onClick: () => this.handleRowClick(idx, entry), onContextMenu: e => this.handleRowContextMenu(e, entry), onMouseEnter: e => this.handleRowMouseEnter(e, entry) },
223
243
  this.renderGraphSvg(graphRow, svgWidth, isHead),
@@ -231,6 +251,39 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
231
251
  this._markdownRenderer ||= this.markdownRendererFactory();
232
252
  return this._markdownRenderer;
233
253
  }
254
+ /**
255
+ * Prefers the hover content supplied by the provider, so that its own links and commands
256
+ * (author `mailto:`, "Open Commit", remote actions) stay intact, and falls back to the hover
257
+ * derived from the history item's fields for providers that supply none.
258
+ */
259
+ buildTooltip(entry) {
260
+ const { tooltip } = entry.item;
261
+ if (tooltip) {
262
+ const provided = (0, scm_history_graph_tooltip_1.buildProviderTooltip)(tooltip, this.markdownRenderer, this.openerService, this.toDisposeOnHover);
263
+ if (provided) {
264
+ return provided;
265
+ }
266
+ }
267
+ return (0, scm_history_graph_tooltip_1.buildHtmlTooltip)(entry, this.markdownRenderer, this.model.provider, {
268
+ openCommit: () => this.openCommitFromTooltip(entry),
269
+ copyCommitHash: () => this.clipboardService.writeText(entry.item.id),
270
+ });
271
+ }
272
+ /** Selects the commit and expands its changes, closing the hover first. */
273
+ openCommitFromTooltip(entry) {
274
+ this.hoverService.cancelHover();
275
+ const idx = this.model.entries.indexOf(entry);
276
+ if (idx < 0) {
277
+ return;
278
+ }
279
+ if (this.expandedIds.has(entry.item.id)) {
280
+ this.selectedIndex = idx;
281
+ this.update();
282
+ }
283
+ else {
284
+ this.handleRowClick(idx, entry);
285
+ }
286
+ }
234
287
  renderChangesRows(itemId, svgWidth, graphRow, changes) {
235
288
  if (changes === 'loading' || changes === undefined) {
236
289
  return (React.createElement("div", { key: `${itemId}-loading`, className: 'scm-history-changes-loading' }, nls_1.nls.localizeByDefault('Loading')));
@@ -282,7 +335,7 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
282
335
  }
283
336
  }
284
337
  catch (err) {
285
- console.error('ScmHistoryGraphWidget: failed to open change', err);
338
+ this.logger.error('Failed to open change', err);
286
339
  }
287
340
  }
288
341
  renderChangeRowSvg(graphRow, svgWidth) {
@@ -345,9 +398,11 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
345
398
  }
346
399
  // Commit lane lines — split at cy=11
347
400
  // Top segment: only drawn if there is an incoming line from above
348
- // (i.e. this commit was referenced as a parent by an earlier row)
401
+ // (i.e. this commit was referenced as a parent by an earlier row).
402
+ // It keeps the color inherited from the chain above, which may differ
403
+ // from the commit's own (ref-based) color.
349
404
  if (row.hasTopLine) {
350
- elements.push(React.createElement("path", { key: `top-${keyIdx++}`, fill: 'none', strokeWidth: '1px', strokeLinecap: 'round', d: `M ${commitX} 0 V ${cy}`, style: { stroke: commitColor } }));
405
+ elements.push(React.createElement("path", { key: `top-${keyIdx++}`, fill: 'none', strokeWidth: '1px', strokeLinecap: 'round', d: `M ${commitX} 0 V ${cy}`, style: { stroke: (0, scm_history_graph_helpers_1.laneColor)(row.topColor) } }));
351
406
  }
352
407
  // Bottom segment: only drawn if the lane continues to a parent below
353
408
  if (row.hasContinuation) {
@@ -381,11 +436,14 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
381
436
  if (!refs || refs.length === 0) {
382
437
  return undefined;
383
438
  }
439
+ const provider = this.model.provider;
440
+ const visibleRefs = (0, scm_history_graph_helpers_1.filterRefsForBadges)(refs, provider, this.scmPreferences['scm.graph.badges'] ?? 'filter', this.model.historyItemRefFilter);
441
+ if (visibleRefs.length === 0) {
442
+ return undefined;
443
+ }
384
444
  const laneColorValue = entry ? (0, scm_history_graph_helpers_1.laneColor)(entry.graphRow.color) : undefined;
385
- const deduplicated = (0, scm_history_graph_helpers_1.deduplicateRefs)(refs);
386
- const style = laneColorValue
387
- ? { backgroundColor: laneColorValue, color: 'var(--theia-scmGraph-historyItemRefForeground, var(--theia-badge-foreground))' }
388
- : {};
445
+ const deduplicated = (0, scm_history_graph_helpers_1.deduplicateRefs)(visibleRefs);
446
+ const badgeForeground = 'var(--theia-scmGraph-historyItemRefForeground, var(--theia-badge-foreground))';
389
447
  const badges = [];
390
448
  for (const info of deduplicated) {
391
449
  if (badges.length >= 3) {
@@ -395,18 +453,16 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
395
453
  const isTag = (0, scm_history_graph_helpers_1.isTagRef)(ref);
396
454
  const isRemote = (0, scm_history_graph_helpers_1.isRemoteRef)(ref);
397
455
  const onContextMenu = entry ? (e) => this.handleRefBadgeContextMenu(e, entry, ref) : undefined;
398
- if (isTag) {
399
- badges.push(renderJsxRefBadge(ref, 'codicon-tag', false, style, ref.id, onContextMenu));
400
- }
401
- else if (isRemote) {
402
- badges.push(renderJsxRefBadge(ref, 'codicon-cloud', true, style, ref.id, onContextMenu));
403
- }
404
- else {
405
- badges.push(renderJsxRefBadge(ref, 'codicon-git-branch', true, style, ref.id, onContextMenu));
406
- if (hasBoth && badges.length < 3) {
407
- badges.push(React.createElement("span", { key: `${ref.id}-cloud`, className: 'scm-history-ref-badge scm-history-ref-badge-cloud', title: ref.description ?? ref.name, style: style },
408
- React.createElement("i", { className: 'codicon codicon-cloud scm-history-ref-icon' })));
409
- }
456
+ // Current/remote/base refs are colored by role, others by the row's lane color
457
+ const { iconClass, colorIndex } = (0, scm_history_graph_helpers_1.getRefBadgePresentation)(ref, provider);
458
+ const backgroundColor = colorIndex !== undefined ? (0, scm_history_graph_helpers_1.laneColor)(colorIndex) : laneColorValue;
459
+ const style = backgroundColor
460
+ ? { backgroundColor, color: badgeForeground }
461
+ : {};
462
+ badges.push(renderJsxRefBadge(ref, iconClass, !isTag, style, ref.id, onContextMenu));
463
+ if (!isTag && !isRemote && hasBoth && badges.length < 3) {
464
+ badges.push(React.createElement("span", { key: `${ref.id}-cloud`, className: 'scm-history-ref-badge scm-history-ref-badge-cloud', title: ref.description ?? ref.name, style: style },
465
+ React.createElement("i", { className: 'codicon codicon-cloud scm-history-ref-icon' })));
410
466
  }
411
467
  }
412
468
  return badges;
@@ -434,7 +490,7 @@ let ScmHistoryGraphWidget = class ScmHistoryGraphWidget extends react_widget_1.R
434
490
  }
435
491
  catch (err) {
436
492
  if (!cts.token.isCancellationRequested) {
437
- console.error('ScmHistoryGraphWidget: failed to load changes', err);
493
+ this.logger.error('Failed to load changes', err);
438
494
  this.expandedChanges.set(item.id, []);
439
495
  this.update();
440
496
  }
@@ -453,6 +509,10 @@ tslib_1.__decorate([
453
509
  (0, inversify_1.inject)(hover_service_1.HoverService),
454
510
  tslib_1.__metadata("design:type", hover_service_1.HoverService)
455
511
  ], ScmHistoryGraphWidget.prototype, "hoverService", void 0);
512
+ tslib_1.__decorate([
513
+ (0, inversify_1.inject)(clipboard_service_1.ClipboardService),
514
+ tslib_1.__metadata("design:type", Object)
515
+ ], ScmHistoryGraphWidget.prototype, "clipboardService", void 0);
456
516
  tslib_1.__decorate([
457
517
  (0, inversify_1.inject)(markdown_renderer_1.MarkdownRendererFactory),
458
518
  tslib_1.__metadata("design:type", Function)
@@ -477,6 +537,15 @@ tslib_1.__decorate([
477
537
  (0, inversify_1.inject)(scm_context_key_service_1.ScmContextKeyService),
478
538
  tslib_1.__metadata("design:type", scm_context_key_service_1.ScmContextKeyService)
479
539
  ], ScmHistoryGraphWidget.prototype, "scmContextKeys", void 0);
540
+ tslib_1.__decorate([
541
+ (0, inversify_1.inject)(scm_preferences_1.ScmPreferences),
542
+ tslib_1.__metadata("design:type", Object)
543
+ ], ScmHistoryGraphWidget.prototype, "scmPreferences", void 0);
544
+ tslib_1.__decorate([
545
+ (0, inversify_1.inject)(core_1.ILogger),
546
+ (0, inversify_1.named)('scm:ScmHistoryGraphWidget'),
547
+ tslib_1.__metadata("design:type", Object)
548
+ ], ScmHistoryGraphWidget.prototype, "logger", void 0);
480
549
  tslib_1.__decorate([
481
550
  (0, inversify_1.postConstruct)(),
482
551
  tslib_1.__metadata("design:type", Function),