diff options
author | Kristóf Marussy <kristof@marussy.com> | 2021-06-03 19:01:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-03 19:01:01 +0200 |
commit | 2ad39ffb1cb0d0e5f79d6948f798ca79ed73c76c (patch) | |
tree | dcb679119cf4963126a3520b7c62ae4b032e0225 | |
parent | Upgraded electron to '13.1.0'. (diff) | |
download | ferdium-app-2ad39ffb1cb0d0e5f79d6948f798ca79ed73c76c.tar.gz ferdium-app-2ad39ffb1cb0d0e5f79d6948f798ca79ed73c76c.tar.zst ferdium-app-2ad39ffb1cb0d0e5f79d6948f798ca79ed73c76c.zip |
* Expose Chrome version to todos webview (fix #1211)
The TickTick todo service fails to load if the Chrome version number
does not appear in the User-Agent string. However, login to Google Tasks
is prevented by the same.
We adopt the "chromeless" User-Agent logic from the service webview,
which selectively exposes the Chrome version everywhere except the
Google login screen. The common logic was moved into the
userAgent-helpers module.
* Refactor user agent switching
* "Chromeless" user agent switching is extracted into a separate model
* Both the service and the todos webview uses the same model
-rw-r--r-- | src/features/todos/components/TodosWebview.js | 10 | ||||
-rw-r--r-- | src/features/todos/containers/TodosScreen.js | 1 | ||||
-rw-r--r-- | src/features/todos/store.js | 13 | ||||
-rw-r--r-- | src/helpers/userAgent-helpers.js | 4 | ||||
-rw-r--r-- | src/i18n/locales/defaultMessages.json | 12 | ||||
-rw-r--r-- | src/i18n/messages/src/features/todos/components/TodosWebview.json | 12 | ||||
-rw-r--r-- | src/models/Service.js | 39 | ||||
-rw-r--r-- | src/models/UserAgent.js | 80 |
8 files changed, 120 insertions, 51 deletions
diff --git a/src/features/todos/components/TodosWebview.js b/src/features/todos/components/TodosWebview.js index 18a900e8a..634ec4caa 100644 --- a/src/features/todos/components/TodosWebview.js +++ b/src/features/todos/components/TodosWebview.js | |||
@@ -14,8 +14,6 @@ import Appear from '../../../components/ui/effects/Appear'; | |||
14 | import UpgradeButton from '../../../components/ui/UpgradeButton'; | 14 | import UpgradeButton from '../../../components/ui/UpgradeButton'; |
15 | import { TODOS_PARTITION_ID } from '..'; | 15 | import { TODOS_PARTITION_ID } from '..'; |
16 | 16 | ||
17 | import userAgent from '../../../helpers/userAgent-helpers'; | ||
18 | |||
19 | // NOTE: https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url | 17 | // NOTE: https://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-a-url |
20 | function validURL(str) { | 18 | function validURL(str) { |
21 | let url; | 19 | let url; |
@@ -112,6 +110,7 @@ class TodosWebview extends Component { | |||
112 | resize: PropTypes.func.isRequired, | 110 | resize: PropTypes.func.isRequired, |
113 | width: PropTypes.number.isRequired, | 111 | width: PropTypes.number.isRequired, |
114 | minWidth: PropTypes.number.isRequired, | 112 | minWidth: PropTypes.number.isRequired, |
113 | userAgent: PropTypes.string.isRequired, | ||
115 | isTodosIncludedInCurrentPlan: PropTypes.bool.isRequired, | 114 | isTodosIncludedInCurrentPlan: PropTypes.bool.isRequired, |
116 | stores: PropTypes.shape({ | 115 | stores: PropTypes.shape({ |
117 | settings: PropTypes.instanceOf(SettingsStore).isRequired, | 116 | settings: PropTypes.instanceOf(SettingsStore).isRequired, |
@@ -139,11 +138,6 @@ class TodosWebview extends Component { | |||
139 | this.node.addEventListener('mousemove', this.resizePanel.bind(this)); | 138 | this.node.addEventListener('mousemove', this.resizePanel.bind(this)); |
140 | this.node.addEventListener('mouseup', this.stopResize.bind(this)); | 139 | this.node.addEventListener('mouseup', this.stopResize.bind(this)); |
141 | this.node.addEventListener('mouseleave', this.stopResize.bind(this)); | 140 | this.node.addEventListener('mouseleave', this.stopResize.bind(this)); |
142 | |||
143 | const webViewInstance = this; | ||
144 | this.webview.addEventListener('dom-ready', () => { | ||
145 | webViewInstance.webview.setUserAgent(userAgent(true)); | ||
146 | }); | ||
147 | } | 141 | } |
148 | 142 | ||
149 | startResize = (event) => { | 143 | startResize = (event) => { |
@@ -214,6 +208,7 @@ class TodosWebview extends Component { | |||
214 | classes, | 208 | classes, |
215 | isTodosServiceActive, | 209 | isTodosServiceActive, |
216 | isVisible, | 210 | isVisible, |
211 | userAgent, | ||
217 | isTodosIncludedInCurrentPlan, | 212 | isTodosIncludedInCurrentPlan, |
218 | stores, | 213 | stores, |
219 | } = this.props; | 214 | } = this.props; |
@@ -275,6 +270,7 @@ class TodosWebview extends Component { | |||
275 | partition={TODOS_PARTITION_ID} | 270 | partition={TODOS_PARTITION_ID} |
276 | preload="./features/todos/preload.js" | 271 | preload="./features/todos/preload.js" |
277 | ref={(webview) => { this.webview = webview ? webview.view : null; }} | 272 | ref={(webview) => { this.webview = webview ? webview.view : null; }} |
273 | useragent={userAgent} | ||
278 | src={todoUrl} | 274 | src={todoUrl} |
279 | /> | 275 | /> |
280 | ) | 276 | ) |
diff --git a/src/features/todos/containers/TodosScreen.js b/src/features/todos/containers/TodosScreen.js index 884925be6..631893f93 100644 --- a/src/features/todos/containers/TodosScreen.js +++ b/src/features/todos/containers/TodosScreen.js | |||
@@ -27,6 +27,7 @@ class TodosScreen extends Component { | |||
27 | width={todosStore.width} | 27 | width={todosStore.width} |
28 | minWidth={TODOS_MIN_WIDTH} | 28 | minWidth={TODOS_MIN_WIDTH} |
29 | resize={width => todoActions.resize({ width })} | 29 | resize={width => todoActions.resize({ width })} |
30 | userAgent={todosStore.userAgent} | ||
30 | isTodosIncludedInCurrentPlan | 31 | isTodosIncludedInCurrentPlan |
31 | /> | 32 | /> |
32 | </ErrorBoundary> | 33 | </ErrorBoundary> |
diff --git a/src/features/todos/store.js b/src/features/todos/store.js index c1d6a9049..af8519d9c 100644 --- a/src/features/todos/store.js +++ b/src/features/todos/store.js | |||
@@ -16,6 +16,8 @@ import { | |||
16 | import { IPC } from './constants'; | 16 | import { IPC } from './constants'; |
17 | import { state as delayAppState } from '../delayApp'; | 17 | import { state as delayAppState } from '../delayApp'; |
18 | 18 | ||
19 | import UserAgent from '../../models/UserAgent'; | ||
20 | |||
19 | const debug = require('debug')('Ferdi:feature:todos:store'); | 21 | const debug = require('debug')('Ferdi:feature:todos:store'); |
20 | 22 | ||
21 | export default class TodoStore extends FeatureStore { | 23 | export default class TodoStore extends FeatureStore { |
@@ -25,6 +27,8 @@ export default class TodoStore extends FeatureStore { | |||
25 | 27 | ||
26 | @observable webview = null; | 28 | @observable webview = null; |
27 | 29 | ||
30 | @observable userAgentModel = new UserAgent(); | ||
31 | |||
28 | isInitialized = false; | 32 | isInitialized = false; |
29 | 33 | ||
30 | @computed get width() { | 34 | @computed get width() { |
@@ -51,6 +55,10 @@ export default class TodoStore extends FeatureStore { | |||
51 | return localStorage.getItem('todos') || {}; | 55 | return localStorage.getItem('todos') || {}; |
52 | } | 56 | } |
53 | 57 | ||
58 | @computed get userAgent() { | ||
59 | return this.userAgentModel.userAgent; | ||
60 | } | ||
61 | |||
54 | // ========== PUBLIC API ========= // | 62 | // ========== PUBLIC API ========= // |
55 | 63 | ||
56 | @action start(stores, actions) { | 64 | @action start(stores, actions) { |
@@ -123,7 +131,10 @@ export default class TodoStore extends FeatureStore { | |||
123 | 131 | ||
124 | @action _setTodosWebview = ({ webview }) => { | 132 | @action _setTodosWebview = ({ webview }) => { |
125 | debug('_setTodosWebview', webview); | 133 | debug('_setTodosWebview', webview); |
126 | this.webview = webview; | 134 | if (this.webview !== webview) { |
135 | this.webview = webview; | ||
136 | this.userAgentModel.setWebviewReference(webview); | ||
137 | } | ||
127 | }; | 138 | }; |
128 | 139 | ||
129 | @action _handleHostMessage = (message) => { | 140 | @action _handleHostMessage = (message) => { |
diff --git a/src/helpers/userAgent-helpers.js b/src/helpers/userAgent-helpers.js index c5eee0082..73c454304 100644 --- a/src/helpers/userAgent-helpers.js +++ b/src/helpers/userAgent-helpers.js | |||
@@ -19,6 +19,10 @@ function linux() { | |||
19 | return 'X11; Ubuntu; Linux x86_64'; | 19 | return 'X11; Ubuntu; Linux x86_64'; |
20 | } | 20 | } |
21 | 21 | ||
22 | export function isChromeless(url) { | ||
23 | return url.startsWith('https://accounts.google.com'); | ||
24 | } | ||
25 | |||
22 | export default function userAgent(removeChromeVersion = false, addFerdiVersion = false) { | 26 | export default function userAgent(removeChromeVersion = false, addFerdiVersion = false) { |
23 | let platformString = ''; | 27 | let platformString = ''; |
24 | 28 | ||
diff --git a/src/i18n/locales/defaultMessages.json b/src/i18n/locales/defaultMessages.json index ef25aa3d9..c44357396 100644 --- a/src/i18n/locales/defaultMessages.json +++ b/src/i18n/locales/defaultMessages.json | |||
@@ -6412,39 +6412,39 @@ | |||
6412 | "defaultMessage": "!!!Franz Todos are available to premium users now!", | 6412 | "defaultMessage": "!!!Franz Todos are available to premium users now!", |
6413 | "end": { | 6413 | "end": { |
6414 | "column": 3, | 6414 | "column": 3, |
6415 | "line": 36 | 6415 | "line": 34 |
6416 | }, | 6416 | }, |
6417 | "file": "src/features/todos/components/TodosWebview.js", | 6417 | "file": "src/features/todos/components/TodosWebview.js", |
6418 | "id": "feature.todos.premium.info", | 6418 | "id": "feature.todos.premium.info", |
6419 | "start": { | 6419 | "start": { |
6420 | "column": 15, | 6420 | "column": 15, |
6421 | "line": 33 | 6421 | "line": 31 |
6422 | } | 6422 | } |
6423 | }, | 6423 | }, |
6424 | { | 6424 | { |
6425 | "defaultMessage": "!!!Upgrade Account", | 6425 | "defaultMessage": "!!!Upgrade Account", |
6426 | "end": { | 6426 | "end": { |
6427 | "column": 3, | 6427 | "column": 3, |
6428 | "line": 40 | 6428 | "line": 38 |
6429 | }, | 6429 | }, |
6430 | "file": "src/features/todos/components/TodosWebview.js", | 6430 | "file": "src/features/todos/components/TodosWebview.js", |
6431 | "id": "feature.todos.premium.upgrade", | 6431 | "id": "feature.todos.premium.upgrade", |
6432 | "start": { | 6432 | "start": { |
6433 | "column": 14, | 6433 | "column": 14, |
6434 | "line": 37 | 6434 | "line": 35 |
6435 | } | 6435 | } |
6436 | }, | 6436 | }, |
6437 | { | 6437 | { |
6438 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", | 6438 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", |
6439 | "end": { | 6439 | "end": { |
6440 | "column": 3, | 6440 | "column": 3, |
6441 | "line": 44 | 6441 | "line": 42 |
6442 | }, | 6442 | }, |
6443 | "file": "src/features/todos/components/TodosWebview.js", | 6443 | "file": "src/features/todos/components/TodosWebview.js", |
6444 | "id": "feature.todos.premium.rollout", | 6444 | "id": "feature.todos.premium.rollout", |
6445 | "start": { | 6445 | "start": { |
6446 | "column": 15, | 6446 | "column": 15, |
6447 | "line": 41 | 6447 | "line": 39 |
6448 | } | 6448 | } |
6449 | } | 6449 | } |
6450 | ], | 6450 | ], |
diff --git a/src/i18n/messages/src/features/todos/components/TodosWebview.json b/src/i18n/messages/src/features/todos/components/TodosWebview.json index 0652b0a33..ff6e037fc 100644 --- a/src/i18n/messages/src/features/todos/components/TodosWebview.json +++ b/src/i18n/messages/src/features/todos/components/TodosWebview.json | |||
@@ -4,11 +4,11 @@ | |||
4 | "defaultMessage": "!!!Franz Todos are available to premium users now!", | 4 | "defaultMessage": "!!!Franz Todos are available to premium users now!", |
5 | "file": "src/features/todos/components/TodosWebview.js", | 5 | "file": "src/features/todos/components/TodosWebview.js", |
6 | "start": { | 6 | "start": { |
7 | "line": 33, | 7 | "line": 31, |
8 | "column": 15 | 8 | "column": 15 |
9 | }, | 9 | }, |
10 | "end": { | 10 | "end": { |
11 | "line": 36, | 11 | "line": 34, |
12 | "column": 3 | 12 | "column": 3 |
13 | } | 13 | } |
14 | }, | 14 | }, |
@@ -17,11 +17,11 @@ | |||
17 | "defaultMessage": "!!!Upgrade Account", | 17 | "defaultMessage": "!!!Upgrade Account", |
18 | "file": "src/features/todos/components/TodosWebview.js", | 18 | "file": "src/features/todos/components/TodosWebview.js", |
19 | "start": { | 19 | "start": { |
20 | "line": 37, | 20 | "line": 35, |
21 | "column": 14 | 21 | "column": 14 |
22 | }, | 22 | }, |
23 | "end": { | 23 | "end": { |
24 | "line": 40, | 24 | "line": 38, |
25 | "column": 3 | 25 | "column": 3 |
26 | } | 26 | } |
27 | }, | 27 | }, |
@@ -30,11 +30,11 @@ | |||
30 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", | 30 | "defaultMessage": "!!!Everyone else will have to wait a little longer.", |
31 | "file": "src/features/todos/components/TodosWebview.js", | 31 | "file": "src/features/todos/components/TodosWebview.js", |
32 | "start": { | 32 | "start": { |
33 | "line": 41, | 33 | "line": 39, |
34 | "column": 15 | 34 | "column": 15 |
35 | }, | 35 | }, |
36 | "end": { | 36 | "end": { |
37 | "line": 44, | 37 | "line": 42, |
38 | "column": 3 | 38 | "column": 3 |
39 | } | 39 | } |
40 | } | 40 | } |
diff --git a/src/models/Service.js b/src/models/Service.js index b01881beb..0d1dff431 100644 --- a/src/models/Service.js +++ b/src/models/Service.js | |||
@@ -4,9 +4,9 @@ import { webContents } from '@electron/remote'; | |||
4 | import normalizeUrl from 'normalize-url'; | 4 | import normalizeUrl from 'normalize-url'; |
5 | import path from 'path'; | 5 | import path from 'path'; |
6 | 6 | ||
7 | import userAgent from '../helpers/userAgent-helpers'; | ||
8 | import { TODOS_RECIPE_ID, todosStore } from '../features/todos'; | 7 | import { TODOS_RECIPE_ID, todosStore } from '../features/todos'; |
9 | import { isValidExternalURL } from '../helpers/url-helpers'; | 8 | import { isValidExternalURL } from '../helpers/url-helpers'; |
9 | import UserAgent from './UserAgent'; | ||
10 | 10 | ||
11 | const debug = require('debug')('Ferdi:Service'); | 11 | const debug = require('debug')('Ferdi:Service'); |
12 | 12 | ||
@@ -94,7 +94,7 @@ export default class Service { | |||
94 | 94 | ||
95 | @observable lostRecipeReloadAttempt = 0; | 95 | @observable lostRecipeReloadAttempt = 0; |
96 | 96 | ||
97 | @observable chromelessUserAgent = false; | 97 | @observable userAgentModel = null; |
98 | 98 | ||
99 | constructor(data, recipe) { | 99 | constructor(data, recipe) { |
100 | if (!data) { | 100 | if (!data) { |
@@ -156,6 +156,8 @@ export default class Service { | |||
156 | this.isHibernating = true; | 156 | this.isHibernating = true; |
157 | } | 157 | } |
158 | 158 | ||
159 | this.userAgentModel = new UserAgent(recipe.overrideUserAgent); | ||
160 | |||
159 | autorun(() => { | 161 | autorun(() => { |
160 | if (!this.isEnabled) { | 162 | if (!this.isEnabled) { |
161 | this.webview = null; | 163 | this.webview = null; |
@@ -234,12 +236,7 @@ export default class Service { | |||
234 | } | 236 | } |
235 | 237 | ||
236 | @computed get userAgent() { | 238 | @computed get userAgent() { |
237 | let ua = userAgent(this.chromelessUserAgent); | 239 | return this.userAgentModel.userAgent; |
238 | if (typeof this.recipe.overrideUserAgent === 'function') { | ||
239 | ua = this.recipe.overrideUserAgent(); | ||
240 | } | ||
241 | |||
242 | return ua; | ||
243 | } | 240 | } |
244 | 241 | ||
245 | @computed get partition() { | 242 | @computed get partition() { |
@@ -250,6 +247,8 @@ export default class Service { | |||
250 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { | 247 | initializeWebViewEvents({ handleIPCMessage, openWindow, stores }) { |
251 | const webviewWebContents = webContents.fromId(this.webview.getWebContentsId()); | 248 | const webviewWebContents = webContents.fromId(this.webview.getWebContentsId()); |
252 | 249 | ||
250 | this.userAgentModel.setWebviewReference(this.webview); | ||
251 | |||
253 | // If the recipe has implemented modifyRequestHeaders, | 252 | // If the recipe has implemented modifyRequestHeaders, |
254 | // Send those headers to ipcMain so that it can be set in session | 253 | // Send those headers to ipcMain so that it can be set in session |
255 | if (typeof this.recipe.modifyRequestHeaders === 'function') { | 254 | if (typeof this.recipe.modifyRequestHeaders === 'function') { |
@@ -263,23 +262,6 @@ export default class Service { | |||
263 | debug(this.name, 'modifyRequestHeaders is not defined in the recipe'); | 262 | debug(this.name, 'modifyRequestHeaders is not defined in the recipe'); |
264 | } | 263 | } |
265 | 264 | ||
266 | const handleUserAgent = (url, forwardingHack = false) => { | ||
267 | if (url.startsWith('https://accounts.google.com')) { | ||
268 | if (!this.chromelessUserAgent) { | ||
269 | debug('Setting user agent to chromeless for url', url); | ||
270 | this.webview.setUserAgent(userAgent(true)); | ||
271 | if (forwardingHack) { | ||
272 | this.webview.loadURL(url); | ||
273 | } | ||
274 | this.chromelessUserAgent = true; | ||
275 | } | ||
276 | } else if (this.chromelessUserAgent) { | ||
277 | debug('Setting user agent to contain chrome'); | ||
278 | this.webview.setUserAgent(this.userAgent); | ||
279 | this.chromelessUserAgent = false; | ||
280 | } | ||
281 | }; | ||
282 | |||
283 | this.webview.addEventListener('ipc-message', e => handleIPCMessage({ | 265 | this.webview.addEventListener('ipc-message', e => handleIPCMessage({ |
284 | serviceId: this.id, | 266 | serviceId: this.id, |
285 | channel: e.channel, | 267 | channel: e.channel, |
@@ -306,8 +288,6 @@ export default class Service { | |||
306 | } | 288 | } |
307 | }); | 289 | }); |
308 | 290 | ||
309 | this.webview.addEventListener('will-navigate', event => handleUserAgent(event.url, true)); | ||
310 | |||
311 | this.webview.addEventListener('did-start-loading', (event) => { | 291 | this.webview.addEventListener('did-start-loading', (event) => { |
312 | debug('Did start load', this.name, event); | 292 | debug('Did start load', this.name, event); |
313 | 293 | ||
@@ -325,10 +305,7 @@ export default class Service { | |||
325 | }; | 305 | }; |
326 | 306 | ||
327 | this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); | 307 | this.webview.addEventListener('did-frame-finish-load', didLoad.bind(this)); |
328 | this.webview.addEventListener('did-navigate', (event) => { | 308 | this.webview.addEventListener('did-navigate', didLoad.bind(this)); |
329 | handleUserAgent(event.url); | ||
330 | didLoad(); | ||
331 | }); | ||
332 | 309 | ||
333 | this.webview.addEventListener('did-fail-load', (event) => { | 310 | this.webview.addEventListener('did-fail-load', (event) => { |
334 | debug('Service failed to load', this.name, event); | 311 | debug('Service failed to load', this.name, event); |
diff --git a/src/models/UserAgent.js b/src/models/UserAgent.js new file mode 100644 index 000000000..f51f2e5a6 --- /dev/null +++ b/src/models/UserAgent.js | |||
@@ -0,0 +1,80 @@ | |||
1 | import { | ||
2 | action, | ||
3 | computed, | ||
4 | observe, | ||
5 | observable, | ||
6 | } from 'mobx'; | ||
7 | |||
8 | import defaultUserAgent, { isChromeless } from '../helpers/userAgent-helpers'; | ||
9 | |||
10 | const debug = require('debug')('Ferdi:UserAgent'); | ||
11 | |||
12 | export default class UserAgent { | ||
13 | _willNavigateListener = null; | ||
14 | |||
15 | _didNavigateListener = null; | ||
16 | |||
17 | @observable.ref webview = null; | ||
18 | |||
19 | @observable chromelessUserAgent = false; | ||
20 | |||
21 | @observable getUserAgent = defaultUserAgent; | ||
22 | |||
23 | constructor(overrideUserAgent = null) { | ||
24 | if (typeof overrideUserAgent === 'function') { | ||
25 | this.getUserAgent = overrideUserAgent; | ||
26 | } | ||
27 | |||
28 | observe(this, 'webview', (change) => { | ||
29 | const { oldValue, newValue } = change; | ||
30 | if (oldValue !== null) { | ||
31 | this._removeWebviewEvents(oldValue); | ||
32 | } | ||
33 | if (newValue !== null) { | ||
34 | this._addWebviewEvents(newValue); | ||
35 | } | ||
36 | }); | ||
37 | } | ||
38 | |||
39 | @computed get userAgent() { | ||
40 | return this.chromelessUserAgent ? defaultUserAgent(true) : this.getUserAgent(); | ||
41 | } | ||
42 | |||
43 | @action setWebviewReference(webview) { | ||
44 | this.webview = webview; | ||
45 | } | ||
46 | |||
47 | @action _handleNavigate(url, forwardingHack = false) { | ||
48 | if (isChromeless(url)) { | ||
49 | if (!this.chromelessUserAgent) { | ||
50 | debug('Setting user agent to chromeless for url', url); | ||
51 | this.chromelessUserAgent = true; | ||
52 | this.webview.userAgent = this.userAgent; | ||
53 | if (forwardingHack) { | ||
54 | this.webview.loadURL(url); | ||
55 | } | ||
56 | } | ||
57 | } else if (this.chromelessUserAgent) { | ||
58 | debug('Setting user agent to contain chrome for url', url); | ||
59 | this.chromelessUserAgent = false; | ||
60 | this.webview.userAgent = this.userAgent; | ||
61 | } | ||
62 | } | ||
63 | |||
64 | _addWebviewEvents(webview) { | ||
65 | debug('Adding event handlers'); | ||
66 | |||
67 | this._willNavigateListener = event => this._handleNavigate(event.url, true); | ||
68 | webview.addEventListener('will-navigate', this._willNavigateListener); | ||
69 | |||
70 | this._didNavigateListener = event => this._handleNavigate(event.url); | ||
71 | webview.addEventListener('did-navigate', this._didNavigateListener); | ||
72 | } | ||
73 | |||
74 | _removeWebviewEvents(webview) { | ||
75 | debug('Removing event handlers'); | ||
76 | |||
77 | webview.removeEventListener('will-navigate', this._willNavigateListener); | ||
78 | webview.removeEventListener('did-navigate', this._didNavigateListener); | ||
79 | } | ||
80 | } | ||