diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index 20ad3185..27f983b4 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -234,26 +234,34 @@ export default class CodeEditor extends React.Component { } handlePaste (editor, e) { - const dataTransferItem = e.clipboardData.items[0] - if (!dataTransferItem.type.match('image')) return + const clipboardData = e.clipboardData + 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 reader = new FileReader() + let base64data - const blob = dataTransferItem.getAsFile() - const reader = new window.FileReader() - let base64data - - reader.readAsDataURL(blob) - reader.onloadend = () => { - base64data = reader.result.replace(/^data:image\/png;base64,/, '') - base64data += base64data.replace('+', ' ') - const binaryData = new Buffer(base64data, 'base64').toString('binary') - const imageName = Math.random().toString(36).slice(-16) - const storagePath = findStorage(this.props.storageKey).path - const imageDir = path.join(storagePath, 'images') - if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir) - const imagePath = path.join(imageDir, `${imageName}.png`) - fs.writeFile(imagePath, binaryData, 'binary') - const imageMd = `![${imageName}](${path.join('/:storage', `${imageName}.png`)})` - this.insertImageMd(imageMd) + reader.readAsDataURL(blob) + reader.onloadend = () => { + base64data = reader.result.replace(/^data:image\/png;base64,/, '') + base64data += base64data.replace('+', ' ') + const binaryData = new Buffer(base64data, 'base64').toString('binary') + const imageName = Math.random().toString(36).slice(-16) + const storagePath = findStorage(this.props.storageKey).path + const imageDir = path.join(storagePath, 'images') + if (!fs.existsSync(imageDir)) fs.mkdirSync(imageDir) + const imagePath = path.join(imageDir, `${imageName}.png`) + fs.writeFile(imagePath, binaryData, 'binary') + const imageMd = `![${imageName}](${path.join('/:storage', `${imageName}.png`)})` + this.insertImageMd(imageMd) + } + } else if (this.props.fetchUrlTitle && isURL(pastedTxt)) { + this.handlePasteUrl(e, editor, pastedTxt) } } @@ -261,6 +269,31 @@ export default class CodeEditor extends React.Component { 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 () { diff --git a/browser/components/MarkdownEditor.js b/browser/components/MarkdownEditor.js index 8d79629d..f02a146a 100644 --- a/browser/components/MarkdownEditor.js +++ b/browser/components/MarkdownEditor.js @@ -261,6 +261,7 @@ class MarkdownEditor extends React.Component { displayLineNumbers={config.editor.displayLineNumbers} scrollPastEnd={config.editor.scrollPastEnd} storageKey={storageKey} + fetchUrlTitle={config.editor.fetchUrlTitle} onChange={(e) => this.handleChange(e)} onBlur={(e) => this.handleBlur(e)} /> diff --git a/browser/components/MarkdownSplitEditor.js b/browser/components/MarkdownSplitEditor.js index ea1a7b1e..505fbaf4 100644 --- a/browser/components/MarkdownSplitEditor.js +++ b/browser/components/MarkdownSplitEditor.js @@ -111,6 +111,7 @@ class MarkdownSplitEditor extends React.Component { indentType={config.editor.indentType} indentSize={editorIndentSize} scrollPastEnd={config.editor.scrollPastEnd} + fetchUrlTitle={config.editor.fetchUrlTitle} storageKey={storageKey} onChange={this.handleOnChange.bind(this)} onScroll={this.handleScroll.bind(this)} diff --git a/browser/finder/NoteDetail.js b/browser/finder/NoteDetail.js new file mode 100644 index 00000000..e69de29b diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js index 366c785b..791b490e 100644 --- a/browser/main/Detail/SnippetNoteDetail.js +++ b/browser/main/Detail/SnippetNoteDetail.js @@ -568,6 +568,7 @@ class SnippetNoteDetail extends React.Component { displayLineNumbers={config.editor.displayLineNumbers} keyMap={config.editor.keyMap} scrollPastEnd={config.editor.scrollPastEnd} + fetchUrlTitle={config.editor.fetchUrlTitle} onChange={(e) => this.handleCodeChange(index)(e)} ref={'code-' + index} /> diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js index fde7dafd..0c8d6ee9 100644 --- a/browser/main/lib/ConfigManager.js +++ b/browser/main/lib/ConfigManager.js @@ -36,7 +36,8 @@ export const DEFAULT_CONFIG = { displayLineNumbers: true, switchPreview: 'BLUR', // Available value: RIGHTCLICK, BLUR scrollPastEnd: false, - type: 'SPLIT' + type: 'SPLIT', + fetchUrlTitle: true }, preview: { fontSize: '14', diff --git a/browser/main/modals/PreferencesModal/UiTab.js b/browser/main/modals/PreferencesModal/UiTab.js index 654e1dfd..50e13f6c 100644 --- a/browser/main/modals/PreferencesModal/UiTab.js +++ b/browser/main/modals/PreferencesModal/UiTab.js @@ -76,7 +76,8 @@ class UiTab extends React.Component { displayLineNumbers: this.refs.editorDisplayLineNumbers.checked, switchPreview: this.refs.editorSwitchPreview.value, keyMap: this.refs.editorKeyMap.value, - scrollPastEnd: this.refs.scrollPastEnd.checked + scrollPastEnd: this.refs.scrollPastEnd.checked, + fetchUrlTitle: this.refs.editorFetchUrlTitle.checked }, preview: { fontSize: this.refs.previewFontSize.value, @@ -328,6 +329,17 @@ class UiTab extends React.Component { +
+ +
+
Preview