mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
Merge branch 'master' into feature/scrollbarAppearance
This commit is contained in:
@@ -18,7 +18,9 @@
|
|||||||
"globals": {
|
"globals": {
|
||||||
"FileReader": true,
|
"FileReader": true,
|
||||||
"localStorage": true,
|
"localStorage": true,
|
||||||
"fetch": true
|
"fetch": true,
|
||||||
|
"Image": true,
|
||||||
|
"MutationObserver": true
|
||||||
},
|
},
|
||||||
"env": {
|
"env": {
|
||||||
"jest": true
|
"jest": true
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import styles from '../components/CodeEditor.styl'
|
|||||||
const { ipcRenderer, remote, clipboard } = require('electron')
|
const { ipcRenderer, remote, clipboard } = require('electron')
|
||||||
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
|
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
|
||||||
const spellcheck = require('browser/lib/spellcheck')
|
const spellcheck = require('browser/lib/spellcheck')
|
||||||
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
|
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder').buildEditorContextMenu
|
||||||
import TurndownService from 'turndown'
|
import TurndownService from 'turndown'
|
||||||
import {languageMaps} from '../lib/CMLanguageList'
|
import {languageMaps} from '../lib/CMLanguageList'
|
||||||
import snippetManager from '../lib/SnippetManager'
|
import snippetManager from '../lib/SnippetManager'
|
||||||
@@ -28,6 +28,7 @@ import {generateInEditor, tocExistsInEditor} from 'browser/lib/markdown-toc-gene
|
|||||||
import markdownlint from 'markdownlint'
|
import markdownlint from 'markdownlint'
|
||||||
import Jsonlint from 'jsonlint-mod'
|
import Jsonlint from 'jsonlint-mod'
|
||||||
import { DEFAULT_CONFIG } from '../main/lib/ConfigManager'
|
import { DEFAULT_CONFIG } from '../main/lib/ConfigManager'
|
||||||
|
import prettier from 'prettier'
|
||||||
|
|
||||||
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
||||||
|
|
||||||
@@ -106,7 +107,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
const component = this
|
const component = this
|
||||||
|
|
||||||
if (component.searchState) cm.removeOverlay(component.searchState)
|
if (component.searchState) cm.removeOverlay(component.searchState)
|
||||||
if (msg.length < 3) return
|
if (msg.length < 1) return
|
||||||
|
|
||||||
cm.operation(function () {
|
cm.operation(function () {
|
||||||
component.searchState = makeOverlay(msg, 'searching')
|
component.searchState = makeOverlay(msg, 'searching')
|
||||||
@@ -216,6 +217,28 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
return CodeMirror.Pass
|
return CodeMirror.Pass
|
||||||
},
|
},
|
||||||
|
[translateHotkey(hotkey.prettifyMarkdown)]: cm => {
|
||||||
|
// Default / User configured prettier options
|
||||||
|
const currentConfig = JSON.parse(self.props.prettierConfig)
|
||||||
|
|
||||||
|
// Parser type will always need to be markdown so we override the option before use
|
||||||
|
currentConfig.parser = 'markdown'
|
||||||
|
|
||||||
|
// Get current cursor position
|
||||||
|
const cursorPos = cm.getCursor()
|
||||||
|
currentConfig.cursorOffset = cm.doc.indexFromPos(cursorPos)
|
||||||
|
|
||||||
|
// Prettify contents of editor
|
||||||
|
const formattedTextDetails = prettier.formatWithCursor(cm.doc.getValue(), currentConfig)
|
||||||
|
|
||||||
|
const formattedText = formattedTextDetails.formatted
|
||||||
|
const formattedCursorPos = formattedTextDetails.cursorOffset
|
||||||
|
cm.doc.setValue(formattedText)
|
||||||
|
|
||||||
|
// Reset Cursor position to be at the same markdown as was before prettifying
|
||||||
|
const newCursorPos = cm.doc.posFromIndex(formattedCursorPos)
|
||||||
|
cm.doc.setCursor(newCursorPos)
|
||||||
|
},
|
||||||
[translateHotkey(hotkey.pasteSmartly)]: cm => {
|
[translateHotkey(hotkey.pasteSmartly)]: cm => {
|
||||||
this.handlePaste(cm, true)
|
this.handlePaste(cm, true)
|
||||||
}
|
}
|
||||||
@@ -251,7 +274,7 @@ export default class CodeEditor extends React.Component {
|
|||||||
value: this.props.value,
|
value: this.props.value,
|
||||||
linesHighlighted: this.props.linesHighlighted,
|
linesHighlighted: this.props.linesHighlighted,
|
||||||
lineNumbers: this.props.displayLineNumbers,
|
lineNumbers: this.props.displayLineNumbers,
|
||||||
lineWrapping: true,
|
lineWrapping: this.props.lineWrapping,
|
||||||
theme: this.props.theme,
|
theme: this.props.theme,
|
||||||
indentUnit: this.props.indentSize,
|
indentUnit: this.props.indentSize,
|
||||||
tabSize: this.props.indentSize,
|
tabSize: this.props.indentSize,
|
||||||
@@ -269,7 +292,8 @@ export default class CodeEditor extends React.Component {
|
|||||||
explode: this.props.explodingPairs,
|
explode: this.props.explodingPairs,
|
||||||
override: true
|
override: true
|
||||||
},
|
},
|
||||||
extraKeys: this.defaultKeyMap
|
extraKeys: this.defaultKeyMap,
|
||||||
|
prettierConfig: this.props.prettierConfig
|
||||||
})
|
})
|
||||||
|
|
||||||
document.querySelector('.CodeMirror-lint-markers').style.display = enableMarkdownLint ? 'inline-block' : 'none'
|
document.querySelector('.CodeMirror-lint-markers').style.display = enableMarkdownLint ? 'inline-block' : 'none'
|
||||||
@@ -550,6 +574,10 @@ export default class CodeEditor extends React.Component {
|
|||||||
this.editor.setOption('lineNumbers', this.props.displayLineNumbers)
|
this.editor.setOption('lineNumbers', this.props.displayLineNumbers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (prevProps.lineWrapping !== this.props.lineWrapping) {
|
||||||
|
this.editor.setOption('lineWrapping', this.props.lineWrapping)
|
||||||
|
}
|
||||||
|
|
||||||
if (prevProps.scrollPastEnd !== this.props.scrollPastEnd) {
|
if (prevProps.scrollPastEnd !== this.props.scrollPastEnd) {
|
||||||
this.editor.setOption('scrollPastEnd', this.props.scrollPastEnd)
|
this.editor.setOption('scrollPastEnd', this.props.scrollPastEnd)
|
||||||
}
|
}
|
||||||
@@ -832,6 +860,17 @@ export default class CodeEditor extends React.Component {
|
|||||||
this.editor.setCursor(cursor)
|
this.editor.setCursor(cursor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update content of one line
|
||||||
|
* @param {Number} lineNumber
|
||||||
|
* @param {String} content
|
||||||
|
*/
|
||||||
|
setLineContent (lineNumber, content) {
|
||||||
|
const prevContent = this.editor.getLine(lineNumber)
|
||||||
|
const prevContentLength = prevContent ? prevContent.length : 0
|
||||||
|
this.editor.replaceRange(content, { line: lineNumber, ch: 0 }, { line: lineNumber, ch: prevContentLength })
|
||||||
|
}
|
||||||
|
|
||||||
handleDropImage (dropEvent) {
|
handleDropImage (dropEvent) {
|
||||||
dropEvent.preventDefault()
|
dropEvent.preventDefault()
|
||||||
const {
|
const {
|
||||||
@@ -1179,5 +1218,6 @@ CodeEditor.defaultProps = {
|
|||||||
autoDetect: false,
|
autoDetect: false,
|
||||||
spellCheck: false,
|
spellCheck: false,
|
||||||
enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint,
|
enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint,
|
||||||
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig
|
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig,
|
||||||
|
prettierConfig: DEFAULT_CONFIG.editor.prettierConfig
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -169,14 +169,15 @@ class MarkdownEditor extends React.Component {
|
|||||||
.split('\n')
|
.split('\n')
|
||||||
|
|
||||||
const targetLine = lines[lineIndex]
|
const targetLine = lines[lineIndex]
|
||||||
|
let newLine = targetLine
|
||||||
|
|
||||||
if (targetLine.match(checkedMatch)) {
|
if (targetLine.match(checkedMatch)) {
|
||||||
lines[lineIndex] = targetLine.replace(checkReplace, '[ ]')
|
newLine = targetLine.replace(checkReplace, '[ ]')
|
||||||
}
|
}
|
||||||
if (targetLine.match(uncheckedMatch)) {
|
if (targetLine.match(uncheckedMatch)) {
|
||||||
lines[lineIndex] = targetLine.replace(uncheckReplace, '[x]')
|
newLine = targetLine.replace(uncheckReplace, '[x]')
|
||||||
}
|
}
|
||||||
this.refs.code.setValue(lines.join('\n'))
|
this.refs.code.setLineContent(lineIndex, newLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,6 +305,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
enableRulers={config.editor.enableRulers}
|
enableRulers={config.editor.enableRulers}
|
||||||
rulers={config.editor.rulers}
|
rulers={config.editor.rulers}
|
||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
|
lineWrapping
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
@@ -321,6 +323,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
switchPreview={config.editor.switchPreview}
|
switchPreview={config.editor.switchPreview}
|
||||||
enableMarkdownLint={config.editor.enableMarkdownLint}
|
enableMarkdownLint={config.editor.enableMarkdownLint}
|
||||||
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
|
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
|
||||||
|
prettierConfig={config.editor.prettierConfig}
|
||||||
/>
|
/>
|
||||||
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
|
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
|
||||||
? 'preview'
|
? 'preview'
|
||||||
@@ -340,6 +343,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
smartArrows={config.preview.smartArrows}
|
smartArrows={config.preview.smartArrows}
|
||||||
breaks={config.preview.breaks}
|
breaks={config.preview.breaks}
|
||||||
sanitize={config.preview.sanitize}
|
sanitize={config.preview.sanitize}
|
||||||
|
mermaidHTMLLabel={config.preview.mermaidHTMLLabel}
|
||||||
ref='preview'
|
ref='preview'
|
||||||
onContextMenu={(e) => this.handleContextMenu(e)}
|
onContextMenu={(e) => this.handleContextMenu(e)}
|
||||||
onDoubleClick={(e) => this.handleDoubleClick(e)}
|
onDoubleClick={(e) => this.handleDoubleClick(e)}
|
||||||
|
|||||||
@@ -18,15 +18,13 @@ import mdurl from 'mdurl'
|
|||||||
import exportNote from 'browser/main/lib/dataApi/exportNote'
|
import exportNote from 'browser/main/lib/dataApi/exportNote'
|
||||||
import { escapeHtmlCharacters } from 'browser/lib/utils'
|
import { escapeHtmlCharacters } from 'browser/lib/utils'
|
||||||
import yaml from 'js-yaml'
|
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 { render } from 'react-dom'
|
||||||
import Carousel from 'react-image-carousel'
|
import Carousel from 'react-image-carousel'
|
||||||
import ConfigManager from '../main/lib/ConfigManager'
|
import ConfigManager from '../main/lib/ConfigManager'
|
||||||
|
|
||||||
const { remote, shell } = require('electron')
|
const { remote, shell } = require('electron')
|
||||||
const attachmentManagement = require('../main/lib/dataApi/attachmentManagement')
|
const attachmentManagement = require('../main/lib/dataApi/attachmentManagement')
|
||||||
|
const buildMarkdownPreviewContextMenu = require('browser/lib/contextMenuBuilder').buildMarkdownPreviewContextMenu
|
||||||
|
|
||||||
const { app } = remote
|
const { app } = remote
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
@@ -34,8 +32,6 @@ const fileUrl = require('file-url')
|
|||||||
|
|
||||||
const dialog = remote.dialog
|
const dialog = remote.dialog
|
||||||
|
|
||||||
const uri2path = require('file-uri-to-path')
|
|
||||||
|
|
||||||
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
||||||
const appPath = fileUrl(
|
const appPath = fileUrl(
|
||||||
process.env.NODE_ENV === 'production' ? app.getAppPath() : path.resolve()
|
process.env.NODE_ENV === 'production' ? app.getAppPath() : path.resolve()
|
||||||
@@ -45,7 +41,6 @@ const CSS_FILES = [
|
|||||||
`${appPath}/node_modules/codemirror/lib/codemirror.css`,
|
`${appPath}/node_modules/codemirror/lib/codemirror.css`,
|
||||||
`${appPath}/node_modules/react-image-carousel/lib/css/main.min.css`
|
`${appPath}/node_modules/react-image-carousel/lib/css/main.min.css`
|
||||||
]
|
]
|
||||||
const win = global.process.platform === 'win32'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} opts
|
* @param {Object} opts
|
||||||
@@ -267,30 +262,12 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleContextMenu (event) {
|
handleContextMenu (event) {
|
||||||
// If a contextMenu handler was passed to us, use it instead of the self-defined one -> return
|
const menu = buildMarkdownPreviewContextMenu(this, event)
|
||||||
if (_.isFunction(this.props.onContextMenu)) {
|
const switchPreview = ConfigManager.get().editor.switchPreview
|
||||||
|
if (menu != null && switchPreview !== 'RIGHTCLICK') {
|
||||||
|
menu.popup(remote.getCurrentWindow())
|
||||||
|
} else if (_.isFunction(this.props.onContextMenu)) {
|
||||||
this.props.onContextMenu(event)
|
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -367,7 +344,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
body,
|
body,
|
||||||
this.props.storagePath
|
this.props.storagePath
|
||||||
)
|
)
|
||||||
const files = [this.GetCodeThemeLink(codeBlockTheme), ...CSS_FILES]
|
const files = [this.getCodeThemeLink(codeBlockTheme), ...CSS_FILES]
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
if (global.process.platform === 'win32') {
|
if (global.process.platform === 'win32') {
|
||||||
file = file.replace('file:///', '')
|
file = file.replace('file:///', '')
|
||||||
@@ -403,7 +380,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
|
|
||||||
handleSaveAsPdf () {
|
handleSaveAsPdf () {
|
||||||
this.exportAsDocument('pdf', (noteContent, exportTasks, targetDir) => {
|
this.exportAsDocument('pdf', (noteContent, exportTasks, targetDir) => {
|
||||||
const printout = new remote.BrowserWindow({show: false, webPreferences: {webSecurity: false}})
|
const printout = new remote.BrowserWindow({show: false, webPreferences: {webSecurity: false, javascript: false}})
|
||||||
printout.loadURL('data:text/html;charset=UTF-8,' + this.htmlContentFormatter(noteContent, exportTasks, targetDir))
|
printout.loadURL('data:text/html;charset=UTF-8,' + this.htmlContentFormatter(noteContent, exportTasks, targetDir))
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
printout.webContents.on('did-finish-load', () => {
|
printout.webContents.on('did-finish-load', () => {
|
||||||
@@ -598,16 +575,19 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate (prevProps) {
|
componentDidUpdate (prevProps) {
|
||||||
if (prevProps.value !== this.props.value) this.rewriteIframe()
|
// actual rewriteIframe function should be called only once
|
||||||
|
let needsRewriteIframe = false
|
||||||
|
if (prevProps.value !== this.props.value) needsRewriteIframe = true
|
||||||
if (
|
if (
|
||||||
prevProps.smartQuotes !== this.props.smartQuotes ||
|
prevProps.smartQuotes !== this.props.smartQuotes ||
|
||||||
prevProps.sanitize !== this.props.sanitize ||
|
prevProps.sanitize !== this.props.sanitize ||
|
||||||
|
prevProps.mermaidHTMLLabel !== this.props.mermaidHTMLLabel ||
|
||||||
prevProps.smartArrows !== this.props.smartArrows ||
|
prevProps.smartArrows !== this.props.smartArrows ||
|
||||||
prevProps.breaks !== this.props.breaks ||
|
prevProps.breaks !== this.props.breaks ||
|
||||||
prevProps.lineThroughCheckbox !== this.props.lineThroughCheckbox
|
prevProps.lineThroughCheckbox !== this.props.lineThroughCheckbox
|
||||||
) {
|
) {
|
||||||
this.initMarkdown()
|
this.initMarkdown()
|
||||||
this.rewriteIframe()
|
needsRewriteIframe = true
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
prevProps.fontFamily !== this.props.fontFamily ||
|
prevProps.fontFamily !== this.props.fontFamily ||
|
||||||
@@ -622,8 +602,17 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
prevProps.customCSS !== this.props.customCSS
|
prevProps.customCSS !== this.props.customCSS
|
||||||
) {
|
) {
|
||||||
this.applyStyle()
|
this.applyStyle()
|
||||||
|
needsRewriteIframe = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (needsRewriteIframe) {
|
||||||
this.rewriteIframe()
|
this.rewriteIframe()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Should scroll to top after selecting another note
|
||||||
|
if (prevProps.noteKey !== this.props.noteKey) {
|
||||||
|
this.getWindow().scrollTo(0, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getStyleParams () {
|
getStyleParams () {
|
||||||
@@ -679,8 +668,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
|
|
||||||
this.getWindow().document.getElementById(
|
this.getWindow().document.getElementById(
|
||||||
'codeTheme'
|
'codeTheme'
|
||||||
).href = this.GetCodeThemeLink(codeBlockTheme)
|
).href = this.getCodeThemeLink(codeBlockTheme)
|
||||||
|
|
||||||
this.getWindow().document.getElementById('style').innerHTML = buildStyle({
|
this.getWindow().document.getElementById('style').innerHTML = buildStyle({
|
||||||
fontFamily,
|
fontFamily,
|
||||||
fontSize,
|
fontSize,
|
||||||
@@ -695,11 +683,11 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.getWindow().document.documentElement.style.overflowY = 'hidden'
|
this.getWindow().document.documentElement.style.overflowY = 'hidden'
|
||||||
}
|
}
|
||||||
|
|
||||||
GetCodeThemeLink (name) {
|
getCodeThemeLink (name) {
|
||||||
const theme = consts.THEMES.find(theme => theme.name === name)
|
const theme = consts.THEMES.find(theme => theme.name === name)
|
||||||
|
|
||||||
return theme
|
return theme != null
|
||||||
? (win ? theme.path : `${appPath}/${theme.path}`)
|
? theme.path
|
||||||
: `${appPath}/node_modules/codemirror/theme/elegant.css`
|
: `${appPath}/node_modules/codemirror/theme/elegant.css`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -726,7 +714,8 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
showCopyNotification,
|
showCopyNotification,
|
||||||
storagePath,
|
storagePath,
|
||||||
noteKey,
|
noteKey,
|
||||||
sanitize
|
sanitize,
|
||||||
|
mermaidHTMLLabel
|
||||||
} = this.props
|
} = this.props
|
||||||
let { value, codeBlockTheme } = this.props
|
let { value, codeBlockTheme } = this.props
|
||||||
|
|
||||||
@@ -858,6 +847,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
canvas.height = height.value + 'vh'
|
canvas.height = height.value + 'vh'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
const chart = new Chart(canvas, chartConfig)
|
const chart = new Chart(canvas, chartConfig)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
el.className = 'chart-error'
|
el.className = 'chart-error'
|
||||||
@@ -868,7 +858,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
_.forEach(
|
_.forEach(
|
||||||
this.refs.root.contentWindow.document.querySelectorAll('.mermaid'),
|
this.refs.root.contentWindow.document.querySelectorAll('.mermaid'),
|
||||||
el => {
|
el => {
|
||||||
mermaidRender(el, htmlTextHelper.decodeEntities(el.innerHTML), theme)
|
mermaidRender(el, htmlTextHelper.decodeEntities(el.innerHTML), theme, mermaidHTMLLabel)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -996,8 +986,6 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
overlay.appendChild(zoomImg)
|
overlay.appendChild(zoomImg)
|
||||||
document.body.appendChild(overlay)
|
document.body.appendChild(overlay)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getWindow().scrollTo(0, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
focus () {
|
focus () {
|
||||||
|
|||||||
@@ -88,14 +88,15 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
.split('\n')
|
.split('\n')
|
||||||
|
|
||||||
const targetLine = lines[lineIndex]
|
const targetLine = lines[lineIndex]
|
||||||
|
let newLine = targetLine
|
||||||
|
|
||||||
if (targetLine.match(checkedMatch)) {
|
if (targetLine.match(checkedMatch)) {
|
||||||
lines[lineIndex] = targetLine.replace(checkReplace, '[ ]')
|
newLine = targetLine.replace(checkReplace, '[ ]')
|
||||||
}
|
}
|
||||||
if (targetLine.match(uncheckedMatch)) {
|
if (targetLine.match(uncheckedMatch)) {
|
||||||
lines[lineIndex] = targetLine.replace(uncheckReplace, '[x]')
|
newLine = targetLine.replace(uncheckReplace, '[x]')
|
||||||
}
|
}
|
||||||
this.refs.code.setValue(lines.join('\n'))
|
this.refs.code.setLineContent(lineIndex, newLine)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +151,6 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
onMouseMove={e => this.handleMouseMove(e)}
|
onMouseMove={e => this.handleMouseMove(e)}
|
||||||
onMouseUp={e => this.handleMouseUp(e)}>
|
onMouseUp={e => this.handleMouseUp(e)}>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
styleName='codeEditor'
|
|
||||||
ref='code'
|
ref='code'
|
||||||
width={this.state.codeEditorWidthInPercent + '%'}
|
width={this.state.codeEditorWidthInPercent + '%'}
|
||||||
mode='Boost Flavored Markdown'
|
mode='Boost Flavored Markdown'
|
||||||
@@ -160,6 +160,7 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
fontFamily={config.editor.fontFamily}
|
fontFamily={config.editor.fontFamily}
|
||||||
fontSize={editorFontSize}
|
fontSize={editorFontSize}
|
||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
|
lineWrapping
|
||||||
matchingPairs={config.editor.matchingPairs}
|
matchingPairs={config.editor.matchingPairs}
|
||||||
matchingTriples={config.editor.matchingTriples}
|
matchingTriples={config.editor.matchingTriples}
|
||||||
explodingPairs={config.editor.explodingPairs}
|
explodingPairs={config.editor.explodingPairs}
|
||||||
@@ -187,7 +188,6 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
<MarkdownPreview
|
<MarkdownPreview
|
||||||
style={previewStyle}
|
style={previewStyle}
|
||||||
styleName='preview'
|
|
||||||
theme={config.ui.theme}
|
theme={config.ui.theme}
|
||||||
keyMap={config.editor.keyMap}
|
keyMap={config.editor.keyMap}
|
||||||
fontSize={config.preview.fontSize}
|
fontSize={config.preview.fontSize}
|
||||||
@@ -200,6 +200,7 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
smartArrows={config.preview.smartArrows}
|
smartArrows={config.preview.smartArrows}
|
||||||
breaks={config.preview.breaks}
|
breaks={config.preview.breaks}
|
||||||
sanitize={config.preview.sanitize}
|
sanitize={config.preview.sanitize}
|
||||||
|
mermaidHTMLLabel={config.preview.mermaidHTMLLabel}
|
||||||
ref='preview'
|
ref='preview'
|
||||||
tabInde='0'
|
tabInde='0'
|
||||||
value={value}
|
value={value}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const ModalEscButton = ({
|
|||||||
}) => (
|
}) => (
|
||||||
<button styleName='escButton' onClick={handleEscButtonClick}>
|
<button styleName='escButton' onClick={handleEscButtonClick}>
|
||||||
<div styleName='esc-mark'>×</div>
|
<div styleName='esc-mark'>×</div>
|
||||||
<div styleName='esc-text'>esc</div>
|
<div>esc</div>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { isArray } from 'lodash'
|
import { isArray, sortBy } from 'lodash'
|
||||||
import invertColor from 'invert-color'
|
import invertColor from 'invert-color'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
import { getTodoStatus } from 'browser/lib/getTodoStatus'
|
import { getTodoStatus } from 'browser/lib/getTodoStatus'
|
||||||
@@ -43,7 +43,7 @@ const TagElementList = (tags, showTagsAlphabetically, coloredTags) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (showTagsAlphabetically) {
|
if (showTagsAlphabetically) {
|
||||||
return _.sortBy(tags).map(tag => TagElement({ tagName: tag, color: coloredTags[tag] }))
|
return sortBy(tags).map(tag => TagElement({ tagName: tag, color: coloredTags[tag] }))
|
||||||
} else {
|
} else {
|
||||||
return tags.map(tag => TagElement({ tagName: tag, color: coloredTags[tag] }))
|
return tags.map(tag => TagElement({ tagName: tag, color: coloredTags[tag] }))
|
||||||
}
|
}
|
||||||
@@ -148,15 +148,14 @@ NoteItem.propTypes = {
|
|||||||
tags: PropTypes.array,
|
tags: PropTypes.array,
|
||||||
isStarred: PropTypes.bool.isRequired,
|
isStarred: PropTypes.bool.isRequired,
|
||||||
isTrashed: PropTypes.bool.isRequired,
|
isTrashed: PropTypes.bool.isRequired,
|
||||||
blog: {
|
blog: PropTypes.shape({
|
||||||
blogLink: PropTypes.string,
|
blogLink: PropTypes.string,
|
||||||
blogId: PropTypes.number
|
blogId: PropTypes.number
|
||||||
}
|
})
|
||||||
}),
|
}),
|
||||||
handleNoteClick: PropTypes.func.isRequired,
|
handleNoteClick: PropTypes.func.isRequired,
|
||||||
handleNoteContextMenu: PropTypes.func.isRequired,
|
handleNoteContextMenu: PropTypes.func.isRequired,
|
||||||
handleDragStart: PropTypes.func.isRequired,
|
handleDragStart: PropTypes.func.isRequired
|
||||||
handleDragEnd: PropTypes.func.isRequired
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(NoteItem, styles)
|
export default CSSModules(NoteItem, styles)
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ SideNavFilter.propTypes = {
|
|||||||
isStarredActive: PropTypes.bool.isRequired,
|
isStarredActive: PropTypes.bool.isRequired,
|
||||||
isTrashedActive: PropTypes.bool.isRequired,
|
isTrashedActive: PropTypes.bool.isRequired,
|
||||||
handleStarredButtonClick: PropTypes.func.isRequired,
|
handleStarredButtonClick: PropTypes.func.isRequired,
|
||||||
handleTrashdButtonClick: PropTypes.func.isRequired
|
handleTrashedButtonClick: PropTypes.func.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(SideNavFilter, styles)
|
export default CSSModules(SideNavFilter, styles)
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ class SnippetTab extends React.Component {
|
|||||||
>
|
>
|
||||||
{snippet.name.trim().length > 0
|
{snippet.name.trim().length > 0
|
||||||
? snippet.name
|
? snippet.name
|
||||||
: <span styleName='button-unnamed'>
|
: <span>
|
||||||
{i18n.__('Unnamed')}
|
{i18n.__('Unnamed')}
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ const TodoProcess = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
TodoProcess.propTypes = {
|
TodoProcess.propTypes = {
|
||||||
todoStatus: {
|
todoStatus: PropTypes.exact({
|
||||||
total: PropTypes.number.isRequired,
|
total: PropTypes.number.isRequired,
|
||||||
completed: PropTypes.number.isRequired
|
completed: PropTypes.number.isRequired
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(TodoProcess, styles)
|
export default CSSModules(TodoProcess, styles)
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ function getId () {
|
|||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
function render (element, content, theme) {
|
function render (element, content, theme, enableHTMLLabel) {
|
||||||
try {
|
try {
|
||||||
const height = element.attributes.getNamedItem('data-height')
|
const height = element.attributes.getNamedItem('data-height')
|
||||||
if (height && height.value !== 'undefined') {
|
if (height && height.value !== 'undefined') {
|
||||||
@@ -29,7 +29,8 @@ function render (element, content, theme) {
|
|||||||
mermaidAPI.initialize({
|
mermaidAPI.initialize({
|
||||||
theme: isDarkTheme ? 'dark' : 'default',
|
theme: isDarkTheme ? 'dark' : 'default',
|
||||||
themeCSS: isDarkTheme ? darkThemeStyling : '',
|
themeCSS: isDarkTheme ? darkThemeStyling : '',
|
||||||
useMaxWidth: false
|
useMaxWidth: false,
|
||||||
|
flowchart: { htmlLabels: enableHTMLLabel }
|
||||||
})
|
})
|
||||||
mermaidAPI.render(getId(), content, (svgGraph) => {
|
mermaidAPI.render(getId(), content, (svgGraph) => {
|
||||||
element.innerHTML = svgGraph
|
element.innerHTML = svgGraph
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const themes = paths
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
name,
|
name,
|
||||||
path: path.join(directory.split(/\//g).slice(-3).join('/'), file),
|
path: path.join(directory, file),
|
||||||
className: `cm-s-${name}`
|
className: `cm-s-${name}`
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@@ -28,17 +28,16 @@ const themes = paths
|
|||||||
|
|
||||||
themes.splice(themes.findIndex(({ name }) => name === 'solarized'), 1, {
|
themes.splice(themes.findIndex(({ name }) => name === 'solarized'), 1, {
|
||||||
name: 'solarized dark',
|
name: 'solarized dark',
|
||||||
path: `${CODEMIRROR_THEME_PATH}/solarized.css`,
|
path: path.join(paths[0], 'solarized.css'),
|
||||||
className: `cm-s-solarized cm-s-dark`
|
className: `cm-s-solarized cm-s-dark`
|
||||||
}, {
|
}, {
|
||||||
name: 'solarized light',
|
name: 'solarized light',
|
||||||
path: `${CODEMIRROR_THEME_PATH}/solarized.css`,
|
path: path.join(paths[0], 'solarized.css'),
|
||||||
className: `cm-s-solarized cm-s-light`
|
className: `cm-s-solarized cm-s-light`
|
||||||
})
|
})
|
||||||
|
|
||||||
themes.splice(0, 0, {
|
themes.splice(0, 0, {
|
||||||
name: 'default',
|
name: 'default',
|
||||||
path: `${CODEMIRROR_THEME_PATH}/elegant.css`,
|
path: path.join(paths[0], 'elegant.css'),
|
||||||
className: `cm-s-default`
|
className: `cm-s-default`
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import i18n from 'browser/lib/i18n'
|
||||||
|
import fs from 'fs'
|
||||||
|
|
||||||
const {remote} = require('electron')
|
const {remote} = require('electron')
|
||||||
const {Menu} = remote.require('electron')
|
const {Menu} = remote.require('electron')
|
||||||
|
const {clipboard} = remote.require('electron')
|
||||||
|
const {shell} = remote.require('electron')
|
||||||
const spellcheck = require('./spellcheck')
|
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.
|
* Creates the context menu that is shown when there is a right click in the editor of a (not-snippet) note.
|
||||||
@@ -62,4 +68,57 @@ const buildEditorContextMenu = function (editor, event) {
|
|||||||
return Menu.buildFromTemplate(template)
|
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: 'copy'
|
||||||
|
}, {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import CodeMirror from 'codemirror'
|
import CodeMirror from 'codemirror'
|
||||||
import 'codemirror-mode-elixir'
|
import 'codemirror-mode-elixir'
|
||||||
|
|
||||||
CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl'], alias: ['styl']})
|
const stylusCodeInfo = CodeMirror.modeInfo.find(info => info.name === 'Stylus')
|
||||||
|
if (stylusCodeInfo == null) {
|
||||||
|
CodeMirror.modeInfo.push({name: 'Stylus', mime: 'text/x-styl', mode: 'stylus', ext: ['styl'], alias: ['styl']})
|
||||||
|
} else {
|
||||||
|
stylusCodeInfo.alias = ['styl']
|
||||||
|
}
|
||||||
CodeMirror.modeInfo.push({name: 'Elixir', mime: 'text/x-elixir', mode: 'elixir', ext: ['ex']})
|
CodeMirror.modeInfo.push({name: 'Elixir', mime: 'text/x-elixir', mode: 'elixir', ext: ['ex']})
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
const _ = require('lodash')
|
|
||||||
const uuidv4 = require('uuid/v4')
|
const uuidv4 = require('uuid/v4')
|
||||||
|
|
||||||
module.exports = function (uuid) {
|
module.exports = function (uuid) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ module.exports = function sanitizePlugin (md, options) {
|
|||||||
options
|
options
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (state.tokens[tokenIdx].type === '_fence') {
|
if (state.tokens[tokenIdx].type.match(/.*_fence$/)) {
|
||||||
// escapeHtmlCharacters has better performance
|
// escapeHtmlCharacters has better performance
|
||||||
state.tokens[tokenIdx].content = escapeHtmlCharacters(
|
state.tokens[tokenIdx].content = escapeHtmlCharacters(
|
||||||
state.tokens[tokenIdx].content,
|
state.tokens[tokenIdx].content,
|
||||||
@@ -96,6 +96,10 @@ function sanitizeInline (html, options) {
|
|||||||
|
|
||||||
function naughtyHRef (href, options) {
|
function naughtyHRef (href, options) {
|
||||||
// href = href.replace(/[\x00-\x20]+/g, '')
|
// href = href.replace(/[\x00-\x20]+/g, '')
|
||||||
|
if (!href) {
|
||||||
|
// No href
|
||||||
|
return false
|
||||||
|
}
|
||||||
href = href.replace(/<\!\-\-.*?\-\-\>/g, '')
|
href = href.replace(/<\!\-\-.*?\-\-\>/g, '')
|
||||||
|
|
||||||
const matches = href.match(/^([a-zA-Z]+)\:/)
|
const matches = href.match(/^([a-zA-Z]+)\:/)
|
||||||
|
|||||||
@@ -289,7 +289,9 @@ class Markdown {
|
|||||||
case 'list_item_open':
|
case 'list_item_open':
|
||||||
case 'paragraph_open':
|
case 'paragraph_open':
|
||||||
case 'table_open':
|
case 'table_open':
|
||||||
token.attrPush(['data-line', token.map[0]])
|
if (token.map) {
|
||||||
|
token.attrPush(['data-line', token.map[0]])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const result = originalRender.call(this.md.renderer, tokens, options, env)
|
const result = originalRender.call(this.md.renderer, tokens, options, env)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const FullscreenButton = ({
|
|||||||
const hotkey = (OSX ? i18n.__('Command(⌘)') : i18n.__('Ctrl(^)')) + '+B'
|
const hotkey = (OSX ? i18n.__('Command(⌘)') : i18n.__('Ctrl(^)')) + '+B'
|
||||||
return (
|
return (
|
||||||
<button styleName='control-fullScreenButton' title={i18n.__('Fullscreen')} onMouseDown={(e) => onClick(e)}>
|
<button styleName='control-fullScreenButton' title={i18n.__('Fullscreen')} onMouseDown={(e) => onClick(e)}>
|
||||||
<img styleName='iconInfo' src='../resources/icon/icon-full.svg' />
|
<img src='../resources/icon/icon-full.svg' />
|
||||||
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Fullscreen')}({hotkey})</span>
|
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Fullscreen')}({hotkey})</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class InfoPanel extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<input styleName='infoPanel-noteLink' ref='noteLink' value={noteLink} onClick={(e) => { e.target.select() }} />
|
<input styleName='infoPanel-noteLink' ref='noteLink' defaultValue={noteLink} onClick={(e) => { e.target.select() }} />
|
||||||
<button onClick={() => this.copyNoteLink()} styleName='infoPanel-copyButton'>
|
<button onClick={() => this.copyNoteLink()} styleName='infoPanel-copyButton'>
|
||||||
<i className='fa fa-clipboard' />
|
<i className='fa fa-clipboard' />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleFolderChange (e) {
|
handleFolderChange (e) {
|
||||||
const { dispatch } = this.props
|
|
||||||
const { note } = this.state
|
const { note } = this.state
|
||||||
const value = this.refs.folder.value
|
const value = this.refs.folder.value
|
||||||
const splitted = value.split('-')
|
const splitted = value.split('-')
|
||||||
@@ -410,7 +409,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { data, location, config } = this.props
|
const { data, dispatch, location, config } = this.props
|
||||||
const { note, editorType } = this.state
|
const { note, editorType } = this.state
|
||||||
const storageKey = note.storage
|
const storageKey = note.storage
|
||||||
const folderKey = note.folder
|
const folderKey = note.folder
|
||||||
@@ -450,7 +449,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
|
|
||||||
const detailTopBar = <div styleName='info'>
|
const detailTopBar = <div styleName='info'>
|
||||||
<div styleName='info-left'>
|
<div styleName='info-left'>
|
||||||
<div styleName='info-left-top'>
|
<div>
|
||||||
<FolderSelect styleName='info-left-top-folderSelect'
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
value={this.state.note.storage + '-' + this.state.note.folder}
|
value={this.state.note.storage + '-' + this.state.note.folder}
|
||||||
ref='folder'
|
ref='folder'
|
||||||
@@ -465,6 +464,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
saveTagsAlphabetically={config.ui.saveTagsAlphabetically}
|
saveTagsAlphabetically={config.ui.saveTagsAlphabetically}
|
||||||
showTagsAlphabetically={config.ui.showTagsAlphabetically}
|
showTagsAlphabetically={config.ui.showTagsAlphabetically}
|
||||||
data={data}
|
data={data}
|
||||||
|
dispatch={dispatch}
|
||||||
onChange={this.handleUpdateTag.bind(this)}
|
onChange={this.handleUpdateTag.bind(this)}
|
||||||
coloredTags={config.coloredTags}
|
coloredTags={config.coloredTags}
|
||||||
/>
|
/>
|
||||||
@@ -484,7 +484,7 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
onFocus={(e) => this.handleFocus(e)}
|
onFocus={(e) => this.handleFocus(e)}
|
||||||
onMouseDown={(e) => this.handleLockButtonMouseDown(e)}
|
onMouseDown={(e) => this.handleLockButtonMouseDown(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconInfo' src={imgSrc} />
|
<img src={imgSrc} />
|
||||||
{this.state.isLocked ? <span styleName='tooltip'>Unlock</span> : <span styleName='tooltip'>Lock</span>}
|
{this.state.isLocked ? <span styleName='tooltip'>Unlock</span> : <span styleName='tooltip'>Lock</span>}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
|||||||
@@ -81,11 +81,4 @@ body[data-theme="dracula"]
|
|||||||
.root
|
.root
|
||||||
border-left 1px solid $ui-dracula-borderColor
|
border-left 1px solid $ui-dracula-borderColor
|
||||||
background-color $ui-dracula-noteDetail-backgroundColor
|
background-color $ui-dracula-noteDetail-backgroundColor
|
||||||
|
|
||||||
div
|
|
||||||
> button, div
|
|
||||||
-webkit-user-drag none
|
|
||||||
user-select none
|
|
||||||
> img, span
|
|
||||||
-webkit-user-drag none
|
|
||||||
user-select none
|
|
||||||
|
|||||||
@@ -107,4 +107,12 @@ body[data-theme="monokai"]
|
|||||||
body[data-theme="dracula"]
|
body[data-theme="dracula"]
|
||||||
.info
|
.info
|
||||||
border-color $ui-dracula-borderColor
|
border-color $ui-dracula-borderColor
|
||||||
background-color $ui-dracula-noteDetail-backgroundColor
|
background-color $ui-dracula-noteDetail-backgroundColor
|
||||||
|
|
||||||
|
.info > div
|
||||||
|
> button
|
||||||
|
-webkit-user-drag none
|
||||||
|
user-select none
|
||||||
|
> img, span
|
||||||
|
-webkit-user-drag none
|
||||||
|
user-select none
|
||||||
@@ -10,7 +10,7 @@ const PermanentDeleteButton = ({
|
|||||||
<button styleName='control-trashButton--in-trash'
|
<button styleName='control-trashButton--in-trash'
|
||||||
onClick={(e) => onClick(e)}
|
onClick={(e) => onClick(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
<img src='../resources/icon/icon-trash.svg' />
|
||||||
<span styleName='tooltip'>{i18n.__('Permanent Delete')}</span>
|
<span styleName='tooltip'>{i18n.__('Permanent Delete')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -518,6 +518,19 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleWrapLineButtonClick (e) {
|
||||||
|
context.popup([
|
||||||
|
{
|
||||||
|
label: 'on',
|
||||||
|
click: (e) => this.handleWrapLineItemClick(e, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'off',
|
||||||
|
click: (e) => this.handleWrapLineItemClick(e, false)
|
||||||
|
}
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
handleIndentSizeItemClick (e, indentSize) {
|
handleIndentSizeItemClick (e, indentSize) {
|
||||||
const { config, dispatch } = this.props
|
const { config, dispatch } = this.props
|
||||||
const editor = Object.assign({}, config.editor, {
|
const editor = Object.assign({}, config.editor, {
|
||||||
@@ -550,6 +563,22 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleWrapLineItemClick (e, lineWrapping) {
|
||||||
|
const { config, dispatch } = this.props
|
||||||
|
const editor = Object.assign({}, config.editor, {
|
||||||
|
lineWrapping
|
||||||
|
})
|
||||||
|
ConfigManager.set({
|
||||||
|
editor
|
||||||
|
})
|
||||||
|
dispatch({
|
||||||
|
type: 'SET_CONFIG',
|
||||||
|
config: {
|
||||||
|
editor
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
focus () {
|
focus () {
|
||||||
this.refs.description.focus()
|
this.refs.description.focus()
|
||||||
}
|
}
|
||||||
@@ -670,7 +699,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { data, config, location } = this.props
|
const { data, dispatch, config, location } = this.props
|
||||||
const { note } = this.state
|
const { note } = this.state
|
||||||
|
|
||||||
const storageKey = note.storage
|
const storageKey = note.storage
|
||||||
@@ -720,6 +749,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
mode={snippet.mode || (autoDetect ? null : config.editor.snippetDefaultLanguage)}
|
mode={snippet.mode || (autoDetect ? null : config.editor.snippetDefaultLanguage)}
|
||||||
value={snippet.content}
|
value={snippet.content}
|
||||||
linesHighlighted={snippet.linesHighlighted}
|
linesHighlighted={snippet.linesHighlighted}
|
||||||
|
lineWrapping={config.editor.lineWrapping}
|
||||||
theme={config.editor.theme}
|
theme={config.editor.theme}
|
||||||
fontFamily={config.editor.fontFamily}
|
fontFamily={config.editor.fontFamily}
|
||||||
fontSize={editorFontSize}
|
fontSize={editorFontSize}
|
||||||
@@ -778,7 +808,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
|
|
||||||
const detailTopBar = <div styleName='info'>
|
const detailTopBar = <div styleName='info'>
|
||||||
<div styleName='info-left'>
|
<div styleName='info-left'>
|
||||||
<div styleName='info-left-top'>
|
<div>
|
||||||
<FolderSelect styleName='info-left-top-folderSelect'
|
<FolderSelect styleName='info-left-top-folderSelect'
|
||||||
value={this.state.note.storage + '-' + this.state.note.folder}
|
value={this.state.note.storage + '-' + this.state.note.folder}
|
||||||
ref='folder'
|
ref='folder'
|
||||||
@@ -793,6 +823,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
saveTagsAlphabetically={config.ui.saveTagsAlphabetically}
|
saveTagsAlphabetically={config.ui.saveTagsAlphabetically}
|
||||||
showTagsAlphabetically={config.ui.showTagsAlphabetically}
|
showTagsAlphabetically={config.ui.showTagsAlphabetically}
|
||||||
data={data}
|
data={data}
|
||||||
|
dispatch={dispatch}
|
||||||
onChange={(e) => this.handleChange(e)}
|
onChange={(e) => this.handleChange(e)}
|
||||||
coloredTags={config.coloredTags}
|
coloredTags={config.coloredTags}
|
||||||
/>
|
/>
|
||||||
@@ -899,6 +930,12 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
size: {config.editor.indentSize}
|
size: {config.editor.indentSize}
|
||||||
<i className='fa fa-caret-down' />
|
<i className='fa fa-caret-down' />
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
onClick={(e) => this.handleWrapLineButtonClick(e)}
|
||||||
|
>
|
||||||
|
Wrap Line: {config.editor.lineWrapping ? 'on' : 'off'}
|
||||||
|
<i className='fa fa-caret-down' />
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StatusBar
|
<StatusBar
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
|
|||||||
import i18n from 'browser/lib/i18n'
|
import i18n from 'browser/lib/i18n'
|
||||||
import ee from 'browser/main/lib/eventEmitter'
|
import ee from 'browser/main/lib/eventEmitter'
|
||||||
import Autosuggest from 'react-autosuggest'
|
import Autosuggest from 'react-autosuggest'
|
||||||
|
import { push } from 'connected-react-router'
|
||||||
|
|
||||||
class TagSelect extends React.Component {
|
class TagSelect extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
@@ -96,8 +97,11 @@ class TagSelect extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleTagLabelClick (tag) {
|
handleTagLabelClick (tag) {
|
||||||
const { router } = this.context
|
const { dispatch } = this.props
|
||||||
router.push(`/tags/${tag}`)
|
|
||||||
|
// Note: `tag` requires encoding later.
|
||||||
|
// E.g. % in tag is a problem (see issue #3170) - encodeURIComponent(tag) is not working.
|
||||||
|
dispatch(push(`/tags/${tag}`))
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTagRemoveButtonClick (tag) {
|
handleTagRemoveButtonClick (tag) {
|
||||||
@@ -255,11 +259,8 @@ class TagSelect extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TagSelect.contextTypes = {
|
|
||||||
router: PropTypes.shape({})
|
|
||||||
}
|
|
||||||
|
|
||||||
TagSelect.propTypes = {
|
TagSelect.propTypes = {
|
||||||
|
dispatch: PropTypes.func,
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
value: PropTypes.arrayOf(PropTypes.string),
|
value: PropTypes.arrayOf(PropTypes.string),
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ const ToggleModeButton = ({
|
|||||||
onClick, editorType
|
onClick, editorType
|
||||||
}) => (
|
}) => (
|
||||||
<div styleName='control-toggleModeButton'>
|
<div styleName='control-toggleModeButton'>
|
||||||
<div styleName={editorType === 'SPLIT' ? 'active' : 'non-active'} onClick={() => onClick('SPLIT')}>
|
<div styleName={editorType === 'SPLIT' ? 'active' : undefined} onClick={() => onClick('SPLIT')}>
|
||||||
<img styleName='item-star' src={editorType === 'EDITOR_PREVIEW' ? '../resources/icon/icon-mode-markdown-off-active.svg' : ''} />
|
<img src={editorType === 'EDITOR_PREVIEW' ? '../resources/icon/icon-mode-markdown-off-active.svg' : ''} />
|
||||||
</div>
|
</div>
|
||||||
<div styleName={editorType === 'EDITOR_PREVIEW' ? 'active' : 'non-active'} onClick={() => onClick('EDITOR_PREVIEW')}>
|
<div styleName={editorType === 'EDITOR_PREVIEW' ? 'active' : undefined} onClick={() => onClick('EDITOR_PREVIEW')}>
|
||||||
<img styleName='item-star' src={editorType === 'EDITOR_PREVIEW' ? '' : '../resources/icon/icon-mode-split-on-active.svg'} />
|
<img src={editorType === 'EDITOR_PREVIEW' ? '' : '../resources/icon/icon-mode-split-on-active.svg'} />
|
||||||
</div>
|
</div>
|
||||||
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Toggle Mode')}</span>
|
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Toggle Mode')}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,7 +20,7 @@ const ToggleModeButton = ({
|
|||||||
|
|
||||||
ToggleModeButton.propTypes = {
|
ToggleModeButton.propTypes = {
|
||||||
onClick: PropTypes.func.isRequired,
|
onClick: PropTypes.func.isRequired,
|
||||||
editorType: PropTypes.string.Required
|
editorType: PropTypes.string.isRequired
|
||||||
}
|
}
|
||||||
|
|
||||||
export default CSSModules(ToggleModeButton, styles)
|
export default CSSModules(ToggleModeButton, styles)
|
||||||
|
|||||||
@@ -75,3 +75,10 @@ body[data-theme="dracula"]
|
|||||||
.active
|
.active
|
||||||
background-color #bd93f9
|
background-color #bd93f9
|
||||||
box-shadow 2px 0px 7px #222222
|
box-shadow 2px 0px 7px #222222
|
||||||
|
|
||||||
|
.control-toggleModeButton
|
||||||
|
-webkit-user-drag none
|
||||||
|
user-select none
|
||||||
|
> div img
|
||||||
|
-webkit-user-drag none
|
||||||
|
user-select none
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const TrashButton = ({
|
|||||||
<button styleName='control-trashButton'
|
<button styleName='control-trashButton'
|
||||||
onClick={(e) => onClick(e)}
|
onClick={(e) => onClick(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconInfo' src='../resources/icon/icon-trash.svg' />
|
<img src='../resources/icon/icon-trash.svg' />
|
||||||
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Trash')}</span>
|
<span lang={i18n.locale} styleName='tooltip'>{i18n.__('Trash')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class Main extends React.Component {
|
|||||||
{
|
{
|
||||||
name: 'example.js',
|
name: 'example.js',
|
||||||
mode: 'javascript',
|
mode: 'javascript',
|
||||||
content: "var boostnote = document.getElementById('enjoy').innerHTML\n\nconsole.log(boostnote)",
|
content: "var boostnote = document.getElementById('hello').innerHTML\n\nconsole.log(boostnote)",
|
||||||
linesHighlighted: []
|
linesHighlighted: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -169,6 +169,7 @@ class Main extends React.Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
delete CodeMirror.keyMap.emacs['Ctrl-V']
|
delete CodeMirror.keyMap.emacs['Ctrl-V']
|
||||||
|
|
||||||
eventEmitter.on('editor:fullscreen', this.toggleFullScreen)
|
eventEmitter.on('editor:fullscreen', this.toggleFullScreen)
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ class NewNoteButton extends React.Component {
|
|||||||
<div styleName='control'>
|
<div styleName='control'>
|
||||||
<button styleName='control-newNoteButton'
|
<button styleName='control-newNoteButton'
|
||||||
onClick={this.handleNewNoteButtonClick}>
|
onClick={this.handleNewNoteButtonClick}>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-newnote.svg' />
|
<img src='../resources/icon/icon-newnote.svg' />
|
||||||
<span styleName='control-newNoteButton-tooltip'>
|
<span styleName='control-newNoteButton-tooltip'>
|
||||||
{i18n.__('Make a note')} {OSX ? '⌘' : i18n.__('Ctrl')} + N
|
{i18n.__('Make a note')} {OSX ? '⌘' : i18n.__('Ctrl')} + N
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -1138,7 +1138,7 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
|
onClick={(e) => this.handleListStyleButtonClick(e, 'DEFAULT')}
|
||||||
>
|
>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-column.svg' />
|
<img src='../resources/icon/icon-column.svg' />
|
||||||
</button>
|
</button>
|
||||||
<button title={i18n.__('Compressed View')} styleName={config.listStyle === 'SMALL'
|
<button title={i18n.__('Compressed View')} styleName={config.listStyle === 'SMALL'
|
||||||
? 'control-button--active'
|
? 'control-button--active'
|
||||||
@@ -1146,7 +1146,7 @@ class NoteList extends React.Component {
|
|||||||
}
|
}
|
||||||
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
|
onClick={(e) => this.handleListStyleButtonClick(e, 'SMALL')}
|
||||||
>
|
>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-column-list.svg' />
|
<img src='../resources/icon/icon-column-list.svg' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const PreferenceButton = ({
|
|||||||
onClick
|
onClick
|
||||||
}) => (
|
}) => (
|
||||||
<button styleName='top-menu-preference' onClick={(e) => onClick(e)}>
|
<button styleName='top-menu-preference' onClick={(e) => onClick(e)}>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-setting.svg' />
|
<img src='../resources/icon/icon-setting.svg' />
|
||||||
<span styleName='tooltip'>{i18n.__('Preferences')}</span>
|
<span styleName='tooltip'>{i18n.__('Preferences')}</span>
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -362,14 +362,14 @@ class StorageItem extends React.Component {
|
|||||||
<button styleName='header-addFolderButton'
|
<button styleName='header-addFolderButton'
|
||||||
onClick={(e) => this.handleAddFolderButtonClick(e)}
|
onClick={(e) => this.handleAddFolderButtonClick(e)}
|
||||||
>
|
>
|
||||||
<img styleName='iconTag' src='../resources/icon/icon-plus.svg' />
|
<img src='../resources/icon/icon-plus.svg' />
|
||||||
</button>
|
</button>
|
||||||
}
|
}
|
||||||
|
|
||||||
<button styleName='header-info'
|
<button styleName='header-info'
|
||||||
onClick={(e) => this.handleHeaderInfoClick(e)}
|
onClick={(e) => this.handleHeaderInfoClick(e)}
|
||||||
>
|
>
|
||||||
<span styleName='header-info-name'>
|
<span>
|
||||||
{isFolded ? _.truncate(storage.name, {length: 1, omission: ''}) : storage.name}
|
{isFolded ? _.truncate(storage.name, {length: 1, omission: ''}) : storage.name}
|
||||||
</span>
|
</span>
|
||||||
{isFolded &&
|
{isFolded &&
|
||||||
@@ -380,7 +380,7 @@ class StorageItem extends React.Component {
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
{this.state.isOpen &&
|
{this.state.isOpen &&
|
||||||
<div styleName='folderList' >
|
<div>
|
||||||
{folderList}
|
{folderList}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ import context from 'browser/lib/context'
|
|||||||
import { remote } from 'electron'
|
import { remote } from 'electron'
|
||||||
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
|
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
|
||||||
import ColorPicker from 'browser/components/ColorPicker'
|
import ColorPicker from 'browser/components/ColorPicker'
|
||||||
|
import { every, sortBy } from 'lodash'
|
||||||
|
|
||||||
function matchActiveTags (tags, activeTags) {
|
function matchActiveTags (tags, activeTags) {
|
||||||
return _.every(activeTags, v => tags.indexOf(v) >= 0)
|
return every(activeTags, v => tags.indexOf(v) >= 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SideNav extends React.Component {
|
class SideNav extends React.Component {
|
||||||
@@ -283,7 +284,7 @@ class SideNav extends React.Component {
|
|||||||
const { colorPicker } = this.state
|
const { colorPicker } = this.state
|
||||||
const activeTags = this.getActiveTags(location.pathname)
|
const activeTags = this.getActiveTags(location.pathname)
|
||||||
const relatedTags = this.getRelatedTags(activeTags, data.noteMap)
|
const relatedTags = this.getRelatedTags(activeTags, data.noteMap)
|
||||||
let tagList = _.sortBy(data.tagNoteMap.map(
|
let tagList = sortBy(data.tagNoteMap.map(
|
||||||
(tag, name) => ({ name, size: tag.size, related: relatedTags.has(name) })
|
(tag, name) => ({ name, size: tag.size, related: relatedTags.has(name) })
|
||||||
).filter(
|
).filter(
|
||||||
tag => tag.size > 0
|
tag => tag.size > 0
|
||||||
@@ -296,7 +297,7 @@ class SideNav extends React.Component {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if (config.sortTagsBy === 'COUNTER') {
|
if (config.sortTagsBy === 'COUNTER') {
|
||||||
tagList = _.sortBy(tagList, item => (0 - item.size))
|
tagList = sortBy(tagList, item => (0 - item.size))
|
||||||
}
|
}
|
||||||
if (config.ui.showOnlyRelatedTags && (relatedTags.size > 0)) {
|
if (config.ui.showOnlyRelatedTags && (relatedTags.size > 0)) {
|
||||||
tagList = tagList.filter(
|
tagList = tagList.filter(
|
||||||
@@ -440,7 +441,7 @@ class SideNav extends React.Component {
|
|||||||
|
|
||||||
const style = {}
|
const style = {}
|
||||||
if (!isFolded) style.width = this.props.width
|
if (!isFolded) style.width = this.props.width
|
||||||
const isTagActive = location.pathname.match(/tag/)
|
const isTagActive = /tag/.test(location.pathname)
|
||||||
return (
|
return (
|
||||||
<div className='SideNav'
|
<div className='SideNav'
|
||||||
styleName={isFolded ? 'root--folded' : 'root'}
|
styleName={isFolded ? 'root--folded' : 'root'}
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ class TopBar extends React.Component {
|
|||||||
this.refs.search.childNodes[0].blur
|
this.refs.search.childNodes[0].blur
|
||||||
dispatch(push('/searched'))
|
dispatch(push('/searched'))
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
this.debouncedUpdateKeyword('')
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown (e) {
|
handleKeyDown (e) {
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M',
|
toggleMode: OSX ? 'Command + Alt + M' : 'Ctrl + M',
|
||||||
deleteNote: OSX ? 'Command + Shift + Backspace' : 'Ctrl + Shift + Backspace',
|
deleteNote: OSX ? 'Command + Shift + Backspace' : 'Ctrl + Shift + Backspace',
|
||||||
pasteSmartly: OSX ? 'Command + Shift + V' : 'Ctrl + Shift + V',
|
pasteSmartly: OSX ? 'Command + Shift + V' : 'Ctrl + Shift + V',
|
||||||
|
prettifyMarkdown: 'Shift + F',
|
||||||
insertDate: OSX ? 'Command + /' : 'Ctrl + /',
|
insertDate: OSX ? 'Command + /' : 'Ctrl + /',
|
||||||
insertDateTime: OSX ? 'Command + Alt + /' : 'Ctrl + Shift + /',
|
insertDateTime: OSX ? 'Command + Alt + /' : 'Ctrl + Shift + /',
|
||||||
toggleMenuBar: 'Alt'
|
toggleMenuBar: 'Alt'
|
||||||
@@ -50,6 +51,7 @@ export const DEFAULT_CONFIG = {
|
|||||||
fontFamily: win ? 'Consolas' : 'Monaco',
|
fontFamily: win ? 'Consolas' : 'Monaco',
|
||||||
indentType: 'space',
|
indentType: 'space',
|
||||||
indentSize: '2',
|
indentSize: '2',
|
||||||
|
lineWrapping: true,
|
||||||
enableRulers: false,
|
enableRulers: false,
|
||||||
rulers: [80, 120],
|
rulers: [80, 120],
|
||||||
displayLineNumbers: true,
|
displayLineNumbers: true,
|
||||||
@@ -67,7 +69,14 @@ export const DEFAULT_CONFIG = {
|
|||||||
spellcheck: false,
|
spellcheck: false,
|
||||||
enableSmartPaste: false,
|
enableSmartPaste: false,
|
||||||
enableMarkdownLint: false,
|
enableMarkdownLint: false,
|
||||||
customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG
|
customMarkdownLintConfig: DEFAULT_MARKDOWN_LINT_CONFIG,
|
||||||
|
prettierConfig: ` {
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true
|
||||||
|
}`
|
||||||
|
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
fontSize: '14',
|
fontSize: '14',
|
||||||
@@ -85,8 +94,10 @@ export const DEFAULT_CONFIG = {
|
|||||||
breaks: true,
|
breaks: true,
|
||||||
smartArrows: false,
|
smartArrows: false,
|
||||||
allowCustomCSS: false,
|
allowCustomCSS: false,
|
||||||
|
|
||||||
customCSS: '/* Drop Your Custom CSS Code Here */',
|
customCSS: '/* Drop Your Custom CSS Code Here */',
|
||||||
sanitize: 'STRICT', // 'STRICT', 'ALLOW_STYLES', 'NONE'
|
sanitize: 'STRICT', // 'STRICT', 'ALLOW_STYLES', 'NONE'
|
||||||
|
mermaidHTMLLabel: false,
|
||||||
lineThroughCheckbox: true
|
lineThroughCheckbox: true
|
||||||
},
|
},
|
||||||
blog: {
|
blog: {
|
||||||
@@ -142,7 +153,7 @@ function get () {
|
|||||||
const theme = consts.THEMES.find(theme => theme.name === config.editor.theme)
|
const theme = consts.THEMES.find(theme => theme.name === config.editor.theme)
|
||||||
|
|
||||||
if (theme) {
|
if (theme) {
|
||||||
editorTheme.setAttribute('href', win ? theme.path : `../${theme.path}`)
|
editorTheme.setAttribute('href', theme.path)
|
||||||
} else {
|
} else {
|
||||||
config.editor.theme = 'default'
|
config.editor.theme = 'default'
|
||||||
}
|
}
|
||||||
@@ -190,7 +201,7 @@ function set (updates) {
|
|||||||
const newTheme = consts.THEMES.find(theme => theme.name === newConfig.editor.theme)
|
const newTheme = consts.THEMES.find(theme => theme.name === newConfig.editor.theme)
|
||||||
|
|
||||||
if (newTheme) {
|
if (newTheme) {
|
||||||
editorTheme.setAttribute('href', win ? newTheme.path : `../${newTheme.path}`)
|
editorTheme.setAttribute('href', newTheme.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
ipcRenderer.send('config-renew', {
|
ipcRenderer.send('config-renew', {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const escapeStringRegexp = require('escape-string-regexp')
|
|||||||
const sander = require('sander')
|
const sander = require('sander')
|
||||||
const url = require('url')
|
const url = require('url')
|
||||||
import i18n from 'browser/lib/i18n'
|
import i18n from 'browser/lib/i18n'
|
||||||
|
import { isString } from 'lodash'
|
||||||
|
|
||||||
const STORAGE_FOLDER_PLACEHOLDER = ':storage'
|
const STORAGE_FOLDER_PLACEHOLDER = ':storage'
|
||||||
const DESTINATION_FOLDER = 'attachments'
|
const DESTINATION_FOLDER = 'attachments'
|
||||||
@@ -19,7 +20,7 @@ const PATH_SEPARATORS = escapeStringRegexp(path.posix.sep) + escapeStringRegexp(
|
|||||||
* @returns {Promise<Image>} Image element created
|
* @returns {Promise<Image>} Image element created
|
||||||
*/
|
*/
|
||||||
function getImage (file) {
|
function getImage (file) {
|
||||||
if (_.isString(file)) {
|
if (isString(file)) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const img = new Image()
|
const img = new Image()
|
||||||
img.onload = () => resolve(img)
|
img.onload = () => resolve(img)
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ const path = require('path')
|
|||||||
const resolveStorageData = require('./resolveStorageData')
|
const resolveStorageData = require('./resolveStorageData')
|
||||||
const resolveStorageNotes = require('./resolveStorageNotes')
|
const resolveStorageNotes = require('./resolveStorageNotes')
|
||||||
const CSON = require('@rokt33r/season')
|
const CSON = require('@rokt33r/season')
|
||||||
const sander = require('sander')
|
|
||||||
const { findStorage } = require('browser/lib/findStorage')
|
const { findStorage } = require('browser/lib/findStorage')
|
||||||
const deleteSingleNote = require('./deleteNote')
|
const deleteSingleNote = require('./deleteNote')
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function exportNote (nodeKey, storageKey, noteContent, targetPath, outputFormatt
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (outputFormatter) {
|
if (outputFormatter) {
|
||||||
exportedData = outputFormatter(exportedData, exportTasks, path.dirname(targetPath))
|
exportedData = outputFormatter(exportedData, exportTasks, targetPath)
|
||||||
} else {
|
} else {
|
||||||
exportedData = Promise.resolve(exportedData)
|
exportedData = Promise.resolve(exportedData)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
const resolveStorageData = require('./resolveStorageData')
|
const resolveStorageData = require('./resolveStorageData')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const fs = require('fs')
|
|
||||||
const CSON = require('@rokt33r/season')
|
const CSON = require('@rokt33r/season')
|
||||||
const keygen = require('browser/lib/keygen')
|
const keygen = require('browser/lib/keygen')
|
||||||
const sander = require('sander')
|
const sander = require('sander')
|
||||||
|
|||||||
@@ -225,7 +225,7 @@ class FolderItem extends React.Component {
|
|||||||
<div styleName='folderItem-left'
|
<div styleName='folderItem-left'
|
||||||
style={{borderColor: folder.color}}
|
style={{borderColor: folder.color}}
|
||||||
>
|
>
|
||||||
<span styleName='folderItem-left-name'>{folder.name}</span>
|
<span>{folder.name}</span>
|
||||||
<span styleName='folderItem-left-key'>({folder.key})</span>
|
<span styleName='folderItem-left-key'>({folder.key})</span>
|
||||||
</div>
|
</div>
|
||||||
<div styleName='folderItem-right'>
|
<div styleName='folderItem-right'>
|
||||||
@@ -288,10 +288,10 @@ class Handle extends React.Component {
|
|||||||
|
|
||||||
class SortableFolderItemComponent extends React.Component {
|
class SortableFolderItemComponent extends React.Component {
|
||||||
render () {
|
render () {
|
||||||
const StyledHandle = CSSModules(Handle, this.props.styles)
|
const StyledHandle = CSSModules(Handle, styles)
|
||||||
const DragHandle = SortableHandle(StyledHandle)
|
const DragHandle = SortableHandle(StyledHandle)
|
||||||
|
|
||||||
const StyledFolderItem = CSSModules(FolderItem, this.props.styles)
|
const StyledFolderItem = CSSModules(FolderItem, styles)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class FolderList extends React.Component {
|
|||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div styleName='folderList'>
|
<div>
|
||||||
{folderList.length > 0
|
{folderList.length > 0
|
||||||
? folderList
|
? folderList
|
||||||
: <div styleName='folderList-empty'>{i18n.__('No Folders')}</div>
|
: <div styleName='folderList-empty'>{i18n.__('No Folders')}</div>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ class HotkeyTab extends React.Component {
|
|||||||
toggleMode: this.refs.toggleMode.value,
|
toggleMode: this.refs.toggleMode.value,
|
||||||
deleteNote: this.refs.deleteNote.value,
|
deleteNote: this.refs.deleteNote.value,
|
||||||
pasteSmartly: this.refs.pasteSmartly.value,
|
pasteSmartly: this.refs.pasteSmartly.value,
|
||||||
|
prettifyMarkdown: this.refs.prettifyMarkdown.value,
|
||||||
toggleMenuBar: this.refs.toggleMenuBar.value
|
toggleMenuBar: this.refs.toggleMenuBar.value
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
@@ -173,6 +174,16 @@ class HotkeyTab extends React.Component {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>{i18n.__('Prettify Markdown')}</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<input styleName='group-section-control-input'
|
||||||
|
onChange={(e) => this.handleHotkeyChange(e)}
|
||||||
|
ref='prettifyMarkdown'
|
||||||
|
value={config.hotkey.prettifyMarkdown}
|
||||||
|
type='text' />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>{i18n.__('Insert Current Date')}</div>
|
<div styleName='group-section-label'>{i18n.__('Insert Current Date')}</div>
|
||||||
<div styleName='group-section-control'>
|
<div styleName='group-section-control'>
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import { getLanguages } from 'browser/lib/Languages'
|
|||||||
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
|
import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily'
|
||||||
|
|
||||||
const OSX = global.process.platform === 'darwin'
|
const OSX = global.process.platform === 'darwin'
|
||||||
const win = global.process.platform === 'win32'
|
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const ipc = electron.ipcRenderer
|
const ipc = electron.ipcRenderer
|
||||||
@@ -32,8 +31,12 @@ class UiTab extends React.Component {
|
|||||||
CodeMirror.autoLoadMode(this.codeMirrorInstance.getCodeMirror(), 'javascript')
|
CodeMirror.autoLoadMode(this.codeMirrorInstance.getCodeMirror(), 'javascript')
|
||||||
CodeMirror.autoLoadMode(this.customCSSCM.getCodeMirror(), 'css')
|
CodeMirror.autoLoadMode(this.customCSSCM.getCodeMirror(), 'css')
|
||||||
CodeMirror.autoLoadMode(this.customMarkdownLintConfigCM.getCodeMirror(), 'javascript')
|
CodeMirror.autoLoadMode(this.customMarkdownLintConfigCM.getCodeMirror(), 'javascript')
|
||||||
|
CodeMirror.autoLoadMode(this.prettierConfigCM.getCodeMirror(), 'javascript')
|
||||||
|
// Set CM editor Sizes
|
||||||
this.customCSSCM.getCodeMirror().setSize('400px', '400px')
|
this.customCSSCM.getCodeMirror().setSize('400px', '400px')
|
||||||
|
this.prettierConfigCM.getCodeMirror().setSize('400px', '400px')
|
||||||
this.customMarkdownLintConfigCM.getCodeMirror().setSize('400px', '200px')
|
this.customMarkdownLintConfigCM.getCodeMirror().setSize('400px', '200px')
|
||||||
|
|
||||||
this.handleSettingDone = () => {
|
this.handleSettingDone = () => {
|
||||||
this.setState({UiAlert: {
|
this.setState({UiAlert: {
|
||||||
type: 'success',
|
type: 'success',
|
||||||
@@ -92,6 +95,7 @@ class UiTab extends React.Component {
|
|||||||
enableRulers: this.refs.enableEditorRulers.value === 'true',
|
enableRulers: this.refs.enableEditorRulers.value === 'true',
|
||||||
rulers: this.refs.editorRulers.value.replace(/[^0-9,]/g, '').split(','),
|
rulers: this.refs.editorRulers.value.replace(/[^0-9,]/g, '').split(','),
|
||||||
displayLineNumbers: this.refs.editorDisplayLineNumbers.checked,
|
displayLineNumbers: this.refs.editorDisplayLineNumbers.checked,
|
||||||
|
lineWrapping: this.refs.editorLineWrapping.checked,
|
||||||
switchPreview: this.refs.editorSwitchPreview.value,
|
switchPreview: this.refs.editorSwitchPreview.value,
|
||||||
keyMap: this.refs.editorKeyMap.value,
|
keyMap: this.refs.editorKeyMap.value,
|
||||||
snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value,
|
snippetDefaultLanguage: this.refs.editorSnippetDefaultLanguage.value,
|
||||||
@@ -106,7 +110,9 @@ class UiTab extends React.Component {
|
|||||||
spellcheck: this.refs.spellcheck.checked,
|
spellcheck: this.refs.spellcheck.checked,
|
||||||
enableSmartPaste: this.refs.enableSmartPaste.checked,
|
enableSmartPaste: this.refs.enableSmartPaste.checked,
|
||||||
enableMarkdownLint: this.refs.enableMarkdownLint.checked,
|
enableMarkdownLint: this.refs.enableMarkdownLint.checked,
|
||||||
customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue()
|
customMarkdownLintConfig: this.customMarkdownLintConfigCM.getCodeMirror().getValue(),
|
||||||
|
prettierConfig: this.prettierConfigCM.getCodeMirror().getValue()
|
||||||
|
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
fontSize: this.refs.previewFontSize.value,
|
fontSize: this.refs.previewFontSize.value,
|
||||||
@@ -124,6 +130,7 @@ class UiTab extends React.Component {
|
|||||||
breaks: this.refs.previewBreaks.checked,
|
breaks: this.refs.previewBreaks.checked,
|
||||||
smartArrows: this.refs.previewSmartArrows.checked,
|
smartArrows: this.refs.previewSmartArrows.checked,
|
||||||
sanitize: this.refs.previewSanitize.value,
|
sanitize: this.refs.previewSanitize.value,
|
||||||
|
mermaidHTMLLabel: this.refs.previewMermaidHTMLLabel.checked,
|
||||||
allowCustomCSS: this.refs.previewAllowCustomCSS.checked,
|
allowCustomCSS: this.refs.previewAllowCustomCSS.checked,
|
||||||
lineThroughCheckbox: this.refs.lineThroughCheckbox.checked,
|
lineThroughCheckbox: this.refs.lineThroughCheckbox.checked,
|
||||||
customCSS: this.customCSSCM.getCodeMirror().getValue()
|
customCSS: this.customCSSCM.getCodeMirror().getValue()
|
||||||
@@ -136,7 +143,7 @@ class UiTab extends React.Component {
|
|||||||
const theme = consts.THEMES.find(theme => theme.name === newCodemirrorTheme)
|
const theme = consts.THEMES.find(theme => theme.name === newCodemirrorTheme)
|
||||||
|
|
||||||
if (theme) {
|
if (theme) {
|
||||||
checkHighLight.setAttribute('href', win ? theme.path : `../${theme.path}`)
|
checkHighLight.setAttribute('href', theme.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,6 +553,17 @@ class UiTab extends React.Component {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-checkBoxSection'>
|
||||||
|
<label>
|
||||||
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
|
checked={this.state.config.editor.lineWrapping}
|
||||||
|
ref='editorLineWrapping'
|
||||||
|
type='checkbox'
|
||||||
|
/>
|
||||||
|
{i18n.__('Wrap line in Snippet Note')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='group-checkBoxSection'>
|
<div styleName='group-checkBoxSection'>
|
||||||
<label>
|
<label>
|
||||||
<input onChange={(e) => this.handleUIChange(e)}
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
@@ -801,6 +819,16 @@ class UiTab extends React.Component {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div styleName='group-checkBoxSection'>
|
||||||
|
<label>
|
||||||
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
|
checked={this.state.config.preview.mermaidHTMLLabel}
|
||||||
|
ref='previewMermaidHTMLLabel'
|
||||||
|
type='checkbox'
|
||||||
|
/>
|
||||||
|
{i18n.__('Enable HTML label in mermaid flowcharts')}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
{i18n.__('LaTeX Inline Open Delimiter')}
|
{i18n.__('LaTeX Inline Open Delimiter')}
|
||||||
@@ -892,7 +920,27 @@ class UiTab extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div styleName='group-section'>
|
||||||
|
<div styleName='group-section-label'>
|
||||||
|
{i18n.__('Prettier Config')}
|
||||||
|
</div>
|
||||||
|
<div styleName='group-section-control'>
|
||||||
|
<div style={{fontFamily}}>
|
||||||
|
<ReactCodeMirror
|
||||||
|
width='400px'
|
||||||
|
height='400px'
|
||||||
|
onChange={e => this.handleUIChange(e)}
|
||||||
|
ref={e => (this.prettierConfigCM = e)}
|
||||||
|
value={config.editor.prettierConfig}
|
||||||
|
options={{
|
||||||
|
lineNumbers: true,
|
||||||
|
mode: 'application/json',
|
||||||
|
lint: true,
|
||||||
|
theme: codemirrorTheme
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div styleName='group-control'>
|
<div styleName='group-control'>
|
||||||
<button styleName='group-control-rightButton'
|
<button styleName='group-control-rightButton'
|
||||||
onClick={(e) => this.handleSaveUIClick(e)}>{i18n.__('Save')}
|
onClick={(e) => this.handleSaveUIClick(e)}>{i18n.__('Save')}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class Preferences extends React.Component {
|
|||||||
key={tab.target}
|
key={tab.target}
|
||||||
onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
|
onClick={(e) => this.handleNavButtonClick(tab.target)(e)}
|
||||||
>
|
>
|
||||||
<span styleName='nav-button-label'>
|
<span>
|
||||||
{tab.label}
|
{tab.label}
|
||||||
</span>
|
</span>
|
||||||
{isUiHotkeyTab ? this.haveToSaveNotif(tab[tab.label].type, tab[tab.label].message) : null}
|
{isUiHotkeyTab ? this.haveToSaveNotif(tab[tab.label].type, tab[tab.label].message) : null}
|
||||||
|
|||||||
@@ -72,6 +72,11 @@
|
|||||||
border-left-color: rgba(142, 142, 142, 0.5);
|
border-left-color: rgba(142, 142, 142, 0.5);
|
||||||
mix-blend-mode: difference;
|
mix-blend-mode: difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.CodeMirror-scroll {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.CodeMirror-lint-tooltip {
|
.CodeMirror-lint-tooltip {
|
||||||
z-index: 1003;
|
z-index: 1003;
|
||||||
@@ -110,7 +115,6 @@
|
|||||||
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
|||||||
@@ -71,6 +71,11 @@
|
|||||||
border-left-color: rgba(142, 142, 142, 0.5);
|
border-left-color: rgba(142, 142, 142, 0.5);
|
||||||
mix-blend-mode: difference;
|
mix-blend-mode: difference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.CodeMirror-scroll {
|
||||||
|
margin-bottom: 0;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
@@ -105,7 +110,6 @@
|
|||||||
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
|
||||||
<script src="../extra_scripts/codemirror/mode/bfm/bfm.js"></script>
|
|
||||||
|
|
||||||
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
|
||||||
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>
|
||||||
|
|||||||
@@ -156,5 +156,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,5 +212,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,5 +187,7 @@
|
|||||||
"Snippet Default Language": "Snippet Default Language",
|
"Snippet Default Language": "Snippet Default Language",
|
||||||
"New notes are tagged with the filtering tags": "New notes are tagged with the filtering tags",
|
"New notes are tagged with the filtering tags": "New notes are tagged with the filtering tags",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,5 +158,7 @@
|
|||||||
"Spellcheck disabled": "Deshabilitar corrector ortográfico",
|
"Spellcheck disabled": "Deshabilitar corrector ortográfico",
|
||||||
"Show menu bar": "Mostrar barra del menú",
|
"Show menu bar": "Mostrar barra del menú",
|
||||||
"Auto Detect": "Detección automática",
|
"Auto Detect": "Detección automática",
|
||||||
"Snippet Default Language": "Lenguaje por defecto de los fragmentos de código"
|
"Snippet Default Language": "Lenguaje por defecto de los fragmentos de código",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,5 +160,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,5 +172,7 @@
|
|||||||
"Snippet name": "Nom du snippet",
|
"Snippet name": "Nom du snippet",
|
||||||
"Snippet prefix": "Préfixe du snippet",
|
"Snippet prefix": "Préfixe du snippet",
|
||||||
"Delete Note": "Supprimer la note",
|
"Delete Note": "Supprimer la note",
|
||||||
"New notes are tagged with the filtering tags": "Les nouvelles notes sont taggées avec les tags de filtrage"
|
"New notes are tagged with the filtering tags": "Les nouvelles notes sont taggées avec les tags de filtrage",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,5 +180,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,5 +160,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -219,5 +219,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ このノートのストレージに存在しない添付ファイルへのリンクを貼り付けました。添付ファイルへのリンクの貼り付けは同一ストレージ内でのみサポートされています。代わりに添付ファイルをドラッグアンドドロップしてください! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ このノートのストレージに存在しない添付ファイルへのリンクを貼り付けました。添付ファイルへのリンクの貼り付けは同一ストレージ内でのみサポートされています。代わりに添付ファイルをドラッグアンドドロップしてください! ⚠",
|
||||||
"Spellcheck disabled": "スペルチェック無効",
|
"Spellcheck disabled": "スペルチェック無効",
|
||||||
"Show menu bar": "メニューバーを表示",
|
"Show menu bar": "メニューバーを表示",
|
||||||
"Auto Detect": "自動検出"
|
"Auto Detect": "自動検出",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "mermaid flowchartでHTMLラベルを有効にする ⚠ このオプションには潜在的なXSSの危険性があります。",
|
||||||
|
"Wrap line in Snippet Note": "行を右端で折り返す(Snippet Note)"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,5 +163,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,5 +156,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -165,5 +165,7 @@
|
|||||||
"Add tag...": "Dodaj tag...",
|
"Add tag...": "Dodaj tag...",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,5 +156,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,5 +155,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ Você colou um link referente a um anexo que não pôde ser encontrado no local de armazenamento desta nota. A vinculação de anexos de referência de links só é suportada se o local de origem e de destino for o mesmo de armazenamento. Por favor, arraste e solte o anexo na nota! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ Você colou um link referente a um anexo que não pôde ser encontrado no local de armazenamento desta nota. A vinculação de anexos de referência de links só é suportada se o local de origem e de destino for o mesmo de armazenamento. Por favor, arraste e solte o anexo na nota! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,5 +153,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,5 +155,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,5 +182,7 @@
|
|||||||
"Snippet Default Language": "ทำการ Snippet ภาษาที่เป็นค่าเริ่มต้น",
|
"Snippet Default Language": "ทำการ Snippet ภาษาที่เป็นค่าเริ่มต้น",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,5 +155,7 @@
|
|||||||
"Allow dangerous html tags": "Tehlikeli html etiketlerine izin ver",
|
"Allow dangerous html tags": "Tehlikeli html etiketlerine izin ver",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
4
locales/zh-CN.json
Executable file → Normal file
4
locales/zh-CN.json
Executable file → Normal file
@@ -220,5 +220,7 @@
|
|||||||
"Render newlines in Markdown paragraphs as <br>":"在 Markdown 段落中使用 <br> 换行",
|
"Render newlines in Markdown paragraphs as <br>":"在 Markdown 段落中使用 <br> 换行",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
4
locales/zh-TW.json
Executable file → Normal file
4
locales/zh-TW.json
Executable file → Normal file
@@ -164,5 +164,7 @@
|
|||||||
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
"⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠": "⚠ You have pasted a link referring an attachment that could not be found in the storage location of this note. Pasting links referring attachments is only supported if the source and destination location is the same storage. Please Drag&Drop the attachment instead! ⚠",
|
||||||
"Spellcheck disabled": "Spellcheck disabled",
|
"Spellcheck disabled": "Spellcheck disabled",
|
||||||
"Show menu bar": "Show menu bar",
|
"Show menu bar": "Show menu bar",
|
||||||
"Auto Detect": "Auto Detect"
|
"Auto Detect": "Auto Detect",
|
||||||
|
"Enable HTML label in mermaid flowcharts": "Enable HTML label in mermaid flowcharts ⚠ This option potentially has a risk of XSS.",
|
||||||
|
"Wrap line in Snippet Note": "Wrap line in Snippet Note"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "boost",
|
"name": "boost",
|
||||||
"productName": "Boostnote",
|
"productName": "Boostnote",
|
||||||
"version": "0.11.17",
|
"version": "0.12.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"description": "Boostnote",
|
"description": "Boostnote",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
@@ -98,6 +98,7 @@
|
|||||||
"mousetrap": "^1.6.2",
|
"mousetrap": "^1.6.2",
|
||||||
"mousetrap-global-bind": "^1.1.0",
|
"mousetrap-global-bind": "^1.1.0",
|
||||||
"node-ipc": "^8.1.0",
|
"node-ipc": "^8.1.0",
|
||||||
|
"prettier": "^1.18.2",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"query-string": "^6.5.0",
|
"query-string": "^6.5.0",
|
||||||
"raphael": "^2.2.7",
|
"raphael": "^2.2.7",
|
||||||
|
|||||||
6
prettier.config
Normal file
6
prettier.config
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"tabWidth": 4,
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
8
tests/fixtures/markdowns.js
vendored
8
tests/fixtures/markdowns.js
vendored
@@ -104,6 +104,11 @@ Term 2 with *inline markup*
|
|||||||
`
|
`
|
||||||
const shortcuts = '<kbd>Ctrl</kbd>\n\n[[Ctrl]]'
|
const shortcuts = '<kbd>Ctrl</kbd>\n\n[[Ctrl]]'
|
||||||
|
|
||||||
|
const footnote = `
|
||||||
|
^[hello-world]
|
||||||
|
hello-world: https://github.com/BoostIO/Boostnote/
|
||||||
|
`
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
basic,
|
basic,
|
||||||
codeblock,
|
codeblock,
|
||||||
@@ -115,5 +120,6 @@ export default {
|
|||||||
subTexts,
|
subTexts,
|
||||||
supTexts,
|
supTexts,
|
||||||
deflists,
|
deflists,
|
||||||
shortcuts
|
shortcuts,
|
||||||
|
footnote
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,12 +4,14 @@ jest.mock('electron', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const spellcheck = require('browser/lib/spellcheck')
|
const spellcheck = require('browser/lib/spellcheck')
|
||||||
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
|
const buildEditorContextMenu = require('browser/lib/contextMenuBuilder').buildEditorContextMenu
|
||||||
|
const buildMarkdownPreviewContextMenu = require('browser/lib/contextMenuBuilder').buildMarkdownPreviewContextMenu
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
menuBuilderParameter = null
|
menuBuilderParameter = null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Editor Context Menu
|
||||||
it('should make sure that no context menu is build if the passed editor instance was null', function () {
|
it('should make sure that no context menu is build if the passed editor instance was null', function () {
|
||||||
const event = {
|
const event = {
|
||||||
pageX: 12,
|
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(menuBuilderParameter[7].role).toEqual('selectall')
|
||||||
expect(spellcheck.getSpellingSuggestion).toHaveBeenCalledWith(wordToCorrect)
|
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)
|
||||||
|
})
|
||||||
|
|||||||
@@ -68,3 +68,8 @@ test('Markdown.render() should render shortcuts correctly', t => {
|
|||||||
const rendered = md.render(markdownFixtures.shortcuts)
|
const rendered = md.render(markdownFixtures.shortcuts)
|
||||||
t.snapshot(rendered)
|
t.snapshot(rendered)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('Markdown.render() should render footnote correctly', t => {
|
||||||
|
const rendered = md.render(markdownFixtures.footnote)
|
||||||
|
t.snapshot(rendered)
|
||||||
|
})
|
||||||
|
|||||||
@@ -4,6 +4,21 @@ The actual snapshot is saved in `markdown-test.js.snap`.
|
|||||||
|
|
||||||
Generated by [AVA](https://ava.li).
|
Generated by [AVA](https://ava.li).
|
||||||
|
|
||||||
|
## Markdown.render() should render footnote correctly
|
||||||
|
|
||||||
|
> Snapshot 1
|
||||||
|
|
||||||
|
`<p data-line="1"><sup class="footnote-ref"><a href="#fn1" id="fnref1">[1]</a></sup><br />␊
|
||||||
|
hello-world: <a href="https://github.com/BoostIO/Boostnote/">https://github.com/BoostIO/Boostnote/</a></p>␊
|
||||||
|
<hr class="footnotes-sep" />␊
|
||||||
|
<section class="footnotes">␊
|
||||||
|
<ol class="footnotes-list">␊
|
||||||
|
<li id="fn1" class="footnote-item"><p>hello-world <a href="#fnref1" class="footnote-backref">↩︎</a></p>␊
|
||||||
|
</li>␊
|
||||||
|
</ol>␊
|
||||||
|
</section>␊
|
||||||
|
`
|
||||||
|
|
||||||
## Markdown.render() should render line breaks correctly
|
## Markdown.render() should render line breaks correctly
|
||||||
|
|
||||||
> Snapshot 1
|
> Snapshot 1
|
||||||
|
|||||||
Binary file not shown.
@@ -7482,6 +7482,11 @@ preserve@^0.2.0:
|
|||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||||
|
|
||||||
|
prettier@^1.18.2:
|
||||||
|
version "1.18.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea"
|
||||||
|
integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==
|
||||||
|
|
||||||
pretty-bytes@^1.0.2:
|
pretty-bytes@^1.0.2:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84"
|
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84"
|
||||||
|
|||||||
Reference in New Issue
Block a user