mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 01:36:22 +00:00
Merge branch 'master' into master
This commit is contained in:
@@ -22,7 +22,9 @@
|
||||
"fontSize": "14",
|
||||
"lineNumber": true
|
||||
},
|
||||
"sortBy": "UPDATED_AT",
|
||||
"sortBy": {
|
||||
"default": "UPDATED_AT"
|
||||
},
|
||||
"sortTagsBy": "ALPHABETICAL",
|
||||
"ui": {
|
||||
"defaultNote": "ALWAYS_ASK",
|
||||
|
||||
@@ -20,14 +20,18 @@ import { gfm } from 'turndown-plugin-gfm'
|
||||
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
||||
|
||||
const buildCMRulers = (rulers, enableRulers) =>
|
||||
enableRulers ? rulers.map(ruler => ({column: ruler})) : []
|
||||
(enableRulers ? rulers.map(ruler => ({ column: ruler })) : [])
|
||||
|
||||
export default class CodeEditor extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
||||
this.changeHandler = (e) => this.handleChange(e)
|
||||
this.state = { isReady: false }
|
||||
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {
|
||||
leading: false,
|
||||
trailing: true
|
||||
})
|
||||
this.changeHandler = e => this.handleChange(e)
|
||||
this.focusHandler = () => {
|
||||
ipcRenderer.send('editor:focused', true)
|
||||
}
|
||||
@@ -43,11 +47,15 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
this.props.onBlur != null && this.props.onBlur(e)
|
||||
|
||||
const {storageKey, noteKey} = this.props
|
||||
attachmentManagement.deleteAttachmentsNotPresentInNote(this.editor.getValue(), storageKey, noteKey)
|
||||
const { storageKey, noteKey } = this.props
|
||||
attachmentManagement.deleteAttachmentsNotPresentInNote(
|
||||
this.editor.getValue(),
|
||||
storageKey,
|
||||
noteKey
|
||||
)
|
||||
}
|
||||
this.pasteHandler = (editor, e) => this.handlePaste(editor, e)
|
||||
this.loadStyleHandler = (e) => {
|
||||
this.loadStyleHandler = e => {
|
||||
this.editor.refresh()
|
||||
}
|
||||
this.searchHandler = (e, msg) => this.handleSearch(msg)
|
||||
@@ -71,7 +79,10 @@ export default class CodeEditor extends React.Component {
|
||||
cm.addOverlay(component.searchState)
|
||||
|
||||
function makeOverlay (query, style) {
|
||||
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), 'gi')
|
||||
query = new RegExp(
|
||||
query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'),
|
||||
'gi'
|
||||
)
|
||||
return {
|
||||
token: function (stream) {
|
||||
query.lastIndex = stream.pos
|
||||
@@ -107,7 +118,11 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
]
|
||||
if (!fs.existsSync(consts.SNIPPET_FILE)) {
|
||||
fs.writeFileSync(consts.SNIPPET_FILE, JSON.stringify(defaultSnippet, null, 4), 'utf8')
|
||||
fs.writeFileSync(
|
||||
consts.SNIPPET_FILE,
|
||||
JSON.stringify(defaultSnippet, null, 4),
|
||||
'utf8'
|
||||
)
|
||||
}
|
||||
|
||||
this.value = this.props.value
|
||||
@@ -149,9 +164,14 @@ export default class CodeEditor extends React.Component {
|
||||
cm.execCommand('insertSoftTab')
|
||||
}
|
||||
cm.execCommand('goLineEnd')
|
||||
} else if (!charBeforeCursor.match(/\t|\s|\r|\n/) && cursor.ch > 1) {
|
||||
} else if (
|
||||
!charBeforeCursor.match(/\t|\s|\r|\n/) &&
|
||||
cursor.ch > 1
|
||||
) {
|
||||
// text expansion on tab key if the char before is alphabet
|
||||
const snippets = JSON.parse(fs.readFileSync(consts.SNIPPET_FILE, 'utf8'))
|
||||
const snippets = JSON.parse(
|
||||
fs.readFileSync(consts.SNIPPET_FILE, 'utf8')
|
||||
)
|
||||
if (expandSnippet(line, cursor, cm, snippets) === false) {
|
||||
if (tabs) {
|
||||
cm.execCommand('insertTab')
|
||||
@@ -172,7 +192,7 @@ export default class CodeEditor extends React.Component {
|
||||
// Do nothing
|
||||
},
|
||||
Enter: 'boostNewLineAndIndentContinueMarkdownList',
|
||||
'Ctrl-C': (cm) => {
|
||||
'Ctrl-C': cm => {
|
||||
if (cm.getOption('keyMap').substr(0, 3) === 'vim') {
|
||||
document.execCommand('copy')
|
||||
}
|
||||
@@ -200,13 +220,17 @@ export default class CodeEditor extends React.Component {
|
||||
CodeMirror.Vim.defineEx('wq', 'wq', this.quitEditor)
|
||||
CodeMirror.Vim.defineEx('qw', 'qw', this.quitEditor)
|
||||
CodeMirror.Vim.map('ZZ', ':q', 'normal')
|
||||
|
||||
this.setState({ isReady: true })
|
||||
this.tableEditor = new TableEditor(new TextEditorInterface(this.editor))
|
||||
eventEmitter.on('code:format-table', this.formatTable)
|
||||
}
|
||||
|
||||
expandSnippet (line, cursor, cm, snippets) {
|
||||
const wordBeforeCursor = this.getWordBeforeCursor(line, cursor.line, cursor.ch)
|
||||
const wordBeforeCursor = this.getWordBeforeCursor(
|
||||
line,
|
||||
cursor.line,
|
||||
cursor.ch
|
||||
)
|
||||
const templateCursorString = ':{}'
|
||||
for (let i = 0; i < snippets.length; i++) {
|
||||
if (snippets[i].prefix.indexOf(wordBeforeCursor.text) !== -1) {
|
||||
@@ -224,7 +248,10 @@ export default class CodeEditor extends React.Component {
|
||||
wordBeforeCursor.range.from,
|
||||
wordBeforeCursor.range.to
|
||||
)
|
||||
cm.setCursor({ line: cursor.line + cursorLineNumber, ch: cursorLinePosition })
|
||||
cm.setCursor({
|
||||
line: cursor.line + cursorLineNumber,
|
||||
ch: cursorLinePosition
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -266,8 +293,8 @@ export default class CodeEditor extends React.Component {
|
||||
return {
|
||||
text: wordBeforeCursor,
|
||||
range: {
|
||||
from: {line: lineNumber, ch: originCursorPosition},
|
||||
to: {line: lineNumber, ch: cursorPosition}
|
||||
from: { line: lineNumber, ch: originCursorPosition },
|
||||
to: { line: lineNumber, ch: cursorPosition }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -291,7 +318,7 @@ export default class CodeEditor extends React.Component {
|
||||
|
||||
componentDidUpdate (prevProps, prevState) {
|
||||
let needRefresh = false
|
||||
const {rulers, enableRulers} = this.props
|
||||
const { rulers, enableRulers } = this.props
|
||||
if (prevProps.mode !== this.props.mode) {
|
||||
this.setMode(this.props.mode)
|
||||
}
|
||||
@@ -309,7 +336,10 @@ export default class CodeEditor extends React.Component {
|
||||
needRefresh = true
|
||||
}
|
||||
|
||||
if (prevProps.enableRulers !== enableRulers || prevProps.rulers !== rulers) {
|
||||
if (
|
||||
prevProps.enableRulers !== enableRulers ||
|
||||
prevProps.rulers !== rulers
|
||||
) {
|
||||
this.editor.setOption('rulers', buildCMRulers(rulers, enableRulers))
|
||||
}
|
||||
|
||||
@@ -349,11 +379,9 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
moveCursorTo (row, col) {
|
||||
}
|
||||
moveCursorTo (row, col) {}
|
||||
|
||||
scrollToLine (num) {
|
||||
}
|
||||
scrollToLine (num) {}
|
||||
|
||||
focus () {
|
||||
this.editor.focus()
|
||||
@@ -381,8 +409,13 @@ export default class CodeEditor extends React.Component {
|
||||
|
||||
handleDropImage (dropEvent) {
|
||||
dropEvent.preventDefault()
|
||||
const {storageKey, noteKey} = this.props
|
||||
attachmentManagement.handleAttachmentDrop(this, storageKey, noteKey, dropEvent)
|
||||
const { storageKey, noteKey } = this.props
|
||||
attachmentManagement.handleAttachmentDrop(
|
||||
this,
|
||||
storageKey,
|
||||
noteKey,
|
||||
dropEvent
|
||||
)
|
||||
}
|
||||
|
||||
insertAttachmentMd (imageMd) {
|
||||
@@ -391,23 +424,23 @@ export default class CodeEditor extends React.Component {
|
||||
|
||||
handlePaste (editor, e) {
|
||||
const clipboardData = e.clipboardData
|
||||
const {storageKey, noteKey} = this.props
|
||||
const { storageKey, noteKey } = this.props
|
||||
const dataTransferItem = clipboardData.items[0]
|
||||
const pastedTxt = clipboardData.getData('text')
|
||||
const isURL = (str) => {
|
||||
const isURL = str => {
|
||||
const matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/
|
||||
return matcher.test(str)
|
||||
}
|
||||
const isInLinkTag = (editor) => {
|
||||
const isInLinkTag = editor => {
|
||||
const startCursor = editor.getCursor('start')
|
||||
const prevChar = editor.getRange(
|
||||
{line: startCursor.line, ch: startCursor.ch - 2},
|
||||
{line: startCursor.line, ch: startCursor.ch}
|
||||
{ line: startCursor.line, ch: startCursor.ch - 2 },
|
||||
{ line: startCursor.line, ch: startCursor.ch }
|
||||
)
|
||||
const endCursor = editor.getCursor('end')
|
||||
const nextChar = editor.getRange(
|
||||
{line: endCursor.line, ch: endCursor.ch},
|
||||
{line: endCursor.line, ch: endCursor.ch + 1}
|
||||
{ line: endCursor.line, ch: endCursor.ch },
|
||||
{ line: endCursor.line, ch: endCursor.ch + 1 }
|
||||
)
|
||||
return prevChar === '](' && nextChar === ')'
|
||||
}
|
||||
@@ -416,13 +449,23 @@ export default class CodeEditor extends React.Component {
|
||||
if (pastedHtml !== '') {
|
||||
this.handlePasteHtml(e, editor, pastedHtml)
|
||||
} else if (dataTransferItem.type.match('image')) {
|
||||
attachmentManagement.handlePastImageEvent(this, storageKey, noteKey, dataTransferItem)
|
||||
} else if (this.props.fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) {
|
||||
attachmentManagement.handlePastImageEvent(
|
||||
this,
|
||||
storageKey,
|
||||
noteKey,
|
||||
dataTransferItem
|
||||
)
|
||||
} else if (
|
||||
this.props.fetchUrlTitle &&
|
||||
isURL(pastedTxt) &&
|
||||
!isInLinkTag(editor)
|
||||
) {
|
||||
this.handlePasteUrl(e, editor, pastedTxt)
|
||||
}
|
||||
if (attachmentManagement.isAttachmentLink(pastedTxt)) {
|
||||
attachmentManagement.handleAttachmentLinkPaste(storageKey, noteKey, pastedTxt)
|
||||
.then((modifiedText) => {
|
||||
attachmentManagement
|
||||
.handleAttachmentLinkPaste(storageKey, noteKey, pastedTxt)
|
||||
.then(modifiedText => {
|
||||
this.editor.replaceSelection(modifiedText)
|
||||
})
|
||||
e.preventDefault()
|
||||
@@ -440,32 +483,39 @@ export default class CodeEditor extends React.Component {
|
||||
const taggedUrl = `<${pastedTxt}>`
|
||||
editor.replaceSelection(taggedUrl)
|
||||
|
||||
const isImageReponse = (response) => {
|
||||
return response.headers.has('content-type') &&
|
||||
const isImageReponse = response => {
|
||||
return (
|
||||
response.headers.has('content-type') &&
|
||||
response.headers.get('content-type').match(/^image\/.+$/)
|
||||
)
|
||||
}
|
||||
const replaceTaggedUrl = (replacement) => {
|
||||
const replaceTaggedUrl = replacement => {
|
||||
const value = editor.getValue()
|
||||
const cursor = editor.getCursor()
|
||||
const newValue = value.replace(taggedUrl, replacement)
|
||||
const newCursor = Object.assign({}, cursor, { ch: cursor.ch + newValue.length - value.length })
|
||||
const newCursor = Object.assign({}, cursor, {
|
||||
ch: cursor.ch + newValue.length - value.length
|
||||
})
|
||||
editor.setValue(newValue)
|
||||
editor.setCursor(newCursor)
|
||||
}
|
||||
|
||||
fetch(pastedTxt, {
|
||||
method: 'get'
|
||||
}).then((response) => {
|
||||
if (isImageReponse(response)) {
|
||||
return this.mapImageResponse(response, pastedTxt)
|
||||
} else {
|
||||
return this.mapNormalResponse(response, pastedTxt)
|
||||
}
|
||||
}).then((replacement) => {
|
||||
replaceTaggedUrl(replacement)
|
||||
}).catch((e) => {
|
||||
replaceTaggedUrl(pastedTxt)
|
||||
})
|
||||
.then(response => {
|
||||
if (isImageReponse(response)) {
|
||||
return this.mapImageResponse(response, pastedTxt)
|
||||
} else {
|
||||
return this.mapNormalResponse(response, pastedTxt)
|
||||
}
|
||||
})
|
||||
.then(replacement => {
|
||||
replaceTaggedUrl(replacement)
|
||||
})
|
||||
.catch(e => {
|
||||
replaceTaggedUrl(pastedTxt)
|
||||
})
|
||||
}
|
||||
|
||||
handlePasteHtml (e, editor, pastedHtml) {
|
||||
@@ -475,10 +525,13 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
|
||||
mapNormalResponse (response, pastedTxt) {
|
||||
return this.decodeResponse(response).then((body) => {
|
||||
return this.decodeResponse(response).then(body => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const parsedBody = (new window.DOMParser()).parseFromString(body, 'text/html')
|
||||
const parsedBody = new window.DOMParser().parseFromString(
|
||||
body,
|
||||
'text/html'
|
||||
)
|
||||
const linkWithTitle = `[${parsedBody.title}](${pastedTxt})`
|
||||
resolve(linkWithTitle)
|
||||
} catch (e) {
|
||||
@@ -506,10 +559,13 @@ export default class CodeEditor extends React.Component {
|
||||
const _charset = headers.has('content-type')
|
||||
? this.extractContentTypeCharset(headers.get('content-type'))
|
||||
: undefined
|
||||
return response.arrayBuffer().then((buff) => {
|
||||
return response.arrayBuffer().then(buff => {
|
||||
return new Promise((resolve, reject) => {
|
||||
try {
|
||||
const charset = _charset !== undefined && iconv.encodingExists(_charset) ? _charset : 'utf-8'
|
||||
const charset = _charset !== undefined &&
|
||||
iconv.encodingExists(_charset)
|
||||
? _charset
|
||||
: 'utf-8'
|
||||
resolve(iconv.decode(new Buffer(buff), charset).toString())
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
@@ -519,11 +575,14 @@ export default class CodeEditor extends React.Component {
|
||||
}
|
||||
|
||||
extractContentTypeCharset (contentType) {
|
||||
return contentType.split(';').filter((str) => {
|
||||
return str.trim().toLowerCase().startsWith('charset')
|
||||
}).map((str) => {
|
||||
return str.replace(/['"]/g, '').split('=')[1]
|
||||
})[0]
|
||||
return contentType
|
||||
.split(';')
|
||||
.filter(str => {
|
||||
return str.trim().toLowerCase().startsWith('charset')
|
||||
})
|
||||
.map(str => {
|
||||
return str.replace(/['"]/g, '').split('=')[1]
|
||||
})[0]
|
||||
}
|
||||
|
||||
render () {
|
||||
@@ -532,18 +591,16 @@ export default class CodeEditor extends React.Component {
|
||||
const width = this.props.width
|
||||
return (
|
||||
<div
|
||||
className={className == null
|
||||
? 'CodeEditor'
|
||||
: `CodeEditor ${className}`
|
||||
}
|
||||
className={className == null ? 'CodeEditor' : `CodeEditor ${className}`}
|
||||
ref='root'
|
||||
tabIndex='-1'
|
||||
style={{
|
||||
fontFamily,
|
||||
fontSize: fontSize,
|
||||
width: width
|
||||
width: width,
|
||||
opacity: this.state.isReady ? '1' : '0'
|
||||
}}
|
||||
onDrop={(e) => this.handleDropImage(e)}
|
||||
onDrop={e => this.handleDropImage(e)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import CodeEditor from 'browser/components/CodeEditor'
|
||||
import MarkdownPreview from 'browser/components/MarkdownPreview'
|
||||
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||
import { findStorage } from 'browser/lib/findStorage'
|
||||
import debounceRender from 'react-debounce-render'
|
||||
|
||||
class MarkdownEditor extends React.Component {
|
||||
constructor (props) {
|
||||
@@ -312,4 +313,4 @@ MarkdownEditor.propTypes = {
|
||||
ignorePreviewPointerEvents: PropTypes.bool
|
||||
}
|
||||
|
||||
export default CSSModules(MarkdownEditor, styles)
|
||||
export default debounceRender(CSSModules(MarkdownEditor, styles))
|
||||
|
||||
@@ -28,15 +28,24 @@ const fileUrl = require('file-url')
|
||||
const dialog = remote.dialog
|
||||
|
||||
const markdownStyle = require('!!css!stylus?sourceMap!./markdown.styl')[0][1]
|
||||
const appPath = fileUrl(process.env.NODE_ENV === 'production'
|
||||
? app.getAppPath()
|
||||
: path.resolve())
|
||||
const appPath = fileUrl(
|
||||
process.env.NODE_ENV === 'production' ? app.getAppPath() : path.resolve()
|
||||
)
|
||||
const CSS_FILES = [
|
||||
`${appPath}/node_modules/katex/dist/katex.min.css`,
|
||||
`${appPath}/node_modules/codemirror/lib/codemirror.css`
|
||||
]
|
||||
|
||||
function buildStyle (fontFamily, fontSize, codeBlockFontFamily, lineNumber, scrollPastEnd, theme, allowCustomCSS, customCSS) {
|
||||
function buildStyle (
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
) {
|
||||
return `
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
@@ -160,17 +169,29 @@ if (!OSX) {
|
||||
defaultFontFamily.unshift('Microsoft YaHei')
|
||||
defaultFontFamily.unshift('meiryo')
|
||||
}
|
||||
const defaultCodeBlockFontFamily = ['Monaco', 'Menlo', 'Ubuntu Mono', 'Consolas', 'source-code-pro', 'monospace']
|
||||
const defaultCodeBlockFontFamily = [
|
||||
'Monaco',
|
||||
'Menlo',
|
||||
'Ubuntu Mono',
|
||||
'Consolas',
|
||||
'source-code-pro',
|
||||
'monospace'
|
||||
]
|
||||
export default class MarkdownPreview extends React.Component {
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
this.contextMenuHandler = (e) => this.handleContextMenu(e)
|
||||
this.mouseDownHandler = (e) => this.handleMouseDown(e)
|
||||
this.mouseUpHandler = (e) => this.handleMouseUp(e)
|
||||
this.DoubleClickHandler = (e) => this.handleDoubleClick(e)
|
||||
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
||||
this.checkboxClickHandler = (e) => this.handleCheckboxClick(e)
|
||||
this.state = {
|
||||
isReady: false
|
||||
}
|
||||
this.contextMenuHandler = e => this.handleContextMenu(e)
|
||||
this.mouseDownHandler = e => this.handleMouseDown(e)
|
||||
this.mouseUpHandler = e => this.handleMouseUp(e)
|
||||
this.DoubleClickHandler = e => this.handleDoubleClick(e)
|
||||
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {
|
||||
leading: false,
|
||||
trailing: true
|
||||
})
|
||||
this.checkboxClickHandler = e => this.handleCheckboxClick(e)
|
||||
this.saveAsTextHandler = () => this.handleSaveAsText()
|
||||
this.saveAsMdHandler = () => this.handleSaveAsMd()
|
||||
this.saveAsHtmlHandler = () => this.handleSaveAsHtml()
|
||||
@@ -235,14 +256,20 @@ export default class MarkdownPreview extends React.Component {
|
||||
this.exportAsDocument('md', (noteContent, exportTasks) => {
|
||||
let result = noteContent
|
||||
if (this.props && this.props.storagePath && this.props.noteKey) {
|
||||
const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent(noteContent, this.props.storagePath)
|
||||
attachmentsAbsolutePaths.forEach((attachment) => {
|
||||
const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent(
|
||||
noteContent,
|
||||
this.props.storagePath
|
||||
)
|
||||
attachmentsAbsolutePaths.forEach(attachment => {
|
||||
exportTasks.push({
|
||||
src: attachment,
|
||||
dst: attachmentManagement.DESTINATION_FOLDER
|
||||
})
|
||||
})
|
||||
result = attachmentManagement.removeStorageAndNoteReferences(noteContent, this.props.noteKey)
|
||||
result = attachmentManagement.removeStorageAndNoteReferences(
|
||||
noteContent,
|
||||
this.props.noteKey
|
||||
)
|
||||
}
|
||||
return result
|
||||
})
|
||||
@@ -250,36 +277,61 @@ export default class MarkdownPreview extends React.Component {
|
||||
|
||||
handleSaveAsHtml () {
|
||||
this.exportAsDocument('html', (noteContent, exportTasks) => {
|
||||
const {fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, scrollPastEnd, theme, allowCustomCSS, customCSS} = this.getStyleParams()
|
||||
|
||||
const inlineStyles = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, scrollPastEnd, theme, allowCustomCSS, customCSS)
|
||||
let body = this.markdown.render(escapeHtmlCharacters(noteContent, { detectCodeBlock: true }))
|
||||
const {
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
codeBlockTheme,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
} = this.getStyleParams()
|
||||
|
||||
const inlineStyles = buildStyle(
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
)
|
||||
let body = this.markdown.render(
|
||||
escapeHtmlCharacters(noteContent, { detectCodeBlock: true })
|
||||
)
|
||||
const files = [this.GetCodeThemeLink(codeBlockTheme), ...CSS_FILES]
|
||||
const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent(noteContent, this.props.storagePath)
|
||||
const attachmentsAbsolutePaths = attachmentManagement.getAbsolutePathsOfAttachmentsInContent(
|
||||
noteContent,
|
||||
this.props.storagePath
|
||||
)
|
||||
|
||||
files.forEach((file) => {
|
||||
files.forEach(file => {
|
||||
if (global.process.platform === 'win32') {
|
||||
file = file.replace('file:///', '')
|
||||
} else {
|
||||
file = file.replace('file://', '')
|
||||
}
|
||||
|
||||
exportTasks.push({
|
||||
src: file,
|
||||
dst: 'css'
|
||||
})
|
||||
})
|
||||
attachmentsAbsolutePaths.forEach((attachment) => {
|
||||
attachmentsAbsolutePaths.forEach(attachment => {
|
||||
exportTasks.push({
|
||||
src: attachment,
|
||||
dst: attachmentManagement.DESTINATION_FOLDER
|
||||
})
|
||||
})
|
||||
body = attachmentManagement.removeStorageAndNoteReferences(body, this.props.noteKey)
|
||||
body = attachmentManagement.removeStorageAndNoteReferences(
|
||||
body,
|
||||
this.props.noteKey
|
||||
)
|
||||
|
||||
let styles = ''
|
||||
files.forEach((file) => {
|
||||
files.forEach(file => {
|
||||
styles += `<link rel="stylesheet" href="css/${path.basename(file)}">`
|
||||
})
|
||||
|
||||
@@ -301,43 +353,47 @@ export default class MarkdownPreview extends React.Component {
|
||||
|
||||
exportAsDocument (fileType, contentFormatter) {
|
||||
const options = {
|
||||
filters: [
|
||||
{name: 'Documents', extensions: [fileType]}
|
||||
],
|
||||
filters: [{ name: 'Documents', extensions: [fileType] }],
|
||||
properties: ['openFile', 'createDirectory']
|
||||
}
|
||||
|
||||
dialog.showSaveDialog(remote.getCurrentWindow(), options,
|
||||
(filename) => {
|
||||
if (filename) {
|
||||
const content = this.props.value
|
||||
const storage = this.props.storagePath
|
||||
dialog.showSaveDialog(remote.getCurrentWindow(), options, filename => {
|
||||
if (filename) {
|
||||
const content = this.props.value
|
||||
const storage = this.props.storagePath
|
||||
|
||||
exportNote(storage, content, filename, contentFormatter)
|
||||
.then((res) => {
|
||||
dialog.showMessageBox(remote.getCurrentWindow(), {type: 'info', message: `Exported to ${filename}`})
|
||||
}).catch((err) => {
|
||||
dialog.showErrorBox('Export error', err ? err.message || err : 'Unexpected error during export')
|
||||
throw err
|
||||
})
|
||||
}
|
||||
})
|
||||
exportNote(storage, content, filename, contentFormatter)
|
||||
.then(res => {
|
||||
dialog.showMessageBox(remote.getCurrentWindow(), {
|
||||
type: 'info',
|
||||
message: `Exported to ${filename}`
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
dialog.showErrorBox(
|
||||
'Export error',
|
||||
err ? err.message || err : 'Unexpected error during export'
|
||||
)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fixDecodedURI (node) {
|
||||
if (node && node.children.length === 1 && typeof node.children[0] === 'string') {
|
||||
if (
|
||||
node &&
|
||||
node.children.length === 1 &&
|
||||
typeof node.children[0] === 'string'
|
||||
) {
|
||||
const { innerText, href } = node
|
||||
|
||||
node.innerText = mdurl.decode(href) === innerText
|
||||
? href
|
||||
: innerText
|
||||
node.innerText = mdurl.decode(href) === innerText ? href : innerText
|
||||
}
|
||||
}
|
||||
|
||||
getScrollBarStyle () {
|
||||
const {
|
||||
theme
|
||||
} = this.props
|
||||
const { theme } = this.props
|
||||
|
||||
switch (theme) {
|
||||
case 'dark':
|
||||
@@ -351,7 +407,10 @@ export default class MarkdownPreview extends React.Component {
|
||||
|
||||
componentDidMount () {
|
||||
this.refs.root.setAttribute('sandbox', 'allow-scripts')
|
||||
this.refs.root.contentWindow.document.body.addEventListener('contextmenu', this.contextMenuHandler)
|
||||
this.refs.root.contentWindow.document.body.addEventListener(
|
||||
'contextmenu',
|
||||
this.contextMenuHandler
|
||||
)
|
||||
|
||||
let styles = `
|
||||
<style id='style'></style>
|
||||
@@ -362,7 +421,7 @@ export default class MarkdownPreview extends React.Component {
|
||||
</style>
|
||||
`
|
||||
|
||||
CSS_FILES.forEach((file) => {
|
||||
CSS_FILES.forEach(file => {
|
||||
styles += `<link rel="stylesheet" href="${file}">`
|
||||
})
|
||||
|
||||
@@ -370,26 +429,66 @@ export default class MarkdownPreview extends React.Component {
|
||||
this.rewriteIframe()
|
||||
this.applyStyle()
|
||||
|
||||
this.refs.root.contentWindow.document.addEventListener('mousedown', this.mouseDownHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener('mouseup', this.mouseUpHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener('dblclick', this.DoubleClickHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener('drop', this.preventImageDroppedHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener('dragover', this.preventImageDroppedHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener('scroll', this.scrollHandler)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'mousedown',
|
||||
this.mouseDownHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'mouseup',
|
||||
this.mouseUpHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'dblclick',
|
||||
this.DoubleClickHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'drop',
|
||||
this.preventImageDroppedHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'dragover',
|
||||
this.preventImageDroppedHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.addEventListener(
|
||||
'scroll',
|
||||
this.scrollHandler
|
||||
)
|
||||
eventEmitter.on('export:save-text', this.saveAsTextHandler)
|
||||
eventEmitter.on('export:save-md', this.saveAsMdHandler)
|
||||
eventEmitter.on('export:save-html', this.saveAsHtmlHandler)
|
||||
eventEmitter.on('print', this.printHandler)
|
||||
setTimeout(() => this.setState({ isReady: true }))
|
||||
}
|
||||
|
||||
componentWillUnmount () {
|
||||
this.refs.root.contentWindow.document.body.removeEventListener('contextmenu', this.contextMenuHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('mousedown', this.mouseDownHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('mouseup', this.mouseUpHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('dblclick', this.DoubleClickHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('drop', this.preventImageDroppedHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('dragover', this.preventImageDroppedHandler)
|
||||
this.refs.root.contentWindow.document.removeEventListener('scroll', this.scrollHandler)
|
||||
this.refs.root.contentWindow.document.body.removeEventListener(
|
||||
'contextmenu',
|
||||
this.contextMenuHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'mousedown',
|
||||
this.mouseDownHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'mouseup',
|
||||
this.mouseUpHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'dblclick',
|
||||
this.DoubleClickHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'drop',
|
||||
this.preventImageDroppedHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'dragover',
|
||||
this.preventImageDroppedHandler
|
||||
)
|
||||
this.refs.root.contentWindow.document.removeEventListener(
|
||||
'scroll',
|
||||
this.scrollHandler
|
||||
)
|
||||
eventEmitter.off('export:save-text', this.saveAsTextHandler)
|
||||
eventEmitter.off('export:save-md', this.saveAsMdHandler)
|
||||
eventEmitter.off('export:save-html', this.saveAsHtmlHandler)
|
||||
@@ -398,14 +497,17 @@ export default class MarkdownPreview extends React.Component {
|
||||
|
||||
componentDidUpdate (prevProps) {
|
||||
if (prevProps.value !== this.props.value) this.rewriteIframe()
|
||||
if (prevProps.smartQuotes !== this.props.smartQuotes ||
|
||||
prevProps.sanitize !== this.props.sanitize ||
|
||||
prevProps.smartArrows !== this.props.smartArrows ||
|
||||
prevProps.breaks !== this.props.breaks) {
|
||||
if (
|
||||
prevProps.smartQuotes !== this.props.smartQuotes ||
|
||||
prevProps.sanitize !== this.props.sanitize ||
|
||||
prevProps.smartArrows !== this.props.smartArrows ||
|
||||
prevProps.breaks !== this.props.breaks
|
||||
) {
|
||||
this.initMarkdown()
|
||||
this.rewriteIframe()
|
||||
}
|
||||
if (prevProps.fontFamily !== this.props.fontFamily ||
|
||||
if (
|
||||
prevProps.fontFamily !== this.props.fontFamily ||
|
||||
prevProps.fontSize !== this.props.fontSize ||
|
||||
prevProps.codeBlockFontFamily !== this.props.codeBlockFontFamily ||
|
||||
prevProps.codeBlockTheme !== this.props.codeBlockTheme ||
|
||||
@@ -414,34 +516,82 @@ 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
|
||||
) {
|
||||
this.applyStyle()
|
||||
this.rewriteIframe()
|
||||
}
|
||||
}
|
||||
|
||||
getStyleParams () {
|
||||
const { fontSize, lineNumber, codeBlockTheme, scrollPastEnd, theme, allowCustomCSS, customCSS } = this.props
|
||||
const {
|
||||
fontSize,
|
||||
lineNumber,
|
||||
codeBlockTheme,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
} = this.props
|
||||
let { fontFamily, codeBlockFontFamily } = this.props
|
||||
fontFamily = _.isString(fontFamily) && fontFamily.trim().length > 0
|
||||
? fontFamily.split(',').map(fontName => fontName.trim()).concat(defaultFontFamily)
|
||||
: defaultFontFamily
|
||||
codeBlockFontFamily = _.isString(codeBlockFontFamily) && codeBlockFontFamily.trim().length > 0
|
||||
? codeBlockFontFamily.split(',').map(fontName => fontName.trim()).concat(defaultCodeBlockFontFamily)
|
||||
: defaultCodeBlockFontFamily
|
||||
? fontFamily
|
||||
.split(',')
|
||||
.map(fontName => fontName.trim())
|
||||
.concat(defaultFontFamily)
|
||||
: defaultFontFamily
|
||||
codeBlockFontFamily = _.isString(codeBlockFontFamily) &&
|
||||
codeBlockFontFamily.trim().length > 0
|
||||
? codeBlockFontFamily
|
||||
.split(',')
|
||||
.map(fontName => fontName.trim())
|
||||
.concat(defaultCodeBlockFontFamily)
|
||||
: defaultCodeBlockFontFamily
|
||||
|
||||
return {fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, scrollPastEnd, theme, allowCustomCSS, customCSS}
|
||||
return {
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
codeBlockTheme,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
}
|
||||
}
|
||||
|
||||
applyStyle () {
|
||||
const {fontFamily, fontSize, codeBlockFontFamily, lineNumber, codeBlockTheme, scrollPastEnd, theme, allowCustomCSS, customCSS} = this.getStyleParams()
|
||||
const {
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
codeBlockTheme,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
} = this.getStyleParams()
|
||||
|
||||
this.getWindow().document.getElementById('codeTheme').href = this.GetCodeThemeLink(codeBlockTheme)
|
||||
this.getWindow().document.getElementById('style').innerHTML = buildStyle(fontFamily, fontSize, codeBlockFontFamily, lineNumber, scrollPastEnd, theme, allowCustomCSS, customCSS)
|
||||
this.getWindow().document.getElementById(
|
||||
'codeTheme'
|
||||
).href = this.GetCodeThemeLink(codeBlockTheme)
|
||||
this.getWindow().document.getElementById('style').innerHTML = buildStyle(
|
||||
fontFamily,
|
||||
fontSize,
|
||||
codeBlockFontFamily,
|
||||
lineNumber,
|
||||
scrollPastEnd,
|
||||
theme,
|
||||
allowCustomCSS,
|
||||
customCSS
|
||||
)
|
||||
}
|
||||
|
||||
GetCodeThemeLink (theme) {
|
||||
theme = consts.THEMES.some((_theme) => _theme === theme) && theme !== 'default'
|
||||
theme = consts.THEMES.some(_theme => _theme === theme) &&
|
||||
theme !== 'default'
|
||||
? theme
|
||||
: 'elegant'
|
||||
return theme.startsWith('solarized')
|
||||
@@ -450,64 +600,92 @@ export default class MarkdownPreview extends React.Component {
|
||||
}
|
||||
|
||||
rewriteIframe () {
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
||||
el.removeEventListener('click', this.checkboxClickHandler)
|
||||
})
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll(
|
||||
'input[type="checkbox"]'
|
||||
),
|
||||
el => {
|
||||
el.removeEventListener('click', this.checkboxClickHandler)
|
||||
}
|
||||
)
|
||||
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
||||
el.removeEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('a'),
|
||||
el => {
|
||||
el.removeEventListener('click', this.linkClickHandler)
|
||||
}
|
||||
)
|
||||
|
||||
const { theme, indentSize, showCopyNotification, storagePath, noteKey } = this.props
|
||||
const {
|
||||
theme,
|
||||
indentSize,
|
||||
showCopyNotification,
|
||||
storagePath,
|
||||
noteKey
|
||||
} = this.props
|
||||
let { value, codeBlockTheme } = this.props
|
||||
|
||||
this.refs.root.contentWindow.document.body.setAttribute('data-theme', theme)
|
||||
const renderedHTML = this.markdown.render(value)
|
||||
attachmentManagement.migrateAttachments(value, storagePath, noteKey)
|
||||
this.refs.root.contentWindow.document.body.innerHTML = attachmentManagement.fixLocalURLS(renderedHTML, storagePath)
|
||||
this.refs.root.contentWindow.document.body.innerHTML = attachmentManagement.fixLocalURLS(
|
||||
renderedHTML,
|
||||
storagePath
|
||||
)
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll(
|
||||
'input[type="checkbox"]'
|
||||
),
|
||||
el => {
|
||||
el.addEventListener('click', this.checkboxClickHandler)
|
||||
}
|
||||
)
|
||||
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('input[type="checkbox"]'), (el) => {
|
||||
el.addEventListener('click', this.checkboxClickHandler)
|
||||
})
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('a'),
|
||||
el => {
|
||||
this.fixDecodedURI(el)
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
}
|
||||
)
|
||||
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('a'), (el) => {
|
||||
this.fixDecodedURI(el)
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
|
||||
codeBlockTheme = consts.THEMES.some((_theme) => _theme === codeBlockTheme)
|
||||
codeBlockTheme = consts.THEMES.some(_theme => _theme === codeBlockTheme)
|
||||
? codeBlockTheme
|
||||
: 'default'
|
||||
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.code code'), (el) => {
|
||||
let syntax = CodeMirror.findModeByName(convertModeName(el.className))
|
||||
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
|
||||
CodeMirror.requireMode(syntax.mode, () => {
|
||||
const content = htmlTextHelper.decodeEntities(el.innerHTML)
|
||||
const copyIcon = document.createElement('i')
|
||||
copyIcon.innerHTML = '<button class="clipboardButton"><svg width="13" height="13" viewBox="0 0 1792 1792" ><path d="M768 1664h896v-640h-416q-40 0-68-28t-28-68v-416h-384v1152zm256-1440v-64q0-13-9.5-22.5t-22.5-9.5h-704q-13 0-22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h704q13 0 22.5-9.5t9.5-22.5zm256 672h299l-299-299v299zm512 128v672q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-160h-544q-40 0-68-28t-28-68v-1344q0-40 28-68t68-28h1088q40 0 68 28t28 68v328q21 13 36 28l408 408q28 28 48 76t20 88z"/></svg></button>'
|
||||
copyIcon.onclick = (e) => {
|
||||
copy(content)
|
||||
if (showCopyNotification) {
|
||||
this.notify('Saved to Clipboard!', {
|
||||
body: 'Paste it wherever you want!',
|
||||
silent: true
|
||||
})
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('.code code'),
|
||||
el => {
|
||||
let syntax = CodeMirror.findModeByName(convertModeName(el.className))
|
||||
if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text')
|
||||
CodeMirror.requireMode(syntax.mode, () => {
|
||||
const content = htmlTextHelper.decodeEntities(el.innerHTML)
|
||||
const copyIcon = document.createElement('i')
|
||||
copyIcon.innerHTML =
|
||||
'<button class="clipboardButton"><svg width="13" height="13" viewBox="0 0 1792 1792" ><path d="M768 1664h896v-640h-416q-40 0-68-28t-28-68v-416h-384v1152zm256-1440v-64q0-13-9.5-22.5t-22.5-9.5h-704q-13 0-22.5 9.5t-9.5 22.5v64q0 13 9.5 22.5t22.5 9.5h704q13 0 22.5-9.5t9.5-22.5zm256 672h299l-299-299v299zm512 128v672q0 40-28 68t-68 28h-960q-40 0-68-28t-28-68v-160h-544q-40 0-68-28t-28-68v-1344q0-40 28-68t68-28h1088q40 0 68 28t28 68v328q21 13 36 28l408 408q28 28 48 76t20 88z"/></svg></button>'
|
||||
copyIcon.onclick = e => {
|
||||
copy(content)
|
||||
if (showCopyNotification) {
|
||||
this.notify('Saved to Clipboard!', {
|
||||
body: 'Paste it wherever you want!',
|
||||
silent: true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
el.parentNode.appendChild(copyIcon)
|
||||
el.innerHTML = ''
|
||||
if (codeBlockTheme.indexOf('solarized') === 0) {
|
||||
const [refThema, color] = codeBlockTheme.split(' ')
|
||||
el.parentNode.className += ` cm-s-${refThema} cm-s-${color}`
|
||||
} else {
|
||||
el.parentNode.className += ` cm-s-${codeBlockTheme}`
|
||||
}
|
||||
CodeMirror.runMode(content, syntax.mime, el, {
|
||||
tabSize: indentSize
|
||||
el.parentNode.appendChild(copyIcon)
|
||||
el.innerHTML = ''
|
||||
if (codeBlockTheme.indexOf('solarized') === 0) {
|
||||
const [refThema, color] = codeBlockTheme.split(' ')
|
||||
el.parentNode.className += ` cm-s-${refThema} cm-s-${color}`
|
||||
} else {
|
||||
el.parentNode.className += ` cm-s-${codeBlockTheme}`
|
||||
}
|
||||
CodeMirror.runMode(content, syntax.mime, el, {
|
||||
tabSize: indentSize
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
)
|
||||
const opts = {}
|
||||
// if (this.props.theme === 'dark') {
|
||||
// opts['font-color'] = '#DDD'
|
||||
@@ -515,41 +693,51 @@ export default class MarkdownPreview extends React.Component {
|
||||
// opts['element-color'] = '#DDD'
|
||||
// opts['fill'] = '#3A404C'
|
||||
// }
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.flowchart'), (el) => {
|
||||
Raphael.setWindow(this.getWindow())
|
||||
try {
|
||||
const diagram = flowchart.parse(htmlTextHelper.decodeEntities(el.innerHTML))
|
||||
el.innerHTML = ''
|
||||
diagram.drawSVG(el, opts)
|
||||
_.forEach(el.querySelectorAll('a'), (el) => {
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
el.className = 'flowchart-error'
|
||||
el.innerHTML = 'Flowchart parse error: ' + e.message
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('.flowchart'),
|
||||
el => {
|
||||
Raphael.setWindow(this.getWindow())
|
||||
try {
|
||||
const diagram = flowchart.parse(
|
||||
htmlTextHelper.decodeEntities(el.innerHTML)
|
||||
)
|
||||
el.innerHTML = ''
|
||||
diagram.drawSVG(el, opts)
|
||||
_.forEach(el.querySelectorAll('a'), el => {
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
el.className = 'flowchart-error'
|
||||
el.innerHTML = 'Flowchart parse error: ' + e.message
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
_.forEach(this.refs.root.contentWindow.document.querySelectorAll('.sequence'), (el) => {
|
||||
Raphael.setWindow(this.getWindow())
|
||||
try {
|
||||
const diagram = SequenceDiagram.parse(htmlTextHelper.decodeEntities(el.innerHTML))
|
||||
el.innerHTML = ''
|
||||
diagram.drawSVG(el, {theme: 'simple'})
|
||||
_.forEach(el.querySelectorAll('a'), (el) => {
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
el.className = 'sequence-error'
|
||||
el.innerHTML = 'Sequence diagram parse error: ' + e.message
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('.sequence'),
|
||||
el => {
|
||||
Raphael.setWindow(this.getWindow())
|
||||
try {
|
||||
const diagram = SequenceDiagram.parse(
|
||||
htmlTextHelper.decodeEntities(el.innerHTML)
|
||||
)
|
||||
el.innerHTML = ''
|
||||
diagram.drawSVG(el, { theme: 'simple' })
|
||||
_.forEach(el.querySelectorAll('a'), el => {
|
||||
el.addEventListener('click', this.linkClickHandler)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
el.className = 'sequence-error'
|
||||
el.innerHTML = 'Sequence diagram parse error: ' + e.message
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('.chart'),
|
||||
(el) => {
|
||||
el => {
|
||||
try {
|
||||
const chartConfig = JSON.parse(el.innerHTML)
|
||||
el.innerHTML = ''
|
||||
@@ -566,7 +754,7 @@ export default class MarkdownPreview extends React.Component {
|
||||
)
|
||||
_.forEach(
|
||||
this.refs.root.contentWindow.document.querySelectorAll('.mermaid'),
|
||||
(el) => {
|
||||
el => {
|
||||
mermaidRender(el, htmlTextHelper.decodeEntities(el.innerHTML), theme)
|
||||
}
|
||||
)
|
||||
@@ -581,7 +769,9 @@ export default class MarkdownPreview extends React.Component {
|
||||
}
|
||||
|
||||
scrollTo (targetRow) {
|
||||
const blocks = this.getWindow().document.querySelectorAll('body>[data-line]')
|
||||
const blocks = this.getWindow().document.querySelectorAll(
|
||||
'body>[data-line]'
|
||||
)
|
||||
|
||||
for (let index = 0; index < blocks.length; index++) {
|
||||
let block = blocks[index]
|
||||
@@ -601,7 +791,11 @@ export default class MarkdownPreview extends React.Component {
|
||||
|
||||
notify (title, options) {
|
||||
if (global.process.platform === 'win32') {
|
||||
options.icon = path.join('file://', global.__dirname, '../../resources/app.png')
|
||||
options.icon = path.join(
|
||||
'file://',
|
||||
global.__dirname,
|
||||
'../../resources/app.png'
|
||||
)
|
||||
}
|
||||
return new window.Notification(title, options)
|
||||
}
|
||||
@@ -616,7 +810,9 @@ export default class MarkdownPreview extends React.Component {
|
||||
const regexNoteInternalLink = /main.html#(.+)/
|
||||
if (regexNoteInternalLink.test(linkHash)) {
|
||||
const targetId = mdurl.encode(linkHash.match(regexNoteInternalLink)[1])
|
||||
const targetElement = this.refs.root.contentWindow.document.getElementById(targetId)
|
||||
const targetElement = this.refs.root.contentWindow.document.getElementById(
|
||||
targetId
|
||||
)
|
||||
|
||||
if (targetElement != null) {
|
||||
this.getWindow().scrollTo(0, targetElement.offsetTop)
|
||||
@@ -650,11 +846,15 @@ export default class MarkdownPreview extends React.Component {
|
||||
render () {
|
||||
const { className, style, tabIndex } = this.props
|
||||
return (
|
||||
<iframe className={className != null
|
||||
? 'MarkdownPreview ' + className
|
||||
: 'MarkdownPreview'
|
||||
<iframe
|
||||
className={
|
||||
className != null ? 'MarkdownPreview ' + className : 'MarkdownPreview'
|
||||
}
|
||||
style={
|
||||
this.state.isReady
|
||||
? Object.assign(style, { opacity: '1' })
|
||||
: Object.assign(style, { opacity: '0' })
|
||||
}
|
||||
style={style}
|
||||
tabIndex={tabIndex}
|
||||
ref='root'
|
||||
/>
|
||||
|
||||
@@ -26,14 +26,12 @@ const TagElement = ({ tagName }) => (
|
||||
* @param {Array|null} tags
|
||||
* @return {React.Component}
|
||||
*/
|
||||
const TagElementList = (tags) => {
|
||||
const TagElementList = tags => {
|
||||
if (!isArray(tags)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const tagElements = tags.map(tag => (
|
||||
TagElement({tagName: tag})
|
||||
))
|
||||
const tagElements = tags.map(tag => TagElement({ tagName: tag }))
|
||||
|
||||
return tagElements
|
||||
}
|
||||
@@ -59,10 +57,8 @@ const NoteItem = ({
|
||||
folderName,
|
||||
viewType
|
||||
}) => (
|
||||
<div styleName={isActive
|
||||
? 'item--active'
|
||||
: 'item'
|
||||
}
|
||||
<div
|
||||
styleName={isActive ? 'item--active' : 'item'}
|
||||
key={note.key}
|
||||
onClick={e => handleNoteClick(e, note.key)}
|
||||
onContextMenu={e => handleNoteContextMenu(e, note.key)}
|
||||
@@ -72,42 +68,54 @@ const NoteItem = ({
|
||||
<div styleName='item-wrapper'>
|
||||
{note.type === 'SNIPPET_NOTE'
|
||||
? <i styleName='item-title-icon' className='fa fa-fw fa-code' />
|
||||
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o' />
|
||||
}
|
||||
: <i styleName='item-title-icon' className='fa fa-fw fa-file-text-o' />}
|
||||
<div styleName='item-title'>
|
||||
{note.title.trim().length > 0
|
||||
? note.title
|
||||
: <span styleName='item-title-empty'>{i18n.__('Empty note')}</span>
|
||||
}
|
||||
: <span styleName='item-title-empty'>{i18n.__('Empty note')}</span>}
|
||||
</div>
|
||||
{['ALL', 'STORAGE'].includes(viewType) && <div styleName='item-middle'>
|
||||
<div styleName='item-middle-time'>{dateDisplay}</div>
|
||||
<div styleName='item-middle-app-meta'>
|
||||
<div title={viewType === 'ALL' ? storageName : viewType === 'STORAGE' ? folderName : null} styleName='item-middle-app-meta-label'>
|
||||
{viewType === 'ALL' && storageName}
|
||||
{viewType === 'STORAGE' && folderName}
|
||||
{['ALL', 'STORAGE'].includes(viewType) &&
|
||||
<div styleName='item-middle'>
|
||||
<div styleName='item-middle-time'>{dateDisplay}</div>
|
||||
<div styleName='item-middle-app-meta'>
|
||||
<div
|
||||
title={
|
||||
viewType === 'ALL'
|
||||
? storageName
|
||||
: viewType === 'STORAGE' ? folderName : null
|
||||
}
|
||||
styleName='item-middle-app-meta-label'
|
||||
>
|
||||
{viewType === 'ALL' && storageName}
|
||||
{viewType === 'STORAGE' && folderName}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>}
|
||||
</div>}
|
||||
|
||||
<div styleName='item-bottom'>
|
||||
<div styleName='item-bottom-tagList'>
|
||||
{note.tags.length > 0
|
||||
? TagElementList(note.tags)
|
||||
: <span style={{ fontStyle: 'italic', opacity: 0.5 }} styleName='item-bottom-tagList-empty'>{i18n.__('No tags')}</span>
|
||||
}
|
||||
: <span
|
||||
style={{ fontStyle: 'italic', opacity: 0.5 }}
|
||||
styleName='item-bottom-tagList-empty'
|
||||
>
|
||||
{i18n.__('No tags')}
|
||||
</span>}
|
||||
</div>
|
||||
<div>
|
||||
{note.isStarred
|
||||
? <img styleName='item-star' src='../resources/icon/icon-starred.svg' /> : ''
|
||||
}
|
||||
? <img
|
||||
styleName='item-star'
|
||||
src='../resources/icon/icon-starred.svg'
|
||||
/>
|
||||
: ''}
|
||||
{note.isPinned && !pathname.match(/\/starred|\/trash/)
|
||||
? <i styleName='item-pin' className='fa fa-thumb-tack' /> : ''
|
||||
}
|
||||
? <i styleName='item-pin' className='fa fa-thumb-tack' />
|
||||
: ''}
|
||||
{note.type === 'MARKDOWN_NOTE'
|
||||
? <TodoProcess todoStatus={getTodoStatus(note.content)} />
|
||||
: ''
|
||||
}
|
||||
: ''}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -54,9 +54,8 @@ const StorageItem = ({
|
||||
onDragEnter={handleDragEnter}
|
||||
onDragLeave={handleDragLeave}
|
||||
>
|
||||
{!isFolded && (
|
||||
<DraggableIcon className={styles['folderList-item-reorder']} />
|
||||
)}
|
||||
{!isFolded &&
|
||||
<DraggableIcon className={styles['folderList-item-reorder']} />}
|
||||
<span
|
||||
styleName={
|
||||
isFolded ? 'folderList-item-name--folded' : 'folderList-item-name'
|
||||
@@ -72,12 +71,10 @@ const StorageItem = ({
|
||||
: folderName}
|
||||
</span>
|
||||
{!isFolded &&
|
||||
_.isNumber(noteCount) && (
|
||||
<span styleName='folderList-item-noteCount'>{noteCount}</span>
|
||||
)}
|
||||
{isFolded && (
|
||||
<span styleName='folderList-item-tooltip'>{folderName}</span>
|
||||
)}
|
||||
_.isNumber(noteCount) &&
|
||||
<span styleName='folderList-item-noteCount'>{noteCount}</span>}
|
||||
{isFolded &&
|
||||
<span styleName='folderList-item-tooltip'>{folderName}</span>}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ export function getTodoStatus (content) {
|
||||
|
||||
splitted.forEach((line) => {
|
||||
const trimmedLine = line.trim()
|
||||
if (trimmedLine.match(/^[\+\-\*] \[(\s|x)\] ./)) {
|
||||
if (trimmedLine.match(/^[\+\-\*] \[(\s|x)\] ./i)) {
|
||||
numberOfTodo++
|
||||
}
|
||||
if (trimmedLine.match(/^[\+\-\*] \[x\] ./)) {
|
||||
if (trimmedLine.match(/^[\+\-\*] \[x\] ./i)) {
|
||||
numberOfCompletedTodo++
|
||||
}
|
||||
})
|
||||
|
||||
@@ -22,7 +22,6 @@ const electron = require('electron')
|
||||
const { remote } = electron
|
||||
|
||||
class Main extends React.Component {
|
||||
|
||||
constructor (props) {
|
||||
super(props)
|
||||
|
||||
@@ -60,10 +59,10 @@ class Main extends React.Component {
|
||||
name: 'My Storage',
|
||||
path: path.join(remote.app.getPath('home'), 'Boostnote')
|
||||
})
|
||||
.then((data) => {
|
||||
.then(data => {
|
||||
return data
|
||||
})
|
||||
.then((data) => {
|
||||
.then(data => {
|
||||
if (data.storage.folders[0] != null) {
|
||||
return data
|
||||
} else {
|
||||
@@ -72,7 +71,7 @@ class Main extends React.Component {
|
||||
color: '#1278BD',
|
||||
name: 'Default'
|
||||
})
|
||||
.then((_data) => {
|
||||
.then(_data => {
|
||||
return {
|
||||
storage: _data.storage,
|
||||
notes: data.notes
|
||||
@@ -80,7 +79,7 @@ class Main extends React.Component {
|
||||
})
|
||||
}
|
||||
})
|
||||
.then((data) => {
|
||||
.then(data => {
|
||||
console.log(data)
|
||||
store.dispatch({
|
||||
type: 'ADD_STORAGE',
|
||||
@@ -98,16 +97,16 @@ class Main extends React.Component {
|
||||
{
|
||||
name: 'example.html',
|
||||
mode: 'html',
|
||||
content: '<html>\n<body>\n<h1 id=\'hello\'>Enjoy Boostnote!</h1>\n</body>\n</html>'
|
||||
content: "<html>\n<body>\n<h1 id='hello'>Enjoy Boostnote!</h1>\n</body>\n</html>"
|
||||
},
|
||||
{
|
||||
name: 'example.js',
|
||||
mode: 'javascript',
|
||||
content: 'var boostnote = document.getElementById(\'enjoy\').innerHTML\n\nconsole.log(boostnote)'
|
||||
content: "var boostnote = document.getElementById('enjoy').innerHTML\n\nconsole.log(boostnote)"
|
||||
}
|
||||
]
|
||||
})
|
||||
.then((note) => {
|
||||
.then(note => {
|
||||
store.dispatch({
|
||||
type: 'UPDATE_NOTE',
|
||||
note: note
|
||||
@@ -120,7 +119,7 @@ class Main extends React.Component {
|
||||
title: 'Welcome to Boostnote!',
|
||||
content: '# Welcome to Boostnote!\n## Click here to edit markdown :wave:\n\n<iframe width="560" height="315" src="https://www.youtube.com/embed/L0qNPLsvmyM" frameborder="0" allowfullscreen></iframe>\n\n## Docs :memo:\n- [Boostnote | Boost your happiness, productivity and creativity.](https://hackernoon.com/boostnote-boost-your-happiness-productivity-and-creativity-315034efeebe)\n- [Cloud Syncing & Backups](https://github.com/BoostIO/Boostnote/wiki/Cloud-Syncing-and-Backup)\n- [How to sync your data across Desktop and Mobile apps](https://github.com/BoostIO/Boostnote/wiki/Sync-Data-Across-Desktop-and-Mobile-apps)\n- [Convert data from **Evernote** to Boostnote.](https://github.com/BoostIO/Boostnote/wiki/Evernote)\n- [Keyboard Shortcuts](https://github.com/BoostIO/Boostnote/wiki/Keyboard-Shortcuts)\n- [Keymaps in Editor mode](https://github.com/BoostIO/Boostnote/wiki/Keymaps-in-Editor-mode)\n- [How to set syntax highlight in Snippet note](https://github.com/BoostIO/Boostnote/wiki/Syntax-Highlighting)\n\n---\n\n## Article Archive :books:\n- [Reddit English](http://bit.ly/2mOJPu7)\n- [Reddit Spanish](https://www.reddit.com/r/boostnote_es/)\n- [Reddit Chinese](https://www.reddit.com/r/boostnote_cn/)\n- [Reddit Japanese](https://www.reddit.com/r/boostnote_jp/)\n\n---\n\n## Community :beers:\n- [GitHub](http://bit.ly/2AWWzkD)\n- [Twitter](http://bit.ly/2z8BUJZ)\n- [Facebook Group](http://bit.ly/2jcca8t)'
|
||||
})
|
||||
.then((note) => {
|
||||
.then(note => {
|
||||
store.dispatch({
|
||||
type: 'UPDATE_NOTE',
|
||||
note: note
|
||||
@@ -131,10 +130,10 @@ class Main extends React.Component {
|
||||
.then(defaultMarkdownNote)
|
||||
.then(() => data.storage)
|
||||
})
|
||||
.then((storage) => {
|
||||
.then(storage => {
|
||||
hashHistory.push('/storages/' + storage.key)
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -142,12 +141,7 @@ class Main extends React.Component {
|
||||
componentDidMount () {
|
||||
const { dispatch, config } = this.props
|
||||
|
||||
const supportedThemes = [
|
||||
'dark',
|
||||
'white',
|
||||
'solarized-dark',
|
||||
'monokai'
|
||||
]
|
||||
const supportedThemes = ['dark', 'white', 'solarized-dark', 'monokai']
|
||||
|
||||
if (supportedThemes.indexOf(config.ui.theme) !== -1) {
|
||||
document.body.setAttribute('data-theme', config.ui.theme)
|
||||
@@ -162,19 +156,18 @@ class Main extends React.Component {
|
||||
}
|
||||
applyShortcuts()
|
||||
// Reload all data
|
||||
dataApi.init()
|
||||
.then((data) => {
|
||||
dispatch({
|
||||
type: 'INIT_ALL',
|
||||
storages: data.storages,
|
||||
notes: data.notes
|
||||
})
|
||||
|
||||
if (data.storages.length < 1) {
|
||||
this.init()
|
||||
}
|
||||
dataApi.init().then(data => {
|
||||
dispatch({
|
||||
type: 'INIT_ALL',
|
||||
storages: data.storages,
|
||||
notes: data.notes
|
||||
})
|
||||
|
||||
if (data.storages.length < 1) {
|
||||
this.init()
|
||||
}
|
||||
})
|
||||
|
||||
eventEmitter.on('editor:fullscreen', this.toggleFullScreen)
|
||||
}
|
||||
|
||||
@@ -199,34 +192,40 @@ class Main extends React.Component {
|
||||
handleMouseUp (e) {
|
||||
// Change width of NoteList component.
|
||||
if (this.state.isRightSliderFocused) {
|
||||
this.setState({
|
||||
isRightSliderFocused: false
|
||||
}, () => {
|
||||
const { dispatch } = this.props
|
||||
const newListWidth = this.state.listWidth
|
||||
// TODO: ConfigManager should dispatch itself.
|
||||
ConfigManager.set({listWidth: newListWidth})
|
||||
dispatch({
|
||||
type: 'SET_LIST_WIDTH',
|
||||
listWidth: newListWidth
|
||||
})
|
||||
})
|
||||
this.setState(
|
||||
{
|
||||
isRightSliderFocused: false
|
||||
},
|
||||
() => {
|
||||
const { dispatch } = this.props
|
||||
const newListWidth = this.state.listWidth
|
||||
// TODO: ConfigManager should dispatch itself.
|
||||
ConfigManager.set({ listWidth: newListWidth })
|
||||
dispatch({
|
||||
type: 'SET_LIST_WIDTH',
|
||||
listWidth: newListWidth
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Change width of SideNav component.
|
||||
if (this.state.isLeftSliderFocused) {
|
||||
this.setState({
|
||||
isLeftSliderFocused: false
|
||||
}, () => {
|
||||
const { dispatch } = this.props
|
||||
const navWidth = this.state.navWidth
|
||||
// TODO: ConfigManager should dispatch itself.
|
||||
ConfigManager.set({ navWidth })
|
||||
dispatch({
|
||||
type: 'SET_NAV_WIDTH',
|
||||
navWidth
|
||||
})
|
||||
})
|
||||
this.setState(
|
||||
{
|
||||
isLeftSliderFocused: false
|
||||
},
|
||||
() => {
|
||||
const { dispatch } = this.props
|
||||
const navWidth = this.state.navWidth
|
||||
// TODO: ConfigManager should dispatch itself.
|
||||
ConfigManager.set({ navWidth })
|
||||
dispatch({
|
||||
type: 'SET_NAV_WIDTH',
|
||||
navWidth
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,8 +270,8 @@ class Main extends React.Component {
|
||||
}
|
||||
|
||||
hideLeftLists (noteDetail, noteList, mainBody) {
|
||||
this.setState({noteDetailWidth: noteDetail.style.left})
|
||||
this.setState({mainBodyWidth: mainBody.style.left})
|
||||
this.setState({ noteDetailWidth: noteDetail.style.left })
|
||||
this.setState({ mainBodyWidth: mainBody.style.left })
|
||||
noteDetail.style.left = '0px'
|
||||
mainBody.style.left = '0px'
|
||||
noteList.style.display = 'none'
|
||||
@@ -294,33 +293,36 @@ class Main extends React.Component {
|
||||
<div
|
||||
className='Main'
|
||||
styleName='root'
|
||||
onMouseMove={(e) => this.handleMouseMove(e)}
|
||||
onMouseUp={(e) => this.handleMouseUp(e)}
|
||||
onMouseMove={e => this.handleMouseMove(e)}
|
||||
onMouseUp={e => this.handleMouseUp(e)}
|
||||
>
|
||||
<SideNav
|
||||
{..._.pick(this.props, [
|
||||
'dispatch',
|
||||
'data',
|
||||
'config',
|
||||
'location'
|
||||
])}
|
||||
{..._.pick(this.props, ['dispatch', 'data', 'config', 'location'])}
|
||||
width={this.state.navWidth}
|
||||
/>
|
||||
{!config.isSideNavFolded &&
|
||||
<div styleName={this.state.isLeftSliderFocused ? 'slider--active' : 'slider'}
|
||||
style={{left: this.state.navWidth}}
|
||||
onMouseDown={(e) => this.handleLeftSlideMouseDown(e)}
|
||||
<div
|
||||
styleName={
|
||||
this.state.isLeftSliderFocused ? 'slider--active' : 'slider'
|
||||
}
|
||||
style={{ left: this.state.navWidth }}
|
||||
onMouseDown={e => this.handleLeftSlideMouseDown(e)}
|
||||
draggable='false'
|
||||
>
|
||||
<div styleName='slider-hitbox' />
|
||||
</div>
|
||||
}
|
||||
<div styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
||||
</div>}
|
||||
<div
|
||||
styleName={config.isSideNavFolded ? 'body--expanded' : 'body'}
|
||||
id='main-body'
|
||||
ref='body'
|
||||
style={{left: config.isSideNavFolded ? foldedNavigationWidth : this.state.navWidth}}
|
||||
style={{
|
||||
left: config.isSideNavFolded
|
||||
? foldedNavigationWidth
|
||||
: this.state.navWidth
|
||||
}}
|
||||
>
|
||||
<TopBar style={{width: this.state.listWidth}}
|
||||
<TopBar
|
||||
style={{ width: this.state.listWidth }}
|
||||
{..._.pick(this.props, [
|
||||
'dispatch',
|
||||
'config',
|
||||
@@ -329,7 +331,8 @@ class Main extends React.Component {
|
||||
'location'
|
||||
])}
|
||||
/>
|
||||
<NoteList style={{width: this.state.listWidth}}
|
||||
<NoteList
|
||||
style={{ width: this.state.listWidth }}
|
||||
{..._.pick(this.props, [
|
||||
'dispatch',
|
||||
'data',
|
||||
@@ -338,15 +341,20 @@ class Main extends React.Component {
|
||||
'location'
|
||||
])}
|
||||
/>
|
||||
<div styleName={this.state.isRightSliderFocused ? 'slider-right--active' : 'slider-right'}
|
||||
style={{left: this.state.listWidth - 1}}
|
||||
onMouseDown={(e) => this.handleRightSlideMouseDown(e)}
|
||||
<div
|
||||
styleName={
|
||||
this.state.isRightSliderFocused
|
||||
? 'slider-right--active'
|
||||
: 'slider-right'
|
||||
}
|
||||
style={{ left: this.state.listWidth - 1 }}
|
||||
onMouseDown={e => this.handleRightSlideMouseDown(e)}
|
||||
draggable='false'
|
||||
>
|
||||
<div styleName='slider-hitbox' />
|
||||
</div>
|
||||
<Detail
|
||||
style={{left: this.state.listWidth}}
|
||||
style={{ left: this.state.listWidth }}
|
||||
{..._.pick(this.props, [
|
||||
'dispatch',
|
||||
'data',
|
||||
@@ -374,4 +382,4 @@ Main.propTypes = {
|
||||
data: PropTypes.shape({}).isRequired
|
||||
}
|
||||
|
||||
export default connect((x) => x)(CSSModules(Main, styles))
|
||||
export default connect(x => x)(CSSModules(Main, styles))
|
||||
|
||||
@@ -418,10 +418,10 @@ class NoteList extends React.Component {
|
||||
}
|
||||
|
||||
handleSortByChange (e) {
|
||||
const { dispatch } = this.props
|
||||
const { dispatch, params: { folderKey } } = this.props
|
||||
|
||||
const config = {
|
||||
sortBy: e.target.value
|
||||
[folderKey]: { sortBy: e.target.value }
|
||||
}
|
||||
|
||||
ConfigManager.set(config)
|
||||
@@ -909,12 +909,13 @@ class NoteList extends React.Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
const { location, config } = this.props
|
||||
const { location, config, params: { folderKey } } = this.props
|
||||
let { notes } = this.props
|
||||
const { selectedNoteKeys } = this.state
|
||||
const sortFunc = config.sortBy === 'CREATED_AT'
|
||||
const sortBy = _.get(config, [folderKey, 'sortBy'], config.sortBy.default)
|
||||
const sortFunc = sortBy === 'CREATED_AT'
|
||||
? sortByCreatedAt
|
||||
: config.sortBy === 'ALPHABETICAL'
|
||||
: sortBy === 'ALPHABETICAL'
|
||||
? sortByAlphabetical
|
||||
: sortByUpdatedAt
|
||||
const sortedNotes = location.pathname.match(/\/starred|\/trash/)
|
||||
@@ -965,7 +966,7 @@ class NoteList extends React.Component {
|
||||
notes.length === 1 ||
|
||||
(autoSelectFirst && index === 0)
|
||||
const dateDisplay = moment(
|
||||
config.sortBy === 'CREATED_AT'
|
||||
sortBy === 'CREATED_AT'
|
||||
? note.createdAt : note.updatedAt
|
||||
).fromNow('D')
|
||||
|
||||
@@ -1014,7 +1015,7 @@ class NoteList extends React.Component {
|
||||
<i className='fa fa-angle-down' />
|
||||
<select styleName='control-sortBy-select'
|
||||
title={i18n.__('Select filter mode')}
|
||||
value={config.sortBy}
|
||||
value={sortBy}
|
||||
onChange={(e) => this.handleSortByChange(e)}
|
||||
>
|
||||
<option title='Sort by update time' value='UPDATED_AT'>{i18n.__('Updated')}</option>
|
||||
|
||||
@@ -152,3 +152,7 @@ body[data-theme="monokai"]
|
||||
background-color $ui-monokai-backgroundColor
|
||||
.sortableItemHelper
|
||||
color: $ui-monokai-text-color
|
||||
|
||||
body[data-theme="default"]
|
||||
.SideNav ::-webkit-scrollbar-thumb
|
||||
background-color rgba(255, 255, 255, 0.3)
|
||||
|
||||
@@ -16,7 +16,9 @@ export const DEFAULT_CONFIG = {
|
||||
isSideNavFolded: false,
|
||||
listWidth: 280,
|
||||
navWidth: 200,
|
||||
sortBy: 'UPDATED_AT', // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
|
||||
sortBy: {
|
||||
default: 'UPDATED_AT' // 'CREATED_AT', 'UPDATED_AT', 'APLHABETICAL'
|
||||
},
|
||||
sortTagsBy: 'ALPHABETICAL', // 'ALPHABETICAL', 'COUNTER'
|
||||
listStyle: 'DEFAULT', // 'DEFAULT', 'SMALL'
|
||||
amaEnabled: true,
|
||||
|
||||
@@ -22,7 +22,7 @@ class SnippetList extends React.Component {
|
||||
reloadSnippetList () {
|
||||
dataApi.fetchSnippet().then(snippets => {
|
||||
this.setState({snippets})
|
||||
this.props.onSnippetSelect(snippets[0])
|
||||
this.props.onSnippetSelect(this.props.currentSnippet)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
76
dev-scripts/dev.js
Normal file
76
dev-scripts/dev.js
Normal file
@@ -0,0 +1,76 @@
|
||||
const webpack = require('webpack')
|
||||
const WebpackDevServer = require('webpack-dev-server')
|
||||
const config = require('../webpack.config')
|
||||
const signale = require('signale')
|
||||
const { spawn } = require('child_process')
|
||||
const electron = require('electron')
|
||||
const port = 8080
|
||||
let server = null
|
||||
let firstRun = true
|
||||
|
||||
const options = {
|
||||
publicPath: config.output.publicPath,
|
||||
hot: true,
|
||||
inline: true,
|
||||
quiet: true
|
||||
}
|
||||
|
||||
function startServer () {
|
||||
config.plugins.push(new webpack.HotModuleReplacementPlugin())
|
||||
config.entry.main.unshift(
|
||||
`webpack-dev-server/client?http://localhost:${port}/`,
|
||||
'webpack/hot/dev-server'
|
||||
)
|
||||
const compiler = webpack(config)
|
||||
server = new WebpackDevServer(compiler, options)
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
server.listen(port, 'localhost', function (err) {
|
||||
if (err) {
|
||||
reject(err)
|
||||
}
|
||||
signale.success(`Webpack Dev Server listening at localhost:${port}`)
|
||||
signale.watch(`Waiting for webpack to bundle...`)
|
||||
compiler.plugin('done', stats => {
|
||||
if (!stats.hasErrors()) {
|
||||
signale.success(`Bundle success !`)
|
||||
resolve()
|
||||
} else {
|
||||
if (!firstRun) {
|
||||
console.log(stats.compilation.errors[0])
|
||||
} else {
|
||||
firstRun = false
|
||||
reject(stats.compilation.errors[0])
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function startElectron () {
|
||||
spawn(electron, ['--hot', './index.js'])
|
||||
.on('close', () => {
|
||||
server.close()
|
||||
})
|
||||
.on('error', err => {
|
||||
signale.error(err)
|
||||
server.close()
|
||||
})
|
||||
.on('disconnect', () => {
|
||||
server.close()
|
||||
})
|
||||
.on('exit', () => {
|
||||
server.close()
|
||||
})
|
||||
}
|
||||
|
||||
startServer()
|
||||
.then(() => {
|
||||
startElectron()
|
||||
signale.success('Electron started')
|
||||
})
|
||||
.catch(err => {
|
||||
signale.error(err)
|
||||
process.exit(1)
|
||||
})
|
||||
@@ -2,10 +2,9 @@
|
||||
This page is also available in [Japanese](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Korean](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russain](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Simplified Chinese](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [French](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) and [German](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md).
|
||||
|
||||
## Environments
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
You should use `npm v4.x` because `$ grunt pre-build` fails on `v5.x`.
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## Development
|
||||
|
||||
@@ -21,17 +20,9 @@ $ yarn
|
||||
Build and run.
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
This command runs `yarn run webpack` and `yarn run hot` in parallel. It is the same as running these commands in two terminals.
|
||||
|
||||
The `webpack` will watch for code changes and then apply them automatically.
|
||||
|
||||
If the following error occurs: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, please reload Boostnote.
|
||||
|
||||

|
||||
|
||||
> ### Notice
|
||||
> There are some cases where you have to refresh the app manually.
|
||||
> 1. When editing a constructor method of a component
|
||||
@@ -44,8 +35,6 @@ You can build the program by using `grunt`. However, we don't recommend this bec
|
||||
|
||||
So, we've prepared a separate script which just makes an executable file.
|
||||
|
||||
This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
Diese Seite ist auch verfügbar in [Japanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Koreanisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russisch](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Vereinfachtem Chinesisch](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [Französisch](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) und [Deutsch](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md).
|
||||
|
||||
## Umgebungen
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
Du solltest `npm v4.x` benutzen weil `$ grunt pre-build` scheitert mit Version `v5.x`.
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## Entwicklung
|
||||
|
||||
@@ -21,17 +20,9 @@ $ yarn
|
||||
Bauen und Ausführen.
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
Dieser Befehl startet `yarn run webpack` und `yarn run hot` parallel. Es hat den selben Effekt wie beide Befehle separat in zwei Terminals zu starten.
|
||||
|
||||
Das `webpack` überprüft den Code auf Änderungen und wendet diese dann automatisch an.
|
||||
|
||||
Wenn folgender Fehler passiert: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, bitte Boostnote neu starten.
|
||||
|
||||

|
||||
|
||||
> ### Notiz
|
||||
> Es gibt einige Fälle bei denen die App manuell zu refreshen ist.
|
||||
> 1. Wenn eine "constructor method" einer Komponente manuell editiert wird.
|
||||
@@ -44,11 +35,10 @@ Du kannst das Programm unter Verwendung von `grunt` bauen. Jedoch empfehlen wir
|
||||
|
||||
Deshalb haben wir ein separates Script vorbereitet welches eine ausführbare Datei erstellt.
|
||||
|
||||
Dieser build funktioniert nicht mit npm v5.3.0. Deshalb musst du für den Build die Version v5.2.0 verwenden.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
Du findest die ausführbare Datein in dem Verzeichnis `dist`. Beachte, der auto updater funktioniert nicht da die app nicht signiert ist.
|
||||
|
||||
Wenn du es für notwendig erachtest, kannst du codesign or authenticode mit dieser ausführbaren Datei verwenden.
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
Cette page est également disponible en [Anglais](https://github.com/BoostIO/Boostnote/blob/master/docs/build.md), [Japonais](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [Coréen](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [Russe](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [Chinois Simplifié](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md) et en [Allemand](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md)
|
||||
|
||||
## Environnements
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
Il est conseillé d'utiliser `npm v4.x` car `$ grunt pre-build` ne marche pas sur la `v5.x`.
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## Développement
|
||||
|
||||
@@ -20,17 +19,9 @@ $ yarn
|
||||
Build et start
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
Cette commande lance `yarn run webpack` et `yarn run hot` en parallèle. Cela revient au même que si on utilisait ces deux commandes dans 2 terminaux.
|
||||
|
||||
La commande `webpack` va surveiller les changements de code et les appliquer automatiquement.
|
||||
|
||||
Si l'erreur suivante apparait : `Failed to load resource: net::ERR_CONNECTION_REFUSED`, relancez Boostnote.
|
||||
|
||||

|
||||
|
||||
> ### Notice
|
||||
> Il y a certains cas où vous voudrez relancer l'application manuellement.
|
||||
> 1. Quand vous éditez la méthode constructeur dans un composant
|
||||
@@ -43,8 +34,6 @@ Vous pouvez build le programme en utilisant `grunt`. Cependant, nous ne recomman
|
||||
|
||||
Nous avons donc préparé un script séparé qui va rendre un fichier exécutable.
|
||||
|
||||
Le build ne fonctionne pas sur `npm v5.3.0`. Il faut donc utiliser `npm v5.2.0` quand vous faites le build.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Build
|
||||
|
||||
## 環境
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
`npm v5.x` だと `$ grunt pre-build` が失敗するので、 `npm v4.x` を使用してください。
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## 開発
|
||||
|
||||
@@ -21,17 +20,9 @@ $ yarn
|
||||
ビルドして実行します。
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
このコマンドは `yarn run webpack` と `yarn run hot`を並列に実行します。つまりこのコマンドは2つのターミナルで同時にこれらのコマンドを実行するのと同じことです。
|
||||
|
||||
そして、Webpackが自動的にコードの変更を確認し、それを適用してくれるようになります。
|
||||
|
||||
もし、 `Failed to load resource: net::ERR_CONNECTION_REFUSED`というエラーが起きた場合、Boostnoteをリロードしてください。
|
||||
|
||||

|
||||
|
||||
> ### 注意
|
||||
> 時々、直接リフレッシュをする必要があります。
|
||||
> 1. コンポーネントのコンストラクタ関数を編集する場合
|
||||
@@ -44,8 +35,6 @@ Gruntを使います。
|
||||
|
||||
代わりに、実行ファイルを作るスクリプトを用意しておきました。
|
||||
|
||||
このビルドはnpm v5.3.0では動かないのでv5.2.0で動かす必要があります。
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
# Build
|
||||
|
||||
## 환경
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
`$ grunt pre-build`를 `npm v5.x`에서 실행할 수 없기 때문에, 반드시 `npm v4.x`를 사용하셔야 합니다.
|
||||
|
||||
@@ -20,17 +21,9 @@ $ yarn
|
||||
그 다음, 아래의 명령으로 빌드를 끝내고 자동적으로 어플리케이션을 실행합니다.
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
이 명령은 `yarn run webpack` 과 `yarn run hot`을 동시에 실행합니다. 이는 두개의 터미널에서 각각의 명령을 동시에 실행하는 것과 같습니다.
|
||||
|
||||
`Webpack`은 코드의 변화를 자동으로 탐지하여 적용시키는 역할을 합니다.
|
||||
|
||||
만약, `Failed to load resource: net::ERR_CONNECTION_REFUSED`과 같은 에러가 나타난다면 Boostnote를 리로드해주세요.
|
||||
|
||||

|
||||
|
||||
> ### 주의
|
||||
> 가끔 직접 리프레쉬를 해주어야 하는 경우가 있습니다.
|
||||
> 1. 콤포넌트의 컨스트럭터 함수를 수정할 경우
|
||||
@@ -43,8 +36,6 @@ Boostnote에서는 배포 자동화를 위하여 그런트를 사용합니다.
|
||||
|
||||
그래서, 실행파일만을 만드는 스크립트를 준비해 뒀습니다.
|
||||
|
||||
이 빌드는 npm v5.3.0에서는 작동하지 않습니다. 그러므로, 성공적으로 빌드하기 위해서는 v5.2.0을 사용해야 합니다.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# Сборка
|
||||
|
||||
## Используемые инструменты
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
Вы должны использовать `npm v4.x`, так как `$ grunt pre-build` не работает в `v5.x`.
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## Разработка
|
||||
|
||||
@@ -20,17 +19,9 @@ $ yarn
|
||||
Соберите и запустите.
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
Эта команда выполняет `yarn run webpack` и `yarn run hot` параллельно. Результат будет такой же, если вы выполните эти две команды раздельно.
|
||||
|
||||
`Webpack` будет следить за изменениями в коде и будет применять их автоматически.
|
||||
|
||||
Если возникает следующая ошибка: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, пожалуйста, перезапустите Boostnote.
|
||||
|
||||

|
||||
|
||||
> ### Примечание
|
||||
> В некоторых случаях вам необходимо обновить приложение вручную.
|
||||
> 1. При редактировании метода конструктора компонента
|
||||
@@ -41,9 +32,7 @@ $ yarn run dev-start
|
||||
Мы используем Grunt для автоматического деплоя.
|
||||
Вы можете создать задачу, используя `grunt`. Однако мы не рекомендуем этого делать, так как задача по умолчанию включает в себя код и аутентификацию.
|
||||
|
||||
Мы подготовили отдельный скрипт, который просто создает исполняемый файл:
|
||||
|
||||
This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it.
|
||||
Мы подготовили отдельный скрипт, который просто создает исполняемый файл.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
|
||||
@@ -1,37 +1,27 @@
|
||||
# 构建Boostnote
|
||||
|
||||
## 环境
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
因为`$ grunt pre-build`的问题,您只能使用`npm v4.x`而不能使用`npm v5.x`。
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## 开发
|
||||
|
||||
我们使用Webpack HMR来开发Boostnote。
|
||||
在代码根目录下运行下列指令可以以默认配置运行Boostnote。
|
||||
我们使用Webpack HMR来开发Boostnote。
|
||||
在代码根目录下运行下列指令可以以默认配置运行Boostnote。
|
||||
|
||||
### 首先使用yarn安装所需的依赖包。
|
||||
### 首先使用yarn安装所需的依赖包。
|
||||
|
||||
```
|
||||
$ yarn
|
||||
```
|
||||
|
||||
### 接着编译并且运行Boostnote。
|
||||
### 接着编译并且运行Boostnote。
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
这个指令相当于在两个终端内同时运行`yarn run webpack`和`yarn run hot`。
|
||||
|
||||
如果出现错误`Failed to load resource: net::ERR_CONNECTION_REFUSED`,请尝试重新运行Boostnote。
|
||||

|
||||
|
||||
### 然后您就可以进行开发了
|
||||
|
||||
当您对代码作出更改的时候,`webpack`会自动抓取并应用所有代码更改。
|
||||
|
||||
> ### 提示
|
||||
> 在如下情况中,您可能需要重新运行Boostnote才能应用代码更改
|
||||
> 1. 当您在修改了一个组件的构造函数的时候When editing a constructor method of a component
|
||||
@@ -39,18 +29,16 @@ $ yarn run dev-start
|
||||
|
||||
## 部署
|
||||
|
||||
我们使用Grunt来自动部署Boostnote。
|
||||
因为部署需要协同设计(codesign)与验证码(authenticode),所以您可以但我们不建议通过`grunt`来部署。
|
||||
所以我们准备了一个脚本文件来生成执行文件。
|
||||
我们使用Grunt来自动部署Boostnote。
|
||||
因为部署需要协同设计(codesign)与验证码(authenticode),所以您可以但我们不建议通过`grunt`来部署。
|
||||
所以我们准备了一个脚本文件来生成执行文件。
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
您只能使用`npm v5.2.0`而不能使用`npm v5.3.0`。
|
||||
|
||||
接下来您就可以在`dist`目录中找到可执行文件。
|
||||
接下来您就可以在`dist`目录中找到可执行文件。
|
||||
|
||||
> ### 提示
|
||||
> 因为此可执行文件并没有被注册,所以自动更新不可用。
|
||||
> 如果需要,您也可将协同设计(codesign)与验证码(authenticode)使用于这个可执行文件中。
|
||||
> 如果需要,您也可将协同设计(codesign)与验证码(authenticode)使用于这个可执行文件中。
|
||||
|
||||
@@ -2,10 +2,9 @@
|
||||
此文件還提供下列的語言 [日文](https://github.com/BoostIO/Boostnote/blob/master/docs/jp/build.md), [韓文](https://github.com/BoostIO/Boostnote/blob/master/docs/ko/build.md), [俄文](https://github.com/BoostIO/Boostnote/blob/master/docs/ru/build.md), [簡體中文](https://github.com/BoostIO/Boostnote/blob/master/docs/zh_CN/build.md), [法文](https://github.com/BoostIO/Boostnote/blob/master/docs/fr/build.md) and [德文](https://github.com/BoostIO/Boostnote/blob/master/docs/de/build.md).
|
||||
|
||||
## 環境
|
||||
* npm: 4.x
|
||||
* node: 7.x
|
||||
|
||||
`$ grunt pre-build` 在 `npm v5.x` 有問題,所以只能用 `npm v4.x` 。
|
||||
* npm: 6.x
|
||||
* node: 8.x
|
||||
|
||||
## 開發
|
||||
|
||||
@@ -22,18 +21,9 @@ $ yarn
|
||||
**開始開發**
|
||||
|
||||
```
|
||||
$ yarn run dev-start
|
||||
$ yarn run dev
|
||||
```
|
||||
|
||||
上述指令同時運行了 `yarn run webpack` 及 `yarn run hot`,相當於將這兩個指令在不同的 terminal 中運行。
|
||||
|
||||
`webpack` 會同時監控修改過的程式碼,並
|
||||
The `webpack` will watch for code changes and then apply them automatically.
|
||||
|
||||
If the following error occurs: `Failed to load resource: net::ERR_CONNECTION_REFUSED`, please reload Boostnote.
|
||||
|
||||

|
||||
|
||||
> ### Notice
|
||||
> There are some cases where you have to refresh the app manually.
|
||||
> 1. When editing a constructor method of a component
|
||||
@@ -46,8 +36,6 @@ You can build the program by using `grunt`. However, we don't recommend this bec
|
||||
|
||||
So, we've prepared a separate script which just makes an executable file.
|
||||
|
||||
This build doesn't work on npm v5.3.0. So you need to use v5.2.0 when you build it.
|
||||
|
||||
```
|
||||
grunt pre-build
|
||||
```
|
||||
|
||||
@@ -7,9 +7,11 @@ const config = new Config()
|
||||
const _ = require('lodash')
|
||||
|
||||
var showMenu = process.platform !== 'win32'
|
||||
const windowSize = config.get('windowsize') || { width: 1080, height: 720 }
|
||||
const windowSize = config.get('windowsize') || { x: null, y: null, width: 1080, height: 720 }
|
||||
|
||||
const mainWindow = new BrowserWindow({
|
||||
x: windowSize.x,
|
||||
y: windowSize.y,
|
||||
width: windowSize.width,
|
||||
height: windowSize.height,
|
||||
minWidth: 500,
|
||||
@@ -59,6 +61,7 @@ if (process.platform === 'darwin') {
|
||||
}
|
||||
|
||||
mainWindow.on('resize', _.throttle(storeWindowSize, 500))
|
||||
mainWindow.on('move', _.throttle(storeWindowSize, 500))
|
||||
|
||||
function storeWindowSize () {
|
||||
try {
|
||||
|
||||
118
lib/main.html
118
lib/main.html
@@ -1,72 +1,83 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" />
|
||||
|
||||
<link rel="stylesheet" href="../node_modules/font-awesome/css/font-awesome.min.css" media="screen" charset="utf-8">
|
||||
<link rel="shortcut icon" href="../resources/favicon.ico">
|
||||
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../node_modules/katex/dist/katex.min.css">
|
||||
<link rel="stylesheet" href="../node_modules/codemirror/addon/dialog/dialog.css">
|
||||
<title>Boostnote</title>
|
||||
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.ttf') format('truetype');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.ttf') format('truetype');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
#loadingCover{
|
||||
background-color: #f4f4f4;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 65px 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
#loadingCover img{
|
||||
display: block;
|
||||
margin: 75px auto 5px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
#loadingCover .message{
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
font-weight: 100;
|
||||
color: #888;
|
||||
}
|
||||
.CodeEditor {
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left-color: rgba(142, 142, 142, 0.5);
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'OpenSans';
|
||||
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.ttf') format('truetype');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Lato';
|
||||
src: url('../resources/fonts/Lato-Regular.woff2') format('woff2'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.woff') format('woff'), /* Modern Browsers */
|
||||
url('../resources/fonts/Lato-Regular.ttf') format('truetype');
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
#loadingCover {
|
||||
background-color: #f4f4f4;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
padding: 65px 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
#loadingCover img {
|
||||
display: block;
|
||||
margin: 75px auto 5px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
}
|
||||
|
||||
#loadingCover .message {
|
||||
font-size: 30px;
|
||||
text-align: center;
|
||||
line-height: 1.6;
|
||||
font-weight: 100;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.CodeEditor {
|
||||
opacity: 1 !important;
|
||||
pointer-events: auto !important;
|
||||
}
|
||||
|
||||
.CodeMirror-ruler {
|
||||
border-left-color: rgba(142, 142, 142, 0.5);
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="loadingCover">
|
||||
<img src="../resources/app.png">
|
||||
<div class='message'><i class="fa fa-spinner fa-spin" spin></i></div>
|
||||
<div class='message'>
|
||||
<i class="fa fa-spinner fa-spin" spin></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content"></div>
|
||||
@@ -130,4 +141,5 @@
|
||||
}
|
||||
</style>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</html>
|
||||
13
package.json
13
package.json
@@ -7,17 +7,15 @@
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"start": "electron ./index.js",
|
||||
"hot": "electron ./index.js --hot",
|
||||
"webpack": "webpack-dev-server --hot --inline --config webpack.config.js",
|
||||
"compile": "grunt compile",
|
||||
"test": "PWD=$(pwd) NODE_ENV=test ava --serial",
|
||||
"jest": "jest",
|
||||
"fix": "eslint . --fix",
|
||||
"lint": "eslint .",
|
||||
"dev-start": "concurrently --kill-others \"npm run webpack\" \"npm run hot\""
|
||||
"dev": "node dev-scripts/dev.js"
|
||||
},
|
||||
"config": {
|
||||
"electron-version": "2.0.3"
|
||||
"electron-version": "2.0.7"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -57,7 +55,7 @@
|
||||
"chart.js": "^2.7.2",
|
||||
"codemirror": "^5.39.0",
|
||||
"codemirror-mode-elixir": "^1.1.1",
|
||||
"electron-config": "^0.2.1",
|
||||
"electron-config": "^1.0.0",
|
||||
"electron-gh-releases": "^2.0.2",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"file-url": "^2.0.2",
|
||||
@@ -122,8 +120,8 @@
|
||||
"css-loader": "^0.19.0",
|
||||
"devtron": "^1.1.0",
|
||||
"dom-storage": "^2.0.2",
|
||||
"electron": "2.0.3",
|
||||
"electron-packager": "^6.0.0",
|
||||
"electron": "2.0.7",
|
||||
"electron-packager": "^12.0.0",
|
||||
"eslint": "^3.13.1",
|
||||
"eslint-config-standard": "^6.2.1",
|
||||
"eslint-config-standard-jsx": "^3.2.0",
|
||||
@@ -147,6 +145,7 @@
|
||||
"react-router": "^2.4.0",
|
||||
"react-router-redux": "^4.0.4",
|
||||
"react-test-renderer": "^15.6.2",
|
||||
"signale": "^1.2.1",
|
||||
"standard": "^8.4.0",
|
||||
"style-loader": "^0.12.4",
|
||||
"stylus": "^0.52.4",
|
||||
|
||||
@@ -12,6 +12,7 @@ test('getTodoStatus should return a correct hash object', t => {
|
||||
['- [ ] a\n- [x] a\n', { total: 2, completed: 1 }],
|
||||
['+ [ ] a\n', { total: 1, completed: 0 }],
|
||||
['+ [ ] a\n+ [x] a\n', { total: 2, completed: 1 }],
|
||||
['+ [ ] a\n+ [X] a\n', { total: 2, completed: 1 }],
|
||||
['+ [ ] a\n+ [testx] a\n', { total: 1, completed: 0 }],
|
||||
['+ [ ] a\n+ [xtest] a\n', { total: 1, completed: 0 }],
|
||||
['+ [ ] a\n+ foo[x]bar a\n', { total: 1, completed: 0 }],
|
||||
|
||||
@@ -5,7 +5,7 @@ const { parse } = require('browser/lib/RcParser')
|
||||
// Unit test
|
||||
test('RcParser should return a json object', t => {
|
||||
const validJson = { 'editor': { 'keyMap': 'vim', 'switchPreview': 'BLUR', 'theme': 'monokai' }, 'hotkey': { 'toggleMain': 'Control + L' }, 'listWidth': 135, 'navWidth': 135 }
|
||||
const allJson = { 'amaEnabled': true, 'editor': { 'fontFamily': 'Monaco, Consolas', 'fontSize': '14', 'indentSize': '2', 'indentType': 'space', 'keyMap': 'vim', 'switchPreview': 'BLUR', 'theme': 'monokai' }, 'hotkey': { 'toggleMain': 'Cmd + Alt + L' }, 'isSideNavFolded': false, 'listStyle': 'DEFAULT', 'listWidth': 174, 'navWidth': 200, 'preview': { 'codeBlockTheme': 'dracula', 'fontFamily': 'Lato', 'fontSize': '14', 'lineNumber': true }, 'sortBy': 'UPDATED_AT', 'ui': { 'defaultNote': 'ALWAYS_ASK', 'disableDirectWrite': false, 'theme': 'default' }, 'zoom': 1 }
|
||||
const allJson = { 'amaEnabled': true, 'editor': { 'fontFamily': 'Monaco, Consolas', 'fontSize': '14', 'indentSize': '2', 'indentType': 'space', 'keyMap': 'vim', 'switchPreview': 'BLUR', 'theme': 'monokai' }, 'hotkey': { 'toggleMain': 'Cmd + Alt + L' }, 'isSideNavFolded': false, 'listStyle': 'DEFAULT', 'listWidth': 174, 'navWidth': 200, 'preview': { 'codeBlockTheme': 'dracula', 'fontFamily': 'Lato', 'fontSize': '14', 'lineNumber': true }, 'sortBy': { 'default': 'UPDATED_AT' }, 'ui': { 'defaultNote': 'ALWAYS_ASK', 'disableDirectWrite': false, 'theme': 'default' }, 'zoom': 1 }
|
||||
|
||||
// [input, expected]
|
||||
const validTestCases = [
|
||||
|
||||
@@ -4,20 +4,24 @@ const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin')
|
||||
|
||||
var config = {
|
||||
entry: {
|
||||
main: './browser/main/index.js'
|
||||
main: ['./browser/main/index.js']
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['', '.js', '.jsx', '.styl'],
|
||||
packageMains: ['webpack', 'browser', 'web', 'browserify', ['jam', 'main'], 'main'],
|
||||
packageMains: [
|
||||
'webpack',
|
||||
'browser',
|
||||
'web',
|
||||
'browserify',
|
||||
['jam', 'main'],
|
||||
'main'
|
||||
],
|
||||
alias: {
|
||||
'lib': path.join(__dirname, 'lib'),
|
||||
'browser': path.join(__dirname, 'browser')
|
||||
lib: path.join(__dirname, 'lib'),
|
||||
browser: path.join(__dirname, 'browser')
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
new webpack.NoErrorsPlugin(),
|
||||
new NodeTargetPlugin()
|
||||
],
|
||||
plugins: [new webpack.NoErrorsPlugin(), new NodeTargetPlugin()],
|
||||
stylus: {
|
||||
use: [require('nib')()],
|
||||
import: [
|
||||
@@ -43,14 +47,13 @@ var config = {
|
||||
react: 'var React',
|
||||
'react-dom': 'var ReactDOM',
|
||||
'react-redux': 'var ReactRedux',
|
||||
'codemirror': 'var CodeMirror',
|
||||
'redux': 'var Redux',
|
||||
'raphael': 'var Raphael',
|
||||
'flowchart': 'var flowchart',
|
||||
codemirror: 'var CodeMirror',
|
||||
redux: 'var Redux',
|
||||
raphael: 'var Raphael',
|
||||
flowchart: 'var flowchart',
|
||||
'sequence-diagram': 'var Diagram'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
module.exports = config
|
||||
|
||||
|
||||
359
yarn.lock
359
yarn.lock
@@ -366,6 +366,19 @@ asar@^0.12.0:
|
||||
mksnapshot "^0.3.0"
|
||||
tmp "0.0.28"
|
||||
|
||||
asar@^0.14.0:
|
||||
version "0.14.3"
|
||||
resolved "https://registry.yarnpkg.com/asar/-/asar-0.14.3.tgz#c72a81542a48e3bca459fb1b07ee2b6adfae265d"
|
||||
dependencies:
|
||||
chromium-pickle-js "^0.2.0"
|
||||
commander "^2.9.0"
|
||||
cuint "^0.2.1"
|
||||
glob "^6.0.4"
|
||||
minimatch "^3.0.3"
|
||||
mkdirp "^0.5.0"
|
||||
mksnapshot "^0.3.0"
|
||||
tmp "0.0.28"
|
||||
|
||||
asar@^0.9.0:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/asar/-/asar-0.9.1.tgz#b2f2fe1b49c163013bdb229d6eba2d2078ff5cc4"
|
||||
@@ -446,6 +459,10 @@ atob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a"
|
||||
|
||||
author-regex@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450"
|
||||
|
||||
auto-bind@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-1.2.0.tgz#8b7e318aad53d43ba8a8ecaf0066d85d5f798cd6"
|
||||
@@ -1230,9 +1247,9 @@ balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
|
||||
base64-js@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.8.tgz#1101e9544f4a76b1bc3b26d452ca96d7a35e7978"
|
||||
base64-js@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1"
|
||||
|
||||
base64-js@^1.0.2:
|
||||
version "1.3.0"
|
||||
@@ -1285,7 +1302,7 @@ bluebird@^2.9.30:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
|
||||
|
||||
bluebird@^3.0.0, bluebird@^3.1.1, bluebird@^3.3.4:
|
||||
bluebird@^3.0.0, bluebird@^3.1.1, bluebird@^3.3.4, bluebird@^3.5.0:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
||||
|
||||
@@ -1404,6 +1421,21 @@ buf-compare@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/buf-compare/-/buf-compare-1.0.1.tgz#fef28da8b8113a0a0db4430b0b6467b69730b34a"
|
||||
|
||||
buffer-alloc-unsafe@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0"
|
||||
|
||||
buffer-alloc@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec"
|
||||
dependencies:
|
||||
buffer-alloc-unsafe "^1.1.0"
|
||||
buffer-fill "^1.0.0"
|
||||
|
||||
buffer-fill@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.0.0.tgz#4cb8832d23612589b0406e9e2956c17f06fdf531"
|
||||
@@ -1580,7 +1612,7 @@ chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
strip-ansi "^3.0.0"
|
||||
supports-color "^2.0.0"
|
||||
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1:
|
||||
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
|
||||
dependencies:
|
||||
@@ -1868,6 +1900,10 @@ commondir@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
|
||||
compare-version@^0.1.2:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080"
|
||||
|
||||
compare-versions@^3.1.0:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.2.1.tgz#a49eb7689d4caaf0b6db5220173fd279614000f7"
|
||||
@@ -1936,14 +1972,15 @@ concurrently@^3.4.0:
|
||||
supports-color "^3.2.3"
|
||||
tree-kill "^1.1.0"
|
||||
|
||||
conf@^0.11.1:
|
||||
version "0.11.2"
|
||||
resolved "https://registry.yarnpkg.com/conf/-/conf-0.11.2.tgz#879f479267600483e502583462ca4063fc9779b2"
|
||||
conf@^1.0.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/conf/-/conf-1.4.0.tgz#1ea66c9d7a9b601674a5bb9d2b8dc3c726625e67"
|
||||
dependencies:
|
||||
dot-prop "^3.0.0"
|
||||
env-paths "^0.3.0"
|
||||
mkdirp "^0.5.1"
|
||||
pkg-up "^1.0.0"
|
||||
dot-prop "^4.1.0"
|
||||
env-paths "^1.0.0"
|
||||
make-dir "^1.0.0"
|
||||
pkg-up "^2.0.0"
|
||||
write-file-atomic "^2.3.0"
|
||||
|
||||
configstore@^3.0.0:
|
||||
version "3.1.2"
|
||||
@@ -2478,7 +2515,7 @@ debug-log@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f"
|
||||
|
||||
debug@*, debug@^3.0.1, debug@^3.1.0:
|
||||
debug@*, debug@^3.0.0, debug@^3.0.1, debug@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
dependencies:
|
||||
@@ -2706,12 +2743,6 @@ domutils@^1.5.1:
|
||||
dom-serializer "0"
|
||||
domelementtype "1"
|
||||
|
||||
dot-prop@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177"
|
||||
dependencies:
|
||||
is-obj "^1.0.0"
|
||||
|
||||
dot-prop@^4.1.0:
|
||||
version "4.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57"
|
||||
@@ -2742,24 +2773,11 @@ ee-first@1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
|
||||
|
||||
electron-config@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-0.2.1.tgz#7e12c26412d06bf3ed3896d0479df162986b95ba"
|
||||
electron-config@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-config/-/electron-config-1.0.0.tgz#069d044cc794f04784ae72f12916725d3c8c39af"
|
||||
dependencies:
|
||||
conf "^0.11.1"
|
||||
|
||||
electron-download@^2.0.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-2.2.1.tgz#3d78af3645c96435e3bf3df9b882a14cc2ca294c"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
home-path "^1.0.1"
|
||||
minimist "^1.2.0"
|
||||
mkdirp "^0.5.0"
|
||||
mv "^2.0.3"
|
||||
nugget "^1.5.1"
|
||||
path-exists "^1.0.0"
|
||||
rc "^1.1.2"
|
||||
conf "^1.0.0"
|
||||
|
||||
electron-download@^3.0.1:
|
||||
version "3.3.0"
|
||||
@@ -2775,6 +2793,20 @@ electron-download@^3.0.1:
|
||||
semver "^5.3.0"
|
||||
sumchecker "^1.2.0"
|
||||
|
||||
electron-download@^4.0.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-download/-/electron-download-4.1.0.tgz#bf932c746f2f87ffcc09d1dd472f2ff6b9187845"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
env-paths "^1.0.0"
|
||||
fs-extra "^2.0.0"
|
||||
minimist "^1.2.0"
|
||||
nugget "^2.0.0"
|
||||
path-exists "^3.0.0"
|
||||
rc "^1.1.2"
|
||||
semver "^5.3.0"
|
||||
sumchecker "^2.0.1"
|
||||
|
||||
electron-gh-releases@^2.0.2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/electron-gh-releases/-/electron-gh-releases-2.0.4.tgz#198c07a0970fb8e80fcc67bd0b4198a010923dc3"
|
||||
@@ -2811,34 +2843,38 @@ electron-installer-redhat@^0.3.0:
|
||||
word-wrap "^1.1.0"
|
||||
yargs "^6.0.0"
|
||||
|
||||
electron-osx-sign@^0.3.0:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.3.2.tgz#88fa7d6ebadb5d9c79368b96491a0d8c4630146e"
|
||||
electron-osx-sign@^0.4.1:
|
||||
version "0.4.10"
|
||||
resolved "https://registry.yarnpkg.com/electron-osx-sign/-/electron-osx-sign-0.4.10.tgz#be4f3b89b2a75a1dc5f1e7249081ab2929ca3a26"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
minimist "^1.1.1"
|
||||
run-series "^1.1.1"
|
||||
bluebird "^3.5.0"
|
||||
compare-version "^0.1.2"
|
||||
debug "^2.6.8"
|
||||
isbinaryfile "^3.0.2"
|
||||
minimist "^1.2.0"
|
||||
plist "^2.1.0"
|
||||
|
||||
electron-packager@^6.0.0:
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-6.0.2.tgz#8ee00669fe8a36309502732fcfed117d7ee9ac29"
|
||||
electron-packager@^12.0.0:
|
||||
version "12.1.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-packager/-/electron-packager-12.1.0.tgz#048dd4ff3848be19c5873c315b5b312df6215328"
|
||||
dependencies:
|
||||
asar "^0.11.0"
|
||||
electron-download "^2.0.0"
|
||||
electron-osx-sign "^0.3.0"
|
||||
asar "^0.14.0"
|
||||
debug "^3.0.0"
|
||||
electron-download "^4.0.0"
|
||||
electron-osx-sign "^0.4.1"
|
||||
extract-zip "^1.0.3"
|
||||
fs-extra "^0.26.5"
|
||||
get-package-info "0.0.2"
|
||||
minimist "^1.1.1"
|
||||
mkdirp "^0.5.0"
|
||||
mv "^2.0.3"
|
||||
ncp "^2.0.0"
|
||||
object-assign "^4.0.1"
|
||||
plist "^1.1.0"
|
||||
rcedit "^0.5.0"
|
||||
fs-extra "^5.0.0"
|
||||
galactus "^0.2.1"
|
||||
get-package-info "^1.0.0"
|
||||
nodeify "^1.0.1"
|
||||
parse-author "^2.0.0"
|
||||
pify "^3.0.0"
|
||||
plist "^2.0.0"
|
||||
rcedit "^1.0.0"
|
||||
resolve "^1.1.6"
|
||||
rimraf "^2.3.2"
|
||||
run-series "^1.1.1"
|
||||
sanitize-filename "^1.6.0"
|
||||
semver "^5.3.0"
|
||||
yargs-parser "^10.0.0"
|
||||
|
||||
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.47:
|
||||
version "1.3.48"
|
||||
@@ -2855,9 +2891,9 @@ electron-winstaller@^2.2.0:
|
||||
lodash.template "^4.2.2"
|
||||
temp "^0.8.3"
|
||||
|
||||
electron@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.3.tgz#8e591e820cae2ccdb0c3fd74c6d07834913fc133"
|
||||
electron@2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-2.0.7.tgz#f7ce410433298e319032ce31f0e6ffd709ff052c"
|
||||
dependencies:
|
||||
"@types/node" "^8.0.24"
|
||||
electron-download "^3.0.1"
|
||||
@@ -2896,9 +2932,9 @@ entities@^1.1.1, entities@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
|
||||
|
||||
env-paths@^0.3.0:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-0.3.1.tgz#c30ccfcbc30c890943dc08a85582517ef00da463"
|
||||
env-paths@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
|
||||
|
||||
equal-length@^1.0.0:
|
||||
version "1.0.1"
|
||||
@@ -3602,6 +3638,13 @@ flatten@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782"
|
||||
|
||||
flora-colossus@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/flora-colossus/-/flora-colossus-1.0.0.tgz#54729c361edecee014dd441679e1a37c1d773a45"
|
||||
dependencies:
|
||||
debug "^3.1.0"
|
||||
fs-extra "^4.0.0"
|
||||
|
||||
flowchart.js@^1.6.5:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/flowchart.js/-/flowchart.js-1.11.0.tgz#e8df60e69d08df90c07ffb09e857d555d8981fc7"
|
||||
@@ -3678,7 +3721,7 @@ fs-extra@0.18.2:
|
||||
jsonfile "^2.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@0.26.7, fs-extra@^0.26.0, fs-extra@^0.26.5, fs-extra@^0.26.7:
|
||||
fs-extra@0.26.7, fs-extra@^0.26.0, fs-extra@^0.26.7:
|
||||
version "0.26.7"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9"
|
||||
dependencies:
|
||||
@@ -3706,6 +3749,21 @@ fs-extra@^1.0.0:
|
||||
jsonfile "^2.1.0"
|
||||
klaw "^1.0.0"
|
||||
|
||||
fs-extra@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-2.1.2.tgz#046c70163cef9aad46b0e4a7fa467fb22d71de35"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^2.1.0"
|
||||
|
||||
fs-extra@^4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd"
|
||||
@@ -3748,6 +3806,14 @@ function-name-support@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/function-name-support/-/function-name-support-0.2.0.tgz#55d3bfaa6eafd505a50f9bc81fdf57564a0bb071"
|
||||
|
||||
galactus@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/galactus/-/galactus-0.2.1.tgz#cbed2d20a40c1f5679a35908e2b9415733e78db9"
|
||||
dependencies:
|
||||
debug "^3.1.0"
|
||||
flora-colossus "^1.0.0"
|
||||
fs-extra "^4.0.0"
|
||||
|
||||
gar@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/gar/-/gar-1.0.3.tgz#cd6e954dff11821697a9ed5852c7ac5f18df02ce"
|
||||
@@ -3786,13 +3852,14 @@ get-folder-size@^1.0.0:
|
||||
async "^1.4.2"
|
||||
gar "^1.0.2"
|
||||
|
||||
get-package-info@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/get-package-info/-/get-package-info-0.0.2.tgz#72c38fbee2e76728424a00dc14e24dd1a28c2391"
|
||||
get-package-info@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-package-info/-/get-package-info-1.0.0.tgz#6432796563e28113cd9474dbbd00052985a4999c"
|
||||
dependencies:
|
||||
bluebird "^3.1.1"
|
||||
debug "^2.2.0"
|
||||
lodash.get "^4.0.0"
|
||||
resolve "^1.1.6"
|
||||
read-pkg-up "^2.0.0"
|
||||
|
||||
get-port@^3.0.0:
|
||||
version "3.2.0"
|
||||
@@ -3865,7 +3932,7 @@ glob@^5.0.5:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^6.0.1, glob@^6.0.3, glob@^6.0.4:
|
||||
glob@^6.0.3, glob@^6.0.4:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||
dependencies:
|
||||
@@ -4740,6 +4807,10 @@ is-promise@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
|
||||
|
||||
is-promise@~1, is-promise@~1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-1.0.1.tgz#31573761c057e33c2e91aab9e96da08cefbe76e5"
|
||||
|
||||
is-property@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
|
||||
@@ -4800,6 +4871,12 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
|
||||
isbinaryfile@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.3.tgz#5d6def3edebf6e8ca8cae9c30183a804b5f8be80"
|
||||
dependencies:
|
||||
buffer-alloc "^1.2.0"
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
@@ -5632,10 +5709,6 @@ lodash.uniq@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
|
||||
|
||||
lodash@^3.5.0:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
|
||||
|
||||
lodash@^4.0.0, lodash@^4.0.1, lodash@^4.11.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1:
|
||||
version "4.17.10"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7"
|
||||
@@ -6088,14 +6161,6 @@ mute-stream@0.0.5:
|
||||
version "0.0.5"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
|
||||
|
||||
mv@^2.0.3:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2"
|
||||
dependencies:
|
||||
mkdirp "~0.5.1"
|
||||
ncp "~2.0.0"
|
||||
rimraf "~2.4.0"
|
||||
|
||||
nan@^2.9.2:
|
||||
version "2.10.0"
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f"
|
||||
@@ -6125,10 +6190,6 @@ natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
|
||||
ncp@^2.0.0, ncp@~2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
|
||||
|
||||
needle@^2.2.0:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d"
|
||||
@@ -6231,6 +6292,13 @@ node-uuid@~1.4.0:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
|
||||
|
||||
nodeify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nodeify/-/nodeify-1.0.1.tgz#64ab69a7bdbaf03ce107b4f0335c87c0b9e91b1d"
|
||||
dependencies:
|
||||
is-promise "~1.0.0"
|
||||
promise "~1.3.0"
|
||||
|
||||
nopt@^3.0.1:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9"
|
||||
@@ -6304,18 +6372,6 @@ npmlog@^4.0.2:
|
||||
gauge "~2.7.3"
|
||||
set-blocking "~2.0.0"
|
||||
|
||||
nugget@^1.5.1:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/nugget/-/nugget-1.6.2.tgz#88ca6e03ba5706a99173f5da0902593d6bcae107"
|
||||
dependencies:
|
||||
debug "^2.1.3"
|
||||
minimist "^1.1.0"
|
||||
pretty-bytes "^1.0.2"
|
||||
progress-stream "^1.1.0"
|
||||
request "^2.45.0"
|
||||
single-line-log "^0.4.1"
|
||||
throttleit "0.0.2"
|
||||
|
||||
nugget@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nugget/-/nugget-2.0.1.tgz#201095a487e1ad36081b3432fa3cada4f8d071b0"
|
||||
@@ -6558,6 +6614,12 @@ pako@~0.2.0:
|
||||
version "0.2.9"
|
||||
resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75"
|
||||
|
||||
parse-author@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f"
|
||||
dependencies:
|
||||
author-regex "^1.0.0"
|
||||
|
||||
parse-glob@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c"
|
||||
@@ -6608,10 +6670,6 @@ path-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a"
|
||||
|
||||
path-exists@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081"
|
||||
|
||||
path-exists@^2.0.0, path-exists@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b"
|
||||
@@ -6696,7 +6754,7 @@ pinkie@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
|
||||
|
||||
pkg-conf@^2.0.0:
|
||||
pkg-conf@^2.0.0, pkg-conf@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.1.0.tgz#2126514ca6f2abfebd168596df18ba57867f0058"
|
||||
dependencies:
|
||||
@@ -6723,19 +6781,18 @@ pkg-dir@^2.0.0:
|
||||
dependencies:
|
||||
find-up "^2.1.0"
|
||||
|
||||
pkg-up@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-1.0.0.tgz#3e08fb461525c4421624a33b9f7e6d0af5b05a26"
|
||||
pkg-up@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f"
|
||||
dependencies:
|
||||
find-up "^1.0.0"
|
||||
find-up "^2.1.0"
|
||||
|
||||
plist@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/plist/-/plist-1.2.0.tgz#084b5093ddc92506e259f874b8d9b1afb8c79593"
|
||||
plist@^2.0.0, plist@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/plist/-/plist-2.1.0.tgz#57ccdb7a0821df21831217a3cad54e3e146a1025"
|
||||
dependencies:
|
||||
base64-js "0.0.8"
|
||||
util-deprecate "1.0.2"
|
||||
xmlbuilder "4.0.0"
|
||||
base64-js "1.2.0"
|
||||
xmlbuilder "8.2.2"
|
||||
xmldom "0.1.x"
|
||||
|
||||
plur@^2.0.0:
|
||||
@@ -7065,6 +7122,12 @@ promise@^7.1.1:
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
promise@~1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-1.3.0.tgz#e5cc9a4c8278e4664ffedc01c7da84842b040175"
|
||||
dependencies:
|
||||
is-promise "~1"
|
||||
|
||||
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0:
|
||||
version "15.6.1"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca"
|
||||
@@ -7187,9 +7250,9 @@ rc@^1.0.1, rc@^1.1.2, rc@^1.1.6, rc@^1.1.7:
|
||||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
rcedit@^0.5.0:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-0.5.1.tgz#d0bdcf5d280a9d1c29da6f118ccce2ce153cef1d"
|
||||
rcedit@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/rcedit/-/rcedit-1.1.0.tgz#ae21c28d4efdd78e95fcab7309a5dd084920b16a"
|
||||
|
||||
react-codemirror@^0.3.0:
|
||||
version "0.3.0"
|
||||
@@ -7674,7 +7737,7 @@ right-align@^0.1.1:
|
||||
dependencies:
|
||||
align-text "^0.1.1"
|
||||
|
||||
rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1:
|
||||
rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
|
||||
dependencies:
|
||||
@@ -7684,12 +7747,6 @@ rimraf@~2.2.6, rimraf@~2.2.8:
|
||||
version "2.2.8"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582"
|
||||
|
||||
rimraf@~2.4.0:
|
||||
version "2.4.5"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da"
|
||||
dependencies:
|
||||
glob "^6.0.1"
|
||||
|
||||
ripemd160@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-0.2.0.tgz#2bf198bde167cacfa51c0a928e84b68bbe171fce"
|
||||
@@ -7708,10 +7765,6 @@ run-parallel@^1.1.2:
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679"
|
||||
|
||||
run-series@^1.1.1:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/run-series/-/run-series-1.1.8.tgz#2c4558f49221e01cd6371ff4e0a1e203e460fc36"
|
||||
|
||||
rw@1:
|
||||
version "1.3.3"
|
||||
resolved "http://registry.npm.taobao.org/rw/download/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
@@ -7766,6 +7819,12 @@ sane@^2.0.0:
|
||||
optionalDependencies:
|
||||
fsevents "^1.2.3"
|
||||
|
||||
sanitize-filename@^1.6.0:
|
||||
version "1.6.1"
|
||||
resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.1.tgz#612da1c96473fa02dccda92dcd5b4ab164a6772a"
|
||||
dependencies:
|
||||
truncate-utf8-bytes "^1.0.0"
|
||||
|
||||
sanitize-html@^1.18.2:
|
||||
version "1.18.2"
|
||||
resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.18.2.tgz#61877ba5a910327e42880a28803c2fbafa8e4642"
|
||||
@@ -7922,9 +7981,13 @@ signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
|
||||
single-line-log@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/single-line-log/-/single-line-log-0.4.1.tgz#87a55649f749d783ec0dcd804e8140d9873c7cee"
|
||||
signale@^1.2.1:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/signale/-/signale-1.2.1.tgz#fbd4b952603ea3315dbe9e88f4f482f336cee828"
|
||||
dependencies:
|
||||
chalk "^2.3.2"
|
||||
figures "^2.0.0"
|
||||
pkg-conf "^2.1.0"
|
||||
|
||||
single-line-log@^1.1.2:
|
||||
version "1.1.2"
|
||||
@@ -8363,6 +8426,12 @@ sumchecker@^1.2.0:
|
||||
debug "^2.2.0"
|
||||
es6-promise "^4.0.5"
|
||||
|
||||
sumchecker@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/sumchecker/-/sumchecker-2.0.2.tgz#0f42c10e5d05da5d42eea3e56c3399a37d6c5b3e"
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
|
||||
supertap@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supertap/-/supertap-1.0.0.tgz#bd9751c7fafd68c68cf8222a29892206a119fa9e"
|
||||
@@ -8622,6 +8691,12 @@ trim-right@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||
|
||||
truncate-utf8-bytes@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b"
|
||||
dependencies:
|
||||
utf8-byte-length "^1.0.1"
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
@@ -8849,7 +8924,11 @@ user-home@^2.0.0:
|
||||
dependencies:
|
||||
os-homedir "^1.0.0"
|
||||
|
||||
util-deprecate@1.0.2, util-deprecate@~1.0.1:
|
||||
utf8-byte-length@^1.0.1:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61"
|
||||
|
||||
util-deprecate@~1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
|
||||
@@ -9140,7 +9219,7 @@ write-file-atomic@^1.1.4:
|
||||
imurmurhash "^0.1.4"
|
||||
slide "^1.1.5"
|
||||
|
||||
write-file-atomic@^2.0.0, write-file-atomic@^2.1.0:
|
||||
write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab"
|
||||
dependencies:
|
||||
@@ -9204,11 +9283,9 @@ xml2js@0.4.17:
|
||||
sax ">=0.6.0"
|
||||
xmlbuilder "^4.1.0"
|
||||
|
||||
xmlbuilder@4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.0.0.tgz#98b8f651ca30aa624036f127d11cc66dc7b907a3"
|
||||
dependencies:
|
||||
lodash "^3.5.0"
|
||||
xmlbuilder@8.2.2:
|
||||
version "8.2.2"
|
||||
resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773"
|
||||
|
||||
xmlbuilder@^4.1.0:
|
||||
version "4.2.1"
|
||||
@@ -9246,6 +9323,12 @@ yallist@^3.0.0, yallist@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9"
|
||||
|
||||
yargs-parser@^10.0.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"
|
||||
dependencies:
|
||||
camelcase "^4.1.0"
|
||||
|
||||
yargs-parser@^4.2.0:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c"
|
||||
|
||||
Reference in New Issue
Block a user