diff options
author | 2017-10-13 12:29:40 +0200 | |
---|---|---|
committer | 2017-10-13 12:29:40 +0200 | |
commit | 58cda9cc7fb79ca9df6746de7f9662bc08dc156a (patch) | |
tree | 1211600c2a5d3b5f81c435c6896618111a611720 /src/webview | |
download | ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.gz ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.tar.zst ferdium-app-58cda9cc7fb79ca9df6746de7f9662bc08dc156a.zip |
initial commit
Diffstat (limited to 'src/webview')
-rw-r--r-- | src/webview/ime.js | 10 | ||||
-rw-r--r-- | src/webview/lib/RecipeWebview.js | 74 | ||||
-rw-r--r-- | src/webview/notifications.js | 45 | ||||
-rw-r--r-- | src/webview/plugin.js | 24 | ||||
-rw-r--r-- | src/webview/spellchecker.js | 14 | ||||
-rw-r--r-- | src/webview/zoom.js | 37 |
6 files changed, 204 insertions, 0 deletions
diff --git a/src/webview/ime.js b/src/webview/ime.js new file mode 100644 index 000000000..43df6267c --- /dev/null +++ b/src/webview/ime.js | |||
@@ -0,0 +1,10 @@ | |||
1 | const { ipcRenderer } = require('electron'); | ||
2 | const { claimDocumentFocus } = require('../helpers/webview-ime-focus-helpers'); | ||
3 | |||
4 | ipcRenderer.on('claim-document-focus', claimDocumentFocus); | ||
5 | |||
6 | window.addEventListener('DOMContentLoaded', () => { | ||
7 | if (document.querySelector('[autofocus]')) { | ||
8 | ipcRenderer.sendToHost('autofocus'); | ||
9 | } | ||
10 | }); | ||
diff --git a/src/webview/lib/RecipeWebview.js b/src/webview/lib/RecipeWebview.js new file mode 100644 index 000000000..1787f85e2 --- /dev/null +++ b/src/webview/lib/RecipeWebview.js | |||
@@ -0,0 +1,74 @@ | |||
1 | // @flow | ||
2 | const { ipcRenderer } = require('electron'); | ||
3 | const fs = require('fs-extra'); | ||
4 | |||
5 | class RecipeWebview { | ||
6 | constructor() { | ||
7 | this.countCache = { | ||
8 | direct: 0, | ||
9 | indirect: 0, | ||
10 | }; | ||
11 | |||
12 | ipcRenderer.on('poll', () => { | ||
13 | this.loopFunc(); | ||
14 | }); | ||
15 | } | ||
16 | |||
17 | loopFunc = () => null; | ||
18 | |||
19 | /** | ||
20 | * Initialize the loop | ||
21 | * | ||
22 | * @param {Function} Function that will be executed | ||
23 | */ | ||
24 | loop(fn) { | ||
25 | this.loopFunc = fn; | ||
26 | } | ||
27 | |||
28 | /** | ||
29 | * Set the unread message badge | ||
30 | * | ||
31 | * @param {int} direct Set the count of direct messages | ||
32 | * eg. Slack direct mentions, or a | ||
33 | * message to @channel | ||
34 | * @param {int} indirect Set a badge that defines there are | ||
35 | * new messages but they do not involve | ||
36 | * me directly to me eg. in a channel | ||
37 | */ | ||
38 | setBadge(direct = 0, indirect = 0) { | ||
39 | if (this.countCache.direct === direct | ||
40 | && this.countCache.indirect === indirect) return; | ||
41 | |||
42 | const count = { | ||
43 | direct, | ||
44 | indirect, | ||
45 | }; | ||
46 | |||
47 | ipcRenderer.sendToHost('messages', count); | ||
48 | Object.assign(this.countCache, count); | ||
49 | } | ||
50 | |||
51 | /** | ||
52 | * Injects the contents of a CSS file into the current webview | ||
53 | * | ||
54 | * @param {Array} files CSS files that should be injected. This must | ||
55 | * be an absolute path to the file | ||
56 | */ | ||
57 | injectCSS(...files) { | ||
58 | files.forEach((file) => { | ||
59 | const data = fs.readFileSync(file); | ||
60 | const styles = document.createElement('style'); | ||
61 | styles.innerHTML = data.toString(); | ||
62 | |||
63 | document.querySelector('head').appendChild(styles); | ||
64 | }); | ||
65 | } | ||
66 | |||
67 | initialize(fn) { | ||
68 | if (typeof fn === 'function') { | ||
69 | fn(); | ||
70 | } | ||
71 | } | ||
72 | } | ||
73 | |||
74 | module.exports = RecipeWebview; | ||
diff --git a/src/webview/notifications.js b/src/webview/notifications.js new file mode 100644 index 000000000..97ce9d69b --- /dev/null +++ b/src/webview/notifications.js | |||
@@ -0,0 +1,45 @@ | |||
1 | const { ipcRenderer } = require('electron'); | ||
2 | const uuidV1 = require('uuid/v1'); | ||
3 | // const FranzNotificationStore = []; | ||
4 | |||
5 | class Notification { | ||
6 | constructor(title = '', options = {}) { | ||
7 | this.title = title; | ||
8 | this.options = options; | ||
9 | this.notificationId = uuidV1(); | ||
10 | this.onclick = () => {}; | ||
11 | |||
12 | ipcRenderer.sendToHost('notification', { | ||
13 | notificationId: this.notificationId, | ||
14 | title, | ||
15 | options, | ||
16 | }); | ||
17 | |||
18 | ipcRenderer.on(`notification-onclick:${this.notificationId}`, () => { | ||
19 | this.onclick(); | ||
20 | }); | ||
21 | } | ||
22 | } | ||
23 | |||
24 | Notification.permission = 'granted'; | ||
25 | |||
26 | Notification.requestPermission = (cb = null) => { | ||
27 | console.log(this); | ||
28 | if (!cb) { | ||
29 | return new Promise((resolve) => { | ||
30 | resolve(Notification.permission); | ||
31 | }); | ||
32 | } | ||
33 | |||
34 | if (typeof (cb) === 'function') { | ||
35 | return cb(Notification.permission); | ||
36 | } | ||
37 | |||
38 | return Notification.permission; | ||
39 | }; | ||
40 | |||
41 | Notification.close = () => { | ||
42 | // no implementation yet | ||
43 | }; | ||
44 | |||
45 | window.Notification = Notification; | ||
diff --git a/src/webview/plugin.js b/src/webview/plugin.js new file mode 100644 index 000000000..ffc9084e4 --- /dev/null +++ b/src/webview/plugin.js | |||
@@ -0,0 +1,24 @@ | |||
1 | const { ipcRenderer } = require('electron'); | ||
2 | const path = require('path'); | ||
3 | |||
4 | const RecipeWebview = require('./lib/RecipeWebview'); | ||
5 | |||
6 | require('./notifications.js'); | ||
7 | require('./spellchecker.js'); | ||
8 | require('./ime.js'); | ||
9 | |||
10 | ipcRenderer.on('initializeRecipe', (e, data) => { | ||
11 | const modulePath = path.join(data.recipe.path, 'webview.js'); | ||
12 | // Delete module from cache | ||
13 | delete require.cache[require.resolve(modulePath)]; | ||
14 | try { | ||
15 | // eslint-disable-next-line | ||
16 | require(modulePath)(new RecipeWebview(), data); | ||
17 | } catch (err) { | ||
18 | console.error(err); | ||
19 | } | ||
20 | }); | ||
21 | |||
22 | document.addEventListener('DOMContentLoaded', () => { | ||
23 | ipcRenderer.sendToHost('hello'); | ||
24 | }, false); | ||
diff --git a/src/webview/spellchecker.js b/src/webview/spellchecker.js new file mode 100644 index 000000000..ec8807874 --- /dev/null +++ b/src/webview/spellchecker.js | |||
@@ -0,0 +1,14 @@ | |||
1 | import { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } from 'electron-spellchecker'; | ||
2 | |||
3 | window.spellCheckHandler = new SpellCheckHandler(); | ||
4 | setTimeout(() => { | ||
5 | window.spellCheckHandler.attachToInput(); | ||
6 | }, 1000); | ||
7 | |||
8 | // TODO: should we set the language to user settings? | ||
9 | // window.spellCheckHandler.switchLanguage('en-US'); | ||
10 | |||
11 | const contextMenuBuilder = new ContextMenuBuilder(window.spellCheckHandler); | ||
12 | const contextMenuListener = new ContextMenuListener((info) => { // eslint-disable-line | ||
13 | contextMenuBuilder.showPopupMenu(info); | ||
14 | }); | ||
diff --git a/src/webview/zoom.js b/src/webview/zoom.js new file mode 100644 index 000000000..99c647036 --- /dev/null +++ b/src/webview/zoom.js | |||
@@ -0,0 +1,37 @@ | |||
1 | const electron = require('electron'); | ||
2 | |||
3 | const { ipcRenderer, webFrame } = electron; | ||
4 | |||
5 | const maxZoomLevel = 9; | ||
6 | const minZoomLevel = -8; | ||
7 | let zoomLevel = 0; | ||
8 | |||
9 | ipcRenderer.on('zoomIn', () => { | ||
10 | if (maxZoomLevel > zoomLevel) { | ||
11 | zoomLevel += 1; | ||
12 | } | ||
13 | webFrame.setZoomLevel(zoomLevel); | ||
14 | |||
15 | ipcRenderer.sendToHost('zoomLevel', { zoom: zoomLevel }); | ||
16 | }); | ||
17 | |||
18 | ipcRenderer.on('zoomOut', () => { | ||
19 | if (minZoomLevel < zoomLevel) { | ||
20 | zoomLevel -= 1; | ||
21 | } | ||
22 | webFrame.setZoomLevel(zoomLevel); | ||
23 | |||
24 | ipcRenderer.sendToHost('zoomLevel', { zoom: zoomLevel }); | ||
25 | }); | ||
26 | |||
27 | ipcRenderer.on('zoomReset', () => { | ||
28 | zoomLevel = 0; | ||
29 | webFrame.setZoomLevel(zoomLevel); | ||
30 | |||
31 | ipcRenderer.sendToHost('zoomLevel', { zoom: zoomLevel }); | ||
32 | }); | ||
33 | |||
34 | ipcRenderer.on('setZoom', (e, arg) => { | ||
35 | zoomLevel = arg; | ||
36 | webFrame.setZoomLevel(zoomLevel); | ||
37 | }); | ||