Skip to content

Commit f26dea2

Browse files
committed
Merge branch 'master' into feature-tag-links
2 parents 5f96e31 + 052fb3d commit f26dea2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1021
-330
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"test": {
88
"presets": ["env" ,"react", "es2015"],
99
"plugins": [
10-
[ "babel-plugin-webpack-alias", { "config": "${PWD}/webpack.config.js" } ]
10+
[ "babel-plugin-webpack-alias", { "config": "<rootDir>/webpack.config.js" } ]
1111
]
1212
}
1313
}

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
custom: https://issuehunt.io/r/BoostIo/Boostnote

browser/components/CodeEditor.js

Lines changed: 79 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ import {languageMaps} from '../lib/CMLanguageList'
2626
import snippetManager from '../lib/SnippetManager'
2727
import {generateInEditor, tocExistsInEditor} from 'browser/lib/markdown-toc-generator'
2828
import markdownlint from 'markdownlint'
29+
import Jsonlint from 'jsonlint-mod'
30+
import { DEFAULT_CONFIG } from '../main/lib/ConfigManager'
2931

3032
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
3133

@@ -38,38 +40,6 @@ function translateHotkey (hotkey) {
3840
return hotkey.replace(/\s*\+\s*/g, '-').replace(/Command/g, 'Cmd').replace(/Control/g, 'Ctrl')
3941
}
4042

