mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-13 17:56:25 +00:00
Merge branch 'master' of https://github.com/BoostIO/Boostnote into all-notes-storage-labels
This commit is contained in:
@@ -7,6 +7,7 @@ import path from 'path'
|
|||||||
import copyImage from 'browser/main/lib/dataApi/copyImage'
|
import copyImage from 'browser/main/lib/dataApi/copyImage'
|
||||||
import { findStorage } from 'browser/lib/findStorage'
|
import { findStorage } from 'browser/lib/findStorage'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import eventEmitter from 'browser/main/lib/eventEmitter'
|
||||||
|
|
||||||
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
CodeMirror.modeURL = '../node_modules/codemirror/mode/%N/%N.js'
|
||||||
|
|
||||||
@@ -47,6 +48,40 @@ export default class CodeEditor extends React.Component {
|
|||||||
this.loadStyleHandler = (e) => {
|
this.loadStyleHandler = (e) => {
|
||||||
this.editor.refresh()
|
this.editor.refresh()
|
||||||
}
|
}
|
||||||
|
this.searchHandler = (e, msg) => this.handleSearch(msg)
|
||||||
|
this.searchState = null
|
||||||
|
}
|
||||||
|
|
||||||
|
handleSearch (msg) {
|
||||||
|
const cm = this.editor
|
||||||
|
const component = this
|
||||||
|
|
||||||
|
if (component.searchState) cm.removeOverlay(component.searchState)
|
||||||
|
if (msg.length < 3) return
|
||||||
|
|
||||||
|
cm.operation(function () {
|
||||||
|
component.searchState = makeOverlay(msg, 'searching')
|
||||||
|
cm.addOverlay(component.searchState)
|
||||||
|
|
||||||
|
function makeOverlay (query, style) {
|
||||||
|
query = new RegExp(query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), 'gi')
|
||||||
|
return {
|
||||||
|
token: function (stream) {
|
||||||
|
query.lastIndex = stream.pos
|
||||||
|
var match = query.exec(stream.string)
|
||||||
|
if (match && match.index === stream.pos) {
|
||||||
|
stream.pos += match[0].length || 1
|
||||||
|
return style
|
||||||
|
} else if (match) {
|
||||||
|
stream.pos = match.index
|
||||||
|
} else {
|
||||||
|
stream.skipToEnd()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
@@ -107,6 +142,10 @@ export default class CodeEditor extends React.Component {
|
|||||||
this.editor.on('blur', this.blurHandler)
|
this.editor.on('blur', this.blurHandler)
|
||||||
this.editor.on('change', this.changeHandler)
|
this.editor.on('change', this.changeHandler)
|
||||||
this.editor.on('paste', this.pasteHandler)
|
this.editor.on('paste', this.pasteHandler)
|
||||||
|
eventEmitter.on('top:search', this.searchHandler)
|
||||||
|
|
||||||
|
eventEmitter.emit('code:init')
|
||||||
|
this.editor.on('scroll', this.scrollHandler)
|
||||||
|
|
||||||
const editorTheme = document.getElementById('editorTheme')
|
const editorTheme = document.getElementById('editorTheme')
|
||||||
editorTheme.addEventListener('load', this.loadStyleHandler)
|
editorTheme.addEventListener('load', this.loadStyleHandler)
|
||||||
@@ -126,6 +165,8 @@ export default class CodeEditor extends React.Component {
|
|||||||
this.editor.off('blur', this.blurHandler)
|
this.editor.off('blur', this.blurHandler)
|
||||||
this.editor.off('change', this.changeHandler)
|
this.editor.off('change', this.changeHandler)
|
||||||
this.editor.off('paste', this.pasteHandler)
|
this.editor.off('paste', this.pasteHandler)
|
||||||
|
eventEmitter.off('top:search', this.searchHandler)
|
||||||
|
this.editor.off('scroll', this.scrollHandler)
|
||||||
const editorTheme = document.getElementById('editorTheme')
|
const editorTheme = document.getElementById('editorTheme')
|
||||||
editorTheme.removeEventListener('load', this.loadStyleHandler)
|
editorTheme.removeEventListener('load', this.loadStyleHandler)
|
||||||
}
|
}
|
||||||
@@ -231,11 +272,16 @@ export default class CodeEditor extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handlePaste (editor, e) {
|
handlePaste (editor, e) {
|
||||||
const dataTransferItem = e.clipboardData.items[0]
|
const clipboardData = e.clipboardData
|
||||||
if (!dataTransferItem.type.match('image')) return
|
const dataTransferItem = clipboardData.items[0]
|
||||||
|
const pastedTxt = clipboardData.getData('text')
|
||||||
|
const isURL = (str) => {
|
||||||
|
const matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/
|
||||||
|
return matcher.test(str)
|
||||||
|
}
|
||||||
|
if (dataTransferItem.type.match('image')) {
|
||||||
const blob = dataTransferItem.getAsFile()
|
const blob = dataTransferItem.getAsFile()
|
||||||
const reader = new window.FileReader()
|
const reader = new FileReader()
|
||||||
let base64data
|
let base64data
|
||||||
|
|
||||||
reader.readAsDataURL(blob)
|
reader.readAsDataURL(blob)
|
||||||
@@ -252,6 +298,41 @@ export default class CodeEditor extends React.Component {
|
|||||||
const imageMd = `})`
|
const imageMd = `})`
|
||||||
this.insertImageMd(imageMd)
|
this.insertImageMd(imageMd)
|
||||||
}
|
}
|
||||||
|
} else if (this.props.fetchUrlTitle && isURL(pastedTxt)) {
|
||||||
|
this.handlePasteUrl(e, editor, pastedTxt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleScroll (e) {
|
||||||
|
if (this.props.onScroll) {
|
||||||
|
this.props.onScroll(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePasteUrl (e, editor, pastedTxt) {
|
||||||
|
e.preventDefault()
|
||||||
|
const taggedUrl = `<${pastedTxt}>`
|
||||||
|
editor.replaceSelection(taggedUrl)
|
||||||
|
|
||||||
|
fetch(pastedTxt, {
|
||||||
|
method: 'get'
|
||||||
|
}).then((response) => {
|
||||||
|
return (response.text())
|
||||||
|
}).then((response) => {
|
||||||
|
const parsedResponse = (new window.DOMParser()).parseFromString(response, 'text/html')
|
||||||
|
const value = editor.getValue()
|
||||||
|
const cursor = editor.getCursor()
|
||||||
|
const LinkWithTitle = `[${parsedResponse.title}](${pastedTxt})`
|
||||||
|
const newValue = value.replace(taggedUrl, LinkWithTitle)
|
||||||
|
editor.setValue(newValue)
|
||||||
|
editor.setCursor(cursor)
|
||||||
|
}).catch((e) => {
|
||||||
|
const value = editor.getValue()
|
||||||
|
const newValue = value.replace(taggedUrl, pastedTxt)
|
||||||
|
const cursor = editor.getCursor()
|
||||||
|
editor.setValue(newValue)
|
||||||
|
editor.setCursor(cursor)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
|
|||||||
@@ -261,6 +261,7 @@ class MarkdownEditor extends React.Component {
|
|||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
storageKey={storageKey}
|
storageKey={storageKey}
|
||||||
|
fetchUrlTitle={config.editor.fetchUrlTitle}
|
||||||
onChange={(e) => this.handleChange(e)}
|
onChange={(e) => this.handleChange(e)}
|
||||||
onBlur={(e) => this.handleBlur(e)}
|
onBlur={(e) => this.handleBlur(e)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.mouseDownHandler = (e) => this.handleMouseDown(e)
|
this.mouseDownHandler = (e) => this.handleMouseDown(e)
|
||||||
this.mouseUpHandler = (e) => this.handleMouseUp(e)
|
this.mouseUpHandler = (e) => this.handleMouseUp(e)
|
||||||
this.DoubleClickHandler = (e) => this.handleDoubleClick(e)
|
this.DoubleClickHandler = (e) => this.handleDoubleClick(e)
|
||||||
|
this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, {leading: false, trailing: true})
|
||||||
this.anchorClickHandler = (e) => this.handlePreviewAnchorClick(e)
|
this.anchorClickHandler = (e) => this.handlePreviewAnchorClick(e)
|
||||||
this.checkboxClickHandler = (e) => this.handleCheckboxClick(e)
|
this.checkboxClickHandler = (e) => this.handleCheckboxClick(e)
|
||||||
this.saveAsTextHandler = () => this.handleSaveAsText()
|
this.saveAsTextHandler = () => this.handleSaveAsText()
|
||||||
@@ -151,6 +152,12 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.props.onCheckboxClick(e)
|
this.props.onCheckboxClick(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleScroll (e) {
|
||||||
|
if (this.props.onScroll) {
|
||||||
|
this.props.onScroll(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleContextMenu (e) {
|
handleContextMenu (e) {
|
||||||
this.props.onContextMenu(e)
|
this.props.onContextMenu(e)
|
||||||
}
|
}
|
||||||
@@ -279,6 +286,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.refs.root.contentWindow.document.addEventListener('dblclick', this.DoubleClickHandler)
|
this.refs.root.contentWindow.document.addEventListener('dblclick', this.DoubleClickHandler)
|
||||||
this.refs.root.contentWindow.document.addEventListener('drop', this.preventImageDroppedHandler)
|
this.refs.root.contentWindow.document.addEventListener('drop', this.preventImageDroppedHandler)
|
||||||
this.refs.root.contentWindow.document.addEventListener('dragover', 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-text', this.saveAsTextHandler)
|
||||||
eventEmitter.on('export:save-md', this.saveAsMdHandler)
|
eventEmitter.on('export:save-md', this.saveAsMdHandler)
|
||||||
eventEmitter.on('export:save-html', this.saveAsHtmlHandler)
|
eventEmitter.on('export:save-html', this.saveAsHtmlHandler)
|
||||||
@@ -292,6 +300,7 @@ export default class MarkdownPreview extends React.Component {
|
|||||||
this.refs.root.contentWindow.document.removeEventListener('dblclick', this.DoubleClickHandler)
|
this.refs.root.contentWindow.document.removeEventListener('dblclick', this.DoubleClickHandler)
|
||||||
this.refs.root.contentWindow.document.removeEventListener('drop', this.preventImageDroppedHandler)
|
this.refs.root.contentWindow.document.removeEventListener('drop', this.preventImageDroppedHandler)
|
||||||
this.refs.root.contentWindow.document.removeEventListener('dragover', 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-text', this.saveAsTextHandler)
|
||||||
eventEmitter.off('export:save-md', this.saveAsMdHandler)
|
eventEmitter.off('export:save-md', this.saveAsMdHandler)
|
||||||
eventEmitter.off('export:save-html', this.saveAsHtmlHandler)
|
eventEmitter.off('export:save-html', this.saveAsHtmlHandler)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import React from 'react'
|
|||||||
import CodeEditor from 'browser/components/CodeEditor'
|
import CodeEditor from 'browser/components/CodeEditor'
|
||||||
import MarkdownPreview from 'browser/components/MarkdownPreview'
|
import MarkdownPreview from 'browser/components/MarkdownPreview'
|
||||||
import { findStorage } from 'browser/lib/findStorage'
|
import { findStorage } from 'browser/lib/findStorage'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
import styles from './MarkdownSplitEditor.styl'
|
import styles from './MarkdownSplitEditor.styl'
|
||||||
import CSSModules from 'browser/lib/CSSModules'
|
import CSSModules from 'browser/lib/CSSModules'
|
||||||
@@ -12,6 +13,7 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
this.value = props.value
|
this.value = props.value
|
||||||
this.focus = () => this.refs.code.focus()
|
this.focus = () => this.refs.code.focus()
|
||||||
this.reload = () => this.refs.code.reload()
|
this.reload = () => this.refs.code.reload()
|
||||||
|
this.userScroll = true
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOnChange () {
|
handleOnChange () {
|
||||||
@@ -19,6 +21,49 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
this.props.onChange()
|
this.props.onChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleScroll (e) {
|
||||||
|
const previewDoc = _.get(this, 'refs.preview.refs.root.contentWindow.document')
|
||||||
|
const codeDoc = _.get(this, 'refs.code.editor.doc')
|
||||||
|
let srcTop, srcHeight, targetTop, targetHeight
|
||||||
|
|
||||||
|
if (this.userScroll) {
|
||||||
|
if (e.doc) {
|
||||||
|
srcTop = _.get(e, 'doc.scrollTop')
|
||||||
|
srcHeight = _.get(e, 'doc.height')
|
||||||
|
targetTop = _.get(previewDoc, 'body.scrollTop')
|
||||||
|
targetHeight = _.get(previewDoc, 'body.scrollHeight')
|
||||||
|
} else {
|
||||||
|
srcTop = _.get(previewDoc, 'body.scrollTop')
|
||||||
|
srcHeight = _.get(previewDoc, 'body.scrollHeight')
|
||||||
|
targetTop = _.get(codeDoc, 'scrollTop')
|
||||||
|
targetHeight = _.get(codeDoc, 'height')
|
||||||
|
}
|
||||||
|
|
||||||
|
const distance = (targetHeight * srcTop / srcHeight) - targetTop
|
||||||
|
const framerate = 1000 / 60
|
||||||
|
const frames = 20
|
||||||
|
const refractory = frames * framerate
|
||||||
|
|
||||||
|
this.userScroll = false
|
||||||
|
|
||||||
|
let frame = 0
|
||||||
|
let scrollPos, time
|
||||||
|
const timer = setInterval(() => {
|
||||||
|
time = frame / frames
|
||||||
|
scrollPos = time < 0.5
|
||||||
|
? 2 * time * time // ease in
|
||||||
|
: -1 + (4 - 2 * time) * time // ease out
|
||||||
|
if (e.doc) _.set(previewDoc, 'body.scrollTop', targetTop + scrollPos * distance)
|
||||||
|
else _.get(this, 'refs.code.editor').scrollTo(0, targetTop + scrollPos * distance)
|
||||||
|
if (frame >= frames) {
|
||||||
|
clearInterval(timer)
|
||||||
|
setTimeout(() => { this.userScroll = true }, refractory)
|
||||||
|
}
|
||||||
|
frame++
|
||||||
|
}, framerate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleCheckboxClick (e) {
|
handleCheckboxClick (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -66,8 +111,10 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
indentType={config.editor.indentType}
|
indentType={config.editor.indentType}
|
||||||
indentSize={editorIndentSize}
|
indentSize={editorIndentSize}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
|
fetchUrlTitle={config.editor.fetchUrlTitle}
|
||||||
storageKey={storageKey}
|
storageKey={storageKey}
|
||||||
onChange={this.handleOnChange.bind(this)}
|
onChange={this.handleOnChange.bind(this)}
|
||||||
|
onScroll={this.handleScroll.bind(this)}
|
||||||
/>
|
/>
|
||||||
<MarkdownPreview
|
<MarkdownPreview
|
||||||
style={previewStyle}
|
style={previewStyle}
|
||||||
@@ -84,6 +131,7 @@ class MarkdownSplitEditor extends React.Component {
|
|||||||
tabInde='0'
|
tabInde='0'
|
||||||
value={value}
|
value={value}
|
||||||
onCheckboxClick={(e) => this.handleCheckboxClick(e)}
|
onCheckboxClick={(e) => this.handleCheckboxClick(e)}
|
||||||
|
onScroll={this.handleScroll.bind(this)}
|
||||||
showCopyNotification={config.ui.showCopyNotification}
|
showCopyNotification={config.ui.showCopyNotification}
|
||||||
storagePath={storage.path}
|
storagePath={storage.path}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -220,6 +220,7 @@ pre
|
|||||||
background-color white
|
background-color white
|
||||||
&.CodeMirror
|
&.CodeMirror
|
||||||
height initial
|
height initial
|
||||||
|
flex-wrap wrap
|
||||||
&>code
|
&>code
|
||||||
flex 1
|
flex 1
|
||||||
overflow-x auto
|
overflow-x auto
|
||||||
@@ -229,6 +230,13 @@ pre
|
|||||||
padding 0
|
padding 0
|
||||||
border none
|
border none
|
||||||
border-radius 0
|
border-radius 0
|
||||||
|
&>span.filename
|
||||||
|
width 100%
|
||||||
|
border-radius: 5px 0px 0px 0px
|
||||||
|
margin -8px 100% 8px -8px
|
||||||
|
padding 0px 6px
|
||||||
|
background-color #777;
|
||||||
|
color white
|
||||||
&>span.lineNumber
|
&>span.lineNumber
|
||||||
display none
|
display none
|
||||||
font-size 1em
|
font-size 1em
|
||||||
|
|||||||
0
browser/finder/NoteDetail.js
Normal file
0
browser/finder/NoteDetail.js
Normal file
@@ -9,10 +9,11 @@ import {lastFindInArray} from './utils'
|
|||||||
const katex = window.katex
|
const katex = window.katex
|
||||||
const config = ConfigManager.get()
|
const config = ConfigManager.get()
|
||||||
|
|
||||||
function createGutter (str) {
|
function createGutter (str, firstLineNumber) {
|
||||||
const lc = (str.match(/\n/g) || []).length
|
if (Number.isNaN(firstLineNumber)) firstLineNumber = 1
|
||||||
|
const lastLineNumber = (str.match(/\n/g) || []).length + firstLineNumber - 1
|
||||||
const lines = []
|
const lines = []
|
||||||
for (let i = 1; i <= lc; i++) {
|
for (let i = firstLineNumber; i <= lastLineNumber; i++) {
|
||||||
lines.push('<span class="CodeMirror-linenumber">' + i + '</span>')
|
lines.push('<span class="CodeMirror-linenumber">' + i + '</span>')
|
||||||
}
|
}
|
||||||
return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
|
return '<span class="lineNumber CodeMirror-gutters">' + lines.join('') + '</span>'
|
||||||
@@ -25,15 +26,22 @@ var md = markdownit({
|
|||||||
xhtmlOut: true,
|
xhtmlOut: true,
|
||||||
breaks: true,
|
breaks: true,
|
||||||
highlight: function (str, lang) {
|
highlight: function (str, lang) {
|
||||||
if (lang === 'flowchart') {
|
const delimiter = ':'
|
||||||
|
const langInfo = lang.split(delimiter)
|
||||||
|
const langType = langInfo[0]
|
||||||
|
const fileName = langInfo[1] || ''
|
||||||
|
const firstLineNumber = parseInt(langInfo[2], 10)
|
||||||
|
|
||||||
|
if (langType === 'flowchart') {
|
||||||
return `<pre class="flowchart">${str}</pre>`
|
return `<pre class="flowchart">${str}</pre>`
|
||||||
}
|
}
|
||||||
if (lang === 'sequence') {
|
if (langType === 'sequence') {
|
||||||
return `<pre class="sequence">${str}</pre>`
|
return `<pre class="sequence">${str}</pre>`
|
||||||
}
|
}
|
||||||
return '<pre class="code">' +
|
return '<pre class="code">' +
|
||||||
createGutter(str) +
|
'<span class="filename">' + fileName + '</span>' +
|
||||||
'<code class="' + lang + '">' +
|
createGutter(str, firstLineNumber) +
|
||||||
|
'<code class="' + langType + '">' +
|
||||||
str +
|
str +
|
||||||
'</code></pre>'
|
'</code></pre>'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,11 +68,8 @@ class MarkdownNoteDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
if (this.saveQueue != null) this.saveNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidUnmount () {
|
|
||||||
ee.off('topbar:togglelockbutton', this.toggleLockButton)
|
ee.off('topbar:togglelockbutton', this.toggleLockButton)
|
||||||
|
if (this.saveQueue != null) this.saveNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUpdateTag () {
|
handleUpdateTag () {
|
||||||
|
|||||||
@@ -568,6 +568,7 @@ class SnippetNoteDetail extends React.Component {
|
|||||||
displayLineNumbers={config.editor.displayLineNumbers}
|
displayLineNumbers={config.editor.displayLineNumbers}
|
||||||
keyMap={config.editor.keyMap}
|
keyMap={config.editor.keyMap}
|
||||||
scrollPastEnd={config.editor.scrollPastEnd}
|
scrollPastEnd={config.editor.scrollPastEnd}
|
||||||
|
fetchUrlTitle={config.editor.fetchUrlTitle}
|
||||||
onChange={(e) => this.handleCodeChange(index)(e)}
|
onChange={(e) => this.handleCodeChange(index)(e)}
|
||||||
ref={'code-' + index}
|
ref={'code-' + index}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -22,14 +22,18 @@ class TopBar extends React.Component {
|
|||||||
this.focusSearchHandler = () => {
|
this.focusSearchHandler = () => {
|
||||||
this.handleOnSearchFocus()
|
this.handleOnSearchFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.codeInitHandler = this.handleCodeInit.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
ee.on('top:focus-search', this.focusSearchHandler)
|
ee.on('top:focus-search', this.focusSearchHandler)
|
||||||
|
ee.on('code:init', this.codeInitHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
ee.off('top:focus-search', this.focusSearchHandler)
|
ee.off('top:focus-search', this.focusSearchHandler)
|
||||||
|
ee.off('code:init', this.codeInitHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleKeyDown (e) {
|
handleKeyDown (e) {
|
||||||
@@ -73,14 +77,16 @@ class TopBar extends React.Component {
|
|||||||
|
|
||||||
handleSearchChange (e) {
|
handleSearchChange (e) {
|
||||||
const { router } = this.context
|
const { router } = this.context
|
||||||
|
const keyword = this.refs.searchInput.value
|
||||||
if (this.state.isAlphabet || this.state.isConfirmTranslation) {
|
if (this.state.isAlphabet || this.state.isConfirmTranslation) {
|
||||||
router.push('/searched')
|
router.push('/searched')
|
||||||
} else {
|
} else {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
}
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
search: this.refs.searchInput.value
|
search: keyword
|
||||||
})
|
})
|
||||||
|
ee.emit('top:search', keyword)
|
||||||
}
|
}
|
||||||
|
|
||||||
handleSearchFocus (e) {
|
handleSearchFocus (e) {
|
||||||
@@ -115,6 +121,10 @@ class TopBar extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleCodeInit () {
|
||||||
|
ee.emit('top:search', this.refs.searchInput.value)
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { config, style, location } = this.props
|
const { config, style, location } = this.props
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ export const DEFAULT_CONFIG = {
|
|||||||
displayLineNumbers: true,
|
displayLineNumbers: true,
|
||||||
switchPreview: 'BLUR', // Available value: RIGHTCLICK, BLUR
|
switchPreview: 'BLUR', // Available value: RIGHTCLICK, BLUR
|
||||||
scrollPastEnd: false,
|
scrollPastEnd: false,
|
||||||
type: 'SPLIT'
|
type: 'SPLIT',
|
||||||
|
fetchUrlTitle: true
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
fontSize: '14',
|
fontSize: '14',
|
||||||
|
|||||||
@@ -76,7 +76,8 @@ class UiTab extends React.Component {
|
|||||||
displayLineNumbers: this.refs.editorDisplayLineNumbers.checked,
|
displayLineNumbers: this.refs.editorDisplayLineNumbers.checked,
|
||||||
switchPreview: this.refs.editorSwitchPreview.value,
|
switchPreview: this.refs.editorSwitchPreview.value,
|
||||||
keyMap: this.refs.editorKeyMap.value,
|
keyMap: this.refs.editorKeyMap.value,
|
||||||
scrollPastEnd: this.refs.scrollPastEnd.checked
|
scrollPastEnd: this.refs.scrollPastEnd.checked,
|
||||||
|
fetchUrlTitle: this.refs.editorFetchUrlTitle.checked
|
||||||
},
|
},
|
||||||
preview: {
|
preview: {
|
||||||
fontSize: this.refs.previewFontSize.value,
|
fontSize: this.refs.previewFontSize.value,
|
||||||
@@ -328,6 +329,17 @@ class UiTab extends React.Component {
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div styleName='group-checkBoxSection'>
|
||||||
|
<label>
|
||||||
|
<input onChange={(e) => this.handleUIChange(e)}
|
||||||
|
checked={this.state.config.editor.fetchUrlTitle}
|
||||||
|
ref='editorFetchUrlTitle'
|
||||||
|
type='checkbox'
|
||||||
|
/>
|
||||||
|
Bring in web page title when pasting URL on editor
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div styleName='group-header2'>Preview</div>
|
<div styleName='group-header2'>Preview</div>
|
||||||
<div styleName='group-section'>
|
<div styleName='group-section'>
|
||||||
<div styleName='group-section-label'>
|
<div styleName='group-section-label'>
|
||||||
|
|||||||
Reference in New Issue
Block a user