Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf0d79bd

Browse files
echarlesmeeseeksmachine
authored andcommitted
Backport PRjupyterlab#10949: Enable document wide history tracking
1 parentb38e084 commitf0d79bd

File tree

11 files changed

+130
-27
lines changed

11 files changed

+130
-27
lines changed

‎packages/notebook-extension/schema/tracker.json‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,12 @@
825825
"description":"Defines the maximum number of output cells to to to be rendered in the output area for cells with many outputs. The output area will have a head and a tail, and the outputs between will be trimmed and not displayed unless the user clicks on the information message.",
826826
"type":"number",
827827
"default":50
828+
},
829+
"experimentalEnableDocumentWideUndoRedo": {
830+
"title":"Experimental settings to enable the undo/redo on the notebook document level.",
831+
"description":"Enable the undo/redo on the notebook document level, so actions like cells move, change... can have history. The undo/redo never applies on the outputs, in other words, outputs don't have history.",
832+
"type":"boolean",
833+
"default":true
828834
}
829835
},
830836
"additionalProperties":false,

‎packages/notebook-extension/src/index.ts‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1160,7 +1160,11 @@ function activateNotebookHandler(
11601160
}
11611161

11621162
constregistry=app.docRegistry;
1163-
registry.addModelFactory(newNotebookModelFactory({}));
1163+
constmodelFactory=newNotebookModelFactory({
1164+
enableDocumentWideUndoRedo:
1165+
factory.notebookConfig.enableDocumentWideUndoRedo
1166+
});
1167+
registry.addModelFactory(modelFactory);
11641168

11651169
addCommands(app,tracker,translator,sessionDialogs);
11661170

@@ -1228,11 +1232,18 @@ function activateNotebookHandler(
12281232
observedTopMargin:settings.get('observedTopMargin').compositeasstring,
12291233
observedBottomMargin:settings.get('observedBottomMargin')
12301234
.compositeasstring,
1231-
maxNumberOutputs:settings.get('maxNumberOutputs').compositeasnumber
1235+
maxNumberOutputs:settings.get('maxNumberOutputs').compositeasnumber,
1236+
enableDocumentWideUndoRedo:settings.get(
1237+
'experimentalEnableDocumentWideUndoRedo'
1238+
).compositeasboolean
12321239
};
12331240
factory.shutdownOnClose=settings.get('kernelShutdown')
12341241
.compositeasboolean;
12351242

