提交 79187508 编写于 作者: J Joao Moreno

navbar in extension editor

上级 ecf2e326
......@@ -9,6 +9,8 @@ import 'vs/css!./media/extensionEditor';
import { localize } from 'vs/nls';
import { TPromise } from 'vs/base/common/winjs.base';
import { marked } from 'vs/base/common/marked/marked';
import Event, { Emitter } from 'vs/base/common/event';
import { Action } from 'vs/base/common/actions';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, empty, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { Builder } from 'vs/base/browser/builder';
......@@ -21,7 +23,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IThemeService } from 'vs/workbench/services/themes/common/themeService';
import { ExtensionsInput } from './extensionsInput';
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID } from './extensions';
import { IExtensionsWorkbenchService, IExtensionsViewlet, VIEWLET_ID, IExtension } from './extensions';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITemplateData } from './extensionsList';
import { RatingsWidget, InstallWidget } from './extensionsWidgets';
......@@ -44,6 +46,52 @@ function renderBody(body: string): string {
</html>`;
}
class NavBar {
private _onChange = new Emitter<string>();
get onChange(): Event<string> { return this._onChange.event; }
private actions: Action[];
private actionbar: ActionBar;
constructor(container: HTMLElement) {
const element = append(container, $('.navbar'));
this.actions = [];
this.actionbar = new ActionBar(element, { animated: false });
}
push(id: string, label: string): void {
const run = () => {
this._onChange.fire(id);
this.actions.forEach(a => a.enabled = a.id !== action.id);
return TPromise.as(null);
};
const action = new Action(id, label, null, true, run);
this.actions.push(action);
this.actionbar.push(action);
if (this.actions.length === 1) {
run();
}
}
clear(): void {
this.actions = dispose(this.actions);
this.actionbar.clear();
}
dispose(): void {
this.actionbar = dispose(this.actionbar);
}
}
const NavbarSection = {
Readme: 'readme',
Configuration: 'configuration'
};
export class ExtensionEditor extends BaseEditor {
static ID: string = 'workbench.editor.extension';
......@@ -55,13 +103,15 @@ export class ExtensionEditor extends BaseEditor {
private installCount: HTMLElement;
private rating: HTMLAnchorElement;
private description: HTMLElement;
private actionBar: ActionBar;
private body: HTMLElement;
private extensionActionBar: ActionBar;
private navbar: NavBar;
private content: HTMLElement;
private _highlight: ITemplateData;
private highlightDisposable: IDisposable;
private transientDisposables: IDisposable[];
private contentDisposables: IDisposable[] = [];
private transientDisposables: IDisposable[] = [];
private disposables: IDisposable[];
constructor(
......@@ -111,11 +161,14 @@ export class ExtensionEditor extends BaseEditor {
this.description = append(details, $('.description'));
const actions = append(details, $('.actions'));
this.actionBar = new ActionBar(actions, { animated: false });
this.disposables.push(this.actionBar);
const extensionActions = append(details, $('.actions'));
this.extensionActionBar = new ActionBar(extensionActions, { animated: false });
this.disposables.push(this.extensionActionBar);
const body = append(root, $('.body'));
this.navbar = new NavBar(body);
this.body = append(root, $('.body'));
this.content = append(body, $('.content'));
}
setInput(input: ExtensionsInput, options: EditorOptions): TPromise<void> {
......@@ -163,42 +216,64 @@ export class ExtensionEditor extends BaseEditor {
updateAction.extension = extension;
enableAction.extension = extension;
this.actionBar.clear();
this.actionBar.push([enableAction, updateAction, installAction], { icon: true, label: true });
this.extensionActionBar.clear();
this.extensionActionBar.push([enableAction, updateAction, installAction], { icon: true, label: true });
this.transientDisposables.push(enableAction, updateAction, installAction);
this.body.innerHTML = '';
let promise: TPromise<any> = super.setInput(input, options);
if (extension.readmeUrl) {
promise = promise
.then(() => addClass(this.body, 'loading'))
.then(() => this.extensionsWorkbenchService.getReadmeContents(extension))
.then(marked.parse)
.then<void>(body => {
const webview = new WebView(
this.body,
document.querySelector('.monaco-editor-background')
);
webview.style(this.themeService.getColorTheme());
webview.contents = [renderBody(body)];
const linkListener = webview.onDidClickLink(link => shell.openExternal(link.toString()));
const themeListener = this.themeService.onDidColorThemeChange(themeId => webview.style(themeId));
this.transientDisposables.push(webview, linkListener, themeListener);
})
.then(null, () => null)
.then(() => removeClass(this.body, 'loading'));
} else {
promise = promise
.then(() => append(this.body, $('p')))
.then(p => p.textContent = localize('noReadme', "No README available."));
this.navbar.clear();
this.navbar.onChange(this.onNavbarChange.bind(this, extension), this, this.transientDisposables);
this.navbar.push(NavbarSection.Readme, localize('readme', "Readme"));
// this.navbar.push(NavbarSection.Configuration, localize('configuration', "Config"));
this.content.innerHTML = '';
return super.setInput(input, options);
}
private onNavbarChange(extension: IExtension, id: string): void {
this.contentDisposables = dispose(this.contentDisposables);
this.content.innerHTML = '';
switch (id) {
case NavbarSection.Readme: return this.openReadme(extension);
case NavbarSection.Configuration: return this.openConfiguration(extension);
}
}
this.transientDisposables.push(toDisposable(() => promise.cancel()));
private openReadme(extension: IExtension) {
if (!extension.readmeUrl) {
const p = append(this.content, $('p'));
p.textContent = localize('noReadme', "No README available.");
return;
}
addClass(this.content, 'loading');
const promise = this.extensionsWorkbenchService.getReadmeContents(extension)
.then(marked.parse)
.then<void>(body => {
const webview = new WebView(
this.content,
document.querySelector('.monaco-editor-background')
);
webview.style(this.themeService.getColorTheme());
webview.contents = [renderBody(body)];
const linkListener = webview.onDidClickLink(link => shell.openExternal(link.toString()));
const themeListener = this.themeService.onDidColorThemeChange(themeId => webview.style(themeId));
this.contentDisposables.push(webview, linkListener, themeListener);
})
.then(null, () => null)
.then(() => removeClass(this.content, 'loading'));
this.contentDisposables.push(toDisposable(() => promise.cancel()));
}
return TPromise.as(null);
private openConfiguration(extension: IExtension) {
this.content.innerHTML = '';
this.content.innerText = 'configuration';
}
layout(): void {
......
......@@ -101,6 +101,39 @@
overflow: hidden;
}
.extension-editor > .body > p {
margin: 20px;
.extension-editor > .body > .navbar {
height: 36px;
text-transform: uppercase;
font-size: 14px;
line-height: 36px;
padding-left: 20px;
border-bottom: 1px solid rgba(136, 136, 136, 0.45);
box-sizing: border-box;
}
.extension-editor > .body > .navbar > .monaco-action-bar > .actions-container {
justify-content: initial;
}
.extension-editor > .body > .navbar > .monaco-action-bar > .actions-container > .action-item > .action-label {
margin-right: 16px;
}
.extension-editor > .body > .navbar > .monaco-action-bar > .actions-container > .action-item > .action-label {
font-size: inherit;
}
.extension-editor > .body > .navbar > .monaco-action-bar > .actions-container > .action-item.disabled > .action-label {
opacity: 1;
text-decoration: underline;
font-weight: bold;
}
.extension-editor > .body > .navbar > .monaco-action-bar > .actions-container > .action-item > .action-label:hover {
text-decoration: underline;
}
.extension-editor > .body > .content {
height: calc(100% - 36px);
overflow: hidden;
}
\ No newline at end of file
......@@ -10,7 +10,7 @@
.quick-open-widget .extension.loading,
.extensions-viewlet > .extensions .extension.loading,
.extension-editor > .body.loading {
.extension-editor > .body > .content.loading {
background: url('data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgd2lkdGg9IjU3NSIgaGVpZ2h0PSI2cHgiPg0KICA8c3R5bGU+DQogICAgY2lyY2xlIHsNCiAgICAgIGFuaW1hdGlvbjogYmFsbCAyLjVzIGN1YmljLWJlemllcigwLjAwMCwgMS4wMDAsIDEuMDAwLCAwLjAwMCkgaW5maW5pdGU7DQogICAgICBmaWxsOiAjYmJiOw0KICAgIH0NCg0KICAgICNiYWxscyB7DQogICAgICBhbmltYXRpb246IGJhbGxzIDIuNXMgbGluZWFyIGluZmluaXRlOw0KICAgIH0NCg0KICAgICNjaXJjbGUyIHsgYW5pbWF0aW9uLWRlbGF5OiAwLjFzOyB9DQogICAgI2NpcmNsZTMgeyBhbmltYXRpb24tZGVsYXk6IDAuMnM7IH0NCiAgICAjY2lyY2xlNCB7IGFuaW1hdGlvbi1kZWxheTogMC4zczsgfQ0KICAgICNjaXJjbGU1IHsgYW5pbWF0aW9uLWRlbGF5OiAwLjRzOyB9DQoNCiAgICBAa2V5ZnJhbWVzIGJhbGwgew0KICAgICAgZnJvbSB7IHRyYW5zZm9ybTogbm9uZTsgfQ0KICAgICAgMjAlIHsgdHJhbnNmb3JtOiBub25lOyB9DQogICAgICA4MCUgeyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoODY0cHgpOyB9DQogICAgICB0byB7IHRyYW5zZm9ybTogdHJhbnNsYXRlWCg4NjRweCk7IH0NCiAgICB9DQoNCiAgICBAa2V5ZnJhbWVzIGJhbGxzIHsNCiAgICAgIGZyb20geyB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTQwcHgpOyB9DQogICAgICB0byB7IHRyYW5zZm9ybTogdHJhbnNsYXRlWCgzMHB4KTsgfQ0KICAgIH0NCiAgPC9zdHlsZT4NCiAgPGcgaWQ9ImJhbGxzIj4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGUxIiBjeD0iLTExNSIgY3k9IjMiIHI9IjMiLz4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGUyIiBjeD0iLTEzMCIgY3k9IjMiIHI9IjMiIC8+DQogICAgPGNpcmNsZSBjbGFzcz0iY2lyY2xlIiBpZD0iY2lyY2xlMyIgY3g9Ii0xNDUiIGN5PSIzIiByPSIzIiAvPg0KICAgIDxjaXJjbGUgY2xhc3M9ImNpcmNsZSIgaWQ9ImNpcmNsZTQiIGN4PSItMTYwIiBjeT0iMyIgcj0iMyIgLz4NCiAgICA8Y2lyY2xlIGNsYXNzPSJjaXJjbGUiIGlkPSJjaXJjbGU1IiBjeD0iLTE3NSIgY3k9IjMiIHI9IjMiIC8+DQogIDwvZz4NCjwvc3ZnPg==') center center no-repeat;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册