Files: 612509945be4d8cb719d3b0a5a0390a0ddbcf911 / lib / context-menu-and-spellcheck.js
5959 bytesRaw
1 | const { remote, shell, clipboard, ipcRenderer } = require('electron') |
2 | const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('electron-spellchecker') |
3 | const { MenuItem, Menu } = remote |
4 | const ref = require('ssb-ref') |
5 | |
6 | let navigateHandler = null |
7 | module.exports = setupContextMenuAndSpellCheck |
8 | |
9 | function setupContextMenuAndSpellCheck (config, { navigate, getMessageText, language }) { |
10 | navigateHandler = navigate |
11 | const spellCheckHandler = new SpellCheckHandler() |
12 | spellCheckHandler.attachToInput() |
13 | |
14 | // Start off as US English, America #1 (lol) |
15 | spellCheckHandler.switchLanguage(language || 'en-US') |
16 | |
17 | const contextMenuBuilder = new ContextMenuBuilder(spellCheckHandler, null, true, (menu, menuInfo) => { |
18 | const ddg = new MenuItem({ |
19 | label: 'Search With DuckDuckGo', |
20 | click: () => { |
21 | const url = `https://duckduckgo.com/?q=${encodeURIComponent(menuInfo.selectionText)}` |
22 | shell.openExternal(url) |
23 | } |
24 | }) |
25 | |
26 | // There's no menu.remove(id) so this is a convoluted way of removing the |
27 | // 'Search with Google' menu item |
28 | const oldItems = menu.items |
29 | menu.clear() |
30 | |
31 | oldItems.forEach(oldItem => { |
32 | if (oldItem.label === 'Search with Google') { |
33 | menu.append(ddg) |
34 | } else { |
35 | menu.append(oldItem) |
36 | } |
37 | }) |
38 | |
39 | if (menuInfo.mediaType !== 'none') { |
40 | console.log(menuInfo) |
41 | const copyEmbed = new MenuItem({ |
42 | label: 'Copy Embed Markdown', |
43 | click: () => { |
44 | // Omit the mailto: portion of the link; we just want the address |
45 | const extractedRef = ref.extract(menuInfo.srcURL) |
46 | clipboard.writeText(`![${menuInfo.titleText}](${extractedRef})`) |
47 | } |
48 | }) |
49 | menu.append(copyEmbed) |
50 | const openImageInBrowser = new MenuItem({ |
51 | label: 'Open Image With Browser', |
52 | click: () => { |
53 | shell.openExternal(menuInfo.srcURL) |
54 | } |
55 | }) |
56 | menu.append(openImageInBrowser) |
57 | } |
58 | }) |
59 | |
60 | contextMenuBuilder.buildMenuForLink = function (menuInfo) { |
61 | const element = document.elementFromPoint(menuInfo.x, menuInfo.y) |
62 | |
63 | const menu = new Menu() |
64 | const isEmailAddress = menuInfo.linkURL.startsWith('mailto:') |
65 | const isFile = menuInfo.linkURL.startsWith('file:') |
66 | |
67 | // use the anchor of a link if it directly references an ID |
68 | const extractedRef = element && ref.isLink(element.anchor) ? element.anchor : ref.extract(menuInfo.linkURL) |
69 | |
70 | if (!isFile) { |
71 | const copyLink = new MenuItem({ |
72 | label: isEmailAddress ? this.stringTable.copyMail() : this.stringTable.copyLinkUrl(), |
73 | click: () => { |
74 | // Omit the mailto: portion of the link; we just want the address |
75 | clipboard.writeText(isEmailAddress ? menuInfo.linkText : menuInfo.linkURL) |
76 | } |
77 | }) |
78 | |
79 | const openLink = new MenuItem({ |
80 | label: this.stringTable.openLinkUrl(), |
81 | click: () => { |
82 | shell.openExternal(menuInfo.linkURL) |
83 | } |
84 | }) |
85 | |
86 | menu.append(copyLink) |
87 | menu.append(openLink) |
88 | } |
89 | |
90 | if (extractedRef) { |
91 | if (navigateHandler) { |
92 | menu.append(new MenuItem({ |
93 | label: 'Find Link References', |
94 | click: function () { |
95 | navigateHandler('?' + extractedRef) |
96 | } |
97 | })) |
98 | this.addSeparator(menu) |
99 | } |
100 | const copyRef = new MenuItem({ |
101 | label: `Copy Link Ref (${extractedRef.slice(0, 10)}...)`, |
102 | click: () => { |
103 | // Omit the mailto: portion of the link; we just want the address |
104 | clipboard.writeText(extractedRef) |
105 | } |
106 | }) |
107 | menu.append(copyRef) |
108 | } |
109 | |
110 | if (this.isSrcUrlValid(menuInfo)) { |
111 | if (!isFile) this.addSeparator(menu) |
112 | this.addImageItems(menu, menuInfo) |
113 | } |
114 | |
115 | this.addInspectElement(menu, menuInfo) |
116 | this.processMenu(menu, menuInfo) |
117 | |
118 | return menu |
119 | } |
120 | |
121 | module.exports.menu = new ContextMenuListener((info) => { |
122 | contextMenuBuilder.buildMenuForElement(info).then((menu) => { |
123 | let element = document.elementFromPoint(info.x, info.y) |
124 | while (element && !element.msg) { |
125 | element = element.parentNode |
126 | } |
127 | |
128 | menu.append(new MenuItem({ |
129 | label: 'Inspect Server Process', |
130 | click: function () { |
131 | ipcRenderer.send('open-background-devtools') |
132 | } |
133 | })) |
134 | |
135 | menu.append(new MenuItem({ |
136 | type: 'separator' |
137 | })) |
138 | |
139 | menu.append(new MenuItem({ |
140 | label: 'Reload', |
141 | click: function (item, focusedWindow) { |
142 | if (focusedWindow) { |
143 | focusedWindow.reload() |
144 | } |
145 | } |
146 | })) |
147 | |
148 | if (element && element.msg) { |
149 | menu.append(new MenuItem({ |
150 | type: 'separator' |
151 | })) |
152 | menu.append(new MenuItem({ |
153 | label: 'Copy Message ID', |
154 | click: function () { |
155 | clipboard.writeText(element.msg.key) |
156 | } |
157 | })) |
158 | menu.append(new MenuItem({ |
159 | label: 'Copy Message Text', |
160 | click: function () { |
161 | getMessageText(element.msg.key, (err, value) => { |
162 | if (!err) { |
163 | clipboard.writeText(value) |
164 | } else { |
165 | showDialog({ |
166 | type: 'error', |
167 | title: 'Error', |
168 | buttons: ['OK'], |
169 | message: 'Could not get message text.', |
170 | detail: err && err.message |
171 | }) |
172 | } |
173 | }) |
174 | } |
175 | })) |
176 | menu.append(new MenuItem({ |
177 | label: 'Copy External Link', |
178 | click: function () { |
179 | const key = element.msg.key |
180 | const gateway = config.gateway || |
181 | 'https://viewer.scuttlebot.io' |
182 | const url = `${gateway}/${encodeURIComponent(key)}` |
183 | clipboard.writeText(url) |
184 | } |
185 | })) |
186 | } |
187 | menu.popup(remote.getCurrentWindow()) |
188 | }).catch((err) => { |
189 | throw err |
190 | }) |
191 | }) |
192 | } |
193 | |
194 | function showDialog (opts) { |
195 | remote.dialog.showMessageBox(remote.getCurrentWindow(), opts) |
196 | } |
197 |
Built with git-ssb-web