Skip to content

Commit

Permalink
fix #5519: clipboard vscode api
Browse files Browse the repository at this point in the history
Signed-off-by: Anton Kosyakov <anton.kosyakov@typefox.io>
  • Loading branch information
akosyakov committed Jun 19, 2019
1 parent 0fec2f0 commit c6c4137
Show file tree
Hide file tree
Showing 14 changed files with 245 additions and 17 deletions.
3 changes: 2 additions & 1 deletion configs/warnings.tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"vscode-languageserver-types",
"vscode-ws-jsonrpc",
"vscode-uri",
"yargs"
"yargs",
"electron"
]
]
},
Expand Down
50 changes: 50 additions & 0 deletions packages/core/src/browser/browser-clipboard-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable } from 'inversify';
import { ClipboardService } from './clipboard-service';

export interface NavigatorClipboard {
readText(): Promise<string>;
writeText(value: string): Promise<void>;
}
export interface NavigatorPermissions {
query(options: { name: string }): Promise<{ state: 'granted' | 'prompt' | 'denied' }>
}

@injectable()
export class BrowserClipboardService implements ClipboardService {

async readText(): Promise<string> {
if ('permissions' in navigator && 'clipboard' in navigator) {
const result = await (<NavigatorPermissions>navigator['permissions']).query({ name: 'clipboard-read' });
if (result.state === 'granted' || result.state === 'prompt') {
return (<NavigatorClipboard>navigator['clipboard']).readText();
}
}
return '';
}

async writeText(value: string): Promise<void> {
if ('permissions' in navigator && 'clipboard' in navigator) {
const result = await (<NavigatorPermissions>navigator['permissions']).query({ name: 'clipboard-write' });
if (result.state === 'granted' || result.state === 'prompt') {
return (<NavigatorClipboard>navigator['clipboard']).writeText(value);
}
}
}

}
23 changes: 23 additions & 0 deletions packages/core/src/browser/clipboard-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { MaybePromise } from '../common/types';

export const ClipboardService = Symbol('ClipboardService');
export interface ClipboardService {
readText(): MaybePromise<string>;
writeText(value: string): MaybePromise<void>;
}
3 changes: 3 additions & 0 deletions packages/core/src/browser/window/browser-window-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import { ContainerModule } from 'inversify';
import { WindowService } from '../../browser/window/window-service';
import { DefaultWindowService } from '../../browser/window/default-window-service';
import { FrontendApplicationContribution } from '../frontend-application';
import { ClipboardService } from '../clipboard-service';
import { BrowserClipboardService } from '../browser-clipboard-service';

export default new ContainerModule(bind => {
bind(DefaultWindowService).toSelf().inSingletonScope();
bind(WindowService).toService(DefaultWindowService);
bind(FrontendApplicationContribution).toService(DefaultWindowService);
bind(ClipboardService).to(BrowserClipboardService).inSingletonScope();
});
32 changes: 32 additions & 0 deletions packages/core/src/electron-browser/electron-clipboard-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { clipboard } from 'electron';
import { injectable } from 'inversify';
import { ClipboardService } from '../browser/clipboard-service';

