Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moves styleSheetPath to uiExports #23007

Merged
merged 16 commits into from
Sep 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/kbn-plugin-generator/sao_template/template/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ export default function (kibana) {
title: '<%= startCase(name) %>',
description: '<%= description %>',
main: 'plugins/<%= snakeCase(name) %>/app',
<%_ if (generateScss) { -%>
styleSheetPath: require('path').resolve(__dirname, 'public/app.scss'),
<%_ } -%>
},
<%_ } -%>
<%_ if (generateHack) { -%>
hacks: [
'plugins/<%= snakeCase(name) %>/hack'
]
<%_ } -%>
<%_ if (generateScss) { -%>
styleSheetPaths: require('path').resolve(__dirname, 'public/app.scss'),
<%_ } -%>
},

config(Joi) {
Expand Down
3 changes: 1 addition & 2 deletions src/core_plugins/kibana/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,8 @@ export default function (kibana) {
listed: false,
description: 'the kibana you know and love',
main: 'plugins/kibana/kibana',
styleSheetPath: `${__dirname}/public/index.scss`,
},

styleSheetPaths: `${__dirname}/public/index.scss`,
links: [
{
id: 'kibana:discover',
Expand Down
4 changes: 2 additions & 2 deletions src/core_plugins/status_page/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default function (kibana) {
main: 'plugins/status_page/status_page',
hidden: true,
url: '/status',
styleSheetPath: `${__dirname}/public/index.scss`
}
},
styleSheetPaths: `${__dirname}/public/index.scss`,
}
});
}
2 changes: 1 addition & 1 deletion src/core_plugins/status_page/public/index.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@import 'ui/public/styles/styling_constants';

// SASSTODO: Remove when K7 applies background color to body
.stsPage {
#status_page-app .stsPage {
min-height: 100vh;
}
4 changes: 3 additions & 1 deletion src/dev/build/tasks/transpile_scss_task.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import { toArray } from 'rxjs/operators';
import { buildAll } from '../../../server/sass/build_all';
import { findPluginSpecs } from '../../../plugin_discovery/find_plugin_specs';
import { collectUiExports } from '../../../ui/ui_exports/collect_ui_exports';

