blob: e54b73987587ca673a4b41c4d2f029c8fa8d9a79 [file] [log] [blame]
<!--
Copyright 2016 The LUCI Authors. All rights reserved.
Use of this source code is governed under the Apache License, Version 2.0
that can be found in the LICENSE file.
-->
<link rel="import" href="../bower_components/polymer/polymer.html">
<script src="third_party/ace/ace.js"></script>
<script src="third_party/ace/ext-language_tools.js"></script>
<script src="third_party/ace/mode-json.js"></script>
<link rel="import" href="rpc-completer.html">
<!-- The `rpc-editor` is an Ace editor for JSON with optional autocomplete -->
<dom-module id="rpc-editor">
<template>
<style>
:host, pre {
display: block;
height: 100%;
}
</style>
<pre id="editor" class="editor"></pre>
<rpc-completer id="completer"
description="[[description]]" root-type-name="[[rootTypeName]]">
</rpc-completer>
</template>
<script>
'use strict';
Polymer({
is: 'rpc-editor',
properties: {
value: {
type: String,
notify: true,
observer: '_onValueChanged'
},
editor: {
type: Object,
readOnly: true
},
/** @type {FileDescriptorSet} */
description: Object,
rootTypeName: String
},
ready: function() {
var self = this;
this._setEditor(ace.edit(this.$.editor));
this.editor.session.setMode('ace/mode/json');
// Set and sync text;
this.editor.session.setValue(this.value || '');
this.editor.session.on('change', function() {
var text = self.editor.session.getValue();
if (text !== self.value) {
self._maybeSync(function() {
self.value = text;
});
}
});
this.editor.commands.removeCommands(['gotoline', 'find']);
this.editor.setOptions({
enableBasicAutocompletion: [this.$.completer],
});
},
_onValueChanged: function(newVal) {
var newText = newVal || '';
if (this.editor && this.editor.session.getValue() != newText) {
this._maybeSync(function() {
var selection = this.editor.selection;
var origRange = selection.getRange();
this.editor.session.setValue(newText);
// Restore cursor position, in a lame way, best effort.
selection.setSelectionRange(origRange);
})
}
},
_maybeSync: function(action) {
if (this._syncing) {
return;
}
this._syncing = true;
try {
action.call(this);
} finally {
this._syncing = false;
}
}
});
</script>
</dom-module>