>> & {
- WrappedComponent: ComponentType;
-} {
- class InjectUICapabilities extends Component
{
- public static displayName = `InjectUICapabilities(${getDisplayName(WrappedComponent)})`;
-
- public static WrappedComponent: ComponentType
= WrappedComponent;
-
- public static contextType = UICapabilitiesContext;
-
- constructor(props: any, context: any) {
- super(props, context);
- }
-
- public render() {
- return ;
- }
- }
- return InjectUICapabilities;
-}
diff --git a/src/legacy/ui/public/capabilities/react/legacy/index.ts b/src/legacy/ui/public/capabilities/react/legacy/index.ts
deleted file mode 100644
index 78d95a2603290..0000000000000
--- a/src/legacy/ui/public/capabilities/react/legacy/index.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { UICapabilitiesProvider } from './ui_capabilities_provider';
-export { injectUICapabilities } from './inject_ui_capabilities';
diff --git a/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.test.tsx b/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.test.tsx
deleted file mode 100644
index dbc7cd03e27a3..0000000000000
--- a/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.test.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-jest.mock('ui/capabilities', () => ({
- capabilities: {
- get: () => ({
- uiCapability1: true,
- uiCapability2: {
- nestedProp: 'nestedValue',
- },
- }),
- },
-}));
-
-import { mount } from 'enzyme';
-import React from 'react';
-import { UICapabilities } from '../..';
-import { injectUICapabilities } from './inject_ui_capabilities';
-import { UICapabilitiesProvider } from './ui_capabilities_provider';
-
-describe('injectUICapabilities', () => {
- it('provides UICapabilities to FCs', () => {
- interface FCProps {
- uiCapabilities: UICapabilities;
- }
-
- const MyFC = injectUICapabilities(({ uiCapabilities }: FCProps) => {
- return {uiCapabilities.uiCapability2.nestedProp} ;
- });
-
- const wrapper = mount(
-
-
-
- );
-
- expect(wrapper).toMatchInlineSnapshot(`
-
-
-
-
- nestedValue
-
-
-
-
-`);
- });
-
- it('provides UICapabilities to class components', () => {
- interface ClassProps {
- uiCapabilities: UICapabilities;
- }
-
- // eslint-disable-next-line react/prefer-stateless-function
- class MyClassComponent extends React.Component {
- public render() {
- return {this.props.uiCapabilities.uiCapability2.nestedProp} ;
- }
- }
-
- const WrappedComponent = injectUICapabilities(MyClassComponent);
-
- const wrapper = mount(
-
-
-
- );
-
- expect(wrapper).toMatchInlineSnapshot(`
-
-
-
-
- nestedValue
-
-
-
-
-`);
- });
-});
diff --git a/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.tsx b/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.tsx
deleted file mode 100644
index 0253326809721..0000000000000
--- a/src/legacy/ui/public/capabilities/react/legacy/inject_ui_capabilities.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import PropTypes from 'prop-types';
-import React, { Component, ComponentClass, ComponentType } from 'react';
-import { UICapabilities } from '../..';
-
-function getDisplayName(component: ComponentType) {
- return component.displayName || component.name || 'Component';
-}
-
-interface InjectedProps {
- uiCapabilities: UICapabilities;
-}
-
-export function injectUICapabilities(
- WrappedComponent: ComponentType
-): ComponentClass>> & {
- WrappedComponent: ComponentType;
-} {
- class InjectUICapabilities extends Component
{
- public static displayName = `InjectUICapabilities(${getDisplayName(WrappedComponent)})`;
-
- public static WrappedComponent: ComponentType
= WrappedComponent;
-
- public static contextTypes = {
- uiCapabilities: PropTypes.object.isRequired,
- };
-
- constructor(props: any, context: any) {
- super(props, context);
- }
-
- public render() {
- return (
-
- );
- }
- }
- return InjectUICapabilities;
-}
diff --git a/src/legacy/ui/public/capabilities/react/legacy/ui_capabilities_provider.tsx b/src/legacy/ui/public/capabilities/react/legacy/ui_capabilities_provider.tsx
deleted file mode 100644
index 2e1f6add20d09..0000000000000
--- a/src/legacy/ui/public/capabilities/react/legacy/ui_capabilities_provider.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import PropTypes from 'prop-types';
-import React, { ReactNode } from 'react';
-import { capabilities, UICapabilities } from '../..';
-
-interface Props {
- children: ReactNode;
-}
-
-interface ProviderContext {
- uiCapabilities: UICapabilities;
-}
-
-export class UICapabilitiesProvider extends React.Component {
- public static displayName: string = 'UICapabilitiesProvider';
-
- public static childContextTypes = {
- uiCapabilities: PropTypes.object.isRequired,
- };
-
- public getChildContext(): ProviderContext {
- return {
- uiCapabilities: capabilities.get(),
- };
- }
-
- public render() {
- return React.Children.only(this.props.children);
- }
-}
diff --git a/src/legacy/ui/public/capabilities/react/ui_capabilities_context.ts b/src/legacy/ui/public/capabilities/react/ui_capabilities_context.ts
deleted file mode 100644
index ed299662899bb..0000000000000
--- a/src/legacy/ui/public/capabilities/react/ui_capabilities_context.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import { UICapabilities } from '..';
-
-export const UICapabilitiesContext = React.createContext({
- navLinks: {},
- catalogue: {},
- management: {},
-});
diff --git a/src/legacy/ui/public/capabilities/react/ui_capabilities_provider.tsx b/src/legacy/ui/public/capabilities/react/ui_capabilities_provider.tsx
deleted file mode 100644
index 90da657cc93e0..0000000000000
--- a/src/legacy/ui/public/capabilities/react/ui_capabilities_provider.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import { UICapabilitiesContext } from './ui_capabilities_context';
-import { capabilities } from '..';
-
-export const UICapabilitiesProvider: React.FC = (props) => (
-
- {props.children}
-
-);
-
-UICapabilitiesProvider.displayName = 'UICapabilitiesProvider';
diff --git a/src/legacy/ui/public/chrome/__mocks__/index.js b/src/legacy/ui/public/chrome/__mocks__/index.js
deleted file mode 100644
index cf977cd2c9f81..0000000000000
--- a/src/legacy/ui/public/chrome/__mocks__/index.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiSettingsServiceMock } from '../../../../../core/public/mocks';
-
-const uiSettingsClient = {
- ...uiSettingsServiceMock.createSetupContract(),
- getUpdate$: () => ({
- subscribe: jest.fn(),
- }),
-};
-
-const chrome = {
- addBasePath: (path) => (path ? path : 'test/base/path'),
- breadcrumbs: {
- set: () => ({}),
- },
- getBasePath: () => '/test/base/path',
- getInjected: jest.fn(),
- getUiSettingsClient: () => uiSettingsClient,
- getSavedObjectsClient: () => '',
- getXsrfToken: () => 'kbn-xsrf-token',
-};
-
-// eslint-disable-next-line import/no-default-export
-export default chrome;
-
-// Copied from `src/legacy/ui/public/chrome/chrome.js`
-import _ from 'lodash';
-import angular from 'angular';
-import { metadata } from '../../metadata';
-
-const internals = _.defaults(_.cloneDeep(metadata), {
- basePath: '',
- rootController: null,
- rootTemplate: null,
- showAppsLink: null,
- xsrfToken: null,
- devMode: true,
- brand: null,
- nav: [],
- applicationClasses: [],
-});
-
-const waitForBootstrap = new Promise((resolve) => {
- chrome.bootstrap = function (targetDomElement) {
- // sets attribute on body for stylesheet sandboxing
- document.body.setAttribute('id', `${internals.app.id}-app`);
-
- chrome.setupAngular();
- targetDomElement.setAttribute('kbn-chrome', 'true');
- targetDomElement.setAttribute('ng-class', "{ 'hidden-chrome': !chrome.getVisible() }");
- targetDomElement.className = 'app-wrapper';
- angular.bootstrap(targetDomElement, ['kibana']);
- resolve(targetDomElement);
- };
-});
-
-chrome.dangerouslyGetActiveInjector = () => {
- return waitForBootstrap.then((targetDomElement) => {
- const $injector = angular.element(targetDomElement).injector();
- if (!$injector) {
- return Promise.reject('targetDomElement had no angular context after bootstrapping');
- }
- return $injector;
- });
-};
diff --git a/src/legacy/ui/public/chrome/api/__tests__/angular.js b/src/legacy/ui/public/chrome/api/__tests__/angular.js
deleted file mode 100644
index 797498a24265e..0000000000000
--- a/src/legacy/ui/public/chrome/api/__tests__/angular.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { initAngularApi } from '../angular';
-import { noop } from 'lodash';
-
-describe('Chrome API :: Angular', () => {
- describe('location helper methods', () => {
- it('should return the sub app based on the url', () => {
- const chrome = {
- getInjected: noop,
- addBasePath: noop,
- };
- initAngularApi(chrome, {
- devMode: true,
- });
- });
- it('should return breadcrumbs based on the url', () => {});
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/__tests__/apps.js b/src/legacy/ui/public/chrome/api/__tests__/apps.js
deleted file mode 100644
index 98da8db52bad1..0000000000000
--- a/src/legacy/ui/public/chrome/api/__tests__/apps.js
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-
-import setup from '../apps';
-
-describe('Chrome API :: apps', function () {
- describe('#get/setShowAppsLink()', function () {
- describe('defaults to false if there are less than two apps', function () {
- it('appCount = 0', function () {
- const chrome = {};
- setup(chrome, { nav: [] });
- expect(chrome.getShowAppsLink()).to.equal(false);
- });
-
- it('appCount = 1', function () {
- const chrome = {};
- setup(chrome, { nav: [{ url: '/' }] });
- expect(chrome.getShowAppsLink()).to.equal(false);
- });
- });
-
- describe('defaults to true if there are two or more apps', function () {
- it('appCount = 2', function () {
- const chrome = {};
- setup(chrome, { nav: [{ url: '/' }, { url: '/2' }] });
- expect(chrome.getShowAppsLink()).to.equal(true);
- });
-
- it('appCount = 3', function () {
- const chrome = {};
- setup(chrome, { nav: [{ url: '/' }, { url: '/2' }, { url: '/3' }] });
- expect(chrome.getShowAppsLink()).to.equal(true);
- });
- });
-
- it('is chainable', function () {
- const chrome = {};
- setup(chrome, { nav: [{ url: '/' }] });
- expect(chrome.setShowAppsLink(true)).to.equal(chrome);
- });
-
- it('can be changed', function () {
- const chrome = {};
- setup(chrome, { nav: [{ url: '/' }] });
-
- expect(chrome.setShowAppsLink(true).getShowAppsLink()).to.equal(true);
- expect(chrome.getShowAppsLink()).to.equal(true);
-
- expect(chrome.setShowAppsLink(false).getShowAppsLink()).to.equal(false);
- expect(chrome.getShowAppsLink()).to.equal(false);
- });
- });
-
- describe('#getApp()', function () {
- it('returns a clone of the current app', function () {
- const chrome = {};
- const app = { url: '/' };
- setup(chrome, { app });
-
- expect(chrome.getApp()).to.eql(app);
- expect(chrome.getApp()).to.not.equal(app);
- });
-
- it('returns undefined if no active app', function () {
- const chrome = {};
- setup(chrome, {});
- expect(chrome.getApp()).to.equal(undefined);
- });
- });
-
- describe('#getAppTitle()', function () {
- it('returns the title property of the current app', function () {
- const chrome = {};
- const app = { url: '/', title: 'foo' };
- setup(chrome, { app });
- expect(chrome.getAppTitle()).to.eql('foo');
- });
-
- it('returns undefined if no active app', function () {
- const chrome = {};
- setup(chrome, {});
- expect(chrome.getAppTitle()).to.equal(undefined);
- });
- });
-
- describe('#getAppUrl()', function () {
- it('returns the resolved url of the current app', function () {
- const chrome = {};
- const app = { navLink: { url: '/foo' } };
- setup(chrome, { app });
-
- const a = document.createElement('a');
- a.setAttribute('href', app.navLink.url);
- expect(chrome.getAppUrl()).to.equal(a.href);
- });
-
- it('returns undefined if no active app', function () {
- const chrome = {};
- setup(chrome, {});
- expect(chrome.getAppUrl()).to.equal(undefined);
- });
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/__tests__/nav.js b/src/legacy/ui/public/chrome/api/__tests__/nav.js
deleted file mode 100644
index accb56dd42aa3..0000000000000
--- a/src/legacy/ui/public/chrome/api/__tests__/nav.js
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-import { initChromeNavApi } from '../nav';
-import { StubBrowserStorage } from 'test_utils/stub_browser_storage';
-import { npStart } from 'ui/new_platform';
-import { absoluteToParsedUrl } from '../../../url/absolute_to_parsed_url';
-
-const basePath = '/someBasePath';
-
-function init(customInternals = { basePath }) {
- const chrome = {
- addBasePath: (path) => path,
- getBasePath: () => customInternals.basePath || '',
- };
- const internals = {
- nav: [],
- ...customInternals,
- };
- initChromeNavApi(chrome, internals);
- return { chrome, internals };
-}
-
-describe('chrome nav apis', function () {
- let coreNavLinks;
- let fakedLinks = [];
-
- const baseUrl = (function () {
- const a = document.createElement('a');
- a.setAttribute('href', '/');
- return a.href.slice(0, a.href.length - 1);
- })();
-
- beforeEach(() => {
- coreNavLinks = npStart.core.chrome.navLinks;
- sinon.stub(coreNavLinks, 'update').callsFake((linkId, updateAttrs) => {
- const link = fakedLinks.find(({ id }) => id === linkId);
- for (const key of Object.keys(updateAttrs)) {
- link[key] = updateAttrs[key];
- }
- return link;
- });
- sinon.stub(coreNavLinks, 'getAll').callsFake(() => fakedLinks);
- sinon
- .stub(coreNavLinks, 'get')
- .callsFake((linkId) => fakedLinks.find(({ id }) => id === linkId));
- });
-
- afterEach(() => {
- coreNavLinks.update.restore();
- coreNavLinks.getAll.restore();
- coreNavLinks.get.restore();
- });
-
- describe('#untrackNavLinksForDeletedSavedObjects', function () {
- const appId = 'appId';
- const appUrl = `${baseUrl}/app/kibana#test`;
- const deletedId = 'IAMDELETED';
-
- it('should clear last url when last url contains link to deleted saved object', function () {
- const appUrlStore = new StubBrowserStorage();
- fakedLinks = [
- {
- id: appId,
- title: 'Discover',
- url: `${appUrl}?id=${deletedId}`,
- baseUrl: appUrl,
- linkToLastSubUrl: true,
- legacy: true,
- },
- ];
-
- const { chrome } = init({ appUrlStore });
- chrome.untrackNavLinksForDeletedSavedObjects([deletedId]);
- expect(coreNavLinks.update.calledWith(appId, { url: appUrl })).to.be(true);
- });
-
- it('should not clear last url when last url does not contains link to deleted saved object', function () {
- const lastUrl = `${appUrl}?id=anotherSavedObjectId`;
- const appUrlStore = new StubBrowserStorage();
- fakedLinks = [
- {
- id: appId,
- title: 'Discover',
- url: lastUrl,
- baseUrl: appUrl,
- linkToLastSubUrl: true,
- legacy: true,
- },
- ];
-
- const { chrome } = init({ appUrlStore });
- chrome.untrackNavLinksForDeletedSavedObjects([deletedId]);
- expect(coreNavLinks.update.calledWith(appId, { url: appUrl })).to.be(false);
- });
- });
-
- describe('chrome.trackSubUrlForApp()', function () {
- it('injects a manual app url', function () {
- const appUrlStore = new StubBrowserStorage();
- fakedLinks = [
- {
- id: 'visualize',
- baseUrl: `${baseUrl}/app/visualize#`,
- url: `${baseUrl}/app/visualize#`,
- subUrlBase: '/app/visualize#',
- legacy: true,
- },
- ];
-
- const { chrome } = init({ appUrlStore });
- const kibanaParsedUrl = absoluteToParsedUrl(
- `${baseUrl}/xyz/app/visualize#/1234?_g=globalstate`,
- '/xyz'
- );
- chrome.trackSubUrlForApp('visualize', kibanaParsedUrl);
- expect(
- coreNavLinks.update.calledWith('visualize', {
- url: `${baseUrl}/xyz/app/visualize#/1234?_g=globalstate`,
- })
- ).to.be(true);
- });
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/__tests__/sub_url_route_filter.js b/src/legacy/ui/public/chrome/api/__tests__/sub_url_route_filter.js
deleted file mode 100644
index 901fbd1d0edf6..0000000000000
--- a/src/legacy/ui/public/chrome/api/__tests__/sub_url_route_filter.js
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import ngMock from 'ng_mock';
-import expect from '@kbn/expect';
-
-import { SubUrlRouteFilterProvider } from '../sub_url_hooks';
-
-describe('kbn-chrome subUrlRouteFilter()', () => {
- describe('no ngRoute', () => {
- beforeEach(ngMock.module('kibana/private'));
- beforeEach(
- ngMock.inject(($injector) => {
- expect($injector.has('$route')).to.be(false);
- })
- );
-
- it(
- 'always returns true when there is no $route service',
- ngMock.inject((Private) => {
- const subUrlRouteFilter = Private(SubUrlRouteFilterProvider);
- expect(subUrlRouteFilter()).to.be(true);
- })
- );
- });
-
- describe('with ngRoute', () => {
- beforeEach(
- ngMock.module('kibana/private', 'ngRoute', ($routeProvider) => {
- $routeProvider.when('/foo', {
- redirectTo: '/bar',
- });
-
- $routeProvider.when('/bar', {
- template: 'foo => bar
',
- });
- })
- );
-
- let test;
- beforeEach(
- ngMock.inject((Private, $location, $rootScope, $route) => {
- test = ({ path, assert }) => {
- const subUrlRouteFilter = Private(SubUrlRouteFilterProvider);
- $location.path(path);
-
- let result;
- function runAssert() {
- if (result) {
- // only run once
- return;
- }
-
- try {
- assert($route, subUrlRouteFilter);
- result = {};
- } catch (error) {
- result = { error };
- }
- }
-
- $rootScope.$on('$routeUpdate', runAssert);
- $rootScope.$on('$routeChangeSuccess', runAssert);
- $rootScope.$apply();
-
- // when no route matches there is no event so we run manually
- if (!result) {
- runAssert();
- }
-
- if (result.error) {
- throw result.error;
- }
- };
- })
- );
-
- describe('no current route', () => {
- it('returns false', () => {
- test({
- path: '/baz',
- assert($route, subUrlRouteFilter) {
- expect($route.current).to.not.be.ok();
- expect(subUrlRouteFilter()).to.eql(false);
- },
- });
- });
- });
-
- describe('redirectTo route', () => {
- it('is called on target route', () => {
- test({
- path: '/foo',
- assert($route) {
- expect($route.current.$$route.originalPath).to.be('/bar');
- },
- });
- });
- });
-
- describe('standard route', () => {
- it('returns true', () => {
- test({
- path: '/bar',
- assert($route, subUrlRouteFilter) {
- expect($route.current).to.be.ok();
- expect($route.current.template).to.be.ok();
- expect(subUrlRouteFilter()).to.eql(true);
- },
- });
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/__tests__/xsrf.js b/src/legacy/ui/public/chrome/api/__tests__/xsrf.js
deleted file mode 100644
index 3197b79f407da..0000000000000
--- a/src/legacy/ui/public/chrome/api/__tests__/xsrf.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-import { initChromeXsrfApi } from '../xsrf';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { version } from '../../../../../../core/server/utils/package_json';
-
-describe('chrome xsrf apis', function () {
- const sandbox = sinon.createSandbox();
-
- afterEach(function () {
- sandbox.restore();
- });
-
- describe('#getXsrfToken()', function () {
- it('exposes the token', function () {
- const chrome = {};
- initChromeXsrfApi(chrome, { version });
- expect(chrome.getXsrfToken()).to.be(version);
- });
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/angular.js b/src/legacy/ui/public/chrome/api/angular.js
deleted file mode 100644
index a9113b2df2ed7..0000000000000
--- a/src/legacy/ui/public/chrome/api/angular.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../../modules';
-
-import { directivesProvider } from '../directives';
-import { registerSubUrlHooks } from './sub_url_hooks';
-import { configureAppAngularModule } from 'ui/legacy_compat';
-import { npStart } from '../../new_platform/new_platform';
-
-export function initAngularApi(chrome, internals) {
- chrome.setupAngular = function () {
- const kibana = uiModules.get('kibana');
-
- configureAppAngularModule(kibana, npStart.core, false);
-
- kibana.value('chrome', chrome);
-
- registerSubUrlHooks(kibana, internals);
- directivesProvider(chrome, internals);
-
- uiModules.link(kibana);
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/apps.js b/src/legacy/ui/public/chrome/api/apps.js
deleted file mode 100644
index c4cbe7be6f1c3..0000000000000
--- a/src/legacy/ui/public/chrome/api/apps.js
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { clone, get } from 'lodash';
-import { resolve } from 'url';
-
-// eslint-disable-next-line import/no-default-export
-export default function (chrome, internals) {
- if (get(internals, 'app.navLink.url')) {
- internals.app.navLink.url = resolve(window.location.href, internals.app.navLink.url);
- }
-
- internals.appUrlStore = internals.appUrlStore || window.sessionStorage;
- try {
- const verifySessionStorage = 'verify sessionStorage';
- internals.appUrlStore.setItem(verifySessionStorage, 1);
- internals.appUrlStore.removeItem(verifySessionStorage);
- } catch (error) {
- throw new Error(
- 'Kibana requires access to sessionStorage, and it looks like ' +
- "your browser is restricting it. If you're " +
- 'using Safari with private browsing enabled, you can solve this ' +
- 'problem by disabling private browsing, or by using another browser.'
- );
- }
-
- /**
- * ui/chrome apps API
- *
- * ui/chrome has some metadata about the current app, and enables the
- * navbar link, a small grid to the left of the tabs, when there is more
- * than one app installed.
- */
-
- chrome.setShowAppsLink = function (val) {
- internals.showAppsLink = !!val;
- return chrome;
- };
-
- chrome.getShowAppsLink = function () {
- return internals.showAppsLink == null ? internals.nav.length > 1 : internals.showAppsLink;
- };
-
- chrome.getKibanaVersion = function () {
- return internals.version;
- };
-
- chrome.getApp = function () {
- return clone(internals.app);
- };
-
- chrome.getAppTitle = function () {
- return get(internals, ['app', 'title']);
- };
-
- chrome.getAppUrl = function () {
- return get(internals, ['app', 'navLink', 'url']);
- };
-
- chrome.getLastUrlFor = function (appId) {
- return internals.appUrlStore.getItem(`appLastUrl:${appId}`);
- };
-
- chrome.setLastUrlFor = function (appId, url) {
- internals.appUrlStore.setItem(`appLastUrl:${appId}`, url);
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/badge.test.mocks.ts b/src/legacy/ui/public/chrome/api/badge.test.mocks.ts
deleted file mode 100644
index 9e78805272b2d..0000000000000
--- a/src/legacy/ui/public/chrome/api/badge.test.mocks.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { chromeServiceMock } from '../../../../../core/public/mocks';
-
-export const newPlatformChrome = chromeServiceMock.createStartContract();
-jest.doMock('ui/new_platform', () => ({
- npStart: {
- core: { chrome: newPlatformChrome },
- },
-}));
diff --git a/src/legacy/ui/public/chrome/api/badge.test.ts b/src/legacy/ui/public/chrome/api/badge.test.ts
deleted file mode 100644
index 6a19afb609f8a..0000000000000
--- a/src/legacy/ui/public/chrome/api/badge.test.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { ChromeBadge } from 'src/core/public/chrome';
-import { newPlatformChrome } from './badge.test.mocks';
-import { initChromeBadgeApi } from './badge';
-
-function setup() {
- const getBadge$ = new Rx.BehaviorSubject(undefined);
- newPlatformChrome.getBadge$.mockReturnValue(getBadge$);
-
- const chrome: any = {};
- initChromeBadgeApi(chrome);
- return { chrome, getBadge$ };
-}
-
-afterEach(() => {
- jest.resetAllMocks();
-});
-
-describe('badge', () => {
- describe('#get$()', () => {
- it('returns newPlatformChrome.getBadge$()', () => {
- const { chrome } = setup();
- expect(chrome.badge.get$()).toBe(newPlatformChrome.getBadge$());
- });
- });
-
- describe('#set()', () => {
- it('calls newPlatformChrome.setBadge', () => {
- const { chrome } = setup();
- const badge = {
- text: 'foo',
- tooltip: `foo's tooltip`,
- iconType: 'alert',
- };
- chrome.badge.set(badge);
- expect(newPlatformChrome.setBadge).toHaveBeenCalledTimes(1);
- expect(newPlatformChrome.setBadge).toHaveBeenCalledWith(badge);
- });
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/badge.ts b/src/legacy/ui/public/chrome/api/badge.ts
deleted file mode 100644
index e607e6c47dc39..0000000000000
--- a/src/legacy/ui/public/chrome/api/badge.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Chrome } from 'ui/chrome';
-import { npStart } from 'ui/new_platform';
-import { ChromeBadge } from '../../../../../core/public';
-export type Badge = ChromeBadge;
-
-export type BadgeApi = ReturnType['badge'];
-
-const newPlatformChrome = npStart.core.chrome;
-
-function createBadgeApi() {
- return {
- badge: {
- /**
- * Get an observable that emits the current badge
- * and emits each update to the badge
- */
- get$() {
- return newPlatformChrome.getBadge$();
- },
-
- /**
- * Replace the badge with a new one
- */
- set(newBadge?: Badge) {
- newPlatformChrome.setBadge(newBadge);
- },
- },
- };
-}
-
-export function initChromeBadgeApi(chrome: Chrome) {
- const { badge } = createBadgeApi();
- chrome.badge = badge;
-}
diff --git a/src/legacy/ui/public/chrome/api/base_path.test.mocks.ts b/src/legacy/ui/public/chrome/api/base_path.test.mocks.ts
deleted file mode 100644
index f2c5fd5734b10..0000000000000
--- a/src/legacy/ui/public/chrome/api/base_path.test.mocks.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { httpServiceMock } from '../../../../../core/public/mocks';
-
-const newPlatformHttp = httpServiceMock.createSetupContract({ basePath: 'npBasePath' });
-jest.doMock('ui/new_platform', () => ({
- npSetup: {
- core: { http: newPlatformHttp },
- },
-}));
diff --git a/src/legacy/ui/public/chrome/api/base_path.test.ts b/src/legacy/ui/public/chrome/api/base_path.test.ts
deleted file mode 100644
index d3cfc6a3168a8..0000000000000
--- a/src/legacy/ui/public/chrome/api/base_path.test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import './base_path.test.mocks';
-import { initChromeBasePathApi } from './base_path';
-
-function initChrome() {
- const chrome: any = {};
- initChromeBasePathApi(chrome);
- return chrome;
-}
-
-beforeEach(() => {
- jest.clearAllMocks();
-});
-
-describe('#getBasePath()', () => {
- it('proxies to newPlatformHttp.basePath.get()', () => {
- const chrome = initChrome();
- expect(chrome.getBasePath()).toBe('npBasePath');
- });
-});
-
-describe('#addBasePath()', () => {
- it('proxies to newPlatformHttp.basePath.prepend(path)', () => {
- const chrome = initChrome();
- expect(chrome.addBasePath('/foo/bar')).toBe('npBasePath/foo/bar');
- });
-});
-
-describe('#removeBasePath', () => {
- it('proxies to newPlatformBasePath.basePath.remove(path)', () => {
- const chrome = initChrome();
- expect(chrome.removeBasePath('npBasePath/foo/bar')).toBe('/foo/bar');
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/base_path.ts b/src/legacy/ui/public/chrome/api/base_path.ts
deleted file mode 100644
index da823425b7c22..0000000000000
--- a/src/legacy/ui/public/chrome/api/base_path.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-
-const newPlatformHttp = npSetup.core.http;
-
-export function initChromeBasePathApi(chrome: { [key: string]: any }) {
- chrome.getBasePath = newPlatformHttp.basePath.get;
- chrome.addBasePath = newPlatformHttp.basePath.prepend;
- chrome.removeBasePath = newPlatformHttp.basePath.remove;
-}
diff --git a/src/legacy/ui/public/chrome/api/breadcrumbs.ts b/src/legacy/ui/public/chrome/api/breadcrumbs.ts
deleted file mode 100644
index df1b7e1736bb4..0000000000000
--- a/src/legacy/ui/public/chrome/api/breadcrumbs.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npStart } from 'ui/new_platform';
-import { ChromeBreadcrumb } from '../../../../../core/public';
-export type Breadcrumb = ChromeBreadcrumb;
-
-export type BreadcrumbsApi = ReturnType['breadcrumbs'];
-
-const newPlatformChrome = npStart.core.chrome;
-
-function createBreadcrumbsApi(chrome: { [key: string]: any }) {
- let currentBreadcrumbs: Breadcrumb[] = [];
-
- // reset breadcrumbSetSinceRouteChange any time the breadcrumbs change, even
- // if it was done directly through the new platform
- newPlatformChrome.getBreadcrumbs$().subscribe({
- next(nextBreadcrumbs) {
- currentBreadcrumbs = nextBreadcrumbs;
- },
- });
-
- return {
- breadcrumbs: {
- /**
- * Get an observerable that emits the current list of breadcrumbs
- * and emits each update to the breadcrumbs
- */
- get$() {
- return newPlatformChrome.getBreadcrumbs$();
- },
-
- /**
- * Replace the set of breadcrumbs with a new set
- */
- set(newBreadcrumbs: Breadcrumb[]) {
- newPlatformChrome.setBreadcrumbs(newBreadcrumbs);
- },
-
- /**
- * Add a breadcrumb to the end of the list of breadcrumbs
- */
- push(breadcrumb: Breadcrumb) {
- newPlatformChrome.setBreadcrumbs([...currentBreadcrumbs, breadcrumb]);
- },
-
- /**
- * Filter the current set of breadcrumbs with a function. Works like Array#filter()
- */
- filter(fn: (breadcrumb: Breadcrumb, i: number, all: Breadcrumb[]) => boolean) {
- newPlatformChrome.setBreadcrumbs(currentBreadcrumbs.filter(fn));
- },
-
- /**
- * Remove last element of the breadcrumb
- */
- pop() {
- newPlatformChrome.setBreadcrumbs(currentBreadcrumbs.slice(0, -1));
- },
- },
- };
-}
-
-export function initBreadcrumbsApi(
- chrome: { [key: string]: any },
- internals: { [key: string]: any }
-) {
- const { breadcrumbs } = createBreadcrumbsApi(chrome);
- chrome.breadcrumbs = breadcrumbs;
-}
diff --git a/src/legacy/ui/public/chrome/api/controls.test.mocks.ts b/src/legacy/ui/public/chrome/api/controls.test.mocks.ts
deleted file mode 100644
index 9e78805272b2d..0000000000000
--- a/src/legacy/ui/public/chrome/api/controls.test.mocks.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { chromeServiceMock } from '../../../../../core/public/mocks';
-
-export const newPlatformChrome = chromeServiceMock.createStartContract();
-jest.doMock('ui/new_platform', () => ({
- npStart: {
- core: { chrome: newPlatformChrome },
- },
-}));
diff --git a/src/legacy/ui/public/chrome/api/controls.test.ts b/src/legacy/ui/public/chrome/api/controls.test.ts
deleted file mode 100644
index f41f2041993a3..0000000000000
--- a/src/legacy/ui/public/chrome/api/controls.test.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-
-import { newPlatformChrome } from './controls.test.mocks';
-import { initChromeControlsApi } from './controls';
-
-function setup() {
- const isVisible$ = new Rx.BehaviorSubject(true);
- newPlatformChrome.getIsVisible$.mockReturnValue(isVisible$);
-
- const chrome: any = {};
- initChromeControlsApi(chrome);
- return { chrome, isVisible$ };
-}
-
-afterEach(() => {
- jest.resetAllMocks();
-});
-
-describe('setVisible', () => {
- it('passes the visibility to the newPlatform', () => {
- const { chrome } = setup();
- chrome.setVisible(true);
- chrome.setVisible(false);
- chrome.setVisible(false);
- expect(newPlatformChrome.setIsVisible.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [
- true,
- ],
- Array [
- false,
- ],
- Array [
- false,
- ],
-]
-`);
- });
-});
-
-describe('getVisible', () => {
- it('returns a the cached value emitted by the newPlatformChrome', () => {
- const { chrome, isVisible$ } = setup();
- isVisible$.next(true);
- expect(chrome.getVisible()).toBe(true);
- isVisible$.next(false);
- expect(chrome.getVisible()).toBe(false);
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/controls.ts b/src/legacy/ui/public/chrome/api/controls.ts
deleted file mode 100644
index a95d53ec2eab6..0000000000000
--- a/src/legacy/ui/public/chrome/api/controls.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-import { npStart } from 'ui/new_platform';
-
-const newPlatformChrome = npStart.core.chrome;
-
-export function initChromeControlsApi(chrome: { [key: string]: any }) {
- // cache of chrome visibility state
- const visible$ = new Rx.BehaviorSubject(false);
- newPlatformChrome.getIsVisible$().subscribe(visible$);
-
- /**
- * Set the temporary visibility for the chrome. This does nothing if the chrome is hidden
- * by default and should be used to hide the chrome for things like full-screen modes
- * with an exit button.
- */
- chrome.setVisible = (visibility: boolean) => {
- newPlatformChrome.setIsVisible(visibility);
- return chrome;
- };
-
- /**
- * Get the current visibility state of the chrome. Note that this drives the UI so it
- * might be incorrect in the moments just before the UI is updated.
- */
- chrome.getVisible = () => visible$.getValue();
-
- chrome.visible$ = visible$.asObservable();
-}
diff --git a/src/legacy/ui/public/chrome/api/help_extension.ts b/src/legacy/ui/public/chrome/api/help_extension.ts
deleted file mode 100644
index b59f27e37512c..0000000000000
--- a/src/legacy/ui/public/chrome/api/help_extension.ts
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npStart } from 'ui/new_platform';
-import { ChromeHelpExtension } from '../../../../../core/public';
-
-const newPlatformChrome = npStart.core.chrome;
-
-export type HelpExtensionApi = ReturnType['helpExtension'];
-export type HelpExtension = ChromeHelpExtension;
-
-function createHelpExtensionApi() {
- return {
- helpExtension: {
- /**
- * Set the custom help extension, or clear it by passing undefined. This
- * will be rendered within the help popover in the header
- */
- set: (helpExtension: HelpExtension | undefined) => {
- newPlatformChrome.setHelpExtension(helpExtension);
- },
-
- /**
- * Get the current help extension that should be rendered in the header
- */
- get$: () => newPlatformChrome.getHelpExtension$(),
- },
- };
-}
-
-export function initHelpExtensionApi(
- chrome: { [key: string]: any },
- internal: { [key: string]: any }
-) {
- const { helpExtension } = createHelpExtensionApi();
- chrome.helpExtension = helpExtension;
-}
diff --git a/src/legacy/ui/public/chrome/api/injected_vars.test.mocks.ts b/src/legacy/ui/public/chrome/api/injected_vars.test.mocks.ts
deleted file mode 100644
index 3ad713ccce9a4..0000000000000
--- a/src/legacy/ui/public/chrome/api/injected_vars.test.mocks.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export const newPlatformInjectedMetadata: any = {
- getInjectedVars: jest.fn(),
- getInjectedVar: jest.fn(),
-};
-jest.doMock('ui/new_platform', () => ({
- npSetup: {
- core: { injectedMetadata: newPlatformInjectedMetadata },
- },
-}));
diff --git a/src/legacy/ui/public/chrome/api/injected_vars.test.ts b/src/legacy/ui/public/chrome/api/injected_vars.test.ts
deleted file mode 100644
index 2147aed06320e..0000000000000
--- a/src/legacy/ui/public/chrome/api/injected_vars.test.ts
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { newPlatformInjectedMetadata } from './injected_vars.test.mocks';
-import { initChromeInjectedVarsApi } from './injected_vars';
-
-function initChrome() {
- const chrome: any = {};
- initChromeInjectedVarsApi(chrome);
- return chrome;
-}
-
-beforeEach(() => {
- jest.resetAllMocks();
-});
-
-describe('#getInjected()', () => {
- it('proxies to newPlatformInjectedMetadata service', () => {
- const chrome = initChrome();
-
- chrome.getInjected();
- chrome.getInjected('foo');
- chrome.getInjected('foo', 'bar');
- expect(newPlatformInjectedMetadata.getInjectedVars.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [],
-]
-`);
- expect(newPlatformInjectedMetadata.getInjectedVar.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [
- "foo",
- undefined,
- ],
- Array [
- "foo",
- "bar",
- ],
-]
-`);
- });
-
- it('returns mutable values, but does not persist changes internally', () => {
- const chrome = initChrome();
-
- newPlatformInjectedMetadata.getInjectedVars.mockReturnValue(
- Object.freeze({
- foo: Object.freeze({
- bar: Object.freeze({
- baz: 1,
- }),
- }),
- })
- );
-
- const vars = chrome.getInjected();
- expect(() => {
- vars.newProperty = true;
- }).not.toThrowError();
- expect(chrome.getInjected()).not.toHaveProperty('newProperty');
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/injected_vars.ts b/src/legacy/ui/public/chrome/api/injected_vars.ts
deleted file mode 100644
index a827c1bf65f51..0000000000000
--- a/src/legacy/ui/public/chrome/api/injected_vars.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { cloneDeep } from 'lodash';
-import { npSetup } from 'ui/new_platform';
-
-const newPlatformInjectedVars = npSetup.core.injectedMetadata;
-
-export function initChromeInjectedVarsApi(chrome: { [key: string]: any }) {
- chrome.getInjected = (name?: string, defaultValue?: any) =>
- cloneDeep(
- name
- ? newPlatformInjectedVars.getInjectedVar(name, defaultValue)
- : newPlatformInjectedVars.getInjectedVars()
- );
-}
diff --git a/src/legacy/ui/public/chrome/api/loading_count.js b/src/legacy/ui/public/chrome/api/loading_count.js
deleted file mode 100644
index 71d1e354773d5..0000000000000
--- a/src/legacy/ui/public/chrome/api/loading_count.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-import { npSetup } from 'ui/new_platform';
-
-const newPlatformHttp = npSetup.core.http;
-
-export function initLoadingCountApi(chrome) {
- const manualCount$ = new Rx.BehaviorSubject(0);
- newPlatformHttp.addLoadingCountSource(manualCount$);
-
- chrome.loadingCount = new (class ChromeLoadingCountApi {
- /**
- * Call to add a subscriber to for the loading count that
- * will be called every time the loading count changes.
- *
- * @type {Observable}
- * @return {Function} unsubscribe
- */
- subscribe(handler) {
- const subscription = newPlatformHttp.getLoadingCount$().subscribe({
- next(count) {
- handler(count);
- },
- });
-
- return () => {
- subscription.unsubscribe();
- };
- }
-
- /**
- * Increment the loading count by one
- * @return {undefined}
- */
- increment() {
- manualCount$.next(manualCount$.getValue() + 1);
- }
-
- /**
- * Decrement the loading count by one
- * @return {undefined}
- */
- decrement() {
- manualCount$.next(manualCount$.getValue() - 1);
- }
- })();
-}
diff --git a/src/legacy/ui/public/chrome/api/nav.ts b/src/legacy/ui/public/chrome/api/nav.ts
deleted file mode 100644
index 2b655419d98aa..0000000000000
--- a/src/legacy/ui/public/chrome/api/nav.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { KibanaParsedUrl } from 'ui/url/kibana_parsed_url';
-import { absoluteToParsedUrl } from '../../url/absolute_to_parsed_url';
-import { npStart } from '../../new_platform';
-import { ChromeNavLink } from '../../../../../core/public';
-import { relativeToAbsolute } from '../../url/relative_to_absolute';
-
-export interface ChromeNavLinks {
- untrackNavLinksForDeletedSavedObjects(deletedIds: string[]): void;
- trackSubUrlForApp(linkId: string, parsedKibanaUrl: KibanaParsedUrl): void;
-}
-
-interface NavInternals {
- appUrlStore: Storage;
- trackPossibleSubUrl(url: string): void;
-}
-
-export function initChromeNavApi(chrome: any, internals: NavInternals) {
- const coreNavLinks = npStart.core.chrome.navLinks;
-
- /**
- * Clear last url for deleted saved objects to avoid loading pages with "Could not locate..."
- */
- chrome.untrackNavLinksForDeletedSavedObjects = (deletedIds: string[]) => {
- function urlContainsDeletedId(url: string) {
- const includedId = deletedIds.find((deletedId) => {
- return url.includes(deletedId);
- });
- return includedId !== undefined;
- }
-
- coreNavLinks.getAll().forEach((link) => {
- if (link.linkToLastSubUrl && urlContainsDeletedId(link.url!)) {
- setLastUrl(link, link.baseUrl);
- }
- });
- };
-
- /**
- * Manually sets the last url for the given app. The last url for a given app is updated automatically during
- * normal page navigation, so this should only need to be called to insert a last url that was not actually
- * navigated to. For instance, when saving an object and redirecting to another page, the last url of the app
- * should be the saved instance, but because of the redirect to a different page (e.g. `Save and Add to Dashboard`
- * on visualize tab), it won't be tracked automatically and will need to be inserted manually. See
- * https://github.com/elastic/kibana/pull/11932 for more background on why this was added.
- *
- * @param id {String} - an id that represents the navigation link.
- * @param kibanaParsedUrl {KibanaParsedUrl} the url to track
- */
- chrome.trackSubUrlForApp = (id: string, kibanaParsedUrl: KibanaParsedUrl) => {
- const navLink = coreNavLinks.get(id);
- if (navLink) {
- setLastUrl(navLink, kibanaParsedUrl.getAbsoluteUrl());
- }
- };
-
- internals.trackPossibleSubUrl = async function (url: string) {
- const kibanaParsedUrl = absoluteToParsedUrl(url, chrome.getBasePath());
-
- coreNavLinks
- .getAll()
- // Filter only legacy links
- .filter((link) => link.legacy && !link.disableSubUrlTracking)
- .forEach((link) => {
- const active = url.startsWith(link.subUrlBase!);
- link = coreNavLinks.update(link.id, { active })!;
-
- if (active) {
- setLastUrl(link, url);
- return;
- }
-
- link = refreshLastUrl(link);
-
- const newGlobalState = kibanaParsedUrl.getGlobalState();
- if (newGlobalState) {
- injectNewGlobalState(link, kibanaParsedUrl.appId, newGlobalState);
- }
- });
- };
-
- function lastSubUrlKey(link: ChromeNavLink) {
- return `lastSubUrl:${link.baseUrl}`;
- }
-
- function getLastUrl(link: ChromeNavLink) {
- return internals.appUrlStore.getItem(lastSubUrlKey(link));
- }
-
- function setLastUrl(link: ChromeNavLink, url: string) {
- if (link.linkToLastSubUrl === false) {
- return;
- }
-
- internals.appUrlStore.setItem(lastSubUrlKey(link), url);
- refreshLastUrl(link);
- }
-
- function refreshLastUrl(link: ChromeNavLink) {
- const lastSubUrl = getLastUrl(link);
-
- return coreNavLinks.update(link.id, {
- url: lastSubUrl || link.url || link.baseUrl,
- })!;
- }
-
- function injectNewGlobalState(
- link: ChromeNavLink,
- fromAppId: string,
- newGlobalState: string | string[]
- ) {
- const kibanaParsedUrl = absoluteToParsedUrl(
- getLastUrl(link) || link.url || link.baseUrl,
- chrome.getBasePath()
- );
-
- // don't copy global state if links are for different apps
- if (fromAppId !== kibanaParsedUrl.appId) return;
-
- kibanaParsedUrl.setGlobalState(newGlobalState);
-
- coreNavLinks.update(link.id, {
- url: kibanaParsedUrl.getAbsoluteUrl(),
- });
- }
-
- // simulate a possible change in url to initialize the
- // link.active and link.lastUrl properties
- coreNavLinks
- .getAll()
- .filter((link) => link.subUrlBase && !link.disableSubUrlTracking)
- .forEach((link) => {
- coreNavLinks.update(link.id, {
- subUrlBase: relativeToAbsolute(chrome.addBasePath(link.subUrlBase)),
- });
- });
-
- internals.trackPossibleSubUrl(document.location.href);
-}
diff --git a/src/legacy/ui/public/chrome/api/saved_object_client.ts b/src/legacy/ui/public/chrome/api/saved_object_client.ts
deleted file mode 100644
index 76d4e301e3c77..0000000000000
--- a/src/legacy/ui/public/chrome/api/saved_object_client.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npStart } from 'ui/new_platform';
-import { Chrome } from '..';
-
-const savedObjectsClient = npStart.core.savedObjects.client;
-
-export function initSavedObjectClient(chrome: Chrome) {
- chrome.getSavedObjectsClient = function () {
- return savedObjectsClient;
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/sub_url_hooks.js b/src/legacy/ui/public/chrome/api/sub_url_hooks.js
deleted file mode 100644
index f147aef7b4b7d..0000000000000
--- a/src/legacy/ui/public/chrome/api/sub_url_hooks.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { unhashUrl } from '../../../../../plugins/kibana_utils/public';
-import { toastNotifications } from '../../notify/toasts';
-import { npSetup } from '../../new_platform';
-import { areHashesDifferentButDecodedHashesEquals } from './sub_url_hooks_utils';
-
-export function registerSubUrlHooks(angularModule, internals) {
- angularModule.run(($rootScope, Private, $location) => {
- const subUrlRouteFilter = Private(SubUrlRouteFilterProvider);
-
- function updateSubUrls() {
- const urlWithHashes = window.location.href;
- let urlWithStates;
- try {
- urlWithStates = unhashUrl(urlWithHashes);
- } catch (e) {
- toastNotifications.addDanger(e.message);
- }
-
- internals.trackPossibleSubUrl(urlWithStates || urlWithHashes);
- }
-
- function onRouteChange($event) {
- if (subUrlRouteFilter($event)) {
- updateUsage($event);
- updateSubUrls();
- }
- }
-
- $rootScope.$on('$locationChangeStart', (e, newUrl) => {
- // This handler fixes issue #31238 where browser back navigation
- // fails due to angular 1.6 parsing url encoded params wrong.
- if (areHashesDifferentButDecodedHashesEquals($location.absUrl(), newUrl)) {
- // replace the urlencoded hash with the version that angular sees.
- const newHash = newUrl.split('#')[1] || '';
- $location.url(newHash).replace();
- }
- });
-
- $rootScope.$on('$routeChangeSuccess', onRouteChange);
- $rootScope.$on('$routeUpdate', onRouteChange);
- updateSubUrls();
- });
-}
-
-function updateUsage($event) {
- const scope = $event.targetScope;
- const app = scope.chrome.getApp();
- const appId = app.id === 'kibana' ? scope.getFirstPathSegment() : app.id;
- if (npSetup.plugins.usageCollection) npSetup.plugins.usageCollection.__LEGACY.appChanged(appId);
-}
-
-/**
- * Creates a function that will be called on each route change
- * to determine if the event should be used to update the last
- * subUrl of chrome links/tabs
- * @injected
- */
-export function SubUrlRouteFilterProvider($injector) {
- if (!$injector.has('$route')) {
- return function alwaysUpdate() {
- return true;
- };
- }
-
- const $route = $injector.get('$route');
- return function ignoreRedirectToRoutes() {
- return Boolean($route.current && !$route.current.redirectTo);
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts
deleted file mode 100644
index 4dec526302344..0000000000000
--- a/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.test.ts
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { areHashesDifferentButDecodedHashesEquals } from './sub_url_hooks_utils';
-
-test('false for different hashes', () => {
- const url1 = `https://localhost/kibana/#/dashboard/id`;
- const url2 = `https://localhost/kibana/#/dashboard/DIFFERENT`;
- expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeFalsy();
-});
-
-test('false for same hashes', () => {
- const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
- const url1 = `https://localhost/kibana/#/${hash}`;
- expect(areHashesDifferentButDecodedHashesEquals(url1, url1)).toBeFalsy();
-});
-
-test('true for same hashes, but one is encoded', () => {
- const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
- const url1 = `https://localhost/kibana/#/${hash}`;
- const url2 = `https://localhost/kibana/#/${encodeURIComponent(hash)}`;
- expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeTruthy();
-});
-
-/**
- * This edge case occurs when trying to navigate within kibana app using core's `navigateToApp` api
- * and there is reserved characters in hash (see: query:'' part)
- * For example:
- * ```ts
- * navigateToApp('kibana', {
- * path: '#/dashboard/f8bc19f0-6918-11ea-9258-a74c2ded064d?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))'
- * })
- * ```
- * Core internally is using url.parse which parses ' -> %27 and performs the navigation
- * Then angular decodes it back and causes redundant history record if not the fix which is covered by the test below
- */
-test("true for same hashes, but one has reserved character (') encoded", () => {
- const hash = `/dashboard/id?_a=(filters:!(),query:(language:kuery,query:''))&_g=(filters:!(),time:(from:now-120m,to:now))`;
- const url1 = `https://localhost/kibana/#/${hash}`;
- const url2 = `https://localhost/kibana/#/${hash.replace(/\'/g, '%27')}`;
- expect(areHashesDifferentButDecodedHashesEquals(url1, url2)).toBeTruthy();
-});
diff --git a/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts b/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts
deleted file mode 100644
index 8517877acd387..0000000000000
--- a/src/legacy/ui/public/chrome/api/sub_url_hooks_utils.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export function areHashesDifferentButDecodedHashesEquals(urlA: string, urlB: string): boolean {
- const getHash = (url: string) => url.split('#')[1] ?? '';
- const hashA = getHash(urlA);
- const decodedHashA = decodeURIComponent(hashA);
-
- const hashB = getHash(urlB);
- const decodedHashB = decodeURIComponent(hashB);
-
- return hashA !== hashB && decodedHashA === decodedHashB;
-}
diff --git a/src/legacy/ui/public/chrome/api/template.js b/src/legacy/ui/public/chrome/api/template.js
deleted file mode 100644
index d29a7eba7316f..0000000000000
--- a/src/legacy/ui/public/chrome/api/template.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// eslint-disable-next-line import/no-default-export
-export default function (chrome, internals) {
- /**
- * ui/chrome Template API
- *
- * Root Template
- * The root template is rendered within the primary chrome ui and should
- * be used when building an app that is more of a page, or to override the
- * placement of ng-view. When including a root template, the mark-up will
- * look something like this:
- *
- * body
- * notifs
- * div.content
- * nav
- * config
- * div.application
- * <-- your template here -->
- *
- * Root Controller
- * To attach a controller to the root of ui/chrome's content area, outside of
- * where it attaches the ng-view directive (assuming no rootTemplate is used)
- * which will allow cause the controller to persist across views or make for
- * a simple place to define some quick global functionality for a very simple
- * app (like the status page).
- */
-
- /**
- * @param {string} template
- * @return {chrome}
- */
- chrome.setRootTemplate = function (template) {
- internals.rootTemplate = template;
- return chrome;
- };
-
- /**
- * @param {string} as - the name that the controller should bind to
- * @param {Function} controller - the controller initializer function
- * @return {chrome}
- */
- chrome.setRootController = function (as, controllerName) {
- if (controllerName === undefined) {
- controllerName = as;
- as = null;
- }
-
- if (typeof controllerName === 'function') {
- chrome.$$rootControllerConstruct = controllerName;
- controllerName = 'chrome.$$rootControllerConstruct';
- }
-
- internals.rootController = controllerName + (as ? ' as ' + as : '');
- return chrome;
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/theme.test.mocks.ts b/src/legacy/ui/public/chrome/api/theme.test.mocks.ts
deleted file mode 100644
index 9e78805272b2d..0000000000000
--- a/src/legacy/ui/public/chrome/api/theme.test.mocks.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { chromeServiceMock } from '../../../../../core/public/mocks';
-
-export const newPlatformChrome = chromeServiceMock.createStartContract();
-jest.doMock('ui/new_platform', () => ({
- npStart: {
- core: { chrome: newPlatformChrome },
- },
-}));
diff --git a/src/legacy/ui/public/chrome/api/theme.test.ts b/src/legacy/ui/public/chrome/api/theme.test.ts
deleted file mode 100644
index 1e829329f9680..0000000000000
--- a/src/legacy/ui/public/chrome/api/theme.test.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-
-import { newPlatformChrome } from './theme.test.mocks';
-import { initChromeThemeApi } from './theme';
-
-function setup() {
- const brand$ = new Rx.BehaviorSubject({ logo: 'foo', smallLogo: 'foo' });
- newPlatformChrome.getBrand$.mockReturnValue(brand$);
-
- const applicationClasses$ = new Rx.BehaviorSubject([] as string[]);
- newPlatformChrome.getApplicationClasses$.mockReturnValue(applicationClasses$);
-
- const chrome: any = {};
- initChromeThemeApi(chrome);
- return { chrome, brand$, applicationClasses$ };
-}
-
-afterEach(() => {
- jest.resetAllMocks();
-});
-
-describe('setBrand', () => {
- it('proxies to newPlatformChrome', () => {
- const { chrome } = setup();
-
- chrome.setBrand({
- logo: 'foo.svg',
- smallLogo: 'smallFoo.svg',
- });
-
- chrome.setBrand({
- logo: 'baz',
- });
-
- expect(newPlatformChrome.setBrand.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [
- Object {
- "logo": "foo.svg",
- "smallLogo": "smallFoo.svg",
- },
- ],
- Array [
- Object {
- "logo": "baz",
- },
- ],
-]
-`);
- });
-});
-
-describe('getBrand', () => {
- it('returns named properties from cached values emitted from newPlatformChrome', () => {
- const { chrome, brand$ } = setup();
- expect(chrome.getBrand('logo')).toBe('foo');
- expect(chrome.getBrand('smallLogo')).toBe('foo');
- expect(chrome.getBrand()).toBe(undefined);
-
- brand$.next({
- logo: 'bar.svg',
- smallLogo: 'smallBar.svg',
- });
-
- expect(chrome.getBrand('logo')).toBe('bar.svg');
- expect(chrome.getBrand('smallLogo')).toBe('smallBar.svg');
- expect(chrome.getBrand()).toBe(undefined);
- });
-});
-
-describe('addApplicationClass', () => {
- it('proxies each class as a separate argument to newPlatformChrome', () => {
- const { chrome } = setup();
- chrome.addApplicationClass('foo');
- chrome.addApplicationClass(['bar', 'baz']);
- chrome.addApplicationClass([]);
- expect(newPlatformChrome.addApplicationClass.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [
- "foo",
- ],
- Array [
- "bar",
- ],
- Array [
- "baz",
- ],
-]
-`);
- });
-});
-
-describe('removeApplicationClass', () => {
- it('proxies each class as a separate argument to newPlatformChrome', () => {
- const { chrome } = setup();
- chrome.removeApplicationClass('foo');
- chrome.removeApplicationClass(['bar', 'baz']);
- chrome.removeApplicationClass([]);
- expect(newPlatformChrome.removeApplicationClass.mock.calls).toMatchInlineSnapshot(`
-Array [
- Array [
- "foo",
- ],
- Array [
- "bar",
- ],
- Array [
- "baz",
- ],
-]
-`);
- });
-});
-
-describe('getApplicationClasses', () => {
- it('returns cached values emitted from newPlatformChrome as a single string', () => {
- const { chrome, applicationClasses$ } = setup();
-
- expect(chrome.getApplicationClasses()).toBe('');
- applicationClasses$.next(['foo', 'bar']);
- expect(chrome.getApplicationClasses()).toBe('foo bar');
- applicationClasses$.next(['bar']);
- expect(chrome.getApplicationClasses()).toBe('bar');
- });
-});
diff --git a/src/legacy/ui/public/chrome/api/theme.ts b/src/legacy/ui/public/chrome/api/theme.ts
deleted file mode 100644
index c01344bf56fe3..0000000000000
--- a/src/legacy/ui/public/chrome/api/theme.ts
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import * as Rx from 'rxjs';
-
-import { npStart } from 'ui/new_platform';
-import { ChromeBrand } from '../../../../../core/public';
-
-const newPlatformChrome = npStart.core.chrome;
-
-export function initChromeThemeApi(chrome: { [key: string]: any }) {
- const brandCache$ = new Rx.BehaviorSubject({});
- newPlatformChrome.getBrand$().subscribe(brandCache$);
-
- const applicationClassesCache$ = new Rx.BehaviorSubject([]);
- newPlatformChrome.getApplicationClasses$().subscribe(applicationClassesCache$);
-
- chrome.setBrand = (brand: ChromeBrand) => {
- newPlatformChrome.setBrand(brand);
- return chrome;
- };
-
- chrome.getBrand = (key: keyof ChromeBrand) => {
- return brandCache$.getValue()[key];
- };
-
- chrome.addApplicationClass = (classNames: string | string[] = []) => {
- if (typeof classNames === 'string') {
- classNames = [classNames];
- }
-
- for (const className of classNames) {
- newPlatformChrome.addApplicationClass(className);
- }
-
- return chrome;
- };
-
- chrome.removeApplicationClass = (classNames: string | string[]) => {
- if (typeof classNames === 'string') {
- classNames = [classNames];
- }
-
- for (const className of classNames) {
- newPlatformChrome.removeApplicationClass(className);
- }
- return chrome;
- };
-
- chrome.getApplicationClasses = () => {
- return applicationClassesCache$.getValue().join(' ');
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/ui_settings.js b/src/legacy/ui/public/chrome/api/ui_settings.js
deleted file mode 100644
index dbdd6a9c12653..0000000000000
--- a/src/legacy/ui/public/chrome/api/ui_settings.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-
-const newPlatformUiSettingsClient = npSetup.core.uiSettings;
-
-export function initUiSettingsApi(chrome) {
- chrome.getUiSettingsClient = function () {
- return newPlatformUiSettingsClient;
- };
-}
diff --git a/src/legacy/ui/public/chrome/api/xsrf.js b/src/legacy/ui/public/chrome/api/xsrf.js
deleted file mode 100644
index 5086903604667..0000000000000
--- a/src/legacy/ui/public/chrome/api/xsrf.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export function initChromeXsrfApi(chrome, internals) {
- chrome.getXsrfToken = function () {
- return internals.version;
- };
-}
diff --git a/src/legacy/ui/public/chrome/chrome.js b/src/legacy/ui/public/chrome/chrome.js
deleted file mode 100644
index cdb0734f61622..0000000000000
--- a/src/legacy/ui/public/chrome/chrome.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import angular from 'angular';
-
-import { metadata } from '../metadata';
-import '../state_management/global_state';
-import '../config';
-import '../notify';
-import '../private';
-import '../promises';
-import '../directives/storage';
-import '../directives/watch_multi';
-import '../react_components';
-import '../i18n';
-
-import { initAngularApi } from './api/angular';
-import appsApi from './api/apps';
-import { initChromeControlsApi } from './api/controls';
-import { initChromeNavApi } from './api/nav';
-import { initChromeBadgeApi } from './api/badge';
-import { initBreadcrumbsApi } from './api/breadcrumbs';
-import templateApi from './api/template';
-import { initChromeThemeApi } from './api/theme';
-import { initChromeXsrfApi } from './api/xsrf';
-import { initUiSettingsApi } from './api/ui_settings';
-import { initLoadingCountApi } from './api/loading_count';
-import { initSavedObjectClient } from './api/saved_object_client';
-import { initChromeBasePathApi } from './api/base_path';
-import { initChromeInjectedVarsApi } from './api/injected_vars';
-import { initHelpExtensionApi } from './api/help_extension';
-import { npStart } from '../new_platform';
-
-export const chrome = {};
-const internals = _.defaults(_.cloneDeep(metadata), {
- basePath: '',
- rootController: null,
- rootTemplate: null,
- showAppsLink: null,
- xsrfToken: null,
- devMode: true,
- brand: null,
- nav: [],
- applicationClasses: [],
-});
-
-initUiSettingsApi(chrome);
-initSavedObjectClient(chrome);
-appsApi(chrome, internals);
-initChromeXsrfApi(chrome, internals);
-initChromeBasePathApi(chrome);
-initChromeInjectedVarsApi(chrome);
-initChromeNavApi(chrome, internals);
-initChromeBadgeApi(chrome);
-initBreadcrumbsApi(chrome, internals);
-initLoadingCountApi(chrome, internals);
-initHelpExtensionApi(chrome, internals);
-initAngularApi(chrome, internals);
-initChromeControlsApi(chrome);
-templateApi(chrome, internals);
-initChromeThemeApi(chrome);
-
-npStart.core.chrome.setAppTitle(chrome.getAppTitle());
-
-const waitForBootstrap = new Promise((resolve) => {
- chrome.bootstrap = function (targetDomElement) {
- // sets attribute on body for stylesheet sandboxing
- document.body.setAttribute('id', `${internals.app.id}-app`);
-
- chrome.setupAngular();
- targetDomElement.setAttribute('kbn-chrome', 'true');
- targetDomElement.setAttribute('ng-class', "{ 'hidden-chrome': !chrome.getVisible() }");
- targetDomElement.className = 'app-wrapper';
- angular.bootstrap(targetDomElement, ['kibana']);
- resolve(targetDomElement);
- };
-});
-
-/**
- * ---- ATTENTION: Read documentation carefully before using this! ----
- *
- * Returns a promise, that resolves with an instance of the currently used Angular
- * $injector service for usage outside of Angular.
- * You can use this injector to get access to any other injectable component (service,
- * constant, etc.) by using its get method.
- *
- * If you ever use Angular outside of an Angular context via this method, you should
- * be really sure you know what you are doing!
- *
- * When using this method inside your code, you will need to stub it while running
- * tests. Look into 'src/test_utils/public/stub_get_active_injector' for more information.
- */
-chrome.dangerouslyGetActiveInjector = () => {
- return waitForBootstrap.then((targetDomElement) => {
- const $injector = angular.element(targetDomElement).injector();
- if (!$injector) {
- return Promise.reject('targetDomElement had no angular context after bootstrapping');
- }
- return $injector;
- });
-};
diff --git a/src/legacy/ui/public/chrome/directives/index.js b/src/legacy/ui/public/chrome/directives/index.js
deleted file mode 100644
index 51d63f086e196..0000000000000
--- a/src/legacy/ui/public/chrome/directives/index.js
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { kbnChromeProvider } from './kbn_chrome';
-
-export function directivesProvider(chrome, internals) {
- kbnChromeProvider(chrome, internals);
-}
diff --git a/src/legacy/ui/public/chrome/directives/kbn_chrome.html b/src/legacy/ui/public/chrome/directives/kbn_chrome.html
deleted file mode 100644
index 7738093fe9dea..0000000000000
--- a/src/legacy/ui/public/chrome/directives/kbn_chrome.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
diff --git a/src/legacy/ui/public/chrome/directives/kbn_chrome.js b/src/legacy/ui/public/chrome/directives/kbn_chrome.js
deleted file mode 100644
index 5ba34e553201e..0000000000000
--- a/src/legacy/ui/public/chrome/directives/kbn_chrome.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-import $ from 'jquery';
-import { fatalError } from 'ui/notify/fatal_error';
-
-import { uiModules } from '../../modules';
-import template from './kbn_chrome.html';
-
-import { I18nContext } from '../../i18n';
-import { npStart } from '../../new_platform';
-import {
- chromeHeaderNavControlsRegistry,
- NavControlSide,
-} from '../../registry/chrome_header_nav_controls';
-import { subscribeWithScope } from '../../../../../plugins/kibana_legacy/public';
-
-export function kbnChromeProvider(chrome, internals) {
- uiModules.get('kibana').directive('kbnChrome', () => {
- return {
- template() {
- const $content = $(template);
- const $app = $content.find('.application');
-
- if (internals.rootController) {
- $app.attr('ng-controller', internals.rootController);
- }
-
- if (internals.rootTemplate) {
- $app.removeAttr('ng-view');
- $app.html(internals.rootTemplate);
- }
-
- return $content;
- },
-
- controllerAs: 'chrome',
- controller($scope, $location, Private) {
- $scope.getFirstPathSegment = () => {
- return $location.path().split('/')[1];
- };
-
- // Continue to support legacy nav controls not registered with the NP.
- const navControls = Private(chromeHeaderNavControlsRegistry);
- (navControls.bySide[NavControlSide.Left] || []).forEach((navControl) =>
- npStart.core.chrome.navControls.registerLeft({
- order: navControl.order,
- mount: navControl.render,
- })
- );
- (navControls.bySide[NavControlSide.Right] || []).forEach((navControl) =>
- npStart.core.chrome.navControls.registerRight({
- order: navControl.order,
- mount: navControl.render,
- })
- );
-
- // Non-scope based code (e.g., React)
-
- // Banners
- const bannerListContainer = document.getElementById('globalBannerList');
- if (bannerListContainer) {
- // This gets rendered manually by the legacy platform because this component must be inside the .app-wrapper
- ReactDOM.render(
- {npStart.core.overlays.banners.getComponent()} ,
- bannerListContainer
- );
- }
-
- const chromeVisibility = subscribeWithScope(
- $scope,
- chrome.visible$,
- {
- next: () => {
- // just makes sure change detection is triggered when chrome visibility changes
- },
- },
- fatalError
- );
- $scope.$on('$destroy', () => {
- chromeVisibility.unsubscribe();
- });
-
- return chrome;
- },
- };
- });
-}
diff --git a/src/legacy/ui/public/chrome/index.d.ts b/src/legacy/ui/public/chrome/index.d.ts
deleted file mode 100644
index b295746d92054..0000000000000
--- a/src/legacy/ui/public/chrome/index.d.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { SavedObjectsClientContract } from 'src/core/public';
-import { ChromeBrand } from '../../../../core/public';
-import { BadgeApi } from './api/badge';
-import { BreadcrumbsApi } from './api/breadcrumbs';
-import { HelpExtensionApi } from './api/help_extension';
-import { ChromeNavLinks } from './api/nav';
-
-export interface IInjector {
- get(injectable: string): T;
- invoke(
- injectable: (this: T2, ...args: any[]) => T,
- self?: T2,
- locals?: { [key: string]: any }
- ): T;
- instantiate(constructor: Function, locals?: { [key: string]: any }): any;
-}
-
-declare interface Chrome extends ChromeNavLinks {
- badge: BadgeApi;
- breadcrumbs: BreadcrumbsApi;
- helpExtension: HelpExtensionApi;
- addBasePath(path: T): T;
- dangerouslyGetActiveInjector(): Promise;
- getBasePath(): string;
- getXsrfToken(): string;
- getKibanaVersion(): string;
- getSavedObjectsClient(): SavedObjectsClientContract;
- getUiSettingsClient(): any;
- setVisible(visible: boolean): any;
- getInjected(key: string, defaultValue?: any): any;
- setRootController(name: string, Controller: any): any;
- setBrand(brand: ChromeBrand): this;
- getBrand(key: keyof ChromeBrand): ChromeBrand[keyof ChromeBrand];
- addApplicationClass(classNames: string | string[]): this;
- removeApplicationClass(classNames: string | string[]): this;
- getApplicationClasses(): string;
-}
-
-declare const chrome: Chrome;
-
-// eslint-disable-next-line import/no-default-export
-export default chrome;
-export { Chrome };
-export { Breadcrumb } from './api/breadcrumbs';
-export { HelpExtension } from './api/help_extension';
diff --git a/src/legacy/ui/public/chrome/index.js b/src/legacy/ui/public/chrome/index.js
deleted file mode 100644
index 3c6c3d2e74143..0000000000000
--- a/src/legacy/ui/public/chrome/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { chrome } from './chrome';
-
-// eslint-disable-next-line import/no-default-export
-export default chrome;
diff --git a/src/legacy/ui/public/config/__tests__/config.js b/src/legacy/ui/public/config/__tests__/config.js
deleted file mode 100644
index 90dbdaf264a29..0000000000000
--- a/src/legacy/ui/public/config/__tests__/config.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-import ngMock from 'ng_mock';
-import chrome from '../../chrome';
-
-describe('Config service', () => {
- let config;
- let uiSettings;
- let $q;
- let $rootScope;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(($injector) => {
- config = $injector.get('config');
- uiSettings = chrome.getUiSettingsClient();
- $q = $injector.get('$q');
- $rootScope = $injector.get('$rootScope');
- })
- );
-
- describe('#getAll', () => {
- it('calls uiSettings.getAll()', () => {
- sinon.stub(uiSettings, 'getAll');
- config.getAll();
- sinon.assert.calledOnce(uiSettings.getAll);
- sinon.assert.calledWithExactly(uiSettings.getAll);
- uiSettings.getAll.restore();
- });
- });
-
- describe('#get', () => {
- it('calls uiSettings.get(key, default)', () => {
- sinon.stub(uiSettings, 'get');
- config.get('key', 'default');
- sinon.assert.calledOnce(uiSettings.get);
- sinon.assert.calledWithExactly(uiSettings.get, 'key', 'default');
- uiSettings.get.restore();
- });
- });
-
- describe('#isDeclared', () => {
- it('calls uiSettings.isDeclared(key)', () => {
- sinon.stub(uiSettings, 'isDeclared');
- config.isDeclared('key');
- sinon.assert.calledOnce(uiSettings.isDeclared);
- sinon.assert.calledWithExactly(uiSettings.isDeclared, 'key');
- uiSettings.isDeclared.restore();
- });
- });
-
- describe('#isDefault', () => {
- it('calls uiSettings.isDefault(key)', () => {
- sinon.stub(uiSettings, 'isDefault');
- config.isDefault('key');
- sinon.assert.calledOnce(uiSettings.isDefault);
- sinon.assert.calledWithExactly(uiSettings.isDefault, 'key');
- uiSettings.isDefault.restore();
- });
- });
-
- describe('#isCustom', () => {
- it('calls uiSettings.isCustom(key)', () => {
- sinon.stub(uiSettings, 'isCustom');
- config.isCustom('key');
- sinon.assert.calledOnce(uiSettings.isCustom);
- sinon.assert.calledWithExactly(uiSettings.isCustom, 'key');
- });
- });
-
- describe('#remove', () => {
- it('calls uiSettings.remove(key)', () => {
- sinon.stub(uiSettings, 'remove');
- config.remove('foobar');
- sinon.assert.calledOnce(uiSettings.remove);
- sinon.assert.calledWithExactly(uiSettings.remove, 'foobar');
- uiSettings.remove.restore();
- });
-
- it('returns an angular promise', () => {
- const promise = config.remove('dateFormat:tz');
- expect(promise).to.be.a($q);
- });
- });
-
- describe('#set', () => {
- it('returns an angular promise', () => {
- const promise = config.set('dateFormat:tz', 'foo');
- expect(promise).to.be.a($q);
- });
-
- it('strips $$-prefixed properties from plain objects', () => {
- config.set('dateFormat:scaled', {
- foo: 'bar',
- $$bax: 'box',
- });
-
- expect(config.get('dateFormat:scaled')).to.eql({
- foo: 'bar',
- });
- });
- });
-
- describe('$scope events', () => {
- it('synchronously emits change:config on $rootScope when config changes', () => {
- const stub = sinon.stub();
- $rootScope.$on('change:config', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits change:config.${key} on $rootScope when config changes', () => {
- const stub = sinon.stub();
- $rootScope.$on('change:config.foobar', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits change:config on child scope when config changes', () => {
- const stub = sinon.stub();
- const $parent = $rootScope.$new(false);
- const $scope = $rootScope.$new(false, $parent);
- $scope.$on('change:config', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits change:config.${key} on child scope when config changes', () => {
- const stub = sinon.stub();
- const $parent = $rootScope.$new(false);
- const $scope = $rootScope.$new(false, $parent);
- $scope.$on('change:config.foobar', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits change:config on isolate scope when config changes', () => {
- const stub = sinon.stub();
- const $scope = $rootScope.$new(true);
- $scope.$on('change:config', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits change:config.${key} on isolate scope when config changes', () => {
- const stub = sinon.stub();
- const $scope = $rootScope.$new(true);
- $scope.$on('change:config.foobar', stub);
- config.set('foobar', 'baz');
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits events when changes are inside a digest cycle', async () => {
- const stub = sinon.stub();
-
- $rootScope.$apply(() => {
- $rootScope.$on('change:config.foobar', stub);
- config.set('foobar', 'baz');
- });
-
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
-
- it('synchronously emits events when changes are outside a digest cycle', async () => {
- const stub = sinon.stub();
-
- await new Promise((resolve) => {
- setTimeout(function () {
- const off = $rootScope.$on('change:config.foobar', stub);
- config.set('foobar', 'baz');
- // we unlisten to make sure that stub is not called before our assertions below
- off();
- resolve();
- }, 0);
- });
-
- sinon.assert.calledOnce(stub);
- sinon.assert.calledWithExactly(stub, sinon.match({}), 'baz', undefined, 'foobar', config);
- });
- });
-});
diff --git a/src/legacy/ui/public/config/config.js b/src/legacy/ui/public/config/config.js
deleted file mode 100644
index a8f24c126caff..0000000000000
--- a/src/legacy/ui/public/config/config.js
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import { fatalError } from 'ui/notify/fatal_error';
-import chrome from '../chrome';
-import { isPlainObject } from 'lodash';
-import { uiModules } from '../modules';
-import { subscribeWithScope } from '../../../../plugins/kibana_legacy/public';
-
-const module = uiModules.get('kibana/config');
-
-/**
- * Angular tie-in to UiSettingsClient, which is implemented in vanilla JS. Designed
- * to expose the exact same API as the config service that has existed since forever.
- * @name config
- */
-module.service(`config`, function ($rootScope, Promise) {
- const uiSettings = chrome.getUiSettingsClient();
-
- // direct bind sync methods
- this.getAll = (...args) => uiSettings.getAll(...args);
- this.get = (...args) => uiSettings.get(...args);
- this.isDeclared = (...args) => uiSettings.isDeclared(...args);
- this.isDefault = (...args) => uiSettings.isDefault(...args);
- this.isCustom = (...args) => uiSettings.isCustom(...args);
- this.isOverridden = (...args) => uiSettings.isOverridden(...args);
-
- // modify remove() to use angular Promises
- this.remove = (key) => Promise.resolve(uiSettings.remove(key));
-
- // modify set() to use angular Promises and angular.toJson()
- this.set = (key, value) =>
- Promise.resolve(uiSettings.set(key, isPlainObject(value) ? angular.toJson(value) : value));
-
- //////////////////////////////
- //* angular specific methods *
- //////////////////////////////
-
- const subscription = subscribeWithScope(
- $rootScope,
- uiSettings.getUpdate$(),
- {
- next: ({ key, newValue, oldValue }) => {
- $rootScope.$broadcast('change:config', newValue, oldValue, key, this);
- $rootScope.$broadcast(`change:config.${key}`, newValue, oldValue, key, this);
- },
- },
- fatalError
- );
- $rootScope.$on('$destroy', () => subscription.unsubscribe());
-
- this.watchAll = function (handler, scope = $rootScope) {
- // call handler immediately to initialize
- handler(null, null, null, this);
-
- return scope.$on('change:config', (event, ...args) => {
- handler(...args);
- });
- };
-
- this.watch = function (key, handler, scope = $rootScope) {
- if (!this.isDeclared(key)) {
- throw new Error(`Unexpected \`config.watch("${key}", fn)\` call on unrecognized configuration setting "${key}".
-Setting an initial value via \`config.set("${key}", value)\` before binding
-any custom setting configuration watchers for "${key}" may fix this issue.`);
- }
-
- // call handler immediately with current value
- handler(this.get(key), null, key, uiSettings);
-
- // call handler again on each change for this key
- return scope.$on(`change:config.${key}`, (event, ...args) => {
- handler(...args);
- });
- };
-
- /**
- * A little helper for binding config variables to $scopes
- *
- * @param {Scope} $scope - an angular $scope object
- * @param {string} key - the config key to bind to
- * @param {string} [property] - optional property name where the value should
- * be stored. Defaults to the config key
- * @return {function} - an unbind function
- */
- this.bindToScope = function (scope, key, property = key) {
- const onUpdate = (newVal) => {
- scope[property] = newVal;
- };
-
- return this.watch(key, onUpdate, scope);
- };
-});
diff --git a/src/legacy/ui/public/config/index.js b/src/legacy/ui/public/config/index.js
deleted file mode 100644
index 54602df57d65c..0000000000000
--- a/src/legacy/ui/public/config/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './config';
diff --git a/src/legacy/ui/public/directives/__tests__/input_focus.js b/src/legacy/ui/public/directives/__tests__/input_focus.js
deleted file mode 100644
index a9cd9b3c87974..0000000000000
--- a/src/legacy/ui/public/directives/__tests__/input_focus.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import $ from 'jquery';
-import '../input_focus';
-import uiRoutes from 'ui/routes';
-
-describe('Input focus directive', function () {
- let $compile;
- let $rootScope;
- let $timeout;
- let element;
- let $el;
- let selectedEl;
- let selectedText;
- const inputValue = 'Input Text Value';
-
- uiRoutes.enable();
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_$compile_, _$rootScope_, _$timeout_) {
- $compile = _$compile_;
- $rootScope = _$rootScope_;
- $timeout = _$timeout_;
-
- $el = $('');
- $el.appendTo('body');
- })
- );
-
- afterEach(function () {
- $el.remove();
- $el = null;
- });
-
- function renderEl(html) {
- $rootScope.value = inputValue;
- element = $compile(html)($rootScope);
- element.appendTo($el);
- $rootScope.$digest();
- $timeout.flush();
- selectedEl = document.activeElement;
- if (selectedEl.value) {
- selectedText = selectedEl.value.slice(selectedEl.selectionStart, selectedEl.selectionEnd);
- }
- }
-
- it('should focus the input', function () {
- renderEl('
');
- expect(selectedEl).to.equal(element[0]);
- expect(selectedText.length).to.equal(0);
- });
-
- it('should select the text in the input', function () {
- renderEl('
');
- expect(selectedEl).to.equal(element[0]);
- expect(selectedText.length).to.equal(inputValue.length);
- expect(selectedText).to.equal(inputValue);
- });
-
- it('should not focus the input if disable-input-focus is set to true on the same element', function () {
- renderEl('
');
- expect(selectedEl).not.to.be(element[0]);
- });
-
- it('should still focus the input if disable-input-focus is falsy', function () {
- renderEl('
');
- expect(selectedEl).to.be(element[0]);
- });
-});
diff --git a/src/legacy/ui/public/directives/_index.scss b/src/legacy/ui/public/directives/_index.scss
deleted file mode 100644
index 7ff5c9b9c540c..0000000000000
--- a/src/legacy/ui/public/directives/_index.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-@import './input_datetime';
-@import './saved_object_paginated_selectable'
diff --git a/src/legacy/ui/public/directives/_input_datetime.scss b/src/legacy/ui/public/directives/_input_datetime.scss
deleted file mode 100644
index 0704d70e9df1b..0000000000000
--- a/src/legacy/ui/public/directives/_input_datetime.scss
+++ /dev/null
@@ -1,5 +0,0 @@
-.input-datetime-format {
- font-size: $euiFontSizeXS;
- color: $euiColorMediumShade;
- padding: $euiSizeXS $euiSize;
-}
diff --git a/src/legacy/ui/public/directives/_saved_object_paginated_selectable.scss b/src/legacy/ui/public/directives/_saved_object_paginated_selectable.scss
deleted file mode 100644
index f8b5cdb440997..0000000000000
--- a/src/legacy/ui/public/directives/_saved_object_paginated_selectable.scss
+++ /dev/null
@@ -1,70 +0,0 @@
-saved-object-finder,
-paginated-selectable-list {
-
- .list-sort-button {
- border-top-left-radius: 0 !important;
- border-top-right-radius: 0 !important;
- border: none;
- padding: $euiSizeS $euiSize;
- font-weight: $euiFontWeightRegular;
- background-color: $euiColorLightestShade;
- }
-
- ul.li-striped {
- li {
- border: none;
- }
-
- li:nth-child(even) {
- background-color: $euiColorLightestShade;
- }
-
- li:nth-child(odd) {
- background-color: $euiColorEmptyShade;
- }
-
- .paginate-heading {
- font-weight: $euiFontWeightRegular;
- color: $euiColorDarkestShade;
- }
-
- .list-group-item {
- padding: $euiSizeS $euiSize;
-
- ul {
- padding: 0;
- display: flex;
- flex-direction: row;
-
- .finder-type {
- margin-right: $euiSizeS;
- }
- }
-
- a {
- display: block;
- color: $euiColorPrimary !important;
-
- i {
- color: shade($euiColorPrimary, 10%) !important;
- margin-right: $euiSizeS;
- }
- }
-
- &:first-child {
- border-top-left-radius: 0 !important;
- border-top-right-radius: 0 !important;
- }
-
- &.list-group-no-results p {
- margin-bottom: 0 !important;
- }
- }
- }
-
- paginate {
- paginate-controls {
- margin: $euiSize;
- }
- }
-}
diff --git a/src/legacy/ui/public/directives/bind/__tests__/bind.js b/src/legacy/ui/public/directives/bind/__tests__/bind.js
deleted file mode 100644
index 658a726e8c4cf..0000000000000
--- a/src/legacy/ui/public/directives/bind/__tests__/bind.js
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-describe('$scope.$bind', function () {
- let $rootScope;
- let $scope;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector) {
- $rootScope = $injector.get('$rootScope');
- $scope = $rootScope.$new();
- })
- );
-
- it('exposes $bind on all scopes', function () {
- expect($rootScope.$bind).to.be.a('function');
- expect($scope).to.have.property('$bind', $rootScope.$bind);
-
- const $isoScope = $scope.$new(true);
- expect($isoScope).to.have.property('$bind', $rootScope.$bind);
- });
-
- it("sets up binding from a parent scope to it's child", function () {
- $rootScope.val = 'foo';
- $scope.$bind('localVal', 'val');
- expect($scope.localVal).to.be('foo');
-
- $rootScope.val = 'bar';
- expect($scope.localVal).to.be('foo'); // shouldn't have changed yet
-
- $rootScope.$apply();
- expect($scope.localVal).to.be('bar');
- });
-
- it('sets up a binding from the child to the parent scope', function () {
- $rootScope.val = 'foo';
- $scope.$bind('localVal', 'val');
- expect($scope.localVal).to.be('foo');
-
- $scope.localVal = 'bar';
- expect($rootScope.val).to.be('foo'); // shouldn't have changed yet
-
- $scope.$apply();
- expect($rootScope.val).to.be('bar');
- });
-
- it('pulls from the scopes $parent by default', function () {
- const $parent = $rootScope.$new();
- const $self = $parent.$new();
-
- $parent.val = 'foo';
- $self.val = 'bar';
-
- $self.$bind('localVal', 'val');
- expect($self.localVal).to.be('foo');
- });
-
- it('accepts an alternate scope to read from', function () {
- const $parent = $rootScope.$new();
- const $self = $parent.$new();
-
- $parent.val = 'foo';
- $self.val = 'bar';
-
- $self.$bind('localVal', 'val', $self);
- expect($self.localVal).to.be('bar');
- });
-});
diff --git a/src/legacy/ui/public/directives/bind/bind.js b/src/legacy/ui/public/directives/bind/bind.js
deleted file mode 100644
index a9210cace5cea..0000000000000
--- a/src/legacy/ui/public/directives/bind/bind.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import { uiModules } from '../../modules';
-
-uiModules.get('kibana').config(function ($provide) {
- function strictEquality(a, b) {
- // are the values equal? or, are they both NaN?
- return a === b || (a !== a && b !== b);
- }
-
- function errorNotAssignable(source, target) {
- throw Error(
- 'Unable to accept change to bound $scope property "' +
- source +
- '"' +
- ' because source expression "' +
- target +
- '" is not assignable!'
- );
- }
-
- $provide.decorator('$rootScope', function ($delegate, $parse) {
- /**
- * Two-way bind a value from scope to another property on scope. This
- * allow values on scope that work like they do in an isolate scope, but
- * without requiring one.
- *
- * @param {expression} to - the location on scope to bind to
- * @param {expression} from - the location on scope to bind from
- * @param {Scope} $sourceScope - the scope to read "from" expression from
- * @return {undefined}
- */
- $delegate.constructor.prototype.$bind = function (to, from, $sourceScope) {
- const $source = $sourceScope || this.$parent;
- const $target = this;
-
- // parse expressions
- const $to = $parse(to);
- if (!$to.assign) errorNotAssignable(to, from);
- const $from = $parse(from);
-
- // bind scopes to expressions
- const getTarget = function () {
- return $to($target);
- };
- const setTarget = function (v) {
- return $to.assign($target, v);
- };
- const getSource = function () {
- return $from($source);
- };
- const setSource = function (v) {
- return $from.assignOrFail($source, v);
- };
-
- // to support writing from the child to the parent we need to know
- // which source has changed. Track the source value and anytime it
- // changes (even if the target value changed too) push from source
- // to target. If the source hasn't changed then the change is from
- // the target and push accordingly
- let lastSourceVal = getSource();
-
- $from.assignOrFail =
- $from.assign ||
- function () {
- // revert the change and throw an error, child writes aren't supported
- $to($target, (lastSourceVal = $from($source)));
- errorNotAssignable(from, to);
- };
-
- // if we are syncing down a literal, then we use loose equality check
- const strict = !$from.literal;
- const compare = strict ? strictEquality : angular.equals;
-
- // push the initial value down, start off in sync
- setTarget(lastSourceVal);
-
- $target.$watch(
- function () {
- const sourceVal = getSource();
- const targetVal = getTarget();
-
- const outOfSync = !compare(sourceVal, targetVal);
- const sourceChanged = outOfSync && !compare(sourceVal, lastSourceVal);
-
- if (sourceChanged) setTarget(sourceVal);
- else if (outOfSync) setSource(targetVal);
-
- return (lastSourceVal = sourceVal);
- },
- null,
- !strict
- );
- };
-
- return $delegate;
- });
-});
diff --git a/src/legacy/ui/public/directives/bind/index.js b/src/legacy/ui/public/directives/bind/index.js
deleted file mode 100644
index d542452d1a80f..0000000000000
--- a/src/legacy/ui/public/directives/bind/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './bind';
diff --git a/src/legacy/ui/public/directives/input_focus.js b/src/legacy/ui/public/directives/input_focus.js
deleted file mode 100644
index f047ff2547ba2..0000000000000
--- a/src/legacy/ui/public/directives/input_focus.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../modules';
-const module = uiModules.get('kibana');
-
-module.directive('inputFocus', function ($parse, $timeout) {
- return {
- restrict: 'A',
- link: function ($scope, $elem, attrs) {
- const isDisabled = attrs.disableInputFocus && $parse(attrs.disableInputFocus)($scope);
- if (!isDisabled) {
- $timeout(function () {
- $elem.focus();
- if (attrs.inputFocus === 'select') $elem.select();
- });
- }
- },
- };
-});
diff --git a/src/legacy/ui/public/directives/kbn_href.js b/src/legacy/ui/public/directives/kbn_href.js
deleted file mode 100644
index 5c71396e6c4de..0000000000000
--- a/src/legacy/ui/public/directives/kbn_href.js
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../modules';
-import { words, kebabCase } from 'lodash';
-
-export function kbnUrlDirective(name) {
- const attr = kebabCase(words(name).slice(1));
-
- uiModules.get('kibana').directive(name, function (chrome) {
- return {
- restrict: 'A',
- link: function ($scope, $el, $attr) {
- $attr.$observe(name, function (val) {
- $attr.$set(attr, chrome.addBasePath(val));
- });
- },
- };
- });
-}
-
-kbnUrlDirective('kbnHref');
diff --git a/src/legacy/ui/public/directives/listen/__tests__/listen.js b/src/legacy/ui/public/directives/listen/__tests__/listen.js
deleted file mode 100644
index 9a1d482956154..0000000000000
--- a/src/legacy/ui/public/directives/listen/__tests__/listen.js
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import '..';
-import { EventsProvider } from '../../../events';
-
-describe('listen component', function () {
- let $rootScope;
- let Events;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector, Private) {
- $rootScope = $injector.get('$rootScope');
- Events = Private(EventsProvider);
- })
- );
-
- it('exposes the $listen method on all scopes', function () {
- expect($rootScope.$listen).to.be.a('function');
- expect($rootScope.$new().$listen).to.be.a('function');
- });
-
- it('binds to an event emitter', function () {
- const emitter = new Events();
- const $scope = $rootScope.$new();
-
- function handler() {}
- $scope.$listen(emitter, 'hello', handler);
-
- expect(emitter._listeners.hello).to.have.length(1);
- expect(emitter._listeners.hello[0].handler).to.be(handler);
- });
-
- it('binds to $scope, waiting for the destroy event', function () {
- const emitter = new Events();
- const $scope = $rootScope.$new();
-
- sinon.stub($scope, '$on');
- sinon.stub($rootScope, '$on');
-
- function handler() {}
- $scope.$listen(emitter, 'hello', handler);
-
- expect($rootScope.$on).to.have.property('callCount', 0);
- expect($scope.$on).to.have.property('callCount', 1);
-
- const call = $scope.$on.firstCall;
- expect(call.args[0]).to.be('$destroy');
- expect(call.args[1]).to.be.a('function');
- });
-
- it('unbinds the event handler when $destroy is triggered', function () {
- const emitter = new Events();
- const $scope = $rootScope.$new();
-
- sinon.stub($scope, '$on');
- sinon.stub(emitter, 'off');
-
- // set the listener
- function handler() {}
- $scope.$listen(emitter, 'hello', handler);
-
- // get the unbinder that was registered to $scope
- const unbinder = $scope.$on.firstCall.args[1];
-
- // call the unbinder
- expect(emitter.off).to.have.property('callCount', 0);
- unbinder();
- expect(emitter.off).to.have.property('callCount', 1);
-
- // check that the off args were as expected
- const call = emitter.off.firstCall;
- expect(call.args[0]).to.be('hello');
- expect(call.args[1]).to.be(handler);
- });
-});
diff --git a/src/legacy/ui/public/directives/listen/index.js b/src/legacy/ui/public/directives/listen/index.js
deleted file mode 100644
index 6efc1b71431a2..0000000000000
--- a/src/legacy/ui/public/directives/listen/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './listen';
diff --git a/src/legacy/ui/public/directives/listen/listen.js b/src/legacy/ui/public/directives/listen/listen.js
deleted file mode 100644
index db19471fdb640..0000000000000
--- a/src/legacy/ui/public/directives/listen/listen.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../../modules';
-import { registerListenEventListener } from '../../../../../plugins/kibana_legacy/public';
-
-uiModules.get('kibana').run(registerListenEventListener);
diff --git a/src/legacy/ui/public/directives/render_directive/__tests__/render_directive.js b/src/legacy/ui/public/directives/render_directive/__tests__/render_directive.js
deleted file mode 100644
index a604eca52affe..0000000000000
--- a/src/legacy/ui/public/directives/render_directive/__tests__/render_directive.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import '..';
-
-let init;
-let $rootScope;
-let $compile;
-
-describe('render_directive', function () {
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector) {
- $rootScope = $injector.get('$rootScope');
- $compile = $injector.get('$compile');
- init = function init(markup = '', definition = {}) {
- const $parentScope = $rootScope;
-
- // create the markup
- const $elem = angular.element('
');
- $elem.html(markup);
- if (definition !== null) {
- $parentScope.definition = definition;
- $elem.attr('definition', 'definition');
- }
-
- // compile the directive
- $compile($elem)($parentScope);
- $parentScope.$apply();
-
- const $directiveScope = $elem.isolateScope();
-
- return { $parentScope, $directiveScope, $elem };
- };
- })
- );
-
- describe('directive requirements', function () {
- it('should throw if not given a definition', function () {
- expect(() => init('', null)).to.throwException(/must have a definition/);
- });
- });
-
- describe('rendering with definition', function () {
- it('should call link method', function () {
- const markup = 'hello world
';
- const definition = {
- link: sinon.stub(),
- };
-
- init(markup, definition);
-
- sinon.assert.callCount(definition.link, 1);
- });
-
- it('should call controller method', function () {
- const markup = 'hello world
';
- const definition = {
- controller: sinon.stub(),
- };
-
- init(markup, definition);
-
- sinon.assert.callCount(definition.controller, 1);
- });
- });
-
- describe('definition scope binding', function () {
- it('should accept two-way, attribute, and expression binding directives', function () {
- const $el = angular.element(`
-
- {{two}},{{attr}},{{expr()}}
-
- `);
-
- const $parentScope = $rootScope.$new();
- $parentScope.definition = {
- scope: {
- two: '=twoWayProp',
- attr: '@',
- expr: '&expr',
- },
- };
- $parentScope.parentTwoWay = true;
- $parentScope.parentExpression = function () {
- return !$parentScope.parentTwoWay;
- };
-
- $compile($el)($parentScope);
- $parentScope.$apply();
-
- expect($el.text().trim()).to.eql('true,Simple Attribute,false');
- $parentScope.parentTwoWay = false;
- $parentScope.$apply();
- expect($el.text().trim()).to.eql('false,Simple Attribute,true');
- });
- });
-});
diff --git a/src/legacy/ui/public/directives/render_directive/apply_scope_bindings.js b/src/legacy/ui/public/directives/render_directive/apply_scope_bindings.js
deleted file mode 100644
index 09948bda96b9f..0000000000000
--- a/src/legacy/ui/public/directives/render_directive/apply_scope_bindings.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { forOwn, noop } from 'lodash';
-
-import '../../directives/bind';
-
-const bindingRE = /^(=|=\?|&|@)([a-zA-Z0-9_$]+)?$/;
-
-export function ApplyScopeBindingsProvider($parse) {
- return function (bindings, $scope, $attrs) {
- forOwn(bindings, (binding, local) => {
- if (!bindingRE.test(binding)) {
- throw new Error(`Invalid scope binding "${binding}". Expected it to match ${bindingRE}`);
- }
-
- const [, type, attribute = local] = binding.match(bindingRE);
- const attr = $attrs[attribute];
- switch (type) {
- case '=':
- $scope.$bind(local, attr);
- break;
- case '=?':
- throw new Error(
- ' does not currently support optional two-way bindings.'
- );
- break;
- case '&':
- if (attr) {
- const getter = $parse(attr);
- $scope[local] = function () {
- return getter($scope.$parent);
- };
- } else {
- $scope[local] = noop;
- }
- break;
- case '@':
- $scope[local] = attr;
- $attrs.$observe(attribute, (v) => ($scope[local] = v));
- break;
- }
- });
- };
-}
diff --git a/src/legacy/ui/public/directives/render_directive/index.js b/src/legacy/ui/public/directives/render_directive/index.js
deleted file mode 100644
index 8c1f126dc48f0..0000000000000
--- a/src/legacy/ui/public/directives/render_directive/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './render_directive';
diff --git a/src/legacy/ui/public/directives/render_directive/render_directive.js b/src/legacy/ui/public/directives/render_directive/render_directive.js
deleted file mode 100644
index a5232f39b82c3..0000000000000
--- a/src/legacy/ui/public/directives/render_directive/render_directive.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { isPlainObject } from 'lodash';
-import { uiModules } from '../../modules';
-import { ApplyScopeBindingsProvider } from './apply_scope_bindings';
-
-/**
- * The directive is useful for programmatically modifying or
- * extending a view. It allows defining the majority of the directives behavior
- * using a "definition" object, which the implementer can obtain from plugins (for instance).
- *
- * The definition object supports the parts of a directive definition that are
- * easy enough to implement without having to hack angular, and does it's best to
- * make sure standard directive life-cycle timing is respected.
- *
- * @param [Object] definition - the external configuration for this directive to assume
- * @param [Function] definition.controller - a constructor used to create the controller for this directive
- * @param [String] definition.controllerAs - a name where the controller should be stored on scope
- * @param [Object] definition.scope - an object defining the binding properties for values read from
- * attributes and bound to $scope. The keys of this object are the
- * local names of $scope properties, and the values are a combination
- * of the binding style (=, @, or &) and the external attribute name.
- * See [the Angular docs]
- * (https://code.angularjs.org/1.4.9/docs/api/ng/service/$compile#-scope-)
- * for more info
- * @param [Object|Function] definition.link - either a post link function or an object with pre and/or
- * post link functions.
- */
-uiModules.get('kibana').directive('renderDirective', function (Private) {
- const applyScopeBindings = Private(ApplyScopeBindingsProvider);
-
- return {
- restrict: 'E',
- scope: {
- definition: '=',
- },
- template: function ($el) {
- return $el.html();
- },
- controller: function ($scope, $element, $attrs, $transclude, $injector) {
- if (!$scope.definition) throw new Error('render-directive must have a definition attribute');
-
- const { controller, controllerAs, scope } = $scope.definition;
-
- applyScopeBindings(scope, $scope, $attrs);
-
- if (controller) {
- if (controllerAs) {
- $scope[controllerAs] = this;
- }
-
- const locals = { $scope, $element, $attrs, $transclude };
- const controllerInstance = $injector.invoke(controller, this, locals) || this;
-
- if (controllerAs) {
- $scope[controllerAs] = controllerInstance;
- }
- }
- },
- link: {
- pre($scope, $el, $attrs, controller) {
- const { link } = $scope.definition;
- const preLink = isPlainObject(link) ? link.pre : null;
- if (preLink) preLink($scope, $el, $attrs, controller);
- },
- post($scope, $el, $attrs, controller) {
- const { link } = $scope.definition;
- const postLink = isPlainObject(link) ? link.post : link;
- if (postLink) postLink($scope, $el, $attrs, controller);
- },
- },
- };
-});
diff --git a/src/legacy/ui/public/directives/storage/index.js b/src/legacy/ui/public/directives/storage/index.js
deleted file mode 100644
index 7c195ecc85d2f..0000000000000
--- a/src/legacy/ui/public/directives/storage/index.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../../modules';
-import { Storage } from '../../../../../plugins/kibana_utils/public';
-
-const createService = function (type) {
- return function ($window) {
- return new Storage($window[type]);
- };
-};
-
-uiModules
- .get('kibana/storage')
- .service('localStorage', createService('localStorage'))
- .service('sessionStorage', createService('sessionStorage'));
diff --git a/src/legacy/ui/public/directives/watch_multi/__tests__/watch_multi.js b/src/legacy/ui/public/directives/watch_multi/__tests__/watch_multi.js
deleted file mode 100644
index 0de41a5ae57cb..0000000000000
--- a/src/legacy/ui/public/directives/watch_multi/__tests__/watch_multi.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import ngMock from 'ng_mock';
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-describe('$scope.$watchMulti', function () {
- let $rootScope;
- let $scope;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector) {
- $rootScope = $injector.get('$rootScope');
- $scope = $rootScope.$new();
- })
- );
-
- describe('basic functionality', function () {
- it('exposes $watchMulti on all scopes', function () {
- expect($rootScope.$watchMulti).to.be.a('function');
- expect($scope).to.have.property('$watchMulti', $rootScope.$watchMulti);
-
- const $isoScope = $scope.$new(true);
- expect($isoScope).to.have.property('$watchMulti', $rootScope.$watchMulti);
- });
-
- it('returns a working unwatch function', function () {
- $scope.a = 0;
- $scope.b = 0;
- let triggers = 0;
- const unwatch = $scope.$watchMulti(['a', 'b'], function () {
- triggers++;
- });
-
- // initial watch
- $scope.$apply();
- expect(triggers).to.be(1);
-
- // prove that it triggers on change
- $scope.a++;
- $scope.$apply();
- expect(triggers).to.be(2);
-
- // remove watchers
- expect($scope.$$watchers).to.not.have.length(0);
- unwatch();
- expect($scope.$$watchers).to.have.length(0);
-
- // prove that it doesn't trigger anymore
- $scope.a++;
- $scope.$apply();
- expect(triggers).to.be(2);
- });
- });
-
- describe('simple scope watchers', function () {
- it('only triggers a single watch on initialization', function () {
- const stub = sinon.stub();
-
- $scope.$watchMulti(['one', 'two', 'three'], stub);
- $rootScope.$apply();
-
- expect(stub.callCount).to.be(1);
- });
-
- it('only triggers a single watch when multiple values change', function () {
- const stub = sinon.spy(function () {});
-
- $scope.$watchMulti(['one', 'two', 'three'], stub);
-
- $rootScope.$apply();
- expect(stub.callCount).to.be(1);
-
- $scope.one = 'a';
- $scope.two = 'b';
- $scope.three = 'c';
- $rootScope.$apply();
-
- expect(stub.callCount).to.be(2);
- });
-
- it('passes an array of the current and previous values, in order', function () {
- const stub = sinon.spy(function () {});
-
- $scope.one = 'a';
- $scope.two = 'b';
- $scope.three = 'c';
- $scope.$watchMulti(['one', 'two', 'three'], stub);
-
- $rootScope.$apply();
- expect(stub.firstCall.args).to.eql([
- ['a', 'b', 'c'],
- ['a', 'b', 'c'],
- ]);
-
- $scope.one = 'do';
- $scope.two = 're';
- $scope.three = 'mi';
- $rootScope.$apply();
-
- expect(stub.secondCall.args).to.eql([
- ['do', 're', 'mi'],
- ['a', 'b', 'c'],
- ]);
- });
-
- it('always has an up to date value', function () {
- let count = 0;
-
- $scope.vals = [1, 0];
- $scope.$watchMulti(['vals[0]', 'vals[1]'], function (cur) {
- expect(cur).to.eql($scope.vals);
- count++;
- });
-
- const $child = $scope.$new();
- $child.$watch('vals[0]', function (cur) {
- $child.vals[1] = cur;
- });
-
- $rootScope.$apply();
- expect(count).to.be(2);
- });
- });
-
- describe('complex watch expressions', function () {
- let stateWatchers;
- let firstValue;
- let secondValue;
-
- beforeEach(function () {
- const firstGetter = function () {
- return firstValue;
- };
-
- const secondGetter = function () {
- return secondValue;
- };
-
- stateWatchers = [
- {
- fn: $rootScope.$watch,
- get: firstGetter,
- },
- {
- fn: $rootScope.$watch,
- get: secondGetter,
- },
- ];
- });
-
- it('should trigger the watcher on initialization', function () {
- const stub = sinon.stub();
- firstValue = 'first';
- secondValue = 'second';
-
- $scope.$watchMulti(stateWatchers, stub);
- $rootScope.$apply();
-
- expect(stub.callCount).to.be(1);
-
- expect(stub.firstCall.args[0]).to.eql([firstValue, secondValue]);
- expect(stub.firstCall.args[1]).to.eql([firstValue, secondValue]);
- });
- });
-
- describe('nested watchers', function () {
- it('should trigger the handler at least once', function () {
- const $scope = $rootScope.$new();
- $scope.$$watchers = [
- {
- get: _.noop,
- fn: _.noop,
- eq: false,
- last: false,
- },
- {
- get: _.noop,
- fn: registerWatchers,
- eq: false,
- last: false,
- },
- ];
-
- const first = sinon.stub();
- const second = sinon.stub();
-
- function registerWatchers() {
- $scope.$watchMulti([first, second], function () {
- expect(first.callCount).to.be.greaterThan(0);
- expect(second.callCount).to.be.greaterThan(0);
- });
- }
- $scope.$digest();
- });
- });
-});
diff --git a/src/legacy/ui/public/directives/watch_multi/index.js b/src/legacy/ui/public/directives/watch_multi/index.js
deleted file mode 100644
index 800bb503088d4..0000000000000
--- a/src/legacy/ui/public/directives/watch_multi/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../../modules';
-import { watchMultiDecorator } from '../../../../../plugins/kibana_legacy/public';
-uiModules.get('kibana').config(watchMultiDecorator);
diff --git a/src/legacy/ui/public/doc_title/__tests__/doc_title.js b/src/legacy/ui/public/doc_title/__tests__/doc_title.js
deleted file mode 100644
index fa8b83f755957..0000000000000
--- a/src/legacy/ui/public/doc_title/__tests__/doc_title.js
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import { docTitle } from '../doc_title';
-import { npStart } from '../../new_platform';
-
-describe('docTitle Service', function () {
- let initialDocTitle;
- const MAIN_TITLE = 'Kibana 4';
- let $rootScope;
-
- beforeEach(function () {
- initialDocTitle = document.title;
- document.title = MAIN_TITLE;
- npStart.core.chrome.docTitle.__legacy.setBaseTitle(MAIN_TITLE);
- });
- afterEach(function () {
- document.title = initialDocTitle;
- npStart.core.chrome.docTitle.__legacy.setBaseTitle(initialDocTitle);
- });
-
- beforeEach(
- ngMock.module('kibana', function ($provide) {
- $provide.decorator('$rootScope', decorateWithSpy('$on'));
- })
- );
-
- beforeEach(
- ngMock.inject(function ($injector) {
- $rootScope = $injector.get('$rootScope');
- })
- );
-
- describe('setup', function () {
- it('resets the title when a route change begins', function () {
- const spy = $rootScope.$on;
-
- const found = spy.args.some(function (args) {
- return args[0] === '$routeChangeStart' && args[1] === docTitle.reset;
- });
-
- if (!found) {
- throw new Error('$rootScope.$on not called');
- }
- });
- });
-
- describe('#reset', function () {
- it('clears the internal state', function () {
- docTitle.change('some title');
- expect(document.title).to.be('some title - ' + MAIN_TITLE);
-
- docTitle.reset();
- expect(document.title).to.be(MAIN_TITLE);
- });
- });
-
- describe('#change', function () {
- it('writes the first param to as the first part of the doc name', function () {
- expect(document.title).to.be(MAIN_TITLE);
- docTitle.change('some secondary title');
- expect(document.title).to.be('some secondary title - ' + MAIN_TITLE);
- });
- });
-
- function decorateWithSpy(prop) {
- return function ($delegate) {
- sinon.spy($delegate, prop);
- return $delegate;
- };
- }
-});
diff --git a/src/legacy/ui/public/doc_title/doc_title.d.ts b/src/legacy/ui/public/doc_title/doc_title.d.ts
deleted file mode 100644
index 8253a45850e19..0000000000000
--- a/src/legacy/ui/public/doc_title/doc_title.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export interface DocTitle {
- change: (title: string) => void;
-}
-
-export const docTitle: DocTitle;
diff --git a/src/legacy/ui/public/doc_title/doc_title.js b/src/legacy/ui/public/doc_title/doc_title.js
deleted file mode 100644
index 096e49e7a6de8..0000000000000
--- a/src/legacy/ui/public/doc_title/doc_title.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { isArray } from 'lodash';
-import { uiModules } from '../modules';
-import { npStart } from '../new_platform';
-
-const npDocTitle = () => npStart.core.chrome.docTitle;
-
-function change(title) {
- npDocTitle().change(isArray(title) ? title : [title]);
-}
-
-function reset() {
- npDocTitle().reset();
-}
-
-export const docTitle = {
- change,
- reset,
-};
-
-uiModules.get('kibana').run(function ($rootScope) {
- // always bind to the route events
- $rootScope.$on('$routeChangeStart', docTitle.reset);
-});
diff --git a/src/legacy/ui/public/doc_title/index.js b/src/legacy/ui/public/doc_title/index.js
deleted file mode 100644
index 1507797cc749c..0000000000000
--- a/src/legacy/ui/public/doc_title/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './doc_title';
-
-export { docTitle } from './doc_title';
diff --git a/src/legacy/ui/public/documentation_links/__mocks__/documentation_links.ts b/src/legacy/ui/public/documentation_links/__mocks__/documentation_links.ts
deleted file mode 100644
index 3fe123c3ccb80..0000000000000
--- a/src/legacy/ui/public/documentation_links/__mocks__/documentation_links.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { docLinksServiceMock } from '../../../../../core/public/mocks';
-
-const { DOC_LINK_VERSION, ELASTIC_WEBSITE_URL, links } = docLinksServiceMock.createStartContract();
-
-export { DOC_LINK_VERSION, ELASTIC_WEBSITE_URL };
-export const documentationLinks = links;
diff --git a/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js b/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js
deleted file mode 100644
index 6c9cdd12422cf..0000000000000
--- a/src/legacy/ui/public/documentation_links/__tests__/documentation_links.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import { documentationLinks } from '../documentation_links';
-import { metadata } from '../../metadata';
-
-const urlVersion = metadata.branch;
-
-describe('documentation link service', function () {
- it("should inject Kibana's major.minor version into doc links", function () {
- expect(documentationLinks.filebeat.configuration).to.contain(urlVersion);
- });
-});
diff --git a/src/legacy/ui/public/documentation_links/documentation_links.ts b/src/legacy/ui/public/documentation_links/documentation_links.ts
index 45aba1a5121fb..2520fb7180160 100644
--- a/src/legacy/ui/public/documentation_links/documentation_links.ts
+++ b/src/legacy/ui/public/documentation_links/documentation_links.ts
@@ -17,14 +17,12 @@
* under the License.
*/
-import { npStart } from 'ui/new_platform';
-
/*
WARNING: The links in this file are validated during the docs build. This is accomplished with some regex magic that
looks for these particular constants. As a result, we should not add new constants or change the existing ones.
If you absolutely must make a change, talk to Clinton Gormley first so he can update his Perl scripts.
*/
-export const DOC_LINK_VERSION = npStart.core.docLinks.DOC_LINK_VERSION;
-export const ELASTIC_WEBSITE_URL = npStart.core.docLinks.ELASTIC_WEBSITE_URL;
+export const DOC_LINK_VERSION = 'stub';
+export const ELASTIC_WEBSITE_URL = 'stub';
-export const documentationLinks = npStart.core.docLinks.links;
+export const documentationLinks = {};
diff --git a/src/legacy/ui/public/documentation_links/get_doc_link.ts b/src/legacy/ui/public/documentation_links/get_doc_link.ts
deleted file mode 100644
index 7d0d8033e3a5f..0000000000000
--- a/src/legacy/ui/public/documentation_links/get_doc_link.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { get } from 'lodash';
-import { documentationLinks } from './documentation_links';
-
-export const getDocLink = (id: string): string | undefined => get(documentationLinks, id);
diff --git a/src/legacy/ui/public/documentation_links/index.ts b/src/legacy/ui/public/documentation_links/index.ts
deleted file mode 100644
index 59499d3b8d9aa..0000000000000
--- a/src/legacy/ui/public/documentation_links/index.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { ELASTIC_WEBSITE_URL, DOC_LINK_VERSION, documentationLinks } from './documentation_links';
-
-export { getDocLink } from './get_doc_link';
diff --git a/src/legacy/ui/public/dom_location.js b/src/legacy/ui/public/dom_location.js
deleted file mode 100644
index baf03ba4c4b1c..0000000000000
--- a/src/legacy/ui/public/dom_location.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export function DomLocationProvider($window) {
- return {
- reload: function (forceFetch) {
- $window.location.reload(forceFetch);
- },
-
- get href() {
- return $window.location.href;
- },
-
- set href(val) {
- return ($window.location.href = val);
- },
- };
-}
diff --git a/src/legacy/ui/public/elastic_charts/index.ts b/src/legacy/ui/public/elastic_charts/index.ts
deleted file mode 100644
index 661ea693102a7..0000000000000
--- a/src/legacy/ui/public/elastic_charts/index.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import chrome from 'ui/chrome';
-import { Theme, LIGHT_THEME, DARK_THEME } from '@elastic/charts';
-
-export function getChartTheme(): Theme {
- const isDarkMode = chrome.getUiSettingsClient().get('theme:darkMode');
- return isDarkMode ? DARK_THEME : LIGHT_THEME;
-}
diff --git a/src/legacy/ui/public/events.js b/src/legacy/ui/public/events.js
deleted file mode 100644
index 464c03d98b83f..0000000000000
--- a/src/legacy/ui/public/events.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @name Events
- *
- * @extends EventEmitter
- */
-
-import _ from 'lodash';
-import { EventEmitter } from 'events';
-import { fatalError } from './notify';
-import { createLegacyClass } from './utils/legacy_class';
-import { createDefer } from 'ui/promises';
-
-const location = 'EventEmitter';
-
-export function EventsProvider(Promise) {
- createLegacyClass(Events).inherits(EventEmitter);
- function Events() {
- Events.Super.call(this);
- this._listeners = {};
- this._emitChain = Promise.resolve();
- }
-
- /**
- * Listens for events
- * @param {string} name - The name of the event
- * @param {function} handler - The function to call when the event is triggered
- * @return {Events} - this, for chaining
- */
- Events.prototype.on = function (name, handler) {
- if (!Array.isArray(this._listeners[name])) {
- this._listeners[name] = [];
- }
-
- const listener = {
- handler: handler,
- };
- this._listeners[name].push(listener);
-
- (function rebuildDefer() {
- listener.defer = createDefer(Promise);
- listener.resolved = listener.defer.promise.then(function (args) {
- rebuildDefer();
-
- // we ignore the completion of handlers, just watch for unhandled errors
- Promise.resolve(handler.apply(handler, args)).catch((error) => fatalError(error, location));
-
- // indicate to bluebird not to worry about this promise being a "runaway"
- return null;
- });
- })();
-
- return this;
- };
-
- /**
- * Removes an event listener
- * @param {string} [name] - The name of the event
- * @param {function} [handler] - The handler to remove
- * @return {Events} - this, for chaining
- */
- Events.prototype.off = function (name, handler) {
- if (!name && !handler) {
- this._listeners = {};
- return this.removeAllListeners();
- }
-
- // exit early if there is not an event that matches
- if (!this._listeners[name]) return this;
-
- // If no hander remove all the events
- if (!handler) {
- delete this._listeners[name];
- } else {
- this._listeners[name] = _.filter(this._listeners[name], function (listener) {
- return handler !== listener.handler;
- });
- }
-
- return this;
- };
-
- /**
- * Emits the event to all listeners
- *
- * @param {string} name - The name of the event.
- * @param {any} [value] - The value that will be passed to all event handlers.
- * @returns {Promise}
- */
- Events.prototype.emit = function (name) {
- const self = this;
- const args = _.tail(arguments);
-
- if (!self._listeners[name]) {
- return self._emitChain;
- }
-
- return Promise.map(self._listeners[name], function (listener) {
- return (self._emitChain = self._emitChain.then(function () {
- // Double check that off wasn't called after an emit, but before this is fired.
- if (!self._listeners[name] || self._listeners[name].indexOf(listener) < 0) return;
-
- listener.defer.resolve(args);
- return listener.resolved;
- }));
- });
- };
-
- /**
- * Get a list of the handler functions for a specific event
- *
- * @param {string} name
- * @return {array[function]}
- */
- Events.prototype.listeners = function (name) {
- return _.map(this._listeners[name], 'handler');
- };
-
- return Events;
-}
diff --git a/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap b/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap
deleted file mode 100644
index ad13256c8245a..0000000000000
--- a/src/legacy/ui/public/exit_full_screen/__snapshots__/exit_full_screen_button.test.js.snap
+++ /dev/null
@@ -1,53 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`is rendered 1`] = `
-
-
- In full screen mode, press ESC to exit.
-
-
-
-`;
diff --git a/src/legacy/ui/public/exit_full_screen/_index.scss b/src/legacy/ui/public/exit_full_screen/_index.scss
deleted file mode 100644
index 33dff05e2a687..0000000000000
--- a/src/legacy/ui/public/exit_full_screen/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
-@import '../../../../plugins/kibana_react/public/exit_full_screen_button/index';
diff --git a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.test.js b/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.test.js
deleted file mode 100644
index d4273c0fdb207..0000000000000
--- a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.test.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-jest.mock(
- 'ui/chrome',
- () => ({
- getKibanaVersion: () => '6.0.0',
- setVisible: () => {},
- }),
- { virtual: true }
-);
-
-import React from 'react';
-import { mountWithIntl, renderWithIntl } from 'test_utils/enzyme_helpers';
-import sinon from 'sinon';
-import chrome from 'ui/chrome';
-
-import { ExitFullScreenButton } from './exit_full_screen_button';
-
-import { keys } from '@elastic/eui';
-
-test('is rendered', () => {
- const component = renderWithIntl( {}} />);
-
- expect(component).toMatchSnapshot();
-});
-
-describe('onExitFullScreenMode', () => {
- test('is called when the button is pressed', () => {
- const onExitHandler = sinon.stub();
-
- const component = mountWithIntl( );
-
- component.find('button').simulate('click');
-
- sinon.assert.calledOnce(onExitHandler);
- });
-
- test('is called when the ESC key is pressed', () => {
- const onExitHandler = sinon.stub();
-
- mountWithIntl( );
-
- const escapeKeyEvent = new KeyboardEvent('keydown', { key: keys.ESCAPE });
- document.dispatchEvent(escapeKeyEvent);
-
- sinon.assert.calledOnce(onExitHandler);
- });
-});
-
-describe('chrome.setVisible', () => {
- test('is called with false when the component is rendered', () => {
- chrome.setVisible = sinon.stub();
-
- const component = mountWithIntl( {}} />);
-
- component.find('button').simulate('click');
-
- sinon.assert.calledOnce(chrome.setVisible);
- sinon.assert.calledWith(chrome.setVisible, false);
- });
-
- test('is called with true the component is unmounted', () => {
- const component = mountWithIntl( {}} />);
-
- chrome.setVisible = sinon.stub();
- component.unmount();
-
- sinon.assert.calledOnce(chrome.setVisible);
- sinon.assert.calledWith(chrome.setVisible, true);
- });
-});
diff --git a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx b/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx
deleted file mode 100644
index db4101010f6d6..0000000000000
--- a/src/legacy/ui/public/exit_full_screen/exit_full_screen_button.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React, { PureComponent } from 'react';
-import chrome from 'ui/chrome';
-import { ExitFullScreenButton as ExitFullScreenButtonUi } from '../../../../plugins/kibana_react/public';
-
-/**
- * DO NOT USE THIS COMPONENT, IT IS DEPRECATED.
- * Use the one in `src/plugins/kibana_react`.
- */
-
-interface Props {
- onExitFullScreenMode: () => void;
-}
-
-export class ExitFullScreenButton extends PureComponent {
- public UNSAFE_componentWillMount() {
- chrome.setVisible(false);
- }
-
- public componentWillUnmount() {
- chrome.setVisible(true);
- }
-
- public render() {
- return ;
- }
-}
diff --git a/src/legacy/ui/public/exit_full_screen/index.ts b/src/legacy/ui/public/exit_full_screen/index.ts
deleted file mode 100644
index a965fd776e0c2..0000000000000
--- a/src/legacy/ui/public/exit_full_screen/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { ExitFullScreenButton } from './exit_full_screen_button';
diff --git a/src/legacy/ui/public/flot-charts/API.md b/src/legacy/ui/public/flot-charts/API.md
deleted file mode 100644
index 699e2500f4942..0000000000000
--- a/src/legacy/ui/public/flot-charts/API.md
+++ /dev/null
@@ -1,1498 +0,0 @@
-# Flot Reference #
-
-**Table of Contents**
-
-[Introduction](#introduction)
-| [Data Format](#data-format)
-| [Plot Options](#plot-options)
-| [Customizing the legend](#customizing-the-legend)
-| [Customizing the axes](#customizing-the-axes)
-| [Multiple axes](#multiple-axes)
-| [Time series data](#time-series-data)
-| [Customizing the data series](#customizing-the-data-series)
-| [Customizing the grid](#customizing-the-grid)
-| [Specifying gradients](#specifying-gradients)
-| [Plot Methods](#plot-methods)
-| [Hooks](#hooks)
-| [Plugins](#plugins)
-| [Version number](#version-number)
-
----
-
-## Introduction ##
-
-Consider a call to the plot function:
-
-```js
-var plot = $.plot(placeholder, data, options)
-```
-
-The placeholder is a jQuery object or DOM element or jQuery expression
-that the plot will be put into. This placeholder needs to have its
-width and height set as explained in the [README](README.md) (go read that now if
-you haven't, it's short). The plot will modify some properties of the
-placeholder so it's recommended you simply pass in a div that you
-don't use for anything else. Make sure you check any fancy styling
-you apply to the div, e.g. background images have been reported to be a
-problem on IE 7.
-
-The plot function can also be used as a jQuery chainable property. This form
-naturally can't return the plot object directly, but you can still access it
-via the 'plot' data key, like this:
-
-```js
-var plot = $("#placeholder").plot(data, options).data("plot");
-```
-
-The format of the data is documented below, as is the available
-options. The plot object returned from the call has some methods you
-can call. These are documented separately below.
-
-Note that in general Flot gives no guarantees if you change any of the
-objects you pass in to the plot function or get out of it since
-they're not necessarily deep-copied.
-
-
-## Data Format ##
-
-The data is an array of data series:
-
-```js
-[ series1, series2, ... ]
-```
-
-A series can either be raw data or an object with properties. The raw
-data format is an array of points:
-
-```js
-[ [x1, y1], [x2, y2], ... ]
-```
-
-E.g.
-
-```js
-[ [1, 3], [2, 14.01], [3.5, 3.14] ]
-```
-
-Note that to simplify the internal logic in Flot both the x and y
-values must be numbers (even if specifying time series, see below for
-how to do this). This is a common problem because you might retrieve
-data from the database and serialize them directly to JSON without
-noticing the wrong type. If you're getting mysterious errors, double
-check that you're inputting numbers and not strings.
-
-If a null is specified as a point or if one of the coordinates is null
-or couldn't be converted to a number, the point is ignored when
-drawing. As a special case, a null value for lines is interpreted as a
-line segment end, i.e. the points before and after the null value are
-not connected.
-
-Lines and points take two coordinates. For filled lines and bars, you
-can specify a third coordinate which is the bottom of the filled
-area/bar (defaults to 0).
-
-The format of a single series object is as follows:
-
-```js
-{
- color: color or number
- data: rawdata
- label: string
- lines: specific lines options
- bars: specific bars options
- points: specific points options
- xaxis: number
- yaxis: number
- clickable: boolean
- hoverable: boolean
- shadowSize: number
- highlightColor: color or number
-}
-```
-
-You don't have to specify any of them except the data, the rest are
-options that will get default values. Typically you'd only specify
-label and data, like this:
-
-```js
-{
- label: "y = 3",
- data: [[0, 3], [10, 3]]
-}
-```
-
-The label is used for the legend, if you don't specify one, the series
-will not show up in the legend.
-
-If you don't specify color, the series will get a color from the
-auto-generated colors. The color is either a CSS color specification
-(like "rgb(255, 100, 123)") or an integer that specifies which of
-auto-generated colors to select, e.g. 0 will get color no. 0, etc.
-
-The latter is mostly useful if you let the user add and remove series,
-in which case you can hard-code the color index to prevent the colors
-from jumping around between the series.
-
-The "xaxis" and "yaxis" options specify which axis to use. The axes
-are numbered from 1 (default), so { yaxis: 2} means that the series
-should be plotted against the second y axis.
-
-"clickable" and "hoverable" can be set to false to disable
-interactivity for specific series if interactivity is turned on in
-the plot, see below.
-
-The rest of the options are all documented below as they are the same
-as the default options passed in via the options parameter in the plot
-command. When you specify them for a specific data series, they will
-override the default options for the plot for that data series.
-
-Here's a complete example of a simple data specification:
-
-```js
-[ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] },
- { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] }
-]
-```
-
-
-## Plot Options ##
-
-All options are completely optional. They are documented individually
-below, to change them you just specify them in an object, e.g.
-
-```js
-var options = {
- series: {
- lines: { show: true },
- points: { show: true }
- }
-};
-
-$.plot(placeholder, data, options);
-```
-
-
-## Customizing the legend ##
-
-```js
-legend: {
- show: boolean
- labelFormatter: null or (fn: string, series object -> string)
- labelBoxBorderColor: color
- noColumns: number
- position: "ne" or "nw" or "se" or "sw"
- margin: number of pixels or [x margin, y margin]
- backgroundColor: null or color
- backgroundOpacity: number between 0 and 1
- container: null or jQuery object/DOM element/jQuery expression
- sorted: null/false, true, "ascending", "descending", "reverse", or a comparator
-}
-```
-
-The legend is generated as a table with the data series labels and
-small label boxes with the color of the series. If you want to format
-the labels in some way, e.g. make them to links, you can pass in a
-function for "labelFormatter". Here's an example that makes them
-clickable:
-
-```js
-labelFormatter: function(label, series) {
- // series is the series object for the label
- return '' + label + ' ';
-}
-```
-
-To prevent a series from showing up in the legend, simply have the function
-return null.
-
-"noColumns" is the number of columns to divide the legend table into.
-"position" specifies the overall placement of the legend within the
-plot (top-right, top-left, etc.) and margin the distance to the plot
-edge (this can be either a number or an array of two numbers like [x,
-y]). "backgroundColor" and "backgroundOpacity" specifies the
-background. The default is a partly transparent auto-detected
-background.
-
-If you want the legend to appear somewhere else in the DOM, you can
-specify "container" as a jQuery object/expression to put the legend
-table into. The "position" and "margin" etc. options will then be
-ignored. Note that Flot will overwrite the contents of the container.
-
-Legend entries appear in the same order as their series by default. If "sorted"
-is "reverse" then they appear in the opposite order from their series. To sort
-them alphabetically, you can specify true, "ascending" or "descending", where
-true and "ascending" are equivalent.
-
-You can also provide your own comparator function that accepts two
-objects with "label" and "color" properties, and returns zero if they
-are equal, a positive value if the first is greater than the second,
-and a negative value if the first is less than the second.
-
-```js
-sorted: function(a, b) {
- // sort alphabetically in ascending order
- return a.label == b.label ? 0 : (
- a.label > b.label ? 1 : -1
- )
-}
-```
-
-
-## Customizing the axes ##
-
-```js
-xaxis, yaxis: {
- show: null or true/false
- position: "bottom" or "top" or "left" or "right"
- mode: null or "time" ("time" requires jquery.flot.time.js plugin)
- timezone: null, "browser" or timezone (only makes sense for mode: "time")
-
- color: null or color spec
- tickColor: null or color spec
- font: null or font spec object
-
- min: null or number
- max: null or number
- autoscaleMargin: null or number
-
- transform: null or fn: number -> number
- inverseTransform: null or fn: number -> number
-
- ticks: null or number or ticks array or (fn: axis -> ticks array)
- tickSize: number or array
- minTickSize: number or array
- tickFormatter: (fn: number, object -> string) or string
- tickDecimals: null or number
-
- labelWidth: null or number
- labelHeight: null or number
- reserveSpace: null or true
-
- tickLength: null or number
-
- alignTicksWithAxis: null or number
-}
-```
-
-All axes have the same kind of options. The following describes how to
-configure one axis, see below for what to do if you've got more than
-one x axis or y axis.
-
-If you don't set the "show" option (i.e. it is null), visibility is
-auto-detected, i.e. the axis will show up if there's data associated
-with it. You can override this by setting the "show" option to true or
-false.
-
-The "position" option specifies where the axis is placed, bottom or
-top for x axes, left or right for y axes. The "mode" option determines
-how the data is interpreted, the default of null means as decimal
-numbers. Use "time" for time series data; see the time series data
-section. The time plugin (jquery.flot.time.js) is required for time
-series support.
-
-The "color" option determines the color of the line and ticks for the axis, and
-defaults to the grid color with transparency. For more fine-grained control you
-can also set the color of the ticks separately with "tickColor".
-
-You can customize the font and color used to draw the axis tick labels with CSS
-or directly via the "font" option. When "font" is null - the default - each
-tick label is given the 'flot-tick-label' class. For compatibility with Flot
-0.7 and earlier the labels are also given the 'tickLabel' class, but this is
-deprecated and scheduled to be removed with the release of version 1.0.0.
-
-To enable more granular control over styles, labels are divided between a set
-of text containers, with each holding the labels for one axis. These containers
-are given the classes 'flot-[x|y]-axis', and 'flot-[x|y]#-axis', where '#' is
-the number of the axis when there are multiple axes. For example, the x-axis
-labels for a simple plot with only a single x-axis might look like this:
-
-```html
-
-```
-
-For direct control over label styles you can also provide "font" as an object
-with this format:
-
-```js
-{
- size: 11,
- lineHeight: 13,
- style: "italic",
- weight: "bold",
- family: "sans-serif",
- variant: "small-caps",
- color: "#545454"
-}
-```
-
-The size and lineHeight must be expressed in pixels; CSS units such as 'em'
-or 'smaller' are not allowed.
-
-The options "min"/"max" are the precise minimum/maximum value on the
-scale. If you don't specify either of them, a value will automatically
-be chosen based on the minimum/maximum data values. Note that Flot
-always examines all the data values you feed to it, even if a
-restriction on another axis may make some of them invisible (this
-makes interactive use more stable).
-
-The "autoscaleMargin" is a bit esoteric: it's the fraction of margin
-that the scaling algorithm will add to avoid that the outermost points
-ends up on the grid border. Note that this margin is only applied when
-a min or max value is not explicitly set. If a margin is specified,
-the plot will furthermore extend the axis end-point to the nearest
-whole tick. The default value is "null" for the x axes and 0.02 for y
-axes which seems appropriate for most cases.
-
-"transform" and "inverseTransform" are callbacks you can put in to
-change the way the data is drawn. You can design a function to
-compress or expand certain parts of the axis non-linearly, e.g.
-suppress weekends or compress far away points with a logarithm or some
-other means. When Flot draws the plot, each value is first put through
-the transform function. Here's an example, the x axis can be turned
-into a natural logarithm axis with the following code:
-
-```js
-xaxis: {
- transform: function (v) { return Math.log(v); },
- inverseTransform: function (v) { return Math.exp(v); }
-}
-```
-
-Similarly, for reversing the y axis so the values appear in inverse
-order:
-
-```js
-yaxis: {
- transform: function (v) { return -v; },
- inverseTransform: function (v) { return -v; }
-}
-```
-
-Note that for finding extrema, Flot assumes that the transform
-function does not reorder values (it should be monotone).
-
-The inverseTransform is simply the inverse of the transform function
-(so v == inverseTransform(transform(v)) for all relevant v). It is
-required for converting from canvas coordinates to data coordinates,
-e.g. for a mouse interaction where a certain pixel is clicked. If you
-don't use any interactive features of Flot, you may not need it.
-
-
-The rest of the options deal with the ticks.
-
-If you don't specify any ticks, a tick generator algorithm will make
-some for you. The algorithm has two passes. It first estimates how
-many ticks would be reasonable and uses this number to compute a nice
-round tick interval size. Then it generates the ticks.
-
-You can specify how many ticks the algorithm aims for by setting
-"ticks" to a number. The algorithm always tries to generate reasonably
-round tick values so even if you ask for three ticks, you might get
-five if that fits better with the rounding. If you don't want any
-ticks at all, set "ticks" to 0 or an empty array.
-
-Another option is to skip the rounding part and directly set the tick
-interval size with "tickSize". If you set it to 2, you'll get ticks at
-2, 4, 6, etc. Alternatively, you can specify that you just don't want
-ticks at a size less than a specific tick size with "minTickSize".
-Note that for time series, the format is an array like [2, "month"],
-see the next section.
-
-If you want to completely override the tick algorithm, you can specify
-an array for "ticks", either like this:
-
-```js
-ticks: [0, 1.2, 2.4]
-```
-
-Or like this where the labels are also customized:
-
-```js
-ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]]
-```
-
-You can mix the two if you like.
-
-For extra flexibility you can specify a function as the "ticks"
-parameter. The function will be called with an object with the axis
-min and max and should return a ticks array. Here's a simplistic tick
-generator that spits out intervals of pi, suitable for use on the x
-axis for trigonometric functions:
-
-```js
-function piTickGenerator(axis) {
- var res = [], i = Math.floor(axis.min / Math.PI);
- do {
- var v = i * Math.PI;
- res.push([v, i + "\u03c0"]);
- ++i;
- } while (v < axis.max);
- return res;
-}
-```
-
-You can control how the ticks look like with "tickDecimals", the
-number of decimals to display (default is auto-detected).
-
-Alternatively, for ultimate control over how ticks are formatted you can
-provide a function to "tickFormatter". The function is passed two
-parameters, the tick value and an axis object with information, and
-should return a string. The default formatter looks like this:
-
-```js
-function formatter(val, axis) {
- return val.toFixed(axis.tickDecimals);
-}
-```
-
-The axis object has "min" and "max" with the range of the axis,
-"tickDecimals" with the number of decimals to round the value to and
-"tickSize" with the size of the interval between ticks as calculated
-by the automatic axis scaling algorithm (or specified by you). Here's
-an example of a custom formatter:
-
-```js
-function suffixFormatter(val, axis) {
- if (val > 1000000)
- return (val / 1000000).toFixed(axis.tickDecimals) + " MB";
- else if (val > 1000)
- return (val / 1000).toFixed(axis.tickDecimals) + " kB";
- else
- return val.toFixed(axis.tickDecimals) + " B";
-}
-```
-
-"labelWidth" and "labelHeight" specifies a fixed size of the tick
-labels in pixels. They're useful in case you need to align several
-plots. "reserveSpace" means that even if an axis isn't shown, Flot
-should reserve space for it - it is useful in combination with
-labelWidth and labelHeight for aligning multi-axis charts.
-
-"tickLength" is the length of the tick lines in pixels. By default, the
-innermost axes will have ticks that extend all across the plot, while
-any extra axes use small ticks. A value of null means use the default,
-while a number means small ticks of that length - set it to 0 to hide
-the lines completely.
-
-If you set "alignTicksWithAxis" to the number of another axis, e.g.
-alignTicksWithAxis: 1, Flot will ensure that the autogenerated ticks
-of this axis are aligned with the ticks of the other axis. This may
-improve the looks, e.g. if you have one y axis to the left and one to
-the right, because the grid lines will then match the ticks in both
-ends. The trade-off is that the forced ticks won't necessarily be at
-natural places.
-
-
-## Multiple axes ##
-
-If you need more than one x axis or y axis, you need to specify for
-each data series which axis they are to use, as described under the
-format of the data series, e.g. { data: [...], yaxis: 2 } specifies
-that a series should be plotted against the second y axis.
-
-To actually configure that axis, you can't use the xaxis/yaxis options
-directly - instead there are two arrays in the options:
-
-```js
-xaxes: []
-yaxes: []
-```
-
-Here's an example of configuring a single x axis and two y axes (we
-can leave options of the first y axis empty as the defaults are fine):
-
-```js
-{
- xaxes: [ { position: "top" } ],
- yaxes: [ { }, { position: "right", min: 20 } ]
-}
-```
-
-The arrays get their default values from the xaxis/yaxis settings, so
-say you want to have all y axes start at zero, you can simply specify
-yaxis: { min: 0 } instead of adding a min parameter to all the axes.
-
-Generally, the various interfaces in Flot dealing with data points
-either accept an xaxis/yaxis parameter to specify which axis number to
-use (starting from 1), or lets you specify the coordinate directly as
-x2/x3/... or x2axis/x3axis/... instead of "x" or "xaxis".
-
-
-## Time series data ##
-
-Please note that it is now required to include the time plugin,
-jquery.flot.time.js, for time series support.
-
-Time series are a bit more difficult than scalar data because
-calendars don't follow a simple base 10 system. For many cases, Flot
-abstracts most of this away, but it can still be a bit difficult to
-get the data into Flot. So we'll first discuss the data format.
-
-The time series support in Flot is based on JavaScript timestamps,
-i.e. everywhere a time value is expected or handed over, a JavaScript
-timestamp number is used. This is a number, not a Date object. A
-JavaScript timestamp is the number of milliseconds since January 1,
-1970 00:00:00 UTC. This is almost the same as Unix timestamps, except it's
-in milliseconds, so remember to multiply by 1000!
-
-You can see a timestamp like this
-
-```js
-alert((new Date()).getTime())
-```
-
-There are different schools of thought when it comes to display of
-timestamps. Many will want the timestamps to be displayed according to
-a certain time zone, usually the time zone in which the data has been
-produced. Some want the localized experience, where the timestamps are
-displayed according to the local time of the visitor. Flot supports
-both. Optionally you can include a third-party library to get
-additional timezone support.
-
-Default behavior is that Flot always displays timestamps according to
-UTC. The reason being that the core JavaScript Date object does not
-support other fixed time zones. Often your data is at another time
-zone, so it may take a little bit of tweaking to work around this
-limitation.
-
-The easiest way to think about it is to pretend that the data
-production time zone is UTC, even if it isn't. So if you have a
-datapoint at 2002-02-20 08:00, you can generate a timestamp for eight
-o'clock UTC even if it really happened eight o'clock UTC+0200.
-
-In PHP you can get an appropriate timestamp with:
-
-```php
-strtotime("2002-02-20 UTC") * 1000
-```
-
-In Python you can get it with something like:
-
-```python
-calendar.timegm(datetime_object.timetuple()) * 1000
-```
-In Ruby you can get it using the `#to_i` method on the
-[`Time`](http://apidock.com/ruby/Time/to_i) object. If you're using the
-`active_support` gem (default for Ruby on Rails applications) `#to_i` is also
-available on the `DateTime` and `ActiveSupport::TimeWithZone` objects. You
-simply need to multiply the result by 1000:
-
-```ruby
-Time.now.to_i * 1000 # => 1383582043000
-# ActiveSupport examples:
-DateTime.now.to_i * 1000 # => 1383582043000
-ActiveSupport::TimeZone.new('Asia/Shanghai').now.to_i * 1000
-# => 1383582043000
-```
-
-In .NET you can get it with something like:
-
-```aspx
-public static int GetJavaScriptTimestamp(System.DateTime input)
-{
- System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks);
- System.DateTime time = input.Subtract(span);
- return (long)(time.Ticks / 10000);
-}
-```
-
-JavaScript also has some support for parsing date strings, so it is
-possible to generate the timestamps manually client-side.
-
-If you've already got the real UTC timestamp, it's too late to use the
-pretend trick described above. But you can fix up the timestamps by
-adding the time zone offset, e.g. for UTC+0200 you would add 2 hours
-to the UTC timestamp you got. Then it'll look right on the plot. Most
-programming environments have some means of getting the timezone
-offset for a specific date (note that you need to get the offset for
-each individual timestamp to account for daylight savings).
-
-The alternative with core JavaScript is to interpret the timestamps
-according to the time zone that the visitor is in, which means that
-the ticks will shift with the time zone and daylight savings of each
-visitor. This behavior is enabled by setting the axis option
-"timezone" to the value "browser".
-
-If you need more time zone functionality than this, there is still
-another option. If you include the "timezone-js" library
- in the page and set axis.timezone
-to a value recognized by said library, Flot will use timezone-js to
-interpret the timestamps according to that time zone.
-
-Once you've gotten the timestamps into the data and specified "time"
-as the axis mode, Flot will automatically generate relevant ticks and
-format them. As always, you can tweak the ticks via the "ticks" option
-- just remember that the values should be timestamps (numbers), not
-Date objects.
-
-Tick generation and formatting can also be controlled separately
-through the following axis options:
-
-```js
-minTickSize: array
-timeformat: null or format string
-monthNames: null or array of size 12 of strings
-dayNames: null or array of size 7 of strings
-twelveHourClock: boolean
-```
-
-Here "timeformat" is a format string to use. You might use it like
-this:
-
-```js
-xaxis: {
- mode: "time",
- timeformat: "%Y/%m/%d"
-}
-```
-
-This will result in tick labels like "2000/12/24". A subset of the
-standard strftime specifiers are supported (plus the nonstandard %q):
-
-```js
-%a: weekday name (customizable)
-%b: month name (customizable)
-%d: day of month, zero-padded (01-31)
-%e: day of month, space-padded ( 1-31)
-%H: hours, 24-hour time, zero-padded (00-23)
-%I: hours, 12-hour time, zero-padded (01-12)
-%m: month, zero-padded (01-12)
-%M: minutes, zero-padded (00-59)
-%q: quarter (1-4)
-%S: seconds, zero-padded (00-59)
-%y: year (two digits)
-%Y: year (four digits)
-%p: am/pm
-%P: AM/PM (uppercase version of %p)
-%w: weekday as number (0-6, 0 being Sunday)
-```
-
-Flot 0.8 switched from %h to the standard %H hours specifier. The %h specifier
-is still available, for backwards-compatibility, but is deprecated and
-scheduled to be removed permanently with the release of version 1.0.
-
-You can customize the month names with the "monthNames" option. For
-instance, for Danish you might specify:
-
-```js
-monthNames: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
-```
-
-Similarly you can customize the weekday names with the "dayNames"
-option. An example in French:
-
-```js
-dayNames: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"]
-```
-
-If you set "twelveHourClock" to true, the autogenerated timestamps
-will use 12 hour AM/PM timestamps instead of 24 hour. This only
-applies if you have not set "timeformat". Use the "%I" and "%p" or
-"%P" options if you want to build your own format string with 12-hour
-times.
-
-If the Date object has a strftime property (and it is a function), it
-will be used instead of the built-in formatter. Thus you can include
-a strftime library such as http://hacks.bluesmoon.info/strftime/ for
-more powerful date/time formatting.
-
-If everything else fails, you can control the formatting by specifying
-a custom tick formatter function as usual. Here's a simple example
-which will format December 24 as 24/12:
-
-```js
-tickFormatter: function (val, axis) {
- var d = new Date(val);
- return d.getUTCDate() + "/" + (d.getUTCMonth() + 1);
-}
-```
-
-Note that for the time mode "tickSize" and "minTickSize" are a bit
-special in that they are arrays on the form "[value, unit]" where unit
-is one of "second", "minute", "hour", "day", "month" and "year". So
-you can specify
-
-```js
-minTickSize: [1, "month"]
-```
-
-to get a tick interval size of at least 1 month and correspondingly,
-if axis.tickSize is [2, "day"] in the tick formatter, the ticks have
-been produced with two days in-between.
-
-
-## Customizing the data series ##
-
-```js
-series: {
- lines, points, bars: {
- show: boolean
- lineWidth: number
- fill: boolean or number
- fillColor: null or color/gradient
- }
-
- lines, bars: {
- zero: boolean
- }
-
- points: {
- radius: number
- symbol: "circle" or function
- }
-
- bars: {
- barWidth: number
- align: "left", "right" or "center"
- horizontal: boolean
- }
-
- lines: {
- steps: boolean
- }
-
- shadowSize: number
- highlightColor: color or number
-}
-
-colors: [ color1, color2, ... ]
-```
-
-The options inside "series: {}" are copied to each of the series. So
-you can specify that all series should have bars by putting it in the
-global options, or override it for individual series by specifying
-bars in a particular the series object in the array of data.
-
-The most important options are "lines", "points" and "bars" that
-specify whether and how lines, points and bars should be shown for
-each data series. In case you don't specify anything at all, Flot will
-default to showing lines (you can turn this off with
-lines: { show: false }). You can specify the various types
-independently of each other, and Flot will happily draw each of them
-in turn (this is probably only useful for lines and points), e.g.
-
-```js
-var options = {
- series: {
- lines: { show: true, fill: true, fillColor: "rgba(255, 255, 255, 0.8)" },
- points: { show: true, fill: false }
- }
-};
-```
-
-"lineWidth" is the thickness of the line or outline in pixels. You can
-set it to 0 to prevent a line or outline from being drawn; this will
-also hide the shadow.
-
-"fill" is whether the shape should be filled. For lines, this produces
-area graphs. You can use "fillColor" to specify the color of the fill.
-If "fillColor" evaluates to false (default for everything except
-points which are filled with white), the fill color is auto-set to the
-color of the data series. You can adjust the opacity of the fill by
-setting fill to a number between 0 (fully transparent) and 1 (fully
-opaque).
-
-For bars, fillColor can be a gradient, see the gradient documentation
-below. "barWidth" is the width of the bars in units of the x axis (or
-the y axis if "horizontal" is true), contrary to most other measures
-that are specified in pixels. For instance, for time series the unit
-is milliseconds so 24 * 60 * 60 * 1000 produces bars with the width of
-a day. "align" specifies whether a bar should be left-aligned
-(default), right-aligned or centered on top of the value it represents.
-When "horizontal" is on, the bars are drawn horizontally, i.e. from the
-y axis instead of the x axis; note that the bar end points are still
-defined in the same way so you'll probably want to swap the
-coordinates if you've been plotting vertical bars first.
-
-Area and bar charts normally start from zero, regardless of the data's range.
-This is because they convey information through size, and starting from a
-different value would distort their meaning. In cases where the fill is purely
-for decorative purposes, however, "zero" allows you to override this behavior.
-It defaults to true for filled lines and bars; setting it to false tells the
-series to use the same automatic scaling as an un-filled line.
-
-For lines, "steps" specifies whether two adjacent data points are
-connected with a straight (possibly diagonal) line or with first a
-horizontal and then a vertical line. Note that this transforms the
-data by adding extra points.
-
-For points, you can specify the radius and the symbol. The only
-built-in symbol type is circles, for other types you can use a plugin
-or define them yourself by specifying a callback:
-
-```js
-function cross(ctx, x, y, radius, shadow) {
- var size = radius * Math.sqrt(Math.PI) / 2;
- ctx.moveTo(x - size, y - size);
- ctx.lineTo(x + size, y + size);
- ctx.moveTo(x - size, y + size);
- ctx.lineTo(x + size, y - size);
-}
-```
-
-The parameters are the drawing context, x and y coordinates of the
-center of the point, a radius which corresponds to what the circle
-would have used and whether the call is to draw a shadow (due to
-limited canvas support, shadows are currently faked through extra
-draws). It's good practice to ensure that the area covered by the
-symbol is the same as for the circle with the given radius, this
-ensures that all symbols have approximately the same visual weight.
-
-"shadowSize" is the default size of shadows in pixels. Set it to 0 to
-remove shadows.
-
-"highlightColor" is the default color of the translucent overlay used
-to highlight the series when the mouse hovers over it.
-
-The "colors" array specifies a default color theme to get colors for
-the data series from. You can specify as many colors as you like, like
-this:
-
-```js
-colors: ["#d18b2c", "#dba255", "#919733"]
-```
-
-If there are more data series than colors, Flot will try to generate
-extra colors by lightening and darkening colors in the theme.
-
-
-## Customizing the grid ##
-
-```js
-grid: {
- show: boolean
- aboveData: boolean
- color: color
- backgroundColor: color/gradient or null
- margin: number or margin object
- labelMargin: number
- axisMargin: number
- markings: array of markings or (fn: axes -> array of markings)
- borderWidth: number or object with "top", "right", "bottom" and "left" properties with different widths
- borderColor: color or null or object with "top", "right", "bottom" and "left" properties with different colors
- minBorderMargin: number or null
- clickable: boolean
- hoverable: boolean
- autoHighlight: boolean
- mouseActiveRadius: number
-}
-
-interaction: {
- redrawOverlayInterval: number or -1
-}
-```
-
-The grid is the thing with the axes and a number of ticks. Many of the
-things in the grid are configured under the individual axes, but not
-all. "color" is the color of the grid itself whereas "backgroundColor"
-specifies the background color inside the grid area, here null means
-that the background is transparent. You can also set a gradient, see
-the gradient documentation below.
-
-You can turn off the whole grid including tick labels by setting
-"show" to false. "aboveData" determines whether the grid is drawn
-above the data or below (below is default).
-
-"margin" is the space in pixels between the canvas edge and the grid,
-which can be either a number or an object with individual margins for
-each side, in the form:
-
-```js
-margin: {
- top: top margin in pixels
- left: left margin in pixels
- bottom: bottom margin in pixels
- right: right margin in pixels
-}
-```
-
-"labelMargin" is the space in pixels between tick labels and axis
-line, and "axisMargin" is the space in pixels between axes when there
-are two next to each other.
-
-"borderWidth" is the width of the border around the plot. Set it to 0
-to disable the border. Set it to an object with "top", "right",
-"bottom" and "left" properties to use different widths. You can
-also set "borderColor" if you want the border to have a different color
-than the grid lines. Set it to an object with "top", "right", "bottom"
-and "left" properties to use different colors. "minBorderMargin" controls
-the default minimum margin around the border - it's used to make sure
-that points aren't accidentally clipped by the canvas edge so by default
-the value is computed from the point radius.
-
-"markings" is used to draw simple lines and rectangular areas in the
-background of the plot. You can either specify an array of ranges on
-the form { xaxis: { from, to }, yaxis: { from, to } } (with multiple
-axes, you can specify coordinates for other axes instead, e.g. as
-x2axis/x3axis/...) or with a function that returns such an array given
-the axes for the plot in an object as the first parameter.
-
-You can set the color of markings by specifying "color" in the ranges
-object. Here's an example array:
-
-```js
-markings: [ { xaxis: { from: 0, to: 2 }, yaxis: { from: 10, to: 10 }, color: "#bb0000" }, ... ]
-```
-
-If you leave out one of the values, that value is assumed to go to the
-border of the plot. So for example if you only specify { xaxis: {
-from: 0, to: 2 } } it means an area that extends from the top to the
-bottom of the plot in the x range 0-2.
-
-A line is drawn if from and to are the same, e.g.
-
-```js
-markings: [ { yaxis: { from: 1, to: 1 } }, ... ]
-```
-
-would draw a line parallel to the x axis at y = 1. You can control the
-line width with "lineWidth" in the range object.
-
-An example function that makes vertical stripes might look like this:
-
-```js
-markings: function (axes) {
- var markings = [];
- for (var x = Math.floor(axes.xaxis.min); x < axes.xaxis.max; x += 2)
- markings.push({ xaxis: { from: x, to: x + 1 } });
- return markings;
-}
-```
-
-If you set "clickable" to true, the plot will listen for click events
-on the plot area and fire a "plotclick" event on the placeholder with
-a position and a nearby data item object as parameters. The coordinates
-are available both in the unit of the axes (not in pixels) and in
-global screen coordinates.
-
-Likewise, if you set "hoverable" to true, the plot will listen for
-mouse move events on the plot area and fire a "plothover" event with
-the same parameters as the "plotclick" event. If "autoHighlight" is
-true (the default), nearby data items are highlighted automatically.
-If needed, you can disable highlighting and control it yourself with
-the highlight/unhighlight plot methods described elsewhere.
-
-You can use "plotclick" and "plothover" events like this:
-
-```js
-$.plot($("#placeholder"), [ d ], { grid: { clickable: true } });
-
-$("#placeholder").bind("plotclick", function (event, pos, item) {
- alert("You clicked at " + pos.x + ", " + pos.y);
- // axis coordinates for other axes, if present, are in pos.x2, pos.x3, ...
- // if you need global screen coordinates, they are pos.pageX, pos.pageY
-
- if (item) {
- highlight(item.series, item.datapoint);
- alert("You clicked a point!");
- }
-});
-```
-
-The item object in this example is either null or a nearby object on the form:
-
-```js
-item: {
- datapoint: the point, e.g. [0, 2]
- dataIndex: the index of the point in the data array
- series: the series object
- seriesIndex: the index of the series
- pageX, pageY: the global screen coordinates of the point
-}
-```
-
-For instance, if you have specified the data like this
-
-```js
-$.plot($("#placeholder"), [ { label: "Foo", data: [[0, 10], [7, 3]] } ], ...);
-```
-
-and the mouse is near the point (7, 3), "datapoint" is [7, 3],
-"dataIndex" will be 1, "series" is a normalized series object with
-among other things the "Foo" label in series.label and the color in
-series.color, and "seriesIndex" is 0. Note that plugins and options
-that transform the data can shift the indexes from what you specified
-in the original data array.
-
-If you use the above events to update some other information and want
-to clear out that info in case the mouse goes away, you'll probably
-also need to listen to "mouseout" events on the placeholder div.
-
-"mouseActiveRadius" specifies how far the mouse can be from an item
-and still activate it. If there are two or more points within this
-radius, Flot chooses the closest item. For bars, the top-most bar
-(from the latest specified data series) is chosen.
-
-If you want to disable interactivity for a specific data series, you
-can set "hoverable" and "clickable" to false in the options for that
-series, like this:
-
-```js
-{ data: [...], label: "Foo", clickable: false }
-```
-
-"redrawOverlayInterval" specifies the maximum time to delay a redraw
-of interactive things (this works as a rate limiting device). The
-default is capped to 60 frames per second. You can set it to -1 to
-disable the rate limiting.
-
-
-## Specifying gradients ##
-
-A gradient is specified like this:
-
-```js
-{ colors: [ color1, color2, ... ] }
-```
-
-For instance, you might specify a background on the grid going from
-black to gray like this:
-
-```js
-grid: {
- backgroundColor: { colors: ["#000", "#999"] }
-}
-```
-
-For the series you can specify the gradient as an object that
-specifies the scaling of the brightness and the opacity of the series
-color, e.g.
-
-```js
-{ colors: [{ opacity: 0.8 }, { brightness: 0.6, opacity: 0.8 } ] }
-```
-
-where the first color simply has its alpha scaled, whereas the second
-is also darkened. For instance, for bars the following makes the bars
-gradually disappear, without outline:
-
-```js
-bars: {
- show: true,
- lineWidth: 0,
- fill: true,
- fillColor: { colors: [ { opacity: 0.8 }, { opacity: 0.1 } ] }
-}
-```
-
-Flot currently only supports vertical gradients drawn from top to
-bottom because that's what works with IE.
-
-
-## Plot Methods ##
-
-The Plot object returned from the plot function has some methods you
-can call:
-
- - highlight(series, datapoint)
-
- Highlight a specific datapoint in the data series. You can either
- specify the actual objects, e.g. if you got them from a
- "plotclick" event, or you can specify the indices, e.g.
- highlight(1, 3) to highlight the fourth point in the second series
- (remember, zero-based indexing).
-
- - unhighlight(series, datapoint) or unhighlight()
-
- Remove the highlighting of the point, same parameters as
- highlight.
-
- If you call unhighlight with no parameters, e.g. as
- plot.unhighlight(), all current highlights are removed.
-
- - setData(data)
-
- You can use this to reset the data used. Note that axis scaling,
- ticks, legend etc. will not be recomputed (use setupGrid() to do
- that). You'll probably want to call draw() afterwards.
-
- You can use this function to speed up redrawing a small plot if
- you know that the axes won't change. Put in the new data with
- setData(newdata), call draw(), and you're good to go. Note that
- for large datasets, almost all the time is consumed in draw()
- plotting the data so in this case don't bother.
-
- - setupGrid()
-
- Recalculate and set axis scaling, ticks, legend etc.
-
- Note that because of the drawing model of the canvas, this
- function will immediately redraw (actually reinsert in the DOM)
- the labels and the legend, but not the actual tick lines because
- they're drawn on the canvas. You need to call draw() to get the
- canvas redrawn.
-
- - draw()
-
- Redraws the plot canvas.
-
- - triggerRedrawOverlay()
-
- Schedules an update of an overlay canvas used for drawing
- interactive things like a selection and point highlights. This
- is mostly useful for writing plugins. The redraw doesn't happen
- immediately, instead a timer is set to catch multiple successive
- redraws (e.g. from a mousemove). You can get to the overlay by
- setting up a drawOverlay hook.
-
- - width()/height()
-
- Gets the width and height of the plotting area inside the grid.
- This is smaller than the canvas or placeholder dimensions as some
- extra space is needed (e.g. for labels).
-
- - offset()
-
- Returns the offset of the plotting area inside the grid relative
- to the document, useful for instance for calculating mouse
- positions (event.pageX/Y minus this offset is the pixel position
- inside the plot).
-
- - pointOffset({ x: xpos, y: ypos })
-
- Returns the calculated offset of the data point at (x, y) in data
- space within the placeholder div. If you are working with multiple
- axes, you can specify the x and y axis references, e.g.
-
- ```js
- o = pointOffset({ x: xpos, y: ypos, xaxis: 2, yaxis: 3 })
- // o.left and o.top now contains the offset within the div
- ````
-
- - resize()
-
- Tells Flot to resize the drawing canvas to the size of the
- placeholder. You need to run setupGrid() and draw() afterwards as
- canvas resizing is a destructive operation. This is used
- internally by the resize plugin.
-
- - shutdown()
-
- Cleans up any event handlers Flot has currently registered. This
- is used internally.
-
-There are also some members that let you peek inside the internal
-workings of Flot which is useful in some cases. Note that if you change
-something in the objects returned, you're changing the objects used by
-Flot to keep track of its state, so be careful.
-
- - getData()
-
- Returns an array of the data series currently used in normalized
- form with missing settings filled in according to the global
- options. So for instance to find out what color Flot has assigned
- to the data series, you could do this:
-
- ```js
- var series = plot.getData();
- for (var i = 0; i < series.length; ++i)
- alert(series[i].color);
- ```
-
- A notable other interesting field besides color is datapoints
- which has a field "points" with the normalized data points in a
- flat array (the field "pointsize" is the increment in the flat
- array to get to the next point so for a dataset consisting only of
- (x,y) pairs it would be 2).
-
- - getAxes()
-
- Gets an object with the axes. The axes are returned as the
- attributes of the object, so for instance getAxes().xaxis is the
- x axis.
-
- Various things are stuffed inside an axis object, e.g. you could
- use getAxes().xaxis.ticks to find out what the ticks are for the
- xaxis. Two other useful attributes are p2c and c2p, functions for
- transforming from data point space to the canvas plot space and
- back. Both returns values that are offset with the plot offset.
- Check the Flot source code for the complete set of attributes (or
- output an axis with console.log() and inspect it).
-
- With multiple axes, the extra axes are returned as x2axis, x3axis,
- etc., e.g. getAxes().y2axis is the second y axis. You can check
- y2axis.used to see whether the axis is associated with any data
- points and y2axis.show to see if it is currently shown.
-
- - getPlaceholder()
-
- Returns placeholder that the plot was put into. This can be useful
- for plugins for adding DOM elements or firing events.
-
- - getCanvas()
-
- Returns the canvas used for drawing in case you need to hack on it
- yourself. You'll probably need to get the plot offset too.
-
- - getPlotOffset()
-
- Gets the offset that the grid has within the canvas as an object
- with distances from the canvas edges as "left", "right", "top",
- "bottom". I.e., if you draw a circle on the canvas with the center
- placed at (left, top), its center will be at the top-most, left
- corner of the grid.
-
- - getOptions()
-
- Gets the options for the plot, normalized, with default values
- filled in. You get a reference to actual values used by Flot, so
- if you modify the values in here, Flot will use the new values.
- If you change something, you probably have to call draw() or
- setupGrid() or triggerRedrawOverlay() to see the change.
-
-
-## Hooks ##
-
-In addition to the public methods, the Plot object also has some hooks
-that can be used to modify the plotting process. You can install a
-callback function at various points in the process, the function then
-gets access to the internal data structures in Flot.
-
-Here's an overview of the phases Flot goes through:
-
- 1. Plugin initialization, parsing options
-
- 2. Constructing the canvases used for drawing
-
- 3. Set data: parsing data specification, calculating colors,
- copying raw data points into internal format,
- normalizing them, finding max/min for axis auto-scaling
-
- 4. Grid setup: calculating axis spacing, ticks, inserting tick
- labels, the legend
-
- 5. Draw: drawing the grid, drawing each of the series in turn
-
- 6. Setting up event handling for interactive features
-
- 7. Responding to events, if any
-
- 8. Shutdown: this mostly happens in case a plot is overwritten
-
-Each hook is simply a function which is put in the appropriate array.
-You can add them through the "hooks" option, and they are also available
-after the plot is constructed as the "hooks" attribute on the returned
-plot object, e.g.
-
-```js
- // define a simple draw hook
- function hellohook(plot, canvascontext) { alert("hello!"); };
-
- // pass it in, in an array since we might want to specify several
- var plot = $.plot(placeholder, data, { hooks: { draw: [hellohook] } });
-
- // we can now find it again in plot.hooks.draw[0] unless a plugin
- // has added other hooks
-```
-
-The available hooks are described below. All hook callbacks get the
-plot object as first parameter. You can find some examples of defined
-hooks in the plugins bundled with Flot.
-
- - processOptions [phase 1]
-
- ```function(plot, options)```
-
- Called after Flot has parsed and merged options. Useful in the
- instance where customizations beyond simple merging of default
- values is needed. A plugin might use it to detect that it has been
- enabled and then turn on or off other options.
-
-
- - processRawData [phase 3]
-
- ```function(plot, series, data, datapoints)```
-
- Called before Flot copies and normalizes the raw data for the given
- series. If the function fills in datapoints.points with normalized
- points and sets datapoints.pointsize to the size of the points,
- Flot will skip the copying/normalization step for this series.
-
- In any case, you might be interested in setting datapoints.format,
- an array of objects for specifying how a point is normalized and
- how it interferes with axis scaling. It accepts the following options:
-
- ```js
- {
- x, y: boolean,
- number: boolean,
- required: boolean,
- defaultValue: value,
- autoscale: boolean
- }
- ```
-
- "x" and "y" specify whether the value is plotted against the x or y axis,
- and is currently used only to calculate axis min-max ranges. The default
- format array, for example, looks like this:
-
- ```js
- [
- { x: true, number: true, required: true },
- { y: true, number: true, required: true }
- ]
- ```
-
- This indicates that a point, i.e. [0, 25], consists of two values, with the
- first being plotted on the x axis and the second on the y axis.
-
- If "number" is true, then the value must be numeric, and is set to null if
- it cannot be converted to a number.
-
- "defaultValue" provides a fallback in case the original value is null. This
- is for instance handy for bars, where one can omit the third coordinate
- (the bottom of the bar), which then defaults to zero.
-
- If "required" is true, then the value must exist (be non-null) for the
- point as a whole to be valid. If no value is provided, then the entire
- point is cleared out with nulls, turning it into a gap in the series.
-
- "autoscale" determines whether the value is considered when calculating an
- automatic min-max range for the axes that the value is plotted against.
-
- - processDatapoints [phase 3]
-
- ```function(plot, series, datapoints)```
-
- Called after normalization of the given series but before finding
- min/max of the data points. This hook is useful for implementing data
- transformations. "datapoints" contains the normalized data points in
- a flat array as datapoints.points with the size of a single point
- given in datapoints.pointsize. Here's a simple transform that
- multiplies all y coordinates by 2:
-
- ```js
- function multiply(plot, series, datapoints) {
- var points = datapoints.points, ps = datapoints.pointsize;
- for (var i = 0; i < points.length; i += ps)
- points[i + 1] *= 2;
- }
- ```
-
- Note that you must leave datapoints in a good condition as Flot
- doesn't check it or do any normalization on it afterwards.
-
- - processOffset [phase 4]
-
- ```function(plot, offset)```
-
- Called after Flot has initialized the plot's offset, but before it
- draws any axes or plot elements. This hook is useful for customizing
- the margins between the grid and the edge of the canvas. "offset" is
- an object with attributes "top", "bottom", "left" and "right",
- corresponding to the margins on the four sides of the plot.
-
- - drawBackground [phase 5]
-
- ```function(plot, canvascontext)```
-
- Called before all other drawing operations. Used to draw backgrounds
- or other custom elements before the plot or axes have been drawn.
-
- - drawSeries [phase 5]
-
- ```function(plot, canvascontext, series)```
-
- Hook for custom drawing of a single series. Called just before the
- standard drawing routine has been called in the loop that draws
- each series.
-
- - draw [phase 5]
-
- ```function(plot, canvascontext)```
-
- Hook for drawing on the canvas. Called after the grid is drawn
- (unless it's disabled or grid.aboveData is set) and the series have
- been plotted (in case any points, lines or bars have been turned
- on). For examples of how to draw things, look at the source code.
-
- - bindEvents [phase 6]
-
- ```function(plot, eventHolder)```
-
- Called after Flot has setup its event handlers. Should set any
- necessary event handlers on eventHolder, a jQuery object with the
- canvas, e.g.
-
- ```js
- function (plot, eventHolder) {
- eventHolder.mousedown(function (e) {
- alert("You pressed the mouse at " + e.pageX + " " + e.pageY);
- });
- }
- ```
-
- Interesting events include click, mousemove, mouseup/down. You can
- use all jQuery events. Usually, the event handlers will update the
- state by drawing something (add a drawOverlay hook and call
- triggerRedrawOverlay) or firing an externally visible event for
- user code. See the crosshair plugin for an example.
-
- Currently, eventHolder actually contains both the static canvas
- used for the plot itself and the overlay canvas used for
- interactive features because some versions of IE get the stacking
- order wrong. The hook only gets one event, though (either for the
- overlay or for the static canvas).
-
- Note that custom plot events generated by Flot are not generated on
- eventHolder, but on the div placeholder supplied as the first
- argument to the plot call. You can get that with
- plot.getPlaceholder() - that's probably also the one you should use
- if you need to fire a custom event.
-
- - drawOverlay [phase 7]
-
- ```function (plot, canvascontext)```
-
- The drawOverlay hook is used for interactive things that need a
- canvas to draw on. The model currently used by Flot works the way
- that an extra overlay canvas is positioned on top of the static
- canvas. This overlay is cleared and then completely redrawn
- whenever something interesting happens. This hook is called when
- the overlay canvas is to be redrawn.
-
- "canvascontext" is the 2D context of the overlay canvas. You can
- use this to draw things. You'll most likely need some of the
- metrics computed by Flot, e.g. plot.width()/plot.height(). See the
- crosshair plugin for an example.
-
- - shutdown [phase 8]
-
- ```function (plot, eventHolder)```
-
- Run when plot.shutdown() is called, which usually only happens in
- case a plot is overwritten by a new plot. If you're writing a
- plugin that adds extra DOM elements or event handlers, you should
- add a callback to clean up after you. Take a look at the section in
- the [PLUGINS](PLUGINS.md) document for more info.
-
-
-## Plugins ##
-
-Plugins extend the functionality of Flot. To use a plugin, simply
-include its JavaScript file after Flot in the HTML page.
-
-If you're worried about download size/latency, you can concatenate all
-the plugins you use, and Flot itself for that matter, into one big file
-(make sure you get the order right), then optionally run it through a
-JavaScript minifier such as YUI Compressor.
-
-Here's a brief explanation of how the plugin plumbings work:
-
-Each plugin registers itself in the global array $.plot.plugins. When
-you make a new plot object with $.plot, Flot goes through this array
-calling the "init" function of each plugin and merging default options
-from the "option" attribute of the plugin. The init function gets a
-reference to the plot object created and uses this to register hooks
-and add new public methods if needed.
-
-See the [PLUGINS](PLUGINS.md) document for details on how to write a plugin. As the
-above description hints, it's actually pretty easy.
-
-
-## Version number ##
-
-The version number of Flot is available in ```$.plot.version```.
diff --git a/src/legacy/ui/public/flot-charts/index.js b/src/legacy/ui/public/flot-charts/index.js
deleted file mode 100644
index f98aca30d2dec..0000000000000
--- a/src/legacy/ui/public/flot-charts/index.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/* @notice
- *
- * This product includes code that is based on flot-charts, which was available
- * under a "MIT" license.
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2007-2014 IOLA and Ole Laursen
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-import $ from 'jquery';
-if (window) window.jQuery = $;
-require('ui/flot-charts/jquery.flot');
-require('ui/flot-charts/jquery.flot.time');
-require('ui/flot-charts/jquery.flot.canvas');
-require('ui/flot-charts/jquery.flot.symbol');
-require('ui/flot-charts/jquery.flot.crosshair');
-require('ui/flot-charts/jquery.flot.selection');
-require('ui/flot-charts/jquery.flot.pie');
-require('ui/flot-charts/jquery.flot.stack');
-require('ui/flot-charts/jquery.flot.threshold');
-require('ui/flot-charts/jquery.flot.fillbetween');
-require('ui/flot-charts/jquery.flot.log');
-module.exports = $;
diff --git a/src/legacy/ui/public/flot-charts/jquery.colorhelpers.js b/src/legacy/ui/public/flot-charts/jquery.colorhelpers.js
deleted file mode 100644
index b2f6dc4e433a3..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.colorhelpers.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* Plugin for jQuery for working with colors.
- *
- * Version 1.1.
- *
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- * var c = $.color.extract($("#mydiv"), 'background-color');
- * console.log(c.r, c.g, c.b, c.a);
- * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() return the same modified object
- * instead of making a new one.
- *
- * V. 1.1: Fix error handling so e.g. parsing an empty string does
- * produce a color rather than just crashing.
- */
-
-(function($) {
- $.color = {};
-
- // construct color object with some convenient chainable helpers
- $.color.make = function (r, g, b, a) {
- var o = {};
- o.r = r || 0;
- o.g = g || 0;
- o.b = b || 0;
- o.a = a != null ? a : 1;
-
- o.add = function (c, d) {
- for (var i = 0; i < c.length; ++i)
- o[c.charAt(i)] += d;
- return o.normalize();
- };
-
- o.scale = function (c, f) {
- for (var i = 0; i < c.length; ++i)
- o[c.charAt(i)] *= f;
- return o.normalize();
- };
-
- o.toString = function () {
- if (o.a >= 1.0) {
- return "rgb("+[o.r, o.g, o.b].join(",")+")";
- } else {
- return "rgba("+[o.r, o.g, o.b, o.a].join(",")+")";
- }
- };
-
- o.normalize = function () {
- function clamp(min, value, max) {
- return value < min ? min: (value > max ? max: value);
- }
-
- o.r = clamp(0, parseInt(o.r), 255);
- o.g = clamp(0, parseInt(o.g), 255);
- o.b = clamp(0, parseInt(o.b), 255);
- o.a = clamp(0, o.a, 1);
- return o;
- };
-
- o.clone = function () {
- return $.color.make(o.r, o.b, o.g, o.a);
- };
-
- return o.normalize();
- }
-
- // extract CSS color property from element, going up in the DOM
- // if it's "transparent"
- $.color.extract = function (elem, css) {
- var c;
-
- do {
- c = elem.css(css).toLowerCase();
- // keep going until we find an element that has color, or
- // we hit the body or root (have no parent)
- if (c != '' && c != 'transparent')
- break;
- elem = elem.parent();
- } while (elem.length && !$.nodeName(elem.get(0), "body"));
-
- // catch Safari's way of signalling transparent
- if (c == "rgba(0, 0, 0, 0)")
- c = "transparent";
-
- return $.color.parse(c);
- }
-
- // parse CSS color string (like "rgb(10, 32, 43)" or "#fff"),
- // returns color object, if parsing failed, you get black (0, 0,
- // 0) out
- $.color.parse = function (str) {
- var res, m = $.color.make;
-
- // Look for rgb(num,num,num)
- if (res = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
- return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));
-
- // Look for rgba(num,num,num,num)
- if (res = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
- return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));
-
- // Look for rgb(num%,num%,num%)
- if (res = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
- return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);
-
- // Look for rgba(num%,num%,num%,num)
- if (res = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
- return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));
-
- // Look for #a0b1c2
- if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
- return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));
-
- // Look for #fff
- if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
- return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));
-
- // Otherwise, we're most likely dealing with a named color
- var name = $.trim(str).toLowerCase();
- if (name == "transparent")
- return m(255, 255, 255, 0);
- else {
- // default to black
- res = lookupColors[name] || [0, 0, 0];
- return m(res[0], res[1], res[2]);
- }
- }
-
- var lookupColors = {
- aqua:[0,255,255],
- azure:[240,255,255],
- beige:[245,245,220],
- black:[0,0,0],
- blue:[0,0,255],
- brown:[165,42,42],
- cyan:[0,255,255],
- darkblue:[0,0,139],
- darkcyan:[0,139,139],
- darkgrey:[169,169,169],
- darkgreen:[0,100,0],
- darkkhaki:[189,183,107],
- darkmagenta:[139,0,139],
- darkolivegreen:[85,107,47],
- darkorange:[255,140,0],
- darkorchid:[153,50,204],
- darkred:[139,0,0],
- darksalmon:[233,150,122],
- darkviolet:[148,0,211],
- fuchsia:[255,0,255],
- gold:[255,215,0],
- green:[0,128,0],
- indigo:[75,0,130],
- khaki:[240,230,140],
- lightblue:[173,216,230],
- lightcyan:[224,255,255],
- lightgreen:[144,238,144],
- lightgrey:[211,211,211],
- lightpink:[255,182,193],
- lightyellow:[255,255,224],
- lime:[0,255,0],
- magenta:[255,0,255],
- maroon:[128,0,0],
- navy:[0,0,128],
- olive:[128,128,0],
- orange:[255,165,0],
- pink:[255,192,203],
- purple:[128,0,128],
- violet:[128,0,128],
- red:[255,0,0],
- silver:[192,192,192],
- white:[255,255,255],
- yellow:[255,255,0]
- };
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.canvas.js b/src/legacy/ui/public/flot-charts/jquery.flot.canvas.js
deleted file mode 100644
index 29328d5812127..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.canvas.js
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Flot plugin for drawing all elements of a plot on the canvas.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-Flot normally produces certain elements, like axis labels and the legend, using
-HTML elements. This permits greater interactivity and customization, and often
-looks better, due to cross-browser canvas text inconsistencies and limitations.
-
-It can also be desirable to render the plot entirely in canvas, particularly
-if the goal is to save it as an image, or if Flot is being used in a context
-where the HTML DOM does not exist, as is the case within Node.js. This plugin
-switches out Flot's standard drawing operations for canvas-only replacements.
-
-Currently the plugin supports only axis labels, but it will eventually allow
-every element of the plot to be rendered directly to canvas.
-
-The plugin supports these options:
-
-{
- canvas: boolean
-}
-
-The "canvas" option controls whether full canvas drawing is enabled, making it
-possible to toggle on and off. This is useful when a plot uses HTML text in the
-browser, but needs to redraw with canvas text when exporting as an image.
-
-*/
-
-(function($) {
-
- var options = {
- canvas: true
- };
-
- var render, getTextInfo, addText;
-
- // Cache the prototype hasOwnProperty for faster access
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- function init(plot, classes) {
-
- var Canvas = classes.Canvas;
-
- // We only want to replace the functions once; the second time around
- // we would just get our new function back. This whole replacing of
- // prototype functions is a disaster, and needs to be changed ASAP.
-
- if (render == null) {
- getTextInfo = Canvas.prototype.getTextInfo,
- addText = Canvas.prototype.addText,
- render = Canvas.prototype.render;
- }
-
- // Finishes rendering the canvas, including overlaid text
-
- Canvas.prototype.render = function() {
-
- if (!plot.getOptions().canvas) {
- return render.call(this);
- }
-
- var context = this.context,
- cache = this._textCache;
-
- // For each text layer, render elements marked as active
-
- context.save();
- context.textBaseline = "middle";
-
- for (var layerKey in cache) {
- if (hasOwnProperty.call(cache, layerKey)) {
- var layerCache = cache[layerKey];
- for (var styleKey in layerCache) {
- if (hasOwnProperty.call(layerCache, styleKey)) {
- var styleCache = layerCache[styleKey],
- updateStyles = true;
- for (var key in styleCache) {
- if (hasOwnProperty.call(styleCache, key)) {
-
- var info = styleCache[key],
- positions = info.positions,
- lines = info.lines;
-
- // Since every element at this level of the cache have the
- // same font and fill styles, we can just change them once
- // using the values from the first element.
-
- if (updateStyles) {
- context.fillStyle = info.font.color;
- context.font = info.font.definition;
- updateStyles = false;
- }
-
- for (var i = 0, position; position = positions[i]; i++) {
- if (position.active) {
- for (var j = 0, line; line = position.lines[j]; j++) {
- context.fillText(lines[j].text, line[0], line[1]);
- }
- } else {
- positions.splice(i--, 1);
- }
- }
-
- if (positions.length == 0) {
- delete styleCache[key];
- }
- }
- }
- }
- }
- }
- }
-
- context.restore();
- };
-
- // Creates (if necessary) and returns a text info object.
- //
- // When the canvas option is set, the object looks like this:
- //
- // {
- // width: Width of the text's bounding box.
- // height: Height of the text's bounding box.
- // positions: Array of positions at which this text is drawn.
- // lines: [{
- // height: Height of this line.
- // widths: Width of this line.
- // text: Text on this line.
- // }],
- // font: {
- // definition: Canvas font property string.
- // color: Color of the text.
- // },
- // }
- //
- // The positions array contains objects that look like this:
- //
- // {
- // active: Flag indicating whether the text should be visible.
- // lines: Array of [x, y] coordinates at which to draw the line.
- // x: X coordinate at which to draw the text.
- // y: Y coordinate at which to draw the text.
- // }
-
- Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
-
- if (!plot.getOptions().canvas) {
- return getTextInfo.call(this, layer, text, font, angle, width);
- }
-
- var textStyle, layerCache, styleCache, info;
-
- // Cast the value to a string, in case we were given a number
-
- text = "" + text;
-
- // If the font is a font-spec object, generate a CSS definition
-
- if (typeof font === "object") {
- textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
- } else {
- textStyle = font;
- }
-
- // Retrieve (or create) the cache for the text's layer and styles
-
- layerCache = this._textCache[layer];
-
- if (layerCache == null) {
- layerCache = this._textCache[layer] = {};
- }
-
- styleCache = layerCache[textStyle];
-
- if (styleCache == null) {
- styleCache = layerCache[textStyle] = {};
- }
-
- info = styleCache[text];
-
- if (info == null) {
-
- var context = this.context;
-
- // If the font was provided as CSS, create a div with those
- // classes and examine it to generate a canvas font spec.
-
- if (typeof font !== "object") {
-
- var element = $("
")
- .css("position", "absolute")
- .addClass(typeof font === "string" ? font : null)
- .appendTo(this.getTextLayer(layer));
-
- font = {
- lineHeight: element.height(),
- style: element.css("font-style"),
- variant: element.css("font-variant"),
- weight: element.css("font-weight"),
- family: element.css("font-family"),
- color: element.css("color")
- };
-
- // Setting line-height to 1, without units, sets it equal
- // to the font-size, even if the font-size is abstract,
- // like 'smaller'. This enables us to read the real size
- // via the element's height, working around browsers that
- // return the literal 'smaller' value.
-
- font.size = element.css("line-height", 1).height();
-
- element.remove();
- }
-
- textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px " + font.family;
-
- // Create a new info object, initializing the dimensions to
- // zero so we can count them up line-by-line.
-
- info = styleCache[text] = {
- width: 0,
- height: 0,
- positions: [],
- lines: [],
- font: {
- definition: textStyle,
- color: font.color
- }
- };
-
- context.save();
- context.font = textStyle;
-
- // Canvas can't handle multi-line strings; break on various
- // newlines, including HTML brs, to build a list of lines.
- // Note that we could split directly on regexps, but IE < 9 is
- // broken; revisit when we drop IE 7/8 support.
-
- var lines = (text + "").replace(/ |\r\n|\r/g, "\n").split("\n");
-
- for (var i = 0; i < lines.length; ++i) {
-
- var lineText = lines[i],
- measured = context.measureText(lineText);
-
- info.width = Math.max(measured.width, info.width);
- info.height += font.lineHeight;
-
- info.lines.push({
- text: lineText,
- width: measured.width,
- height: font.lineHeight
- });
- }
-
- context.restore();
- }
-
- return info;
- };
-
- // Adds a text string to the canvas text overlay.
-
- Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
-
- if (!plot.getOptions().canvas) {
- return addText.call(this, layer, x, y, text, font, angle, width, halign, valign);
- }
-
- var info = this.getTextInfo(layer, text, font, angle, width),
- positions = info.positions,
- lines = info.lines;
-
- // Text is drawn with baseline 'middle', which we need to account
- // for by adding half a line's height to the y position.
-
- y += info.height / lines.length / 2;
-
- // Tweak the initial y-position to match vertical alignment
-
- if (valign == "middle") {
- y = Math.round(y - info.height / 2);
- } else if (valign == "bottom") {
- y = Math.round(y - info.height);
- } else {
- y = Math.round(y);
- }
-
- // FIXME: LEGACY BROWSER FIX
- // AFFECTS: Opera < 12.00
-
- // Offset the y coordinate, since Opera is off pretty
- // consistently compared to the other browsers.
-
- if (!!(window.opera && window.opera.version().split(".")[0] < 12)) {
- y -= 2;
- }
-
- // Determine whether this text already exists at this position.
- // If so, mark it for inclusion in the next render pass.
-
- for (var i = 0, position; position = positions[i]; i++) {
- if (position.x == x && position.y == y) {
- position.active = true;
- return;
- }
- }
-
- // If the text doesn't exist at this position, create a new entry
-
- position = {
- active: true,
- lines: [],
- x: x,
- y: y
- };
-
- positions.push(position);
-
- // Fill in the x & y positions of each line, adjusting them
- // individually for horizontal alignment.
-
- for (var i = 0, line; line = lines[i]; i++) {
- if (halign == "center") {
- position.lines.push([Math.round(x - line.width / 2), y]);
- } else if (halign == "right") {
- position.lines.push([Math.round(x - line.width), y]);
- } else {
- position.lines.push([Math.round(x), y]);
- }
- y += line.height;
- }
- };
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: "canvas",
- version: "1.0"
- });
-
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.categories.js b/src/legacy/ui/public/flot-charts/jquery.flot.categories.js
deleted file mode 100644
index 2f9b257971499..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.categories.js
+++ /dev/null
@@ -1,190 +0,0 @@
-/* Flot plugin for plotting textual data or categories.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-Consider a dataset like [["February", 34], ["March", 20], ...]. This plugin
-allows you to plot such a dataset directly.
-
-To enable it, you must specify mode: "categories" on the axis with the textual
-labels, e.g.
-
- $.plot("#placeholder", data, { xaxis: { mode: "categories" } });
-
-By default, the labels are ordered as they are met in the data series. If you
-need a different ordering, you can specify "categories" on the axis options
-and list the categories there:
-
- xaxis: {
- mode: "categories",
- categories: ["February", "March", "April"]
- }
-
-If you need to customize the distances between the categories, you can specify
-"categories" as an object mapping labels to values
-
- xaxis: {
- mode: "categories",
- categories: { "February": 1, "March": 3, "April": 4 }
- }
-
-If you don't specify all categories, the remaining categories will be numbered
-from the max value plus 1 (with a spacing of 1 between each).
-
-Internally, the plugin works by transforming the input data through an auto-
-generated mapping where the first category becomes 0, the second 1, etc.
-Hence, a point like ["February", 34] becomes [0, 34] internally in Flot (this
-is visible in hover and click events that return numbers rather than the
-category labels). The plugin also overrides the tick generator to spit out the
-categories as ticks instead of the values.
-
-If you need to map a value back to its label, the mapping is always accessible
-as "categories" on the axis object, e.g. plot.getAxes().xaxis.categories.
-
-*/
-
-(function ($) {
- var options = {
- xaxis: {
- categories: null
- },
- yaxis: {
- categories: null
- }
- };
-
- function processRawData(plot, series, data, datapoints) {
- // if categories are enabled, we need to disable
- // auto-transformation to numbers so the strings are intact
- // for later processing
-
- var xCategories = series.xaxis.options.mode == "categories",
- yCategories = series.yaxis.options.mode == "categories";
-
- if (!(xCategories || yCategories))
- return;
-
- var format = datapoints.format;
-
- if (!format) {
- // FIXME: auto-detection should really not be defined here
- var s = series;
- format = [];
- format.push({ x: true, number: true, required: true });
- format.push({ y: true, number: true, required: true });
-
- if (s.bars.show || (s.lines.show && s.lines.fill)) {
- var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
- format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
- if (s.bars.horizontal) {
- delete format[format.length - 1].y;
- format[format.length - 1].x = true;
- }
- }
-
- datapoints.format = format;
- }
-
- for (var m = 0; m < format.length; ++m) {
- if (format[m].x && xCategories)
- format[m].number = false;
-
- if (format[m].y && yCategories)
- format[m].number = false;
- }
- }
-
- function getNextIndex(categories) {
- var index = -1;
-
- for (var v in categories)
- if (categories[v] > index)
- index = categories[v];
-
- return index + 1;
- }
-
- function categoriesTickGenerator(axis) {
- var res = [];
- for (var label in axis.categories) {
- var v = axis.categories[label];
- if (v >= axis.min && v <= axis.max)
- res.push([v, label]);
- }
-
- res.sort(function (a, b) { return a[0] - b[0]; });
-
- return res;
- }
-
- function setupCategoriesForAxis(series, axis, datapoints) {
- if (series[axis].options.mode != "categories")
- return;
-
- if (!series[axis].categories) {
- // parse options
- var c = {}, o = series[axis].options.categories || {};
- if ($.isArray(o)) {
- for (var i = 0; i < o.length; ++i)
- c[o[i]] = i;
- }
- else {
- for (var v in o)
- c[v] = o[v];
- }
-
- series[axis].categories = c;
- }
-
- // fix ticks
- if (!series[axis].options.ticks)
- series[axis].options.ticks = categoriesTickGenerator;
-
- transformPointsOnAxis(datapoints, axis, series[axis].categories);
- }
-
- function transformPointsOnAxis(datapoints, axis, categories) {
- // go through the points, transforming them
- var points = datapoints.points,
- ps = datapoints.pointsize,
- format = datapoints.format,
- formatColumn = axis.charAt(0),
- index = getNextIndex(categories);
-
- for (var i = 0; i < points.length; i += ps) {
- if (points[i] == null)
- continue;
-
- for (var m = 0; m < ps; ++m) {
- var val = points[i + m];
-
- if (val == null || !format[m][formatColumn])
- continue;
-
- if (!(val in categories)) {
- categories[val] = index;
- ++index;
- }
-
- points[i + m] = categories[val];
- }
- }
- }
-
- function processDatapoints(plot, series, datapoints) {
- setupCategoriesForAxis(series, "xaxis", datapoints);
- setupCategoriesForAxis(series, "yaxis", datapoints);
- }
-
- function init(plot) {
- plot.hooks.processRawData.push(processRawData);
- plot.hooks.processDatapoints.push(processDatapoints);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'categories',
- version: '1.0'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.crosshair.js b/src/legacy/ui/public/flot-charts/jquery.flot.crosshair.js
deleted file mode 100644
index 5111695e3d12c..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.crosshair.js
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Flot plugin for showing crosshairs when the mouse hovers over the plot.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The plugin supports these options:
-
- crosshair: {
- mode: null or "x" or "y" or "xy"
- color: color
- lineWidth: number
- }
-
-Set the mode to one of "x", "y" or "xy". The "x" mode enables a vertical
-crosshair that lets you trace the values on the x axis, "y" enables a
-horizontal crosshair and "xy" enables them both. "color" is the color of the
-crosshair (default is "rgba(170, 0, 0, 0.80)"), "lineWidth" is the width of
-the drawn lines (default is 1).
-
-The plugin also adds four public methods:
-
- - setCrosshair( pos )
-
- Set the position of the crosshair. Note that this is cleared if the user
- moves the mouse. "pos" is in coordinates of the plot and should be on the
- form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple
- axes), which is coincidentally the same format as what you get from a
- "plothover" event. If "pos" is null, the crosshair is cleared.
-
- - clearCrosshair()
-
- Clear the crosshair.
-
- - lockCrosshair(pos)
-
- Cause the crosshair to lock to the current location, no longer updating if
- the user moves the mouse. Optionally supply a position (passed on to
- setCrosshair()) to move it to.
-
- Example usage:
-
- var myFlot = $.plot( $("#graph"), ..., { crosshair: { mode: "x" } } };
- $("#graph").bind( "plothover", function ( evt, position, item ) {
- if ( item ) {
- // Lock the crosshair to the data point being hovered
- myFlot.lockCrosshair({
- x: item.datapoint[ 0 ],
- y: item.datapoint[ 1 ]
- });
- } else {
- // Return normal crosshair operation
- myFlot.unlockCrosshair();
- }
- });
-
- - unlockCrosshair()
-
- Free the crosshair to move again after locking it.
-*/
-
-(function ($) {
- var options = {
- crosshair: {
- mode: null, // one of null, "x", "y" or "xy",
- color: "rgba(170, 0, 0, 0.80)",
- lineWidth: 1
- }
- };
-
- function init(plot) {
- // position of crosshair in pixels
- var crosshair = { x: -1, y: -1, locked: false };
-
- plot.setCrosshair = function setCrosshair(pos) {
- if (!pos)
- crosshair.x = -1;
- else {
- var o = plot.p2c(pos);
- crosshair.x = Math.max(0, Math.min(o.left, plot.width()));
- crosshair.y = Math.max(0, Math.min(o.top, plot.height()));
- }
-
- plot.triggerRedrawOverlay();
- };
-
- plot.clearCrosshair = plot.setCrosshair; // passes null for pos
-
- plot.lockCrosshair = function lockCrosshair(pos) {
- if (pos)
- plot.setCrosshair(pos);
- crosshair.locked = true;
- };
-
- plot.unlockCrosshair = function unlockCrosshair() {
- crosshair.locked = false;
- };
-
- function onMouseOut(e) {
- if (crosshair.locked)
- return;
-
- if (crosshair.x != -1) {
- crosshair.x = -1;
- plot.triggerRedrawOverlay();
- }
- }
-
- function onMouseMove(e) {
- if (crosshair.locked)
- return;
-
- if (plot.getSelection && plot.getSelection()) {
- crosshair.x = -1; // hide the crosshair while selecting
- return;
- }
-
- var offset = plot.offset();
- crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));
- crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));
- plot.triggerRedrawOverlay();
- }
-
- plot.hooks.bindEvents.push(function (plot, eventHolder) {
- if (!plot.getOptions().crosshair.mode)
- return;
-
- eventHolder.mouseout(onMouseOut);
- eventHolder.mousemove(onMouseMove);
- });
-
- plot.hooks.drawOverlay.push(function (plot, ctx) {
- var c = plot.getOptions().crosshair;
- if (!c.mode)
- return;
-
- var plotOffset = plot.getPlotOffset();
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- if (crosshair.x != -1) {
- var adj = plot.getOptions().crosshair.lineWidth % 2 ? 0.5 : 0;
-
- ctx.strokeStyle = c.color;
- ctx.lineWidth = c.lineWidth;
- ctx.lineJoin = "round";
-
- ctx.beginPath();
- if (c.mode.indexOf("x") != -1) {
- var drawX = Math.floor(crosshair.x) + adj;
- ctx.moveTo(drawX, 0);
- ctx.lineTo(drawX, plot.height());
- }
- if (c.mode.indexOf("y") != -1) {
- var drawY = Math.floor(crosshair.y) + adj;
- ctx.moveTo(0, drawY);
- ctx.lineTo(plot.width(), drawY);
- }
- ctx.stroke();
- }
- ctx.restore();
- });
-
- plot.hooks.shutdown.push(function (plot, eventHolder) {
- eventHolder.unbind("mouseout", onMouseOut);
- eventHolder.unbind("mousemove", onMouseMove);
- });
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'crosshair',
- version: '1.0'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.errorbars.js b/src/legacy/ui/public/flot-charts/jquery.flot.errorbars.js
deleted file mode 100644
index 655036e0db846..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.errorbars.js
+++ /dev/null
@@ -1,353 +0,0 @@
-/* Flot plugin for plotting error bars.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-Error bars are used to show standard deviation and other statistical
-properties in a plot.
-
-* Created by Rui Pereira - rui (dot) pereira (at) gmail (dot) com
-
-This plugin allows you to plot error-bars over points. Set "errorbars" inside
-the points series to the axis name over which there will be error values in
-your data array (*even* if you do not intend to plot them later, by setting
-"show: null" on xerr/yerr).
-
-The plugin supports these options:
-
- series: {
- points: {
- errorbars: "x" or "y" or "xy",
- xerr: {
- show: null/false or true,
- asymmetric: null/false or true,
- upperCap: null or "-" or function,
- lowerCap: null or "-" or function,
- color: null or color,
- radius: null or number
- },
- yerr: { same options as xerr }
- }
- }
-
-Each data point array is expected to be of the type:
-
- "x" [ x, y, xerr ]
- "y" [ x, y, yerr ]
- "xy" [ x, y, xerr, yerr ]
-
-Where xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and
-equivalently for yerr. E.g., a datapoint for the "xy" case with symmetric
-error-bars on X and asymmetric on Y would be:
-
- [ x, y, xerr, yerr_lower, yerr_upper ]
-
-By default no end caps are drawn. Setting upperCap and/or lowerCap to "-" will
-draw a small cap perpendicular to the error bar. They can also be set to a
-user-defined drawing function, with (ctx, x, y, radius) as parameters, as e.g.:
-
- function drawSemiCircle( ctx, x, y, radius ) {
- ctx.beginPath();
- ctx.arc( x, y, radius, 0, Math.PI, false );
- ctx.moveTo( x - radius, y );
- ctx.lineTo( x + radius, y );
- ctx.stroke();
- }
-
-Color and radius both default to the same ones of the points series if not
-set. The independent radius parameter on xerr/yerr is useful for the case when
-we may want to add error-bars to a line, without showing the interconnecting
-points (with radius: 0), and still showing end caps on the error-bars.
-shadowSize and lineWidth are derived as well from the points series.
-
-*/
-
-(function ($) {
- var options = {
- series: {
- points: {
- errorbars: null, //should be 'x', 'y' or 'xy'
- xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},
- yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}
- }
- }
- };
-
- function processRawData(plot, series, data, datapoints){
- if (!series.points.errorbars)
- return;
-
- // x,y values
- var format = [
- { x: true, number: true, required: true },
- { y: true, number: true, required: true }
- ];
-
- var errors = series.points.errorbars;
- // error bars - first X then Y
- if (errors == 'x' || errors == 'xy') {
- // lower / upper error
- if (series.points.xerr.asymmetric) {
- format.push({ x: true, number: true, required: true });
- format.push({ x: true, number: true, required: true });
- } else
- format.push({ x: true, number: true, required: true });
- }
- if (errors == 'y' || errors == 'xy') {
- // lower / upper error
- if (series.points.yerr.asymmetric) {
- format.push({ y: true, number: true, required: true });
- format.push({ y: true, number: true, required: true });
- } else
- format.push({ y: true, number: true, required: true });
- }
- datapoints.format = format;
- }
-
- function parseErrors(series, i){
-
- var points = series.datapoints.points;
-
- // read errors from points array
- var exl = null,
- exu = null,
- eyl = null,
- eyu = null;
- var xerr = series.points.xerr,
- yerr = series.points.yerr;
-
- var eb = series.points.errorbars;
- // error bars - first X
- if (eb == 'x' || eb == 'xy') {
- if (xerr.asymmetric) {
- exl = points[i + 2];
- exu = points[i + 3];
- if (eb == 'xy')
- if (yerr.asymmetric){
- eyl = points[i + 4];
- eyu = points[i + 5];
- } else eyl = points[i + 4];
- } else {
- exl = points[i + 2];
- if (eb == 'xy')
- if (yerr.asymmetric) {
- eyl = points[i + 3];
- eyu = points[i + 4];
- } else eyl = points[i + 3];
- }
- // only Y
- } else if (eb == 'y')
- if (yerr.asymmetric) {
- eyl = points[i + 2];
- eyu = points[i + 3];
- } else eyl = points[i + 2];
-
- // symmetric errors?
- if (exu == null) exu = exl;
- if (eyu == null) eyu = eyl;
-
- var errRanges = [exl, exu, eyl, eyu];
- // nullify if not showing
- if (!xerr.show){
- errRanges[0] = null;
- errRanges[1] = null;
- }
- if (!yerr.show){
- errRanges[2] = null;
- errRanges[3] = null;
- }
- return errRanges;
- }
-
- function drawSeriesErrors(plot, ctx, s){
-
- var points = s.datapoints.points,
- ps = s.datapoints.pointsize,
- ax = [s.xaxis, s.yaxis],
- radius = s.points.radius,
- err = [s.points.xerr, s.points.yerr];
-
- //sanity check, in case some inverted axis hack is applied to flot
- var invertX = false;
- if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {
- invertX = true;
- var tmp = err[0].lowerCap;
- err[0].lowerCap = err[0].upperCap;
- err[0].upperCap = tmp;
- }
-
- var invertY = false;
- if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {
- invertY = true;
- var tmp = err[1].lowerCap;
- err[1].lowerCap = err[1].upperCap;
- err[1].upperCap = tmp;
- }
-
- for (var i = 0; i < s.datapoints.points.length; i += ps) {
-
- //parse
- var errRanges = parseErrors(s, i);
-
- //cycle xerr & yerr
- for (var e = 0; e < err.length; e++){
-
- var minmax = [ax[e].min, ax[e].max];
-
- //draw this error?
- if (errRanges[e * err.length]){
-
- //data coordinates
- var x = points[i],
- y = points[i + 1];
-
- //errorbar ranges
- var upper = [x, y][e] + errRanges[e * err.length + 1],
- lower = [x, y][e] - errRanges[e * err.length];
-
- //points outside of the canvas
- if (err[e].err == 'x')
- if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)
- continue;
- if (err[e].err == 'y')
- if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)
- continue;
-
- // prevent errorbars getting out of the canvas
- var drawUpper = true,
- drawLower = true;
-
- if (upper > minmax[1]) {
- drawUpper = false;
- upper = minmax[1];
- }
- if (lower < minmax[0]) {
- drawLower = false;
- lower = minmax[0];
- }
-
- //sanity check, in case some inverted axis hack is applied to flot
- if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {
- //swap coordinates
- var tmp = lower;
- lower = upper;
- upper = tmp;
- tmp = drawLower;
- drawLower = drawUpper;
- drawUpper = tmp;
- tmp = minmax[0];
- minmax[0] = minmax[1];
- minmax[1] = tmp;
- }
-
- // convert to pixels
- x = ax[0].p2c(x),
- y = ax[1].p2c(y),
- upper = ax[e].p2c(upper);
- lower = ax[e].p2c(lower);
- minmax[0] = ax[e].p2c(minmax[0]);
- minmax[1] = ax[e].p2c(minmax[1]);
-
- //same style as points by default
- var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,
- sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;
-
- //shadow as for points
- if (lw > 0 && sw > 0) {
- var w = sw / 2;
- ctx.lineWidth = w;
- ctx.strokeStyle = "rgba(0,0,0,0.1)";
- drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);
-
- ctx.strokeStyle = "rgba(0,0,0,0.2)";
- drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);
- }
-
- ctx.strokeStyle = err[e].color? err[e].color: s.color;
- ctx.lineWidth = lw;
- //draw it
- drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);
- }
- }
- }
- }
-
- function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){
-
- //shadow offset
- y += offset;
- upper += offset;
- lower += offset;
-
- // error bar - avoid plotting over circles
- if (err.err == 'x'){
- if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);
- else drawUpper = false;
- if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );
- else drawLower = false;
- }
- else {
- if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );
- else drawUpper = false;
- if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );
- else drawLower = false;
- }
-
- //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps
- //this is a way to get errorbars on lines without visible connecting dots
- radius = err.radius != null? err.radius: radius;
-
- // upper cap
- if (drawUpper) {
- if (err.upperCap == '-'){
- if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );
- else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );
- } else if ($.isFunction(err.upperCap)){
- if (err.err=='x') err.upperCap(ctx, upper, y, radius);
- else err.upperCap(ctx, x, upper, radius);
- }
- }
- // lower cap
- if (drawLower) {
- if (err.lowerCap == '-'){
- if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );
- else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );
- } else if ($.isFunction(err.lowerCap)){
- if (err.err=='x') err.lowerCap(ctx, lower, y, radius);
- else err.lowerCap(ctx, x, lower, radius);
- }
- }
- }
-
- function drawPath(ctx, pts){
- ctx.beginPath();
- ctx.moveTo(pts[0][0], pts[0][1]);
- for (var p=1; p < pts.length; p++)
- ctx.lineTo(pts[p][0], pts[p][1]);
- ctx.stroke();
- }
-
- function draw(plot, ctx){
- var plotOffset = plot.getPlotOffset();
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
- $.each(plot.getData(), function (i, s) {
- if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))
- drawSeriesErrors(plot, ctx, s);
- });
- ctx.restore();
- }
-
- function init(plot) {
- plot.hooks.processRawData.push(processRawData);
- plot.hooks.draw.push(draw);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'errorbars',
- version: '1.0'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.fillbetween.js b/src/legacy/ui/public/flot-charts/jquery.flot.fillbetween.js
deleted file mode 100644
index 18b15d26db8c9..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.fillbetween.js
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Flot plugin for computing bottoms for filled line and bar charts.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The case: you've got two series that you want to fill the area between. In Flot
-terms, you need to use one as the fill bottom of the other. You can specify the
-bottom of each data point as the third coordinate manually, or you can use this
-plugin to compute it for you.
-
-In order to name the other series, you need to give it an id, like this:
-
- var dataset = [
- { data: [ ... ], id: "foo" } , // use default bottom
- { data: [ ... ], fillBetween: "foo" }, // use first dataset as bottom
- ];
-
- $.plot($("#placeholder"), dataset, { lines: { show: true, fill: true }});
-
-As a convenience, if the id given is a number that doesn't appear as an id in
-the series, it is interpreted as the index in the array instead (so fillBetween:
-0 can also mean the first series).
-
-Internally, the plugin modifies the datapoints in each series. For line series,
-extra data points might be inserted through interpolation. Note that at points
-where the bottom line is not defined (due to a null point or start/end of line),
-the current line will show a gap too. The algorithm comes from the
-jquery.flot.stack.js plugin, possibly some code could be shared.
-
-*/
-
-(function ( $ ) {
-
- var options = {
- series: {
- fillBetween: null // or number
- }
- };
-
- function init( plot ) {
-
- function findBottomSeries( s, allseries ) {
-
- var i;
-
- for ( i = 0; i < allseries.length; ++i ) {
- if ( allseries[ i ].id === s.fillBetween ) {
- return allseries[ i ];
- }
- }
-
- if ( typeof s.fillBetween === "number" ) {
- if ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {
- return null;
- }
- return allseries[ s.fillBetween ];
- }
-
- return null;
- }
-
- function computeFillBottoms( plot, s, datapoints ) {
-
- if ( s.fillBetween == null ) {
- return;
- }
-
- var other = findBottomSeries( s, plot.getData() );
-
- if ( !other ) {
- return;
- }
-
- var ps = datapoints.pointsize,
- points = datapoints.points,
- otherps = other.datapoints.pointsize,
- otherpoints = other.datapoints.points,
- newpoints = [],
- px, py, intery, qx, qy, bottom,
- withlines = s.lines.show,
- withbottom = ps > 2 && datapoints.format[2].y,
- withsteps = withlines && s.lines.steps,
- fromgap = true,
- i = 0,
- j = 0,
- l, m;
-
- while ( true ) {
-
- if ( i >= points.length ) {
- break;
- }
-
- l = newpoints.length;
-
- if ( points[ i ] == null ) {
-
- // copy gaps
-
- for ( m = 0; m < ps; ++m ) {
- newpoints.push( points[ i + m ] );
- }
-
- i += ps;
-
- } else if ( j >= otherpoints.length ) {
-
- // for lines, we can't use the rest of the points
-
- if ( !withlines ) {
- for ( m = 0; m < ps; ++m ) {
- newpoints.push( points[ i + m ] );
- }
- }
-
- i += ps;
-
- } else if ( otherpoints[ j ] == null ) {
-
- // oops, got a gap
-
- for ( m = 0; m < ps; ++m ) {
- newpoints.push( null );
- }
-
- fromgap = true;
- j += otherps;
-
- } else {
-
- // cases where we actually got two points
-
- px = points[ i ];
- py = points[ i + 1 ];
- qx = otherpoints[ j ];
- qy = otherpoints[ j + 1 ];
- bottom = 0;
-
- if ( px === qx ) {
-
- for ( m = 0; m < ps; ++m ) {
- newpoints.push( points[ i + m ] );
- }
-
- //newpoints[ l + 1 ] += qy;
- bottom = qy;
-
- i += ps;
- j += otherps;
-
- } else if ( px > qx ) {
-
- // we got past point below, might need to
- // insert interpolated extra point
-
- if ( withlines && i > 0 && points[ i - ps ] != null ) {
- intery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );
- newpoints.push( qx );
- newpoints.push( intery );
- for ( m = 2; m < ps; ++m ) {
- newpoints.push( points[ i + m ] );
- }
- bottom = qy;
- }
-
- j += otherps;
-
- } else { // px < qx
-
- // if we come from a gap, we just skip this point
-
- if ( fromgap && withlines ) {
- i += ps;
- continue;
- }
-
- for ( m = 0; m < ps; ++m ) {
- newpoints.push( points[ i + m ] );
- }
-
- // we might be able to interpolate a point below,
- // this can give us a better y
-
- if ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {
- bottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );
- }
-
- //newpoints[l + 1] += bottom;
-
- i += ps;
- }
-
- fromgap = false;
-
- if ( l !== newpoints.length && withbottom ) {
- newpoints[ l + 2 ] = bottom;
- }
- }
-
- // maintain the line steps invariant
-
- if ( withsteps && l !== newpoints.length && l > 0 &&
- newpoints[ l ] !== null &&
- newpoints[ l ] !== newpoints[ l - ps ] &&
- newpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {
- for (m = 0; m < ps; ++m) {
- newpoints[ l + ps + m ] = newpoints[ l + m ];
- }
- newpoints[ l + 1 ] = newpoints[ l - ps + 1 ];
- }
- }
-
- datapoints.points = newpoints;
- }
-
- plot.hooks.processDatapoints.push( computeFillBottoms );
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: "fillbetween",
- version: "1.0"
- });
-
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.image.js b/src/legacy/ui/public/flot-charts/jquery.flot.image.js
deleted file mode 100644
index 178f0e69069ef..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.image.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/* Flot plugin for plotting images.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and
-(x2, y2) are where you intend the two opposite corners of the image to end up
-in the plot. Image must be a fully loaded JavaScript image (you can make one
-with new Image()). If the image is not complete, it's skipped when plotting.
-
-There are two helpers included for retrieving images. The easiest work the way
-that you put in URLs instead of images in the data, like this:
-
- [ "myimage.png", 0, 0, 10, 10 ]
-
-Then call $.plot.image.loadData( data, options, callback ) where data and
-options are the same as you pass in to $.plot. This loads the images, replaces
-the URLs in the data with the corresponding images and calls "callback" when
-all images are loaded (or failed loading). In the callback, you can then call
-$.plot with the data set. See the included example.
-
-A more low-level helper, $.plot.image.load(urls, callback) is also included.
-Given a list of URLs, it calls callback with an object mapping from URL to
-Image object when all images are loaded or have failed loading.
-
-The plugin supports these options:
-
- series: {
- images: {
- show: boolean
- anchor: "corner" or "center"
- alpha: [ 0, 1 ]
- }
- }
-
-They can be specified for a specific series:
-
- $.plot( $("#placeholder"), [{
- data: [ ... ],
- images: { ... }
- ])
-
-Note that because the data format is different from usual data points, you
-can't use images with anything else in a specific data series.
-
-Setting "anchor" to "center" causes the pixels in the image to be anchored at
-the corner pixel centers inside of at the pixel corners, effectively letting
-half a pixel stick out to each side in the plot.
-
-A possible future direction could be support for tiling for large images (like
-Google Maps).
-
-*/
-
-(function ($) {
- var options = {
- series: {
- images: {
- show: false,
- alpha: 1,
- anchor: "corner" // or "center"
- }
- }
- };
-
- $.plot.image = {};
-
- $.plot.image.loadDataImages = function (series, options, callback) {
- var urls = [], points = [];
-
- var defaultShow = options.series.images.show;
-
- $.each(series, function (i, s) {
- if (!(defaultShow || s.images.show))
- return;
-
- if (s.data)
- s = s.data;
-
- $.each(s, function (i, p) {
- if (typeof p[0] == "string") {
- urls.push(p[0]);
- points.push(p);
- }
- });
- });
-
- $.plot.image.load(urls, function (loadedImages) {
- $.each(points, function (i, p) {
- var url = p[0];
- if (loadedImages[url])
- p[0] = loadedImages[url];
- });
-
- callback();
- });
- }
-
- $.plot.image.load = function (urls, callback) {
- var missing = urls.length, loaded = {};
- if (missing == 0)
- callback({});
-
- $.each(urls, function (i, url) {
- var handler = function () {
- --missing;
-
- loaded[url] = this;
-
- if (missing == 0)
- callback(loaded);
- };
-
- $(' ').load(handler).error(handler).attr('src', url);
- });
- };
-
- function drawSeries(plot, ctx, series) {
- var plotOffset = plot.getPlotOffset();
-
- if (!series.images || !series.images.show)
- return;
-
- var points = series.datapoints.points,
- ps = series.datapoints.pointsize;
-
- for (var i = 0; i < points.length; i += ps) {
- var img = points[i],
- x1 = points[i + 1], y1 = points[i + 2],
- x2 = points[i + 3], y2 = points[i + 4],
- xaxis = series.xaxis, yaxis = series.yaxis,
- tmp;
-
- // actually we should check img.complete, but it
- // appears to be a somewhat unreliable indicator in
- // IE6 (false even after load event)
- if (!img || img.width <= 0 || img.height <= 0)
- continue;
-
- if (x1 > x2) {
- tmp = x2;
- x2 = x1;
- x1 = tmp;
- }
- if (y1 > y2) {
- tmp = y2;
- y2 = y1;
- y1 = tmp;
- }
-
- // if the anchor is at the center of the pixel, expand the
- // image by 1/2 pixel in each direction
- if (series.images.anchor == "center") {
- tmp = 0.5 * (x2-x1) / (img.width - 1);
- x1 -= tmp;
- x2 += tmp;
- tmp = 0.5 * (y2-y1) / (img.height - 1);
- y1 -= tmp;
- y2 += tmp;
- }
-
- // clip
- if (x1 == x2 || y1 == y2 ||
- x1 >= xaxis.max || x2 <= xaxis.min ||
- y1 >= yaxis.max || y2 <= yaxis.min)
- continue;
-
- var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;
- if (x1 < xaxis.min) {
- sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);
- x1 = xaxis.min;
- }
-
- if (x2 > xaxis.max) {
- sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);
- x2 = xaxis.max;
- }
-
- if (y1 < yaxis.min) {
- sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);
- y1 = yaxis.min;
- }
-
- if (y2 > yaxis.max) {
- sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);
- y2 = yaxis.max;
- }
-
- x1 = xaxis.p2c(x1);
- x2 = xaxis.p2c(x2);
- y1 = yaxis.p2c(y1);
- y2 = yaxis.p2c(y2);
-
- // the transformation may have swapped us
- if (x1 > x2) {
- tmp = x2;
- x2 = x1;
- x1 = tmp;
- }
- if (y1 > y2) {
- tmp = y2;
- y2 = y1;
- y1 = tmp;
- }
-
- tmp = ctx.globalAlpha;
- ctx.globalAlpha *= series.images.alpha;
- ctx.drawImage(img,
- sx1, sy1, sx2 - sx1, sy2 - sy1,
- x1 + plotOffset.left, y1 + plotOffset.top,
- x2 - x1, y2 - y1);
- ctx.globalAlpha = tmp;
- }
- }
-
- function processRawData(plot, series, data, datapoints) {
- if (!series.images.show)
- return;
-
- // format is Image, x1, y1, x2, y2 (opposite corners)
- datapoints.format = [
- { required: true },
- { x: true, number: true, required: true },
- { y: true, number: true, required: true },
- { x: true, number: true, required: true },
- { y: true, number: true, required: true }
- ];
- }
-
- function init(plot) {
- plot.hooks.processRawData.push(processRawData);
- plot.hooks.drawSeries.push(drawSeries);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'image',
- version: '1.1'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.js b/src/legacy/ui/public/flot-charts/jquery.flot.js
deleted file mode 100644
index 43db1cc3d93db..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.js
+++ /dev/null
@@ -1,3168 +0,0 @@
-/* JavaScript plotting library for jQuery, version 0.8.3.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-*/
-
-// first an inline dependency, jquery.colorhelpers.js, we inline it here
-// for convenience
-
-/* Plugin for jQuery for working with colors.
- *
- * Version 1.1.
- *
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- * $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- * var c = $.color.extract($("#mydiv"), 'background-color');
- * console.log(c.r, c.g, c.b, c.a);
- * $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() return the same modified object
- * instead of making a new one.
- *
- * V. 1.1: Fix error handling so e.g. parsing an empty string does
- * produce a color rather than just crashing.
- */
-(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i=1){return"rgb("+[o.r,o.g,o.b].join(",")+")"}else{return"rgba("+[o.r,o.g,o.b,o.a].join(",")+")"}};o.normalize=function(){function clamp(min,value,max){return valuemax?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=""&&c!="transparent")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),"body"));if(c=="rgba(0, 0, 0, 0)")c="transparent";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name=="transparent")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);
-
-// the actual Flot code
-(function($) {
-
- // Cache the prototype hasOwnProperty for faster access
-
- var hasOwnProperty = Object.prototype.hasOwnProperty;
-
- // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM
- // operation produces the same effect as detach, i.e. removing the element
- // without touching its jQuery data.
-
- // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
-
- if (!$.fn.detach) {
- $.fn.detach = function() {
- return this.each(function() {
- if (this.parentNode) {
- this.parentNode.removeChild( this );
- }
- });
- };
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // The Canvas object is a wrapper around an HTML5 tag.
- //
- // @constructor
- // @param {string} cls List of classes to apply to the canvas.
- // @param {element} container Element onto which to append the canvas.
- //
- // Requiring a container is a little iffy, but unfortunately canvas
- // operations don't work unless the canvas is attached to the DOM.
-
- function Canvas(cls, container) {
-
- var element = container.children("." + cls)[0];
-
- if (element == null) {
-
- element = document.createElement("canvas");
- element.className = cls;
-
- $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
- .appendTo(container);
-
- // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
-
- if (!element.getContext) {
- if (window.G_vmlCanvasManager) {
- element = window.G_vmlCanvasManager.initElement(element);
- } else {
- throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
- }
- }
- }
-
- this.element = element;
-
- var context = this.context = element.getContext("2d");
-
- // Determine the screen's ratio of physical to device-independent
- // pixels. This is the ratio between the canvas width that the browser
- // advertises and the number of pixels actually present in that space.
-
- // The iPhone 4, for example, has a device-independent width of 320px,
- // but its screen is actually 640px wide. It therefore has a pixel
- // ratio of 2, while most normal devices have a ratio of 1.
-
- var devicePixelRatio = window.devicePixelRatio || 1,
- backingStoreRatio =
- context.webkitBackingStorePixelRatio ||
- context.mozBackingStorePixelRatio ||
- context.msBackingStorePixelRatio ||
- context.oBackingStorePixelRatio ||
- context.backingStorePixelRatio || 1;
-
- this.pixelRatio = devicePixelRatio / backingStoreRatio;
-
- // Size the canvas to match the internal dimensions of its container
-
- this.resize(container.width(), container.height());
-
- // Collection of HTML div layers for text overlaid onto the canvas
-
- this.textContainer = null;
- this.text = {};
-
- // Cache of text fragments and metrics, so we can avoid expensively
- // re-calculating them when the plot is re-rendered in a loop.
-
- this._textCache = {};
- }
-
- // Resizes the canvas to the given dimensions.
- //
- // @param {number} width New width of the canvas, in pixels.
- // @param {number} width New height of the canvas, in pixels.
-
- Canvas.prototype.resize = function(width, height) {
-
- if (width <= 0 || height <= 0) {
- throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
- }
-
- var element = this.element,
- context = this.context,
- pixelRatio = this.pixelRatio;
-
- // Resize the canvas, increasing its density based on the display's
- // pixel ratio; basically giving it more pixels without increasing the
- // size of its element, to take advantage of the fact that retina
- // displays have that many more pixels in the same advertised space.
-
- // Resizing should reset the state (excanvas seems to be buggy though)
-
- if (this.width != width) {
- element.width = width * pixelRatio;
- element.style.width = width + "px";
- this.width = width;
- }
-
- if (this.height != height) {
- element.height = height * pixelRatio;
- element.style.height = height + "px";
- this.height = height;
- }
-
- // Save the context, so we can reset in case we get replotted. The
- // restore ensure that we're really back at the initial state, and
- // should be safe even if we haven't saved the initial state yet.
-
- context.restore();
- context.save();
-
- // Scale the coordinate space to match the display density; so even though we
- // may have twice as many pixels, we still want lines and other drawing to
- // appear at the same size; the extra pixels will just make them crisper.
-
- context.scale(pixelRatio, pixelRatio);
- };
-
- // Clears the entire canvas area, not including any overlaid HTML text
-
- Canvas.prototype.clear = function() {
- this.context.clearRect(0, 0, this.width, this.height);
- };
-
- // Finishes rendering the canvas, including managing the text overlay.
-
- Canvas.prototype.render = function() {
-
- var cache = this._textCache;
-
- // For each text layer, add elements marked as active that haven't
- // already been rendered, and remove those that are no longer active.
-
- for (var layerKey in cache) {
- if (hasOwnProperty.call(cache, layerKey)) {
-
- var layer = this.getTextLayer(layerKey),
- layerCache = cache[layerKey];
-
- layer.hide();
-
- for (var styleKey in layerCache) {
- if (hasOwnProperty.call(layerCache, styleKey)) {
- var styleCache = layerCache[styleKey];
- for (var key in styleCache) {
- if (hasOwnProperty.call(styleCache, key)) {
-
- var positions = styleCache[key].positions;
-
- for (var i = 0, position; position = positions[i]; i++) {
- if (position.active) {
- if (!position.rendered) {
- layer.append(position.element);
- position.rendered = true;
- }
- } else {
- positions.splice(i--, 1);
- if (position.rendered) {
- position.element.detach();
- }
- }
- }
-
- if (positions.length == 0) {
- delete styleCache[key];
- }
- }
- }
- }
- }
-
- layer.show();
- }
- }
- };
-
- // Creates (if necessary) and returns the text overlay container.
- //
- // @param {string} classes String of space-separated CSS classes used to
- // uniquely identify the text layer.
- // @return {object} The jQuery-wrapped text-layer div.
-
- Canvas.prototype.getTextLayer = function(classes) {
-
- var layer = this.text[classes];
-
- // Create the text layer if it doesn't exist
-
- if (layer == null) {
-
- // Create the text layer container, if it doesn't exist
-
- if (this.textContainer == null) {
- this.textContainer = $("
")
- .css({
- position: "absolute",
- top: 0,
- left: 0,
- bottom: 0,
- right: 0,
- 'font-size': "smaller",
- color: "#545454"
- })
- .insertAfter(this.element);
- }
-
- layer = this.text[classes] = $("
")
- .addClass(classes)
- .css({
- position: "absolute",
- top: 0,
- left: 0,
- bottom: 0,
- right: 0
- })
- .appendTo(this.textContainer);
- }
-
- return layer;
- };
-
- // Creates (if necessary) and returns a text info object.
- //
- // The object looks like this:
- //
- // {
- // width: Width of the text's wrapper div.
- // height: Height of the text's wrapper div.
- // element: The jQuery-wrapped HTML div containing the text.
- // positions: Array of positions at which this text is drawn.
- // }
- //
- // The positions array contains objects that look like this:
- //
- // {
- // active: Flag indicating whether the text should be visible.
- // rendered: Flag indicating whether the text is currently visible.
- // element: The jQuery-wrapped HTML div containing the text.
- // x: X coordinate at which to draw the text.
- // y: Y coordinate at which to draw the text.
- // }
- //
- // Each position after the first receives a clone of the original element.
- //
- // The idea is that that the width, height, and general 'identity' of the
- // text is constant no matter where it is placed; the placements are a
- // secondary property.
- //
- // Canvas maintains a cache of recently-used text info objects; getTextInfo
- // either returns the cached element or creates a new entry.
- //
- // @param {string} layer A string of space-separated CSS classes uniquely
- // identifying the layer containing this text.
- // @param {string} text Text string to retrieve info for.
- // @param {(string|object)=} font Either a string of space-separated CSS
- // classes or a font-spec object, defining the text's font and style.
- // @param {number=} angle Angle at which to rotate the text, in degrees.
- // Angle is currently unused, it will be implemented in the future.
- // @param {number=} width Maximum width of the text before it wraps.
- // @return {object} a text info object.
-
- Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
-
- var textStyle, layerCache, styleCache, info;
-
- // Cast the value to a string, in case we were given a number or such
-
- text = "" + text;
-
- // If the font is a font-spec object, generate a CSS font definition
-
- if (typeof font === "object") {
- textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
- } else {
- textStyle = font;
- }
-
- // Retrieve (or create) the cache for the text's layer and styles
-
- layerCache = this._textCache[layer];
-
- if (layerCache == null) {
- layerCache = this._textCache[layer] = {};
- }
-
- styleCache = layerCache[textStyle];
-
- if (styleCache == null) {
- styleCache = layerCache[textStyle] = {};
- }
-
- info = styleCache[text];
-
- // If we can't find a matching element in our cache, create a new one
-
- if (info == null) {
-
- var element = $("
").html(text)
- .css({
- position: "absolute",
- 'max-width': width,
- top: -9999
- })
- .appendTo(this.getTextLayer(layer));
-
- if (typeof font === "object") {
- element.css({
- font: textStyle,
- color: font.color
- });
- } else if (typeof font === "string") {
- element.addClass(font);
- }
-
- info = styleCache[text] = {
- width: element.outerWidth(true),
- height: element.outerHeight(true),
- element: element,
- positions: []
- };
-
- element.detach();
- }
-
- return info;
- };
-
- // Adds a text string to the canvas text overlay.
- //
- // The text isn't drawn immediately; it is marked as rendering, which will
- // result in its addition to the canvas on the next render pass.
- //
- // @param {string} layer A string of space-separated CSS classes uniquely
- // identifying the layer containing this text.
- // @param {number} x X coordinate at which to draw the text.
- // @param {number} y Y coordinate at which to draw the text.
- // @param {string} text Text string to draw.
- // @param {(string|object)=} font Either a string of space-separated CSS
- // classes or a font-spec object, defining the text's font and style.
- // @param {number=} angle Angle at which to rotate the text, in degrees.
- // Angle is currently unused, it will be implemented in the future.
- // @param {number=} width Maximum width of the text before it wraps.
- // @param {string=} halign Horizontal alignment of the text; either "left",
- // "center" or "right".
- // @param {string=} valign Vertical alignment of the text; either "top",
- // "middle" or "bottom".
-
- Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
-
- var info = this.getTextInfo(layer, text, font, angle, width),
- positions = info.positions;
-
- // Tweak the div's position to match the text's alignment
-
- if (halign == "center") {
- x -= info.width / 2;
- } else if (halign == "right") {
- x -= info.width;
- }
-
- if (valign == "middle") {
- y -= info.height / 2;
- } else if (valign == "bottom") {
- y -= info.height;
- }
-
- // Determine whether this text already exists at this position.
- // If so, mark it for inclusion in the next render pass.
-
- for (var i = 0, position; position = positions[i]; i++) {
- if (position.x == x && position.y == y) {
- position.active = true;
- return;
- }
- }
-
- // If the text doesn't exist at this position, create a new entry
-
- // For the very first position we'll re-use the original element,
- // while for subsequent ones we'll clone it.
-
- position = {
- active: true,
- rendered: false,
- element: positions.length ? info.element.clone() : info.element,
- x: x,
- y: y
- };
-
- positions.push(position);
-
- // Move the element to its final position within the container
-
- position.element.css({
- top: Math.round(y),
- left: Math.round(x),
- 'text-align': halign // In case the text wraps
- });
- };
-
- // Removes one or more text strings from the canvas text overlay.
- //
- // If no parameters are given, all text within the layer is removed.
- //
- // Note that the text is not immediately removed; it is simply marked as
- // inactive, which will result in its removal on the next render pass.
- // This avoids the performance penalty for 'clear and redraw' behavior,
- // where we potentially get rid of all text on a layer, but will likely
- // add back most or all of it later, as when redrawing axes, for example.
- //
- // @param {string} layer A string of space-separated CSS classes uniquely
- // identifying the layer containing this text.
- // @param {number=} x X coordinate of the text.
- // @param {number=} y Y coordinate of the text.
- // @param {string=} text Text string to remove.
- // @param {(string|object)=} font Either a string of space-separated CSS
- // classes or a font-spec object, defining the text's font and style.
- // @param {number=} angle Angle at which the text is rotated, in degrees.
- // Angle is currently unused, it will be implemented in the future.
-
- Canvas.prototype.removeText = function(layer, x, y, text, font, angle) {
- if (text == null) {
- var layerCache = this._textCache[layer];
- if (layerCache != null) {
- for (var styleKey in layerCache) {
- if (hasOwnProperty.call(layerCache, styleKey)) {
- var styleCache = layerCache[styleKey];
- for (var key in styleCache) {
- if (hasOwnProperty.call(styleCache, key)) {
- var positions = styleCache[key].positions;
- for (var i = 0, position; position = positions[i]; i++) {
- position.active = false;
- }
- }
- }
- }
- }
- }
- } else {
- var positions = this.getTextInfo(layer, text, font, angle).positions;
- for (var i = 0, position; position = positions[i]; i++) {
- if (position.x == x && position.y == y) {
- position.active = false;
- }
- }
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- // The top-level container for the entire plot.
-
- function Plot(placeholder, data_, options_, plugins) {
- // data is on the form:
- // [ series1, series2 ... ]
- // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
- // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
-
- var series = [],
- options = {
- // the color theme used for graphs
- colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
- legend: {
- show: true,
- noColumns: 1, // number of columns in legend table
- labelFormatter: null, // fn: string -> string
- labelBoxBorderColor: "#ccc", // border color for the little label boxes
- container: null, // container (as jQuery object) to put legend in, null means default on top of graph
- position: "ne", // position of default legend container within plot
- margin: 5, // distance from grid edge to default legend container within plot
- backgroundColor: null, // null means auto-detect
- backgroundOpacity: 0.85, // set to 0 to avoid background
- sorted: null // default to no legend sorting
- },
- xaxis: {
- show: null, // null = auto-detect, true = always, false = never
- position: "bottom", // or "top"
- mode: null, // null or "time"
- font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
- color: null, // base color, labels, ticks
- tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
- transform: null, // null or f: number -> number to transform axis
- inverseTransform: null, // if transform is set, this should be the inverse function
- min: null, // min. value to show, null means set automatically
- max: null, // max. value to show, null means set automatically
- autoscaleMargin: null, // margin in % to add if auto-setting min/max
- ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
- tickFormatter: null, // fn: number -> string
- labelWidth: null, // size of tick labels in pixels
- labelHeight: null,
- reserveSpace: null, // whether to reserve space even if axis isn't shown
- tickLength: null, // size in pixels of ticks, or "full" for whole line
- alignTicksWithAxis: null, // axis number or null for no sync
- tickDecimals: null, // no. of decimals, null means auto
- tickSize: null, // number or [number, "unit"]
- minTickSize: null // number or [number, "unit"]
- },
- yaxis: {
- autoscaleMargin: 0.02,
- position: "left" // or "right"
- },
- xaxes: [],
- yaxes: [],
- series: {
- points: {
- show: false,
- radius: 3,
- lineWidth: 2, // in pixels
- fill: true,
- fillColor: "#ffffff",
- symbol: "circle" // or callback
- },
- lines: {
- // we don't put in show: false so we can see
- // whether lines were actively disabled
- lineWidth: 2, // in pixels
- fill: false,
- fillColor: null,
- steps: false
- // Omit 'zero', so we can later default its value to
- // match that of the 'fill' option.
- },
- bars: {
- show: false,
- lineWidth: 2, // in pixels
- barWidth: 1, // in units of the x axis
- fill: true,
- fillColor: null,
- align: "left", // "left", "right", or "center"
- horizontal: false,
- zero: true
- },
- shadowSize: 3,
- highlightColor: null
- },
- grid: {
- show: true,
- aboveData: false,
- color: "#545454", // primary color used for outline and labels
- backgroundColor: null, // null for transparent, else color
- borderColor: null, // set if different from the grid color
- tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
- margin: 0, // distance from the canvas edge to the grid
- labelMargin: 5, // in pixels
- axisMargin: 8, // in pixels
- borderWidth: 2, // in pixels
- minBorderMargin: null, // in pixels, null means taken from points radius
- markings: null, // array of ranges or fn: axes -> array of ranges
- markingsColor: "#f4f4f4",
- markingsLineWidth: 2,
- // interactive stuff
- clickable: false,
- hoverable: false,
- autoHighlight: true, // highlight in case mouse is near
- mouseActiveRadius: 10 // how far the mouse can be away to activate an item
- },
- interaction: {
- redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow
- },
- hooks: {}
- },
- surface = null, // the canvas for the plot itself
- overlay = null, // canvas for interactive stuff on top of plot
- eventHolder = null, // jQuery object that events should be bound to
- ctx = null, octx = null,
- xaxes = [], yaxes = [],
- plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
- plotWidth = 0, plotHeight = 0,
- hooks = {
- processOptions: [],
- processRawData: [],
- processDatapoints: [],
- processOffset: [],
- drawBackground: [],
- drawSeries: [],
- draw: [],
- bindEvents: [],
- drawOverlay: [],
- shutdown: []
- },
- plot = this;
-
- // public functions
- plot.setData = setData;
- plot.setupGrid = setupGrid;
- plot.draw = draw;
- plot.getPlaceholder = function() { return placeholder; };
- plot.getCanvas = function() { return surface.element; };
- plot.getPlotOffset = function() { return plotOffset; };
- plot.width = function () { return plotWidth; };
- plot.height = function () { return plotHeight; };
- plot.offset = function () {
- var o = eventHolder.offset();
- o.left += plotOffset.left;
- o.top += plotOffset.top;
- return o;
- };
- plot.getData = function () { return series; };
- plot.getAxes = function () {
- var res = {}, i;
- $.each(xaxes.concat(yaxes), function (_, axis) {
- if (axis)
- res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
- });
- return res;
- };
- plot.getXAxes = function () { return xaxes; };
- plot.getYAxes = function () { return yaxes; };
- plot.c2p = canvasToAxisCoords;
- plot.p2c = axisToCanvasCoords;
- plot.getOptions = function () { return options; };
- plot.highlight = highlight;
- plot.unhighlight = unhighlight;
- plot.triggerRedrawOverlay = triggerRedrawOverlay;
- plot.pointOffset = function(point) {
- return {
- left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
- top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
- };
- };
- plot.shutdown = shutdown;
- plot.destroy = function () {
- shutdown();
- placeholder.removeData("plot").empty();
-
- series = [];
- options = null;
- surface = null;
- overlay = null;
- eventHolder = null;
- ctx = null;
- octx = null;
- xaxes = [];
- yaxes = [];
- hooks = null;
- highlights = [];
- plot = null;
- };
- plot.resize = function () {
- var width = placeholder.width(),
- height = placeholder.height();
- surface.resize(width, height);
- overlay.resize(width, height);
- };
-
- // public attributes
- plot.hooks = hooks;
-
- // initialize
- initPlugins(plot);
- parseOptions(options_);
- setupCanvases();
- setData(data_);
- setupGrid();
- draw();
- bindEvents();
-
-
- function executeHooks(hook, args) {
- args = [plot].concat(args);
- for (var i = 0; i < hook.length; ++i)
- hook[i].apply(this, args);
- }
-
- function initPlugins() {
-
- // References to key classes, allowing plugins to modify them
-
- var classes = {
- Canvas: Canvas
- };
-
- for (var i = 0; i < plugins.length; ++i) {
- var p = plugins[i];
- p.init(plot, classes);
- if (p.options)
- $.extend(true, options, p.options);
- }
- }
-
- function parseOptions(opts) {
-
- $.extend(true, options, opts);
-
- // $.extend merges arrays, rather than replacing them. When less
- // colors are provided than the size of the default palette, we
- // end up with those colors plus the remaining defaults, which is
- // not expected behavior; avoid it by replacing them here.
-
- if (opts && opts.colors) {
- options.colors = opts.colors;
- }
-
- if (options.xaxis.color == null)
- options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
- if (options.yaxis.color == null)
- options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
-
- if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
- options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
- if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
- options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
-
- if (options.grid.borderColor == null)
- options.grid.borderColor = options.grid.color;
- if (options.grid.tickColor == null)
- options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
-
- // Fill in defaults for axis options, including any unspecified
- // font-spec fields, if a font-spec was provided.
-
- // If no x/y axis options were provided, create one of each anyway,
- // since the rest of the code assumes that they exist.
-
- var i, axisOptions, axisCount,
- fontSize = placeholder.css("font-size"),
- fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
- fontDefaults = {
- style: placeholder.css("font-style"),
- size: Math.round(0.8 * fontSizeDefault),
- variant: placeholder.css("font-variant"),
- weight: placeholder.css("font-weight"),
- family: placeholder.css("font-family")
- };
-
- axisCount = options.xaxes.length || 1;
- for (i = 0; i < axisCount; ++i) {
-
- axisOptions = options.xaxes[i];
- if (axisOptions && !axisOptions.tickColor) {
- axisOptions.tickColor = axisOptions.color;
- }
-
- axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
- options.xaxes[i] = axisOptions;
-
- if (axisOptions.font) {
- axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
- if (!axisOptions.font.color) {
- axisOptions.font.color = axisOptions.color;
- }
- if (!axisOptions.font.lineHeight) {
- axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
- }
- }
- }
-
- axisCount = options.yaxes.length || 1;
- for (i = 0; i < axisCount; ++i) {
-
- axisOptions = options.yaxes[i];
- if (axisOptions && !axisOptions.tickColor) {
- axisOptions.tickColor = axisOptions.color;
- }
-
- axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
- options.yaxes[i] = axisOptions;
-
- if (axisOptions.font) {
- axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
- if (!axisOptions.font.color) {
- axisOptions.font.color = axisOptions.color;
- }
- if (!axisOptions.font.lineHeight) {
- axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
- }
- }
- }
-
- // backwards compatibility, to be removed in future
- if (options.xaxis.noTicks && options.xaxis.ticks == null)
- options.xaxis.ticks = options.xaxis.noTicks;
- if (options.yaxis.noTicks && options.yaxis.ticks == null)
- options.yaxis.ticks = options.yaxis.noTicks;
- if (options.x2axis) {
- options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
- options.xaxes[1].position = "top";
- // Override the inherit to allow the axis to auto-scale
- if (options.x2axis.min == null) {
- options.xaxes[1].min = null;
- }
- if (options.x2axis.max == null) {
- options.xaxes[1].max = null;
- }
- }
- if (options.y2axis) {
- options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
- options.yaxes[1].position = "right";
- // Override the inherit to allow the axis to auto-scale
- if (options.y2axis.min == null) {
- options.yaxes[1].min = null;
- }
- if (options.y2axis.max == null) {
- options.yaxes[1].max = null;
- }
- }
- if (options.grid.coloredAreas)
- options.grid.markings = options.grid.coloredAreas;
- if (options.grid.coloredAreasColor)
- options.grid.markingsColor = options.grid.coloredAreasColor;
- if (options.lines)
- $.extend(true, options.series.lines, options.lines);
- if (options.points)
- $.extend(true, options.series.points, options.points);
- if (options.bars)
- $.extend(true, options.series.bars, options.bars);
- if (options.shadowSize != null)
- options.series.shadowSize = options.shadowSize;
- if (options.highlightColor != null)
- options.series.highlightColor = options.highlightColor;
-
- // save options on axes for future reference
- for (i = 0; i < options.xaxes.length; ++i)
- getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
- for (i = 0; i < options.yaxes.length; ++i)
- getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
-
- // add hooks from options
- for (var n in hooks)
- if (options.hooks[n] && options.hooks[n].length)
- hooks[n] = hooks[n].concat(options.hooks[n]);
-
- executeHooks(hooks.processOptions, [options]);
- }
-
- function setData(d) {
- series = parseData(d);
- fillInSeriesOptions();
- processData();
- }
-
- function parseData(d) {
- var res = [];
- for (var i = 0; i < d.length; ++i) {
- var s = $.extend(true, {}, options.series);
-
- if (d[i].data != null) {
- s.data = d[i].data; // move the data instead of deep-copy
- delete d[i].data;
-
- $.extend(true, s, d[i]);
-
- d[i].data = s.data;
- }
- else
- s.data = d[i];
- res.push(s);
- }
-
- return res;
- }
-
- function axisNumber(obj, coord) {
- var a = obj[coord + "axis"];
- if (typeof a == "object") // if we got a real axis, extract number
- a = a.n;
- if (typeof a != "number")
- a = 1; // default to first axis
- return a;
- }
-
- function allAxes() {
- // return flat array without annoying null entries
- return $.grep(xaxes.concat(yaxes), function (a) { return a; });
- }
-
- function canvasToAxisCoords(pos) {
- // return an object with x/y corresponding to all used axes
- var res = {}, i, axis;
- for (i = 0; i < xaxes.length; ++i) {
- axis = xaxes[i];
- if (axis && axis.used)
- res["x" + axis.n] = axis.c2p(pos.left);
- }
-
- for (i = 0; i < yaxes.length; ++i) {
- axis = yaxes[i];
- if (axis && axis.used)
- res["y" + axis.n] = axis.c2p(pos.top);
- }
-
- if (res.x1 !== undefined)
- res.x = res.x1;
- if (res.y1 !== undefined)
- res.y = res.y1;
-
- return res;
- }
-
- function axisToCanvasCoords(pos) {
- // get canvas coords from the first pair of x/y found in pos
- var res = {}, i, axis, key;
-
- for (i = 0; i < xaxes.length; ++i) {
- axis = xaxes[i];
- if (axis && axis.used) {
- key = "x" + axis.n;
- if (pos[key] == null && axis.n == 1)
- key = "x";
-
- if (pos[key] != null) {
- res.left = axis.p2c(pos[key]);
- break;
- }
- }
- }
-
- for (i = 0; i < yaxes.length; ++i) {
- axis = yaxes[i];
- if (axis && axis.used) {
- key = "y" + axis.n;
- if (pos[key] == null && axis.n == 1)
- key = "y";
-
- if (pos[key] != null) {
- res.top = axis.p2c(pos[key]);
- break;
- }
- }
- }
-
- return res;
- }
-
- function getOrCreateAxis(axes, number) {
- if (!axes[number - 1])
- axes[number - 1] = {
- n: number, // save the number for future reference
- direction: axes == xaxes ? "x" : "y",
- options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
- };
-
- return axes[number - 1];
- }
-
- function fillInSeriesOptions() {
-
- var neededColors = series.length, maxIndex = -1, i;
-
- // Subtract the number of series that already have fixed colors or
- // color indexes from the number that we still need to generate.
-
- for (i = 0; i < series.length; ++i) {
- var sc = series[i].color;
- if (sc != null) {
- neededColors--;
- if (typeof sc == "number" && sc > maxIndex) {
- maxIndex = sc;
- }
- }
- }
-
- // If any of the series have fixed color indexes, then we need to
- // generate at least as many colors as the highest index.
-
- if (neededColors <= maxIndex) {
- neededColors = maxIndex + 1;
- }
-
- // Generate all the colors, using first the option colors and then
- // variations on those colors once they're exhausted.
-
- var c, colors = [], colorPool = options.colors,
- colorPoolSize = colorPool.length, variation = 0;
-
- for (i = 0; i < neededColors; i++) {
-
- c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
-
- // Each time we exhaust the colors in the pool we adjust
- // a scaling factor used to produce more variations on
- // those colors. The factor alternates negative/positive
- // to produce lighter/darker colors.
-
- // Reset the variation after every few cycles, or else
- // it will end up producing only white or black colors.
-
- if (i % colorPoolSize == 0 && i) {
- if (variation >= 0) {
- if (variation < 0.5) {
- variation = -variation - 0.2;
- } else variation = 0;
- } else variation = -variation;
- }
-
- colors[i] = c.scale('rgb', 1 + variation);
- }
-
- // Finalize the series options, filling in their colors
-
- var colori = 0, s;
- for (i = 0; i < series.length; ++i) {
- s = series[i];
-
- // assign colors
- if (s.color == null) {
- s.color = colors[colori].toString();
- ++colori;
- }
- else if (typeof s.color == "number")
- s.color = colors[s.color].toString();
-
- // turn on lines automatically in case nothing is set
- if (s.lines.show == null) {
- var v, show = true;
- for (v in s)
- if (s[v] && s[v].show) {
- show = false;
- break;
- }
- if (show)
- s.lines.show = true;
- }
-
- // If nothing was provided for lines.zero, default it to match
- // lines.fill, since areas by default should extend to zero.
-
- if (s.lines.zero == null) {
- s.lines.zero = !!s.lines.fill;
- }
-
- // setup axes
- s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
- s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
- }
- }
-
- function processData() {
- var topSentry = Number.POSITIVE_INFINITY,
- bottomSentry = Number.NEGATIVE_INFINITY,
- fakeInfinity = Number.MAX_VALUE,
- i, j, k, m, length,
- s, points, ps, x, y, axis, val, f, p,
- data, format;
-
- function updateAxis(axis, min, max) {
- if (min < axis.datamin && min != -fakeInfinity)
- axis.datamin = min;
- if (max > axis.datamax && max != fakeInfinity)
- axis.datamax = max;
- }
-
- $.each(allAxes(), function (_, axis) {
- // init axis
- axis.datamin = topSentry;
- axis.datamax = bottomSentry;
- axis.used = false;
- });
-
- for (i = 0; i < series.length; ++i) {
- s = series[i];
- s.datapoints = { points: [] };
-
- executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
- }
-
- // first pass: clean and copy data
- for (i = 0; i < series.length; ++i) {
- s = series[i];
-
- data = s.data;
- format = s.datapoints.format;
-
- if (!format) {
- format = [];
- // find out how to copy
- format.push({ x: true, number: true, required: true });
- format.push({ y: true, number: true, required: true });
-
- if (s.bars.show || (s.lines.show && s.lines.fill)) {
- var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
- format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
- if (s.bars.horizontal) {
- delete format[format.length - 1].y;
- format[format.length - 1].x = true;
- }
- }
-
- s.datapoints.format = format;
- }
-
- if (s.datapoints.pointsize != null)
- continue; // already filled in
-
- s.datapoints.pointsize = format.length;
-
- ps = s.datapoints.pointsize;
- points = s.datapoints.points;
-
- var insertSteps = s.lines.show && s.lines.steps;
- s.xaxis.used = s.yaxis.used = true;
-
- for (j = k = 0; j < data.length; ++j, k += ps) {
- p = data[j];
-
- var nullify = p == null;
- if (!nullify) {
- for (m = 0; m < ps; ++m) {
- val = p[m];
- f = format[m];
-
- if (f) {
- if (f.number && val != null) {
- val = +val; // convert to number
- if (isNaN(val))
- val = null;
- else if (val == Infinity)
- val = fakeInfinity;
- else if (val == -Infinity)
- val = -fakeInfinity;
- }
-
- if (val == null) {
- if (f.required)
- nullify = true;
-
- if (f.defaultValue != null)
- val = f.defaultValue;
- }
- }
-
- points[k + m] = val;
- }
- }
-
- if (nullify) {
- for (m = 0; m < ps; ++m) {
- val = points[k + m];
- if (val != null) {
- f = format[m];
- // extract min/max info
- if (f.autoscale !== false) {
- if (f.x) {
- updateAxis(s.xaxis, val, val);
- }
- if (f.y) {
- updateAxis(s.yaxis, val, val);
- }
- }
- }
- points[k + m] = null;
- }
- }
- else {
- // a little bit of line specific stuff that
- // perhaps shouldn't be here, but lacking
- // better means...
- if (insertSteps && k > 0
- && points[k - ps] != null
- && points[k - ps] != points[k]
- && points[k - ps + 1] != points[k + 1]) {
- // copy the point to make room for a middle point
- for (m = 0; m < ps; ++m)
- points[k + ps + m] = points[k + m];
-
- // middle point has same y
- points[k + 1] = points[k - ps + 1];
-
- // we've added a point, better reflect that
- k += ps;
- }
- }
- }
- }
-
- // give the hooks a chance to run
- for (i = 0; i < series.length; ++i) {
- s = series[i];
-
- executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
- }
-
- // second pass: find datamax/datamin for auto-scaling
- for (i = 0; i < series.length; ++i) {
- s = series[i];
- points = s.datapoints.points;
- ps = s.datapoints.pointsize;
- format = s.datapoints.format;
-
- var xmin = topSentry, ymin = topSentry,
- xmax = bottomSentry, ymax = bottomSentry;
-
- for (j = 0; j < points.length; j += ps) {
- if (points[j] == null)
- continue;
-
- for (m = 0; m < ps; ++m) {
- val = points[j + m];
- f = format[m];
- if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
- continue;
-
- if (f.x) {
- if (val < xmin)
- xmin = val;
- if (val > xmax)
- xmax = val;
- }
- if (f.y) {
- if (val < ymin)
- ymin = val;
- if (val > ymax)
- ymax = val;
- }
- }
- }
-
- if (s.bars.show) {
- // make sure we got room for the bar on the dancing floor
- var delta;
-
- switch (s.bars.align) {
- case "left":
- delta = 0;
- break;
- case "right":
- delta = -s.bars.barWidth;
- break;
- default:
- delta = -s.bars.barWidth / 2;
- }
-
- if (s.bars.horizontal) {
- ymin += delta;
- ymax += delta + s.bars.barWidth;
- }
- else {
- xmin += delta;
- xmax += delta + s.bars.barWidth;
- }
- }
-
- updateAxis(s.xaxis, xmin, xmax);
- updateAxis(s.yaxis, ymin, ymax);
- }
-
- $.each(allAxes(), function (_, axis) {
- if (axis.datamin == topSentry)
- axis.datamin = null;
- if (axis.datamax == bottomSentry)
- axis.datamax = null;
- });
- }
-
- function setupCanvases() {
-
- // Make sure the placeholder is clear of everything except canvases
- // from a previous plot in this container that we'll try to re-use.
-
- placeholder.css("padding", 0) // padding messes up the positioning
- .children().filter(function(){
- return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
- }).remove();
-
- if (placeholder.css("position") == 'static')
- placeholder.css("position", "relative"); // for positioning labels and overlay
-
- surface = new Canvas("flot-base", placeholder);
- overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
-
- ctx = surface.context;
- octx = overlay.context;
-
- // define which element we're listening for events on
- eventHolder = $(overlay.element).unbind();
-
- // If we're re-using a plot object, shut down the old one
-
- var existing = placeholder.data("plot");
-
- if (existing) {
- existing.shutdown();
- overlay.clear();
- }
-
- // save in case we get replotted
- placeholder.data("plot", plot);
- }
-
- function bindEvents() {
- // bind events
- if (options.grid.hoverable) {
- eventHolder.mousemove(onMouseMove);
-
- // Use bind, rather than .mouseleave, because we officially
- // still support jQuery 1.2.6, which doesn't define a shortcut
- // for mouseenter or mouseleave. This was a bug/oversight that
- // was fixed somewhere around 1.3.x. We can return to using
- // .mouseleave when we drop support for 1.2.6.
-
- eventHolder.bind("mouseleave", onMouseLeave);
- }
-
- if (options.grid.clickable)
- eventHolder.click(onClick);
-
- executeHooks(hooks.bindEvents, [eventHolder]);
- }
-
- function shutdown() {
- if (redrawTimeout)
- clearTimeout(redrawTimeout);
-
- eventHolder.unbind("mousemove", onMouseMove);
- eventHolder.unbind("mouseleave", onMouseLeave);
- eventHolder.unbind("click", onClick);
-
- executeHooks(hooks.shutdown, [eventHolder]);
- }
-
- function setTransformationHelpers(axis) {
- // set helper functions on the axis, assumes plot area
- // has been computed already
-
- function identity(x) { return x; }
-
- var s, m, t = axis.options.transform || identity,
- it = axis.options.inverseTransform;
-
- // precompute how much the axis is scaling a point
- // in canvas space
- if (axis.direction == "x") {
- s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
- m = Math.min(t(axis.max), t(axis.min));
- }
- else {
- s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
- s = -s;
- m = Math.max(t(axis.max), t(axis.min));
- }
-
- // data point to canvas coordinate
- if (t == identity) // slight optimization
- axis.p2c = function (p) { return (p - m) * s; };
- else
- axis.p2c = function (p) { return (t(p) - m) * s; };
- // canvas coordinate to data point
- if (!it)
- axis.c2p = function (c) { return m + c / s; };
- else
- axis.c2p = function (c) { return it(m + c / s); };
- }
-
- function measureTickLabels(axis) {
-
- var opts = axis.options,
- ticks = axis.ticks || [],
- labelWidth = opts.labelWidth || 0,
- labelHeight = opts.labelHeight || 0,
- maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
- legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
- layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
- font = opts.font || "flot-tick-label tickLabel";
-
- for (var i = 0; i < ticks.length; ++i) {
-
- var t = ticks[i];
-
- if (!t.label)
- continue;
-
- var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
-
- labelWidth = Math.max(labelWidth, info.width);
- labelHeight = Math.max(labelHeight, info.height);
- }
-
- axis.labelWidth = opts.labelWidth || labelWidth;
- axis.labelHeight = opts.labelHeight || labelHeight;
- }
-
- function allocateAxisBoxFirstPhase(axis) {
- // find the bounding box of the axis by looking at label
- // widths/heights and ticks, make room by diminishing the
- // plotOffset; this first phase only looks at one
- // dimension per axis, the other dimension depends on the
- // other axes so will have to wait
-
- var lw = axis.labelWidth,
- lh = axis.labelHeight,
- pos = axis.options.position,
- isXAxis = axis.direction === "x",
- tickLength = axis.options.tickLength,
- axisMargin = options.grid.axisMargin,
- padding = options.grid.labelMargin,
- innermost = true,
- outermost = true,
- first = true,
- found = false;
-
- // Determine the axis's position in its direction and on its side
-
- $.each(isXAxis ? xaxes : yaxes, function(i, a) {
- if (a && (a.show || a.reserveSpace)) {
- if (a === axis) {
- found = true;
- } else if (a.options.position === pos) {
- if (found) {
- outermost = false;
- } else {
- innermost = false;
- }
- }
- if (!found) {
- first = false;
- }
- }
- });
-
- // The outermost axis on each side has no margin
-
- if (outermost) {
- axisMargin = 0;
- }
-
- // The ticks for the first axis in each direction stretch across
-
- if (tickLength == null) {
- tickLength = first ? "full" : 5;
- }
-
- if (!isNaN(+tickLength))
- padding += +tickLength;
-
- if (isXAxis) {
- lh += padding;
-
- if (pos == "bottom") {
- plotOffset.bottom += lh + axisMargin;
- axis.box = { top: surface.height - plotOffset.bottom, height: lh };
- }
- else {
- axis.box = { top: plotOffset.top + axisMargin, height: lh };
- plotOffset.top += lh + axisMargin;
- }
- }
- else {
- lw += padding;
-
- if (pos == "left") {
- axis.box = { left: plotOffset.left + axisMargin, width: lw };
- plotOffset.left += lw + axisMargin;
- }
- else {
- plotOffset.right += lw + axisMargin;
- axis.box = { left: surface.width - plotOffset.right, width: lw };
- }
- }
-
- // save for future reference
- axis.position = pos;
- axis.tickLength = tickLength;
- axis.box.padding = padding;
- axis.innermost = innermost;
- }
-
- function allocateAxisBoxSecondPhase(axis) {
- // now that all axis boxes have been placed in one
- // dimension, we can set the remaining dimension coordinates
- if (axis.direction == "x") {
- axis.box.left = plotOffset.left - axis.labelWidth / 2;
- axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
- }
- else {
- axis.box.top = plotOffset.top - axis.labelHeight / 2;
- axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
- }
- }
-
- function adjustLayoutForThingsStickingOut() {
- // possibly adjust plot offset to ensure everything stays
- // inside the canvas and isn't clipped off
-
- var minMargin = options.grid.minBorderMargin,
- axis, i;
-
- // check stuff from the plot (FIXME: this should just read
- // a value from the series, otherwise it's impossible to
- // customize)
- if (minMargin == null) {
- minMargin = 0;
- for (i = 0; i < series.length; ++i)
- minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
- }
-
- var margins = {
- left: minMargin,
- right: minMargin,
- top: minMargin,
- bottom: minMargin
- };
-
- // check axis labels, note we don't check the actual
- // labels but instead use the overall width/height to not
- // jump as much around with replots
- $.each(allAxes(), function (_, axis) {
- if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
- if (axis.direction === "x") {
- margins.left = Math.max(margins.left, axis.labelWidth / 2);
- margins.right = Math.max(margins.right, axis.labelWidth / 2);
- } else {
- margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
- margins.top = Math.max(margins.top, axis.labelHeight / 2);
- }
- }
- });
-
- plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
- plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
- plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
- plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
- }
-
- function setupGrid() {
- var i, axes = allAxes(), showGrid = options.grid.show;
-
- // Initialize the plot's offset from the edge of the canvas
-
- for (var a in plotOffset) {
- var margin = options.grid.margin || 0;
- plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
- }
-
- executeHooks(hooks.processOffset, [plotOffset]);
-
- // If the grid is visible, add its border width to the offset
-
- for (var a in plotOffset) {
- if(typeof(options.grid.borderWidth) == "object") {
- plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
- }
- else {
- plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
- }
- }
-
- $.each(axes, function (_, axis) {
- var axisOpts = axis.options;
- axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
- axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
- setRange(axis);
- });
-
- if (showGrid) {
-
- var allocatedAxes = $.grep(axes, function (axis) {
- return axis.show || axis.reserveSpace;
- });
-
- $.each(allocatedAxes, function (_, axis) {
- // make the ticks
- setupTickGeneration(axis);
- setTicks(axis);
- snapRangeToTicks(axis, axis.ticks);
- // find labelWidth/Height for axis
- measureTickLabels(axis);
- });
-
- // with all dimensions calculated, we can compute the
- // axis bounding boxes, start from the outside
- // (reverse order)
- for (i = allocatedAxes.length - 1; i >= 0; --i)
- allocateAxisBoxFirstPhase(allocatedAxes[i]);
-
- // make sure we've got enough space for things that
- // might stick out
- adjustLayoutForThingsStickingOut();
-
- $.each(allocatedAxes, function (_, axis) {
- allocateAxisBoxSecondPhase(axis);
- });
- }
-
- plotWidth = surface.width - plotOffset.left - plotOffset.right;
- plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
-
- // now we got the proper plot dimensions, we can compute the scaling
- $.each(axes, function (_, axis) {
- setTransformationHelpers(axis);
- });
-
- if (showGrid) {
- drawAxisLabels();
- }
-
- insertLegend();
- }
-
- function setRange(axis) {
- var opts = axis.options,
- min = +(opts.min != null ? opts.min : axis.datamin),
- max = +(opts.max != null ? opts.max : axis.datamax),
- delta = max - min;
-
- if (delta == 0.0) {
- // degenerate case
- var widen = max == 0 ? 1 : 0.01;
-
- if (opts.min == null)
- min -= widen;
- // always widen max if we couldn't widen min to ensure we
- // don't fall into min == max which doesn't work
- if (opts.max == null || opts.min != null)
- max += widen;
- }
- else {
- // consider autoscaling
- var margin = opts.autoscaleMargin;
- if (margin != null) {
- if (opts.min == null) {
- min -= delta * margin;
- // make sure we don't go below zero if all values
- // are positive
- if (min < 0 && axis.datamin != null && axis.datamin >= 0)
- min = 0;
- }
- if (opts.max == null) {
- max += delta * margin;
- if (max > 0 && axis.datamax != null && axis.datamax <= 0)
- max = 0;
- }
- }
- }
- axis.min = min;
- axis.max = max;
- }
-
- function setupTickGeneration(axis) {
- var opts = axis.options;
-
- // estimate number of ticks
- var noTicks;
- if (typeof opts.ticks == "number" && opts.ticks > 0)
- noTicks = opts.ticks;
- else
- // heuristic based on the model a*sqrt(x) fitted to
- // some data points that seemed reasonable
- noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
-
- var delta = (axis.max - axis.min) / noTicks,
- dec = -Math.floor(Math.log(delta) / Math.LN10),
- maxDec = opts.tickDecimals;
-
- if (maxDec != null && dec > maxDec) {
- dec = maxDec;
- }
-
- var magn = Math.pow(10, -dec),
- norm = delta / magn, // norm is between 1.0 and 10.0
- size;
-
- if (norm < 1.5) {
- size = 1;
- } else if (norm < 3) {
- size = 2;
- // special case for 2.5, requires an extra decimal
- if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
- size = 2.5;
- ++dec;
- }
- } else if (norm < 7.5) {
- size = 5;
- } else {
- size = 10;
- }
-
- size *= magn;
-
- if (opts.minTickSize != null && size < opts.minTickSize) {
- size = opts.minTickSize;
- }
-
- axis.delta = delta;
- axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
- axis.tickSize = opts.tickSize || size;
-
- // Time mode was moved to a plug-in in 0.8, and since so many people use it
- // we'll add an especially friendly reminder to make sure they included it.
-
- if (opts.mode == "time" && !axis.tickGenerator) {
- throw new Error("Time mode requires the flot.time plugin.");
- }
-
- // Flot supports base-10 axes; any other mode else is handled by a plug-in,
- // like flot.time.js.
-
- if (!axis.tickGenerator) {
-
- axis.tickGenerator = function (axis) {
-
- var ticks = [],
- start = floorInBase(axis.min, axis.tickSize),
- i = 0,
- v = Number.NaN,
- prev;
-
- do {
- prev = v;
- v = start + i * axis.tickSize;
- ticks.push(v);
- ++i;
- } while (v < axis.max && v != prev);
- return ticks;
- };
-
- axis.tickFormatter = function (value, axis) {
-
- var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
- var formatted = "" + Math.round(value * factor) / factor;
-
- // If tickDecimals was specified, ensure that we have exactly that
- // much precision; otherwise default to the value's own precision.
-
- if (axis.tickDecimals != null) {
- var decimal = formatted.indexOf(".");
- var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
- if (precision < axis.tickDecimals) {
- return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
- }
- }
-
- return formatted;
- };
- }
-
- if ($.isFunction(opts.tickFormatter))
- axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
-
- if (opts.alignTicksWithAxis != null) {
- var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
- if (otherAxis && otherAxis.used && otherAxis != axis) {
- // consider snapping min/max to outermost nice ticks
- var niceTicks = axis.tickGenerator(axis);
- if (niceTicks.length > 0) {
- if (opts.min == null)
- axis.min = Math.min(axis.min, niceTicks[0]);
- if (opts.max == null && niceTicks.length > 1)
- axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
- }
-
- axis.tickGenerator = function (axis) {
- // copy ticks, scaled to this axis
- var ticks = [], v, i;
- for (i = 0; i < otherAxis.ticks.length; ++i) {
- v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
- v = axis.min + v * (axis.max - axis.min);
- ticks.push(v);
- }
- return ticks;
- };
-
- // we might need an extra decimal since forced
- // ticks don't necessarily fit naturally
- if (!axis.mode && opts.tickDecimals == null) {
- var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
- ts = axis.tickGenerator(axis);
-
- // only proceed if the tick interval rounded
- // with an extra decimal doesn't give us a
- // zero at end
- if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
- axis.tickDecimals = extraDec;
- }
- }
- }
- }
-
- function setTicks(axis) {
- var oticks = axis.options.ticks, ticks = [];
- if (oticks == null || (typeof oticks == "number" && oticks > 0))
- ticks = axis.tickGenerator(axis);
- else if (oticks) {
- if ($.isFunction(oticks))
- // generate the ticks
- ticks = oticks(axis);
- else
- ticks = oticks;
- }
-
- // clean up/labelify the supplied ticks, copy them over
- var i, v;
- axis.ticks = [];
- for (i = 0; i < ticks.length; ++i) {
- var label = null;
- var t = ticks[i];
- if (typeof t == "object") {
- v = +t[0];
- if (t.length > 1)
- label = t[1];
- }
- else
- v = +t;
- if (label == null)
- label = axis.tickFormatter(v, axis);
- if (!isNaN(v))
- axis.ticks.push({ v: v, label: label });
- }
- }
-
- function snapRangeToTicks(axis, ticks) {
- if (axis.options.autoscaleMargin && ticks.length > 0) {
- // snap to ticks
- if (axis.options.min == null)
- axis.min = Math.min(axis.min, ticks[0].v);
- if (axis.options.max == null && ticks.length > 1)
- axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
- }
- }
-
- function draw() {
-
- surface.clear();
-
- executeHooks(hooks.drawBackground, [ctx]);
-
- var grid = options.grid;
-
- // draw background, if any
- if (grid.show && grid.backgroundColor)
- drawBackground();
-
- if (grid.show && !grid.aboveData) {
- drawGrid();
- }
-
- for (var i = 0; i < series.length; ++i) {
- executeHooks(hooks.drawSeries, [ctx, series[i]]);
- drawSeries(series[i]);
- }
-
- executeHooks(hooks.draw, [ctx]);
-
- if (grid.show && grid.aboveData) {
- drawGrid();
- }
-
- surface.render();
-
- // A draw implies that either the axes or data have changed, so we
- // should probably update the overlay highlights as well.
-
- triggerRedrawOverlay();
- }
-
- function extractRange(ranges, coord) {
- var axis, from, to, key, axes = allAxes();
-
- for (var i = 0; i < axes.length; ++i) {
- axis = axes[i];
- if (axis.direction == coord) {
- key = coord + axis.n + "axis";
- if (!ranges[key] && axis.n == 1)
- key = coord + "axis"; // support x1axis as xaxis
- if (ranges[key]) {
- from = ranges[key].from;
- to = ranges[key].to;
- break;
- }
- }
- }
-
- // backwards-compat stuff - to be removed in future
- if (!ranges[key]) {
- axis = coord == "x" ? xaxes[0] : yaxes[0];
- from = ranges[coord + "1"];
- to = ranges[coord + "2"];
- }
-
- // auto-reverse as an added bonus
- if (from != null && to != null && from > to) {
- var tmp = from;
- from = to;
- to = tmp;
- }
-
- return { from: from, to: to, axis: axis };
- }
-
- function drawBackground() {
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
- ctx.fillRect(0, 0, plotWidth, plotHeight);
- ctx.restore();
- }
-
- function drawGrid() {
- var i, axes, bw, bc;
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- // draw markings
- var markings = options.grid.markings;
- if (markings) {
- if ($.isFunction(markings)) {
- axes = plot.getAxes();
- // xmin etc. is backwards compatibility, to be
- // removed in the future
- axes.xmin = axes.xaxis.min;
- axes.xmax = axes.xaxis.max;
- axes.ymin = axes.yaxis.min;
- axes.ymax = axes.yaxis.max;
-
- markings = markings(axes);
- }
-
- for (i = 0; i < markings.length; ++i) {
- var m = markings[i],
- xrange = extractRange(m, "x"),
- yrange = extractRange(m, "y");
-
- // fill in missing
- if (xrange.from == null)
- xrange.from = xrange.axis.min;
- if (xrange.to == null)
- xrange.to = xrange.axis.max;
- if (yrange.from == null)
- yrange.from = yrange.axis.min;
- if (yrange.to == null)
- yrange.to = yrange.axis.max;
-
- // clip
- if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
- yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
- continue;
-
- xrange.from = Math.max(xrange.from, xrange.axis.min);
- xrange.to = Math.min(xrange.to, xrange.axis.max);
- yrange.from = Math.max(yrange.from, yrange.axis.min);
- yrange.to = Math.min(yrange.to, yrange.axis.max);
-
- var xequal = xrange.from === xrange.to,
- yequal = yrange.from === yrange.to;
-
- if (xequal && yequal) {
- continue;
- }
-
- // then draw
- xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
- xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
- yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
- yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
-
- if (xequal || yequal) {
- var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
- subPixel = lineWidth % 2 ? 0.5 : 0;
- ctx.beginPath();
- ctx.strokeStyle = m.color || options.grid.markingsColor;
- ctx.lineWidth = lineWidth;
- if (xequal) {
- ctx.moveTo(xrange.to + subPixel, yrange.from);
- ctx.lineTo(xrange.to + subPixel, yrange.to);
- } else {
- ctx.moveTo(xrange.from, yrange.to + subPixel);
- ctx.lineTo(xrange.to, yrange.to + subPixel);
- }
- ctx.stroke();
- } else {
- ctx.fillStyle = m.color || options.grid.markingsColor;
- ctx.fillRect(xrange.from, yrange.to,
- xrange.to - xrange.from,
- yrange.from - yrange.to);
- }
- }
- }
-
- // draw the ticks
- axes = allAxes();
- bw = options.grid.borderWidth;
-
- for (var j = 0; j < axes.length; ++j) {
- var axis = axes[j], box = axis.box,
- t = axis.tickLength, x, y, xoff, yoff;
- if (!axis.show || axis.ticks.length == 0)
- continue;
-
- ctx.lineWidth = 1;
-
- // find the edges
- if (axis.direction == "x") {
- x = 0;
- if (t == "full")
- y = (axis.position == "top" ? 0 : plotHeight);
- else
- y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
- }
- else {
- y = 0;
- if (t == "full")
- x = (axis.position == "left" ? 0 : plotWidth);
- else
- x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
- }
-
- // draw tick bar
- if (!axis.innermost) {
- ctx.strokeStyle = axis.options.color;
- ctx.beginPath();
- xoff = yoff = 0;
- if (axis.direction == "x")
- xoff = plotWidth + 1;
- else
- yoff = plotHeight + 1;
-
- if (ctx.lineWidth == 1) {
- if (axis.direction == "x") {
- y = Math.floor(y) + 0.5;
- } else {
- x = Math.floor(x) + 0.5;
- }
- }
-
- ctx.moveTo(x, y);
- ctx.lineTo(x + xoff, y + yoff);
- ctx.stroke();
- }
-
- // draw ticks
-
- ctx.strokeStyle = axis.options.tickColor;
-
- ctx.beginPath();
- for (i = 0; i < axis.ticks.length; ++i) {
- var v = axis.ticks[i].v;
-
- xoff = yoff = 0;
-
- if (isNaN(v) || v < axis.min || v > axis.max
- // skip those lying on the axes if we got a border
- || (t == "full"
- && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
- && (v == axis.min || v == axis.max)))
- continue;
-
- if (axis.direction == "x") {
- x = axis.p2c(v);
- yoff = t == "full" ? -plotHeight : t;
-
- if (axis.position == "top")
- yoff = -yoff;
- }
- else {
- y = axis.p2c(v);
- xoff = t == "full" ? -plotWidth : t;
-
- if (axis.position == "left")
- xoff = -xoff;
- }
-
- if (ctx.lineWidth == 1) {
- if (axis.direction == "x")
- x = Math.floor(x) + 0.5;
- else
- y = Math.floor(y) + 0.5;
- }
-
- ctx.moveTo(x, y);
- ctx.lineTo(x + xoff, y + yoff);
- }
-
- ctx.stroke();
- }
-
-
- // draw border
- if (bw) {
- // If either borderWidth or borderColor is an object, then draw the border
- // line by line instead of as one rectangle
- bc = options.grid.borderColor;
- if(typeof bw == "object" || typeof bc == "object") {
- if (typeof bw !== "object") {
- bw = {top: bw, right: bw, bottom: bw, left: bw};
- }
- if (typeof bc !== "object") {
- bc = {top: bc, right: bc, bottom: bc, left: bc};
- }
-
- if (bw.top > 0) {
- ctx.strokeStyle = bc.top;
- ctx.lineWidth = bw.top;
- ctx.beginPath();
- ctx.moveTo(0 - bw.left, 0 - bw.top/2);
- ctx.lineTo(plotWidth, 0 - bw.top/2);
- ctx.stroke();
- }
-
- if (bw.right > 0) {
- ctx.strokeStyle = bc.right;
- ctx.lineWidth = bw.right;
- ctx.beginPath();
- ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
- ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
- ctx.stroke();
- }
-
- if (bw.bottom > 0) {
- ctx.strokeStyle = bc.bottom;
- ctx.lineWidth = bw.bottom;
- ctx.beginPath();
- ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
- ctx.lineTo(0, plotHeight + bw.bottom / 2);
- ctx.stroke();
- }
-
- if (bw.left > 0) {
- ctx.strokeStyle = bc.left;
- ctx.lineWidth = bw.left;
- ctx.beginPath();
- ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);
- ctx.lineTo(0- bw.left/2, 0);
- ctx.stroke();
- }
- }
- else {
- ctx.lineWidth = bw;
- ctx.strokeStyle = options.grid.borderColor;
- ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
- }
- }
-
- ctx.restore();
- }
-
- function drawAxisLabels() {
-
- $.each(allAxes(), function (_, axis) {
- var box = axis.box,
- legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
- layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
- font = axis.options.font || "flot-tick-label tickLabel",
- tick, x, y, halign, valign;
-
- // Remove text before checking for axis.show and ticks.length;
- // otherwise plugins, like flot-tickrotor, that draw their own
- // tick labels will end up with both theirs and the defaults.
-
- surface.removeText(layer);
-
- if (!axis.show || axis.ticks.length == 0)
- return;
-
- for (var i = 0; i < axis.ticks.length; ++i) {
-
- tick = axis.ticks[i];
- if (!tick.label || tick.v < axis.min || tick.v > axis.max)
- continue;
-
- if (axis.direction == "x") {
- halign = "center";
- x = plotOffset.left + axis.p2c(tick.v);
- if (axis.position == "bottom") {
- y = box.top + box.padding;
- } else {
- y = box.top + box.height - box.padding;
- valign = "bottom";
- }
- } else {
- valign = "middle";
- y = plotOffset.top + axis.p2c(tick.v);
- if (axis.position == "left") {
- x = box.left + box.width - box.padding;
- halign = "right";
- } else {
- x = box.left + box.padding;
- }
- }
-
- surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
- }
- });
- }
-
- function drawSeries(series) {
- if (series.lines.show)
- drawSeriesLines(series);
- if (series.bars.show)
- drawSeriesBars(series);
- if (series.points.show)
- drawSeriesPoints(series);
- }
-
- function drawSeriesLines(series) {
- function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
- var points = datapoints.points,
- ps = datapoints.pointsize,
- prevx = null, prevy = null;
-
- ctx.beginPath();
- for (var i = ps; i < points.length; i += ps) {
- var x1 = points[i - ps], y1 = points[i - ps + 1],
- x2 = points[i], y2 = points[i + 1];
-
- if (x1 == null || x2 == null)
- continue;
-
- // clip with ymin
- if (y1 <= y2 && y1 < axisy.min) {
- if (y2 < axisy.min)
- continue; // line segment is outside
- // compute new intersection point
- x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
- y1 = axisy.min;
- }
- else if (y2 <= y1 && y2 < axisy.min) {
- if (y1 < axisy.min)
- continue;
- x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
- y2 = axisy.min;
- }
-
- // clip with ymax
- if (y1 >= y2 && y1 > axisy.max) {
- if (y2 > axisy.max)
- continue;
- x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
- y1 = axisy.max;
- }
- else if (y2 >= y1 && y2 > axisy.max) {
- if (y1 > axisy.max)
- continue;
- x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
- y2 = axisy.max;
- }
-
- // clip with xmin
- if (x1 <= x2 && x1 < axisx.min) {
- if (x2 < axisx.min)
- continue;
- y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
- x1 = axisx.min;
- }
- else if (x2 <= x1 && x2 < axisx.min) {
- if (x1 < axisx.min)
- continue;
- y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
- x2 = axisx.min;
- }
-
- // clip with xmax
- if (x1 >= x2 && x1 > axisx.max) {
- if (x2 > axisx.max)
- continue;
- y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
- x1 = axisx.max;
- }
- else if (x2 >= x1 && x2 > axisx.max) {
- if (x1 > axisx.max)
- continue;
- y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
- x2 = axisx.max;
- }
-
- if (x1 != prevx || y1 != prevy)
- ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
-
- prevx = x2;
- prevy = y2;
- ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
- }
- ctx.stroke();
- }
-
- function plotLineArea(datapoints, axisx, axisy) {
- var points = datapoints.points,
- ps = datapoints.pointsize,
- bottom = Math.min(Math.max(0, axisy.min), axisy.max),
- i = 0, top, areaOpen = false,
- ypos = 1, segmentStart = 0, segmentEnd = 0;
-
- // we process each segment in two turns, first forward
- // direction to sketch out top, then once we hit the
- // end we go backwards to sketch the bottom
- while (true) {
- if (ps > 0 && i > points.length + ps)
- break;
-
- i += ps; // ps is negative if going backwards
-
- var x1 = points[i - ps],
- y1 = points[i - ps + ypos],
- x2 = points[i], y2 = points[i + ypos];
-
- if (areaOpen) {
- if (ps > 0 && x1 != null && x2 == null) {
- // at turning point
- segmentEnd = i;
- ps = -ps;
- ypos = 2;
- continue;
- }
-
- if (ps < 0 && i == segmentStart + ps) {
- // done with the reverse sweep
- ctx.fill();
- areaOpen = false;
- ps = -ps;
- ypos = 1;
- i = segmentStart = segmentEnd + ps;
- continue;
- }
- }
-
- if (x1 == null || x2 == null)
- continue;
-
- // clip x values
-
- // clip with xmin
- if (x1 <= x2 && x1 < axisx.min) {
- if (x2 < axisx.min)
- continue;
- y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
- x1 = axisx.min;
- }
- else if (x2 <= x1 && x2 < axisx.min) {
- if (x1 < axisx.min)
- continue;
- y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
- x2 = axisx.min;
- }
-
- // clip with xmax
- if (x1 >= x2 && x1 > axisx.max) {
- if (x2 > axisx.max)
- continue;
- y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
- x1 = axisx.max;
- }
- else if (x2 >= x1 && x2 > axisx.max) {
- if (x1 > axisx.max)
- continue;
- y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
- x2 = axisx.max;
- }
-
- if (!areaOpen) {
- // open area
- ctx.beginPath();
- ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
- areaOpen = true;
- }
-
- // now first check the case where both is outside
- if (y1 >= axisy.max && y2 >= axisy.max) {
- ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
- ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
- continue;
- }
- else if (y1 <= axisy.min && y2 <= axisy.min) {
- ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
- ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
- continue;
- }
-
- // else it's a bit more complicated, there might
- // be a flat maxed out rectangle first, then a
- // triangular cutout or reverse; to find these
- // keep track of the current x values
- var x1old = x1, x2old = x2;
-
- // clip the y values, without shortcutting, we
- // go through all cases in turn
-
- // clip with ymin
- if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
- x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
- y1 = axisy.min;
- }
- else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
- x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
- y2 = axisy.min;
- }
-
- // clip with ymax
- if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
- x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
- y1 = axisy.max;
- }
- else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
- x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
- y2 = axisy.max;
- }
-
- // if the x value was changed we got a rectangle
- // to fill
- if (x1 != x1old) {
- ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
- // it goes to (x1, y1), but we fill that below
- }
-
- // fill triangular section, this sometimes result
- // in redundant points if (x1, y1) hasn't changed
- // from previous line to, but we just ignore that
- ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
- ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
-
- // fill the other rectangle if it's there
- if (x2 != x2old) {
- ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
- ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
- }
- }
- }
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
- ctx.lineJoin = "round";
-
- var lw = series.lines.lineWidth,
- sw = series.shadowSize;
- // FIXME: consider another form of shadow when filling is turned on
- if (lw > 0 && sw > 0) {
- // draw shadow as a thick and thin line with transparency
- ctx.lineWidth = sw;
- ctx.strokeStyle = "rgba(0,0,0,0.1)";
- // position shadow at angle from the mid of line
- var angle = Math.PI/18;
- plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
- ctx.lineWidth = sw/2;
- plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
- }
-
- ctx.lineWidth = lw;
- ctx.strokeStyle = series.color;
- var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
- if (fillStyle) {
- ctx.fillStyle = fillStyle;
- plotLineArea(series.datapoints, series.xaxis, series.yaxis);
- }
-
- if (lw > 0)
- plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
- ctx.restore();
- }
-
- function drawSeriesPoints(series) {
- function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
- var points = datapoints.points, ps = datapoints.pointsize;
-
- for (var i = 0; i < points.length; i += ps) {
- var x = points[i], y = points[i + 1];
- if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
- continue;
-
- ctx.beginPath();
- x = axisx.p2c(x);
- y = axisy.p2c(y) + offset;
- if (symbol == "circle")
- ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
- else
- symbol(ctx, x, y, radius, shadow);
- ctx.closePath();
-
- if (fillStyle) {
- ctx.fillStyle = fillStyle;
- ctx.fill();
- }
- ctx.stroke();
- }
- }
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- var lw = series.points.lineWidth,
- sw = series.shadowSize,
- radius = series.points.radius,
- symbol = series.points.symbol;
-
- // If the user sets the line width to 0, we change it to a very
- // small value. A line width of 0 seems to force the default of 1.
- // Doing the conditional here allows the shadow setting to still be
- // optional even with a lineWidth of 0.
-
- if( lw == 0 )
- lw = 0.0001;
-
- if (lw > 0 && sw > 0) {
- // draw shadow in two steps
- var w = sw / 2;
- ctx.lineWidth = w;
- ctx.strokeStyle = "rgba(0,0,0,0.1)";
- plotPoints(series.datapoints, radius, null, w + w/2, true,
- series.xaxis, series.yaxis, symbol);
-
- ctx.strokeStyle = "rgba(0,0,0,0.2)";
- plotPoints(series.datapoints, radius, null, w/2, true,
- series.xaxis, series.yaxis, symbol);
- }
-
- ctx.lineWidth = lw;
- ctx.strokeStyle = series.color;
- plotPoints(series.datapoints, radius,
- getFillStyle(series.points, series.color), 0, false,
- series.xaxis, series.yaxis, symbol);
- ctx.restore();
- }
-
- function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
- var left, right, bottom, top,
- drawLeft, drawRight, drawTop, drawBottom,
- tmp;
-
- // in horizontal mode, we start the bar from the left
- // instead of from the bottom so it appears to be
- // horizontal rather than vertical
- if (horizontal) {
- drawBottom = drawRight = drawTop = true;
- drawLeft = false;
- left = b;
- right = x;
- top = y + barLeft;
- bottom = y + barRight;
-
- // account for negative bars
- if (right < left) {
- tmp = right;
- right = left;
- left = tmp;
- drawLeft = true;
- drawRight = false;
- }
- }
- else {
- drawLeft = drawRight = drawTop = true;
- drawBottom = false;
- left = x + barLeft;
- right = x + barRight;
- bottom = b;
- top = y;
-
- // account for negative bars
- if (top < bottom) {
- tmp = top;
- top = bottom;
- bottom = tmp;
- drawBottom = true;
- drawTop = false;
- }
- }
-
- // clip
- if (right < axisx.min || left > axisx.max ||
- top < axisy.min || bottom > axisy.max)
- return;
-
- if (left < axisx.min) {
- left = axisx.min;
- drawLeft = false;
- }
-
- if (right > axisx.max) {
- right = axisx.max;
- drawRight = false;
- }
-
- if (bottom < axisy.min) {
- bottom = axisy.min;
- drawBottom = false;
- }
-
- if (top > axisy.max) {
- top = axisy.max;
- drawTop = false;
- }
-
- left = axisx.p2c(left);
- bottom = axisy.p2c(bottom);
- right = axisx.p2c(right);
- top = axisy.p2c(top);
-
- // fill the bar
- if (fillStyleCallback) {
- c.fillStyle = fillStyleCallback(bottom, top);
- c.fillRect(left, top, right - left, bottom - top)
- }
-
- // draw outline
- if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
- c.beginPath();
-
- // FIXME: inline moveTo is buggy with excanvas
- c.moveTo(left, bottom);
- if (drawLeft)
- c.lineTo(left, top);
- else
- c.moveTo(left, top);
- if (drawTop)
- c.lineTo(right, top);
- else
- c.moveTo(right, top);
- if (drawRight)
- c.lineTo(right, bottom);
- else
- c.moveTo(right, bottom);
- if (drawBottom)
- c.lineTo(left, bottom);
- else
- c.moveTo(left, bottom);
- c.stroke();
- }
- }
-
- function drawSeriesBars(series) {
- function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
- var points = datapoints.points, ps = datapoints.pointsize;
-
- for (var i = 0; i < points.length; i += ps) {
- if (points[i] == null)
- continue;
- drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
- }
- }
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- // FIXME: figure out a way to add shadows (for instance along the right edge)
- ctx.lineWidth = series.bars.lineWidth;
- ctx.strokeStyle = series.color;
-
- var barLeft;
-
- switch (series.bars.align) {
- case "left":
- barLeft = 0;
- break;
- case "right":
- barLeft = -series.bars.barWidth;
- break;
- default:
- barLeft = -series.bars.barWidth / 2;
- }
-
- var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
- plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
- ctx.restore();
- }
-
- function getFillStyle(filloptions, seriesColor, bottom, top) {
- var fill = filloptions.fill;
- if (!fill)
- return null;
-
- if (filloptions.fillColor)
- return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
-
- var c = $.color.parse(seriesColor);
- c.a = typeof fill == "number" ? fill : 0.4;
- c.normalize();
- return c.toString();
- }
-
- function insertLegend() {
-
- if (options.legend.container != null) {
- $(options.legend.container).html("");
- } else {
- placeholder.find(".legend").remove();
- }
-
- if (!options.legend.show) {
- return;
- }
-
- var fragments = [], entries = [], rowStarted = false,
- lf = options.legend.labelFormatter, s, label;
-
- // Build a list of legend entries, with each having a label and a color
-
- for (var i = 0; i < series.length; ++i) {
- s = series[i];
- if (s.label) {
- label = lf ? lf(s.label, s) : s.label;
- if (label) {
- entries.push({
- label: label,
- color: s.color
- });
- }
- }
- }
-
- // Sort the legend using either the default or a custom comparator
-
- if (options.legend.sorted) {
- if ($.isFunction(options.legend.sorted)) {
- entries.sort(options.legend.sorted);
- } else if (options.legend.sorted == "reverse") {
- entries.reverse();
- } else {
- var ascending = options.legend.sorted != "descending";
- entries.sort(function(a, b) {
- return a.label == b.label ? 0 : (
- (a.label < b.label) != ascending ? 1 : -1 // Logical XOR
- );
- });
- }
- }
-
- // Generate markup for the list of entries, in their final order
-
- for (var i = 0; i < entries.length; ++i) {
-
- var entry = entries[i];
-
- if (i % options.legend.noColumns == 0) {
- if (rowStarted)
- fragments.push('');
- fragments.push('');
- rowStarted = true;
- }
-
- fragments.push(
- ' ' +
- '' + entry.label + ' '
- );
- }
-
- if (rowStarted)
- fragments.push(' ');
-
- if (fragments.length == 0)
- return;
-
- var table = '' + fragments.join("") + '
';
- if (options.legend.container != null)
- $(options.legend.container).html(table);
- else {
- var pos = "",
- p = options.legend.position,
- m = options.legend.margin;
- if (m[0] == null)
- m = [m, m];
- if (p.charAt(0) == "n")
- pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
- else if (p.charAt(0) == "s")
- pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
- if (p.charAt(1) == "e")
- pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
- else if (p.charAt(1) == "w")
- pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
- var legend = $('' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
').appendTo(placeholder);
- if (options.legend.backgroundOpacity != 0.0) {
- // put in the transparent background
- // separately to avoid blended labels and
- // label boxes
- var c = options.legend.backgroundColor;
- if (c == null) {
- c = options.grid.backgroundColor;
- if (c && typeof c == "string")
- c = $.color.parse(c);
- else
- c = $.color.extract(legend, 'background-color');
- c.a = 1;
- c = c.toString();
- }
- var div = legend.children();
- $('
').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
- }
- }
- }
-
-
- // interactive features
-
- var highlights = [],
- redrawTimeout = null;
-
- // returns the data item the mouse is over, or null if none is found
- function findNearbyItem(mouseX, mouseY, seriesFilter) {
- var maxDistance = options.grid.mouseActiveRadius,
- smallestDistance = maxDistance * maxDistance + 1,
- item = null, foundPoint = false, i, j, ps;
-
- for (i = series.length - 1; i >= 0; --i) {
- if (!seriesFilter(series[i]))
- continue;
-
- var s = series[i],
- axisx = s.xaxis,
- axisy = s.yaxis,
- points = s.datapoints.points,
- mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
- my = axisy.c2p(mouseY),
- maxx = maxDistance / axisx.scale,
- maxy = maxDistance / axisy.scale;
-
- ps = s.datapoints.pointsize;
- // with inverse transforms, we can't use the maxx/maxy
- // optimization, sadly
- if (axisx.options.inverseTransform)
- maxx = Number.MAX_VALUE;
- if (axisy.options.inverseTransform)
- maxy = Number.MAX_VALUE;
-
- if (s.lines.show || s.points.show) {
- for (j = 0; j < points.length; j += ps) {
- var x = points[j], y = points[j + 1];
- if (x == null)
- continue;
-
- // For points and lines, the cursor must be within a
- // certain distance to the data point
- if (x - mx > maxx || x - mx < -maxx ||
- y - my > maxy || y - my < -maxy)
- continue;
-
- // We have to calculate distances in pixels, not in
- // data units, because the scales of the axes may be different
- var dx = Math.abs(axisx.p2c(x) - mouseX),
- dy = Math.abs(axisy.p2c(y) - mouseY),
- dist = dx * dx + dy * dy; // we save the sqrt
-
- // use <= to ensure last point takes precedence
- // (last generally means on top of)
- if (dist < smallestDistance) {
- smallestDistance = dist;
- item = [i, j / ps];
- }
- }
- }
-
- if (s.bars.show && !item) { // no other point can be nearby
-
- var barLeft, barRight;
-
- switch (s.bars.align) {
- case "left":
- barLeft = 0;
- break;
- case "right":
- barLeft = -s.bars.barWidth;
- break;
- default:
- barLeft = -s.bars.barWidth / 2;
- }
-
- barRight = barLeft + s.bars.barWidth;
-
- for (j = 0; j < points.length; j += ps) {
- var x = points[j], y = points[j + 1], b = points[j + 2];
- if (x == null)
- continue;
-
- // for a bar graph, the cursor must be inside the bar
- if (series[i].bars.horizontal ?
- (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
- my >= y + barLeft && my <= y + barRight) :
- (mx >= x + barLeft && mx <= x + barRight &&
- my >= Math.min(b, y) && my <= Math.max(b, y)))
- item = [i, j / ps];
- }
- }
- }
-
- if (item) {
- i = item[0];
- j = item[1];
- ps = series[i].datapoints.pointsize;
-
- return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
- dataIndex: j,
- series: series[i],
- seriesIndex: i };
- }
-
- return null;
- }
-
- function onMouseMove(e) {
- if (options.grid.hoverable)
- triggerClickHoverEvent("plothover", e,
- function (s) { return s["hoverable"] != false; });
- }
-
- function onMouseLeave(e) {
- if (options.grid.hoverable)
- triggerClickHoverEvent("plothover", e,
- function (s) { return false; });
- }
-
- function onClick(e) {
- triggerClickHoverEvent("plotclick", e,
- function (s) { return s["clickable"] != false; });
- }
-
- // trigger click or hover event (they send the same parameters
- // so we share their code)
- function triggerClickHoverEvent(eventname, event, seriesFilter) {
- var offset = eventHolder.offset(),
- canvasX = event.pageX - offset.left - plotOffset.left,
- canvasY = event.pageY - offset.top - plotOffset.top,
- pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
-
- pos.pageX = event.pageX;
- pos.pageY = event.pageY;
-
- var item = findNearbyItem(canvasX, canvasY, seriesFilter);
-
- if (item) {
- // fill in mouse pos for any listeners out there
- item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
- item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
- }
-
- if (options.grid.autoHighlight) {
- // clear auto-highlights
- for (var i = 0; i < highlights.length; ++i) {
- var h = highlights[i];
- if (h.auto == eventname &&
- !(item && h.series == item.series &&
- h.point[0] == item.datapoint[0] &&
- h.point[1] == item.datapoint[1]))
- unhighlight(h.series, h.point);
- }
-
- if (item)
- highlight(item.series, item.datapoint, eventname);
- }
-
- placeholder.trigger(eventname, [ pos, item ]);
- }
-
- function triggerRedrawOverlay() {
- var t = options.interaction.redrawOverlayInterval;
- if (t == -1) { // skip event queue
- drawOverlay();
- return;
- }
-
- if (!redrawTimeout)
- redrawTimeout = setTimeout(drawOverlay, t);
- }
-
- function drawOverlay() {
- redrawTimeout = null;
-
- // draw highlights
- octx.save();
- overlay.clear();
- octx.translate(plotOffset.left, plotOffset.top);
-
- var i, hi;
- for (i = 0; i < highlights.length; ++i) {
- hi = highlights[i];
-
- if (hi.series.bars.show)
- drawBarHighlight(hi.series, hi.point);
- else
- drawPointHighlight(hi.series, hi.point);
- }
- octx.restore();
-
- executeHooks(hooks.drawOverlay, [octx]);
- }
-
- function highlight(s, point, auto) {
- if (typeof s == "number")
- s = series[s];
-
- if (typeof point == "number") {
- var ps = s.datapoints.pointsize;
- point = s.datapoints.points.slice(ps * point, ps * (point + 1));
- }
-
- var i = indexOfHighlight(s, point);
- if (i == -1) {
- highlights.push({ series: s, point: point, auto: auto });
-
- triggerRedrawOverlay();
- }
- else if (!auto)
- highlights[i].auto = false;
- }
-
- function unhighlight(s, point) {
- if (s == null && point == null) {
- highlights = [];
- triggerRedrawOverlay();
- return;
- }
-
- if (typeof s == "number")
- s = series[s];
-
- if (typeof point == "number") {
- var ps = s.datapoints.pointsize;
- point = s.datapoints.points.slice(ps * point, ps * (point + 1));
- }
-
- var i = indexOfHighlight(s, point);
- if (i != -1) {
- highlights.splice(i, 1);
-
- triggerRedrawOverlay();
- }
- }
-
- function indexOfHighlight(s, p) {
- for (var i = 0; i < highlights.length; ++i) {
- var h = highlights[i];
- if (h.series == s && h.point[0] == p[0]
- && h.point[1] == p[1])
- return i;
- }
- return -1;
- }
-
- function drawPointHighlight(series, point) {
- var x = point[0], y = point[1],
- axisx = series.xaxis, axisy = series.yaxis,
- highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
-
- if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
- return;
-
- var pointRadius = series.points.radius + series.points.lineWidth / 2;
- octx.lineWidth = pointRadius;
- octx.strokeStyle = highlightColor;
- var radius = 1.5 * pointRadius;
- x = axisx.p2c(x);
- y = axisy.p2c(y);
-
- octx.beginPath();
- if (series.points.symbol == "circle")
- octx.arc(x, y, radius, 0, 2 * Math.PI, false);
- else
- series.points.symbol(octx, x, y, radius, false);
- octx.closePath();
- octx.stroke();
- }
-
- function drawBarHighlight(series, point) {
- var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
- fillStyle = highlightColor,
- barLeft;
-
- switch (series.bars.align) {
- case "left":
- barLeft = 0;
- break;
- case "right":
- barLeft = -series.bars.barWidth;
- break;
- default:
- barLeft = -series.bars.barWidth / 2;
- }
-
- octx.lineWidth = series.bars.lineWidth;
- octx.strokeStyle = highlightColor;
-
- drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
- function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
- }
-
- function getColorOrGradient(spec, bottom, top, defaultColor) {
- if (typeof spec == "string")
- return spec;
- else {
- // assume this is a gradient spec; IE currently only
- // supports a simple vertical gradient properly, so that's
- // what we support too
- var gradient = ctx.createLinearGradient(0, top, 0, bottom);
-
- for (var i = 0, l = spec.colors.length; i < l; ++i) {
- var c = spec.colors[i];
- if (typeof c != "string") {
- var co = $.color.parse(defaultColor);
- if (c.brightness != null)
- co = co.scale('rgb', c.brightness);
- if (c.opacity != null)
- co.a *= c.opacity;
- c = co.toString();
- }
- gradient.addColorStop(i / (l - 1), c);
- }
-
- return gradient;
- }
- }
- }
-
- // Add the plot function to the top level of the jQuery object
-
- $.plot = function(placeholder, data, options) {
- //var t0 = new Date();
- var plot = new Plot($(placeholder), data, options, $.plot.plugins);
- //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
- return plot;
- };
-
- $.plot.version = "0.8.3";
-
- $.plot.plugins = [];
-
- // Also add the plot function as a chainable property
-
- $.fn.plot = function(data, options) {
- return this.each(function() {
- $.plot(this, data, options);
- });
- };
-
- // round to nearby lower multiple of base
- function floorInBase(n, base) {
- return base * Math.floor(n / base);
- }
-
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.log.js b/src/legacy/ui/public/flot-charts/jquery.flot.log.js
deleted file mode 100644
index e32bf5cf7e817..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.log.js
+++ /dev/null
@@ -1,163 +0,0 @@
-/* @notice
- *
- * Pretty handling of logarithmic axes.
- * Copyright (c) 2007-2014 IOLA and Ole Laursen.
- * Licensed under the MIT license.
- * Created by Arne de Laat
- * Set axis.mode to "log" and make the axis logarithmic using transform:
- * axis: {
- * mode: 'log',
- * transform: function(v) {v <= 0 ? Math.log(v) / Math.LN10 : null},
- * inverseTransform: function(v) {Math.pow(10, v)}
- * }
- * The transform filters negative and zero values, because those are
- * invalid on logarithmic scales.
- * This plugin tries to create good looking logarithmic ticks, using
- * unicode superscript characters. If all data to be plotted is between two
- * powers of ten then the default flot tick generator and renderer are
- * used. Logarithmic ticks are places at powers of ten and at half those
- * values if there are not to many ticks already (e.g. [1, 5, 10, 50, 100]).
- * For details, see https://github.com/flot/flot/pull/1328
-*/
-
-(function($) {
-
- function log10(value) {
- /* Get the Log10 of the value
- */
- return Math.log(value) / Math.LN10;
- }
-
- function floorAsLog10(value) {
- /* Get power of the first power of 10 below the value
- */
- return Math.floor(log10(value));
- }
-
- function ceilAsLog10(value) {
- /* Get power of the first power of 10 above the value
- */
- return Math.ceil(log10(value));
- }
-
-
- // round to nearby lower multiple of base
- function floorInBase(n, base) {
- return base * Math.floor(n / base);
- }
-
- function getUnicodePower(power) {
- var superscripts = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"],
- result = "",
- str_power = "" + power;
- for (var i = 0; i < str_power.length; i++) {
- if (str_power[i] === "+") {
- }
- else if (str_power[i] === "-") {
- result += "⁻";
- }
- else {
- result += superscripts[str_power[i]];
- }
- }
- return result;
- }
-
- function init(plot) {
- plot.hooks.processOptions.push(function (plot) {
- $.each(plot.getAxes(), function(axisName, axis) {
-
- var opts = axis.options;
-
- if (opts.mode === "log") {
-
- axis.tickGenerator = function (axis) {
-
- var ticks = [],
- end = ceilAsLog10(axis.max),
- start = floorAsLog10(axis.min),
- tick = Number.NaN,
- i = 0;
-
- if (axis.min === null || axis.min <= 0) {
- // Bad minimum, make ticks from 1 (10**0) to max
- start = 0;
- axis.min = 0.6;
- }
-
- if (end <= start) {
- // Start less than end?!
- ticks = [1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
- 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6,
- 1e7, 1e8, 1e9];
- }
- else if (log10(axis.max) - log10(axis.datamin) < 1) {
- // Default flot generator incase no powers of 10
- // are between start and end
- var prev;
- start = floorInBase(axis.min, axis.tickSize);
- do {
- prev = tick;
- tick = start + i * axis.tickSize;
- ticks.push(tick);
- ++i;
- } while (tick < axis.max && tick !== prev);
- }
- else {
- // Make ticks at each power of ten
- for (; i <= (end - start); i++) {
- tick = Math.pow(10, start + i);
- ticks.push(tick);
- }
-
- var length = ticks.length;
-
- // If not to many ticks also put a tick between
- // the powers of ten
- if (end - start < 6) {
- for (var j = 1; j < length * 2 - 1; j += 2) {
- tick = ticks[j - 1] * 5;
- ticks.splice(j, 0, tick);
- }
- }
- }
- return ticks;
- };
-
- axis.tickFormatter = function (value, axis) {
- var formatted;
- if (log10(axis.max) - log10(axis.datamin) < 1) {
- // Default flot formatter
- var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
- formatted = "" + Math.round(value * factor) / factor;
- if (axis.tickDecimals !== null) {
- var decimal = formatted.indexOf(".");
- var precision = decimal === -1 ? 0 : formatted.length - decimal - 1;
- if (precision < axis.tickDecimals) {
- return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
- }
- }
- }
- else {
- var multiplier = "",
- exponential = parseFloat(value).toExponential(0),
- power = getUnicodePower(exponential.slice(2));
- if (exponential[0] !== "1") {
- multiplier = exponential[0] + "x";
- }
- formatted = multiplier + "10" + power;
- }
- return formatted;
- };
- }
- });
- });
- }
-
- $.plot.plugins.push({
- init: init,
- name: "log",
- version: "0.9"
- });
-
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.navigate.js b/src/legacy/ui/public/flot-charts/jquery.flot.navigate.js
deleted file mode 100644
index 13fb7f17d04b2..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.navigate.js
+++ /dev/null
@@ -1,346 +0,0 @@
-/* Flot plugin for adding the ability to pan and zoom the plot.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The default behaviour is double click and scrollwheel up/down to zoom in, drag
-to pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and
-plot.pan( offset ) so you easily can add custom controls. It also fires
-"plotpan" and "plotzoom" events, useful for synchronizing plots.
-
-The plugin supports these options:
-
- zoom: {
- interactive: false
- trigger: "dblclick" // or "click" for single click
- amount: 1.5 // 2 = 200% (zoom in), 0.5 = 50% (zoom out)
- }
-
- pan: {
- interactive: false
- cursor: "move" // CSS mouse cursor value used when dragging, e.g. "pointer"
- frameRate: 20
- }
-
- xaxis, yaxis, x2axis, y2axis: {
- zoomRange: null // or [ number, number ] (min range, max range) or false
- panRange: null // or [ number, number ] (min, max) or false
- }
-
-"interactive" enables the built-in drag/click behaviour. If you enable
-interactive for pan, then you'll have a basic plot that supports moving
-around; the same for zoom.
-
-"amount" specifies the default amount to zoom in (so 1.5 = 150%) relative to
-the current viewport.
-
-"cursor" is a standard CSS mouse cursor string used for visual feedback to the
-user when dragging.
-
-"frameRate" specifies the maximum number of times per second the plot will
-update itself while the user is panning around on it (set to null to disable
-intermediate pans, the plot will then not update until the mouse button is
-released).
-
-"zoomRange" is the interval in which zooming can happen, e.g. with zoomRange:
-[1, 100] the zoom will never scale the axis so that the difference between min
-and max is smaller than 1 or larger than 100. You can set either end to null
-to ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis
-will be disabled.
-
-"panRange" confines the panning to stay within a range, e.g. with panRange:
-[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can
-be null, e.g. [-10, null]. If you set panRange to false, panning on that axis
-will be disabled.
-
-Example API usage:
-
- plot = $.plot(...);
-
- // zoom default amount in on the pixel ( 10, 20 )
- plot.zoom({ center: { left: 10, top: 20 } });
-
- // zoom out again
- plot.zoomOut({ center: { left: 10, top: 20 } });
-
- // zoom 200% in on the pixel (10, 20)
- plot.zoom({ amount: 2, center: { left: 10, top: 20 } });
-
- // pan 100 pixels to the left and 20 down
- plot.pan({ left: -100, top: 20 })
-
-Here, "center" specifies where the center of the zooming should happen. Note
-that this is defined in pixel space, not the space of the data points (you can
-use the p2c helpers on the axes in Flot to help you convert between these).
-
-"amount" is the amount to zoom the viewport relative to the current range, so
-1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You
-can set the default in the options.
-
-*/
-
-// First two dependencies, jquery.event.drag.js and
-// jquery.mousewheel.js, we put them inline here to save people the
-// effort of downloading them.
-
-/*
-jquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)
-Licensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt
-*/
-(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case"mousedown":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,"mousemove mouseup",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&"mousemove":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY) max) {
- // make sure min < max
- var tmp = min;
- min = max;
- max = tmp;
- }
-
- //Check that we are in panRange
- if (pr) {
- if (pr[0] != null && min < pr[0]) {
- min = pr[0];
- }
- if (pr[1] != null && max > pr[1]) {
- max = pr[1];
- }
- }
-
- var range = max - min;
- if (zr &&
- ((zr[0] != null && range < zr[0] && amount >1) ||
- (zr[1] != null && range > zr[1] && amount <1)))
- return;
-
- opts.min = min;
- opts.max = max;
- });
-
- plot.setupGrid();
- plot.draw();
-
- if (!args.preventEvent)
- plot.getPlaceholder().trigger("plotzoom", [ plot, args ]);
- };
-
- plot.pan = function (args) {
- var delta = {
- x: +args.left,
- y: +args.top
- };
-
- if (isNaN(delta.x))
- delta.x = 0;
- if (isNaN(delta.y))
- delta.y = 0;
-
- $.each(plot.getAxes(), function (_, axis) {
- var opts = axis.options,
- min, max, d = delta[axis.direction];
-
- min = axis.c2p(axis.p2c(axis.min) + d),
- max = axis.c2p(axis.p2c(axis.max) + d);
-
- var pr = opts.panRange;
- if (pr === false) // no panning on this axis
- return;
-
- if (pr) {
- // check whether we hit the wall
- if (pr[0] != null && pr[0] > min) {
- d = pr[0] - min;
- min += d;
- max += d;
- }
-
- if (pr[1] != null && pr[1] < max) {
- d = pr[1] - max;
- min += d;
- max += d;
- }
- }
-
- opts.min = min;
- opts.max = max;
- });
-
- plot.setupGrid();
- plot.draw();
-
- if (!args.preventEvent)
- plot.getPlaceholder().trigger("plotpan", [ plot, args ]);
- };
-
- function shutdown(plot, eventHolder) {
- eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);
- eventHolder.unbind("mousewheel", onMouseWheel);
- eventHolder.unbind("dragstart", onDragStart);
- eventHolder.unbind("drag", onDrag);
- eventHolder.unbind("dragend", onDragEnd);
- if (panTimeout)
- clearTimeout(panTimeout);
- }
-
- plot.hooks.bindEvents.push(bindEvents);
- plot.hooks.shutdown.push(shutdown);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'navigate',
- version: '1.3'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.pie.js b/src/legacy/ui/public/flot-charts/jquery.flot.pie.js
deleted file mode 100644
index 06f900bdc950f..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.pie.js
+++ /dev/null
@@ -1,824 +0,0 @@
-/* Flot plugin for rendering pie charts.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The plugin assumes that each series has a single data value, and that each
-value is a positive integer or zero. Negative numbers don't make sense for a
-pie chart, and have unpredictable results. The values do NOT need to be
-passed in as percentages; the plugin will calculate the total and per-slice
-percentages internally.
-
-* Created by Brian Medendorp
-
-* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars
-
-The plugin supports these options:
-
- series: {
- pie: {
- show: true/false
- radius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'
- innerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect
- startAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result
- tilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)
- offset: {
- top: integer value to move the pie up or down
- left: integer value to move the pie left or right, or 'auto'
- },
- stroke: {
- color: any hexadecimal color value (other formats may or may not work, so best to stick with something like '#FFF')
- width: integer pixel width of the stroke
- },
- label: {
- show: true/false, or 'auto'
- formatter: a user-defined function that modifies the text/style of the label text
- radius: 0-1 for percentage of fullsize, or a specified pixel length
- background: {
- color: any hexadecimal color value (other formats may or may not work, so best to stick with something like '#000')
- opacity: 0-1
- },
- threshold: 0-1 for the percentage value at which to hide labels (if they're too small)
- },
- combine: {
- threshold: 0-1 for the percentage value at which to combine slices (if they're too small)
- color: any hexadecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined
- label: any text value of what the combined slice should be labeled
- }
- highlight: {
- opacity: 0-1
- }
- }
- }
-
-More detail and specific examples can be found in the included HTML file.
-
-*/
-
-import { i18n } from '@kbn/i18n';
-
-(function($) {
- // Maximum redraw attempts when fitting labels within the plot
-
- var REDRAW_ATTEMPTS = 10;
-
- // Factor by which to shrink the pie when fitting labels within the plot
-
- var REDRAW_SHRINK = 0.95;
-
- function init(plot) {
-
- var canvas = null,
- target = null,
- options = null,
- maxRadius = null,
- centerLeft = null,
- centerTop = null,
- processed = false,
- ctx = null;
-
- // interactive variables
-
- var highlights = [];
-
- // add hook to determine if pie plugin in enabled, and then perform necessary operations
-
- plot.hooks.processOptions.push(function(plot, options) {
- if (options.series.pie.show) {
-
- options.grid.show = false;
-
- // set labels.show
-
- if (options.series.pie.label.show == "auto") {
- if (options.legend.show) {
- options.series.pie.label.show = false;
- } else {
- options.series.pie.label.show = true;
- }
- }
-
- // set radius
-
- if (options.series.pie.radius == "auto") {
- if (options.series.pie.label.show) {
- options.series.pie.radius = 3/4;
- } else {
- options.series.pie.radius = 1;
- }
- }
-
- // ensure sane tilt
-
- if (options.series.pie.tilt > 1) {
- options.series.pie.tilt = 1;
- } else if (options.series.pie.tilt < 0) {
- options.series.pie.tilt = 0;
- }
- }
- });
-
- plot.hooks.bindEvents.push(function(plot, eventHolder) {
- var options = plot.getOptions();
- if (options.series.pie.show) {
- if (options.grid.hoverable) {
- eventHolder.unbind("mousemove").mousemove(onMouseMove);
- }
- if (options.grid.clickable) {
- eventHolder.unbind("click").click(onClick);
- }
- }
- });
-
- plot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {
- var options = plot.getOptions();
- if (options.series.pie.show) {
- processDatapoints(plot, series, data, datapoints);
- }
- });
-
- plot.hooks.drawOverlay.push(function(plot, octx) {
- var options = plot.getOptions();
- if (options.series.pie.show) {
- drawOverlay(plot, octx);
- }
- });
-
- plot.hooks.draw.push(function(plot, newCtx) {
- var options = plot.getOptions();
- if (options.series.pie.show) {
- draw(plot, newCtx);
- }
- });
-
- function processDatapoints(plot, series, datapoints) {
- if (!processed) {
- processed = true;
- canvas = plot.getCanvas();
- target = $(canvas).parent();
- options = plot.getOptions();
- plot.setData(combine(plot.getData()));
- }
- }
-
- function combine(data) {
-
- var total = 0,
- combined = 0,
- numCombined = 0,
- color = options.series.pie.combine.color,
- newdata = [];
-
- // Fix up the raw data from Flot, ensuring the data is numeric
-
- for (var i = 0; i < data.length; ++i) {
-
- var value = data[i].data;
-
- // If the data is an array, we'll assume that it's a standard
- // Flot x-y pair, and are concerned only with the second value.
-
- // Note how we use the original array, rather than creating a
- // new one; this is more efficient and preserves any extra data
- // that the user may have stored in higher indexes.
-
- if ($.isArray(value) && value.length == 1) {
- value = value[0];
- }
-
- if ($.isArray(value)) {
- // Equivalent to $.isNumeric() but compatible with jQuery < 1.7
- if (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {
- value[1] = +value[1];
- } else {
- value[1] = 0;
- }
- } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
- value = [1, +value];
- } else {
- value = [1, 0];
- }
-
- data[i].data = [value];
- }
-
- // Sum up all the slices, so we can calculate percentages for each
-
- for (var i = 0; i < data.length; ++i) {
- total += data[i].data[0][1];
- }
-
- // Count the number of slices with percentages below the combine
- // threshold; if it turns out to be just one, we won't combine.
-
- for (var i = 0; i < data.length; ++i) {
- var value = data[i].data[0][1];
- if (value / total <= options.series.pie.combine.threshold) {
- combined += value;
- numCombined++;
- if (!color) {
- color = data[i].color;
- }
- }
- }
-
- for (var i = 0; i < data.length; ++i) {
- var value = data[i].data[0][1];
- if (numCombined < 2 || value / total > options.series.pie.combine.threshold) {
- newdata.push(
- $.extend(data[i], { /* extend to allow keeping all other original data values
- and using them e.g. in labelFormatter. */
- data: [[1, value]],
- color: data[i].color,
- label: data[i].label,
- angle: value * Math.PI * 2 / total,
- percent: value / (total / 100)
- })
- );
- }
- }
-
- if (numCombined > 1) {
- newdata.push({
- data: [[1, combined]],
- color: color,
- label: options.series.pie.combine.label,
- angle: combined * Math.PI * 2 / total,
- percent: combined / (total / 100)
- });
- }
-
- return newdata;
- }
-
- function draw(plot, newCtx) {
-
- if (!target) {
- return; // if no series were passed
- }
-
- var canvasWidth = plot.getPlaceholder().width(),
- canvasHeight = plot.getPlaceholder().height(),
- legendWidth = target.children().filter(".legend").children().width() || 0;
-
- ctx = newCtx;
-
- // WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!
-
- // When combining smaller slices into an 'other' slice, we need to
- // add a new series. Since Flot gives plugins no way to modify the
- // list of series, the pie plugin uses a hack where the first call
- // to processDatapoints results in a call to setData with the new
- // list of series, then subsequent processDatapoints do nothing.
-
- // The plugin-global 'processed' flag is used to control this hack;
- // it starts out false, and is set to true after the first call to
- // processDatapoints.
-
- // Unfortunately this turns future setData calls into no-ops; they
- // call processDatapoints, the flag is true, and nothing happens.
-
- // To fix this we'll set the flag back to false here in draw, when
- // all series have been processed, so the next sequence of calls to
- // processDatapoints once again starts out with a slice-combine.
- // This is really a hack; in 0.9 we need to give plugins a proper
- // way to modify series before any processing begins.
-
- processed = false;
-
- // calculate maximum radius and center point
-
- maxRadius = Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;
- centerTop = canvasHeight / 2 + options.series.pie.offset.top;
- centerLeft = canvasWidth / 2;
-
- if (options.series.pie.offset.left == "auto") {
- if (options.legend.position.match("w")) {
- centerLeft += legendWidth / 2;
- } else {
- centerLeft -= legendWidth / 2;
- }
- if (centerLeft < maxRadius) {
- centerLeft = maxRadius;
- } else if (centerLeft > canvasWidth - maxRadius) {
- centerLeft = canvasWidth - maxRadius;
- }
- } else {
- centerLeft += options.series.pie.offset.left;
- }
-
- var slices = plot.getData(),
- attempts = 0;
-
- // Keep shrinking the pie's radius until drawPie returns true,
- // indicating that all the labels fit, or we try too many times.
-
- do {
- if (attempts > 0) {
- maxRadius *= REDRAW_SHRINK;
- }
- attempts += 1;
- clear();
- if (options.series.pie.tilt <= 0.8) {
- drawShadow();
- }
- } while (!drawPie() && attempts < REDRAW_ATTEMPTS)
-
- if (attempts >= REDRAW_ATTEMPTS) {
- clear();
- const errorMessage = i18n.translate('common.ui.flotCharts.pie.unableToDrawLabelsInsideCanvasErrorMessage', {
- defaultMessage: 'Could not draw pie with labels contained inside canvas',
- });
- target.prepend(`${errorMessage}
`);
- }
-
- if (plot.setSeries && plot.insertLegend) {
- plot.setSeries(slices);
- plot.insertLegend();
- }
-
- // we're actually done at this point, just defining internal functions at this point
-
- function clear() {
- ctx.clearRect(0, 0, canvasWidth, canvasHeight);
- target.children().filter(".pieLabel, .pieLabelBackground").remove();
- }
-
- function drawShadow() {
-
- var shadowLeft = options.series.pie.shadow.left;
- var shadowTop = options.series.pie.shadow.top;
- var edge = 10;
- var alpha = options.series.pie.shadow.alpha;
- var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-
- if (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {
- return; // shadow would be outside canvas, so don't draw it
- }
-
- ctx.save();
- ctx.translate(shadowLeft,shadowTop);
- ctx.globalAlpha = alpha;
- ctx.fillStyle = "#000";
-
- // center and rotate to starting position
-
- ctx.translate(centerLeft,centerTop);
- ctx.scale(1, options.series.pie.tilt);
-
- //radius -= edge;
-
- for (var i = 1; i <= edge; i++) {
- ctx.beginPath();
- ctx.arc(0, 0, radius, 0, Math.PI * 2, false);
- ctx.fill();
- radius -= i;
- }
-
- ctx.restore();
- }
-
- function drawPie() {
-
- var startAngle = Math.PI * options.series.pie.startAngle;
- var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-
- // center and rotate to starting position
-
- ctx.save();
- ctx.translate(centerLeft,centerTop);
- ctx.scale(1, options.series.pie.tilt);
- //ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera
-
- // draw slices
-
- ctx.save();
- var currentAngle = startAngle;
- for (var i = 0; i < slices.length; ++i) {
- slices[i].startAngle = currentAngle;
- drawSlice(slices[i].angle, slices[i].color, true);
- }
- ctx.restore();
-
- // draw slice outlines
-
- if (options.series.pie.stroke.width > 0) {
- ctx.save();
- ctx.lineWidth = options.series.pie.stroke.width;
- currentAngle = startAngle;
- for (var i = 0; i < slices.length; ++i) {
- drawSlice(slices[i].angle, options.series.pie.stroke.color, false);
- }
- ctx.restore();
- }
-
- // draw donut hole
-
- drawDonutHole(ctx);
-
- ctx.restore();
-
- // Draw the labels, returning true if they fit within the plot
-
- if (options.series.pie.label.show) {
- return drawLabels();
- } else return true;
-
- function drawSlice(angle, color, fill) {
-
- if (angle <= 0 || isNaN(angle)) {
- return;
- }
-
- if (fill) {
- ctx.fillStyle = color;
- } else {
- ctx.strokeStyle = color;
- ctx.lineJoin = "round";
- }
-
- ctx.beginPath();
- if (Math.abs(angle - Math.PI * 2) > 0.000000001) {
- ctx.moveTo(0, 0); // Center of the pie
- }
-
- //ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera
- ctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);
- ctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);
- ctx.closePath();
- //ctx.rotate(angle); // This doesn't work properly in Opera
- currentAngle += angle;
-
- if (fill) {
- ctx.fill();
- } else {
- ctx.stroke();
- }
- }
-
- function drawLabels() {
-
- var currentAngle = startAngle;
- var radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;
-
- for (var i = 0; i < slices.length; ++i) {
- if (slices[i].percent >= options.series.pie.label.threshold * 100) {
- if (!drawLabel(slices[i], currentAngle, i)) {
- return false;
- }
- }
- currentAngle += slices[i].angle;
- }
-
- return true;
-
- function drawLabel(slice, startAngle, index) {
-
- if (slice.data[0][1] == 0) {
- return true;
- }
-
- // format label text
-
- var lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;
-
- if (lf) {
- text = lf(slice.label, slice);
- } else {
- text = slice.label;
- }
-
- if (plf) {
- text = plf(text, slice);
- }
-
- var halfAngle = ((startAngle + slice.angle) + startAngle) / 2;
- var x = centerLeft + Math.round(Math.cos(halfAngle) * radius);
- var y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;
-
- var html = "" + text + " ";
- target.append(html);
-
- var label = target.children("#pieLabel" + index);
- var labelTop = (y - label.height() / 2);
- var labelLeft = (x - label.width() / 2);
-
- label.css("top", labelTop);
- label.css("left", labelLeft);
-
- // check to make sure that the label is not outside the canvas
-
- if (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {
- return false;
- }
-
- if (options.series.pie.label.background.opacity != 0) {
-
- // put in the transparent background separately to avoid blended labels and label boxes
-
- var c = options.series.pie.label.background.color;
-
- if (c == null) {
- c = slice.color;
- }
-
- var pos = "top:" + labelTop + "px;left:" + labelLeft + "px;";
- $("
")
- .css("opacity", options.series.pie.label.background.opacity)
- .insertBefore(label);
- }
-
- return true;
- } // end individual label function
- } // end drawLabels function
- } // end drawPie function
- } // end draw function
-
- // Placed here because it needs to be accessed from multiple locations
-
- function drawDonutHole(layer) {
- if (options.series.pie.innerRadius > 0) {
-
- // subtract the center
-
- layer.save();
- var innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;
- layer.globalCompositeOperation = "destination-out"; // this does not work with excanvas, but it will fall back to using the stroke color
- layer.beginPath();
- layer.fillStyle = options.series.pie.stroke.color;
- layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
- layer.fill();
- layer.closePath();
- layer.restore();
-
- // add inner stroke
-
- layer.save();
- layer.beginPath();
- layer.strokeStyle = options.series.pie.stroke.color;
- layer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);
- layer.stroke();
- layer.closePath();
- layer.restore();
-
- // TODO: add extra shadow inside hole (with a mask) if the pie is tilted.
- }
- }
-
- //-- Additional Interactive related functions --
-
- function isPointInPoly(poly, pt) {
- for(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
- ((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))
- && (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])
- && (c = !c);
- return c;
- }
-
- function findNearbySlice(mouseX, mouseY) {
-
- var slices = plot.getData(),
- options = plot.getOptions(),
- radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,
- x, y;
-
- for (var i = 0; i < slices.length; ++i) {
-
- var s = slices[i];
-
- if (s.pie.show) {
-
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(0, 0); // Center of the pie
- //ctx.scale(1, options.series.pie.tilt); // this actually seems to break everything when here.
- ctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);
- ctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);
- ctx.closePath();
- x = mouseX - centerLeft;
- y = mouseY - centerTop;
-
- if (ctx.isPointInPath) {
- if (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {
- ctx.restore();
- return {
- datapoint: [s.percent, s.data],
- dataIndex: 0,
- series: s,
- seriesIndex: i
- };
- }
- } else {
-
- // excanvas for IE doesn;t support isPointInPath, this is a workaround.
-
- var p1X = radius * Math.cos(s.startAngle),
- p1Y = radius * Math.sin(s.startAngle),
- p2X = radius * Math.cos(s.startAngle + s.angle / 4),
- p2Y = radius * Math.sin(s.startAngle + s.angle / 4),
- p3X = radius * Math.cos(s.startAngle + s.angle / 2),
- p3Y = radius * Math.sin(s.startAngle + s.angle / 2),
- p4X = radius * Math.cos(s.startAngle + s.angle / 1.5),
- p4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),
- p5X = radius * Math.cos(s.startAngle + s.angle),
- p5Y = radius * Math.sin(s.startAngle + s.angle),
- arrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],
- arrPoint = [x, y];
-
- // TODO: perhaps do some mathematical trickery here with the Y-coordinate to compensate for pie tilt?
-
- if (isPointInPoly(arrPoly, arrPoint)) {
- ctx.restore();
- return {
- datapoint: [s.percent, s.data],
- dataIndex: 0,
- series: s,
- seriesIndex: i
- };
- }
- }
-
- ctx.restore();
- }
- }
-
- return null;
- }
-
- function onMouseMove(e) {
- triggerClickHoverEvent("plothover", e);
- }
-
- function onClick(e) {
- triggerClickHoverEvent("plotclick", e);
- }
-
- // trigger click or hover event (they send the same parameters so we share their code)
-
- function triggerClickHoverEvent(eventname, e) {
-
- var offset = plot.offset();
- var canvasX = parseInt(e.pageX - offset.left);
- var canvasY = parseInt(e.pageY - offset.top);
- var item = findNearbySlice(canvasX, canvasY);
-
- if (options.grid.autoHighlight) {
-
- // clear auto-highlights
-
- for (var i = 0; i < highlights.length; ++i) {
- var h = highlights[i];
- if (h.auto == eventname && !(item && h.series == item.series)) {
- unhighlight(h.series);
- }
- }
- }
-
- // highlight the slice
-
- if (item) {
- highlight(item.series, eventname);
- }
-
- // trigger any hover bind events
-
- var pos = { pageX: e.pageX, pageY: e.pageY };
- target.trigger(eventname, [pos, item]);
- }
-
- function highlight(s, auto) {
- //if (typeof s == "number") {
- // s = series[s];
- //}
-
- var i = indexOfHighlight(s);
-
- if (i == -1) {
- highlights.push({ series: s, auto: auto });
- plot.triggerRedrawOverlay();
- } else if (!auto) {
- highlights[i].auto = false;
- }
- }
-
- function unhighlight(s) {
- if (s == null) {
- highlights = [];
- plot.triggerRedrawOverlay();
- }
-
- //if (typeof s == "number") {
- // s = series[s];
- //}
-
- var i = indexOfHighlight(s);
-
- if (i != -1) {
- highlights.splice(i, 1);
- plot.triggerRedrawOverlay();
- }
- }
-
- function indexOfHighlight(s) {
- for (var i = 0; i < highlights.length; ++i) {
- var h = highlights[i];
- if (h.series == s)
- return i;
- }
- return -1;
- }
-
- function drawOverlay(plot, octx) {
-
- var options = plot.getOptions();
-
- var radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;
-
- octx.save();
- octx.translate(centerLeft, centerTop);
- octx.scale(1, options.series.pie.tilt);
-
- for (var i = 0; i < highlights.length; ++i) {
- drawHighlight(highlights[i].series);
- }
-
- drawDonutHole(octx);
-
- octx.restore();
-
- function drawHighlight(series) {
-
- if (series.angle <= 0 || isNaN(series.angle)) {
- return;
- }
-
- //octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();
- octx.fillStyle = "rgba(255, 255, 255, " + options.series.pie.highlight.opacity + ")"; // this is temporary until we have access to parseColor
- octx.beginPath();
- if (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {
- octx.moveTo(0, 0); // Center of the pie
- }
- octx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);
- octx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);
- octx.closePath();
- octx.fill();
- }
- }
- } // end init (plugin body)
-
- // define pie specific options and their default values
-
- var options = {
- series: {
- pie: {
- show: false,
- radius: "auto", // actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)
- innerRadius: 0, /* for donut */
- startAngle: 3/2,
- tilt: 1,
- shadow: {
- left: 5, // shadow left offset
- top: 15, // shadow top offset
- alpha: 0.02 // shadow alpha
- },
- offset: {
- top: 0,
- left: "auto"
- },
- stroke: {
- color: "#fff",
- width: 1
- },
- label: {
- show: "auto",
- formatter: function(label, slice) {
- return "" + label + " " + Math.round(slice.percent) + "%
";
- }, // formatter function
- radius: 1, // radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)
- background: {
- color: null,
- opacity: 0
- },
- threshold: 0 // percentage at which to hide the label (i.e. the slice is too narrow)
- },
- combine: {
- threshold: -1, // percentage at which to combine little slices into one larger slice
- color: null, // color to give the new slice (auto-generated if null)
- label: "Other" // label to give the new slice
- },
- highlight: {
- //color: "#fff", // will add this functionality once parseColor is available
- opacity: 0.5
- }
- }
- }
- };
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: "pie",
- version: "1.1"
- });
-
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.resize.js b/src/legacy/ui/public/flot-charts/jquery.flot.resize.js
deleted file mode 100644
index 8a626dda0addb..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.resize.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Flot plugin for automatically redrawing plots as the placeholder resizes.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-It works by listening for changes on the placeholder div (through the jQuery
-resize event plugin) - if the size changes, it will redraw the plot.
-
-There are no options. If you need to disable the plugin for some plots, you
-can just fix the size of their placeholders.
-
-*/
-
-/* Inline dependency:
- * jQuery resize event - v1.1 - 3/14/2010
- * http://benalman.com/projects/jquery-resize-plugin/
- *
- * Copyright (c) 2010 "Cowboy" Ben Alman
- * Dual licensed under the MIT and GPL licenses.
- * http://benalman.com/about/license/
- */
-(function($,e,t){"$:nomunge";var i=[],n=$.resize=$.extend($.resize,{}),a,r=false,s="setTimeout",u="resize",m=u+"-special-event",o="pendingDelay",l="activeDelay",f="throttleWindow";n[o]=200;n[l]=20;n[f]=true;$.event.special[u]={setup:function(){if(!n[f]&&this[s]){return false}var e=$(this);i.push(this);e.data(m,{w:e.width(),h:e.height()});if(i.length===1){a=t;h()}},teardown:function(){if(!n[f]&&this[s]){return false}var e=$(this);for(var t=i.length-1;t>=0;t--){if(i[t]==this){i.splice(t,1);break}}e.removeData(m);if(!i.length){if(r){cancelAnimationFrame(a)}else{clearTimeout(a)}a=null}},add:function(e){if(!n[f]&&this[s]){return false}var i;function a(e,n,a){var r=$(this),s=r.data(m)||{};s.w=n!==t?n:r.width();s.h=a!==t?a:r.height();i.apply(this,arguments)}if($.isFunction(e)){i=e;return a}else{i=e.handler;e.handler=a}}};function h(t){if(r===true){r=t||1}for(var s=i.length-1;s>=0;s--){var l=$(i[s]);if(l[0]==e||l.is(":visible")){var f=l.width(),c=l.height(),d=l.data(m);if(d&&(f!==d.w||c!==d.h)){l.trigger(u,[d.w=f,d.h=c]);r=t||true}}else{d=l.data(m);d.w=0;d.h=0}}if(a!==null){if(r&&(t==null||t-r<1e3)){a=e.requestAnimationFrame(h)}else{a=setTimeout(h,n[o]);r=false}}}if(!e.requestAnimationFrame){e.requestAnimationFrame=function(){return e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.oRequestAnimationFrame||e.msRequestAnimationFrame||function(t,i){return e.setTimeout(function(){t((new Date).getTime())},n[l])}}()}if(!e.cancelAnimationFrame){e.cancelAnimationFrame=function(){return e.webkitCancelRequestAnimationFrame||e.mozCancelRequestAnimationFrame||e.oCancelRequestAnimationFrame||e.msCancelRequestAnimationFrame||clearTimeout}()}})(jQuery,this);
-
-(function ($) {
- var options = { }; // no options
-
- function init(plot) {
- function onResize() {
- var placeholder = plot.getPlaceholder();
-
- // somebody might have hidden us and we can't plot
- // when we don't have the dimensions
- if (placeholder.width() == 0 || placeholder.height() == 0)
- return;
-
- plot.resize();
- plot.setupGrid();
- plot.draw();
- }
-
- function bindEvents(plot, eventHolder) {
- plot.getPlaceholder().resize(onResize);
- }
-
- function shutdown(plot, eventHolder) {
- plot.getPlaceholder().unbind("resize", onResize);
- }
-
- plot.hooks.bindEvents.push(bindEvents);
- plot.hooks.shutdown.push(shutdown);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'resize',
- version: '1.0'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.selection.js b/src/legacy/ui/public/flot-charts/jquery.flot.selection.js
deleted file mode 100644
index c8707b30f4e6f..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.selection.js
+++ /dev/null
@@ -1,360 +0,0 @@
-/* Flot plugin for selecting regions of a plot.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The plugin supports these options:
-
-selection: {
- mode: null or "x" or "y" or "xy",
- color: color,
- shape: "round" or "miter" or "bevel",
- minSize: number of pixels
-}
-
-Selection support is enabled by setting the mode to one of "x", "y" or "xy".
-In "x" mode, the user will only be able to specify the x range, similarly for
-"y" mode. For "xy", the selection becomes a rectangle where both ranges can be
-specified. "color" is color of the selection (if you need to change the color
-later on, you can get to it with plot.getOptions().selection.color). "shape"
-is the shape of the corners of the selection.
-
-"minSize" is the minimum size a selection can be in pixels. This value can
-be customized to determine the smallest size a selection can be and still
-have the selection rectangle be displayed. When customizing this value, the
-fact that it refers to pixels, not axis units must be taken into account.
-Thus, for example, if there is a bar graph in time mode with BarWidth set to 1
-minute, setting "minSize" to 1 will not make the minimum selection size 1
-minute, but rather 1 pixel. Note also that setting "minSize" to 0 will prevent
-"plotunselected" events from being fired when the user clicks the mouse without
-dragging.
-
-When selection support is enabled, a "plotselected" event will be emitted on
-the DOM element you passed into the plot function. The event handler gets a
-parameter with the ranges selected on the axes, like this:
-
- placeholder.bind( "plotselected", function( event, ranges ) {
- alert("You selected " + ranges.xaxis.from + " to " + ranges.xaxis.to)
- // similar for yaxis - with multiple axes, the extra ones are in
- // x2axis, x3axis, ...
- });
-
-The "plotselected" event is only fired when the user has finished making the
-selection. A "plotselecting" event is fired during the process with the same
-parameters as the "plotselected" event, in case you want to know what's
-happening while it's happening,
-
-A "plotunselected" event with no arguments is emitted when the user clicks the
-mouse to remove the selection. As stated above, setting "minSize" to 0 will
-destroy this behavior.
-
-The plugin also adds the following methods to the plot object:
-
-- setSelection( ranges, preventEvent )
-
- Set the selection rectangle. The passed in ranges is on the same form as
- returned in the "plotselected" event. If the selection mode is "x", you
- should put in either an xaxis range, if the mode is "y" you need to put in
- an yaxis range and both xaxis and yaxis if the selection mode is "xy", like
- this:
-
- setSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });
-
- setSelection will trigger the "plotselected" event when called. If you don't
- want that to happen, e.g. if you're inside a "plotselected" handler, pass
- true as the second parameter. If you are using multiple axes, you can
- specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of
- xaxis, the plugin picks the first one it sees.
-
-- clearSelection( preventEvent )
-
- Clear the selection rectangle. Pass in true to avoid getting a
- "plotunselected" event.
-
-- getSelection()
-
- Returns the current selection in the same format as the "plotselected"
- event. If there's currently no selection, the function returns null.
-
-*/
-
-(function ($) {
- function init(plot) {
- var selection = {
- first: { x: -1, y: -1}, second: { x: -1, y: -1},
- show: false,
- active: false
- };
-
- // FIXME: The drag handling implemented here should be
- // abstracted out, there's some similar code from a library in
- // the navigation plugin, this should be massaged a bit to fit
- // the Flot cases here better and reused. Doing this would
- // make this plugin much slimmer.
- var savedhandlers = {};
-
- var mouseUpHandler = null;
-
- function onMouseMove(e) {
- if (selection.active) {
- updateSelection(e);
-
- plot.getPlaceholder().trigger("plotselecting", [ getSelection() ]);
- }
- }
-
- function onMouseDown(e) {
- if (e.which != 1) // only accept left-click
- return;
-
- // cancel out any text selections
- document.body.focus();
-
- // prevent text selection and drag in old-school browsers
- if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {
- savedhandlers.onselectstart = document.onselectstart;
- document.onselectstart = function () { return false; };
- }
- if (document.ondrag !== undefined && savedhandlers.ondrag == null) {
- savedhandlers.ondrag = document.ondrag;
- document.ondrag = function () { return false; };
- }
-
- setSelectionPos(selection.first, e);
-
- selection.active = true;
-
- // this is a bit silly, but we have to use a closure to be
- // able to whack the same handler again
- mouseUpHandler = function (e) { onMouseUp(e); };
-
- $(document).one("mouseup", mouseUpHandler);
- }
-
- function onMouseUp(e) {
- mouseUpHandler = null;
-
- // revert drag stuff for old-school browsers
- if (document.onselectstart !== undefined)
- document.onselectstart = savedhandlers.onselectstart;
- if (document.ondrag !== undefined)
- document.ondrag = savedhandlers.ondrag;
-
- // no more dragging
- selection.active = false;
- updateSelection(e);
-
- if (selectionIsSane())
- triggerSelectedEvent();
- else {
- // this counts as a clear
- plot.getPlaceholder().trigger("plotunselected", [ ]);
- plot.getPlaceholder().trigger("plotselecting", [ null ]);
- }
-
- return false;
- }
-
- function getSelection() {
- if (!selectionIsSane())
- return null;
-
- if (!selection.show) return null;
-
- var r = {}, c1 = selection.first, c2 = selection.second;
- $.each(plot.getAxes(), function (name, axis) {
- if (axis.used) {
- var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]);
- r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };
- }
- });
- return r;
- }
-
- function triggerSelectedEvent() {
- var r = getSelection();
-
- plot.getPlaceholder().trigger("plotselected", [ r ]);
-
- // backwards-compat stuff, to be removed in future
- if (r.xaxis && r.yaxis)
- plot.getPlaceholder().trigger("selected", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);
- }
-
- function clamp(min, value, max) {
- return value < min ? min: (value > max ? max: value);
- }
-
- function setSelectionPos(pos, e) {
- var o = plot.getOptions();
- var offset = plot.getPlaceholder().offset();
- var plotOffset = plot.getPlotOffset();
- pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());
- pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());
-
- if (o.selection.mode == "y")
- pos.x = pos == selection.first ? 0 : plot.width();
-
- if (o.selection.mode == "x")
- pos.y = pos == selection.first ? 0 : plot.height();
- }
-
- function updateSelection(pos) {
- if (pos.pageX == null)
- return;
-
- setSelectionPos(selection.second, pos);
- if (selectionIsSane()) {
- selection.show = true;
- plot.triggerRedrawOverlay();
- }
- else
- clearSelection(true);
- }
-
- function clearSelection(preventEvent) {
- if (selection.show) {
- selection.show = false;
- plot.triggerRedrawOverlay();
- if (!preventEvent)
- plot.getPlaceholder().trigger("plotunselected", [ ]);
- }
- }
-
- // function taken from markings support in Flot
- function extractRange(ranges, coord) {
- var axis, from, to, key, axes = plot.getAxes();
-
- for (var k in axes) {
- axis = axes[k];
- if (axis.direction == coord) {
- key = coord + axis.n + "axis";
- if (!ranges[key] && axis.n == 1)
- key = coord + "axis"; // support x1axis as xaxis
- if (ranges[key]) {
- from = ranges[key].from;
- to = ranges[key].to;
- break;
- }
- }
- }
-
- // backwards-compat stuff - to be removed in future
- if (!ranges[key]) {
- axis = coord == "x" ? plot.getXAxes()[0] : plot.getYAxes()[0];
- from = ranges[coord + "1"];
- to = ranges[coord + "2"];
- }
-
- // auto-reverse as an added bonus
- if (from != null && to != null && from > to) {
- var tmp = from;
- from = to;
- to = tmp;
- }
-
- return { from: from, to: to, axis: axis };
- }
-
- function setSelection(ranges, preventEvent) {
- var axis, range, o = plot.getOptions();
-
- if (o.selection.mode == "y") {
- selection.first.x = 0;
- selection.second.x = plot.width();
- }
- else {
- range = extractRange(ranges, "x");
-
- selection.first.x = range.axis.p2c(range.from);
- selection.second.x = range.axis.p2c(range.to);
- }
-
- if (o.selection.mode == "x") {
- selection.first.y = 0;
- selection.second.y = plot.height();
- }
- else {
- range = extractRange(ranges, "y");
-
- selection.first.y = range.axis.p2c(range.from);
- selection.second.y = range.axis.p2c(range.to);
- }
-
- selection.show = true;
- plot.triggerRedrawOverlay();
- if (!preventEvent && selectionIsSane())
- triggerSelectedEvent();
- }
-
- function selectionIsSane() {
- var minSize = plot.getOptions().selection.minSize;
- return Math.abs(selection.second.x - selection.first.x) >= minSize &&
- Math.abs(selection.second.y - selection.first.y) >= minSize;
- }
-
- plot.clearSelection = clearSelection;
- plot.setSelection = setSelection;
- plot.getSelection = getSelection;
-
- plot.hooks.bindEvents.push(function(plot, eventHolder) {
- var o = plot.getOptions();
- if (o.selection.mode != null) {
- eventHolder.mousemove(onMouseMove);
- eventHolder.mousedown(onMouseDown);
- }
- });
-
-
- plot.hooks.drawOverlay.push(function (plot, ctx) {
- // draw selection
- if (selection.show && selectionIsSane()) {
- var plotOffset = plot.getPlotOffset();
- var o = plot.getOptions();
-
- ctx.save();
- ctx.translate(plotOffset.left, plotOffset.top);
-
- var c = $.color.parse(o.selection.color);
-
- ctx.strokeStyle = c.scale('a', 0.8).toString();
- ctx.lineWidth = 1;
- ctx.lineJoin = o.selection.shape;
- ctx.fillStyle = c.scale('a', 0.4).toString();
-
- var x = Math.min(selection.first.x, selection.second.x) + 0.5,
- y = Math.min(selection.first.y, selection.second.y) + 0.5,
- w = Math.abs(selection.second.x - selection.first.x) - 1,
- h = Math.abs(selection.second.y - selection.first.y) - 1;
-
- ctx.fillRect(x, y, w, h);
- ctx.strokeRect(x, y, w, h);
-
- ctx.restore();
- }
- });
-
- plot.hooks.shutdown.push(function (plot, eventHolder) {
- eventHolder.unbind("mousemove", onMouseMove);
- eventHolder.unbind("mousedown", onMouseDown);
-
- if (mouseUpHandler)
- $(document).unbind("mouseup", mouseUpHandler);
- });
-
- }
-
- $.plot.plugins.push({
- init: init,
- options: {
- selection: {
- mode: null, // one of null, "x", "y" or "xy"
- color: "#e8cfac",
- shape: "round", // one of "round", "miter", or "bevel"
- minSize: 5 // minimum number of pixels
- }
- },
- name: 'selection',
- version: '1.1'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.stack.js b/src/legacy/ui/public/flot-charts/jquery.flot.stack.js
deleted file mode 100644
index 0d91c0f3c0160..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.stack.js
+++ /dev/null
@@ -1,188 +0,0 @@
-/* Flot plugin for stacking data sets rather than overlaying them.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The plugin assumes the data is sorted on x (or y if stacking horizontally).
-For line charts, it is assumed that if a line has an undefined gap (from a
-null point), then the line above it should have the same gap - insert zeros
-instead of "null" if you want another behaviour. This also holds for the start
-and end of the chart. Note that stacking a mix of positive and negative values
-in most instances doesn't make sense (so it looks weird).
-
-Two or more series are stacked when their "stack" attribute is set to the same
-key (which can be any number or string or just "true"). To specify the default
-stack, you can set the stack option like this:
-
- series: {
- stack: null/false, true, or a key (number/string)
- }
-
-You can also specify it for a single series, like this:
-
- $.plot( $("#placeholder"), [{
- data: [ ... ],
- stack: true
- }])
-
-The stacking order is determined by the order of the data series in the array
-(later series end up on top of the previous).
-
-Internally, the plugin modifies the datapoints in each series, adding an
-offset to the y value. For line series, extra data points are inserted through
-interpolation. If there's a second y value, it's also adjusted (e.g for bar
-charts or filled areas).
-
-*/
-
-(function ($) {
- var options = {
- series: { stack: null } // or number/string
- };
-
- function init(plot) {
- function findMatchingSeries(s, allseries) {
- var res = null;
- for (var i = 0; i < allseries.length; ++i) {
- if (s == allseries[i])
- break;
-
- if (allseries[i].stack == s.stack)
- res = allseries[i];
- }
-
- return res;
- }
-
- function stackData(plot, s, datapoints) {
- if (s.stack == null || s.stack === false)
- return;
-
- var other = findMatchingSeries(s, plot.getData());
- if (!other)
- return;
-
- var ps = datapoints.pointsize,
- points = datapoints.points,
- otherps = other.datapoints.pointsize,
- otherpoints = other.datapoints.points,
- newpoints = [],
- px, py, intery, qx, qy, bottom,
- withlines = s.lines.show,
- horizontal = s.bars.horizontal,
- withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),
- withsteps = withlines && s.lines.steps,
- fromgap = true,
- keyOffset = horizontal ? 1 : 0,
- accumulateOffset = horizontal ? 0 : 1,
- i = 0, j = 0, l, m;
-
- while (true) {
- if (i >= points.length)
- break;
-
- l = newpoints.length;
-
- if (points[i] == null) {
- // copy gaps
- for (m = 0; m < ps; ++m)
- newpoints.push(points[i + m]);
- i += ps;
- }
- else if (j >= otherpoints.length) {
- // for lines, we can't use the rest of the points
- if (!withlines) {
- for (m = 0; m < ps; ++m)
- newpoints.push(points[i + m]);
- }
- i += ps;
- }
- else if (otherpoints[j] == null) {
- // oops, got a gap
- for (m = 0; m < ps; ++m)
- newpoints.push(null);
- fromgap = true;
- j += otherps;
- }
- else {
- // cases where we actually got two points
- px = points[i + keyOffset];
- py = points[i + accumulateOffset];
- qx = otherpoints[j + keyOffset];
- qy = otherpoints[j + accumulateOffset];
- bottom = 0;
-
- if (px == qx) {
- for (m = 0; m < ps; ++m)
- newpoints.push(points[i + m]);
-
- newpoints[l + accumulateOffset] += qy;
- bottom = qy;
-
- i += ps;
- j += otherps;
- }
- else if (px > qx) {
- // we got past point below, might need to
- // insert interpolated extra point
- if (withlines && i > 0 && points[i - ps] != null) {
- intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);
- newpoints.push(qx);
- newpoints.push(intery + qy);
- for (m = 2; m < ps; ++m)
- newpoints.push(points[i + m]);
- bottom = qy;
- }
-
- j += otherps;
- }
- else { // px < qx
- if (fromgap && withlines) {
- // if we come from a gap, we just skip this point
- i += ps;
- continue;
- }
-
- for (m = 0; m < ps; ++m)
- newpoints.push(points[i + m]);
-
- // we might be able to interpolate a point below,
- // this can give us a better y
- if (withlines && j > 0 && otherpoints[j - otherps] != null)
- bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);
-
- newpoints[l + accumulateOffset] += bottom;
-
- i += ps;
- }
-
- fromgap = false;
-
- if (l != newpoints.length && withbottom)
- newpoints[l + 2] += bottom;
- }
-
- // maintain the line steps invariant
- if (withsteps && l != newpoints.length && l > 0
- && newpoints[l] != null
- && newpoints[l] != newpoints[l - ps]
- && newpoints[l + 1] != newpoints[l - ps + 1]) {
- for (m = 0; m < ps; ++m)
- newpoints[l + ps + m] = newpoints[l + m];
- newpoints[l + 1] = newpoints[l - ps + 1];
- }
- }
-
- datapoints.points = newpoints;
- }
-
- plot.hooks.processDatapoints.push(stackData);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'stack',
- version: '1.2'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.symbol.js b/src/legacy/ui/public/flot-charts/jquery.flot.symbol.js
deleted file mode 100644
index 79f634971b6fa..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.symbol.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Flot plugin that adds some extra symbols for plotting points.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The symbols are accessed as strings through the standard symbol options:
-
- series: {
- points: {
- symbol: "square" // or "diamond", "triangle", "cross"
- }
- }
-
-*/
-
-(function ($) {
- function processRawData(plot, series, datapoints) {
- // we normalize the area of each symbol so it is approximately the
- // same as a circle of the given radius
-
- var handlers = {
- square: function (ctx, x, y, radius, shadow) {
- // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
- var size = radius * Math.sqrt(Math.PI) / 2;
- ctx.rect(x - size, y - size, size + size, size + size);
- },
- diamond: function (ctx, x, y, radius, shadow) {
- // pi * r^2 = 2s^2 => s = r * sqrt(pi/2)
- var size = radius * Math.sqrt(Math.PI / 2);
- ctx.moveTo(x - size, y);
- ctx.lineTo(x, y - size);
- ctx.lineTo(x + size, y);
- ctx.lineTo(x, y + size);
- ctx.lineTo(x - size, y);
- },
- triangle: function (ctx, x, y, radius, shadow) {
- // pi * r^2 = 1/2 * s^2 * sin (pi / 3) => s = r * sqrt(2 * pi / sin(pi / 3))
- var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));
- var height = size * Math.sin(Math.PI / 3);
- ctx.moveTo(x - size/2, y + height/2);
- ctx.lineTo(x + size/2, y + height/2);
- if (!shadow) {
- ctx.lineTo(x, y - height/2);
- ctx.lineTo(x - size/2, y + height/2);
- }
- },
- cross: function (ctx, x, y, radius, shadow) {
- // pi * r^2 = (2s)^2 => s = r * sqrt(pi)/2
- var size = radius * Math.sqrt(Math.PI) / 2;
- ctx.moveTo(x - size, y - size);
- ctx.lineTo(x + size, y + size);
- ctx.moveTo(x - size, y + size);
- ctx.lineTo(x + size, y - size);
- }
- };
-
- var s = series.points.symbol;
- if (handlers[s])
- series.points.symbol = handlers[s];
- }
-
- function init(plot) {
- plot.hooks.processDatapoints.push(processRawData);
- }
-
- $.plot.plugins.push({
- init: init,
- name: 'symbols',
- version: '1.0'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.threshold.js b/src/legacy/ui/public/flot-charts/jquery.flot.threshold.js
deleted file mode 100644
index 8c99c401d87e5..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.threshold.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/* Flot plugin for thresholding data.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-The plugin supports these options:
-
- series: {
- threshold: {
- below: number
- color: colorspec
- }
- }
-
-It can also be applied to a single series, like this:
-
- $.plot( $("#placeholder"), [{
- data: [ ... ],
- threshold: { ... }
- }])
-
-An array can be passed for multiple thresholding, like this:
-
- threshold: [{
- below: number1
- color: color1
- },{
- below: number2
- color: color2
- }]
-
-These multiple threshold objects can be passed in any order since they are
-sorted by the processing function.
-
-The data points below "below" are drawn with the specified color. This makes
-it easy to mark points below 0, e.g. for budget data.
-
-Internally, the plugin works by splitting the data into two series, above and
-below the threshold. The extra series below the threshold will have its label
-cleared and the special "originSeries" attribute set to the original series.
-You may need to check for this in hover events.
-
-*/
-
-(function ($) {
- var options = {
- series: { threshold: null } // or { below: number, color: color spec}
- };
-
- function init(plot) {
- function thresholdData(plot, s, datapoints, below, color) {
- var ps = datapoints.pointsize, i, x, y, p, prevp,
- thresholded = $.extend({}, s); // note: shallow copy
-
- thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };
- thresholded.label = null;
- thresholded.color = color;
- thresholded.threshold = null;
- thresholded.originSeries = s;
- thresholded.data = [];
-
- var origpoints = datapoints.points,
- addCrossingPoints = s.lines.show;
-
- var threspoints = [];
- var newpoints = [];
- var m;
-
- for (i = 0; i < origpoints.length; i += ps) {
- x = origpoints[i];
- y = origpoints[i + 1];
-
- prevp = p;
- if (y < below)
- p = threspoints;
- else
- p = newpoints;
-
- if (addCrossingPoints && prevp != p && x != null
- && i > 0 && origpoints[i - ps] != null) {
- var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);
- prevp.push(interx);
- prevp.push(below);
- for (m = 2; m < ps; ++m)
- prevp.push(origpoints[i + m]);
-
- p.push(null); // start new segment
- p.push(null);
- for (m = 2; m < ps; ++m)
- p.push(origpoints[i + m]);
- p.push(interx);
- p.push(below);
- for (m = 2; m < ps; ++m)
- p.push(origpoints[i + m]);
- }
-
- p.push(x);
- p.push(y);
- for (m = 2; m < ps; ++m)
- p.push(origpoints[i + m]);
- }
-
- datapoints.points = newpoints;
- thresholded.datapoints.points = threspoints;
-
- if (thresholded.datapoints.points.length > 0) {
- var origIndex = $.inArray(s, plot.getData());
- // Insert newly-generated series right after original one (to prevent it from becoming top-most)
- plot.getData().splice(origIndex + 1, 0, thresholded);
- }
-
- // FIXME: there are probably some edge cases left in bars
- }
-
- function processThresholds(plot, s, datapoints) {
- if (!s.threshold)
- return;
-
- if (s.threshold instanceof Array) {
- s.threshold.sort(function(a, b) {
- return a.below - b.below;
- });
-
- $(s.threshold).each(function(i, th) {
- thresholdData(plot, s, datapoints, th.below, th.color);
- });
- }
- else {
- thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);
- }
- }
-
- plot.hooks.processDatapoints.push(processThresholds);
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'threshold',
- version: '1.2'
- });
-})(jQuery);
diff --git a/src/legacy/ui/public/flot-charts/jquery.flot.time.js b/src/legacy/ui/public/flot-charts/jquery.flot.time.js
deleted file mode 100644
index 7612a03302764..0000000000000
--- a/src/legacy/ui/public/flot-charts/jquery.flot.time.js
+++ /dev/null
@@ -1,473 +0,0 @@
-/* Pretty handling of time axes.
-
-Copyright (c) 2007-2014 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-Set axis.mode to "time" to enable. See the section "Time series data" in
-API.txt for details.
-
-*/
-
-import { i18n } from '@kbn/i18n';
-
-(function($) {
-
- var options = {
- xaxis: {
- timezone: null, // "browser" for local to the client or timezone for timezone-js
- timeformat: null, // format string to use
- twelveHourClock: false, // 12 or 24 time in time mode
- monthNames: null // list of names of months
- }
- };
-
- // round to nearby lower multiple of base
-
- function floorInBase(n, base) {
- return base * Math.floor(n / base);
- }
-
- // Returns a string with the date d formatted according to fmt.
- // A subset of the Open Group's strftime format is supported.
-
- function formatDate(d, fmt, monthNames, dayNames) {
-
- if (typeof d.strftime == "function") {
- return d.strftime(fmt);
- }
-
- var leftPad = function(n, pad) {
- n = "" + n;
- pad = "" + (pad == null ? "0" : pad);
- return n.length == 1 ? pad + n : n;
- };
-
- var r = [];
- var escape = false;
- var hours = d.getHours();
- var isAM = hours < 12;
-
- if (monthNames == null) {
- monthNames = [
- i18n.translate('common.ui.flotCharts.janLabel', {
- defaultMessage: 'Jan',
- }), i18n.translate('common.ui.flotCharts.febLabel', {
- defaultMessage: 'Feb',
- }), i18n.translate('common.ui.flotCharts.marLabel', {
- defaultMessage: 'Mar',
- }), i18n.translate('common.ui.flotCharts.aprLabel', {
- defaultMessage: 'Apr',
- }), i18n.translate('common.ui.flotCharts.mayLabel', {
- defaultMessage: 'May',
- }), i18n.translate('common.ui.flotCharts.junLabel', {
- defaultMessage: 'Jun',
- }), i18n.translate('common.ui.flotCharts.julLabel', {
- defaultMessage: 'Jul',
- }), i18n.translate('common.ui.flotCharts.augLabel', {
- defaultMessage: 'Aug',
- }), i18n.translate('common.ui.flotCharts.sepLabel', {
- defaultMessage: 'Sep',
- }), i18n.translate('common.ui.flotCharts.octLabel', {
- defaultMessage: 'Oct',
- }), i18n.translate('common.ui.flotCharts.novLabel', {
- defaultMessage: 'Nov',
- }), i18n.translate('common.ui.flotCharts.decLabel', {
- defaultMessage: 'Dec',
- })];
- }
-
- if (dayNames == null) {
- dayNames = [i18n.translate('common.ui.flotCharts.sunLabel', {
- defaultMessage: 'Sun',
- }), i18n.translate('common.ui.flotCharts.monLabel', {
- defaultMessage: 'Mon',
- }), i18n.translate('common.ui.flotCharts.tueLabel', {
- defaultMessage: 'Tue',
- }), i18n.translate('common.ui.flotCharts.wedLabel', {
- defaultMessage: 'Wed',
- }), i18n.translate('common.ui.flotCharts.thuLabel', {
- defaultMessage: 'Thu',
- }), i18n.translate('common.ui.flotCharts.friLabel', {
- defaultMessage: 'Fri',
- }), i18n.translate('common.ui.flotCharts.satLabel', {
- defaultMessage: 'Sat',
- })];
- }
-
- var hours12;
-
- if (hours > 12) {
- hours12 = hours - 12;
- } else if (hours == 0) {
- hours12 = 12;
- } else {
- hours12 = hours;
- }
-
- for (var i = 0; i < fmt.length; ++i) {
-
- var c = fmt.charAt(i);
-
- if (escape) {
- switch (c) {
- case 'a': c = "" + dayNames[d.getDay()]; break;
- case 'b': c = "" + monthNames[d.getMonth()]; break;
- case 'd': c = leftPad(d.getDate()); break;
- case 'e': c = leftPad(d.getDate(), " "); break;
- case 'h': // For back-compat with 0.7; remove in 1.0
- case 'H': c = leftPad(hours); break;
- case 'I': c = leftPad(hours12); break;
- case 'l': c = leftPad(hours12, " "); break;
- case 'm': c = leftPad(d.getMonth() + 1); break;
- case 'M': c = leftPad(d.getMinutes()); break;
- // quarters not in Open Group's strftime specification
- case 'q':
- c = "" + (Math.floor(d.getMonth() / 3) + 1); break;
- case 'S': c = leftPad(d.getSeconds()); break;
- case 'y': c = leftPad(d.getFullYear() % 100); break;
- case 'Y': c = "" + d.getFullYear(); break;
- case 'p': c = (isAM) ? ("" + "am") : ("" + "pm"); break;
- case 'P': c = (isAM) ? ("" + "AM") : ("" + "PM"); break;
- case 'w': c = "" + d.getDay(); break;
- }
- r.push(c);
- escape = false;
- } else {
- if (c == "%") {
- escape = true;
- } else {
- r.push(c);
- }
- }
- }
-
- return r.join("");
- }
-
- // To have a consistent view of time-based data independent of which time
- // zone the client happens to be in we need a date-like object independent
- // of time zones. This is done through a wrapper that only calls the UTC
- // versions of the accessor methods.
-
- function makeUtcWrapper(d) {
-
- function addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {
- sourceObj[sourceMethod] = function() {
- return targetObj[targetMethod].apply(targetObj, arguments);
- };
- };
-
- var utc = {
- date: d
- };
-
- // support strftime, if found
-
- if (d.strftime != undefined) {
- addProxyMethod(utc, "strftime", d, "strftime");
- }
-
- addProxyMethod(utc, "getTime", d, "getTime");
- addProxyMethod(utc, "setTime", d, "setTime");
-
- var props = ["Date", "Day", "FullYear", "Hours", "Milliseconds", "Minutes", "Month", "Seconds"];
-
- for (var p = 0; p < props.length; p++) {
- addProxyMethod(utc, "get" + props[p], d, "getUTC" + props[p]);
- addProxyMethod(utc, "set" + props[p], d, "setUTC" + props[p]);
- }
-
- return utc;
- };
-
- // select time zone strategy. This returns a date-like object tied to the
- // desired timezone
-
- function dateGenerator(ts, opts) {
- if (opts.timezone == "browser") {
- return new Date(ts);
- } else if (!opts.timezone || opts.timezone == "utc") {
- return makeUtcWrapper(new Date(ts));
- } else if (typeof timezoneJS != "undefined" && typeof timezoneJS.Date != "undefined") {
- var d = new timezoneJS.Date();
- // timezone-js is fickle, so be sure to set the time zone before
- // setting the time.
- d.setTimezone(opts.timezone);
- d.setTime(ts);
- return d;
- } else {
- return makeUtcWrapper(new Date(ts));
- }
- }
-
- // map of app. size of time units in milliseconds
-
- var timeUnitSize = {
- "second": 1000,
- "minute": 60 * 1000,
- "hour": 60 * 60 * 1000,
- "day": 24 * 60 * 60 * 1000,
- "month": 30 * 24 * 60 * 60 * 1000,
- "quarter": 3 * 30 * 24 * 60 * 60 * 1000,
- "year": 365.2425 * 24 * 60 * 60 * 1000
- };
-
- // the allowed tick sizes, after 1 year we use
- // an integer algorithm
-
- var baseSpec = [
- [1, "second"], [2, "second"], [5, "second"], [10, "second"],
- [30, "second"],
- [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"],
- [30, "minute"],
- [1, "hour"], [2, "hour"], [4, "hour"],
- [8, "hour"], [12, "hour"],
- [1, "day"], [2, "day"], [3, "day"],
- [0.25, "month"], [0.5, "month"], [1, "month"],
- [2, "month"]
- ];
-
- // we don't know which variant(s) we'll need yet, but generating both is
- // cheap
-
- var specMonths = baseSpec.concat([[3, "month"], [6, "month"],
- [1, "year"]]);
- var specQuarters = baseSpec.concat([[1, "quarter"], [2, "quarter"],
- [1, "year"]]);
-
- function init(plot) {
- plot.hooks.processOptions.push(function (plot, options) {
- $.each(plot.getAxes(), function(axisName, axis) {
-
- var opts = axis.options;
-
- if (opts.mode == "time") {
- axis.tickGenerator = function(axis) {
-
- var ticks = [];
- var d = dateGenerator(axis.min, opts);
- var minSize = 0;
-
- // make quarter use a possibility if quarters are
- // mentioned in either of these options
-
- var spec = (opts.tickSize && opts.tickSize[1] ===
- "quarter") ||
- (opts.minTickSize && opts.minTickSize[1] ===
- "quarter") ? specQuarters : specMonths;
-
- if (opts.minTickSize != null) {
- if (typeof opts.tickSize == "number") {
- minSize = opts.tickSize;
- } else {
- minSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];
- }
- }
-
- for (var i = 0; i < spec.length - 1; ++i) {
- if (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]
- + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2
- && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {
- break;
- }
- }
-
- var size = spec[i][0];
- var unit = spec[i][1];
-
- // special-case the possibility of several years
-
- if (unit == "year") {
-
- // if given a minTickSize in years, just use it,
- // ensuring that it's an integer
-
- if (opts.minTickSize != null && opts.minTickSize[1] == "year") {
- size = Math.floor(opts.minTickSize[0]);
- } else {
-
- var magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));
- var norm = (axis.delta / timeUnitSize.year) / magn;
-
- if (norm < 1.5) {
- size = 1;
- } else if (norm < 3) {
- size = 2;
- } else if (norm < 7.5) {
- size = 5;
- } else {
- size = 10;
- }
-
- size *= magn;
- }
-
- // minimum size for years is 1
-
- if (size < 1) {
- size = 1;
- }
- }
-
- axis.tickSize = opts.tickSize || [size, unit];
- var tickSize = axis.tickSize[0];
- unit = axis.tickSize[1];
-
- var step = tickSize * timeUnitSize[unit];
-
- if (unit == "second") {
- d.setSeconds(floorInBase(d.getSeconds(), tickSize));
- } else if (unit == "minute") {
- d.setMinutes(floorInBase(d.getMinutes(), tickSize));
- } else if (unit == "hour") {
- d.setHours(floorInBase(d.getHours(), tickSize));
- } else if (unit == "month") {
- d.setMonth(floorInBase(d.getMonth(), tickSize));
- } else if (unit == "quarter") {
- d.setMonth(3 * floorInBase(d.getMonth() / 3,
- tickSize));
- } else if (unit == "year") {
- d.setFullYear(floorInBase(d.getFullYear(), tickSize));
- }
-
- // reset smaller components
-
- d.setMilliseconds(0);
-
- if (step >= timeUnitSize.minute) {
- d.setSeconds(0);
- }
- if (step >= timeUnitSize.hour) {
- d.setMinutes(0);
- }
- if (step >= timeUnitSize.day) {
- d.setHours(0);
- }
- if (step >= timeUnitSize.day * 4) {
- d.setDate(1);
- }
- if (step >= timeUnitSize.month * 2) {
- d.setMonth(floorInBase(d.getMonth(), 3));
- }
- if (step >= timeUnitSize.quarter * 2) {
- d.setMonth(floorInBase(d.getMonth(), 6));
- }
- if (step >= timeUnitSize.year) {
- d.setMonth(0);
- }
-
- var carry = 0;
- var v = Number.NaN;
- var prev;
-
- do {
-
- prev = v;
- v = d.getTime();
- ticks.push(v);
-
- if (unit == "month" || unit == "quarter") {
- if (tickSize < 1) {
-
- // a bit complicated - we'll divide the
- // month/quarter up but we need to take
- // care of fractions so we don't end up in
- // the middle of a day
-
- d.setDate(1);
- var start = d.getTime();
- d.setMonth(d.getMonth() +
- (unit == "quarter" ? 3 : 1));
- var end = d.getTime();
- d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);
- carry = d.getHours();
- d.setHours(0);
- } else {
- d.setMonth(d.getMonth() +
- tickSize * (unit == "quarter" ? 3 : 1));
- }
- } else if (unit == "year") {
- d.setFullYear(d.getFullYear() + tickSize);
- } else {
- d.setTime(v + step);
- }
- } while (v < axis.max && v != prev);
-
- return ticks;
- };
-
- axis.tickFormatter = function (v, axis) {
-
- var d = dateGenerator(v, axis.options);
-
- // first check global format
-
- if (opts.timeformat != null) {
- return formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);
- }
-
- // possibly use quarters if quarters are mentioned in
- // any of these places
-
- var useQuarters = (axis.options.tickSize &&
- axis.options.tickSize[1] == "quarter") ||
- (axis.options.minTickSize &&
- axis.options.minTickSize[1] == "quarter");
-
- var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];
- var span = axis.max - axis.min;
- var suffix = (opts.twelveHourClock) ? " %p" : "";
- var hourCode = (opts.twelveHourClock) ? "%I" : "%H";
- var fmt;
-
- if (t < timeUnitSize.minute) {
- fmt = hourCode + ":%M:%S" + suffix;
- } else if (t < timeUnitSize.day) {
- if (span < 2 * timeUnitSize.day) {
- fmt = hourCode + ":%M" + suffix;
- } else {
- fmt = "%b %d " + hourCode + ":%M" + suffix;
- }
- } else if (t < timeUnitSize.month) {
- fmt = "%b %d";
- } else if ((useQuarters && t < timeUnitSize.quarter) ||
- (!useQuarters && t < timeUnitSize.year)) {
- if (span < timeUnitSize.year) {
- fmt = "%b";
- } else {
- fmt = "%b %Y";
- }
- } else if (useQuarters && t < timeUnitSize.year) {
- if (span < timeUnitSize.year) {
- fmt = "Q%q";
- } else {
- fmt = "Q%q %Y";
- }
- } else {
- fmt = "%Y";
- }
-
- var rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);
-
- return rt;
- };
- }
- });
- });
- }
-
- $.plot.plugins.push({
- init: init,
- options: options,
- name: 'time',
- version: '1.0'
- });
-
- // Time-axis support used to be in Flot core, which exposed the
- // formatDate function on the plot object. Various plugins depend
- // on the function, so we need to re-expose it here.
-
- $.plot.formatDate = formatDate;
- $.plot.dateGenerator = dateGenerator;
-
-})(jQuery);
diff --git a/src/legacy/ui/public/i18n/__snapshots__/index.test.tsx.snap b/src/legacy/ui/public/i18n/__snapshots__/index.test.tsx.snap
deleted file mode 100644
index fd6a0a07ba39c..0000000000000
--- a/src/legacy/ui/public/i18n/__snapshots__/index.test.tsx.snap
+++ /dev/null
@@ -1,10 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`ui/i18n renders children and forwards properties 1`] = `
-
- Context:
-
- Child: some prop:100500
-
-
-`;
diff --git a/src/legacy/ui/public/i18n/index.test.tsx b/src/legacy/ui/public/i18n/index.test.tsx
deleted file mode 100644
index be8ab4cf8d696..0000000000000
--- a/src/legacy/ui/public/i18n/index.test.tsx
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { render } from 'enzyme';
-import PropTypes from 'prop-types';
-import React from 'react';
-
-jest.mock('angular-sanitize', () => {});
-jest.mock('ui/new_platform', () => ({
- npStart: {
- core: {
- i18n: { Context: ({ children }: any) => Context: {children}
},
- },
- },
-}));
-
-import { wrapInI18nContext } from '.';
-
-describe('ui/i18n', () => {
- test('renders children and forwards properties', () => {
- const mockPropTypes = {
- stringProp: PropTypes.string.isRequired,
- numberProp: PropTypes.number,
- };
-
- const WrappedComponent = wrapInI18nContext(
- class extends React.PureComponent<{ [P in keyof typeof mockPropTypes]: unknown }> {
- public static propTypes = mockPropTypes;
-
- public render() {
- return (
-
- Child: {this.props.stringProp}:{this.props.numberProp}
-
- );
- }
- }
- );
-
- expect(WrappedComponent.propTypes).toBe(mockPropTypes);
- expect(
- render( )
- ).toMatchSnapshot();
- });
-});
diff --git a/src/legacy/ui/public/i18n/index.tsx b/src/legacy/ui/public/i18n/index.tsx
deleted file mode 100644
index 290e82a1334b9..0000000000000
--- a/src/legacy/ui/public/i18n/index.tsx
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-// required for `ngSanitize` angular module
-import 'angular-sanitize';
-
-import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular';
-// @ts-ignore
-import { uiModules } from 'ui/modules';
-import { npStart } from 'ui/new_platform';
-
-export const I18nContext = npStart.core.i18n.Context;
-
-export function wrapInI18nContext(ComponentToWrap: React.ComponentType
) {
- const ContextWrapper: React.FC
= (props) => {
- return (
-
-
-
- );
- };
-
- // Original propTypes from the wrapped component should be re-exposed
- // since it will be used by reactDirective Angular service
- // that will rely on propTypes to watch attributes with these names
- ContextWrapper.propTypes = ComponentToWrap.propTypes;
-
- return ContextWrapper;
-}
-
-uiModules
- .get('i18n', ['ngSanitize'])
- .provider('i18n', I18nProvider)
- .filter('i18n', i18nFilter)
- .directive('i18nId', i18nDirective);
diff --git a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js b/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js
deleted file mode 100644
index df96a58a6e99f..0000000000000
--- a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import expect from '@kbn/expect';
-import { IndexedArray } from '..';
-
-// this is generally a data-structure that IndexedArray is good for managing
-const users = [
- { name: 'John', id: 6, username: 'beast', group: 'admins' },
- { name: 'Anon', id: 0, username: 'shhhh', group: 'secret' },
- { name: 'Fern', id: 42, username: 'kitty', group: 'editor' },
- { name: 'Mary', id: 55, username: 'sheep', group: 'editor' },
-];
-
-// this is how we used to accomplish this, before IndexedArray
-users.byName = _.keyBy(users, 'name');
-users.byUsername = _.keyBy(users, 'username');
-users.byGroup = _.groupBy(users, 'group');
-users.inIdOrder = _.sortBy(users, 'id');
-
-// then things started becoming unruly... so IndexedArray!
-
-describe('IndexedArray', function () {
- describe('Basics', function () {
- let reg;
-
- beforeEach(function () {
- reg = new IndexedArray();
- });
-
- it('Extends Array', function () {
- expect(reg).to.be.a(Array);
- });
-
- it('fails basic lodash check', function () {
- expect(Array.isArray(reg)).to.be(false);
- });
-
- it('clones to an object', function () {
- expect(_.isObject(_.clone(reg))).to.be(true);
- expect(Array.isArray(_.clone(reg))).to.be(false);
- });
- });
-
- describe('Indexing', function () {
- it('provides the initial set', function () {
- const reg = new IndexedArray({
- initialSet: [1, 2, 3],
- });
-
- expect(reg).to.have.length(3);
-
- reg.forEach(function (v, i) {
- expect(v).to.eql(i + 1);
- });
- });
-
- it('indexes the initial set', function () {
- const reg = new IndexedArray({
- index: ['username'],
- initialSet: users,
- });
-
- expect(reg).to.have.property('byUsername');
- expect(reg.byUsername).to.eql(users.byUsername);
- });
-
- it('updates indices after values are added', function () {
- // split up the user list, and add it in chunks
- const firstUser = users.slice(0, 1).pop();
- const otherUsers = users.slice(1);
-
- // start off with all but the first
- const reg = new IndexedArray({
- group: ['group'],
- order: ['id'],
- initialSet: otherUsers,
- });
-
- // add the first
- reg.push(firstUser);
-
- // end up with the same structure that is in the users fixture
- expect(Object.keys(reg.byGroup).length).to.be(Object.keys(users.byGroup).length);
- for (const group of Object.keys(reg.byGroup)) {
- expect(reg.byGroup[group].toJSON()).to.eql(users.byGroup[group]);
- }
-
- expect(reg.inIdOrder).to.eql(users.inIdOrder);
- });
-
- it('updates indices after values are removed', function () {
- // start off with all
- const reg = new IndexedArray({
- group: ['group'],
- order: ['id'],
- initialSet: users,
- });
-
- // remove the last
- reg.pop();
-
- const expectedCount = users.length - 1;
- // indexed lists should be updated
- expect(reg).to.have.length(expectedCount);
-
- const sumOfGroups = _.reduce(
- reg.byGroup,
- function (note, group) {
- return note + group.length;
- },
- 0
- );
- expect(sumOfGroups).to.eql(expectedCount);
- });
-
- it('removes items based on a predicate', function () {
- const reg = new IndexedArray({
- group: ['group'],
- order: ['id'],
- initialSet: users,
- });
-
- reg.remove({ name: 'John' });
-
- expect(_.isEqual(reg.raw, reg.slice(0))).to.be(true);
- expect(reg.length).to.be(3);
- expect(reg[0].name).to.be('Anon');
- });
-
- it('updates indices after values are re-ordered', function () {
- const rawUsers = users.slice(0);
-
- // collect and shuffle the ids available
- let ids = [];
- _.times(rawUsers.length, function (i) {
- ids.push(i);
- });
- ids = _.shuffle(ids);
-
- // move something here
- const toI = ids.shift();
- // from here
- const fromI = ids.shift();
- // do the move
- const move = function (arr) {
- arr.splice(toI, 0, arr.splice(fromI, 1)[0]);
- };
-
- const reg = new IndexedArray({
- index: ['username'],
- initialSet: rawUsers,
- });
-
- const index = reg.byUsername;
-
- move(reg);
-
- expect(reg.byUsername).to.eql(index);
- expect(reg.byUsername).to.not.be(index);
- });
- });
-
- describe('Ordering', function () {
- it('ordering is case insensitive', function () {
- const reg = new IndexedArray({
- index: ['title'],
- order: ['title'],
- initialSet: [{ title: 'APM' }, { title: 'Advanced Settings' }],
- });
-
- const ordered = reg.inTitleOrder;
- expect(ordered[0].title).to.be('Advanced Settings');
- expect(ordered[1].title).to.be('APM');
- });
-
- it('ordering handles numbers', function () {
- const reg = new IndexedArray({
- index: ['id'],
- order: ['id'],
- initialSet: users,
- });
-
- const ordered = reg.inIdOrder;
- expect(ordered[0].id).to.be(0);
- expect(ordered[1].id).to.be(6);
- expect(ordered[2].id).to.be(42);
- expect(ordered[3].id).to.be(55);
- });
- });
-});
diff --git a/src/legacy/ui/public/indexed_array/__tests__/inflector.js b/src/legacy/ui/public/indexed_array/__tests__/inflector.js
deleted file mode 100644
index 49ac79094e501..0000000000000
--- a/src/legacy/ui/public/indexed_array/__tests__/inflector.js
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { inflector } from '../inflector';
-import expect from '@kbn/expect';
-
-describe('IndexedArray Inflector', function () {
- it('returns a function', function () {
- const getter = inflector();
- expect(getter).to.be.a('function');
- });
-
- describe('fn', function () {
- it('prepends a prefix', function () {
- const inflect = inflector('my');
-
- expect(inflect('Family')).to.be('myFamily');
- expect(inflect('family')).to.be('myFamily');
- expect(inflect('fAmIlY')).to.be('myFAmIlY');
- });
-
- it('adds both a prefix and suffix', function () {
- const inflect = inflector('foo', 'Bar');
-
- expect(inflect('box')).to.be('fooBoxBar');
- expect(inflect('box.car.MAX')).to.be('fooBoxCarMaxBar');
- expect(inflect('BaZzY')).to.be('fooBaZzYBar');
- });
-
- it('ignores prefix if it is already at the end of the inflected string', function () {
- const inflect = inflector('foo', 'Bar');
- expect(inflect('fooBox')).to.be('fooBoxBar');
- expect(inflect('FooBox')).to.be('FooBoxBar');
- });
-
- it('ignores postfix if it is already at the end of the inflected string', function () {
- const inflect = inflector('foo', 'Bar');
- expect(inflect('bar')).to.be('fooBar');
- expect(inflect('showBoxBar')).to.be('fooShowBoxBar');
- });
-
- it('works with "name"', function () {
- const inflect = inflector('in', 'Order');
- expect(inflect('name')).to.be('inNameOrder');
- });
- });
-});
diff --git a/src/legacy/ui/public/indexed_array/helpers/organize_by.test.ts b/src/legacy/ui/public/indexed_array/helpers/organize_by.test.ts
deleted file mode 100644
index fc4ca8469382a..0000000000000
--- a/src/legacy/ui/public/indexed_array/helpers/organize_by.test.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { groupBy } from 'lodash';
-import { organizeBy } from './organize_by';
-
-describe('organizeBy', () => {
- test('it works', () => {
- const col = [
- {
- name: 'one',
- roles: ['user', 'admin', 'owner'],
- },
- {
- name: 'two',
- roles: ['user'],
- },
- {
- name: 'three',
- roles: ['user'],
- },
- {
- name: 'four',
- roles: ['user', 'admin'],
- },
- ];
-
- const resp = organizeBy(col, 'roles');
- expect(resp).toHaveProperty('user');
- expect(resp.user.length).toBe(4);
-
- expect(resp).toHaveProperty('admin');
- expect(resp.admin.length).toBe(2);
-
- expect(resp).toHaveProperty('owner');
- expect(resp.owner.length).toBe(1);
- });
-
- test('behaves just like groupBy in normal scenarios', () => {
- const col = [{ name: 'one' }, { name: 'two' }, { name: 'three' }, { name: 'four' }];
-
- const orgs = organizeBy(col, 'name');
- const groups = groupBy(col, 'name');
-
- expect(orgs).toEqual(groups);
- });
-});
diff --git a/src/legacy/ui/public/indexed_array/helpers/organize_by.ts b/src/legacy/ui/public/indexed_array/helpers/organize_by.ts
deleted file mode 100644
index e923767c892cd..0000000000000
--- a/src/legacy/ui/public/indexed_array/helpers/organize_by.ts
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { each, isFunction } from 'lodash';
-
-/**
- * Like _.groupBy, but allows specifying multiple groups for a
- * single object.
- *
- * organizeBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
- * // Object {1: Array[2], 2: Array[1], 3: Array[1], 4: Array[1]}
- *
- * _.groupBy([{ a: [1, 2, 3] }, { b: true, a: [1, 4] }], 'a')
- * // Object {'1,2,3': Array[1], '1,4': Array[1]}
- *
- * @param {array} collection - the list of values to organize
- * @param {Function} callback - either a property name, or a callback.
- * @return {object}
- */
-export function organizeBy(collection: object[], callback: ((obj: object) => string) | string) {
- const buckets: { [key: string]: object[] } = {};
-
- function add(key: string, obj: object) {
- if (!buckets[key]) {
- buckets[key] = [];
- }
- buckets[key].push(obj);
- }
-
- each(collection, (obj: Record) => {
- const keys = isFunction(callback) ? callback(obj) : obj[callback];
-
- if (!Array.isArray(keys)) {
- add(keys, obj);
- return;
- }
-
- let length = keys.length;
- while (length-- > 0) {
- add(keys[length], obj);
- }
- });
-
- return buckets;
-}
diff --git a/src/legacy/ui/public/indexed_array/index.d.ts b/src/legacy/ui/public/indexed_array/index.d.ts
deleted file mode 100644
index 21c0a818731ac..0000000000000
--- a/src/legacy/ui/public/indexed_array/index.d.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { ListIterator } from 'lodash';
-
-interface IndexedArrayConfig {
- index?: string[];
- group?: string[];
- order?: string[];
- initialSet?: T[];
- immutable?: boolean;
-}
-
-declare class IndexedArray extends Array {
- public immutable: boolean;
- public raw: T[];
-
- // These may not actually be present, as they are dynamically defined
- public inOrder: T[];
- public byType: Record;
- public byName: Record;
-
- constructor(config: IndexedArrayConfig);
-
- public remove(predicate: ListIterator): T[];
-
- public toJSON(): T[];
-}
diff --git a/src/legacy/ui/public/indexed_array/index.js b/src/legacy/ui/public/indexed_array/index.js
deleted file mode 100644
index 6a42961c9e680..0000000000000
--- a/src/legacy/ui/public/indexed_array/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { IndexedArray } from './indexed_array';
diff --git a/src/legacy/ui/public/indexed_array/indexed_array.js b/src/legacy/ui/public/indexed_array/indexed_array.js
deleted file mode 100644
index b9a427b8da7ad..0000000000000
--- a/src/legacy/ui/public/indexed_array/indexed_array.js
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { inflector } from './inflector';
-import { organizeBy } from './helpers/organize_by';
-
-const pathGetter = _(_.get).rearg(1, 0).ary(2);
-const inflectIndex = inflector('by');
-const inflectOrder = inflector('in', 'Order');
-
-const CLEAR_CACHE = {};
-const OPT_NAMES = ['index', 'group', 'order', 'initialSet', 'immutable'];
-
-/**
- * Generic extension of Array class, which will index (and reindex) the
- * objects it contains based on their properties.
- *
- * @param {Object} config describes the properties of this registry object
- * @param {Array} [config.index] a list of props/paths that should be used to index the docs.
- * @param {Array} [config.group] a list of keys/paths to group docs by.
- * @param {Array} [config.order] a list of keys/paths to order the keys by.
- * @param {Array} [config.initialSet] the initial dataset the IndexedArray should contain.
- * @param {boolean} [config.immutable] a flag that hints to people reading the implementation that this IndexedArray
- * should not be modified
- */
-
-export class IndexedArray {
- static OPT_NAMES = OPT_NAMES;
-
- constructor(config) {
- config = _.pick(config || {}, OPT_NAMES);
-
- // use defineProperty so that value can't be changed
- Object.defineProperty(this, 'raw', { value: [] });
-
- this._indexNames = _.union(
- this._setupIndex(config.group, inflectIndex, organizeByIndexedArray(config)),
- this._setupIndex(config.index, inflectIndex, _.keyBy),
- this._setupIndex(config.order, inflectOrder, (raw, pluckValue) => {
- return [...raw].sort((itemA, itemB) => {
- const a = pluckValue(itemA);
- const b = pluckValue(itemB);
- if (typeof a === 'number' && typeof b === 'number') {
- return a - b;
- }
- return String(a).toLowerCase().localeCompare(String(b).toLowerCase());
- });
- })
- );
-
- if (config.initialSet) {
- this.push.apply(this, config.initialSet);
- }
-
- Object.defineProperty(this, 'immutable', { value: !!config.immutable });
- }
-
- /**
- * Remove items from this based on a predicate
- * @param {Function|Object|string} predicate - the predicate used to decide what is removed
- * @return {array} - the removed data
- */
- remove(predicate) {
- this._assertMutable('remove');
- const out = _.remove(this, predicate);
- _.remove(this.raw, predicate);
- this._clearIndices();
- return out;
- }
-
- /**
- * provide a hook for the JSON serializer
- * @return {array} - a plain, vanilla array with our same data
- */
- toJSON() {
- return this.raw;
- }
-
- // wrappers for mutable Array methods
- copyWithin(...args) {
- return this._mutation('copyWithin', args);
- }
- fill(...args) {
- return this._mutation('fill', args);
- }
- pop(...args) {
- return this._mutation('pop', args);
- }
- push(...args) {
- return this._mutation('push', args);
- }
- reverse(...args) {
- return this._mutation('reverse', args);
- }
- shift(...args) {
- return this._mutation('shift', args);
- }
- sort(...args) {
- return this._mutation('sort', args);
- }
- splice(...args) {
- return this._mutation('splice', args);
- }
- unshift(...args) {
- return this._mutation('unshift', args);
- }
-
- /**
- * If this instance of IndexedArray is not mutable, throw an error
- * @private
- * @param {String} methodName - user facing method name, for error message
- * @return {undefined}
- */
- _assertMutable(methodName) {
- if (this.immutable) {
- throw new Error(`${methodName}() is not allowed on immutable IndexedArray instances`);
- }
- }
-
- /**
- * Execute some mutable method from the Array prototype
- * on the IndexedArray and this.raw
- *
- * @private
- * @param {string} methodName
- * @param {Array} args
- * @return {any}
- */
- _mutation(methodName, args) {
- this._assertMutable(methodName);
- super[methodName].apply(this, args);
- this._clearIndices();
- return super[methodName].apply(this.raw, args);
- }
-
- /**
- * Create indices for a group of object properties. getters and setters are used to
- * read and control the indices.
- * @private
- * @param {string[]} props - the properties that should be used to index docs
- * @param {function} inflect - a function that will be called with a property name, and
- * creates the public property at which the index will be exposed
- * @param {function} op - the function that will be used to create the indices, it is passed
- * the raw representation of the registry, and a getter for reading the
- * right prop
- *
- * @returns {string[]} - the public keys of all indices created
- */
- _setupIndex(props, inflect, op) {
- // shortcut for empty props
- if (!props || props.length === 0) return;
-
- return props.map((prop) => {
- const indexName = inflect(prop);
- const getIndexValueFromItem = pathGetter.partial(prop).value();
- let cache;
-
- Object.defineProperty(this, indexName, {
- enumerable: false,
- configurable: false,
-
- set: (val) => {
- // can't set any value other than the CLEAR_CACHE constant
- if (val === CLEAR_CACHE) {
- cache = false;
- } else {
- throw new TypeError(indexName + ' can not be set, it is a computed index of values');
- }
- },
- get: () => {
- if (!cache) {
- cache = op(this.raw, getIndexValueFromItem);
- }
-
- return cache;
- },
- });
-
- return indexName;
- });
- }
-
- /**
- * Clear cached index/group/order caches so they will be recreated
- * on next access
- * @private
- * @return {undefined}
- */
- _clearIndices() {
- this._indexNames.forEach((name) => {
- this[name] = CLEAR_CACHE;
- });
- }
-}
-
-// using traditional `extends Array` syntax doesn't work with babel
-// See https://babeljs.io/docs/usage/caveats/
-Object.setPrototypeOf(IndexedArray.prototype, Array.prototype);
-
-// Similar to `organizeBy` but returns IndexedArrays instead of normal Arrays.
-function organizeByIndexedArray(config) {
- return (...args) => {
- const grouped = organizeBy(...args);
-
- return _.reduce(
- grouped,
- (acc, value, group) => {
- acc[group] = new IndexedArray({
- ...config,
- initialSet: value,
- });
-
- return acc;
- },
- {}
- );
- };
-}
diff --git a/src/legacy/ui/public/indexed_array/inflector.js b/src/legacy/ui/public/indexed_array/inflector.js
deleted file mode 100644
index e034146f5f62f..0000000000000
--- a/src/legacy/ui/public/indexed_array/inflector.js
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-function upFirst(str, total) {
- return str.charAt(0).toUpperCase() + (total ? str.substr(1).toLowerCase() : str.substr(1));
-}
-
-function startsWith(str, test) {
- return str.substr(0, test.length).toLowerCase() === test.toLowerCase();
-}
-
-function endsWith(str, test) {
- const tooShort = str.length < test.length;
- if (tooShort) return;
-
- return str.substr(str.length - test.length).toLowerCase() === test.toLowerCase();
-}
-
-export function inflector(prefix, postfix) {
- return function inflect(key) {
- let inflected;
-
- if (key.indexOf('.') !== -1) {
- inflected = key
- .split('.')
- .map(function (step, i) {
- return i === 0 ? step : upFirst(step, true);
- })
- .join('');
- } else {
- inflected = key;
- }
-
- if (prefix && !startsWith(key, prefix)) {
- inflected = prefix + upFirst(inflected);
- }
-
- if (postfix && !endsWith(key, postfix)) {
- inflected = inflected + postfix;
- }
-
- return inflected;
- };
-}
diff --git a/src/legacy/ui/public/kfetch/__mocks__/index.ts b/src/legacy/ui/public/kfetch/__mocks__/index.ts
deleted file mode 100644
index 1a128e2b85260..0000000000000
--- a/src/legacy/ui/public/kfetch/__mocks__/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export const kfetch = () => Promise.resolve();
diff --git a/src/legacy/ui/public/kfetch/_import_objects.ndjson b/src/legacy/ui/public/kfetch/_import_objects.ndjson
deleted file mode 100644
index 3511fb44cdfb2..0000000000000
--- a/src/legacy/ui/public/kfetch/_import_objects.ndjson
+++ /dev/null
@@ -1 +0,0 @@
-{"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"title":"Log Agents","uiStateJSON":"{}","visState":"{\"title\":\"Log Agents\",\"type\":\"area\",\"params\":{\"type\":\"area\",\"grid\":{\"categoryLines\":false,\"style\":{\"color\":\"#eee\"}},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"truncate\":100},\"title\":{\"text\":\"agent.raw: Descending\"}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Count\"}}],\"seriesParams\":[{\"show\":\"true\",\"type\":\"area\",\"mode\":\"stacked\",\"data\":{\"label\":\"Count\",\"id\":\"1\"},\"drawLinesBetweenPoints\":true,\"showCircles\":true,\"interpolate\":\"linear\",\"valueAxis\":\"ValueAxis-1\"}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"agent.raw\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\"}}]}"},"id":"082f1d60-a2e7-11e7-bb30-233be9be6a15","migrationVersion":{"visualization":"7.0.0"},"references":[{"id":"f1e4c910-a2e6-11e7-bb30-233be9be6a15","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"}],"type":"visualization","version":1}
diff --git a/src/legacy/ui/public/kfetch/index.ts b/src/legacy/ui/public/kfetch/index.ts
deleted file mode 100644
index 105df171ad370..0000000000000
--- a/src/legacy/ui/public/kfetch/index.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-import { createKfetch, KFetchKibanaOptions, KFetchOptions } from './kfetch';
-export { addInterceptor, KFetchOptions, KFetchQuery } from './kfetch';
-
-const kfetchInstance = createKfetch(npSetup.core.http);
-
-export const kfetch = (options: KFetchOptions, kfetchOptions?: KFetchKibanaOptions) => {
- return kfetchInstance(options, kfetchOptions);
-};
diff --git a/src/legacy/ui/public/kfetch/kfetch.test.mocks.ts b/src/legacy/ui/public/kfetch/kfetch.test.mocks.ts
deleted file mode 100644
index ea066b3623f13..0000000000000
--- a/src/legacy/ui/public/kfetch/kfetch.test.mocks.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { setup } from '../../../../test_utils/public/http_test_setup';
-
-jest.doMock('ui/new_platform', () => ({
- npSetup: {
- core: setup(),
- },
-}));
diff --git a/src/legacy/ui/public/kfetch/kfetch.test.ts b/src/legacy/ui/public/kfetch/kfetch.test.ts
deleted file mode 100644
index c45a142d54e9b..0000000000000
--- a/src/legacy/ui/public/kfetch/kfetch.test.ts
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// @ts-ignore
-import fetchMock from 'fetch-mock/es5/client';
-import './kfetch.test.mocks';
-import { readFileSync } from 'fs';
-import { join } from 'path';
-import { addInterceptor, kfetch, KFetchOptions } from '.';
-import { Interceptor, resetInterceptors, withDefaultOptions } from './kfetch';
-import { KFetchError } from './kfetch_error';
-
-describe('kfetch', () => {
- afterEach(() => {
- fetchMock.restore();
- resetInterceptors();
- });
-
- it('should use supplied request method', async () => {
- fetchMock.post('*', {});
- await kfetch({ pathname: '/my/path', method: 'POST' });
- expect(fetchMock.lastOptions()!.method).toBe('POST');
- });
-
- it('should use supplied Content-Type', async () => {
- fetchMock.get('*', {});
- await kfetch({ pathname: '/my/path', headers: { 'Content-Type': 'CustomContentType' } });
- expect(fetchMock.lastOptions()!.headers).toMatchObject({
- 'content-type': 'CustomContentType',
- });
- });
-
- it('should use supplied pathname and querystring', async () => {
- fetchMock.get('*', {});
- await kfetch({ pathname: '/my/path', query: { a: 'b' } });
- expect(fetchMock.lastUrl()).toBe('http://localhost/myBase/my/path?a=b');
- });
-
- it('should use supplied headers', async () => {
- fetchMock.get('*', {});
- await kfetch({
- pathname: '/my/path',
- headers: { myHeader: 'foo' },
- });
-
- expect(fetchMock.lastOptions()!.headers).toEqual({
- 'content-type': 'application/json',
- 'kbn-version': 'kibanaVersion',
- myheader: 'foo',
- });
- });
-
- it('should return response', async () => {
- fetchMock.get('*', { foo: 'bar' });
- const res = await kfetch({ pathname: '/my/path' });
- expect(res).toEqual({ foo: 'bar' });
- });
-
- it('should prepend url with basepath by default', async () => {
- fetchMock.get('*', {});
- await kfetch({ pathname: '/my/path' });
- expect(fetchMock.lastUrl()).toBe('http://localhost/myBase/my/path');
- });
-
- it('should not prepend url with basepath when disabled', async () => {
- fetchMock.get('*', {});
- await kfetch({ pathname: '/my/path' }, { prependBasePath: false });
- expect(fetchMock.lastUrl()).toBe('/my/path');
- });
-
- it('should make request with defaults', async () => {
- fetchMock.get('*', {});
- await kfetch({ pathname: '/my/path' });
-
- expect(fetchMock.lastCall()!.request.credentials).toBe('same-origin');
- expect(fetchMock.lastOptions()!).toMatchObject({
- method: 'GET',
- headers: {
- 'content-type': 'application/json',
- 'kbn-version': 'kibanaVersion',
- },
- });
- });
-
- it('should make requests for NDJSON content', async () => {
- const content = readFileSync(join(__dirname, '_import_objects.ndjson'), { encoding: 'utf-8' });
-
- fetchMock.post('*', {
- body: content,
- headers: { 'Content-Type': 'application/ndjson' },
- });
-
- const data = await kfetch({
- method: 'POST',
- pathname: '/my/path',
- body: content,
- headers: {
- 'Content-Type': 'multipart/form-data',
- },
- });
-
- expect(data).toBeInstanceOf(Blob);
-
- const ndjson = await new Response(data).text();
-
- expect(ndjson).toEqual(content);
- });
-
- it('should reject on network error', async () => {
- expect.assertions(1);
- fetchMock.get('*', { status: 500 });
-
- try {
- await kfetch({ pathname: '/my/path' });
- } catch (e) {
- expect(e.message).toBe('Internal Server Error');
- }
- });
-
- describe('when throwing response error (KFetchError)', () => {
- let error: KFetchError;
- beforeEach(async () => {
- fetchMock.get('*', { status: 404, body: { foo: 'bar' } });
- try {
- await kfetch({ pathname: '/my/path' });
- } catch (e) {
- error = e;
- }
- });
-
- it('should contain error message', () => {
- expect(error.message).toBe('Not Found');
- });
-
- it('should return response body', () => {
- expect(error.body).toEqual({ foo: 'bar' });
- });
-
- it('should contain response properties', () => {
- expect(error.res.status).toBe(404);
- expect(error.res.url).toBe('http://localhost/myBase/my/path');
- });
- });
-
- describe('when all interceptor resolves', () => {
- let resp: any;
- let interceptorCalls: string[];
-
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
-
- interceptorCalls = mockInterceptorCalls([{}, {}, {}]);
- resp = await kfetch({ pathname: '/my/path' });
- });
-
- it('should call interceptors in correct order', () => {
- expect(interceptorCalls).toEqual([
- 'Request #3',
- 'Request #2',
- 'Request #1',
- 'Response #1',
- 'Response #2',
- 'Response #3',
- ]);
- });
-
- it('should make request', () => {
- expect(fetchMock.called()).toBe(true);
- });
-
- it('should return response', () => {
- expect(resp).toEqual({ foo: 'bar' });
- });
- });
-
- describe('when a request interceptor throws; and the next requestError interceptor resolves', () => {
- let resp: any;
- let interceptorCalls: string[];
-
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
-
- interceptorCalls = mockInterceptorCalls([
- { requestError: () => ({ pathname: '/my/path' } as KFetchOptions) },
- { request: () => Promise.reject(new Error('Error in request')) },
- {},
- ]);
-
- resp = await kfetch({ pathname: '/my/path' });
- });
-
- it('should call interceptors in correct order', () => {
- expect(interceptorCalls).toEqual([
- 'Request #3',
- 'Request #2',
- 'RequestError #1',
- 'Response #1',
- 'Response #2',
- 'Response #3',
- ]);
- });
-
- it('should make request', () => {
- expect(fetchMock.called()).toBe(true);
- });
-
- it('should return response', () => {
- expect(resp).toEqual({ foo: 'bar' });
- });
- });
-
- describe('when a request interceptor throws', () => {
- let error: Error;
- let interceptorCalls: string[];
-
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
-
- interceptorCalls = mockInterceptorCalls([
- {},
- { request: () => Promise.reject(new Error('Error in request')) },
- {},
- ]);
-
- try {
- await kfetch({ pathname: '/my/path' });
- } catch (e) {
- error = e;
- }
- });
-
- it('should call interceptors in correct order', () => {
- expect(interceptorCalls).toEqual([
- 'Request #3',
- 'Request #2',
- 'RequestError #1',
- 'ResponseError #1',
- 'ResponseError #2',
- 'ResponseError #3',
- ]);
- });
-
- it('should not make request', () => {
- expect(fetchMock.called()).toBe(false);
- });
-
- it('should throw error', () => {
- expect(error.message).toEqual('Error in request');
- });
- });
-
- describe('when a response interceptor throws', () => {
- let error: Error;
- let interceptorCalls: string[];
-
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
-
- interceptorCalls = mockInterceptorCalls([
- { response: () => Promise.reject(new Error('Error in response')) },
- {},
- {},
- ]);
-
- try {
- await kfetch({ pathname: '/my/path' });
- } catch (e) {
- error = e;
- }
- });
-
- it('should call in correct order', () => {
- expect(interceptorCalls).toEqual([
- 'Request #3',
- 'Request #2',
- 'Request #1',
- 'Response #1',
- 'ResponseError #2',
- 'ResponseError #3',
- ]);
- });
-
- it('should make request', () => {
- expect(fetchMock.called()).toBe(true);
- });
-
- it('should throw error', () => {
- expect(error.message).toEqual('Error in response');
- });
- });
-
- describe('when request interceptor throws; and a responseError interceptor resolves', () => {
- let resp: any;
- let interceptorCalls: string[];
-
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
-
- interceptorCalls = mockInterceptorCalls([
- {},
- {
- request: () => {
- throw new Error('My request error');
- },
- responseError: () => {
- return { custom: 'response' };
- },
- },
- {},
- ]);
-
- resp = await kfetch({ pathname: '/my/path' });
- });
-
- it('should call in correct order', () => {
- expect(interceptorCalls).toEqual([
- 'Request #3',
- 'Request #2',
- 'RequestError #1',
- 'ResponseError #1',
- 'ResponseError #2',
- 'Response #3',
- ]);
- });
-
- it('should not make request', () => {
- expect(fetchMock.called()).toBe(false);
- });
-
- it('should resolve', () => {
- expect(resp).toEqual({ custom: 'response' });
- });
- });
-
- describe('when interceptors return synchronously', () => {
- let resp: any;
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
- addInterceptor({
- request: (config) => ({
- ...config,
- pathname: '/my/intercepted-route',
- }),
- response: (res) => ({
- ...res,
- addedByResponseInterceptor: true,
- }),
- });
-
- resp = await kfetch({ pathname: '/my/path' });
- });
-
- it('should modify request', () => {
- expect(fetchMock.lastUrl()).toContain('/my/intercepted-route');
- expect(fetchMock.lastOptions()!).toMatchObject({
- method: 'GET',
- });
- });
-
- it('should modify response', () => {
- expect(resp).toEqual({
- addedByResponseInterceptor: true,
- foo: 'bar',
- });
- });
- });
-
- describe('when interceptors return promise', () => {
- let resp: any;
- beforeEach(async () => {
- fetchMock.get('*', { foo: 'bar' });
- addInterceptor({
- request: (config) =>
- Promise.resolve({
- ...config,
- pathname: '/my/intercepted-route',
- }),
- response: (res) =>
- Promise.resolve({
- ...res,
- addedByResponseInterceptor: true,
- }),
- });
-
- resp = await kfetch({ pathname: '/my/path' });
- });
-
- it('should modify request', () => {
- expect(fetchMock.lastUrl()).toContain('/my/intercepted-route');
- expect(fetchMock.lastOptions()!).toMatchObject({
- method: 'GET',
- });
- });
-
- it('should modify response', () => {
- expect(resp).toEqual({
- addedByResponseInterceptor: true,
- foo: 'bar',
- });
- });
- });
-});
-
-function mockInterceptorCalls(interceptors: Interceptor[]) {
- const interceptorCalls: string[] = [];
- interceptors.forEach((interceptor, i) => {
- addInterceptor({
- request: (config) => {
- interceptorCalls.push(`Request #${i + 1}`);
-
- if (interceptor.request) {
- return interceptor.request(config);
- }
-
- return config;
- },
- requestError: (e) => {
- interceptorCalls.push(`RequestError #${i + 1}`);
- if (interceptor.requestError) {
- return interceptor.requestError(e);
- }
-
- throw e;
- },
- response: (res) => {
- interceptorCalls.push(`Response #${i + 1}`);
-
- if (interceptor.response) {
- return interceptor.response(res);
- }
-
- return res;
- },
- responseError: (e) => {
- interceptorCalls.push(`ResponseError #${i + 1}`);
-
- if (interceptor.responseError) {
- return interceptor.responseError(e);
- }
-
- throw e;
- },
- });
- });
-
- return interceptorCalls;
-}
-
-describe('withDefaultOptions', () => {
- it('should remove undefined query params', () => {
- const { query } = withDefaultOptions({
- pathname: '/withDefaultOptions',
- query: {
- foo: 'bar',
- param1: (undefined as any) as string,
- param2: (null as any) as string,
- param3: '',
- },
- });
- expect(query).toEqual({ foo: 'bar', param2: null, param3: '' });
- });
-
- it('should add default options', () => {
- expect(withDefaultOptions({ pathname: '/addDefaultOptions' })).toEqual({
- pathname: '/addDefaultOptions',
- credentials: 'same-origin',
- headers: { 'Content-Type': 'application/json' },
- method: 'GET',
- });
- });
-});
diff --git a/src/legacy/ui/public/kfetch/kfetch.ts b/src/legacy/ui/public/kfetch/kfetch.ts
deleted file mode 100644
index 4eb7149931575..0000000000000
--- a/src/legacy/ui/public/kfetch/kfetch.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { merge } from 'lodash';
-// @ts-ignore not really worth typing
-import { KFetchError } from './kfetch_error';
-
-import { HttpSetup } from '../../../../core/public';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { HttpRequestInit } from '../../../../core/public/http/types';
-
-export interface KFetchQuery {
- [key: string]: string | number | boolean | undefined;
-}
-
-export interface KFetchOptions extends HttpRequestInit {
- pathname: string;
- query?: KFetchQuery;
- asSystemRequest?: boolean;
-}
-
-export interface KFetchKibanaOptions {
- prependBasePath?: boolean;
-}
-
-export interface Interceptor {
- request?: (config: KFetchOptions) => Promise | KFetchOptions;
- requestError?: (e: any) => Promise | KFetchOptions;
- response?: (res: any) => any;
- responseError?: (e: any) => any;
-}
-
-const interceptors: Interceptor[] = [];
-export const resetInterceptors = () => (interceptors.length = 0);
-export const addInterceptor = (interceptor: Interceptor) => interceptors.push(interceptor);
-
-export function createKfetch(http: HttpSetup) {
- return function kfetch(
- options: KFetchOptions,
- { prependBasePath = true }: KFetchKibanaOptions = {}
- ) {
- return responseInterceptors(
- requestInterceptors(withDefaultOptions(options))
- .then(({ pathname, ...restOptions }) =>
- http.fetch(pathname, { ...restOptions, prependBasePath })
- )
- .catch((err) => {
- throw new KFetchError(err.response || { statusText: err.message }, err.body);
- })
- );
- };
-}
-
-// Request/response interceptors are called in opposite orders.
-// Request hooks start from the newest interceptor and end with the oldest.
-function requestInterceptors(config: KFetchOptions): Promise {
- return interceptors.reduceRight((acc, interceptor) => {
- return acc.then(interceptor.request, interceptor.requestError);
- }, Promise.resolve(config));
-}
-
-// Response hooks start from the oldest interceptor and end with the newest.
-function responseInterceptors(responsePromise: Promise) {
- return interceptors.reduce((acc, interceptor) => {
- return acc.then(interceptor.response, interceptor.responseError);
- }, responsePromise);
-}
-
-export function withDefaultOptions(options?: KFetchOptions): KFetchOptions {
- const withDefaults = merge(
- {
- method: 'GET',
- credentials: 'same-origin',
- headers: {
- 'Content-Type': 'application/json',
- },
- },
- options
- ) as KFetchOptions;
-
- if (
- options &&
- options.headers &&
- 'Content-Type' in options.headers &&
- options.headers['Content-Type'] === undefined
- ) {
- // TS thinks headers could be undefined here, but that isn't possible because
- // of the merge above.
- // @ts-ignore
- withDefaults.headers['Content-Type'] = undefined;
- }
-
- return withDefaults;
-}
diff --git a/src/legacy/ui/public/kfetch/kfetch_error.ts b/src/legacy/ui/public/kfetch/kfetch_error.ts
deleted file mode 100644
index f351959e624b8..0000000000000
--- a/src/legacy/ui/public/kfetch/kfetch_error.ts
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export class KFetchError extends Error {
- constructor(public readonly res: Response, public readonly body?: any) {
- super(res.statusText);
-
- // captureStackTrace is only available in the V8 engine, so any browser using
- // a different JS engine won't have access to this method.
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, KFetchError);
- }
- }
-}
diff --git a/src/legacy/ui/public/legacy_compat/__tests__/xsrf.js b/src/legacy/ui/public/legacy_compat/__tests__/xsrf.js
deleted file mode 100644
index efcfb77997265..0000000000000
--- a/src/legacy/ui/public/legacy_compat/__tests__/xsrf.js
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import $ from 'jquery';
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-import ngMock from 'ng_mock';
-
-import { $setupXsrfRequestInterceptor } from '../../../../../plugins/kibana_legacy/public';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { version } from '../../../../../core/server/utils/package_json';
-
-const xsrfHeader = 'kbn-version';
-
-describe('chrome xsrf apis', function () {
- const sandbox = sinon.createSandbox();
-
- afterEach(function () {
- sandbox.restore();
- });
-
- describe('jQuery support', function () {
- it('adds a global jQuery prefilter', function () {
- sandbox.stub($, 'ajaxPrefilter');
- $setupXsrfRequestInterceptor(version);
- expect($.ajaxPrefilter.callCount).to.be(1);
- });
-
- describe('jQuery prefilter', function () {
- let prefilter;
-
- beforeEach(function () {
- sandbox.stub($, 'ajaxPrefilter');
- $setupXsrfRequestInterceptor(version);
- prefilter = $.ajaxPrefilter.args[0][0];
- });
-
- it(`sets the ${xsrfHeader} header`, function () {
- const setHeader = sinon.stub();
- prefilter({}, {}, { setRequestHeader: setHeader });
-
- expect(setHeader.callCount).to.be(1);
- expect(setHeader.args[0]).to.eql([xsrfHeader, version]);
- });
-
- it('can be canceled by setting the kbnXsrfToken option', function () {
- const setHeader = sinon.stub();
- prefilter({ kbnXsrfToken: false }, {}, { setRequestHeader: setHeader });
- expect(setHeader.callCount).to.be(0);
- });
- });
-
- describe('Angular support', function () {
- let $http;
- let $httpBackend;
-
- beforeEach(function () {
- sandbox.stub($, 'ajaxPrefilter');
- ngMock.module($setupXsrfRequestInterceptor(version));
- });
-
- beforeEach(
- ngMock.inject(function ($injector) {
- $http = $injector.get('$http');
- $httpBackend = $injector.get('$httpBackend');
-
- $httpBackend.when('POST', '/api/test').respond('ok');
- })
- );
-
- afterEach(function () {
- $httpBackend.verifyNoOutstandingExpectation();
- $httpBackend.verifyNoOutstandingRequest();
- });
-
- it(`injects a ${xsrfHeader} header on every request`, function () {
- $httpBackend
- .expectPOST('/api/test', undefined, function (headers) {
- return headers[xsrfHeader] === version;
- })
- .respond(200, '');
-
- $http.post('/api/test');
- $httpBackend.flush();
- });
-
- it('skips requests with the kbnXsrfToken set falsy', function () {
- $httpBackend
- .expectPOST('/api/test', undefined, function (headers) {
- return !(xsrfHeader in headers);
- })
- .respond(200, '');
-
- $http({
- method: 'POST',
- url: '/api/test',
- kbnXsrfToken: 0,
- });
-
- $http({
- method: 'POST',
- url: '/api/test',
- kbnXsrfToken: '',
- });
-
- $http({
- method: 'POST',
- url: '/api/test',
- kbnXsrfToken: false,
- });
-
- $httpBackend.flush();
- });
-
- it('treats the kbnXsrfToken option as boolean-y', function () {
- const customToken = `custom:${version}`;
- $httpBackend
- .expectPOST('/api/test', undefined, function (headers) {
- return headers[xsrfHeader] === version;
- })
- .respond(200, '');
-
- $http({
- method: 'POST',
- url: '/api/test',
- kbnXsrfToken: customToken,
- });
-
- $httpBackend.flush();
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/legacy_compat/index.ts b/src/legacy/ui/public/legacy_compat/index.ts
deleted file mode 100644
index 2067fa6489304..0000000000000
--- a/src/legacy/ui/public/legacy_compat/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { configureAppAngularModule } from '../../../../plugins/kibana_legacy/public';
diff --git a/src/legacy/ui/public/metadata.ts b/src/legacy/ui/public/metadata.ts
deleted file mode 100644
index fade0f0d8629a..0000000000000
--- a/src/legacy/ui/public/metadata.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-
-export const metadata: {
- branch: string;
- version: string;
-} = npSetup.core.injectedMetadata.getLegacyMetadata();
diff --git a/src/legacy/ui/public/modules.js b/src/legacy/ui/public/modules.js
deleted file mode 100644
index bb1c8aead1c34..0000000000000
--- a/src/legacy/ui/public/modules.js
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import _ from 'lodash';
-/**
- * This module is used by Kibana to create and reuse angular modules. Angular modules
- * can only be created once and need to have their dependencies at creation. This is
- * hard/impossible to do in require.js since all of the dependencies for a module are
- * loaded before it is.
- *
- * Here is an example:
- *
- * In the scenario below, require.js would load directive.js first because it is a
- * dependency of app.js. This would cause the call to `angular.module('app')` to
- * execute before the module is actually created. This causes angular to throw an
- * error. This effect is magnified when app.js links off to many different modules.
- *
- * This is normally solved by creating unique modules per file, listed as the 1st
- * alternate solution below. Unfortunately this solution would have required that
- * we replicate our require statements.
- *
- * app.js
- * ```
- * angular.module('app', ['ui.bootstrap'])
- * .controller('AppController', function () { ... });
- *
- * require('./directive');
- * ```
- *
- * directive.js
- * ```
- * angular.module('app')
- * .directive('someDirective', function () { ... });
- * ```
- *
- * Before taking this approach we saw three possible solutions:
- * 1. replicate our js modules in angular modules/use a different module per file
- * 2. create a single module outside of our js modules and share it
- * 3. use a helper lib to dynamically create modules as needed.
- *
- * We decided to go with #3
- *
- * This ends up working by creating a list of modules that the code base creates by
- * calling `modules.get(name)` with different names, and then before bootstrapping
- * the application kibana uses `modules.link()` to set the dependencies of the "kibana"
- * module to include every defined module. This guarantees that kibana can always find
- * any angular dependency defined in the kibana code base. This **also** means that
- * Private modules are able to find any dependency, since they are injected using the
- * "kibana" module's injector.
- *
- */
-const existingModules = {};
-const links = [];
-
-/**
- * Take an angular module and extends the dependencies for that module to include all of the modules
- * created using `ui/modules`
- *
- * @param {AngularModule} module - the module to extend
- * @return {undefined}
- */
-export function link(module) {
- // as modules are defined they will be set as requirements for this app
- links.push(module);
-
- // merge in the existing modules
- module.requires = _.union(module.requires, _.keys(existingModules));
-}
-
-/**
- * The primary means of interacting with `ui/modules`. Returns an angular module. If the module already
- * exists the existing version will be returned. `dependencies` are either set as or merged into the
- * modules total dependencies.
- *
- * This is in contrast to the `angular.module(name, [dependencies])` function which will only
- * create a module if the `dependencies` list is passed and get an existing module if no dependencies
- * are passed. This requires knowing the order that your files will load, which we can't guarantee.
- *
- * @param {string} moduleName - the unique name for this module
- * @param {array[string]} [requires=[]] - the other modules this module requires
- * @return {AngularModule}
- */
-export function get(moduleName, requires) {
- let module = existingModules[moduleName];
-
- if (module === void 0) {
- // create the module
- module = existingModules[moduleName] = angular.module(moduleName, []);
-
- module.close = _.partial(close, moduleName);
-
- // ensure that it is required by linked modules
- _.each(links, function (app) {
- if (!~app.requires.indexOf(moduleName)) app.requires.push(moduleName);
- });
- }
-
- if (requires) {
- // update requires list with possibly new requirements
- module.requires = _.union(module.requires, requires);
- }
-
- return module;
-}
-
-export function close(moduleName) {
- const module = existingModules[moduleName];
-
- // already closed
- if (!module) return;
-
- // if the module is currently linked, unlink it
- const i = links.indexOf(module);
- if (i > -1) links.splice(i, 1);
-
- // remove from linked modules list of required modules
- _.each(links, function (app) {
- _.pull(app.requires, moduleName);
- });
-
- // remove module from existingModules
- delete existingModules[moduleName];
-}
-
-export const uiModules = { link, get, close };
diff --git a/src/legacy/ui/public/new_platform/__mocks__/helpers.ts b/src/legacy/ui/public/new_platform/__mocks__/helpers.ts
deleted file mode 100644
index 35aa8e4830428..0000000000000
--- a/src/legacy/ui/public/new_platform/__mocks__/helpers.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { coreMock } from '../../../../../core/public/mocks';
-import { dataPluginMock } from '../../../../../plugins/data/public/mocks';
-import { embeddablePluginMock } from '../../../../../plugins/embeddable/public/mocks';
-import { navigationPluginMock } from '../../../../../plugins/navigation/public/mocks';
-import { expressionsPluginMock } from '../../../../../plugins/expressions/public/mocks';
-import { inspectorPluginMock } from '../../../../../plugins/inspector/public/mocks';
-import { uiActionsPluginMock } from '../../../../../plugins/ui_actions/public/mocks';
-import { managementPluginMock } from '../../../../../plugins/management/public/mocks';
-import { usageCollectionPluginMock } from '../../../../../plugins/usage_collection/public/mocks';
-import { kibanaLegacyPluginMock } from '../../../../../plugins/kibana_legacy/public/mocks';
-import { chartPluginMock } from '../../../../../plugins/charts/public/mocks';
-import { advancedSettingsMock } from '../../../../../plugins/advanced_settings/public/mocks';
-import { savedObjectsManagementPluginMock } from '../../../../../plugins/saved_objects_management/public/mocks';
-import { visualizationsPluginMock } from '../../../../../plugins/visualizations/public/mocks';
-import { discoverPluginMock } from '../../../../../plugins/discover/public/mocks';
-
-export const pluginsMock = {
- createSetup: () => ({
- data: dataPluginMock.createSetupContract(),
- charts: chartPluginMock.createSetupContract(),
- navigation: navigationPluginMock.createSetupContract(),
- embeddable: embeddablePluginMock.createSetupContract(),
- inspector: inspectorPluginMock.createSetupContract(),
- expressions: expressionsPluginMock.createSetupContract(),
- uiActions: uiActionsPluginMock.createSetupContract(),
- usageCollection: usageCollectionPluginMock.createSetupContract(),
- advancedSettings: advancedSettingsMock.createSetupContract(),
- visualizations: visualizationsPluginMock.createSetupContract(),
- kibanaLegacy: kibanaLegacyPluginMock.createSetupContract(),
- savedObjectsManagement: savedObjectsManagementPluginMock.createSetupContract(),
- discover: discoverPluginMock.createSetupContract(),
- }),
- createStart: () => ({
- data: dataPluginMock.createStartContract(),
- charts: chartPluginMock.createStartContract(),
- navigation: navigationPluginMock.createStartContract(),
- embeddable: embeddablePluginMock.createStartContract(),
- inspector: inspectorPluginMock.createStartContract(),
- expressions: expressionsPluginMock.createStartContract(),
- uiActions: uiActionsPluginMock.createStartContract(),
- management: managementPluginMock.createStartContract(),
- advancedSettings: advancedSettingsMock.createStartContract(),
- visualizations: visualizationsPluginMock.createStartContract(),
- kibanaLegacy: kibanaLegacyPluginMock.createStartContract(),
- savedObjectsManagement: savedObjectsManagementPluginMock.createStartContract(),
- discover: discoverPluginMock.createStartContract(),
- }),
-};
-
-export const createUiNewPlatformMock = () => {
- const mock = {
- npSetup: {
- core: coreMock.createSetup(),
- plugins: pluginsMock.createSetup(),
- },
- npStart: {
- core: coreMock.createStart(),
- plugins: pluginsMock.createStart(),
- },
- };
- return mock;
-};
diff --git a/src/legacy/ui/public/new_platform/__mocks__/index.ts b/src/legacy/ui/public/new_platform/__mocks__/index.ts
deleted file mode 100644
index d469960ddd7b7..0000000000000
--- a/src/legacy/ui/public/new_platform/__mocks__/index.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { createUiNewPlatformMock } from './helpers';
-
-const { npSetup, npStart } = createUiNewPlatformMock();
-export { npSetup, npStart };
diff --git a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js b/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
deleted file mode 100644
index b8d48b784dba7..0000000000000
--- a/src/legacy/ui/public/new_platform/new_platform.karma_mock.js
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import { getFieldFormatsRegistry } from '../../../../test_utils/public/stub_field_formats';
-import { METRIC_TYPE } from '@kbn/analytics';
-import { setSetupServices, setStartServices } from './set_services';
-import {
- AggTypesRegistry,
- getAggTypes,
- AggConfigs,
- // eslint-disable-next-line @kbn/eslint/no-restricted-paths
-} from '../../../../../src/plugins/data/common/search/aggs';
-import { ComponentRegistry } from '../../../../../src/plugins/advanced_settings/public/';
-import { UI_SETTINGS } from '../../../../../src/plugins/data/public/';
-import {
- CSV_SEPARATOR_SETTING,
- CSV_QUOTE_VALUES_SETTING,
-} from '../../../../../src/plugins/share/public';
-
-const mockObservable = () => {
- return {
- subscribe: () => {},
- pipe: () => {
- return {
- subscribe: () => {},
- };
- },
- };
-};
-
-const mockComponent = () => {
- return null;
-};
-
-let refreshInterval = undefined;
-let isTimeRangeSelectorEnabled = true;
-let isAutoRefreshSelectorEnabled = true;
-
-export const mockUiSettings = {
- get: (item, defaultValue) => {
- const defaultValues = {
- dateFormat: 'MMM D, YYYY @ HH:mm:ss.SSS',
- 'dateFormat:tz': 'UTC',
- [UI_SETTINGS.SHORT_DOTS_ENABLE]: true,
- [UI_SETTINGS.COURIER_IGNORE_FILTER_IF_FIELD_NOT_IN_INDEX]: true,
- [UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS]: true,
- [UI_SETTINGS.QUERY_STRING_OPTIONS]: {},
- [UI_SETTINGS.FORMAT_CURRENCY_DEFAULT_PATTERN]: '($0,0.[00])',
- [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_PATTERN]: '0,0.[000]',
- [UI_SETTINGS.FORMAT_PERCENT_DEFAULT_PATTERN]: '0,0.[000]%',
- [UI_SETTINGS.FORMAT_NUMBER_DEFAULT_LOCALE]: 'en',
- [UI_SETTINGS.FORMAT_DEFAULT_TYPE_MAP]: {},
- [CSV_SEPARATOR_SETTING]: ',',
- [CSV_QUOTE_VALUES_SETTING]: true,
- [UI_SETTINGS.SEARCH_QUERY_LANGUAGE]: 'kuery',
- 'state:storeInSessionStorage': false,
- };
-
- return defaultValues[item] || defaultValue;
- },
- getUpdate$: () => ({
- subscribe: sinon.fake(),
- }),
- isDefault: sinon.fake(),
-};
-
-const mockCoreSetup = {
- chrome: {},
- http: {
- basePath: {
- get: sinon.fake.returns(''),
- },
- },
- injectedMetadata: {},
- uiSettings: mockUiSettings,
-};
-
-const mockCoreStart = {
- application: {
- capabilities: {},
- },
- chrome: {
- overlays: {
- openModal: sinon.fake(),
- },
- },
- http: {
- basePath: {
- get: sinon.fake.returns(''),
- },
- },
- notifications: {
- toasts: {},
- },
- i18n: {},
- overlays: {},
- savedObjects: {
- client: {},
- },
- uiSettings: mockUiSettings,
-};
-
-const querySetup = {
- state$: mockObservable(),
- filterManager: {
- getFetches$: sinon.fake(),
- getFilters: sinon.fake(),
- getAppFilters: sinon.fake(),
- getGlobalFilters: sinon.fake(),
- removeFilter: sinon.fake(),
- addFilters: sinon.fake(),
- setFilters: sinon.fake(),
- removeAll: sinon.fake(),
- getUpdates$: mockObservable,
- },
- timefilter: {
- timefilter: {
- getFetch$: mockObservable,
- getAutoRefreshFetch$: mockObservable,
- getEnabledUpdated$: mockObservable,
- getTimeUpdate$: mockObservable,
- getRefreshIntervalUpdate$: mockObservable,
- isTimeRangeSelectorEnabled: () => {
- return isTimeRangeSelectorEnabled;
- },
- isAutoRefreshSelectorEnabled: () => {
- return isAutoRefreshSelectorEnabled;
- },
- disableAutoRefreshSelector: () => {
- isAutoRefreshSelectorEnabled = false;
- },
- enableAutoRefreshSelector: () => {
- isAutoRefreshSelectorEnabled = true;
- },
- getRefreshInterval: () => {
- return refreshInterval;
- },
- setRefreshInterval: (interval) => {
- refreshInterval = interval;
- },
- enableTimeRangeSelector: () => {
- isTimeRangeSelectorEnabled = true;
- },
- disableTimeRangeSelector: () => {
- isTimeRangeSelectorEnabled = false;
- },
- getTime: sinon.fake(),
- setTime: sinon.fake(),
- getActiveBounds: sinon.fake(),
- getBounds: sinon.fake(),
- calculateBounds: sinon.fake(),
- createFilter: sinon.fake(),
- },
- history: sinon.fake(),
- },
- savedQueries: {
- saveQuery: sinon.fake(),
- getAllSavedQueries: sinon.fake(),
- findSavedQueries: sinon.fake(),
- getSavedQuery: sinon.fake(),
- deleteSavedQuery: sinon.fake(),
- getSavedQueryCount: sinon.fake(),
- },
-};
-
-const mockAggTypesRegistry = () => {
- const registry = new AggTypesRegistry();
- const registrySetup = registry.setup();
- const aggTypes = getAggTypes({
- calculateBounds: sinon.fake(),
- getConfig: sinon.fake(),
- getFieldFormatsStart: () => ({
- deserialize: sinon.fake(),
- getDefaultInstance: sinon.fake(),
- }),
- isDefaultTimezone: () => true,
- });
- aggTypes.buckets.forEach((type) => registrySetup.registerBucket(type));
- aggTypes.metrics.forEach((type) => registrySetup.registerMetric(type));
-
- return registry;
-};
-
-const aggTypesRegistry = mockAggTypesRegistry();
-
-export const npSetup = {
- core: mockCoreSetup,
- plugins: {
- advancedSettings: {
- component: {
- register: sinon.fake(),
- componentType: ComponentRegistry.componentType,
- },
- },
- usageCollection: {
- allowTrackUserAgent: sinon.fake(),
- reportUiStats: sinon.fake(),
- METRIC_TYPE,
- },
- embeddable: {
- registerEmbeddableFactory: sinon.fake(),
- },
- expressions: {
- registerFunction: sinon.fake(),
- registerRenderer: sinon.fake(),
- registerType: sinon.fake(),
- },
- data: {
- autocomplete: {
- addProvider: sinon.fake(),
- getProvider: sinon.fake(),
- },
- query: querySetup,
- search: {
- aggs: {
- types: aggTypesRegistry.setup(),
- },
- __LEGACY: {
- esClient: {
- search: sinon.fake(),
- msearch: sinon.fake(),
- },
- },
- },
- fieldFormats: getFieldFormatsRegistry(mockCoreSetup),
- },
- share: {
- register: () => {},
- urlGenerators: {
- registerUrlGenerator: () => {},
- },
- },
- devTools: {
- register: () => {},
- },
- kibanaLegacy: {
- registerLegacyApp: () => {},
- forwardApp: () => {},
- config: {
- defaultAppId: 'home',
- },
- },
- inspector: {
- registerView: () => undefined,
- __LEGACY: {
- views: {
- register: () => undefined,
- },
- },
- },
- uiActions: {
- attachAction: sinon.fake(),
- registerAction: sinon.fake(),
- registerTrigger: sinon.fake(),
- },
- home: {
- featureCatalogue: {
- register: sinon.fake(),
- },
- environment: {
- update: sinon.fake(),
- },
- config: {
- disableWelcomeScreen: false,
- },
- tutorials: {
- setVariable: sinon.fake(),
- },
- },
- charts: {
- theme: {
- chartsTheme$: mockObservable,
- useChartsTheme: sinon.fake(),
- },
- colors: {
- seedColors: ['white', 'black'],
- },
- },
- management: {
- sections: {
- getSection: () => ({
- registerApp: sinon.fake(),
- }),
- },
- },
- indexPatternManagement: {
- list: { addListConfig: sinon.fake() },
- creation: { addCreationConfig: sinon.fake() },
- },
- discover: {
- docViews: {
- addDocView: sinon.fake(),
- setAngularInjectorGetter: sinon.fake(),
- },
- },
- visTypeVega: {
- config: sinon.fake(),
- },
- visualizations: {
- createBaseVisualization: sinon.fake(),
- createReactVisualization: sinon.fake(),
- registerAlias: sinon.fake(),
- hideTypes: sinon.fake(),
- },
-
- mapsLegacy: {
- serviceSettings: sinon.fake(),
- getPrecision: sinon.fake(),
- getZoomPrecision: sinon.fake(),
- },
- },
-};
-
-export const npStart = {
- core: mockCoreStart,
- plugins: {
- management: {
- legacy: {
- getSection: () => ({
- register: sinon.fake(),
- deregister: sinon.fake(),
- hasItem: sinon.fake(),
- }),
- },
- sections: {
- getSection: () => ({
- registerApp: sinon.fake(),
- }),
- },
- },
- indexPatternManagement: {
- list: {
- getType: sinon.fake(),
- getIndexPatternCreationOptions: sinon.fake(),
- },
- creation: {
- getIndexPatternTags: sinon.fake(),
- getFieldInfo: sinon.fake(),
- areScriptedFieldsEnabled: sinon.fake(),
- },
- },
- embeddable: {
- getEmbeddableFactory: sinon.fake(),
- getEmbeddableFactories: sinon.fake(),
- registerEmbeddableFactory: sinon.fake(),
- },
- expressions: {
- registerFunction: sinon.fake(),
- registerRenderer: sinon.fake(),
- registerType: sinon.fake(),
- },
- kibanaLegacy: {
- getForwards: () => [],
- loadFontAwesome: () => {},
- config: {
- defaultAppId: 'home',
- },
- dashboardConfig: {
- turnHideWriteControlsOn: sinon.fake(),
- getHideWriteControls: sinon.fake(),
- },
- },
- dashboard: {
- getSavedDashboardLoader: sinon.fake(),
- },
- data: {
- actions: {
- createFiltersFromValueClickAction: Promise.resolve(['yes']),
- createFiltersFromRangeSelectAction: sinon.fake(),
- },
- autocomplete: {
- getProvider: sinon.fake(),
- },
- getSuggestions: sinon.fake(),
- indexPatterns: {
- get: sinon.spy((indexPatternId) =>
- Promise.resolve({
- id: indexPatternId,
- isTimeNanosBased: () => false,
- popularizeField: () => {},
- })
- ),
- },
- ui: {
- IndexPatternSelect: mockComponent,
- SearchBar: mockComponent,
- },
- query: {
- filterManager: {
- getFetches$: sinon.fake(),
- getFilters: sinon.fake(),
- getAppFilters: sinon.fake(),
- getGlobalFilters: sinon.fake(),
- removeFilter: sinon.fake(),
- addFilters: sinon.fake(),
- setFilters: sinon.fake(),
- removeAll: sinon.fake(),
- getUpdates$: mockObservable,
- },
- timefilter: {
- timefilter: {
- getFetch$: mockObservable,
- getAutoRefreshFetch$: mockObservable,
- getEnabledUpdated$: mockObservable,
- getTimeUpdate$: mockObservable,
- getRefreshIntervalUpdate$: mockObservable,
- isTimeRangeSelectorEnabled: () => {
- return isTimeRangeSelectorEnabled;
- },
- isAutoRefreshSelectorEnabled: () => {
- return isAutoRefreshSelectorEnabled;
- },
- disableAutoRefreshSelector: () => {
- isAutoRefreshSelectorEnabled = false;
- },
- enableAutoRefreshSelector: () => {
- isAutoRefreshSelectorEnabled = true;
- },
- getRefreshInterval: () => {
- return refreshInterval;
- },
- setRefreshInterval: (interval) => {
- refreshInterval = interval;
- },
- enableTimeRangeSelector: () => {
- isTimeRangeSelectorEnabled = true;
- },
- disableTimeRangeSelector: () => {
- isTimeRangeSelectorEnabled = false;
- },
- getTime: sinon.fake(),
- setTime: sinon.fake(),
- getActiveBounds: sinon.fake(),
- getBounds: sinon.fake(),
- calculateBounds: sinon.fake(),
- createFilter: sinon.fake(),
- },
- history: sinon.fake(),
- },
- },
- search: {
- aggs: {
- calculateAutoTimeExpression: sinon.fake(),
- createAggConfigs: (indexPattern, configStates = []) => {
- return new AggConfigs(indexPattern, configStates, {
- typesRegistry: aggTypesRegistry.start(),
- fieldFormats: getFieldFormatsRegistry(mockCoreStart),
- });
- },
- types: aggTypesRegistry.start(),
- },
- __LEGACY: {
- esClient: {
- search: sinon.fake(),
- msearch: sinon.fake(),
- },
- },
- },
- fieldFormats: getFieldFormatsRegistry(mockCoreStart),
- },
- share: {
- toggleShareContextMenu: () => {},
- },
- inspector: {
- isAvailable: () => false,
- open: () => ({
- onClose: Promise.resolve(undefined),
- close: () => Promise.resolve(undefined),
- }),
- },
- uiActions: {
- attachAction: sinon.fake(),
- registerAction: sinon.fake(),
- registerTrigger: sinon.fake(),
- detachAction: sinon.fake(),
- executeTriggerActions: sinon.fake(),
- getTrigger: sinon.fake(),
- getTriggerActions: sinon.fake(),
- getTriggerCompatibleActions: sinon.fake(),
- },
- visualizations: {
- get: sinon.fake(),
- all: sinon.fake(),
- getAliases: sinon.fake(),
- savedVisualizationsLoader: {},
- showNewVisModal: sinon.fake(),
- createVis: sinon.fake(),
- convertFromSerializedVis: sinon.fake(),
- convertToSerializedVis: sinon.fake(),
- },
- navigation: {
- ui: {
- TopNavMenu: mockComponent,
- },
- },
- charts: {
- theme: {
- chartsTheme$: mockObservable,
- useChartsTheme: sinon.fake(),
- },
- },
- discover: {
- docViews: {
- DocViewer: () => null,
- },
- savedSearchLoader: {},
- },
- },
-};
-
-export function __setup__(coreSetup) {
- npSetup.core = coreSetup;
-
- // no-op application register calls (this is overwritten to
- // bootstrap an LP plugin outside of tests)
- npSetup.core.application.register = () => {};
-
- npSetup.core.uiSettings.get = mockUiSettings.get;
-
- // Services that need to be set in the legacy platform since the legacy data
- // & vis plugins which previously provided them have been removed.
- setSetupServices(npSetup);
-}
-
-export function __start__(coreStart) {
- npStart.core = coreStart;
-
- npStart.core.uiSettings.get = mockUiSettings.get;
-
- // Services that need to be set in the legacy platform since the legacy data
- // & vis plugins which previously provided them have been removed.
- setStartServices(npStart);
-}
diff --git a/src/legacy/ui/public/new_platform/new_platform.test.mocks.ts b/src/legacy/ui/public/new_platform/new_platform.test.mocks.ts
deleted file mode 100644
index f44efe17ef8ee..0000000000000
--- a/src/legacy/ui/public/new_platform/new_platform.test.mocks.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { scopedHistoryMock } from '../../../../core/public/mocks';
-
-export const setRootControllerMock = jest.fn();
-
-jest.doMock('ui/chrome', () => ({
- setRootController: setRootControllerMock,
-}));
-
-export const historyMock = scopedHistoryMock.create();
-jest.doMock('../../../../core/public', () => ({
- ScopedHistory: jest.fn(() => historyMock),
-}));
diff --git a/src/legacy/ui/public/new_platform/new_platform.test.ts b/src/legacy/ui/public/new_platform/new_platform.test.ts
deleted file mode 100644
index d515c348ca440..0000000000000
--- a/src/legacy/ui/public/new_platform/new_platform.test.ts
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-jest.mock('history');
-
-import { setRootControllerMock, historyMock } from './new_platform.test.mocks';
-import { legacyAppRegister, __reset__, __setup__, __start__ } from './new_platform';
-import { coreMock } from '../../../../core/public/mocks';
-import { AppMount } from '../../../../core/public';
-
-describe('ui/new_platform', () => {
- describe('legacyAppRegister', () => {
- beforeEach(() => {
- setRootControllerMock.mockReset();
- __reset__();
- __setup__(coreMock.createSetup({ basePath: '/test/base/path' }) as any, {} as any);
- });
-
- const registerApp = () => {
- const unmountMock = jest.fn();
- const mountMock = jest.fn, Parameters>(() => unmountMock);
- legacyAppRegister({
- id: 'test',
- title: 'Test',
- mount: mountMock,
- });
- return { mountMock, unmountMock };
- };
-
- test('sets ui/chrome root controller', () => {
- registerApp();
- expect(setRootControllerMock).toHaveBeenCalledWith('test', expect.any(Function));
- });
-
- test('throws if called more than once', () => {
- registerApp();
- expect(registerApp).toThrowErrorMatchingInlineSnapshot(
- `"core.application.register may only be called once for legacy plugins."`
- );
- });
-
- test('controller calls app.mount when invoked', () => {
- const { mountMock } = registerApp();
- const controller = setRootControllerMock.mock.calls[0][1];
- const scopeMock = { $on: jest.fn() };
- const elementMock = [document.createElement('div')];
-
- controller(scopeMock, elementMock);
- expect(mountMock).toHaveBeenCalledWith({
- element: expect.any(HTMLElement),
- appBasePath: '/test/base/path/app/test',
- onAppLeave: expect.any(Function),
- history: historyMock,
- });
- });
-
- test('app is mounted in new div inside containing element', () => {
- const { mountMock } = registerApp();
- const controller = setRootControllerMock.mock.calls[0][1];
- const scopeMock = { $on: jest.fn() };
- const elementMock = [document.createElement('div')];
-
- controller(scopeMock, elementMock);
-
- const { element } = mountMock.mock.calls[0][0];
- expect(element.parentElement).toEqual(elementMock[0]);
- });
-
- test('controller calls deprecated context app.mount when invoked', () => {
- const unmountMock = jest.fn();
- // Two arguments changes how this is called.
- const mountMock = jest.fn((context, params) => unmountMock);
- legacyAppRegister({
- id: 'test',
- title: 'Test',
- mount: mountMock,
- });
- const controller = setRootControllerMock.mock.calls[0][1];
- const scopeMock = { $on: jest.fn() };
- const elementMock = [document.createElement('div')];
-
- controller(scopeMock, elementMock);
- expect(mountMock).toHaveBeenCalledWith(expect.any(Object), {
- element: expect.any(HTMLElement),
- appBasePath: '/test/base/path/app/test',
- onAppLeave: expect.any(Function),
- history: historyMock,
- });
- });
-
- test('controller calls unmount when $scope.$destroy', async () => {
- const { unmountMock } = registerApp();
- const controller = setRootControllerMock.mock.calls[0][1];
- const scopeMock = { $on: jest.fn() };
- const elementMock = [document.createElement('div')];
-
- controller(scopeMock, elementMock);
- // Flush promise queue. Must be done this way because the controller cannot return a Promise without breaking
- // angular.
- await new Promise((resolve) => setTimeout(resolve, 1));
-
- const [event, eventHandler] = scopeMock.$on.mock.calls[0];
- expect(event).toEqual('$destroy');
- eventHandler();
- expect(unmountMock).toHaveBeenCalled();
- });
- });
-});
diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts
deleted file mode 100644
index 37787ffbde4fc..0000000000000
--- a/src/legacy/ui/public/new_platform/new_platform.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { IScope } from 'angular';
-
-import { UiActionsStart, UiActionsSetup } from 'src/plugins/ui_actions/public';
-import { EmbeddableStart, EmbeddableSetup } from 'src/plugins/embeddable/public';
-import { createBrowserHistory } from 'history';
-import { VisTypeXyPluginSetup } from 'src/plugins/vis_type_xy/public';
-import { DashboardStart } from '../../../../plugins/dashboard/public';
-import { setSetupServices, setStartServices } from './set_services';
-import {
- LegacyCoreSetup,
- LegacyCoreStart,
- App,
- AppMountDeprecated,
- ScopedHistory,
-} from '../../../../core/public';
-import { Plugin as DataPlugin } from '../../../../plugins/data/public';
-import { Plugin as ExpressionsPlugin } from '../../../../plugins/expressions/public';
-import {
- Setup as InspectorSetup,
- Start as InspectorStart,
-} from '../../../../plugins/inspector/public';
-import { ChartsPluginSetup, ChartsPluginStart } from '../../../../plugins/charts/public';
-import { DevToolsSetup } from '../../../../plugins/dev_tools/public';
-import { KibanaLegacySetup, KibanaLegacyStart } from '../../../../plugins/kibana_legacy/public';
-import { HomePublicPluginSetup } from '../../../../plugins/home/public';
-import { SharePluginSetup, SharePluginStart } from '../../../../plugins/share/public';
-import {
- AdvancedSettingsSetup,
- AdvancedSettingsStart,
-} from '../../../../plugins/advanced_settings/public';
-import { ManagementSetup, ManagementStart } from '../../../../plugins/management/public';
-import {
- IndexPatternManagementSetup,
- IndexPatternManagementStart,
-} from '../../../../plugins/index_pattern_management/public';
-import { BfetchPublicSetup, BfetchPublicStart } from '../../../../plugins/bfetch/public';
-import { UsageCollectionSetup } from '../../../../plugins/usage_collection/public';
-import { TelemetryPluginSetup, TelemetryPluginStart } from '../../../../plugins/telemetry/public';
-import {
- NavigationPublicPluginSetup,
- NavigationPublicPluginStart,
-} from '../../../../plugins/navigation/public';
-import { DiscoverSetup, DiscoverStart } from '../../../../plugins/discover/public';
-import {
- SavedObjectsManagementPluginSetup,
- SavedObjectsManagementPluginStart,
-} from '../../../../plugins/saved_objects_management/public';
-import {
- VisualizationsSetup,
- VisualizationsStart,
-} from '../../../../plugins/visualizations/public';
-import { VisTypeTimelionPluginStart } from '../../../../plugins/vis_type_timelion/public';
-import { MapsLegacyPluginSetup } from '../../../../plugins/maps_legacy/public';
-
-export interface PluginsSetup {
- bfetch: BfetchPublicSetup;
- charts: ChartsPluginSetup;
- data: ReturnType;
- embeddable: EmbeddableSetup;
- expressions: ReturnType;
- home: HomePublicPluginSetup;
- inspector: InspectorSetup;
- uiActions: UiActionsSetup;
- navigation: NavigationPublicPluginSetup;
- devTools: DevToolsSetup;
- kibanaLegacy: KibanaLegacySetup;
- share: SharePluginSetup;
- usageCollection: UsageCollectionSetup;
- advancedSettings: AdvancedSettingsSetup;
- management: ManagementSetup;
- discover: DiscoverSetup;
- visualizations: VisualizationsSetup;
- telemetry?: TelemetryPluginSetup;
- savedObjectsManagement: SavedObjectsManagementPluginSetup;
- mapsLegacy: MapsLegacyPluginSetup;
- indexPatternManagement: IndexPatternManagementSetup;
- visTypeXy?: VisTypeXyPluginSetup;
-}
-
-export interface PluginsStart {
- bfetch: BfetchPublicStart;
- charts: ChartsPluginStart;
- data: ReturnType;
- embeddable: EmbeddableStart;
- expressions: ReturnType;
- inspector: InspectorStart;
- uiActions: UiActionsStart;
- navigation: NavigationPublicPluginStart;
- kibanaLegacy: KibanaLegacyStart;
- share: SharePluginStart;
- management: ManagementStart;
- advancedSettings: AdvancedSettingsStart;
- discover: DiscoverStart;
- visualizations: VisualizationsStart;
- telemetry?: TelemetryPluginStart;
- dashboard: DashboardStart;
- savedObjectsManagement: SavedObjectsManagementPluginStart;
- visTypeTimelion: VisTypeTimelionPluginStart;
- indexPatternManagement: IndexPatternManagementStart;
-}
-
-export const npSetup = {
- core: (null as unknown) as LegacyCoreSetup,
- plugins: {} as PluginsSetup,
-};
-
-export const npStart = {
- core: (null as unknown) as LegacyCoreStart,
- plugins: {} as PluginsStart,
-};
-
-/**
- * Only used by unit tests
- * @internal
- */
-export function __reset__() {
- npSetup.core = (null as unknown) as LegacyCoreSetup;
- npSetup.plugins = {} as any;
- npStart.core = (null as unknown) as LegacyCoreStart;
- npStart.plugins = {} as any;
- legacyAppRegistered = false;
-}
-
-export function __setup__(coreSetup: LegacyCoreSetup, plugins: PluginsSetup) {
- npSetup.core = coreSetup;
- npSetup.plugins = plugins;
-
- // Setup compatibility layer for AppService in legacy platform
- npSetup.core.application.register = legacyAppRegister;
-
- // Services that need to be set in the legacy platform since the legacy data
- // & vis plugins which previously provided them have been removed.
- setSetupServices(npSetup);
-}
-
-export function __start__(coreStart: LegacyCoreStart, plugins: PluginsStart) {
- npStart.core = coreStart;
- npStart.plugins = plugins;
-
- // Services that need to be set in the legacy platform since the legacy data
- // & vis plugins which previously provided them have been removed.
- setStartServices(npStart);
-}
-
-/** Flag used to ensure `legacyAppRegister` is only called once. */
-let legacyAppRegistered = false;
-
-/**
- * Exported for testing only. Use `npSetup.core.application.register` in legacy apps.
- * @internal
- */
-export const legacyAppRegister = (app: App) => {
- if (legacyAppRegistered) {
- throw new Error(`core.application.register may only be called once for legacy plugins.`);
- }
- legacyAppRegistered = true;
-
- // eslint-disable-next-line @typescript-eslint/no-var-requires
- require('ui/chrome').setRootController(app.id, ($scope: IScope, $element: JQLite) => {
- const element = document.createElement('div');
- $element[0].appendChild(element);
-
- // Root controller cannot return a Promise so use an internal async function and call it immediately
- (async () => {
- const appRoute = app.appRoute || `/app/${app.id}`;
- const appBasePath = npSetup.core.http.basePath.prepend(appRoute);
- const params = {
- element,
- appBasePath,
- history: new ScopedHistory(
- createBrowserHistory({ basename: npSetup.core.http.basePath.get() }),
- appRoute
- ),
- onAppLeave: () => undefined,
- };
- const unmount = isAppMountDeprecated(app.mount)
- ? await app.mount({ core: npStart.core }, params)
- : await app.mount(params);
- $scope.$on('$destroy', () => {
- unmount();
- });
- })();
- });
-};
-
-function isAppMountDeprecated(mount: (...args: any[]) => any): mount is AppMountDeprecated {
- // Mount functions with two arguments are assumed to expect deprecated `context` object.
- return mount.length === 2;
-}
diff --git a/src/legacy/ui/public/new_platform/set_services.test.ts b/src/legacy/ui/public/new_platform/set_services.test.ts
deleted file mode 100644
index 74e789ec220b1..0000000000000
--- a/src/legacy/ui/public/new_platform/set_services.test.ts
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { __reset__, __setup__, __start__, PluginsSetup, PluginsStart } from './new_platform';
-import * as dataServices from '../../../../plugins/data/public/services';
-import * as visualizationsServices from '../../../../plugins/visualizations/public/services';
-import { LegacyCoreSetup, LegacyCoreStart } from '../../../../core/public';
-import { coreMock } from '../../../../core/public/mocks';
-import { npSetup, npStart } from './__mocks__';
-
-describe('ui/new_platform', () => {
- describe('set service getters', () => {
- const testServiceGetters = (name: string, services: Record) => {
- const getters = Object.keys(services).filter((k) => k.substring(0, 3) === 'get');
- getters.forEach((g) => {
- it(`ui/new_platform sets a value for ${name} getter ${g}`, () => {
- __reset__();
- __setup__(
- (coreMock.createSetup() as unknown) as LegacyCoreSetup,
- (npSetup.plugins as unknown) as PluginsSetup
- );
- __start__(
- (coreMock.createStart() as unknown) as LegacyCoreStart,
- (npStart.plugins as unknown) as PluginsStart
- );
-
- expect(services[g]()).toBeDefined();
- });
- });
- };
-
- testServiceGetters('data', dataServices);
- testServiceGetters('visualizations', visualizationsServices);
- });
-});
diff --git a/src/legacy/ui/public/new_platform/set_services.ts b/src/legacy/ui/public/new_platform/set_services.ts
deleted file mode 100644
index 036157a9f3fbc..0000000000000
--- a/src/legacy/ui/public/new_platform/set_services.ts
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { pick } from 'lodash';
-
-import { PluginsSetup, PluginsStart } from './new_platform';
-import { LegacyCoreSetup, LegacyCoreStart } from '../../../../core/public';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import * as dataServices from '../../../../plugins/data/public/services';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import * as visualizationsServices from '../../../../plugins/visualizations/public/services';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { createSavedVisLoader } from '../../../../plugins/visualizations/public/saved_visualizations/saved_visualizations';
-
-interface NpSetup {
- core: LegacyCoreSetup;
- plugins: PluginsSetup;
-}
-
-interface NpStart {
- core: LegacyCoreStart;
- plugins: PluginsStart;
-}
-
-export function setSetupServices(npSetup: NpSetup) {
- // Services that need to be set in the legacy platform since the legacy data plugin
- // which previously provided them has been removed.
- visualizationsServices.setUISettings(npSetup.core.uiSettings);
- visualizationsServices.setUsageCollector(npSetup.plugins.usageCollection);
-}
-
-export function setStartServices(npStart: NpStart) {
- // Services that need to be set in the legacy platform since the legacy data plugin
- // which previously provided them has been removed.
- dataServices.setNotifications(npStart.core.notifications);
- dataServices.setOverlays(npStart.core.overlays);
- dataServices.setUiSettings(npStart.core.uiSettings);
- dataServices.setFieldFormats(npStart.plugins.data.fieldFormats);
- dataServices.setIndexPatterns(npStart.plugins.data.indexPatterns);
- dataServices.setQueryService(npStart.plugins.data.query);
- dataServices.setSearchService(npStart.plugins.data.search);
-
- visualizationsServices.setI18n(npStart.core.i18n);
- visualizationsServices.setTypes(
- pick(npStart.plugins.visualizations, ['get', 'all', 'getAliases'])
- );
- visualizationsServices.setCapabilities(npStart.core.application.capabilities);
- visualizationsServices.setHttp(npStart.core.http);
- visualizationsServices.setApplication(npStart.core.application);
- visualizationsServices.setEmbeddable(npStart.plugins.embeddable);
- visualizationsServices.setSavedObjects(npStart.core.savedObjects);
- visualizationsServices.setIndexPatterns(npStart.plugins.data.indexPatterns);
- visualizationsServices.setFilterManager(npStart.plugins.data.query.filterManager);
- visualizationsServices.setExpressions(npStart.plugins.expressions);
- visualizationsServices.setUiActions(npStart.plugins.uiActions);
- visualizationsServices.setTimeFilter(npStart.plugins.data.query.timefilter.timefilter);
- visualizationsServices.setAggs(npStart.plugins.data.search.aggs);
- visualizationsServices.setOverlays(npStart.core.overlays);
- visualizationsServices.setChrome(npStart.core.chrome);
- visualizationsServices.setSearch(npStart.plugins.data.search);
- const savedVisualizationsLoader = createSavedVisLoader({
- savedObjectsClient: npStart.core.savedObjects.client,
- indexPatterns: npStart.plugins.data.indexPatterns,
- search: npStart.plugins.data.search,
- chrome: npStart.core.chrome,
- overlays: npStart.core.overlays,
- visualizationTypes: visualizationsServices.getTypes(),
- });
- visualizationsServices.setSavedVisualizationsLoader(savedVisualizationsLoader);
- visualizationsServices.setSavedSearchLoader(npStart.plugins.discover.savedSearchLoader);
-}
diff --git a/src/legacy/ui/public/notify/banners/BANNERS.md b/src/legacy/ui/public/notify/banners/BANNERS.md
deleted file mode 100644
index fc6bddc3aa4ed..0000000000000
--- a/src/legacy/ui/public/notify/banners/BANNERS.md
+++ /dev/null
@@ -1,360 +0,0 @@
-# Banners
-
-Use this service to surface banners at the top of the screen. The expectation is that the banner will used an
-` ` to render, but that is not a requirement. See [the EUI docs](https://elastic.github.io/eui/) for
-more information on banners and their role within the UI.
-
-Banners should be considered with respect to their lifecycle. Most banners are best served by using the `add` and
-`remove` functions.
-
-## Importing the module
-
-```js
-import { banners } from 'ui/notify';
-```
-
-## Interface
-
-There are three methods defined to manipulate the list of banners: `add`, `set`, and `remove`. A fourth method,
-`onChange` exists to listen to changes made via `add`, `set`, and `remove`.
-
-### `add()`
-
-This is the preferred way to add banners because it implies the best usage of the banner: added once during a page's
-lifecycle. For other usages, consider *not* using a banner.
-
-#### Syntax
-
-```js
-const bannerId = banners.add({
- // required:
- component,
- // optional:
- priority,
-});
-```
-
-##### Parameters
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `component` | Any | The value displayed as the banner. |
-| `priority` | Number | Optional priority, which defaults to `0` used to place the banner. |
-
-To add a banner, you only need to define the `component` field.
-
-The `priority` sorts in descending order. Items sharing the same priority are sorted from oldest to newest. For example:
-
-```js
-const banner1 = banners.add({ component: });
-const banner2 = banners.add({ component: , priority: 0 });
-const banner3 = banners.add({ component: , priority: 1 });
-```
-
-That would be displayed as:
-
-```
-[ fake3 ]
-[ fake1 ]
-[ fake2 ]
-```
-
-##### Returns
-
-| Type | Description |
-|------|-------------|
-| String | A newly generated ID. |
-
-#### Example
-
-This example includes buttons that allow the user to remove the banner. In some cases, you may not want any buttons
-and in other cases you will want an action to proceed the banner's removal (e.g., apply an Advanced Setting).
-
-This makes the most sense to use when a banner is added at the beginning of the page life cycle and not expected to
-be touched, except by its own buttons triggering an action or navigating away.
-
-```js
-const bannerId = banners.add({
- component: (
-
-
-
- banners.remove(bannerId)}
- >
- Dismiss
-
-
-
- window.alert('Do Something Else')}
- >
- Do Something Else
-
-
-
-
- ),
-});
-```
-
-### `remove()`
-
-Unlike toast notifications, banners stick around until they are explicitly removed. Using the `add` example above,you can remove it by calling `remove`.
-
-Note: They will stick around as long as the scope is remembered by whatever set it; navigating away won't remove it
-unless the scope is forgotten (e.g., when the "app" changes)!
-
-#### Syntax
-
-```js
-const removed = banners.remove(bannerId);
-```
-
-##### Parameters
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `id` | String | ID of a banner. |
-
-##### Returns
-
-| Type | Description |
-|------|-------------|
-| Boolean | `true` if the ID was recognized and the banner was removed. `false` otherwise. |
-
-#### Example
-
-To remove a banner, you need to pass the `id` of the banner.
-
-```js
-if (banners.remove(bannerId)) {
- // removed; otherwise it didn't exist (maybe it was already removed)
-}
-```
-
-#### Scheduled removal
-
-Like toast notifications do automatically, you can have a banner automatically removed after a set of time, by
-setting a timer:
-
-```js
-setTimeout(() => banners.remove(bannerId), 15000);
-```
-
-Note: It is safe to remove a banner more than once as unknown IDs will be ignored.
-
-### `set()`
-
-Banners can be replaced once added by supplying their `id`. If one is supplied, then the ID will be used to replace
-any banner with the same ID and a **new** `id` will be returned.
-
-You should only consider using `set` when the banner is manipulated frequently in the lifecycle of the page, where
-maintaining the banner's `id` can be a burden. It is easier to allow `banners` to create the ID for you in most
-situations where a banner is useful (e.g., set once), which safely avoids any chance to have an ID-based collision,
-which happens automatically with `add`.
-
-Usage of `set` can imply that your use case is abusing the banner system.
-
-Note: `set` will only trigger the callback once for both the implicit remove and add operation.
-
-#### Syntax
-
-```js
-const id = banners.set({
- // required:
- component,
- // optional:
- id,
- priority,
-});
-```
-
-##### Parameters
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `component` | Any | The value displayed as the banner. |
-| `id` | String | Optional ID used to remove an existing banner. |
-| `priority` | Number | Optional priority, which defaults to `0` used to place the banner. |
-
-The `id` is optional because it follows the same semantics as the `remove` method: unknown IDs are ignored. This
-is useful when first creating a banner so that you do not have to call `add` instead.
-
-##### Returns
-
-| Type | Description |
-|------|-------------|
-| String | A newly generated ID. |
-
-#### Example
-
-This example does not include any way for the user to clear the banner directly. Instead, it is cleared based on
-time. Related to it being cleared by time, it can also reappear within the same page life cycle by navigating between
-different paths that need it displayed. Instead of adding a new banner for every navigation, you should replace any
-existing banner.
-
-```js
-let bannerId;
-let timeoutId;
-
-function displayBanner() {
- clearTimeout(timeoutId);
-
- bannerId = banners.set({
- id: bannerId, // the first time it will be undefined, but reused as long as this is in the same lifecycle
- component: (
-
- )
- });
-
- // hide the message after the user has had a chance to acknowledge it -- so it doesn't permanently stick around
- banner.timeoutId = setTimeout(() => {
- banners.remove(bannerId);
- timeoutId = undefined;
- }, 6000);
-}
-```
-
-### `onChange()`
-
-For React components that intend to display the banners, it is not enough to simply `render` the `banners.list`
-values. Because they can change after being rendered, the React component that renders the list must be alerted
-to changes to the list.
-
-#### Syntax
-
-```js
-// inside your React component
-banners.onChange(() => this.forceUpdate());
-```
-
-##### Parameters
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `callback` | Function | The function to invoke whenever the internal banner list is changed. |
-
-Every new `callback` replaces the previous callback. So calling this with `null` or `undefined` will unset the
-callback.
-
-##### Returns
-
-Nothing.
-
-#### Example
-
-This can be used inside of a React component to trigger a re-`render` of the banners.
-
-```js
-import { GlobalBannerList } from 'ui/notify';
-
-
-```
-
-### `list`
-
-For React components that intend to display the banners, it is not enough to simply `render` the `banners.list`
-values. Because they can change after being rendered, the React component that renders the list must be alerted
-to changes to the list.
-
-#### Syntax
-
-```js
-
-```
-
-##### Returns
-
-| Type | Description |
-|------|-------------|
-| Array | The array of banner objects. |
-
-Banner objects are sorted in descending order based on their `priority`, in the form:
-
-```js
-{
- id: 'banner-123',
- component: ,
- priority: 12,
-}
-```
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `component` | Any | The value displayed as the banner. |
-| `id` | String | The ID of the banner, which can be used as a React "key". |
-| `priority` | Number | The priority of the banner. |
-
-#### Example
-
-This can be used to supply the banners to the `GlobalBannerList` React component (which is done for you).
-
-```js
-import { GlobalBannerList } from 'ui/notify';
-
-
-```
-
-## Use in functional tests
-
-Functional tests are commonly used to verify that an action yielded a successful outcome. You can place a
-`data-test-subj` attribute on the banner and use it to check if the banner exists inside of your functional test.
-This acts as a proxy for verifying the successful outcome. Any unrecognized field will be added as a property of the
-containing element.
-
-```js
-banners.add({
- component: (
-
- ),
- data-test-subj: 'my-tested-banner',
-});
-```
-
-This will apply the `data-test-subj` to the element containing the `component`, so the inner HTML of that element
-will exclusively be the specified `component`.
-
-Given that `component` is expected to be a React component, you could also add the `data-test-subj` directly to it:
-
-```js
-banners.add({
- component: (
-
- ),
-});
-```
\ No newline at end of file
diff --git a/src/legacy/ui/public/notify/banners/banners.tsx b/src/legacy/ui/public/notify/banners/banners.tsx
deleted file mode 100644
index 777e408b8dfc4..0000000000000
--- a/src/legacy/ui/public/notify/banners/banners.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import ReactDOM from 'react-dom';
-import { npStart } from 'ui/new_platform';
-import { I18nProvider } from '@kbn/i18n/react';
-
-const npBanners = npStart.core.overlays.banners;
-
-/** compatibility layer for new platform */
-const mountForComponent = (component: React.ReactElement) => (element: HTMLElement) => {
- ReactDOM.render({component} , element);
- return () => ReactDOM.unmountComponentAtNode(element);
-};
-
-/**
- * Banners represents a prioritized list of displayed components.
- */
-export class Banners {
- /**
- * Add a new banner.
- *
- * @param {Object} component The React component to display.
- * @param {Number} priority The optional priority order to display this banner. Higher priority values are shown first.
- * @return {String} A newly generated ID. This value can be used to remove/replace the banner.
- */
- add = ({ component, priority }: { component: React.ReactElement; priority?: number }) => {
- return npBanners.add(mountForComponent(component), priority);
- };
-
- /**
- * Remove an existing banner.
- *
- * @param {String} id The ID of the banner to remove.
- * @return {Boolean} {@code true} if the ID is recognized and the banner is removed. {@code false} otherwise.
- */
- remove = (id: string): boolean => {
- return npBanners.remove(id);
- };
-
- /**
- * Replace an existing banner by removing it, if it exists, and adding a new one in its place.
- *
- * This is similar to calling banners.remove, followed by banners.add, except that it only notifies the listener
- * after adding.
- *
- * @param {Object} component The React component to display.
- * @param {String} id The ID of the Banner to remove.
- * @param {Number} priority The optional priority order to display this banner. Higher priority values are shown first.
- * @return {String} A newly generated ID. This value can be used to remove/replace the banner.
- */
- set = ({
- component,
- id,
- priority = 0,
- }: {
- component: React.ReactElement;
- id: string;
- priority?: number;
- }): string => {
- return npBanners.replace(id, mountForComponent(component), priority);
- };
-}
-
-/**
- * A singleton instance meant to represent all Kibana banners.
- */
-export const banners = new Banners();
diff --git a/src/legacy/ui/public/notify/banners/index.ts b/src/legacy/ui/public/notify/banners/index.ts
deleted file mode 100644
index 9221f95074cd9..0000000000000
--- a/src/legacy/ui/public/notify/banners/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { banners } from './banners';
diff --git a/src/legacy/ui/public/notify/fatal_error.ts b/src/legacy/ui/public/notify/fatal_error.ts
deleted file mode 100644
index 5614ffea7913e..0000000000000
--- a/src/legacy/ui/public/notify/fatal_error.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-import { AngularHttpError, addFatalError } from '../../../../plugins/kibana_legacy/public';
-
-export function fatalError(error: AngularHttpError | Error | string, location?: string) {
- addFatalError(npSetup.core.fatalErrors, error, location);
-}
diff --git a/src/legacy/ui/public/notify/index.d.ts b/src/legacy/ui/public/notify/index.d.ts
deleted file mode 100644
index 3c1a7ba02db72..0000000000000
--- a/src/legacy/ui/public/notify/index.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { toastNotifications } from './toasts';
-export { fatalError } from './fatal_error';
diff --git a/src/legacy/ui/public/notify/index.js b/src/legacy/ui/public/notify/index.js
deleted file mode 100644
index 51394033e4d2e..0000000000000
--- a/src/legacy/ui/public/notify/index.js
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { fatalError } from './fatal_error';
-export { toastNotifications } from './toasts';
-export { banners } from './banners';
diff --git a/src/legacy/ui/public/notify/toasts/index.ts b/src/legacy/ui/public/notify/toasts/index.ts
deleted file mode 100644
index c5e8e3b7ca7a3..0000000000000
--- a/src/legacy/ui/public/notify/toasts/index.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-export { ToastNotifications } from './toast_notifications';
-export { toastNotifications } from './toasts';
diff --git a/src/legacy/ui/public/notify/toasts/toasts.ts b/src/legacy/ui/public/notify/toasts/toasts.ts
deleted file mode 100644
index 15be7a7891553..0000000000000
--- a/src/legacy/ui/public/notify/toasts/toasts.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { npSetup } from 'ui/new_platform';
-import { ToastNotifications } from './toast_notifications';
-export const toastNotifications = new ToastNotifications(npSetup.core.notifications.toasts);
diff --git a/src/legacy/ui/public/private/__tests__/private.js b/src/legacy/ui/public/private/__tests__/private.js
deleted file mode 100644
index 1f9d696bb440f..0000000000000
--- a/src/legacy/ui/public/private/__tests__/private.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-
-describe('Private module loader', function () {
- let Private;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector) {
- Private = $injector.get('Private');
- })
- );
-
- it('accepts a provider that will be called to init a module', function () {
- const football = {};
- function Provider() {
- return football;
- }
-
- const instance = Private(Provider);
- expect(instance).to.be(football);
- });
-
- it('injects angular dependencies into the Provider', function () {
- function Provider(Private) {
- return Private;
- }
-
- const instance = Private(Provider);
- expect(instance).to.be(Private);
- });
-
- it('detects circular dependencies', function () {
- expect(function () {
- function Provider1() {
- Private(Provider2);
- }
-
- function Provider2() {
- Private(Provider1);
- }
-
- Private(Provider1);
- }).to.throwException(/circular/i);
- });
-
- it('always provides the same instance form the Provider', function () {
- function Provider() {
- return {};
- }
-
- expect(Private(Provider)).to.be(Private(Provider));
- });
-
- describe('#stub', function () {
- it('accepts a replacement instance for a Provider', function () {
- const replaced = {};
- const replacement = {};
-
- function Provider() {
- return replaced;
- }
-
- const instance = Private(Provider);
- expect(instance).to.be(replaced);
-
- Private.stub(Provider, replacement);
-
- const instance2 = Private(Provider);
- expect(instance2).to.be(replacement);
-
- Private.stub(Provider, replaced);
-
- const instance3 = Private(Provider);
- expect(instance3).to.be(replaced);
- });
- });
-
- describe('#swap', function () {
- it('accepts a new Provider that should replace an existing Provider', function () {
- function Provider1() {
- return {};
- }
-
- function Provider2() {
- return {};
- }
-
- const instance1 = Private(Provider1);
- expect(instance1).to.be.an('object');
-
- Private.swap(Provider1, Provider2);
-
- const instance2 = Private(Provider1);
- expect(instance2).to.be.an('object');
- expect(instance2).to.not.be(instance1);
-
- Private.swap(Provider1, Provider1);
-
- const instance3 = Private(Provider1);
- expect(instance3).to.be(instance1);
- });
-
- it('gives the new Provider access to the Provider it replaced via an injectable dependency called $decorate', function () {
- function Provider1() {
- return {};
- }
-
- function Provider2($decorate) {
- return {
- instance1: $decorate(),
- };
- }
-
- const instance1 = Private(Provider1);
- expect(instance1).to.be.an('object');
-
- Private.swap(Provider1, Provider2);
-
- const instance2 = Private(Provider1);
- expect(instance2).to.have.property('instance1');
- expect(instance2.instance1).to.be(instance1);
- });
- });
-});
diff --git a/src/legacy/ui/public/private/index.d.ts b/src/legacy/ui/public/private/index.d.ts
deleted file mode 100644
index 3b692ba58cbe1..0000000000000
--- a/src/legacy/ui/public/private/index.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { IPrivate } from '../../../../plugins/kibana_legacy/public/';
diff --git a/src/legacy/ui/public/private/index.js b/src/legacy/ui/public/private/index.js
deleted file mode 100644
index 3815f230df466..0000000000000
--- a/src/legacy/ui/public/private/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './private';
diff --git a/src/legacy/ui/public/private/private.js b/src/legacy/ui/public/private/private.js
deleted file mode 100644
index 7a0751959417e..0000000000000
--- a/src/legacy/ui/public/private/private.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiModules } from '../modules';
-import { PrivateProvider } from '../../../../plugins/kibana_legacy/public';
-
-uiModules.get('kibana/private').provider('Private', PrivateProvider);
diff --git a/src/legacy/ui/public/promises/__tests__/promises.js b/src/legacy/ui/public/promises/__tests__/promises.js
deleted file mode 100644
index 7041aa2993376..0000000000000
--- a/src/legacy/ui/public/promises/__tests__/promises.js
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import sinon from 'sinon';
-
-describe('Promise service', () => {
- let Promise;
- let $rootScope;
-
- const sandbox = sinon.createSandbox();
- function tick(ms = 0) {
- sandbox.clock.tick(ms);
-
- // Ugly, but necessary for promises to resolve: https://github.com/angular/angular.js/issues/12555
- $rootScope.$apply();
- }
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(($injector) => {
- sandbox.useFakeTimers();
-
- Promise = $injector.get('Promise');
- $rootScope = $injector.get('$rootScope');
- })
- );
-
- afterEach(() => sandbox.restore());
-
- describe('Constructor', () => {
- it('provides resolve and reject function', () => {
- const executor = sinon.stub();
- new Promise(executor);
-
- sinon.assert.calledOnce(executor);
- sinon.assert.calledWithExactly(executor, sinon.match.func, sinon.match.func);
- });
- });
-
- it('Promise.resolve', () => {
- const onResolve = sinon.stub();
- Promise.resolve(true).then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, true);
- });
-
- describe('Promise.fromNode', () => {
- it('creates a callback that controls a promise', () => {
- const callback = sinon.stub();
- Promise.fromNode(callback);
-
- tick();
-
- sinon.assert.calledOnce(callback);
- sinon.assert.calledWithExactly(callback, sinon.match.func);
- });
-
- it('rejects if the callback receives an error', () => {
- const err = new Error();
- const onReject = sinon.stub();
- Promise.fromNode(sinon.stub().yields(err)).catch(onReject);
-
- tick();
-
- sinon.assert.calledOnce(onReject);
- sinon.assert.calledWithExactly(onReject, sinon.match.same(err));
- });
-
- it('resolves with the second argument', () => {
- const result = {};
- const onResolve = sinon.stub();
- Promise.fromNode(sinon.stub().yields(null, result)).then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, sinon.match.same(result));
- });
-
- it('resolves with an array if multiple arguments are received', () => {
- const result1 = {};
- const result2 = {};
- const onResolve = sinon.stub();
- Promise.fromNode(sinon.stub().yields(null, result1, result2)).then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, [
- sinon.match.same(result1),
- sinon.match.same(result2),
- ]);
- });
-
- it('resolves with an array if multiple undefined are received', () => {
- const onResolve = sinon.stub();
- Promise.fromNode(sinon.stub().yields(null, undefined, undefined)).then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, [undefined, undefined]);
- });
- });
-
- describe('Promise.race()', () => {
- it(`resolves with the first resolved promise's value`, () => {
- const p1 = new Promise((resolve) => setTimeout(resolve, 100, 1));
- const p2 = new Promise((resolve) => setTimeout(resolve, 200, 2));
- const onResolve = sinon.stub();
- Promise.race([p1, p2]).then(onResolve);
-
- tick(200);
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 1);
- });
-
- it(`rejects with the first rejected promise's rejection reason`, () => {
- const p1Error = new Error('1');
- const p1 = new Promise((r, reject) => setTimeout(reject, 200, p1Error));
-
- const p2Error = new Error('2');
- const p2 = new Promise((r, reject) => setTimeout(reject, 100, p2Error));
-
- const onReject = sinon.stub();
- Promise.race([p1, p2]).catch(onReject);
-
- tick(200);
-
- sinon.assert.calledOnce(onReject);
- sinon.assert.calledWithExactly(onReject, sinon.match.same(p2Error));
- });
-
- it('does not wait for subsequent promises to resolve/reject', () => {
- const onP1Resolve = sinon.stub();
- const p1 = new Promise((resolve) => setTimeout(resolve, 100)).then(onP1Resolve);
-
- const onP2Resolve = sinon.stub();
- const p2 = new Promise((resolve) => setTimeout(resolve, 101)).then(onP2Resolve);
-
- const onResolve = sinon.stub();
- Promise.race([p1, p2]).then(onResolve);
-
- tick(100);
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledOnce(onP1Resolve);
- sinon.assert.callOrder(onP1Resolve, onResolve);
- sinon.assert.notCalled(onP2Resolve);
- });
-
- it('allows non-promises in the array', () => {
- const onResolve = sinon.stub();
- Promise.race([1, 2, 3]).then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 1);
- });
-
- describe('argument is undefined', () => {
- it('rejects the promise', () => {
- const football = {};
- const onReject = sinon.stub();
- Promise.race()
- .catch(() => football)
- .then(onReject);
-
- tick();
-
- sinon.assert.calledOnce(onReject);
- sinon.assert.calledWithExactly(onReject, sinon.match.same(football));
- });
- });
-
- describe('argument is a string', () => {
- it(`resolves with the first character`, () => {
- const onResolve = sinon.stub();
- Promise.race('abc').then(onResolve);
-
- tick();
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 'a');
- });
- });
-
- describe('argument is a non-iterable object', () => {
- it('reject the promise', () => {
- const football = {};
- const onReject = sinon.stub();
- Promise.race({})
- .catch(() => football)
- .then(onReject);
-
- tick();
-
- sinon.assert.calledOnce(onReject);
- sinon.assert.calledWithExactly(onReject, sinon.match.same(football));
- });
- });
-
- describe('argument is a generator', () => {
- it('resolves with the first resolved value', () => {
- function* gen() {
- yield new Promise((resolve) => setTimeout(resolve, 100, 1));
- yield new Promise((resolve) => setTimeout(resolve, 200, 2));
- }
-
- const onResolve = sinon.stub();
- Promise.race(gen()).then(onResolve);
-
- tick(200);
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 1);
- });
-
- it('resolves with the first non-promise value', () => {
- function* gen() {
- yield 1;
- yield new Promise((resolve) => setTimeout(resolve, 200, 2));
- }
-
- const onResolve = sinon.stub();
- Promise.race(gen()).then(onResolve);
-
- tick(200);
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 1);
- });
-
- it('iterates all values from the generator, even if one is already "resolved"', () => {
- let yieldCount = 0;
- function* gen() {
- yieldCount += 1;
- yield 1;
- yieldCount += 1;
- yield new Promise((resolve) => setTimeout(resolve, 200, 2));
- }
-
- const onResolve = sinon.stub();
- Promise.race(gen()).then(onResolve);
-
- tick(200);
-
- sinon.assert.calledOnce(onResolve);
- sinon.assert.calledWithExactly(onResolve, 1);
- expect(yieldCount).to.be(2);
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/promises/defer.ts b/src/legacy/ui/public/promises/defer.ts
deleted file mode 100644
index 3d435f2ba8dfd..0000000000000
--- a/src/legacy/ui/public/promises/defer.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export interface Defer {
- promise: Promise;
- resolve(value: T): void;
- reject(reason: Error): void;
-}
-
-export function createDefer(Class: typeof Promise): Defer {
- const defer: Partial> = {};
- defer.promise = new Class((resolve, reject) => {
- defer.resolve = resolve;
- defer.reject = reject;
- });
- return defer as Defer;
-}
diff --git a/src/legacy/ui/public/promises/index.ts b/src/legacy/ui/public/promises/index.ts
deleted file mode 100644
index 07bb2554c5eda..0000000000000
--- a/src/legacy/ui/public/promises/index.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { PromiseServiceCreator } from '../../../../plugins/kibana_legacy/public';
-export { createDefer } from './defer';
-// @ts-ignore
-import { uiModules } from '../modules';
-
-const module = uiModules.get('kibana');
-// Provides a tiny subset of the excellent API from
-// bluebird, reimplemented using the $q service
-module.service('Promise', PromiseServiceCreator);
diff --git a/src/legacy/ui/public/react_components.js b/src/legacy/ui/public/react_components.js
deleted file mode 100644
index 21fb53d6407fa..0000000000000
--- a/src/legacy/ui/public/react_components.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import 'ngreact';
-
-import { EuiIcon, EuiIconTip } from '@elastic/eui';
-
-import { uiModules } from './modules';
-
-const app = uiModules.get('app/kibana', ['react']);
-
-app.directive('icon', (reactDirective) => reactDirective(EuiIcon));
-
-app.directive('iconTip', (reactDirective) =>
- reactDirective(EuiIconTip, ['content', 'type', 'position', 'title', 'color'])
-);
diff --git a/src/legacy/ui/public/registry/__tests__/registry.js b/src/legacy/ui/public/registry/__tests__/registry.js
deleted file mode 100644
index 10b2423abc0e3..0000000000000
--- a/src/legacy/ui/public/registry/__tests__/registry.js
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiRegistry } from '../_registry';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-
-describe('Registry', function () {
- let Private;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function ($injector) {
- Private = $injector.get('Private');
- })
- );
-
- it('is technically a function', function () {
- const reg = uiRegistry();
- expect(reg).to.be.a('function');
- });
-
- describe('#register', function () {
- it('accepts a Private module', function () {
- const reg = uiRegistry();
- const mod = function SomePrivateModule() {};
-
- reg.register(mod);
- // modules are not exposed, so this is the most that we can test
- });
-
- it('applies the filter function if one is specified', function () {
- const reg = uiRegistry({
- filter: (item) => item.value % 2 === 0, // register only even numbers
- });
-
- reg.register(() => ({ value: 17 }));
- reg.register(() => ({ value: 18 })); // only this one should get registered
- reg.register(() => ({ value: 19 }));
-
- const modules = Private(reg);
- expect(modules).to.have.length(1);
- expect(modules[0].value).to.be(18);
- });
- });
-
- describe('as a module', function () {
- it('exposes the list of registered modules', function () {
- const reg = uiRegistry();
- const mod = function SomePrivateModule(Private) {
- this.PrivateModuleLoader = Private;
- };
-
- reg.register(mod);
- const modules = Private(reg);
- expect(modules).to.have.length(1);
- expect(modules[0]).to.have.property('PrivateModuleLoader', Private);
- });
- });
-
- describe('spec', function () {
- it('executes with the module list as "this", and can override it', function () {
- let self;
-
- const reg = uiRegistry({
- constructor: function () {
- return { mods: (self = this) };
- },
- });
-
- const modules = Private(reg);
- expect(modules).to.be.an('object');
- expect(modules).to.have.property('mods', self);
- });
- });
-
- describe('spec.name', function () {
- it('sets the displayName of the registry and the name param on the final instance', function () {
- const reg = uiRegistry({
- name: 'visTypes',
- });
-
- expect(reg).to.have.property('displayName', '[registry visTypes]');
- expect(Private(reg)).to.have.property('name', 'visTypes');
- });
- });
-
- describe('spec.constructor', function () {
- it('executes before the modules are returned', function () {
- let i = 0;
-
- const reg = uiRegistry({
- constructor: function () {
- i = i + 1;
- },
- });
-
- Private(reg);
- expect(i).to.be(1);
- });
-
- it('executes with the module list as "this", and can override it', function () {
- let self;
-
- const reg = uiRegistry({
- constructor: function () {
- return { mods: (self = this) };
- },
- });
-
- const modules = Private(reg);
- expect(modules).to.be.an('object');
- expect(modules).to.have.property('mods', self);
- });
- });
-
- describe('spec.invokeProviders', () => {
- it('is called with the registered providers and defines the initial set of values in the registry', () => {
- const reg = uiRegistry({
- invokeProviders(providers) {
- return providers.map((i) => i * 1000);
- },
- });
-
- reg.register(1);
- reg.register(2);
- reg.register(3);
- expect(Private(reg).toJSON()).to.eql([1000, 2000, 3000]);
- });
- it('does not get assigned as a property of the registry', () => {
- expect(
- uiRegistry({
- invokeProviders() {},
- })
- ).to.not.have.property('invokeProviders');
- });
- });
-
- describe('spec[any]', function () {
- it('mixes the extra properties into the module list', function () {
- const reg = uiRegistry({
- someMethod: function () {
- return this;
- },
- });
-
- const modules = Private(reg);
- expect(modules).to.have.property('someMethod');
- expect(modules.someMethod()).to.be(modules);
- });
- });
-});
diff --git a/src/legacy/ui/public/registry/_registry.d.ts b/src/legacy/ui/public/registry/_registry.d.ts
deleted file mode 100644
index 42f1bb521763c..0000000000000
--- a/src/legacy/ui/public/registry/_registry.d.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { IndexedArray, IndexedArrayConfig } from '../indexed_array';
-
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-interface UIRegistry extends IndexedArray {}
-
-interface UIRegistrySpec extends IndexedArrayConfig {
- name: string;
- filter?(item: T): boolean;
-}
-
-/**
- * Creates a new UiRegistry (See js method for detailed documentation)
- * The generic type T is the type of objects which are stored in the registry.
- * The generic type A is an interface of accessors which depend on the
- * fields of the objects stored in the registry.
- * Example: if there is a string field "name" in type T, then A should be
- * `{ byName: { [typeName: string]: T }; }`
- */
-declare function uiRegistry(
- spec: UIRegistrySpec
-): { (): UIRegistry & A; register(privateModule: T): UIRegistry & A };
diff --git a/src/legacy/ui/public/registry/_registry.js b/src/legacy/ui/public/registry/_registry.js
deleted file mode 100644
index 85aa1d9f2eca8..0000000000000
--- a/src/legacy/ui/public/registry/_registry.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { IndexedArray } from '../indexed_array';
-
-const notPropsOptNames = IndexedArray.OPT_NAMES.concat('constructor', 'invokeProviders');
-
-/**
- * Create a registry, which is just a Private module provider.
- *
- * The registry allows modifying the values it will provide
- * using the #register method.
- *
- * To access these modules, pass the registry to the Private
- * module loader.
- *
- * # Examples
- *
- * + register a module
- * ```js
- * let registry = require('ui/registry/vis_types');
- * registry.add(function InjectablePrivateModule($http, Promise) {
- * ...
- * })
- * ```
- *
- * + get all registered modules
- * ```js
- * let visTypes = Private(RegistryVisTypesProvider);
- * ```
- *
- *
- * @param {object} [spec] - an object describing the properties of
- * the registry to create. Any property specified
- * that is not listed below will be mixed into the
- * final IndexedArray object.
- *
- * # init
- * @param {Function} [spec.constructor] - an injectable function that is called when
- * the registry is first instantiated by the app.
- * @param {boolean} [spec.filter] - function that will be used to filter items before
- * registering them. Function will called on each item and
- * should return true to keep the item (register it) or
- * skip it (don't register it)
- *
- * # IndexedArray params
- * @param {array[String]} [spec.index] - passed to the IndexedArray constructor
- * @param {array[String]} [spec.group] - passed to the IndexedArray constructor
- * @param {array[String]} [spec.order] - passed to the IndexedArray constructor
- * @param {array[String]} [spec.initialSet] - passed to the IndexedArray constructor
- * @param {array[String]} [spec.immutable] - passed to the IndexedArray constructor
- *
- * @return {[type]} [description]
- */
-export function uiRegistry(spec) {
- spec = spec || {};
-
- const constructor = _.has(spec, 'constructor') && spec.constructor;
- const filter = _.has(spec, 'filter') && spec.filter;
- const invokeProviders = _.has(spec, 'invokeProviders') && spec.invokeProviders;
- const iaOpts = _.defaults(_.pick(spec, IndexedArray.OPT_NAMES), { index: ['name'] });
- const props = _.omit(spec, notPropsOptNames);
- const providers = [];
-
- let isInstantiated = false;
- let getInvokedProviders;
- let modules;
-
- /**
- * This is the Private module that will be instantiated by
- *
- * @tag:PrivateModule
- * @return {IndexedArray} - an indexed array containing the values
- * that were registered, the registry spec
- * defines how things will be indexed.
- */
- const registry = function (Private, $injector) {
- getInvokedProviders = function (newProviders) {
- let set = invokeProviders
- ? $injector.invoke(invokeProviders, undefined, { providers: newProviders })
- : newProviders.map(Private);
-
- if (filter && _.isFunction(filter)) {
- set = set.filter((item) => filter(item));
- }
-
- return set;
- };
-
- iaOpts.initialSet = getInvokedProviders(providers);
-
- modules = new IndexedArray(iaOpts);
-
- // mixin other props
- _.assign(modules, props);
-
- // construct
- if (constructor) {
- modules = $injector.invoke(constructor, modules) || modules;
- }
-
- isInstantiated = true;
-
- return modules;
- };
-
- registry.displayName = '[registry ' + props.name + ']';
-
- registry.register = function (privateModule) {
- providers.push(privateModule);
-
- if (isInstantiated) {
- const [provider] = getInvokedProviders([privateModule]);
-
- if (provider) {
- modules.push(provider);
- }
- }
-
- return registry;
- };
-
- return registry;
-}
diff --git a/src/legacy/ui/public/registry/chrome_header_nav_controls.ts b/src/legacy/ui/public/registry/chrome_header_nav_controls.ts
deleted file mode 100644
index 7e6c80692cd63..0000000000000
--- a/src/legacy/ui/public/registry/chrome_header_nav_controls.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { IndexedArray } from '../indexed_array';
-import { uiRegistry, UIRegistry } from './_registry';
-
-interface ChromeHeaderNavControlsRegistryAccessors {
- bySide: { [typeName: string]: IndexedArray };
-}
-
-export enum NavControlSide {
- Left = 'left',
- Right = 'right',
-}
-
-export interface NavControl {
- name: string;
- order: number;
- side: NavControlSide;
- render: (targetDomElement: HTMLDivElement) => () => void;
-}
-
-export type ChromeHeaderNavControlsRegistry = UIRegistry &
- ChromeHeaderNavControlsRegistryAccessors;
-
-export const chromeHeaderNavControlsRegistry = uiRegistry<
- NavControl,
- ChromeHeaderNavControlsRegistryAccessors
->({
- name: 'chromeHeaderNavControls',
- order: ['order'],
- group: ['side'],
-});
diff --git a/src/legacy/ui/public/registry/field_format_editors.ts b/src/legacy/ui/public/registry/field_format_editors.ts
deleted file mode 100644
index 5489ce9250e04..0000000000000
--- a/src/legacy/ui/public/registry/field_format_editors.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiRegistry } from './_registry';
-
-export const RegistryFieldFormatEditorsProvider = uiRegistry({
- name: 'fieldFormatEditors',
- index: ['formatId'],
-});
diff --git a/src/legacy/ui/public/routes/__tests__/_route_manager.js b/src/legacy/ui/public/routes/__tests__/_route_manager.js
deleted file mode 100644
index eb47a3e9ace70..0000000000000
--- a/src/legacy/ui/public/routes/__tests__/_route_manager.js
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import ngMock from 'ng_mock';
-import sinon from 'sinon';
-import RouteManager from '../route_manager';
-import expect from '@kbn/expect';
-
-let routes; // will contain an new instance of RouteManager for each test
-const chainableMethods = [
- { name: 'when', args: ['', {}] },
- { name: 'otherwise', args: [{}] },
- { name: 'defaults', args: [/regexp/, {}] },
-];
-
-let $rp;
-describe('routes/route_manager', function () {
- beforeEach(
- ngMock.module('kibana', function ($routeProvider) {
- $rp = $routeProvider;
- sinon.stub($rp, 'otherwise');
- sinon.stub($rp, 'when');
- })
- );
-
- beforeEach(
- ngMock.inject(function () {
- routes = new RouteManager();
- })
- );
-
- it('should have chainable methods: ' + _.map(chainableMethods, 'name').join(', '), function () {
- chainableMethods.forEach(function (meth) {
- expect(routes[meth.name].apply(routes, _.clone(meth.args))).to.be(routes);
- });
- });
-
- describe('#otherwise', function () {
- it('should forward the last otherwise route', function () {
- const otherRoute = {};
- routes.otherwise({});
- routes.otherwise(otherRoute);
-
- routes.config($rp);
-
- expect($rp.otherwise.callCount).to.be(1);
- expect($rp.otherwise.getCall(0).args[0]).to.be(otherRoute);
- });
- });
-
- describe('#when', function () {
- it('should merge the additions into the when() defined routes', function () {
- routes.when('/some/route');
- routes.when('/some/other/route');
-
- // add the addition resolve to every route
- routes.defaults(/.*/, {
- resolve: {
- addition: function () {},
- },
- });
-
- routes.config($rp);
-
- // should have run once for each when route
- expect($rp.when.callCount).to.be(2);
- expect($rp.otherwise.callCount).to.be(0);
-
- // every route should have the "addition" resolve
- expect($rp.when.getCall(0).args[1].resolve.addition).to.be.a('function');
- expect($rp.when.getCall(1).args[1].resolve.addition).to.be.a('function');
- });
- });
-
- describe('#config', function () {
- it('should add defined routes to the global $routeProvider service in order', function () {
- const args = [
- ['/one', {}],
- ['/two', {}],
- ];
-
- args.forEach(function (a) {
- routes.when(a[0], a[1]);
- });
-
- routes.config($rp);
-
- expect($rp.when.callCount).to.be(args.length);
- _.times(args.length, function (i) {
- const call = $rp.when.getCall(i);
- const a = args.shift();
-
- expect(call.args[0]).to.be(a[0]);
- expect(call.args[1]).to.be(a[1]);
- });
- });
-
- it('sets route.reloadOnSearch to false by default', function () {
- routes.when('/nothing-set');
- routes.when('/no-reload', { reloadOnSearch: false });
- routes.when('/always-reload', { reloadOnSearch: true });
- routes.config($rp);
-
- expect($rp.when.callCount).to.be(3);
- expect($rp.when.firstCall.args[1]).to.have.property('reloadOnSearch', false);
- expect($rp.when.secondCall.args[1]).to.have.property('reloadOnSearch', false);
- expect($rp.when.lastCall.args[1]).to.have.property('reloadOnSearch', true);
- });
- });
-
- describe('#defaults()', () => {
- it('adds defaults to routes with matching paths', () => {
- routes.when('/foo', { name: 'foo' });
- routes.when('/bar', { name: 'bar' });
- routes.when('/baz', { name: 'baz' });
- routes.defaults(/^\/ba/, {
- withDefaults: true,
- });
- routes.config($rp);
-
- sinon.assert.calledWithExactly(
- $rp.when,
- '/foo',
- sinon.match({ name: 'foo', withDefaults: undefined })
- );
- sinon.assert.calledWithExactly(
- $rp.when,
- '/bar',
- sinon.match({ name: 'bar', withDefaults: true })
- );
- sinon.assert.calledWithExactly(
- $rp.when,
- '/baz',
- sinon.match({ name: 'baz', withDefaults: true })
- );
- });
-
- it('does not override values specified in the route', () => {
- routes.when('/foo', { name: 'foo' });
- routes.defaults(/./, { name: 'bar' });
- routes.config($rp);
-
- sinon.assert.calledWithExactly($rp.when, '/foo', sinon.match({ name: 'foo' }));
- });
-
- // See https://github.com/elastic/kibana/issues/13294
- it('does not assign defaults by reference, to prevent accidentally merging unrelated defaults together', () => {
- routes.when('/foo', { name: 'foo' });
- routes.when('/bar', { name: 'bar' });
- routes.when('/baz', { name: 'baz', funcs: { bazFunc() {} } });
-
- // multiple defaults must be defined that, when applied correctly, will
- // create a new object property on all routes that is unique to all of them
- routes.defaults(/./, { funcs: { all() {} } });
- routes.defaults(/^\/foo/, { funcs: { fooFunc() {} } });
- routes.defaults(/^\/bar/, { funcs: { barFunc() {} } });
- routes.config($rp);
-
- sinon.assert.calledThrice($rp.when);
- sinon.assert.calledWithExactly(
- $rp.when,
- '/foo',
- sinon.match({
- name: 'foo',
- funcs: sinon.match({
- all: sinon.match.func,
- fooFunc: sinon.match.func,
- barFunc: undefined,
- bazFunc: undefined,
- }),
- })
- );
- sinon.assert.calledWithExactly(
- $rp.when,
- '/bar',
- sinon.match({
- name: 'bar',
- funcs: sinon.match({
- all: sinon.match.func,
- fooFunc: undefined,
- barFunc: sinon.match.func,
- bazFunc: undefined,
- }),
- })
- );
- sinon.assert.calledWithExactly(
- $rp.when,
- '/baz',
- sinon.match({
- name: 'baz',
- funcs: sinon.match({
- all: sinon.match.func,
- fooFunc: undefined,
- barFunc: undefined,
- bazFunc: sinon.match.func,
- }),
- })
- );
- });
- });
-});
diff --git a/src/legacy/ui/public/routes/__tests__/_work_queue.js b/src/legacy/ui/public/routes/__tests__/_work_queue.js
deleted file mode 100644
index 72891f7321fbd..0000000000000
--- a/src/legacy/ui/public/routes/__tests__/_work_queue.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import { WorkQueue } from '../work_queue';
-import sinon from 'sinon';
-import { createDefer } from 'ui/promises';
-
-describe('work queue', function () {
- let queue;
- let Promise;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_Promise_) {
- Promise = _Promise_;
- })
- );
- beforeEach(function () {
- queue = new WorkQueue();
- });
- afterEach(function () {
- queue.empty();
- });
-
- describe('#push', function () {
- it('adds to the interval queue', function () {
- queue.push(createDefer(Promise));
- expect(queue).to.have.length(1);
- });
- });
-
- describe('#resolveWhenFull', function () {
- it('resolves requests waiting for the queue to fill when appropriate', function () {
- const size = _.random(5, 50);
- queue.limit = size;
-
- const whenFull = createDefer(Promise);
- sinon.stub(whenFull, 'resolve');
- queue.resolveWhenFull(whenFull);
-
- // push all but one into the queue
- _.times(size - 1, function () {
- queue.push(createDefer(Promise));
- });
-
- expect(whenFull.resolve.callCount).to.be(0);
- queue.push(createDefer(Promise));
- expect(whenFull.resolve.callCount).to.be(1);
-
- queue.empty();
- });
- });
-
- /**
- * Fills the queue with a random number of work defers, but stubs all defer methods
- * with the same stub and passed it back.
- *
- * @param {function} then - called with then(size, stub) so that the test
- * can manipulate the filled queue
- */
- function fillWithStubs(then) {
- const size = _.random(5, 50);
- const stub = sinon.stub();
-
- _.times(size, function () {
- const d = createDefer(Promise);
- // overwrite the defer methods with the stub
- d.resolve = stub;
- d.reject = stub;
- queue.push(d);
- });
-
- then(size, stub);
- }
-
- describe('#doWork', function () {
- it('flushes the queue and resolves all promises', function () {
- fillWithStubs(function (size, stub) {
- expect(queue).to.have.length(size);
- queue.doWork();
- expect(queue).to.have.length(0);
- expect(stub.callCount).to.be(size);
- });
- });
- });
-
- describe('#empty()', function () {
- it('empties the internal queue WITHOUT resolving any promises', function () {
- fillWithStubs(function (size, stub) {
- expect(queue).to.have.length(size);
- queue.empty();
- expect(queue).to.have.length(0);
- expect(stub.callCount).to.be(0);
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js b/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js
deleted file mode 100644
index 8ae85fce591a1..0000000000000
--- a/src/legacy/ui/public/routes/__tests__/_wrap_route_with_prep.js
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import RouteManager from '../route_manager';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-
-import _ from 'lodash';
-import '../../private';
-
-let routes;
-
-describe('wrapRouteWithPrep fn', function () {
- require('test_utils/no_digest_promises').activateForSuite();
-
- beforeEach(function () {
- routes = new RouteManager();
- });
-
- const SchedulingTest = function (opts) {
- opts = opts || {};
-
- const delaySetup = opts.delayUserWork ? 0 : 50;
- const delayUserWork = opts.delayUserWork ? 50 : 0;
-
- return function () {
- ngMock.module('kibana');
- let setupComplete = false;
- let userWorkComplete = false;
- let route;
- let Promise;
- let $injector;
-
- ngMock.inject(function (_Promise_, _$injector_) {
- Promise = _Promise_;
- $injector = _$injector_;
- });
-
- routes.addSetupWork(function () {
- return new Promise(function (resolve) {
- setTimeout(function () {
- setupComplete = true;
- resolve();
- }, delaySetup);
- });
- });
-
- routes
- .when('/', {
- resolve: {
- test: function () {
- expect(setupComplete).to.be(true);
- userWorkComplete = true;
- },
- },
- })
- .config({
- when: function (p, _r) {
- route = _r;
- },
- });
-
- return new Promise(function (resolve, reject) {
- setTimeout(function () {
- Promise.all(
- _.map(route.resolve, function (fn) {
- return $injector.invoke(fn);
- })
- )
- .then(function () {
- expect(setupComplete).to.be(true);
- expect(userWorkComplete).to.be(true);
- })
- .then(resolve, reject);
- }, delayUserWork);
- });
- };
- };
-
- it('always waits for setup to complete before calling user work', new SchedulingTest());
-
- it('does not call user work when setup fails', new SchedulingTest({ failSetup: true }));
-
- it(
- 'calls all user work even if it is not initialized until after setup is complete',
- new SchedulingTest({
- delayUserWork: false,
- })
- );
-});
diff --git a/src/legacy/ui/public/routes/__tests__/index.js b/src/legacy/ui/public/routes/__tests__/index.js
deleted file mode 100644
index 30cedaaca3d19..0000000000000
--- a/src/legacy/ui/public/routes/__tests__/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import './_route_manager';
-import './_work_queue';
-import './_wrap_route_with_prep';
-describe('Custom Route Management', function () {});
diff --git a/src/legacy/ui/public/routes/breadcrumbs.js b/src/legacy/ui/public/routes/breadcrumbs.js
deleted file mode 100644
index 7917ffbd7c6e6..0000000000000
--- a/src/legacy/ui/public/routes/breadcrumbs.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { trim, startCase } from 'lodash';
-
-/**
- * Take a path (from $location.path() usually) and parse
- * it's segments into a list of breadcrumbs
- *
- * @param {string} path
- * @return {Array}
- */
-export function parsePathToBreadcrumbs(path) {
- return trim(path, '/')
- .split('/')
- .reduce(
- (acc, id, i, parts) => [
- ...acc,
- {
- id,
- display: startCase(id),
- href: i === 0 ? `#/${id}` : `${acc[i - 1].href}/${id}`,
- current: i === parts.length - 1,
- },
- ],
- []
- );
-}
diff --git a/src/legacy/ui/public/routes/index.d.ts b/src/legacy/ui/public/routes/index.d.ts
deleted file mode 100644
index 84e17b0a69452..0000000000000
--- a/src/legacy/ui/public/routes/index.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiRoutes, UIRoutes } from 'ui/routes/routes';
-
-// eslint-disable-next-line import/no-default-export
-export default uiRoutes;
-export { UIRoutes };
diff --git a/src/legacy/ui/public/routes/index.js b/src/legacy/ui/public/routes/index.js
deleted file mode 100644
index 9c826ebee1230..0000000000000
--- a/src/legacy/ui/public/routes/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { uiRoutes } from './routes';
-
-// eslint-disable-next-line import/no-default-export
-export default uiRoutes;
diff --git a/src/legacy/ui/public/routes/route_manager.d.ts b/src/legacy/ui/public/routes/route_manager.d.ts
deleted file mode 100644
index a5261a7c8ee3a..0000000000000
--- a/src/legacy/ui/public/routes/route_manager.d.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * WARNING: these types are incomplete
- */
-
-import { ChromeBreadcrumb } from '../../../../core/public';
-
-export interface RouteConfiguration {
- controller?: string | ((...args: any[]) => void);
- redirectTo?: string;
- resolveRedirectTo?: (...args: any[]) => void;
- reloadOnSearch?: boolean;
- reloadOnUrl?: boolean;
- outerAngularWrapperRoute?: boolean;
- resolve?: object;
- template?: string;
- k7Breadcrumbs?: (...args: any[]) => ChromeBreadcrumb[];
- requireUICapability?: string;
-}
-
-interface RouteManager {
- addSetupWork(cb: (...args: any[]) => void): void;
- when(path: string, routeConfiguration: RouteConfiguration): RouteManager;
- otherwise(routeConfiguration: RouteConfiguration): RouteManager;
- defaults(path: string | RegExp, defaults: RouteConfiguration): RouteManager;
-}
-
-// eslint-disable-next-line import/no-default-export
-export default RouteManager;
diff --git a/src/legacy/ui/public/routes/route_manager.js b/src/legacy/ui/public/routes/route_manager.js
deleted file mode 100644
index de8a541d1c50a..0000000000000
--- a/src/legacy/ui/public/routes/route_manager.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { cloneDeep, defaultsDeep, wrap } from 'lodash';
-
-import { wrapRouteWithPrep } from './wrap_route_with_prep';
-import { RouteSetupManager } from './route_setup_manager';
-import { parsePathToBreadcrumbs } from './breadcrumbs';
-
-// eslint-disable-next-line import/no-default-export
-export default function RouteManager() {
- const self = this;
- const setup = new RouteSetupManager();
- const when = [];
- const defaults = [];
- let otherwise;
-
- self.config = function ($routeProvider) {
- when.forEach(function (args) {
- const path = args[0];
- const route = args[1] || {};
-
- defaults.forEach((def) => {
- if (def.regex.test(path)) {
- defaultsDeep(route, cloneDeep(def.value));
- }
- });
-
- if (route.reloadOnSearch == null) {
- route.reloadOnSearch = false;
- }
-
- wrapRouteWithPrep(route, setup);
- $routeProvider.when(path, route);
- });
-
- if (otherwise) {
- wrapRouteWithPrep(otherwise, setup);
- $routeProvider.otherwise(otherwise);
- }
- };
-
- self.run = function ($location, $route, $injector, $rootScope) {
- if (window.elasticApm && typeof window.elasticApm.startTransaction === 'function') {
- /**
- * capture route-change events as transactions which happens after
- * the browser's on load event.
- *
- * In Kibana app, this logic would run after the boostrap js files gets
- * downloaded and get associated with the page-load transaction
- */
- $rootScope.$on('$routeChangeStart', (_, nextRoute) => {
- if (nextRoute.$$route) {
- const name = nextRoute.$$route.originalPath;
- window.elasticApm.startTransaction(name, 'route-change');
- }
- });
- }
-
- self.getBreadcrumbs = () => {
- const breadcrumbs = parsePathToBreadcrumbs($location.path());
- const map = $route.current.mapBreadcrumbs;
- return map ? $injector.invoke(map, null, { breadcrumbs }) : breadcrumbs;
- };
- };
-
- const wrapSetupAndChain = (fn, ...args) => {
- fn.apply(setup, args);
- return this;
- };
-
- this.addSetupWork = wrap(setup.addSetupWork, wrapSetupAndChain);
- this.afterSetupWork = wrap(setup.afterSetupWork, wrapSetupAndChain);
- this.afterWork = wrap(setup.afterWork, wrapSetupAndChain);
-
- self.when = function (path, route) {
- when.push([path, route]);
- return self;
- };
-
- // before attaching the routes to the routeProvider, test the RE
- // against the .when() path and add/override the resolves if there is a match
- self.defaults = function (regex, value) {
- defaults.push({ regex, value });
- return self;
- };
-
- self.otherwise = function (route) {
- otherwise = route;
- return self;
- };
-
- self.getBreadcrumbs = function () {
- // overwritten in self.run();
- return [];
- };
-
- self.RouteManager = RouteManager;
-}
diff --git a/src/legacy/ui/public/routes/route_setup_manager.js b/src/legacy/ui/public/routes/route_setup_manager.js
deleted file mode 100644
index a7a2f078f40fb..0000000000000
--- a/src/legacy/ui/public/routes/route_setup_manager.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { createDefer } from 'ui/promises';
-
-// Throw this inside of an Angular route resolver after calling `kbnUrl.change`
-// so that the $router can observe the $location update. Otherwise, the location
-// route setup work will resolve before the route update occurs.
-export const WAIT_FOR_URL_CHANGE_TOKEN = new Error('WAIT_FOR_URL_CHANGE_TOKEN');
-
-export class RouteSetupManager {
- constructor() {
- this.setupWork = [];
- this.onSetupComplete = [];
- this.onSetupError = [];
- this.onWorkComplete = [];
- this.onWorkError = [];
- }
-
- addSetupWork(fn) {
- this.setupWork.push(fn);
- }
-
- afterSetupWork(onComplete, onError) {
- this.onSetupComplete.push(onComplete);
- this.onSetupError.push(onError);
- }
-
- afterWork(onComplete, onError) {
- this.onWorkComplete.push(onComplete);
- this.onWorkError.push(onError);
- }
-
- /**
- * Do each setupWork function by injecting it with angular dependencies
- * and accepting promises from it.
- * @return {[type]} [description]
- */
- doWork(Promise, $injector, userWork) {
- const invokeEach = (arr, locals) => {
- return Promise.map(arr, (fn) => {
- if (!fn) return;
- return $injector.invoke(fn, null, locals);
- });
- };
-
- // call each error handler in order, until one of them resolves
- // or we run out of handlers
- const callErrorHandlers = (handlers, origError) => {
- if (!_.size(handlers)) throw origError;
-
- // clone so we don't discard handlers or loose them
- handlers = handlers.slice(0);
-
- const next = (err) => {
- if (!handlers.length) throw err;
-
- const handler = handlers.shift();
- if (!handler) return next(err);
-
- return Promise.try(function () {
- return $injector.invoke(handler, null, { err });
- }).catch(next);
- };
-
- return next(origError);
- };
-
- return invokeEach(this.setupWork)
- .then(
- () => invokeEach(this.onSetupComplete),
- (err) => callErrorHandlers(this.onSetupError, err)
- )
- .then(() => {
- // wait for the queue to fill up, then do all the work
- const defer = createDefer(Promise);
- userWork.resolveWhenFull(defer);
-
- return defer.promise.then(() => Promise.all(userWork.doWork()));
- })
- .catch((error) => {
- if (error === WAIT_FOR_URL_CHANGE_TOKEN) {
- // prevent moving forward, return a promise that never resolves
- // so that the $router can observe the $location update
- return Promise.halt();
- }
-
- throw error;
- })
- .then(
- () => invokeEach(this.onWorkComplete),
- (err) => callErrorHandlers(this.onWorkError, err)
- );
- }
-}
diff --git a/src/legacy/ui/public/routes/routes.d.ts b/src/legacy/ui/public/routes/routes.d.ts
deleted file mode 100644
index d48230e9d56f9..0000000000000
--- a/src/legacy/ui/public/routes/routes.d.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import RouteManager from 'ui/routes/route_manager';
-
-interface DefaultRouteManager extends RouteManager {
- WAIT_FOR_URL_CHANGE_TOKEN: string;
- enable(): void;
-}
-
-export const uiRoutes: DefaultRouteManager;
-export type UIRoutes = DefaultRouteManager;
diff --git a/src/legacy/ui/public/routes/routes.js b/src/legacy/ui/public/routes/routes.js
deleted file mode 100644
index 2cfb7a608e853..0000000000000
--- a/src/legacy/ui/public/routes/routes.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import RouteManager from './route_manager';
-import 'angular-route/angular-route';
-import { uiModules } from '../modules';
-import { WAIT_FOR_URL_CHANGE_TOKEN } from './route_setup_manager';
-const defaultRouteManager = new RouteManager();
-
-export const uiRoutes = Object.create(defaultRouteManager, {
- WAIT_FOR_URL_CHANGE_TOKEN: {
- value: WAIT_FOR_URL_CHANGE_TOKEN,
- },
-
- enable: {
- value() {
- uiModules
- .get('kibana', ['ngRoute'])
- .config(defaultRouteManager.config)
- .run(defaultRouteManager.run);
- },
- },
-});
diff --git a/src/legacy/ui/public/routes/work_queue.js b/src/legacy/ui/public/routes/work_queue.js
deleted file mode 100644
index 5c4c83663c590..0000000000000
--- a/src/legacy/ui/public/routes/work_queue.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export function WorkQueue() {
- const q = this;
-
- const work = [];
- const fullDefers = [];
-
- q.limit = 0;
- Object.defineProperty(q, 'length', {
- get: function () {
- return work.length;
- },
- });
-
- const resolve = function (defers) {
- return defers.splice(0).map(function (defer) {
- return defer.resolve();
- });
- };
-
- const checkIfFull = function () {
- if (work.length >= q.limit && fullDefers.length) {
- resolve(fullDefers);
- }
- };
-
- q.resolveWhenFull = function (defer) {
- fullDefers.push(defer);
- checkIfFull();
- };
-
- q.doWork = function () {
- const resps = resolve(work);
- checkIfFull();
- return resps;
- };
-
- q.empty = function () {
- work.splice(0);
- checkIfFull();
- };
-
- q.push = function (defer) {
- work.push(defer);
- checkIfFull();
- };
-}
diff --git a/src/legacy/ui/public/routes/wrap_route_with_prep.js b/src/legacy/ui/public/routes/wrap_route_with_prep.js
deleted file mode 100644
index e9ed33148d9ac..0000000000000
--- a/src/legacy/ui/public/routes/wrap_route_with_prep.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import angular from 'angular';
-import _ from 'lodash';
-import { createDefer } from 'ui/promises';
-import { WorkQueue } from './work_queue';
-
-export function wrapRouteWithPrep(route, setup) {
- if (!route.resolve && route.redirectTo) return;
-
- const userWork = new WorkQueue();
- // the point at which we will consider the queue "full"
- userWork.limit = _.keys(route.resolve).length;
-
- const resolve = {
- __prep__: function ($injector) {
- return $injector.invoke(setup.doWork, setup, { userWork });
- },
- };
-
- // send each user resolve to the userWork queue, which will prevent it from running before the
- // prep is complete
- _.forOwn(route.resolve || {}, function (expr, name) {
- resolve[name] = function ($injector, Promise) {
- const defer = createDefer(Promise);
- userWork.push(defer);
- return defer.promise.then(function () {
- return $injector[angular.isString(expr) ? 'get' : 'invoke'](expr);
- });
- };
- });
-
- // we're copied everything over so now overwrite
- route.resolve = resolve;
-}
diff --git a/src/legacy/ui/public/state_management/__tests__/app_state.js b/src/legacy/ui/public/state_management/__tests__/app_state.js
deleted file mode 100644
index c47fa3bb0417f..0000000000000
--- a/src/legacy/ui/public/state_management/__tests__/app_state.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import { AppStateProvider } from '../app_state';
-
-describe('State Management', function () {
- let $rootScope;
- let AppState;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_$rootScope_, _$location_, Private) {
- $rootScope = _$rootScope_;
- AppState = Private(AppStateProvider);
- })
- );
-
- describe('App State', function () {
- let appState;
-
- beforeEach(function () {
- appState = new AppState();
- });
-
- it('should have _urlParam of _a', function () {
- expect(appState).to.have.property('_urlParam');
- expect(appState._urlParam).to.equal('_a');
- });
-
- it('should use passed in params', function () {
- const params = {
- test: true,
- mock: false,
- };
-
- appState = new AppState(params);
- expect(appState).to.have.property('_defaults');
-
- Object.keys(params).forEach(function (key) {
- expect(appState._defaults).to.have.property(key);
- expect(appState._defaults[key]).to.equal(params[key]);
- });
- });
-
- it('should have a destroy method', function () {
- expect(appState).to.have.property('destroy');
- });
-
- it('should be destroyed on $routeChangeStart', function () {
- const destroySpy = sinon.spy(appState, 'destroy');
-
- $rootScope.$emit('$routeChangeStart');
-
- expect(destroySpy.callCount).to.be(1);
- });
- });
-});
diff --git a/src/legacy/ui/public/state_management/__tests__/config_provider.js b/src/legacy/ui/public/state_management/__tests__/config_provider.js
deleted file mode 100644
index 9f756bc51dcb0..0000000000000
--- a/src/legacy/ui/public/state_management/__tests__/config_provider.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import '../config_provider';
-
-describe('State Management Config', function () {
- let stateManagementConfig;
-
- describe('is enabled', () => {
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_stateManagementConfig_) {
- stateManagementConfig = _stateManagementConfig_;
- })
- );
-
- it('should be enabled by default', () => {
- expect(stateManagementConfig.enabled).to.be(true);
- });
- });
-
- describe('can be disabled', () => {
- beforeEach(
- ngMock.module('kibana', function (stateManagementConfigProvider) {
- stateManagementConfigProvider.disable();
- })
- );
-
- beforeEach(
- ngMock.inject(function (_stateManagementConfig_) {
- stateManagementConfig = _stateManagementConfig_;
- })
- );
-
- it('is disabled by config', () => {
- expect(stateManagementConfig.enabled).to.be(false);
- });
- });
-});
diff --git a/src/legacy/ui/public/state_management/__tests__/global_state.js b/src/legacy/ui/public/state_management/__tests__/global_state.js
deleted file mode 100644
index e9dae5880a8d1..0000000000000
--- a/src/legacy/ui/public/state_management/__tests__/global_state.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import '../global_state';
-
-describe('State Management', function () {
- let $location;
- let state;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_$location_, globalState) {
- $location = _$location_;
- state = globalState;
- })
- );
-
- describe('Global State', function () {
- it('should use previous state when not in URL', function () {
- // set satte via URL
- $location.search({ _g: '(foo:(bar:baz))' });
- state.fetch();
- expect(state.toObject()).to.eql({ foo: { bar: 'baz' } });
-
- $location.search({ _g: '(fizz:buzz)' });
- state.fetch();
- expect(state.toObject()).to.eql({ fizz: 'buzz' });
-
- $location.search({});
- state.fetch();
- expect(state.toObject()).to.eql({ fizz: 'buzz' });
- });
- });
-});
diff --git a/src/legacy/ui/public/state_management/__tests__/state.js b/src/legacy/ui/public/state_management/__tests__/state.js
deleted file mode 100644
index b6c705e814509..0000000000000
--- a/src/legacy/ui/public/state_management/__tests__/state.js
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import { encode as encodeRison } from 'rison-node';
-import uiRoutes from 'ui/routes';
-import '../../private';
-import { toastNotifications } from '../../notify';
-import * as FatalErrorNS from '../../notify/fatal_error';
-import { StateProvider } from '../state';
-import {
- unhashQuery,
- createStateHash,
- isStateHash,
- HashedItemStore,
-} from '../../../../../plugins/kibana_utils/public';
-import { StubBrowserStorage } from 'test_utils/stub_browser_storage';
-import { EventsProvider } from '../../events';
-
-describe('State Management', () => {
- const sandbox = sinon.createSandbox();
- afterEach(() => sandbox.restore());
-
- uiRoutes.enable();
-
- describe('Enabled', () => {
- let $rootScope;
- let $location;
- let Events;
- let setup;
-
- beforeEach(ngMock.module('kibana'));
- beforeEach(
- ngMock.inject(function (_$rootScope_, _$location_, Private, config) {
- const State = Private(StateProvider);
- $location = _$location_;
- $rootScope = _$rootScope_;
- Events = Private(EventsProvider);
-
- setup = (opts) => {
- const { param, initial, storeInHash } = opts || {};
- sinon.stub(config, 'get').withArgs('state:storeInSessionStorage').returns(!!storeInHash);
- const store = new StubBrowserStorage();
- const hashedItemStore = new HashedItemStore(store);
- const state = new State(param, initial, hashedItemStore);
-
- const getUnhashedSearch = () => unhashQuery($location.search());
-
- return { store, hashedItemStore, state, getUnhashedSearch };
- };
- })
- );
-
- describe('Provider', () => {
- it('should reset the state to the defaults', () => {
- const { state, getUnhashedSearch } = setup({ initial: { message: ['test'] } });
- state.reset();
- const search = getUnhashedSearch(state);
- expect(search).to.have.property('_s');
- expect(search._s).to.equal('(message:!(test))');
- expect(state.message).to.eql(['test']);
- });
-
- it('should apply the defaults upon initialization', () => {
- const { state } = setup({ initial: { message: 'test' } });
- expect(state).to.have.property('message', 'test');
- });
-
- it('should inherit from Events', () => {
- const { state } = setup();
- expect(state).to.be.an(Events);
- });
-
- it('should emit an event if reset with changes', (done) => {
- const { state } = setup({ initial: { message: ['test'] } });
- state.on('reset_with_changes', (keys) => {
- expect(keys).to.eql(['message']);
- done();
- });
- state.save();
- state.message = 'foo';
- state.reset();
- $rootScope.$apply();
- });
-
- it('should not emit an event if reset without changes', () => {
- const { state } = setup({ initial: { message: 'test' } });
- state.on('reset_with_changes', () => {
- expect().fail();
- });
- state.save();
- state.message = 'test';
- state.reset();
- $rootScope.$apply();
- });
- });
-
- describe('Search', () => {
- it('should save to $location.search()', () => {
- const { state, getUnhashedSearch } = setup({ initial: { test: 'foo' } });
- state.save();
- const search = getUnhashedSearch(state);
- expect(search).to.have.property('_s');
- expect(search._s).to.equal('(test:foo)');
- });
-
- it('should emit an event if changes are saved', (done) => {
- const { state, getUnhashedSearch } = setup();
- state.on('save_with_changes', (keys) => {
- expect(keys).to.eql(['test']);
- done();
- });
- state.test = 'foo';
- state.save();
- getUnhashedSearch(state);
- $rootScope.$apply();
- });
- });
-
- describe('Fetch', () => {
- it('should emit an event if changes are fetched', (done) => {
- const { state } = setup();
- state.on('fetch_with_changes', (keys) => {
- expect(keys).to.eql(['foo']);
- done();
- });
- $location.search({ _s: '(foo:bar)' });
- state.fetch();
- expect(state).to.have.property('foo', 'bar');
- $rootScope.$apply();
- });
-
- it('should have events that attach to scope', (done) => {
- const { state } = setup();
- state.on('test', (message) => {
- expect(message).to.equal('foo');
- done();
- });
- state.emit('test', 'foo');
- $rootScope.$apply();
- });
-
- it('should fire listeners for #onUpdate() on #fetch()', (done) => {
- const { state } = setup();
- state.on('fetch_with_changes', (keys) => {
- expect(keys).to.eql(['foo']);
- done();
- });
- $location.search({ _s: '(foo:bar)' });
- state.fetch();
- expect(state).to.have.property('foo', 'bar');
- $rootScope.$apply();
- });
-
- it('should apply defaults to fetches', () => {
- const { state } = setup({ initial: { message: 'test' } });
- $location.search({ _s: '(foo:bar)' });
- state.fetch();
- expect(state).to.have.property('foo', 'bar');
- expect(state).to.have.property('message', 'test');
- });
-
- it('should call fetch when $routeUpdate is fired on $rootScope', () => {
- const { state } = setup();
- const spy = sinon.spy(state, 'fetch');
- $rootScope.$emit('$routeUpdate', 'test');
- sinon.assert.calledOnce(spy);
- });
-
- it('should clear state when missing form URL', () => {
- let stateObj;
- const { state } = setup();
-
- // set state via URL
- $location.search({ _s: '(foo:(bar:baz))' });
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({ foo: { bar: 'baz' } });
-
- // ensure changing URL changes state
- $location.search({ _s: '(one:two)' });
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({ one: 'two' });
-
- // remove search, state should be empty
- $location.search({});
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({});
- });
-
- it('should clear state when it is invalid', () => {
- let stateObj;
- const { state } = setup();
-
- $location.search({ _s: '' });
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({});
-
- $location.search({ _s: '!n' });
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({});
-
- $location.search({ _s: 'alert(1)' });
- state.fetch();
- stateObj = state.toObject();
- expect(stateObj).to.eql({});
- });
-
- it('does not replace the state value on read', () => {
- const { state } = setup();
- sinon.stub($location, 'search').callsFake((newSearch) => {
- if (newSearch) {
- return $location;
- } else {
- return {
- [state.getQueryParamName()]: '(a:1)',
- };
- }
- });
- const replaceStub = sinon.stub($location, 'replace').returns($location);
-
- state.fetch();
- sinon.assert.notCalled(replaceStub);
- });
- });
-
- describe('Hashing', () => {
- it('stores state values in a hashedItemStore, writing the hash to the url', () => {
- const { state, hashedItemStore } = setup({ storeInHash: true });
- state.foo = 'bar';
- state.save();
- const urlVal = $location.search()[state.getQueryParamName()];
-
- expect(isStateHash(urlVal)).to.be(true);
- expect(hashedItemStore.getItem(urlVal)).to.eql(JSON.stringify({ foo: 'bar' }));
- });
-
- it('should replace rison in the URL with a hash', () => {
- const { state, hashedItemStore } = setup({ storeInHash: true });
- const obj = { foo: { bar: 'baz' } };
- const rison = encodeRison(obj);
-
- $location.search({ _s: rison });
- state.fetch();
-
- const urlVal = $location.search()._s;
- expect(urlVal).to.not.be(rison);
- expect(isStateHash(urlVal)).to.be(true);
- expect(hashedItemStore.getItem(urlVal)).to.eql(JSON.stringify(obj));
- });
-
- describe('error handling', () => {
- it('notifies the user when a hash value does not map to a stored value', () => {
- // Ideally, state.js shouldn't be tightly coupled to toastNotifications. Instead, it
- // should notify its consumer of this error state and the consumer should be responsible
- // for notifying the user of the error. This test verifies the side effect of the error
- // until we can remove this coupling.
-
- // Clear existing toasts.
- toastNotifications.list.splice(0);
-
- const { state } = setup({ storeInHash: true });
- const search = $location.search();
- const badHash = createStateHash('{"a": "b"}', () => null);
-
- search[state.getQueryParamName()] = badHash;
- $location.search(search);
-
- expect(toastNotifications.list).to.have.length(0);
- state.fetch();
- expect(toastNotifications.list).to.have.length(1);
- expect(toastNotifications.list[0].title).to.match(/use the share functionality/i);
- });
-
- it.skip('triggers fatal error linking to github when setting item fails', () => {
- // NOTE: this test needs to be written in jest and removed from the browser ones
- // More info could be read in the opened issue:
- // https://github.com/elastic/kibana/issues/22751
- const { state, hashedItemStore } = setup({ storeInHash: true });
- const fatalErrorStub = sandbox.stub();
- Object.defineProperty(FatalErrorNS, 'fatalError', {
- writable: true,
- value: fatalErrorStub,
- });
-
- sandbox.stub(hashedItemStore, 'setItem').returns(false);
- state.toQueryParam();
- sinon.assert.calledOnce(fatalErrorStub);
- sinon.assert.calledWith(
- fatalErrorStub,
- sinon.match((error) => error instanceof Error && error.message.includes('github.com'))
- );
- });
-
- it('translateHashToRison should gracefully fallback if parameter can not be parsed', () => {
- const { state, hashedItemStore } = setup({ storeInHash: false });
-
- expect(state.translateHashToRison('(a:b)')).to.be('(a:b)');
- expect(state.translateHashToRison('')).to.be('');
-
- const existingHash = createStateHash('{"a": "b"}', () => null);
- hashedItemStore.setItem(existingHash, '{"a": "b"}');
-
- const nonExistingHash = createStateHash('{"b": "c"}', () => null);
-
- expect(state.translateHashToRison(existingHash)).to.be('(a:b)');
- expect(state.translateHashToRison(nonExistingHash)).to.be('!n');
- });
- });
- });
- });
-
- describe('Disabled with persisted state', () => {
- let state;
- let $location;
- let $rootScope;
- const stateParam = '_config_test';
-
- const getLocationState = () => {
- const search = $location.search();
- return search[stateParam];
- };
-
- beforeEach(
- ngMock.module('kibana', function (stateManagementConfigProvider) {
- stateManagementConfigProvider.disable();
- })
- );
- beforeEach(
- ngMock.inject(function (_$rootScope_, _$location_, Private, config) {
- const State = Private(StateProvider);
- $location = _$location_;
- $rootScope = _$rootScope_;
-
- sinon.stub(config, 'get').withArgs('state:storeInSessionStorage').returns(false);
-
- class MockPersistedState extends State {
- _persistAcrossApps = true;
- }
-
- MockPersistedState.prototype._persistAcrossApps = true;
-
- state = new MockPersistedState(stateParam);
- })
- );
-
- describe('changing state', () => {
- const methods = ['save', 'replace', 'reset'];
-
- methods.forEach((method) => {
- it(`${method} should not change the URL`, () => {
- $location.search({ _s: '(foo:bar)' });
- state[method]();
- $rootScope.$apply();
- expect(getLocationState()).to.be(undefined);
- });
- });
- });
-
- describe('reading state', () => {
- it('should not change the URL', () => {
- const saveSpy = sinon.spy(state, 'save');
- $location.search({ _s: '(foo:bar)' });
- state.fetch();
- $rootScope.$apply();
- sinon.assert.notCalled(saveSpy);
- expect(getLocationState()).to.be(undefined);
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js b/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js
deleted file mode 100644
index dc00d4e05e82f..0000000000000
--- a/src/legacy/ui/public/state_management/__tests__/state_monitor_factory.js
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-import { EventEmitter } from 'events';
-import { cloneDeep } from 'lodash';
-import { stateMonitorFactory } from '../state_monitor_factory';
-
-describe('stateMonitorFactory', function () {
- const noop = () => {};
- const eventTypes = ['save_with_changes', 'reset_with_changes', 'fetch_with_changes'];
-
- let mockState;
-
- function setState(mockState, obj, emit = true) {
- mockState.toJSON = () => cloneDeep(obj);
- if (emit) mockState.emit(eventTypes[0]);
- }
-
- function createMockState(state = {}) {
- const mockState = new EventEmitter();
- setState(mockState, state, false);
- return mockState;
- }
-
- beforeEach(() => {
- mockState = createMockState({});
- });
-
- it('should have a create method', function () {
- expect(stateMonitorFactory).to.have.property('create');
- expect(stateMonitorFactory.create).to.be.a('function');
- });
-
- describe('factory creation', function () {
- it('should not call onChange with only the state', function () {
- const monitor = stateMonitorFactory.create(mockState);
- const changeStub = sinon.stub();
- monitor.onChange(changeStub);
- sinon.assert.notCalled(changeStub);
- });
-
- it('should not call onChange with matching defaultState', function () {
- const monitor = stateMonitorFactory.create(mockState, {});
- const changeStub = sinon.stub();
- monitor.onChange(changeStub);
- sinon.assert.notCalled(changeStub);
- });
-
- it('should call onChange with differing defaultState', function () {
- const monitor = stateMonitorFactory.create(mockState, { test: true });
- const changeStub = sinon.stub();
- monitor.onChange(changeStub);
- sinon.assert.calledOnce(changeStub);
- });
- });
-
- describe('instance', function () {
- let monitor;
-
- beforeEach(() => {
- monitor = stateMonitorFactory.create(mockState);
- });
-
- describe('onChange', function () {
- it('should throw if not given a handler function', function () {
- const fn = () => monitor.onChange('not a function');
- expect(fn).to.throwException(/must be a function/);
- });
-
- eventTypes.forEach((eventType) => {
- describe(`when ${eventType} is emitted`, function () {
- let handlerFn;
-
- beforeEach(() => {
- handlerFn = sinon.stub();
- monitor.onChange(handlerFn);
- sinon.assert.notCalled(handlerFn);
- });
-
- it('should get called', function () {
- mockState.emit(eventType);
- sinon.assert.calledOnce(handlerFn);
- });
-
- it('should be given the state status', function () {
- mockState.emit(eventType);
- const args = handlerFn.firstCall.args;
- expect(args[0]).to.be.an('object');
- });
-
- it('should be given the event type', function () {
- mockState.emit(eventType);
- const args = handlerFn.firstCall.args;
- expect(args[1]).to.equal(eventType);
- });
-
- it('should be given the changed keys', function () {
- const keys = ['one', 'two', 'three'];
- mockState.emit(eventType, keys);
- const args = handlerFn.firstCall.args;
- expect(args[2]).to.equal(keys);
- });
- });
- });
- });
-
- describe('ignoreProps', function () {
- it('should not set status to dirty when ignored properties change', function () {
- let status;
- const mockState = createMockState({ messages: { world: 'hello', foo: 'bar' } });
- const monitor = stateMonitorFactory.create(mockState);
- const changeStub = sinon.stub();
- monitor.ignoreProps('messages.world');
- monitor.onChange(changeStub);
- sinon.assert.notCalled(changeStub);
-
- // update the ignored state prop
- setState(mockState, { messages: { world: 'howdy', foo: 'bar' } });
- sinon.assert.calledOnce(changeStub);
- status = changeStub.firstCall.args[0];
- expect(status).to.have.property('clean', true);
- expect(status).to.have.property('dirty', false);
-
- // update a prop that is not ignored
- setState(mockState, { messages: { world: 'howdy', foo: 'baz' } });
- sinon.assert.calledTwice(changeStub);
- status = changeStub.secondCall.args[0];
- expect(status).to.have.property('clean', false);
- expect(status).to.have.property('dirty', true);
- });
- });
-
- describe('setInitialState', function () {
- let changeStub;
-
- beforeEach(() => {
- changeStub = sinon.stub();
- monitor.onChange(changeStub);
- sinon.assert.notCalled(changeStub);
- });
-
- it('should throw if no state is provided', function () {
- const fn = () => monitor.setInitialState();
- expect(fn).to.throwException(/must be an object/);
- });
-
- it('should throw if given the wrong type', function () {
- const fn = () => monitor.setInitialState([]);
- expect(fn).to.throwException(/must be an object/);
- });
-
- it('should trigger the onChange handler', function () {
- monitor.setInitialState({ new: 'state' });
- sinon.assert.calledOnce(changeStub);
- });
-
- it('should change the status with differing state', function () {
- monitor.setInitialState({ new: 'state' });
- sinon.assert.calledOnce(changeStub);
-
- const status = changeStub.firstCall.args[0];
- expect(status).to.have.property('clean', false);
- expect(status).to.have.property('dirty', true);
- });
-
- it('should not trigger the onChange handler without state change', function () {
- monitor.setInitialState(cloneDeep(mockState.toJSON()));
- sinon.assert.notCalled(changeStub);
- });
- });
-
- describe('status object', function () {
- let handlerFn;
-
- beforeEach(() => {
- handlerFn = sinon.stub();
- monitor.onChange(handlerFn);
- });
-
- it('should be clean by default', function () {
- mockState.emit(eventTypes[0]);
- const status = handlerFn.firstCall.args[0];
- expect(status).to.have.property('clean', true);
- expect(status).to.have.property('dirty', false);
- });
-
- it('should be dirty when state changes', function () {
- setState(mockState, { message: 'i am dirty now' });
- const status = handlerFn.firstCall.args[0];
- expect(status).to.have.property('clean', false);
- expect(status).to.have.property('dirty', true);
- });
-
- it('should be clean when state is reset', function () {
- const defaultState = { message: 'i am the original state' };
- const handlerFn = sinon.stub();
-
- let status;
-
- // initial state and monitor setup
- const mockState = createMockState(defaultState);
- const monitor = stateMonitorFactory.create(mockState);
- monitor.onChange(handlerFn);
- sinon.assert.notCalled(handlerFn);
-
- // change the state and emit an event
- setState(mockState, { message: 'i am dirty now' });
- sinon.assert.calledOnce(handlerFn);
- status = handlerFn.firstCall.args[0];
- expect(status).to.have.property('clean', false);
- expect(status).to.have.property('dirty', true);
-
- // reset the state and emit an event
- setState(mockState, defaultState);
- sinon.assert.calledTwice(handlerFn);
- status = handlerFn.secondCall.args[0];
- expect(status).to.have.property('clean', true);
- expect(status).to.have.property('dirty', false);
- });
- });
-
- describe('destroy', function () {
- let stateSpy;
-
- beforeEach(() => {
- stateSpy = sinon.spy(mockState, 'off');
- sinon.assert.notCalled(stateSpy);
- });
-
- it('should remove the listeners', function () {
- monitor.onChange(noop);
- monitor.destroy();
- sinon.assert.callCount(stateSpy, eventTypes.length);
- eventTypes.forEach((eventType) => {
- sinon.assert.calledWith(stateSpy, eventType);
- });
- });
-
- it('should stop the instance from being used any more', function () {
- monitor.onChange(noop);
- monitor.destroy();
- const fn = () => monitor.onChange(noop);
- expect(fn).to.throwException(/has been destroyed/);
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/state_management/app_state.d.ts b/src/legacy/ui/public/state_management/app_state.d.ts
deleted file mode 100644
index ddd0b90710766..0000000000000
--- a/src/legacy/ui/public/state_management/app_state.d.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { State } from './state';
-
-export class AppState extends State {}
-
-export type AppStateClass<
- TAppState extends AppState = AppState,
- TDefaults = { [key: string]: any }
-> = new (defaults: TDefaults) => TAppState;
diff --git a/src/legacy/ui/public/state_management/app_state.js b/src/legacy/ui/public/state_management/app_state.js
deleted file mode 100644
index ec680d163b9da..0000000000000
--- a/src/legacy/ui/public/state_management/app_state.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @name AppState
- *
- * @extends State
- *
- * @description Inherits State, which inherits Events. This class seems to be
- * concerned with mapping "props" to PersistedState instances, and surfacing the
- * ability to destroy those mappings.
- */
-
-import { uiModules } from '../modules';
-import { StateProvider } from './state';
-import { PersistedState } from '../../../../plugins/visualizations/public';
-import { createLegacyClass } from '../utils/legacy_class';
-
-const urlParam = '_a';
-
-export function AppStateProvider(Private, $location) {
- const State = Private(StateProvider);
-
- let persistedStates;
- let eventUnsubscribers;
-
- createLegacyClass(AppState).inherits(State);
- function AppState(defaults) {
- // Initialize persistedStates. This object maps "prop" names to
- // PersistedState instances. These are used to make properties "stateful".
- persistedStates = {};
-
- // Initialize eventUnsubscribers. These will be called in `destroy`, to
- // remove handlers for the 'change' and 'fetch_with_changes' events which
- // are dispatched via the rootScope.
- eventUnsubscribers = [];
-
- AppState.Super.call(this, urlParam, defaults);
- AppState.getAppState._set(this);
- }
-
- // if the url param is missing, write it back
- AppState.prototype._persistAcrossApps = false;
-
- AppState.prototype.destroy = function () {
- AppState.Super.prototype.destroy.call(this);
- AppState.getAppState._set(null);
-
- eventUnsubscribers.forEach((listener) => listener());
- };
-
- /**
- * @returns PersistedState instance.
- */
- AppState.prototype.makeStateful = function (prop) {
- if (persistedStates[prop]) return persistedStates[prop];
- const self = this;
-
- // set up the ui state
- persistedStates[prop] = new PersistedState();
-
- // update the app state when the stateful instance changes
- const updateOnChange = function () {
- const replaceState = false; // TODO: debouncing logic
- self[prop] = persistedStates[prop].getChanges();
- // Save state to the URL.
- self.save(replaceState);
- };
- const handlerOnChange = (method) => persistedStates[prop][method]('change', updateOnChange);
- handlerOnChange('on');
- eventUnsubscribers.push(() => handlerOnChange('off'));
-
- // update the stateful object when the app state changes
- const persistOnChange = function (changes) {
- if (!changes) return;
-
- if (changes.indexOf(prop) !== -1) {
- persistedStates[prop].set(self[prop]);
- }
- };
- const handlePersist = (method) => this[method]('fetch_with_changes', persistOnChange);
- handlePersist('on');
- eventUnsubscribers.push(() => handlePersist('off'));
-
- // if the thing we're making stateful has an appState value, write to persisted state
- if (self[prop]) persistedStates[prop].setSilent(self[prop]);
-
- return persistedStates[prop];
- };
-
- AppState.getAppState = (function () {
- let currentAppState;
-
- function get() {
- return currentAppState;
- }
-
- // Checks to see if the appState might already exist, even if it hasn't been newed up
- get.previouslyStored = function () {
- const search = $location.search();
- return search[urlParam] ? true : false;
- };
-
- get._set = function (current) {
- currentAppState = current;
- };
-
- return get;
- })();
-
- return AppState;
-}
-
-uiModules
- .get('kibana/global_state')
- .factory('AppState', function (Private) {
- return Private(AppStateProvider);
- })
- .service('getAppState', function (Private) {
- return Private(AppStateProvider).getAppState;
- });
diff --git a/src/legacy/ui/public/state_management/config_provider.js b/src/legacy/ui/public/state_management/config_provider.js
deleted file mode 100644
index 68de449a57a56..0000000000000
--- a/src/legacy/ui/public/state_management/config_provider.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @name stateManagementConfig
- *
- * @description Allows apps to configure state management
- */
-
-import { uiModules } from '../modules';
-
-export class StateManagementConfigProvider {
- _enabled = true;
-
- $get(/* inject stuff */) {
- return {
- enabled: this._enabled,
- };
- }
-
- disable() {
- this._enabled = false;
- }
-
- enable() {
- this._enabled = true;
- }
-}
-
-uiModules
- .get('kibana/state_management')
- .provider('stateManagementConfig', StateManagementConfigProvider);
diff --git a/src/legacy/ui/public/state_management/global_state.d.ts b/src/legacy/ui/public/state_management/global_state.d.ts
deleted file mode 100644
index 66a85d88956c7..0000000000000
--- a/src/legacy/ui/public/state_management/global_state.d.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { State } from './state';
-
-export type GlobalState = State;
diff --git a/src/legacy/ui/public/state_management/global_state.js b/src/legacy/ui/public/state_management/global_state.js
deleted file mode 100644
index 0e8dfe40d5950..0000000000000
--- a/src/legacy/ui/public/state_management/global_state.js
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { StateProvider } from './state';
-import { uiModules } from '../modules';
-import { createLegacyClass } from '../utils/legacy_class';
-
-const module = uiModules.get('kibana/global_state');
-
-export function GlobalStateProvider(Private) {
- const State = Private(StateProvider);
-
- createLegacyClass(GlobalState).inherits(State);
- function GlobalState(defaults) {
- GlobalState.Super.call(this, '_g', defaults);
- }
-
- // if the url param is missing, write it back
- GlobalState.prototype._persistAcrossApps = true;
-
- return new GlobalState();
-}
-
-module.service('globalState', function (Private) {
- return Private(GlobalStateProvider);
-});
diff --git a/src/legacy/ui/public/state_management/state.d.ts b/src/legacy/ui/public/state_management/state.d.ts
deleted file mode 100644
index b31862b681f55..0000000000000
--- a/src/legacy/ui/public/state_management/state.d.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export class State {
- [key: string]: any;
- translateHashToRison: (stateHashOrRison: string | string[]) => string | string[];
- getQueryParamName: () => string;
-}
diff --git a/src/legacy/ui/public/state_management/state.js b/src/legacy/ui/public/state_management/state.js
deleted file mode 100644
index d91834adb4a79..0000000000000
--- a/src/legacy/ui/public/state_management/state.js
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * @name State
- *
- * @extends Events
- *
- * @description Persists generic "state" to and reads it from the URL.
- */
-
-import _ from 'lodash';
-import { i18n } from '@kbn/i18n';
-import angular from 'angular';
-import rison from 'rison-node';
-import { EventsProvider } from '../events';
-import { fatalError, toastNotifications } from '../notify';
-import './config_provider';
-import { createLegacyClass } from '../utils/legacy_class';
-import {
- hashedItemStore,
- isStateHash,
- createStateHash,
- applyDiff,
-} from '../../../../plugins/kibana_utils/public';
-
-export function StateProvider(
- Private,
- $rootScope,
- $location,
- stateManagementConfig,
- config,
- kbnUrl,
- $injector
-) {
- const Events = Private(EventsProvider);
-
- const isDummyRoute = () =>
- $injector.has('$route') &&
- $injector.get('$route').current &&
- $injector.get('$route').current.outerAngularWrapperRoute;
-
- createLegacyClass(State).inherits(Events);
- function State(urlParam, defaults, _hashedItemStore = hashedItemStore) {
- State.Super.call(this);
-
- this.setDefaults(defaults);
- this._urlParam = urlParam || '_s';
- this._hashedItemStore = _hashedItemStore;
-
- // When the URL updates we need to fetch the values from the URL
- this._cleanUpListeners = [
- // partial route update, no app reload
- $rootScope.$on('$routeUpdate', () => {
- this.fetch();
- }),
-
- // beginning of full route update, new app will be initialized before
- // $routeChangeSuccess or $routeChangeError
- $rootScope.$on('$routeChangeStart', () => {
- if (!this._persistAcrossApps) {
- this.destroy();
- }
- }),
-
- $rootScope.$on('$routeChangeSuccess', () => {
- if (this._persistAcrossApps) {
- this.fetch();
- }
- }),
- ];
-
- // Initialize the State with fetch
- this.fetch();
- }
-
- State.prototype._readFromURL = function () {
- const search = $location.search();
- const urlVal = search[this._urlParam];
-
- if (!urlVal) {
- return null;
- }
-
- if (isStateHash(urlVal)) {
- return this._parseStateHash(urlVal);
- }
-
- let risonEncoded;
- let unableToParse;
- try {
- risonEncoded = rison.decode(urlVal);
- } catch (e) {
- unableToParse = true;
- }
-
- if (unableToParse) {
- toastNotifications.addDanger(
- i18n.translate('common.ui.stateManagement.unableToParseUrlErrorMessage', {
- defaultMessage: 'Unable to parse URL',
- })
- );
- search[this._urlParam] = this.toQueryParam(this._defaults);
- $location.search(search).replace();
- }
-
- if (!risonEncoded) {
- return null;
- }
-
- if (this.isHashingEnabled()) {
- // RISON can find its way into the URL any number of ways, including the navbar links or
- // shared urls with the entire state embedded. These values need to be translated into
- // hashes and replaced in the browser history when state-hashing is enabled
- search[this._urlParam] = this.toQueryParam(risonEncoded);
- $location.search(search).replace();
- }
-
- return risonEncoded;
- };
-
- /**
- * Fetches the state from the url
- * @returns {void}
- */
- State.prototype.fetch = function () {
- if (!stateManagementConfig.enabled) {
- return;
- }
-
- let stash = this._readFromURL();
-
- // nothing to read from the url? save if ordered to persist, but only if it's not on a wrapper route
- if (stash === null) {
- if (this._persistAcrossApps) {
- return this.save();
- } else {
- stash = {};
- }
- }
-
- _.defaults(stash, this._defaults);
- // apply diff to state from stash, will change state in place via side effect
- const diffResults = applyDiff(this, stash);
-
- if (!isDummyRoute() && diffResults.keys.length) {
- this.emit('fetch_with_changes', diffResults.keys);
- }
- };
-
- /**
- * Saves the state to the url
- * @returns {void}
- */
- State.prototype.save = function (replace) {
- if (!stateManagementConfig.enabled) {
- return;
- }
-
- if (isDummyRoute()) {
- return;
- }
-
- let stash = this._readFromURL();
- const state = this.toObject();
- replace = replace || false;
-
- if (!stash) {
- replace = true;
- stash = {};
- }
-
- // apply diff to state from stash, will change state in place via side effect
- const diffResults = applyDiff(stash, _.defaults({}, state, this._defaults));
-
- if (diffResults.keys.length) {
- this.emit('save_with_changes', diffResults.keys);
- }
-
- // persist the state in the URL
- const search = $location.search();
- search[this._urlParam] = this.toQueryParam(state);
- if (replace) {
- $location.search(search).replace();
- } else {
- $location.search(search);
- }
- };
-
- /**
- * Calls save with a forced replace
- * @returns {void}
- */
- State.prototype.replace = function () {
- if (!stateManagementConfig.enabled) {
- return;
- }
-
- this.save(true);
- };
-
- /**
- * Resets the state to the defaults
- *
- * @returns {void}
- */
- State.prototype.reset = function () {
- if (!stateManagementConfig.enabled) {
- return;
- }
-
- kbnUrl.removeParam(this.getQueryParamName());
- // apply diff to attributes from defaults, this is side effecting so
- // it will change the state in place.
- const diffResults = applyDiff(this, this._defaults);
- if (diffResults.keys.length) {
- this.emit('reset_with_changes', diffResults.keys);
- }
- this.save();
- };
-
- /**
- * Cleans up the state object
- * @returns {void}
- */
- State.prototype.destroy = function () {
- this.off(); // removes all listeners
-
- // Removes the $routeUpdate listener
- this._cleanUpListeners.forEach((listener) => listener(this));
- };
-
- State.prototype.setDefaults = function (defaults) {
- this._defaults = defaults || {};
- };
-
- /**
- * Parse the state hash to it's unserialized value. Hashes are restored
- * to their pre-hashed state.
- *
- * @param {string} stateHash - state hash value from the query string.
- * @return {any} - the stored value, or null if hash does not resolve.
- */
- State.prototype._parseStateHash = function (stateHash) {
- const json = this._hashedItemStore.getItem(stateHash);
- if (json === null) {
- toastNotifications.addDanger(
- i18n.translate('common.ui.stateManagement.unableToRestoreUrlErrorMessage', {
- defaultMessage:
- 'Unable to completely restore the URL, be sure to use the share functionality.',
- })
- );
- }
-
- return JSON.parse(json);
- };
-
- /**
- * Lookup the value for a hash and return it's value in rison format or just
- * return passed argument if it's not recognized as state hash.
- *
- * @param {string} stateHashOrRison - either state hash value or rison string.
- * @return {string} rison
- */
- State.prototype.translateHashToRison = function (stateHashOrRison) {
- if (isStateHash(stateHashOrRison)) {
- return rison.encode(this._parseStateHash(stateHashOrRison));
- }
-
- return stateHashOrRison;
- };
-
- State.prototype.isHashingEnabled = function () {
- return !!config.get('state:storeInSessionStorage');
- };
-
- /**
- * Produce the hash version of the state in it's current position
- *
- * @return {string}
- */
- State.prototype.toQueryParam = function (state = this.toObject()) {
- if (!this.isHashingEnabled()) {
- return rison.encode(state);
- }
-
- // We need to strip out Angular-specific properties.
- const json = angular.toJson(state);
- const hash = createStateHash(json);
- const isItemSet = this._hashedItemStore.setItem(hash, json);
-
- if (isItemSet) {
- return hash;
- }
-
- // If we ran out of space trying to persist the state, notify the user.
- const message = i18n.translate(
- 'common.ui.stateManagement.unableToStoreHistoryInSessionErrorMessage',
- {
- defaultMessage:
- 'Kibana is unable to store history items in your session ' +
- `because it is full and there don't seem to be items any items safe ` +
- 'to delete.\n\n' +
- 'This can usually be fixed by moving to a fresh tab, but could ' +
- 'be caused by a larger issue. If you are seeing this message regularly, ' +
- 'please file an issue at {gitHubIssuesUrl}.',
- values: { gitHubIssuesUrl: 'https://github.com/elastic/kibana/issues' },
- }
- );
- fatalError(new Error(message));
- };
-
- /**
- * Get the query string parameter name where this state writes and reads
- * @return {string}
- */
- State.prototype.getQueryParamName = function () {
- return this._urlParam;
- };
-
- /**
- * Returns an object with each property name and value corresponding to the entries in this collection
- * excluding fields started from '$', '_' and all methods
- *
- * @return {object}
- */
- State.prototype.toObject = function () {
- return _.omitBy(this, (value, key) => {
- return key.charAt(0) === '$' || key.charAt(0) === '_' || _.isFunction(value);
- });
- };
-
- /** Alias for method 'toObject'
- *
- * @obsolete Please use 'toObject' method instead
- * @return {object}
- */
- State.prototype.toJSON = function () {
- return this.toObject();
- };
-
- return State;
-}
diff --git a/src/legacy/ui/public/state_management/state_monitor_factory.ts b/src/legacy/ui/public/state_management/state_monitor_factory.ts
deleted file mode 100644
index 968ececfe3be5..0000000000000
--- a/src/legacy/ui/public/state_management/state_monitor_factory.ts
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { set } from '@elastic/safer-lodash-set';
-import { cloneDeep, isEqual, isPlainObject } from 'lodash';
-import { State } from './state';
-
-export const stateMonitorFactory = {
- create: (
- state: State,
- customInitialState: TStateDefault
- ) => stateMonitor(state, customInitialState),
-};
-
-interface StateStatus {
- clean: boolean;
- dirty: boolean;
-}
-
-export interface StateMonitor {
- setInitialState: (innerCustomInitialState: TStateDefault) => void;
- ignoreProps: (props: string[] | string) => void;
- onChange: (callback: ChangeHandlerFn) => StateMonitor;
- destroy: () => void;
-}
-
-type ChangeHandlerFn = (status: StateStatus, type: string | null, keys: string[]) => void;
-
-function stateMonitor(
- state: State,
- customInitialState: TStateDefault
-): StateMonitor {
- let destroyed = false;
- let ignoredProps: string[] = [];
- let changeHandlers: ChangeHandlerFn[] | undefined = [];
- let initialState: TStateDefault;
-
- setInitialState(customInitialState);
-
- function setInitialState(innerCustomInitialState: TStateDefault) {
- // state.toJSON returns a reference, clone so we can mutate it safely
- initialState = cloneDeep(innerCustomInitialState) || cloneDeep(state.toJSON());
- }
-
- function removeIgnoredProps(innerState: TStateDefault) {
- ignoredProps.forEach((path) => {
- set(innerState, path, true);
- });
- return innerState;
- }
-
- function getStatus(): StateStatus {
- // state.toJSON returns a reference, clone so we can mutate it safely
- const currentState = removeIgnoredProps(cloneDeep(state.toJSON()));
- const isClean = isEqual(currentState, initialState);
-
- return {
- clean: isClean,
- dirty: !isClean,
- };
- }
-
- function dispatchChange(type: string | null = null, keys: string[] = []) {
- const status = getStatus();
- if (!changeHandlers) {
- throw new Error('Change handlers is undefined, this object has been destroyed');
- }
- changeHandlers.forEach((changeHandler) => {
- changeHandler(status, type, keys);
- });
- }
-
- function dispatchFetch(keys: string[]) {
- dispatchChange('fetch_with_changes', keys);
- }
-
- function dispatchSave(keys: string[]) {
- dispatchChange('save_with_changes', keys);
- }
-
- function dispatchReset(keys: string[]) {
- dispatchChange('reset_with_changes', keys);
- }
-
- return {
- setInitialState(innerCustomInitialState: TStateDefault) {
- if (!isPlainObject(innerCustomInitialState)) {
- throw new TypeError('The default state must be an object');
- }
-
- // check the current status
- const previousStatus = getStatus();
-
- // update the initialState and apply ignoredProps
- setInitialState(innerCustomInitialState);
- removeIgnoredProps(initialState);
-
- // fire the change handler if the status has changed
- if (!isEqual(previousStatus, getStatus())) {
- dispatchChange();
- }
- },
-
- ignoreProps(props: string[] | string) {
- ignoredProps = ignoredProps.concat(props);
- removeIgnoredProps(initialState);
- return this;
- },
-
- onChange(callback: ChangeHandlerFn) {
- if (destroyed || !changeHandlers) {
- throw new Error('Monitor has been destroyed');
- }
- if (typeof callback !== 'function') {
- throw new Error('onChange handler must be a function');
- }
-
- changeHandlers.push(callback);
-
- // Listen for state events.
- state.on('fetch_with_changes', dispatchFetch);
- state.on('save_with_changes', dispatchSave);
- state.on('reset_with_changes', dispatchReset);
-
- // if the state is already dirty, fire the change handler immediately
- const status = getStatus();
- if (status.dirty) {
- dispatchChange();
- }
-
- return this;
- },
-
- destroy() {
- destroyed = true;
- changeHandlers = undefined;
- state.off('fetch_with_changes', dispatchFetch);
- state.off('save_with_changes', dispatchSave);
- state.off('reset_with_changes', dispatchReset);
- },
- };
-}
diff --git a/src/legacy/ui/public/system_api/__tests__/system_api.js b/src/legacy/ui/public/system_api/__tests__/system_api.js
deleted file mode 100644
index 816024f13f8b2..0000000000000
--- a/src/legacy/ui/public/system_api/__tests__/system_api.js
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import {
- addSystemApiHeader,
- isSystemApiRequest,
-} from '../../../../../plugins/kibana_legacy/public';
-
-describe('system_api', () => {
- describe('#addSystemApiHeader', () => {
- it('adds the correct system API header', () => {
- const headers = {
- 'kbn-version': '4.6.0',
- };
- const newHeaders = addSystemApiHeader(headers);
-
- expect(newHeaders).to.have.property('kbn-system-request');
- expect(newHeaders['kbn-system-request']).to.be(true);
-
- expect(newHeaders).to.have.property('kbn-version');
- expect(newHeaders['kbn-version']).to.be('4.6.0');
- });
- });
-
- describe('#isSystemApiRequest', () => {
- it('returns true for a system HTTP request', () => {
- const mockRequest = {
- headers: {
- 'kbn-system-request': true,
- },
- };
- expect(isSystemApiRequest(mockRequest)).to.be(true);
- });
-
- it('returns true for a legacy system API HTTP request', () => {
- const mockRequest = {
- headers: {
- 'kbn-system-api': true,
- },
- };
- expect(isSystemApiRequest(mockRequest)).to.be(true);
- });
-
- it('returns false for a non-system API HTTP request', () => {
- const mockRequest = {
- headers: {},
- };
- expect(isSystemApiRequest(mockRequest)).to.be(false);
- });
- });
-});
diff --git a/src/legacy/ui/public/system_api/index.js b/src/legacy/ui/public/system_api/index.js
deleted file mode 100644
index 6361c0ea6c69a..0000000000000
--- a/src/legacy/ui/public/system_api/index.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { addSystemApiHeader, isSystemApiRequest } from '../../../../plugins/kibana_legacy/public';
diff --git a/src/legacy/ui/public/timefilter/index.ts b/src/legacy/ui/public/timefilter/index.ts
deleted file mode 100644
index 83795c73112be..0000000000000
--- a/src/legacy/ui/public/timefilter/index.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import uiRoutes from 'ui/routes';
-import { npStart } from 'ui/new_platform';
-
-import { TimefilterContract, TimeHistoryContract } from '../../../../plugins/data/public';
-import { registerTimefilterWithGlobalState } from './setup_router';
-
-export {
- getTime,
- InputTimeRange,
- TimeHistoryContract,
- TimefilterContract,
-} from '../../../../plugins/data/public';
-export type Timefilter = TimefilterContract;
-export type TimeHistory = TimeHistoryContract;
-export const timeHistory = npStart.plugins.data.query.timefilter.history;
-export const timefilter = npStart.plugins.data.query.timefilter.timefilter;
-
-uiRoutes.addSetupWork((globalState, $rootScope) => {
- return registerTimefilterWithGlobalState(timefilter, globalState, $rootScope);
-});
diff --git a/src/legacy/ui/public/timefilter/setup_router.test.js b/src/legacy/ui/public/timefilter/setup_router.test.js
deleted file mode 100644
index 2ae9a053ae2db..0000000000000
--- a/src/legacy/ui/public/timefilter/setup_router.test.js
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { registerTimefilterWithGlobalState } from './setup_router';
-
-jest.mock('../../../../plugins/kibana_legacy/public', () => ({
- subscribeWithScope: jest.fn(),
-}));
-
-describe('registerTimefilterWithGlobalState()', () => {
- it('should always use iso8601 strings', async () => {
- const setTime = jest.fn();
- const timefilter = {
- setTime,
- setRefreshInterval: jest.fn(),
- getRefreshIntervalUpdate$: jest.fn(),
- getTimeUpdate$: jest.fn(),
- };
-
- const globalState = {
- time: {
- from: '2017-09-07T20:12:04.011Z',
- to: '2017-09-07T20:18:55.733Z',
- },
- on: (eventName, callback) => {
- callback();
- },
- };
-
- const rootScope = {
- $on: jest.fn(),
- };
-
- registerTimefilterWithGlobalState(timefilter, globalState, rootScope);
-
- expect(setTime.mock.calls.length).toBe(2);
- expect(setTime.mock.calls[1][0]).toEqual(globalState.time);
- });
-});
diff --git a/src/legacy/ui/public/timefilter/setup_router.ts b/src/legacy/ui/public/timefilter/setup_router.ts
deleted file mode 100644
index 7c25c6aa3166e..0000000000000
--- a/src/legacy/ui/public/timefilter/setup_router.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { IScope } from 'angular';
-import moment from 'moment';
-import chrome from 'ui/chrome';
-import { Subscription } from 'rxjs';
-import { fatalError } from 'ui/notify/fatal_error';
-import { subscribeWithScope } from '../../../../plugins/kibana_legacy/public';
-import {
- RefreshInterval,
- TimeRange,
- TimefilterContract,
- UI_SETTINGS,
-} from '../../../../plugins/data/public';
-
-// TODO
-// remove everything underneath once globalState is no longer an angular service
-// and listener can be registered without angular.
-function convertISO8601(stringTime: string): string {
- const obj = moment(stringTime, 'YYYY-MM-DDTHH:mm:ss.SSSZ', true);
- return obj.isValid() ? obj.toISOString() : stringTime;
-}
-
-export function getTimefilterConfig() {
- const settings = chrome.getUiSettingsClient();
- return {
- timeDefaults: settings.get('timepicker:timeDefaults'),
- refreshIntervalDefaults: settings.get(UI_SETTINGS.TIMEPICKER_REFRESH_INTERVAL_DEFAULTS),
- };
-}
-
-export const registerTimefilterWithGlobalStateFactory = (
- timefilter: TimefilterContract,
- globalState: any,
- $rootScope: IScope
-) => {
- // settings have to be re-fetched here, to make sure that settings changed by overrideLocalDefault are taken into account.
- const config = getTimefilterConfig();
- timefilter.setTime(_.defaults(globalState.time || {}, config.timeDefaults));
- timefilter.setRefreshInterval(
- _.defaults(globalState.refreshInterval || {}, config.refreshIntervalDefaults)
- );
-
- globalState.on('fetch_with_changes', () => {
- // clone and default to {} in one
- const newTime: TimeRange = _.defaults({}, globalState.time, config.timeDefaults);
- const newRefreshInterval: RefreshInterval = _.defaults(
- {},
- globalState.refreshInterval,
- config.refreshIntervalDefaults
- );
-
- if (newTime) {
- if (newTime.to) newTime.to = convertISO8601(newTime.to);
- if (newTime.from) newTime.from = convertISO8601(newTime.from);
- }
-
- timefilter.setTime(newTime);
- timefilter.setRefreshInterval(newRefreshInterval);
- });
-
- const updateGlobalStateWithTime = () => {
- globalState.time = timefilter.getTime();
- globalState.refreshInterval = timefilter.getRefreshInterval();
- globalState.save();
- };
-
- const subscriptions = new Subscription();
- subscriptions.add(
- subscribeWithScope(
- $rootScope,
- timefilter.getRefreshIntervalUpdate$(),
- {
- next: updateGlobalStateWithTime,
- },
- fatalError
- )
- );
-
- subscriptions.add(
- subscribeWithScope(
- $rootScope,
- timefilter.getTimeUpdate$(),
- {
- next: updateGlobalStateWithTime,
- },
- fatalError
- )
- );
-
- $rootScope.$on('$destroy', () => {
- subscriptions.unsubscribe();
- });
-};
-
-// Currently some parts of Kibana (index patterns, timefilter) rely on addSetupWork in the uiRouter
-// and require it to be executed to properly function.
-// This function is exposed for applications that do not use uiRoutes like APM
-// Kibana issue https://github.com/elastic/kibana/issues/19110 tracks the removal of this dependency on uiRouter
-export const registerTimefilterWithGlobalState = _.once(registerTimefilterWithGlobalStateFactory);
diff --git a/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js b/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js
deleted file mode 100644
index 965e8f4bc9f38..0000000000000
--- a/src/legacy/ui/public/url/__tests__/extract_app_path_and_id.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-
-import { extractAppPathAndId } from '../extract_app_path_and_id';
-
-describe('extractAppPathAndId', function () {
- describe('from an absolute url with a base path', function () {
- describe('with a base path', function () {
- const basePath = '/gza';
- const absoluteUrl = 'http://www.test.com:5601/gza/app/appId#appPathIsHere?query=here';
- it('extracts app path', function () {
- expect(extractAppPathAndId(absoluteUrl, basePath).appPath).to.be(
- 'appPathIsHere?query=here'
- );
- });
-
- it('extracts app id', function () {
- expect(extractAppPathAndId(absoluteUrl, basePath).appId).to.be('appId');
- });
-
- it('returns an empty object when there is no app path', function () {
- const appPathAndId = extractAppPathAndId('http://www.test.com:5601/gza/noapppath');
- expect(appPathAndId.appId).to.be(undefined);
- expect(appPathAndId.appPath).to.be(undefined);
- });
- });
-
- describe('without a base path', function () {
- const absoluteUrl = 'http://www.test.com:5601/app/appId#appPathIsHere?query=here';
- it('extracts app path', function () {
- expect(extractAppPathAndId(absoluteUrl).appPath).to.be('appPathIsHere?query=here');
- });
-
- it('extracts app id', function () {
- expect(extractAppPathAndId(absoluteUrl).appId).to.be('appId');
- });
-
- it('returns an empty object when there is no app path', function () {
- const appPathAndId = extractAppPathAndId('http://www.test.com:5601/noapppath');
- expect(appPathAndId.appId).to.be(undefined);
- expect(appPathAndId.appPath).to.be(undefined);
- });
- });
-
- describe('when appPath is empty', function () {
- const absoluteUrl = 'http://www.test.com:5601/app/appId';
- it('extracts app id', function () {
- expect(extractAppPathAndId(absoluteUrl).appId).to.be('appId');
- });
- it('extracts empty appPath', function () {
- expect(extractAppPathAndId(absoluteUrl).appPath).to.be('');
- });
- });
- });
-
- describe('from a root relative url', function () {
- describe('with a base path', function () {
- const basePath = '/gza';
- const rootRelativePath = '/gza/app/appId#appPathIsHere?query=here';
- it('extracts app path', function () {
- expect(extractAppPathAndId(rootRelativePath, basePath).appPath).to.be(
- 'appPathIsHere?query=here'
- );
- });
-
- it('extracts app id', function () {
- expect(extractAppPathAndId(rootRelativePath, basePath).appId).to.be('appId');
- });
-
- it('returns an empty object when there is no app path', function () {
- const appPathAndId = extractAppPathAndId('/gza/notformattedright');
- expect(appPathAndId.appId).to.be(undefined);
- expect(appPathAndId.appPath).to.be(undefined);
- });
- });
-
- describe('without a base path', function () {
- const rootRelativePath = '/app/appId#appPathIsHere?query=here';
- it('extracts app path', function () {
- expect(extractAppPathAndId(rootRelativePath).appPath).to.be('appPathIsHere?query=here');
- });
-
- it('extracts app id', function () {
- expect(extractAppPathAndId(rootRelativePath).appId).to.be('appId');
- });
-
- it('returns an empty object when there is no app path', function () {
- const appPathAndId = extractAppPathAndId('/notformattedright');
- expect(appPathAndId.appId).to.be(undefined);
- expect(appPathAndId.appPath).to.be(undefined);
- });
- });
-
- describe('when appPath is empty', function () {
- const rootRelativePath = '/app/appId';
- it('extracts app id', function () {
- expect(extractAppPathAndId(rootRelativePath).appId).to.be('appId');
- });
- it('extracts empty appPath', function () {
- expect(extractAppPathAndId(rootRelativePath).appPath).to.be('');
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js b/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js
deleted file mode 100644
index 6ea199c3d22cc..0000000000000
--- a/src/legacy/ui/public/url/__tests__/kibana_parsed_url.js
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-
-import { KibanaParsedUrl } from '../kibana_parsed_url';
-
-describe('KibanaParsedUrl', function () {
- it('getHashedAppPath', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/hi',
- appId: 'bye',
- appPath: 'visualize?hi=there&bye',
- });
- expect(kibanaParsedUrl.getHashedAppPath()).to.be('#visualize?hi=there&bye');
- });
-
- it('getAppRootPath', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/hi',
- appId: 'appId',
- appPath: 'dashboard?edit=123',
- });
- expect(kibanaParsedUrl.getAppRootPath()).to.be('/app/appId#dashboard?edit=123');
- });
-
- describe('when basePath is specified', function () {
- it('getRootRelativePath', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/base',
- appId: 'appId',
- appPath: 'visualize?hi=there&bye',
- });
- expect(kibanaParsedUrl.getRootRelativePath()).to.be('/base/app/appId#visualize?hi=there&bye');
- });
-
- describe('getAbsolutePath', function () {
- const protocol = 'http';
- const hostname = 'www.test.com';
- const port = '5601';
-
- it('returns the absolute url when there is a port', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/base',
- appId: 'appId',
- appPath: 'visualize?hi=there&bye',
- hostname,
- protocol,
- port,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be(
- 'http://www.test.com:5601/base/app/appId#visualize?hi=there&bye'
- );
- });
-
- it('returns the absolute url when there are no query parameters', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/base',
- appId: 'appId',
- appPath: 'visualize',
- hostname,
- protocol,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be(
- 'http://www.test.com/base/app/appId#visualize'
- );
- });
-
- it('returns the absolute url when the are query parameters', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- basePath: '/base',
- appId: 'appId',
- appPath: 'visualize?hi=bye&tata',
- hostname,
- protocol,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be(
- 'http://www.test.com/base/app/appId#visualize?hi=bye&tata'
- );
- });
- });
- });
-
- describe('when basePath is not specified', function () {
- it('getRootRelativePath', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- appId: 'appId',
- appPath: 'visualize?hi=there&bye',
- });
- expect(kibanaParsedUrl.getRootRelativePath()).to.be('/app/appId#visualize?hi=there&bye');
- });
-
- describe('getAbsolutePath', function () {
- const protocol = 'http';
- const hostname = 'www.test.com';
- const port = '5601';
-
- it('returns the absolute url when there is a port', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- appId: 'appId',
- appPath: 'visualize?hi=there&bye',
- hostname,
- protocol,
- port,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be(
- 'http://www.test.com:5601/app/appId#visualize?hi=there&bye'
- );
- });
-
- it('returns the absolute url when there are no query parameters', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- appId: 'appId',
- appPath: 'visualize',
- hostname,
- protocol,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be('http://www.test.com/app/appId#visualize');
- });
-
- it('returns the absolute url when there are query parameters', function () {
- const kibanaParsedUrl = new KibanaParsedUrl({
- appId: 'appId',
- appPath: 'visualize?hi=bye&tata',
- hostname,
- protocol,
- });
- expect(kibanaParsedUrl.getAbsoluteUrl()).to.be(
- 'http://www.test.com/app/appId#visualize?hi=bye&tata'
- );
- });
- });
- });
-
- describe('getGlobalState', function () {
- const basePath = '/xyz';
- const appId = 'myApp';
-
- it('returns an empty string when the KibanaParsedUrl is in an invalid state', function () {
- const url = new KibanaParsedUrl({ basePath });
- expect(url.getGlobalState()).to.be('');
- });
-
- it('returns an empty string when there is no global state', function () {
- const url = new KibanaParsedUrl({ basePath, appId, appPath: '/hi?notg=something' });
- expect(url.getGlobalState()).to.be('');
- });
-
- it('returns the global state when it is the last parameter', function () {
- const url = new KibanaParsedUrl({
- basePath,
- appId,
- appPath: '/hi?notg=something&_g=(thisismyglobalstate)',
- });
- expect(url.getGlobalState()).to.be('(thisismyglobalstate)');
- });
-
- it('returns the global state when it is the first parameter', function () {
- const url = new KibanaParsedUrl({
- basePath,
- appId,
- appPath: '/hi?_g=(thisismyglobalstate)&hi=bye',
- });
- expect(url.getGlobalState()).to.be('(thisismyglobalstate)');
- });
- });
-
- describe('setGlobalState', function () {
- const basePath = '/xyz';
- const appId = 'myApp';
-
- it('does nothing when KibanaParsedUrl is in an invalid state', function () {
- const url = new KibanaParsedUrl({ basePath });
- url.setGlobalState('newglobalstate');
- expect(url.getGlobalState()).to.be('');
- });
-
- it('clears the global state when setting it to an empty string', function () {
- const url = new KibanaParsedUrl({ basePath, appId, appPath: '/hi?_g=globalstate' });
- url.setGlobalState('');
- expect(url.getGlobalState()).to.be('');
- });
-
- it('updates the global state when a string is passed in', function () {
- const url = new KibanaParsedUrl({
- basePath,
- appId,
- appPath: '/hi?notg=something&_g=oldstate',
- });
- url.setGlobalState('newstate');
- expect(url.getGlobalState()).to.be('newstate');
- });
-
- it('adds the global state parameters if it did not exist before', function () {
- const url = new KibanaParsedUrl({ basePath, appId, appPath: '/hi' });
- url.setGlobalState('newstate');
- expect(url.getGlobalState()).to.be('newstate');
- expect(url.appPath).to.be('/hi?_g=newstate');
- });
- });
-});
diff --git a/src/legacy/ui/public/url/__tests__/prepend_path.js b/src/legacy/ui/public/url/__tests__/prepend_path.js
deleted file mode 100644
index 36991b77553e4..0000000000000
--- a/src/legacy/ui/public/url/__tests__/prepend_path.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-
-import { prependPath } from '../prepend_path';
-
-describe('url prependPath', function () {
- describe('returns the relative path unchanged', function () {
- it('if it is null', function () {
- expect(prependPath(null, 'kittens')).to.be(null);
- });
-
- it('if it is undefined', function () {
- expect(prependPath(undefined, 'kittens')).to.be(undefined);
- });
-
- it('if it is an absolute url', function () {
- expect(prependPath('http://www.hithere.com/howareyou', 'welcome')).to.be(
- 'http://www.hithere.com/howareyou'
- );
- });
-
- it('if it does not start with a /', function () {
- expect(prependPath('are/so/cool', 'cats')).to.be('are/so/cool');
- });
-
- it('when new path is empty', function () {
- expect(prependPath('/are/so/cool', '')).to.be('/are/so/cool');
- });
-
- it('when it is only a slash and new path is empty', function () {
- expect(prependPath('/', '')).to.be('/');
- });
- });
-
- describe('returns an updated relative path', function () {
- it('when it starts with a slash', function () {
- expect(prependPath('/are/so/cool', 'dinosaurs')).to.be('dinosaurs/are/so/cool');
- });
-
- it('when new path starts with a slash', function () {
- expect(prependPath('/are/so/cool', '/fish')).to.be('/fish/are/so/cool');
- });
-
- it('with two slashes if new path is a slash', function () {
- expect(prependPath('/are/so/cool', '/')).to.be('//are/so/cool');
- });
-
- it('when there is a slash on the end', function () {
- expect(prependPath('/are/delicious/', 'lollipops')).to.be('lollipops/are/delicious/');
- });
-
- it('when pathname that ends with a file', function () {
- expect(prependPath('/are/delicious/index.html', 'donuts')).to.be(
- 'donuts/are/delicious/index.html'
- );
- });
-
- it('when it is only a slash', function () {
- expect(prependPath('/', 'kittens')).to.be('kittens/');
- });
- });
-});
diff --git a/src/legacy/ui/public/url/__tests__/url.js b/src/legacy/ui/public/url/__tests__/url.js
deleted file mode 100644
index 8b173482e1bb4..0000000000000
--- a/src/legacy/ui/public/url/__tests__/url.js
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import sinon from 'sinon';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import faker from 'faker';
-import _ from 'lodash';
-import { AppStateProvider } from '../../state_management/app_state';
-import '..';
-
-// global vars, injected and mocked in init()
-let kbnUrl;
-let $route;
-let $location;
-let $rootScope;
-let appState;
-
-class StubAppState {
- constructor() {
- this.getQueryParamName = () => '_a';
- this.toQueryParam = () => 'stateQueryParam';
- this.destroy = sinon.stub();
- }
-}
-
-function init() {
- ngMock.module('kibana/url', 'kibana', function ($provide, PrivateProvider) {
- $provide.service('$route', function () {
- return {
- reload: _.noop,
- };
- });
-
- appState = new StubAppState();
- PrivateProvider.swap(AppStateProvider, ($decorate) => {
- const AppState = $decorate();
- AppState.getAppState = () => appState;
- return AppState;
- });
- });
-
- ngMock.inject(function ($injector) {
- $route = $injector.get('$route');
- $location = $injector.get('$location');
- $rootScope = $injector.get('$rootScope');
- kbnUrl = $injector.get('kbnUrl');
- });
-}
-
-describe('kbnUrl', function () {
- beforeEach(function () {
- init();
- });
-
- describe('forcing reload', function () {
- it('schedules a listener for $locationChangeSuccess on the $rootScope', function () {
- $location.url('/url');
- $route.current = {
- $$route: {
- regex: /.*/,
- },
- };
-
- sinon.stub($rootScope, '$on');
-
- expect($rootScope.$on.callCount).to.be(0);
- kbnUrl.change('/url');
- sinon.assert.calledOnce(appState.destroy);
- expect($rootScope.$on.callCount).to.be(1);
- expect($rootScope.$on.firstCall.args[0]).to.be('$locationChangeSuccess');
- });
-
- it('handler unbinds the listener and calls reload', function () {
- $location.url('/url');
- $route.current = {
- $$route: {
- regex: /.*/,
- },
- };
-
- const unbind = sinon.stub();
- sinon.stub($rootScope, '$on').returns(unbind);
- $route.reload = sinon.stub();
-
- expect($rootScope.$on.callCount).to.be(0);
- kbnUrl.change('/url');
- expect($rootScope.$on.callCount).to.be(1);
-
- const handler = $rootScope.$on.firstCall.args[1];
- handler();
- expect(unbind.callCount).to.be(1);
- expect($route.reload.callCount).to.be(1);
- });
-
- it('reloads requested before the first are ignored', function () {
- $location.url('/url');
- $route.current = {
- $$route: {
- regex: /.*/,
- },
- };
- $route.reload = sinon.stub();
-
- sinon.stub($rootScope, '$on').returns(sinon.stub());
-
- expect($rootScope.$on.callCount).to.be(0);
- kbnUrl.change('/url');
- expect($rootScope.$on.callCount).to.be(1);
-
- // don't call the first handler
-
- kbnUrl.change('/url');
- expect($rootScope.$on.callCount).to.be(1);
- });
-
- it('one reload can happen once the first has completed', function () {
- $location.url('/url');
- $route.current = {
- $$route: {
- regex: /.*/,
- },
- };
- $route.reload = sinon.stub();
-
- sinon.stub($rootScope, '$on').returns(sinon.stub());
-
- expect($rootScope.$on.callCount).to.be(0);
- kbnUrl.change('/url');
- expect($rootScope.$on.callCount).to.be(1);
-
- // call the first handler
- $rootScope.$on.firstCall.args[1]();
- expect($route.reload.callCount).to.be(1);
-
- expect($rootScope.$on.callCount).to.be(1);
- kbnUrl.change('/url');
- expect($rootScope.$on.callCount).to.be(2);
- });
- });
-
- describe('remove', function () {
- it('removes a parameter with a value from the url', function () {
- $location.url('/myurl?exist&WithAParamToRemove=2&anothershouldexist=5');
- kbnUrl.removeParam('WithAParamToRemove');
- expect($location.url()).to.be('/myurl?exist&anothershouldexist=5');
- });
-
- it('removes a parameter with no value from the url', function () {
- $location.url('/myurl?removeme&hi=5');
- kbnUrl.removeParam('removeme');
- expect($location.url()).to.be('/myurl?hi=5');
- });
-
- it('is noop if the given parameter doesn\t exist in the url', function () {
- $location.url('/myurl?hi&bye');
- kbnUrl.removeParam('noexist');
- expect($location.url()).to.be('/myurl?hi&bye');
- });
-
- it('is noop if given empty string param', function () {
- $location.url('/myurl?hi&bye');
- kbnUrl.removeParam('');
- expect($location.url()).to.be('/myurl?hi&bye');
- });
- });
-
- describe('change', function () {
- it('should set $location.url', function () {
- sinon.stub($location, 'url');
-
- expect($location.url.callCount).to.be(0);
- kbnUrl.change('/some-url');
- expect($location.url.callCount).to.be(1);
- });
-
- it('should uri encode replaced params', function () {
- const url = '/some/path/';
- const params = { replace: faker.Lorem.words(3).join(' ') };
- const check = encodeURIComponent(params.replace);
- sinon.stub($location, 'url');
-
- kbnUrl.change(url + '{{replace}}', params);
-
- expect($location.url.firstCall.args[0]).to.be(url + check);
- });
-
- it('should parse angular expression in substitutions and uri encode the results', function () {
- // build url by piecing together these parts
- const urlParts = ['/', '/', '?', '&', '#'];
- // make sure it can parse templates with weird spacing
- const wrappers = [
- ['{{', '}}'],
- ['{{ ', ' }}'],
- ['{{', ' }}'],
- ['{{ ', '}}'],
- ['{{ ', ' }}'],
- ];
- // make sure filters are evaluated via angular expressions
- const objIndex = 4; // used to case one replace as an object
- const filters = ['', 'uppercase', '', 'uppercase', ''];
-
- // the words (template keys) used must all be unique
- const words = _.uniq(faker.Lorem.words(10))
- .slice(0, urlParts.length)
- .map(function (word, i) {
- if (filters[i].length) {
- return word + '|' + filters[i];
- }
- return word;
- });
-
- const replacements = faker.Lorem.words(urlParts.length).map(function (word, i) {
- // make selected replacement into an object
- if (i === objIndex) {
- return { replace: word };
- }
-
- return word;
- });
-
- // build the url and test url
- let url = '';
- let testUrl = '';
- urlParts.forEach(function (part, i) {
- url += part + wrappers[i][0] + words[i] + wrappers[i][1];
- const locals = {};
- locals[words[i].split('|')[0]] = replacements[i];
- testUrl += part + encodeURIComponent($rootScope.$eval(words[i], locals));
- });
-
- // create the locals replacement object
- const params = {};
- replacements.forEach(function (replacement, i) {
- const word = words[i].split('|')[0];
- params[word] = replacement;
- });
-
- sinon.stub($location, 'url');
-
- kbnUrl.change(url, params);
-
- expect($location.url.firstCall.args[0]).to.not.be(url);
- expect($location.url.firstCall.args[0]).to.be(testUrl);
- });
-
- it('should handle dot notation', function () {
- const url = '/some/thing/{{that.is.substituted}}';
-
- kbnUrl.change(url, {
- that: {
- is: {
- substituted: 'test',
- },
- },
- });
-
- expect($location.url()).to.be('/some/thing/test');
- });
-
- it('should throw when params are missing', function () {
- const url = '/{{replace_me}}';
- const params = {};
-
- try {
- kbnUrl.change(url, params);
- throw new Error('this should not run');
- } catch (err) {
- expect(err).to.be.an(Error);
- expect(err.message).to.match(/replace_me/);
- }
- });
-
- it('should throw when filtered params are missing', function () {
- const url = '/{{replace_me|number}}';
- const params = {};
-
- try {
- kbnUrl.change(url, params);
- throw new Error('this should not run');
- } catch (err) {
- expect(err).to.be.an(Error);
- expect(err.message).to.match(/replace_me\|number/);
- }
- });
-
- it('should change the entire url', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.change(newPath);
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql({});
- expect($location.hash()).to.be('');
- });
-
- it('should allow setting app state on the target url', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.change(newPath, null, new StubAppState());
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql({ _a: 'stateQueryParam' });
- expect($location.hash()).to.be('');
- });
- });
-
- describe('changePath', function () {
- it('should change just the path', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.changePath(newPath);
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
- });
- });
-
- describe('redirect', function () {
- it('should change the entire url', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.redirect(newPath);
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql({});
- expect($location.hash()).to.be('');
- });
-
- it('should allow setting app state on the target url', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.redirect(newPath, null, new StubAppState());
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql({ _a: 'stateQueryParam' });
- expect($location.hash()).to.be('');
- });
-
- it('should replace the current history entry', function () {
- sinon.stub($location, 'replace');
- $location.url('/some/path');
-
- expect($location.replace.callCount).to.be(0);
- kbnUrl.redirect('/new/path/');
- expect($location.replace.callCount).to.be(1);
- });
-
- it('should call replace on $location', function () {
- sinon.stub(kbnUrl, '_shouldForceReload').returns(false);
- sinon.stub($location, 'replace');
-
- expect($location.replace.callCount).to.be(0);
- kbnUrl.redirect('/poop');
- expect($location.replace.callCount).to.be(1);
- });
- });
-
- describe('redirectPath', function () {
- it('should only change the path', function () {
- const path = '/test/path';
- const search = { search: 'test' };
- const hash = 'hash';
- const newPath = '/new/location';
-
- $location.path(path).search(search).hash(hash);
-
- // verify the starting state
- expect($location.path()).to.be(path);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
-
- kbnUrl.redirectPath(newPath);
-
- // verify the ending state
- expect($location.path()).to.be(newPath);
- expect($location.search()).to.eql(search);
- expect($location.hash()).to.be(hash);
- });
-
- it('should call replace on $location', function () {
- sinon.stub(kbnUrl, '_shouldForceReload').returns(false);
- sinon.stub($location, 'replace');
-
- expect($location.replace.callCount).to.be(0);
- kbnUrl.redirectPath('/poop');
- expect($location.replace.callCount).to.be(1);
- });
- });
-
- describe('_shouldForceReload', function () {
- let next;
- let prev;
-
- beforeEach(function () {
- $route.current = {
- $$route: {
- regexp: /^\/is-current-route\/(\d+)/,
- reloadOnSearch: true,
- },
- };
-
- prev = { path: '/is-current-route/1', search: {} };
- next = { path: '/is-current-route/1', search: {} };
- });
-
- it("returns false if the passed url doesn't match the current route", function () {
- next.path = '/not current';
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
-
- describe('if the passed url does match the route', function () {
- describe('and the route reloads on search', function () {
- describe('and the path is the same', function () {
- describe('and the search params are the same', function () {
- it('returns true', function () {
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(true);
- });
- });
- describe('but the search params are different', function () {
- it('returns false', function () {
- next.search = {};
- prev.search = { q: 'search term' };
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
- });
- });
-
- describe('and the path is different', function () {
- beforeEach(function () {
- next.path = '/not-same';
- });
-
- describe('and the search params are the same', function () {
- it('returns false', function () {
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
- });
- describe('but the search params are different', function () {
- it('returns false', function () {
- next.search = {};
- prev.search = { q: 'search term' };
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
- });
- });
- });
-
- describe('but the route does not reload on search', function () {
- beforeEach(function () {
- $route.current.$$route.reloadOnSearch = false;
- });
-
- describe('and the path is the same', function () {
- describe('and the search params are the same', function () {
- it('returns true', function () {
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(true);
- });
- });
- describe('but the search params are different', function () {
- it('returns true', function () {
- next.search = {};
- prev.search = { q: 'search term' };
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(true);
- });
- });
- });
-
- describe('and the path is different', function () {
- beforeEach(function () {
- next.path = '/not-same';
- });
-
- describe('and the search params are the same', function () {
- it('returns false', function () {
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
- });
- describe('but the search params are different', function () {
- it('returns false', function () {
- next.search = {};
- prev.search = { q: 'search term' };
- expect(kbnUrl._shouldForceReload(next, prev, $route)).to.be(false);
- });
- });
- });
- });
- });
- });
-});
diff --git a/src/legacy/ui/public/url/absolute_to_parsed_url.ts b/src/legacy/ui/public/url/absolute_to_parsed_url.ts
deleted file mode 100644
index 30f493c25776c..0000000000000
--- a/src/legacy/ui/public/url/absolute_to_parsed_url.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { parse } from 'url';
-
-import { extractAppPathAndId } from './extract_app_path_and_id';
-import { KibanaParsedUrl } from './kibana_parsed_url';
-
-/**
- *
- * @param absoluteUrl - an absolute url, e.g. https://localhost:5601/gra/app/visualize#/edit/viz_id?hi=bye
- * @param basePath - An optional base path for kibana. If supplied, should start with a "/".
- * e.g. in https://localhost:5601/gra/app/visualize#/edit/viz_id the basePath is
- * "/gra".
- * @return {KibanaParsedUrl}
- */
-export function absoluteToParsedUrl(absoluteUrl: string, basePath = '') {
- const { appPath, appId } = extractAppPathAndId(absoluteUrl, basePath);
- const { hostname, port, protocol } = parse(absoluteUrl);
- return new KibanaParsedUrl({
- basePath,
- appId: appId!,
- appPath,
- hostname,
- port,
- protocol,
- });
-}
diff --git a/src/legacy/ui/public/url/extract_app_path_and_id.ts b/src/legacy/ui/public/url/extract_app_path_and_id.ts
deleted file mode 100644
index 44bba272e0873..0000000000000
--- a/src/legacy/ui/public/url/extract_app_path_and_id.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { parse } from 'url';
-
-/**
- * If the url is determined to contain an appId and appPath, it returns those portions. If it is not in the right
- * format and an appId and appPath can't be extracted, it returns an empty object.
- * @param {string} url - a relative or absolute url which contains an appPath, an appId, and optionally, a basePath.
- * @param {string} basePath - optional base path, if given should start with "/".
- */
-export function extractAppPathAndId(url: string, basePath = '') {
- const parsedUrl = parse(url);
- if (!parsedUrl.path) {
- return {};
- }
- const pathWithoutBase = parsedUrl.path.slice(basePath.length);
-
- if (!pathWithoutBase.startsWith('/app/')) {
- return {};
- }
-
- const appPath = parsedUrl.hash && parsedUrl.hash.length > 0 ? parsedUrl.hash.slice(1) : '';
- return { appId: pathWithoutBase.slice('/app/'.length), appPath };
-}
diff --git a/src/legacy/ui/public/url/index.js b/src/legacy/ui/public/url/index.js
deleted file mode 100644
index 8ef267de2890c..0000000000000
--- a/src/legacy/ui/public/url/index.js
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export { KbnUrlProvider } from './url';
-export { RedirectWhenMissingProvider } from './redirect_when_missing';
-// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-export { modifyUrl } from '../../../../core/utils';
diff --git a/src/legacy/ui/public/url/kbn_url.ts b/src/legacy/ui/public/url/kbn_url.ts
deleted file mode 100644
index 42b6a8f19f9a9..0000000000000
--- a/src/legacy/ui/public/url/kbn_url.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-export interface KbnUrl {
- change: (url: string) => void;
- removeParam: (param: string) => void;
-}
diff --git a/src/legacy/ui/public/url/kibana_parsed_url.ts b/src/legacy/ui/public/url/kibana_parsed_url.ts
deleted file mode 100644
index 1c60e8729e0ff..0000000000000
--- a/src/legacy/ui/public/url/kibana_parsed_url.ts
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { parse } from 'url';
-
-import { modifyUrl } from '../../../../core/public';
-import { prependPath } from './prepend_path';
-
-interface Options {
- /**
- * An optional base path for kibana. If supplied, should start with a "/".
- * e.g. in https://localhost:5601/gra/app/visualize#/edit/viz_id the
- * basePath is "/gra"
- */
- basePath?: string;
-
- /**
- * The app id.
- * e.g. in https://localhost:5601/gra/app/visualize#/edit/viz_id the app id is "kibana".
- */
- appId: string;
-
- /**
- * The path for a page in the the app. Should start with a "/". Don't include the hash sign. Can
- * include all query parameters.
- * e.g. in https://localhost:5601/gra/app/visualize#/edit/viz_id?g=state the appPath is
- * "/edit/viz_id?g=state"
- */
- appPath?: string;
-
- /**
- * Optional hostname. Uses current window location's hostname if hostname, port,
- * and protocol are undefined.
- */
- hostname?: string;
-
- /**
- * Optional port. Uses current window location's port if hostname, port,
- * and protocol are undefined.
- */
- port?: string;
-
- /**
- * Optional protocol. Uses current window location's protocol if hostname, port,
- * and protocol are undefined.
- */
- protocol?: string;
-}
-
-/**
- * Represents the pieces that make up a url in Kibana, offering some helpful functionality
- * for translating those pieces into absolute or relative urls. A Kibana url with a basePath
- * looks like this: http://localhost:5601/basePath/app/appId#/an/appPath?with=query¶ms
- *
- * - basePath is "/basePath"
- * - appId is "appId"
- * - appPath is "/an/appPath?with=query¶ms"
- *
- * Almost all urls in Kibana should have this structure, including the "/app" portion in front of the appId
- * (one exception is the login link).
- */
-export class KibanaParsedUrl {
- public appId: string;
- public appPath: string;
- public basePath: string;
- public hostname?: string;
- public protocol?: string;
- public port?: string;
-
- constructor(options: Options) {
- const { appId, basePath = '', appPath = '', hostname, protocol, port } = options;
-
- // We'll use window defaults
- const hostOrProtocolSpecified = hostname || protocol || port;
-
- this.basePath = basePath;
- this.appId = appId;
- this.appPath = appPath;
- this.hostname = hostOrProtocolSpecified ? hostname : window.location.hostname;
- this.port = hostOrProtocolSpecified ? port : window.location.port;
- this.protocol = hostOrProtocolSpecified ? protocol : window.location.protocol;
- }
-
- public getGlobalState() {
- if (!this.appPath) {
- return '';
- }
- const parsedUrl = parse(this.appPath, true);
- const query = parsedUrl.query || {};
- return query._g || '';
- }
-
- public setGlobalState(newGlobalState: string | string[]) {
- if (!this.appPath) {
- return;
- }
-
- this.appPath = modifyUrl(this.appPath, (parsed) => {
- parsed.query._g = newGlobalState;
- });
- }
-
- public addQueryParameter(name: string, val: string) {
- this.appPath = modifyUrl(this.appPath, (parsed) => {
- parsed.query[name] = val;
- });
- }
-
- public getHashedAppPath() {
- return `#${this.appPath}`;
- }
-
- public getAppBasePath() {
- return `/${this.appId}`;
- }
-
- public getAppRootPath() {
- return `/app${this.getAppBasePath()}${this.getHashedAppPath()}`;
- }
-
- public getRootRelativePath() {
- return prependPath(this.getAppRootPath(), this.basePath);
- }
-
- public getAbsoluteUrl() {
- return modifyUrl(this.getRootRelativePath(), (parsed) => {
- parsed.protocol = this.protocol;
- parsed.port = this.port;
- parsed.hostname = this.hostname;
- });
- }
-}
diff --git a/src/legacy/ui/public/url/prepend_path.ts b/src/legacy/ui/public/url/prepend_path.ts
deleted file mode 100644
index b8a77d5c23bee..0000000000000
--- a/src/legacy/ui/public/url/prepend_path.ts
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { isString } from 'lodash';
-import { format, parse } from 'url';
-
-/**
- *
- * @param {string} relativePath - a relative path that must start with a "/".
- * @param {string} newPath - the new path to prefix. ex: 'xyz'
- * @return {string} the url with the basePath prepended. ex. '/xyz/app/kibana#/management'. If
- * the relative path isn't in the right format (e.g. doesn't start with a "/") the relativePath is returned
- * unchanged.
- */
-export function prependPath(relativePath: string, newPath = '') {
- if (!relativePath || !isString(relativePath)) {
- return relativePath;
- }
-
- const parsed = parse(relativePath, true, true);
- if (!parsed.host && parsed.pathname) {
- if (parsed.pathname[0] === '/') {
- parsed.pathname = newPath + parsed.pathname;
- }
- }
-
- return format({
- protocol: parsed.protocol,
- host: parsed.host,
- pathname: parsed.pathname,
- query: parsed.query,
- hash: parsed.hash,
- });
-}
diff --git a/src/legacy/ui/public/url/redirect_when_missing.js b/src/legacy/ui/public/url/redirect_when_missing.js
deleted file mode 100644
index 85c90a14d9fd7..0000000000000
--- a/src/legacy/ui/public/url/redirect_when_missing.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import React from 'react';
-import { i18n } from '@kbn/i18n';
-import { MarkdownSimple } from '../../../../plugins/kibana_react/public';
-import { toastNotifications } from 'ui/notify';
-import { SavedObjectNotFound } from '../../../../plugins/kibana_utils/public';
-import { uiModules } from '../modules';
-
-uiModules.get('kibana/url').service('redirectWhenMissing', function (Private) {
- return Private(RedirectWhenMissingProvider);
-});
-
-export function RedirectWhenMissingProvider(kbnUrl, Promise) {
- /**
- * Creates an error handler that will redirect to a url when a SavedObjectNotFound
- * error is thrown
- *
- * @param {string|object} mapping - a mapping of url's to redirect to based on the saved object that
- * couldn't be found, or just a string that will be used for all types
- * @return {function} - the handler to pass to .catch()
- */
- return function (mapping) {
- if (typeof mapping === 'string') {
- mapping = { '*': mapping };
- }
-
- return function (error) {
- // if this error is not "404", rethrow
- const savedObjectNotFound = error instanceof SavedObjectNotFound;
- const unknownVisType = error.message.indexOf('Invalid type') === 0;
- if (unknownVisType) {
- error.savedObjectType = 'visualization';
- } else if (!savedObjectNotFound) {
- throw error;
- }
-
- let url = mapping[error.savedObjectType] || mapping['*'];
- if (!url) url = '/';
-
- url += (url.indexOf('?') >= 0 ? '&' : '?') + `notFound=${error.savedObjectType}`;
-
- toastNotifications.addWarning({
- title: i18n.translate('common.ui.url.savedObjectIsMissingNotificationMessage', {
- defaultMessage: 'Saved object is missing',
- }),
- text: {error.message} ,
- });
-
- kbnUrl.redirect(url);
- return Promise.halt();
- };
- };
-}
diff --git a/src/legacy/ui/public/url/relative_to_absolute.ts b/src/legacy/ui/public/url/relative_to_absolute.ts
deleted file mode 100644
index 7d0737d145a1b..0000000000000
--- a/src/legacy/ui/public/url/relative_to_absolute.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- *
- * @param {string} url - a relative or root relative url. If a relative path is given then the
- * absolute url returned will depend on the current page where this function is called from. For example
- * if you are on page "http://www.mysite.com/shopping/kids" and you pass this function "adults", you would get
- * back "http://www.mysite.com/shopping/adults". If you passed this function a root relative path, or one that
- * starts with a "/", for example "/account/cart", you would get back "http://www.mysite.com/account/cart".
- * @return {string} the relative url transformed into an absolute url
- */
-export function relativeToAbsolute(url: string) {
- // convert all link urls to absolute urls
- const a = document.createElement('a');
- a.setAttribute('href', url);
- return a.href;
-}
diff --git a/src/legacy/ui/public/url/url.js b/src/legacy/ui/public/url/url.js
deleted file mode 100644
index fb243b02e05c7..0000000000000
--- a/src/legacy/ui/public/url/url.js
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { i18n } from '@kbn/i18n';
-import { uiModules } from '../modules';
-import { AppStateProvider } from '../state_management/app_state';
-
-uiModules.get('kibana/url').service('kbnUrl', function (Private, $injector) {
- //config is not directly used but registers global event listeners to kbnUrl to function
- $injector.get('config');
- return Private(KbnUrlProvider);
-});
-
-export function KbnUrlProvider($injector, $location, $rootScope, $parse, Private) {
- /**
- * the `kbnUrl` service was created to smooth over some of the
- * inconsistent behavior that occurs when modifying the url via
- * the `$location` api. In general it is recommended that you use
- * the `kbnUrl` service any time you want to modify the url.
- *
- * "features" that `kbnUrl` does it's best to guarantee, which
- * are not guaranteed with the `$location` service:
- * - calling `kbnUrl.change()` with a url that resolves to the current
- * route will force a full transition (rather than just updating the
- * properties of the $route object)
- *
- * Additional features of `kbnUrl`
- * - parameterized urls
- * - easily include an app state with the url
- *
- * @type {KbnUrl}
- */
- const self = this;
-
- /**
- * Navigate to a url
- *
- * @param {String} url - the new url, can be a template. See #eval
- * @param {Object} [paramObj] - optional set of parameters for the url template
- * @return {undefined}
- */
- self.change = function (url, paramObj, appState) {
- self._changeLocation('url', url, paramObj, false, appState);
- };
-
- /**
- * Same as #change except only changes the url's path,
- * leaving the search string and such intact
- *
- * @param {String} path - the new path, can be a template. See #eval
- * @param {Object} [paramObj] - optional set of parameters for the path template
- * @return {undefined}
- */
- self.changePath = function (path, paramObj) {
- self._changeLocation('path', path, paramObj);
- };
-
- /**
- * Same as #change except that it removes the current url from history
- *
- * @param {String} url - the new url, can be a template. See #eval
- * @param {Object} [paramObj] - optional set of parameters for the url template
- * @return {undefined}
- */
- self.redirect = function (url, paramObj, appState) {
- self._changeLocation('url', url, paramObj, true, appState);
- };
-
- /**
- * Same as #redirect except only changes the url's path,
- * leaving the search string and such intact
- *
- * @param {String} path - the new path, can be a template. See #eval
- * @param {Object} [paramObj] - optional set of parameters for the path template
- * @return {undefined}
- */
- self.redirectPath = function (path, paramObj) {
- self._changeLocation('path', path, paramObj, true);
- };
-
- /**
- * Evaluate a url template. templates can contain double-curly wrapped
- * expressions that are evaluated in the context of the paramObj
- *
- * @param {String} template - the url template to evaluate
- * @param {Object} [paramObj] - the variables to expose to the template
- * @return {String} - the evaluated result
- * @throws {Error} If any of the expressions can't be parsed.
- */
- self.eval = function (template, paramObj) {
- paramObj = paramObj || {};
-
- return template.replace(/\{\{([^\}]+)\}\}/g, function (match, expr) {
- // remove filters
- const key = expr.split('|')[0].trim();
-
- // verify that the expression can be evaluated
- const p = $parse(key)(paramObj);
-
- // if evaluation can't be made, throw
- if (_.isUndefined(p)) {
- throw new Error(
- i18n.translate('common.ui.url.replacementFailedErrorMessage', {
- defaultMessage: 'Replacement failed, unresolved expression: {expr}',
- values: { expr },
- })
- );
- }
-
- return encodeURIComponent($parse(expr)(paramObj));
- });
- };
-
- /**
- * convert an object's route to an href, compatible with
- * window.location.href= and
- *
- * @param {Object} obj - any object that list's it's routes at obj.routes{}
- * @param {string} route - the route name
- * @return {string} - the computed href
- */
- self.getRouteHref = function (obj, route) {
- return '#' + self.getRouteUrl(obj, route);
- };
-
- /**
- * convert an object's route to a url, compatible with url.change() or $location.url()
- *
- * @param {Object} obj - any object that list's it's routes at obj.routes{}
- * @param {string} route - the route name
- * @return {string} - the computed url
- */
- self.getRouteUrl = function (obj, route) {
- const template = obj && obj.routes && obj.routes[route];
- if (template) return self.eval(template, obj);
- };
-
- /**
- * Similar to getRouteUrl, supports objects which list their routes,
- * and redirects to the named route. See #redirect
- *
- * @param {Object} obj - any object that list's it's routes at obj.routes{}
- * @param {string} route - the route name
- * @return {undefined}
- */
- self.redirectToRoute = function (obj, route) {
- self.redirect(self.getRouteUrl(obj, route));
- };
-
- /**
- * Similar to getRouteUrl, supports objects which list their routes,
- * and changes the url to the named route. See #change
- *
- * @param {Object} obj - any object that list's it's routes at obj.routes{}
- * @param {string} route - the route name
- * @return {undefined}
- */
- self.changeToRoute = function (obj, route) {
- self.change(self.getRouteUrl(obj, route));
- };
-
- /**
- * Removes the given parameter from the url. Does so without modifying the browser
- * history.
- * @param param
- */
- self.removeParam = function (param) {
- $location.search(param, null).replace();
- };
-
- /////
- // private api
- /////
- let reloading;
-
- self._changeLocation = function (type, url, paramObj, replace, appState) {
- const prev = {
- path: $location.path(),
- search: $location.search(),
- };
-
- url = self.eval(url, paramObj);
- $location[type](url);
- if (replace) $location.replace();
-
- if (appState) {
- $location.search(appState.getQueryParamName(), appState.toQueryParam());
- }
-
- const next = {
- path: $location.path(),
- search: $location.search(),
- };
-
- if ($injector.has('$route')) {
- const $route = $injector.get('$route');
-
- if (self._shouldForceReload(next, prev, $route)) {
- const appState = Private(AppStateProvider).getAppState();
- if (appState) appState.destroy();
-
- reloading = $rootScope.$on('$locationChangeSuccess', function () {
- // call the "unlisten" function returned by $on
- reloading();
- reloading = false;
-
- $route.reload();
- });
- }
- }
- };
-
- // determine if the router will automatically reload the route
- self._shouldForceReload = function (next, prev, $route) {
- if (reloading) return false;
-
- const route = $route.current && $route.current.$$route;
- if (!route) return false;
-
- // for the purposes of determining whether the router will
- // automatically be reloading, '' and '/' are equal
- const nextPath = next.path || '/';
- const prevPath = prev.path || '/';
- if (nextPath !== prevPath) return false;
-
- const reloadOnSearch = route.reloadOnSearch;
- const searchSame = _.isEqual(next.search, prev.search);
- return (reloadOnSearch && searchSame) || !reloadOnSearch;
- };
-}
diff --git a/src/legacy/ui/public/utils/collection.test.ts b/src/legacy/ui/public/utils/collection.test.ts
deleted file mode 100644
index 0841e3554c0d0..0000000000000
--- a/src/legacy/ui/public/utils/collection.test.ts
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { move } from './collection';
-
-describe('collection', () => {
- describe('move', () => {
- test('accepts previous from->to syntax', () => {
- const list = [1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1];
-
- expect(list[3]).toBe(1);
- expect(list[8]).toBe(8);
-
- move(list, 8, 3);
-
- expect(list[8]).toBe(1);
- expect(list[3]).toBe(8);
- });
-
- test('moves an object up based on a function callback', () => {
- const list = [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1];
-
- expect(list[4]).toBe(0);
- expect(list[5]).toBe(1);
- expect(list[6]).toBe(0);
-
- move(list, 5, false, (v: any) => v === 0);
-
- expect(list[4]).toBe(1);
- expect(list[5]).toBe(0);
- expect(list[6]).toBe(0);
- });
-
- test('moves an object down based on a function callback', () => {
- const list = [1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1];
-
- expect(list[4]).toBe(0);
- expect(list[5]).toBe(1);
- expect(list[6]).toBe(0);
-
- move(list, 5, true, (v: any) => v === 0);
-
- expect(list[4]).toBe(0);
- expect(list[5]).toBe(0);
- expect(list[6]).toBe(1);
- });
-
- test('moves an object up based on a where callback', () => {
- const list = [
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 0 },
- { v: 1 },
- { v: 0 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- ];
-
- expect(list[4]).toHaveProperty('v', 0);
- expect(list[5]).toHaveProperty('v', 1);
- expect(list[6]).toHaveProperty('v', 0);
-
- move(list, 5, false, { v: 0 });
-
- expect(list[4]).toHaveProperty('v', 1);
- expect(list[5]).toHaveProperty('v', 0);
- expect(list[6]).toHaveProperty('v', 0);
- });
-
- test('moves an object down based on a where callback', () => {
- const list = [
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 0 },
- { v: 1 },
- { v: 0 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- { v: 1 },
- ];
-
- expect(list[4]).toHaveProperty('v', 0);
- expect(list[5]).toHaveProperty('v', 1);
- expect(list[6]).toHaveProperty('v', 0);
-
- move(list, 5, true, { v: 0 });
-
- expect(list[4]).toHaveProperty('v', 0);
- expect(list[5]).toHaveProperty('v', 0);
- expect(list[6]).toHaveProperty('v', 1);
- });
-
- test('moves an object down based on a pluck callback', () => {
- const list = [
- { id: 0, normal: true },
- { id: 1, normal: true },
- { id: 2, normal: true },
- { id: 3, normal: true },
- { id: 4, normal: true },
- { id: 5, normal: false },
- { id: 6, normal: true },
- { id: 7, normal: true },
- { id: 8, normal: true },
- { id: 9, normal: true },
- ];
-
- expect(list[4]).toHaveProperty('id', 4);
- expect(list[5]).toHaveProperty('id', 5);
- expect(list[6]).toHaveProperty('id', 6);
-
- move(list, 5, true, 'normal');
-
- expect(list[4]).toHaveProperty('id', 4);
- expect(list[5]).toHaveProperty('id', 6);
- expect(list[6]).toHaveProperty('id', 5);
- });
- });
-});
diff --git a/src/legacy/ui/public/utils/collection.ts b/src/legacy/ui/public/utils/collection.ts
deleted file mode 100644
index b882a2bbe6e5b..0000000000000
--- a/src/legacy/ui/public/utils/collection.ts
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-
-/**
- * move an obj either up or down in the collection by
- * injecting it either before/after the prev/next obj that
- * satisfied the qualifier
- *
- * or, just from one index to another...
- *
- * @param {array} objs - the list to move the object within
- * @param {number|any} obj - the object that should be moved, or the index that the object is currently at
- * @param {number|boolean} below - the index to move the object to, or whether it should be moved up or down
- * @param {function} qualifier - a lodash-y callback, object = _.where, string = _.pluck
- * @return {array} - the objs argument
- */
-export function move(
- objs: any[],
- obj: object | number,
- below: number | boolean,
- qualifier?: ((object: object, index: number) => any) | Record | string
-): object[] {
- const origI = _.isNumber(obj) ? obj : objs.indexOf(obj);
- if (origI === -1) {
- return objs;
- }
-
- if (_.isNumber(below)) {
- // move to a specific index
- objs.splice(below, 0, objs.splice(origI, 1)[0]);
- return objs;
- }
-
- below = !!below;
- qualifier = qualifier && _.iteratee(qualifier);
-
- const above = !below;
- const finder = below ? _.findIndex : _.findLastIndex;
-
- // find the index of the next/previous obj that meets the qualifications
- const targetI = finder(objs, (otherAgg, otherI) => {
- if (below && otherI <= origI) {
- return;
- }
- if (above && otherI >= origI) {
- return;
- }
- return Boolean(_.isFunction(qualifier) && qualifier(otherAgg, otherI));
- });
-
- if (targetI === -1) {
- return objs;
- }
-
- // place the obj at it's new index
- objs.splice(targetI, 0, objs.splice(origI, 1)[0]);
- return objs;
-}
diff --git a/src/legacy/ui/public/utils/legacy_class.js b/src/legacy/ui/public/utils/legacy_class.js
deleted file mode 100644
index f47650a77bb6d..0000000000000
--- a/src/legacy/ui/public/utils/legacy_class.js
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-// create a property descriptor for properties
-// that won't change
-function describeConst(val) {
- return {
- writable: false,
- enumerable: false,
- configurable: false,
- value: val,
- };
-}
-
-const props = {
- inherits: describeConst(function (SuperClass) {
- const prototype = Object.create(SuperClass.prototype, {
- constructor: describeConst(this),
- superConstructor: describeConst(SuperClass),
- });
-
- Object.defineProperties(this, {
- prototype: describeConst(prototype),
- Super: describeConst(SuperClass),
- });
-
- return this;
- }),
-};
-
-/**
- * Add class-related behavior to a function, currently this
- * only attaches an .inherits() method.
- *
- * @param {Constructor} ClassConstructor - The function that should be extended
- * @return {Constructor} - the constructor passed in;
- */
-export function createLegacyClass(ClassConstructor) {
- return Object.defineProperties(ClassConstructor, props);
-}
diff --git a/src/plugins/advanced_settings/public/management_app/advanced_settings.test.tsx b/src/plugins/advanced_settings/public/management_app/advanced_settings.test.tsx
index 6103041cf0a4c..68a21c6a1587c 100644
--- a/src/plugins/advanced_settings/public/management_app/advanced_settings.test.tsx
+++ b/src/plugins/advanced_settings/public/management_app/advanced_settings.test.tsx
@@ -32,10 +32,6 @@ import { AdvancedSettingsComponent } from './advanced_settings';
import { notificationServiceMock, docLinksServiceMock } from '../../../../core/public/mocks';
import { ComponentRegistry } from '../component_registry';
-jest.mock('ui/new_platform', () => ({
- npStart: mockConfig(),
-}));
-
jest.mock('./components/field', () => ({
Field: () => {
return 'field';
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.test.mock.ts b/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.test.mock.ts
index 51f4fc7ce94b9..5e0eeaee3c0d0 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.test.mock.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index_patterns_api_client.test.mock.ts
@@ -22,5 +22,3 @@ import { setup } from 'test_utils/http_test_setup';
export const { http } = setup((injectedMetadata) => {
injectedMetadata.getBasePath.mockReturnValue('/hola/daro/');
});
-
-jest.doMock('ui/new_platform', () => ({ npSetup: { core: { http } } }));
diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md
index ba40dece25df9..0c4465ae7f4b9 100644
--- a/src/plugins/data/public/public.api.md
+++ b/src/plugins/data/public/public.api.md
@@ -1508,7 +1508,7 @@ export interface QueryState {
// Warning: (ae-missing-release-tag) "QueryStringInput" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
//
// @public (undocumented)
-export const QueryStringInput: React.FC>;
+export const QueryStringInput: React.FC>;
// @public (undocumented)
export type QuerySuggestion = QuerySuggestionBasic | QuerySuggestionField;
diff --git a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
index 86ee98b7af9d8..2d311fd88eb39 100644
--- a/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
+++ b/src/plugins/data/public/ui/query_string_input/query_string_input.tsx
@@ -17,8 +17,7 @@
* under the License.
*/
-import { Component } from 'react';
-import React from 'react';
+import React, { Component, RefObject, createRef } from 'react';
import { i18n } from '@kbn/i18n';
import {
@@ -30,6 +29,7 @@ import {
EuiButton,
EuiLink,
htmlIdGenerator,
+ EuiPortal,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -42,6 +42,7 @@ import { withKibana, KibanaReactContextValue, toMountPoint } from '../../../../k
import { fetchIndexPatterns } from './fetch_index_patterns';
import { QueryLanguageSwitcher } from './language_switcher';
import { PersistedLog, getQueryLog, matchPairs, toUser, fromUser } from '../../query';
+import { SuggestionsListSize } from '../typeahead/suggestions_component';
import { SuggestionsComponent } from '..';
interface Props {
@@ -60,6 +61,7 @@ interface Props {
onChangeQueryInputFocus?: (isFocused: boolean) => void;
onSubmit?: (query: Query) => void;
dataTestSubj?: string;
+ size?: SuggestionsListSize;
}
interface State {
@@ -70,6 +72,7 @@ interface State {
selectionStart: number | null;
selectionEnd: number | null;
indexPatterns: IIndexPattern[];
+ queryBarRect: DOMRect | undefined;
}
const KEY_CODES = {
@@ -93,6 +96,7 @@ export class QueryStringInputUI extends Component {
selectionStart: null,
selectionEnd: null,
indexPatterns: [],
+ queryBarRect: undefined,
};
public inputRef: HTMLTextAreaElement | null = null;
@@ -101,6 +105,7 @@ export class QueryStringInputUI extends Component {
private abortController?: AbortController;
private services = this.props.kibana.services;
private componentIsUnmounting = false;
+ private queryBarInputDivRefInstance: RefObject = createRef();
private getQueryString = () => {
return toUser(this.props.query.query);
@@ -494,8 +499,13 @@ export class QueryStringInputUI extends Component {
this.initPersistedLog();
this.fetchIndexPatterns().then(this.updateSuggestions);
+ this.handleListUpdate();
window.addEventListener('resize', this.handleAutoHeight);
+ window.addEventListener('scroll', this.handleListUpdate, {
+ passive: true, // for better performance as we won't call preventDefault
+ capture: true, // scroll events don't bubble, they must be captured instead
+ });
}
public componentDidUpdate(prevProps: Props) {
@@ -533,12 +543,19 @@ export class QueryStringInputUI extends Component {
this.updateSuggestions.cancel();
this.componentIsUnmounting = true;
window.removeEventListener('resize', this.handleAutoHeight);
+ window.removeEventListener('scroll', this.handleListUpdate);
}
+ handleListUpdate = () =>
+ this.setState({
+ queryBarRect: this.queryBarInputDivRefInstance.current?.getBoundingClientRect(),
+ });
+
handleAutoHeight = () => {
if (this.inputRef !== null && document.activeElement === this.inputRef) {
this.inputRef.style.setProperty('height', `${this.inputRef.scrollHeight}px`, 'important');
}
+ this.handleListUpdate();
};
handleRemoveHeight = () => {
@@ -587,6 +604,7 @@ export class QueryStringInputUI extends Component {
{
{this.getQueryString()}
-
-
+
+
+
diff --git a/src/plugins/data/public/ui/typeahead/__snapshots__/suggestions_component.test.tsx.snap b/src/plugins/data/public/ui/typeahead/__snapshots__/suggestions_component.test.tsx.snap
index 3b51c1db50d00..2fa7834872f6b 100644
--- a/src/plugins/data/public/ui/typeahead/__snapshots__/suggestions_component.test.tsx.snap
+++ b/src/plugins/data/public/ui/typeahead/__snapshots__/suggestions_component.test.tsx.snap
@@ -1,17 +1,21 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`SuggestionsComponent Passing the index should control which suggestion is selected 1`] = `
-
+
`;
exports[`SuggestionsComponent Should display given suggestions if the show prop is true 1`] = `
-
+
`;
diff --git a/src/plugins/data/public/ui/typeahead/_suggestion.scss b/src/plugins/data/public/ui/typeahead/_suggestion.scss
index 81c05f1a8a78c..67ff17d017053 100644
--- a/src/plugins/data/public/ui/typeahead/_suggestion.scss
+++ b/src/plugins/data/public/ui/typeahead/_suggestion.scss
@@ -6,28 +6,36 @@ $kbnTypeaheadTypes: (
conjunction: $euiColorVis3,
);
+.kbnTypeahead.kbnTypeahead--small {
+ max-height: 20vh;
+}
+
+.kbnTypeahead__popover--top {
+ @include euiBottomShadowFlat;
+ border-top-left-radius: $euiBorderRadius;
+ border-top-right-radius: $euiBorderRadius;
+}
+
+.kbnTypeahead__popover--bottom {
+ @include euiBottomShadow($adjustBorders: true);
+ border-bottom-left-radius: $euiBorderRadius;
+ border-bottom-right-radius: $euiBorderRadius;
+}
+
.kbnTypeahead {
- position: relative;
+ max-height: 60vh;
.kbnTypeahead__popover {
- @include euiBottomShadow($adjustBorders: true);
+ max-height: inherit;
+ @include euiScrollBar;
border: 1px solid;
border-color: $euiBorderColor;
color: $euiTextColor;
background-color: $euiColorEmptyShade;
- position: absolute;
- top: -2px;
+ position: relative;
z-index: $euiZContentMenu;
width: 100%;
- border-bottom-left-radius: $euiBorderRadius;
- border-bottom-right-radius: $euiBorderRadius;
-
- .kbnTypeahead__items {
- @include euiScrollBar;
-
- max-height: 60vh;
- overflow-y: auto;
- }
+ overflow-y: auto;
.kbnTypeahead__item {
height: $euiSizeXL;
diff --git a/src/legacy/ui/public/notify/toasts/toast_notifications.ts b/src/plugins/data/public/ui/typeahead/constants.ts
similarity index 64%
rename from src/legacy/ui/public/notify/toasts/toast_notifications.ts
rename to src/plugins/data/public/ui/typeahead/constants.ts
index d3ec8edb5d73a..08f9bd23e16f3 100644
--- a/src/legacy/ui/public/notify/toasts/toast_notifications.ts
+++ b/src/plugins/data/public/ui/typeahead/constants.ts
@@ -16,7 +16,21 @@
* specific language governing permissions and limitations
* under the License.
*/
+
/**
- * ToastNotifications is deprecated! Please use npSetup.core.notifications.toasts instead
+ * Minimum width in px to display suggestion description correctly
+ * @public
*/
-export { ToastNotifications } from '../../../../../plugins/kibana_legacy/public';
+export const SUGGESTIONS_LIST_REQUIRED_WIDTH = 600;
+
+/**
+ * Minimum bottom distance in px to display list of suggestions
+ * @public
+ */
+export const SUGGESTIONS_LIST_REQUIRED_BOTTOM_SPACE = 250;
+
+/**
+ * A distance in px to display suggestions list right under the query input without a gap
+ * @public
+ */
+export const SUGGESTIONS_LIST_REQUIRED_TOP_OFFSET = 2;
diff --git a/src/plugins/data/public/ui/typeahead/suggestion_component.test.tsx b/src/plugins/data/public/ui/typeahead/suggestion_component.test.tsx
index 9fe33b003527e..ba78bdd802601 100644
--- a/src/plugins/data/public/ui/typeahead/suggestion_component.test.tsx
+++ b/src/plugins/data/public/ui/typeahead/suggestion_component.test.tsx
@@ -44,6 +44,7 @@ describe('SuggestionComponent', () => {
suggestion={mockSuggestion}
innerRef={noop}
ariaId={'suggestion-1'}
+ shouldDisplayDescription={true}
/>
);
@@ -59,6 +60,7 @@ describe('SuggestionComponent', () => {
suggestion={mockSuggestion}
innerRef={noop}
ariaId={'suggestion-1'}
+ shouldDisplayDescription={true}
/>
);
@@ -79,6 +81,7 @@ describe('SuggestionComponent', () => {
suggestion={mockSuggestion}
innerRef={innerRefCallback}
ariaId={'suggestion-1'}
+ shouldDisplayDescription={true}
/>
);
});
@@ -94,6 +97,7 @@ describe('SuggestionComponent', () => {
suggestion={mockSuggestion}
innerRef={noop}
ariaId={'suggestion-1'}
+ shouldDisplayDescription={true}
/>
);
@@ -113,6 +117,7 @@ describe('SuggestionComponent', () => {
suggestion={mockSuggestion}
innerRef={noop}
ariaId={'suggestion-1'}
+ shouldDisplayDescription={true}
/>
);
diff --git a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx
index b859428e6ed7e..724287b874bf7 100644
--- a/src/plugins/data/public/ui/typeahead/suggestion_component.tsx
+++ b/src/plugins/data/public/ui/typeahead/suggestion_component.tsx
@@ -46,6 +46,7 @@ interface Props {
suggestion: QuerySuggestion;
innerRef: (node: HTMLDivElement) => void;
ariaId: string;
+ shouldDisplayDescription: boolean;
}
export function SuggestionComponent(props: Props) {
@@ -72,7 +73,9 @@ export function SuggestionComponent(props: Props) {
{props.suggestion.text}
-
{props.suggestion.description}
+ {props.shouldDisplayDescription && (
+
{props.suggestion.description}
+ )}