Update to Electron 3.0.10 (#56149)

* update to 3.0.0-beta.3

* update d.ts files; rename NodeBuffer => Buffer

* update to 3.0.0-beta.4

* undo invalid change

* remove some Electron 2.0.x specific workarounds

* pinch zoom is now disabled by default

* update vscode-nsfw

* change vscode-nsfw

* update smoke test electron version

* streams: use destroy() over close()

* workaround broken tests

* bump distro and OSS

* try to bump node version for build

* update macOS build to use node.js 10.8.0

* fix extension tests

* use node.js 10.2.1 for all builds

* remove nsfw from dev dependencies

* back to node 8.x for build

* Revert "back to node 8.x for build"

This reverts commit 90ea2b7af2.

* update distro

* disable test run on macOS prod build for now

* bump distro

* ensure proper nsfw dep

* fix more native dependencies

* temp disable failing test

* fix packages

* update deps

* fix deps

* update deps

* enable macOS unit tests again

* fix deprecated buffer use

* Electron 3.0.0.beta.5

* bump deps

* fix tree accidentally treating auxclick as click

* improve overlay cleanup scheduler (fixes flicker seen with Electron 3.0.x)

* update distro

* remove obsolete disableBlinkFeatures: 'Auxclick'

* update to Electron 3.0 beta 6

* fix compile

* workaround #56994

* do not use backgroundColor to find shared process (causes flicker)

* fix flicker on windows from shared process background color

* webview - bubble up keyboard events (workaround for #56988)

* bump electron to 3.0.0-beta.8

* webview - fix deprecation

* webview - fix another deprecation

* debt - handle SIGPIPE on more processes

* workaround more webview focus issues (for #56988)

* webview - use proper way to focus()

* debt - avoid window-focus/blur and use native focus events instead

* webview - restore previous focus method

* webview - improve focus tracking (do not rely on DOM events)

* bump to electron 3.0.0-beta.9

* update deps

* update electron@3.0.0-beta.10

* webview - do not rely on DOM focus for certain commands (for #56988)

* update to electron@3.0.0-beta.11

* electron@3.0.0-beta.12

* update to beta 13

* update to electron 3.0.0

* update to Electron 3.0.1

* electron@3.0.2

* revert build changes (node.js version)

* try with: enable mojave dark mode support

* fix types

* electron 3.0.3

* electron@3.0.4

* fix deps

* bump electron@3.0.6

* bump electron@3.0.9

* fix strict null issue

* reset format

* bump electron@3.0.10

* fix strict null issue

* webview - print error when revive fails

* electron 3.0.x - try to fix keybindings in webviews (#64417)

* bump @types/node => ^10.12.12

* 💄

* update distro
This commit is contained in:
Benjamin Pasero 2018-12-10 12:54:38 +01:00 committed by GitHub
parent b97740c4e6
commit 0bcf5cff8a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 934 additions and 516 deletions

View file

@ -1,3 +1,3 @@
disturl "https://atom.io/download/electron"
target "2.0.12"
target "3.0.10"
runtime "electron"

View file

@ -6,7 +6,7 @@
"git": {
"name": "chromium",
"repositoryUrl": "https://chromium.googlesource.com/chromium/src",
"commitHash": "7accc8730b0f99b5e7c0702ea89d1fa7c17bfe33"
"commitHash": "164c37e3f235134c88e80fac2a182cfba3f07f00"
}
},
"licenseDetail": [
@ -40,7 +40,7 @@
"SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"isOnlyProductionDependency": true,
"version": "61.0.3163.100"
"version": "66.0.3359.181"
},
{
"component": {
@ -48,12 +48,12 @@
"git": {
"name": "libchromiumcontent",
"repositoryUrl": "https://github.com/electron/libchromiumcontent",
"commitHash": "ccdb085454b0a387ee96e0f81a7ca9a8ce07a710"
"commitHash": "d9e39391cfae447a84e276a402342cf8b4b5bcba"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "61.0.3163.100"
"version": "66.0.3359.181"
},
{
"component": {
@ -61,11 +61,11 @@
"git": {
"name": "nodejs",
"repositoryUrl": "https://github.com/nodejs/node",
"commitHash": "8a44289089a08b7b19fa3c4651b5f1f5d1edd71b"
"commitHash": "5cbb905c1af7cea2d709932d59827d7c6d03ef4a"
}
},
"isOnlyProductionDependency": true,
"version": "8.9.3"
"version": "10.2.0"
},
{
"component": {
@ -73,12 +73,12 @@
"git": {
"name": "electron",
"repositoryUrl": "https://github.com/electron/electron",
"commitHash": "d281859cf59f12c7107a540a9f4cba0ecf5eff41"
"commitHash": "4305657858592be2b44c95ae7af53c627dcdc5e7"
}
},
"isOnlyProductionDependency": true,
"license": "MIT",
"version": "2.0.12"
"version": "3.0.10"
},
{
"component": {

View file

@ -1,7 +1,7 @@
{
"name": "code-oss-dev",
"version": "1.31.0",
"distro": "573bd4fedabe1c0bcebeb1e683109079ae560312",
"distro": "2fc810c2f29040b34dbeab2be175a22cca2624db",
"author": {
"name": "Microsoft Corporation"
},
@ -63,7 +63,7 @@
"@types/keytar": "^4.0.1",
"@types/minimist": "^1.2.0",
"@types/mocha": "2.2.39",
"@types/node": "^8.9.1",
"@types/node": "^10.12.12",
"@types/semver": "^5.5.0",
"@types/sinon": "^1.16.36",
"@types/webpack": "^4.4.10",

View file

@ -51,9 +51,8 @@ exports.load = function (modulePaths, resultCallback, options) {
// Enable ASAR support
bootstrap.enableASARSupport(path.join(configuration.appRoot, 'node_modules'));
// disable pinch zoom & apply zoom level early to avoid glitches
// Apply zoom level early to avoid glitches
const zoomLevel = configuration.zoomLevel;
webFrame.setVisualZoomLevelLimits(1, 1);
if (typeof zoomLevel === 'number' && zoomLevel !== 0) {
webFrame.setZoomLevel(zoomLevel);
}

View file

@ -147,10 +147,8 @@ function onReady() {
*/
function configureCommandlineSwitches(cliArgs, nodeCachedDataDir) {
// TODO@Ben Electron 2.0.x: prevent localStorage migration from SQLite to LevelDB due to issues
app.commandLine.appendSwitch('disable-mojo-local-storage');
// Force pre-Chrome-60 color profile handling (for https://github.com/Microsoft/vscode/issues/51791)
// TODO@Ben check if future versions of Electron still support this flag
app.commandLine.appendSwitch('disable-features', 'ColorCorrectRendering');
// Support JS Flags

File diff suppressed because it is too large Load diff

View file

@ -390,7 +390,7 @@ function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream,
if (error) {
if (isOpen) {
writer.once('close', () => callback(error));
writer.close();
writer.destroy();
} else {
callback(error);
}
@ -450,10 +450,10 @@ function doWriteFileStreamAndFlush(path: string, reader: NodeJS.ReadableStream,
canFlush = false;
}
writer.close();
writer.destroy();
});
} else {
writer.close();
writer.destroy();
}
});

View file

@ -81,7 +81,7 @@ export function request(options: IRequestOptions, token: CancellationToken): Pro
opts.auth = options.user + ':' + options.password;
}
req = rawRequest(opts, (res: http.ClientResponse) => {
req = rawRequest(opts, (res: http.IncomingMessage) => {
const followRedirects: number = isNumber(options.followRedirects) ? options.followRedirects : 3;
if (res.statusCode && res.statusCode >= 300 && res.statusCode < 400 && followRedirects > 0 && res.headers['location']) {
request(assign({}, options, {

View file

@ -1658,6 +1658,17 @@ export class WindowsManager implements IWindowsMainService {
// Unresponsive
if (error === WindowError.UNRESPONSIVE) {
if (window.isExtensionDevelopmentHost || window.isExtensionTestHost || (window.win && window.win.webContents && window.win.webContents.isDevToolsOpened())) {
// TODO@Ben Workaround for https://github.com/Microsoft/vscode/issues/56994
// In certain cases the window can report unresponsiveness because a breakpoint was hit
// and the process is stopped executing. The most typical cases are:
// - devtools are opened and debugging happens
// - window is an extensions development host that is being debugged
// - window is an extension test development host that is being debugged
return;
}
// Show Dialog
this.dialogs.showMessageBox({
title: product.nameLong,
type: 'warning',

View file

@ -210,7 +210,7 @@ class DecorationTypeOptionsProvider implements IModelDecorationOptionsProvider {
const _CSS_MAP: { [prop: string]: string; } = {
color: 'color:{0} !important;',
opacity: 'opacity:{0}; will-change: opacity;', // TODO@Ben: 'will-change: opacity' is a workaround for https://github.com/Microsoft/vscode/issues/52196
opacity: 'opacity:{0};',
backgroundColor: 'background-color:{0};',
outline: 'outline:{0};',

View file

@ -1832,7 +1832,7 @@ registerThemingParticipant((theme, collector) => {
const unnecessaryForeground = theme.getColor(editorUnnecessaryCodeOpacity);
if (unnecessaryForeground) {
collector.addRule(`.${SHOW_UNUSED_ENABLED_CLASS} .monaco-editor .${ClassName.EditorUnnecessaryInlineDecoration} { opacity: ${unnecessaryForeground.rgba.a}; will-change: opacity; }`); // TODO@Ben: 'will-change: opacity' is a workaround for https://github.com/Microsoft/vscode/issues/52196
collector.addRule(`.${SHOW_UNUSED_ENABLED_CLASS} .monaco-editor .${ClassName.EditorUnnecessaryInlineDecoration} { opacity: ${unnecessaryForeground.rgba.a}; }`);
}
const unnecessaryBorder = theme.getColor(editorUnnecessaryCodeBorder);

View file

@ -328,4 +328,4 @@ export class IssueService implements IIssueService {
return `${require.toUrl('vs/code/electron-browser/issue/issueReporter.html')}?config=${encodeURIComponent(JSON.stringify(config))}`;
}
}
}

View file

@ -101,6 +101,10 @@ export abstract class AbstractKeybindingService extends Disposable implements IK
return result.resolvedKeybinding;
}
public dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
return this._dispatch(e, target);
}
public softDispatch(e: IKeyboardEvent, target: IContextKeyServiceTarget): IResolveResult | null {
const keybinding = this.resolveKeyboardEvent(e);
if (keybinding.isChord()) {

View file

@ -52,6 +52,11 @@ export interface IKeybindingService {
resolveUserBinding(userBinding: string): ResolvedKeybinding[];
/**
* Resolve and dispatch `keyboardEvent` and invoke the command.
*/
dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean;
/**
* Resolve and dispatch `keyboardEvent`, but do not invoke the command or change inner state.
*/

View file

@ -120,11 +120,11 @@ export class MockKeybindingService implements IKeybindingService {
return null;
}
dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
public dispatchEvent(e: IKeyboardEvent, target: IContextKeyServiceTarget): boolean {
return false;
}
mightProducePrintableCharacter(e: IKeyboardEvent): boolean {
public mightProducePrintableCharacter(e: IKeyboardEvent): boolean {
return false;
}
}

View file

@ -83,7 +83,7 @@ function extractEntry(stream: Readable, fileName: string, mode: number, targetPa
once(token.onCancellationRequested)(() => {
if (istream) {
istream.close();
istream.destroy();
}
});

View file

@ -19,6 +19,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG
import * as vscode from 'vscode';
import { extHostNamedCustomer } from './extHostCustomers';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { onUnexpectedError } from 'vs/base/common/errors';
@extHostNamedCustomer(MainContext.MainThreadWebviews)
export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviver {
@ -169,7 +170,9 @@ export class MainThreadWebviews implements MainThreadWebviewsShape, WebviewReviv
}
return this._proxy.$deserializeWebviewPanel(handle, webview.state.viewType, webview.getTitle(), state, editorGroupToViewColumn(this._editorGroupService, webview.group), webview.options)
.then(undefined, () => {
.then(undefined, error => {
onUnexpectedError(error);
webview.html = MainThreadWebviews.getDeserializationFailedContents(viewType);
});
}));

View file

@ -17,14 +17,11 @@ import { IPartService, Parts, Position as SideBarPosition } from 'vs/workbench/s
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { ToggleActivityBarVisibilityAction } from 'vs/workbench/browser/actions/toggleActivityBarVisibility';
import { IThemeService, registerThemingParticipant, ITheme } from 'vs/platform/theme/common/themeService';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import { ACTIVITY_BAR_BACKGROUND, ACTIVITY_BAR_BORDER, ACTIVITY_BAR_FOREGROUND, ACTIVITY_BAR_BADGE_BACKGROUND, ACTIVITY_BAR_BADGE_FOREGROUND, ACTIVITY_BAR_DRAG_AND_DROP_BACKGROUND, ACTIVITY_BAR_INACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
import { contrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { CompositeBar } from 'vs/workbench/browser/parts/compositeBar';
import { isMacintosh } from 'vs/base/common/platform';
import { ILifecycleService, LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { scheduleAtNextAnimationFrame, Dimension, addClass } from 'vs/base/browser/dom';
import { Color } from 'vs/base/common/color';
import { Dimension, addClass } from 'vs/base/browser/dom';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { URI } from 'vs/base/common/uri';
@ -63,7 +60,6 @@ export class ActivitybarPart extends Part {
@IInstantiationService private instantiationService: IInstantiationService,
@IPartService private partService: IPartService,
@IThemeService themeService: IThemeService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IStorageService private storageService: IStorageService,
@IExtensionService private extensionService: IExtensionService,
@IViewsService private viewsService: IViewsService,
@ -189,27 +185,6 @@ export class ActivitybarPart extends Part {
this.createGlobalActivityActionBar(globalActivities);
// TODO@Ben: workaround for https://github.com/Microsoft/vscode/issues/45700
// It looks like there are rendering glitches on macOS with Chrome 61 when
// using --webkit-mask with a background color that is different from the image
// The workaround is to promote the element onto its own drawing layer. We do
// this only after the workbench has loaded because otherwise there is ugly flicker.
if (isMacintosh) {
this.lifecycleService.when(LifecyclePhase.Restored).then(() => {
scheduleAtNextAnimationFrame(() => { // another delay...
scheduleAtNextAnimationFrame(() => { // ...to prevent more flickering on startup
registerThemingParticipant((theme, collector) => {
const activityBarForeground = theme.getColor(ACTIVITY_BAR_FOREGROUND);
if (activityBarForeground && !activityBarForeground.equals(Color.white)) {
// only apply this workaround if the color is different from the image one (white)
collector.addRule('.monaco-workbench .activitybar > .content .monaco-action-bar .action-label { will-change: transform; }');
}
});
});
});
});
}
return content;
}

View file

@ -22,6 +22,7 @@ import { WebviewElement, WebviewOptions } from 'vs/workbench/parts/webview/elect
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/group/common/editorGroupsService';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Event, Emitter } from 'vs/base/common/event';
export interface HtmlPreviewEditorViewState {
scrollYPercentage: number;
@ -47,6 +48,9 @@ export class HtmlPreviewPart extends BaseWebviewEditor {
private editorMemento: IEditorMemento<HtmlPreviewEditorViewState>;
private readonly _onDidFocusWebview = this._register(new Emitter<void>());
public get onDidFocus(): Event<any> { return this._onDidFocusWebview.event; }
constructor(
@ITelemetryService telemetryService: ITelemetryService,
@IThemeService themeService: IThemeService,
@ -113,6 +117,8 @@ export class HtmlPreviewPart extends BaseWebviewEditor {
this._scrollYPercentage = data.scrollYPercentage;
}),
];
this._register(this._webview.onDidFocus(() => this._onDidFocusWebview.fire()));
}
return this._webview;
}

View file

@ -325,6 +325,20 @@
// write new content onto iframe
newFrame.contentDocument.open('text/html', 'replace');
newFrame.contentWindow.addEventListener('focus', function () { ipcRenderer.sendToHost('did-focus'); });
newFrame.contentWindow.addEventListener('blur', function () { ipcRenderer.sendToHost('did-blur'); });
newFrame.contentWindow.addEventListener('keydown', function (e) {
ipcRenderer.sendToHost('did-keydown', {
key: e.key,
keyCode: e.keyCode,
code: e.code,
shiftKey: e.shiftKey,
altKey: e.altKey,
ctrlKey: e.ctrlKey,
metaKey: e.metaKey,
repeat: e.repeat
});
});
newFrame.contentWindow.onbeforeunload = () => {
if (isInDevelopmentMode) { // Allow reloads while developing a webview
ipcRenderer.sendToHost('do-reload');

View file

@ -6,7 +6,7 @@
import * as DOM from 'vs/base/browser/dom';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Emitter, Event } from 'vs/base/common/event';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@ -31,11 +31,11 @@ export class WebviewEditor extends BaseWebviewEditor {
private _content: HTMLElement;
private _webviewContent: HTMLElement | undefined;
private _webviewFocusTracker?: DOM.IFocusTracker;
private _webviewFocusListenerDisposable?: IDisposable;
private _webviewFocusTrackerDisposables: IDisposable[] = [];
private _onFocusWindowHandler?: IDisposable;
private readonly _onDidFocusWebview = new Emitter<void>();
private readonly _onDidFocusWebview = this._register(new Emitter<void>());
public get onDidFocus(): Event<any> { return this._onDidFocusWebview.event; }
constructor(
@ITelemetryService telemetryService: ITelemetryService,
@ -102,17 +102,7 @@ export class WebviewEditor extends BaseWebviewEditor {
this._content = undefined;
}
this._onDidFocusWebview.dispose();
if (this._webviewFocusTracker) {
this._webviewFocusTracker.dispose();
this._webviewFocusTracker = undefined;
}
if (this._webviewFocusListenerDisposable) {
this._webviewFocusListenerDisposable.dispose();
this._webviewFocusListenerDisposable = undefined;
}
this._webviewFocusTrackerDisposables = dispose(this._webviewFocusTrackerDisposables);
if (this._onFocusWindowHandler) {
this._onFocusWindowHandler.dispose();
@ -127,10 +117,6 @@ export class WebviewEditor extends BaseWebviewEditor {
}
}
public get onDidFocus(): Event<any> {
return this._onDidFocusWebview.event;
}
protected setEditorVisible(visible: boolean, group: IEditorGroup): void {
if (this.input && this.input instanceof WebviewEditorInput) {
if (visible) {
@ -225,53 +211,49 @@ export class WebviewEditor extends BaseWebviewEditor {
this._webviewContent = input.container;
if (input.webview) {
this._webview = input.webview;
} else {
if (input.options.enableFindWidget) {
this._contextKeyService = this._register(this._contextKeyService.createScoped(this._webviewContent));
this.findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._contextKeyService);
}
this._webview = this._instantiationService.createInstance(WebviewElement,
this._partService.getContainer(Parts.EDITOR_PART),
{
enableWrappedPostMessage: true,
useSameOriginForRoot: false,
extensionLocation: input.extensionLocation
});
this._webview.mountTo(this._webviewContent);
input.webview = this._webview;
if (input.options.tryRestoreScrollPosition) {
this._webview.initialScrollProgress = input.scrollYPercentage;
}
this._webview.state = input.webviewState;
this._content.setAttribute('aria-flowto', this._webviewContent.id);
this.doUpdateContainer();
}
this.trackFocus();
const existing = input.webview;
if (existing) {
this._webview = existing;
return existing;
}
if (input.options.enableFindWidget) {
this._contextKeyService = this._register(this._contextKeyService.createScoped(this._webviewContent));
this.findWidgetVisible = KEYBINDING_CONTEXT_WEBVIEW_FIND_WIDGET_VISIBLE.bindTo(this._contextKeyService);
}
this._webview = this._instantiationService.createInstance(WebviewElement,
this._partService.getContainer(Parts.EDITOR_PART),
{
enableWrappedPostMessage: true,
useSameOriginForRoot: false,
extensionLocation: input.extensionLocation
});
this._webview.mountTo(this._webviewContent);
input.webview = this._webview;
if (input.options.tryRestoreScrollPosition) {
this._webview.initialScrollProgress = input.scrollYPercentage;
}
this._webview.state = input.webviewState;
this._content.setAttribute('aria-flowto', this._webviewContent.id);
this.doUpdateContainer();
return this._webview;
}
private trackFocus() {
if (this._webviewFocusTracker) {
this._webviewFocusTracker.dispose();
}
if (this._webviewFocusListenerDisposable) {
this._webviewFocusListenerDisposable.dispose();
}
this._webviewFocusTrackerDisposables = dispose(this._webviewFocusTrackerDisposables);
this._webviewFocusTracker = DOM.trackFocus(this._webviewContent);
this._webviewFocusListenerDisposable = this._webviewFocusTracker.onDidFocus(() => {
this._onDidFocusWebview.fire();
});
// Track focus in webview content
const webviewContentFocusTracker = DOM.trackFocus(this._webviewContent);
this._webviewFocusTrackerDisposables.push(webviewContentFocusTracker);
this._webviewFocusTrackerDisposables.push(webviewContentFocusTracker.onDidFocus(() => this._onDidFocusWebview.fire()));
// Track focus in webview element
this._webviewFocusTrackerDisposables.push(this._webview.onDidFocus(() => this._onDidFocusWebview.fire()));
}
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { addClass, addDisposableListener } from 'vs/base/browser/dom';
import { Emitter } from 'vs/base/common/event';
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@ -15,6 +15,8 @@ import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/the
import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/parts/webview/electron-browser/webviewProtocols';
import { areWebviewInputOptionsEqual } from './webviewEditorService';
import { WebviewFindWidget } from './webviewFindWidget';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
export interface WebviewOptions {
readonly allowScripts?: boolean;
@ -26,6 +28,17 @@ export interface WebviewOptions {
readonly extensionLocation?: URI;
}
interface IKeydownEvent {
key: string;
keyCode: number;
code: string;
shiftKey: boolean;
altKey: boolean;
ctrlKey: boolean;
metaKey: boolean;
repeat: boolean;
}
export class WebviewElement extends Disposable {
private _webview: Electron.WebviewTag;
private _ready: Promise<this>;
@ -35,6 +48,9 @@ export class WebviewElement extends Disposable {
private _contents: string = '';
private _state: string | undefined = undefined;
private readonly _onDidFocus = this._register(new Emitter<void>());
public get onDidFocus(): Event<void> { return this._onDidFocus.event; }
constructor(
private readonly _styleElement: Element,
private _options: WebviewOptions,
@ -42,12 +58,12 @@ export class WebviewElement extends Disposable {
@IThemeService private readonly _themeService: IThemeService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IFileService private readonly _fileService: IFileService,
@IKeybindingService private readonly _keybindingService: IKeybindingService
) {
super();
this._webview = document.createElement('webview');
this._webview.setAttribute('partition', this._options.allowSvgs ? 'webview' : `webview${Date.now()}`);
this._webview.setAttribute('disableguestresize', '');
this._webview.setAttribute('webpreferences', 'contextIsolation=yes');
this._webview.style.flex = '0 1';
@ -164,6 +180,21 @@ export class WebviewElement extends Disposable {
this._state = event.args[0];
this._onDidUpdateState.fire(this._state);
return;
case 'did-focus':
this.handleFocusChange(true);
return;
case 'did-blur':
this.handleFocusChange(false);
return;
case 'did-keydown':
// Electron: workaround for https://github.com/electron/electron/issues/14258
// We have to detect keyboard events in the <webview> and dispatch them to our
// keybinding service because these events do not bubble to the parent window anymore.
this.handleKeydown(event.args[0]);
return;
}
}));
this._register(addDisposableListener(this._webview, 'devtools-opened', () => {
@ -183,8 +214,6 @@ export class WebviewElement extends Disposable {
dispose(): void {
if (this._webview) {
this._webview.guestinstance = 'none';
if (this._webview.parentElement) {
this._webview.parentElement.removeChild(this._webview);
}
@ -263,6 +292,35 @@ export class WebviewElement extends Disposable {
public focus(): void {
this._webview.focus();
this._send('focus');
// Handle focus change programmatically (do not rely on event from <webview>)
this.handleFocusChange(true);
}
private handleFocusChange(isFocused: boolean): void {
if (isFocused) {
this._onDidFocus.fire();
}
}
private handleKeydown(event: IKeydownEvent): void {
// Create a fake KeyboardEvent from the data provided
const emulatedKeyboardEvent = new KeyboardEvent('keydown', {
code: event.code,
key: event.key,
keyCode: event.keyCode,
shiftKey: event.shiftKey,
altKey: event.altKey,
ctrlKey: event.ctrlKey,
metaKey: event.metaKey,
repeat: event.repeat
} as KeyboardEvent);
// Dispatch through our keybinding service
// Note: we set the <webview> as target of the event so that scoped context key
// services function properly to enable commands like select all and find.
this._keybindingService.dispatchEvent(new StandardKeyboardEvent(emulatedKeyboardEvent), this._webview);
}
public sendMessage(data: any): void {
@ -325,18 +383,6 @@ export class WebviewElement extends Disposable {
}
contents.setZoomFactor(factor);
if (!this._webview || !this._webview.parentElement) {
return;
}
const width = this._webview.parentElement.clientWidth;
const height = this._webview.parentElement.clientHeight;
contents.setSize({
normal: {
width: Math.floor(width * factor),
height: Math.floor(height * factor)
}
});
});
}

View file

@ -22,7 +22,7 @@
"@types/webdriverio": "4.6.1",
"concurrently": "^3.5.1",
"cpx": "^1.5.0",
"electron": "^2.0.12",
"electron": "3.0.10",
"htmlparser2": "^3.9.2",
"mkdirp": "^0.5.1",
"mocha": "^5.2.0",

View file

@ -494,11 +494,23 @@ debug@3.1.0, debug@^3.1.0:
dependencies:
ms "2.0.0"
debug@^3.0.0:
version "3.2.6"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
dependencies:
ms "^2.1.1"
decamelize@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
deep-extend@~0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f"
@ -569,28 +581,28 @@ ecc-jsbn@~0.1.1:
dependencies:
jsbn "~0.1.0"
electron-download@^3.0.1:
version "3.3.0"
resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-3.3.0.tgz#2cfd54d6966c019c4d49ad65fbe65cc9cdef68c8"
integrity sha1-LP1U1pZsAZxNSa1l++Zcyc3vaMg=
electron-download@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-4.1.1.tgz#02e69556705cc456e520f9e035556ed5a015ebe8"
integrity sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==
dependencies:
debug "^2.2.0"
fs-extra "^0.30.0"
home-path "^1.0.1"
debug "^3.0.0"
env-paths "^1.0.0"
fs-extra "^4.0.1"
minimist "^1.2.0"
nugget "^2.0.0"
path-exists "^2.1.0"
rc "^1.1.2"
semver "^5.3.0"
sumchecker "^1.2.0"
nugget "^2.0.1"
path-exists "^3.0.0"
rc "^1.2.1"
semver "^5.4.1"
sumchecker "^2.0.2"
electron@^2.0.12:
version "2.0.12"
resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.12.tgz#04b11ef3246cd2a5839a8f16314051341dc5c449"
integrity sha512-mw8hoM/GPtFPP8FGiJcVNe8Rx63YJ7O8bf7McQj21HAvrXGAwReGFrpIe5xN6ec10fDXNSNyfzRucjFXtOtLcg==
electron@3.0.10:
version "3.0.10"
resolved "https://registry.yarnpkg.com/electron/-/electron-3.0.10.tgz#7d412856e8cf0d3041a612a32dd09e2af2d50f50"
integrity sha512-I39IeQP3NOlbjKzTDK8uK2JdiHDfhV5SruCS2Gttkn2MaKCY+yIzQ6Wr4DyBXLeTEkL1sbZxbqQVhCavAliv5w==
dependencies:
"@types/node" "^8.0.24"
electron-download "^3.0.1"
electron-download "^4.1.0"
extract-zip "^1.0.3"
entities@^1.1.1, entities@~1.1.1:
@ -598,6 +610,11 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
integrity sha1-blwtClYhtdra7O+AuQ7ftc13cvA=
env-paths@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
integrity sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=
error-ex@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc"
@ -605,11 +622,6 @@ error-ex@^1.2.0:
dependencies:
is-arrayish "^0.2.1"
es6-promise@^4.0.5:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
integrity sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng==
escape-string-regexp@1.0.5, escape-string-regexp@^1.0.0:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
@ -744,16 +756,14 @@ form-data@~2.3.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
fs-extra@^0.30.0:
version "0.30.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0"
integrity sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=
fs-extra@^4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==
dependencies:
graceful-fs "^4.1.2"
jsonfile "^2.1.0"
klaw "^1.0.0"
path-is-absolute "^1.0.0"
rimraf "^2.2.8"
jsonfile "^4.0.0"
universalify "^0.1.0"
fs.realpath@^1.0.0:
version "1.0.0"
@ -847,7 +857,7 @@ glob@7.1.2, glob@^7.0.5:
once "^1.3.0"
path-is-absolute "^1.0.0"
graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9:
graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=
@ -940,11 +950,6 @@ hoek@4.x.x:
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
integrity sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==
home-path@^1.0.1:
version "1.0.5"
resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.5.tgz#788b29815b12d53bacf575648476e6f9041d133f"
integrity sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=
hosted-git-info@^2.1.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
@ -1155,10 +1160,10 @@ json-stringify-safe@~5.0.1:
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=
jsonfile@^2.1.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8"
integrity sha1-NzaitCi4e72gzIO1P6PWM6NcKug=
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=
optionalDependencies:
graceful-fs "^4.1.6"
@ -1191,13 +1196,6 @@ kind-of@^4.0.0:
dependencies:
is-buffer "^1.1.5"
klaw@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439"
integrity sha1-QIhDO0azsbolnXh4XY6W9zugJDk=
optionalDependencies:
graceful-fs "^4.1.9"
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@ -1377,6 +1375,11 @@ ms@2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a"
integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==
nan@^2.3.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
@ -1439,7 +1442,7 @@ npmlog@^4.0.2:
gauge "~2.7.3"
set-blocking "~2.0.0"
nugget@^2.0.0:
nugget@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0"
integrity sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=
@ -1522,13 +1525,18 @@ parse-json@^2.2.0:
dependencies:
error-ex "^1.2.0"
path-exists@^2.0.0, path-exists@^2.1.0:
path-exists@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=
dependencies:
pinkie-promise "^2.0.0"
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
@ -1643,16 +1651,6 @@ randomatic@^1.1.3:
is-number "^3.0.0"
kind-of "^4.0.0"
rc@^1.1.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.2.tgz#d8ce9cb57e8d64d9c7badd9876c7c34cbe3c7077"
integrity sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=
dependencies:
deep-extend "~0.4.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
rc@^1.1.7:
version "1.2.6"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.6.tgz#eb18989c6d4f4f162c399f79ddd29f3835568092"
@ -1663,6 +1661,16 @@ rc@^1.1.7:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
rc@^1.2.1:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
dependencies:
deep-extend "^0.6.0"
ini "~1.3.0"
minimist "^1.2.0"
strip-json-comments "~2.0.1"
read-pkg-up@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02"
@ -1831,7 +1839,7 @@ resolve@^1.1.7:
dependencies:
path-parse "^1.0.5"
rimraf@2, rimraf@^2.2.8, rimraf@^2.5.1, rimraf@^2.6.1:
rimraf@2, rimraf@^2.5.1, rimraf@^2.6.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
@ -1853,6 +1861,11 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.1, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
integrity sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==
semver@^5.4.1:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@ -2021,13 +2034,12 @@ subarg@^1.0.0:
dependencies:
minimist "^1.1.0"
sumchecker@^1.2.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-1.3.1.tgz#79bb3b4456dd04f18ebdbc0d703a1d1daec5105d"
integrity sha1-ebs7RFbdBPGOvbwNcDodHa7FEF0=
sumchecker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-2.0.2.tgz#0f42c10e5d05da5d42eea3e56c3399a37d6c5b3e"
integrity sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=
dependencies:
debug "^2.2.0"
es6-promise "^4.0.5"
supports-color@5.4.0:
version "5.4.0"
@ -2142,6 +2154,11 @@ uid-number@^0.0.6:
resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81"
integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"

View file

@ -34,10 +34,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-4.2.22.tgz#cf488a0f6b4a9c245d09927f4f757ca278b9c8ce"
integrity sha512-LXRap3bb4AjtLZ5NOFc4ssVZrQPTgdPcNm++0SEJuJZaOA+xHkojJNYqy33A5q/94BmG5tA6yaMeD4VdCv5aSA==
"@types/node@^8.9.1":
version "8.10.34"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.34.tgz#a94d9f3767fe45f211e09e49af598bb84822280c"
integrity sha512-alypNiaAEd0RBGXoWehJ2gchPYCITmw4CYBoB5nDlji8l8on7FsklfdfIs4DDmgpKLSX3OF3ha6SV+0W7cTzUA==
"@types/node@^10.12.12":
version "10.12.12"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.12.tgz#e15a9d034d9210f00320ef718a50c4a799417c47"
integrity sha512-Pr+6JRiKkfsFvmU/LK68oBRCQeEg36TyAbPhc2xpez24OOZZCuoIhWGTd39VZy6nGafSbxzGouFPTFD/rR1A0A==
"@types/semver@^5.4.0", "@types/semver@^5.5.0":
version "5.5.0"