@theia/editor-preview 1.74.0-next.9 → 1.75.0-next.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/editor-preview-manager.d.ts.map +1 -1
- package/lib/browser/editor-preview-manager.js +8 -18
- package/lib/browser/editor-preview-manager.js.map +1 -1
- package/lib/browser/editor-preview-widget.d.ts +5 -5
- package/lib/browser/editor-preview-widget.d.ts.map +1 -1
- package/lib/browser/editor-preview-widget.js +17 -40
- package/lib/browser/editor-preview-widget.js.map +1 -1
- package/lib/browser/preview-tab-widget.d.ts +59 -0
- package/lib/browser/preview-tab-widget.d.ts.map +1 -0
- package/lib/browser/preview-tab-widget.js +109 -0
- package/lib/browser/preview-tab-widget.js.map +1 -0
- package/lib/browser/preview-tab-widget.spec.d.ts +2 -0
- package/lib/browser/preview-tab-widget.spec.d.ts.map +1 -0
- package/lib/browser/preview-tab-widget.spec.js +108 -0
- package/lib/browser/preview-tab-widget.spec.js.map +1 -0
- package/lib/common/editor-preview-preferences.d.ts +1 -0
- package/lib/common/editor-preview-preferences.d.ts.map +1 -1
- package/lib/common/editor-preview-preferences.js +3 -2
- package/lib/common/editor-preview-preferences.js.map +1 -1
- package/package.json +6 -6
- package/src/browser/editor-preview-manager.ts +10 -18
- package/src/browser/editor-preview-widget.ts +20 -38
- package/src/browser/preview-tab-widget.spec.ts +119 -0
- package/src/browser/preview-tab-widget.ts +138 -0
- package/src/common/editor-preview-preferences.ts +3 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-manager.d.ts","sourceRoot":"","sources":["../../src/browser/editor-preview-manager.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE7F,OAAO,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"editor-preview-manager.d.ts","sourceRoot":"","sources":["../../src/browser/editor-preview-manager.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE7F,OAAO,EAAE,wBAAwB,EAA6B,MAAM,sCAAsC,CAAC;AAC3G,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,GAAG,MAAM,4BAA4B,CAAC;AAC7C,OAAO,EAA8B,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAE9D,OAAO,EAAE,+BAA+B,EAAE,MAAM,oDAAoD,CAAC;AAGrG,qBACa,oBAAqB,SAAQ,aAAa;IACnD,SAAkB,EAAE,SAAiC;IAEnB,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,wBAAwB,CAAC;IAClD,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,+BAA+B,CAAC;IAE1G;;OAEG;IACH,SAAS,CAAC,WAAW,UAAS;cAGX,IAAI,IAAI,IAAI;cAkCN,MAAM,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBpH,SAAS,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,mBAAmB,GAAG,IAAI;cAIpD,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,YAAY,CAAC,YAAY,CAAC,GAAG,SAAS;cAK9F,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;cAIrF,iBAAiB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC;cAIvF,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,oBAAoB;IAMrG,SAAS,CAAC,0BAA0B,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;CAM3D"}
|
|
@@ -21,7 +21,7 @@ const browser_1 = require("@theia/editor/lib/browser");
|
|
|
21
21
|
const inversify_1 = require("@theia/core/shared/inversify");
|
|
22
22
|
const editor_preview_preferences_1 = require("../common/editor-preview-preferences");
|
|
23
23
|
const editor_preview_widget_factory_1 = require("./editor-preview-widget-factory");
|
|
24
|
-
const
|
|
24
|
+
const preview_tab_widget_1 = require("./preview-tab-widget");
|
|
25
25
|
const frontend_application_state_1 = require("@theia/core/lib/browser/frontend-application-state");
|
|
26
26
|
let EditorPreviewManager = class EditorPreviewManager extends browser_1.EditorManager {
|
|
27
27
|
constructor() {
|
|
@@ -44,14 +44,13 @@ let EditorPreviewManager = class EditorPreviewManager extends browser_1.EditorMa
|
|
|
44
44
|
}
|
|
45
45
|
});
|
|
46
46
|
this.preferences.onPreferenceChanged(change => {
|
|
47
|
-
if (change.preferenceName ===
|
|
48
|
-
this.
|
|
49
|
-
if (
|
|
50
|
-
|
|
47
|
+
if (change.preferenceName === editor_preview_preferences_1.ENABLE_PREVIEW_PREFERENCE && !this.preferences[editor_preview_preferences_1.ENABLE_PREVIEW_PREFERENCE]) {
|
|
48
|
+
this.shell.widgets.forEach(widget => {
|
|
49
|
+
if (preview_tab_widget_1.PreviewTabWidget.is(widget) && widget.isPreview) {
|
|
50
|
+
widget.convertToNonPreview();
|
|
51
51
|
}
|
|
52
52
|
});
|
|
53
53
|
}
|
|
54
|
-
;
|
|
55
54
|
});
|
|
56
55
|
this.stateService.reachedState('initialized_layout').then(() => {
|
|
57
56
|
const editors = this.all;
|
|
@@ -80,16 +79,7 @@ let EditorPreviewManager = class EditorPreviewManager extends browser_1.EditorMa
|
|
|
80
79
|
await this.revealSelection(widget, uri, options);
|
|
81
80
|
}
|
|
82
81
|
handleNewPreview(newPreviewWidget) {
|
|
83
|
-
|
|
84
|
-
const tabbar = this.shell.getTabBarFor(newPreviewWidget);
|
|
85
|
-
if (tabbar) {
|
|
86
|
-
for (const title of tabbar.titles) {
|
|
87
|
-
if (title.owner !== newPreviewWidget && title.owner instanceof editor_preview_widget_1.EditorPreviewWidget && title.owner.isPreview) {
|
|
88
|
-
title.owner.dispose();
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
82
|
+
preview_tab_widget_1.PreviewTabWidget.disposeOtherPreviews(this.shell, newPreviewWidget);
|
|
93
83
|
}
|
|
94
84
|
tryGetPendingWidget(uri, options) {
|
|
95
85
|
return super.tryGetPendingWidget(uri, { ...options, preview: true }) ??
|
|
@@ -103,12 +93,12 @@ let EditorPreviewManager = class EditorPreviewManager extends browser_1.EditorMa
|
|
|
103
93
|
}
|
|
104
94
|
createWidgetOptions(uri, options) {
|
|
105
95
|
const navigatableOptions = super.createWidgetOptions(uri, options);
|
|
106
|
-
navigatableOptions.preview = !!(options?.preview && this.preferences[
|
|
96
|
+
navigatableOptions.preview = !!(options?.preview && this.preferences[editor_preview_preferences_1.ENABLE_PREVIEW_PREFERENCE]);
|
|
107
97
|
return navigatableOptions;
|
|
108
98
|
}
|
|
109
99
|
convertEditorOnDoubleClick(event) {
|
|
110
100
|
const widget = this.shell.findTargetedWidget(event);
|
|
111
|
-
if (widget
|
|
101
|
+
if (preview_tab_widget_1.PreviewTabWidget.is(widget) && widget.isPreview) {
|
|
112
102
|
widget.convertToNonPreview();
|
|
113
103
|
}
|
|
114
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-manager.js","sourceRoot":"","sources":["../../src/browser/editor-preview-manager.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,6CAA6C;AAC7C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;;AAEhF,uDAA6F;AAC7F,4DAAiF;AACjF,
|
|
1
|
+
{"version":3,"file":"editor-preview-manager.js","sourceRoot":"","sources":["../../src/browser/editor-preview-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { TabBar, Widget } from '@theia/core/lib/browser';
|
|
2
2
|
import { EditorWidget, TextEditor } from '@theia/editor/lib/browser';
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
protected readonly
|
|
7
|
-
readonly onDidChangePreviewState: import("@theia/core/lib/common").Event<void>;
|
|
3
|
+
import { Event, SelectionService } from '@theia/core/lib/common';
|
|
4
|
+
import { PreviewTabWidget, PreviewTabSupport } from './preview-tab-widget';
|
|
5
|
+
export declare class EditorPreviewWidget extends EditorWidget implements PreviewTabWidget {
|
|
6
|
+
protected readonly previewSupport: PreviewTabSupport;
|
|
8
7
|
get isPreview(): boolean;
|
|
8
|
+
get onDidChangePreviewState(): Event<void>;
|
|
9
9
|
constructor(editor: TextEditor, selectionService: SelectionService);
|
|
10
10
|
initializePreview(): void;
|
|
11
11
|
convertToNonPreview(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-widget.d.ts","sourceRoot":"","sources":["../../src/browser/editor-preview-widget.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"editor-preview-widget.d.ts","sourceRoot":"","sources":["../../src/browser/editor-preview-widget.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAmB,MAAM,wBAAwB,CAAC;AAClF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE3E,qBAAa,mBAAoB,SAAQ,YAAa,YAAW,gBAAgB;IAE7E,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAErD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,IAAI,uBAAuB,IAAI,KAAK,CAAC,IAAI,CAAC,CAEzC;gBAGG,MAAM,EAAE,UAAU,EAClB,gBAAgB,EAAE,gBAAgB;IAWtC,iBAAiB,IAAI,IAAI;IAIzB,mBAAmB,IAAI,IAAI;cAIR,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,IAAI;IAKlH,UAAU,IAAI;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAMrE,YAAY,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAMrF"}
|
|
@@ -16,61 +16,38 @@
|
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.EditorPreviewWidget = void 0;
|
|
19
|
-
const browser_1 = require("@theia/
|
|
20
|
-
const browser_2 = require("@theia/editor/lib/browser");
|
|
19
|
+
const browser_1 = require("@theia/editor/lib/browser");
|
|
21
20
|
const common_1 = require("@theia/core/lib/common");
|
|
22
|
-
const
|
|
23
|
-
class EditorPreviewWidget extends
|
|
21
|
+
const preview_tab_widget_1 = require("./preview-tab-widget");
|
|
22
|
+
class EditorPreviewWidget extends browser_1.EditorWidget {
|
|
24
23
|
get isPreview() {
|
|
25
|
-
return this.
|
|
24
|
+
return this.previewSupport.isPreview;
|
|
25
|
+
}
|
|
26
|
+
get onDidChangePreviewState() {
|
|
27
|
+
return this.previewSupport.onDidChangePreviewState;
|
|
26
28
|
}
|
|
27
29
|
constructor(editor, selectionService) {
|
|
28
30
|
super(editor, selectionService);
|
|
29
|
-
this.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
this.previewSupport = new preview_tab_widget_1.PreviewTabSupport({
|
|
32
|
+
title: this.title,
|
|
33
|
+
saveable: this.saveable,
|
|
34
|
+
toDispose: this.toDispose,
|
|
35
|
+
onConvertToNonPreview: () => this.tabBarTracker.reset()
|
|
36
|
+
});
|
|
33
37
|
}
|
|
34
38
|
initializePreview() {
|
|
35
|
-
|
|
36
|
-
this._isPreview = true;
|
|
37
|
-
this.title.className += ` ${PREVIEW_TITLE_CLASS}`;
|
|
38
|
-
const oneTimeDirtyChangeListener = this.saveable.onDirtyChanged(() => {
|
|
39
|
-
this.convertToNonPreview();
|
|
40
|
-
oneTimeListeners.dispose();
|
|
41
|
-
});
|
|
42
|
-
oneTimeListeners.push(oneTimeDirtyChangeListener);
|
|
43
|
-
const oneTimeTitleChangeHandler = () => {
|
|
44
|
-
if (this.title.className.includes(browser_1.PINNED_CLASS)) {
|
|
45
|
-
this.convertToNonPreview();
|
|
46
|
-
oneTimeListeners.dispose();
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
this.title.changed.connect(oneTimeTitleChangeHandler);
|
|
50
|
-
oneTimeListeners.push(common_1.Disposable.create(() => this.title.changed.disconnect(oneTimeTitleChangeHandler)));
|
|
51
|
-
this.toDispose.push(oneTimeListeners);
|
|
39
|
+
this.previewSupport.initializePreview();
|
|
52
40
|
}
|
|
53
41
|
convertToNonPreview() {
|
|
54
|
-
|
|
55
|
-
this._isPreview = false;
|
|
56
|
-
this.currentTabbar = undefined;
|
|
57
|
-
this.title.className = this.title.className.replace(PREVIEW_TITLE_CLASS, '');
|
|
58
|
-
this.onDidChangePreviewStateEmitter.fire();
|
|
59
|
-
this.onDidChangePreviewStateEmitter.dispose();
|
|
60
|
-
}
|
|
42
|
+
this.previewSupport.convertToNonPreview();
|
|
61
43
|
}
|
|
62
44
|
handleTabBarChange(oldTabBar, newTabBar) {
|
|
63
45
|
super.handleTabBarChange(oldTabBar, newTabBar);
|
|
64
|
-
|
|
65
|
-
if (oldTabBar && newTabBar) {
|
|
66
|
-
this.convertToNonPreview();
|
|
67
|
-
}
|
|
68
|
-
}
|
|
46
|
+
this.previewSupport.handleTabBarChange(oldTabBar, newTabBar);
|
|
69
47
|
}
|
|
70
48
|
storeState() {
|
|
71
49
|
if (this.getResourceUri()?.scheme !== common_1.UNTITLED_SCHEME) {
|
|
72
|
-
|
|
73
|
-
return { isPreview, editorState: this.editor.storeViewState() };
|
|
50
|
+
return { isPreview: this.isPreview, editorState: this.editor.storeViewState() };
|
|
74
51
|
}
|
|
75
52
|
}
|
|
76
53
|
restoreState(oldState) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-widget.js","sourceRoot":"","sources":["../../src/browser/editor-preview-widget.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;
|
|
1
|
+
{"version":3,"file":"editor-preview-widget.js","sourceRoot":"","sources":["../../src/browser/editor-preview-widget.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0CAA0C;AAC1C,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAGhF,uDAAqE;AACrE,mDAAkF;AAClF,6DAA2E;AAE3E,MAAa,mBAAoB,SAAQ,sBAAY;IAIjD,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC;IACzC,CAAC;IAED,IAAI,uBAAuB;QACvB,OAAO,IAAI,CAAC,cAAc,CAAC,uBAAuB,CAAC;IACvD,CAAC;IAED,YACI,MAAkB,EAClB,gBAAkC;QAElC,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,sCAAiB,CAAC;YACxC,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,qBAAqB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE;SAC1D,CAAC,CAAC;IACP,CAAC;IAED,iBAAiB;QACb,IAAI,CAAC,cAAc,CAAC,iBAAiB,EAAE,CAAC;IAC5C,CAAC;IAED,mBAAmB;QACf,IAAI,CAAC,cAAc,CAAC,mBAAmB,EAAE,CAAC;IAC9C,CAAC;IAEkB,kBAAkB,CAAC,SAAsC,EAAE,SAAsC;QAChH,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,CAAC,cAAc,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjE,CAAC;IAEQ,UAAU;QACf,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,MAAM,KAAK,wBAAe,EAAE,CAAC;YACpD,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;QACpF,CAAC;IACL,CAAC;IAEQ,YAAY,CAAC,QAAqD;QACvE,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;YACtB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC/B,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvD,CAAC;CACJ;AAlDD,kDAkDC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { ApplicationShell, Saveable } from '@theia/core/lib/browser';
|
|
2
|
+
import { TabBar, Title, Widget } from '@theia/core/shared/@lumino/widgets';
|
|
3
|
+
import { DisposableCollection, Emitter, Event } from '@theia/core/lib/common';
|
|
4
|
+
export declare const PREVIEW_TITLE_CLASS = "theia-editor-preview-title-unpinned";
|
|
5
|
+
/**
|
|
6
|
+
* A widget that can be displayed as a reusable "preview" tab. A preview tab is rendered with an
|
|
7
|
+
* italic (unpinned) title and is promoted to a permanent tab once its content becomes dirty,
|
|
8
|
+
* its title is pinned, it is double-clicked, or it is moved to a different tab-bar.
|
|
9
|
+
*/
|
|
10
|
+
export interface PreviewTabWidget {
|
|
11
|
+
readonly isPreview: boolean;
|
|
12
|
+
readonly onDidChangePreviewState: Event<void>;
|
|
13
|
+
initializePreview(): void;
|
|
14
|
+
convertToNonPreview(): void;
|
|
15
|
+
}
|
|
16
|
+
export declare namespace PreviewTabWidget {
|
|
17
|
+
function is(arg: unknown): arg is Widget & PreviewTabWidget;
|
|
18
|
+
/**
|
|
19
|
+
* Dispose every other preview widget sharing the target widget's tab-bar so that at most one
|
|
20
|
+
* preview tab exists per editor group, regardless of the concrete preview widget types.
|
|
21
|
+
*/
|
|
22
|
+
function disposeOtherPreviews(shell: ApplicationShell, widget: Widget & PreviewTabWidget): void;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The host widget capabilities required by {@link PreviewTabSupport}.
|
|
26
|
+
*/
|
|
27
|
+
export interface PreviewTabHost {
|
|
28
|
+
readonly title: Title<Widget>;
|
|
29
|
+
readonly saveable: Saveable;
|
|
30
|
+
readonly toDispose: DisposableCollection;
|
|
31
|
+
/**
|
|
32
|
+
* Invoked from {@link PreviewTabSupport.convertToNonPreview} to let the host perform additional
|
|
33
|
+
* clean-up, e.g. resetting its tab-bar tracking.
|
|
34
|
+
*/
|
|
35
|
+
onConvertToNonPreview?(): void;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Reusable implementation of the {@link PreviewTabWidget} behavior. Widgets that cannot share a
|
|
39
|
+
* common base class compose this and delegate their preview-related members to it.
|
|
40
|
+
*
|
|
41
|
+
* It only owns the preview *state* and its promotion triggers. Detecting a move between tab-bars is
|
|
42
|
+
* left to the host (e.g. via `TabBarTracker`), which feeds {@link handleTabBarChange}; hosts whose
|
|
43
|
+
* base class already tracks this (like `EditorWidget`) reuse that instead.
|
|
44
|
+
*/
|
|
45
|
+
export declare class PreviewTabSupport implements PreviewTabWidget {
|
|
46
|
+
protected readonly host: PreviewTabHost;
|
|
47
|
+
protected _isPreview: boolean;
|
|
48
|
+
protected readonly onDidChangePreviewStateEmitter: Emitter<void>;
|
|
49
|
+
readonly onDidChangePreviewState: Event<void>;
|
|
50
|
+
constructor(host: PreviewTabHost);
|
|
51
|
+
get isPreview(): boolean;
|
|
52
|
+
initializePreview(): void;
|
|
53
|
+
convertToNonPreview(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Promote the preview to a permanent tab when it is moved between two tab-bars.
|
|
56
|
+
*/
|
|
57
|
+
handleTabBarChange(oldTabBar?: TabBar<Widget>, newTabBar?: TabBar<Widget>): void;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=preview-tab-widget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-tab-widget.d.ts","sourceRoot":"","sources":["../../src/browser/preview-tab-widget.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,gBAAgB,EAAgB,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAc,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAE1F,eAAO,MAAM,mBAAmB,wCAAwC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,uBAAuB,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,iBAAiB,IAAI,IAAI,CAAC;IAC1B,mBAAmB,IAAI,IAAI,CAAC;CAC/B;AAED,yBAAiB,gBAAgB,CAAC;IAC9B,SAAgB,EAAE,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,MAAM,GAAG,gBAAgB,CAMjE;IAED;;;OAGG;IACH,SAAgB,oBAAoB,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAYrG;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,oBAAoB,CAAC;IACzC;;;OAGG;IACH,qBAAqB,CAAC,IAAI,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,YAAW,gBAAgB;IAO1C,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc;IALnD,SAAS,CAAC,UAAU,UAAS;IAE7B,SAAS,CAAC,QAAQ,CAAC,8BAA8B,gBAAuB;IACxE,QAAQ,CAAC,uBAAuB,cAA6C;gBAE9C,IAAI,EAAE,cAAc;IAInD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,iBAAiB,IAAI,IAAI;IAoBzB,mBAAmB,IAAI,IAAI;IAU3B;;OAEG;IACH,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI;CAKnF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 JuliaHub, Inc. and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.PreviewTabSupport = exports.PreviewTabWidget = exports.PREVIEW_TITLE_CLASS = void 0;
|
|
19
|
+
const browser_1 = require("@theia/core/lib/browser");
|
|
20
|
+
const widgets_1 = require("@theia/core/shared/@lumino/widgets");
|
|
21
|
+
const common_1 = require("@theia/core/lib/common");
|
|
22
|
+
exports.PREVIEW_TITLE_CLASS = 'theia-editor-preview-title-unpinned';
|
|
23
|
+
var PreviewTabWidget;
|
|
24
|
+
(function (PreviewTabWidget) {
|
|
25
|
+
function is(arg) {
|
|
26
|
+
return arg instanceof widgets_1.Widget
|
|
27
|
+
&& 'isPreview' in arg && typeof arg.isPreview === 'boolean'
|
|
28
|
+
&& 'onDidChangePreviewState' in arg && typeof arg.onDidChangePreviewState === 'function'
|
|
29
|
+
&& 'initializePreview' in arg && typeof arg.initializePreview === 'function'
|
|
30
|
+
&& 'convertToNonPreview' in arg && typeof arg.convertToNonPreview === 'function';
|
|
31
|
+
}
|
|
32
|
+
PreviewTabWidget.is = is;
|
|
33
|
+
/**
|
|
34
|
+
* Dispose every other preview widget sharing the target widget's tab-bar so that at most one
|
|
35
|
+
* preview tab exists per editor group, regardless of the concrete preview widget types.
|
|
36
|
+
*/
|
|
37
|
+
function disposeOtherPreviews(shell, widget) {
|
|
38
|
+
if (!widget.isPreview) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const tabbar = shell.getTabBarFor(widget);
|
|
42
|
+
if (tabbar) {
|
|
43
|
+
for (const title of tabbar.titles) {
|
|
44
|
+
if (title.owner !== widget && is(title.owner) && title.owner.isPreview) {
|
|
45
|
+
title.owner.dispose();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
PreviewTabWidget.disposeOtherPreviews = disposeOtherPreviews;
|
|
51
|
+
})(PreviewTabWidget || (exports.PreviewTabWidget = PreviewTabWidget = {}));
|
|
52
|
+
/**
|
|
53
|
+
* Reusable implementation of the {@link PreviewTabWidget} behavior. Widgets that cannot share a
|
|
54
|
+
* common base class compose this and delegate their preview-related members to it.
|
|
55
|
+
*
|
|
56
|
+
* It only owns the preview *state* and its promotion triggers. Detecting a move between tab-bars is
|
|
57
|
+
* left to the host (e.g. via `TabBarTracker`), which feeds {@link handleTabBarChange}; hosts whose
|
|
58
|
+
* base class already tracks this (like `EditorWidget`) reuse that instead.
|
|
59
|
+
*/
|
|
60
|
+
class PreviewTabSupport {
|
|
61
|
+
constructor(host) {
|
|
62
|
+
this.host = host;
|
|
63
|
+
this._isPreview = false;
|
|
64
|
+
this.onDidChangePreviewStateEmitter = new common_1.Emitter();
|
|
65
|
+
this.onDidChangePreviewState = this.onDidChangePreviewStateEmitter.event;
|
|
66
|
+
this.host.toDispose.push(this.onDidChangePreviewStateEmitter);
|
|
67
|
+
}
|
|
68
|
+
get isPreview() {
|
|
69
|
+
return this._isPreview;
|
|
70
|
+
}
|
|
71
|
+
initializePreview() {
|
|
72
|
+
const oneTimeListeners = new common_1.DisposableCollection();
|
|
73
|
+
this._isPreview = true;
|
|
74
|
+
this.host.title.className += ` ${exports.PREVIEW_TITLE_CLASS}`;
|
|
75
|
+
const oneTimeDirtyChangeListener = this.host.saveable.onDirtyChanged(() => {
|
|
76
|
+
this.convertToNonPreview();
|
|
77
|
+
oneTimeListeners.dispose();
|
|
78
|
+
});
|
|
79
|
+
oneTimeListeners.push(oneTimeDirtyChangeListener);
|
|
80
|
+
const oneTimeTitleChangeHandler = () => {
|
|
81
|
+
if (this.host.title.className.includes(browser_1.PINNED_CLASS)) {
|
|
82
|
+
this.convertToNonPreview();
|
|
83
|
+
oneTimeListeners.dispose();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
this.host.title.changed.connect(oneTimeTitleChangeHandler);
|
|
87
|
+
oneTimeListeners.push(common_1.Disposable.create(() => this.host.title.changed.disconnect(oneTimeTitleChangeHandler)));
|
|
88
|
+
this.host.toDispose.push(oneTimeListeners);
|
|
89
|
+
}
|
|
90
|
+
convertToNonPreview() {
|
|
91
|
+
if (this._isPreview) {
|
|
92
|
+
this._isPreview = false;
|
|
93
|
+
this.host.onConvertToNonPreview?.();
|
|
94
|
+
this.host.title.className = this.host.title.className.replace(exports.PREVIEW_TITLE_CLASS, '');
|
|
95
|
+
this.onDidChangePreviewStateEmitter.fire();
|
|
96
|
+
this.onDidChangePreviewStateEmitter.dispose();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Promote the preview to a permanent tab when it is moved between two tab-bars.
|
|
101
|
+
*/
|
|
102
|
+
handleTabBarChange(oldTabBar, newTabBar) {
|
|
103
|
+
if (this._isPreview && oldTabBar && newTabBar) {
|
|
104
|
+
this.convertToNonPreview();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
exports.PreviewTabSupport = PreviewTabSupport;
|
|
109
|
+
//# sourceMappingURL=preview-tab-widget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-tab-widget.js","sourceRoot":"","sources":["../../src/browser/preview-tab-widget.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-tab-widget.spec.d.ts","sourceRoot":"","sources":["../../src/browser/preview-tab-widget.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2026 JuliaHub, Inc. and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
const jsdom_1 = require("@theia/core/lib/browser/test/jsdom");
|
|
19
|
+
let disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
20
|
+
const chai_1 = require("chai");
|
|
21
|
+
const common_1 = require("@theia/core/lib/common");
|
|
22
|
+
const browser_1 = require("@theia/core/lib/browser");
|
|
23
|
+
const widgets_1 = require("@theia/core/shared/@lumino/widgets");
|
|
24
|
+
const preview_tab_widget_1 = require("./preview-tab-widget");
|
|
25
|
+
disableJSDOM();
|
|
26
|
+
describe('PreviewTabSupport', () => {
|
|
27
|
+
before(() => {
|
|
28
|
+
disableJSDOM = (0, jsdom_1.enableJSDOM)();
|
|
29
|
+
});
|
|
30
|
+
after(() => {
|
|
31
|
+
disableJSDOM();
|
|
32
|
+
});
|
|
33
|
+
function createHost(overrides) {
|
|
34
|
+
const widget = new widgets_1.Widget();
|
|
35
|
+
const dirtyEmitter = new common_1.Emitter();
|
|
36
|
+
const saveable = {
|
|
37
|
+
dirty: false,
|
|
38
|
+
onDirtyChanged: dirtyEmitter.event,
|
|
39
|
+
onContentChanged: new common_1.Emitter().event,
|
|
40
|
+
save: async () => { }
|
|
41
|
+
};
|
|
42
|
+
const host = {
|
|
43
|
+
title: widget.title,
|
|
44
|
+
saveable,
|
|
45
|
+
toDispose: new common_1.DisposableCollection(),
|
|
46
|
+
...overrides
|
|
47
|
+
};
|
|
48
|
+
return { host, dirtyEmitter };
|
|
49
|
+
}
|
|
50
|
+
it('is not a preview until initialized', () => {
|
|
51
|
+
const { host } = createHost();
|
|
52
|
+
(0, chai_1.expect)(new preview_tab_widget_1.PreviewTabSupport(host).isPreview).false;
|
|
53
|
+
});
|
|
54
|
+
it('adds the italic preview title class on initialize', () => {
|
|
55
|
+
const { host } = createHost();
|
|
56
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
57
|
+
trait.initializePreview();
|
|
58
|
+
(0, chai_1.expect)(trait.isPreview).true;
|
|
59
|
+
(0, chai_1.expect)(host.title.className).contains(preview_tab_widget_1.PREVIEW_TITLE_CLASS);
|
|
60
|
+
});
|
|
61
|
+
it('promotes to a permanent tab when the content becomes dirty', () => {
|
|
62
|
+
const { host, dirtyEmitter } = createHost();
|
|
63
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
64
|
+
trait.initializePreview();
|
|
65
|
+
dirtyEmitter.fire();
|
|
66
|
+
(0, chai_1.expect)(trait.isPreview).false;
|
|
67
|
+
(0, chai_1.expect)(host.title.className).not.contains(preview_tab_widget_1.PREVIEW_TITLE_CLASS);
|
|
68
|
+
});
|
|
69
|
+
it('promotes to a permanent tab when the title is pinned', () => {
|
|
70
|
+
const { host } = createHost();
|
|
71
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
72
|
+
trait.initializePreview();
|
|
73
|
+
host.title.className += ` ${browser_1.PINNED_CLASS}`;
|
|
74
|
+
host.title.label = 'trigger change'; // fires title.changed
|
|
75
|
+
(0, chai_1.expect)(trait.isPreview).false;
|
|
76
|
+
});
|
|
77
|
+
it('fires onDidChangePreviewState once and is idempotent', () => {
|
|
78
|
+
const { host } = createHost();
|
|
79
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
80
|
+
trait.initializePreview();
|
|
81
|
+
let count = 0;
|
|
82
|
+
trait.onDidChangePreviewState(() => count++);
|
|
83
|
+
trait.convertToNonPreview();
|
|
84
|
+
trait.convertToNonPreview();
|
|
85
|
+
(0, chai_1.expect)(count).equal(1);
|
|
86
|
+
(0, chai_1.expect)(trait.isPreview).false;
|
|
87
|
+
});
|
|
88
|
+
it('promotes only when moved between two tab-bars', () => {
|
|
89
|
+
const { host } = createHost();
|
|
90
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
91
|
+
trait.initializePreview();
|
|
92
|
+
const tabBarA = new widgets_1.TabBar();
|
|
93
|
+
const tabBarB = new widgets_1.TabBar();
|
|
94
|
+
trait.handleTabBarChange(undefined, tabBarA); // first attach: no promotion
|
|
95
|
+
(0, chai_1.expect)(trait.isPreview).true;
|
|
96
|
+
trait.handleTabBarChange(tabBarA, tabBarB); // moved: promote
|
|
97
|
+
(0, chai_1.expect)(trait.isPreview).false;
|
|
98
|
+
});
|
|
99
|
+
it('invokes onConvertToNonPreview on promotion', () => {
|
|
100
|
+
let called = false;
|
|
101
|
+
const { host } = createHost({ onConvertToNonPreview: () => { called = true; } });
|
|
102
|
+
const trait = new preview_tab_widget_1.PreviewTabSupport(host);
|
|
103
|
+
trait.initializePreview();
|
|
104
|
+
trait.convertToNonPreview();
|
|
105
|
+
(0, chai_1.expect)(called).true;
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=preview-tab-widget.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview-tab-widget.spec.js","sourceRoot":"","sources":["../../src/browser/preview-tab-widget.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { interfaces } from '@theia/core/shared/inversify';
|
|
2
2
|
import { PreferenceProxy, PreferenceSchema, PreferenceService } from '@theia/core/lib/common';
|
|
3
|
+
export declare const ENABLE_PREVIEW_PREFERENCE = "editor.enablePreview";
|
|
3
4
|
export declare const EditorPreviewConfigSchema: PreferenceSchema;
|
|
4
5
|
export interface EditorPreviewConfiguration {
|
|
5
6
|
'editor.enablePreview': boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-preferences.d.ts","sourceRoot":"","sources":["../../src/common/editor-preview-preferences.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAiD,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG7I,eAAO,MAAM,yBAAyB,EAAE,gBASvC,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACvC,sBAAsB,EAAE,OAAO,CAAC;CACnC;AAED,eAAO,MAAM,mCAAmC,eAAgD,CAAC;AACjG,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAC3E,MAAM,MAAM,wBAAwB,GAAG,eAAe,CAAC,0BAA0B,CAAC,CAAC;AAEnF,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,iBAAiB,EAAE,MAAM,GAAE,gBAA4C,GAAG,wBAAwB,CAE7J;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAQxE"}
|
|
1
|
+
{"version":3,"file":"editor-preview-preferences.d.ts","sourceRoot":"","sources":["../../src/common/editor-preview-preferences.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAiD,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAG7I,eAAO,MAAM,yBAAyB,yBAAyB,CAAC;AAEhE,eAAO,MAAM,yBAAyB,EAAE,gBASvC,CAAC;AAEF,MAAM,WAAW,0BAA0B;IACvC,sBAAsB,EAAE,OAAO,CAAC;CACnC;AAED,eAAO,MAAM,mCAAmC,eAAgD,CAAC;AACjG,eAAO,MAAM,wBAAwB,eAAqC,CAAC;AAC3E,MAAM,MAAM,wBAAwB,GAAG,eAAe,CAAC,0BAA0B,CAAC,CAAC;AAEnF,wBAAgB,8BAA8B,CAAC,WAAW,EAAE,iBAAiB,EAAE,MAAM,GAAE,gBAA4C,GAAG,wBAAwB,CAE7J;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAQxE"}
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
16
|
// *****************************************************************************
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.EditorPreviewPreferences = exports.EditorPreviewPreferenceContribution = exports.EditorPreviewConfigSchema = void 0;
|
|
18
|
+
exports.EditorPreviewPreferences = exports.EditorPreviewPreferenceContribution = exports.EditorPreviewConfigSchema = exports.ENABLE_PREVIEW_PREFERENCE = void 0;
|
|
19
19
|
exports.createEditorPreviewPreferences = createEditorPreviewPreferences;
|
|
20
20
|
exports.bindEditorPreviewPreferences = bindEditorPreviewPreferences;
|
|
21
21
|
const common_1 = require("@theia/core/lib/common");
|
|
22
22
|
const nls_1 = require("@theia/core/lib/common/nls");
|
|
23
|
+
exports.ENABLE_PREVIEW_PREFERENCE = 'editor.enablePreview';
|
|
23
24
|
exports.EditorPreviewConfigSchema = {
|
|
24
25
|
properties: {
|
|
25
|
-
|
|
26
|
+
[exports.ENABLE_PREVIEW_PREFERENCE]: {
|
|
26
27
|
type: 'boolean',
|
|
27
28
|
// eslint-disable-next-line max-len
|
|
28
29
|
description: nls_1.nls.localizeByDefault("Controls whether preview mode is used when editors open. There is a maximum of one preview mode editor per editor group. This editor displays its filename in italics on its tab or title label and in the Open Editors view. Its contents will be replaced by the next editor opened in preview mode. Making a change in a preview mode editor will persist it, as will a double-click on its label, or the 'Keep Open' option in its label context menu. Opening a file from Explorer with a double-click persists its editor immediately."),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-preview-preferences.js","sourceRoot":"","sources":["../../src/common/editor-preview-preferences.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;
|
|
1
|
+
{"version":3,"file":"editor-preview-preferences.js","sourceRoot":"","sources":["../../src/common/editor-preview-preferences.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,wCAAwC;AACxC,EAAE;AACF,2EAA2E;AAC3E,mEAAmE;AACnE,wCAAwC;AACxC,EAAE;AACF,4EAA4E;AAC5E,8EAA8E;AAC9E,6EAA6E;AAC7E,yDAAyD;AACzD,uDAAuD;AACvD,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AA2BhF,wEAEC;AAED,oEAQC;AApCD,mDAA6I;AAC7I,oDAAiD;AAEpC,QAAA,yBAAyB,GAAG,sBAAsB,CAAC;AAEnD,QAAA,yBAAyB,GAAqB;IACvD,UAAU,EAAE;QACR,CAAC,iCAAyB,CAAC,EAAE;YACzB,IAAI,EAAE,SAAS;YACf,mCAAmC;YACnC,WAAW,EAAE,SAAG,CAAC,iBAAiB,CAAC,8gBAA8gB,CAAC;YACljB,OAAO,EAAE,IAAI;SAChB;KACJ;CACJ,CAAC;AAMW,QAAA,mCAAmC,GAAG,MAAM,CAAC,qCAAqC,CAAC,CAAC;AACpF,QAAA,wBAAwB,GAAG,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAG3E,SAAgB,8BAA8B,CAAC,WAA8B,EAAE,SAA2B,iCAAyB;IAC/H,OAAO,IAAA,8BAAqB,EAAC,WAAW,EAAE,MAAM,CAAC,CAAC;AACtD,CAAC;AAED,SAAgB,4BAA4B,CAAC,IAAqB;IAC9D,IAAI,CAAC,gCAAwB,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;QAChD,MAAM,WAAW,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAoB,0BAAiB,CAAC,CAAC;QAC5E,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG,CAAyB,2CAAmC,CAAC,CAAC;QACpG,OAAO,8BAA8B,CAAC,WAAW,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACtB,IAAI,CAAC,2CAAmC,CAAC,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,iCAAyB,EAAE,CAAC,CAAC;IACjG,IAAI,CAAC,+BAAsB,CAAC,CAAC,SAAS,CAAC,2CAAmC,CAAC,CAAC;AAChF,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@theia/editor-preview",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.75.0-next.0+172494ea2",
|
|
4
4
|
"description": "Theia - Editor Preview Extension",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@theia/core": "1.
|
|
7
|
-
"@theia/editor": "1.
|
|
8
|
-
"@theia/navigator": "1.
|
|
6
|
+
"@theia/core": "1.75.0-next.0+172494ea2",
|
|
7
|
+
"@theia/editor": "1.75.0-next.0+172494ea2",
|
|
8
|
+
"@theia/navigator": "1.75.0-next.0+172494ea2",
|
|
9
9
|
"tslib": "^2.8.1"
|
|
10
10
|
},
|
|
11
11
|
"publishConfig": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"watch": "theiaext watch"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@theia/ext-scripts": "1.
|
|
45
|
+
"@theia/ext-scripts": "1.74.0"
|
|
46
46
|
},
|
|
47
47
|
"nyc": {
|
|
48
48
|
"extends": "../../configs/nyc.json"
|
|
49
49
|
},
|
|
50
|
-
"gitHead": "
|
|
50
|
+
"gitHead": "172494ea2564ca07690e230805861146007fae79"
|
|
51
51
|
}
|
|
@@ -16,11 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
import { EditorManager, EditorOpenerOptions, EditorWidget } from '@theia/editor/lib/browser';
|
|
18
18
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
19
|
-
import { EditorPreviewPreferences } from '../common/editor-preview-preferences';
|
|
19
|
+
import { EditorPreviewPreferences, ENABLE_PREVIEW_PREFERENCE } from '../common/editor-preview-preferences';
|
|
20
20
|
import { MaybePromise } from '@theia/core/lib/common';
|
|
21
21
|
import URI from '@theia/core/lib/common/uri';
|
|
22
22
|
import { EditorPreviewWidgetFactory, EditorPreviewOptions } from './editor-preview-widget-factory';
|
|
23
23
|
import { EditorPreviewWidget } from './editor-preview-widget';
|
|
24
|
+
import { PreviewTabWidget } from './preview-tab-widget';
|
|
24
25
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
25
26
|
import { WidgetOpenerOptions } from '@theia/core/lib/browser';
|
|
26
27
|
|
|
@@ -50,13 +51,13 @@ export class EditorPreviewManager extends EditorManager {
|
|
|
50
51
|
});
|
|
51
52
|
|
|
52
53
|
this.preferences.onPreferenceChanged(change => {
|
|
53
|
-
if (change.preferenceName ===
|
|
54
|
-
this.
|
|
55
|
-
if (
|
|
56
|
-
|
|
54
|
+
if (change.preferenceName === ENABLE_PREVIEW_PREFERENCE && !this.preferences[ENABLE_PREVIEW_PREFERENCE]) {
|
|
55
|
+
this.shell.widgets.forEach(widget => {
|
|
56
|
+
if (PreviewTabWidget.is(widget) && widget.isPreview) {
|
|
57
|
+
widget.convertToNonPreview();
|
|
57
58
|
}
|
|
58
59
|
});
|
|
59
|
-
}
|
|
60
|
+
}
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
this.stateService.reachedState('initialized_layout').then(() => {
|
|
@@ -88,16 +89,7 @@ export class EditorPreviewManager extends EditorManager {
|
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
protected handleNewPreview(newPreviewWidget: EditorPreviewWidget): void {
|
|
91
|
-
|
|
92
|
-
const tabbar = this.shell.getTabBarFor(newPreviewWidget);
|
|
93
|
-
if (tabbar) {
|
|
94
|
-
for (const title of tabbar.titles) {
|
|
95
|
-
if (title.owner !== newPreviewWidget && title.owner instanceof EditorPreviewWidget && title.owner.isPreview) {
|
|
96
|
-
title.owner.dispose();
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
92
|
+
PreviewTabWidget.disposeOtherPreviews(this.shell, newPreviewWidget);
|
|
101
93
|
}
|
|
102
94
|
|
|
103
95
|
protected override tryGetPendingWidget(uri: URI, options?: EditorOpenerOptions): MaybePromise<EditorWidget> | undefined {
|
|
@@ -115,13 +107,13 @@ export class EditorPreviewManager extends EditorManager {
|
|
|
115
107
|
|
|
116
108
|
protected override createWidgetOptions(uri: URI, options?: EditorOpenerOptions): EditorPreviewOptions {
|
|
117
109
|
const navigatableOptions = super.createWidgetOptions(uri, options) as EditorPreviewOptions;
|
|
118
|
-
navigatableOptions.preview = !!(options?.preview && this.preferences[
|
|
110
|
+
navigatableOptions.preview = !!(options?.preview && this.preferences[ENABLE_PREVIEW_PREFERENCE]);
|
|
119
111
|
return navigatableOptions;
|
|
120
112
|
}
|
|
121
113
|
|
|
122
114
|
protected convertEditorOnDoubleClick(event: Event): void {
|
|
123
115
|
const widget = this.shell.findTargetedWidget(event);
|
|
124
|
-
if (widget
|
|
116
|
+
if (PreviewTabWidget.is(widget) && widget.isPreview) {
|
|
125
117
|
widget.convertToNonPreview();
|
|
126
118
|
}
|
|
127
119
|
}
|
|
@@ -14,19 +14,21 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { TabBar, Widget
|
|
17
|
+
import { TabBar, Widget } from '@theia/core/lib/browser';
|
|
18
18
|
import { EditorWidget, TextEditor } from '@theia/editor/lib/browser';
|
|
19
|
-
import {
|
|
19
|
+
import { Event, SelectionService, UNTITLED_SCHEME } from '@theia/core/lib/common';
|
|
20
|
+
import { PreviewTabWidget, PreviewTabSupport } from './preview-tab-widget';
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
export class EditorPreviewWidget extends EditorWidget {
|
|
23
|
-
protected _isPreview = false;
|
|
22
|
+
export class EditorPreviewWidget extends EditorWidget implements PreviewTabWidget {
|
|
24
23
|
|
|
25
|
-
protected readonly
|
|
26
|
-
readonly onDidChangePreviewState = this.onDidChangePreviewStateEmitter.event;
|
|
24
|
+
protected readonly previewSupport: PreviewTabSupport;
|
|
27
25
|
|
|
28
26
|
get isPreview(): boolean {
|
|
29
|
-
return this.
|
|
27
|
+
return this.previewSupport.isPreview;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get onDidChangePreviewState(): Event<void> {
|
|
31
|
+
return this.previewSupport.onDidChangePreviewState;
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
constructor(
|
|
@@ -34,50 +36,30 @@ export class EditorPreviewWidget extends EditorWidget {
|
|
|
34
36
|
selectionService: SelectionService
|
|
35
37
|
) {
|
|
36
38
|
super(editor, selectionService);
|
|
37
|
-
this.
|
|
39
|
+
this.previewSupport = new PreviewTabSupport({
|
|
40
|
+
title: this.title,
|
|
41
|
+
saveable: this.saveable,
|
|
42
|
+
toDispose: this.toDispose,
|
|
43
|
+
onConvertToNonPreview: () => this.tabBarTracker.reset()
|
|
44
|
+
});
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
initializePreview(): void {
|
|
41
|
-
|
|
42
|
-
this._isPreview = true;
|
|
43
|
-
this.title.className += ` ${PREVIEW_TITLE_CLASS}`;
|
|
44
|
-
const oneTimeDirtyChangeListener = this.saveable.onDirtyChanged(() => {
|
|
45
|
-
this.convertToNonPreview();
|
|
46
|
-
oneTimeListeners.dispose();
|
|
47
|
-
});
|
|
48
|
-
oneTimeListeners.push(oneTimeDirtyChangeListener);
|
|
49
|
-
const oneTimeTitleChangeHandler = () => {
|
|
50
|
-
if (this.title.className.includes(PINNED_CLASS)) {
|
|
51
|
-
this.convertToNonPreview();
|
|
52
|
-
oneTimeListeners.dispose();
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
this.title.changed.connect(oneTimeTitleChangeHandler);
|
|
56
|
-
oneTimeListeners.push(Disposable.create(() => this.title.changed.disconnect(oneTimeTitleChangeHandler)));
|
|
57
|
-
this.toDispose.push(oneTimeListeners);
|
|
48
|
+
this.previewSupport.initializePreview();
|
|
58
49
|
}
|
|
59
50
|
|
|
60
51
|
convertToNonPreview(): void {
|
|
61
|
-
|
|
62
|
-
this._isPreview = false;
|
|
63
|
-
this.currentTabbar = undefined;
|
|
64
|
-
this.title.className = this.title.className.replace(PREVIEW_TITLE_CLASS, '');
|
|
65
|
-
this.onDidChangePreviewStateEmitter.fire();
|
|
66
|
-
this.onDidChangePreviewStateEmitter.dispose();
|
|
67
|
-
}
|
|
52
|
+
this.previewSupport.convertToNonPreview();
|
|
68
53
|
}
|
|
69
54
|
|
|
70
55
|
protected override handleTabBarChange(oldTabBar?: TabBar<Widget> | undefined, newTabBar?: TabBar<Widget> | undefined): void {
|
|
71
56
|
super.handleTabBarChange(oldTabBar, newTabBar);
|
|
72
|
-
|
|
73
|
-
if (oldTabBar && newTabBar) { this.convertToNonPreview(); }
|
|
74
|
-
}
|
|
57
|
+
this.previewSupport.handleTabBarChange(oldTabBar, newTabBar);
|
|
75
58
|
}
|
|
76
59
|
|
|
77
60
|
override storeState(): { isPreview: boolean, editorState: object } | undefined {
|
|
78
61
|
if (this.getResourceUri()?.scheme !== UNTITLED_SCHEME) {
|
|
79
|
-
|
|
80
|
-
return { isPreview, editorState: this.editor.storeViewState() };
|
|
62
|
+
return { isPreview: this.isPreview, editorState: this.editor.storeViewState() };
|
|
81
63
|
}
|
|
82
64
|
}
|
|
83
65
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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 { enableJSDOM } from '@theia/core/lib/browser/test/jsdom';
|
|
18
|
+
let disableJSDOM = enableJSDOM();
|
|
19
|
+
|
|
20
|
+
import { expect } from 'chai';
|
|
21
|
+
import { DisposableCollection, Emitter } from '@theia/core/lib/common';
|
|
22
|
+
import { PINNED_CLASS, Saveable } from '@theia/core/lib/browser';
|
|
23
|
+
import { TabBar, Widget } from '@theia/core/shared/@lumino/widgets';
|
|
24
|
+
import { PREVIEW_TITLE_CLASS, PreviewTabHost, PreviewTabSupport } from './preview-tab-widget';
|
|
25
|
+
|
|
26
|
+
disableJSDOM();
|
|
27
|
+
|
|
28
|
+
describe('PreviewTabSupport', () => {
|
|
29
|
+
|
|
30
|
+
before(() => {
|
|
31
|
+
disableJSDOM = enableJSDOM();
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
after(() => {
|
|
35
|
+
disableJSDOM();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function createHost(overrides?: Partial<PreviewTabHost>): { host: PreviewTabHost, dirtyEmitter: Emitter<void> } {
|
|
39
|
+
const widget = new Widget();
|
|
40
|
+
const dirtyEmitter = new Emitter<void>();
|
|
41
|
+
const saveable: Saveable = {
|
|
42
|
+
dirty: false,
|
|
43
|
+
onDirtyChanged: dirtyEmitter.event,
|
|
44
|
+
onContentChanged: new Emitter<void>().event,
|
|
45
|
+
save: async () => { }
|
|
46
|
+
};
|
|
47
|
+
const host: PreviewTabHost = {
|
|
48
|
+
title: widget.title,
|
|
49
|
+
saveable,
|
|
50
|
+
toDispose: new DisposableCollection(),
|
|
51
|
+
...overrides
|
|
52
|
+
};
|
|
53
|
+
return { host, dirtyEmitter };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
it('is not a preview until initialized', () => {
|
|
57
|
+
const { host } = createHost();
|
|
58
|
+
expect(new PreviewTabSupport(host).isPreview).false;
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('adds the italic preview title class on initialize', () => {
|
|
62
|
+
const { host } = createHost();
|
|
63
|
+
const trait = new PreviewTabSupport(host);
|
|
64
|
+
trait.initializePreview();
|
|
65
|
+
expect(trait.isPreview).true;
|
|
66
|
+
expect(host.title.className).contains(PREVIEW_TITLE_CLASS);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('promotes to a permanent tab when the content becomes dirty', () => {
|
|
70
|
+
const { host, dirtyEmitter } = createHost();
|
|
71
|
+
const trait = new PreviewTabSupport(host);
|
|
72
|
+
trait.initializePreview();
|
|
73
|
+
dirtyEmitter.fire();
|
|
74
|
+
expect(trait.isPreview).false;
|
|
75
|
+
expect(host.title.className).not.contains(PREVIEW_TITLE_CLASS);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('promotes to a permanent tab when the title is pinned', () => {
|
|
79
|
+
const { host } = createHost();
|
|
80
|
+
const trait = new PreviewTabSupport(host);
|
|
81
|
+
trait.initializePreview();
|
|
82
|
+
host.title.className += ` ${PINNED_CLASS}`;
|
|
83
|
+
host.title.label = 'trigger change'; // fires title.changed
|
|
84
|
+
expect(trait.isPreview).false;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('fires onDidChangePreviewState once and is idempotent', () => {
|
|
88
|
+
const { host } = createHost();
|
|
89
|
+
const trait = new PreviewTabSupport(host);
|
|
90
|
+
trait.initializePreview();
|
|
91
|
+
let count = 0;
|
|
92
|
+
trait.onDidChangePreviewState(() => count++);
|
|
93
|
+
trait.convertToNonPreview();
|
|
94
|
+
trait.convertToNonPreview();
|
|
95
|
+
expect(count).equal(1);
|
|
96
|
+
expect(trait.isPreview).false;
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('promotes only when moved between two tab-bars', () => {
|
|
100
|
+
const { host } = createHost();
|
|
101
|
+
const trait = new PreviewTabSupport(host);
|
|
102
|
+
trait.initializePreview();
|
|
103
|
+
const tabBarA = new TabBar<Widget>();
|
|
104
|
+
const tabBarB = new TabBar<Widget>();
|
|
105
|
+
trait.handleTabBarChange(undefined, tabBarA); // first attach: no promotion
|
|
106
|
+
expect(trait.isPreview).true;
|
|
107
|
+
trait.handleTabBarChange(tabBarA, tabBarB); // moved: promote
|
|
108
|
+
expect(trait.isPreview).false;
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('invokes onConvertToNonPreview on promotion', () => {
|
|
112
|
+
let called = false;
|
|
113
|
+
const { host } = createHost({ onConvertToNonPreview: () => { called = true; } });
|
|
114
|
+
const trait = new PreviewTabSupport(host);
|
|
115
|
+
trait.initializePreview();
|
|
116
|
+
trait.convertToNonPreview();
|
|
117
|
+
expect(called).true;
|
|
118
|
+
});
|
|
119
|
+
});
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2026 JuliaHub, Inc. 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 { ApplicationShell, PINNED_CLASS, Saveable } from '@theia/core/lib/browser';
|
|
18
|
+
import { TabBar, Title, Widget } from '@theia/core/shared/@lumino/widgets';
|
|
19
|
+
import { Disposable, DisposableCollection, Emitter, Event } from '@theia/core/lib/common';
|
|
20
|
+
|
|
21
|
+
export const PREVIEW_TITLE_CLASS = 'theia-editor-preview-title-unpinned';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* A widget that can be displayed as a reusable "preview" tab. A preview tab is rendered with an
|
|
25
|
+
* italic (unpinned) title and is promoted to a permanent tab once its content becomes dirty,
|
|
26
|
+
* its title is pinned, it is double-clicked, or it is moved to a different tab-bar.
|
|
27
|
+
*/
|
|
28
|
+
export interface PreviewTabWidget {
|
|
29
|
+
readonly isPreview: boolean;
|
|
30
|
+
readonly onDidChangePreviewState: Event<void>;
|
|
31
|
+
initializePreview(): void;
|
|
32
|
+
convertToNonPreview(): void;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export namespace PreviewTabWidget {
|
|
36
|
+
export function is(arg: unknown): arg is Widget & PreviewTabWidget {
|
|
37
|
+
return arg instanceof Widget
|
|
38
|
+
&& 'isPreview' in arg && typeof arg.isPreview === 'boolean'
|
|
39
|
+
&& 'onDidChangePreviewState' in arg && typeof arg.onDidChangePreviewState === 'function'
|
|
40
|
+
&& 'initializePreview' in arg && typeof arg.initializePreview === 'function'
|
|
41
|
+
&& 'convertToNonPreview' in arg && typeof arg.convertToNonPreview === 'function';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Dispose every other preview widget sharing the target widget's tab-bar so that at most one
|
|
46
|
+
* preview tab exists per editor group, regardless of the concrete preview widget types.
|
|
47
|
+
*/
|
|
48
|
+
export function disposeOtherPreviews(shell: ApplicationShell, widget: Widget & PreviewTabWidget): void {
|
|
49
|
+
if (!widget.isPreview) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const tabbar = shell.getTabBarFor(widget);
|
|
53
|
+
if (tabbar) {
|
|
54
|
+
for (const title of tabbar.titles) {
|
|
55
|
+
if (title.owner !== widget && is(title.owner) && title.owner.isPreview) {
|
|
56
|
+
title.owner.dispose();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The host widget capabilities required by {@link PreviewTabSupport}.
|
|
65
|
+
*/
|
|
66
|
+
export interface PreviewTabHost {
|
|
67
|
+
readonly title: Title<Widget>;
|
|
68
|
+
readonly saveable: Saveable;
|
|
69
|
+
readonly toDispose: DisposableCollection;
|
|
70
|
+
/**
|
|
71
|
+
* Invoked from {@link PreviewTabSupport.convertToNonPreview} to let the host perform additional
|
|
72
|
+
* clean-up, e.g. resetting its tab-bar tracking.
|
|
73
|
+
*/
|
|
74
|
+
onConvertToNonPreview?(): void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Reusable implementation of the {@link PreviewTabWidget} behavior. Widgets that cannot share a
|
|
79
|
+
* common base class compose this and delegate their preview-related members to it.
|
|
80
|
+
*
|
|
81
|
+
* It only owns the preview *state* and its promotion triggers. Detecting a move between tab-bars is
|
|
82
|
+
* left to the host (e.g. via `TabBarTracker`), which feeds {@link handleTabBarChange}; hosts whose
|
|
83
|
+
* base class already tracks this (like `EditorWidget`) reuse that instead.
|
|
84
|
+
*/
|
|
85
|
+
export class PreviewTabSupport implements PreviewTabWidget {
|
|
86
|
+
|
|
87
|
+
protected _isPreview = false;
|
|
88
|
+
|
|
89
|
+
protected readonly onDidChangePreviewStateEmitter = new Emitter<void>();
|
|
90
|
+
readonly onDidChangePreviewState = this.onDidChangePreviewStateEmitter.event;
|
|
91
|
+
|
|
92
|
+
constructor(protected readonly host: PreviewTabHost) {
|
|
93
|
+
this.host.toDispose.push(this.onDidChangePreviewStateEmitter);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get isPreview(): boolean {
|
|
97
|
+
return this._isPreview;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
initializePreview(): void {
|
|
101
|
+
const oneTimeListeners = new DisposableCollection();
|
|
102
|
+
this._isPreview = true;
|
|
103
|
+
this.host.title.className += ` ${PREVIEW_TITLE_CLASS}`;
|
|
104
|
+
const oneTimeDirtyChangeListener = this.host.saveable.onDirtyChanged(() => {
|
|
105
|
+
this.convertToNonPreview();
|
|
106
|
+
oneTimeListeners.dispose();
|
|
107
|
+
});
|
|
108
|
+
oneTimeListeners.push(oneTimeDirtyChangeListener);
|
|
109
|
+
const oneTimeTitleChangeHandler = () => {
|
|
110
|
+
if (this.host.title.className.includes(PINNED_CLASS)) {
|
|
111
|
+
this.convertToNonPreview();
|
|
112
|
+
oneTimeListeners.dispose();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
this.host.title.changed.connect(oneTimeTitleChangeHandler);
|
|
116
|
+
oneTimeListeners.push(Disposable.create(() => this.host.title.changed.disconnect(oneTimeTitleChangeHandler)));
|
|
117
|
+
this.host.toDispose.push(oneTimeListeners);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
convertToNonPreview(): void {
|
|
121
|
+
if (this._isPreview) {
|
|
122
|
+
this._isPreview = false;
|
|
123
|
+
this.host.onConvertToNonPreview?.();
|
|
124
|
+
this.host.title.className = this.host.title.className.replace(PREVIEW_TITLE_CLASS, '');
|
|
125
|
+
this.onDidChangePreviewStateEmitter.fire();
|
|
126
|
+
this.onDidChangePreviewStateEmitter.dispose();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Promote the preview to a permanent tab when it is moved between two tab-bars.
|
|
132
|
+
*/
|
|
133
|
+
handleTabBarChange(oldTabBar?: TabBar<Widget>, newTabBar?: TabBar<Widget>): void {
|
|
134
|
+
if (this._isPreview && oldTabBar && newTabBar) {
|
|
135
|
+
this.convertToNonPreview();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -18,9 +18,11 @@ import { interfaces } from '@theia/core/shared/inversify';
|
|
|
18
18
|
import { createPreferenceProxy, PreferenceContribution, PreferenceProxy, PreferenceSchema, PreferenceService } from '@theia/core/lib/common';
|
|
19
19
|
import { nls } from '@theia/core/lib/common/nls';
|
|
20
20
|
|
|
21
|
+
export const ENABLE_PREVIEW_PREFERENCE = 'editor.enablePreview';
|
|
22
|
+
|
|
21
23
|
export const EditorPreviewConfigSchema: PreferenceSchema = {
|
|
22
24
|
properties: {
|
|
23
|
-
|
|
25
|
+
[ENABLE_PREVIEW_PREFERENCE]: {
|
|
24
26
|
type: 'boolean',
|
|
25
27
|
// eslint-disable-next-line max-len
|
|
26
28
|
description: nls.localizeByDefault("Controls whether preview mode is used when editors open. There is a maximum of one preview mode editor per editor group. This editor displays its filename in italics on its tab or title label and in the Open Editors view. Its contents will be replaced by the next editor opened in preview mode. Making a change in a preview mode editor will persist it, as will a double-click on its label, or the 'Keep Open' option in its label context menu. Opening a file from Explorer with a double-click persists its editor immediately."),
|