mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-12 17:26:17 +00:00
feat: Added Context Menu for markdown preview mode and copy url when hyperlink
This commit is contained in:
committed by
Junyoung Choi
parent
c83e5cc7d8
commit
e85767b4a0
@@ -20,7 +20,7 @@ import styles from '../components/CodeEditor.styl'
|
||||
const { ipcRenderer, remote, clipboard } = require('electron')
|
||||
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
|
||||
const spellcheck = require('browser/lib/spellcheck')
|
||||
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
|
||||
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder').buildEditorContextMenu
|
||||
import TurndownService from 'turndown'
|
||||
import {languageMaps} from '../lib/CMLanguageList'
|
||||
import snippetManager from '../lib/SnippetManager'
|
||||
|
||||
@@ -18,15 +18,13 @@ import mdurl from 'mdurl'
|
||||
import exportNote from 'browser/main/lib/dataApi/exportNote'
|
||||
import { escapeHtmlCharacters } from 'browser/lib/utils'
|
||||
import yaml from 'js-yaml'
|
||||
import context from 'browser/lib/context'
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import fs from 'fs'
|
||||
import { render } from 'react-dom'
|
||||
import Carousel from 'react-image-carousel'
|
||||
import ConfigManager from '../main/lib/ConfigManager'
|
||||
|
||||
const { remote, shell } = require('electron')
|
||||
const attachmentManagement = require('../main/lib/dataApi/attachmentManagement')
|
||||
const buildMarkdownPreviewContextMenu = require('browser/lib/contextMenuBuilder').buildMarkdownPreviewContextMenu
|
||||
|
||||
const { app } = remote
|
||||
const path = require('path')
|
||||
@@ -34,8 +32,6 @@ const fileUrl = require('file-url')
|
||||
|
||||
const dialog = remote.dialog
|
||||
|
||||
const uri2path = require('file-uri-to-path')
|
||||
|
||||
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
||||
const appPath = fileUrl(
|
||||
process.env.NODE_ENV === 'production' ? app.getAppPath() : path.resolve()
|
||||
@@ -250,30 +246,9 @@ export default class MarkdownPreview extends React.Component {
|
||||
}
|
||||
|
||||
handleContextMenu (event) {
|
||||
// If a contextMenu handler was passed to us, use it instead of the self-defined one -> return
|
||||
if (_.isFunction(this.props.onContextMenu)) {
|
||||
this.props.onContextMenu(event)
|
||||
return
|
||||
}
|
||||
// No contextMenu was passed to us -> execute our own link-opener
|
||||
if (event.target.tagName.toLowerCase() === 'a' && event.target.getAttribute('href')) {
|
||||
const href = event.target.href
|
||||
const isLocalFile = href.startsWith('file:')
|
||||
if (isLocalFile) {
|
||||
const absPath = uri2path(href)
|
||||
try {
|
||||
if (fs.lstatSync(absPath).isFile()) {
|
||||
context.popup([
|
||||
{
|
||||
label: i18n.__('Show in explorer'),
|
||||
click: (e) => shell.showItemInFolder(absPath)
|
||||
}
|
||||
])
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Error while evaluating if the file is locally available', e)
|
||||
}
|
||||
}
|
||||
const menu = buildMarkdownPreviewContextMenu(this, event)
|
||||
if (menu != null) {
|
||||
setTimeout(() => menu.popup(remote.getCurrentWindow()), 30)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import i18n from 'browser/lib/i18n'
|
||||
import fs from 'fs'
|
||||
|
||||
const {remote} = require('electron')
|
||||
const {Menu} = remote.require('electron')
|
||||
const {clipboard} = remote.require('electron')
|
||||
const {shell} = remote.require('electron')
|
||||
const spellcheck = require('./spellcheck')
|
||||
const uri2path = require('file-uri-to-path')
|
||||
|
||||
/**
|
||||
* Creates the context menu that is shown when there is a right click in the editor of a (not-snippet) note.
|
||||
@@ -62,4 +68,61 @@ const buildEditorContextMenu = function (editor, event) {
|
||||
return Menu.buildFromTemplate(template)
|
||||
}
|
||||
|
||||
module.exports = buildEditorContextMenu
|
||||
/**
|
||||
* Creates the context menu that is shown when there is a right click Markdown preview of a (not-snippet) note.
|
||||
* @param {MarkdownPreview} markdownPreview
|
||||
* @param {MouseEvent} event that has triggered the creation of the context menu
|
||||
* @returns {Electron.Menu} The created electron context menu
|
||||
*/
|
||||
const buildMarkdownPreviewContextMenu = function (markdownPreview, event) {
|
||||
if (markdownPreview == null || event == null || event.pageX == null || event.pageY == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Default context menu inclusions
|
||||
const template = [{
|
||||
role: 'cut'
|
||||
}, {
|
||||
role: 'copy'
|
||||
}, {
|
||||
role: 'paste'
|
||||
}, {
|
||||
role: 'selectall'
|
||||
}]
|
||||
|
||||
if (event.target.tagName.toLowerCase() === 'a' && event.target.getAttribute('href')) {
|
||||
// Link opener for files on the local system pointed to by href
|
||||
const href = event.target.href
|
||||
const isLocalFile = href.startsWith('file:')
|
||||
if (isLocalFile) {
|
||||
const absPath = uri2path(href)
|
||||
try {
|
||||
if (fs.lstatSync(absPath).isFile()) {
|
||||
template.push(
|
||||
{
|
||||
label: i18n.__('Show in explorer'),
|
||||
click: (e) => shell.showItemInFolder(absPath)
|
||||
}
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('Error while evaluating if the file is locally available', e)
|
||||
}
|
||||
}
|
||||
|
||||
// Add option to context menu to copy url
|
||||
template.push(
|
||||
{
|
||||
label: i18n.__('Copy Url'),
|
||||
click: (e) => clipboard.writeText(href)
|
||||
}
|
||||
)
|
||||
}
|
||||
return Menu.buildFromTemplate(template)
|
||||
}
|
||||
|
||||
module.exports =
|
||||
{
|
||||
buildEditorContextMenu: buildEditorContextMenu,
|
||||
buildMarkdownPreviewContextMenu: buildMarkdownPreviewContextMenu
|
||||
}
|
||||
|
||||
@@ -5,11 +5,13 @@ jest.mock('electron', () => {
|
||||
|
||||
const spellcheck = require('browser/lib/spellcheck')
|
||||
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
|
||||
const buildMarkdownPreviewContextMenu = require('browser/lib/contextMenuBuilder')
|
||||
|
||||
beforeEach(() => {
|
||||
menuBuilderParameter = null
|
||||
})
|
||||
|
||||
// Editor Context Menu
|
||||
it('should make sure that no context menu is build if the passed editor instance was null', function () {
|
||||
const event = {
|
||||
pageX: 12,
|
||||
@@ -124,3 +126,13 @@ it('should make sure that word suggestions creates a correct menu if there was a
|
||||
expect(menuBuilderParameter[7].role).toEqual('selectall')
|
||||
expect(spellcheck.getSpellingSuggestion).toHaveBeenCalledWith(wordToCorrect)
|
||||
})
|
||||
|
||||
// Markdown Preview Context Menu
|
||||
it('should make sure that no context menu is built if the Markdown Preview instance was null', function () {
|
||||
const event = {
|
||||
pageX: 12,
|
||||
pageY: 12
|
||||
}
|
||||
buildMarkdownPreviewContextMenu(null, event)
|
||||
expect(menuBuilderParameter).toEqual(null)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user