git ssb

1+

Daan Patchwork / patchwork



Tree: 703b5de55b4f80cf231d914b9257bc81cd59ceef

Files: 703b5de55b4f80cf231d914b9257bc81cd59ceef / lib / context-menu-and-spellcheck.js

5959 bytesRaw
1const { remote, shell, clipboard, ipcRenderer } = require('electron')
2const { SpellCheckHandler, ContextMenuListener, ContextMenuBuilder } = require('electron-spellchecker')
3const { MenuItem, Menu } = remote
4const ref = require('ssb-ref')
5
6let navigateHandler = null
7module.exports = setupContextMenuAndSpellCheck
8
9function 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
194function showDialog (opts) {
195 remote.dialog.showMessageBox(remote.getCurrentWindow(), opts)
196}
197

Built with git-ssb-web