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