|
| 1 | +import { injectable, interfaces, Container } from 'inversify'; |
| 2 | +import { Widget } from '@phosphor/widgets'; |
| 3 | +import { SourceTreeWidget } from '@theia/core/lib/browser/source-tree'; |
| 4 | +import { DisposableCollection } from '@theia/core/lib/common/disposable'; |
| 5 | +import { DebugEditor } from '@theia/debug/lib/browser/editor/debug-editor'; |
| 6 | +import { DebugVariable } from '@theia/debug/lib/browser/console/debug-console-items'; |
| 7 | +import { DebugExpressionProvider } from '@theia/debug/lib/browser/editor/debug-expression-provider'; |
| 8 | +import { DebugHoverSource as TheiaDebugHoverSource } from '@theia/debug/lib/browser/editor/debug-hover-source'; |
| 9 | +import { DebugHoverWidget as TheiaDebugHoverWidget, ShowDebugHoverOptions } from '@theia/debug/lib/browser/editor/debug-hover-widget'; |
| 10 | +import { DebugHoverSource } from './debug-hover-source'; |
| 11 | + |
| 12 | +export function createDebugHoverWidgetContainer(parent: interfaces.Container, editor: DebugEditor): Container { |
| 13 | + const child = SourceTreeWidget.createContainer(parent, { |
| 14 | + virtualized: false |
| 15 | + }); |
| 16 | + child.bind(DebugEditor).toConstantValue(editor); |
| 17 | + child.bind(TheiaDebugHoverSource).toSelf(); |
| 18 | + child.bind(DebugHoverSource).toSelf(); |
| 19 | + child.rebind(TheiaDebugHoverSource).to(DebugHoverSource); |
| 20 | + child.unbind(SourceTreeWidget); |
| 21 | + child.bind(DebugExpressionProvider).toSelf(); |
| 22 | + child.bind(TheiaDebugHoverWidget).toSelf(); |
| 23 | + child.bind(DebugHoverWidget).toSelf(); |
| 24 | + child.rebind(TheiaDebugHoverWidget).to(DebugHoverWidget); |
| 25 | + return child; |
| 26 | +} |
| 27 | + |
| 28 | +// TODO: remove patch after https://github.com/eclipse-theia/theia/pull/9256/ |
| 29 | +@injectable() |
| 30 | +export class DebugHoverWidget extends TheiaDebugHoverWidget { |
| 31 | + |
| 32 | + protected async doShow(options: ShowDebugHoverOptions | undefined = this.options): Promise<void> { |
| 33 | + if (!this.isEditorFrame()) { |
| 34 | + this.hide(); |
| 35 | + return; |
| 36 | + } |
| 37 | + if (!options) { |
| 38 | + this.hide(); |
| 39 | + return; |
| 40 | + } |
| 41 | + if (this.options && this.options.selection.equalsRange(options.selection)) { |
| 42 | + return; |
| 43 | + } |
| 44 | + if (!this.isAttached) { |
| 45 | + Widget.attach(this, this.contentNode); |
| 46 | + } |
| 47 | + |
| 48 | + this.options = options; |
| 49 | + const matchingExpression = this.expressionProvider.get(this.editor.getControl().getModel()!, options.selection); |
| 50 | + if (!matchingExpression) { |
| 51 | + this.hide(); |
| 52 | + return; |
| 53 | + } |
| 54 | + const toFocus = new DisposableCollection(); |
| 55 | + if (this.options.focus === true) { |
| 56 | + toFocus.push(this.model.onNodeRefreshed(() => { |
| 57 | + toFocus.dispose(); |
| 58 | + this.activate(); |
| 59 | + })); |
| 60 | + } |
| 61 | + const expression = await (this.hoverSource as DebugHoverSource).evaluate2(matchingExpression); |
| 62 | + if (!expression || !expression.value) { |
| 63 | + toFocus.dispose(); |
| 64 | + this.hide(); |
| 65 | + return; |
| 66 | + } |
| 67 | + |
| 68 | + this.contentNode.hidden = false; |
| 69 | + ['number', 'boolean', 'string'].forEach(token => this.titleNode.classList.remove(token)); |
| 70 | + this.domNode.classList.remove('complex-value'); |
| 71 | + if (expression.hasElements) { |
| 72 | + this.domNode.classList.add('complex-value'); |
| 73 | + } else { |
| 74 | + this.contentNode.hidden = true; |
| 75 | + if (expression.type === 'number' || expression.type === 'boolean' || expression.type === 'string') { |
| 76 | + this.titleNode.classList.add(expression.type); |
| 77 | + } else if (!isNaN(+expression.value)) { |
| 78 | + this.titleNode.classList.add('number'); |
| 79 | + } else if (DebugVariable.booleanRegex.test(expression.value)) { |
| 80 | + this.titleNode.classList.add('boolean'); |
| 81 | + } else if (DebugVariable.stringRegex.test(expression.value)) { |
| 82 | + this.titleNode.classList.add('string'); |
| 83 | + } |
| 84 | + } |
| 85 | + |
| 86 | + // super.show(); // Here we cannot call `super.show()` but have to call `show` on the `Widget` prototype. |
| 87 | + Widget.prototype.show.call(this); |
| 88 | + await new Promise<void>(resolve => { |
| 89 | + setTimeout(() => window.requestAnimationFrame(() => { |
| 90 | + this.editor.getControl().layoutContentWidget(this); |
| 91 | + resolve(); |
| 92 | + }), 0); |
| 93 | + }); |
| 94 | + } |
| 95 | + |
| 96 | +} |
0 commit comments