Merge pull request #288 from jtpio/scroll-outputs

Enable auto scrolling for outputs by default
pull/6294/head
Jeremy Tuloup 4 years ago committed by GitHub
commit 6815878b79
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -11,59 +11,59 @@
"watch": "webpack --config ./webpack.config.watch.js"
},
"resolutions": {
"@jupyterlab/application": "~3.2.0",
"@jupyterlab/application-extension": "~3.2.0",
"@jupyterlab/apputils": "~3.2.0",
"@jupyterlab/apputils-extension": "~3.2.0",
"@jupyterlab/celltags": "~3.2.0",
"@jupyterlab/codeeditor": "~3.2.0",
"@jupyterlab/codemirror-extension": "~3.2.0",
"@jupyterlab/completer": "~3.2.0",
"@jupyterlab/completer-extension": "~3.2.0",
"@jupyterlab/console": "~3.2.0",
"@jupyterlab/console-extension": "~3.2.0",
"@jupyterlab/coreutils": "~5.2.0",
"@jupyterlab/docmanager": "~3.2.0",
"@jupyterlab/docmanager-extension": "~3.2.0",
"@jupyterlab/docprovider": "~3.2.0",
"@jupyterlab/docprovider-extension": "~3.2.0",
"@jupyterlab/documentsearch": "~3.2.4",
"@jupyterlab/documentsearch-extension": "~3.2.4",
"@jupyterlab/filebrowser": "~3.2.0",
"@jupyterlab/filebrowser-extension": "~3.2.0",
"@jupyterlab/fileeditor": "~3.2.0",
"@jupyterlab/fileeditor-extension": "~3.2.0",
"@jupyterlab/hub-extension": "~3.2.0",
"@jupyterlab/javascript-extension": "~3.2.0",
"@jupyterlab/json-extension": "~3.2.0",
"@jupyterlab/mainmenu": "~3.2.0",
"@jupyterlab/mainmenu-extension": "~3.2.0",
"@jupyterlab/mathjax2-extension": "~3.2.0",
"@jupyterlab/notebook": "~3.2.0",
"@jupyterlab/notebook-extension": "~3.2.0",
"@jupyterlab/observables": "~4.2.0",
"@jupyterlab/outputarea": "~3.2.0",
"@jupyterlab/pdf-extension": "~3.2.0",
"@jupyterlab/rendermime": "~3.2.0",
"@jupyterlab/rendermime-extension": "~3.2.0",
"@jupyterlab/rendermime-interfaces": "~3.2.0",
"@jupyterlab/running-extension": "~3.2.0",
"@jupyterlab/services": "~6.2.0",
"@jupyterlab/settingregistry": "~3.2.0",
"@jupyterlab/shared-models": "~3.2.0",
"@jupyterlab/shortcuts-extension": "~3.2.0",
"@jupyterlab/statedb": "~3.2.0",
"@jupyterlab/statusbar": "~3.2.0",
"@jupyterlab/terminal": "~3.2.0",
"@jupyterlab/terminal-extension": "~3.2.0",
"@jupyterlab/theme-dark-extension": "~3.2.0",
"@jupyterlab/theme-light-extension": "~3.2.0",
"@jupyterlab/tooltip": "~3.2.0",
"@jupyterlab/tooltip-extension": "~3.2.0",
"@jupyterlab/translation": "~3.2.0",
"@jupyterlab/translation-extension": "~3.2.0",
"@jupyterlab/ui-components": "~3.2.0",
"@jupyterlab/vega5-extension": "~3.2.0",
"@jupyterlab/application": "~3.2.5",
"@jupyterlab/application-extension": "~3.2.5",
"@jupyterlab/apputils": "~3.2.5",
"@jupyterlab/apputils-extension": "~3.2.5",
"@jupyterlab/celltags": "~3.2.5",
"@jupyterlab/codeeditor": "~3.2.5",
"@jupyterlab/codemirror-extension": "~3.2.5",
"@jupyterlab/completer": "~3.2.5",
"@jupyterlab/completer-extension": "~3.2.5",
"@jupyterlab/console": "~3.2.5",
"@jupyterlab/console-extension": "~3.2.5",
"@jupyterlab/coreutils": "~5.2.5",
"@jupyterlab/docmanager": "~3.2.5",
"@jupyterlab/docmanager-extension": "~3.2.5",
"@jupyterlab/docprovider": "~3.2.5",
"@jupyterlab/docprovider-extension": "~3.2.5",
"@jupyterlab/documentsearch": "~3.2.5",
"@jupyterlab/documentsearch-extension": "~3.2.5",
"@jupyterlab/filebrowser": "~3.2.5",
"@jupyterlab/filebrowser-extension": "~3.2.5",
"@jupyterlab/fileeditor": "~3.2.5",
"@jupyterlab/fileeditor-extension": "~3.2.5",
"@jupyterlab/hub-extension": "~3.2.5",
"@jupyterlab/javascript-extension": "~3.2.5",
"@jupyterlab/json-extension": "~3.2.5",
"@jupyterlab/mainmenu": "~3.2.5",
"@jupyterlab/mainmenu-extension": "~3.2.5",
"@jupyterlab/mathjax2-extension": "~3.2.5",
"@jupyterlab/notebook": "~3.2.5",
"@jupyterlab/notebook-extension": "~3.2.5",
"@jupyterlab/observables": "~4.2.5",
"@jupyterlab/outputarea": "~3.2.5",
"@jupyterlab/pdf-extension": "~3.2.5",
"@jupyterlab/rendermime": "~3.2.5",
"@jupyterlab/rendermime-extension": "~3.2.5",
"@jupyterlab/rendermime-interfaces": "~3.2.5",
"@jupyterlab/running-extension": "~3.2.5",
"@jupyterlab/services": "~6.2.5",
"@jupyterlab/settingregistry": "~3.2.5",
"@jupyterlab/shared-models": "~3.2.5",
"@jupyterlab/shortcuts-extension": "~3.2.5",
"@jupyterlab/statedb": "~3.2.5",
"@jupyterlab/statusbar": "~3.2.5",
"@jupyterlab/terminal": "~3.2.5",
"@jupyterlab/terminal-extension": "~3.2.5",
"@jupyterlab/theme-dark-extension": "~3.2.5",
"@jupyterlab/theme-light-extension": "~3.2.5",
"@jupyterlab/tooltip": "~3.2.5",
"@jupyterlab/tooltip-extension": "~3.2.5",
"@jupyterlab/translation": "~3.2.5",
"@jupyterlab/translation-extension": "~3.2.5",
"@jupyterlab/ui-components": "~3.2.5",
"@jupyterlab/vega5-extension": "~3.2.5",
"@lumino/algorithm": "~1.6.0",
"@lumino/application": "~1.20.0",
"@lumino/commands": "~1.15.0",
@ -88,37 +88,37 @@
"@retrolab/ui-components": "~0.3.14",
"react": "~17.0.2",
"react-dom": "~17.0.2",
"yjs": "~13.5.10"
"yjs": "~13.5.23"
},
"dependencies": {
"@jupyterlab/application-extension": "^3.2.0",
"@jupyterlab/apputils-extension": "^3.2.0",
"@jupyterlab/celltags": "^3.2.0",
"@jupyterlab/codemirror-extension": "^3.2.0",
"@jupyterlab/completer-extension": "^3.2.0",
"@jupyterlab/console-extension": "^3.2.0",
"@jupyterlab/coreutils": "~5.2.0",
"@jupyterlab/docmanager-extension": "^3.2.0",
"@jupyterlab/docprovider-extension": "^3.2.0",
"@jupyterlab/documentsearch-extension": "^3.2.0",
"@jupyterlab/filebrowser-extension": "^3.2.0",
"@jupyterlab/fileeditor-extension": "^3.2.0",
"@jupyterlab/hub-extension": "^3.2.0",
"@jupyterlab/javascript-extension": "^3.2.0",
"@jupyterlab/json-extension": "^3.2.0",
"@jupyterlab/mainmenu-extension": "^3.2.0",
"@jupyterlab/mathjax2-extension": "^3.2.0",
"@jupyterlab/notebook-extension": "^3.2.0",
"@jupyterlab/pdf-extension": "^3.2.0",
"@jupyterlab/rendermime-extension": "^3.2.0",
"@jupyterlab/running-extension": "^3.2.0",
"@jupyterlab/shortcuts-extension": "^3.2.0",
"@jupyterlab/terminal-extension": "^3.2.0",
"@jupyterlab/theme-dark-extension": "^3.2.0",
"@jupyterlab/theme-light-extension": "^3.2.0",
"@jupyterlab/tooltip-extension": "^3.2.0",
"@jupyterlab/translation-extension": "^3.2.0",
"@jupyterlab/vega5-extension": "^3.2.0",
"@jupyterlab/application-extension": "^3.2.5",
"@jupyterlab/apputils-extension": "^3.2.5",
"@jupyterlab/celltags": "^3.2.5",
"@jupyterlab/codemirror-extension": "^3.2.5",
"@jupyterlab/completer-extension": "^3.2.5",
"@jupyterlab/console-extension": "^3.2.5",
"@jupyterlab/coreutils": "~5.2.5",
"@jupyterlab/docmanager-extension": "^3.2.5",
"@jupyterlab/docprovider-extension": "^3.2.5",
"@jupyterlab/documentsearch-extension": "^3.2.5",
"@jupyterlab/filebrowser-extension": "^3.2.5",
"@jupyterlab/fileeditor-extension": "^3.2.5",
"@jupyterlab/hub-extension": "^3.2.5",
"@jupyterlab/javascript-extension": "^3.2.5",
"@jupyterlab/json-extension": "^3.2.5",
"@jupyterlab/mainmenu-extension": "^3.2.5",
"@jupyterlab/mathjax2-extension": "^3.2.5",
"@jupyterlab/notebook-extension": "^3.2.5",
"@jupyterlab/pdf-extension": "^3.2.5",
"@jupyterlab/rendermime-extension": "^3.2.5",
"@jupyterlab/running-extension": "^3.2.5",
"@jupyterlab/shortcuts-extension": "^3.2.5",
"@jupyterlab/terminal-extension": "^3.2.5",
"@jupyterlab/theme-dark-extension": "^3.2.5",
"@jupyterlab/theme-light-extension": "^3.2.5",
"@jupyterlab/tooltip-extension": "^3.2.5",
"@jupyterlab/translation-extension": "^3.2.5",
"@jupyterlab/vega5-extension": "^3.2.5",
"@retrolab/application": "^0.3.14",
"@retrolab/application-extension": "^0.3.14",
"@retrolab/console-extension": "^0.3.14",
@ -131,8 +131,8 @@
"@retrolab/ui-components": "^0.3.14"
},
"devDependencies": {
"@jupyterlab/builder": "^3.2.0",
"@jupyterlab/buildutils": "^3.2.0",
"@jupyterlab/builder": "^3.2.5",
"@jupyterlab/buildutils": "^3.2.5",
"@types/rimraf": "^3.0.0",
"css-loader": "~5.0.1",
"file-loader": "~5.0.2",

@ -30,7 +30,7 @@
"watch": "tsc -w --listEmittedFiles"
},
"dependencies": {
"@jupyterlab/buildutils": "^3.2.0",
"@jupyterlab/buildutils": "^3.2.5",
"commander": "^6.2.0",
"fs-extra": "^9.1.0",
"typescript": "~4.1.3"

@ -24,9 +24,9 @@
"build:prod": "lerna run build:prod",
"build:test": "lerna run build:test",
"clean": "lerna run clean",
"develop": "jupyter labextension develop . --overwrite && node ./buildutils/lib/develop.js --overwrite",
"eslint": "eslint . --ext .ts,.tsx --fix",
"eslint:check": "eslint . --ext .ts,.tsx",
"develop": "jupyter labextension develop . --overwrite && node ./buildutils/lib/develop.js --overwrite",
"install": "lerna bootstrap",
"integrity": "node buildutils/lib/ensure-repo.js",
"prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
@ -45,7 +45,7 @@
}
},
"devDependencies": {
"@jupyterlab/buildutils": "^3.2.0",
"@jupyterlab/buildutils": "^3.2.5",
"@typescript-eslint/eslint-plugin": "^4.2.0",
"@typescript-eslint/parser": "^4.2.0",
"eslint": "^7.10.0",

@ -39,18 +39,18 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/apputils": "^3.2.0",
"@jupyterlab/celltags": "^3.2.0",
"@jupyterlab/codeeditor": "^3.2.0",
"@jupyterlab/codemirror": "^3.2.0",
"@jupyterlab/console": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/docmanager": "^3.2.0",
"@jupyterlab/docregistry": "^3.2.0",
"@jupyterlab/mainmenu": "^3.2.0",
"@jupyterlab/settingregistry": "^3.2.0",
"@jupyterlab/translation": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/apputils": "^3.2.5",
"@jupyterlab/celltags": "^3.2.5",
"@jupyterlab/codeeditor": "^3.2.5",
"@jupyterlab/codemirror": "^3.2.5",
"@jupyterlab/console": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/docmanager": "^3.2.5",
"@jupyterlab/docregistry": "^3.2.5",
"@jupyterlab/mainmenu": "^3.2.5",
"@jupyterlab/settingregistry": "^3.2.5",
"@jupyterlab/translation": "^3.2.5",
"@lumino/coreutils": "^1.8.0",
"@lumino/disposable": "^1.7.0",
"@lumino/widgets": "^1.23.0",

@ -27,6 +27,8 @@ import { DocumentWidget } from '@jupyterlab/docregistry';
import { IMainMenu } from '@jupyterlab/mainmenu';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { ITranslator } from '@jupyterlab/translation';
import { RetroApp, RetroShell, IRetroShell } from '@retrolab/application';
@ -38,7 +40,6 @@ import { PromiseDelegate } from '@lumino/coreutils';
import { DisposableDelegate, DisposableSet } from '@lumino/disposable';
import { Widget } from '@lumino/widgets';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
/**
* The default notebook factory.

@ -43,11 +43,11 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/docregistry": "^3.2.0",
"@jupyterlab/rendermime-interfaces": "^3.2.0",
"@jupyterlab/ui-components": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/docregistry": "^3.2.5",
"@jupyterlab/rendermime-interfaces": "^3.2.5",
"@jupyterlab/ui-components": "^3.2.5",
"@lumino/algorithm": "^1.6.0",
"@lumino/coreutils": "^1.8.0",
"@lumino/messaging": "^1.7.0",
@ -58,7 +58,7 @@
"devDependencies": {
"@babel/core": "^7.11.6",
"@babel/preset-env": "^7.12.1",
"@jupyterlab/testutils": "^3.2.0",
"@jupyterlab/testutils": "^3.2.5",
"@types/jest": "^26.0.10",
"jest": "^26.4.2",
"rimraf": "~3.0.0",

@ -39,9 +39,9 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/console": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/console": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@lumino/algorithm": "^1.6.0"
},
"devDependencies": {

@ -39,11 +39,11 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/docmanager": "^3.2.0",
"@jupyterlab/docregistry": "^3.2.0",
"@jupyterlab/services": "^6.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/docmanager": "^3.2.5",
"@jupyterlab/docregistry": "^3.2.5",
"@jupyterlab/services": "^6.2.5",
"@lumino/algorithm": "^1.6.0"
},
"devDependencies": {

@ -39,8 +39,8 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/documentsearch": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/documentsearch": "^3.2.5",
"@lumino/widgets": "^1.23.0",
"@retrolab/application": "^0.3.14"
},

@ -39,10 +39,10 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/apputils": "^3.2.0",
"@jupyterlab/mainmenu": "^3.2.0",
"@jupyterlab/translation": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/apputils": "^3.2.5",
"@jupyterlab/mainmenu": "^3.2.5",
"@jupyterlab/translation": "^3.2.5",
"@retrolab/ui-components": "^0.3.14"
},
"devDependencies": {

@ -43,19 +43,19 @@
"watch:src": "tsc -w"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/apputils": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/docregistry": "^3.2.0",
"@jupyterlab/mainmenu": "^3.2.0",
"@jupyterlab/notebook": "^3.2.0",
"@jupyterlab/translation": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/apputils": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/docregistry": "^3.2.5",
"@jupyterlab/mainmenu": "^3.2.5",
"@jupyterlab/notebook": "^3.2.5",
"@jupyterlab/translation": "^3.2.5",
"@lumino/commands": "^1.15.0",
"@lumino/disposable": "^1.7.0",
"@retrolab/application": "^0.3.14"
},
"devDependencies": {
"@jupyterlab/builder": "^3.2.0",
"@jupyterlab/builder": "^3.2.5",
"rimraf": "~3.0.0",
"typescript": "~4.1.3"
},

@ -39,11 +39,13 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/apputils": "^3.2.0",
"@jupyterlab/docmanager": "^3.2.0",
"@jupyterlab/notebook": "^3.2.0",
"@jupyterlab/translation": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/apputils": "^3.2.5",
"@jupyterlab/cells": "^3.2.5",
"@jupyterlab/docmanager": "^3.2.5",
"@jupyterlab/notebook": "^3.2.5",
"@jupyterlab/settingregistry": "^3.2.5",
"@jupyterlab/translation": "^3.2.5",
"@lumino/polling": "^1.6.0",
"@lumino/widgets": "^1.23.0",
"@retrolab/application": "^0.3.14"
@ -56,7 +58,8 @@
"access": "public"
},
"jupyterlab": {
"extension": true
"extension": true,
"schemaDir": "schema"
},
"styleModule": "style/index.js"
}

@ -0,0 +1,16 @@
{
"jupyter.lab.setting-icon": "retro-ui-components:retroSun",
"jupyter.lab.setting-icon-label": "RetroLab Notebook",
"title": "RetroLab Notebook",
"description": "RetroLab Notebook settings",
"properties": {
"autoScrollOutputs": {
"type": "boolean",
"title": "Auto Scroll Outputs",
"description": "Whether to auto scroll the output area when the outputs become too long",
"default": true
}
},
"additionalProperties": false,
"type": "object"
}

@ -8,11 +8,15 @@ import {
import { ISessionContext, DOMUtils } from '@jupyterlab/apputils';
import { CodeCell } from '@jupyterlab/cells';
import { Text, Time } from '@jupyterlab/coreutils';
import { IDocumentManager } from '@jupyterlab/docmanager';
import { NotebookPanel } from '@jupyterlab/notebook';
import { NotebookPanel, INotebookTracker } from '@jupyterlab/notebook';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { ITranslator } from '@jupyterlab/translation';
@ -42,6 +46,11 @@ const KERNEL_STATUS_INFO_CLASS = 'jp-RetroKernelStatus-info';
*/
const KERNEL_STATUS_FADE_OUT_CLASS = 'jp-RetroKernelStatus-fade';
/**
* The class for scrolled outputs
*/
const SCROLLED_OUTPUTS_CLASS = 'jp-mod-outputsScrolled';
/**
* A plugin for the checkpoint indicator
*/
@ -214,13 +223,103 @@ const kernelStatus: JupyterFrontEndPlugin<void> = {
}
};
/**
* A plugin to enable scrolling for outputs by default.
* Mimic the logic from the classic notebook, as found here:
* https://github.com/jupyter/notebook/blob/a9a31c096eeffe1bff4e9164c6a0442e0e13cdb3/notebook/static/notebook/js/outputarea.js#L96-L120
*/
const scrollOutput: JupyterFrontEndPlugin<void> = {
id: '@retrolab/notebook-extension:scroll-output',
autoStart: true,
requires: [INotebookTracker],
optional: [ISettingRegistry],
activate: async (
app: JupyterFrontEnd,
tracker: INotebookTracker,
settingRegistry: ISettingRegistry | null
) => {
const autoScrollThreshold = 100;
let autoScrollOutputs = true;
// decide whether to scroll the output of the cell based on some heuristics
const autoScroll = (cell: CodeCell) => {
if (!autoScrollOutputs) {
// bail if disabled via the settings
return;
}
const { outputArea } = cell;
// respect cells with an explicit scrolled state
const scrolled = cell.model.metadata.get('scrolled');
if (scrolled !== undefined) {
return;
}
const { node } = outputArea;
const height = node.scrollHeight;
const fontSize = parseFloat(node.style.fontSize.replace('px', ''));
const lineHeight = (fontSize || 14) * 1.3;
// do not set via cell.outputScrolled = true, as this would
// otherwise synchronize the scrolled state to the notebook metadata
const scroll = height > lineHeight * autoScrollThreshold;
cell.toggleClass(SCROLLED_OUTPUTS_CLASS, scroll);
};
tracker.widgetAdded.connect((sender, notebook) => {
notebook.model?.cells.changed.connect((sender, changed) => {
// process new cells only
if (!(changed.type === 'add')) {
return;
}
const [cellModel] = changed.newValues;
notebook.content.widgets.forEach(cell => {
if (cell.model.id === cellModel.id && cell.model.type === 'code') {
const codeCell = cell as CodeCell;
codeCell.outputArea.model.changed.connect(() =>
autoScroll(codeCell)
);
}
});
});
// when the notebook widget is created, process all the cells
// TODO: investigate why notebook.content.fullyRendered is not enough
notebook.sessionContext.ready.then(() => {
notebook.content.widgets.forEach(cell => {
if (cell.model.type === 'code') {
autoScroll(cell as CodeCell);
}
});
});
});
if (settingRegistry) {
const loadSettings = settingRegistry.load(scrollOutput.id);
const updateSettings = (settings: ISettingRegistry.ISettings): void => {
autoScrollOutputs = settings.get('autoScrollOutputs')
.composite as boolean;
};
Promise.all([loadSettings, app.restored])
.then(([settings]) => {
updateSettings(settings);
settings.changed.connect(settings => {
updateSettings(settings);
});
})
.catch((reason: Error) => {
console.error(reason.message);
});
}
}
};
/**
* Export the plugins as default.
*/
const plugins: JupyterFrontEndPlugin<any>[] = [
checkpoints,
kernelLogo,
kernelStatus
kernelStatus,
scrollOutput
];
export default plugins;

