mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-11 10:38:31 -05:00
Merge VS Code 1.23.1 (#1520)
This commit is contained in:
204
src/vs/platform/driver/electron-browser/driver.ts
Normal file
204
src/vs/platform/driver/electron-browser/driver.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IWindowDriver, IElement, WindowDriverChannel, WindowDriverRegistryChannelClient } from 'vs/platform/driver/common/driver';
|
||||
import { IPCClient } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { getTopLeftOffset, getClientArea } from 'vs/base/browser/dom';
|
||||
import * as electron from 'electron';
|
||||
|
||||
function serializeElement(element: Element, recursive: boolean): IElement {
|
||||
const attributes = Object.create(null);
|
||||
|
||||
for (let j = 0; j < element.attributes.length; j++) {
|
||||
const attr = element.attributes.item(j);
|
||||
attributes[attr.name] = attr.value;
|
||||
}
|
||||
|
||||
const children = [];
|
||||
|
||||
if (recursive) {
|
||||
for (let i = 0; i < element.children.length; i++) {
|
||||
children.push(serializeElement(element.children.item(i), true));
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
tagName: element.tagName,
|
||||
className: element.className,
|
||||
textContent: element.textContent || '',
|
||||
attributes,
|
||||
children
|
||||
};
|
||||
}
|
||||
|
||||
class WindowDriver implements IWindowDriver {
|
||||
|
||||
constructor() { }
|
||||
|
||||
async click(selector: string, xoffset?: number, yoffset?: number): TPromise<void> {
|
||||
return this._click(selector, 1, xoffset, yoffset);
|
||||
}
|
||||
|
||||
doubleClick(selector: string): TPromise<void> {
|
||||
return this._click(selector, 2);
|
||||
}
|
||||
|
||||
private async _getElementXY(selector: string, xoffset?: number, yoffset?: number): TPromise<{ x: number; y: number; }> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Element not found');
|
||||
}
|
||||
|
||||
const { left, top } = getTopLeftOffset(element as HTMLElement);
|
||||
const { width, height } = getClientArea(element as HTMLElement);
|
||||
let x: number, y: number;
|
||||
|
||||
if ((typeof xoffset === 'number') || (typeof yoffset === 'number')) {
|
||||
x = left + xoffset;
|
||||
y = top + yoffset;
|
||||
} else {
|
||||
x = left + (width / 2);
|
||||
y = top + (height / 2);
|
||||
}
|
||||
|
||||
x = Math.round(x);
|
||||
y = Math.round(y);
|
||||
|
||||
return { x, y };
|
||||
}
|
||||
|
||||
private async _click(selector: string, clickCount: number, xoffset?: number, yoffset?: number): TPromise<void> {
|
||||
const { x, y } = await this._getElementXY(selector, xoffset, yoffset);
|
||||
const webContents = electron.remote.getCurrentWebContents();
|
||||
webContents.sendInputEvent({ type: 'mouseDown', x, y, button: 'left', clickCount } as any);
|
||||
webContents.sendInputEvent({ type: 'mouseUp', x, y, button: 'left', clickCount } as any);
|
||||
|
||||
await TPromise.timeout(100);
|
||||
}
|
||||
|
||||
async move(selector: string): TPromise<void> {
|
||||
const { x, y } = await this._getElementXY(selector);
|
||||
const webContents = electron.remote.getCurrentWebContents();
|
||||
webContents.sendInputEvent({ type: 'mouseMove', x, y } as any);
|
||||
|
||||
await TPromise.timeout(100);
|
||||
}
|
||||
|
||||
async setValue(selector: string, text: string): TPromise<void> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Element not found');
|
||||
}
|
||||
|
||||
const inputElement = element as HTMLInputElement;
|
||||
inputElement.value = text;
|
||||
|
||||
const event = new Event('input', { bubbles: true, cancelable: true });
|
||||
inputElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
async paste(selector: string, text: string): TPromise<void> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Element not found');
|
||||
}
|
||||
|
||||
const inputElement = element as HTMLInputElement;
|
||||
const clipboardData = new DataTransfer();
|
||||
clipboardData.setData('text/plain', text);
|
||||
const event = new ClipboardEvent('paste', { clipboardData } as any);
|
||||
|
||||
inputElement.dispatchEvent(event);
|
||||
}
|
||||
|
||||
async getTitle(): TPromise<string> {
|
||||
return document.title;
|
||||
}
|
||||
|
||||
async isActiveElement(selector: string): TPromise<boolean> {
|
||||
const element = document.querySelector(selector);
|
||||
return element === document.activeElement;
|
||||
}
|
||||
|
||||
async getElements(selector: string, recursive: boolean): TPromise<IElement[]> {
|
||||
const query = document.querySelectorAll(selector);
|
||||
const result: IElement[] = [];
|
||||
|
||||
for (let i = 0; i < query.length; i++) {
|
||||
const element = query.item(i);
|
||||
result.push(serializeElement(element, recursive));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async typeInEditor(selector: string, text: string): TPromise<void> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Editor not found: ' + selector);
|
||||
}
|
||||
|
||||
const textarea = element as HTMLTextAreaElement;
|
||||
const start = textarea.selectionStart;
|
||||
const newStart = start + text.length;
|
||||
const value = textarea.value;
|
||||
const newValue = value.substr(0, start) + text + value.substr(start);
|
||||
|
||||
textarea.value = newValue;
|
||||
textarea.setSelectionRange(newStart, newStart);
|
||||
|
||||
const event = new Event('input', { 'bubbles': true, 'cancelable': true });
|
||||
textarea.dispatchEvent(event);
|
||||
}
|
||||
|
||||
async getTerminalBuffer(selector: string): TPromise<string[]> {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
if (!element) {
|
||||
throw new Error('Terminal not found: ' + selector);
|
||||
}
|
||||
|
||||
const xterm = (element as any).xterm;
|
||||
|
||||
if (!xterm) {
|
||||
throw new Error('Xterm not found: ' + selector);
|
||||
}
|
||||
|
||||
const lines: string[] = [];
|
||||
|
||||
for (let i = 0; i < xterm.buffer.lines.length; i++) {
|
||||
lines.push(xterm.buffer.translateBufferLineToString(i, true));
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
export async function registerWindowDriver(
|
||||
client: IPCClient,
|
||||
windowId: number,
|
||||
instantiationService: IInstantiationService
|
||||
): TPromise<IDisposable> {
|
||||
const windowDriver = instantiationService.createInstance(WindowDriver);
|
||||
const windowDriverChannel = new WindowDriverChannel(windowDriver);
|
||||
client.registerChannel('windowDriver', windowDriverChannel);
|
||||
|
||||
const windowDriverRegistryChannel = client.getChannel('windowDriverRegistry');
|
||||
const windowDriverRegistry = new WindowDriverRegistryChannelClient(windowDriverRegistryChannel);
|
||||
|
||||
await windowDriverRegistry.registerWindowDriver(windowId);
|
||||
|
||||
const disposable = toDisposable(() => windowDriverRegistry.reloadWindowDriver(windowId));
|
||||
return combinedDisposable([disposable, client]);
|
||||
}
|
||||
Reference in New Issue
Block a user