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

parameter hints: drop builder

上级 0cf16d08
......@@ -9,13 +9,15 @@ import 'vs/css!./parameterHints';
import nls = require('vs/nls');
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { TPromise } from 'vs/base/common/winjs.base';
import { Builder, $ } from 'vs/base/browser/builder';
import * as dom from 'vs/base/browser/dom';
import aria = require('vs/base/browser/ui/aria/aria');
import { ICursorSelectionChangedEvent, IConfigurationChangedEvent } from 'vs/editor/common/editorCommon';
import { SignatureHelp, SignatureInformation } from 'vs/editor/common/modes';
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
import { IHintEvent, ParameterHintsModel } from './parameterHintsModel';
const $ = dom.emmet;
interface ISignatureView {
top: number;
height: number;
......@@ -27,17 +29,15 @@ export class ParameterHintsWidget implements IContentWidget {
private editor: ICodeEditor;
private model: ParameterHintsModel;
private $el: Builder;
private $wrapper: Builder;
private $signatures: Builder;
private $overloads: Builder;
private element: HTMLElement;
private signatures: HTMLElement;
private overloads: HTMLElement;
private signatureViews: ISignatureView[];
private currentSignature: number;
private isDisposed: boolean;
private isVisible: boolean;
private visible: boolean;
private parameterHints: SignatureHelp;
private announcedLabel: string;
private toDispose: IDisposable[];
private disposables: IDisposable[];
private _onShown: () => void;
private _onHidden: () => void;
......@@ -50,14 +50,12 @@ export class ParameterHintsWidget implements IContentWidget {
this._onHidden = onHidden;
this.editor = editor;
this.model = null;
this.isVisible = false;
this.isDisposed = false;
this.visible = false;
this.model = model;
this.toDispose = [];
this.disposables = [];
this.toDispose.push(this.model.onHint((e:IHintEvent) => {
this.disposables.push(this.model.onHint((e:IHintEvent) => {
this.show();
this.parameterHints = e.hints;
this.render(e.hints);
......@@ -65,34 +63,34 @@ export class ParameterHintsWidget implements IContentWidget {
this.select(this.currentSignature);
}));
this.toDispose.push(this.model.onCancel(() => {
this.hide();
}));
this.disposables.push(this.model.onCancel(() => this.hide()));
this.$el = $('.editor-widget.parameter-hints-widget').on('click', () => {
this.element = $('.editor-widget.parameter-hints-widget');
this.disposables.push(dom.addDisposableListener(this.element, 'click', () => {
this.selectNext();
this.editor.focus();
});
this.$wrapper = $('.wrapper.monaco-editor-background').appendTo(this.$el);
}));
const $buttons = $('.buttons').appendTo(this.$wrapper);
const wrapper = dom.append(this.element, $('.wrapper.monaco-editor-background'));
const buttons = dom.append(wrapper, $('.buttons'));
const previous = dom.append(buttons, $('.button.previous'));
const next = dom.append(buttons, $('.button.next'));
$('.button.previous').on('click', (e) => {
this.disposables.push(dom.addDisposableListener(previous, 'click', e => {
e.preventDefault();
e.stopPropagation();
this.selectPrevious();
}).appendTo($buttons);
}));
$('.button.next').on('click', (e) => {
this.disposables.push(dom.addDisposableListener(next, 'click', e => {
e.preventDefault();
e.stopPropagation();
this.selectNext();
}).appendTo($buttons);
this.$overloads = $('.overloads').appendTo(this.$wrapper);
}));
this.$signatures = $('.signatures').appendTo(this.$wrapper);
this.overloads = dom.append(wrapper, $('.overloads'));
this.signatures = dom.append(wrapper, $('.signatures'));
this.signatureViews = [];
this.currentSignature = 0;
......@@ -100,14 +98,14 @@ export class ParameterHintsWidget implements IContentWidget {
this.editor.addContentWidget(this);
this.hide();
this.toDispose.push(this.editor.onDidChangeCursorSelection((e: ICursorSelectionChangedEvent) => {
if (this.isVisible) {
this.disposables.push(this.editor.onDidChangeCursorSelection((e: ICursorSelectionChangedEvent) => {
if (this.visible) {
this.editor.layoutContentWidget(this);
}
}));
this.editor.applyFontInfo(this.getDomNode());
this.toDispose.push(this.editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
this.disposables.push(this.editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => {
if (e.fontInfo) {
this.editor.applyFontInfo(this.getDomNode());
}
......@@ -115,39 +113,31 @@ export class ParameterHintsWidget implements IContentWidget {
}
private show(): void {
if (this.isDisposed) {
return;
}
if (this.isVisible) {
if (!this.model || this.visible) {
return;
}
this._onShown();
this.isVisible = true;
TPromise.timeout(100).done(() => {
this.$el.addClass('visible');
});
this._onShown();
this.visible = true;
TPromise.timeout(100).done(() => dom.addClass(this.element, 'visible'));
this.editor.layoutContentWidget(this);
}
private hide(): void {
if (this.isDisposed) {
return;
}
if (!this.isVisible) {
if (!this.model || !this.visible) {
return;
}
this._onHidden();
this.isVisible = false;
this._onHidden();
this.visible = false;
this.parameterHints = null;
this.announcedLabel = null;
this.$el.removeClass('visible');
dom.removeClass(this.element, 'visible');
this.editor.layoutContentWidget(this);
}
getPosition():IContentWidgetPosition {
if (this.isVisible) {
if (this.visible) {
return {
position: this.editor.getPosition(),
preference: [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW]
......@@ -158,22 +148,22 @@ export class ParameterHintsWidget implements IContentWidget {
private render(hints:SignatureHelp): void {
if (hints.signatures.length > 1) {
this.$el.addClass('multiple');
dom.addClass(this.element, 'multiple');
} else {
this.$el.removeClass('multiple');
dom.removeClass(this.element, 'multiple');
}
this.$signatures.empty();
this.signatures.innerHTML = '';
this.signatureViews = [];
let height = 0;
for (let i = 0, len = hints.signatures.length; i < len; i++) {
const signature = hints.signatures[i];
const $signature = this.renderSignature(this.$signatures, signature, hints.activeParameter);
const signatureElement = this.renderSignature(this.signatures, signature, hints.activeParameter);
this.renderDocumentation($signature, signature, hints.activeParameter);
this.renderDocumentation(signatureElement, signature, hints.activeParameter);
const signatureHeight = $signature.getClientArea().height;
const signatureHeight = dom.getContentHeight(signatureElement);
this.signatureViews.push({
top: height,
......@@ -184,55 +174,76 @@ export class ParameterHintsWidget implements IContentWidget {
}
}
private renderSignature($el:Builder, signature:SignatureInformation, currentParameter:number):Builder {
const $signature = $('.signature').appendTo($el),
hasParameters = signature.parameters.length > 0;
private renderSignature(element: HTMLElement, signature:SignatureInformation, currentParameter:number): HTMLElement {
const signatureElement = dom.append(element, $('.signature'));
const hasParameters = signature.parameters.length > 0;
if(!hasParameters) {
$signature.append($('span').text(signature.label));
const label = dom.append(signatureElement, $('span'));
label.textContent = signature.label;
return signatureElement;
}
} else {
const parameters = $('span.parameters');
let offset = 0;
let idx = 0;
for (let i = 0, len = signature.parameters.length; i < len; i++) {
const parameter = signature.parameters[i];
idx = signature.label.indexOf(parameter.label, idx);
const $parameters = $('span.parameters');
let offset = 0;
let idx = 0;
for (let i = 0, len = signature.parameters.length; i < len; i++) {
const parameter = signature.parameters[i];
idx = signature.label.indexOf(parameter.label, idx);
let signatureLabelOffset = 0;
let signatureLabelEnd = 0;
if (idx >= 0) {
signatureLabelOffset = idx;
idx += parameter.label.length;
signatureLabelEnd = idx;
}
(i === 0 ? $signature : $parameters).append($('span').text(signature.label.substring(offset, signatureLabelOffset)));
$parameters.append($('span.parameter').addClass(i === currentParameter ? 'active' : '').text(signature.label.substring(signatureLabelOffset, signatureLabelEnd)));
offset = signatureLabelEnd;
let signatureLabelOffset = 0;
let signatureLabelEnd = 0;
if (idx >= 0) {
signatureLabelOffset = idx;
idx += parameter.label.length;
signatureLabelEnd = idx;
}
$signature.append($parameters);
$signature.append($('span').text(signature.label.substring(offset)));
const element = i === 0 ? signatureElement : parameters;
const label = $('span');
label.textContent = signature.label.substring(offset, signatureLabelOffset);
dom.append(element, label);
const parameterElement = $('span.parameter');
dom.addClass(parameterElement, i === currentParameter ? 'active' : '');
parameterElement.textContent = signature.label.substring(signatureLabelOffset, signatureLabelEnd);
dom.append(parameters, parameterElement);
offset = signatureLabelEnd;
}
return $signature;
}
const label = $('span');
label.textContent = signature.label.substring(offset);
private renderDocumentation($el:Builder, signature:SignatureInformation, activeParameterIdx:number): void {
dom.append(signatureElement, parameters);
dom.append(signatureElement, label);
return signatureElement;
}
private renderDocumentation(element: HTMLElement, signature:SignatureInformation, activeParameterIdx:number): void {
if(signature.documentation) {
$el.append($('.documentation').text(signature.documentation));
const documentation = $('.documentation');
documentation.textContent = signature.documentation;
dom.append(element, documentation);
}
const activeParameter = signature.parameters[activeParameterIdx];
if(activeParameter && activeParameter.documentation) {
const $parameter = $('.documentation');
$parameter.append($('span.parameter').text(activeParameter.label));
$parameter.append($('span').text(activeParameter.documentation));
$el.append($parameter);
const parameter = $('.documentation');
const label = $('span.parameter');
label.textContent = activeParameter.label;
const documentation = $('span');
documentation.textContent = activeParameter.documentation;
dom.append(parameter, label);
dom.append(parameter, documentation);
dom.append(element, parameter);
}
}
......@@ -243,8 +254,8 @@ export class ParameterHintsWidget implements IContentWidget {
return;
}
this.$signatures.style({ height: signature.height + 'px' });
this.$signatures.getHTMLElement().scrollTop = signature.top;
this.signatures.style.height = `${ signature.height }px`;
this.signatures.scrollTop = signature.top;
let overloads = '' + (position + 1);
......@@ -252,7 +263,8 @@ export class ParameterHintsWidget implements IContentWidget {
overloads += '/' + this.signatureViews.length;
}
this.$overloads.text(overloads);
this.overloads.textContent = overloads;
if (this.parameterHints && this.parameterHints.signatures[position].parameters[this.parameterHints.activeParameter]) {
const labelToAnnounce = this.parameterHints.signatures[position].parameters[this.parameterHints.activeParameter].label;
// Select method gets called on every user type while parameter hints are visible.
......@@ -262,6 +274,7 @@ export class ParameterHintsWidget implements IContentWidget {
this.announcedLabel = labelToAnnounce;
}
}
this.editor.layoutContentWidget(this);
}
......@@ -297,7 +310,7 @@ export class ParameterHintsWidget implements IContentWidget {
}
getDomNode(): HTMLElement {
return this.$el.getHTMLElement();
return this.element;
}
getId(): string {
......@@ -305,31 +318,7 @@ export class ParameterHintsWidget implements IContentWidget {
}
destroy(): void {
this.toDispose = dispose(this.toDispose);
this.disposables = dispose(this.disposables);
this.model = null;
if (this.$overloads) {
this.$overloads.destroy();
delete this.$overloads;
}
if (this.$signatures) {
this.$signatures.destroy();
delete this.$signatures;
}
if (this.$wrapper) {
this.$wrapper.destroy();
delete this.$wrapper;
}
if (this.$el) {
this.$el.destroy();
delete this.$el;
}
this.isDisposed = true;
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册