@codingame/monaco-vscode-welcome-service-override 1.85.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 (53) hide show
  1. package/assets/commandPalette.svg +50 -0
  2. package/assets/dark-hc.png +0 -0
  3. package/assets/dark.png +0 -0
  4. package/assets/debug.svg +87 -0
  5. package/assets/extensions-web.svg +216 -0
  6. package/assets/extensions.svg +236 -0
  7. package/assets/git.svg +105 -0
  8. package/assets/languages.svg +88 -0
  9. package/assets/learn.svg +85 -0
  10. package/assets/light-hc.png +0 -0
  11. package/assets/light.png +0 -0
  12. package/assets/menuBar.svg +100 -0
  13. package/assets/openFolder.svg +91 -0
  14. package/assets/profiles.svg +47 -0
  15. package/assets/runTask.svg +42 -0
  16. package/assets/search.svg +48 -0
  17. package/assets/settings.svg +53 -0
  18. package/assets/settingsSync.svg +148 -0
  19. package/assets/shortcuts.svg +180 -0
  20. package/assets/terminal.svg +42 -0
  21. package/assets/workspaceTrust.svg +43 -0
  22. package/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
  23. package/external/tslib/tslib.es6.js +11 -0
  24. package/index.d.ts +1 -0
  25. package/index.js +1 -0
  26. package/package.json +24 -0
  27. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.js +366 -0
  28. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.js +1461 -0
  29. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedColors.js +38 -0
  30. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedDetailsRenderer.js +263 -0
  31. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedIcons.js +16 -0
  32. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedInput.js +53 -0
  33. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedList.js +97 -0
  34. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/media/gettingStarted.css.js +6 -0
  35. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/browser/startupPage.js +205 -0
  36. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/common/media/all.png.js +8 -0
  37. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/common/media/all.svg.js +21 -0
  38. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/common/media/notebookProfile.js +37 -0
  39. package/vscode/src/vs/workbench/contrib/welcomeGettingStarted/common/media/theme_picker.js +53 -0
  40. package/vscode/src/vs/workbench/contrib/welcomeViews/common/newFile.contribution.js +240 -0
  41. package/vscode/src/vs/workbench/contrib/welcomeViews/common/viewsWelcome.contribution.js +19 -0
  42. package/vscode/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeContribution.js +75 -0
  43. package/vscode/src/vs/workbench/contrib/welcomeViews/common/viewsWelcomeExtensionPoint.js +99 -0
  44. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/editor/editorWalkThrough.js +62 -0
  45. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/editor/vs_code_editor_walkthrough.js +190 -0
  46. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/media/walkThroughPart.css.js +6 -0
  47. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThrough.contribution.js +40 -0
  48. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughActions.js +59 -0
  49. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughInput.js +115 -0
  50. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/browser/walkThroughPart.js +434 -0
  51. package/vscode/src/vs/workbench/contrib/welcomeWalkthrough/common/walkThroughContentProvider.js +75 -0
  52. package/welcome.d.ts +5 -0
  53. package/welcome.js +25 -0