@injectable()
export class ElectronClipboardService implements ClipboardService {

readText(): string {
return clipboard.readText();
}

writeText(value: string): void {
clipboard.writeText(value);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ import { ContainerModule } from 'inversify';
import { WindowService } from '../../browser/window/window-service';
import { ElectronWindowService } from './electron-window-service';
import { FrontendApplicationContribution } from '../../browser/frontend-application';
import { ElectronClipboardService } from '../electron-clipboard-service';
import { ClipboardService } from '../../browser/clipboard-service';

export default new ContainerModule(bind => {
bind(WindowService).to(ElectronWindowService).inSingletonScope();
bind(FrontendApplicationContribution).toService(WindowService);
bind(ClipboardService).to(ElectronClipboardService).inSingletonScope();
});
8 changes: 7 additions & 1 deletion packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,11 @@ export interface FileSystemMain {
$unregisterProvider(handle: number): void;
}

export interface ClipboardMain {
$readText(): Promise<string>;
$writeText(value: string): Promise<void>;
}

export const PLUGIN_RPC_CONTEXT = {
COMMAND_REGISTRY_MAIN: <ProxyIdentifier<CommandRegistryMain>>createProxyIdentifier<CommandRegistryMain>('CommandRegistryMain'),
QUICK_OPEN_MAIN: createProxyIdentifier<QuickOpenMain>('QuickOpenMain'),
Expand All @@ -1203,7 +1208,8 @@ export const PLUGIN_RPC_CONTEXT = {
DEBUG_MAIN: createProxyIdentifier<DebugMain>('DebugMain'),
FILE_SYSTEM_MAIN: createProxyIdentifier<FileSystemMain>('FileSystemMain'),
SCM_MAIN: createProxyIdentifier<ScmMain>('ScmMain'),
DECORATIONS_MAIN: createProxyIdentifier<DecorationsMain>('DecorationsMain')
DECORATIONS_MAIN: createProxyIdentifier<DecorationsMain>('DecorationsMain'),
CLIPBOARD_MAIN: <ProxyIdentifier<ClipboardMain>>createProxyIdentifier<ClipboardMain>('ClipboardMain')
};

export const MAIN_RPC_CONTEXT = {
Expand Down
5 changes: 4 additions & 1 deletion packages/plugin-ext/src/hosted/browser/worker/worker-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import { EditorsAndDocumentsExtImpl } from '../../../plugin/editors-and-document
import { WorkspaceExtImpl } from '../../../plugin/workspace';
import { MessageRegistryExt } from '../../../plugin/message-registry';
import { WorkerEnvExtImpl } from './worker-env-ext';
import { ClipboardExt } from '../../../plugin/clipboard-ext';

// tslint:disable-next-line:no-any
const ctx = self as any;
Expand Down Expand Up @@ -55,6 +56,7 @@ const messageRegistryExt = new MessageRegistryExt(rpc);
const workspaceExt = new WorkspaceExtImpl(rpc, editorsAndDocuments, messageRegistryExt);
const preferenceRegistryExt = new PreferenceRegistryExtImpl(rpc, workspaceExt);
const debugExt = createDebugExtStub(rpc);
const clipboardExt = new ClipboardExt(rpc);

const pluginManager = new PluginManagerExtImpl({
// tslint:disable-next-line:no-any
Expand Down Expand Up @@ -133,7 +135,8 @@ const apiFactory = createAPIFactory(
preferenceRegistryExt,
editorsAndDocuments,
workspaceExt,
messageRegistryExt
messageRegistryExt,
clipboardExt
);
let defaultApi: typeof theia;

Expand Down
5 changes: 4 additions & 1 deletion packages/plugin-ext/src/hosted/node/plugin-host-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { EditorsAndDocumentsExtImpl } from '../../plugin/editors-and-documents';
import { WorkspaceExtImpl } from '../../plugin/workspace';
import { MessageRegistryExt } from '../../plugin/message-registry';
import { EnvNodeExtImpl } from '../../plugin/node/env-node-ext';
import { ClipboardExt } from '../../plugin/clipboard-ext';

/**
* Handle the RPC calls.
Expand All @@ -47,6 +48,7 @@ export class PluginHostRPC {
const messageRegistryExt = new MessageRegistryExt(this.rpc);
const workspaceExt = new WorkspaceExtImpl(this.rpc, editorsAndDocumentsExt, messageRegistryExt);
const preferenceRegistryExt = new PreferenceRegistryExtImpl(this.rpc, workspaceExt);
const clipboardExt = new ClipboardExt(this.rpc);
this.pluginManager = this.createPluginManager(envExt, preferenceRegistryExt, this.rpc);
this.rpc.set(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT, this.pluginManager);
this.rpc.set(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT, editorsAndDocumentsExt);
Expand All @@ -61,7 +63,8 @@ export class PluginHostRPC {
preferenceRegistryExt,
editorsAndDocumentsExt,
workspaceExt,
messageRegistryExt
messageRegistryExt,
clipboardExt
);
}

Expand Down
38 changes: 38 additions & 0 deletions packages/plugin-ext/src/main/browser/clipboard-main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { interfaces } from 'inversify';
import { ClipboardMain } from '../../common';
import { ClipboardService } from '@theia/core/lib/browser/clipboard-service';

export class ClipboardMainImpl implements ClipboardMain {

protected readonly clipboardService: ClipboardService;

constructor(container: interfaces.Container) {
this.clipboardService = container.get(ClipboardService);
}

async $readText(): Promise<string> {
const result = await this.clipboardService.readText();
return result;
}

async $writeText(value: string): Promise<void> {
await this.clipboardService.writeText(value);
}

}
4 changes: 4 additions & 0 deletions packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { DebugMainImpl } from './debug/debug-main';
import { FileSystemMainImpl } from './file-system-main';
import { ScmMainImpl } from './scm-main';
import { DecorationsMainImpl } from './decorations/decorations-main';
import { ClipboardMainImpl } from './clipboard-main';

export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): void {
const commandRegistryMain = new CommandRegistryMainImpl(rpc, container);
Expand Down Expand Up @@ -111,4 +112,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container

const decorationsMain = new DecorationsMainImpl(rpc, container);
rpc.set(PLUGIN_RPC_CONTEXT.DECORATIONS_MAIN, decorationsMain);

const clipboardMain = new ClipboardMainImpl(container);
rpc.set(PLUGIN_RPC_CONTEXT.CLIPBOARD_MAIN, clipboardMain);
}
37 changes: 37 additions & 0 deletions packages/plugin-ext/src/plugin/clipboard-ext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/********************************************************************************
* Copyright (C) 2019 TypeFox and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import * as theia from '@theia/plugin';
import { RPCProtocol } from '../api/rpc-protocol';
import { PLUGIN_RPC_CONTEXT, ClipboardMain } from '../common';

export class ClipboardExt implements theia.Clipboard {

protected readonly proxy: ClipboardMain;

constructor(rpc: RPCProtocol) {
this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.CLIPBOARD_MAIN);
}

readText(): Promise<string> {
return this.proxy.$readText();
}

writeText(value: string): Promise<void> {
return this.proxy.$writeText(value);
}

}
6 changes: 4 additions & 2 deletions packages/plugin-ext/src/plugin/plugin-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ import { QuickPick, QuickPickItem } from '@theia/plugin';
import { ScmExtImpl } from './scm';
import { DecorationProvider, LineChange } from '@theia/plugin';
import { DecorationsExtImpl } from './decorations';
import { ClipboardExt } from './clipboard-ext';

export function createAPIFactory(
rpc: RPCProtocol,
Expand All @@ -144,7 +145,8 @@ export function createAPIFactory(
preferenceRegistryExt: PreferenceRegistryExtImpl,
editorsAndDocumentsExt: EditorsAndDocumentsExtImpl,
workspaceExt: WorkspaceExtImpl,
messageRegistryExt: MessageRegistryExt
messageRegistryExt: MessageRegistryExt,
clipboard: ClipboardExt
): PluginAPIFactory {

const commandRegistry = rpc.set(MAIN_RPC_CONTEXT.COMMAND_REGISTRY_EXT, new CommandRegistryImpl(rpc));
Expand Down Expand Up @@ -478,7 +480,7 @@ export function createAPIFactory(
get machineId() { return envExt.machineId; },
get sessionId() { return envExt.sessionId; },
get uriScheme() { return envExt.uriScheme; },

clipboard,
getEnvVariable(envVarName: string): PromiseLike<string | undefined> {
return envExt.getEnvVariable(envVarName);
},
Expand Down
Loading

0 comments on commit c6c4137

Please sign in to comment.