From dbf7cb41ca41dedd9bae98bf690ae31d1cdb5418 Mon Sep 17 00:00:00 2001 From: Jan-Niklas Spangenberg Date: Fri, 19 Jun 2020 12:18:28 +0200 Subject: [PATCH] 'Copy all' for context menu in output view This adds another option to the context menu of the output view, which copies everything in the selected channel into the clipboard, using the clipboardService Closes #7912 Signed-off-by: Jan-Niklas Spangenberg --- .../output/src/browser/output-contribution.ts | 61 ++++--------------- packages/output/src/browser/output-widget.tsx | 4 +- 2 files changed, 13 insertions(+), 52 deletions(-) diff --git a/packages/output/src/browser/output-contribution.ts b/packages/output/src/browser/output-contribution.ts index 44f33bf5bc69a..daf4a4903929a 100644 --- a/packages/output/src/browser/output-contribution.ts +++ b/packages/output/src/browser/output-contribution.ts @@ -14,16 +14,17 @@ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 ********************************************************************************/ -import { injectable } from 'inversify'; +import { injectable, inject } from 'inversify'; import URI from '@theia/core/lib/common/uri'; import { Widget } from '@theia/core/lib/browser/widgets/widget'; import { MaybePromise } from '@theia/core/lib/common/types'; -import { CommonCommands, quickCommand, OpenHandler, OpenerOptions, isFirefox, KeybindingRegistry } from '@theia/core/lib/browser'; +import { CommonCommands, quickCommand, OpenHandler, OpenerOptions } from '@theia/core/lib/browser'; import { Command, CommandRegistry, MenuModelRegistry } from '@theia/core/lib/common'; import { AbstractViewContribution } from '@theia/core/lib/browser/shell/view-contribution'; import { OutputWidget } from './output-widget'; import { OutputContextMenu } from './output-context-menu'; import { OutputUri } from '../common/output-uri'; +import { ClipboardService } from '@theia/core/lib/browser/clipboard-service'; export namespace OutputCommands { @@ -102,7 +103,7 @@ export namespace OutputCommands { export const COPY_ALL: Command = { id: 'output:copy-all', - label: 'Copy all', + label: 'Copy All', category: OUTPUT_CATEGORY, }; } @@ -110,8 +111,10 @@ export namespace OutputCommands { @injectable() export class OutputContribution extends AbstractViewContribution implements OpenHandler { + @inject(ClipboardService) + protected readonly clipboardService: ClipboardService; + readonly id: string = `${OutputWidget.ID}-opener`; - private textToCopy: string; constructor() { super({ @@ -144,21 +147,14 @@ export class OutputContribution extends AbstractViewContribution i }); registry.registerCommand(OutputCommands.COPY_ALL, { execute: () => { - this.widget.then(widget => { - const textToCopy = widget.getText(); - this.copy(textToCopy); - }); + const textToCopy = this.tryGetWidget()?.getText(); + if (textToCopy) { + this.clipboardService.writeText(textToCopy); + } } }); } - registerKeybindings(registry: KeybindingRegistry): void { - registry.registerKeybinding({ - command: OutputCommands.COPY_ALL.id, - keybinding: 'ctrlcmd+shift+c' - }); - } - registerMenus(registry: MenuModelRegistry): void { super.registerMenus(registry); registry.registerMenuAction(OutputContextMenu.TEXT_EDIT_GROUP, { @@ -197,39 +193,4 @@ export class OutputContribution extends AbstractViewContribution i return widget instanceof OutputWidget ? predicate(widget) : false; } - private async clipBoardCopyIsGranted(): Promise { - // Unfortunately Firefox doesn't support permission check `clipboard-write`, so let try to copy anyway, - if (isFirefox) { - return true; - } - try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const permissions = (navigator as any).permissions; - const { state } = await permissions.query({ name: 'clipboard-write' }); - if (state === 'granted') { - return true; - } - } catch (e) { } - - return false; - } - - private async writeToClipBoard(): Promise { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const clipboard = (navigator as any).clipboard; - - try { - await clipboard.writeText(this.textToCopy); - } catch (e) {} - } - - async copy(text: string): Promise { - this.textToCopy = text; - - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const permissions = (navigator as any).permissions; - if (permissions && permissions.query && await this.clipBoardCopyIsGranted()) { - await this.writeToClipBoard(); - } - } } diff --git a/packages/output/src/browser/output-widget.tsx b/packages/output/src/browser/output-widget.tsx index 021af088f0d4e..470a224d5c61c 100644 --- a/packages/output/src/browser/output-widget.tsx +++ b/packages/output/src/browser/output-widget.tsx @@ -220,7 +220,7 @@ export class OutputWidget extends BaseWidget implements StatefulWidget { return undefined; } - getText(): string { + getText(): string | undefined { const editor = this.editor; if (editor) { const model = editor.getControl().getModel(); @@ -228,7 +228,7 @@ export class OutputWidget extends BaseWidget implements StatefulWidget { return model.getValue(); } } - return ''; + return undefined; } }