41-
const validatorOfMarkdown = (text, updateLinting) => {
42-
const lintOptions = {
43-
'strings': {
44-
'content': text
45-
}
46-
}
47-
48-
return markdownlint(lintOptions, (err, result) => {
49-
if (!err) {
50-
const foundIssues = []
51-
result.content.map(item => {
52-
let ruleNames = ''
53-
item.ruleNames.map((ruleName, index) => {
54-
ruleNames += ruleName
55-
if (index === item.ruleNames.length - 1) {
56-
ruleNames += ': '
57-
} else {
58-
ruleNames += '/'
59-
}
60-
})
61-
foundIssues.push({
62-
from: CodeMirror.Pos(item.lineNumber, 0),
63-
to: CodeMirror.Pos(item.lineNumber, 1),
64-
message: ruleNames + item.ruleDescription,
65-
severity: 'warning'
66-
})
67-
})
68-
updateLinting(foundIssues)
69-
}
70-
})
71-
}
72-
7343
export default class CodeEditor extends React.Component {
7444
constructor (props) {
7545
super(props)
@@ -116,6 +86,8 @@ export default class CodeEditor extends React.Component {
11686
this.searchHandler = (e, msg) => this.handleSearch(msg)
11787
this.searchState = null
11888
this.scrollToLineHandeler = this.scrollToLine.bind(this)
89+
this.getCodeEditorLintConfig = this.getCodeEditorLintConfig.bind(this)
90+
this.validatorOfMarkdown = this.validatorOfMarkdown.bind(this)
11991

12092
this.formatTable = () => this.handleFormatTable()
12193

@@ -283,13 +255,12 @@ export default class CodeEditor extends React.Component {
283255
}
284256

285257
componentDidMount () {
286-
const { rulers, enableRulers } = this.props
258+
const { rulers, enableRulers, enableMarkdownLint } = this.props
287259
eventEmitter.on('line:jump', this.scrollToLineHandeler)
288260

289261
snippetManager.init()
290262
this.updateDefaultKeyMap()
291263

292-
const checkMarkdownNoteIsOpening = this.props.mode === 'Boost Flavored Markdown'
293264
this.value = this.props.value
294265
this.editor = CodeMirror(this.refs.root, {
295266
rulers: buildCMRulers(rulers, enableRulers),
@@ -306,10 +277,7 @@ export default class CodeEditor extends React.Component {
306277
inputStyle: 'textarea',
307278
dragDrop: false,
308279
foldGutter: true,
309-
lint: checkMarkdownNoteIsOpening ? {
310-
'getAnnotations': validatorOfMarkdown,
311-
'async': true
312-
} : false,
280+
lint: enableMarkdownLint ? this.getCodeEditorLintConfig() : false,
313281
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'],
314282
autoCloseBrackets: {
315283
pairs: this.props.matchingPairs,
@@ -320,6 +288,8 @@ export default class CodeEditor extends React.Component {
320288
extraKeys: this.defaultKeyMap
321289
})
322290

291+
document.querySelector('.CodeMirror-lint-markers').style.display = enableMarkdownLint ? 'inline-block' : 'none'
292+
323293
if (!this.props.mode && this.props.value && this.props.autoDetect) {
324294
this.autoDetectLanguage(this.props.value)
325295
} else {
@@ -546,7 +516,9 @@ export default class CodeEditor extends React.Component {
546516
let needRefresh = false
547517
const {
548518
rulers,
549-
enableRulers
519+
enableRulers,
520+
enableMarkdownLint,
521+
customMarkdownLintConfig
550522
} = this.props
551523
if (prevProps.mode !== this.props.mode) {
552524
this.setMode(this.props.mode)
@@ -564,6 +536,16 @@ export default class CodeEditor extends React.Component {
564536
if (prevProps.keyMap !== this.props.keyMap) {
565537
needRefresh = true
566538
}
539+
if (prevProps.enableMarkdownLint !== enableMarkdownLint || prevProps.customMarkdownLintConfig !== customMarkdownLintConfig) {
540+
if (!enableMarkdownLint) {
541+
this.editor.setOption('lint', {default: false})
542+
document.querySelector('.CodeMirror-lint-markers').style.display = 'none'
543+
} else {
544+
this.editor.setOption('lint', this.getCodeEditorLintConfig())
545+
document.querySelector('.CodeMirror-lint-markers').style.display = 'inline-block'
546+
}
547+
needRefresh = true
548+
}
567549

568550
if (
569551
prevProps.enableRulers !== enableRulers ||
@@ -644,6 +626,56 @@ export default class CodeEditor extends React.Component {
644626
}
645627
}
646628

629+
getCodeEditorLintConfig () {
630+
const { mode } = this.props
631+
const checkMarkdownNoteIsOpen = mode === 'Boost Flavored Markdown'
632+
633+
return checkMarkdownNoteIsOpen ? {
634+
'getAnnotations': this.validatorOfMarkdown,
635+
'async': true
636+
} : false
637+
}
638+
639+
validatorOfMarkdown (text, updateLinting) {
640+
const { customMarkdownLintConfig } = this.props
641+
let lintConfigJson
642+
try {
643+
Jsonlint.parse(customMarkdownLintConfig)
644+
lintConfigJson = JSON.parse(customMarkdownLintConfig)
645+
} catch (err) {
646+
eventEmitter.emit('APP_SETTING_ERROR')
647+
return
648+
}
649+
const lintOptions = {
650+
'strings': {
651+
'content': text
652+
},
653+
'config': lintConfigJson
654+
}
655+
656+
return markdownlint(lintOptions, (err, result) => {
657+
if (!err) {
658+
const foundIssues = []
659+
const splitText = text.split('\n')
660+
result.content.map(item => {
661+
let ruleNames = ''
662+
item.ruleNames.map((ruleName, index) => {
663+
ruleNames += ruleName
664+
ruleNames += (index === item.ruleNames.length - 1) ? ': ' : '/'
665+
})
666+
const lineNumber = item.lineNumber - 1
667+
foundIssues.push({
668+
from: CodeMirror.Pos(lineNumber, 0),
669+
to: CodeMirror.Pos(lineNumber, splitText[lineNumber].length),
670+
message: ruleNames + item.ruleDescription,
671+
severity: 'warning'
672+
})
673+
})
674+
updateLinting(foundIssues)
675+
}
676+
})
677+
}
678+
647679
setMode (mode) {
648680
let syntax = CodeMirror.findModeByName(convertModeName(mode || 'text'))
649681
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
@@ -1105,13 +1137,11 @@ export default class CodeEditor extends React.Component {
11051137
}
11061138
ref='root'
11071139
tabIndex='-1'
1108-
style={
1109-
{
1140+
style={{
11101141
fontFamily,
11111142
fontSize: fontSize,
11121143
width: width
1113-
}
1114-
}
1144+
}}
11151145
onDrop={
11161146
e => this.handleDropImage(e)
11171147
}
@@ -1149,7 +1179,9 @@ CodeEditor.propTypes = {
11491179
onChange: PropTypes.func,
11501180
readOnly: PropTypes.bool,
11511181
autoDetect: PropTypes.bool,
1152-
spellCheck: PropTypes.bool
1182+
spellCheck: PropTypes.bool,
1183+
enableMarkdownLint: PropTypes.bool,
1184+
customMarkdownLintConfig: PropTypes.string
11531185
}
11541186

11551187
CodeEditor.defaultProps = {
@@ -1161,5 +1193,7 @@ CodeEditor.defaultProps = {
11611193
indentSize: 4,
11621194
indentType: 'space',
11631195
autoDetect: false,
1164-
spellCheck: false
1196+
spellCheck: false,
1197+
enableMarkdownLint: DEFAULT_CONFIG.editor.enableMarkdownLint,
1198+
customMarkdownLintConfig: DEFAULT_CONFIG.editor.customMarkdownLintConfig
11651199
}

browser/components/MarkdownEditor.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ class MarkdownEditor extends React.Component {
319319
enableSmartPaste={config.editor.enableSmartPaste}
320320
hotkey={config.hotkey}
321321
switchPreview={config.editor.switchPreview}
322+
enableMarkdownLint={config.editor.enableMarkdownLint}
323+
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
322324
/>
323325
<MarkdownPreview styleName={this.state.status === 'PREVIEW'
324326
? 'preview'

browser/components/MarkdownSplitEditor.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,8 @@ class MarkdownSplitEditor extends React.Component {
179179
enableSmartPaste={config.editor.enableSmartPaste}
180180
hotkey={config.hotkey}
181181
switchPreview={config.editor.switchPreview}
182+
enableMarkdownLint={config.editor.enableMarkdownLint}
183+
customMarkdownLintConfig={config.editor.customMarkdownLintConfig}
182184
/>
183185
<div styleName='slider' style={{left: this.state.codeEditorWidthInPercent + '%'}} onMouseDown={e => this.handleMouseDown(e)} >
184186
<div styleName='slider-hitbox' />

browser/lib/CSSModules.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import CSSModules from 'react-css-modules'
22

33
export default function (component, styles) {
4-
return CSSModules(component, styles, {errorWhenNotFound: false})
4+
return CSSModules(component, styles, {handleNotFoundStyleName: 'log'})
55
}

browser/lib/Languages.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ const languages = [
6262
{
6363
name: 'Spanish',
6464
locale: 'es-ES'
65-
}, {
65+
},
66+
{
6667
name: 'Turkish',
6768
locale: 'tr'
68-
}, {
69+
},
70+
{
6971
name: 'Thai',
7072
locale: 'th'
7173
}
@@ -82,4 +84,3 @@ module.exports = {
8284
return languages
8385
}
8486
}
85-

browser/lib/newNote.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { hashHistory } from 'react-router'
21
import dataApi from 'browser/main/lib/dataApi'
32
import ee from 'browser/main/lib/eventEmitter'
43
import AwsMobileAnalyticsConfig from 'browser/main/lib/AwsMobileAnalyticsConfig'
4+
import queryString from 'query-string'
5+
import { push } from 'connected-react-router'
56

67
export function createMarkdownNote (storage, folder, dispatch, location, params, config) {
78
AwsMobileAnalyticsConfig.recordDynamicCustomEvent('ADD_MARKDOWN')
@@ -28,10 +29,10 @@ export function createMarkdownNote (storage, folder, dispatch, location, params,
2829
note: note
2930
})
3031

31-
hashHistory.push({
32+
dispatch(push({
3233
pathname: location.pathname,
33-
query: { key: noteHash }
34-
})
34+
search: queryString.stringify({ key: noteHash })
35+
}))
3536
ee.emit('list:jump', noteHash)
3637
ee.emit('detail:focus')
3738
})
@@ -70,10 +71,10 @@ export function createSnippetNote (storage, folder, dispatch, location, params,
7071
type: 'UPDATE_NOTE',
7172
note: note
7273
})
73-
hashHistory.push({
74+
dispatch(push({
7475
pathname: location.pathname,
75-
query: { key: noteHash }
76-
})
76+
search: queryString.stringify({ key: noteHash })
77+
}))
7778
ee.emit('list:jump', noteHash)
7879
ee.emit('detail:focus')
7980
})

browser/main/Detail/MarkdownNoteDetail.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import StarButton from './StarButton'
99
import TagSelect from './TagSelect'
1010
import FolderSelect from './FolderSelect'
1111
import dataApi from 'browser/main/lib/dataApi'
12-
import { hashHistory } from 'react-router'
1312
import ee from 'browser/main/lib/eventEmitter'
1413
import markdown from 'browser/lib/markdownTextHelper'
1514
import StatusBar from '../StatusBar'
@@ -30,6 +29,8 @@ import { getTodoPercentageOfCompleted } from 'browser/lib/getTodoStatus'
3029
import striptags from 'striptags'
3130
import { confirmDeleteNote } from 'browser/lib/confirmDeleteNote'
3231
import markdownToc from 'browser/lib/markdown-toc-generator'
32+
import queryString from 'query-string'
33+
import { replace } from 'connected-react-router'
3334

3435
class MarkdownNoteDetail extends React.Component {
3536
constructor (props) {
@@ -140,6 +141,7 @@ class MarkdownNoteDetail extends React.Component {
140141
}
141142

142143
handleFolderChange (e) {
144+
const { dispatch } = this.props
143145
const { note } = this.state
144146
const value = this.refs.folder.value
145147
const splitted = value.split('-')
@@ -159,12 +161,12 @@ class MarkdownNoteDetail extends React.Component {
159161
originNote: note,
160162
note: newNote
161163
})
162-
hashHistory.replace({
164+
dispatch(replace({
163165
pathname: location.pathname,
164-
query: {
166+
search: queryString.stringify({
165167
key: newNote.key
166-
}
167-
})
168+
})
169+
}))
168170
this.setState({
169171
isMovingNote: false
170172
})
@@ -491,7 +493,7 @@ class MarkdownNoteDetail extends React.Component {
491493
<InfoPanel
492494
storageName={currentOption.storage.name}
493495
folderName={currentOption.folder.name}
494-
noteLink={`[${note.title}](:note:${location.query.key})`}
496+
noteLink={`[${note.title}](:note:${queryString.parse(location.search).key})`}
495497
updatedAt={formatDate(note.updatedAt)}
496498
createdAt={formatDate(note.createdAt)}
497499
exportAsMd={this.exportAsMd}

browser/main/Detail/MarkdownNoteDetail.styl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,12 @@ body[data-theme="monokai"]
8080
body[data-theme="dracula"]
8181
.root
8282
border-left 1px solid $ui-dracula-borderColor
83-
background-color $ui-dracula-noteDetail-backgroundColor
83+
background-color $ui-dracula-noteDetail-backgroundColor
84+
85+
div
86+
> button, div
87+
-webkit-user-drag none
88+
user-select none
89+
> img, span
90+
-webkit-user-drag none
91+
user-select none

0 commit comments

Comments
 (0)