export const TranspileScssTask = {
description: 'Transpiling SCSS to CSS',
Expand All @@ -30,9 +31,10 @@ export const TranspileScssTask = {

const { spec$ } = findPluginSpecs({ plugins: { scanDirs, paths } });
const enabledPlugins = await spec$.pipe(toArray()).toPromise();
const uiExports = collectUiExports(enabledPlugins);

try {
const bundles = await buildAll(enabledPlugins);
const bundles = await buildAll(uiExports.styleSheetPaths);
bundles.forEach(bundle => log.info(`Compiled SCSS: ${bundle.source}`));
} catch (error) {
const { message, line, file } = error;
Expand Down
11 changes: 5 additions & 6 deletions src/server/sass/build_all.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,15 @@
*/

import { Build } from './build';
import { collectUiExports } from '../../ui/ui_exports';

export async function buildAll(enabledPluginSpecs) {
const { uiAppSpecs = [] } = collectUiExports(enabledPluginSpecs);
const bundles = await Promise.all(uiAppSpecs.map(async uiAppSpec => {
if (!uiAppSpec.styleSheetPath) {
export async function buildAll(styleSheets = []) {
const bundles = await Promise.all(styleSheets.map(async styleSheet => {

if (!styleSheet.localPath.endsWith('.scss')) {
return;
}

const bundle = new Build(uiAppSpec.styleSheetPath);
const bundle = new Build(styleSheet.localPath);
await bundle.build();

return bundle;
Expand Down
3 changes: 1 addition & 2 deletions src/server/sass/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export async function sassMixin(kbnServer, server, config) {
return;
}


/**
* Build assets
*
Expand All @@ -40,7 +39,7 @@ export async function sassMixin(kbnServer, server, config) {
let trackedFiles = new Set();

try {
scssBundles = await buildAll(kbnServer.pluginSpecs);
scssBundles = await buildAll(kbnServer.uiExports.styleSheetPaths);

scssBundles.forEach(bundle => {
bundle.includedFiles.forEach(file => trackedFiles.add(file));
Expand Down
3 changes: 3 additions & 0 deletions src/ui/public/chrome/chrome.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ const waitForBootstrap = new Promise(resolve => {
require('uiExports/chromeNavControls');
require('uiExports/hacks');

// sets attribute on body for stylesheet sandboxing
document.body.setAttribute('id', `${internals.app.id}-app`);

chrome.setupAngular();
targetDomElement.setAttribute('id', 'kibana-body');
targetDomElement.setAttribute('kbn-chrome', 'true');
Expand Down
15 changes: 0 additions & 15 deletions src/ui/ui_apps/__tests__/ui_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,6 @@ describe('ui apps / UiApp', () => {
expect(app.getMainModuleId()).to.be(undefined);
});

it('has no styleSheetPath', () => {
expect(app.getStyleSheetUrlPath()).to.be(undefined);
});

it('has a mostly empty JSON representation', () => {
expect(JSON.parse(JSON.stringify(app))).to.eql({
id: spec.id,
Expand Down Expand Up @@ -312,15 +308,4 @@ describe('ui apps / UiApp', () => {
expect(app.getMainModuleId()).to.be('bar');
});
});

describe('#getStyleSheetUrlPath', () => {
it('returns public path to styleSheetPath', () => {
const app = createUiApp(
createStubUiAppSpec({ pluginId: 'foo', id: 'foo', styleSheetPath: '/bar/public/baz/style.scss' }),
createStubKbnServer({ plugins: [{ id: 'foo', publicDir: '/bar/public' }] })
);

expect(app.getStyleSheetUrlPath()).to.eql('plugins/foo/baz/style.css');
});
});
});
23 changes: 0 additions & 23 deletions src/ui/ui_apps/ui_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* under the License.
*/

import path from 'path';
import { UiNavLink } from '../ui_nav_links';

export class UiApp {
Expand All @@ -34,7 +33,6 @@ export class UiApp {
linkToLastSubUrl,
listed,
url = `/app/${id}`,
styleSheetPath,
} = spec;

if (!id) {
Expand All @@ -53,7 +51,6 @@ export class UiApp {
this._url = url;
this._pluginId = pluginId;
this._kbnServer = kbnServer;
this._styleSheetPath = styleSheetPath;

if (this._pluginId && !this._getPlugin()) {
throw new Error(`Unknown plugin id "${this._pluginId}"`);
Expand Down Expand Up @@ -105,25 +102,6 @@ export class UiApp {
return this._main;
}

getStyleSheetUrlPath() {
if (!this._styleSheetPath) {
return;
}

const plugin = this._getPlugin();

// get the path of the stylesheet relative to the public dir for the plugin
let relativePath = path.relative(plugin.publicDir, this._styleSheetPath);

// replace back slashes on windows
relativePath = relativePath.split('\\').join('/');

// replace the extension of relativePath to be .css
relativePath = relativePath.slice(0, -path.extname(relativePath).length) + '.css';

return `plugins/${plugin.id}/${relativePath}`;
}

_getPlugin() {
const pluginId = this._pluginId;
const { plugins } = this._kbnServer;
Expand All @@ -142,7 +120,6 @@ export class UiApp {
main: this._main,
navLink: this._navLink,
linkToLastSubUrl: this._linkToLastSubUrl,
styleSheetPath: this._styleSheetPath,
};
}
}
2 changes: 2 additions & 0 deletions src/ui/ui_exports/ui_export_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export const UI_EXPORT_DEFAULTS = {

translationPaths: [],

styleSheetPaths: [],

appExtensions: {
fieldFormatEditors: [
'ui/field_editor/components/field_format_editor/register'
Expand Down
4 changes: 4 additions & 0 deletions src/ui/ui_exports/ui_export_types/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ export {
links,
} from './ui_nav_links';

export {
styleSheetPaths
} from './style_sheet_paths';

export {
uiSettingDefaults,
} from './ui_settings';
Expand Down
67 changes: 67 additions & 0 deletions src/ui/ui_exports/ui_export_types/style_sheet_paths.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* 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 path from 'path';
import { flatConcatAtType } from './reduce';
import { mapSpec, wrap } from './modify_reduce';

const OK_EXTNAMES = ['.css', '.scss'];

function normalize(localPath, type, pluginSpec) {
const pluginId = pluginSpec.getId();
const publicDir = pluginSpec.getPublicDir();
const extname = path.extname(localPath);

if (!OK_EXTNAMES.includes(extname)) {
throw new Error(
`[plugin:${pluginId}] uiExports.styleSheetPaths supported extensions [${OK_EXTNAMES.join(', ')}], got "${extname}"`
);
}

if (!path.isAbsolute(localPath)) {
throw new Error(
`[plugin:${pluginId}] uiExports.styleSheetPaths must be an absolute path, got "${localPath}"`
);
}

if (!localPath.startsWith(publicDir)) {
throw new Error(
`[plugin:${pluginId}] uiExports.styleSheetPaths must be child of publicDir [${publicDir}]`
);
}

// get the path of the stylesheet relative to the public dir for the plugin
let relativePath = path.relative(publicDir, localPath);

// replace back slashes on windows
relativePath = relativePath.split('\\').join('/');

// replace the extension of relativePath to be .css
// publicPath will always point to the css file
relativePath = relativePath.slice(0, -extname.length) + '.css';

const publicPath = `plugins/${pluginSpec.getId()}/${relativePath}`;

return {
localPath,
publicPath
};
}

export const styleSheetPaths = wrap(mapSpec(normalize), flatConcatAtType);
60 changes: 60 additions & 0 deletions src/ui/ui_exports/ui_export_types/style_sheet_paths.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* 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 { styleSheetPaths } from './style_sheet_paths';

describe('uiExports.styleSheetPaths', () => {
const pluginSpec = {
getId: () => 'test',
getPublicDir: () => '/kibana/public'
};

it('does not support relative paths', () => {
expect(() => styleSheetPaths([], 'public/bar.css', 'styleSheetPaths', pluginSpec))
.toThrowError('[plugin:test] uiExports.styleSheetPaths must be an absolute path, got "public/bar.css"');
});

it('path must be child of public path', () => {
expect(() => styleSheetPaths([], '/another/public/bar.css', 'styleSheetPaths', pluginSpec))
.toThrowError('[plugin:test] uiExports.styleSheetPaths must be child of publicDir [/kibana/public]');
});

it('only supports css or scss extensions', () => {
expect(() => styleSheetPaths([], '/kibana/public/bar.bad', 'styleSheetPaths', pluginSpec))
.toThrowError('[plugin:test] uiExports.styleSheetPaths supported extensions [.css, .scss], got ".bad"');
});

it('provides publicPath for scss extensions', () => {
const localPath = '/kibana/public/bar.scss';
const uiExports = styleSheetPaths([], localPath, 'styleSheetPaths', pluginSpec);

expect(uiExports.styleSheetPaths).toHaveLength(1);
expect(uiExports.styleSheetPaths[0].localPath).toEqual(localPath);
expect(uiExports.styleSheetPaths[0].publicPath).toEqual('plugins/test/bar.css');
});

it('provides publicPath for css extensions', () => {
const localPath = '/kibana/public/bar.css';
const uiExports = styleSheetPaths([], localPath, 'styleSheetPaths', pluginSpec);

expect(uiExports.styleSheetPaths).toHaveLength(1);
expect(uiExports.styleSheetPaths[0].localPath).toEqual(localPath);
expect(uiExports.styleSheetPaths[0].publicPath).toEqual('plugins/test/bar.css');
});
});
10 changes: 0 additions & 10 deletions src/ui/ui_exports/ui_export_types/ui_apps.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
* under the License.
*/

import { isAbsolute, normalize } from 'path';
import { flatConcatAtType } from './reduce';
import { alias, mapSpec, wrap } from './modify_reduce';

Expand Down Expand Up @@ -48,14 +47,6 @@ function applySpecDefaults(spec, type, pluginSpec) {
);
}

const styleSheetPath = spec.styleSheetPath ? normalize(spec.styleSheetPath) : undefined;

if (styleSheetPath && (!isAbsolute(styleSheetPath) || !styleSheetPath.startsWith(pluginSpec.getPublicDir()))) {
throw new Error(
`[plugin:${pluginId}] uiExports.app.styleSheetPath must be an absolute path within the public directory`
);
}

return {
pluginId,
id,
Expand All @@ -68,7 +59,6 @@ function applySpecDefaults(spec, type, pluginSpec) {
linkToLastSubUrl,
listed,
url,
styleSheetPath,
};
}

Expand Down
Loading