Skip to content

Commit

Permalink
fix #5950: migrate layout from version 2 to 3
Browse files Browse the repository at this point in the history
- introduced layout migration points
- implemented migration point for version 2 to discard all unversioned layouts (for backward compatibility)
- implemented scm migration point for version 3 to wrap scm widget into view container
- implemented explorer migration point for version 3 to wrap explorer widget into view container
- implemented problem migration point for version 3 to update the widget factory id

Signed-off-by: Anton Kosyakov <[email protected]>
  • Loading branch information
akosyakov committed Aug 21, 2019
1 parent 7406add commit f8a333f
Show file tree
Hide file tree
Showing 12 changed files with 403 additions and 82 deletions.
12 changes: 11 additions & 1 deletion packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import {
ApplicationShell, ApplicationShellOptions, DockPanelRenderer, TabBarRenderer,
TabBarRendererFactory, ShellLayoutRestorer,
SidePanelHandler, SidePanelHandlerFactory,
SplitPositionHandler, DockPanelRendererFactory
SplitPositionHandler, DockPanelRendererFactory, ApplicationShellLayoutMigration, ApplicationShellLayoutMigrationError
} from './shell';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
import { LabelParser } from './label-parser';
Expand Down Expand Up @@ -128,6 +128,16 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
bind(HttpOpenHandler).toSelf().inSingletonScope();
bind(OpenHandler).toService(HttpOpenHandler);

bindContributionProvider(bind, ApplicationShellLayoutMigration);
bind<ApplicationShellLayoutMigration>(ApplicationShellLayoutMigration).toConstantValue({
layoutVersion: 2.0,
onWillInflateLayout({ layoutVersion }): void {
throw ApplicationShellLayoutMigrationError.create(
`It is not possible to migrate layout of version ${layoutVersion} to version ${this.layoutVersion}.`
);
}
});

bindContributionProvider(bind, WidgetFactory);
bind(WidgetManager).toSelf().inSingletonScope();
bind(ShellLayoutRestorer).toSelf().inSingletonScope();
Expand Down
9 changes: 7 additions & 2 deletions packages/core/src/browser/frontend-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { MaybePromise } from '../common/types';
import { KeybindingRegistry } from './keybinding';
import { Widget } from './widgets';
import { ApplicationShell } from './shell/application-shell';
import { ShellLayoutRestorer } from './shell/shell-layout-restorer';
import { ShellLayoutRestorer, ApplicationShellLayoutMigrationError } from './shell/shell-layout-restorer';
import { FrontendApplicationStateService } from './frontend-application-state';
import { preventNavigation, parseCssTime } from './browser';
import { CorePreferences } from './core-preferences';
Expand Down Expand Up @@ -229,7 +229,12 @@ export class FrontendApplication {
try {
return await this.layoutRestorer.restoreLayout(this);
} catch (error) {
this.logger.error('Could not restore layout', error);
if (ApplicationShellLayoutMigrationError.is(error)) {
console.warn(error.message);
console.info('Initializing the defaut layout instead...');
} else {
console.error('Could not restore layout', error);
}
return false;
}
}
Expand Down
24 changes: 13 additions & 11 deletions packages/core/src/browser/shell/application-shell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,16 @@ const MAIN_AREA_CLASS = 'theia-app-main';
/** The class name added to the bottom area panel. */
const BOTTOM_AREA_CLASS = 'theia-app-bottom';

const LAYOUT_DATA_VERSION = '3.0';
export type ApplicationShellLayoutVersion =
/** layout versioning is introduced, unversiouned layout are not compatible */
2.0 |
/** view containers are introduced, backward compatible to 2.0 */
3.0;

/**
* When a version is increased, make sure to introduce a migration (ApplicationShellLayoutMigration) to this version.
*/
export const applicationShellLayoutVersion: ApplicationShellLayoutVersion = 3.0;

export const ApplicationShellOptions = Symbol('ApplicationShellOptions');
export const DockPanelRendererFactory = Symbol('DockPanelRendererFactory');
Expand Down Expand Up @@ -516,7 +525,7 @@ export class ApplicationShell extends Widget {
*/
getLayoutData(): ApplicationShell.LayoutData {
return {
version: LAYOUT_DATA_VERSION,
version: applicationShellLayoutVersion,
mainPanel: this.mainPanel.saveLayout(),
bottomPanel: {
config: this.bottomPanel.saveLayout(),
Expand Down Expand Up @@ -561,7 +570,7 @@ export class ApplicationShell extends Widget {
* Apply a shell layout that has been previously created with `getLayoutData`.
*/
async setLayoutData(layoutData: ApplicationShell.LayoutData): Promise<void> {
const { mainPanel, bottomPanel, leftPanel, rightPanel, activeWidgetId } = this.getValidatedLayoutData(layoutData);
const { mainPanel, bottomPanel, leftPanel, rightPanel, activeWidgetId } = layoutData;
if (leftPanel) {
this.leftPanelHandler.setLayoutData(leftPanel);
await this.registerWithFocusTracker(leftPanel);
Expand Down Expand Up @@ -598,13 +607,6 @@ export class ApplicationShell extends Widget {
}
}

protected getValidatedLayoutData(layoutData: ApplicationShell.LayoutData): ApplicationShell.LayoutData {
if (layoutData.version !== LAYOUT_DATA_VERSION) {
throw new Error(`Saved workbench layout (version ${layoutData.version || 'unknown'}) is incompatible with the current (${LAYOUT_DATA_VERSION})`);
}
return layoutData;
}

/**
* Modify the height of the bottom panel. This implementation assumes that the container of the
* bottom panel is a `SplitPanel`.
Expand Down Expand Up @@ -1585,7 +1587,7 @@ export namespace ApplicationShell {
* Data to save and load the application shell layout.
*/
export interface LayoutData {
version?: string,
version?: string | ApplicationShellLayoutVersion,
mainPanel?: DockPanel.ILayoutConfig;
bottomPanel?: BottomPanelLayoutData;
leftPanel?: SidePanel.LayoutData;
Expand Down
Loading

0 comments on commit f8a333f

Please sign in to comment.