Skip to content

Commit

Permalink
Restore custom editors as part of layout
Browse files Browse the repository at this point in the history
Fixes an incorrect assumption that a custom editor cannot be restored
if no `WebviewPanelSerializer` is registered for its view type. (Actually,
custom editors are created and restored using a custom editor provider.)

Also, ensures that `CustomEditorWidget.modelRef` satisfies the shape for the
`CustomEditorWidget` defined in `editor.ts` and cannot return `undefined`.
(However, `CustomEditorWidget.modelRef.object` can be `undefined`
until the custom editor is resolved.)

Fixes eclipse-theia#10787
  • Loading branch information
pisv committed Jul 10, 2024
1 parent 1e71f0b commit 44c6276
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/monaco/src/browser/monaco-editor-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export class MonacoEditorService extends StandaloneCodeEditorService {
let editor = MonacoEditor.getCurrent(this.editors);
if (!editor && CustomEditorWidget.is(this.shell.activeWidget)) {
const model = this.shell.activeWidget.modelRef.object;
if (model.editorTextModel instanceof MonacoEditorModel) {
if (model?.editorTextModel instanceof MonacoEditorModel) {
editor = MonacoEditor.findByDocument(this.editors, model.editorTextModel)[0];
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/plugin-ext/src/hosted/browser/hosted-plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ export class HostedPluginSupport extends AbstractHostedPluginSupport<PluginManag
this.notebookRendererMessagingService.onWillActivateRenderer(rendererId => this.activateByNotebookRenderer(rendererId));

this.widgets.onDidCreateWidget(({ factoryId, widget }) => {
if ((factoryId === WebviewWidget.FACTORY_ID || factoryId === CustomEditorWidget.FACTORY_ID) && widget instanceof WebviewWidget) {
// note: state restoration of custom editors is handled in `PluginCustomEditorRegistry.init`
if (factoryId === WebviewWidget.FACTORY_ID && widget instanceof WebviewWidget) {
const storeState = widget.storeState.bind(widget);
const restoreState = widget.restoreState.bind(widget);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,36 @@
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
import URI from '@theia/core/lib/common/uri';
import { FileOperation } from '@theia/filesystem/lib/common/files';
import { ApplicationShell, NavigatableWidget, Saveable, SaveableSource, SaveOptions } from '@theia/core/lib/browser';
import { ApplicationShell, DelegatingSaveable, NavigatableWidget, Saveable, SaveableSource, SaveOptions } from '@theia/core/lib/browser';
import { SaveableService } from '@theia/core/lib/browser/saveable-service';
import { Reference } from '@theia/core/lib/common/reference';
import { WebviewWidget } from '../webview/webview';
import { UndoRedoService } from '@theia/editor/lib/browser/undo-redo-service';
import { CustomEditorModel } from './custom-editors-main';
import { CustomEditorWidget as CustomEditorWidgetShape } from '@theia/editor/lib/browser';

@injectable()
export class CustomEditorWidget extends WebviewWidget implements SaveableSource, NavigatableWidget {
export class CustomEditorWidget extends WebviewWidget implements CustomEditorWidgetShape, SaveableSource, NavigatableWidget {
static override FACTORY_ID = 'plugin-custom-editor';

override id: string;
resource: URI;

protected _modelRef: Reference<CustomEditorModel>;
get modelRef(): Reference<CustomEditorModel> {
protected _modelRef: Reference<CustomEditorModel | undefined> = { object: undefined, dispose: () => { } };
get modelRef(): Reference<CustomEditorModel | undefined> {
return this._modelRef;
}
set modelRef(modelRef: Reference<CustomEditorModel>) {
this._modelRef.dispose();
this._modelRef = modelRef;
this.delegatingSaveable.delegate = modelRef.object;
this.doUpdateContent();
}

// ensures that saveable is available even if modelRef.object is undefined
protected readonly delegatingSaveable = new DelegatingSaveable();
get saveable(): Saveable {
return this._modelRef.object;
return this.delegatingSaveable;
}

@inject(UndoRedoService)
Expand Down Expand Up @@ -72,13 +78,17 @@ export class CustomEditorWidget extends WebviewWidget implements SaveableSource,
}

async save(options?: SaveOptions): Promise<void> {
await this._modelRef.object.saveCustomEditor(options);
if (this._modelRef.object) {
await this._modelRef.object.saveCustomEditor(options);
}
}

async saveAs(source: URI, target: URI, options?: SaveOptions): Promise<void> {
const result = await this._modelRef.object.saveCustomEditorAs(source, target, options);
this.doMove(target);
return result;
if (this._modelRef.object) {
const result = await this._modelRef.object.saveCustomEditorAs(source, target, options);
this.doMove(target);
return result;
}
}

getResourceUri(): URI | undefined {
Expand Down

0 comments on commit 44c6276

Please sign in to comment.