Skip to content

Commit 403f90e

Browse files
committed
Extract DynamicWebviewEditorOverlay to own file
1 parent c503af5 commit 403f90e

2 files changed

Lines changed: 168 additions & 173 deletions

File tree

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import { Emitter, Event } from 'vs/base/common/event';
7+
import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
8+
import { URI } from 'vs/base/common/uri';
9+
import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
10+
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
11+
import { memoize } from 'vs/base/common/decorators';
12+
13+
/**
14+
* Webview editor overlay that creates and destroys the underlying webview as needed.
15+
*/
16+
export class DynamicWebviewEditorOverlay extends Disposable implements WebviewEditorOverlay {
17+
18+
private readonly _pendingMessages = new Set<any>();
19+
private readonly _webview = this._register(new MutableDisposable<WebviewElement>());
20+
private readonly _webviewEvents = this._register(new DisposableStore());
21+
22+
private _html: string = '';
23+
private _initialScrollProgress: number = 0;
24+
private _state: string | undefined = undefined;
25+
private _owner: any = undefined;
26+
27+
public constructor(
28+
private readonly id: string,
29+
public readonly options: WebviewOptions,
30+
private _contentOptions: WebviewContentOptions,
31+
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
32+
@IWebviewService private readonly _webviewService: IWebviewService
33+
) {
34+
super();
35+
36+
this._register(toDisposable(() => this.container.remove()));
37+
}
38+
39+
@memoize
40+
public get container() {
41+
const container = document.createElement('div');
42+
container.id = `webview-${this.id}`;
43+
this._layoutService.getContainer(Parts.EDITOR_PART).appendChild(container);
44+
return container;
45+
}
46+
47+
public claim(owner: any) {
48+
this._owner = owner;
49+
this.show();
50+
}
51+
52+
public release(owner: any) {
53+
if (this._owner !== owner) {
54+
return;
55+
}
56+
this._owner = undefined;
57+
this.container.style.visibility = 'hidden';
58+
if (!this.options.retainContextWhenHidden) {
59+
this._webview.clear();
60+
this._webviewEvents.clear();
61+
}
62+
}
63+
64+
private show() {
65+
if (!this._webview.value) {
66+
const webview = this._webviewService.createWebview(this.id, this.options, this._contentOptions);
67+
this._webview.value = webview;
68+
webview.state = this._state;
69+
webview.html = this._html;
70+
if (this.options.tryRestoreScrollPosition) {
71+
webview.initialScrollProgress = this._initialScrollProgress;
72+
}
73+
this._webview.value.mountTo(this.container);
74+
this._webviewEvents.clear();
75+
76+
webview.onDidFocus(() => { this._onDidFocus.fire(); }, undefined, this._webviewEvents);
77+
webview.onDidClickLink(x => { this._onDidClickLink.fire(x); }, undefined, this._webviewEvents);
78+
webview.onMessage(x => { this._onMessage.fire(x); }, undefined, this._webviewEvents);
79+
80+
webview.onDidScroll(x => {
81+
this._initialScrollProgress = x.scrollYPercentage;
82+
this._onDidScroll.fire(x);
83+
}, undefined, this._webviewEvents);
84+
85+
webview.onDidUpdateState(state => {
86+
this._state = state;
87+
this._onDidUpdateState.fire(state);
88+
}, undefined, this._webviewEvents);
89+
90+
this._pendingMessages.forEach(msg => webview.sendMessage(msg));
91+
this._pendingMessages.clear();
92+
}
93+
this.container.style.visibility = 'visible';
94+
}
95+
96+
public get html(): string { return this._html; }
97+
public set html(value: string) {
98+
this._html = value;
99+
this.withWebview(webview => webview.html = value);
100+
}
101+
102+
public get initialScrollProgress(): number { return this._initialScrollProgress; }
103+
public set initialScrollProgress(value: number) {
104+
this._initialScrollProgress = value;
105+
this.withWebview(webview => webview.initialScrollProgress = value);
106+
}
107+
108+
public get state(): string | undefined { return this._state; }
109+
public set state(value: string | undefined) {
110+
this._state = value;
111+
this.withWebview(webview => webview.state = value);
112+
}
113+
114+
public get contentOptions(): WebviewContentOptions { return this._contentOptions; }
115+
public set contentOptions(value: WebviewContentOptions) {
116+
this._contentOptions = value;
117+
this.withWebview(webview => webview.contentOptions = value);
118+
}
119+
120+
private readonly _onDidFocus = this._register(new Emitter<void>());
121+
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
122+
123+
private readonly _onDidClickLink = this._register(new Emitter<URI>());
124+
public readonly onDidClickLink: Event<URI> = this._onDidClickLink.event;
125+
126+
private readonly _onDidScroll = this._register(new Emitter<{ scrollYPercentage: number; }>());
127+
public readonly onDidScroll: Event<{ scrollYPercentage: number; }> = this._onDidScroll.event;
128+
129+
private readonly _onDidUpdateState = this._register(new Emitter<string | undefined>());
130+
public readonly onDidUpdateState: Event<string | undefined> = this._onDidUpdateState.event;
131+
132+
private readonly _onMessage = this._register(new Emitter<any>());
133+
public readonly onMessage: Event<any> = this._onMessage.event;
134+
135+
sendMessage(data: any): void {
136+
if (this._webview.value) {
137+
this._webview.value.sendMessage(data);
138+
} else {
139+
this._pendingMessages.add(data);
140+
}
141+
}
142+
143+
update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean): void {
144+
this._contentOptions = options;
145+
this._html = html;
146+
this.withWebview(webview => {
147+
webview.update(html, options, retainContextWhenHidden);
148+
});
149+
}
150+
151+
layout(): void { this.withWebview(webview => webview.layout()); }
152+
focus(): void { this.withWebview(webview => webview.focus()); }
153+
reload(): void { this.withWebview(webview => webview.reload()); }
154+
showFind(): void { this.withWebview(webview => webview.showFind()); }
155+
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
156+
157+
public getInnerWebview() {
158+
return this._webview.value;
159+
}
160+
161+
private withWebview(f: (webview: Webview) => void): void {
162+
if (this._webview.value) {
163+
f(this._webview.value);
164+
}
165+
}
166+
}

