@theia/preview 1.45.1 → 1.46.0-next.72

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 (42) hide show
  1. package/README.md +45 -45
  2. package/lib/browser/index.d.ts +3 -3
  3. package/lib/browser/index.js +29 -29
  4. package/lib/browser/markdown/index.d.ts +1 -1
  5. package/lib/browser/markdown/index.js +28 -28
  6. package/lib/browser/markdown/markdown-preview-handler.d.ts +28 -28
  7. package/lib/browser/markdown/markdown-preview-handler.js +301 -301
  8. package/lib/browser/markdown/markdown-preview-handler.spec.d.ts +1 -1
  9. package/lib/browser/markdown/markdown-preview-handler.spec.js +193 -193
  10. package/lib/browser/preview-contribution.d.ts +50 -50
  11. package/lib/browser/preview-contribution.js +262 -262
  12. package/lib/browser/preview-frontend-module.d.ts +5 -5
  13. package/lib/browser/preview-frontend-module.js +52 -52
  14. package/lib/browser/preview-handler.d.ts +104 -104
  15. package/lib/browser/preview-handler.js +76 -76
  16. package/lib/browser/preview-link-normalizer.d.ts +7 -7
  17. package/lib/browser/preview-link-normalizer.js +54 -54
  18. package/lib/browser/preview-preferences.d.ts +11 -11
  19. package/lib/browser/preview-preferences.js +46 -46
  20. package/lib/browser/preview-uri.d.ts +8 -8
  21. package/lib/browser/preview-uri.js +47 -47
  22. package/lib/browser/preview-widget.d.ts +54 -54
  23. package/lib/browser/preview-widget.js +261 -261
  24. package/lib/package.spec.js +25 -25
  25. package/package.json +7 -7
  26. package/src/browser/index.ts +19 -19
  27. package/src/browser/markdown/index.ts +17 -17
  28. package/src/browser/markdown/markdown-preview-handler.spec.ts +228 -228
  29. package/src/browser/markdown/markdown-preview-handler.ts +309 -309
  30. package/src/browser/markdown/style/index.css +18 -18
  31. package/src/browser/markdown/style/markdown.css +203 -203
  32. package/src/browser/markdown/style/tomorrow.css +105 -105
  33. package/src/browser/preview-contribution.ts +276 -276
  34. package/src/browser/preview-frontend-module.ts +57 -57
  35. package/src/browser/preview-handler.ts +141 -141
  36. package/src/browser/preview-link-normalizer.ts +40 -40
  37. package/src/browser/preview-preferences.ts +58 -58
  38. package/src/browser/preview-uri.ts +43 -43
  39. package/src/browser/preview-widget.ts +277 -277
  40. package/src/browser/style/index.css +17 -17
  41. package/src/browser/style/preview-widget.css +29 -29
  42. package/src/package.spec.ts +29 -29
