Merge branch 'master' into check-plugin-version-on-startup

This commit is contained in:
Jim Unger 2016-09-15 09:45:01 -05:00
commit 5da33adfdb
79 changed files with 1414 additions and 923 deletions

View file

@ -14,13 +14,28 @@ Kibana is an open source ([Apache Licensed](https://github.com/elastic/kibana/bl
* Run `bin/kibana` on unix, or `bin\kibana.bat` on Windows.
* Visit [http://localhost:5601](http://localhost:5601)
## Upgrade from previous version
* Move any custom configurations in your old kibana.yml to your new one
* Reinstall plugins
* Start or restart Kibana
## Version compatibility with Elasticsearch
Ideally, you should be running Elasticsearch and Kibana with matching version numbers. If your Elasticsearch has an older version number or a newer _major_ number than Kibana, then Kibana will fail to run. If Elasticsearch has a newer minor or patch number than Kibana, then the Kibana Server will log a warning.
_Note: The version numbers below are only examples, meant to illustrate the relationships between different types of version numbers._
| Situation | Example Kibana version | Example ES version | Outcome |
| ------------------------- | -------------------------- |------------------- | ------- |
| Versions are the same. | 5.1.2 | 5.1.2 | 💚 OK |
| ES patch number is newer. | 5.1.__2__ | 5.1.__5__ | ⚠️ Logged warning |
| ES minor number is newer. | 5.__1__.2 | 5.__5__.0 | ⚠️ Logged warning |
| ES major number is newer. | __5__.1.2 | __6__.0.0 | 🚫 Fatal error |
| ES patch number is older. | 5.1.__2__ | 5.1.__0__ | 🚫 Fatal error |
| ES minor number is older. | 5.__1__.2 | 5.__0__.0 | 🚫 Fatal error |
| ES major number is older. | __5__.1.2 | __4__.0.0 | 🚫 Fatal error |
## Quick Start
You're up and running! Fantastic! Kibana is now running on port 5601, so point your browser at http://YOURDOMAIN.com:5601.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 554 B

After

Width:  |  Height:  |  Size: 4.8 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 589 B

After

Width:  |  Height:  |  Size: 4.9 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 5.5 KiB

Before After
Before After

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 125 KiB

Before After
Before After

View file

@ -14,6 +14,7 @@ to this Kibana instance.
`kibana.index:`:: *Default: ".kibana"* Kibana uses an index in Elasticsearch to store saved searches, visualizations and
dashboards. Kibana creates a new index if the index doesnt already exist.
`kibana.defaultAppId:`:: *Default: "discover"* The default application to load.
`kibana.addDataMaxBytes:`:: *Default: 1073741824* The maximum upload size in bytes for the CSV Upload wizard
[[tilemap-settings]]`tilemap.url:`:: *Default: `"https://tiles.elastic.co/v1/default/{z}/{x}/{y}.png?elastic_tile_service_tos=agree&my_app_name=kibana"`* The URL to the tile
service that Kibana uses to display map tiles in tilemap visualizations.
`tilemap.options.minZoom:`:: *Default: 1* The minimum zoom level.

View file

@ -95,7 +95,6 @@
"boom": "2.8.0",
"brace": "0.5.1",
"bunyan": "1.7.1",
"clipboard": "1.5.5",
"commander": "2.8.1",
"css-loader": "0.17.0",
"csv-parse": "1.1.0",
@ -181,7 +180,7 @@
"grunt-cli": "0.1.13",
"grunt-contrib-clean": "1.0.0",
"grunt-contrib-copy": "0.8.1",
"grunt-esvm": "3.2.4",
"grunt-esvm": "3.2.6",
"grunt-karma": "2.0.0",
"grunt-run": "0.6.0",
"grunt-simple-mocha": "0.4.0",

View file

@ -45,7 +45,7 @@ describe('kibana cli', function () {
tempArchiveFile: tempArchiveFilePath,
plugin: 'test-plugin',
version: '5.0.0-SNAPSHOT',
plugins: [ { name: 'foo', path: join(testWorkingPath, 'foo'), version: '5.0.0-SNAPSHOT' } ]
plugins: [ { name: 'foo', path: join(testWorkingPath, 'foo'), kibanaVersion: '5.0.0-SNAPSHOT' } ]
};
const errorStub = sinon.stub();
@ -59,7 +59,7 @@ describe('kibana cli', function () {
expect(errorStub.called).to.be(false);
});
it('should throw an error if plugin does contain a version.', function () {
it('should throw an error if plugin is missing a kibana version.', function () {
const errorStub = sinon.stub();
try {
@ -69,12 +69,12 @@ describe('kibana cli', function () {
errorStub(err);
}
expect(errorStub.firstCall.args[0]).to.match(/plugin version not found/i);
expect(errorStub.firstCall.args[0]).to.match(/plugin package\.json is missing both a version property/i);
});
it('should throw an error if plugin version does does not match kibana version', function () {
it('should throw an error if plugin kibanaVersion does not match kibana version', function () {
const errorStub = sinon.stub();
settings.plugins[0].version = '1.2.3.4';
settings.plugins[0].kibanaVersion = '1.2.3.4';
try {
assertVersion(settings);
@ -83,12 +83,12 @@ describe('kibana cli', function () {
errorStub(err);
}
expect(errorStub.firstCall.args[0]).to.match(/incorrect version/i);
expect(errorStub.firstCall.args[0]).to.match(/incorrect kibana version/i);
});
it('should not throw an error if plugin version matches kibana version', function () {
it('should not throw an error if plugin kibanaVersion matches kibana version', function () {
const errorStub = sinon.stub();
settings.plugins[0].version = '1.0.0';
settings.plugins[0].kibanaVersion = '1.0.0';
try {
assertVersion(settings);
@ -102,7 +102,7 @@ describe('kibana cli', function () {
it('should ignore version info after the dash in checks on valid version', function () {
const errorStub = sinon.stub();
settings.plugins[0].version = '1.0.0-foo-bar-version-1.2.3';
settings.plugins[0].kibanaVersion = '1.0.0-foo-bar-version-1.2.3';
try {
assertVersion(settings);
@ -116,7 +116,7 @@ describe('kibana cli', function () {
it('should ignore version info after the dash in checks on invalid version', function () {
const errorStub = sinon.stub();
settings.plugins[0].version = '2.0.0-foo-bar-version-1.2.3';
settings.plugins[0].kibanaVersion = '2.0.0-foo-bar-version-1.2.3';
try {
assertVersion(settings);
@ -125,7 +125,7 @@ describe('kibana cli', function () {
errorStub(err);
}
expect(errorStub.firstCall.args[0]).to.match(/incorrect version/i);
expect(errorStub.firstCall.args[0]).to.match(/incorrect kibana version/i);
});
});

View file

@ -12,30 +12,41 @@ describe('kibana cli', function () {
describe('pack', function () {
const testWorkingPath = join(__dirname, '.test.data');
const tempArchiveFilePath = join(testWorkingPath, 'archive.part');
const testPluginPath = join(testWorkingPath, '.installedPlugins');
let testNum = 0;
const workingPathRoot = join(__dirname, '.test.data');
let testWorkingPath;
let tempArchiveFilePath;
let testPluginPath;
let logger;
const settings = {
workingPath: testWorkingPath,
tempArchiveFile: tempArchiveFilePath,
pluginDir: testPluginPath,
plugin: 'test-plugin'
};
let settings;
beforeEach(function () {
//These tests are dependent on the file system, and I had some inconsistent
//behavior with rimraf.sync show up. Until these tests are re-written to not
//depend on the file system, I make sure that each test uses a different
//working directory.
testNum += 1;
testWorkingPath = join(workingPathRoot, testNum + '');
tempArchiveFilePath = join(testWorkingPath, 'archive.part');
testPluginPath = join(testWorkingPath, '.installedPlugins');
settings = {
workingPath: testWorkingPath,
tempArchiveFile: tempArchiveFilePath,
pluginDir: testPluginPath,
plugin: 'test-plugin'
};
logger = new Logger(settings);
sinon.stub(logger, 'log');
sinon.stub(logger, 'error');
rimraf.sync(testWorkingPath);
mkdirp.sync(testWorkingPath);
});
afterEach(function () {
logger.log.restore();
logger.error.restore();
rimraf.sync(testWorkingPath);
rimraf.sync(workingPathRoot);
});
function copyReplyFile(filename) {
@ -89,10 +100,33 @@ describe('kibana cli', function () {
expect(settings.plugins[0].name).to.be('test-plugin');
expect(settings.plugins[0].folder).to.be('test-plugin');
expect(settings.plugins[0].version).to.be('1.0.0');
expect(settings.plugins[0].kibanaVersion).to.be('1.0.0');
expect(settings.plugins[0].platform).to.be(undefined);
});
});
it('populate settings.plugin.kibanaVersion', function () {
//kibana.version is defined in this package.json and is different than plugin version
return copyReplyFile('test_plugin_different_version.zip')
.then(() => {
return getPackData(settings, logger);
})
.then(() => {
expect(settings.plugins[0].kibanaVersion).to.be('5.0.1');
});
});
it('populate settings.plugin.kibanaVersion (default to plugin version)', function () {
//kibana.version is not defined in this package.json, defaults to plugin version
return copyReplyFile('test_plugin.zip')
.then(() => {
return getPackData(settings, logger);
})
.then(() => {
expect(settings.plugins[0].kibanaVersion).to.be('1.0.0');
});
});
it('populate settings.plugins with multiple plugins', function () {
return copyReplyFile('test_plugin_many.zip')
.then(() => {

View file

@ -46,14 +46,14 @@ export async function rebuildCache(settings, logger) {
}
export function assertVersion(settings) {
if (!settings.plugins[0].version) {
throw new Error (`Plugin version not found. Check package.json in archive`);
if (!settings.plugins[0].kibanaVersion) {
throw new Error (`Plugin package.json is missing both a version property (required) and a kibana.version property (optional).`);
}
const actual = cleanVersion(settings.plugins[0].version);
const actual = cleanVersion(settings.plugins[0].kibanaVersion);
const expected = cleanVersion(settings.version);
if (!versionSatisfies(actual, expected)) {
throw new Error (`Incorrect version in plugin [${settings.plugins[0].name}]. ` +
throw new Error (`Incorrect Kibana version in plugin [${settings.plugins[0].name}]. ` +
`Expected [${expected}]; found [${actual}]`);
}
}

View file

@ -55,10 +55,10 @@ function assertValidPackageName(plugin) {
}
}
/**
* Examine each package.json file to determine the plugin name,
* version, and platform. Mutates the package objects in the packages array
* version, kibanaVersion, and platform. Mutates the package objects
* in the packages array
* @param {object} settings - a plugin installer settings object
* @param {array} packages - array of package objects from listPackages()
*/
@ -71,6 +71,12 @@ async function mergePackageData(settings, packages) {
pkg.name = _.get(packageInfo, 'name');
pkg.path = resolve(settings.pluginDir, pkg.name);
// Plugins must specify their version, and by default that version should match
// the version of kibana down to the patch level. If these two versions need
// to diverge, they can specify a kibana.version to indicate the version of
// kibana the plugin is intended to work with.
pkg.kibanaVersion = _.get(packageInfo, 'kibana.version', pkg.version);
const regExp = new RegExp(`${pkg.name}-(.+)`, 'i');
const matches = pkg.folder.match(regExp);
pkg.platform = (matches) ? matches[1] : undefined;

View file

@ -9,19 +9,7 @@ module.exports = function (kibana) {
let { existsSync } = require('fs');
const { startsWith, endsWith } = require('lodash');
const apps = [
{
title: 'Console',
description: 'JSON aware developer\'s interface to ElasticSearch',
main: 'plugins/console/console',
icon: 'plugins/console/logo.svg',
injectVars: function (server, options) {
const varsToInject = options;
varsToInject.elasticsearchUrl = server.config().get('elasticsearch.url');
return varsToInject;
}
}
];
const apps = [];
if (existsSync(resolve(__dirname, 'public/tests'))) {
apps.push({
@ -146,7 +134,7 @@ module.exports = function (kibana) {
payload: {
output: 'stream',
parse: false
},
}
}
});
@ -156,7 +144,7 @@ module.exports = function (kibana) {
config: {
...proxyRouteConfig
}
})
});
server.route({
path: '/api/console/api_server',
@ -188,6 +176,14 @@ module.exports = function (kibana) {
uiExports: {
apps: apps,
devTools: ['plugins/console/console'],
injectDefaultVars(server, options) {
const varsToInject = options;
varsToInject.elasticsearchUrl = server.config().get('elasticsearch.url');
return varsToInject;
},
noParse: [
join(modules, 'ace' + sep),
join(modules, 'moment_src/moment' + sep),

View file

@ -1,3 +1,7 @@
import devTools from 'ui/registry/dev_tools';
import uiRoutes from 'ui/routes';
import template from './index.html';
require('ace');
require('ui-bootstrap-custom');
@ -13,6 +17,14 @@ require('./src/directives/sense_help');
require('./src/directives/sense_welcome');
require('./src/directives/sense_navbar');
require('ui/chrome')
.setRootTemplate(require('./index.html'))
.setRootController('sense', 'SenseController');
devTools.register(() => ({
order: 1,
name: 'console',
display: 'Console',
url: '#/dev_tools/console'
}));
uiRoutes.when('/dev_tools/console', {
controller: 'SenseController',
template
});

View file

@ -1,38 +1,43 @@
<sense-navbar></sense-navbar>
<kbn-dev-tools-app data-test-subj="console">
<sense-navbar></sense-navbar>
<div id="editor_output_container">
<div id="editor_container">
<ul id="autocomplete"></ul>
<div id="editor_actions">
<kbn-tooltip text="click to send request">
<a class="editor_action" ng-click="sense.sendSelected()">
<i class="fa fa-play"></i>
</a>
</kbn-tooltip>
<span dropdown>
<a class="editor_action" dropdown-toggle href="#">
<i class="fa fa-wrench"></i>
</a>
<div id="editor_output_container">
<div id="editor_container">
<ul id="autocomplete"></ul>
<div id="editor_actions">
<kbn-tooltip text="click to send request">
<a
class="editor_action"
ng-click="sendSelected()"
data-test-subj="send-request-button">
<i class="fa fa-play"></i>
</a>
</kbn-tooltip>
<span dropdown>
<a class="editor_action" dropdown-toggle href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu" role="menu" aria-labelledby="split-button">
<li role="menuitem">
<a href="#" id="copy_as_curl">Copy as cURL</a>
</li>
<li role="menuitem">
<a ng-click="autoIndent($event)">Auto indent</a>
</li>
</ul>
</span>
</div>
<div id="editor" data-test-subj="request-editor">GET _search
{
"query": { "match_all": {} }
}</div>
<ul class="dropdown-menu" role="menu" aria-labelledby="split-button">
<li role="menuitem">
<a href="#" id="copy_as_curl">Copy as cURL</a>
</li>
<li role="menuitem">
<a ng-click="sense.autoIndent($event)">Auto indent</a>
</li>
</ul>
</span>
</div>
<div id="editor">GET _search
{
"query": { "match_all": {} }
}</div>
<div id="editor_resizer">&#xFE19;</div>
<div id="output_container" data-test-subj="response-editor">
<div id="output">{}</div>
</div>
</div>
<div id="editor_resizer">&#xFE19;</div>
<div id="output_container">
<div id="output">{}</div>
</div>
</div>
</kbn-dev-tools-app>

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M5 0l-3 6h1l3-6h-1zm-4 1l-1 2 1 2h1l-1-2 1-2h-1zm5 0l1 2-1 2h1l1-2-1-2h-1z" transform="translate(0 1)" />
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 217 B

Before After
Before After

View file

@ -2,114 +2,113 @@ var $ = require('jquery');
let curl = require('./curl');
let history = require('./history');
let input = require('./input');
let mappings = require('./mappings');
let output = require('./output');
let es = require('./es');
let utils = require('./utils');
let _ = require('lodash');
const chrome = require('ui/chrome');
$(document.body).removeClass('fouc');
export default function init(input, output) {
$(document.body).removeClass('fouc');
// set the value of the input and clear the output
function resetToValues(content) {
if (content != null) {
input.update(content);
// set the value of the input and clear the output
function resetToValues(content) {
if (content != null) {
input.update(content);
}
output.update("");
}
output.update("");
}
function loadSavedState() {
var sourceLocation = utils.getUrlParam('load_from') || "stored";
var previousSaveState = history.getSavedEditorState();
function loadSavedState() {
var sourceLocation = utils.getUrlParam('load_from') || "stored";
var previousSaveState = history.getSavedEditorState();
if (sourceLocation == "stored") {
if (previousSaveState) {
resetToValues(previousSaveState.content);
if (sourceLocation == "stored") {
if (previousSaveState) {
resetToValues(previousSaveState.content);
}
else {
resetToValues();
input.autoIndent();
}
}
else if (/^https?:\/\//.test(sourceLocation)) {
var loadFrom = {url: sourceLocation, dataType: "text", kbnXsrfToken: false};
if (/https?:\/\/api.github.com/.test(sourceLocation)) {
loadFrom.headers = {Accept: "application/vnd.github.v3.raw"};
}
$.ajax(loadFrom).done(function (data) {
resetToValues(data);
input.moveToNextRequestEdge(true);
input.highlightCurrentRequestsAndUpdateActionBar();
input.updateActionsBar();
});
}
else {
resetToValues();
input.autoIndent();
}
input.moveToNextRequestEdge(true);
}
else if (/^https?:\/\//.test(sourceLocation)) {
var loadFrom = {url: sourceLocation, dataType: "text", kbnXsrfToken: false};
if (/https?:\/\/api.github.com/.test(sourceLocation)) {
loadFrom.headers = {Accept: "application/vnd.github.v3.raw"};
}
$.ajax(loadFrom).done(function (data) {
resetToValues(data);
input.moveToNextRequestEdge(true);
input.highlightCurrentRequestsAndUpdateActionBar();
input.updateActionsBar();
function setupAutosave() {
var timer;
var saveDelay = 500;
input.getSession().on("change", function onChange(e) {
if (timer) {
timer = clearTimeout(timer);
}
timer = setTimeout(saveCurrentState, saveDelay);
});
}
else {
resetToValues();
}
input.moveToNextRequestEdge(true);
}
function setupAutosave() {
var timer;
var saveDelay = 500;
input.getSession().on("change", function onChange(e) {
if (timer) {
timer = clearTimeout(timer);
function saveCurrentState() {
try {
var content = input.getValue();
history.updateCurrentState(content);
}
catch (e) {
console.log("Ignoring saving error: " + e);
}
timer = setTimeout(saveCurrentState, saveDelay);
});
}
function saveCurrentState() {
try {
var content = input.getValue();
history.updateCurrentState(content);
}
catch (e) {
console.log("Ignoring saving error: " + e);
}
}
// stupid simple restore function, called when the user
// chooses to restore a request from the history
// PREVENTS history from needing to know about the input
history.restoreFromHistory = function applyHistoryElem(req) {
var session = input.getSession();
var pos = input.getCursorPosition();
var prefix = "";
var suffix = "\n";
if (input.parser.isStartRequestRow(pos.row)) {
pos.column = 0;
suffix += "\n";
}
else if (input.parser.isEndRequestRow(pos.row)) {
var line = session.getLine(pos.row);
pos.column = line.length;
prefix = "\n\n";
}
else if (input.parser.isInBetweenRequestsRow(pos.row)) {
pos.column = 0;
}
else {
pos = input.nextRequestEnd(pos);
prefix = "\n\n";
}
var s = prefix + req.method + " " + req.endpoint;
if (req.data) {
s += "\n" + req.data;
}
// stupid simple restore function, called when the user
// chooses to restore a request from the history
// PREVENTS history from needing to know about the input
history.restoreFromHistory = function applyHistoryElem(req) {
var session = input.getSession();
var pos = input.getCursorPosition();
var prefix = "";
var suffix = "\n";
if (input.parser.isStartRequestRow(pos.row)) {
pos.column = 0;
suffix += "\n";
}
else if (input.parser.isEndRequestRow(pos.row)) {
var line = session.getLine(pos.row);
pos.column = line.length;
prefix = "\n\n";
}
else if (input.parser.isInBetweenRequestsRow(pos.row)) {
pos.column = 0;
}
else {
pos = input.nextRequestEnd(pos);
prefix = "\n\n";
}
s += suffix;
var s = prefix + req.method + " " + req.endpoint;
if (req.data) {
s += "\n" + req.data;
}
session.insert(pos, s);
input.clearSelection();
input.moveCursorTo(pos.row + prefix.length, 0);
input.focus();
s += suffix;
session.insert(pos, s);
input.clearSelection();
input.moveCursorTo(pos.row + prefix.length, 0);
input.focus();
};
loadSavedState();
setupAutosave();
};
loadSavedState();
setupAutosave();

View file

@ -6,7 +6,6 @@ let utils = require('./utils');
let autocomplete_engine = require('./autocomplete/engine');
let url_pattern_matcher = require('./autocomplete/url_pattern_matcher');
let _ = require('lodash');
let $ = require('jquery');
let ext_lang_tools = require('ace/ext-language_tools');

View file

@ -1,5 +1,10 @@
import 'ui/doc_title';
import { useResizeCheckerProvider } from '../sense_editor_resize';
import $ from 'jquery';
import { initializeInput } from '../input';
import { initializeOutput } from '../output';
import es from '../es';
import init from '../app';
const module = require('ui/modules').get('app/sense');
@ -11,23 +16,27 @@ module.run(function (Private, $rootScope) {
};
});
module.controller('SenseController', function SenseController($scope, docTitle) {
module.controller('SenseController', function SenseController($scope, $timeout, docTitle) {
docTitle.change('Console');
// require the root app code, which expects to execute once the dom is loaded up
require('../app');
let input, output;
const input = require('../input');
const es = require('../es');
// We need to wait for these elements to be rendered before we can select them with jQuery
// and then initialize this app
$timeout(() => {
output = initializeOutput($('#output'));
input = initializeInput($('#editor'), $('#editor_actions'), $('#copy_as_curl'), output);
init(input, output);
});
this.sendSelected = () => {
$scope.sendSelected = () => {
input.focus();
input.sendCurrentRequestToES();
return false;
};
this.autoIndent = (event) => {
$scope.autoIndent = (event) => {
input.autoIndent();
event.preventDefault();
input.focus();

View file

@ -1,9 +1 @@
<kbn-top-nav name="timelion" ng-if="sense" config="navbar.menu">
<div class="kibana-nav-info">
<span class="kibana-nav-info-title">
<span>
Elasticsearch Console
</span>
</span>
</div>
</kbn-top-nav>
<kbn-top-nav name="console" ng-if="sense" config="navbar.menu" data-test-subj="top-nav"></kbn-top-nav>

View file

@ -1,7 +1,6 @@
const $ = require('jquery');
const { uniq } = require('lodash');
const storage = require('./storage');
const chrome = require('ui/chrome');
const history = module.exports = {
restoreFromHistory() {

View file

@ -4,7 +4,6 @@ let ZeroClipboard = require('zeroclip');
let ext_searchbox = require('ace/ext-searchbox');
let Autocomplete = require('./autocomplete');
let mappings = require('./mappings');
let output = require('./output');
let SenseEditor = require('./sense_editor/editor');
let settings = require('./settings');
let storage = require('./storage');
@ -13,232 +12,238 @@ let es = require('./es');
let history = require('./history');
import uiModules from 'ui/modules';
var $el = $('#editor');
var input = new SenseEditor($el);
uiModules.get('app/sense').setupResizeCheckerForRootEditors($el, input, output);
let input;
export function initializeInput($el, $actionsEl, $copyAsCurlEl, output) {
input = new SenseEditor($el);
input.autocomplete = new Autocomplete(input);
uiModules.get('app/sense').setupResizeCheckerForRootEditors($el, input, output);
input.$actions = $("#editor_actions");
input.autocomplete = new Autocomplete(input);
input.commands.addCommand({
name: 'auto indent request',
bindKey: {win: 'Ctrl-I', mac: 'Command-I'},
exec: function () {
input.autoIndent();
}
});
input.commands.addCommand({
name: 'move to previous request start or end',
bindKey: {win: 'Ctrl-Up', mac: 'Command-Up'},
exec: function () {
input.moveToPreviousRequestEdge()
}
});
input.commands.addCommand({
name: 'move to next request start or end',
bindKey: {win: 'Ctrl-Down', mac: 'Command-Down'},
exec: function () {
input.moveToNextRequestEdge()
}
});
input.$actions = $actionsEl;
/**
* COPY AS CURL
*
* Since the copy functionality is powered by a flash movie (via ZeroClipboard)
* the only way to trigger the copy is with a litteral mouseclick from the user.
*
* The original shortcut will now just open the menu and highlight the
*
*/
var $copyAsCURL = $('#copy_as_curl');
var zc = (function setupZeroClipboard() {
var zc = new ZeroClipboard($copyAsCURL); // the ZeroClipboard instance
zc.on('wrongflash noflash', function () {
if (!storage.get('flash_warning_shown')) {
alert('Console needs flash version 10.0 or greater in order to provide "Copy as cURL" functionality');
storage.set('flash_warning_shown', 'true');
input.commands.addCommand({
name: 'auto indent request',
bindKey: {win: 'Ctrl-I', mac: 'Command-I'},
exec: function () {
input.autoIndent();
}
});
input.commands.addCommand({
name: 'move to previous request start or end',
bindKey: {win: 'Ctrl-Up', mac: 'Command-Up'},
exec: function () {
input.moveToPreviousRequestEdge()
}
});
input.commands.addCommand({
name: 'move to next request start or end',
bindKey: {win: 'Ctrl-Down', mac: 'Command-Down'},
exec: function () {
input.moveToNextRequestEdge()
}
$copyAsCURL.hide();
});
zc.on('ready', function () {
function setupCopyButton(cb) {
cb = typeof cb === 'function' ? cb : $.noop;
$copyAsCURL.css('visibility', 'hidden');
input.getRequestsAsCURL(function (curl) {
$copyAsCURL.attr('data-clipboard-text', curl);
$copyAsCURL.css('visibility', 'visible');
cb();
});
}
input.$actions.on('mouseenter', function () {
if (!$(this).hasClass('open')) {
setupCopyButton();
/**
* COPY AS CURL
*
* Since the copy functionality is powered by a flash movie (via ZeroClipboard)
* the only way to trigger the copy is with a litteral mouseclick from the user.
*
* The original shortcut will now just open the menu and highlight the
*
*/
var zc = (function setupZeroClipboard() {
var zc = new ZeroClipboard($copyAsCurlEl); // the ZeroClipboard instance
zc.on('wrongflash noflash', function () {
if (!storage.get('flash_warning_shown')) {
alert('Console needs flash version 10.0 or greater in order to provide "Copy as cURL" functionality');
storage.set('flash_warning_shown', 'true');
}
$copyAsCurlEl.hide();
});
});
zc.on('complete', function () {
$copyAsCURL.click();
input.focus();
});
zc.on('ready', function () {
function setupCopyButton(cb) {
cb = typeof cb === 'function' ? cb : $.noop;
$copyAsCurlEl.css('visibility', 'hidden');
input.getRequestsAsCURL(function (curl) {
$copyAsCurlEl.attr('data-clipboard-text', curl);
$copyAsCurlEl.css('visibility', 'visible');
cb();
});
}
return zc;
}());
input.$actions.on('mouseenter', function () {
if (!$(this).hasClass('open')) {
setupCopyButton();
}
});
});
/**
* Setup the "send" shortcut
*/
zc.on('complete', function () {
$copyAsCurlEl.click();
input.focus();
});
var CURRENT_REQ_ID = 0;
return zc;
}());
function sendCurrentRequestToES() {
/**
* Setup the "send" shortcut
*/
var req_id = ++CURRENT_REQ_ID;
var CURRENT_REQ_ID = 0;
input.getRequestsInRange(function (requests) {
if (req_id != CURRENT_REQ_ID) {
return;
}
output.update('');
function sendCurrentRequestToES() {
if (requests.length == 0) {
return;
}
var req_id = ++CURRENT_REQ_ID;
var isMultiRequest = requests.length > 1;
var finishChain = function () { /* noop */ };
var isFirstRequest = true;
var sendNextRequest = function () {
input.getRequestsInRange(function (requests) {
if (req_id != CURRENT_REQ_ID) {
return;
}
output.update('');
if (requests.length == 0) {
finishChain();
return;
}
var req = requests.shift();
var es_path = req.url;
var es_method = req.method;
var es_data = req.data.join("\n");
if (es_data) {
es_data += "\n";
} //append a new line for bulk requests.
es.send(es_method, es_path, es_data).always(function (dataOrjqXHR, textStatus, jqXhrORerrorThrown) {
var isMultiRequest = requests.length > 1;
var finishChain = function () { /* noop */ };
var isFirstRequest = true;
var sendNextRequest = function () {
if (req_id != CURRENT_REQ_ID) {
return;
}
var xhr;
if (dataOrjqXHR.promise) {
xhr = dataOrjqXHR;
if (requests.length == 0) {
finishChain();
return;
}
else {
xhr = jqXhrORerrorThrown;
}
function modeForContentType(contentType) {
if (contentType.indexOf("text/plain") >= 0) {
return "ace/mode/text";
var req = requests.shift();
var es_path = req.url;
var es_method = req.method;
var es_data = req.data.join("\n");
if (es_data) {
es_data += "\n";
} //append a new line for bulk requests.
es.send(es_method, es_path, es_data).always(function (dataOrjqXHR, textStatus, jqXhrORerrorThrown) {
if (req_id != CURRENT_REQ_ID) {
return;
}
else if (contentType.indexOf("application/yaml") >= 0) {
return "ace/mode/yaml";
}
return null;
}
if (typeof xhr.status == "number" &&
// things like DELETE index where the index is not there are OK.
((xhr.status >= 200 && xhr.status < 300) || xhr.status == 404)
) {
// we have someone on the other side. Add to history
history.addToHistory(es_path, es_method, es_data);
let value = xhr.responseText;
let mode = modeForContentType(xhr.getAllResponseHeaders("Content-Type") || "");
if (mode === null || mode === "application/json") {
// assume json - auto pretty
try {
value = JSON.stringify(JSON.parse(value), null, 2);
}
catch (e) {
}
}
if (isMultiRequest) {
value = "# " + req.method + " " + req.url + "\n" + value;
}
if (isFirstRequest) {
output.update(value, mode);
var xhr;
if (dataOrjqXHR.promise) {
xhr = dataOrjqXHR;
}
else {
output.append("\n" + value);
xhr = jqXhrORerrorThrown;
}
isFirstRequest = false;
// single request terminate via sendNextRequest as well
sendNextRequest();
}
else {
let value, mode;
if (xhr.responseText) {
value = xhr.responseText; // ES error should be shown
mode = modeForContentType(xhr.getAllResponseHeaders("Content-Type") || "");
if (value[0] == "{") {
function modeForContentType(contentType) {
if (contentType.indexOf("text/plain") >= 0) {
return "ace/mode/text";
}
else if (contentType.indexOf("application/yaml") >= 0) {
return "ace/mode/yaml";
}
return null;
}
if (typeof xhr.status == "number" &&
// things like DELETE index where the index is not there are OK.
((xhr.status >= 200 && xhr.status < 300) || xhr.status == 404)
) {
// we have someone on the other side. Add to history
history.addToHistory(es_path, es_method, es_data);
let value = xhr.responseText;
let mode = modeForContentType(xhr.getAllResponseHeaders("Content-Type") || "");
if (mode === null || mode === "application/json") {
// assume json - auto pretty
try {
value = JSON.stringify(JSON.parse(value), null, 2);
}
catch (e) {
}
}
} else {
value = "Request failed to get to the server (status code: " + xhr.status + ")";
mode = 'ace/mode/text';
}
if (isMultiRequest) {
value = "# " + req.method + " " + req.url + "\n" + value;
}
if (isFirstRequest) {
output.update(value, mode);
if (isMultiRequest) {
value = "# " + req.method + " " + req.url + "\n" + value;
}
if (isFirstRequest) {
output.update(value, mode);
}
else {
output.append("\n" + value);
}
isFirstRequest = false;
// single request terminate via sendNextRequest as well
sendNextRequest();
}
else {
output.append("\n" + value);
let value, mode;
if (xhr.responseText) {
value = xhr.responseText; // ES error should be shown
mode = modeForContentType(xhr.getAllResponseHeaders("Content-Type") || "");
if (value[0] == "{") {
try {
value = JSON.stringify(JSON.parse(value), null, 2);
}
catch (e) {
}
}
} else {
value = "Request failed to get to the server (status code: " + xhr.status + ")";
mode = 'ace/mode/text';
}
if (isMultiRequest) {
value = "# " + req.method + " " + req.url + "\n" + value;
}
if (isFirstRequest) {
output.update(value, mode);
}
else {
output.append("\n" + value);
}
finishChain();
}
finishChain();
}
});
};
});
};
sendNextRequest();
sendNextRequest();
});
}
input.commands.addCommand({
name: 'send to elasticsearch',
bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
exec: sendCurrentRequestToES
});
}
input.commands.addCommand({
name: 'send to elasticsearch',
bindKey: {win: 'Ctrl-Enter', mac: 'Command-Enter'},
exec: sendCurrentRequestToES
});
/**
* Init the editor
*/
if (settings) {
settings.applyCurrentSettings(input);
}
input.focus();
input.highlightCurrentRequestsAndUpdateActionBar();
input.sendCurrentRequestToES = sendCurrentRequestToES;
require('./input_resize')(input, output);
/**
* Init the editor
*/
if (settings) {
settings.applyCurrentSettings(input);
}
input.focus();
input.highlightCurrentRequestsAndUpdateActionBar();
return input;
};
input.sendCurrentRequestToES = sendCurrentRequestToES;
require('./input_resize')(input, output);
module.exports = input;
export default function getInput() {
return input;
};

View file

@ -4,63 +4,69 @@ let settings = require('./settings');
let OutputMode = require('./sense_editor/mode/output');
const smartResize = require('./smart_resize');
var $el = $("#output");
var output = ace.require('ace/ace').edit($el[0]);
let output;
export function initializeOutput($el) {
output = ace.require('ace/ace').edit($el[0]);
var outputMode = new OutputMode.Mode();
var outputMode = new OutputMode.Mode();
output.resize = smartResize(output);
output.update = function (val, mode, cb) {
if (typeof mode === 'function') {
cb = mode;
mode = void 0;
output.resize = smartResize(output);
output.update = function (val, mode, cb) {
if (typeof mode === 'function') {
cb = mode;
mode = void 0;
}
var session = output.getSession();
session.setMode(val ? (mode || outputMode) : 'ace/mode/text');
session.setValue(val);
if (typeof cb === 'function') {
setTimeout(cb);
}
};
output.append = function (val, fold_previous, cb) {
if (typeof fold_previous === 'function') {
cb = fold_previous;
fold_previous = true;
}
if (_.isUndefined(fold_previous)) {
fold_previous = true;
}
var session = output.getSession();
var lastLine = session.getLength();
if (fold_previous) {
output.moveCursorTo(Math.max(0, lastLine - 1), 0);
session.toggleFold(false);
}
session.insert({row: lastLine, column: 0}, "\n" + val);
output.moveCursorTo(lastLine + 1, 0);
if (typeof cb === 'function') {
setTimeout(cb);
}
};
output.$el = $el;
(function (session) {
session.setMode("ace/mode/text");
session.setFoldStyle('markbeginend');
session.setTabSize(2);
session.setUseWrapMode(true);
}(output.getSession()));
output.setShowPrintMargin(false);
output.setReadOnly(true);
if (settings) {
settings.applyCurrentSettings(output);
}
var session = output.getSession();
session.setMode(val ? (mode || outputMode) : 'ace/mode/text');
session.setValue(val);
if (typeof cb === 'function') {
setTimeout(cb);
}
return output;
};
output.append = function (val, fold_previous, cb) {
if (typeof fold_previous === 'function') {
cb = fold_previous;
fold_previous = true;
}
if (_.isUndefined(fold_previous)) {
fold_previous = true;
}
var session = output.getSession();
var lastLine = session.getLength();
if (fold_previous) {
output.moveCursorTo(Math.max(0, lastLine - 1), 0);
session.toggleFold(false);
}
session.insert({row: lastLine, column: 0}, "\n" + val);
output.moveCursorTo(lastLine + 1, 0);
if (typeof cb === 'function') {
setTimeout(cb);
}
export default function getOutput() {
return output;
};
output.$el = $el;
(function (session) {
session.setMode("ace/mode/text");
session.setFoldStyle('markbeginend');
session.setTabSize(2);
session.setUseWrapMode(true);
}(output.getSession()));
output.setShowPrintMargin(false);
output.setReadOnly(true);
if (settings) {
settings.applyCurrentSettings(output);
}
module.exports = output;

View file

@ -39,8 +39,8 @@ function setAutocomplete(settings) {
function applyCurrentSettings(editor) {
if (typeof editor === 'undefined') {
applyCurrentSettings(require('./input'));
applyCurrentSettings(require('./output'));
applyCurrentSettings(require('./input')());
applyCurrentSettings(require('./output')());
}
if (editor) {
editor.getSession().setUseWrapMode(getWrapMode());
@ -60,7 +60,7 @@ function updateSettings({ fontSize, wrapMode, autocomplete}) {
setFontSize(fontSize);
setWrapMode(wrapMode);
setAutocomplete(autocomplete);
require('./input').focus();
require('./input')().focus();
return getCurrentSettings();
}

View file

@ -1,2 +1,2 @@
require('ace/ace.js');
module.exports = window.ace;
module.exports = window.consoleAce;

View file

@ -30,7 +30,7 @@
(function() {
var ACE_NAMESPACE = "ace";
var ACE_NAMESPACE = "consoleAce";
var global = (function() {
return this;
@ -169,7 +169,7 @@ exportAce(ACE_NAMESPACE);
})();
ace.define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/placeholder', 'ace/mode/folding/fold_mode', 'ace/theme/textmate', 'ace/ext/error_marker', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/placeholder', 'ace/mode/folding/fold_mode', 'ace/theme/textmate', 'ace/ext/error_marker', 'ace/config'], function(require, exports, module) {
require("./lib/fixoldbrowsers");
@ -230,7 +230,7 @@ exports.EditSession = EditSession;
exports.UndoManager = UndoManager;
});
ace.define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
consoleAce.define('ace/lib/fixoldbrowsers', ['require', 'exports', 'module' , 'ace/lib/regexp', 'ace/lib/es5-shim'], function(require, exports, module) {
require("./regexp");
@ -238,7 +238,7 @@ require("./es5-shim");
});
ace.define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, exports, module) {
var real = {
exec: RegExp.prototype.exec,
@ -310,7 +310,7 @@ ace.define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require
});
ace.define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
function Empty() {}
@ -1007,7 +1007,7 @@ var toObject = function (o) {
});
ace.define('ace/lib/dom', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/dom', ['require', 'exports', 'module' ], function(require, exports, module) {
if (typeof document == "undefined")
@ -1240,7 +1240,7 @@ exports.getParentWindow = function(document) {
});
ace.define('ace/lib/event', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent', 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/lib/event', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent', 'ace/lib/dom'], function(require, exports, module) {
var keys = require("./keys");
@ -1555,7 +1555,7 @@ else
};
});
ace.define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], function(require, exports, module) {
consoleAce.define('ace/lib/keys', ['require', 'exports', 'module' , 'ace/lib/oop'], function(require, exports, module) {
var oop = require("./oop");
@ -1648,7 +1648,7 @@ exports.keyCodeToString = function(keyCode) {
});
ace.define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.inherits = function(ctor, superCtor) {
@ -1676,7 +1676,7 @@ exports.implement = function(proto, mixin) {
});
ace.define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/useragent', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.OS = {
LINUX: "LINUX",
MAC: "MAC",
@ -1719,7 +1719,7 @@ exports.isTouchPad = ua.indexOf("TouchPad") >= 0;
});
ace.define('ace/editor', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/keyboard/textinput', 'ace/mouse/mouse_handler', 'ace/mouse/fold_handler', 'ace/keyboard/keybinding', 'ace/edit_session', 'ace/search', 'ace/range', 'ace/lib/event_emitter', 'ace/commands/command_manager', 'ace/commands/default_commands', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/editor', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/keyboard/textinput', 'ace/mouse/mouse_handler', 'ace/mouse/fold_handler', 'ace/keyboard/keybinding', 'ace/edit_session', 'ace/search', 'ace/range', 'ace/lib/event_emitter', 'ace/commands/command_manager', 'ace/commands/default_commands', 'ace/config'], function(require, exports, module) {
require("./lib/fixoldbrowsers");
@ -3338,7 +3338,7 @@ config.defineOptions(Editor.prototype, "editor", {
exports.Editor = Editor;
});
ace.define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.stringReverse = function(string) {
@ -3521,7 +3521,7 @@ exports.delayedCall = function(fcn, defaultTimeout) {
};
});
ace.define('ace/keyboard/textinput', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/lib/dom', 'ace/lib/lang'], function(require, exports, module) {
consoleAce.define('ace/keyboard/textinput', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/lib/dom', 'ace/lib/lang'], function(require, exports, module) {
var event = require("../lib/event");
@ -3966,7 +3966,7 @@ var TextInput = function(parentNode, host) {
exports.TextInput = TextInput;
});
ace.define('ace/mouse/mouse_handler', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/mouse/default_handlers', 'ace/mouse/default_gutter_handler', 'ace/mouse/mouse_event', 'ace/mouse/dragdrop_handler', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/mouse/mouse_handler', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent', 'ace/mouse/default_handlers', 'ace/mouse/default_gutter_handler', 'ace/mouse/mouse_event', 'ace/mouse/dragdrop_handler', 'ace/config'], function(require, exports, module) {
var event = require("../lib/event");
@ -4095,7 +4095,7 @@ config.defineOptions(MouseHandler.prototype, "mouseHandler", {
exports.MouseHandler = MouseHandler;
});
ace.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
consoleAce.define('ace/mouse/default_handlers', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
var dom = require("../lib/dom");
@ -4332,7 +4332,7 @@ function calcRangeOrientation(range, cursor) {
});
ace.define('ace/mouse/default_gutter_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event'], function(require, exports, module) {
consoleAce.define('ace/mouse/default_gutter_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event'], function(require, exports, module) {
var dom = require("../lib/dom");
var event = require("../lib/event");
@ -4464,7 +4464,7 @@ exports.GutterHandler = GutterHandler;
});
ace.define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
consoleAce.define('ace/mouse/mouse_event', ['require', 'exports', 'module' , 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
var event = require("../lib/event");
@ -4538,7 +4538,7 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
});
ace.define('ace/mouse/dragdrop_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
consoleAce.define('ace/mouse/dragdrop_handler', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent'], function(require, exports, module) {
var dom = require("../lib/dom");
@ -4911,7 +4911,7 @@ exports.DragdropHandler = DragdropHandler;
});
ace.define('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/lib/net', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/lib/net', 'ace/lib/event_emitter'], function(require, exports, module) {
"no use strict";
var lang = require("./lib/lang");
@ -5163,7 +5163,7 @@ exports.setDefaultValues = function(path, optionHash) {
};
});
ace.define('ace/lib/net', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/lib/net', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
var dom = require("./dom");
@ -5196,7 +5196,7 @@ exports.loadScript = function(path, callback) {
});
ace.define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
var EventEmitter = {};
@ -5322,7 +5322,7 @@ exports.EventEmitter = EventEmitter;
});
ace.define('ace/mouse/fold_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/mouse/fold_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
function FoldHandler(editor) {
@ -5384,7 +5384,7 @@ exports.FoldHandler = FoldHandler;
});
ace.define('ace/keyboard/keybinding', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/event'], function(require, exports, module) {
consoleAce.define('ace/keyboard/keybinding', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/event'], function(require, exports, module) {
var keyUtil = require("../lib/keys");
@ -5488,7 +5488,7 @@ var KeyBinding = function(editor) {
exports.KeyBinding = KeyBinding;
});
ace.define('ace/edit_session', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/config', 'ace/lib/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document', 'ace/background_tokenizer', 'ace/search_highlight', 'ace/edit_session/folding', 'ace/edit_session/bracket_match'], function(require, exports, module) {
consoleAce.define('ace/edit_session', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/config', 'ace/lib/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document', 'ace/background_tokenizer', 'ace/search_highlight', 'ace/edit_session/folding', 'ace/edit_session/bracket_match'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -7181,7 +7181,7 @@ config.defineOptions(EditSession.prototype, "session", {
exports.EditSession = EditSession;
});
ace.define('ace/selection', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/selection', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter', 'ace/range'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -7769,7 +7769,7 @@ var Selection = function(session) {
exports.Selection = Selection;
});
ace.define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
var comparePoints = function(p1, p2) {
return p1.row - p2.row || p1.column - p2.column;
@ -8008,7 +8008,7 @@ Range.comparePoints = function(p1, p2) {
exports.Range = Range;
});
ace.define('ace/mode/text', ['require', 'exports', 'module' , 'ace/tokenizer', 'ace/mode/text_highlight_rules', 'ace/mode/behaviour', 'ace/unicode', 'ace/lib/lang', 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/mode/text', ['require', 'exports', 'module' , 'ace/tokenizer', 'ace/mode/text_highlight_rules', 'ace/mode/behaviour', 'ace/unicode', 'ace/lib/lang', 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
var Tokenizer = require("../tokenizer").Tokenizer;
@ -8360,7 +8360,7 @@ var Mode = function() {
exports.Mode = Mode;
});
ace.define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/tokenizer', ['require', 'exports', 'module' ], function(require, exports, module) {
var MAX_TOKEN_COUNT = 1000;
var Tokenizer = function(rules) {
this.states = rules;
@ -8644,7 +8644,7 @@ var Tokenizer = function(rules) {
exports.Tokenizer = Tokenizer;
});
ace.define('ace/mode/text_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/lang'], function(require, exports, module) {
consoleAce.define('ace/mode/text_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/lang'], function(require, exports, module) {
var lang = require("../lib/lang");
@ -8842,7 +8842,7 @@ var TextHighlightRules = function() {
exports.TextHighlightRules = TextHighlightRules;
});
ace.define('ace/mode/behaviour', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/mode/behaviour', ['require', 'exports', 'module' ], function(require, exports, module) {
var Behaviour = function() {
@ -8902,7 +8902,7 @@ var Behaviour = function() {
exports.Behaviour = Behaviour;
});
ace.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/unicode', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.packages = {};
addUnicodePackage({
@ -8953,7 +8953,7 @@ function addUnicodePackage (pack) {
});
ace.define('ace/token_iterator', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/token_iterator', ['require', 'exports', 'module' ], function(require, exports, module) {
var TokenIterator = function(session, initialRow, initialColumn) {
this.$session = session;
this.$row = initialRow;
@ -9025,7 +9025,7 @@ var TokenIterator = function(session, initialRow, initialColumn) {
exports.TokenIterator = TokenIterator;
});
ace.define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
consoleAce.define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -9381,7 +9381,7 @@ var Document = function(text) {
exports.Document = Document;
});
ace.define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -9528,7 +9528,7 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
ace.define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/background_tokenizer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -9675,7 +9675,7 @@ var BackgroundTokenizer = function(tokenizer, editor) {
exports.BackgroundTokenizer = BackgroundTokenizer;
});
ace.define('ace/search_highlight', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/search_highlight', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
var lang = require("./lib/lang");
@ -9727,7 +9727,7 @@ var SearchHighlight = function(regExp, clazz, type) {
exports.SearchHighlight = SearchHighlight;
});
ace.define('ace/edit_session/folding', ['require', 'exports', 'module' , 'ace/range', 'ace/edit_session/fold_line', 'ace/edit_session/fold', 'ace/token_iterator'], function(require, exports, module) {
consoleAce.define('ace/edit_session/folding', ['require', 'exports', 'module' , 'ace/range', 'ace/edit_session/fold_line', 'ace/edit_session/fold', 'ace/token_iterator'], function(require, exports, module) {
var Range = require("../range").Range;
@ -10459,7 +10459,7 @@ exports.Folding = Folding;
});
ace.define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/edit_session/fold_line', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("../range").Range;
@ -10677,7 +10677,7 @@ function FoldLine(foldData, folds) {
exports.FoldLine = FoldLine;
});
ace.define('ace/edit_session/fold', ['require', 'exports', 'module' , 'ace/range', 'ace/range_list', 'ace/lib/oop'], function(require, exports, module) {
consoleAce.define('ace/edit_session/fold', ['require', 'exports', 'module' , 'ace/range', 'ace/range_list', 'ace/lib/oop'], function(require, exports, module) {
var Range = require("../range").Range;
@ -10781,7 +10781,7 @@ function restoreRange(range, anchor) {
});
ace.define('ace/range_list', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/range_list', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("./range").Range;
var comparePoints = Range.comparePoints;
@ -10988,7 +10988,7 @@ var RangeList = function() {
exports.RangeList = RangeList;
});
ace.define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/edit_session/bracket_match', ['require', 'exports', 'module' , 'ace/token_iterator', 'ace/range'], function(require, exports, module) {
var TokenIterator = require("../token_iterator").TokenIterator;
@ -11168,7 +11168,7 @@ exports.BracketMatch = BracketMatch;
});
ace.define('ace/search', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/search', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/lib/oop', 'ace/range'], function(require, exports, module) {
var lang = require("./lib/lang");
@ -11457,7 +11457,7 @@ var Search = function() {
exports.Search = Search;
});
ace.define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/keyboard/hash_handler', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/keyboard/hash_handler', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -11557,7 +11557,7 @@ exports.CommandManager = CommandManager;
});
ace.define('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent'], function(require, exports, module) {
consoleAce.define('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'ace/lib/keys', 'ace/lib/useragent'], function(require, exports, module) {
var keyUtil = require("../lib/keys");
@ -11717,7 +11717,7 @@ function HashHandler(config, platform) {
exports.HashHandler = HashHandler;
});
ace.define('ace/commands/default_commands', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/commands/default_commands', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/config'], function(require, exports, module) {
var lang = require("../lib/lang");
@ -12261,7 +12261,7 @@ exports.commands = [{
});
ace.define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/undomanager', ['require', 'exports', 'module' ], function(require, exports, module) {
var UndoManager = function() {
this.reset();
};
@ -12328,7 +12328,7 @@ var UndoManager = function() {
exports.UndoManager = UndoManager;
});
ace.define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/useragent', 'ace/config', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/useragent', 'ace/config', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -13930,7 +13930,7 @@ config.defineOptions(VirtualRenderer.prototype, "renderer", {
exports.VirtualRenderer = VirtualRenderer;
});
ace.define('ace/layer/gutter', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/layer/gutter', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter'], function(require, exports, module) {
var dom = require("../lib/dom");
@ -14170,7 +14170,7 @@ exports.Gutter = Gutter;
});
ace.define('ace/layer/marker', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/layer/marker', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/dom'], function(require, exports, module) {
var Range = require("../range").Range;
@ -14345,7 +14345,7 @@ exports.Marker = Marker;
});
ace.define('ace/layer/text', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/layer/text', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/useragent', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -14953,7 +14953,7 @@ exports.Text = Text;
});
ace.define('ace/layer/cursor', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/layer/cursor', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
var dom = require("../lib/dom");
@ -15139,7 +15139,7 @@ exports.Cursor = Cursor;
});
ace.define('ace/scrollbar', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/scrollbar', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -15262,7 +15262,7 @@ exports.VScrollBar = VScrollBar;
exports.HScrollBar = HScrollBar;
});
ace.define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
consoleAce.define('ace/renderloop', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
var event = require("./lib/event");
@ -15299,7 +15299,7 @@ var RenderLoop = function(onRender, win) {
exports.RenderLoop = RenderLoop;
});
ace.define('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/lib/event', 'ace/lib/lang', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/lib/event', 'ace/lib/lang', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor', 'ace/config'], function(require, exports, module) {
var RangeList = require("./range_list").RangeList;
var Range = require("./range").Range;
@ -16080,7 +16080,7 @@ require("./config").defineOptions(Editor.prototype, "editor", {
});
ace.define('ace/mouse/multi_select_handler', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
consoleAce.define('ace/mouse/multi_select_handler', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
var event = require("../lib/event");
function isSamePoint(p1, p2) {
@ -16210,7 +16210,7 @@ exports.onMouseDown = onMouseDown;
});
ace.define('ace/commands/multi_select_commands', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler'], function(require, exports, module) {
consoleAce.define('ace/commands/multi_select_commands', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler'], function(require, exports, module) {
exports.defaultCommands = [{
name: "addCursorAbove",
exec: function(editor) { editor.selectMoreLines(-1); },
@ -16274,7 +16274,7 @@ exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
});
ace.define('ace/worker/worker_client', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/config'], function(require, exports, module) {
consoleAce.define('ace/worker/worker_client', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/config'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -16458,7 +16458,7 @@ exports.UIWorkerClient = UIWorkerClient;
exports.WorkerClient = WorkerClient;
});
ace.define('ace/placeholder', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/event_emitter', 'ace/lib/oop'], function(require, exports, module) {
consoleAce.define('ace/placeholder', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/event_emitter', 'ace/lib/oop'], function(require, exports, module) {
var Range = require("./range").Range;
@ -16630,7 +16630,7 @@ var PlaceHolder = function(session, length, pos, others, mainClass, othersClass)
exports.PlaceHolder = PlaceHolder;
});
ace.define('ace/mode/folding/fold_mode', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/mode/folding/fold_mode', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("../../range").Range;
@ -16719,7 +16719,7 @@ var FoldMode = exports.FoldMode = function() {};
});
ace.define('ace/theme/textmate', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/theme/textmate', ['require', 'exports', 'module' , 'ace/lib/dom'], function(require, exports, module) {
exports.isDark = false;
@ -16849,7 +16849,7 @@ var dom = require("../lib/dom");
dom.importCssString(exports.cssText, exports.cssClass);
});
ace.define('ace/ext/error_marker', ['require', 'exports', 'module' , 'ace/line_widgets', 'ace/lib/dom', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/ext/error_marker', ['require', 'exports', 'module' , 'ace/line_widgets', 'ace/lib/dom', 'ace/range'], function(require, exports, module) {
var LineWidgets = require("ace/line_widgets").LineWidgets;
var dom = require("ace/lib/dom");
@ -17030,7 +17030,7 @@ dom.importCssString("\
});
ace.define('ace/line_widgets', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/line_widgets', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/range'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -17299,12 +17299,11 @@ exports.LineWidgets = LineWidgets;
;
(function() {
ace.require(["ace/ace"], function(a) {
consoleAce.require(["ace/ace"], function(a) {
a && a.config.init();
if (!window.ace)
window.ace = {};
if (!window.consoleAce)
window.consoleAce = {};
for (var key in a) if (a.hasOwnProperty(key))
ace[key] = a[key];
consoleAce[key] = a[key];
});
})();

View file

@ -28,7 +28,7 @@
*
* ***** END LICENSE BLOCK ***** */
ace.define('ace/ext/language_tools', ['require', 'exports', 'module' , 'ace/snippets', 'ace/autocomplete', 'ace/config', 'ace/autocomplete/text_completer', 'ace/editor'], function(require, exports, module) {
consoleAce.define('ace/ext/language_tools', ['require', 'exports', 'module' , 'ace/snippets', 'ace/autocomplete', 'ace/config', 'ace/autocomplete/text_completer', 'ace/editor'], function(require, exports, module) {
var snippetManager = require("../snippets").snippetManager;
@ -144,7 +144,7 @@ require("../config").defineOptions(Editor.prototype, "editor", {
});
ace.define('ace/snippets', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/range', 'ace/keyboard/hash_handler', 'ace/tokenizer', 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/snippets', ['require', 'exports', 'module' , 'ace/lib/lang', 'ace/range', 'ace/keyboard/hash_handler', 'ace/tokenizer', 'ace/lib/dom'], function(require, exports, module) {
var lang = require("./lib/lang")
var Range = require("./range").Range
@ -959,7 +959,7 @@ exports.snippetManager = new SnippetManager();
});
ace.define('ace/autocomplete', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler', 'ace/autocomplete/popup', 'ace/autocomplete/util', 'ace/lib/event', 'ace/lib/lang', 'ace/snippets'], function(require, exports, module) {
consoleAce.define('ace/autocomplete', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler', 'ace/autocomplete/popup', 'ace/autocomplete/util', 'ace/lib/event', 'ace/lib/lang', 'ace/snippets'], function(require, exports, module) {
var HashHandler = require("./keyboard/hash_handler").HashHandler;
@ -1276,7 +1276,7 @@ exports.FilteredList = FilteredList;
});
ace.define('ace/autocomplete/popup', ['require', 'exports', 'module' , 'ace/edit_session', 'ace/virtual_renderer', 'ace/editor', 'ace/range', 'ace/lib/event', 'ace/lib/lang', 'ace/lib/dom'], function(require, exports, module) {
consoleAce.define('ace/autocomplete/popup', ['require', 'exports', 'module' , 'ace/edit_session', 'ace/virtual_renderer', 'ace/editor', 'ace/range', 'ace/lib/event', 'ace/lib/lang', 'ace/lib/dom'], function(require, exports, module) {
var EditSession = require("../edit_session").EditSession;
@ -1575,7 +1575,7 @@ exports.AcePopup = AcePopup;
});
ace.define('ace/autocomplete/util', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/autocomplete/util', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.parForEach = function(array, fn, callback) {
@ -1620,7 +1620,7 @@ exports.retrieveFollowingIdentifier = function(text, pos, regex) {
});
ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/autocomplete/text_completer', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("ace/range").Range;
var splitRegex = /[^a-zA-Z_0-9\$\-]+/;
@ -1662,4 +1662,4 @@ ace.define('ace/autocomplete/text_completer', ['require', 'exports', 'module' ,
};
}));
};
});
});

View file

@ -28,7 +28,7 @@
*
* ***** END LICENSE BLOCK ***** */
ace.define('ace/ext/searchbox', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/event', 'ace/keyboard/hash_handler', 'ace/lib/keys'], function(require, exports, module) {
consoleAce.define('ace/ext/searchbox', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/event', 'ace/keyboard/hash_handler', 'ace/lib/keys'], function(require, exports, module) {
var dom = require("../lib/dom");

View file

@ -28,7 +28,7 @@
*
* ***** END LICENSE BLOCK ***** */
ace.define('ace/mode/json', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/json_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle', 'ace/worker/worker_client'], function(require, exports, module) {
consoleAce.define('ace/mode/json', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/json_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/mode/behaviour/cstyle', 'ace/mode/folding/cstyle', 'ace/worker/worker_client'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -93,7 +93,7 @@ oop.inherits(Mode, TextMode);
exports.Mode = Mode;
});
ace.define('ace/mode/json_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
consoleAce.define('ace/mode/json_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -161,7 +161,7 @@ oop.inherits(JsonHighlightRules, TextHighlightRules);
exports.JsonHighlightRules = JsonHighlightRules;
});
ace.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("../range").Range;
@ -201,7 +201,7 @@ var MatchingBraceOutdent = function() {};
exports.MatchingBraceOutdent = MatchingBraceOutdent;
});
ace.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) {
consoleAce.define('ace/mode/behaviour/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/behaviour', 'ace/token_iterator', 'ace/lib/lang'], function(require, exports, module) {
var oop = require("../../lib/oop");
@ -529,7 +529,7 @@ oop.inherits(CstyleBehaviour, Behaviour);
exports.CstyleBehaviour = CstyleBehaviour;
});
ace.define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) {
consoleAce.define('ace/mode/folding/cstyle', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/range', 'ace/mode/folding/fold_mode'], function(require, exports, module) {
var oop = require("../../lib/oop");

View file

@ -28,7 +28,7 @@
*
* ***** END LICENSE BLOCK ***** */
ace.define('ace/mode/yaml', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/yaml_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/mode/folding/coffee'], function(require, exports, module) {
consoleAce.define('ace/mode/yaml', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text', 'ace/tokenizer', 'ace/mode/yaml_highlight_rules', 'ace/mode/matching_brace_outdent', 'ace/mode/folding/coffee'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -78,7 +78,7 @@ exports.Mode = Mode;
});
ace.define('ace/mode/yaml_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
consoleAce.define('ace/mode/yaml_highlight_rules', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -162,7 +162,7 @@ oop.inherits(YamlHighlightRules, TextHighlightRules);
exports.YamlHighlightRules = YamlHighlightRules;
});
ace.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/mode/matching_brace_outdent', ['require', 'exports', 'module' , 'ace/range'], function(require, exports, module) {
var Range = require("../range").Range;
@ -202,7 +202,7 @@ var MatchingBraceOutdent = function() {};
exports.MatchingBraceOutdent = MatchingBraceOutdent;
});
ace.define('ace/mode/folding/coffee', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/folding/fold_mode', 'ace/range'], function(require, exports, module) {
consoleAce.define('ace/mode/folding/coffee', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/mode/folding/fold_mode', 'ace/range'], function(require, exports, module) {
var oop = require("../../lib/oop");

View file

@ -173,7 +173,7 @@ window.onmessage = function(e) {
};
})(this);// https://github.com/kriskowal/es5-shim
ace.define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/es5-shim', ['require', 'exports', 'module' ], function(require, exports, module) {
function Empty() {}
@ -870,7 +870,7 @@ var toObject = function (o) {
});
ace.define('ace/mode/json_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/json/json_parse'], function(require, exports, module) {
consoleAce.define('ace/mode/json_worker', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/worker/mirror', 'ace/mode/json/json_parse'], function(require, exports, module) {
var oop = require("../lib/oop");
@ -908,7 +908,7 @@ oop.inherits(JsonWorker, Mirror);
});
ace.define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/oop', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.inherits = function(ctor, superCtor) {
@ -935,7 +935,7 @@ exports.implement = function(proto, mixin) {
};
});
ace.define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
consoleAce.define('ace/worker/mirror', ['require', 'exports', 'module' , 'ace/document', 'ace/lib/lang'], function(require, exports, module) {
var Document = require("../document").Document;
@ -984,7 +984,7 @@ var Mirror = exports.Mirror = function(sender) {
});
ace.define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
consoleAce.define('ace/document', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/range', 'ace/anchor'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -1340,7 +1340,7 @@ var Document = function(text) {
exports.Document = Document;
});
ace.define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/event_emitter', ['require', 'exports', 'module' ], function(require, exports, module) {
var EventEmitter = {};
@ -1466,7 +1466,7 @@ exports.EventEmitter = EventEmitter;
});
ace.define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/range', ['require', 'exports', 'module' ], function(require, exports, module) {
var comparePoints = function(p1, p2) {
return p1.row - p2.row || p1.column - p2.column;
@ -1705,7 +1705,7 @@ Range.comparePoints = function(p1, p2) {
exports.Range = Range;
});
ace.define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
consoleAce.define('ace/anchor', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter'], function(require, exports, module) {
var oop = require("./lib/oop");
@ -1852,7 +1852,7 @@ var Anchor = exports.Anchor = function(doc, row, column) {
});
ace.define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/lib/lang', ['require', 'exports', 'module' ], function(require, exports, module) {
exports.stringReverse = function(string) {
@ -2035,7 +2035,7 @@ exports.delayedCall = function(fcn, defaultTimeout) {
};
});
ace.define('ace/mode/json/json_parse', ['require', 'exports', 'module' ], function(require, exports, module) {
consoleAce.define('ace/mode/json/json_parse', ['require', 'exports', 'module' ], function(require, exports, module) {
var at, // The index of the current character
ch, // The current character

View file

@ -33,7 +33,6 @@ module.exports = function ({ Plugin }) {
key: string()
}).default(),
apiVersion: Joi.string().default('master'),
engineVersion: Joi.string().valid('^5.0.0').default('^5.0.0')
}).default();
},

View file

@ -8,17 +8,20 @@ import SetupError from '../setup_error';
import serverConfig from '../../../../../test/server_config';
import checkEsVersion from '../check_es_version';
describe('plugins/elasticsearch', function () {
describe('lib/check_es_version', function () {
describe('plugins/elasticsearch', () => {
describe('lib/check_es_version', () => {
const KIBANA_VERSION = '5.1.0';
let server;
let plugin;
beforeEach(function () {
const get = sinon.stub().withArgs('elasticsearch.engineVersion').returns('^1.4.3');
const config = function () { return { get: get }; };
server = {
log: _.noop,
config: config,
// This is required or else we get a SetupError.
config: () => ({
get: sinon.stub(),
}),
plugins: {
elasticsearch: {
client: {
@ -44,7 +47,9 @@ describe('plugins/elasticsearch', function () {
const node = {
version: version,
http_address: 'http_address',
http: {
publish_address: 'http_address',
},
ip: 'ip'
};
@ -54,40 +59,41 @@ describe('plugins/elasticsearch', function () {
const client = server.plugins.elasticsearch.client;
client.nodes.info = sinon.stub().returns(Promise.resolve({ nodes: nodes }));
}
it('passes with single a node that matches', function () {
setNodes('1.4.3');
return checkEsVersion(server);
it('returns true with single a node that matches', async () => {
setNodes('5.1.0');
const result = await checkEsVersion(server, KIBANA_VERSION);
expect(result).to.be(true);
});
it('passes with multiple nodes that satisfy', function () {
setNodes('1.4.3', '1.4.4', '1.4.3-Beta1');
return checkEsVersion(server);
it('returns true with multiple nodes that satisfy', async () => {
setNodes('5.1.0', '5.2.0', '5.1.1-Beta1');
const result = await checkEsVersion(server, KIBANA_VERSION);
expect(result).to.be(true);
});
it('fails with a single node that is out of date', function () {
setNodes('1.4.4', '1.4.2', '1.4.5');
checkEsVersion(server)
.catch(function (e) {
it('throws an error with a single node that is out of date', async () => {
// 5.0.0 ES is too old to work with a 5.1.0 version of Kibana.
setNodes('5.1.0', '5.2.0', '5.0.0');
try {
await checkEsVersion(server, KIBANA_VERSION);
} catch (e) {
expect(e).to.be.a(SetupError);
});
}
});
it('fails if that single node is a client node', function () {
it('fails if that single node is a client node', async () => {
setNodes(
'1.4.4',
{ version: '1.4.2', attributes: { client: 'true' } },
'1.4.5'
'5.1.0',
'5.2.0',
{ version: '5.0.0', attributes: { client: 'true' } },
);
checkEsVersion(server)
.catch(function (e) {
try {
await checkEsVersion(server, KIBANA_VERSION);
} catch (e) {
expect(e).to.be.a(SetupError);
});
}
});
});
});

View file

@ -6,22 +6,24 @@ import url from 'url';
const NoConnections = require('elasticsearch').errors.NoConnections;
import healthCheck from '../health_check';
import kibanaVersion from '../kibana_version';
import serverConfig from '../../../../../test/server_config';
const esPort = serverConfig.servers.elasticsearch.port;
const esUrl = url.format(serverConfig.servers.elasticsearch);
describe('plugins/elasticsearch', function () {
describe('lib/health_check', function () {
describe('plugins/elasticsearch', () => {
describe('lib/health_check', () => {
let health;
let plugin;
let server;
let get;
let set;
let client;
beforeEach(function () {
beforeEach(() => {
const COMPATIBLE_VERSION_NUMBER = '5.0.0';
// Stub the Kibana version instead of drawing from package.json.
sinon.stub(kibanaVersion, 'get').returns(COMPATIBLE_VERSION_NUMBER);
// setup the plugin stub
plugin = {
name: 'elasticsearch',
@ -31,9 +33,7 @@ describe('plugins/elasticsearch', function () {
yellow: sinon.stub()
}
};
// setup the config().get()/.set() stubs
get = sinon.stub();
set = sinon.stub();
// set up the elasticsearch client stub
client = {
cluster: { health: sinon.stub() },
@ -45,17 +45,26 @@ describe('plugins/elasticsearch', function () {
get: sinon.stub().returns(Promise.resolve({ found: false })),
search: sinon.stub().returns(Promise.resolve({ hits: { hits: [] } })),
};
client.nodes.info.returns(Promise.resolve({
nodes: {
'node-01': {
version: '1.5.0',
version: COMPATIBLE_VERSION_NUMBER,
http_address: `inet[/127.0.0.1:${esPort}]`,
ip: '127.0.0.1'
}
}
}));
// setup the config().get()/.set() stubs
const get = sinon.stub();
get.withArgs('elasticsearch.url').returns(esUrl);
get.withArgs('kibana.index').returns('.my-kibana');
const set = sinon.stub();
// Setup the server mock
server = {
const server = {
log: sinon.stub(),
info: { port: 5601 },
config: function () { return { get, set }; },
@ -65,9 +74,11 @@ describe('plugins/elasticsearch', function () {
health = healthCheck(plugin, server);
});
afterEach(() => {
kibanaVersion.get.restore();
});
it('should set the cluster green if everything is ready', function () {
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
get.withArgs('kibana.index').returns('.my-kibana');
client.ping.returns(Promise.resolve());
client.cluster.health.returns(Promise.resolve({ timed_out: false, status: 'green' }));
return health.run()
@ -83,10 +94,6 @@ describe('plugins/elasticsearch', function () {
});
it('should set the cluster red if the ping fails, then to green', function () {
get.withArgs('elasticsearch.url').returns(esUrl);
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
get.withArgs('kibana.index').returns('.my-kibana');
client.ping.onCall(0).returns(Promise.reject(new NoConnections()));
client.ping.onCall(1).returns(Promise.resolve());
client.cluster.health.returns(Promise.resolve({ timed_out: false, status: 'green' }));
@ -104,13 +111,9 @@ describe('plugins/elasticsearch', function () {
sinon.assert.calledOnce(plugin.status.green);
expect(plugin.status.green.args[0][0]).to.be('Kibana index ready');
});
});
it('should set the cluster red if the health check status is red, then to green', function () {
get.withArgs('elasticsearch.url').returns(esUrl);
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
get.withArgs('kibana.index').returns('.my-kibana');
client.ping.returns(Promise.resolve());
client.cluster.health.onCall(0).returns(Promise.resolve({ timed_out: false, status: 'red' }));
client.cluster.health.onCall(1).returns(Promise.resolve({ timed_out: false, status: 'green' }));
@ -131,9 +134,6 @@ describe('plugins/elasticsearch', function () {
});
it('should set the cluster yellow if the health check timed_out and create index', function () {
get.withArgs('elasticsearch.url').returns(esUrl);
get.withArgs('elasticsearch.engineVersion').returns('^1.4.4');
get.withArgs('kibana.index').returns('.my-kibana');
client.ping.returns(Promise.resolve());
client.cluster.health.onCall(0).returns(Promise.resolve({ timed_out: true, status: 'red' }));
client.cluster.health.onCall(1).returns(Promise.resolve({ timed_out: false, status: 'green' }));

View file

@ -0,0 +1,40 @@
import expect from 'expect.js';
import sinon from 'sinon';
import isEsCompatibleWithKibana from '../is_es_compatible_with_kibana';
describe('plugins/elasticsearch', () => {
describe('lib/is_es_compatible_with_kibana', () => {
describe('returns false', () => {
it('when ES major is greater than Kibana major', () => {
expect(isEsCompatibleWithKibana('1.0.0', '0.0.0')).to.be(false);
});
it('when ES major is less than Kibana major', () => {
expect(isEsCompatibleWithKibana('0.0.0', '1.0.0')).to.be(false);
});
it('when majors are equal, but ES minor is less than Kibana minor', () => {
expect(isEsCompatibleWithKibana('1.0.0', '1.1.0')).to.be(false);
});
it('when majors and minors are equal, but ES patch is less than Kibana patch', () => {
expect(isEsCompatibleWithKibana('1.1.0', '1.1.1')).to.be(false);
});
});
describe('returns true', () => {
it('when version numbers are the same', () => {
expect(isEsCompatibleWithKibana('1.1.1', '1.1.1')).to.be(true);
});
it('when majors are equal, and ES minor is greater than Kibana minor', () => {
expect(isEsCompatibleWithKibana('1.1.0', '1.0.0')).to.be(true);
});
it('when majors and minors are equal, and ES patch is greater than Kibana patch', () => {
expect(isEsCompatibleWithKibana('1.1.1', '1.1.0')).to.be(true);
});
});
});
});

View file

@ -6,29 +6,30 @@ import fromRoot from '../../../../utils/from_root';
describe('plugins/elasticsearch', function () {
describe('routes', function () {
let kbnServer;
before(function () {
this.timeout(60000); // sometimes waiting for server takes longer than 10
before(async function () {
// Sometimes waiting for server takes longer than 10s.
// NOTE: This can't be a fat-arrow function because `this` needs to refer to the execution
// context, not to the parent context.
this.timeout(60000);
kbnServer = kbnTestServer.createServer({
plugins: {
scanDirs: [
fromRoot('src/core_plugins')
]
}
},
});
return kbnServer.ready()
.then(() => kbnServer.server.plugins.elasticsearch.waitUntilReady());
});
await kbnServer.ready();
await kbnServer.server.plugins.elasticsearch.waitUntilReady();
});
after(function () {
return kbnServer.close();
});
function testRoute(options) {
if (typeof options.payload === 'object') {
options.payload = JSON.stringify(options.payload);
@ -49,7 +50,6 @@ describe('plugins/elasticsearch', function () {
});
}
testRoute({
method: 'GET',
url: '/elasticsearch/_nodes'

View file

@ -1,45 +0,0 @@
import versionSatisfies from '../version_satisfies';
import expect from 'expect.js';
const versionChecks = [
// order is: ['actual version', 'match expression', satisfied (true/false)]
['0.90.0', '>=0.90.0', true],
['1.2.0', '>=1.2.1 <2.0.0', false],
['1.2.1', '>=1.2.1 <2.0.0', true],
['1.4.4', '>=1.2.1 <2.0.0', true],
['1.7.4', '>=1.3.1 <2.0.0', true],
['2.0.0', '>=1.3.1 <2.0.0', false],
['1.4.3', '^1.4.3', true],
['1.4.3-Beta1', '^1.4.3', true],
['1.4.4', '^1.4.3', true],
['1.1.12', '^1.0.0', true],
['1.1.12', '~1.0.0', false],
['1.6.1-SNAPSHOT', '1.6.1', true],
['1.6.1-SNAPSHOT', '1.6.2', false],
['1.7.1-SNAPSHOT', '^1.3.1', true],
['1.3.4', '^1.4.0', false],
['2.0.1', '^2.0.0', true],
['2.1.1', '^2.1.0', true],
['2.2.0', '^2.1.0', true],
['3.0.0-SNAPSHOT', '^2.1.0', false],
['3.0.0', '^2.1.0', false],
['2.10.20-SNAPSHOT', '^2.10.20', true],
['2.10.999', '^2.10.20', true],
];
describe('plugins/elasticsearch', function () {
describe('lib/version_satisfies', function () {
versionChecks.forEach(function (spec) {
const actual = spec[0];
const match = spec[1];
const satisfied = spec[2];
const desc = actual + ' satisfies ' + match;
describe(desc, function () {
it('should be ' + satisfied, function () {
expect(versionSatisfies(actual, match)).to.be(satisfied);
});
});
});
});
});

View file

@ -1,31 +1,78 @@
/**
* ES and Kibana versions are locked, so Kibana should require that ES has the same version as
* that defined in Kibana's package.json.
*/
import _ from 'lodash';
import esBool from './es_bool';
import versionSatisfies from './version_satisfies';
import semver from 'semver';
import isEsCompatibleWithKibana from './is_es_compatible_with_kibana';
import SetupError from './setup_error';
module.exports = function (server) {
module.exports = function checkEsVersion(server, kibanaVersion) {
server.log(['plugin', 'debug'], 'Checking Elasticsearch version');
const client = server.plugins.elasticsearch.client;
const engineVersion = server.config().get('elasticsearch.engineVersion');
return client.nodes.info()
.then(function (info) {
const badNodes = _.filter(info.nodes, function (node) {
// remove nodes that satify required engine version
return !versionSatisfies(node.version, engineVersion);
// Aggregate incompatible ES nodes.
const incompatibleNodes = [];
// Aggregate ES nodes which should prompt a Kibana upgrade.
const warningNodes = [];
_.forEach(info.nodes, esNode => {
if (!isEsCompatibleWithKibana(esNode.version, kibanaVersion)) {
// Exit early to avoid collecting ES nodes with newer major versions in the `warningNodes`.
return incompatibleNodes.push(esNode);
}
// It's acceptable if ES is ahead of Kibana, but we want to prompt users to upgrade Kibana
// to match it.
if (semver.gt(esNode.version, kibanaVersion)) {
warningNodes.push(esNode);
}
});
if (!badNodes.length) return true;
function getHumanizedNodeNames(nodes) {
return nodes.map(node => {
return 'v' + node.version + ' @ ' + node.http.publish_address + ' (' + node.ip + ')';
});
}
const badNodeNames = badNodes.map(function (node) {
return 'Elasticsearch v' + node.version + ' @ ' + node.http_address + ' (' + node.ip + ')';
});
if (warningNodes.length) {
const simplifiedNodes = warningNodes.map(node => ({
version: node.version,
http: {
publish_address: node.http.publish_address,
},
ip: node.ip,
}));
const message = `This version of Kibana requires Elasticsearch ` +
`${engineVersion} on all nodes. I found ` +
`the following incompatible nodes in your cluster: ${badNodeNames.join(',')}`;
server.log(['warning'], {
tmpl: (
'You\'re running Kibana <%= kibanaVersion %> with some newer versions of ' +
'Elasticsearch. Update Kibana to the latest version to prevent compatibility issues: ' +
'<%= getHumanizedNodeNames(nodes).join(", ") %>'
),
kibanaVersion,
getHumanizedNodeNames,
nodes: simplifiedNodes,
});
}
throw new SetupError(server, message);
if (incompatibleNodes.length) {
const incompatibleNodeNames = getHumanizedNodeNames(incompatibleNodes);
const errorMessage =
`This version of Kibana requires Elasticsearch v` +
`${kibanaVersion} on all nodes. I found ` +
`the following incompatible nodes in your cluster: ${incompatibleNodeNames.join(',')}`;
throw new SetupError(server, errorMessage);
}
return true;
});
};

View file

@ -5,6 +5,8 @@ import exposeClient from './expose_client';
import migrateConfig from './migrate_config';
import createKibanaIndex from './create_kibana_index';
import checkEsVersion from './check_es_version';
import kibanaVersion from './kibana_version';
const NoConnections = elasticsearch.errors.NoConnections;
import util from 'util';
const format = util.format;
@ -85,7 +87,7 @@ module.exports = function (plugin, server) {
function check() {
return waitForPong()
.then(_.partial(checkEsVersion, server))
.then(() => checkEsVersion(server, kibanaVersion.get()))
.then(waitForShards)
.then(setGreenStatus)
.then(_.partial(migrateConfig, server))

View file

@ -0,0 +1,38 @@
/**
* Let's weed out the ES versions that won't work with a given Kibana version.
* 1. Major version differences will never work together.
* 2. Older versions of ES won't work with newer versions of Kibana.
*/
import semver from 'semver';
export default function isEsCompatibleWithKibana(esVersion, kibanaVersion) {
const esVersionNumbers = {
major: semver.major(esVersion),
minor: semver.minor(esVersion),
patch: semver.patch(esVersion),
};
const kibanaVersionNumbers = {
major: semver.major(kibanaVersion),
minor: semver.minor(kibanaVersion),
patch: semver.patch(kibanaVersion),
};
// Reject mismatching major version numbers.
if (esVersionNumbers.major !== kibanaVersionNumbers.major) {
return false;
}
// Reject older minor versions of ES.
if (esVersionNumbers.minor < kibanaVersionNumbers.minor) {
return false;
}
// Reject older patch versions of ES.
if (esVersionNumbers.patch < kibanaVersionNumbers.patch) {
return false;
}
return true;
}

View file

@ -0,0 +1,10 @@
import {
version as kibanaVersion,
} from '../../../../package.json';
export default {
// Make the version stubbable to improve testability.
get() {
return kibanaVersion;
},
};

View file

@ -1,16 +0,0 @@
import semver from 'semver';
module.exports = function (actual, expected) {
try {
const ver = cleanVersion(actual);
return semver.satisfies(ver, expected);
} catch (err) {
return false;
}
function cleanVersion(version) {
const match = version.match(/\d+\.\d+\.\d+/);
if (!match) return version;
return match[0];
}
};

View file

@ -14,10 +14,13 @@ module.exports = function (kibana) {
return new kibana.Plugin({
id: 'kibana',
config: function (Joi) {
const ONE_GIGABYTE = 1024 * 1024 * 1024;
return Joi.object({
enabled: Joi.boolean().default(true),
defaultAppId: Joi.string().default('discover'),
index: Joi.string().default('.kibana')
index: Joi.string().default('.kibana'),
addDataMaxBytes: Joi.number().default(ONE_GIGABYTE)
}).default();
},
@ -34,6 +37,7 @@ module.exports = function (kibana) {
'fieldFormats',
'navbarExtensions',
'managementSections',
'devTools',
'docViews'
],
@ -41,7 +45,8 @@ module.exports = function (kibana) {
let config = server.config();
return {
kbnDefaultAppId: config.get('kibana.defaultAppId'),
tilemap: config.get('tilemap')
tilemap: config.get('tilemap'),
addDataMaxBytes: config.get('kibana.addDataMaxBytes')
};
},
},
@ -79,6 +84,13 @@ module.exports = function (kibana) {
description: 'define index patterns, change config, and more',
icon: 'plugins/kibana/assets/settings.svg',
linkToLastSubUrl: false
},
{
title: 'Dev Tools',
order: 1010,
url: '/app/kibana#/dev_tools',
description: 'development tools',
icon: 'plugins/kibana/assets/wrench.svg'
}
],
injectDefaultVars(server, options) {

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M4 0c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm0 1c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm0 1c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5zm-1.66 1a.5.5 0 0 0-.19.84l.91.91c-.02.08-.06.16-.06.25 0 .55.45 1 1 1s1-.45 1-1-.45-1-1-1c-.09 0-.17.04-.25.06l-.91-.91a.5.5 0 0 0-.44-.16.5.5 0 0 0-.06 0zm3.16 0c-.28 0-.5.22-.5.5s.22.5.5.5.5-.22.5-.5-.22-.5-.5-.5z"
/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 486 B

After

Width:  |  Height:  |  Size: 500 B

Before After
Before After

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M4 0c-2.2 0-4 1.8-4 4s1.8 4 4 4 4-1.8 4-4-1.8-4-4-4zm0 1c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3 1.34-3 3-3zm2 1l-3 1-1 3 3-1 1-3zm-2 1.5c.28 0 .5.22.5.5s-.22.5-.5.5-.5-.22-.5-.5.22-.5.5-.5z" />
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 293 B

After

Width:  |  Height:  |  Size: 307 B

Before After
Before After

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M3 0v1h4v5h-4v1h5v-7h-5zm-1 2l-2 1.5 2 1.5v-1h4v-1h-4v-1z" />
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 159 B

After

Width:  |  Height:  |  Size: 173 B

Before After
Before After

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M4 0c-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm-1 2l3 2-3 2v-4z" />
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 176 B

After

Width:  |  Height:  |  Size: 190 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M3.5 0c-1.93 0-3.5 1.57-3.5 3.5s1.57 3.5 3.5 3.5c.59 0 1.17-.14 1.66-.41a1 1 0 0 0 .13.13l1 1a1.02 1.02 0 1 0 1.44-1.44l-1-1a1 1 0 0 0-.16-.13c.27-.49.44-1.06.44-1.66 0-1.93-1.57-3.5-3.5-3.5zm0 1c1.39 0 2.5 1.11 2.5 2.5 0 .66-.24 1.27-.66 1.72-.01.01-.02.02-.03.03a1 1 0 0 0-.13.13c-.44.4-1.04.63-1.69.63-1.39 0-2.5-1.11-2.5-2.5s1.11-2.5 2.5-2.5z"
/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 450 B

After

Width:  |  Height:  |  Size: 464 B

Before After
Before After

View file

@ -1,4 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M3.5 0l-.5 1.19c-.1.03-.19.08-.28.13l-1.19-.5-.72.72.5 1.19c-.05.1-.09.18-.13.28l-1.19.5v1l1.19.5c.04.1.08.18.13.28l-.5 1.19.72.72 1.19-.5c.09.04.18.09.28.13l.5 1.19h1l.5-1.19c.09-.04.19-.08.28-.13l1.19.5.72-.72-.5-1.19c.04-.09.09-.19.13-.28l1.19-.5v-1l-1.19-.5c-.03-.09-.08-.19-.13-.28l.5-1.19-.72-.72-1.19.5c-.09-.04-.19-.09-.28-.13l-.5-1.19h-1zm.5 2.5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5-1.5-.67-1.5-1.5.67-1.5 1.5-1.5z"
/>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 528 B

After

Width:  |  Height:  |  Size: 542 B

Before After
Before After

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8">
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M0 0v7h8v-1h-7v-6h-1zm5 0v5h2v-5h-2zm-3 2v3h2v-3h-2z" />
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 168 B

Before After
Before After

View file

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="8" viewBox="0 0 8 8" fill="white">
<path d="M5.5 0c-1.38 0-2.5 1.12-2.5 2.5 0 .32.08.62.19.91l-2.91 2.88c-.39.39-.39 1.05 0 1.44.2.2.46.28.72.28.26 0 .52-.09.72-.28l2.88-2.91c.28.11.58.19.91.19 1.38 0 2.5-1.12 2.5-2.5 0-.16 0-.32-.03-.47l-.97.97h-2v-2l.97-.97c-.15-.03-.31-.03-.47-.03zm-4.5 6.5c.28 0 .5.22.5.5s-.22.5-.5.5-.5-.22-.5-.5.22-.5.5-.5z"
/>
</svg>

After

Width:  |  Height:  |  Size: 421 B

View file

@ -0,0 +1,19 @@
import uiModules from 'ui/modules';
import devTools from 'ui/registry/dev_tools';
import template from 'plugins/kibana/dev_tools/partials/dev_tools_app.html';
import 'plugins/kibana/dev_tools/styles/dev_tools_app.less';
uiModules
.get('apps/dev_tools')
.directive('kbnDevToolsApp', function (Private, $location) {
return {
restrict: 'E',
replace: true,
template,
transclude: true,
link: function ($scope) {
$scope.devTools = Private(devTools).inOrder;
$scope.currentPath = `#${$location.path()}`;
}
};
});

View file

@ -0,0 +1,13 @@
import uiRoutes from 'ui/routes';
import devTools from 'ui/registry/dev_tools';
import 'plugins/kibana/dev_tools/directives/dev_tools_app';
uiRoutes
.when('/dev_tools', {
resolve: {
redirect(Private, kbnUrl) {
const items = Private(devTools).inOrder;
kbnUrl.redirect(items[0].url.substring(1));
}
}
});

View file

@ -0,0 +1,15 @@
<div class="dev-tools-app-container app-container">
<nav class="navbar navbar-default navbar-static-top subnav">
<bread-crumbs omit-current-page="true"></bread-crumbs>
<ul class="nav navbar-nav">
<li ng-repeat="item in devTools" ng-class="{active: currentPath === item.url}">
<a class="navbar-link" kbn-href="{{::item.url}}">
{{::item.display}}
</a>
</li>
</ul>
</nav>
<div role="main" class="dev-tools-container" ng-transclude></div>
</div>

View file

@ -0,0 +1,9 @@
@import (reference) "~ui/styles/mixins.less";
.dev-tools-app-container {
.flex-parent;
}
.dev-tools-container {
.flex-parent;
}

View file

@ -13,6 +13,7 @@ import 'plugins/kibana/visualize/index';
import 'plugins/kibana/dashboard/index';
import 'plugins/kibana/management/index';
import 'plugins/kibana/doc';
import 'plugins/kibana/dev_tools';
import 'ui/vislib';
import 'ui/agg_response';
import 'ui/agg_types';

View file

@ -9,7 +9,7 @@
<button class="btn btn-primary btn-lg controls upload" ng-click>
Select File
</button>
<div>Maximum upload file size: 1 GB</div>
<div>Maximum upload file size: {{ wizard.maxBytesFormatted }}</div>
</div>
</file-upload>

View file

@ -4,9 +4,10 @@ import modules from 'ui/modules';
import validateHeaders from './lib/validate_headers';
import template from './parse_csv_step.html';
import './styles/_add_data_parse_csv_step.less';
import numeral from '@spalger/numeral';
modules.get('apps/management')
.directive('parseCsvStep', function () {
.directive('parseCsvStep', function (addDataMaxBytes) {
return {
restrict: 'E',
template: template,
@ -21,6 +22,8 @@ modules.get('apps/management')
const maxSampleRows = 10;
const maxSampleColumns = 20;
this.maxBytesFormatted = numeral(addDataMaxBytes).format('0 b');
this.delimiterOptions = [
{
label: 'comma',
@ -55,6 +58,13 @@ modules.get('apps/management')
this.formattedErrors = [];
this.formattedWarnings = [];
if (this.file.size > addDataMaxBytes) {
this.formattedErrors.push(
`File size (${this.file.size} bytes) is greater than the configured limit of ${addDataMaxBytes} bytes`
);
return;
}
const config = _.assign(
{
header: true,

View file

@ -386,9 +386,3 @@ vis-editor-vis-options > * {
background-color: darken(@vis-editor-navbar-error-state-bg, 12%) !important; /* 1 */
}
}
form.vis-share {
div.form-control {
height: inherit;
}
}

View file

@ -6,16 +6,16 @@ import { patternToIngest } from '../../../../common/lib/convert_pattern_and_inge
import { PassThrough } from 'stream';
import JSONStream from 'JSONStream';
const ONE_GIGABYTE = 1024 * 1024 * 1024;
export function registerData(server) {
const maxBytes = server.config().get('kibana.addDataMaxBytes');
server.route({
path: '/api/kibana/{id}/_data',
method: 'POST',
config: {
payload: {
output: 'stream',
maxBytes: ONE_GIGABYTE
maxBytes
}
},
handler: function (req, reply) {

View file

@ -87,9 +87,9 @@
inkscape:groupmode="layer"
id="Template"
inkscape:label="Layer 1"
style="fill:none;stroke:#000000;stroke-width:0.35433071px">
style="fill:none;stroke:#ffffff;stroke-width:0.35433071px">
<path
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.40064034px"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.40064034px"
d="m 212.51556,43.816204 c -9.94498,-0.10448 -19.76629,0.48399 -29.2095,1.7876 -20.46985,2.82579 -44.80699,10.19267 -63.24889,19.14519 l -4.40117,2.1364 -6.10156,-1.45334 c -9.20676,-2.19337 -20.126509,-3.40347 -34.109639,-3.78106 -24.50715,-0.66175 -46.57065,2.51896 -60.56992,8.73208 l -5.9513901,2.64021 -1.93292,6.24447 c -1.06277,3.43372 -2.4151,8.63049 -3.00598,11.54913 -1.53125,7.56139 -2.05401,22.687276 -1.0682,30.902626 1.65858,13.82185 6.7527,29.78901 13.1066101,41.06865 l 3.20218,5.68496 -2.17516,6.27838 c -6.02018,17.37428 -8.0762301,29.39951 -8.0684001,47.17021 0,15.17828 1.2843301,23.63498 5.5904801,36.97997 12.82745,39.75098 49.84408,72.52427 101.466619,89.83514 5.80702,1.94729 6.68198,2.47716 11.54186,7.0099 6.66504,6.21636 14.39167,11.3493 23.05222,15.31566 9.78729,4.48231 16.27558,6.2191 29.79809,7.9691 20.28599,2.62519 35.75405,3.02196 53.96213,1.38551 10.00303,-0.89906 22.3711,-2.84396 27.60841,-4.34061 12.30523,-3.51643 24.69915,-10.50496 34.98405,-19.72652 7.02577,-6.29943 7.51497,-6.60945 14.28867,-9.0155 47.51848,-16.87912 81.2963,-46.48266 95.69689,-83.87405 6.04823,-15.70401 8.67135,-34.47172 7.17944,-51.3631 -1.01092,-11.44237 -3.54478,-23.93594 -6.7943,-33.49439 -1.35294,-3.97957 -2.45855,-7.52644 -2.45855,-7.88189 0,-0.35549 1.88245,-4.08107 4.18315,-8.27913 14.6159,-26.67106 17.6998,-57.67627 8.47534,-85.211126 l -1.51872,-4.53195 -4.69426,-2.10492 c -21.65103,-9.70728 -66.27117,-12.03073 -96.50835,-5.02609 l -6.55693,1.51872 -12.08444,-5.25862 c -6.64658,-2.89168 -15.19046,-6.27668 -18.98775,-7.5234 -20.33766,-6.6772 -42.81112,-10.25834 -64.69011,-10.48821 z M 114.9584,120.1596 c 0.89827,0 32.56973,11.89177 33.22312,12.4744 1.08465,0.96712 -1.52492,5.9751 -4.57314,8.7757 -1.55336,1.42707 -4.13505,3.09699 -5.73581,3.70841 -15.64828,5.97722 -31.56691,-8.02023 -24.881,-21.87746 0.8177,-1.69469 1.70241,-3.08105 1.96683,-3.08105 z m 184.42024,0.62977 c 0.10351,0.009 0.1807,0.0276 0.22527,0.0606 1.25451,0.92826 3.06168,6.41925 3.06168,9.30132 0,5.85906 -4.47397,11.95187 -10.69651,14.56961 -7.49256,3.15191 -14.37348,2.33937 -20.76566,-2.45612 -2.33787,-1.75398 -5.64618,-6.93055 -5.64618,-8.81687 0.005,-1.53511 30.61194,-12.90841 33.8214,-12.6585 z m -88.55862,28.93337 c 14.37063,-0.027 28.75317,2.4358 36.61178,7.55488 10.61987,6.91764 7.19471,20.25668 -8.13622,31.68501 -5.51941,4.11429 -15.42291,8.75917 -21.67882,10.16846 -7.75654,1.74733 -13.53947,0.90038 -23.13459,-3.38625 -14.44842,-6.45479 -25.26854,-17.48329 -26.11875,-26.625 -0.46187,-4.96531 0.28073,-7.30805 3.1513,-9.94318 6.7457,-6.19289 23.01858,-9.42333 39.3053,-9.45392 z m -0.46507,83.43806 c 8.82994,1e-5 21.90971,3.55346 32.18398,8.74421 15.77369,7.9691 30.57783,21.1565 35.90208,31.98051 3.68786,7.4971 4.18188,16.00812 1.26924,21.86534 -5.22267,10.50284 -25.03716,18.03508 -53.7199,20.42411 -18.1235,1.50956 -40.77834,-0.15131 -56.23658,-4.12259 -16.44895,-4.22581 -26.40281,-10.46652 -28.75897,-18.03341 -4.53633,-14.56882 8.41138,-34.36087 31.45973,-48.0931 12.762,-7.60349 28.08632,-12.76507 37.90042,-12.76507 z"
id="path4206"
inkscape:connector-curvature="0" />

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Before After
Before After

View file

@ -47,7 +47,9 @@ module.exports = function (chrome, internals) {
length--;
}
return path.substr(1, length).split('/');
return path.substr(1, length)
.replace(/_/g, ' ') // Present snake-cased breadcrumb names as individual words
.split('/');
};
const notify = new Notifier();

View file

@ -56,7 +56,6 @@
.global-nav-link__icon-image {
height: 18px;
margin-top: 8px;
filter: invert(100%);
}
/**

View file

@ -20,7 +20,7 @@
</navbar>
<div class="config" ng-show="kbnTopNav.rendered">
<div id="template_wrapper" class="container-fluid"></div>
<div class="config-close remove">
<i class="fa fa-chevron-circle-up" ng-click="kbnTopNav.close()"></i>
<div class="config-close remove" ng-click="kbnTopNav.close()" data-test-subj="config-close-button">
<i class="fa fa-chevron-circle-up"></i>
</div>
</div>

View file

@ -0,0 +1,6 @@
import uiRegistry from 'ui/registry/_registry';
export default uiRegistry({
name: 'devTools',
index: ['name'],
order: ['order']
});

View file

@ -1,18 +1,169 @@
import {
parse as parseUrl,
format as formatUrl,
} from 'url';
import {
getUnhashableStatesProvider,
unhashUrl,
} from 'ui/state_management/state_hashing';
import Notifier from 'ui/notify/notifier';
import urlShortenerProvider from '../lib/url_shortener';
import uiModules from 'ui/modules';
import shareTemplate from 'ui/share/views/share.html';
const app = uiModules.get('kibana');
app.directive('share', function () {
app.directive('share', function (Private) {
const getUnhashableStates = Private(getUnhashableStatesProvider);
const urlShortener = Private(urlShortenerProvider);
return {
restrict: 'E',
scope: {
objectType: '@',
objectId: '@',
setAllowEmbed: '&?allowEmbed'
allowEmbed: '@',
},
template: shareTemplate,
controller: function ($scope) {
$scope.allowEmbed = $scope.setAllowEmbed ? $scope.setAllowEmbed() : true;
controllerAs: 'share',
controller: function ($scope, $document, $location, globalState) {
if ($scope.allowEmbed !== 'false' && $scope.allowEmbed !== undefined) {
throw new Error('allowEmbed must be "false" or undefined');
}
// Default to allowing an embedded IFRAME, unless it's explicitly set to false.
this.allowEmbed = $scope.allowEmbed === 'false' ? false : true;
this.objectType = $scope.objectType;
function getOriginalUrl() {
// If there is no objectId, then it isn't saved, so it has no original URL.
if ($scope.objectId === undefined || $scope.objectId === '') {
return;
}
const url = $location.absUrl();
// Replace hashes with original RISON values.
const unhashedUrl = unhashUrl(url, getUnhashableStates());
const parsedUrl = parseUrl(unhashedUrl);
// Get the Angular route, after the hash, and remove the #.
const parsedAppUrl = parseUrl(parsedUrl.hash.slice(1), true);
return formatUrl({
protocol: parsedUrl.protocol,
auth: parsedUrl.auth,
host: parsedUrl.host,
pathname: parsedUrl.pathname,
hash: formatUrl({
pathname: parsedAppUrl.pathname,
query: {
// Add global state to the URL so that the iframe doesn't just show the time range
// default.
_g: parsedAppUrl.query._g,
},
}),
});
};
function getSnapshotUrl() {
const url = $location.absUrl();
// Replace hashes with original RISON values.
return unhashUrl(url, getUnhashableStates());
}
this.makeUrlEmbeddable = url => {
const embedQueryParam = '?embed=true';
const urlHasQueryString = url.indexOf('?') !== -1;
if (urlHasQueryString) {
return url.replace('?', `${embedQueryParam}&`);
}
return `${url}${embedQueryParam}`;
};
this.makeIframeTag = url => {
if (!url) return;
const embeddableUrl = this.makeUrlEmbeddable(url);
return `<iframe src="${embeddableUrl}" height="600" width="800"></iframe>`;
};
this.urls = {
original: undefined,
snapshot: undefined,
shortSnapshot: undefined,
shortSnapshotIframe: undefined,
};
this.urlFlags = {
shortSnapshot: false,
shortSnapshotIframe: false,
};
const updateUrls = () => {
this.urls = {
original: getOriginalUrl(),
snapshot: getSnapshotUrl(),
shortSnapshot: undefined,
shortSnapshotIframe: undefined,
};
// Whenever the URL changes, reset the Short URLs to regular URLs.
this.urlFlags = {
shortSnapshot: false,
shortSnapshotIframe: false,
};
};
// When the URL changes, update the links in the UI.
$scope.$watch(() => $location.absUrl(), () => {
updateUrls();
});
this.toggleShortSnapshotUrl = () => {
this.urlFlags.shortSnapshot = !this.urlFlags.shortSnapshot;
if (this.urlFlags.shortSnapshot) {
urlShortener.shortenUrl(this.urls.snapshot)
.then(shortUrl => {
this.urls.shortSnapshot = shortUrl;
});
}
};
this.toggleShortSnapshotIframeUrl = () => {
this.urlFlags.shortSnapshotIframe = !this.urlFlags.shortSnapshotIframe;
if (this.urlFlags.shortSnapshotIframe) {
const snapshotIframe = this.makeUrlEmbeddable(this.urls.snapshot);
urlShortener.shortenUrl(snapshotIframe)
.then(shortUrl => {
this.urls.shortSnapshotIframe = shortUrl;
});
}
};
this.copyToClipboard = selector => {
const notify = new Notifier({
location: `Share ${$scope.objectType}`,
});
// Select the text to be copied. If the copy fails, the user can easily copy it manually.
const copyTextarea = $document.find(selector)[0];
copyTextarea.select();
try {
const isCopied = document.execCommand('copy');
if (isCopied) {
notify.info('URL copied to clipboard.');
} else {
notify.info('URL selected. Press Ctrl+C to copy.');
}
} catch (err) {
notify.info('URL selected. Press Ctrl+C to copy.');
}
};
}
};
});

View file

@ -1,91 +0,0 @@
const app = uiModules.get('kibana');
import Clipboard from 'clipboard';
import '../styles/index.less';
import LibUrlShortenerProvider from '../lib/url_shortener';
import uiModules from 'ui/modules';
import shareObjectUrlTemplate from 'ui/share/views/share_object_url.html';
import {
getUnhashableStatesProvider,
unhashUrl,
} from 'ui/state_management/state_hashing';
import { memoize } from 'lodash';
app.directive('shareObjectUrl', function (Private, Notifier) {
const urlShortener = Private(LibUrlShortenerProvider);
const getUnhashableStates = Private(getUnhashableStatesProvider);
return {
restrict: 'E',
scope: {
getShareAsEmbed: '&shareAsEmbed'
},
template: shareObjectUrlTemplate,
link: function ($scope, $el) {
const notify = new Notifier({
location: `Share ${$scope.$parent.objectType}`
});
$scope.textbox = $el.find('input.url')[0];
$scope.clipboardButton = $el.find('button.clipboard-button')[0];
const clipboard = new Clipboard($scope.clipboardButton, {
target(trigger) {
return $scope.textbox;
}
});
clipboard.on('success', e => {
notify.info('URL copied to clipboard.');
e.clearSelection();
});
clipboard.on('error', () => {
notify.info('URL selected. Press Ctrl+C to copy.');
});
$scope.$on('$destroy', () => {
clipboard.destroy();
});
$scope.clipboard = clipboard;
},
controller: function ($scope, $location) {
function updateUrl(url) {
$scope.url = url;
if ($scope.shareAsEmbed) {
$scope.formattedUrl = `<iframe src="${$scope.url}" height="600" width="800"></iframe>`;
} else {
$scope.formattedUrl = $scope.url;
}
$scope.shortGenerated = false;
}
$scope.shareAsEmbed = $scope.getShareAsEmbed();
$scope.generateShortUrl = function () {
if ($scope.shortGenerated) return;
urlShortener.shortenUrl($scope.url)
.then(shortUrl => {
updateUrl(shortUrl);
$scope.shortGenerated = true;
});
};
$scope.getUrl = function () {
const urlWithHashes = $location.absUrl();
const urlWithStates = unhashUrl(urlWithHashes, getUnhashableStates());
if ($scope.shareAsEmbed) {
return urlWithStates.replace('?', '?embed=true&');
}
return urlWithStates;
};
$scope.$watch('getUrl()', updateUrl);
}
};
});

View file

@ -1,2 +1,2 @@
import './styles/index.less';
import './directives/share';
import './directives/share_object_url';

View file

@ -1,21 +1,79 @@
share-object-url {
.input-group {
.share-dropdown {
display: flex;
padding: 5px 15px;
}
.share-panel {
flex: 1 1 0%;
}
.share-panel--left {
margin-right: 30px;
}
.share-panel--right {
margin-left: 30px;
}
.share-panel__title {
margin-bottom: 12px;
padding-bottom: 4px;
font-size: 18px;
color: #000000;
}
.share-panel-section {
margin-bottom: 16px;
}
.share-panel-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 6px;
}
.share-panel-header__label {
font-size: 14px;
font-weight: 700;
color: #000000;
}
.share-panel-header__actions {
display: flex;
}
.clipboard-button {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.share-panel-header__action {
font-size: 12px;
.shorten-button {
border-top-right-radius: 0;
border-top-left-radius: 0;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-control.url {
cursor: text;
& + & {
margin-left: 10px;
}
}
.share-panel-input {
width: 100%;
padding: 4px 10px;
margin-bottom: 6px;
border: 0;
border-radius: 4px;
}
.share-panel-form-note {
font-size: 14px;
color: #5A5A5A;
}
.share-panel-help-text {
margin-bottom: 16px;
font-size: 14px;
color: #2D2D2D;
}
.share-panel-warning {
margin-bottom: 16px;
padding: 6px 10px;
font-size: 14px;
color: #2D2D2D;
background-color: #e4e4e4;
}

View file

@ -1,15 +1,194 @@
<form role="form" class="vis-share">
<div class="form-group" ng-if="allowEmbed">
<label>
Embed this {{objectType}}
<small>Add to your html source. Note all clients must still be able to access kibana</small>
</label>
<share-object-url share-as-embed="true"></share-object-url>
<div class="share-dropdown">
<!-- Left panel -->
<div class="share-panel share-panel--left">
<!-- Title -->
<div
data-test-subj="shareUiTitle"
class="share-panel__title"
>
Share saved {{share.objectType}}
</div>
<!-- Help text -->
<div ng-if="share.urls.original" class="share-panel-help-text">
You can share this URL with people to let them load the most recent saved version of this {{share.objectType}}.
</div>
<div ng-if="!share.urls.original" class="share-panel-warning">
Please save this {{share.objectType}} to enable this sharing option.
</div>
<div ng-if="share.urls.original">
<!-- iframe -->
<div class="share-panel-section" ng-if="share.allowEmbed">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
Embedded iframe
</div>
<div class="share-panel-header__actions">
<a
class="share-panel-header__action"
ng-click="share.copyToClipboard('#originalIframeUrl')"
>
Copy
</a>
</div>
</div>
<!-- Input -->
<input
id="originalIframeUrl"
class="share-panel-input"
type="text"
readonly
value="{{share.makeIframeTag(share.urls.original)}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
Add to your HTML source. Note that all clients must be able to access Kibana.
</div>
</div>
<!-- Link -->
<div class="share-panel-section">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
Link
</div>
<div class="share-panel-header__actions">
<a
class="share-panel-header__action"
ng-click="share.copyToClipboard('#originalUrl')"
>
Copy
</a>
</div>
</div>
<!-- Input -->
<input
id="originalUrl"
class="share-panel-input"
type="text"
readonly
value="{{share.urls.original}}"
/>
</div>
</div>
</div>
<div class="form-group">
<label>
Share a link
</label>
<share-object-url share-as-embed="false"></share-object-url>
<!-- Right panel -->
<div class="share-panel share-panel--right">
<!-- Title -->
<div class="share-panel__title">
Share Snapshot
</div>
<!-- Help text -->
<div class="share-panel-help-text">
Snapshot URLs encode the current state of the {{share.objectType}} in the URL itself. Edits to the saved {{share.objectType}} won't be visible via this URL.
</div>
<!-- iframe -->
<div class="share-panel-section" ng-if="share.allowEmbed">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
Embedded iframe
</div>
<div class="share-panel-header__actions">
<a
class="share-panel-header__action"
ng-if="!share.urlFlags.shortSnapshotIframe"
ng-click="share.toggleShortSnapshotIframeUrl()"
>
Short URL
</a>
<a
class="share-panel-header__action"
ng-if="share.urlFlags.shortSnapshotIframe"
ng-click="share.toggleShortSnapshotIframeUrl()"
>
Long URL
</a>
<a
class="share-panel-header__action"
ng-click="share.copyToClipboard('#snapshotIframeUrl')"
>
Copy
</a>
</div>
</div>
<!-- Input -->
<input
id="snapshotIframeUrl"
class="share-panel-input"
type="text"
readonly
value="{{share.urlFlags.shortSnapshotIframe ? share.makeIframeTag(share.urls.shortSnapshotIframe) : share.makeIframeTag(share.urls.snapshot)}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
Add to your HTML source. Note that all clients must be able to access Kibana.
</div>
</div>
<!-- Link -->
<div class="share-panel-section">
<!-- Header -->
<div class="share-panel-header">
<div class="share-panel-header__label">
Link
</div>
<div class="share-panel-header__actions">
<a
data-test-subj="sharedSnapshotShortUrlButton"
class="share-panel-header__action"
ng-if="!share.urlFlags.shortSnapshot"
ng-click="share.toggleShortSnapshotUrl()"
>
Short URL
</a>
<a
class="share-panel-header__action"
ng-if="share.urlFlags.shortSnapshot"
ng-click="share.toggleShortSnapshotUrl()"
>
Long URL
</a>
<a
data-test-subj="sharedSnapshotCopyButton"
class="share-panel-header__action"
ng-click="share.copyToClipboard('#snapshotUrl')"
>
Copy
</a>
</div>
</div>
<!-- Input -->
<input
data-test-subj="sharedSnapshotUrl"
id="snapshotUrl"
class="share-panel-input"
type="text"
readonly
value="{{share.urlFlags.shortSnapshot ? share.urls.shortSnapshot : share.urls.snapshot}}"
/>
<!-- Notes -->
<div class="share-panel-form-note">
We recommend sharing shortened snapshot URLs for maximum compatibility. Internet Explorer has URL length restrictions, and some wiki and markup parsers don't do well with the full-length version of the snapshot URL, but the short URL should work great.
</div>
</div>
</div>
</form>
</div>

View file

@ -1,21 +0,0 @@
<div class="input-group">
<input
ng-model="formattedUrl"
type="text"
readonly=""
class="form-control url">
</input>
<button
class="shorten-button btn btn-default"
tooltip="Generate Short URL"
ng-click="generateShortUrl()"
ng-disabled="shortGenerated">
<span aria-hidden="true" class="fa fa-compress"></span>
</button>
<button
class="clipboard-button btn btn-default"
tooltip="Copy to Clipboard"
ng-click="copyToClipboard()">
<span aria-hidden="true" class="fa fa-clipboard"></span>
</button>
</div>

View file

@ -53,10 +53,6 @@ export default function ColumnLayoutFactory(Private) {
splits: chartTitleSplit
}
]
},
{
type: 'div',
class: 'legend-col-wrapper'
}
]
}

View file

@ -80,6 +80,7 @@ visualize-legend {
.vis-container--legend-top &,
.vis-container--legend-bottom & {
width: auto;
overflow-y: hidden;
.legend-value {
display: inline-block;

View file

@ -82,6 +82,7 @@ class UiExports {
case 'chromeNavControls':
case 'navbarExtensions':
case 'managementSections':
case 'devTools':
case 'docViews':
case 'hacks':
return (plugin, spec) => {

View file

@ -1,12 +1,22 @@
import expect from 'expect.js';
import PageObjects from '../../../support/page_objects';
import {
bdd,
scenarioManager
} from '../../../support';
import PageObjects from '../../../support/page_objects';
const DEFAULT_REQUEST = `
GET _search
{
"query": {
"match_all": {}
}
}
`.trim();
bdd.describe('console app', function describeIndexTests() {
bdd.before(function () {
@ -15,15 +25,6 @@ bdd.describe('console app', function describeIndexTests() {
});
bdd.it('should show the default request', function () {
var expectedRequest = [
'GET _search',
'{',
' "query": {',
' "match_all": {}',
' }',
'}',
''
];
PageObjects.common.saveScreenshot('Console-help-expanded');
// collapse the help pane because we only get the VISIBLE TEXT, not the part that is scrolled
return PageObjects.console.collapseHelp()
@ -32,14 +33,15 @@ bdd.describe('console app', function describeIndexTests() {
return PageObjects.common.try(function () {
return PageObjects.console.getRequest()
.then(function (actualRequest) {
expect(actualRequest).to.eql(expectedRequest);
expect(actualRequest.trim()).to.eql(DEFAULT_REQUEST);
});
});
});
});
bdd.it('default request response should contain .kibana' , function () {
var expectedResponseContains = '"_index": ".kibana",';
const expectedResponseContains = '"_index": ".kibana",';
return PageObjects.console.clickPlay()
.then(function () {
PageObjects.common.saveScreenshot('Console-default-request');

View file

@ -52,14 +52,14 @@ bdd.describe('shared links', function describeIndexTests() {
bdd.describe('shared link', function () {
bdd.it('should show "Share a link" caption', function () {
var expectedCaption = 'Share a link';
var expectedCaption = 'Share saved';
return PageObjects.discover.clickShare()
.then(function () {
PageObjects.common.saveScreenshot('Discover-share-link');
return PageObjects.discover.getShareCaption();
})
.then(function (actualCaption) {
expect(actualCaption).to.be(expectedCaption);
expect(actualCaption).to.contain(expectedCaption);
});
});
@ -100,7 +100,7 @@ bdd.describe('shared links', function describeIndexTests() {
.then(function () {
return PageObjects.common.try(function tryingForTime() {
PageObjects.common.saveScreenshot('Discover-shorten-url-button');
return PageObjects.discover.getShortenedUrl()
return PageObjects.discover.getSharedUrl()
.then(function (actualUrl) {
expect(actualUrl).to.match(re);
});

View file

@ -43,7 +43,8 @@ module.exports = {
hash: '/management'
},
console: {
pathname: 'app/console',
pathname: kibanaURL,
hash: '/dev_tools/console',
}
}
};

View file

@ -1,59 +1,38 @@
import Bluebird from 'bluebird';
import PageObjects from './';
import {
defaultFindTimeout,
} from '../';
export default class ConsolePage {
init(remote) {
this.remote = remote;
this.findTimeout = this.remote.setFindTimeout(defaultFindTimeout);
}
getServer() {
return this.findTimeout
.findByCssSelector('#kibana-body > div.content > div > div')
.getVisibleText();
}
setServer(server) {
return this.findTimeout
.findByCssSelector('input[aria-label="Server Name"]')
.clearValue()
.type(server);
}
getRequest() {
return this.findTimeout
.findAllByCssSelector('div.ace_line_group')
.then(function (editorData) {
function getEditorData(line) {
return line.getVisibleText();
}
var getEditorDataPromises = editorData.map(getEditorData);
return Promise.all(getEditorDataPromises);
});
}
getResponse() {
return this.findTimeout
.findByCssSelector('#output > div.ace_scroller > div')
.getVisibleText();
}
clickPlay() {
return this.findTimeout
.findByCssSelector('#editor_actions > span.ng-scope > a > i')
.click();
}
collapseHelp() {
return this.findTimeout
.findByCssSelector('div.config-close.remove > i')
.click();
}
async function getVisibleTextFromAceEditor(editor) {
const lines = await editor.findAllByClassName('ace_line_group');
const linesText = await Bluebird.map(lines, l => l.getVisibleText());
return linesText.join('\n');
}
export default class ConsolePage {
init() {
}
async getRequest() {
const requestEditor = await PageObjects.common.findTestSubject('console request-editor');
return await getVisibleTextFromAceEditor(requestEditor);
}
async getResponse() {
const responseEditor = await PageObjects.common.findTestSubject('console response-editor');
return await getVisibleTextFromAceEditor(responseEditor);
}
async clickPlay() {
const sendRequestButton = await PageObjects.common.findTestSubject('console send-request-button');
await sendRequestButton.click();
}
async collapseHelp() {
const closeButton = await PageObjects.common.findTestSubject('console top-nav config-close-button');
await closeButton.click();
}
}

View file

@ -202,31 +202,25 @@ export default class DiscoverPage {
clickShortenUrl() {
return this.findTimeout
.findByCssSelector('button.shorten-button')
.findByCssSelector('[data-test-subj="sharedSnapshotShortUrlButton"]')
.click();
}
clickCopyToClipboard() {
return this.findTimeout
.findDisplayedByCssSelector('button.clipboard-button')
.findByCssSelector('[data-test-subj="sharedSnapshotCopyButton"]')
.click();
}
getShareCaption() {
return this.findTimeout
.findByCssSelector('.vis-share label')
.findByCssSelector('[data-test-subj="shareUiTitle"]')
.getVisibleText();
}
getSharedUrl() {
return this.findTimeout
.findByCssSelector('.url')
.getProperty('value');
}
getShortenedUrl() {
return this.findTimeout
.findByCssSelector('.url')
.findByCssSelector('[data-test-subj="sharedSnapshotUrl"]')
.getProperty('value');
}