src/vs/workbench/contrib/webview/browser/webviewService.ts

Lines changed: 2 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,10 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Emitter, Event } from 'vs/base/common/event';
7-
import { Disposable, DisposableStore, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
8-
import { URI } from 'vs/base/common/uri';
96
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
107
import { IFrameWebview } from 'vs/workbench/contrib/webview/browser/webviewElement';
11-
import { IWebviewService, Webview, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
12-
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
13-
import { memoize } from 'vs/base/common/decorators';
8+
import { IWebviewService, WebviewContentOptions, WebviewEditorOverlay, WebviewElement, WebviewOptions } from 'vs/workbench/contrib/webview/common/webview';
9+
import { DynamicWebviewEditorOverlay } from './dynamicWebviewEditorOverlay';
1410

1511
export class WebviewService implements IWebviewService {
1612
_serviceBrand: any;
@@ -35,170 +31,3 @@ export class WebviewService implements IWebviewService {
3531
return this._instantiationService.createInstance(DynamicWebviewEditorOverlay, id, options, contentOptions);
3632
}
3733
}
38-
39-
/**
40-
* Webview editor overlay that creates and destroys the underlying webview as needed.
41-
*/
42-
class DynamicWebviewEditorOverlay extends Disposable implements WebviewEditorOverlay {
43-
44-
private readonly _pendingMessages = new Set<any>();
45-
private readonly _webview = this._register(new MutableDisposable<WebviewElement>());
46-
private readonly _webviewEvents = this._register(new DisposableStore());
47-
48-
private _html: string = '';
49-
private _initialScrollProgress: number = 0;
50-
private _state: string | undefined = undefined;
51-
private _owner: any = undefined;
52-
53-
public constructor(
54-
private readonly id: string,
55-
public readonly options: WebviewOptions,
56-
private _contentOptions: WebviewContentOptions,
57-
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
58-
@IWebviewService private readonly _webviewService: IWebviewService,
59-
) {
60-
super();
61-
62-
this._register(toDisposable(() => this.container.remove()));
63-
}
64-
65-
@memoize
66-
public get container() {
67-
const container = document.createElement('div');
68-
container.id = `webview-${this.id}`;
69-
this._layoutService.getContainer(Parts.EDITOR_PART).appendChild(container);
70-
return container;
71-
}
72-
73-
public claim(owner: any) {
74-
this._owner = owner;
75-
this.show();
76-
}
77-
78-
public release(owner: any) {
79-
if (this._owner !== owner) {
80-
return;
81-
}
82-
83-
this._owner = undefined;
84-
this.container.style.visibility = 'hidden';
85-
if (!this.options.retainContextWhenHidden) {
86-
this._webview.clear();
87-
this._webviewEvents.clear();
88-
}
89-
}
90-
91-
private show() {
92-
if (!this._webview.value) {
93-
const webview = this._webviewService.createWebview(this.id, this.options, this._contentOptions);
94-
this._webview.value = webview;
95-
webview.state = this._state;
96-
webview.html = this._html;
97-
98-
if (this.options.tryRestoreScrollPosition) {
99-
webview.initialScrollProgress = this._initialScrollProgress;
100-
}
101-
102-
this._webview.value.mountTo(this.container);
103-
104-
this._webviewEvents.clear();
105-
106-
webview.onDidFocus(() => {
107-
this._onDidFocus.fire();
108-
}, undefined, this._webviewEvents);
109-
110-
webview.onDidClickLink(x => {
111-
this._onDidClickLink.fire(x);
112-
}, undefined, this._webviewEvents);
113-
114-
webview.onDidScroll(x => {
115-
this._initialScrollProgress = x.scrollYPercentage;
116-
this._onDidScroll.fire(x);
117-
}, undefined, this._webviewEvents);
118-
119-
webview.onDidUpdateState(state => {
120-
this._state = state;
121-
this._onDidUpdateState.fire(state);
122-
}, undefined, this._webviewEvents);
123-
124-
webview.onMessage(x => {
125-
this._onMessage.fire(x);
126-
}, undefined, this._webviewEvents);
127-
128-
this._pendingMessages.forEach(msg => webview.sendMessage(msg));
129-
this._pendingMessages.clear();
130-
}
131-
this.container.style.visibility = 'visible';
132-
}
133-
134-
public get html(): string { return this._html; }
135-
public set html(value: string) {
136-
this._html = value;
137-
this.withWebview(webview => webview.html = value);
138-
}
139-
140-
public get initialScrollProgress(): number { return this._initialScrollProgress; }
141-
public set initialScrollProgress(value: number) {
142-
this._initialScrollProgress = value;
143-
this.withWebview(webview => webview.initialScrollProgress = value);
144-
}
145-
146-
public get state(): string | undefined { return this._state; }
147-
public set state(value: string | undefined) {
148-
this._state = value;
149-
this.withWebview(webview => webview.state = value);
150-
}
151-
152-
public get contentOptions(): WebviewContentOptions { return this._contentOptions; }
153-
public set contentOptions(value: WebviewContentOptions) {
154-
this._contentOptions = value;
155-
this.withWebview(webview => webview.contentOptions = value);
156-
}
157-
158-
private readonly _onDidFocus = this._register(new Emitter<void>());
159-
public readonly onDidFocus: Event<void> = this._onDidFocus.event;
160-
161-
private readonly _onDidClickLink = this._register(new Emitter<URI>());
162-
public readonly onDidClickLink: Event<URI> = this._onDidClickLink.event;
163-
164-
private readonly _onDidScroll = this._register(new Emitter<{ scrollYPercentage: number; }>());
165-
public readonly onDidScroll: Event<{ scrollYPercentage: number; }> = this._onDidScroll.event;
166-
167-
private readonly _onDidUpdateState = this._register(new Emitter<string | undefined>());
168-
public readonly onDidUpdateState: Event<string | undefined> = this._onDidUpdateState.event;
169-
170-
private readonly _onMessage = this._register(new Emitter<any>());
171-
public readonly onMessage: Event<any> = this._onMessage.event;
172-
173-
sendMessage(data: any): void {
174-
if (this._webview.value) {
175-
this._webview.value.sendMessage(data);
176-
} else {
177-
this._pendingMessages.add(data);
178-
}
179-
}
180-
181-
update(html: string, options: WebviewContentOptions, retainContextWhenHidden: boolean): void {
182-
this._contentOptions = options;
183-
this._html = html;
184-
this.withWebview(webview => {
185-
webview.update(html, options, retainContextWhenHidden);
186-
});
187-
}
188-
189-
layout(): void { this.withWebview(webview => webview.layout()); }
190-
focus(): void { this.withWebview(webview => webview.focus()); }
191-
reload(): void { this.withWebview(webview => webview.reload()); }
192-
showFind(): void { this.withWebview(webview => webview.showFind()); }
193-
hideFind(): void { this.withWebview(webview => webview.hideFind()); }
194-
195-
public getInnerWebview() {
196-
return this._webview.value;
197-
}
198-
199-
private withWebview(f: (webview: Webview) => void): void {
200-
if (this._webview.value) {
201-
f(this._webview.value);
202-
}
203-
}
204-
}

0 commit comments

Comments
 (0)