1
0
mirror of https://github.com/BoostIo/Boostnote synced 2025-12-13 17:56:25 +00:00

Merge branch 'master' into filter-tags-and-folders

# Conflicts:
#	locales/zh-CN.json
This commit is contained in:
amedora
2020-01-30 10:13:16 +09:00
39 changed files with 417 additions and 108 deletions

View File

@@ -273,7 +273,7 @@ export default class CodeEditor extends React.Component {
}
componentDidMount () {
const { rulers, enableRulers, enableMarkdownLint } = this.props
const { rulers, enableRulers, enableMarkdownLint, RTL } = this.props
eventEmitter.on('line:jump', this.scrollToLineHandeler)
snippetManager.init()
@@ -294,6 +294,8 @@ export default class CodeEditor extends React.Component {
scrollPastEnd: this.props.scrollPastEnd,
inputStyle: 'textarea',
dragDrop: false,
direction: RTL ? 'rtl' : 'ltr',
rtlMoveVisually: RTL,
foldGutter: true,
lint: enableMarkdownLint ? this.getCodeEditorLintConfig() : false,
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
@@ -555,6 +557,10 @@ export default class CodeEditor extends React.Component {
if (prevProps.keyMap !== this.props.keyMap) {
needRefresh = true
}
if (prevProps.RTL !== this.props.RTL) {
this.editor.setOption('direction', this.props.RTL ? 'rtl' : 'ltr')
this.editor.setOption('rtlMoveVisually', this.props.RTL)
}
if (prevProps.enableMarkdownLint !== enableMarkdownLint || prevProps.customMarkdownLintConfig !== customMarkdownLintConfig) {
if (!enableMarkdownLint) {
this.editor.setOption('lint', {default: false})
@@ -1219,7 +1225,8 @@ CodeEditor.propTypes = {
spellCheck: PropTypes.bool,
enableMarkdownLint: PropTypes.bool,
customMarkdownLintConfig: PropTypes.string,
deleteUnusedAttachments: PropTypes.bool
deleteUnusedAttachments: PropTypes.bool,
RTL: PropTypes.bool
}
CodeEditor.defaultProps = {
@@ -1235,5 +1242,6 @@ CodeEditor.defaultProps = {
enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint,
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig,
prettierConfig: DEFAULT_CONFIG.editor.prettierConfig,
deleteUnusedAttachments: DEFAULT_CONFIG.editor.deleteUnusedAttachments
deleteUnusedAttachments: DEFAULT_CONFIG.editor.deleteUnusedAttachments,
RTL: false
}

View File

@@ -267,7 +267,7 @@ class MarkdownEditor extends React.Component {
}
render () {
const {className, value, config, storageKey, noteKey, linesHighlighted} = this.props
const {className, value, config, storageKey, noteKey, linesHighlighted, RTL} = this.props
let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
@@ -325,6 +325,7 @@ class MarkdownEditor extends React.Component {
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
prettierConfig={config.editor.prettierConfig}
deleteUnusedAttachments={config.editor.deleteUnusedAttachments}
RTL={RTL}
/>
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
? 'preview'
@@ -360,6 +361,7 @@ class MarkdownEditor extends React.Component {
allowCustomCSS={config.preview.allowCustomCSS}
lineThroughCheckbox={config.preview.lineThroughCheckbox}
onDrop={(e) => this.handleDropImage(e)}
RTL={RTL}
/>
</div>
)

View File

@@ -21,6 +21,7 @@ import yaml from 'js-yaml'
import { render } from 'react-dom'
import Carousel from 'react-image-carousel'
import ConfigManager from '../main/lib/ConfigManager'
import i18n from 'browser/lib/i18n'
const { remote, shell } = require('electron')
const attachmentManagement = require('../main/lib/dataApi/attachmentManagement')
@@ -63,7 +64,8 @@ function buildStyle (opts) {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
} = opts
return `
@font-face {
@@ -100,11 +102,14 @@ ${markdownStyle}
body {
font-family: '${fontFamily.join("','")}';
font-size: ${fontSize}px;
${scrollPastEnd ? `
padding-bottom: 90vh;
box-sizing: border-box;
`
: ''}
${RTL ? 'direction: rtl;' : ''}
${RTL ? 'text-align: right;' : ''}
}
@media print {
body {
@@ -114,6 +119,8 @@ body {
code {
font-family: '${codeBlockFontFamily.join("','")}';
background-color: rgba(0,0,0,0.04);
text-align: left;
direction: ltr;
}
.lineNumber {
${lineNumber && 'display: block !important;'}
@@ -245,6 +252,7 @@ export default class MarkdownPreview extends React.Component {
this.saveAsHtmlHandler = () => this.handleSaveAsHtml()
this.saveAsPdfHandler = () => this.handleSaveAsPdf()
this.printHandler = () => this.handlePrint()
this.resizeHandler = _.throttle(this.handleResize.bind(this), 100)
this.linkClickHandler = this.handleLinkClick.bind(this)
this.initMarkdown = this.initMarkdown.bind(this)
@@ -335,7 +343,8 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
} = this.getStyleParams()
const inlineStyles = buildStyle({
@@ -346,9 +355,10 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
})
let body = this.markdown.render(noteContent)
let body = this.refs.root.contentWindow.document.body.innerHTML
body = attachmentManagement.fixLocalURLS(
body,
this.props.storagePath
@@ -368,7 +378,7 @@ export default class MarkdownPreview extends React.Component {
let styles = ''
files.forEach(file => {
styles += `<link rel="stylesheet" href="css/${path.basename(file)}">`
styles += `<link rel="stylesheet" href="../css/${path.basename(file)}">`
})
return `<html>
@@ -423,7 +433,8 @@ export default class MarkdownPreview extends React.Component {
.then(res => {
dialog.showMessageBox(remote.getCurrentWindow(), {
type: 'info',
message: `Exported to ${filename}`
message: `Exported to ${filename}`,
buttons: [i18n.__('Ok')]
})
})
.catch(err => {
@@ -538,6 +549,10 @@ export default class MarkdownPreview extends React.Component {
'scroll',
this.scrollHandler
)
this.refs.root.contentWindow.addEventListener(
'resize',
this.resizeHandler
)
eventEmitter.on('export:save-text', this.saveAsTextHandler)
eventEmitter.on('export:save-md', this.saveAsMdHandler)
eventEmitter.on('export:save-html', this.saveAsHtmlHandler)
@@ -576,6 +591,10 @@ export default class MarkdownPreview extends React.Component {
'scroll',
this.scrollHandler
)
this.refs.root.contentWindow.removeEventListener(
'resize',
this.resizeHandler
)
eventEmitter.off('export:save-text', this.saveAsTextHandler)
eventEmitter.off('export:save-md', this.saveAsMdHandler)
eventEmitter.off('export:save-html', this.saveAsHtmlHandler)
@@ -608,7 +627,8 @@ export default class MarkdownPreview extends React.Component {
prevProps.theme !== this.props.theme ||
prevProps.scrollPastEnd !== this.props.scrollPastEnd ||
prevProps.allowCustomCSS !== this.props.allowCustomCSS ||
prevProps.customCSS !== this.props.customCSS
prevProps.customCSS !== this.props.customCSS ||
prevProps.RTL !== this.props.RTL
) {
this.applyStyle()
needsRewriteIframe = true
@@ -632,7 +652,8 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
} = this.props
let { fontFamily, codeBlockFontFamily } = this.props
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
@@ -658,7 +679,8 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
}
}
@@ -672,7 +694,8 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
} = this.getStyleParams()
this.getWindow().document.getElementById(
@@ -686,7 +709,8 @@ export default class MarkdownPreview extends React.Component {
scrollPastEnd,
theme,
allowCustomCSS,
customCSS
customCSS,
RTL
})
}
@@ -995,6 +1019,15 @@ export default class MarkdownPreview extends React.Component {
}
}
handleResize () {
_.forEach(
this.refs.root.contentWindow.document.querySelectorAll('svg[ratio]'),
el => {
el.setAttribute('height', el.clientWidth / el.getAttribute('ratio'))
}
)
}
focus () {
this.refs.root.focus()
}

View File

@@ -137,7 +137,7 @@ class MarkdownSplitEditor extends React.Component {
}
render () {
const {config, value, storageKey, noteKey, linesHighlighted} = this.props
const {config, value, storageKey, noteKey, linesHighlighted, RTL} = this.props
const storage = findStorage(storageKey)
let editorFontSize = parseInt(config.editor.fontSize, 10)
if (!(editorFontSize > 0 && editorFontSize < 101)) editorFontSize = 14
@@ -183,6 +183,7 @@ class MarkdownSplitEditor extends React.Component {
enableMarkdownLint={config.editor.enableMarkdownLint}
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
deleteUnusedAttachments={config.editor.deleteUnusedAttachments}
RTL={RTL}
/>
<div styleName='slider' style={{left: this.state.codeEditorWidthInPercent + '%'}} onMouseDown={e => this.handleMouseDown(e)} >
<div styleName='slider-hitbox' />
@@ -213,6 +214,7 @@ class MarkdownSplitEditor extends React.Component {
customCSS={config.preview.customCSS}
allowCustomCSS={config.preview.allowCustomCSS}
lineThroughCheckbox={config.preview.lineThroughCheckbox}
RTL={RTL}
/>
</div>
)

View File

@@ -5,6 +5,7 @@ import PropTypes from 'prop-types'
import React from 'react'
import { isArray, sortBy } from 'lodash'
import invertColor from 'invert-color'
import Emoji from 'react-emoji-render'
import CSSModules from 'browser/lib/CSSModules'
import { getTodoStatus } from 'browser/lib/getTodoStatus'
import styles from './NoteItem.styl'
@@ -87,7 +88,7 @@ const NoteItem = ({
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o' />}
<div styleName='item-title'>
{note.title.trim().length > 0
? note.title
? <Emoji text={note.title} />
: <span styleName='item-title-empty'>{i18n.__('Empty note')}</span>}
</div>
<div styleName='item-middle'>

View File

@@ -427,6 +427,9 @@ pre.fence
canvas, svg
max-width 100% !important
svg[ratio]
width 100%
.gallery
width 100%
height 50vh
@@ -447,6 +450,44 @@ pre.fence
color $ui-text-color
background-color $ui-tag-backgroundColor
.markdownIt-TOC-wrapper
list-style none
position fixed
right 0
top 0
margin-left 15px
z-index 1000
transition transform .2s ease-in-out
transform translateX(100%)
.markdownIt-TOC
display block
max-height 90vh
overflow-y auto
padding 25px
padding-left 38px
&,
&:before
background-color $ui-dark-backgroundColor
color: $ui-dark-text-color
&:hover
transform translateX(-15px)
&:before
content 'TOC'
position absolute
width 60px
height 30px
top 60px
left -29px
display flex
align-items center
justify-content center
transform-origin top left
transform rotate(-90deg)
themeDarkBackground = darken(#21252B, 10%)
themeDarkText = #f9f9f9
themeDarkBorder = lighten(themeDarkBackground, 20%)
@@ -514,6 +555,14 @@ body[data-theme="dark"]
color $ui-dark-text-color
background-color $ui-dark-tag-backgroundColor
.markdownIt-TOC-wrapper
&,
&:before
background-color darken(themeDarkBackground, 5%)
color themeDarkText
themeSolarizedDarkBackground = $ui-solarized-dark-noteDetail-backgroundColor
themeSolarizedDarkTableOdd = $ui-solarized-dark-noteDetail-backgroundColor
themeSolarizedDarkTableEven = darken($ui-solarized-dark-noteDetail-backgroundColor, 10%)
themeSolarizedDarkTableHead = themeSolarizedDarkTableEven
@@ -522,7 +571,7 @@ themeSolarizedDarkTableBorder = themeDarkBorder
body[data-theme="solarized-dark"]
color $ui-solarized-dark-text-color
border-color themeDarkBorder
background-color $ui-solarized-dark-noteDetail-backgroundColor
background-color themeSolarizedDarkBackground
table
thead
tr
@@ -557,6 +606,13 @@ body[data-theme="solarized-dark"]
color $ui-solarized-dark-button--active-color
background-color $ui-solarized-dark-button-backgroundColor
.markdownIt-TOC-wrapper
&,
&:before
background-color darken(themeSolarizedDarkBackground, 15%)
color themeDarkText
themeMonokaiBackground = $ui-monokai-noteDetail-backgroundColor
themeMonokaiTableOdd = $ui-monokai-noteDetail-backgroundColor
themeMonokaiTableEven = darken($ui-monokai-noteDetail-backgroundColor, 10%)
themeMonokaiTableHead = themeMonokaiTableEven
@@ -565,7 +621,7 @@ themeMonokaiTableBorder = themeDarkBorder
body[data-theme="monokai"]
color $ui-monokai-text-color
border-color themeDarkBorder
background-color $ui-monokai-noteDetail-backgroundColor
background-color themeMonokaiBackground
table
thead
tr
@@ -603,6 +659,13 @@ body[data-theme="monokai"]
color $ui-monokai-button--active-color
background-color $ui-monokai-button-backgroundColor
.markdownIt-TOC-wrapper
&,
&:before
background-color darken(themeMonokaiBackground, 15%)
color themeDarkText
themeDraculaBackground = $ui-dracula-noteDetail-backgroundColor
themeDraculaTableOdd = $ui-dracula-noteDetail-backgroundColor
themeDraculaTableEven = darken($ui-dracula-noteDetail-backgroundColor, 10%)
themeDraculaTableHead = themeDraculaTableEven
@@ -611,7 +674,7 @@ themeDraculaTableBorder = themeDarkBorder
body[data-theme="dracula"]
color $ui-dracula-text-color
border-color themeDarkBorder
background-color $ui-dracula-noteDetail-backgroundColor
background-color themeDraculaBackground
table
thead
tr
@@ -648,3 +711,9 @@ body[data-theme="dracula"]
.prev, .next
color $ui-dracula-button--active-color
background-color $ui-dracula-button-backgroundColor
.markdownIt-TOC-wrapper
&,
&:before
background-color darken(themeDraculaBackground, 15%)
color themeDarkText

View File

@@ -22,18 +22,40 @@ function getId () {
function render (element, content, theme, enableHTMLLabel) {
try {
const height = element.attributes.getNamedItem('data-height')
if (height && height.value !== 'undefined') {
const isPredefined = height && height.value !== 'undefined'
if (isPredefined) {
element.style.height = height.value + 'vh'
}
const isDarkTheme = theme === 'dark' || theme === 'solarized-dark' || theme === 'monokai' || theme === 'dracula'
mermaidAPI.initialize({
theme: isDarkTheme ? 'dark' : 'default',
themeCSS: isDarkTheme ? darkThemeStyling : '',
useMaxWidth: false,
flowchart: { htmlLabels: enableHTMLLabel }
flowchart: {
htmlLabels: enableHTMLLabel
},
gantt: {
useWidth: element.clientWidth
}
})
mermaidAPI.render(getId(), content, (svgGraph) => {
element.innerHTML = svgGraph
if (!isPredefined) {
const el = element.firstChild
const viewBox = el.getAttribute('viewBox').split(' ')
let ratio = viewBox[2] / viewBox[3]
if (el.style.maxWidth) {
const maxWidth = parseFloat(el.style.maxWidth)
ratio *= el.parentNode.clientWidth / maxWidth
}
el.setAttribute('ratio', ratio)
el.setAttribute('height', el.parentNode.clientWidth / ratio)
console.log(el)
}
})
} catch (e) {
element.className = 'mermaid-error'