Refactor editor.js for es6

pull/3094/head
Grandschtroumpf 6 years ago
parent fe3ea4518f
commit 1efef9c889
  1. 446
      src/app/editor/editor.js

@ -20,7 +20,7 @@ require('brace/mode/json')
var styleGuide = require('../ui/styles-guide/theme-chooser') var styleGuide = require('../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser() var styles = styleGuide.chooser()
function setTheme (cb) { function setTheme(cb) {
if (styles.appProperties.aceTheme) { if (styles.appProperties.aceTheme) {
cb('brace/theme/', styles.appProperties.aceTheme) cb('brace/theme/', styles.appProperties.aceTheme)
} }
@ -49,112 +49,176 @@ document.head.appendChild(yo`
.highlightreference { .highlightreference {
position:absolute; position:absolute;
z-index:20; z-index:20;
background-color: ${styles.editor.backgroundColor_Editor_Context_Highlights}; background-color: ${
styles.editor.backgroundColor_Editor_Context_Highlights
};
opacity: 0.7 opacity: 0.7
} }
.highlightreferenceline { .highlightreferenceline {
position:absolute; position:absolute;
z-index:20; z-index:20;
background-color: ${styles.editor.backgroundColor_Editor_Context_Highlights}; background-color: ${
styles.editor.backgroundColor_Editor_Context_Highlights
};
opacity: 0.7 opacity: 0.7
} }
.highlightcode { .highlightcode {
position:absolute; position:absolute;
z-index:20; z-index:20;
background-color: ${styles.editor.backgroundColor_Editor_Context_Error_Highlights}; background-color: ${
styles.editor.backgroundColor_Editor_Context_Error_Highlights
};
} }
</style> </style>
`) `)
function Editor (opts = {}, localRegistry) { class Editor {
var self = this /*
var el = yo`<div id="input"></div>` // Private
var editor = ace.edit(el) _components
if (styles.appProperties.aceTheme) { _deps
editor.setTheme('ace/theme/' + styles.appProperties.aceTheme)
} // Public
self._components = {} editor
self._components.registry = localRegistry || globalRegistry event
self._deps = { sessions
fileManager: self._components.registry.get('filemanager').api, modes
config: self._components.registry.get('config').api sourceAnnotations
} readOnlySessions
previousInput
saveTimeout
sourceHighlighters
currentSession
emptySession
*/
constructor(opts = {}, localRegistry) {
const el = yo`<div id="input"></div>`
this.editor = ace.edit(el)
if (styles.appProperties.aceTheme) {
this.editor.setTheme('ace/theme/' + styles.appProperties.aceTheme)
}
this._components = {}
this._components.registry = localRegistry || globalRegistry
this._deps = {
fileManager: this._components.registry.get('filemanager').api,
config: this._components.registry.get('config').api
}
ace.acequire('ace/ext/language_tools') ace.acequire('ace/ext/language_tools')
editor.setOptions({ this.editor.setOptions({
enableBasicAutocompletion: true, enableBasicAutocompletion: true,
enableLiveAutocompletion: true enableLiveAutocompletion: true
}) })
var flowCompleter = { const flowCompleter = {
getCompletions: function (editor, session, pos, prefix, callback) { getCompletions: function(editor, session, pos, prefix, callback) {
// @TODO add here other propositions // @TODO add here other propositions
}
} }
} langTools.addCompleter(flowCompleter)
langTools.addCompleter(flowCompleter) el.className += ' ' + css['ace-editor']
el.className += ' ' + css['ace-editor'] el.editor = this.editor // required to access the editor during tests
el.editor = editor // required to access the editor during tests this.render = () => el
self.render = function () { return el }
var event = new EventManager() this.event = new EventManager()
self.event = event this.sessions = {}
var sessions = {} this.sourceAnnotations = []
var sourceAnnotations = [] this.readOnlySessions = {}
var readOnlySessions = {}
var currentSession this.emptySession = this._createSession('')
this.modes = {
var emptySession = createSession('') sol: 'ace/mode/solidity',
var modes = { js: 'ace/mode/javascript',
'sol': 'ace/mode/solidity', py: 'ace/mode/python',
'js': 'ace/mode/javascript', vy: 'ace/mode/python',
'py': 'ace/mode/python', txt: 'ace/mode/text',
'vy': 'ace/mode/python', json: 'ace/mode/json',
'txt': 'ace/mode/text', abi: 'ace/mode/json'
'json': 'ace/mode/json', }
'abi': 'ace/mode/json'
/** Listen on Gutter Mouse Down */
this.editor.on('guttermousedown', e => {
var target = e.domEvent.target
if (target.className.indexOf('ace_gutter-cell') === -1) {
return
}
var row = e.getDocumentPosition().row
var breakpoints = e.editor.session.getBreakpoints()
for (var k in breakpoints) {
if (k === row.toString()) {
this.event.trigger('breakpointCleared', [this.currentSession, row])
e.editor.session.clearBreakpoint(row)
e.stop()
return
}
}
this.setBreakpoint(row)
this.event.trigger('breakpointAdded', [this.currentSession, row])
e.stop()
})
this.previousInput = ''
this.saveTimeout = null
// Do setup on initialisation here
this.editor.on('changeSession', () => {
this._onChange()
this.event.trigger('sessionSwitched', [])
this.editor.getSession().on('change', () => {
this._onChange()
this.event.trigger('contentChanged', [])
})
})
// Unmap ctrl-t & ctrl-f
this.editor.commands.bindKeys({ 'ctrl-t': null })
this.editor.setShowPrintMargin(false)
this.editor.resize(true)
this.sourceHighlighters = new SourceHighlighters()
} }
editor.on('guttermousedown', function (e) { _onChange() {
var target = e.domEvent.target var currentFile = this._deps.config.get('currentFile')
if (target.className.indexOf('ace_gutter-cell') === -1) { if (!currentFile) {
return return
} }
var row = e.getDocumentPosition().row var input = this.get(currentFile)
var breakpoints = e.editor.session.getBreakpoints() if (!input) {
for (var k in breakpoints) { return
if (k === row.toString()) {
event.trigger('breakpointCleared', [currentSession, row])
e.editor.session.clearBreakpoint(row)
e.stop()
return
}
} }
self.setBreakpoint(row) // if there's no change, don't do anything
event.trigger('breakpointAdded', [currentSession, row]) if (input === this.previousInput) {
e.stop() return
}) }
this.previousInput = input
this.displayEmptyReadOnlySession = function () {
currentSession = null
editor.setSession(emptySession)
editor.setReadOnly(true)
}
this.setBreakpoint = function (row, css) { // fire storage update
editor.session.setBreakpoint(row, css) // NOTE: save at most once per 5 seconds
if (this.saveTimeout) {
window.clearTimeout(this.saveTimeout)
}
this.saveTimeout = window.setTimeout(() => {
this._deps.fileManager.saveCurrentFile()
}, 5000)
} }
this.editorFontSize = function (incr) { _switchSession(path) {
editor.setFontSize(editor.getFontSize() + incr) this.currentSession = path
this.editor.setSession(this.sessions[this.currentSession])
this.editor.setReadOnly(this.readOnlySessions[this.currentSession])
this.editor.focus()
} }
this.setText = function (text) { _getMode(path) {
if (currentSession && sessions[currentSession]) { var ext = path.indexOf('.') !== -1 ? /[^.]+$/.exec(path) : null
sessions[currentSession].setValue(text) if (ext) ext = ext[0]
} return ext && this.modes[ext] ? this.modes[ext] : this.modes['txt']
} }
function createSession (content, mode) { _createSession(content, mode) {
var s = new ace.EditSession(content) var s = new ace.EditSession(content)
s.setMode(mode || 'ace/mode/text') s.setMode(mode || 'ace/mode/text')
s.setUndoManager(new ace.UndoManager()) s.setUndoManager(new ace.UndoManager())
@ -163,98 +227,114 @@ function Editor (opts = {}, localRegistry) {
return s return s
} }
function switchSession (path) { find(string) {
currentSession = path return this.editor.find(string)
editor.setSession(sessions[currentSession])
editor.setReadOnly(readOnlySessions[currentSession])
editor.focus()
} }
function getMode (path) { displayEmptyReadOnlySession() {
var ext = path.indexOf('.') !== -1 ? /[^.]+$/.exec(path) : null this.currentSession = null
if (ext) ext = ext[0] this.editor.setSession(this.emptySession)
return ext && modes[ext] ? modes[ext] : modes['txt'] this.editor.setReadOnly(true)
}
setBreakpoint(row, css) {
this.editor.session.setBreakpoint(row, css)
} }
this.open = function (path, content) { editorFontSize(incr) {
if (!sessions[path]) { this.editor.setFontSize(this.editor.getFontSize() + incr)
var session = createSession(content, getMode(path)) }
sessions[path] = session
readOnlySessions[path] = false setText(text) {
} else if (sessions[path].getValue() !== content) { if (this.currentSession && this.sessions[this.currentSession]) {
sessions[path].setValue(content) this.sessions[this.currentSession].setValue(text)
}
}
open(path, content) {
if (!this.sessions[path]) {
var session = this._createSession(content, this._getMode(path))
this.sessions[path] = session
this.readOnlySessions[path] = false
} else if (this.sessions[path].getValue() !== content) {
this.sessions[path].setValue(content)
} }
switchSession(path) this._switchSession(path)
} }
this.openReadOnly = function (path, content) { openReadOnly(path, content) {
if (!sessions[path]) { if (!this.sessions[path]) {
var session = createSession(content, getMode(path)) var session = this._createSession(content, this._getMode(path))
sessions[path] = session this.sessions[path] = session
readOnlySessions[path] = true this.readOnlySessions[path] = true
} }
switchSession(path) this._switchSession(path)
} }
/** /**
* returns the content of the current session * returns the content of the current session
* *
* @return {String} content of the file referenced by @arg path * @return {String} content of the file referenced by @arg path
*/ */
this.currentContent = function () { currentContent() {
return this.get(this.current()) return this.get(this.current())
} }
/** /**
* returns the content of the session targeted by @arg path * returns the content of the session targeted by @arg path
* if @arg path is null, the content of the current session is returned * if @arg path is null, the content of the current session is returned
* *
* @return {String} content of the file referenced by @arg path * @return {String} content of the file referenced by @arg path
*/ */
this.get = function (path) { get(path) {
if (!path || currentSession === path) { if (!path || this.currentSession === path) {
return editor.getValue() return this.editor.getValue()
} else if (sessions[path]) { } else if (this.sessions[path]) {
return sessions[path].getValue() return this.sessions[path].getValue()
} }
} }
/** /**
* returns the path of the currently editing file * returns the path of the currently editing file
* returns `undefined` if no session is being editer * returns `undefined` if no session is being editer
* *
* @return {String} path of the current session * @return {String} path of the current session
*/ */
this.current = function () { current() {
if (editor.getSession() === emptySession) { if (this.editor.getSession() === this.emptySession) {
return return
} }
return currentSession return this.currentSession
} }
this.getCursorPosition = function () { getCursorPosition() {
return editor.session.doc.positionToIndex(editor.getCursorPosition(), 0) return this.editor.session.doc.positionToIndex(
this.editor.getCursorPosition(),
0
)
} }
this.discardCurrentSession = function () { discardCurrentSession() {
if (sessions[currentSession]) { if (this.sessions[this.currentSession]) {
delete sessions[currentSession] delete this.sessions[this.currentSession]
currentSession = null this.currentSession = null
} }
} }
this.discard = function (path) { discard(path) {
if (sessions[path]) delete sessions[path] if (this.sessions[path]) delete this.sessions[path]
if (currentSession === path) currentSession = null if (this.currentSession === path) this.currentSession = null
} }
this.resize = function (useWrapMode) { resize(useWrapMode) {
editor.resize() this.editor.resize()
var session = editor.getSession() var session = this.editor.getSession()
session.setUseWrapMode(useWrapMode) session.setUseWrapMode(useWrapMode)
if (session.getUseWrapMode()) { if (session.getUseWrapMode()) {
var characterWidth = editor.renderer.characterWidth var characterWidth = this.editor.renderer.characterWidth
var contentWidth = editor.container.ownerDocument.getElementsByClassName('ace_scroller')[0].clientWidth var contentWidth = this.editor.container.ownerDocument.getElementsByClassName(
'ace_scroller'
)[0].clientWidth
if (contentWidth > 0) { if (contentWidth > 0) {
session.setWrapLimit(parseInt(contentWidth / characterWidth, 10)) session.setWrapLimit(parseInt(contentWidth / characterWidth, 10))
@ -262,89 +342,47 @@ function Editor (opts = {}, localRegistry) {
} }
} }
this.addMarker = function (lineColumnPos, source, cssClass) { addMarker(lineColumnPos, source, cssClass) {
var currentRange = new Range(lineColumnPos.start.line, lineColumnPos.start.column, lineColumnPos.end.line, lineColumnPos.end.column) var currentRange = new Range(
if (sessions[source]) { lineColumnPos.start.line,
return sessions[source].addMarker(currentRange, cssClass) lineColumnPos.start.column,
lineColumnPos.end.line,
lineColumnPos.end.column
)
if (this.sessions[source]) {
return this.sessions[source].addMarker(currentRange, cssClass)
} }
return null return null
} }
this.scrollToLine = function (line, center, animate, callback) { scrollToLine(line, center, animate, callback) {
editor.scrollToLine(line, center, animate, callback) this.editor.scrollToLine(line, center, animate, callback)
} }
this.removeMarker = function (markerId, source) { removeMarker(markerId, source) {
if (sessions[source]) { if (this.sessions[source]) {
sessions[source].removeMarker(markerId) this.sessions[source].removeMarker(markerId)
} }
} }
this.clearAnnotations = function () { clearAnnotations() {
sourceAnnotations = [] this.sourceAnnotations = []
editor.getSession().clearAnnotations() this.editor.getSession().clearAnnotations()
} }
this.addAnnotation = function (annotation) { addAnnotation(annotation) {
sourceAnnotations[sourceAnnotations.length] = annotation this.sourceAnnotations[this.sourceAnnotations.length] = annotation
this.setAnnotations(sourceAnnotations) this.setAnnotations(this.sourceAnnotations)
} }
this.setAnnotations = function (sourceAnnotations) { setAnnotations(sourceAnnotations) {
editor.getSession().setAnnotations(sourceAnnotations) this.editor.getSession().setAnnotations(sourceAnnotations)
}
this.gotoLine = function (line, col) {
editor.focus()
editor.gotoLine(line + 1, col - 1, true)
}
this.find = (string) => editor.find(string)
this.previousInput = ''
this.saveTimeout = null
// Do setup on initialisation here
editor.on('changeSession', function () {
editorOnChange(self)
event.trigger('sessionSwitched', [])
editor.getSession().on('change', function () {
editorOnChange(self)
event.trigger('contentChanged', [])
})
})
// Unmap ctrl-t & ctrl-f
editor.commands.bindKeys({ 'ctrl-t': null })
editor.setShowPrintMargin(false)
editor.resize(true)
this.sourceHighlighters = new SourceHighlighters()
}
function editorOnChange (self) {
var currentFile = self._deps.config.get('currentFile')
if (!currentFile) {
return
}
var input = self.get(currentFile)
if (!input) {
return
}
// if there's no change, don't do anything
if (input === self.previousInput) {
return
} }
self.previousInput = input
// fire storage update gotoLine(line, col) {
// NOTE: save at most once per 5 seconds this.editor.focus()
if (self.saveTimeout) { this.editor.gotoLine(line + 1, col - 1, true)
window.clearTimeout(self.saveTimeout)
} }
self.saveTimeout = window.setTimeout(() => {
self._deps.fileManager.saveCurrentFile()
}, 5000)
} }
module.exports = Editor module.exports = Editor

Loading…
Cancel
Save