@@ -1,276 +1,276 @@
1
- // *****************************************************************************
2
- // Copyright (C) 2018 TypeFox and others.
3
- //
4
- // This program and the accompanying materials are made available under the
5
- // terms of the Eclipse Public License v. 2.0 which is available at
6
- // http://www.eclipse.org/legal/epl-2.0.
7
- //
8
- // This Source Code may also be made available under the following Secondary
9
- // Licenses when the conditions for such availability set forth in the Eclipse
10
- // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
- // with the GNU Classpath Exception which is available at
12
- // https://www.gnu.org/software/classpath/license.html.
13
- //
14
- // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
- // *****************************************************************************
16
-
17
- import { injectable, inject } from '@theia/core/shared/inversify';
18
- import { Widget } from '@theia/core/shared/@phosphor/widgets';
19
- import { FrontendApplicationContribution, WidgetOpenerOptions, NavigatableWidgetOpenHandler, codicon } from '@theia/core/lib/browser';
20
- import { EditorManager, TextEditor, EditorWidget, EditorContextMenu } from '@theia/editor/lib/browser';
21
- import { DisposableCollection, CommandContribution, CommandRegistry, Command, MenuContribution, MenuModelRegistry, Disposable } from '@theia/core/lib/common';
22
- import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
23
- import { MiniBrowserCommands } from '@theia/mini-browser/lib/browser/mini-browser-open-handler';
24
- import URI from '@theia/core/lib/common/uri';
25
- import { Position } from '@theia/core/shared/vscode-languageserver-protocol';
26
- import { PreviewWidget } from './preview-widget';
27
- import { PreviewHandlerProvider } from './preview-handler';
28
- import { PreviewUri } from './preview-uri';
29
- import { PreviewPreferences } from './preview-preferences';
30
- import { nls } from '@theia/core/lib/common/nls';
31
-
32
- import debounce = require('@theia/core/shared/lodash.debounce');
33
-
34
- export namespace PreviewCommands {
35
- /**
36
- * No `label`. Otherwise, it would show up in the `Command Palette` and we already have the `Preview` open handler.
37
- * See in (`WorkspaceCommandContribution`)[https://bit.ly/2DncrSD].
38
- */
39
- export const OPEN = Command.toLocalizedCommand({
40
- id: 'preview:open',
41
- label: 'Open Preview',
42
- iconClass: codicon('open-preview')
43
- }, 'vscode.markdown-language-features/package/markdown.preview.title');
44
- export const OPEN_SOURCE: Command = {
45
- id: 'preview.open.source',
46
- iconClass: codicon('go-to-file')
47
- };
48
- }
49
-
50
- export interface PreviewOpenerOptions extends WidgetOpenerOptions {
51
- originUri?: URI;
52
- }
53
-
54
- @injectable()
55
- // eslint-disable-next-line max-len
56
- export class PreviewContribution extends NavigatableWidgetOpenHandler<PreviewWidget> implements CommandContribution, MenuContribution, FrontendApplicationContribution, TabBarToolbarContribution {
57
-
58
- readonly id = PreviewUri.id;
59
- readonly label = nls.localize(MiniBrowserCommands.PREVIEW_CATEGORY_KEY, MiniBrowserCommands.PREVIEW_CATEGORY);
60
-
61
- @inject(EditorManager)
62
- protected readonly editorManager: EditorManager;
63
-
64
- @inject(PreviewHandlerProvider)
65
- protected readonly previewHandlerProvider: PreviewHandlerProvider;
66
-
67
- @inject(PreviewPreferences)
68
- protected readonly preferences: PreviewPreferences;
69
-
70
- protected readonly synchronizedUris = new Set<string>();
71
-
72
- protected scrollSyncLockOn: 'preview' | 'editor' | undefined = undefined;
73
-
74
- protected scrollSyncLockTimeout: number | undefined;
75
-
76
- onStart(): void {
77
- this.onCreated(previewWidget => {
78
- this.registerOpenOnDoubleClick(previewWidget);
79
- this.registerEditorAndPreviewSync(previewWidget);
80
- });
81
- this.editorManager.onCreated(editorWidget => {
82
- this.registerEditorAndPreviewSync(editorWidget);
83
- });
84
- }
85
-
86
- protected async lockScrollSync(on: 'preview' | 'editor', delay: number = 50): Promise<void> {
87
- this.scrollSyncLockOn = on;
88
- if (this.scrollSyncLockTimeout) {
89
- window.clearTimeout(this.scrollSyncLockTimeout);
90
- }
91
- this.scrollSyncLockTimeout = window.setTimeout(() => {
92
- this.scrollSyncLockOn = undefined;
93
- }, delay);
94
- }
95
-
96
- protected async registerEditorAndPreviewSync(source: PreviewWidget | EditorWidget): Promise<void> {
97
- let uri: string;
98
- let editorWidget: EditorWidget | undefined;
99
- let previewWidget: PreviewWidget | undefined;
100
- if (source instanceof EditorWidget) {
101
- editorWidget = source;
102
- uri = editorWidget.editor.uri.toString();
103
- previewWidget = await this.getWidget(editorWidget.editor.uri);
104
- } else {
105
- previewWidget = source;
106
- uri = previewWidget.getUri().toString();
107
- editorWidget = await this.editorManager.getByUri(previewWidget.getUri());
108
- }
109
- if (!previewWidget || !editorWidget || !uri) {
110
- return;
111
- }
112
- if (this.synchronizedUris.has(uri)) {
113
- return;
114
- }
115
- const syncDisposables = new DisposableCollection();
116
- previewWidget.disposed.connect(() => syncDisposables.dispose());
117
- editorWidget.disposed.connect(() => syncDisposables.dispose());
118
-
119
- const editor = editorWidget.editor;
120
- syncDisposables.push(editor.onScrollChanged(debounce(() => {
121
- if (this.scrollSyncLockOn === 'editor') {
122
- // avoid recursive scroll synchronization
123
- return;
124
- }
125
- this.lockScrollSync('preview');
126
- const range = editor.getVisibleRanges();
127
- if (range.length > 0) {
128
- this.revealSourceLineInPreview(previewWidget!, range[0].start);
129
- }
130
- }), 100));
131
- syncDisposables.push(this.synchronizeScrollToEditor(previewWidget, editor));
132
-
133
- this.synchronizedUris.add(uri);
134
- syncDisposables.push(Disposable.create(() => this.synchronizedUris.delete(uri)));
135
- }
136
-
137
- protected revealSourceLineInPreview(previewWidget: PreviewWidget, position: Position): void {
138
- previewWidget.revealForSourceLine(position.line);
139
- }
140
-
141
- protected synchronizeScrollToEditor(previewWidget: PreviewWidget, editor: TextEditor): Disposable {
142
- return previewWidget.onDidScroll(sourceLine => {
143
- if (this.scrollSyncLockOn === 'preview') {
144
- // avoid recursive scroll synchronization
145
- return;
146
- }
147
- const line = Math.floor(sourceLine);
148
- this.lockScrollSync('editor'); // avoid recursive scroll synchronization
149
- editor.revealRange({
150
- start: {
151
- line,
152
- character: 0
153
- },
154
- end: {
155
- line: line + 1,
156
- character: 0
157
- }
158
- }, { at: 'top' });
159
- });
160
- }
161
-
162
- protected registerOpenOnDoubleClick(ref: PreviewWidget): void {
163
- const disposable = ref.onDidDoubleClick(async location => {
164
- const { editor } = await this.openSource(ref);
165
- editor.revealPosition(location.range.start);
166
- editor.selection = location.range;
167
- ref.revealForSourceLine(location.range.start.line);
168
- });
169
- ref.disposed.connect(() => disposable.dispose());
170
- }
171
-
172
- canHandle(uri: URI): number {
173
- if (!this.previewHandlerProvider.canHandle(uri)) {
174
- return 0;
175
- }
176
- const editorPriority = this.editorManager.canHandle(uri);
177
- if (editorPriority === 0) {
178
- return 200;
179
- }
180
- if (PreviewUri.match(uri)) {
181
- return editorPriority * 2;
182
- }
183
- return editorPriority * (this.openByDefault ? 2 : 0.5);
184
- }
185
-
186
- protected get openByDefault(): boolean {
187
- return this.preferences['preview.openByDefault'];
188
- }
189
-
190
- override async open(uri: URI, options?: PreviewOpenerOptions): Promise<PreviewWidget> {
191
- const resolvedOptions = await this.resolveOpenerOptions(options);
192
- return super.open(uri, resolvedOptions);
193
- }
194
- protected override serializeUri(uri: URI): string {
195
- return super.serializeUri(PreviewUri.decode(uri));
196
- }
197
-
198
- protected async resolveOpenerOptions(options?: PreviewOpenerOptions): Promise<PreviewOpenerOptions> {
199
- const resolved: PreviewOpenerOptions = { mode: 'activate', ...options };
200
- if (resolved.originUri) {
201
- const ref = await this.getWidget(resolved.originUri);
202
- if (ref) {
203
- resolved.widgetOptions = { ...resolved.widgetOptions, ref };
204
- }
205
- }
206
- return resolved;
207
- }
208
-
209
- registerCommands(registry: CommandRegistry): void {
210
- registry.registerCommand(PreviewCommands.OPEN, {
211
- execute: widget => this.openForEditor(widget),
212
- isEnabled: widget => this.canHandleEditorUri(widget),
213
- isVisible: widget => this.canHandleEditorUri(widget)
214
- });
215
- registry.registerCommand(PreviewCommands.OPEN_SOURCE, {
216
- execute: widget => this.openSource(widget),
217
- isEnabled: widget => widget instanceof PreviewWidget,
218
- isVisible: widget => widget instanceof PreviewWidget
219
- });
220
- }
221
-
222
- registerMenus(menus: MenuModelRegistry): void {
223
- menus.registerMenuAction(EditorContextMenu.NAVIGATION, {
224
- commandId: PreviewCommands.OPEN.id
225
- });
226
- }
227
-
228
- registerToolbarItems(registry: TabBarToolbarRegistry): void {
229
- registry.registerItem({
230
- id: PreviewCommands.OPEN.id,
231
- command: PreviewCommands.OPEN.id,
232
- tooltip: nls.localize('vscode.markdown-language-features/package/markdown.previewSide.title', 'Open Preview to the Side')
233
- });
234
- registry.registerItem({
235
- id: PreviewCommands.OPEN_SOURCE.id,
236
- command: PreviewCommands.OPEN_SOURCE.id,
237
- tooltip: nls.localize('vscode.markdown-language-features/package/markdown.showSource.title', 'Open Source')
238
- });
239
- }
240
-
241
- protected canHandleEditorUri(widget?: Widget): boolean {
242
- const uri = this.getCurrentEditorUri(widget);
243
- return !!uri && this.previewHandlerProvider.canHandle(uri);
244
- }
245
-
246
- protected getCurrentEditorUri(widget?: Widget): URI | undefined {
247
- const current = this.getCurrentEditor(widget);
248
- return current && current.editor.uri;
249
- }
250
-
251
- protected getCurrentEditor(widget?: Widget): EditorWidget | undefined {
252
- const current = widget ? widget : this.editorManager.currentEditor;
253
- return current instanceof EditorWidget && current || undefined;
254
- }
255
-
256
- protected async openForEditor(widget?: Widget): Promise<void> {
257
- const ref = this.getCurrentEditor(widget);
258
- if (!ref) {
259
- return;
260
- }
261
- await this.open(ref.editor.uri, {
262
- mode: 'reveal',
263
- widgetOptions: { ref, mode: 'open-to-right' }
264
- });
265
- }
266
-
267
- protected async openSource(ref: PreviewWidget): Promise<EditorWidget>;
268
- protected async openSource(ref?: Widget): Promise<EditorWidget | undefined> {
269
- if (ref instanceof PreviewWidget) {
270
- return this.editorManager.open(ref.uri, {
271
- widgetOptions: { ref, mode: 'tab-after' }
272
- });
273
- }
274
- }
275
-
276
- }
1
+ // *****************************************************************************
2
+ // Copyright (C) 2018 TypeFox and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { injectable, inject } from '@theia/core/shared/inversify';
18
+ import { Widget } from '@theia/core/shared/@phosphor/widgets';
19
+ import { FrontendApplicationContribution, WidgetOpenerOptions, NavigatableWidgetOpenHandler, codicon } from '@theia/core/lib/browser';
20
+ import { EditorManager, TextEditor, EditorWidget, EditorContextMenu } from '@theia/editor/lib/browser';
21
+ import { DisposableCollection, CommandContribution, CommandRegistry, Command, MenuContribution, MenuModelRegistry, Disposable } from '@theia/core/lib/common';
22
+ import { TabBarToolbarContribution, TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
23
+ import { MiniBrowserCommands } from '@theia/mini-browser/lib/browser/mini-browser-open-handler';
24
+ import URI from '@theia/core/lib/common/uri';
25
+ import { Position } from '@theia/core/shared/vscode-languageserver-protocol';
26
+ import { PreviewWidget } from './preview-widget';
27
+ import { PreviewHandlerProvider } from './preview-handler';
28
+ import { PreviewUri } from './preview-uri';
29
+ import { PreviewPreferences } from './preview-preferences';
30
+ import { nls } from '@theia/core/lib/common/nls';
31
+
32
+ import debounce = require('@theia/core/shared/lodash.debounce');
33
+
34
+ export namespace PreviewCommands {
35
+ /**
36
+ * No `label`. Otherwise, it would show up in the `Command Palette` and we already have the `Preview` open handler.
37
+ * See in (`WorkspaceCommandContribution`)[https://bit.ly/2DncrSD].
38
+ */
39
+ export const OPEN = Command.toLocalizedCommand({
40
+ id: 'preview:open',
41
+ label: 'Open Preview',
42
+ iconClass: codicon('open-preview')
43
+ }, 'vscode.markdown-language-features/package/markdown.preview.title');
44
+ export const OPEN_SOURCE: Command = {
45
+ id: 'preview.open.source',
46
+ iconClass: codicon('go-to-file')
47
+ };
48
+ }
49
+
50
+ export interface PreviewOpenerOptions extends WidgetOpenerOptions {
51
+ originUri?: URI;
52
+ }
53
+
54
+ @injectable()
55
+ // eslint-disable-next-line max-len
56
+ export class PreviewContribution extends NavigatableWidgetOpenHandler<PreviewWidget> implements CommandContribution, MenuContribution, FrontendApplicationContribution, TabBarToolbarContribution {
57
+
58
+ readonly id = PreviewUri.id;
59
+ readonly label = nls.localize(MiniBrowserCommands.PREVIEW_CATEGORY_KEY, MiniBrowserCommands.PREVIEW_CATEGORY);
60
+
61
+ @inject(EditorManager)
62
+ protected readonly editorManager: EditorManager;
63
+
64
+ @inject(PreviewHandlerProvider)
65
+ protected readonly previewHandlerProvider: PreviewHandlerProvider;
66
+
67
+ @inject(PreviewPreferences)
68
+ protected readonly preferences: PreviewPreferences;
69
+
70
+ protected readonly synchronizedUris = new Set<string>();
71
+
72
+ protected scrollSyncLockOn: 'preview' | 'editor' | undefined = undefined;
73
+
74
+ protected scrollSyncLockTimeout: number | undefined;
75
+
76
+ onStart(): void {
77
+ this.onCreated(previewWidget => {
78
+ this.registerOpenOnDoubleClick(previewWidget);
79
+ this.registerEditorAndPreviewSync(previewWidget);
80
+ });
81
+ this.editorManager.onCreated(editorWidget => {
82
+ this.registerEditorAndPreviewSync(editorWidget);
83
+ });
84
+ }
85
+
86
+ protected async lockScrollSync(on: 'preview' | 'editor', delay: number = 50): Promise<void> {
87
+ this.scrollSyncLockOn = on;
88
+ if (this.scrollSyncLockTimeout) {
89
+ window.clearTimeout(this.scrollSyncLockTimeout);
90
+ }
91
+ this.scrollSyncLockTimeout = window.setTimeout(() => {
92
+ this.scrollSyncLockOn = undefined;
93
+ }, delay);
94
+ }
95
+
96
+ protected async registerEditorAndPreviewSync(source: PreviewWidget | EditorWidget): Promise<void> {
97
+ let uri: string;
98
+ let editorWidget: EditorWidget | undefined;
99
+ let previewWidget: PreviewWidget | undefined;
100
+ if (source instanceof EditorWidget) {
101
+ editorWidget = source;
102
+ uri = editorWidget.editor.uri.toString();
103
+ previewWidget = await this.getWidget(editorWidget.editor.uri);
104
+ } else {
105
+ previewWidget = source;
106
+ uri = previewWidget.getUri().toString();
107
+ editorWidget = await this.editorManager.getByUri(previewWidget.getUri());
108
+ }
109
+ if (!previewWidget || !editorWidget || !uri) {
110
+ return;
111
+ }
112
+ if (this.synchronizedUris.has(uri)) {
113
+ return;
114
+ }
115
+ const syncDisposables = new DisposableCollection();
116
+ previewWidget.disposed.connect(() => syncDisposables.dispose());
117
+ editorWidget.disposed.connect(() => syncDisposables.dispose());
118
+
119
+ const editor = editorWidget.editor;
120
+ syncDisposables.push(editor.onScrollChanged(debounce(() => {
121
+ if (this.scrollSyncLockOn === 'editor') {
122
+ // avoid recursive scroll synchronization
123
+ return;
124
+ }
125
+ this.lockScrollSync('preview');
126
+ const range = editor.getVisibleRanges();
127
+ if (range.length > 0) {
128
+ this.revealSourceLineInPreview(previewWidget!, range[0].start);
129
+ }
130
+ }), 100));
131
+ syncDisposables.push(this.synchronizeScrollToEditor(previewWidget, editor));
132
+
133
+ this.synchronizedUris.add(uri);
134
+ syncDisposables.push(Disposable.create(() => this.synchronizedUris.delete(uri)));
135
+ }
136
+
137
+ protected revealSourceLineInPreview(previewWidget: PreviewWidget, position: Position): void {
138
+ previewWidget.revealForSourceLine(position.line);
139
+ }
140
+
141
+ protected synchronizeScrollToEditor(previewWidget: PreviewWidget, editor: TextEditor): Disposable {
142
+ return previewWidget.onDidScroll(sourceLine => {
143
+ if (this.scrollSyncLockOn === 'preview') {
144
+ // avoid recursive scroll synchronization
145
+ return;
146
+ }
147
+ const line = Math.floor(sourceLine);
148
+ this.lockScrollSync('editor'); // avoid recursive scroll synchronization
149
+ editor.revealRange({
150
+ start: {
151
+ line,
152
+ character: 0
153
+ },
154
+ end: {
155
+ line: line + 1,
156
+ character: 0
157
+ }
158
+ }, { at: 'top' });
159
+ });
160
+ }
161
+
162
+ protected registerOpenOnDoubleClick(ref: PreviewWidget): void {
163
+ const disposable = ref.onDidDoubleClick(async location => {
164
+ const { editor } = await this.openSource(ref);
165
+ editor.revealPosition(location.range.start);
166
+ editor.selection = location.range;
167
+ ref.revealForSourceLine(location.range.start.line);
168
+ });
169
+ ref.disposed.connect(() => disposable.dispose());
170
+ }
171
+
172
+ canHandle(uri: URI): number {
173
+ if (!this.previewHandlerProvider.canHandle(uri)) {
174
+ return 0;
175
+ }
176
+ const editorPriority = this.editorManager.canHandle(uri);
177
+ if (editorPriority === 0) {
178
+ return 200;
179
+ }
180
+ if (PreviewUri.match(uri)) {
181
+ return editorPriority * 2;
182
+ }
183
+ return editorPriority * (this.openByDefault ? 2 : 0.5);
184
+ }
185
+
186
+ protected get openByDefault(): boolean {
187
+ return this.preferences['preview.openByDefault'];
188
+ }
189
+
190
+ override async open(uri: URI, options?: PreviewOpenerOptions): Promise<PreviewWidget> {
191
+ const resolvedOptions = await this.resolveOpenerOptions(options);
192
+ return super.open(uri, resolvedOptions);
193
+ }
194
+ protected override serializeUri(uri: URI): string {
195
+ return super.serializeUri(PreviewUri.decode(uri));
196
+ }
197
+
198
+ protected async resolveOpenerOptions(options?: PreviewOpenerOptions): Promise<PreviewOpenerOptions> {
199
+ const resolved: PreviewOpenerOptions = { mode: 'activate', ...options };
200
+ if (resolved.originUri) {
201
+ const ref = await this.getWidget(resolved.originUri);
202
+ if (ref) {
203
+ resolved.widgetOptions = { ...resolved.widgetOptions, ref };
204
+ }
205
+ }
206
+ return resolved;
207
+ }
208
+
209
+ registerCommands(registry: CommandRegistry): void {
210
+ registry.registerCommand(PreviewCommands.OPEN, {
211
+ execute: widget => this.openForEditor(widget),
212
+ isEnabled: widget => this.canHandleEditorUri(widget),
213
+ isVisible: widget => this.canHandleEditorUri(widget)
214
+ });
215
+ registry.registerCommand(PreviewCommands.OPEN_SOURCE, {
216
+ execute: widget => this.openSource(widget),
217
+ isEnabled: widget => widget instanceof PreviewWidget,
218
+ isVisible: widget => widget instanceof PreviewWidget
219
+ });
220
+ }
221
+
222
+ registerMenus(menus: MenuModelRegistry): void {
223
+ menus.registerMenuAction(EditorContextMenu.NAVIGATION, {
224
+ commandId: PreviewCommands.OPEN.id
225
+ });
226
+ }
227
+
228
+ registerToolbarItems(registry: TabBarToolbarRegistry): void {
229
+ registry.registerItem({
230
+ id: PreviewCommands.OPEN.id,
231
+ command: PreviewCommands.OPEN.id,
232
+ tooltip: nls.localize('vscode.markdown-language-features/package/markdown.previewSide.title', 'Open Preview to the Side')
233
+ });
234
+ registry.registerItem({
235
+ id: PreviewCommands.OPEN_SOURCE.id,
236
+ command: PreviewCommands.OPEN_SOURCE.id,
237
+ tooltip: nls.localize('vscode.markdown-language-features/package/markdown.showSource.title', 'Open Source')
238
+ });
239
+ }
240
+
241
+ protected canHandleEditorUri(widget?: Widget): boolean {
242
+ const uri = this.getCurrentEditorUri(widget);
243
+ return !!uri && this.previewHandlerProvider.canHandle(uri);
244
+ }
245
+
246
+ protected getCurrentEditorUri(widget?: Widget): URI | undefined {
247
+ const current = this.getCurrentEditor(widget);
248
+ return current && current.editor.uri;
249
+ }
250
+
251
+ protected getCurrentEditor(widget?: Widget): EditorWidget | undefined {
252
+ const current = widget ? widget : this.editorManager.currentEditor;
253
+ return current instanceof EditorWidget && current || undefined;
254
+ }
255
+
256
+ protected async openForEditor(widget?: Widget): Promise<void> {
257
+ const ref = this.getCurrentEditor(widget);
258
+ if (!ref) {
259
+ return;
260
+ }
261
+ await this.open(ref.editor.uri, {
262
+ mode: 'reveal',
263
+ widgetOptions: { ref, mode: 'open-to-right' }
264
+ });
265
+ }
266
+
267
+ protected async openSource(ref: PreviewWidget): Promise<EditorWidget>;
268
+ protected async openSource(ref?: Widget): Promise<EditorWidget | undefined> {
269
+ if (ref instanceof PreviewWidget) {
270
+ return this.editorManager.open(ref.uri, {
271
+ widgetOptions: { ref, mode: 'tab-after' }
272
+ });
273
+ }
274
+ }
275
+
276
+ }