diff options
Diffstat (limited to 'src/components/services/content/ServiceWebview.jsx')
-rw-r--r-- | src/components/services/content/ServiceWebview.jsx | 132 |
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 @@ | |||
1 | import { Component } from 'react'; | ||
2 | import PropTypes from 'prop-types'; | ||
3 | import { observer } from 'mobx-react'; | ||
4 | import { action, makeObservable, observable, reaction } from 'mobx'; | ||
5 | import ElectronWebView from 'react-electron-web-view'; | ||
6 | import { join } from 'path'; | ||
7 | |||
8 | import ServiceModel from '../../../models/Service'; | ||
9 | |||
10 | const debug = require('../../../preload-safe-debug')('Ferdium:Services'); | ||
11 | |||
12 | class 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 | |||
132 | export default observer(ServiceWebview); | ||