@theia/editor-preview 1.74.0-next.8 → 1.74.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.
@@ -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,EAAE,MAAM,sCAAsC,CAAC;AAChF,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;AAC9D,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;cAapD,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"}
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 editor_preview_widget_1 = require("./editor-preview-widget");
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 === 'editor.enablePreview' && !this.preferences['editor.enablePreview']) {
48
- this.all.forEach((editor) => {
49
- if (editor.isPreview) {
50
- editor.convertToNonPreview();
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
- if (newPreviewWidget.isPreview) {
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['editor.enablePreview']);
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 instanceof editor_preview_widget_1.EditorPreviewWidget && widget.isPreview) {
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":"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"}
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 { Emitter, SelectionService } from '@theia/core/lib/common';
4
- export declare class EditorPreviewWidget extends EditorWidget {
5
- protected _isPreview: boolean;
6
- protected readonly onDidChangePreviewStateEmitter: Emitter<void>;
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,EAAgB,MAAM,yBAAyB,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAoC,OAAO,EAAE,gBAAgB,EAAmB,MAAM,wBAAwB,CAAC;AAGtH,qBAAa,mBAAoB,SAAQ,YAAY;IACjD,SAAS,CAAC,UAAU,UAAS;IAE7B,SAAS,CAAC,QAAQ,CAAC,8BAA8B,gBAAuB;IACxE,QAAQ,CAAC,uBAAuB,+CAA6C;IAE7E,IAAI,SAAS,IAAI,OAAO,CAEvB;gBAGG,MAAM,EAAE,UAAU,EAClB,gBAAgB,EAAE,gBAAgB;IAMtC,iBAAiB,IAAI,IAAI;IAoBzB,mBAAmB,IAAI,IAAI;cAUR,kBAAkB,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,IAAI;IAOlH,UAAU,IAAI;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS;IAOrE,YAAY,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAMrF"}
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/core/lib/browser");
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 PREVIEW_TITLE_CLASS = 'theia-editor-preview-title-unpinned';
23
- class EditorPreviewWidget extends browser_2.EditorWidget {
21
+ const preview_tab_widget_1 = require("./preview-tab-widget");
22
+ class EditorPreviewWidget extends browser_1.EditorWidget {
24
23
  get isPreview() {
25
- return this._isPreview;
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._isPreview = false;
30
- this.onDidChangePreviewStateEmitter = new common_1.Emitter();
31
- this.onDidChangePreviewState = this.onDidChangePreviewStateEmitter.event;
32
- this.toDispose.push(this.onDidChangePreviewStateEmitter);
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
- const oneTimeListeners = new common_1.DisposableCollection();
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
- if (this._isPreview) {
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
- if (this._isPreview) {
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
- const { _isPreview: isPreview } = this;
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;;;AAEhF,qDAAuE;AACvE,uDAAqE;AACrE,mDAAsH;AAEtH,MAAM,mBAAmB,GAAG,qCAAqC,CAAC;AAClE,MAAa,mBAAoB,SAAQ,sBAAY;IAMjD,IAAI,SAAS;QACT,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED,YACI,MAAkB,EAClB,gBAAkC;QAElC,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;QAb1B,eAAU,GAAG,KAAK,CAAC;QAEV,mCAA8B,GAAG,IAAI,gBAAO,EAAQ,CAAC;QAC/D,4BAAuB,GAAG,IAAI,CAAC,8BAA8B,CAAC,KAAK,CAAC;QAWzE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7D,CAAC;IAED,iBAAiB;QACb,MAAM,gBAAgB,GAAG,IAAI,6BAAoB,EAAE,CAAC;QACpD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,IAAI,mBAAmB,EAAE,CAAC;QAClD,MAAM,0BAA0B,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,GAAG,EAAE;YACjE,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC3B,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,gBAAgB,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;QAClD,MAAM,yBAAyB,GAAG,GAAG,EAAE;YACnC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,sBAAY,CAAC,EAAE,CAAC;gBAC9C,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBAC3B,gBAAgB,CAAC,OAAO,EAAE,CAAC;YAC/B,CAAC;QACL,CAAC,CAAC;QACF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;QACtD,gBAAgB,CAAC,IAAI,CAAC,mBAAU,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC;QACzG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC1C,CAAC;IAED,mBAAmB;QACf,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;YACxB,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;YAC7E,IAAI,CAAC,8BAA8B,CAAC,IAAI,EAAE,CAAC;YAC3C,IAAI,CAAC,8BAA8B,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;IACL,CAAC;IAEkB,kBAAkB,CAAC,SAAsC,EAAE,SAAsC;QAChH,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;gBAAC,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAEQ,UAAU;QACf,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,MAAM,KAAK,wBAAe,EAAE,CAAC;YACpD,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;YACvC,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,EAAE,CAAC;QACpE,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;AApED,kDAoEC"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=preview-tab-widget.spec.d.ts.map
@@ -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
- 'editor.enablePreview': {
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;;;AAyBhF,wEAEC;AAED,oEAQC;AAlCD,mDAA6I;AAC7I,oDAAiD;AAEpC,QAAA,yBAAyB,GAAqB;IACvD,UAAU,EAAE;QACR,sBAAsB,EAAE;YACpB,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"}
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.74.0-next.8+2cd198687",
3
+ "version": "1.74.0",
4
4
  "description": "Theia - Editor Preview Extension",
5
5
  "dependencies": {
6
- "@theia/core": "1.74.0-next.8+2cd198687",
7
- "@theia/editor": "1.74.0-next.8+2cd198687",
8
- "@theia/navigator": "1.74.0-next.8+2cd198687",
6
+ "@theia/core": "1.74.0",
7
+ "@theia/editor": "1.74.0",
8
+ "@theia/navigator": "1.74.0",
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.73.0"
45
+ "@theia/ext-scripts": "1.74.0"
46
46
  },
47
47
  "nyc": {
48
48
  "extends": "../../configs/nyc.json"
49
49
  },
50
- "gitHead": "2cd1986875513fd02f645a2b8e69a68832a3a990"
50
+ "gitHead": "7b7376225f0825b4f13d296d686cc13db95fdb69"
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 === 'editor.enablePreview' && !this.preferences['editor.enablePreview']) {
54
- this.all.forEach((editor: EditorPreviewWidget) => {
55
- if (editor.isPreview) {
56
- editor.convertToNonPreview();
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
- if (newPreviewWidget.isPreview) {
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['editor.enablePreview']);
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 instanceof EditorPreviewWidget && widget.isPreview) {
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, PINNED_CLASS } from '@theia/core/lib/browser';
17
+ import { TabBar, Widget } from '@theia/core/lib/browser';
18
18
  import { EditorWidget, TextEditor } from '@theia/editor/lib/browser';
19
- import { Disposable, DisposableCollection, Emitter, SelectionService, UNTITLED_SCHEME } from '@theia/core/lib/common';
19
+ import { Event, SelectionService, UNTITLED_SCHEME } from '@theia/core/lib/common';
20
+ import { PreviewTabWidget, PreviewTabSupport } from './preview-tab-widget';
20
21
 
21
- const PREVIEW_TITLE_CLASS = 'theia-editor-preview-title-unpinned';
22
- export class EditorPreviewWidget extends EditorWidget {
23
- protected _isPreview = false;
22
+ export class EditorPreviewWidget extends EditorWidget implements PreviewTabWidget {
24
23
 
25
- protected readonly onDidChangePreviewStateEmitter = new Emitter<void>();
26
- readonly onDidChangePreviewState = this.onDidChangePreviewStateEmitter.event;
24
+ protected readonly previewSupport: PreviewTabSupport;
27
25
 
28
26
  get isPreview(): boolean {
29
- return this._isPreview;
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.toDispose.push(this.onDidChangePreviewStateEmitter);
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
- const oneTimeListeners = new DisposableCollection();
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
- if (this._isPreview) {
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
- if (this._isPreview) {
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
- const { _isPreview: isPreview } = this;
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
- 'editor.enablePreview': {
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."),