${this._renderTarget()}
@@ -70,13 +69,14 @@ class ContextView {
}
_renderTarget () {
- var previous = this._current
+ let last
+ const previous = this._current
if (this._nodes && this._nodes.length) {
- var last = this._nodes[this._nodes.length - 1]
+ last = this._nodes[this._nodes.length - 1]
if (isDefinition(last)) {
this._current = last
} else {
- var target = this.contextualListener.declarationOf(last)
+ const target = this.contextualListener.declarationOf(last)
if (target) {
this._current = target
} else {
@@ -91,27 +91,26 @@ class ContextView {
}
_jumpToInternal (position) {
- var self = this
- function jumpToLine (lineColumn) {
+ const jumpToLine = (lineColumn) => {
if (lineColumn.start && lineColumn.start.line && lineColumn.start.column) {
- self.editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1)
+ this.editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1)
}
}
- let lastCompilationResult = self._deps.compilersArtefacts['__last']
+ let lastCompilationResult = this._deps.compilersArtefacts['__last']
if (lastCompilationResult && lastCompilationResult.data) {
- var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(
+ const lineColumn = this._deps.offsetToLineColumnConverter.offsetToLineColumn(
position,
position.file,
lastCompilationResult.getSourceCode().sources,
lastCompilationResult.getAsts())
- var filename = lastCompilationResult.getSourceName(position.file)
+ const filename = lastCompilationResult.getSourceName(position.file)
// TODO: refactor with rendererAPI.errorClick
- if (filename !== self._deps.config.get('currentFile')) {
- var provider = self._deps.fileManager.fileProviderOf(filename)
+ if (filename !== this._deps.config.get('currentFile')) {
+ const provider = this._deps.fileManager.fileProviderOf(filename)
if (provider) {
provider.exists(filename, (error, exist) => {
if (error) return console.log(error)
- self._deps.fileManager.switchFile(filename)
+ this._deps.fileManager.switchFile(filename)
jumpToLine(lineColumn)
})
}
@@ -123,14 +122,13 @@ class ContextView {
_render (node, nodeAtCursorPosition) {
if (!node) return yo`
`
- var self = this
- var references = self.contextualListener.referencesOf(node)
- var type = (node.attributes && node.attributes.type) ? node.attributes.type : node.name
+ let references = this.contextualListener.referencesOf(node)
+ const type = (node.attributes && node.attributes.type) ? node.attributes.type : node.name
references = `${references ? references.length : '0'} reference(s)`
- var ref = 0
- var nodes = self.contextualListener.getActiveHighlights()
- for (var k in nodes) {
+ let ref = 0
+ const nodes = this.contextualListener.getActiveHighlights()
+ for (const k in nodes) {
if (nodeAtCursorPosition.id === nodes[k].nodeId) {
ref = k
break
@@ -138,22 +136,35 @@ class ContextView {
}
// JUMP BETWEEN REFERENCES
- function jump (e) {
+ const jump = (e) => {
e.target.dataset.action === 'next' ? ref++ : ref--
if (ref < 0) ref = nodes.length - 1
if (ref >= nodes.length) ref = 0
- self._jumpToInternal(nodes[ref].position)
+ this._jumpToInternal(nodes[ref].position)
}
- function jumpTo () {
+ const jumpTo = () => {
if (node && node.src) {
- var position = self.sourceMappingDecoder.decode(node.src)
+ const position = this.sourceMappingDecoder.decode(node.src)
if (position) {
- self._jumpToInternal(position)
+ this._jumpToInternal(position)
}
}
}
+ const showGasEstimation = () => {
+ if (node.name === 'FunctionDefinition') {
+ const result = this.contextualListener.gasEstimation(node)
+ const executionCost = 'Execution cost: ' + result.executionCost + ' gas'
+ const codeDepositCost = 'Code deposit cost: ' + result.codeDepositCost + ' gas'
+ const estimatedGas = result.codeDepositCost ? `${codeDepositCost}, ${executionCost}` : `${executionCost}`
+ return yo`
+
+ ${estimatedGas}
+
`
+ }
+ }
+
return yo`
${type}
${node.attributes.name}
@@ -163,19 +174,6 @@ class ContextView {
${showGasEstimation()}
`
-
- function showGasEstimation () {
- if (node.name === 'FunctionDefinition') {
- var result = self.contextualListener.gasEstimation(node)
- var executionCost = 'Execution cost: ' + result.executionCost + ' gas'
- var codeDepositCost = 'Code deposit cost: ' + result.codeDepositCost + ' gas'
- var estimatedGas = result.codeDepositCost ? `${codeDepositCost}, ${executionCost}` : `${executionCost}`
- return yo`
-
- ${estimatedGas}
-
`
- }
- }
}
}
diff --git a/src/app/editor/contextualListener.js b/src/app/editor/contextualListener.js
index ed33c4b15d..5853c36f45 100644
--- a/src/app/editor/contextualListener.js
+++ b/src/app/editor/contextualListener.js
@@ -1,25 +1,24 @@
'use strict'
-var remixLib = require('remix-lib')
-var SourceMappingDecoder = remixLib.SourceMappingDecoder
-var AstWalker = remixLib.AstWalker
-var EventManager = require('../../lib/events')
-var globalRegistry = require('../../global/registry')
+const remixLib = require('remix-lib')
+const SourceMappingDecoder = remixLib.SourceMappingDecoder
+const AstWalker = remixLib.AstWalker
+const EventManager = require('../../lib/events')
+const globalRegistry = require('../../global/registry')
/*
trigger contextChanged(nodes)
*/
class ContextualListener {
constructor (opts, localRegistry) {
- var self = this
this.event = new EventManager()
- self._components = {}
- self._components.registry = localRegistry || globalRegistry
- self.editor = opts.editor
- self.pluginManager = opts.pluginManager
- self._deps = {
- compilersArtefacts: self._components.registry.get('compilersartefacts').api,
- config: self._components.registry.get('config').api,
- offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api
+ this._components = {}
+ this._components.registry = localRegistry || globalRegistry
+ this.editor = opts.editor
+ this.pluginManager = opts.pluginManager
+ this._deps = {
+ compilersArtefacts: this._components.registry.get('compilersartefacts').api,
+ config: this._components.registry.get('config').api,
+ offsetToLineColumnConverter: this._components.registry.get('offsettolinecolumnconverter').api
}
this._index = {
Declarations: {},
@@ -27,7 +26,7 @@ class ContextualListener {
}
this._activeHighlights = []
- self.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
+ this.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
this._stopHighlighting()
this._index = {
Declarations: {},
@@ -36,13 +35,13 @@ class ContextualListener {
this._buildIndex(data, source)
})
- self.editor.event.register('contentChanged', () => { this._stopHighlighting() })
+ this.editor.event.register('contentChanged', () => { this._stopHighlighting() })
this.sourceMappingDecoder = new SourceMappingDecoder()
this.astWalker = new AstWalker()
setInterval(() => {
- if (self._deps.compilersArtefacts['__last']) {
- this._highlightItems(self.editor.getCursorPosition(), self._deps.compilersArtefacts['__last'], self._deps.config.get('currentFile'))
+ if (this._deps.compilersArtefacts['__last']) {
+ this._highlightItems(this.editor.getCursorPosition(), this._deps.compilersArtefacts['__last'], this._deps.config.get('currentFile'))
}
}, 1000)
}
@@ -73,7 +72,7 @@ class ContextualListener {
this.currentPosition = cursorPosition
this.currentFile = file
if (compilationResult && compilationResult.data && compilationResult.data.sources[file]) {
- var nodes = this.sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file])
+ const nodes = this.sourceMappingDecoder.nodesAtPosition(null, cursorPosition, compilationResult.data.sources[file])
this.nodes = nodes
if (nodes && nodes.length && nodes[nodes.length - 1]) {
this._highlightExpressions(nodes[nodes.length - 1], compilationResult)
@@ -84,19 +83,18 @@ class ContextualListener {
_buildIndex (compilationResult, source) {
if (compilationResult && compilationResult.sources) {
- var self = this
- var callback = {}
- callback['*'] = function (node) {
+ const callback = {}
+ callback['*'] = (node) => {
if (node && node.attributes && node.attributes.referencedDeclaration) {
- if (!self._index['Declarations'][node.attributes.referencedDeclaration]) {
- self._index['Declarations'][node.attributes.referencedDeclaration] = []
+ if (!this._index['Declarations'][node.attributes.referencedDeclaration]) {
+ this._index['Declarations'][node.attributes.referencedDeclaration] = []
}
- self._index['Declarations'][node.attributes.referencedDeclaration].push(node)
+ this._index['Declarations'][node.attributes.referencedDeclaration].push(node)
}
- self._index['FlatReferences'][node.id] = node
+ this._index['FlatReferences'][node.id] = node
return true
}
- for (var s in compilationResult.sources) {
+ for (const s in compilationResult.sources) {
this.astWalker.walk(compilationResult.sources[s].legacyAST, callback)
}
}
@@ -104,21 +102,19 @@ class ContextualListener {
_highlight (node, compilationResult) {
if (!node) return
- var self = this
- var position = this.sourceMappingDecoder.decode(node.src)
- var eventId = this._highlightInternal(position, node)
- let lastCompilationResult = self._deps.compilersArtefacts['__last']
+ const position = this.sourceMappingDecoder.decode(node.src)
+ const eventId = this._highlightInternal(position, node)
+ let lastCompilationResult = this._deps.compilersArtefacts['__last']
if (eventId && lastCompilationResult) {
this._activeHighlights.push({ eventId, position, fileTarget: lastCompilationResult.getSourceName(position.file), nodeId: node.id })
}
}
_highlightInternal (position, node) {
- var self = this
- let lastCompilationResult = self._deps.compilersArtefacts['__last']
+ let lastCompilationResult = this._deps.compilersArtefacts['__last']
if (lastCompilationResult) {
- var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, lastCompilationResult.getSourceCode().sources, lastCompilationResult.getAsts())
- var css = 'highlightreference'
+ let lineColumn = this._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, lastCompilationResult.getSourceCode().sources, lastCompilationResult.getAsts())
+ let css = 'highlightreference'
if (node.children && node.children.length) {
// If node has children, highlight the entire line. if not, just highlight the current source position of the node.
css = 'highlightreference'
@@ -133,28 +129,27 @@ class ContextualListener {
}
}
}
- var fileName = lastCompilationResult.getSourceName(position.file)
+ const fileName = lastCompilationResult.getSourceName(position.file)
if (fileName) {
- return self.editor.addMarker(lineColumn, fileName, css)
+ return this.editor.addMarker(lineColumn, fileName, css)
}
}
return null
}
_highlightExpressions (node, compilationResult) {
- var self = this
- function highlights (id) {
- if (self._index['Declarations'] && self._index['Declarations'][id]) {
- var refs = self._index['Declarations'][id]
- for (var ref in refs) {
- var node = refs[ref]
- self._highlight(node, compilationResult)
+ const highlights = (id) => {
+ if (this._index['Declarations'] && this._index['Declarations'][id]) {
+ const refs = this._index['Declarations'][id]
+ for (const ref in refs) {
+ const node = refs[ref]
+ this._highlight(node, compilationResult)
}
}
}
if (node.attributes && node.attributes.referencedDeclaration) {
highlights(node.attributes.referencedDeclaration)
- var current = this._index['FlatReferences'][node.attributes.referencedDeclaration]
+ const current = this._index['FlatReferences'][node.attributes.referencedDeclaration]
this._highlight(current, compilationResult)
} else {
highlights(node.id)
@@ -164,23 +159,21 @@ class ContextualListener {
}
_stopHighlighting () {
- var self = this
- for (var eventKey in this._activeHighlights) {
- var event = this._activeHighlights[eventKey]
- self.editor.removeMarker(event.eventId, event.fileTarget)
+ for (const eventKey in this._activeHighlights) {
+ const event = this._activeHighlights[eventKey]
+ this.editor.removeMarker(event.eventId, event.fileTarget)
}
this._activeHighlights = []
}
gasEstimation (node) {
this._loadContractInfos(node)
- var executionCost
- var codeDepositCost
+ let executionCost, codeDepositCost
if (node.name === 'FunctionDefinition') {
- var visibility = node.attributes.visibility
+ const visibility = node.attributes.visibility
if (!node.attributes.isConstructor) {
- var fnName = node.attributes.name
- var fn = fnName + this._getInputParams(node)
+ const fnName = node.attributes.name
+ const fn = fnName + this._getInputParams(node)
if (visibility === 'public' || visibility === 'external') {
executionCost = this.estimationObj.external[fn]
} else if (visibility === 'private' || visibility === 'internal') {
@@ -197,9 +190,9 @@ class ContextualListener {
}
_loadContractInfos (node) {
- for (var i in this.nodes) {
+ for (const i in this.nodes) {
if (this.nodes[i].id === node.attributes.scope) {
- var contract = this.nodes[i]
+ const contract = this.nodes[i]
this.contract = this.results.data.contracts[this.results.source.target][contract.attributes.name]
this.estimationObj = this.contract.evm.gasEstimates
this.creationCost = this.estimationObj.creation.totalCost
@@ -209,16 +202,17 @@ class ContextualListener {
}
_getInputParams (node) {
- var params = []
- for (var i in node.children) {
+ const params = []
+ let target
+ for (const i in node.children) {
if (node.children[i].name === 'ParameterList') {
- var target = node.children[i]
+ target = node.children[i]
break
}
}
if (target) {
- var children = target.children
- for (var j in children) {
+ const children = target.children
+ for (const j in children) {
if (children[j].name === 'VariableDeclaration') {
params.push(children[j].attributes.type)
}
diff --git a/src/app/editor/editor.js b/src/app/editor/editor.js
index bdb9734a2a..7fb63b24ec 100644
--- a/src/app/editor/editor.js
+++ b/src/app/editor/editor.js
@@ -1,24 +1,24 @@
'use strict'
-var EventManager = require('../../lib/events')
-var yo = require('yo-yo')
-var csjs = require('csjs-inject')
-var ace = require('brace')
+const EventManager = require('../../lib/events')
+const yo = require('yo-yo')
+const csjs = require('csjs-inject')
+const ace = require('brace')
require('brace/theme/tomorrow_night_blue')
-var globalRegistry = require('../../global/registry')
+const globalRegistry = require('../../global/registry')
const SourceHighlighters = require('./SourceHighlighters')
-var Range = ace.acequire('ace/range').Range
+const Range = ace.acequire('ace/range').Range
require('brace/ext/language_tools')
require('brace/ext/searchbox')
-var langTools = ace.acequire('ace/ext/language_tools')
+const langTools = ace.acequire('ace/ext/language_tools')
require('ace-mode-solidity/build/remix-ide/mode-solidity')
require('brace/mode/javascript')
require('brace/mode/python')
require('brace/mode/json')
-var styleGuide = require('../ui/styles-guide/theme-chooser')
-var styles = styleGuide.chooser()
+const styleGuide = require('../ui/styles-guide/theme-chooser')
+const styles = styleGuide.chooser()
function setTheme (cb) {
if (styles.appProperties.aceTheme) {
@@ -30,7 +30,7 @@ setTheme((path, theme) => {
require('brace/theme/tomorrow_night_blue')
})
-var css = csjs`
+const css = csjs`
.ace-editor {
background-color : ${styles.editor.backgroundColor_Editor};
width : 100%;
@@ -49,113 +49,176 @@ document.head.appendChild(yo`
.highlightreference {
position:absolute;
z-index:20;
- background-color: ${styles.editor.backgroundColor_Editor_Context_Highlights};
+ background-color: ${
+ styles.editor.backgroundColor_Editor_Context_Highlights
+ };
opacity: 0.7
}
.highlightreferenceline {
position:absolute;
z-index:20;
- background-color: ${styles.editor.backgroundColor_Editor_Context_Highlights};
+ background-color: ${
+ styles.editor.backgroundColor_Editor_Context_Highlights
+ };
opacity: 0.7
}
.highlightcode {
position:absolute;
z-index:20;
- background-color: ${styles.editor.backgroundColor_Editor_Context_Error_Highlights};
+ background-color: ${
+ styles.editor.backgroundColor_Editor_Context_Error_Highlights
+ };
}
`)
-function Editor (opts = {}, localRegistry) {
- var self = this
- var el = yo`
`
- var editor = ace.edit(el)
- if (styles.appProperties.aceTheme) {
- editor.setTheme('ace/theme/' + styles.appProperties.aceTheme)
- }
- self._components = {}
- self._components.registry = localRegistry || globalRegistry
- self._deps = {
- fileManager: self._components.registry.get('filemanager').api,
- config: self._components.registry.get('config').api
- }
+class Editor {
- ace.acequire('ace/ext/language_tools')
- editor.setOptions({
- enableBasicAutocompletion: true,
- enableLiveAutocompletion: true
- })
- var flowCompleter = {
- getCompletions: function (editor, session, pos, prefix, callback) {
- // @TODO add here other propositions
+ constructor (opts = {}, localRegistry) {
+ // Dependancies
+ this._components = {}
+ this._components.registry = localRegistry || globalRegistry
+ this._deps = {
+ fileManager: this._components.registry.get('filemanager').api,
+ config: this._components.registry.get('config').api
}
- }
- langTools.addCompleter(flowCompleter)
- el.className += ' ' + css['ace-editor']
- el.editor = editor // required to access the editor during tests
- self.render = function () { return el }
- var event = new EventManager()
- self.event = event
- var sessions = {}
- var sourceAnnotations = []
- var readOnlySessions = {}
- var currentSession
-
- var emptySession = createSession('')
- var modes = {
- 'sol': 'ace/mode/solidity',
- 'js': 'ace/mode/javascript',
- 'py': 'ace/mode/python',
- 'vy': 'ace/mode/python',
- 'txt': 'ace/mode/text',
- 'json': 'ace/mode/json',
- 'abi': 'ace/mode/json'
- }
- editor.on('guttermousedown', function (e) {
- var target = e.domEvent.target
- if (target.className.indexOf('ace_gutter-cell') === -1) {
- return
+ // Init
+ this.event = new EventManager()
+ this.sessions = {}
+ this.sourceAnnotations = []
+ this.readOnlySessions = {}
+ this.previousInput = ''
+ this.saveTimeout = null
+ this.sourceHighlighters = new SourceHighlighters()
+ this.emptySession = this._createSession('')
+ this.modes = {
+ sol: 'ace/mode/solidity',
+ js: 'ace/mode/javascript',
+ py: 'ace/mode/python',
+ vy: 'ace/mode/python',
+ txt: 'ace/mode/text',
+ json: 'ace/mode/json',
+ abi: 'ace/mode/json'
}
- var row = e.getDocumentPosition().row
- var breakpoints = e.editor.session.getBreakpoints()
- for (var k in breakpoints) {
- if (k === row.toString()) {
- event.trigger('breakpointCleared', [currentSession, row])
- e.editor.session.clearBreakpoint(row)
- e.stop()
- return
+
+ // Editor Setup
+ const el = yo`
`
+ this.editor = ace.edit(el)
+ ace.acequire('ace/ext/language_tools')
+
+ // Unmap ctrl-t & ctrl-f
+ this.editor.commands.bindKeys({ 'ctrl-t': null })
+ this.editor.setShowPrintMargin(false)
+ this.editor.resize(true)
+
+ if (styles.appProperties.aceTheme) {
+ this.editor.setTheme('ace/theme/' + styles.appProperties.aceTheme)
+ }
+
+ this.editor.setOptions({
+ enableBasicAutocompletion: true,
+ enableLiveAutocompletion: true
+ })
+
+ el.className += ' ' + css['ace-editor']
+ el.editor = this.editor // required to access the editor during tests
+ this.render = () => el
+
+ // Completer for editor
+ const flowCompleter = {
+ getCompletions: (editor, session, pos, prefix, callback) => {
+ // @TODO add here other propositions
}
}
- self.setBreakpoint(row)
- event.trigger('breakpointAdded', [currentSession, row])
- e.stop()
- })
-
- this.displayEmptyReadOnlySession = function () {
- currentSession = null
- editor.setSession(emptySession)
- editor.setReadOnly(true)
+ langTools.addCompleter(flowCompleter)
+
+ // EVENTS LISTENERS
+
+ // Gutter Mouse down
+ this.editor.on('guttermousedown', e => {
+ const target = e.domEvent.target
+ if (target.className.indexOf('ace_gutter-cell') === -1) {
+ return
+ }
+ const row = e.getDocumentPosition().row
+ const breakpoints = e.editor.session.getBreakpoints()
+ for (const 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()
+ })
+
+ // 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', [])
+ })
+ })
}
- this.setBreakpoint = function (row, css) {
- editor.session.setBreakpoint(row, css)
+ _onChange () {
+ const currentFile = this._deps.config.get('currentFile')
+ if (!currentFile) {
+ return
+ }
+ const input = this.get(currentFile)
+ if (!input) {
+ return
+ }
+ // if there's no change, don't do anything
+ if (input === this.previousInput) {
+ return
+ }
+ this.previousInput = input
+
+ // fire storage update
+ // 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) {
- editor.setFontSize(editor.getFontSize() + incr)
+ _switchSession (path) {
+ this.currentSession = path
+ this.editor.setSession(this.sessions[this.currentSession])
+ this.editor.setReadOnly(this.readOnlySessions[this.currentSession])
+ this.editor.focus()
}
- this.setText = function (text) {
- if (currentSession && sessions[currentSession]) {
- sessions[currentSession].setValue(text)
- }
+ /**
+ * Get Ace mode base of the extension of the session file
+ * @param {string} path Path of the file
+ */
+ _getMode (path) {
+ let ext = path.indexOf('.') !== -1 ? /[^.]+$/.exec(path) : null
+ if (ext) ext = ext[0]
+ return ext && this.modes[ext] ? this.modes[ext] : this.modes['txt']
}
- function createSession (content, mode) {
- var s = new ace.EditSession(content)
+ /**
+ * Create an Ace session
+ * @param {string} content Content of the file to open
+ * @param {string} mode Ace Mode for this file [Default is `text`]
+ */
+ _createSession (content, mode) {
+ const s = new ace.EditSession(content)
s.setMode(mode || 'ace/mode/text')
s.setUndoManager(new ace.UndoManager())
s.setTabSize(4)
@@ -163,98 +226,156 @@ function Editor (opts = {}, localRegistry) {
return s
}
- function switchSession (path) {
- currentSession = path
- editor.setSession(sessions[currentSession])
- editor.setReadOnly(readOnlySessions[currentSession])
- editor.focus()
+ /**
+ * Attempts to find the string in the current document
+ * @param {string} string
+ */
+ find (string) {
+ return this.editor.find(string)
}
- function getMode (path) {
- var ext = path.indexOf('.') !== -1 ? /[^.]+$/.exec(path) : null
- if (ext) ext = ext[0]
- return ext && modes[ext] ? modes[ext] : modes['txt']
+ /**
+ * Display an Empty read-only session
+ */
+ displayEmptyReadOnlySession () {
+ this.currentSession = null
+ this.editor.setSession(this.emptySession)
+ this.editor.setReadOnly(true)
+ }
+
+ /**
+ * Sets a breakpoint on the row number
+ * @param {number} row Line index of the breakpoint
+ * @param {string} className Class of the breakpoint
+ */
+ setBreakpoint (row, className) {
+ this.editor.session.setBreakpoint(row, className)
+ }
+
+ /**
+ * Increment the font size (in pixels) for the editor text.
+ * @param {number} incr The amount of pixels to add to the font.
+ */
+ editorFontSize (incr) {
+ this.editor.setFontSize(this.editor.getFontSize() + incr)
}
- this.open = function (path, content) {
- if (!sessions[path]) {
- var session = createSession(content, getMode(path))
- sessions[path] = session
- readOnlySessions[path] = false
- } else if (sessions[path].getValue() !== content) {
- sessions[path].setValue(content)
+ /**
+ * Set the text in the current session, if any.
+ * @param {string} text New text to be place.
+ */
+ setText (text) {
+ if (this.currentSession && this.sessions[this.currentSession]) {
+ this.sessions[this.currentSession].setValue(text)
}
- switchSession(path)
}
- this.openReadOnly = function (path, content) {
- if (!sessions[path]) {
- var session = createSession(content, getMode(path))
- sessions[path] = session
- readOnlySessions[path] = true
+ /**
+ * Upsert and open a session.
+ * @param {string} path Path of the session to open.
+ * @param {string} content Content of the document or update.
+ */
+ open (path, content) {
+ if (!this.sessions[path]) {
+ const 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)
}
/**
- * returns the content of the current session
- *
- * @return {String} content of the file referenced by @arg path
- */
- this.currentContent = function () {
+ * Upsert and Open a session and set it as Read-only.
+ * @param {string} path Path of the session to open.
+ * @param {string} content Content of the document or update.
+ */
+ openReadOnly (path, content) {
+ if (!this.sessions[path]) {
+ const session = this._createSession(content, this._getMode(path))
+ this.sessions[path] = session
+ this.readOnlySessions[path] = true
+ }
+ this._switchSession(path)
+ }
+
+ /**
+ * Content of the current session
+ * @return {String} content of the file referenced by @arg path
+ */
+ currentContent () {
return this.get(this.current())
}
/**
- * returns the content of the session targeted by @arg path
- * if @arg path is null, the content of the current session is returned
- *
- * @return {String} content of the file referenced by @arg path
- */
- this.get = function (path) {
- if (!path || currentSession === path) {
- return editor.getValue()
- } else if (sessions[path]) {
- return sessions[path].getValue()
+ * Content of the session targeted by @arg path
+ * if @arg path is null, the content of the current session is returned
+ * @param {string} path Path of the session to get.
+ * @return {String} content of the file referenced by @arg path
+ */
+ get (path) {
+ if (!path || this.currentSession === path) {
+ return this.editor.getValue()
+ } else if (this.sessions[path]) {
+ return this.sessions[path].getValue()
}
}
/**
- * returns the path of the currently editing file
- * returns `undefined` if no session is being editer
- *
- * @return {String} path of the current session
- */
- this.current = function () {
- if (editor.getSession() === emptySession) {
+ * Path of the currently editing file
+ * returns `undefined` if no session is being editer
+ * @return {String} path of the current session
+ */
+ current () {
+ if (this.editor.getSession() === this.emptySession) {
return
}
- return currentSession
+ return this.currentSession
}
- this.getCursorPosition = function () {
- return editor.session.doc.positionToIndex(editor.getCursorPosition(), 0)
+ /**
+ * The position of the cursor
+ */
+ getCursorPosition () {
+ return this.editor.session.doc.positionToIndex(
+ this.editor.getCursorPosition(),
+ 0
+ )
}
- this.discardCurrentSession = function () {
- if (sessions[currentSession]) {
- delete sessions[currentSession]
- currentSession = null
+ /**
+ * Remove the current session from the list of sessions.
+ */
+ discardCurrentSession () {
+ if (this.sessions[this.currentSession]) {
+ delete this.sessions[this.currentSession]
+ this.currentSession = null
}
}
- this.discard = function (path) {
- if (sessions[path]) delete sessions[path]
- if (currentSession === path) currentSession = null
+ /**
+ * Remove a session based on its path.
+ * @param {string} path
+ */
+ discard (path) {
+ if (this.sessions[path]) delete this.sessions[path]
+ if (this.currentSession === path) this.currentSession = null
}
- this.resize = function (useWrapMode) {
- editor.resize()
- var session = editor.getSession()
+ /**
+ * Resize the editor, and sets whether or not line wrapping is enabled.
+ * @param {boolean} useWrapMode Enable (or disable) wrap mode
+ */
+ resize (useWrapMode) {
+ this.editor.resize()
+ const session = this.editor.getSession()
session.setUseWrapMode(useWrapMode)
if (session.getUseWrapMode()) {
- var characterWidth = editor.renderer.characterWidth
- var contentWidth = editor.container.ownerDocument.getElementsByClassName('ace_scroller')[0].clientWidth
+ const characterWidth = this.editor.renderer.characterWidth
+ const contentWidth = this.editor.container.ownerDocument.getElementsByClassName(
+ 'ace_scroller'
+ )[0].clientWidth
if (contentWidth > 0) {
session.setWrapLimit(parseInt(contentWidth / characterWidth, 10))
@@ -262,89 +383,81 @@ function Editor (opts = {}, localRegistry) {
}
}
- this.addMarker = function (lineColumnPos, source, cssClass) {
- var currentRange = new Range(lineColumnPos.start.line, lineColumnPos.start.column, lineColumnPos.end.line, lineColumnPos.end.column)
- if (sessions[source]) {
- return sessions[source].addMarker(currentRange, cssClass)
+ /**
+ * Adds a new marker to the given `Range`.
+ * @param {*} lineColumnPos
+ * @param {string} source Path of the session to add the mark on.
+ * @param {string} cssClass css to apply to the mark.
+ */
+ addMarker (lineColumnPos, source, cssClass) {
+ const currentRange = new Range(
+ lineColumnPos.start.line,
+ lineColumnPos.start.column,
+ lineColumnPos.end.line,
+ lineColumnPos.end.column
+ )
+ if (this.sessions[source]) {
+ return this.sessions[source].addMarker(currentRange, cssClass)
}
return null
}
- this.scrollToLine = function (line, center, animate, callback) {
- editor.scrollToLine(line, center, animate, callback)
+ /**
+ * Scrolls to a line. If center is true, it puts the line in middle of screen (or attempts to).
+ * @param {number} line The line to scroll to
+ * @param {boolean} center If true
+ * @param {boolean} animate If true animates scrolling
+ * @param {Function} callback Function to be called when the animation has finished
+ */
+ scrollToLine (line, center, animate, callback) {
+ this.editor.scrollToLine(line, center, animate, callback)
}
- this.removeMarker = function (markerId, source) {
- if (sessions[source]) {
- sessions[source].removeMarker(markerId)
+ /**
+ * Remove a marker from the session
+ * @param {string} markerId Id of the marker
+ * @param {string} source Path of the session
+ */
+ removeMarker (markerId, source) {
+ if (this.sessions[source]) {
+ this.sessions[source].removeMarker(markerId)
}
}
- this.clearAnnotations = function () {
- sourceAnnotations = []
- editor.getSession().clearAnnotations()
- }
-
- this.addAnnotation = function (annotation) {
- sourceAnnotations[sourceAnnotations.length] = annotation
- this.setAnnotations(sourceAnnotations)
- }
-
- this.setAnnotations = function (sourceAnnotations) {
- editor.getSession().setAnnotations(sourceAnnotations)
+ /**
+ * Clears all the annotations for the current session.
+ */
+ clearAnnotations () {
+ this.sourceAnnotations = []
+ this.editor.getSession().clearAnnotations()
}
- this.gotoLine = function (line, col) {
- editor.focus()
- editor.gotoLine(line + 1, col - 1, true)
+ /**
+ * Add an annotation to the current session.
+ * @param {Object} annotation
+ */
+ addAnnotation (annotation) {
+ this.sourceAnnotations[this.sourceAnnotations.length] = annotation
+ this.setAnnotations(this.sourceAnnotations)
}
- 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
+ /**
+ * Set a list of annotations to the current session.
+ * @param {Array