@ -39,9 +39,9 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/terminal": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/terminal": "^3.2.5",
"@lumino/algorithm": "^1.6.0"
},
"devDependencies": {

@ -39,17 +39,17 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/application": "^3.2.0",
"@jupyterlab/apputils": "^3.2.0",
"@jupyterlab/coreutils": "^5.2.0",
"@jupyterlab/docmanager": "^3.2.0",
"@jupyterlab/filebrowser": "^3.2.0",
"@jupyterlab/mainmenu": "^3.2.0",
"@jupyterlab/services": "^6.2.0",
"@jupyterlab/settingregistry": "^3.2.0",
"@jupyterlab/statedb": "^3.2.0",
"@jupyterlab/translation": "^3.2.0",
"@jupyterlab/ui-components": "^3.2.0",
"@jupyterlab/application": "^3.2.5",
"@jupyterlab/apputils": "^3.2.5",
"@jupyterlab/coreutils": "^5.2.5",
"@jupyterlab/docmanager": "^3.2.5",
"@jupyterlab/filebrowser": "^3.2.5",
"@jupyterlab/mainmenu": "^3.2.5",
"@jupyterlab/services": "^6.2.5",
"@jupyterlab/settingregistry": "^3.2.5",
"@jupyterlab/statedb": "^3.2.5",
"@jupyterlab/translation": "^3.2.5",
"@jupyterlab/ui-components": "^3.2.5",
"@lumino/algorithm": "^1.6.0",
"@lumino/commands": "^1.15.0",
"@lumino/widgets": "^1.23.0",

@ -43,14 +43,14 @@
"watch": "tsc -b --watch"
},
"dependencies": {
"@jupyterlab/ui-components": "^3.2.0",
"@jupyterlab/ui-components": "^3.2.5",
"react": "^17.0.1",
"react-dom": "^17.0.1"
},
"devDependencies": {
"@babel/core": "^7.10.2",
"@babel/preset-env": "^7.10.2",
"@jupyterlab/testutils": "^3.2.0",
"@jupyterlab/testutils": "^3.2.5",
"@types/jest": "^26.0.10",
"babel-loader": "^8.0.6",
"jest": "^26.4.2",

@ -1,5 +1,4 @@
from ._version import __version__
from .app import RetroApp
from .serverextension import load_jupyter_server_extension
@ -12,6 +11,7 @@ def _jupyter_server_extension_paths():
def _jupyter_server_extension_points():
from .app import RetroApp
return [{"module": "retrolab", "app": RetroApp}]

@ -1,7 +1,5 @@
from .app import RetroApp
def load_jupyter_server_extension(serverapp):
from .app import RetroApp
extension = RetroApp()
extension.serverapp = serverapp
extension.load_config_file()

@ -6,6 +6,7 @@ import path from 'path';
import { expect } from '@playwright/test';
import { test } from './fixtures';
import { waitForKernelReady } from './utils';
test.use({ autoGoto: false, viewport: { width: 512, height: 768 } });
@ -33,21 +34,7 @@ test.describe('Mobile', () => {
// await page.notebook.run();
// wait for the kernel status animations to be finished
await page.waitForSelector('.jp-RetroKernelStatus-fade');
await page.waitForFunction(() => {
const status = window.document.getElementsByClassName(
'jp-RetroKernelStatus'
)[0];
if (!status) {
return false;
}
const finished = status?.getAnimations().reduce((prev, curr) => {
return prev && curr.playState === 'finished';
}, true);
return finished;
});
await waitForKernelReady(page);
expect(await page.screenshot()).toMatchSnapshot('notebook.png');
});

@ -3,9 +3,11 @@
import path from 'path';
import { expect } from '@playwright/test';
import { test } from './fixtures';
import { expect } from '@playwright/test';
import { runAndAdvance, waitForKernelReady } from './utils';
const NOTEBOOK = 'example.ipynb';
@ -55,4 +57,38 @@ test.describe('Notebook', () => {
const url = page.url();
expect(url).toContain(newNameStripped);
});
// TODO: rewrite with page.notebook when fixed upstream in Galata
// and usable in RetroLab without active tabs
test('Outputs should be scrolled automatically', async ({
page,
tmpPath
}) => {
const notebook = 'autoscroll.ipynb';
await page.contents.uploadFile(
path.resolve(__dirname, `./notebooks/${notebook}`),
`${tmpPath}/${notebook}`
);
await page.goto(`notebooks/${tmpPath}/${notebook}`);
await waitForKernelReady(page);
// run the two cells
await runAndAdvance(page);
await runAndAdvance(page);
await page.waitForSelector('.jp-Cell-outputArea pre');
const checkCell = async (n: number): Promise<boolean> => {
const scrolled = await page.$eval(`.jp-Notebook-cell >> nth=${n}`, el =>
el.classList.contains('jp-mod-outputsScrolled')
);
return scrolled;
};
// check the long output area is auto scrolled
expect(await checkCell(0)).toBe(true);
// check the short output area is not auto scrolled
expect(await checkCell(1)).toBe(false);
});
});

@ -0,0 +1,41 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "6f7028b9-4d2c-4fa2-96ee-bfa77bbee434",
"metadata": {},
"outputs": [],
"source": ["print('1\\n' * 200)"]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6f7028b9-4d2c-4fa2-96ee-bfa77bbee434",
"metadata": {},
"outputs": [],
"source": ["print('1\\n' * 20)"]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

@ -0,0 +1,35 @@
import { IJupyterLabPageFixture } from '@jupyterlab/galata';
/**
* Run the selected cell and advance.
*/
export async function runAndAdvance(
page: IJupyterLabPageFixture
): Promise<void> {
await page.click(
"//button[normalize-space(@title)='Run the selected cells and advance']"
);
}
/**
* Wait for the kernel to be ready
*/
export async function waitForKernelReady(
page: IJupyterLabPageFixture
): Promise<void> {
await page.waitForSelector('.jp-RetroKernelStatus-fade');
await page.waitForFunction(() => {
const status = window.document.getElementsByClassName(
'jp-RetroKernelStatus'
)[0];
if (!status) {
return false;
}
const finished = status?.getAnimations().reduce((prev, curr) => {
return prev && curr.playState === 'finished';
}, true);
return finished;
});
}

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save