Improve find by tracking actual rendered text (#9419)

* Improve find by tracking actual rendered text

* Fix tests, add notebook md render
This commit is contained in:
Chris LaFreniere
2020-03-03 16:56:11 -08:00
committed by GitHub
parent ff0992510b
commit 0f9d98730e
5 changed files with 46 additions and 3 deletions

View File

@@ -200,6 +200,7 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges {
this.setLoading(false); this.setLoading(false);
let outputElement = <HTMLElement>this.output.nativeElement; let outputElement = <HTMLElement>this.output.nativeElement;
outputElement.innerHTML = this.markdownResult.element.innerHTML; outputElement.innerHTML = this.markdownResult.element.innerHTML;
this.cellModel.renderedOutputTextContent = this.getRenderedTextOutput();
} }
} }
@@ -331,4 +332,17 @@ export class TextCellComponent extends CellView implements OnInit, OnChanges {
} }
return children; return children;
} }
private getRenderedTextOutput(): string[] {
let textOutput: string[] = [];
let elements = this.getHtmlElements();
elements.forEach(element => {
if (element && element.innerText) {
textOutput.push(element.innerText);
} else {
textOutput.push('');
}
});
return textOutput;
}
} }

View File

@@ -527,9 +527,8 @@ export class NotebookFindModel extends Disposable implements INotebookFindModel
private searchFn(cell: ICellModel, exp: string, matchCase: boolean = false, wholeWord: boolean = false, maxMatches?: number): NotebookRange[] { private searchFn(cell: ICellModel, exp: string, matchCase: boolean = false, wholeWord: boolean = false, maxMatches?: number): NotebookRange[] {
let findResults: NotebookRange[] = []; let findResults: NotebookRange[] = [];
let cellVal = cell.cellType === 'markdown' ? this.cleanUpCellSource(cell.source) : cell.source; let cellVal = cell.cellType === 'markdown' ? cell.renderedOutputTextContent : cell.source;
if (cellVal) { if (cellVal) {
if (typeof cellVal === 'string') { if (typeof cellVal === 'string') {
let findStartResults = this.search(cellVal, exp, matchCase, wholeWord, maxMatches); let findStartResults = this.search(cellVal, exp, matchCase, wholeWord, maxMatches);
findStartResults.forEach(start => { findStartResults.forEach(start => {

View File

@@ -28,6 +28,7 @@ import { ClientSession } from 'sql/workbench/services/notebook/browser/models/cl
import { TestStorageService } from 'vs/workbench/test/browser/workbenchTestServices'; import { TestStorageService } from 'vs/workbench/test/browser/workbenchTestServices';
import { NotebookEditorContentManager } from 'sql/workbench/contrib/notebook/browser/models/notebookInput'; import { NotebookEditorContentManager } from 'sql/workbench/contrib/notebook/browser/models/notebookInput';
import { NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService'; import { NotebookRange } from 'sql/workbench/services/notebook/browser/notebookService';
import { NotebookMarkdownRenderer } from 'sql/workbench/contrib/notebook/browser/outputs/notebookMarkdown';
let expectedNotebookContent: nb.INotebookContents = { let expectedNotebookContent: nb.INotebookContents = {
cells: [{ cells: [{
@@ -69,6 +70,7 @@ suite('Notebook Find Model', function (): void {
let defaultModelOptions: INotebookModelOptions; let defaultModelOptions: INotebookModelOptions;
const logService = new NullLogService(); const logService = new NullLogService();
let model: NotebookModel; let model: NotebookModel;
let markdownRenderer: NotebookMarkdownRenderer = new NotebookMarkdownRenderer();
setup(async () => { setup(async () => {
sessionReady = new Deferred<void>(); sessionReady = new Deferred<void>();
@@ -108,12 +110,15 @@ suite('Notebook Find Model', function (): void {
}); });
test('Should find results in the notebook', async function (): Promise<void> { test('Should find results in the notebook', async function (): Promise<void> {
// Need to set rendered text content for 2nd cell
setRenderedTextContent(1);
//initialize find //initialize find
let notebookFindModel = new NotebookFindModel(model); let notebookFindModel = new NotebookFindModel(model);
await notebookFindModel.find('markdown', false, false, max_find_count); await notebookFindModel.find('markdown', false, false, max_find_count);
assert(notebookFindModel.findMatches, 'Find in notebook failed.'); assert(notebookFindModel.findMatches, 'Find in notebook failed.');
assert.equal(notebookFindModel.findMatches.length, 2, 'Find couldnt find all occurances'); assert.equal(notebookFindModel.findMatches.length, 2, 'Find couldnt find all occurrences');
}); });
test('Should not find results in the notebook', async function (): Promise<void> { test('Should not find results in the notebook', async function (): Promise<void> {
@@ -125,6 +130,9 @@ suite('Notebook Find Model', function (): void {
}); });
test('Should match find result ranges', async function (): Promise<void> { test('Should match find result ranges', async function (): Promise<void> {
// Need to set rendered text content for 2nd cell
setRenderedTextContent(1);
let notebookFindModel = new NotebookFindModel(model); let notebookFindModel = new NotebookFindModel(model);
await notebookFindModel.find('markdown', false, false, max_find_count); await notebookFindModel.find('markdown', false, false, max_find_count);
@@ -154,6 +162,9 @@ suite('Notebook Find Model', function (): void {
}; };
await initNotebookModel(markdownContent); await initNotebookModel(markdownContent);
// Need to set rendered text content for 1st cell
setRenderedTextContent(0);
let notebookFindModel = new NotebookFindModel(model); let notebookFindModel = new NotebookFindModel(model);
await notebookFindModel.find('best', false, false, max_find_count); await notebookFindModel.find('best', false, false, max_find_count);
@@ -190,6 +201,9 @@ suite('Notebook Find Model', function (): void {
}); });
test('Should find results correctly with & without matching case selection', async function (): Promise<void> { test('Should find results correctly with & without matching case selection', async function (): Promise<void> {
// Need to set rendered text content for 2nd cell
setRenderedTextContent(1);
//initialize find //initialize find
let notebookFindModel = new NotebookFindModel(model); let notebookFindModel = new NotebookFindModel(model);
await notebookFindModel.find('insert', false, false, max_find_count); await notebookFindModel.find('insert', false, false, max_find_count);
@@ -285,4 +299,10 @@ suite('Notebook Find Model', function (): void {
await model.requestModelLoad(); await model.requestModelLoad();
} }
function setRenderedTextContent(cellIndex: number): void {
model.cells[cellIndex].renderedOutputTextContent = [markdownRenderer.render({
isTrusted: true,
value: model.cells[cellIndex].source[0]
}).element.innerText.toString()];
}
}); });

View File

@@ -37,6 +37,7 @@ export class CellModel implements ICellModel {
private _cellGuid: string; private _cellGuid: string;
private _future: FutureInternal; private _future: FutureInternal;
private _outputs: nb.ICellOutput[] = []; private _outputs: nb.ICellOutput[] = [];
private _renderedOutputTextContent: string[] = [];
private _isEditMode: boolean; private _isEditMode: boolean;
private _onOutputsChanged = new Emitter<IOutputChangedEvent>(); private _onOutputsChanged = new Emitter<IOutputChangedEvent>();
private _onCellModeChanged = new Emitter<boolean>(); private _onCellModeChanged = new Emitter<boolean>();
@@ -464,6 +465,14 @@ export class CellModel implements ICellModel {
return this._outputs; return this._outputs;
} }
public get renderedOutputTextContent(): string[] {
return this._renderedOutputTextContent;
}
public set renderedOutputTextContent(content: string[]) {
this._renderedOutputTextContent = content;
}
private handleReply(msg: nb.IShellMessage): void { private handleReply(msg: nb.IShellMessage): void {
// TODO #931 we should process this. There can be a payload attached which should be added to outputs. // TODO #931 we should process this. There can be a payload attached which should be added to outputs.
// In all other cases, it is a no-op // In all other cases, it is a no-op

View File

@@ -468,6 +468,7 @@ export interface ICellModel {
executionCount: number | undefined; executionCount: number | undefined;
readonly future: FutureInternal; readonly future: FutureInternal;
readonly outputs: ReadonlyArray<nb.ICellOutput>; readonly outputs: ReadonlyArray<nb.ICellOutput>;
renderedOutputTextContent?: string[];
readonly onOutputsChanged: Event<IOutputChangedEvent>; readonly onOutputsChanged: Event<IOutputChangedEvent>;
readonly onExecutionStateChange: Event<CellExecutionState>; readonly onExecutionStateChange: Event<CellExecutionState>;
readonly executionState: CellExecutionState; readonly executionState: CellExecutionState;