@@ -0,0 +1,1461 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { $, getWindow, addDisposableListener, clearNode, reset, append } from 'monaco-editor/esm/vs/base/browser/dom.js';
3
+ import { renderFormattedText } from 'monaco-editor/esm/vs/base/browser/formattedTextRenderer.js';
4
+ import { StandardKeyboardEvent } from 'monaco-editor/esm/vs/base/browser/keyboardEvent.js';
5
+ import { Button } from 'monaco-editor/esm/vs/base/browser/ui/button/button.js';
6
+ import { renderLabelWithIcons } from 'monaco-editor/esm/vs/base/browser/ui/iconLabel/iconLabels.js';
7
+ import { DomScrollableElement } from 'monaco-editor/esm/vs/base/browser/ui/scrollbar/scrollableElement.js';
8
+ import { Toggle } from 'monaco-editor/esm/vs/base/browser/ui/toggle/toggle.js';
9
+ import { flatten, coalesce, equals } from 'monaco-editor/esm/vs/base/common/arrays.js';
10
+ import { Throttler, Delayer } from 'monaco-editor/esm/vs/base/common/async.js';
11
+ import { Codicon } from 'monaco-editor/esm/vs/base/common/codicons.js';
12
+ import { onUnexpectedError } from 'monaco-editor/esm/vs/base/common/errors.js';
13
+ import { splitRecentLabel } from 'monaco-editor/esm/vs/base/common/labels.js';
14
+ import { DisposableStore, toDisposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
15
+ import { parse } from 'monaco-editor/esm/vs/base/common/marshalling.js';
16
+ import { matchesScheme, Schemas } from 'monaco-editor/esm/vs/base/common/network.js';
17
+ import { isMacintosh } from 'monaco-editor/esm/vs/base/common/platform.js';
18
+ import { ThemeIcon } from 'monaco-editor/esm/vs/base/common/themables.js';
19
+ import { assertIsDefined } from 'monaco-editor/esm/vs/base/common/types.js';
20
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
21
+ import { generateUuid } from 'monaco-editor/esm/vs/base/common/uuid.js';
22
+ import './media/gettingStarted.css.js';
23
+ import { ILanguageService } from 'monaco-editor/esm/vs/editor/common/languages/language.js';
24
+ import { MarkdownRenderer } from 'monaco-editor/esm/vs/editor/contrib/markdownRenderer/browser/markdownRenderer.js';
25
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
26
+ import { IAccessibilityService } from 'monaco-editor/esm/vs/platform/accessibility/common/accessibility.js';
27
+ import { ICommandService } from 'monaco-editor/esm/vs/platform/commands/common/commands.js';
28
+ import { IConfigurationService } from 'monaco-editor/esm/vs/platform/configuration/common/configuration.js';
29
+ import { RawContextKey, ContextKeyExpr, IContextKeyService } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkey.js';
30
+ import { IExtensionManagementService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
31
+ import { ExtensionIdentifier } from 'monaco-editor/esm/vs/platform/extensions/common/extensions.js';
32
+ import { IFileService } from 'monaco-editor/esm/vs/platform/files/common/files.js';
33
+ import { IInstantiationService } from 'monaco-editor/esm/vs/platform/instantiation/common/instantiation.js';
34
+ import { IKeybindingService } from 'monaco-editor/esm/vs/platform/keybinding/common/keybinding.js';
35
+ import { ILabelService } from 'monaco-editor/esm/vs/platform/label/common/label.js';
36
+ import { INotificationService } from 'monaco-editor/esm/vs/platform/notification/common/notification.js';
37
+ import { Link } from 'monaco-editor/esm/vs/platform/opener/browser/link.js';
38
+ import { IOpenerService } from 'monaco-editor/esm/vs/platform/opener/common/opener.js';
39
+ import { IProductService } from 'monaco-editor/esm/vs/platform/product/common/productService.js';
40
+ import { IQuickInputService } from 'monaco-editor/esm/vs/platform/quickinput/common/quickInput.js';
41
+ import { IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
42
+ import { firstSessionDateStorageKey, ITelemetryService } from 'monaco-editor/esm/vs/platform/telemetry/common/telemetry.js';
43
+ import { getTelemetryLevel } from 'vscode/vscode/vs/platform/telemetry/common/telemetryUtils';
44
+ import { defaultToggleStyles, defaultButtonStyles } from 'monaco-editor/esm/vs/platform/theme/browser/defaultStyles.js';
45
+ import { IThemeService } from 'monaco-editor/esm/vs/platform/theme/common/themeService.js';
46
+ import { UNKNOWN_EMPTY_WINDOW_WORKSPACE, IWorkspaceContextService } from 'monaco-editor/esm/vs/platform/workspace/common/workspace.js';
47
+ import { isRecentWorkspace, isRecentFolder, IWorkspacesService } from 'vscode/vscode/vs/platform/workspaces/common/workspaces';
48
+ import { OpenRecentAction } from 'vscode/vscode/vs/workbench/browser/actions/windowActions';
49
+ import { OpenFolderViaWorkspaceAction, OpenFileFolderAction, OpenFolderAction } from 'vscode/vscode/vs/workbench/browser/actions/workspaceActions';
50
+ import { EditorPane } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorPane';
51
+ import { WorkbenchStateContext } from 'vscode/vscode/vs/workbench/common/contextkeys';
52
+ import { IWebviewService } from 'vscode/vscode/vs/workbench/contrib/webview/browser/webview';
53
+ import { IFeaturedExtensionsService } from 'vscode/vscode/vs/workbench/contrib/welcomeGettingStarted/browser/featuredExtensionService';
54
+ import './gettingStartedColors.js';
55
+ import { GettingStartedDetailsRenderer } from './gettingStartedDetailsRenderer.js';
56
+ import { gettingStartedUncheckedCodicon, gettingStartedCheckedCodicon } from './gettingStartedIcons.js';
57
+ import { GettingStartedInput } from './gettingStartedInput.js';
58
+ import { hiddenEntriesConfigurationKey, IWalkthroughsService } from 'vscode/vscode/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedService';
59
+ import { restoreWalkthroughsConfigurationKey } from './startupPage.js';
60
+ import { startEntries } from 'vscode/vscode/vs/workbench/contrib/welcomeGettingStarted/common/gettingStartedContent';
61
+ import { IEditorGroupsService } from 'vscode/vscode/vs/workbench/services/editor/common/editorGroupsService';
62
+ import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
63
+ import { IHostService } from 'vscode/vscode/vs/workbench/services/host/browser/host';
64
+ import { ThemeSettings } from 'vscode/vscode/vs/workbench/services/themes/common/workbenchThemeService';
65
+ import { GettingStartedIndexList } from './gettingStartedList.js';
66
+
67
+ var GettingStartedPage_1;
68
+ const SLIDE_TRANSITION_TIME_MS = 250;
69
+ const configurationKey = 'workbench.startupEditor';
70
+ const allWalkthroughsHiddenContext = ( new RawContextKey('allWalkthroughsHidden', false));
71
+ const inWelcomeContext = ( new RawContextKey('inWelcome', false));
72
+ const parsedStartEntries = ( startEntries.map((e, i) => ({
73
+ command: e.content.command,
74
+ description: e.description,
75
+ icon: { type: 'icon', icon: e.icon },
76
+ id: e.id,
77
+ order: i,
78
+ title: e.title,
79
+ when: ContextKeyExpr.deserialize(e.when) ?? ContextKeyExpr.true()
80
+ })));
81
+ const REDUCED_MOTION_KEY = 'workbench.welcomePage.preferReducedMotion';
82
+ let GettingStartedPage = class GettingStartedPage extends EditorPane {
83
+ static { GettingStartedPage_1 = this; }
84
+ static { this.ID = 'gettingStartedPage'; }
85
+ constructor(commandService, productService, keybindingService, gettingStartedService, featuredExtensionService, configurationService, telemetryService, languageService, fileService, openerService, themeService, storageService, extensionService, instantiationService, notificationService, groupsService, contextService, quickInputService, workspacesService, labelService, hostService, webviewService, workspaceContextService, accessibilityService, extensionManagementService) {
86
+ super(GettingStartedPage_1.ID, telemetryService, themeService, storageService);
87
+ this.commandService = commandService;
88
+ this.productService = productService;
89
+ this.keybindingService = keybindingService;
90
+ this.gettingStartedService = gettingStartedService;
91
+ this.featuredExtensionService = featuredExtensionService;
92
+ this.configurationService = configurationService;
93
+ this.languageService = languageService;
94
+ this.fileService = fileService;
95
+ this.openerService = openerService;
96
+ this.storageService = storageService;
97
+ this.extensionService = extensionService;
98
+ this.instantiationService = instantiationService;
99
+ this.notificationService = notificationService;
100
+ this.groupsService = groupsService;
101
+ this.quickInputService = quickInputService;
102
+ this.workspacesService = workspacesService;
103
+ this.labelService = labelService;
104
+ this.hostService = hostService;
105
+ this.webviewService = webviewService;
106
+ this.workspaceContextService = workspaceContextService;
107
+ this.accessibilityService = accessibilityService;
108
+ this.extensionManagementService = extensionManagementService;
109
+ this.inProgressScroll = Promise.resolve();
110
+ this.dispatchListeners = ( new DisposableStore());
111
+ this.stepDisposables = ( new DisposableStore());
112
+ this.detailsPageDisposables = ( new DisposableStore());
113
+ this.mediaDisposables = ( new DisposableStore());
114
+ this.buildSlideThrottle = ( new Throttler());
115
+ this.hasScrolledToFirstCategory = false;
116
+ this.currentMediaComponent = undefined;
117
+ this.currentMediaType = undefined;
118
+ this.container = $('.gettingStartedContainer', {
119
+ role: 'document',
120
+ tabindex: 0,
121
+ 'aria-label': ( localizeWithPath(
122
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
123
+ 'welcomeAriaLabel',
124
+ "Overview of how to get up to speed with your editor."
125
+ ))
126
+ });
127
+ this.stepMediaComponent = $('.getting-started-media');
128
+ this.stepMediaComponent.id = generateUuid();
129
+ this.categoriesSlideDisposables = this._register(( new DisposableStore()));
130
+ this.detailsRenderer = ( new GettingStartedDetailsRenderer(
131
+ this.fileService,
132
+ this.notificationService,
133
+ this.extensionService,
134
+ this.languageService
135
+ ));
136
+ this.contextService = this._register(contextService.createScoped(this.container));
137
+ inWelcomeContext.bindTo(this.contextService).set(true);
138
+ this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
139
+ this.featuredExtensions = this.featuredExtensionService.getExtensions();
140
+ this._register(this.dispatchListeners);
141
+ this.buildSlideThrottle = ( new Throttler());
142
+ const rerender = () => {
143
+ this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
144
+ this.featuredExtensions = this.featuredExtensionService.getExtensions();
145
+ if (this.currentWalkthrough) {
146
+ const existingSteps = ( this.currentWalkthrough.steps.map(step => step.id));
147
+ const newCategory = this.gettingStartedCategories.find(category => this.currentWalkthrough?.id === category.id);
148
+ if (newCategory) {
149
+ const newSteps = ( newCategory.steps.map(step => step.id));
150
+ if (!equals(newSteps, existingSteps)) {
151
+ this.buildSlideThrottle.queue(() => this.buildCategoriesSlide());
152
+ }
153
+ }
154
+ }
155
+ else {
156
+ this.buildSlideThrottle.queue(() => this.buildCategoriesSlide());
157
+ }
158
+ };
159
+ this._register(this.extensionManagementService.onDidInstallExtensions(async (result) => {
160
+ for (const e of result) {
161
+ const installedFeaturedExtension = (await this.featuredExtensions)?.find(ext => ExtensionIdentifier.equals(ext.id, e.identifier.id));
162
+ if (installedFeaturedExtension) {
163
+ this.hideExtension(e.identifier.id);
164
+ }
165
+ }
166
+ }));
167
+ this._register(this.gettingStartedService.onDidAddWalkthrough(rerender));
168
+ this._register(this.gettingStartedService.onDidRemoveWalkthrough(rerender));
169
+ this.recentlyOpened = this.workspacesService.getRecentlyOpened();
170
+ this._register(workspacesService.onDidChangeRecentlyOpened(() => {
171
+ this.recentlyOpened = workspacesService.getRecentlyOpened();
172
+ rerender();
173
+ }));
174
+ this._register(this.gettingStartedService.onDidChangeWalkthrough(category => {
175
+ const ourCategory = this.gettingStartedCategories.find(c => c.id === category.id);
176
+ if (!ourCategory) {
177
+ return;
178
+ }
179
+ ourCategory.title = category.title;
180
+ ourCategory.description = category.description;
181
+ this.container.querySelectorAll(`[x-category-title-for="${category.id}"]`).forEach(step => step.innerText = ourCategory.title);
182
+ this.container.querySelectorAll(`[x-category-description-for="${category.id}"]`).forEach(step => step.innerText = ourCategory.description);
183
+ }));
184
+ this._register(this.gettingStartedService.onDidProgressStep(step => {
185
+ const category = this.gettingStartedCategories.find(category => category.id === step.category);
186
+ if (!category) {
187
+ throw Error('Could not find category with ID: ' + step.category);
188
+ }
189
+ const ourStep = category.steps.find(_step => _step.id === step.id);
190
+ if (!ourStep) {
191
+ throw Error('Could not find step with ID: ' + step.id);
192
+ }
193
+ const stats = this.getWalkthroughCompletionStats(category);
194
+ if (!ourStep.done && stats.stepsComplete === stats.stepsTotal - 1) {
195
+ this.hideCategory(category.id);
196
+ }
197
+ this._register(this.configurationService.onDidChangeConfiguration(e => {
198
+ if (e.affectsConfiguration(REDUCED_MOTION_KEY)) {
199
+ this.container.classList.toggle('animatable', this.shouldAnimate());
200
+ }
201
+ }));
202
+ ourStep.done = step.done;
203
+ if (category.id === this.currentWalkthrough?.id) {
204
+ const badgeelements = assertIsDefined(getWindow(this.container).document.querySelectorAll(`[data-done-step-id="${step.id}"]`));
205
+ badgeelements.forEach(badgeelement => {
206
+ if (step.done) {
207
+ badgeelement.parentElement?.setAttribute('aria-checked', 'true');
208
+ badgeelement.classList.remove(...ThemeIcon.asClassNameArray(gettingStartedUncheckedCodicon));
209
+ badgeelement.classList.add('complete', ...ThemeIcon.asClassNameArray(gettingStartedCheckedCodicon));
210
+ }
211
+ else {
212
+ badgeelement.parentElement?.setAttribute('aria-checked', 'false');
213
+ badgeelement.classList.remove('complete', ...ThemeIcon.asClassNameArray(gettingStartedCheckedCodicon));
214
+ badgeelement.classList.add(...ThemeIcon.asClassNameArray(gettingStartedUncheckedCodicon));
215
+ }
216
+ });
217
+ }
218
+ this.updateCategoryProgress();
219
+ }));
220
+ }
221
+ shouldAnimate() {
222
+ if (this.configurationService.getValue(REDUCED_MOTION_KEY)) {
223
+ return false;
224
+ }
225
+ if (this.accessibilityService.isMotionReduced()) {
226
+ return false;
227
+ }
228
+ return true;
229
+ }
230
+ getWalkthroughCompletionStats(walkthrough) {
231
+ const activeSteps = walkthrough.steps.filter(s => this.contextService.contextMatchesRules(s.when));
232
+ return {
233
+ stepsComplete: activeSteps.filter(s => s.done).length,
234
+ stepsTotal: activeSteps.length,
235
+ };
236
+ }
237
+ async setInput(newInput, options, context, token) {
238
+ this.container.classList.remove('animatable');
239
+ this.editorInput = newInput;
240
+ await super.setInput(newInput, options, context, token);
241
+ await this.buildCategoriesSlide();
242
+ if (this.shouldAnimate()) {
243
+ setTimeout(() => this.container.classList.add('animatable'), 0);
244
+ }
245
+ }
246
+ async makeCategoryVisibleWhenAvailable(categoryID, stepId) {
247
+ this.scrollToCategory(categoryID, stepId);
248
+ }
249
+ registerDispatchListeners() {
250
+ this.dispatchListeners.clear();
251
+ this.container.querySelectorAll('[x-dispatch]').forEach(element => {
252
+ const [command, argument] = (element.getAttribute('x-dispatch') ?? '').split(':');
253
+ if (command) {
254
+ this.dispatchListeners.add(addDisposableListener(element, 'click', (e) => {
255
+ e.stopPropagation();
256
+ this.runDispatchCommand(command, argument);
257
+ }));
258
+ this.dispatchListeners.add(addDisposableListener(element, 'keyup', (e) => {
259
+ const keyboardEvent = ( new StandardKeyboardEvent(e));
260
+ e.stopPropagation();
261
+ switch (keyboardEvent.keyCode) {
262
+ case 3 :
263
+ case 10 :
264
+ this.runDispatchCommand(command, argument);
265
+ return;
266
+ }
267
+ }));
268
+ }
269
+ });
270
+ }
271
+ async runDispatchCommand(command, argument) {
272
+ this.commandService.executeCommand('workbench.action.keepEditor');
273
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command, argument, walkthroughId: this.currentWalkthrough?.id });
274
+ switch (command) {
275
+ case 'scrollPrev': {
276
+ this.scrollPrev();
277
+ break;
278
+ }
279
+ case 'skip': {
280
+ this.runSkip();
281
+ break;
282
+ }
283
+ case 'showMoreRecents': {
284
+ this.commandService.executeCommand(OpenRecentAction.ID);
285
+ break;
286
+ }
287
+ case 'seeAllWalkthroughs': {
288
+ await this.openWalkthroughSelector();
289
+ break;
290
+ }
291
+ case 'openFolder': {
292
+ if (this.contextService.contextMatchesRules(( ContextKeyExpr.and(( WorkbenchStateContext.isEqualTo('workspace')))))) {
293
+ this.commandService.executeCommand(OpenFolderViaWorkspaceAction.ID);
294
+ }
295
+ else {
296
+ this.commandService.executeCommand(isMacintosh ? 'workbench.action.files.openFileFolder' : 'workbench.action.files.openFolder');
297
+ }
298
+ break;
299
+ }
300
+ case 'selectCategory': {
301
+ this.scrollToCategory(argument);
302
+ this.gettingStartedService.markWalkthroughOpened(argument);
303
+ break;
304
+ }
305
+ case 'selectStartEntry': {
306
+ const selected = startEntries.find(e => e.id === argument);
307
+ if (selected) {
308
+ this.runStepCommand(selected.content.command);
309
+ }
310
+ else {
311
+ throw Error('could not find start entry with id: ' + argument);
312
+ }
313
+ break;
314
+ }
315
+ case 'hideCategory': {
316
+ this.hideCategory(argument);
317
+ break;
318
+ }
319
+ case 'selectTask': {
320
+ this.selectStep(argument);
321
+ break;
322
+ }
323
+ case 'toggleStepCompletion': {
324
+ this.toggleStepCompletion(argument);
325
+ break;
326
+ }
327
+ case 'allDone': {
328
+ this.markAllStepsComplete();
329
+ break;
330
+ }
331
+ case 'nextSection': {
332
+ const next = this.currentWalkthrough?.next;
333
+ if (next) {
334
+ this.scrollToCategory(next);
335
+ }
336
+ else {
337
+ console.error('Error scrolling to next section of', this.currentWalkthrough);
338
+ }
339
+ break;
340
+ }
341
+ case 'openExtensionPage': {
342
+ this.commandService.executeCommand('extension.open', argument);
343
+ break;
344
+ }
345
+ case 'hideExtension': {
346
+ this.hideExtension(argument);
347
+ break;
348
+ }
349
+ default: {
350
+ console.error('Dispatch to', command, argument, 'not defined');
351
+ break;
352
+ }
353
+ }
354
+ }
355
+ hideCategory(categoryId) {
356
+ const selectedCategory = this.gettingStartedCategories.find(category => category.id === categoryId);
357
+ if (!selectedCategory) {
358
+ throw Error('Could not find category with ID ' + categoryId);
359
+ }
360
+ this.setHiddenCategories([...this.getHiddenCategories().add(categoryId)]);
361
+ this.gettingStartedList?.rerender();
362
+ }
363
+ hideExtension(extensionId) {
364
+ this.setHiddenCategories([...this.getHiddenCategories().add(extensionId)]);
365
+ this.featuredExtensionsList?.rerender();
366
+ this.registerDispatchListeners();
367
+ }
368
+ markAllStepsComplete() {
369
+ if (this.currentWalkthrough) {
370
+ this.currentWalkthrough?.steps.forEach(step => {
371
+ if (!step.done) {
372
+ this.gettingStartedService.progressStep(step.id);
373
+ }
374
+ });
375
+ this.hideCategory(this.currentWalkthrough?.id);
376
+ this.scrollPrev();
377
+ }
378
+ else {
379
+ throw Error('No walkthrough opened');
380
+ }
381
+ }
382
+ toggleStepCompletion(argument) {
383
+ const stepToggle = assertIsDefined(this.currentWalkthrough?.steps.find(step => step.id === argument));
384
+ if (stepToggle.done) {
385
+ this.gettingStartedService.deprogressStep(argument);
386
+ }
387
+ else {
388
+ this.gettingStartedService.progressStep(argument);
389
+ }
390
+ }
391
+ async openWalkthroughSelector() {
392
+ const selection = await this.quickInputService.pick(( this.gettingStartedCategories
393
+ .filter(c => this.contextService.contextMatchesRules(c.when))
394
+ .map(x => ({
395
+ id: x.id,
396
+ label: x.title,
397
+ detail: x.description,
398
+ description: x.source,
399
+ }))), { canPickMany: false, matchOnDescription: true, matchOnDetail: true, title: ( localizeWithPath(
400
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
401
+ 'pickWalkthroughs',
402
+ "Open Walkthrough..."
403
+ )) });
404
+ if (selection) {
405
+ this.runDispatchCommand('selectCategory', selection.id);
406
+ }
407
+ }
408
+ getHiddenCategories() {
409
+ return ( new Set(
410
+ JSON.parse(this.storageService.get(hiddenEntriesConfigurationKey, 0 , '[]'))
411
+ ));
412
+ }
413
+ setHiddenCategories(hidden) {
414
+ this.storageService.store(hiddenEntriesConfigurationKey, JSON.stringify(hidden), 0 , 0 );
415
+ }
416
+ async buildMediaComponent(stepId) {
417
+ if (!this.currentWalkthrough) {
418
+ throw Error('no walkthrough selected');
419
+ }
420
+ const stepToExpand = assertIsDefined(this.currentWalkthrough.steps.find(step => step.id === stepId));
421
+ if (this.currentMediaComponent === stepId) {
422
+ return;
423
+ }
424
+ this.currentMediaComponent = stepId;
425
+ this.stepDisposables.clear();
426
+ this.stepDisposables.add({
427
+ dispose: () => {
428
+ this.currentMediaComponent = undefined;
429
+ }
430
+ });
431
+ if (this.currentMediaType !== stepToExpand.media.type) {
432
+ this.currentMediaType = stepToExpand.media.type;
433
+ this.mediaDisposables.add(toDisposable(() => {
434
+ this.currentMediaType = undefined;
435
+ }));
436
+ clearNode(this.stepMediaComponent);
437
+ if (stepToExpand.media.type === 'svg') {
438
+ this.webview = this.mediaDisposables.add(this.webviewService.createWebviewElement({ title: undefined, options: { disableServiceWorker: true }, contentOptions: {}, extension: undefined }));
439
+ this.webview.mountTo(this.stepMediaComponent);
440
+ }
441
+ else if (stepToExpand.media.type === 'markdown') {
442
+ this.webview = this.mediaDisposables.add(this.webviewService.createWebviewElement({ options: {}, contentOptions: { localResourceRoots: [stepToExpand.media.root], allowScripts: true }, title: '', extension: undefined }));
443
+ this.webview.mountTo(this.stepMediaComponent);
444
+ }
445
+ }
446
+ if (stepToExpand.media.type === 'image') {
447
+ this.stepsContent.classList.add('image');
448
+ this.stepsContent.classList.remove('markdown');
449
+ const media = stepToExpand.media;
450
+ const mediaElement = $('img');
451
+ clearNode(this.stepMediaComponent);
452
+ this.stepMediaComponent.appendChild(mediaElement);
453
+ mediaElement.setAttribute('alt', media.altText);
454
+ this.updateMediaSourceForColorMode(mediaElement, media.path);
455
+ this.stepDisposables.add(addDisposableListener(this.stepMediaComponent, 'click', () => {
456
+ const hrefs = flatten(( stepToExpand.description.map(lt => ( lt.nodes.filter((node) => typeof node !== 'string').map(node => node.href)))));
457
+ if (hrefs.length === 1) {
458
+ const href = hrefs[0];
459
+ if (href.startsWith('http')) {
460
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'runStepAction', argument: href, walkthroughId: this.currentWalkthrough?.id });
461
+ this.openerService.open(href);
462
+ }
463
+ }
464
+ }));
465
+ this.stepDisposables.add(this.themeService.onDidColorThemeChange(() => this.updateMediaSourceForColorMode(mediaElement, media.path)));
466
+ }
467
+ else if (stepToExpand.media.type === 'svg') {
468
+ this.stepsContent.classList.add('image');
469
+ this.stepsContent.classList.remove('markdown');
470
+ const media = stepToExpand.media;
471
+ this.webview.setHtml(await this.detailsRenderer.renderSVG(media.path));
472
+ let isDisposed = false;
473
+ this.stepDisposables.add(toDisposable(() => { isDisposed = true; }));
474
+ this.stepDisposables.add(this.themeService.onDidColorThemeChange(async () => {
475
+ const body = await this.detailsRenderer.renderSVG(media.path);
476
+ if (!isDisposed) {
477
+ this.webview.setHtml(body);
478
+ }
479
+ }));
480
+ this.stepDisposables.add(addDisposableListener(this.stepMediaComponent, 'click', () => {
481
+ const hrefs = flatten(( stepToExpand.description.map(lt => ( lt.nodes.filter((node) => typeof node !== 'string').map(node => node.href)))));
482
+ if (hrefs.length === 1) {
483
+ const href = hrefs[0];
484
+ if (href.startsWith('http')) {
485
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'runStepAction', argument: href, walkthroughId: this.currentWalkthrough?.id });
486
+ this.openerService.open(href);
487
+ }
488
+ }
489
+ }));
490
+ this.stepDisposables.add(this.webview.onDidClickLink(link => {
491
+ if (matchesScheme(link, Schemas.https) || matchesScheme(link, Schemas.http) || (matchesScheme(link, Schemas.command))) {
492
+ this.openerService.open(link, { allowCommands: true });
493
+ }
494
+ }));
495
+ }
496
+ else if (stepToExpand.media.type === 'markdown') {
497
+ this.stepsContent.classList.remove('image');
498
+ this.stepsContent.classList.add('markdown');
499
+ const media = stepToExpand.media;
500
+ const rawHTML = await this.detailsRenderer.renderMarkdown(media.path, media.base);
501
+ this.webview.setHtml(rawHTML);
502
+ const serializedContextKeyExprs = rawHTML.match(/checked-on=\"([^'][^"]*)\"/g)?.map(attr => attr.slice('checked-on="'.length, -1)
503
+ .replace(/'/g, '\'')
504
+ .replace(/&/g, '&'));
505
+ const postTrueKeysMessage = () => {
506
+ const enabledContextKeys = serializedContextKeyExprs?.filter(expr => this.contextService.contextMatchesRules(ContextKeyExpr.deserialize(expr)));
507
+ if (enabledContextKeys) {
508
+ this.webview.postMessage({
509
+ enabledContextKeys
510
+ });
511
+ }
512
+ };
513
+ if (serializedContextKeyExprs) {
514
+ const contextKeyExprs = coalesce(( serializedContextKeyExprs.map(expr => ContextKeyExpr.deserialize(expr))));
515
+ const watchingKeys = ( new Set(flatten(( contextKeyExprs.map(expr => ( expr.keys()))))));
516
+ this.stepDisposables.add(this.contextService.onDidChangeContext(e => {
517
+ if (e.affectsSome(watchingKeys)) {
518
+ postTrueKeysMessage();
519
+ }
520
+ }));
521
+ }
522
+ let isDisposed = false;
523
+ this.stepDisposables.add(toDisposable(() => { isDisposed = true; }));
524
+ this.stepDisposables.add(this.webview.onDidClickLink(link => {
525
+ if (matchesScheme(link, Schemas.https) || matchesScheme(link, Schemas.http) || (matchesScheme(link, Schemas.command))) {
526
+ this.openerService.open(link, { allowCommands: true });
527
+ }
528
+ }));
529
+ if (rawHTML.indexOf('<code>') >= 0) {
530
+ this.stepDisposables.add(this.themeService.onDidColorThemeChange(async () => {
531
+ const body = await this.detailsRenderer.renderMarkdown(media.path, media.base);
532
+ if (!isDisposed) {
533
+ this.webview.setHtml(body);
534
+ postTrueKeysMessage();
535
+ }
536
+ }));
537
+ }
538
+ const layoutDelayer = ( new Delayer(50));
539
+ this.layoutMarkdown = () => {
540
+ layoutDelayer.trigger(() => {
541
+ this.webview.postMessage({ layoutMeNow: true });
542
+ });
543
+ };
544
+ this.stepDisposables.add(layoutDelayer);
545
+ this.stepDisposables.add({ dispose: () => this.layoutMarkdown = undefined });
546
+ postTrueKeysMessage();
547
+ this.stepDisposables.add(this.webview.onMessage(e => {
548
+ const message = e.message;
549
+ if (message.startsWith('command:')) {
550
+ this.openerService.open(message, { allowCommands: true });
551
+ }
552
+ else if (message.startsWith('setTheme:')) {
553
+ this.configurationService.updateValue(ThemeSettings.COLOR_THEME, message.slice('setTheme:'.length), 2 );
554
+ }
555
+ else {
556
+ console.error('Unexpected message', message);
557
+ }
558
+ }));
559
+ }
560
+ }
561
+ async selectStepLoose(id) {
562
+ if (id.startsWith(`${this.editorInput.selectedCategory}#`)) {
563
+ this.selectStep(id);
564
+ }
565
+ else {
566
+ const toSelect = this.editorInput.selectedCategory + '#' + id;
567
+ this.selectStep(toSelect);
568
+ }
569
+ }
570
+ async selectStep(id, delayFocus = true) {
571
+ if (id) {
572
+ let stepElement = this.container.querySelector(`[data-step-id="${id}"]`);
573
+ if (!stepElement) {
574
+ stepElement = this.container.querySelector(`[data-step-id]`);
575
+ if (!stepElement) {
576
+ return;
577
+ }
578
+ id = assertIsDefined(stepElement.getAttribute('data-step-id'));
579
+ }
580
+ stepElement.parentElement?.querySelectorAll('.expanded').forEach(node => {
581
+ if (node.getAttribute('data-step-id') !== id) {
582
+ node.classList.remove('expanded');
583
+ node.setAttribute('aria-expanded', 'false');
584
+ }
585
+ });
586
+ setTimeout(() => stepElement.focus(), delayFocus && this.shouldAnimate() ? SLIDE_TRANSITION_TIME_MS : 0);
587
+ this.editorInput.selectedStep = id;
588
+ stepElement.classList.add('expanded');
589
+ stepElement.setAttribute('aria-expanded', 'true');
590
+ this.buildMediaComponent(id);
591
+ this.gettingStartedService.progressStep(id);
592
+ }
593
+ else {
594
+ this.editorInput.selectedStep = undefined;
595
+ }
596
+ this.detailsPageScrollbar?.scanDomNode();
597
+ this.detailsScrollbar?.scanDomNode();
598
+ }
599
+ updateMediaSourceForColorMode(element, sources) {
600
+ const themeType = this.themeService.getColorTheme().type;
601
+ const src = ( sources[themeType].toString(true)).replace(/ /g, '%20');
602
+ element.srcset = src.toLowerCase().endsWith('.svg') ? src : (src + ' 1.5x');
603
+ }
604
+ createEditor(parent) {
605
+ if (this.detailsPageScrollbar) {
606
+ this.detailsPageScrollbar.dispose();
607
+ }
608
+ if (this.categoriesPageScrollbar) {
609
+ this.categoriesPageScrollbar.dispose();
610
+ }
611
+ this.categoriesSlide = $('.gettingStartedSlideCategories.gettingStartedSlide');
612
+ const prevButton = $('button.prev-button.button-link', { 'x-dispatch': 'scrollPrev' }, $('span.scroll-button.codicon.codicon-chevron-left'), $('span.moreText', {}, ( localizeWithPath(
613
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
614
+ 'welcome',
615
+ "Welcome"
616
+ ))));
617
+ this.stepsSlide = $('.gettingStartedSlideDetails.gettingStartedSlide', {}, prevButton);
618
+ this.stepsContent = $('.gettingStartedDetailsContent', {});
619
+ this.detailsPageScrollbar = this._register(( new DomScrollableElement(this.stepsContent, { className: 'full-height-scrollable' })));
620
+ this.categoriesPageScrollbar = this._register(( new DomScrollableElement(
621
+ this.categoriesSlide,
622
+ { className: 'full-height-scrollable categoriesScrollbar' }
623
+ )));
624
+ this.stepsSlide.appendChild(this.detailsPageScrollbar.getDomNode());
625
+ const gettingStartedPage = $('.gettingStarted', {}, this.categoriesPageScrollbar.getDomNode(), this.stepsSlide);
626
+ this.container.appendChild(gettingStartedPage);
627
+ this.categoriesPageScrollbar.scanDomNode();
628
+ this.detailsPageScrollbar.scanDomNode();
629
+ parent.appendChild(this.container);
630
+ }
631
+ async buildCategoriesSlide() {
632
+ this.categoriesSlideDisposables.clear();
633
+ const showOnStartupCheckbox = ( new Toggle({
634
+ icon: Codicon.check,
635
+ actionClassName: 'getting-started-checkbox',
636
+ isChecked: this.configurationService.getValue(configurationKey) === 'welcomePage',
637
+ title: ( localizeWithPath(
638
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
639
+ 'checkboxTitle',
640
+ "When checked, this page will be shown on startup."
641
+ )),
642
+ ...defaultToggleStyles
643
+ }));
644
+ showOnStartupCheckbox.domNode.id = 'showOnStartup';
645
+ const showOnStartupLabel = $('label.caption', { for: 'showOnStartup' }, ( localizeWithPath(
646
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
647
+ 'welcomePage.showOnStartup',
648
+ "Show welcome page on startup"
649
+ )));
650
+ const onShowOnStartupChanged = () => {
651
+ if (showOnStartupCheckbox.checked) {
652
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'showOnStartupChecked', argument: undefined, walkthroughId: this.currentWalkthrough?.id });
653
+ this.configurationService.updateValue(configurationKey, 'welcomePage');
654
+ }
655
+ else {
656
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'showOnStartupUnchecked', argument: undefined, walkthroughId: this.currentWalkthrough?.id });
657
+ this.configurationService.updateValue(configurationKey, 'none');
658
+ }
659
+ };
660
+ this.categoriesSlideDisposables.add(showOnStartupCheckbox);
661
+ this.categoriesSlideDisposables.add(showOnStartupCheckbox.onChange(() => {
662
+ onShowOnStartupChanged();
663
+ }));
664
+ this.categoriesSlideDisposables.add(addDisposableListener(showOnStartupLabel, 'click', () => {
665
+ showOnStartupCheckbox.checked = !showOnStartupCheckbox.checked;
666
+ onShowOnStartupChanged();
667
+ }));
668
+ const header = $('.header', {}, $('h1.product-name.caption', {}, this.productService.nameLong), $('p.subtitle.description', {}, ( localizeWithPath(
669
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
670
+ { key: 'gettingStarted.editingEvolved', comment: ['Shown as subtitle on the Welcome page.'] },
671
+ "Editing evolved"
672
+ ))));
673
+ const leftColumn = $('.categories-column.categories-column-left', {});
674
+ const rightColumn = $('.categories-column.categories-column-right', {});
675
+ const startList = this.buildStartList();
676
+ const recentList = this.buildRecentlyOpenedList();
677
+ const featuredExtensionList = this.buildFeaturedExtensionsList();
678
+ const gettingStartedList = this.buildGettingStartedWalkthroughsList();
679
+ const footer = $('.footer', {}, $('p.showOnStartup', {}, showOnStartupCheckbox.domNode, showOnStartupLabel));
680
+ const layoutLists = () => {
681
+ if (gettingStartedList.itemCount) {
682
+ this.container.classList.remove('noWalkthroughs');
683
+ reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
684
+ }
685
+ else {
686
+ this.container.classList.add('noWalkthroughs');
687
+ reset(rightColumn, featuredExtensionList.getDomElement());
688
+ }
689
+ setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50);
690
+ layoutRecentList();
691
+ };
692
+ const layoutFeaturedExtension = () => {
693
+ if (featuredExtensionList.itemCount) {
694
+ this.container.classList.remove('noExtensions');
695
+ reset(rightColumn, featuredExtensionList.getDomElement(), gettingStartedList.getDomElement());
696
+ }
697
+ else {
698
+ this.container.classList.add('noExtensions');
699
+ reset(rightColumn, gettingStartedList.getDomElement());
700
+ }
701
+ setTimeout(() => this.categoriesPageScrollbar?.scanDomNode(), 50);
702
+ layoutRecentList();
703
+ };
704
+ const layoutRecentList = () => {
705
+ if (this.container.classList.contains('noWalkthroughs') && this.container.classList.contains('noExtensions')) {
706
+ recentList.setLimit(10);
707
+ reset(leftColumn, startList.getDomElement());
708
+ reset(rightColumn, recentList.getDomElement());
709
+ }
710
+ else {
711
+ recentList.setLimit(5);
712
+ reset(leftColumn, startList.getDomElement(), recentList.getDomElement());
713
+ }
714
+ };
715
+ featuredExtensionList.onDidChange(layoutFeaturedExtension);
716
+ layoutFeaturedExtension();
717
+ gettingStartedList.onDidChange(layoutLists);
718
+ layoutLists();
719
+ reset(this.categoriesSlide, $('.gettingStartedCategoriesContainer', {}, header, leftColumn, rightColumn, footer));
720
+ this.categoriesPageScrollbar?.scanDomNode();
721
+ this.updateCategoryProgress();
722
+ this.registerDispatchListeners();
723
+ if (this.editorInput.selectedCategory) {
724
+ this.currentWalkthrough = this.gettingStartedCategories.find(category => category.id === this.editorInput.selectedCategory);
725
+ if (!this.currentWalkthrough) {
726
+ this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
727
+ this.currentWalkthrough = this.gettingStartedCategories.find(category => category.id === this.editorInput.selectedCategory);
728
+ if (this.currentWalkthrough) {
729
+ this.buildCategorySlide(this.editorInput.selectedCategory, this.editorInput.selectedStep);
730
+ this.setSlide('details');
731
+ return;
732
+ }
733
+ }
734
+ }
735
+ const someStepsComplete = ( this.gettingStartedCategories.some(category => category.steps.find(s => s.done)));
736
+ if (this.editorInput.showTelemetryNotice && this.productService.openToWelcomeMainPage) {
737
+ const telemetryNotice = $('p.telemetry-notice');
738
+ this.buildTelemetryFooter(telemetryNotice);
739
+ footer.appendChild(telemetryNotice);
740
+ }
741
+ else if (!this.productService.openToWelcomeMainPage && !someStepsComplete && !this.hasScrolledToFirstCategory) {
742
+ const firstSessionDateString = this.storageService.get(firstSessionDateStorageKey, -1 ) || ( new Date()).toUTCString();
743
+ const daysSinceFirstSession = ((+( new Date())) - (+( new Date(firstSessionDateString)))) / 1000 / 60 / 60 / 24;
744
+ const fistContentBehaviour = daysSinceFirstSession < 1 ? 'openToFirstCategory' : 'index';
745
+ if (fistContentBehaviour === 'openToFirstCategory') {
746
+ const first = this.gettingStartedCategories.filter(c => !c.when || this.contextService.contextMatchesRules(c.when))[0];
747
+ this.hasScrolledToFirstCategory = true;
748
+ if (first) {
749
+ this.currentWalkthrough = first;
750
+ this.editorInput.selectedCategory = this.currentWalkthrough?.id;
751
+ this.buildCategorySlide(this.editorInput.selectedCategory, undefined);
752
+ this.setSlide('details');
753
+ return;
754
+ }
755
+ }
756
+ }
757
+ this.setSlide('categories');
758
+ }
759
+ buildRecentlyOpenedList() {
760
+ const renderRecent = (recent) => {
761
+ let fullPath;
762
+ let windowOpenable;
763
+ if (isRecentFolder(recent)) {
764
+ windowOpenable = { folderUri: recent.folderUri };
765
+ fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.folderUri, { verbose: 2 });
766
+ }
767
+ else {
768
+ fullPath = recent.label || this.labelService.getWorkspaceLabel(recent.workspace, { verbose: 2 });
769
+ windowOpenable = { workspaceUri: recent.workspace.configPath };
770
+ }
771
+ const { name, parentPath } = splitRecentLabel(fullPath);
772
+ const li = $('li');
773
+ const link = $('button.button-link');
774
+ link.innerText = name;
775
+ link.title = fullPath;
776
+ link.setAttribute('aria-label', ( localizeWithPath(
777
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
778
+ 'welcomePage.openFolderWithPath',
779
+ "Open folder {0} with path {1}",
780
+ name,
781
+ parentPath
782
+ )));
783
+ link.addEventListener('click', e => {
784
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'openRecent', argument: undefined, walkthroughId: this.currentWalkthrough?.id });
785
+ this.hostService.openWindow([windowOpenable], {
786
+ forceNewWindow: e.ctrlKey || e.metaKey,
787
+ remoteAuthority: recent.remoteAuthority || null
788
+ });
789
+ e.preventDefault();
790
+ e.stopPropagation();
791
+ });
792
+ li.appendChild(link);
793
+ const span = $('span');
794
+ span.classList.add('path');
795
+ span.classList.add('detail');
796
+ span.innerText = parentPath;
797
+ span.title = fullPath;
798
+ li.appendChild(span);
799
+ return li;
800
+ };
801
+ if (this.recentlyOpenedList) {
802
+ this.recentlyOpenedList.dispose();
803
+ }
804
+ const recentlyOpenedList = this.recentlyOpenedList = ( new GettingStartedIndexList({
805
+ title: ( localizeWithPath(
806
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
807
+ 'recent',
808
+ "Recent"
809
+ )),
810
+ klass: 'recently-opened',
811
+ limit: 5,
812
+ empty: $('.empty-recent', {}, ( localizeWithPath(
813
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
814
+ 'noRecents',
815
+ "You have no recent folders,"
816
+ )), $('button.button-link', { 'x-dispatch': 'openFolder' }, ( localizeWithPath(
817
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
818
+ 'openFolder',
819
+ "open a folder"
820
+ ))), ( localizeWithPath(
821
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
822
+ 'toStart',
823
+ "to start."
824
+ ))),
825
+ more: $('.more', {}, $('button.button-link', {
826
+ 'x-dispatch': 'showMoreRecents',
827
+ title: ( localizeWithPath(
828
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
829
+ 'show more recents',
830
+ "Show All Recent Folders {0}",
831
+ this.getKeybindingLabel(OpenRecentAction.ID)
832
+ ))
833
+ }, ( localizeWithPath(
834
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
835
+ 'showAll',
836
+ "More..."
837
+ )))),
838
+ renderElement: renderRecent,
839
+ contextService: this.contextService
840
+ }));
841
+ recentlyOpenedList.onDidChange(() => this.registerDispatchListeners());
842
+ this.recentlyOpened.then(({ workspaces }) => {
843
+ const workspacesWithID = ( workspaces
844
+ .filter(recent => !this.workspaceContextService.isCurrentWorkspace(isRecentWorkspace(recent) ? recent.workspace : recent.folderUri))
845
+ .map(
846
+ recent => ({ ...recent, id: isRecentWorkspace(recent) ? recent.workspace.id : ( recent.folderUri.toString()) })
847
+ ));
848
+ const updateEntries = () => {
849
+ recentlyOpenedList.setEntries(workspacesWithID);
850
+ };
851
+ updateEntries();
852
+ recentlyOpenedList.register(this.labelService.onDidChangeFormatters(() => updateEntries()));
853
+ }).catch(onUnexpectedError);
854
+ return recentlyOpenedList;
855
+ }
856
+ buildStartList() {
857
+ const renderStartEntry = (entry) => $('li', {}, $('button.button-link', {
858
+ 'x-dispatch': 'selectStartEntry:' + entry.id,
859
+ title: entry.description + ' ' + this.getKeybindingLabel(entry.command),
860
+ }, this.iconWidgetFor(entry), $('span', {}, entry.title)));
861
+ if (this.startList) {
862
+ this.startList.dispose();
863
+ }
864
+ const startList = this.startList = ( new GettingStartedIndexList({
865
+ title: ( localizeWithPath(
866
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
867
+ 'start',
868
+ "Start"
869
+ )),
870
+ klass: 'start-container',
871
+ limit: 10,
872
+ renderElement: renderStartEntry,
873
+ rankElement: e => -e.order,
874
+ contextService: this.contextService
875
+ }));
876
+ startList.setEntries(parsedStartEntries);
877
+ startList.onDidChange(() => this.registerDispatchListeners());
878
+ return startList;
879
+ }
880
+ buildGettingStartedWalkthroughsList() {
881
+ const renderGetttingStaredWalkthrough = (category) => {
882
+ const renderNewBadge = (category.newItems || category.newEntry) && !category.isFeatured;
883
+ const newBadge = $('.new-badge', {});
884
+ if (category.newEntry) {
885
+ reset(newBadge, $('.new-category', {}, ( localizeWithPath(
886
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
887
+ 'new',
888
+ "New"
889
+ ))));
890
+ }
891
+ else if (category.newItems) {
892
+ reset(newBadge, $('.new-items', {}, ( localizeWithPath(
893
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
894
+ { key: 'newItems', comment: ['Shown when a list of items has changed based on an update from a remote source'] },
895
+ "Updated"
896
+ ))));
897
+ }
898
+ const featuredBadge = $('.featured-badge', {});
899
+ const descriptionContent = $('.description-content', {});
900
+ if (category.isFeatured) {
901
+ reset(featuredBadge, $('.featured', {}, $('span.featured-icon.codicon.codicon-star-full')));
902
+ reset(descriptionContent, ...renderLabelWithIcons(category.description));
903
+ }
904
+ const titleContent = $('h3.category-title.max-lines-3', { 'x-category-title-for': category.id });
905
+ reset(titleContent, ...renderLabelWithIcons(category.title));
906
+ return $('button.getting-started-category' + (category.isFeatured ? '.featured' : ''), {
907
+ 'x-dispatch': 'selectCategory:' + category.id,
908
+ 'title': category.description
909
+ }, featuredBadge, $('.main-content', {}, this.iconWidgetFor(category), titleContent, renderNewBadge ? newBadge : $('.no-badge'), $('a.codicon.codicon-close.hide-category-button', {
910
+ 'tabindex': 0,
911
+ 'x-dispatch': 'hideCategory:' + category.id,
912
+ 'title': ( localizeWithPath(
913
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
914
+ 'close',
915
+ "Hide"
916
+ )),
917
+ 'role': 'button',
918
+ 'aria-label': ( localizeWithPath(
919
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
920
+ 'closeAriaLabel',
921
+ "Hide"
922
+ )),
923
+ })), descriptionContent, $('.category-progress', { 'x-data-category-id': category.id, }, $('.progress-bar-outer', { 'role': 'progressbar' }, $('.progress-bar-inner'))));
924
+ };
925
+ if (this.gettingStartedList) {
926
+ this.gettingStartedList.dispose();
927
+ }
928
+ const rankWalkthrough = (e) => {
929
+ let rank = e.order;
930
+ if (e.isFeatured) {
931
+ rank += 7;
932
+ }
933
+ if (e.newEntry) {
934
+ rank += 3;
935
+ }
936
+ if (e.newItems) {
937
+ rank += 2;
938
+ }
939
+ if (e.recencyBonus) {
940
+ rank += 4 * e.recencyBonus;
941
+ }
942
+ if (( this.getHiddenCategories().has(e.id))) {
943
+ rank = null;
944
+ }
945
+ return rank;
946
+ };
947
+ const gettingStartedList = this.gettingStartedList = ( new GettingStartedIndexList({
948
+ title: ( localizeWithPath(
949
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
950
+ 'walkthroughs',
951
+ "Walkthroughs"
952
+ )),
953
+ klass: 'getting-started',
954
+ limit: 5,
955
+ footer: $('span.button-link.see-all-walkthroughs', { 'x-dispatch': 'seeAllWalkthroughs', 'tabindex': 0 }, ( localizeWithPath(
956
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
957
+ 'showAll',
958
+ "More..."
959
+ ))),
960
+ renderElement: renderGetttingStaredWalkthrough,
961
+ rankElement: rankWalkthrough,
962
+ contextService: this.contextService,
963
+ }));
964
+ gettingStartedList.onDidChange(() => {
965
+ const hidden = this.getHiddenCategories();
966
+ const someWalkthroughsHidden = hidden.size || gettingStartedList.itemCount < this.gettingStartedCategories.filter(c => this.contextService.contextMatchesRules(c.when)).length;
967
+ this.container.classList.toggle('someWalkthroughsHidden', !!someWalkthroughsHidden);
968
+ this.registerDispatchListeners();
969
+ allWalkthroughsHiddenContext.bindTo(this.contextService).set(gettingStartedList.itemCount === 0);
970
+ this.updateCategoryProgress();
971
+ });
972
+ gettingStartedList.setEntries(this.gettingStartedCategories);
973
+ allWalkthroughsHiddenContext.bindTo(this.contextService).set(gettingStartedList.itemCount === 0);
974
+ return gettingStartedList;
975
+ }
976
+ buildFeaturedExtensionsList() {
977
+ const renderFeaturedExtensions = (entry) => {
978
+ const descriptionContent = $('.featured-description-content', {});
979
+ reset(descriptionContent, ...renderLabelWithIcons(entry.description));
980
+ const titleContent = $('h3.category-title.max-lines-3', { 'x-category-title-for': entry.id });
981
+ reset(titleContent, ...renderLabelWithIcons(entry.title));
982
+ return $('button.getting-started-category', {
983
+ 'x-dispatch': 'openExtensionPage:' + entry.id,
984
+ 'title': entry.description
985
+ }, $('.main-content', {}, $('img.featured-icon.icon-widget', { src: entry.imagePath }), titleContent, $('a.codicon.codicon-close.hide-category-button', {
986
+ 'tabindex': 0,
987
+ 'x-dispatch': 'hideExtension:' + entry.id,
988
+ 'title': ( localizeWithPath(
989
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
990
+ 'close',
991
+ "Hide"
992
+ )),
993
+ 'role': 'button',
994
+ 'aria-label': ( localizeWithPath(
995
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
996
+ 'closeAriaLabel',
997
+ "Hide"
998
+ )),
999
+ })), descriptionContent);
1000
+ };
1001
+ if (this.featuredExtensionsList) {
1002
+ this.featuredExtensionsList.dispose();
1003
+ }
1004
+ const featuredExtensionsList = this.featuredExtensionsList = ( new GettingStartedIndexList({
1005
+ title: this.featuredExtensionService.title,
1006
+ klass: 'featured-extensions',
1007
+ limit: 5,
1008
+ renderElement: renderFeaturedExtensions,
1009
+ rankElement: (extension) => { if (( this.getHiddenCategories().has(extension.id))) {
1010
+ return null;
1011
+ } return 0; },
1012
+ contextService: this.contextService,
1013
+ }));
1014
+ this.featuredExtensions?.then(extensions => {
1015
+ featuredExtensionsList.setEntries(extensions);
1016
+ });
1017
+ this.featuredExtensionsList?.onDidChange(() => {
1018
+ this.registerDispatchListeners();
1019
+ });
1020
+ return featuredExtensionsList;
1021
+ }
1022
+ layout(size) {
1023
+ this.detailsScrollbar?.scanDomNode();
1024
+ this.categoriesPageScrollbar?.scanDomNode();
1025
+ this.detailsPageScrollbar?.scanDomNode();
1026
+ this.startList?.layout(size);
1027
+ this.gettingStartedList?.layout(size);
1028
+ this.featuredExtensionsList?.layout(size);
1029
+ this.recentlyOpenedList?.layout(size);
1030
+ if (this.editorInput?.selectedStep && this.currentMediaType) {
1031
+ this.mediaDisposables.clear();
1032
+ this.stepDisposables.clear();
1033
+ this.buildMediaComponent(this.editorInput.selectedStep);
1034
+ }
1035
+ this.layoutMarkdown?.();
1036
+ this.container.classList.toggle('height-constrained', size.height <= 600);
1037
+ this.container.classList.toggle('width-constrained', size.width <= 400);
1038
+ this.container.classList.toggle('width-semi-constrained', size.width <= 800);
1039
+ this.categoriesPageScrollbar?.scanDomNode();
1040
+ this.detailsPageScrollbar?.scanDomNode();
1041
+ this.detailsScrollbar?.scanDomNode();
1042
+ }
1043
+ updateCategoryProgress() {
1044
+ getWindow(this.container).document.querySelectorAll('.category-progress').forEach(element => {
1045
+ const categoryID = element.getAttribute('x-data-category-id');
1046
+ const category = this.gettingStartedCategories.find(category => category.id === categoryID);
1047
+ if (!category) {
1048
+ throw Error('Could not find category with ID ' + categoryID);
1049
+ }
1050
+ const stats = this.getWalkthroughCompletionStats(category);
1051
+ const bar = assertIsDefined(element.querySelector('.progress-bar-inner'));
1052
+ bar.setAttribute('aria-valuemin', '0');
1053
+ bar.setAttribute('aria-valuenow', '' + stats.stepsComplete);
1054
+ bar.setAttribute('aria-valuemax', '' + stats.stepsTotal);
1055
+ const progress = (stats.stepsComplete / stats.stepsTotal) * 100;
1056
+ bar.style.width = `${progress}%`;
1057
+ element.parentElement.classList.toggle('no-progress', stats.stepsComplete === 0);
1058
+ if (stats.stepsTotal === stats.stepsComplete) {
1059
+ bar.title = ( localizeWithPath(
1060
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1061
+ 'gettingStarted.allStepsComplete',
1062
+ "All {0} steps complete!",
1063
+ stats.stepsComplete
1064
+ ));
1065
+ }
1066
+ else {
1067
+ bar.title = ( localizeWithPath(
1068
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1069
+ 'gettingStarted.someStepsComplete',
1070
+ "{0} of {1} steps complete",
1071
+ stats.stepsComplete,
1072
+ stats.stepsTotal
1073
+ ));
1074
+ }
1075
+ });
1076
+ }
1077
+ async scrollToCategory(categoryID, stepId) {
1078
+ if (!( this.gettingStartedCategories.some(c => c.id === categoryID))) {
1079
+ this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
1080
+ }
1081
+ const ourCategory = this.gettingStartedCategories.find(c => c.id === categoryID);
1082
+ if (!ourCategory) {
1083
+ throw Error('Could not find category with ID: ' + categoryID);
1084
+ }
1085
+ this.inProgressScroll = this.inProgressScroll.then(async () => {
1086
+ reset(this.stepsContent);
1087
+ this.editorInput.selectedCategory = categoryID;
1088
+ this.editorInput.selectedStep = stepId;
1089
+ this.currentWalkthrough = ourCategory;
1090
+ this.buildCategorySlide(categoryID);
1091
+ this.setSlide('details');
1092
+ });
1093
+ }
1094
+ iconWidgetFor(category) {
1095
+ const widget = category.icon.type === 'icon' ? $(ThemeIcon.asCSSSelector(category.icon.icon)) : $('img.category-icon', { src: category.icon.path });
1096
+ widget.classList.add('icon-widget');
1097
+ return widget;
1098
+ }
1099
+ runStepCommand(href) {
1100
+ const isCommand = href.startsWith('command:');
1101
+ const toSide = href.startsWith('command:toSide:');
1102
+ const command = href.replace(/command:(toSide:)?/, 'command:');
1103
+ this.telemetryService.publicLog2('gettingStarted.ActionExecuted', { command: 'runStepAction', argument: href, walkthroughId: this.currentWalkthrough?.id });
1104
+ const fullSize = this.group ? this.groupsService.getPart(this.group).contentDimension : undefined;
1105
+ if (toSide && fullSize && fullSize.width > 700) {
1106
+ if (this.groupsService.count === 1) {
1107
+ const sideGroup = this.groupsService.addGroup(this.groupsService.groups[0], 3 );
1108
+ this.groupsService.activateGroup(sideGroup);
1109
+ const gettingStartedSize = Math.floor(fullSize.width / 2);
1110
+ const gettingStartedGroup = this.groupsService.getGroups(1 ).find(group => (group.activeEditor instanceof GettingStartedInput));
1111
+ this.groupsService.setSize(assertIsDefined(gettingStartedGroup), { width: gettingStartedSize, height: fullSize.height });
1112
+ }
1113
+ const nonGettingStartedGroup = this.groupsService.getGroups(1 ).find(group => !(group.activeEditor instanceof GettingStartedInput));
1114
+ if (nonGettingStartedGroup) {
1115
+ this.groupsService.activateGroup(nonGettingStartedGroup);
1116
+ nonGettingStartedGroup.focus();
1117
+ }
1118
+ }
1119
+ if (isCommand) {
1120
+ const commandURI = ( URI.parse(command));
1121
+ let args = [];
1122
+ try {
1123
+ args = parse(decodeURIComponent(commandURI.query));
1124
+ }
1125
+ catch {
1126
+ try {
1127
+ args = parse(commandURI.query);
1128
+ }
1129
+ catch {
1130
+ }
1131
+ }
1132
+ if (!Array.isArray(args)) {
1133
+ args = [args];
1134
+ }
1135
+ if ((commandURI.path === ( OpenFileFolderAction.ID.toString()) ||
1136
+ commandURI.path === ( OpenFolderAction.ID.toString())) &&
1137
+ this.workspaceContextService.getWorkspace().folders.length === 0) {
1138
+ const selectedStepIndex = this.currentWalkthrough?.steps.findIndex(step => step.id === this.editorInput.selectedStep);
1139
+ if (selectedStepIndex !== undefined &&
1140
+ selectedStepIndex > -1 &&
1141
+ this.currentWalkthrough?.steps.slice(selectedStepIndex + 1).some(step => !step.done)) {
1142
+ const restoreData = { folder: UNKNOWN_EMPTY_WINDOW_WORKSPACE.id, category: this.editorInput.selectedCategory, step: this.editorInput.selectedStep };
1143
+ this.storageService.store(restoreWalkthroughsConfigurationKey, JSON.stringify(restoreData), 0 , 1 );
1144
+ }
1145
+ }
1146
+ this.commandService.executeCommand(commandURI.path, ...args).then(result => {
1147
+ const toOpen = result?.openFolder;
1148
+ if (toOpen) {
1149
+ if (!URI.isUri(toOpen)) {
1150
+ console.warn('Warn: Running walkthrough command', href, 'yielded non-URI `openFolder` result', toOpen, '. It will be disregarded.');
1151
+ return;
1152
+ }
1153
+ const restoreData = { folder: ( toOpen.toString()), category: this.editorInput.selectedCategory, step: this.editorInput.selectedStep };
1154
+ this.storageService.store(restoreWalkthroughsConfigurationKey, JSON.stringify(restoreData), 0 , 1 );
1155
+ this.hostService.openWindow([{ folderUri: toOpen }]);
1156
+ }
1157
+ });
1158
+ }
1159
+ else {
1160
+ this.openerService.open(command, { allowCommands: true });
1161
+ }
1162
+ if (!isCommand && (href.startsWith('https://') || href.startsWith('http://'))) {
1163
+ this.gettingStartedService.progressByEvent('onLink:' + href);
1164
+ }
1165
+ }
1166
+ buildStepMarkdownDescription(container, text) {
1167
+ while (container.firstChild) {
1168
+ container.removeChild(container.firstChild);
1169
+ }
1170
+ for (const linkedText of text) {
1171
+ if (linkedText.nodes.length === 1 && typeof linkedText.nodes[0] !== 'string') {
1172
+ const node = linkedText.nodes[0];
1173
+ const buttonContainer = append(container, $('.button-container'));
1174
+ const button = ( new Button(
1175
+ buttonContainer,
1176
+ { title: node.title, supportIcons: true, ...defaultButtonStyles }
1177
+ ));
1178
+ const isCommand = node.href.startsWith('command:');
1179
+ const command = node.href.replace(/command:(toSide:)?/, 'command:');
1180
+ button.label = node.label;
1181
+ button.onDidClick(e => {
1182
+ e.stopPropagation();
1183
+ e.preventDefault();
1184
+ this.runStepCommand(node.href);
1185
+ }, null, this.detailsPageDisposables);
1186
+ if (isCommand) {
1187
+ const keybindingLabel = this.getKeybindingLabel(command);
1188
+ if (keybindingLabel) {
1189
+ container.appendChild($('span.shortcut-message', {}, ( localizeWithPath(
1190
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1191
+ 'gettingStarted.keyboardTip',
1192
+ 'Tip: Use keyboard shortcut '
1193
+ )), $('span.keybinding', {}, keybindingLabel)));
1194
+ }
1195
+ }
1196
+ this.detailsPageDisposables.add(button);
1197
+ }
1198
+ else {
1199
+ const p = append(container, $('p'));
1200
+ for (const node of linkedText.nodes) {
1201
+ if (typeof node === 'string') {
1202
+ const labelWithIcon = renderLabelWithIcons(node);
1203
+ for (const element of labelWithIcon) {
1204
+ if (typeof element === 'string') {
1205
+ p.appendChild(renderFormattedText(element, { inline: true, renderCodeSegments: true }));
1206
+ }
1207
+ else {
1208
+ p.appendChild(element);
1209
+ }
1210
+ }
1211
+ }
1212
+ else {
1213
+ const link = this.instantiationService.createInstance(Link, p, node, { opener: (href) => this.runStepCommand(href) });
1214
+ this.detailsPageDisposables.add(link);
1215
+ }
1216
+ }
1217
+ }
1218
+ }
1219
+ return container;
1220
+ }
1221
+ clearInput() {
1222
+ this.stepDisposables.clear();
1223
+ super.clearInput();
1224
+ }
1225
+ buildCategorySlide(categoryID, selectedStep) {
1226
+ if (this.detailsScrollbar) {
1227
+ this.detailsScrollbar.dispose();
1228
+ }
1229
+ this.extensionService.whenInstalledExtensionsRegistered().then(() => {
1230
+ this.extensionService.activateByEvent(`onWalkthrough:${categoryID.replace(/[^#]+#/, '')}`);
1231
+ });
1232
+ this.detailsPageDisposables.clear();
1233
+ this.mediaDisposables.clear();
1234
+ const category = this.gettingStartedCategories.find(category => category.id === categoryID);
1235
+ if (!category) {
1236
+ throw Error('could not find category with ID ' + categoryID);
1237
+ }
1238
+ const categoryDescriptorComponent = $('.getting-started-category', {}, $('.category-description-container', {}, $('h2.category-title.max-lines-3', { 'x-category-title-for': category.id }, ...renderLabelWithIcons(category.title)), $('.category-description.description.max-lines-3', { 'x-category-description-for': category.id }, ...renderLabelWithIcons(category.description))));
1239
+ const stepListContainer = $('.step-list-container');
1240
+ this.detailsPageDisposables.add(addDisposableListener(stepListContainer, 'keydown', (e) => {
1241
+ const event = ( new StandardKeyboardEvent(e));
1242
+ const currentStepIndex = () => category.steps.findIndex(e => e.id === this.editorInput.selectedStep);
1243
+ if (event.keyCode === 16 ) {
1244
+ const toExpand = category.steps.filter((step, index) => index < currentStepIndex() && this.contextService.contextMatchesRules(step.when));
1245
+ if (toExpand.length) {
1246
+ this.selectStep(toExpand[toExpand.length - 1].id, false);
1247
+ }
1248
+ }
1249
+ if (event.keyCode === 18 ) {
1250
+ const toExpand = category.steps.find((step, index) => index > currentStepIndex() && this.contextService.contextMatchesRules(step.when));
1251
+ if (toExpand) {
1252
+ this.selectStep(toExpand.id, false);
1253
+ }
1254
+ }
1255
+ }));
1256
+ let renderedSteps = undefined;
1257
+ const contextKeysToWatch = ( new Set(category.steps.flatMap(step => ( step.when.keys()))));
1258
+ const buildStepList = () => {
1259
+ category.steps.sort((a, b) => a.order - b.order);
1260
+ const toRender = category.steps
1261
+ .filter(step => this.contextService.contextMatchesRules(step.when));
1262
+ if (equals(renderedSteps, toRender, (a, b) => a.id === b.id)) {
1263
+ return;
1264
+ }
1265
+ renderedSteps = toRender;
1266
+ reset(stepListContainer, ...( renderedSteps
1267
+ .map(step => {
1268
+ const codicon = $('.codicon' + (step.done ? '.complete' + ThemeIcon.asCSSSelector(gettingStartedCheckedCodicon) : ThemeIcon.asCSSSelector(gettingStartedUncheckedCodicon)), {
1269
+ 'data-done-step-id': step.id,
1270
+ 'x-dispatch': 'toggleStepCompletion:' + step.id,
1271
+ 'role': 'checkbox',
1272
+ 'tabindex': '0',
1273
+ });
1274
+ const container = $('.step-description-container', { 'x-step-description-for': step.id });
1275
+ this.buildStepMarkdownDescription(container, step.description);
1276
+ const stepTitle = $('h3.step-title.max-lines-3', { 'x-step-title-for': step.id });
1277
+ reset(stepTitle, ...renderLabelWithIcons(step.title));
1278
+ const stepDescription = $('.step-container', {}, stepTitle, container);
1279
+ if (step.media.type === 'image') {
1280
+ stepDescription.appendChild($('.image-description', { 'aria-label': ( localizeWithPath(
1281
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1282
+ 'imageShowing',
1283
+ "Image showing {0}",
1284
+ step.media.altText
1285
+ )) }));
1286
+ }
1287
+ return $('button.getting-started-step', {
1288
+ 'x-dispatch': 'selectTask:' + step.id,
1289
+ 'data-step-id': step.id,
1290
+ 'aria-expanded': 'false',
1291
+ 'aria-checked': '' + step.done,
1292
+ 'role': 'button',
1293
+ }, codicon, stepDescription);
1294
+ })));
1295
+ };
1296
+ buildStepList();
1297
+ this.detailsPageDisposables.add(this.contextService.onDidChangeContext(e => {
1298
+ if (e.affectsSome(contextKeysToWatch)) {
1299
+ buildStepList();
1300
+ this.registerDispatchListeners();
1301
+ this.selectStep(this.editorInput.selectedStep, false);
1302
+ }
1303
+ }));
1304
+ const showNextCategory = this.gettingStartedCategories.find(_category => _category.id === category.next);
1305
+ const stepsContainer = $('.getting-started-detail-container', { 'role': 'list' }, stepListContainer, $('.done-next-container', {}, $('button.button-link.all-done', { 'x-dispatch': 'allDone' }, $('span.codicon.codicon-check-all'), ( localizeWithPath(
1306
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1307
+ 'allDone',
1308
+ "Mark Done"
1309
+ ))), ...(showNextCategory
1310
+ ? [$('button.button-link.next', { 'x-dispatch': 'nextSection' }, ( localizeWithPath(
1311
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1312
+ 'nextOne',
1313
+ "Next Section"
1314
+ )), $('span.codicon.codicon-arrow-right'))]
1315
+ : [])));
1316
+ this.detailsScrollbar = this._register(( new DomScrollableElement(stepsContainer, { className: 'steps-container' })));
1317
+ const stepListComponent = this.detailsScrollbar.getDomNode();
1318
+ const categoryFooter = $('.getting-started-footer');
1319
+ if (this.editorInput.showTelemetryNotice && getTelemetryLevel(this.configurationService) !== 0 && this.productService.enableTelemetry) {
1320
+ this.buildTelemetryFooter(categoryFooter);
1321
+ }
1322
+ reset(this.stepsContent, categoryDescriptorComponent, stepListComponent, this.stepMediaComponent, categoryFooter);
1323
+ const toExpand = category.steps.find(step => this.contextService.contextMatchesRules(step.when) && !step.done) ?? category.steps[0];
1324
+ this.selectStep(selectedStep ?? toExpand.id, !selectedStep);
1325
+ this.detailsScrollbar.scanDomNode();
1326
+ this.detailsPageScrollbar?.scanDomNode();
1327
+ this.registerDispatchListeners();
1328
+ }
1329
+ buildTelemetryFooter(parent) {
1330
+ const mdRenderer = this.instantiationService.createInstance(MarkdownRenderer, {});
1331
+ const privacyStatementCopy = ( localizeWithPath(
1332
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1333
+ 'privacy statement',
1334
+ "privacy statement"
1335
+ ));
1336
+ const privacyStatementButton = `[${privacyStatementCopy}](command:workbench.action.openPrivacyStatementUrl)`;
1337
+ const optOutCopy = ( localizeWithPath(
1338
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1339
+ 'optOut',
1340
+ "opt out"
1341
+ ));
1342
+ const optOutButton = `[${optOutCopy}](command:settings.filterByTelemetry)`;
1343
+ const text = ( localizeWithPath(
1344
+ 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted',
1345
+ { key: 'footer', comment: ['fist substitution is "vs code", second is "privacy statement", third is "opt out".'] },
1346
+ "{0} collects usage data. Read our {1} and learn how to {2}.",
1347
+ this.productService.nameShort,
1348
+ privacyStatementButton,
1349
+ optOutButton
1350
+ ));
1351
+ parent.append(mdRenderer.render({ value: text, isTrusted: true }).element);
1352
+ mdRenderer.dispose();
1353
+ }
1354
+ getKeybindingLabel(command) {
1355
+ command = command.replace(/^command:/, '');
1356
+ const label = this.keybindingService.lookupKeybinding(command)?.getLabel();
1357
+ if (!label) {
1358
+ return '';
1359
+ }
1360
+ else {
1361
+ return `(${label})`;
1362
+ }
1363
+ }
1364
+ async scrollPrev() {
1365
+ this.inProgressScroll = this.inProgressScroll.then(async () => {
1366
+ this.currentWalkthrough = undefined;
1367
+ this.editorInput.selectedCategory = undefined;
1368
+ this.editorInput.selectedStep = undefined;
1369
+ this.editorInput.showTelemetryNotice = false;
1370
+ this.selectStep(undefined);
1371
+ this.setSlide('categories');
1372
+ this.container.focus();
1373
+ });
1374
+ }
1375
+ runSkip() {
1376
+ this.commandService.executeCommand('workbench.action.closeActiveEditor');
1377
+ }
1378
+ escape() {
1379
+ if (this.editorInput.selectedCategory) {
1380
+ this.scrollPrev();
1381
+ }
1382
+ else {
1383
+ this.runSkip();
1384
+ }
1385
+ }
1386
+ setSlide(toEnable) {
1387
+ const slideManager = assertIsDefined(this.container.querySelector('.gettingStarted'));
1388
+ if (toEnable === 'categories') {
1389
+ slideManager.classList.remove('showDetails');
1390
+ slideManager.classList.add('showCategories');
1391
+ this.container.querySelector('.prev-button.button-link').style.display = 'none';
1392
+ this.container.querySelector('.gettingStartedSlideDetails').querySelectorAll('button').forEach(button => button.disabled = true);
1393
+ this.container.querySelector('.gettingStartedSlideCategories').querySelectorAll('button').forEach(button => button.disabled = false);
1394
+ this.container.querySelector('.gettingStartedSlideCategories').querySelectorAll('input').forEach(button => button.disabled = false);
1395
+ }
1396
+ else {
1397
+ slideManager.classList.add('showDetails');
1398
+ slideManager.classList.remove('showCategories');
1399
+ this.container.querySelector('.prev-button.button-link').style.display = 'block';
1400
+ this.container.querySelector('.gettingStartedSlideDetails').querySelectorAll('button').forEach(button => button.disabled = false);
1401
+ this.container.querySelector('.gettingStartedSlideCategories').querySelectorAll('button').forEach(button => button.disabled = true);
1402
+ this.container.querySelector('.gettingStartedSlideCategories').querySelectorAll('input').forEach(button => button.disabled = true);
1403
+ }
1404
+ }
1405
+ focus() {
1406
+ super.focus();
1407
+ const active = this.container.ownerDocument.activeElement;
1408
+ let parent = this.container.parentElement;
1409
+ while (parent && parent !== active) {
1410
+ parent = parent.parentElement;
1411
+ }
1412
+ if (parent) {
1413
+ this.container.focus();
1414
+ }
1415
+ }
1416
+ };
1417
+ GettingStartedPage = GettingStartedPage_1 = ( __decorate([
1418
+ ( __param(0, ICommandService)),
1419
+ ( __param(1, IProductService)),
1420
+ ( __param(2, IKeybindingService)),
1421
+ ( __param(3, IWalkthroughsService)),
1422
+ ( __param(4, IFeaturedExtensionsService)),
1423
+ ( __param(5, IConfigurationService)),
1424
+ ( __param(6, ITelemetryService)),
1425
+ ( __param(7, ILanguageService)),
1426
+ ( __param(8, IFileService)),
1427
+ ( __param(9, IOpenerService)),
1428
+ ( __param(10, IThemeService)),
1429
+ ( __param(11, IStorageService)),
1430
+ ( __param(12, IExtensionService)),
1431
+ ( __param(13, IInstantiationService)),
1432
+ ( __param(14, INotificationService)),
1433
+ ( __param(15, IEditorGroupsService)),
1434
+ ( __param(16, IContextKeyService)),
1435
+ ( __param(17, IQuickInputService)),
1436
+ ( __param(18, IWorkspacesService)),
1437
+ ( __param(19, ILabelService)),
1438
+ ( __param(20, IHostService)),
1439
+ ( __param(21, IWebviewService)),
1440
+ ( __param(22, IWorkspaceContextService)),
1441
+ ( __param(23, IAccessibilityService)),
1442
+ ( __param(24, IExtensionManagementService))
1443
+ ], GettingStartedPage));
1444
+ class GettingStartedInputSerializer {
1445
+ canSerialize(editorInput) {
1446
+ return true;
1447
+ }
1448
+ serialize(editorInput) {
1449
+ return JSON.stringify({ selectedCategory: editorInput.selectedCategory, selectedStep: editorInput.selectedStep });
1450
+ }
1451
+ deserialize(instantiationService, serializedEditorInput) {
1452
+ try {
1453
+ const { selectedCategory, selectedStep } = JSON.parse(serializedEditorInput);
1454
+ return ( new GettingStartedInput({ selectedCategory, selectedStep }));
1455
+ }
1456
+ catch { }
1457
+ return ( new GettingStartedInput({}));
1458
+ }
1459
+ }
1460
+
1461
+ export { GettingStartedInputSerializer, GettingStartedPage, allWalkthroughsHiddenContext, inWelcomeContext };