diff --git a/.eslintrc b/.eslintrc index be8cb903..67b6c8fe 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,6 @@ { - "extends": ["standard", "standard-jsx", "plugin:react/recommended"], - "plugins": ["react"], + "extends": ["standard", "standard-jsx", "plugin:react/recommended", "prettier"], + "plugins": ["react", "prettier"], "rules": { "no-useless-escape": 0, "prefer-const": ["warn", { @@ -13,7 +13,8 @@ "react/no-string-refs": 0, "react/no-find-dom-node": "warn", "react/no-render-return-value": "warn", - "react/no-deprecated": "warn" + "react/no-deprecated": "warn", + "prettier/prettier": ["error"] }, "globals": { "FileReader": true, diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..515c6cd5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "semi": false, + "jsxSingleQuote": true +} \ No newline at end of file diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js index bc2719dc..a5bb009a 100644 --- a/browser/components/CodeEditor.js +++ b/browser/components/CodeEditor.js @@ -6,11 +6,7 @@ import hljs from 'highlight.js' import 'codemirror-mode-elixir' import attachmentManagement from 'browser/main/lib/dataApi/attachmentManagement' import convertModeName from 'browser/lib/convertModeName' -import { - options, - TableEditor, - Alignment -} from '@susisu/mte-kernel' +import { options, TableEditor, Alignment } from '@susisu/mte-kernel' import TextEditorInterface from 'browser/lib/TextEditorInterface' import eventEmitter from 'browser/main/lib/eventEmitter' import iconv from 'iconv-lite' @@ -20,11 +16,15 @@ import styles from '../components/CodeEditor.styl' const { ipcRenderer, remote, clipboard } = require('electron') import normalizeEditorFontFamily from 'browser/lib/normalizeEditorFontFamily' const spellcheck = require('browser/lib/spellcheck') -const buildEditorContextMenu = require('browser/lib/contextMenuBuilder').buildEditorContextMenu +const buildEditorContextMenu = require('browser/lib/contextMenuBuilder') + .buildEditorContextMenu import { createTurndownService } from '../lib/turndown' -import {languageMaps} from '../lib/CMLanguageList' +import { languageMaps } from '../lib/CMLanguageList' import snippetManager from '../lib/SnippetManager' -import {generateInEditor, tocExistsInEditor} from 'browser/lib/markdown-toc-generator' +import { + generateInEditor, + tocExistsInEditor +} from 'browser/lib/markdown-toc-generator' import markdownlint from 'markdownlint' import Jsonlint from 'jsonlint-mod' import { DEFAULT_CONFIG } from '../main/lib/ConfigManager' @@ -33,28 +33,38 @@ import prettier from 'prettier' 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 + })) + : [] -function translateHotkey (hotkey) { - return hotkey.replace(/\s*\+\s*/g, '-').replace(/Command/g, 'Cmd').replace(/Control/g, 'Ctrl') +function translateHotkey(hotkey) { + return hotkey + .replace(/\s*\+\s*/g, '-') + .replace(/Command/g, 'Cmd') + .replace(/Control/g, 'Ctrl') } export default class CodeEditor extends React.Component { - constructor (props) { + constructor(props) { super(props) this.scrollHandler = _.debounce(this.handleScroll.bind(this), 100, { leading: false, trailing: true }) - this.changeHandler = (editor, changeObject) => this.handleChange(editor, changeObject) - this.highlightHandler = (editor, changeObject) => this.handleHighlight(editor, changeObject) + this.changeHandler = (editor, changeObject) => + this.handleChange(editor, changeObject) + this.highlightHandler = (editor, changeObject) => + this.handleHighlight(editor, changeObject) this.focusHandler = () => { ipcRenderer.send('editor:focused', true) } - const debouncedDeletionOfAttachments = _.debounce(attachmentManagement.deleteAttachmentsNotPresentInNote, 30000) + const debouncedDeletionOfAttachments = _.debounce( + attachmentManagement.deleteAttachmentsNotPresentInNote, + 30000 + ) this.blurHandler = (editor, e) => { ipcRenderer.send('editor:focused', false) if (e == null) return null @@ -66,12 +76,13 @@ export default class CodeEditor extends React.Component { el = el.parentNode } this.props.onBlur != null && this.props.onBlur(e) - const { - storageKey, - noteKey - } = this.props + const { storageKey, noteKey } = this.props if (this.props.deleteUnusedAttachments === true) { - debouncedDeletionOfAttachments(this.editor.getValue(), storageKey, noteKey) + debouncedDeletionOfAttachments( + this.editor.getValue(), + storageKey, + noteKey + ) } } this.pasteHandler = (editor, e) => { @@ -91,7 +102,7 @@ export default class CodeEditor extends React.Component { this.formatTable = () => this.handleFormatTable() if (props.switchPreview !== 'RIGHTCLICK') { - this.contextMenuHandler = function (editor, event) { + this.contextMenuHandler = function(editor, event) { const menu = buildEditorContextMenu(editor, event) if (menu != null) { setTimeout(() => menu.popup(remote.getCurrentWindow()), 30) @@ -104,24 +115,24 @@ export default class CodeEditor extends React.Component { this.turndownService = createTurndownService() } - handleSearch (msg) { + handleSearch(msg) { const cm = this.editor const component = this if (component.searchState) cm.removeOverlay(component.searchState) if (msg.length < 1) return - cm.operation(function () { + cm.operation(function() { component.searchState = makeOverlay(msg, 'searching') cm.addOverlay(component.searchState) - function makeOverlay (query, style) { + function makeOverlay(query, style) { query = new RegExp( query.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), 'gi' ) return { - token: function (stream) { + token: function(stream) { query.lastIndex = stream.pos var match = query.exec(stream.string) if (match && match.index === stream.pos) { @@ -138,25 +149,27 @@ export default class CodeEditor extends React.Component { }) } - handleFormatTable () { - this.tableEditor.formatAll(options({ - textWidthOptions: {} - })) + handleFormatTable() { + this.tableEditor.formatAll( + options({ + textWidthOptions: {} + }) + ) } - handleEditorActivity () { + handleEditorActivity() { if (!this.textEditorInterface.transaction) { this.updateTableEditorState() } } - updateDefaultKeyMap () { + updateDefaultKeyMap() { const { hotkey } = this.props const self = this const expandSnippet = snippetManager.expandSnippet this.defaultKeyMap = CodeMirror.normalizeKeyMap({ - Tab: function (cm) { + Tab: function(cm) { const cursor = cm.getCursor() const line = cm.getLine(cursor.line) const cursorPosition = cursor.ch @@ -198,17 +211,17 @@ export default class CodeEditor extends React.Component { } } }, - 'Cmd-Left': function (cm) { + 'Cmd-Left': function(cm) { cm.execCommand('goLineLeft') }, - 'Cmd-T': function (cm) { + 'Cmd-T': function(cm) { // Do nothing }, - [translateHotkey(hotkey.insertDate)]: function (cm) { + [translateHotkey(hotkey.insertDate)]: function(cm) { const dateNow = new Date() cm.replaceSelection(dateNow.toLocaleDateString()) }, - [translateHotkey(hotkey.insertDateTime)]: function (cm) { + [translateHotkey(hotkey.insertDateTime)]: function(cm) { const dateNow = new Date() cm.replaceSelection(dateNow.toLocaleString()) }, @@ -231,7 +244,10 @@ export default class CodeEditor extends React.Component { currentConfig.cursorOffset = cm.doc.indexFromPos(cursorPos) // Prettify contents of editor - const formattedTextDetails = prettier.formatWithCursor(cm.doc.getValue(), currentConfig) + const formattedTextDetails = prettier.formatWithCursor( + cm.doc.getValue(), + currentConfig + ) const formattedText = formattedTextDetails.formatted const formattedCursorPos = formattedTextDetails.cursorOffset @@ -246,7 +262,8 @@ export default class CodeEditor extends React.Component { const appendLineBreak = /\n$/.test(selection) const sorted = _.split(selection.trim(), '\n').sort() - const sortedString = _.join(sorted, '\n') + (appendLineBreak ? '\n' : '') + const sortedString = + _.join(sorted, '\n') + (appendLineBreak ? '\n' : '') cm.doc.replaceSelection(sortedString) }, @@ -256,7 +273,7 @@ export default class CodeEditor extends React.Component { }) } - updateTableEditorState () { + updateTableEditorState() { const active = this.tableEditor.cursorIsInTable(this.tableEditorOptions) if (active) { if (this.extraKeysMode !== 'editor') { @@ -272,7 +289,7 @@ export default class CodeEditor extends React.Component { } } - componentDidMount () { + componentDidMount() { const { rulers, enableRulers, enableMarkdownLint, RTL } = this.props eventEmitter.on('line:jump', this.scrollToLineHandeler) @@ -298,7 +315,11 @@ export default class CodeEditor extends React.Component { rtlMoveVisually: RTL, foldGutter: true, lint: enableMarkdownLint ? this.getCodeEditorLintConfig() : false, - gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter', 'CodeMirror-lint-markers'], + gutters: [ + 'CodeMirror-linenumbers', + 'CodeMirror-foldgutter', + 'CodeMirror-lint-markers' + ], autoCloseBrackets: { pairs: this.props.matchingPairs, triples: this.props.matchingTriples, @@ -309,7 +330,9 @@ export default class CodeEditor extends React.Component { prettierConfig: this.props.prettierConfig }) - document.querySelector('.CodeMirror-lint-markers').style.display = enableMarkdownLint ? 'inline-block' : 'none' + document.querySelector( + '.CodeMirror-lint-markers' + ).style.display = enableMarkdownLint ? 'inline-block' : 'none' if (!this.props.mode && this.props.value && this.props.autoDetect) { this.autoDetectLanguage(this.props.value) @@ -342,7 +365,7 @@ export default class CodeEditor extends React.Component { this.textEditorInterface = new TextEditorInterface(this.editor) this.tableEditor = new TableEditor(this.textEditorInterface) if (this.props.spellCheck) { - this.editor.addPanel(this.createSpellCheckPanel(), {position: 'bottom'}) + this.editor.addPanel(this.createSpellCheckPanel(), { position: 'bottom' }) } eventEmitter.on('code:format-table', this.formatTable) @@ -352,13 +375,13 @@ export default class CodeEditor extends React.Component { }) this.editorKeyMap = CodeMirror.normalizeKeyMap({ - 'Tab': () => { + Tab: () => { this.tableEditor.nextCell(this.tableEditorOptions) }, 'Shift-Tab': () => { this.tableEditor.previousCell(this.tableEditorOptions) }, - 'Enter': () => { + Enter: () => { this.tableEditor.nextRow(this.tableEditorOptions) }, 'Ctrl-Enter': () => { @@ -477,7 +500,7 @@ export default class CodeEditor extends React.Component { this.initialHighlighting() } - getWordBeforeCursor (line, lineNumber, cursorPosition) { + getWordBeforeCursor(line, lineNumber, cursorPosition) { let wordBeforeCursor = '' const originCursorPosition = cursorPosition const emptyChars = /\t|\s|\r|\n|\$/ @@ -514,11 +537,11 @@ export default class CodeEditor extends React.Component { } } - quitEditor () { + quitEditor() { document.querySelector('textarea').blur() } - componentWillUnmount () { + componentWillUnmount() { this.editor.off('focus', this.focusHandler) this.editor.off('blur', this.blurHandler) this.editor.off('change', this.changeHandler) @@ -533,7 +556,7 @@ export default class CodeEditor extends React.Component { eventEmitter.off('code:format-table', this.formatTable) } - componentDidUpdate (prevProps, prevState) { + componentDidUpdate(prevProps, prevState) { let needRefresh = false const { rulers, @@ -561,13 +584,18 @@ export default class CodeEditor extends React.Component { this.editor.setOption('direction', this.props.RTL ? 'rtl' : 'ltr') this.editor.setOption('rtlMoveVisually', this.props.RTL) } - if (prevProps.enableMarkdownLint !== enableMarkdownLint || prevProps.customMarkdownLintConfig !== customMarkdownLintConfig) { + if ( + prevProps.enableMarkdownLint !== enableMarkdownLint || + prevProps.customMarkdownLintConfig !== customMarkdownLintConfig + ) { if (!enableMarkdownLint) { - this.editor.setOption('lint', {default: false}) - document.querySelector('.CodeMirror-lint-markers').style.display = 'none' + this.editor.setOption('lint', { default: false }) + document.querySelector('.CodeMirror-lint-markers').style.display = + 'none' } else { this.editor.setOption('lint', this.getCodeEditorLintConfig()) - document.querySelector('.CodeMirror-lint-markers').style.display = 'inline-block' + document.querySelector('.CodeMirror-lint-markers').style.display = + 'inline-block' } needRefresh = true } @@ -599,9 +627,11 @@ export default class CodeEditor extends React.Component { this.editor.setOption('scrollPastEnd', this.props.scrollPastEnd) } - if (prevProps.matchingPairs !== this.props.matchingPairs || + if ( + prevProps.matchingPairs !== this.props.matchingPairs || prevProps.matchingTriples !== this.props.matchingTriples || - prevProps.explodingPairs !== this.props.explodingPairs) { + prevProps.explodingPairs !== this.props.explodingPairs + ) { const bracketObject = { pairs: this.props.matchingPairs, triples: this.props.matchingTriples, @@ -646,11 +676,18 @@ export default class CodeEditor extends React.Component { const elem = document.getElementById('editor-bottom-panel') elem.parentNode.removeChild(elem) } else { - this.editor.addPanel(this.createSpellCheckPanel(), {position: 'bottom'}) + this.editor.addPanel(this.createSpellCheckPanel(), { + position: 'bottom' + }) } } - if (prevProps.deleteUnusedAttachments !== this.props.deleteUnusedAttachments) { - this.editor.setOption('deleteUnusedAttachments', this.props.deleteUnusedAttachments) + if ( + prevProps.deleteUnusedAttachments !== this.props.deleteUnusedAttachments + ) { + this.editor.setOption( + 'deleteUnusedAttachments', + this.props.deleteUnusedAttachments + ) } if (needRefresh) { @@ -658,17 +695,19 @@ export default class CodeEditor extends React.Component { } } - getCodeEditorLintConfig () { + getCodeEditorLintConfig() { const { mode } = this.props const checkMarkdownNoteIsOpen = mode === 'Boost Flavored Markdown' - return checkMarkdownNoteIsOpen ? { - getAnnotations: this.validatorOfMarkdown, - async: true - } : false + return checkMarkdownNoteIsOpen + ? { + getAnnotations: this.validatorOfMarkdown, + async: true + } + : false } - validatorOfMarkdown (text, updateLinting) { + validatorOfMarkdown(text, updateLinting) { const { customMarkdownLintConfig } = this.props let lintConfigJson try { @@ -693,7 +732,7 @@ export default class CodeEditor extends React.Component { let ruleNames = '' item.ruleNames.map((ruleName, index) => { ruleNames += ruleName - ruleNames += (index === item.ruleNames.length - 1) ? ': ' : '/' + ruleNames += index === item.ruleNames.length - 1 ? ': ' : '/' }) const lineNumber = item.lineNumber - 1 foundIssues.push({ @@ -708,7 +747,7 @@ export default class CodeEditor extends React.Component { }) } - setMode (mode) { + setMode(mode) { let syntax = CodeMirror.findModeByName(convertModeName(mode || 'text')) if (syntax == null) syntax = CodeMirror.findModeByName('Plain Text') @@ -716,7 +755,7 @@ export default class CodeEditor extends React.Component { CodeMirror.autoLoadMode(this.editor, syntax.mode) } - handleChange (editor, changeObject) { + handleChange(editor, changeObject) { spellcheck.handleChange(editor, changeObject) // The current note contains an toc. We'll check for changes on headlines. @@ -726,7 +765,11 @@ export default class CodeEditor extends React.Component { // Check if one of the changed lines contains a headline for (let line = 0; line < changeObject.text.length; line++) { - if (this.linePossibleContainsHeadline(editor.getLine(changeObject.from.line + line))) { + if ( + this.linePossibleContainsHeadline( + editor.getLine(changeObject.from.line + line) + ) + ) { requireTocUpdate = true break } @@ -755,13 +798,13 @@ export default class CodeEditor extends React.Component { } } - linePossibleContainsHeadline (currentLine) { + linePossibleContainsHeadline(currentLine) { // We can't check if the line start with # because when some write text before // the # we also need to update the toc return currentLine.includes('# ') } - incrementLines (start, linesAdded, linesRemoved, editor) { + incrementLines(start, linesAdded, linesRemoved, editor) { const highlightedLines = editor.options.linesHighlighted const totalHighlightedLines = highlightedLines.length @@ -782,7 +825,7 @@ export default class CodeEditor extends React.Component { highlightedLines.splice(highlightedLines.indexOf(lineNumber), 1) // Lines that need to be relocated - if (lineNumber >= (start + linesRemoved)) { + if (lineNumber >= start + linesRemoved) { newLines.push(lineNumber + offset) } } @@ -796,22 +839,30 @@ export default class CodeEditor extends React.Component { } } - handleHighlight (editor, changeObject) { + handleHighlight(editor, changeObject) { const lines = editor.options.linesHighlighted if (!lines.includes(changeObject)) { lines.push(changeObject) - editor.addLineClass(changeObject, 'text', 'CodeMirror-activeline-background') + editor.addLineClass( + changeObject, + 'text', + 'CodeMirror-activeline-background' + ) } else { lines.splice(lines.indexOf(changeObject), 1) - editor.removeLineClass(changeObject, 'text', 'CodeMirror-activeline-background') + editor.removeLineClass( + changeObject, + 'text', + 'CodeMirror-activeline-background' + ) } if (this.props.onChange) { this.props.onChange(editor) } } - updateHighlight (editor, changeObject) { + updateHighlight(editor, changeObject) { const linesAdded = changeObject.text.length - 1 const linesRemoved = changeObject.removed.length - 1 @@ -842,28 +893,28 @@ export default class CodeEditor extends React.Component { this.incrementLines(start, linesAdded, linesRemoved, editor) } - moveCursorTo (row, col) {} + moveCursorTo(row, col) {} - scrollToLine (event, num) { + scrollToLine(event, num) { const cursor = { line: num, ch: 1 } this.editor.setCursor(cursor) - const top = this.editor.charCoords({line: num, ch: 0}, 'local').top + const top = this.editor.charCoords({ line: num, ch: 0 }, 'local').top const middleHeight = this.editor.getScrollerElement().offsetHeight / 2 this.editor.scrollTo(null, top - middleHeight - 5) } - focus () { + focus() { this.editor.focus() } - blur () { + blur() { this.editor.blur() } - reload () { + reload() { // Change event shouldn't be fired when switch note this.editor.off('change', this.changeHandler) this.value = this.props.value @@ -874,7 +925,7 @@ export default class CodeEditor extends React.Component { this.editor.refresh() } - setValue (value) { + setValue(value) { const cursor = this.editor.getCursor() this.editor.setValue(value) this.editor.setCursor(cursor) @@ -885,18 +936,19 @@ export default class CodeEditor extends React.Component { * @param {Number} lineNumber * @param {String} content */ - setLineContent (lineNumber, content) { + setLineContent(lineNumber, content) { const prevContent = this.editor.getLine(lineNumber) const prevContentLength = prevContent ? prevContent.length : 0 - this.editor.replaceRange(content, { line: lineNumber, ch: 0 }, { line: lineNumber, ch: prevContentLength }) + this.editor.replaceRange( + content, + { line: lineNumber, ch: 0 }, + { line: lineNumber, ch: prevContentLength } + ) } - handleDropImage (dropEvent) { + handleDropImage(dropEvent) { dropEvent.preventDefault() - const { - storageKey, - noteKey - } = this.props + const { storageKey, noteKey } = this.props attachmentManagement.handleAttachmentDrop( this, storageKey, @@ -905,37 +957,44 @@ export default class CodeEditor extends React.Component { ) } - insertAttachmentMd (imageMd) { + insertAttachmentMd(imageMd) { this.editor.replaceSelection(imageMd) } - autoDetectLanguage (content) { + autoDetectLanguage(content) { const res = hljs.highlightAuto(content, Object.keys(languageMaps)) this.setMode(languageMaps[res.language]) } - handlePaste (editor, forceSmartPaste) { + handlePaste(editor, forceSmartPaste) { const { storageKey, noteKey, fetchUrlTitle, enableSmartPaste } = this.props - const isURL = str => /(?:^\w+:|^)\/\/(?:[^\s\.]+\.\S{2}|localhost[\:?\d]*)/.test(str) + const isURL = str => + /(?:^\w+:|^)\/\/(?:[^\s\.]+\.\S{2}|localhost[\:?\d]*)/.test(str) 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 - }) + const prevChar = editor.getRange( + { + 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 - }) + const nextChar = editor.getRange( + { + line: endCursor.line, + ch: endCursor.ch + }, + { + line: endCursor.line, + ch: endCursor.ch + 1 + } + ) return prevChar === '](' && nextChar === ')' } @@ -947,7 +1006,7 @@ export default class CodeEditor extends React.Component { return true } - let line = line = cursor.line - 1 + let line = (line = cursor.line - 1) while (line >= 0) { token = editor.getTokenAt({ ch: 3, @@ -979,7 +1038,11 @@ export default class CodeEditor extends React.Component { if (isInFencedCodeBlock(editor)) { this.handlePasteText(editor, pastedTxt) - } else if (fetchUrlTitle && isMarkdownTitleURL(pastedTxt) && !isInLinkTag(editor)) { + } else if ( + fetchUrlTitle && + isMarkdownTitleURL(pastedTxt) && + !isInLinkTag(editor) + ) { this.handlePasteUrl(editor, pastedTxt) } else if (fetchUrlTitle && isURL(pastedTxt) && !isInLinkTag(editor)) { this.handlePasteUrl(editor, pastedTxt) @@ -1015,13 +1078,13 @@ export default class CodeEditor extends React.Component { } } - handleScroll (e) { + handleScroll(e) { if (this.props.onScroll) { this.props.onScroll(e) } } - handlePasteUrl (editor, pastedTxt) { + handlePasteUrl(editor, pastedTxt) { let taggedUrl = `<${pastedTxt}>` let urlToFetch = pastedTxt let titleMark = '' @@ -1071,16 +1134,16 @@ export default class CodeEditor extends React.Component { }) } - handlePasteHtml (editor, pastedHtml) { + handlePasteHtml(editor, pastedHtml) { const markdown = this.turndownService.turndown(pastedHtml) editor.replaceSelection(markdown) } - handlePasteText (editor, pastedTxt) { + handlePasteText(editor, pastedTxt) { editor.replaceSelection(pastedTxt) } - mapNormalResponse (response, pastedTxt) { + mapNormalResponse(response, pastedTxt) { return this.decodeResponse(response).then(body => { return new Promise((resolve, reject) => { try { @@ -1088,10 +1151,12 @@ export default class CodeEditor extends React.Component { body, 'text/html' ) - const escapePipe = (str) => { + const escapePipe = str => { return str.replace('|', '\\|') } - const linkWithTitle = `[${escapePipe(parsedBody.title)}](${pastedTxt})` + const linkWithTitle = `[${escapePipe( + parsedBody.title + )}](${pastedTxt})` resolve(linkWithTitle) } catch (e) { reject(e) @@ -1100,7 +1165,7 @@ export default class CodeEditor extends React.Component { }) } - initialHighlighting () { + initialHighlighting() { if (this.editor.options.linesHighlighted == null) { return } @@ -1114,16 +1179,20 @@ export default class CodeEditor extends React.Component { // make sure that we skip the invalid lines althrough this case should not be happened. continue } - this.editor.addLineClass(lineNumber, 'text', 'CodeMirror-activeline-background') + this.editor.addLineClass( + lineNumber, + 'text', + 'CodeMirror-activeline-background' + ) } } - restartHighlighting () { + restartHighlighting() { this.editor.options.linesHighlighted = this.props.linesHighlighted this.initialHighlighting() } - mapImageResponse (response, pastedTxt) { + mapImageResponse(response, pastedTxt) { return new Promise((resolve, reject) => { try { const url = response.url @@ -1136,7 +1205,7 @@ export default class CodeEditor extends React.Component { }) } - decodeResponse (response) { + decodeResponse(response) { const headers = response.headers const _charset = headers.has('content-type') ? this.extractContentTypeCharset(headers.get('content-type')) @@ -1144,10 +1213,10 @@ export default class CodeEditor extends React.Component { 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(Buffer.from(buff), charset).toString()) } catch (e) { reject(e) @@ -1156,50 +1225,49 @@ export default class CodeEditor extends React.Component { }) } - extractContentTypeCharset (contentType) { + extractContentTypeCharset(contentType) { return contentType .split(';') .filter(str => { - return str.trim().toLowerCase().startsWith('charset') + return str + .trim() + .toLowerCase() + .startsWith('charset') }) .map(str => { return str.replace(/['"]/g, '').split('=')[1] })[0] } - render () { - const { - className, - fontSize - } = this.props + render() { + const { className, fontSize } = this.props const fontFamily = normalizeEditorFontFamily(this.props.fontFamily) const width = this.props.width - return (< - div className={ - className == null ? 'CodeEditor' : `CodeEditor ${className}` - } - ref='root' - tabIndex='-1' - style={{ - fontFamily, - fontSize: fontSize, - width: width - }} - onDrop={ - e => this.handleDropImage(e) - } + return ( +