aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/services/content/ServiceWebview.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/services/content/ServiceWebview.tsx')
-rw-r--r--src/components/services/content/ServiceWebview.tsx140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/components/services/content/ServiceWebview.tsx b/src/components/services/content/ServiceWebview.tsx
new file mode 100644
index 000000000..ac8d1ea66
--- /dev/null
+++ b/src/components/services/content/ServiceWebview.tsx
@@ -0,0 +1,140 @@
1import { Component, ReactElement } from 'react';
2import { observer } from 'mobx-react';
3import { action, makeObservable, observable, reaction } from 'mobx';
4import ElectronWebView from 'react-electron-web-view';
5import { join } from 'path';
6import ServiceModel from '../../../models/Service';
7
8const debug = require('../../../preload-safe-debug')('Ferdium:Services');
9
10interface IProps {
11 service: ServiceModel;
12 setWebviewReference: (options: {
13 serviceId: string;
14 webview: ElectronWebView | null;
15 }) => void;
16 detachService: (options: { service: ServiceModel }) => void;
17 isSpellcheckerEnabled: boolean;
18}
19
20@observer
21class ServiceWebview extends Component<IProps> {
22 @observable webview: ElectronWebView | null = null;
23
24 constructor(props: IProps) {
25 super(props);
26
27 this.refocusWebview = this.refocusWebview.bind(this);
28 this._setWebview = this._setWebview.bind(this);
29
30 makeObservable(this);
31
32 reaction(
33 () => this.webview,
34 () => {
35 if (this.webview && this.webview.view) {
36 this.webview.view.addEventListener('console-message', e => {
37 debug('Service logged a message:', e.message);
38 });
39 this.webview.view.addEventListener('did-navigate', () => {
40 if (this.props.service._webview) {
41 document.title = `Ferdium - ${this.props.service.name} ${
42 this.props.service.dialogTitle
43 ? ` - ${this.props.service.dialogTitle}`
44 : ''
45 } ${`- ${this.props.service._webview.getTitle()}`}`;
46 }
47 });
48 }
49 },
50 );
51 }
52
53 componentWillUnmount(): void {
54 const { service, detachService } = this.props;
55 detachService({ service });
56 }
57
58 refocusWebview(): void {
59 const { webview } = this;
60 debug('Refocus Webview is called', this.props.service);
61 if (!webview) {
62 return;
63 }
64
65 if (this.props.service.isActive) {
66 webview.view.blur();
67 webview.view.focus();
68 window.setTimeout(() => {
69 document.title = `Ferdium - ${this.props.service.name} ${
70 this.props.service.dialogTitle
71 ? ` - ${this.props.service.dialogTitle}`
72 : ''
73 } ${`- ${this.props.service._webview.getTitle()}`}`;
74 }, 100);
75 } else {
76 debug('Refocus not required - Not active service');
77 }
78 }
79
80 @action _setWebview(webview): void {
81 this.webview = webview;
82 }
83
84 render(): ReactElement {
85 const { service, setWebviewReference, isSpellcheckerEnabled } = this.props;
86
87 const preloadScript = join(
88 __dirname,
89 '..',
90 '..',
91 '..',
92 'webview',
93 'recipe.js',
94 );
95
96 return (
97 <ElectronWebView
98 ref={webview => {
99 this._setWebview(webview);
100 if (webview && webview.view) {
101 webview.view.addEventListener(
102 'did-stop-loading',
103 this.refocusWebview,
104 );
105 }
106 }}
107 autosize
108 src={service.url}
109 preload={preloadScript}
110 partition={service.partition}
111 onDidAttach={() => {
112 // Force the event handler to run in a new task.
113 // This resolves a race condition when the `did-attach` is called,
114 // but the webview is not attached to the DOM yet:
115 // https://github.com/electron/electron/issues/31918
116 // This prevents us from immediately attaching listeners such as `did-stop-load`:
117 // https://github.com/ferdium/ferdium-app/issues/157
118 setTimeout(() => {
119 setWebviewReference({
120 serviceId: service.id,
121 webview: this.webview.view,
122 });
123 }, 0);
124 }}
125 // onUpdateTargetUrl={this.updateTargetUrl} // TODO - [TS DEBT] need to check where its from
126 useragent={service.userAgent}
127 disablewebsecurity={
128 service.recipe.disablewebsecurity ? true : undefined
129 }
130 allowpopups
131 nodeintegration
132 webpreferences={`spellcheck=${
133 isSpellcheckerEnabled ? 1 : 0
134 }, contextIsolation=1`}
135 />
136 );
137 }
138}
139
140export default ServiceWebview;