diff --git a/packages/application/src/index.ts b/packages/application/src/index.ts index f84df09be..fe7112874 100644 --- a/packages/application/src/index.ts +++ b/packages/application/src/index.ts @@ -51,11 +51,14 @@ export class Application { this.pluginRegistry.application = this; // Initialize the application state. - this.commands = new CommandRegistry(); - this.contextMenu = new ContextMenu({ + this.commands = options.commands ?? new CommandRegistry(); + const contextMenuOptions = { commands: this.commands, renderer: options.contextMenuRenderer - }); + }; + this.contextMenu = options.contextMenuFactory + ? options.contextMenuFactory(contextMenuOptions) + : new ContextMenu(contextMenuOptions); this.shell = options.shell; this._hasShellWidget = this.shell instanceof Widget; } @@ -197,7 +200,9 @@ export class Application { * If the plugin provides a service which has already been provided * by another plugin, the new service will override the old service. */ - registerPlugin(plugin: IPlugin, any>): void { + registerPlugin( + plugin: IPlugin, any> + ): void { this.pluginRegistry.registerPlugin(plugin); } @@ -209,7 +214,9 @@ export class Application { * #### Notes * This calls `registerPlugin()` for each of the given plugins. */ - registerPlugins(plugins: IPlugin, any>[]): void { + registerPlugins( + plugins: IPlugin, any>[] + ): void { this.pluginRegistry.registerPlugins(plugins); } @@ -340,14 +347,15 @@ export class Application { * A subclass may reimplement this method as needed. */ protected attachShell(id: string): void { - if (this._hasShellWidget){ - Widget.attach( - this.shell as Widget, - (id && document.getElementById(id)) || document.body - );} else { + if (this._hasShellWidget) { + Widget.attach( + this.shell as Widget, + (id && document.getElementById(id)) || document.body + ); + } else { const host = (id && document.getElementById(id)) || document.body; - if(!host.contains(this.shell as HTMLElement)) { - host.appendChild(this.shell as HTMLElement) + if (!host.contains(this.shell as HTMLElement)) { + host.appendChild(this.shell as HTMLElement); } } } @@ -426,7 +434,9 @@ export class Application { * A subclass may reimplement this method as needed. */ protected evtResize(event: Event): void { - if(this._hasShellWidget){(this.shell as Widget).update()} + if (this._hasShellWidget) { + (this.shell as Widget).update(); + } } /** @@ -440,13 +450,14 @@ export class Application { } /** - * The namespace for the `Application` class statics. + * The namespace for the {@link Application} class statics. */ export namespace Application { /** * An options object for creating an application. */ - export interface IOptions extends PluginRegistry.IOptions { + export interface IOptions + extends PluginRegistry.IOptions { /** * The shell element to use for the application. * @@ -455,6 +466,16 @@ export namespace Application { */ shell: T; + /** + * A custom commands registry. + */ + commands?: CommandRegistry; + + /** + * A custom context menu factory. + */ + contextMenuFactory?: (options: ContextMenu.IOptions) => ContextMenu; + /** * A custom renderer for the context menu. */ diff --git a/packages/application/tests/src/index.spec.ts b/packages/application/tests/src/index.spec.ts index e8c5a454a..43b689c2c 100644 --- a/packages/application/tests/src/index.spec.ts +++ b/packages/application/tests/src/index.spec.ts @@ -69,6 +69,27 @@ describe('@lumino/application', () => { expect(app.contextMenu).to.be.instanceOf(ContextMenu); expect(app.shell).to.equal(shell); }); + + it('should instantiate an application with a custom command registry', () => { + const commands = new (class extends CommandRegistry {})(); + + const app = new Application({ shell: new Widget(), commands }); + + expect(app.commands).to.be.equal(commands); + }); + + it('should instantiate an application with a custom context menu factory', () => { + const contextMenuFactory = (options: ContextMenu.IOptions) => + new (class extends ContextMenu {})(options); + + const app = new Application({ + shell: new Widget(), + contextMenuFactory + }); + + expect(app.contextMenu).to.be.instanceOf(ContextMenu); + expect(app.contextMenu.menu.commands).to.be.equal(app.commands); + }); }); describe('#getPluginDescription', () => { @@ -647,7 +668,7 @@ describe('@lumino/application', () => { await app.start(); expect(document.body.contains(shell.node)).to.be.true; - }) + }); it('should attach the shell HTML element to the document body', async () => { const shell = document.createElement('div'); @@ -658,7 +679,7 @@ describe('@lumino/application', () => { await app.start(); expect(document.body.contains(shell)).to.be.true; - }) - }) + }); + }); }); });