mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Fix split cell not working with attachments (#19587)
This commit is contained in:
@@ -1079,6 +1079,96 @@ suite('Cell Model', function (): void {
|
|||||||
assert.deepStrictEqual(serializedCell.attachments, undefined, 'JSON should not include attachments if attachments do not exist');
|
assert.deepStrictEqual(serializedCell.attachments, undefined, 'JSON should not include attachments if attachments do not exist');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Should remove unused attachments name when updating cell source', async function () {
|
||||||
|
const cellAttachment = JSON.parse('{"ads.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAggg=="}}');
|
||||||
|
let notebookModel = new NotebookModelStub({
|
||||||
|
name: '',
|
||||||
|
version: '',
|
||||||
|
mimetype: ''
|
||||||
|
});
|
||||||
|
let contents: nb.ICellContents = {
|
||||||
|
cell_type: CellTypes.Markdown,
|
||||||
|
source: '',
|
||||||
|
attachments: cellAttachment
|
||||||
|
};
|
||||||
|
let model = factory.createCell(contents, { notebook: notebookModel, isTrusted: false });
|
||||||
|
assert.deepStrictEqual(model.attachments, contents.attachments, 'Attachments do not match in cellModel');
|
||||||
|
|
||||||
|
model.source = 'Test';
|
||||||
|
|
||||||
|
assert.notDeepStrictEqual(model.attachments, contents.attachments, 'Unused attachments are not removed after updating cell source');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not remove attachments that are still referenced in cell after updating the cell source', async function () {
|
||||||
|
const cellAttachment = JSON.parse('{"ads.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAggg=="}}');
|
||||||
|
let notebookModel = new NotebookModelStub({
|
||||||
|
name: '',
|
||||||
|
version: '',
|
||||||
|
mimetype: ''
|
||||||
|
});
|
||||||
|
let contents: nb.ICellContents = {
|
||||||
|
cell_type: CellTypes.Markdown,
|
||||||
|
source: '',
|
||||||
|
attachments: cellAttachment
|
||||||
|
};
|
||||||
|
let model = factory.createCell(contents, { notebook: notebookModel, isTrusted: false });
|
||||||
|
|
||||||
|
model.source = ' \n Test';
|
||||||
|
|
||||||
|
assert.deepStrictEqual(model.attachments, contents.attachments, 'Attachments referenced in cell were removed');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should update cell attachments', async function () {
|
||||||
|
const cellAttachment = JSON.parse('{"ads.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAggg=="}}');
|
||||||
|
let notebookModel = new NotebookModelStub({
|
||||||
|
name: '',
|
||||||
|
version: '',
|
||||||
|
mimetype: ''
|
||||||
|
});
|
||||||
|
let contents: nb.ICellContents = {
|
||||||
|
cell_type: CellTypes.Markdown,
|
||||||
|
source: ''
|
||||||
|
};
|
||||||
|
let model = factory.createCell(contents, { notebook: notebookModel, isTrusted: false });
|
||||||
|
model.updateAttachmentsFromSource('', cellAttachment);
|
||||||
|
|
||||||
|
assert.deepStrictEqual(model.attachments, cellAttachment, 'Cell attachments are not updated correctly');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not update cell attachments if they are not referenced in cell source', async function () {
|
||||||
|
const cellAttachment = JSON.parse('{"ads.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAggg=="}}');
|
||||||
|
let notebookModel = new NotebookModelStub({
|
||||||
|
name: '',
|
||||||
|
version: '',
|
||||||
|
mimetype: ''
|
||||||
|
});
|
||||||
|
let contents: nb.ICellContents = {
|
||||||
|
cell_type: CellTypes.Markdown,
|
||||||
|
source: ''
|
||||||
|
};
|
||||||
|
let model = factory.createCell(contents, { notebook: notebookModel, isTrusted: false });
|
||||||
|
model.updateAttachmentsFromSource('test', cellAttachment);
|
||||||
|
|
||||||
|
assert.notDeepStrictEqual(model.attachments, cellAttachment, 'Cell attachments are updated when they are not referenced in cell source');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('Should not update cell attachments if the attachment reference is not in the correct format', async function () {
|
||||||
|
const cellAttachment = JSON.parse('{"ads.png":{"image/png":"iVBORw0KGgoAAAANSUhEUgAAAggg=="}}');
|
||||||
|
let notebookModel = new NotebookModelStub({
|
||||||
|
name: '',
|
||||||
|
version: '',
|
||||||
|
mimetype: ''
|
||||||
|
});
|
||||||
|
let contents: nb.ICellContents = {
|
||||||
|
cell_type: CellTypes.Markdown,
|
||||||
|
source: ''
|
||||||
|
};
|
||||||
|
let model = factory.createCell(contents, { notebook: notebookModel, isTrusted: false });
|
||||||
|
model.updateAttachmentsFromSource('ads.png', cellAttachment);
|
||||||
|
|
||||||
|
assert.notDeepStrictEqual(model.attachments, cellAttachment, 'Cell attachments are updated when the reference is not in the correct format');
|
||||||
|
});
|
||||||
|
|
||||||
test('Should not have cache chart data after new cell created', async function () {
|
test('Should not have cache chart data after new cell created', async function () {
|
||||||
let notebookModel = new NotebookModelStub({
|
let notebookModel = new NotebookModelStub({
|
||||||
name: '',
|
name: '',
|
||||||
|
|||||||
@@ -334,7 +334,7 @@ export class CellModel extends Disposable implements ICellModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public set source(newSource: string | string[]) {
|
public set source(newSource: string | string[]) {
|
||||||
this.cleanUnusedAttachments(Array.isArray(newSource) ? newSource.join() : newSource);
|
this.updateAttachmentsFromSource(Array.isArray(newSource) ? newSource.join() : newSource);
|
||||||
newSource = this.attachImageFromSource(newSource);
|
newSource = this.attachImageFromSource(newSource);
|
||||||
newSource = this.getMultilineSource(newSource);
|
newSource = this.getMultilineSource(newSource);
|
||||||
if (this._source !== newSource) {
|
if (this._source !== newSource) {
|
||||||
@@ -358,12 +358,8 @@ export class CellModel extends Disposable implements ICellModel {
|
|||||||
return newSource;
|
return newSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public updateAttachmentsFromSource(source: string, attachments?: nb.ICellAttachments): void {
|
||||||
* Cleans up the attachments, removing any ones that aren't being currently used in the specified source string.
|
const originalAttachments = attachments ? attachments : this._attachments;
|
||||||
* @param source The new source string to check for attachments being used
|
|
||||||
*/
|
|
||||||
private cleanUnusedAttachments(source: string): void {
|
|
||||||
const originalAttachments = this._attachments;
|
|
||||||
this._attachments = {};
|
this._attachments = {};
|
||||||
// Find existing attachments in the form  so that we can make sure we keep those attachments
|
// Find existing attachments in the form  so that we can make sure we keep those attachments
|
||||||
const attachmentRegex = /!\[.*?\]\(attachment:(.*?)\)/g;
|
const attachmentRegex = /!\[.*?\]\(attachment:(.*?)\)/g;
|
||||||
|
|||||||
@@ -554,6 +554,13 @@ export interface ICellModel {
|
|||||||
* Returns the name of the attachment added to metadata.
|
* Returns the name of the attachment added to metadata.
|
||||||
*/
|
*/
|
||||||
addAttachment(mimeType: string, base64Encoding: string, name: string): string;
|
addAttachment(mimeType: string, base64Encoding: string, name: string): string;
|
||||||
|
/**
|
||||||
|
* Updates the current cell attachments with the attachments provided.
|
||||||
|
* If no attachments are passed in then it cleans up the current cell attachments and removes any ones that aren't being currently used in the specified source string.
|
||||||
|
* @param source The new source string to check for attachments being used
|
||||||
|
* @param attachments (Optional) The new attachments for the cell
|
||||||
|
*/
|
||||||
|
updateAttachmentsFromSource(source: string, attachments?: nb.ICellAttachments): void;
|
||||||
richTextCursorPosition: ICaretPosition;
|
richTextCursorPosition: ICaretPosition;
|
||||||
markdownCursorPosition: IPosition;
|
markdownCursorPosition: IPosition;
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -570,10 +570,11 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
let range = model.getFullModelRange();
|
let range = model.getFullModelRange();
|
||||||
let selection = editorControl.getSelection();
|
let selection = editorControl.getSelection();
|
||||||
let source = this.cells[index].source;
|
let source = this.cells[index].source;
|
||||||
let newCell = undefined, tailCell = undefined, partialSource = undefined;
|
let newCell: ICellModel = undefined, tailCell: ICellModel = undefined, partialSource = undefined;
|
||||||
let newCellIndex = index;
|
let newCellIndex = index;
|
||||||
let tailCellIndex = index;
|
let tailCellIndex = index;
|
||||||
let splitCells: SplitCell[] = [];
|
let splitCells: SplitCell[] = [];
|
||||||
|
let attachments = {};
|
||||||
|
|
||||||
// Save UI state
|
// Save UI state
|
||||||
let showMarkdown = this.cells[index].showMarkdown;
|
let showMarkdown = this.cells[index].showMarkdown;
|
||||||
@@ -607,6 +608,9 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
partialSource = source.slice(selection.startLineNumber - 1, selection.startLineNumber)[0].slice(0, selection.startColumn - 1);
|
partialSource = source.slice(selection.startLineNumber - 1, selection.startLineNumber)[0].slice(0, selection.startColumn - 1);
|
||||||
headsource = headsource.concat(partialSource.toString());
|
headsource = headsource.concat(partialSource.toString());
|
||||||
}
|
}
|
||||||
|
// Save attachments before updating cell contents
|
||||||
|
attachments = this.cells[index].attachments;
|
||||||
|
// No need to update attachments, since unused attachments are removed when updating the cell source
|
||||||
this.cells[index].source = headsource;
|
this.cells[index].source = headsource;
|
||||||
splitCells.push({ cell: this.cells[index], prefix: undefined });
|
splitCells.push({ cell: this.cells[index], prefix: undefined });
|
||||||
}
|
}
|
||||||
@@ -628,6 +632,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
//If the selection is not from the start of the cell, create a new cell.
|
//If the selection is not from the start of the cell, create a new cell.
|
||||||
if (headContent.length) {
|
if (headContent.length) {
|
||||||
newCell = this.createCell(cellType, language);
|
newCell = this.createCell(cellType, language);
|
||||||
|
newCell.updateAttachmentsFromSource(newSource.join(), attachments);
|
||||||
newCell.source = newSource;
|
newCell.source = newSource;
|
||||||
newCellIndex++;
|
newCellIndex++;
|
||||||
this.insertCell(newCell, newCellIndex, false);
|
this.insertCell(newCell, newCellIndex, false);
|
||||||
@@ -651,6 +656,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
if (tailSource[0] === '\r\n' || tailSource[0] === '\n') {
|
if (tailSource[0] === '\r\n' || tailSource[0] === '\n') {
|
||||||
newlinesBeforeTailCellContent = tailSource.splice(0, 1)[0];
|
newlinesBeforeTailCellContent = tailSource.splice(0, 1)[0];
|
||||||
}
|
}
|
||||||
|
tailCell.updateAttachmentsFromSource(tailSource.join(), attachments);
|
||||||
tailCell.source = tailSource;
|
tailCell.source = tailSource;
|
||||||
tailCellIndex = newCellIndex + 1;
|
tailCellIndex = newCellIndex + 1;
|
||||||
this.insertCell(tailCell, tailCellIndex, false);
|
this.insertCell(tailCell, tailCellIndex, false);
|
||||||
@@ -684,6 +690,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
let firstCell = cells[0].cell;
|
let firstCell = cells[0].cell;
|
||||||
// Append the other cell sources to the first cell
|
// Append the other cell sources to the first cell
|
||||||
for (let i = 1; i < cells.length; i++) {
|
for (let i = 1; i < cells.length; i++) {
|
||||||
|
firstCell.attachments = { ...firstCell.attachments, ...cells[i].cell.attachments };
|
||||||
firstCell.source = cells[i].prefix ? [...firstCell.source, ...cells[i].prefix, ...cells[i].cell.source] : [...firstCell.source, ...cells[i].cell.source];
|
firstCell.source = cells[i].prefix ? [...firstCell.source, ...cells[i].prefix, ...cells[i].cell.source] : [...firstCell.source, ...cells[i].cell.source];
|
||||||
}
|
}
|
||||||
// Set newly created cell as active cell
|
// Set newly created cell as active cell
|
||||||
|
|||||||
Reference in New Issue
Block a user