Fix ##3479 ctrl+a select active cell output or preview markdown (#4981)

* Enable ctrl+a to select the output or markdown content when the cell is active

* Moved toggleUserSelect into ngOnChanges

* Resolve PR comments
This commit is contained in:
Yurong He
2019-04-11 11:36:42 -07:00
committed by GitHub
parent 442adfbbc3
commit 4f8d14ed3e
9 changed files with 75 additions and 9 deletions

View File

@@ -9,7 +9,7 @@
<code-component [cellModel]="cellModel" [model]="model" [activeCellId]="activeCellId"></code-component>
</div>
<div style="flex: 0 0 auto; width: 100%; height: 100%; display: block">
<output-area-component *ngIf="cellModel.outputs && cellModel.outputs.length > 0" [cellModel]="cellModel">
<output-area-component *ngIf="cellModel.outputs && cellModel.outputs.length > 0" [cellModel]="cellModel" [activeCellId]="activeCellId">
</output-area-component>
</div>
</div>

View File

@@ -5,7 +5,7 @@
*--------------------------------------------------------------------------------------------*/
-->
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
<div style="flex: 0 0 auto; user-select: initial;">
<div #output ></div>
<div style="flex: 0 0 auto; user-select: none;">
<div #output class="output-userselect" ></div>
</div>
</div>

View File

