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