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