@@ -5,7 +5,7 @@
import 'vs/css!./code';
import 'vs/css!./media/output';
import { OnInit, Component, Input, Inject, ElementRef, ViewChild } from '@angular/core';
import { OnInit, Component, Input, Inject, ElementRef, ViewChild, SimpleChange } from '@angular/core';
import { AngularDisposable } from 'sql/base/node/lifecycle';
import { nb } from 'azdata';
import { ICellModel } from 'sql/workbench/parts/notebook/models/modelInterfaces';
@@ -14,8 +14,10 @@ import { MimeModel } from 'sql/workbench/parts/notebook/outputs/common/mimemodel
import * as outputProcessor from 'sql/workbench/parts/notebook/outputs/common/outputProcessor';
import { RenderMimeRegistry } from 'sql/workbench/parts/notebook/outputs/registry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import * as DOM from 'vs/base/browser/dom';
export const OUTPUT_SELECTOR: string = 'output-component';
const USER_SELECT_CLASS ='actionselect';
@Component({
selector: OUTPUT_SELECTOR,
@@ -28,6 +30,7 @@ export class OutputComponent extends AngularDisposable implements OnInit {
private _trusted: boolean;
private _initialized: boolean = false;
private readonly _minimumHeight = 30;
private _activeCellId: string;
registry: RenderMimeRegistry;
@@ -47,6 +50,27 @@ export class OutputComponent extends AngularDisposable implements OnInit {
});
}
ngOnChanges(changes: { [propKey: string]: SimpleChange }) {
for (let propName in changes) {
if (propName === 'activeCellId') {
this.toggleUserSelect(this.isActive());
break;
}
}
}
private toggleUserSelect(userSelect: boolean): void {
if (!this.outputElement) {
return;
}
if (userSelect) {
DOM.addClass(this.outputElement.nativeElement, USER_SELECT_CLASS);
} else {
DOM.removeClass(this.outputElement.nativeElement, USER_SELECT_CLASS);
}
}
private renderOutput() {
let node = this.outputElement.nativeElement;
let output = this.cellOutput;
@@ -63,14 +87,21 @@ export class OutputComponent extends AngularDisposable implements OnInit {
return this._trusted;
}
@Input()
set trustedMode(value: boolean) {
@Input() set trustedMode(value: boolean) {
this._trusted = value;
if (this._initialized) {
this.renderOutput();
}
}
@Input() set activeCellId(value: string) {
this._activeCellId = value;
}
get activeCellId(): string {
return this._activeCellId;
}
protected createRenderedMimetype(options: MimeModel.IOptions, node: HTMLElement): void {
let mimeType = this.registry.preferredMimeType(
options.data,
@@ -100,4 +131,7 @@ export class OutputComponent extends AngularDisposable implements OnInit {
//this.setState({ node: node });
}
}
protected isActive() {
return this.cellModel && this.cellModel.id === this.activeCellId;
}
}

View File

@@ -6,7 +6,7 @@
-->
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: column">
<div #outputarea class="notebook-output" style="flex: 0 0 auto;">
<output-component *ngFor="let output of cellModel.outputs" [cellOutput]="output" [trustedMode] = "cellModel.trustedMode" [cellModel]="cellModel">
<output-component *ngFor="let output of cellModel.outputs" [cellOutput]="output" [trustedMode] = "cellModel.trustedMode" [cellModel]="cellModel" [activeCellId]="activeCellId">
</output-component>
</div>
</div>

View File

@@ -20,6 +20,8 @@ export class OutputAreaComponent extends AngularDisposable implements OnInit {
@ViewChild('outputarea', { read: ElementRef }) private outputArea: ElementRef;
@Input() cellModel: ICellModel;
private _activeCellId: string;
private readonly _minimumHeight = 30;
constructor(
@@ -41,6 +43,14 @@ export class OutputAreaComponent extends AngularDisposable implements OnInit {
}
}
@Input() set activeCellId(value: string) {
this._activeCellId = value;
}
get activeCellId(): string {
return this._activeCellId;
}
private updateTheme(theme: IColorTheme): void {
let outputElement = <HTMLElement>this.outputArea.nativeElement;
outputElement.style.borderTopColor = theme.getColor(themeColors.SIDE_BAR_BACKGROUND, true).toString();

View File

@@ -10,4 +10,8 @@ output-area-component .notebook-output {
border-top-width: 0px;
user-select: text;
padding: 5px 20px 0px;
}
.output-userselect.actionselect {
user-select: text;
}

View File

@@ -11,7 +11,7 @@
</code-component>
</div>
<div style="overflow: hidden; width: 100%; height: 100%; display: flex; flex-flow: row">
<div #preview class ="notebook-preview" style="flex: 1 1 auto; user-select: initial;" (dblclick)="toggleEditMode()">
<div #preview class ="notebook-preview" style="flex: 1 1 auto" (dblclick)="toggleEditMode()">
</div>
<div #moreactions class="moreActions" style="flex: 0 0 auto; display: flex; flex-flow:column;width: 20px; min-height: 20px; max-height: 20px; padding-top: 0px; orientation: portrait">
</div>

View File

@@ -15,6 +15,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import * as DOM from 'vs/base/browser/dom';
import { CommonServiceInterface } from 'sql/services/common/commonServiceInterface.service';
import { CellView } from 'sql/workbench/parts/notebook/cellViews/interfaces';
@@ -24,6 +25,7 @@ import { NotebookModel } from 'sql/workbench/parts/notebook/models/notebookModel
import { CellToggleMoreActions } from 'sql/workbench/parts/notebook/cellToggleMoreActions';
export const TEXT_SELECTOR: string = 'text-cell-component';
const USER_SELECT_CLASS ='actionselect';
@Component({
selector: TEXT_SELECTOR,
@@ -112,6 +114,7 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges {
if (propName === 'activeCellId') {
let changedProp = changes[propName];
this._activeCellId = changedProp.currentValue;
this.toggleUserSelect(this.isActive());
// If the activeCellId is undefined (i.e. in an active cell update), don't unnecessarily set editMode to false;
// it will be set to true in a subsequent call to toggleEditMode()
if (changedProp.previousValue !== undefined) {
@@ -202,6 +205,17 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges {
}
}
private toggleUserSelect(userSelect: boolean): void {
if (!this.output) {
return;
}
if (userSelect) {
DOM.addClass(this.output.nativeElement, USER_SELECT_CLASS);
} else {
DOM.removeClass(this.output.nativeElement, USER_SELECT_CLASS);
}
}
private setFocusAndScroll(): void {
this.toggleEditMode(this.isActive());

View File

@@ -8,7 +8,11 @@ text-cell-component {
}
text-cell-component .notebook-preview {
user-select: initial;
user-select: none;
padding-left: 8px;
padding-right: 8px;
}
.notebook-preview.actionselect {
user-select: text;
}