1243+
modelFactory.enableDocumentWideUndoRedo=settings.get(
1244+
'experimentalEnableDocumentWideUndoRedo'
1245+
).compositeasboolean;
1246+
12361247
updateTracker({
12371248
editorConfig:factory.editorConfig,
12381249
notebookConfig:factory.notebookConfig,

‎packages/notebook/src/model.ts‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ export class NotebookModel implements INotebookModel {
8989
}else{
9090
this.modelDB=newModelDB();
9191
}
92+
this.sharedModel=models.YNotebook.create(
93+
options.enableDocumentWideUndoRedo||false
94+
)asmodels.ISharedNotebook;
9295
this._isInitialized=options.isInitialized===false ?false :true;
9396
constfactory=
9497
options.contentFactory||NotebookModel.defaultContentFactory;
@@ -497,7 +500,7 @@ close the notebook without saving it.`,
497500
/**
498501
* The shared notebook model.
499502
*/
500-
readonlysharedModel=models.YNotebook.create()asmodels.ISharedNotebook;
503+
readonlysharedModel:models.ISharedNotebook;
501504

502505
/**
503506
* A mutex to update the shared model.
@@ -558,6 +561,11 @@ export namespace NotebookModel {
558561
* If the model is initialized or not.
559562
*/
560563
isInitialized?:boolean;
564+
565+
/**
566+
* Defines if the document can be undo/redo.
567+
*/
568+
enableDocumentWideUndoRedo?:boolean;
561569
}
562570

563571
/**

‎packages/notebook/src/modelfactory.ts‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ export class NotebookModelFactory
1616
* Construct a new notebook model factory.
1717
*/
1818
constructor(options:NotebookModelFactory.IOptions){
19+
this._enableDocumentWideUndoRedo=
20+
options.enableDocumentWideUndoRedo||false;
1921
constcodeCellContentFactory=options.codeCellContentFactory;
2022
this.contentFactory=
2123
options.contentFactory||
@@ -27,6 +29,13 @@ export class NotebookModelFactory
2729
*/
2830
readonlycontentFactory:NotebookModel.IContentFactory;
2931

32+
/**
33+
* Define the enableDocumentWideUndoRedo property.
34+
*/
35+
setenableDocumentWideUndoRedo(enableDocumentWideUndoRedo:boolean){
36+
this._enableDocumentWideUndoRedo=enableDocumentWideUndoRedo;
37+
}
38+
3039
/**
3140
* The name of the model.
3241
*/
@@ -79,7 +88,8 @@ export class NotebookModelFactory
7988
languagePreference,
8089
contentFactory,
8190
modelDB,
82-
isInitialized
91+
isInitialized,
92+
enableDocumentWideUndoRedo:this._enableDocumentWideUndoRedo
8393
});
8494
}
8595

@@ -90,6 +100,11 @@ export class NotebookModelFactory
90100
return'';
91101
}
92102

103+
/**
104+
* Defines if the document can be undo/redo.
105+
*/
106+
private_enableDocumentWideUndoRedo:boolean;
107+
93108
private_disposed=false;
94109
}
95110

@@ -101,6 +116,11 @@ export namespace NotebookModelFactory {
101116
* The options used to initialize a NotebookModelFactory.
102117
*/
103118
exportinterfaceIOptions{
119+
/**
120+
* Defines if the document can be undo/redo.
121+
*/
122+
enableDocumentWideUndoRedo?:boolean;
123+
104124
/**
105125
* The factory for code cell content.
106126
*/

‎packages/notebook/src/widget.ts‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -974,7 +974,13 @@ export namespace StaticNotebook {
974974
* Defines the maximum number of outputs per cell.
975975
*/
976976
maxNumberOutputs:number;
977+
978+
/**
979+
* Defines if the document can be undo/redo.
980+
*/
981+
enableDocumentWideUndoRedo:boolean;
977982
}
983+
978984
/**
979985
* Default configuration options for notebooks.
980986
*/
@@ -986,7 +992,8 @@ export namespace StaticNotebook {
986992
renderCellOnIdle:true,
987993
observedTopMargin:'1000px',
988994
observedBottomMargin:'1000px',
989-
maxNumberOutputs:50
995+
maxNumberOutputs:50,
996+
enableDocumentWideUndoRedo:true
990997
};
991998

992999
/**

‎packages/notebook/test/actions.spec.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ describe('@jupyterlab/notebook', () => {
6262
contentFactory:utils.createNotebookFactory(),
6363
mimeTypeService:utils.mimeTypeService
6464
});
65-
constmodel=newNotebookModel();
65+
constmodel=newNotebookModel({
66+
enableDocumentWideUndoRedo:true
67+
});
6668
model.fromJSON(utils.DEFAULT_CONTENT);
6769
widget.model=model;
6870
model.sharedModel.clearUndoHistory();

‎packages/notebook/test/model.spec.ts‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe('@jupyterlab/notebook', () => {
1313
describe('NotebookModel',()=>{
1414
describe('#constructor()',()=>{
1515
it('should create a notebook model',()=>{
16-
constmodel=newNotebookModel();
16+
constmodel=newNotebookModel({});
1717
expect(model).toBeInstanceOf(NotebookModel);
1818
});
1919

@@ -72,7 +72,9 @@ describe('@jupyterlab/notebook', () => {
7272
});
7373

7474
it('should allow undoing a change',()=>{
75-
constmodel=newNotebookModel();
75+
constmodel=newNotebookModel({
76+
enableDocumentWideUndoRedo:true
77+
});
7678
constcell=model.contentFactory.createCodeCell({});
7779
cell.value.text='foo';
7880
constcellJSON=cell.toJSON();
@@ -380,7 +382,9 @@ describe('@jupyterlab/notebook', () => {
380382
});
381383

382384
it('should clear undo state',()=>{
383-
constmodel=newNotebookModel();
385+
constmodel=newNotebookModel({
386+
enableDocumentWideUndoRedo:true
387+
});
384388
constcell=model.contentFactory.createCodeCell({});
385389
cell.value.text='foo';
386390
model.cells.push(cell);

‎packages/notebook/test/widget.spec.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ const notebookConfig = {
4141
renderCellOnIdle:true,
4242
observedTopMargin:'1000px',
4343
observedBottomMargin:'1000px',
44-
maxNumberOutputs:50
44+
maxNumberOutputs:50,
45+
enableDocumentWideUndoRedo:true
4546
};
4647

4748
constoptions:Notebook.IOptions={

‎packages/shared-models/src/api.ts‎

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,30 @@ export interface ISharedNotebook extends ISharedDocument {
205205
deleteCellRange(from:number,to:number):void;
206206
}
207207

208+
/**
209+
* Definition of the map changes for yjs.
210+
*/
211+
exporttypeMapChange=Map<
212+
string,
213+
{action:'add'|'update'|'delete';oldValue:any;newValue:any}
214+
>;
215+
216+
/**
217+
* The namespace for `ISharedNotebook` class statics.
218+
*/
219+
exportnamespaceISharedNotebook{
220+
/**
221+
* The options used to initialize a a ISharedNotebook
222+
*/
223+
exportinterfaceIOptions{
224+
/**
225+
* Wether the the undo/redo logic should be
226+
* considered on the full document across all cells.
227+
*/
228+
enableDocumentWideUndoRedo:boolean;
229+
}
230+
}
231+
208232
/**
209233
* The Shared kernelspec metadata.
210234
*/
@@ -490,11 +514,3 @@ export type DocumentChange = {
490514
newValue:any;
491515
}>;
492516
};
493-
494-
/**
495-
* Definition of the map changes for yjs.
496-
*/
497-
exporttypeMapChange=Map<
498-
string,
499-
{action:'add'|'update'|'delete';oldValue:any;newValue:any}
500-
>;

‎packages/shared-models/src/ymodels.ts‎

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { ISignal, Signal } from '@lumino/signaling';
99
import{Awareness}from'y-protocols/awareness';
1010
import*asYfrom'yjs';
1111
import*asmodelsfrom'./api';
12-
import{Delta}from'./api';
12+
import{Delta,ISharedNotebook}from'./api';
1313

1414
constdeepCopy=(o:any)=>JSON.parse(JSON.stringify(o));
1515

@@ -199,8 +199,9 @@ export class YFile
199199
exportclassYNotebook
200200
extendsYDocument<models.NotebookChange>
201201
implementsmodels.ISharedNotebook{
202-
constructor(){
202+
constructor(options:ISharedNotebook.IOptions){
203203
super();
204+
this._enableDocumentWideUndoRedo=options.enableDocumentWideUndoRedo;
204205
this.ycells.observe(this._onYCellsChanged);
205206
this.cells=this.ycells.toArray().map(ycell=>{
206207
if(!this._ycellMapping.has(ycell)){
@@ -274,7 +275,9 @@ export class YNotebook
274275
insertCells(index:number,cells:YCellType[]):void{
275276
cells.forEach(cell=>{
276277
this._ycellMapping.set(cell.ymodel,cell);
277-
cell.undoManager=this.undoManager;
278+
if(this.enableDocumentWideUndoRedo){
279+
cell.undoManager=this.undoManager;
280+
}
278281
});
279282
this.transact(()=>{
280283
this.ycells.insert(
@@ -353,8 +356,20 @@ export class YNotebook
353356
/**
354357
* Create a new YNotebook.
355358
*/
356-
publicstaticcreate():models.ISharedNotebook{
357-
returnnewYNotebook();
359+
publicstaticcreate(
360+
enableDocumentWideUndoRedo:boolean
361+
):models.ISharedNotebook{
362+
returnnewYNotebook({ enableDocumentWideUndoRedo});
363+
}
364+
365+
/**
366+
* Wether the the undo/redo logic should be
367+
* considered on the full document across all cells.
368+
*
369+
*@return The enableDocumentWideUndoRedo setting.
370+
*/
371+
getenableDocumentWideUndoRedo():boolean{
372+
returnthis._enableDocumentWideUndoRedo;
358373
}
359374

360375
/**
@@ -369,7 +384,11 @@ export class YNotebook
369384
}
370385
constcell=this._ycellMapping.get(type)asany;
371386
cell._notebook=this;
372-
cell._undoManager=this.undoManager;
387+
if(this.enableDocumentWideUndoRedo){
388+
cell._undoManager=this.undoManager;
389+
}else{
390+
cell._undoManager=newY.UndoManager([cell.ymodel],{});
391+
}
373392
});
374393
event.changes.deleted.forEach(item=>{
375394
consttype=(item.contentasY.ContentType).typeasY.Map<any>;
@@ -441,6 +460,7 @@ export class YNotebook
441460
publicundoManager=newY.UndoManager([this.ycells],{
442461
trackedOrigins:newSet([this])
443462
});
463+
private_enableDocumentWideUndoRedo:boolean;
444464
private_ycellMapping:Map<Y.Map<any>,YCellType>=newMap();
445465
publiccells:YCellType[];
446466
}
@@ -510,7 +530,9 @@ export class YBaseCell<Metadata extends models.ISharedBaseCellMetadata>
510530
* The notebook that this cell belongs to.
511531
*/
512532
getundoManager():Y.UndoManager|null{
513-
returnthis.notebook ?this.notebook.undoManager :this._undoManager;
533+
returnthis.notebook?.enableDocumentWideUndoRedo
534+
?this.notebook.undoManager
535+
:this._undoManager;
514536
}
515537

516538
/**
@@ -617,7 +639,11 @@ export class YBaseCell<Metadata extends models.ISharedBaseCellMetadata>
617639
ymodel.set('cell_type',this.cell_type);
618640
ymodel.set('id',this.getId());
619641
constSelf:any=this.constructor;
620-
returnnewSelf(ymodel);
642+
constclone=newSelf(ymodel);
643+
// TODO The assignmenet of the undoManager does not work for a clone.
644+
// See https://github.com/jupyterlab/jupyterlab/issues/11035
645+
clone._undoManager=this.undoManager;
646+
returnclone;
621647
}
622648

623649
/**

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp