blob: 58ea6a4a8b0b7067ffb022b40ae398bc759368a2 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
module.exports = Editor;
// NOTE(sadovsky): We considered both Ace and CodeMirror, but CodeMirror appears
// to be incompatible with Bootstrap and has other weird issues, e.g. its
// injected editor divs can obscure other DOM elements.
var ace = require('brace');
require('brace/mode/javascript');
require('brace/mode/golang');
require('brace/theme/monokai');
// Mercury widget that wraps a code editor.
// * type: Type of code. Currently either 'js' or 'go'.
// * text: Initial code.
function Editor(type, text) {
this.type_ = type;
this.text_ = text;
// Every explicitly created (not copied) editor has a unique nonce.
this.nonce_ = Editor.nonceSeed_;
Editor.nonceSeed_ = (Editor.nonceSeed_ + 1) & 0x7fffffff;
this.aceEditor_ = null;
}
Editor.nonceSeed_ = 0;
// This tells Mercury to treat Editor as a widget and not try to render its
// internals.
Editor.prototype.type = 'Widget';
Editor.prototype.init = function() {
console.log('EditorWidget.init');
var el = document.createElement('div');
this.mount(el, this.type_, this.text_);
return el;
};
Editor.prototype.update = function(prev, el) {
console.log('EditorWidget.update');
// If update is called with the currently mounted Editor instance or its
// copy (detected by nonce), remount would reset any edits. Remount should
// only happen if a new editor instance (with a new nonce) is explicitly
// created.
if (this.nonce_ !== prev.nonce_) {
this.mount(el, this.type_, this.text_);
}
};
Editor.prototype.getText = function() {
return this.aceEditor_.getValue();
};
Editor.prototype.reset = function() {
// The '-1' argument puts the cursor at the document start.
this.aceEditor_.setValue(this.text_, -1);
};
// Creates a new Ace editor instance and mounts it on a DOM node.
// * el: The DOM node to mount on.
// * type: Type of code. Currently either 'js' or 'go'.
// * text: Initial code.
Editor.prototype.mount = function(el, type, text) {
var editor = this.aceEditor_ = ace.edit(el);
editor.setTheme('ace/theme/monokai');
var session = editor.getSession();
switch (type) {
case 'go':
session.setMode('ace/mode/golang');
break;
case 'vdl':
session.setMode('ace/mode/golang');
break;
case 'json':
session.setMode('ace/mode/javascript');
break;
case 'js':
session.setMode('ace/mode/javascript');
break;
default:
throw new Error('Language type not supported: ' + type);
}
session.setValue(text);
// Disable syntax checking. The UI is annoying and only works for JS anyways.
session.setOption('useWorker', false);
};