diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 92c9ebbf0b9c..56c57d9a7321 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 4, 1, 0, "alpha", 2 +current_version = 4, 1, 6, "final", 0 commit = False tag = False parse = (?P\d+)\,\ (?P\d+)\,\ (?P\d+)\,\ \"(?P\S+)\"\,\ (?P\d+) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000000..304adf777c1b --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,67 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the +// README at: https://github.com/devcontainers/templates/tree/main/src/python +{ + "name": "Python 3", + "build": { + "dockerfile": "../docker/Dockerfile", + "context": "..", + "target": "base" + }, + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + "forwardPorts": [8888], + + // Use 'postCreateCommand' to run commands after the container is created. + // Populate the yarn cache + "postCreateCommand": "micromamba run pip install -e .", + + // Configure tool-specific properties. + "customizations": { + "vscode": { + "extensions": [ + "charliermarsh.ruff", + "dbaeumer.vscode-eslint", + "eamodio.gitlens", + "esbenp.prettier-vscode", + "github.vscode-github-actions", + "github.vscode-pull-request-github", + "meganrogge.template-string-converter", + "ms-python.python", + "streetsidesoftware.code-spell-checker" + ], + "settings": { + "[javascript]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.tabSize": 2 + }, + "[javascriptreact]": { + "editor.defaultFormatter": "dbaeumer.vscode-eslint", + "editor.tabSize": 2 + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.tabSize": 2 + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.tabSize": 2 + }, + "[python]": { + "editor.tabSize": 4 + }, + "terminal.integrated.profiles.linux": { + "bash": { + "path": "bash", + "icon": "terminal-bash" + }, + "zsh": { + "path": "zsh" + } + } + } + } + } + + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. + // "remoteUser": "root" +} diff --git a/docker/Dockerfile.dockerignore b/.dockerignore similarity index 99% rename from docker/Dockerfile.dockerignore rename to .dockerignore index 2b2e51e32df4..1d24d037066d 100644 --- a/docker/Dockerfile.dockerignore +++ b/.dockerignore @@ -40,3 +40,4 @@ tests/**/coverage tests/**/.cache-loader **/node_modules +.yarn diff --git a/.eslintignore b/.eslintignore index 74d8696bbd81..1e01a83b75a7 100644 --- a/.eslintignore +++ b/.eslintignore @@ -27,6 +27,7 @@ jupyterlab/geckodriver jupyterlab/staging/yarn.js jupyterlab/staging/index.js jupyterlab/staging/webpack.config.js +packages/codemirror/test/foo*.js packages/extensionmanager-extension/examples/listings packages/nbconvert-css/raw.js packages/services/dist diff --git a/.eslintrc.js b/.eslintrc.js index 90b9f4a48699..c9827bbab47a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -111,6 +111,7 @@ module.exports = { 'extension_data', 'extension_name', 'file_extension', + 'hash_algorithm', 'help_links', 'hist_access_type', 'ids_only', diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a34b92fc05ae..392b288b8dc1 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,10 @@ updates: schedule: # Check for updates to GitHub Actions every month interval: "monthly" + groups: + actions: + patterns: + - "*" # Set update schedule for pip - package-ecosystem: "pip" directory: "/" @@ -13,3 +17,12 @@ updates: # Check for updates to GitHub Actions every month # Align with pre-commit configuration .pre-commit-config.yaml interval: "monthly" + groups: + pip: + patterns: + - "*" + ignore: + # Prevent the UI tests from failing, as the version number of ipython is visible + # in some of the Galata snapshots + - dependency-name: "ipython" + update-types: ["version-update:semver-minor", "version-update:semver-patch"] diff --git a/.github/labeler.yml b/.github/labeler.yml index a53c996797ae..303b4f3f8385 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,311 +1,437 @@ Design System CSS: - - '**/*.css' - - '*.css' +- changed-files: + - any-glob-to-any-file: + - '**/*.css' + - '*.css' documentation: - - docs/**/* - - docs/* - - '*.md' - - '**/*.md' +- changed-files: + - any-glob-to-any-file: + - docs/**/* + - docs/* + - '*.md' + - '**/*.md' tag:CSS: - - '**/*.css' - - '*.css' +- changed-files: + - any-glob-to-any-file: + - '**/*.css' + - '*.css' 'tag:Design and UX': - - design/**/* - - design/* +- changed-files: + - any-glob-to-any-file: + - design/**/* + - design/* tag:Examples: - - examples/**/* - - examples/* +- changed-files: + - any-glob-to-any-file: + - examples/**/* + - examples/* tag:Testing: - - tests/**/* - - tests/* - - galata/**/* - - galata/* +- changed-files: + - any-glob-to-any-file: + - tests/**/* + - tests/* + - galata/**/* + - galata/* ###################### # Package Labels # ###################### pkg:application: - - packages/application/**/* - - packages/application/* - - packages/application-extension/**/* - - packages/application-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/application/**/* + - packages/application/* + - packages/application-extension/**/* + - packages/application-extension/* pkg:apputils: - - packages/apputils/**/* - - packages/apputils/* - - packages/apputils-extension/**/* - - packages/apputils-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/apputils/**/* + - packages/apputils/* + - packages/apputils-extension/**/* + - packages/apputils-extension/* pkg:attachments: - - packages/attachments/**/* - - packages/attachments/* +- changed-files: + - any-glob-to-any-file: + - packages/attachments/**/* + - packages/attachments/* pkg:cell-toolbar: - - packages/cell-toolbar/**/* - - packages/cell-toolbar/* - - packages/cell-toolbar-extension/**/* - - packages/cell-toolbar-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/cell-toolbar/**/* + - packages/cell-toolbar/* + - packages/cell-toolbar-extension/**/* + - packages/cell-toolbar-extension/* pkg:cells: - - packages/cells/**/* - - packages/cells/* +- changed-files: + - any-glob-to-any-file: + - packages/cells/**/* + - packages/cells/* pkg:celltags: - - packages/celltags-extension/**/* - - packages/celltags-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/celltags-extension/**/* + - packages/celltags-extension/* pkg:codeeditor: - - packages/codeeditor/**/* - - packages/codeeditor/* +- changed-files: + - any-glob-to-any-file: + - packages/codeeditor/**/* + - packages/codeeditor/* pkg:codemirror: - - packages/codemirror/**/* - - packages/codemirror/* - - packages/codemirror-extension/**/* - - packages/codemirror-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/codemirror/**/* + - packages/codemirror/* + - packages/codemirror-extension/**/* + - packages/codemirror-extension/* pkg:completer: - - packages/completer/**/* - - packages/completer/* - - packages/completer-extension/**/* - - packages/completer-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/completer/**/* + - packages/completer/* + - packages/completer-extension/**/* + - packages/completer-extension/* pkg:console: - - packages/console/**/* - - packages/console/* - - packages/console-extension/**/* - - packages/console-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/console/**/* + - packages/console/* + - packages/console-extension/**/* + - packages/console-extension/* pkg:coreutils: - - packages/coreutils/**/* - - packages/coreutils/* +- changed-files: + - any-glob-to-any-file: + - packages/coreutils/**/* + - packages/coreutils/* pkg:csvviewer: - - packages/csvviewer/**/* - - packages/csvviewer/* - - packages/csvviewer-extension/**/* - - packages/csvviewer-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/csvviewer/**/* + - packages/csvviewer/* + - packages/csvviewer-extension/**/* + - packages/csvviewer-extension/* pkg:debugger: - - packages/debugger/**/* - - packages/debugger/* - - packages/debugger-extension/**/* - - packages/debugger-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/debugger/**/* + - packages/debugger/* + - packages/debugger-extension/**/* + - packages/debugger-extension/* pkg:docmanager: - - packages/docmanager/**/* - - packages/docmanager/* - - packages/docmanager-extension/**/* - - packages/docmanager-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/docmanager/**/* + - packages/docmanager/* + - packages/docmanager-extension/**/* + - packages/docmanager-extension/* pkg:docregistry: - - packages/docregistry/**/* - - packages/docregistry/* +- changed-files: + - any-glob-to-any-file: + - packages/docregistry/**/* + - packages/docregistry/* pkg:documentsearch: - - packages/documentsearch/**/* - - packages/documentsearch/* - - packages/documentsearch-extension/**/* - - packages/documentsearch-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/documentsearch/**/* + - packages/documentsearch/* + - packages/documentsearch-extension/**/* + - packages/documentsearch-extension/* pkg:extensionmanager: - - packages/extensionmanager/**/* - - packages/extensionmanager/* - - packages/extensionmanager-extension/**/* - - packages/extensionmanager-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/extensionmanager/**/* + - packages/extensionmanager/* + - packages/extensionmanager-extension/**/* + - packages/extensionmanager-extension/* pkg:filebrowser: - - packages/filebrowser/**/* - - packages/filebrowser/* - - packages/filebrowser-extension/**/* - - packages/filebrowser-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/filebrowser/**/* + - packages/filebrowser/* + - packages/filebrowser-extension/**/* + - packages/filebrowser-extension/* pkg:fileeditor: - - packages/fileeditor/**/* - - packages/fileeditor/* - - packages/fileeditor-extension/**/* - - packages/fileeditor-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/fileeditor/**/* + - packages/fileeditor/* + - packages/fileeditor-extension/**/* + - packages/fileeditor-extension/* pkg:help: - - packages/help-extension/**/* - - packages/help-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/help-extension/**/* + - packages/help-extension/* pkg:htmlviewer: - - packages/htmlviewer/**/* - - packages/htmlviewer/* - - packages/htmlviewer-extension/**/* - - packages/htmlviewer-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/htmlviewer/**/* + - packages/htmlviewer/* + - packages/htmlviewer-extension/**/* + - packages/htmlviewer-extension/* pkg:hub: - - packages/hub-extension/**/* - - packages/hub-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/hub-extension/**/* + - packages/hub-extension/* pkg:imageviewer: - - packages/imageviewer/**/* - - packages/imageviewer/* - - packages/imageviewer-extension/**/* - - packages/imageviewer-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/imageviewer/**/* + - packages/imageviewer/* + - packages/imageviewer-extension/**/* + - packages/imageviewer-extension/* pkg:inspector: - - packages/inspector/**/* - - packages/inspector/* - - packages/inspector-extension/**/* - - packages/inspector-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/inspector/**/* + - packages/inspector/* + - packages/inspector-extension/**/* + - packages/inspector-extension/* pkg:javascript: - - packages/javascript-extension/**/* - - packages/javascript-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/javascript-extension/**/* + - packages/javascript-extension/* pkg:json: - - packages/json-extension/**/* - - packages/json-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/json-extension/**/* + - packages/json-extension/* pkg:launcher: - - packages/launcher/**/* - - packages/launcher/* - - packages/launcher-extension/**/* - - packages/launcher-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/launcher/**/* + - packages/launcher/* + - packages/launcher-extension/**/* + - packages/launcher-extension/* pkg:logconsole: - - packages/logconsole/**/* - - packages/logconsole/* - - packages/logconsole-extension/**/* - - packages/logconsole-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/logconsole/**/* + - packages/logconsole/* + - packages/logconsole-extension/**/* + - packages/logconsole-extension/* pkg:lsp: - - packages/lsp/**/* - - packages/lsp/* - - packages/lsp-extension/**/* - - packages/lsp-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/lsp/**/* + - packages/lsp/* + - packages/lsp-extension/**/* + - packages/lsp-extension/* pkg:mainmenu: - - packages/mainmenu/**/* - - packages/mainmenu/* - - packages/mainmenu-extension/**/* - - packages/mainmenu-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/mainmenu/**/* + - packages/mainmenu/* + - packages/mainmenu-extension/**/* + - packages/mainmenu-extension/* pkg:markdownviewer: - - packages/markdownviewer/**/* - - packages/markdownviewer/* - - packages/markdownviewer-extension/**/* - - packages/markdownviewer-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/markdownviewer/**/* + - packages/markdownviewer/* + - packages/markdownviewer-extension/**/* + - packages/markdownviewer-extension/* pkg:mathjax: - - packages/mathjax-extension/**/* - - packages/mathjax-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/mathjax-extension/**/* + - packages/mathjax-extension/* + +pkg:mermaid: +- changed-files: + - any-glob-to-any-file: + - packages/mermaid/**/* + - packages/mermaid/* + - packages/mermaid-extension/**/* + - packages/mermaid-extension/* pkg:notebook: - - packages/notebook/**/* - - packages/notebook/* - - packages/notebook-extension/**/* - - packages/notebook-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/notebook/**/* + - packages/notebook/* + - packages/notebook-extension/**/* + - packages/notebook-extension/* pkg:observables: - - packages/observables/**/* - - packages/observables/* +- changed-files: + - any-glob-to-any-file: + - packages/observables/**/* + - packages/observables/* pkg:outputarea: - - packages/outputarea/**/* - - packages/outputarea/* +- changed-files: + - any-glob-to-any-file: + - packages/outputarea/**/* + - packages/outputarea/* pkg:pdf: - - packages/pdf-extension/**/* - - packages/pdf-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/pdf-extension/**/* + - packages/pdf-extension/* pkg:property-inspector: - - packages/property-inspector/**/* - - packages/property-inspector/* +- changed-files: + - any-glob-to-any-file: + - packages/property-inspector/**/* + - packages/property-inspector/* pkg:pluginmanager: - - packages/pluginmanager/**/* - - packages/pluginmanager/* - - packages/pluginmanager-extension/**/* - - packages/pluginmanager-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/pluginmanager/**/* + - packages/pluginmanager/* + - packages/pluginmanager-extension/**/* + - packages/pluginmanager-extension/* pkg:rendermime: - - packages/rendermime/**/* - - packages/rendermime/* - - packages/rendermime-interfaces/**/* - - packages/rendermime-interfaces/* - - packages/rendermime-extension/**/* - - packages/rendermime-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/rendermime/**/* + - packages/rendermime/* + - packages/rendermime-interfaces/**/* + - packages/rendermime-interfaces/* + - packages/rendermime-extension/**/* + - packages/rendermime-extension/* pkg:running: - - packages/running/**/* - - packages/running/* - - packages/running-extension/**/* - - packages/running-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/running/**/* + - packages/running/* + - packages/running-extension/**/* + - packages/running-extension/* pkg:services: - - packages/services/**/* - - packages/services/* +- changed-files: + - any-glob-to-any-file: + - packages/services/**/* + - packages/services/* pkg:settingeditor: - - packages/settingeditor/**/* - - packages/settingeditor/* - - packages/settingeditor/**/* - - packages/settingeditor/* +- changed-files: + - any-glob-to-any-file: + - packages/settingeditor/**/* + - packages/settingeditor/* + - packages/settingeditor/**/* + - packages/settingeditor/* pkg:settingregistry: - - packages/settingregistry/**/* - - packages/settingregistry/* +- changed-files: + - any-glob-to-any-file: + - packages/settingregistry/**/* + - packages/settingregistry/* pkg:shortcuts: - - packages/shortcuts-extension/**/* - - packages/shortcuts-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/shortcuts-extension/**/* + - packages/shortcuts-extension/* pkg:statedb: - - packages/statedb/**/* - - packages/statedb/* +- changed-files: + - any-glob-to-any-file: + - packages/statedb/**/* + - packages/statedb/* pkg:statusbar: - - packages/statusbar/**/* - - packages/statusbar/* - - packages/statusbar-extension/**/* - - packages/statusbar-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/statusbar/**/* + - packages/statusbar/* + - packages/statusbar-extension/**/* + - packages/statusbar-extension/* pkg:terminal: - - packages/terminal/**/* - - packages/terminal/* - - packages/terminal-extension/**/* - - packages/terminal-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/terminal/**/* + - packages/terminal/* + - packages/terminal-extension/**/* + - packages/terminal-extension/* pkg:themes: - - packages/theme-dark-extension/**/* - - packages/theme-dark-extension/* - - packages/theme-light-extension/**/* - - packages/theme-light-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/theme-dark-extension/**/* + - packages/theme-dark-extension/* + - packages/theme-light-extension/**/* + - packages/theme-light-extension/* pkg:toc: - - packages/toc/**/* - - packages/toc/* - - packages/toc-extension/**/* - - packages/toc-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/toc/**/* + - packages/toc/* + - packages/toc-extension/**/* + - packages/toc-extension/* pkg:tooltip: - - packages/tooltip/**/* - - packages/tooltip/* - - packages/tooltip-extension/**/* - - packages/tooltip-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/tooltip/**/* + - packages/tooltip/* + - packages/tooltip-extension/**/* + - packages/tooltip-extension/* pkg:translation: - - packages/translation/**/* - - packages/translation/* - - packages/translation-extension/**/* - - packages/translation-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/translation/**/* + - packages/translation/* + - packages/translation-extension/**/* + - packages/translation-extension/* pkg:ui-components: - - packages/ui-components/**/* - - packages/ui-components/* - - packages/ui-components-extension/**/* - - packages/ui-components-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/ui-components/**/* + - packages/ui-components/* + - packages/ui-components-extension/**/* + - packages/ui-components-extension/* pkg:vega: - - packages/vega5-extension/**/* - - packages/vega5-extension/* +- changed-files: + - any-glob-to-any-file: + - packages/vega5-extension/**/* + - packages/vega5-extension/* diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9f3671a8ce8d..98dca2f648b8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,7 +2,7 @@ Thanks for contributing to JupyterLab! Please fill out the following items to submit a pull request. See the contributing guidelines for more information: -https://github.com/jupyterlab/jupyterlab/blob/main/CONTRIBUTING.md +https://github.com/jupyterlab/jupyterlab/blob/4.1.x/CONTRIBUTING.md --> ## References diff --git a/.github/workflows/answered.yml b/.github/workflows/answered.yml index 99326d98194b..bbfde12ee17d 100644 --- a/.github/workflows/answered.yml +++ b/.github/workflows/answered.yml @@ -14,7 +14,7 @@ jobs: stale: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: days-before-pr-stale: -1 days-before-pr-close: -1 diff --git a/.github/workflows/auto_author_assign.yml b/.github/workflows/auto_author_assign.yml index 9a0d281b706d..d470e28c8238 100644 --- a/.github/workflows/auto_author_assign.yml +++ b/.github/workflows/auto_author_assign.yml @@ -12,4 +12,4 @@ jobs: assign-author: runs-on: ubuntu-latest steps: - - uses: toshimaru/auto-author-assign@v2.0.1 + - uses: toshimaru/auto-author-assign@v2.1.0 diff --git a/.github/workflows/benchmark-report.yml b/.github/workflows/benchmark-report.yml index 01319563276c..d55b5686e10c 100644 --- a/.github/workflows/benchmark-report.yml +++ b/.github/workflows/benchmark-report.yml @@ -26,7 +26,7 @@ jobs: if: github.event.workflow_run.conclusion == 'success' || github.event.workflow_run.conclusion == 'failure' steps: - name: 'Download artifact' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | var artifacts = await github.rest.actions.listWorkflowRunArtifacts({ @@ -48,7 +48,7 @@ jobs: - run: unzip benchmark-assets.zip - name: 'Comment on PR' - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml index bee96c204ea5..916819bbeac7 100644 --- a/.github/workflows/benchmark.yml +++ b/.github/workflows/benchmark.yml @@ -1,14 +1,13 @@ name: Benchmark Tests on: - # schedule: - # - cron: '12 1 * * 0' - pull_request_review: + issue_comment: + types: [created, edited] jobs: test: name: Execute benchmark tests - if: github.event_name == 'schedule' || (github.event_name == 'pull_request_review' && (github.event.review.state == 'approved' || contains(github.event.review.body, 'please run benchmark'))) + if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, 'please run benchmarks') }} runs-on: ubuntu-22.04 @@ -30,7 +29,7 @@ jobs: - name: Get hashes for PR review event if: ${{ github.event_name == 'pull_request_review' }} - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const child_process = require("child_process"); @@ -85,10 +84,7 @@ jobs: working-directory: galata - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1 - with: - resource: http-get://localhost:8888/lab - timeout: 360000 + run: npx wait-on@7.2.0 http-get://localhost:8888/lab -t 360000 - name: Execute benchmark tests continue-on-error: true @@ -129,10 +125,7 @@ jobs: jlpm run build - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1 - with: - resource: http-get://localhost:8888/lab - timeout: 360000 + run: npx wait-on@7.2.0 http-get://localhost:8888/lab -t 360000 - name: Execute benchmark tests continue-on-error: true @@ -190,7 +183,7 @@ jobs: - name: Upload Galata Test assets if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: benchmark-assets path: | @@ -216,7 +209,7 @@ jobs: - name: Get hashes for PR review event if: ${{ github.event_name == 'pull_request_review' }} - uses: actions/github-script@v6 + uses: actions/github-script@v7 with: script: | const child_process = require("child_process"); diff --git a/.github/workflows/check-release.yml b/.github/workflows/check-release.yml index cb82187d1e87..4528a6f2e086 100644 --- a/.github/workflows/check-release.yml +++ b/.github/workflows/check-release.yml @@ -2,9 +2,9 @@ name: Check Release on: push: - branches: [main] + branches: [4.1.x] pull_request: - branches: [main] + branches: [4.1.x] release: types: [published] @@ -26,7 +26,7 @@ jobs: version_spec: next - name: Upload Assets - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jupyterlab-releaser-dist-${{ github.run_number }} path: | diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index eb60596ea2f2..f1103c6669b0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -7,10 +7,10 @@ name: "CodeQL" on: push: - branches: [main] + branches: [4.1.x] pull_request: # The branches below must be a subset of the branches above - branches: [main] + branches: [4.1.x] schedule: - cron: '0 8 * * 3' @@ -42,7 +42,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} config-file: ./.github/codeql/codeql-config.yml @@ -55,7 +55,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v2 + uses: github/codeql-action/autobuild@v3 # ℹī¸ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -69,4 +69,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index 4686280468cf..3b1728416929 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -3,10 +3,15 @@ name: Docker Tests on: schedule: - cron: '0 0 * * *' + push: + branches: [4.1.x] + pull_request: + branches: [4.1.x] jobs: docker: name: Docker Dev Container + if: ${{ github.event_name == 'schedule' }} || contains( github.event.pull_request.title, '[docker]') runs-on: ubuntu-22.04 steps: - name: Checkout @@ -22,7 +27,4 @@ jobs: bash ./docker/start.sh dev-detach - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1 - with: - resource: http-get://localhost:8888/ - timeout: 360000 + run: npx wait-on@7.2.0 http-get://localhost:8888/lab -t 360000 diff --git a/.github/workflows/galata-update.yml b/.github/workflows/galata-update.yml index 1c8b5afbbe83..087b4a657a4c 100644 --- a/.github/workflows/galata-update.yml +++ b/.github/workflows/galata-update.yml @@ -51,6 +51,7 @@ jobs: test_folder: galata artifact_name: updated-galata-snapshots report_name: update-galata-report + npm_client: jlpm - name: Comment back on the PR run: | @@ -132,6 +133,7 @@ jobs: update_script: test:doc:update artifact_name: updated-documentation-snapshots report_name: update-documentation-report + npm_client: jlpm - name: Comment back on the PR run: | diff --git a/.github/workflows/galata.yml b/.github/workflows/galata.yml index 69b7223d8312..fcf28f674dc3 100644 --- a/.github/workflows/galata.yml +++ b/.github/workflows/galata.yml @@ -25,7 +25,7 @@ jobs: uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Set up browser cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ${{ github.workspace }}/pw-browsers @@ -50,10 +50,7 @@ jobs: jlpm run build - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1 - with: - resource: http-get://localhost:8888/lab - timeout: 360000 + run: npx wait-on@7.2.0 http-get://localhost:8888/lab -t 360000 - name: Test run: | @@ -65,7 +62,7 @@ jobs: - name: Upload Galata Test assets if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jupyterlab-galata-test-assets path: | @@ -74,7 +71,7 @@ jobs: - name: Upload Galata Test report if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jupyterlab-galata-report path: | @@ -119,7 +116,7 @@ jobs: uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Set up browser cache - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: | ${{ github.workspace }}/pw-browsers @@ -150,7 +147,7 @@ jobs: run: | set -ex cd galata - (jupyter lab --config jupyter_server_test_config.py --extensions-in-dev-mode > /tmp/jupyterlab_server.log 2>&1) & + (jupyter lab --config jupyter_server_test_config.py --extensions-in-dev-mode --custom-css > /tmp/jupyterlab_server.log 2>&1) & working-directory: core - name: Install browser @@ -163,10 +160,7 @@ jobs: working-directory: core - name: Wait for JupyterLab - uses: ifaxity/wait-on-action@v1 - with: - resource: http-get://localhost:8888/lab - timeout: 360000 + run: npx wait-on@7.2.0 http-get://localhost:8888/lab -t 360000 - name: Test run: | @@ -176,7 +170,7 @@ jobs: - name: Upload Galata Test assets if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jupyterlab-documentation-test-assets path: | @@ -184,7 +178,7 @@ jobs: - name: Upload Galata Test report if: always() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jupyterlab-documentation-report path: | diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml index 0e28ad5c6e1b..e8e331e528cd 100644 --- a/.github/workflows/labeler.yml +++ b/.github/workflows/labeler.yml @@ -11,6 +11,6 @@ jobs: name: Update PR Labels runs-on: ubuntu-latest steps: - - uses: actions/labeler@main + - uses: actions/labeler@v5 with: repo-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/license-header.yml b/.github/workflows/license-header.yml index 694dac6e132b..84fb34ecd04d 100644 --- a/.github/workflows/license-header.yml +++ b/.github/workflows/license-header.yml @@ -27,7 +27,7 @@ jobs: - name: Fix License Header # pin to include https://github.com/apache/skywalking-eyes/pull/168 - uses: apache/skywalking-eyes/header@e19b828cea6a6027cceae78f05d81317347d21be + uses: apache/skywalking-eyes/header@ed436a5593c63a25f394ea29da61b0ac3731a9fe with: mode: fix diff --git a/.github/workflows/linuxjs-tests.yml b/.github/workflows/linuxjs-tests.yml index 683a98185d33..2f4d0d8f94a6 100644 --- a/.github/workflows/linuxjs-tests.yml +++ b/.github/workflows/linuxjs-tests.yml @@ -2,9 +2,9 @@ name: Linux JS Tests on: push: - branches: [main] + branches: [4.1.x] pull_request: - branches: [main] + branches: [4.1.x] release: types: [published] @@ -40,6 +40,7 @@ jobs: js-logconsole, js-lsp, js-mainmenu, + js-mermaid, js-metadataform, js-metapackage, js-nbformat, @@ -51,6 +52,7 @@ jobs: js-services, js-settingeditor, js-settingregistry, + js-shortcuts-extension, js-statedb, js-statusbar, js-testing, diff --git a/.github/workflows/linuxtests.yml b/.github/workflows/linuxtests.yml index 127d3d701316..1e76368ad1f0 100644 --- a/.github/workflows/linuxtests.yml +++ b/.github/workflows/linuxtests.yml @@ -2,9 +2,9 @@ name: Linux Tests on: push: - branches: [main] + branches: [4.1.x] pull_request: - branches: [main] + branches: [4.1.x] release: types: [published] @@ -72,7 +72,7 @@ jobs: - name: Upload ${{ matrix.group }} results if: ${{ matrix.upload-output && always() }} - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ${{ matrix.group }} ${{ github.run_number }} path: | @@ -89,8 +89,7 @@ jobs: uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 with: python_version: "3.8" - - name: Install minimum versions - uses: jupyterlab/maintainer-tools/.github/actions/install-minimums@v1 + dependency_type: minimum - name: Install dependencies run: | bash ./scripts/ci_install.sh @@ -112,7 +111,7 @@ jobs: run: | pip install build python -m build --sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: "sdist" path: dist/*.tar.gz @@ -126,7 +125,7 @@ jobs: - name: Base Setup uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 - name: Download sdist - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 - name: Install From SDist run: | set -ex @@ -154,4 +153,4 @@ jobs: - uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1 with: ignore_glob: "docs/api packages/ui-components/docs/source/ui_components.rst images" - ignore_links: ".*/images/[\\w-]+.png https://docs.github.com/en/.* https://jupyterlab.github.io https://mybinder.org/v2/gh/jupyterlab/.*" + ignore_links: ".*/images/[\\w-]+.png https://docs.github.com/en/.* https://jupyterlab.github.io https://mybinder.org/v2/gh/jupyterlab/.* https://github.com/[^/]+/?$" diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index e84180046f75..0b7aa4d562d6 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -14,7 +14,7 @@ jobs: lock: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@v4 + - uses: dessant/lock-threads@v5 with: github-token: ${{ github.token }} issue-lock-inactive-days: '180' diff --git a/.github/workflows/macostests.yml b/.github/workflows/macostests.yml index a3c3bff3c8b9..40bf2514e132 100644 --- a/.github/workflows/macostests.yml +++ b/.github/workflows/macostests.yml @@ -2,9 +2,9 @@ name: macOS Tests on: push: - branches: [main] + branches: [4.1.x] pull_request: - branches: [main] + branches: [4.1.x] release: types: [published] diff --git a/.github/workflows/prep-release.yml b/.github/workflows/prep-release.yml index 7a2a18de7570..396330bb9729 100644 --- a/.github/workflows/prep-release.yml +++ b/.github/workflows/prep-release.yml @@ -12,6 +12,10 @@ on: post_version_spec: description: "Post Version Specifier" required: false + silent: + description: "Set a placeholder in the changelog and don't publish the release." + required: false + type: boolean since: description: "Use PRs with activity since this date or git reference" required: false @@ -22,6 +26,8 @@ on: jobs: prep_release: runs-on: ubuntu-latest + permissions: + contents: write steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 @@ -29,8 +35,9 @@ jobs: id: prep-release uses: jupyter-server/jupyter_releaser/.github/actions/prep-release@v2 with: - token: ${{ secrets.ADMIN_GITHUB_TOKEN }} + token: ${{ secrets.GITHUB_TOKEN }} version_spec: ${{ github.event.inputs.version_spec }} + silent: ${{ github.event.inputs.silent }} post_version_spec: ${{ github.event.inputs.post_version_spec }} target: ${{ github.event.inputs.target }} branch: ${{ github.event.inputs.branch }} diff --git a/.github/workflows/publish-changelog.yml b/.github/workflows/publish-changelog.yml new file mode 100644 index 000000000000..60af4c5f1674 --- /dev/null +++ b/.github/workflows/publish-changelog.yml @@ -0,0 +1,34 @@ +name: "Publish Changelog" +on: + release: + types: [published] + + workflow_dispatch: + inputs: + branch: + description: "The branch to target" + required: false + +jobs: + publish_changelog: + runs-on: ubuntu-latest + environment: release + steps: + - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + + - name: Publish changelog + id: publish-changelog + uses: jupyter-server/jupyter_releaser/.github/actions/publish-changelog@v2 + with: + token: ${{ steps.app-token.outputs.token }} + branch: ${{ github.event.inputs.branch }} + + - name: "** Next Step **" + run: | + echo "Merge the changelog update PR: ${{ steps.publish-changelog.outputs.pr_url }}" diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index dbaaeaad243b..c1881060de28 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -15,15 +15,23 @@ on: jobs: publish_release: runs-on: ubuntu-latest + environment: release + permissions: + id-token: write steps: - uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1 + - uses: actions/create-github-app-token@v1 + id: app-token + with: + app-id: ${{ vars.APP_ID }} + private-key: ${{ secrets.APP_PRIVATE_KEY }} + - name: Populate Release id: populate-release uses: jupyter-server/jupyter_releaser/.github/actions/populate-release@v2 with: - token: ${{ secrets.ADMIN_GITHUB_TOKEN }} - target: ${{ github.event.inputs.target }} + token: ${{ steps.app-token.outputs.token }} branch: ${{ github.event.inputs.branch }} release_url: ${{ github.event.inputs.release_url }} steps_to_skip: ${{ github.event.inputs.steps_to_skip }} @@ -31,14 +39,10 @@ jobs: - name: Finalize Release id: finalize-release env: - PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - PYPI_TOKEN_MAP: ${{ secrets.PYPI_TOKEN_MAP }} - TWINE_USERNAME: __token__ NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - uses: jupyter-server/jupyter-releaser/.github/actions/finalize-release@v2 + uses: jupyter-server/jupyter_releaser/.github/actions/finalize-release@v2 with: - token: ${{ secrets.ADMIN_GITHUB_TOKEN }} - target: ${{ github.event.inputs.target }} + token: ${{ steps.app-token.outputs.token }} release_url: ${{ steps.populate-release.outputs.release_url }} - name: "** Next Step **" diff --git a/.github/workflows/reject-staging-changes.yml b/.github/workflows/reject-staging-changes.yml index 84c0a7ba21f7..bbff94ccc2d9 100644 --- a/.github/workflows/reject-staging-changes.yml +++ b/.github/workflows/reject-staging-changes.yml @@ -16,7 +16,7 @@ jobs: - name: Get modified files in the staging directory id: modified-files-in-staging - uses: tj-actions/changed-files@v39.2.0 + uses: tj-actions/changed-files@v42.0.2 with: # only checks for modified files in this directory files: jupyterlab/staging diff --git a/.github/workflows/windowstests.yml b/.github/workflows/windowstests.yml index e9142e7fa527..49a1edfafcea 100644 --- a/.github/workflows/windowstests.yml +++ b/.github/workflows/windowstests.yml @@ -2,9 +2,9 @@ name: Windows Tests on: push: - branches: [main] + branches: [4.1.x] pull_request: - branches: [main] + branches: [4.1.x] release: types: [published] diff --git a/.licenserc.yaml b/.licenserc.yaml index 99e5c5372444..f686c878f827 100644 --- a/.licenserc.yaml +++ b/.licenserc.yaml @@ -32,7 +32,7 @@ header: - 'dev_mode/style.js' - 'examples/federated/example.cert' - 'galata/test/jupyterlab/notebooks/' - - 'galata/test/*/*-snapshots/*.txt' + - 'galata/test/*/*/*.txt' - 'jupyterlab.desktop' - 'jupyterlab/staging' - 'packages/codemirror/test/foo.grammar' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec91b8935748..a7905f0f12ff 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -27,21 +27,17 @@ repos: exclude: (.bumpversion.cfg|yarn.js) - repo: https://github.com/python-jsonschema/check-jsonschema - rev: 0.27.1 + rev: 0.27.4 hooks: - id: check-github-workflows - - repo: https://github.com/psf/black - rev: 23.10.1 - hooks: - - id: black - # Check ruff version is aligned with the one in pyproject.toml - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.1.4 + rev: v0.2.0 hooks: - id: ruff args: ["--fix"] + - id: ruff-format - repo: local hooks: @@ -50,6 +46,7 @@ repos: entry: 'npm run prettier:files' language: node types_or: [json, ts, tsx, javascript, jsx, css] + exclude: \.ipynb$ - id: eslint name: eslint entry: 'npm run eslint:files' diff --git a/.yarnrc.yml b/.yarnrc.yml index 31b332371383..d1027ee74005 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -6,23 +6,20 @@ enableTelemetry: false httpTimeout: 60000 -nodeLinker: node-modules - -npmRegistryServer: "https://registry.yarnpkg.com" - -yarnPath: ./jupyterlab/staging/yarn.js - -# these messages provide no actionable information, and make non-TTY output -# almost unreadable, masking real dependency-related information -# see: https://yarnpkg.com/advanced/error-codes logFilters: - - code: YN0006 # SOFT_LINK_BUILD + - code: YN0006 level: discard - - code: YN0007 # MUST_BUILD + - code: YN0007 level: discard - - code: YN0008 # MUST_REBUILD + - code: YN0008 level: discard - - code: YN0013 # FETCH_NOT_CACHED + - code: YN0013 level: discard - - code: YN0019 # UNUSED_CACHE_ENTRY + - code: YN0019 level: discard + +nodeLinker: node-modules + +npmRegistryServer: "https://registry.yarnpkg.com" + +yarnPath: ./jupyterlab/staging/yarn.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 320516b63f8c..03b585900c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,164 @@ ## v4.1 -### 4.1.0 - Highlights +JupyterLab 4.1 includes a number of new features (described below), bug fixes, and enhancements for extension developers. This release is compatible with extensions supporting JupyterLab 4.0. Extension authors are recommended to consult the [Extension Migration Guide](https://jupyterlab.readthedocs.io/en/stable/extension/extension_migration.html#jupyterlab-4-0-to-4-1) which lists deprecations and changes to the public API. -#### Moved plugins +### Custom CSS + +JupyterLab now supports automatic loading of custom CSS. +Themes are the recommended way for customizing the JupyterLab look and feel, +while custom CSS is intended for minor personal adjustments. + +To opt in, start JupyterLab with the `--custom-css` flag. +The location of the `custom.css` file is documented in the section on [customizing the user interface](https://jupyterlab.readthedocs.io/en/stable/user/interface_customization.html#custom-css). + +```{note} +`custom.css` is also available in Jupyter Notebook; +while similar selectors can be used for components shared between JupyterLab 4.1 and Jupyter Notebook 7.0, +there was a different set of selectors in Notebook 6 and older versions. +Users with the custom CSS file using the selectors from legacy Notebook versions +will need to update them and note that tutorials may refer to the selectors for the old Notebook versions. +``` + +### Diagrams in Markdown + +Matching GitHub-Flavoured Markdown, JupyterLab 4.1 now supports [Mermaid](https://github.com/mermaid-js/mermaid) diagrams. +To create a mermaid diagram use the `mermaid` language specifier for a code block in a markdown cell or document, for example: + +~~~ +```mermaid +flowchart LR + +A[Hard] -->|Text| B(Round) +B --> C{Decision} +C -->|One| D[Result 1] +C -->|Two| E[Result 2] +``` +~~~ + +which renders as: + + + +### Inline completer + +JupyterLab now supports completion presented as ghost text in the cell and file editors, +allowing generative AI models to provide multi-line completions. +The suggestions are provided by plugins implementing the ``IInlineCompletionProvider`` API; +by default a single provider which uses kernel history is available. + + + +The suggestions can be invoked as-you-type or manually using a configurable shortcut (by default Alt + \\). +The default keyboard shortcuts are displayed in the small widget shown when hovering over the ghost suggestion: +- Alt + End - accept suggestion +- Alt + [ - previous suggestion +- Alt + ] - next suggestion + +To enable the inline suggestions based on the kernel history, go to Settings → Inline Completer → History provider → check the "enabled" checkbox. + +In addition to the built-in history suggestions, +the [`jupyter-ai`](https://github.com/jupyterlab/jupyter-ai) extension can provide +suggestions from supported models. +The `jupyter-ai` integration with inline completer is available starting with the +[v2.10.0](https://github.com/jupyterlab/jupyter-ai/releases/tag/v2.10.0) release. + +The Inline Completer API is still considered experimental and may be subject to changes, please share feedback! + +### Keyboard navigation improvements + +Numerous improvements to keyboard navigation with focus on accessibility and usability are included in this release: +- the notebook cells now retain focus +- the focus can now be moved beyond the active notebook +- the toolbars can now be navigated using arrow keys + +For more details, see [this post on the Jupyter Blog](https://blog.jupyter.org/recent-keyboard-navigation-improvements-in-jupyter-4df32f97628d). + +### Execution history in notebook + +The code from previously executed cells can be used to populate empty cells, +allowing to iterate on code from previous cells or even previous sessions +(depending on how a specific kernel stores history). + +To cycle between history items, press Alt + Arrow Up and Alt + Arrow Down. + +To enable execution history, go to Settings → Notebook → check the "Kernel history access" checkbox. + +This feature was already available in the console in previous releases; it only works with kernels supporting execution history requests. +To clear the execution history, consult the documentation of the kernel you are using (e.g., IPython/ipykernel). + +### Opening files from tracebacks + +Paths to code files detected in tracebacks returned by kernels on execution error are now turned into links. +These links will open the corresponding file for editing, if it is in the Jupyter root directory, +or they will open a read-only preview if the file is outside of the root directory and the active kernel supports the debugger. + + + +### Error indicator in the table of contents + +When a cell fails during execution, an error indicator will be displayed by the corresponding heading, +increasing awareness of the notebook state and enabling users to quickly navigate to the cell which requires attention. + + + +### Plugin Manager + +Individual plugins can now be disabled or enabled from a new Plugin Manager user interface. +Each extension is composed of one or more plugins, and plugins form the basis of JupyterLab itself, +thus the plugin manager enables more extensive customization of the JupyterLab experience. + + + +This feature is intended for advanced users and is documented in depth in the [documentation](https://jupyterlab.readthedocs.io/en/stable/user/extensions.html#managing-plugins-with-plugin-manager). + +Administrators may want to [lock specific plugins](https://jupyterlab.readthedocs.io/en/stable/user/extensions.html#locking-and-unlocking-plugins) if they are required for any reason; this will prevent users from disabling the plugins via Plugin Manager and remote API calls. The Plugin Manager itself can be [disabled using the CLI](https://jupyterlab.readthedocs.io/en/stable/user/extensions.html#enabling-and-disabling-extensions). + +### Virtual scrollbar for notebook in windowed mode + +The windowed notebook received an optional scrollbar delineating the active cell and selected cells. +Users can jump to a specific cell. + + + +To enable the virtual scrollbar, go to Settings → Notebook → Windowing mode, choose "full", and click on the hamburger icon (≡) which appears in the notebook's toolbar. + +Virtual scrollbar is considered experimental, please share feedback! + +### Notifications + +JupyterLab 3.6 added a notification center which so far was only used for announcements and version update notifications (both opt-in). +JupyterLab 4.1 adds two notifications to guide users in potentially confusing situations: +- when a user attempts to save a read-only document, a transient notification suggesting using "save as" is displayed +- when a user attempts to execute a cell before a slow-starting kernel has initialized, a notification is shown to indicate that the cell cannot be yet executed (this is opt-in and needs to be enabled in settings) + +### Full notebook windowing mode improvements + +Notebooks in the `full` windowing mode only render the visible cells, significantly improving the performance of the application. +Numerous improvements for the full windowing mode behaviour (such as scrolling, search, rendering, and navigation) are included in this release (see the list of issues in [#15258](https://github.com/jupyterlab/jupyterlab/issues/15258) for details). + +```{note} +The windowing mode is still experimental and known issues remain to be solved +([#15415](https://github.com/jupyterlab/jupyterlab/issues/15415), [#15465](https://github.com/jupyterlab/jupyterlab/issues/15465), [#15594](https://github.com/jupyterlab/jupyterlab/issues/15594)). +In addition, a sporadic regression in cell ordering ([#15610](https://github.com/jupyterlab/jupyterlab/issues/15610)) was observed in 4.1 beta, +and remains to be fixed, pending reports from users willing to test the windowing mode in JupyterLab 4.1 to help create reproducible steps that would enable fixing this issue. + +Users who already enabled this mode in previous versions are advised to evaluate the benefits of fixes included in 4.1 against regressions linked above before deciding to upgrade. +``` + +### Search improvements +- The search box will now grow automatically to accommodate longer text +- Search in selection can now be toggled using Alt + L and automatic search in selection can be configured in settings +- Tooltips with shortcuts were added to the buttons in the search box to improve discoverability of the shortcuts + +### Miscellaneous +- The current theme (dark/light) can now be synced with the browser/system preference (Settings menu → Theme → Synchronise with System Settings) +- A blue "read-only" status indicator is now displayed in the toolbar of documents which cannot be saved because their model is read-only. +- Native support for viewing jsonl/ndjson files was added +- Collapsing of breadcrumbs in the File Browser can be disabled in File Browser settings +- Extension manager can now use a HTTP proxy for fetching extensions + +### Moved plugins Some internal JupyterLab plugins have been re-organized to allow for better flexibility for deployments and downstream applications like Notebook 7. This might affect users that disable specific plugins with the `jupyter labextension disable` command or the `disabledExtensions` config option. @@ -31,7 +186,7 @@ Developers can now provide editor extensions, like themes and programming langua #### New extension manager Starting with JupyterLab 3, extensions can be installed via Python packages -(or other providers of [prebuilt extensions](https://jupyterlab.readthedocs.io/en/latest/extension/extension_dev.html#prebuilt-extensions)). +(or other providers of [prebuilt extensions](https://jupyterlab.readthedocs.io/en/stable/extension/extension_dev.html#prebuilt-extensions)). In JupyterLab 4, building on this feature, the Extension Manager now includes extensions from [pypi.org](https://pypi.org/search/?c=Framework+%3A%3A+Jupyter+%3A%3A+JupyterLab). This removes the build step from installation of extension when using Extension Manager. @@ -105,12 +260,914 @@ Here are the main tool updates that will benefit extension authors and developer We recommend using Node.js v18 or newer, because older versions will reach end of life in 2023 or earlier (see [Node release schedule](https://github.com/nodejs/release#release-schedule)). -To ease code migration to JupyterLab 4, developers should review the [migration guide](https://jupyterlab.readthedocs.io/en/latest/extension/extension_migration.html). A few existing extensions have already been migrated and can be used as examples: +To ease code migration to JupyterLab 4, developers should review the [migration guide](https://jupyterlab.readthedocs.io/en/stable/extension/extension_migration.html). A few existing extensions have already been migrated and can be used as examples: - the [JupyterLab Extensions by Examples](https://github.com/jupyterlab/extension-examples/pull/232) - the [Jupyter MIME type renderers](https://github.com/jupyterlab/jupyter-renderers/pull/296) +## 4.1.6 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.5...5edd1a2f71250022b1f2660235fe41b755d4cc8a)) + +### Bugs fixed + +- Fix outputarea collapse expand [#16124](https://github.com/jupyterlab/jupyterlab/pull/16124) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Disable placeholder for password input [#16128](https://github.com/jupyterlab/jupyterlab/pull/16128) ([@Alanhou1222](https://github.com/Alanhou1222)) +- Fix for existing shortcuts getting triggered while edit shortcut [#16126](https://github.com/jupyterlab/jupyterlab/pull/16126) ([@Susilkessav](https://github.com/Susilkessav)) +- Use `smart` scroll in debugger to minimize distraction [#16084](https://github.com/jupyterlab/jupyterlab/pull/16084) ([@krassowski](https://github.com/krassowski)) +- Store the real position of the item in reactive toolbar [#16111](https://github.com/jupyterlab/jupyterlab/pull/16111) ([@brichet](https://github.com/brichet)) +- Fix extension installation on Windows [#16064](https://github.com/jupyterlab/jupyterlab/pull/16064) ([@fcollonval](https://github.com/fcollonval)) +- Removes dotted outline from active code cell [#16070](https://github.com/jupyterlab/jupyterlab/pull/16070) ([@JasonWeill](https://github.com/JasonWeill)) +- Long items should not wrap [#15844](https://github.com/jupyterlab/jupyterlab/pull/15844) ([@mdietz94](https://github.com/mdietz94)) +- Fix manager isDisposed is not set [#15997](https://github.com/jupyterlab/jupyterlab/pull/15997) ([@fcollonval](https://github.com/fcollonval)) + +### Maintenance and upkeep improvements + +- Bump semver from 5.7.1 to 7.6.0 [#16121](https://github.com/jupyterlab/jupyterlab/pull/16121) ([@dependabot\[bot\]](https://github.com/apps/dependabot)) +- Revert traitlets pin [#16118](https://github.com/jupyterlab/jupyterlab/pull/16118) ([@krassowski](https://github.com/krassowski)) +- Use `dependency_type: minimum` for Minimum Versions check [#16105](https://github.com/jupyterlab/jupyterlab/pull/16105) ([@krassowski](https://github.com/krassowski)) +- Fix migration script, use extras for its dependencies [#16088](https://github.com/jupyterlab/jupyterlab/pull/16088) ([@krassowski](https://github.com/krassowski)) +- Add devcontainer [#15909](https://github.com/jupyterlab/jupyterlab/pull/15909) ([@fcollonval](https://github.com/fcollonval)) +- Update Release Scripts [#15973](https://github.com/jupyterlab/jupyterlab/pull/15973) ([@blink1073](https://github.com/blink1073)) +- Adjust search test assertion to allow both Node 18 and 20+ [#16024](https://github.com/jupyterlab/jupyterlab/pull/16024) ([@krassowski](https://github.com/krassowski)) + +### Documentation improvements + +- Fix migration script, use extras for its dependencies [#16088](https://github.com/jupyterlab/jupyterlab/pull/16088) ([@krassowski](https://github.com/krassowski)) +- Fix missing backtick in plugin manager docs [#16083](https://github.com/jupyterlab/jupyterlab/pull/16083) ([@krassowski](https://github.com/krassowski)) +- Add devcontainer [#15909](https://github.com/jupyterlab/jupyterlab/pull/15909) ([@fcollonval](https://github.com/fcollonval)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-03-14&to=2024-04-08&type=c)) + +[@afshin](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Aafshin+updated%3A2024-03-14..2024-04-08&type=Issues) | [@brichet](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Abrichet+updated%3A2024-03-14..2024-04-08&type=Issues) | [@fcollonval](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Afcollonval+updated%3A2024-03-14..2024-04-08&type=Issues) | [@gabalafou](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agabalafou+updated%3A2024-03-14..2024-04-08&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agithub-actions+updated%3A2024-03-14..2024-04-08&type=Issues) | [@JasonWeill](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AJasonWeill+updated%3A2024-03-14..2024-04-08&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajtpio+updated%3A2024-03-14..2024-04-08&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-03-14..2024-04-08&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-03-14..2024-04-08&type=Issues) | [@lumberbot-app](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alumberbot-app+updated%3A2024-03-14..2024-04-08&type=Issues) | [@meeseeksmachine](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ameeseeksmachine+updated%3A2024-03-14..2024-04-08&type=Issues) | [@Mehak261124](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AMehak261124+updated%3A2024-03-14..2024-04-08&type=Issues) | [@RRosio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3ARRosio+updated%3A2024-03-14..2024-04-08&type=Issues) | [@trungleduc](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Atrungleduc+updated%3A2024-03-14..2024-04-08&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Awelcome+updated%3A2024-03-14..2024-04-08&type=Issues) + + + +## 4.1.5 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.4...a5fa0aa9ba3b561f116d9b4d2e9bf775f95b67a1)) + +### Bugs fixed + +- Fix Theme color is not applied to Toolbar Button [#15957](https://github.com/jupyterlab/jupyterlab/pull/15957) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Uses the browser window's selection as the default search query [#15834](https://github.com/jupyterlab/jupyterlab/pull/15834) ([@JasonWeill](https://github.com/JasonWeill)) +- Show outline on the full item in file browser, only when needed [#15860](https://github.com/jupyterlab/jupyterlab/pull/15860) ([@krassowski](https://github.com/krassowski)) +- Short-circuit `selectItemByName()` if already selected [#15970](https://github.com/jupyterlab/jupyterlab/pull/15970) ([@krassowski](https://github.com/krassowski)) +- Fix browser-test.js [#15892](https://github.com/jupyterlab/jupyterlab/pull/15892) ([@fcollonval](https://github.com/fcollonval)) +- Avoid concurrency when computing the items in notebook toolbar [#15954](https://github.com/jupyterlab/jupyterlab/pull/15954) ([@brichet](https://github.com/brichet)) +- Fixes filter for Chinese, other non-ASCII filenames [#15935](https://github.com/jupyterlab/jupyterlab/pull/15935) ([@JasonWeill](https://github.com/JasonWeill)) + +### Maintenance and upkeep improvements + +- Ignore links to GitHub user and organisation profiles [#15959](https://github.com/jupyterlab/jupyterlab/pull/15959) ([@krassowski](https://github.com/krassowski)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-03-07&to=2024-03-14&type=c)) + +[@andrii-i](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Aandrii-i+updated%3A2024-03-07..2024-03-14&type=Issues) | [@brichet](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Abrichet+updated%3A2024-03-07..2024-03-14&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajtpio+updated%3A2024-03-07..2024-03-14&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-03-07..2024-03-14&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-03-07..2024-03-14&type=Issues) | [@linlol](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alinlol+updated%3A2024-03-07..2024-03-14&type=Issues) | [@meeseeksmachine](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ameeseeksmachine+updated%3A2024-03-07..2024-03-14&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Awelcome+updated%3A2024-03-07..2024-03-14&type=Issues) + +## 4.1.4 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.3...3eab4adc3053485cacfefc02dd5e8bc6fb256442)) + +### Bugs fixed + +- Fix creating files in custom drives, fix `ContentsManagerMock` [#15291](https://github.com/jupyterlab/jupyterlab/pull/15291) ([@jtpio](https://github.com/jtpio)) +- Fix Theme color is not applied to SwitchKernel ToolbarButton [#15924](https://github.com/jupyterlab/jupyterlab/pull/15924) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Revert "Prevent command shortcuts from preventing user input" [#15938](https://github.com/jupyterlab/jupyterlab/pull/15938) ([@krassowski](https://github.com/krassowski)) +- Fix spurious dedent when opening inspector tooltip [#15898](https://github.com/jupyterlab/jupyterlab/pull/15898) ([@krassowski](https://github.com/krassowski)) +- Add an explicit default for inline completer providers [#15899](https://github.com/jupyterlab/jupyterlab/pull/15899) ([@krassowski](https://github.com/krassowski)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-03-04&to=2024-03-07&type=c)) + +[@ericsnekbytes](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Aericsnekbytes+updated%3A2024-03-04..2024-03-07&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agithub-actions+updated%3A2024-03-04..2024-03-07&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajtpio+updated%3A2024-03-04..2024-03-07&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-03-04..2024-03-07&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-03-04..2024-03-07&type=Issues) | [@meeseeksmachine](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ameeseeksmachine+updated%3A2024-03-04..2024-03-07&type=Issues) + +## 4.1.3 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.2...58a6905e3b29e95d1b7ff00b0fbc5472eaee769b)) + +### Bugs fixed + +- Fix Pressing enter in console with console run keystroke set to enter creates a newline and runs [#15869](https://github.com/jupyterlab/jupyterlab/pull/15869) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Fix saving of item positions in reactive toolbar [#15843](https://github.com/jupyterlab/jupyterlab/pull/15843) ([@brichet](https://github.com/brichet)) +- Prevent command shortcuts from preventing user input [#15790](https://github.com/jupyterlab/jupyterlab/pull/15790) ([@krassowski](https://github.com/krassowski)) +- Fix missing signals in file editor adapter [#15873](https://github.com/jupyterlab/jupyterlab/pull/15873) ([@krassowski](https://github.com/krassowski)) +- Fix codemirror highlight for Python builtin [#15805](https://github.com/jupyterlab/jupyterlab/pull/15805) ([@AllanChain](https://github.com/AllanChain)) +- When attaching only typeset after rendering is completed [#15810](https://github.com/jupyterlab/jupyterlab/pull/15810) ([@krassowski](https://github.com/krassowski)) + +### Maintenance and upkeep improvements + +- Update docstrings to mention Jupyter Server API [#15880](https://github.com/jupyterlab/jupyterlab/pull/15880) ([@jtpio](https://github.com/jtpio)) +- Bump es5-ext from 0.10.62 to 0.10.63 [#15878](https://github.com/jupyterlab/jupyterlab/pull/15878) ([@dependabot\[bot\]](https://github.com/apps/dependabot)) +- Fix clean script [#15854](https://github.com/jupyterlab/jupyterlab/pull/15854) ([@krassowski](https://github.com/krassowski)) +- Update branch configuration for `4.1.x` [#15848](https://github.com/jupyterlab/jupyterlab/pull/15848) ([@krassowski](https://github.com/krassowski)) + +### Documentation improvements + +- Fix broken link [#15851](https://github.com/jupyterlab/jupyterlab/pull/15851) ([@fcollonval](https://github.com/fcollonval)) +- Update branch configuration for `4.1.x` [#15848](https://github.com/jupyterlab/jupyterlab/pull/15848) ([@krassowski](https://github.com/krassowski)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-02-19&to=2024-03-04&type=c)) + +[@AllanChain](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AAllanChain+updated%3A2024-02-19..2024-03-04&type=Issues) | [@brichet](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Abrichet+updated%3A2024-02-19..2024-03-04&type=Issues) | [@ericsnekbytes](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Aericsnekbytes+updated%3A2024-02-19..2024-03-04&type=Issues) | [@fcollonval](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Afcollonval+updated%3A2024-02-19..2024-03-04&type=Issues) | [@FoSuCloud](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AFoSuCloud+updated%3A2024-02-19..2024-03-04&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agithub-actions+updated%3A2024-02-19..2024-03-04&type=Issues) | [@JasonWeill](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AJasonWeill+updated%3A2024-02-19..2024-03-04&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajtpio+updated%3A2024-02-19..2024-03-04&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-02-19..2024-03-04&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-02-19..2024-03-04&type=Issues) | [@linlol](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alinlol+updated%3A2024-02-19..2024-03-04&type=Issues) | [@lumberbot-app](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alumberbot-app+updated%3A2024-02-19..2024-03-04&type=Issues) | [@meeseeksmachine](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ameeseeksmachine+updated%3A2024-02-19..2024-03-04&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Awelcome+updated%3A2024-02-19..2024-03-04&type=Issues) + +## 4.1.2 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.1...d835cf35dfd37bbe930c79c90a6d180a800bae69)) + +### Bugs fixed + +- Fix highlight sequencing when replacing text in code cells [#15803](https://github.com/jupyterlab/jupyterlab/pull/15803) ([@JasonWeill](https://github.com/JasonWeill)) +- Windows platforms, erratic pasting of text into Markdown field [#15794](https://github.com/jupyterlab/jupyterlab/pull/15794) ([@kiliansinger](https://github.com/kiliansinger)) +- Restore notebook scrolling on dragging a cell to the viewport edge [#15782](https://github.com/jupyterlab/jupyterlab/pull/15782) ([@krassowski](https://github.com/krassowski)) +- Fix typing in editable elements inside of open shadow DOM [#15774](https://github.com/jupyterlab/jupyterlab/pull/15774) ([@krassowski](https://github.com/krassowski)) + +### Maintenance and upkeep improvements + +- \[docker\] Allow non-unique GID [#15699](https://github.com/jupyterlab/jupyterlab/pull/15699) ([@trungleduc](https://github.com/trungleduc)) + +### Documentation improvements + +- Remove SO links, add more recent issue to FAQ [#15811](https://github.com/jupyterlab/jupyterlab/pull/15811) ([@krassowski](https://github.com/krassowski)) +- Fix outdated link to mybinder.org on index page of documentation [#15800](https://github.com/jupyterlab/jupyterlab/pull/15800) ([@nluetts](https://github.com/nluetts)) +- Fix typing in editable elements inside of open shadow DOM [#15774](https://github.com/jupyterlab/jupyterlab/pull/15774) ([@krassowski](https://github.com/krassowski)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-02-13&to=2024-02-19&type=c)) + +[@FoSuCloud](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AFoSuCloud+updated%3A2024-02-13..2024-02-19&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agithub-actions+updated%3A2024-02-13..2024-02-19&type=Issues) | [@JasonWeill](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AJasonWeill+updated%3A2024-02-13..2024-02-19&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-02-13..2024-02-19&type=Issues) | [@kiliansinger](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akiliansinger+updated%3A2024-02-13..2024-02-19&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-02-13..2024-02-19&type=Issues) | [@lumberbot-app](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alumberbot-app+updated%3A2024-02-13..2024-02-19&type=Issues) | [@nluetts](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Anluetts+updated%3A2024-02-13..2024-02-19&type=Issues) | [@trungleduc](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Atrungleduc+updated%3A2024-02-13..2024-02-19&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Awelcome+updated%3A2024-02-13..2024-02-19&type=Issues) + +## 4.1.1 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.1.0...6abcf80374af290d7ba958a1f1f64f92c0394d0e)) + +### Bugs fixed + +- Correct Alt + number keyboard shortcuts command map [#15791](https://github.com/jupyterlab/jupyterlab/pull/15791) ([@g547315](https://github.com/g547315)) +- Catch errors attempting to access `document.cookie` [#15788](https://github.com/jupyterlab/jupyterlab/pull/15788) ([@minrk](https://github.com/minrk)) +- Fix undo/redo in console, fix undo/redo enabled state in file editor [#15783](https://github.com/jupyterlab/jupyterlab/pull/15783) ([@krassowski](https://github.com/krassowski)) +- Fix console cells not becoming read-only after execution [#15779](https://github.com/jupyterlab/jupyterlab/pull/15779) ([@krassowski](https://github.com/krassowski)) +- Fix migration of command selectors for shortcuts [#15762](https://github.com/jupyterlab/jupyterlab/pull/15762) ([@krassowski](https://github.com/krassowski)) +- Disable (shift + ) alt + number shortcuts on Mac [#15761](https://github.com/jupyterlab/jupyterlab/pull/15761) ([@krassowski](https://github.com/krassowski)) +- Catch `OSError` in addition to `PermissionError` when `sys_prefix` is read-only [#15756](https://github.com/jupyterlab/jupyterlab/pull/15756) ([@dhml](https://github.com/dhml)) +- Fix completer auto-invoking on non-source changes [#15753](https://github.com/jupyterlab/jupyterlab/pull/15753) ([@krassowski](https://github.com/krassowski)) +- Fix outputs preservation on splitting cells [#15751](https://github.com/jupyterlab/jupyterlab/pull/15751) ([@krassowski](https://github.com/krassowski)) + +### Maintenance and upkeep improvements + +- Update `jupyter-collaboration` for the Binder environment [#15767](https://github.com/jupyterlab/jupyterlab/pull/15767) ([@jtpio](https://github.com/jtpio)) +- Fix failing "Notebook Toolbar â€ē Paste cell" test [#15720](https://github.com/jupyterlab/jupyterlab/pull/15720) ([@krassowski](https://github.com/krassowski)) + +### Documentation improvements + +- Add Edge, remove IE 11 from browser support docs [#15784](https://github.com/jupyterlab/jupyterlab/pull/15784) ([@JasonWeill](https://github.com/JasonWeill)) +- Update changelog to reflect jupyter-ai release status [#15775](https://github.com/jupyterlab/jupyterlab/pull/15775) ([@krassowski](https://github.com/krassowski)) +- Add a link to postmortem for 3.6.7 release [#15743](https://github.com/jupyterlab/jupyterlab/pull/15743) ([@krassowski](https://github.com/krassowski)) +- Update maintainers affiliation [#15724](https://github.com/jupyterlab/jupyterlab/pull/15724) ([@fcollonval](https://github.com/fcollonval)) +- Update lifecycle info for JupyterLab major versions [#15626](https://github.com/jupyterlab/jupyterlab/pull/15626) ([@JasonWeill](https://github.com/JasonWeill)) + +### Contributors to this release + +([GitHub contributors page for this release](https://github.com/jupyterlab/jupyterlab/graphs/contributors?from=2024-02-05&to=2024-02-13&type=c)) + +[@davidbrochart](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Adavidbrochart+updated%3A2024-02-05..2024-02-13&type=Issues) | [@dhml](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Adhml+updated%3A2024-02-05..2024-02-13&type=Issues) | [@fcollonval](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Afcollonval+updated%3A2024-02-05..2024-02-13&type=Issues) | [@g547315](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ag547315+updated%3A2024-02-05..2024-02-13&type=Issues) | [@github-actions](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Agithub-actions+updated%3A2024-02-05..2024-02-13&type=Issues) | [@JasonWeill](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3AJasonWeill+updated%3A2024-02-05..2024-02-13&type=Issues) | [@jtpio](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajtpio+updated%3A2024-02-05..2024-02-13&type=Issues) | [@jupyterlab-probot](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Ajupyterlab-probot+updated%3A2024-02-05..2024-02-13&type=Issues) | [@krassowski](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Akrassowski+updated%3A2024-02-05..2024-02-13&type=Issues) | [@lumberbot-app](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Alumberbot-app+updated%3A2024-02-05..2024-02-13&type=Issues) | [@minrk](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Aminrk+updated%3A2024-02-05..2024-02-13&type=Issues) | [@pre-commit-ci](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Apre-commit-ci+updated%3A2024-02-05..2024-02-13&type=Issues) | [@welcome](https://github.com/search?q=repo%3Ajupyterlab%2Fjupyterlab+involves%3Awelcome+updated%3A2024-02-05..2024-02-13&type=Issues) + +## 4.1.0 + +([Full Changelog](https://github.com/jupyterlab/jupyterlab/compare/v4.0.2...b887949d52310234144dd48496fa7a6f1fbb4645)) + +### New features added + +- Add virtual scrollbar component to windowed lists. [#15533](https://github.com/jupyterlab/jupyterlab/pull/15533) ([@afshin](https://github.com/afshin)) +- Experimental inline completer [#15160](https://github.com/jupyterlab/jupyterlab/pull/15160) ([@krassowski](https://github.com/krassowski)) +- Notebook execution history [#15062](https://github.com/jupyterlab/jupyterlab/pull/15062) ([@andrewfulton9](https://github.com/andrewfulton9)) +- Load custom CSS functionality and documentation [#14743](https://github.com/jupyterlab/jupyterlab/pull/14743) ([@RRosio](https://github.com/RRosio)) +- Add plugin manager and extension locks [#14536](https://github.com/jupyterlab/jupyterlab/pull/14536) ([@krassowski](https://github.com/krassowski)) +- Open files from errors [#13390](https://github.com/jupyterlab/jupyterlab/pull/13390) ([@divyansshhh](https://github.com/divyansshhh)) + +### Enhancements made + +- Show toast notification for running code cell while kernel initializing [#15421](https://github.com/jupyterlab/jupyterlab/pull/15421) ([@misterfads](https://github.com/misterfads)) +- Read only status notification on ctrl+s [#15317](https://github.com/jupyterlab/jupyterlab/pull/15317) ([@andrewfulton9](https://github.com/andrewfulton9)) +- Store information about execution failure timing [#15285](https://github.com/jupyterlab/jupyterlab/pull/15285) ([@krassowski](https://github.com/krassowski)) +- Add `defaultPath` option to set the default directory for file dialog [#15282](https://github.com/jupyterlab/jupyterlab/pull/15282) ([@mmichilot](https://github.com/mmichilot)) +- Expand search box horizontally when text grows long [#15266](https://github.com/jupyterlab/jupyterlab/pull/15266) ([@sinistersnare](https://github.com/sinistersnare)) +- Added alt descriptions to a few icon and images [#15265](https://github.com/jupyterlab/jupyterlab/pull/15265) ([@j264415](https://github.com/j264415)) +- Custom kernel message serializer [#15254](https://github.com/jupyterlab/jupyterlab/pull/15254) ([@DonJayamanne](https://github.com/DonJayamanne)) +- Improve docker script [#15241](https://github.com/jupyterlab/jupyterlab/pull/15241) ([@trungleduc](https://github.com/trungleduc)) +- Clarify labels for user inputs and link dangling labels [#15222](https://github.com/jupyterlab/jupyterlab/pull/15222) ([@m158261](https://github.com/m158261)) +- Add support for HTTP proxy in extension discovery [#15219](https://github.com/jupyterlab/jupyterlab/pull/15219) ([@dolevf](https://github.com/dolevf)) +- Ensure consistent link underline and color on hover [#15181](https://github.com/jupyterlab/jupyterlab/pull/15181) ([@m158261](https://github.com/m158261)) +- Add the standard SQL mimetype [#15180](https://github.com/jupyterlab/jupyterlab/pull/15180) ([@brichet](https://github.com/brichet)) +- Page_config attribute to handle keydown event at bubbling phase [#15142](https://github.com/jupyterlab/jupyterlab/pull/15142) ([@brichet](https://github.com/brichet)) +- Add more LSP request types [#15064](https://github.com/jupyterlab/jupyterlab/pull/15064) ([@krassowski](https://github.com/krassowski)) +- Expose `processedItemsCache` as a protected in `CompleterModel` [#15025](https://github.com/jupyterlab/jupyterlab/pull/15025) ([@krassowski](https://github.com/krassowski)) +- \[Accessibility\] Using arrow keys to navigate in toolbars items [#15021](https://github.com/jupyterlab/jupyterlab/pull/15021) ([@brichet](https://github.com/brichet)) +- Remove the loop to discover transform function if not registered [#14990](https://github.com/jupyterlab/jupyterlab/pull/14990) ([@brichet](https://github.com/brichet)) +- Fix `filebrowser.open` and add ability to provide a factory [#14983](https://github.com/jupyterlab/jupyterlab/pull/14983) ([@fcollonval](https://github.com/fcollonval)) +- Use config compatible with notebook 7 [#14978](https://github.com/jupyterlab/jupyterlab/pull/14978) ([@fcollonval](https://github.com/fcollonval)) +- Bump lumino packages [#14945](https://github.com/jupyterlab/jupyterlab/pull/14945) ([@fcollonval](https://github.com/fcollonval)) +- Recommend major versions for Lab 3/Lab 4 compatible extensions [#14908](https://github.com/jupyterlab/jupyterlab/pull/14908) ([@JasonWeill](https://github.com/JasonWeill)) +- Save and restore sidebar subpanels sizes and expansion states [#14901](https://github.com/jupyterlab/jupyterlab/pull/14901) ([@DenisaCG](https://github.com/DenisaCG)) +- Improve upgrade extension script [#14882](https://github.com/jupyterlab/jupyterlab/pull/14882) ([@fcollonval](https://github.com/fcollonval)) +- Add a setting to show full path in breadcrumbs [#14866](https://github.com/jupyterlab/jupyterlab/pull/14866) ([@dharmaquark](https://github.com/dharmaquark)) +- Make status bar accessible at 400% zoom by hiding items with priority of zero (default) [#14854](https://github.com/jupyterlab/jupyterlab/pull/14854) ([@j264415](https://github.com/j264415)) +- Add page option `copyAbsolutePath` enabling to copy absolute path [#14842](https://github.com/jupyterlab/jupyterlab/pull/14842) ([@pauky](https://github.com/pauky)) +- feat: sync theme with system settings [#14808](https://github.com/jupyterlab/jupyterlab/pull/14808) ([@skyetim](https://github.com/skyetim)) +- Adds rank to ICompletionProvider [#14800](https://github.com/jupyterlab/jupyterlab/pull/14800) ([@hbcarlos](https://github.com/hbcarlos)) +- Add global keyboard shortcuts for all sidebar widgets [#14799](https://github.com/jupyterlab/jupyterlab/pull/14799) ([@g547315](https://github.com/g547315)) +- Deprecates collaborative flag [#14792](https://github.com/jupyterlab/jupyterlab/pull/14792) ([@hbcarlos](https://github.com/hbcarlos)) +- Add error indicator in Table of Contents [#14784](https://github.com/jupyterlab/jupyterlab/pull/14784) ([@skyetim](https://github.com/skyetim)) +- output_area: Add expand/collapse icon in overlay prompt. [#14640](https://github.com/jupyterlab/jupyterlab/pull/14640) ([@brijsiyag](https://github.com/brijsiyag)) +- Activate the deferred plugins after shell restore [#14610](https://github.com/jupyterlab/jupyterlab/pull/14610) ([@brichet](https://github.com/brichet)) +- Add readonly indicator [#14600](https://github.com/jupyterlab/jupyterlab/pull/14600) ([@andrewfulton9](https://github.com/andrewfulton9)) +- Fix skiplink and add placeholder for additional skiplinks [#14597](https://github.com/jupyterlab/jupyterlab/pull/14597) ([@t03857785](https://github.com/t03857785)) +- Add shortcut tooltips to search buttons [#14478](https://github.com/jupyterlab/jupyterlab/pull/14478) ([@bikash30851](https://github.com/bikash30851)) +- Add native viewing support for jsonl/ndjson [#14460](https://github.com/jupyterlab/jupyterlab/pull/14460) ([@timkpaine](https://github.com/timkpaine)) +- Automatically toggle search in selection [#14421](https://github.com/jupyterlab/jupyterlab/pull/14421) ([@krassowski](https://github.com/krassowski)) +- Update to marked 7.0.2, add mermaidjs 10.3.1 [#14102](https://github.com/jupyterlab/jupyterlab/pull/14102) ([@bollwyvl](https://github.com/bollwyvl)) + +### Bugs fixed + +- Fix scrollbars partially blocking code completion [#15736](https://github.com/jupyterlab/jupyterlab/pull/15736) ([@phil-zxx](https://github.com/phil-zxx)) +- Fix running kernels listing for kernels without icons [#15735](https://github.com/jupyterlab/jupyterlab/pull/15735) ([@paolocarinci](https://github.com/paolocarinci)) +- Fix cell toolbar getting stuck when using collapse cell [#15732](https://github.com/jupyterlab/jupyterlab/pull/15732) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Fix kernels sidepanel scrollbar [#15718](https://github.com/jupyterlab/jupyterlab/pull/15718) ([@FoSuCloud](https://github.com/FoSuCloud)) +- Fix `overrides.json` not working for shortcuts [#15716](https://github.com/jupyterlab/jupyterlab/pull/15716) ([@krassowski](https://github.com/krassowski)) +- Add scroll margin to headings for better alignment [#15703](https://github.com/jupyterlab/jupyterlab/pull/15703) ([@krassowski](https://github.com/krassowski)) +- Fix scrolling on execution and switching notebook mode [#15702](https://github.com/jupyterlab/jupyterlab/pull/15702) ([@krassowski](https://github.com/krassowski)) +- Fix shortcut UI failing on filtering when empty command is given [#15695](https://github.com/jupyterlab/jupyterlab/pull/15695) ([@krassowski](https://github.com/krassowski)) +- Fix search highlights removal on clearing input box [#15690](https://github.com/jupyterlab/jupyterlab/pull/15690) ([@krassowski](https://github.com/krassowski)) +- Remove the add cell button from the tabbable item [#15679](https://github.com/jupyterlab/jupyterlab/pull/15679) ([@brichet](https://github.com/brichet)) +- Migrate to `user` level or to none (as fallback) [#15678](https://github.com/jupyterlab/jupyterlab/pull/15678) ([@krassowski](https://github.com/krassowski)) +- Ensure void elements have closing slash in mermaid svg [#15661](https://github.com/jupyterlab/jupyterlab/pull/15661) ([@bollwyvl](https://github.com/bollwyvl)) +- Fix jupyterlab downgrade issue on extension installation [#15650](https://github.com/jupyterlab/jupyterlab/pull/15650) ([@Sarthug99](https://github.com/Sarthug99)) +- Fix outputarea package from not detecting updates [#15642](https://github.com/jupyterlab/jupyterlab/pull/15642) ([@MFA-X-AI](https://github.com/MFA-X-AI)) +- Fix kernel shortcuts, add migration, fix defaults population [#15639](https://github.com/jupyterlab/jupyterlab/pull/15639) ([@krassowski](https://github.com/krassowski)) +- Fix new line getting inserted when running cells with `Ctrl` + `Enter` [#15638](https://github.com/jupyterlab/jupyterlab/pull/15638) ([@krassowski](https://github.com/krassowski)) +- Fix markdown getting un-rendered when focusing on a different cell [#15634](https://github.com/jupyterlab/jupyterlab/pull/15634) ([@krassowski](https://github.com/krassowski)) +- Fixes focus indicator on input checkbox for Firefox [#15612](https://github.com/jupyterlab/jupyterlab/pull/15612) ([@alden-ilao](https://github.com/alden-ilao)) +- Upgrade jupyter-ui-toolkit [#15600](https://github.com/jupyterlab/jupyterlab/pull/15600) ([@fcollonval](https://github.com/fcollonval)) +- Fix ctrl+s notification incorrectly showing up in RTC mode [#15597](https://github.com/jupyterlab/jupyterlab/pull/15597) ([@andrewfulton9](https://github.com/andrewfulton9)) +- Fix spurious "File Changed" dialogs using `hash` from `jupyter-server` v2.11.1+ [#15577](https://github.com/jupyterlab/jupyterlab/pull/15577) ([@Wh1isper](https://github.com/Wh1isper)) +- Accept/invoke inline completions with `Tab` [#15571](https://github.com/jupyterlab/jupyterlab/pull/15571) ([@krassowski](https://github.com/krassowski)) +- Show the notification center if the status bar is disabled [#15568](https://github.com/jupyterlab/jupyterlab/pull/15568) ([@jtpio](https://github.com/jtpio)) +- Fixes the order of items in notebook toolbar [#15553](https://github.com/jupyterlab/jupyterlab/pull/15553) ([@brichet](https://github.com/brichet)) +- Add a title to the Plugin Manager widget [#15552](https://github.com/jupyterlab/jupyterlab/pull/15552) ([@jtpio](https://github.com/jtpio)) +- Link to paths starting at Unix-style root in the tracebacks [#15548](https://github.com/jupyterlab/jupyterlab/pull/15548) ([@krassowski](https://github.com/krassowski)) +- Fix `jupyter labextension watch --help` [#15542](https://github.com/jupyterlab/jupyterlab/pull/15542) ([@akx](https://github.com/akx)) +- Implement `level` trait for plugin/extension managers [#15512](https://github.com/jupyterlab/jupyterlab/pull/15512) ([@krassowski](https://github.com/krassowski)) +- Fix display of float variables with value of infinity in the debugger tree [#15487](https://github.com/jupyterlab/jupyterlab/pull/15487) ([@ashna1jain](https://github.com/ashna1jain)) +- Workaround focus leaving input box on consecutive submissions [#15479](https://github.com/jupyterlab/jupyterlab/pull/15479) ([@krassowski](https://github.com/krassowski)) +- Fix `FormComponent` showing error indicators in all fields when using a `customValidate` function [#15464](https://github.com/jupyterlab/jupyterlab/pull/15464) ([@mmichilot](https://github.com/mmichilot)) +- Fix file dialog contents loading with `defaultPath`, and model disposal [#15463](https://github.com/jupyterlab/jupyterlab/pull/15463) ([@mmichilot](https://github.com/mmichilot)) +- Fix search CM set up [#15459](https://github.com/jupyterlab/jupyterlab/pull/15459) ([@fcollonval](https://github.com/fcollonval)) +- Fix search coming back in notebook and editor [#15443](https://github.com/jupyterlab/jupyterlab/pull/15443) ([@krassowski](https://github.com/krassowski)) +- Fix Shift + L not working in stdin [#15440](https://github.com/jupyterlab/jupyterlab/pull/15440) ([@krassowski](https://github.com/krassowski)) +- Scroll to the active cell when typing (in edit mode) [#15413](https://github.com/jupyterlab/jupyterlab/pull/15413) ([@brichet](https://github.com/brichet)) +- Don't play with the focus when handling focus event [#15408](https://github.com/jupyterlab/jupyterlab/pull/15408) ([@fcollonval](https://github.com/fcollonval)) +- Updated light theme visited link colour to make text visible [#15406](https://github.com/jupyterlab/jupyterlab/pull/15406) ([@m158261](https://github.com/m158261)) +- Optimized and more robust PyPIExtensionManager [#15404](https://github.com/jupyterlab/jupyterlab/pull/15404) ([@fcollonval](https://github.com/fcollonval)) +- Do not update filebrowser breadcrumbs when not needed [#15387](https://github.com/jupyterlab/jupyterlab/pull/15387) ([@krassowski](https://github.com/krassowski)) +- Improve scrolling to heading [#15386](https://github.com/jupyterlab/jupyterlab/pull/15386) ([@fcollonval](https://github.com/fcollonval)) +- Don't show default value for objects in Settings Editor [#15380](https://github.com/jupyterlab/jupyterlab/pull/15380) ([@firai](https://github.com/firai)) +- Fix highlighting search in an out-of-viewport cell [#15376](https://github.com/jupyterlab/jupyterlab/pull/15376) ([@fcollonval](https://github.com/fcollonval)) +- Remove unnecessary requirement from codemirror service plugin [#15362](https://github.com/jupyterlab/jupyterlab/pull/15362) ([@paulkim3151](https://github.com/paulkim3151)) +- Update notebook window on resize if height changes [#15357](https://github.com/jupyterlab/jupyterlab/pull/15357) ([@krassowski](https://github.com/krassowski)) +- Fix scrolling past long outputs in presence of un-rendered headings [#15356](https://github.com/jupyterlab/jupyterlab/pull/15356) ([@krassowski](https://github.com/krassowski)) +- Fix missing default property breaking codemirror `overrides.json` [#15346](https://github.com/jupyterlab/jupyterlab/pull/15346) ([@LJMP](https://github.com/e4e)) +- Fix update button in extension manager [#15331](https://github.com/jupyterlab/jupyterlab/pull/15331) ([@nbowditch-einblick](https://github.com/nbowditch-einblick)) +- Fix collapsed cells styling [#15322](https://github.com/jupyterlab/jupyterlab/pull/15322) ([@fcollonval](https://github.com/fcollonval)) +- Fix scrolling when dragging files in the file browser [#15318](https://github.com/jupyterlab/jupyterlab/pull/15318) ([@krassowski](https://github.com/krassowski)) +- Improve cell toolbar tracker [#15314](https://github.com/jupyterlab/jupyterlab/pull/15314) ([@fcollonval](https://github.com/fcollonval)) +- Declare Webpack loaders with `require.resolve()` [#15299](https://github.com/jupyterlab/jupyterlab/pull/15299) ([@tibdex](https://github.com/tibdex)) +- Fix autobrackets and other default CM extension [#15297](https://github.com/jupyterlab/jupyterlab/pull/15297) ([@fcollonval](https://github.com/fcollonval)) +- Fix rulers position with gutter width [#15296](https://github.com/jupyterlab/jupyterlab/pull/15296) ([@fcollonval](https://github.com/fcollonval)) +- Fix overreactive scrolling to next cell after `Shift + Enter` [#15288](https://github.com/jupyterlab/jupyterlab/pull/15288) ([@krassowski](https://github.com/krassowski)) +- Keep active cell rendered in the `full` windowed mode [#15286](https://github.com/jupyterlab/jupyterlab/pull/15286) ([@krassowski](https://github.com/krassowski)) +- Fix connection loop issue with standalone foreign document in LSP [#15262](https://github.com/jupyterlab/jupyterlab/pull/15262) ([@trungleduc](https://github.com/trungleduc)) +- Update virtual documents conditionally [#15250](https://github.com/jupyterlab/jupyterlab/pull/15250) ([@trungleduc](https://github.com/trungleduc)) +- Fix completer documentation panel hiding and animation [#15238](https://github.com/jupyterlab/jupyterlab/pull/15238) ([@krassowski](https://github.com/krassowski)) +- Fix MathJax font override, avoid double initialization [#15230](https://github.com/jupyterlab/jupyterlab/pull/15230) ([@bollwyvl](https://github.com/bollwyvl)) +- Fix expanionStates error [#15225](https://github.com/jupyterlab/jupyterlab/pull/15225) ([@DenisaCG](https://github.com/DenisaCG)) +- Fix clicking in the TOC does not scroll [#15184](https://github.com/jupyterlab/jupyterlab/pull/15184) ([@parmentelat](https://github.com/parmentelat)) +- Fix translation for Mermaid JS context menu label [#15178](https://github.com/jupyterlab/jupyterlab/pull/15178) ([@Deepali1211](https://github.com/Deepali1211)) +- Restore syntax highlighting for mimetypes with more than one identifier [#15175](https://github.com/jupyterlab/jupyterlab/pull/15175) ([@jans-code](https://github.com/jans-code)) +- Restore horizontal scrolling of outputs for Firefox [#15171](https://github.com/jupyterlab/jupyterlab/pull/15171) ([@fcollonval](https://github.com/fcollonval)) +- Fix Show Keyboard Shortcuts command [#15170](https://github.com/jupyterlab/jupyterlab/pull/15170) ([@jtpio](https://github.com/jtpio)) +- Copy absolute path with first slash in the file browser [#15168](https://github.com/jupyterlab/jupyterlab/pull/15168) ([@pauky](https://github.com/pauky)) +- Fix completer width inflation and jitter [#15132](https://github.com/jupyterlab/jupyterlab/pull/15132) ([@krassowski](https://github.com/krassowski)) +- Fix selection in active line [#15129](https://github.com/jupyterlab/jupyterlab/pull/15129) ([@krassowski](https://github.com/krassowski)) +- Fix documentation panel display logic of the completer [#15106](https://github.com/jupyterlab/jupyterlab/pull/15106) ([@trungleduc](https://github.com/trungleduc)) +- Remove `unusedDocuments`, fix culling of foreign documents [#15105](https://github.com/jupyterlab/jupyterlab/pull/15105) ([@krassowski](https://github.com/krassowski)) +- Fix return type of `getMimeTypeByLanguage()` [#15101](https://github.com/jupyterlab/jupyterlab/pull/15101) ([@krassowski](https://github.com/krassowski)) +- Fix background-color in ` + + + +
+
+ +
+
+ `; + document.body.appendChild(div); + + const lightHost = div.querySelector('.light-host')!; + const shadowHost = div.querySelector('.shadow-host')!; + const shadowRoot = shadowHost.attachShadow({ mode: 'open' }); + // mirror test cases from light DOM in the shadow DOM + shadowRoot.innerHTML = lightHost.innerHTML; + + it.each(testCases)( + 'should work in light DOM: `%s` element should result in `%s`', + (selector, expected) => { + const element = lightHost.querySelector( + selector as string + ) as HTMLElement; + element.focus(); + + const result = DOMUtils.hasActiveEditableElement(div); + expect(result).toBe(expected); + } + ); + + it.each(testCases)( + 'should work in shadow DOM: `%s` element should result in `%s`', + (selector, expected) => { + const element = shadowRoot.querySelector( + selector as string + ) as HTMLElement; + element.focus(); + + const result = DOMUtils.hasActiveEditableElement(div); + expect(result).toBe(expected); + } + ); + }); + }); +}); diff --git a/packages/apputils/test/toolbar.spec.ts b/packages/apputils/test/toolbar.spec.ts index 9d4685628273..48f3f4af0eb2 100644 --- a/packages/apputils/test/toolbar.spec.ts +++ b/packages/apputils/test/toolbar.spec.ts @@ -74,9 +74,7 @@ describe('@jupyterlab/apputils', () => { await sessionContext.initialize(); Widget.attach(item, document.body); await framePromise(); - const node = item.node.querySelector( - '.jp-ToolbarButtonComponent-label' - )!; + const node = item.node.querySelector('.jp-Toolbar-kernelName')!; expect(node.textContent).toBe(sessionContext.kernelDisplayName); }); }); diff --git a/packages/attachments/package.json b/packages/attachments/package.json index bd1996b47fcf..8552d4bf4532 100644 --- a/packages/attachments/package.json +++ b/packages/attachments/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/attachments", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "JupyterLab - Notebook Cell Attachments", "homepage": "https://github.com/jupyterlab/jupyterlab", "bugs": { @@ -37,17 +37,17 @@ "watch": "tsc -b --watch" }, "dependencies": { - "@jupyterlab/nbformat": "^4.1.0-alpha.2", - "@jupyterlab/observables": "^5.1.0-alpha.2", - "@jupyterlab/rendermime": "^4.1.0-alpha.2", - "@jupyterlab/rendermime-interfaces": "^3.9.0-alpha.1", + "@jupyterlab/nbformat": "^4.1.6", + "@jupyterlab/observables": "^5.1.6", + "@jupyterlab/rendermime": "^4.1.6", + "@jupyterlab/rendermime-interfaces": "^3.9.6", "@lumino/disposable": "^2.1.2", "@lumino/signaling": "^2.1.2" }, "devDependencies": { - "rimraf": "~3.0.0", + "rimraf": "~5.0.5", "typedoc": "~0.24.7", - "typescript": "~5.0.4" + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/cell-toolbar-extension/package.json b/packages/cell-toolbar-extension/package.json index 7da91a8298a7..6c1a32d1ff8d 100644 --- a/packages/cell-toolbar-extension/package.json +++ b/packages/cell-toolbar-extension/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/cell-toolbar-extension", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "Extension for cell toolbar adapted from jlab-enhanced-cell-toolbar", "homepage": "https://github.com/jupyterlab/jupyterlab", "bugs": { @@ -34,15 +34,15 @@ "watch": "tsc -b --watch" }, "dependencies": { - "@jupyterlab/application": "^4.1.0-alpha.2", - "@jupyterlab/apputils": "^4.2.0-alpha.2", - "@jupyterlab/cell-toolbar": "^4.1.0-alpha.2", - "@jupyterlab/settingregistry": "^4.1.0-alpha.2", - "@jupyterlab/translation": "^4.1.0-alpha.2" + "@jupyterlab/application": "^4.1.6", + "@jupyterlab/apputils": "^4.2.6", + "@jupyterlab/cell-toolbar": "^4.1.6", + "@jupyterlab/settingregistry": "^4.1.6", + "@jupyterlab/translation": "^4.1.6" }, "devDependencies": { - "rimraf": "~3.0.0", - "typescript": "~5.0.4" + "rimraf": "~5.0.5", + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/cell-toolbar/package.json b/packages/cell-toolbar/package.json index 03755fe09ecd..a0013bd61046 100644 --- a/packages/cell-toolbar/package.json +++ b/packages/cell-toolbar/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/cell-toolbar", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "Contextual cell toolbar adapted from jlab-enhanced-cell-toolbar", "homepage": "https://github.com/jupyterlab/jupyterlab", "bugs": { @@ -41,24 +41,24 @@ }, "dependencies": { "@jupyter/ydoc": "^1.1.1", - "@jupyterlab/apputils": "^4.2.0-alpha.2", - "@jupyterlab/cells": "^4.1.0-alpha.2", - "@jupyterlab/docregistry": "^4.1.0-alpha.2", - "@jupyterlab/notebook": "^4.1.0-alpha.2", - "@jupyterlab/observables": "^5.1.0-alpha.2", - "@jupyterlab/ui-components": "^4.1.0-alpha.2", + "@jupyterlab/apputils": "^4.2.6", + "@jupyterlab/cells": "^4.1.6", + "@jupyterlab/docregistry": "^4.1.6", + "@jupyterlab/notebook": "^4.1.6", + "@jupyterlab/observables": "^5.1.6", + "@jupyterlab/ui-components": "^4.1.6", "@lumino/algorithm": "^2.0.1", - "@lumino/commands": "^2.1.3", + "@lumino/commands": "^2.2.0", "@lumino/disposable": "^2.1.2", "@lumino/signaling": "^2.1.2", - "@lumino/widgets": "^2.3.1-alpha.0" + "@lumino/widgets": "^2.3.1" }, "devDependencies": { - "@jupyterlab/testing": "^4.1.0-alpha.2", + "@jupyterlab/testing": "^4.1.6", "@types/jest": "^29.2.0", "jest": "^29.2.0", - "rimraf": "~3.0.0", - "typescript": "~5.0.4" + "rimraf": "~5.0.5", + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/cell-toolbar/src/celltoolbartracker.ts b/packages/cell-toolbar/src/celltoolbartracker.ts index 8a385958de2a..4a11549e710a 100644 --- a/packages/cell-toolbar/src/celltoolbartracker.ts +++ b/packages/cell-toolbar/src/celltoolbartracker.ts @@ -2,7 +2,11 @@ | Copyright (c) Jupyter Development Team. | Distributed under the terms of the Modified BSD License. |----------------------------------------------------------------------------*/ -import { createDefaultFactory, ToolbarRegistry } from '@jupyterlab/apputils'; +import { + createDefaultFactory, + setToolbar, + ToolbarRegistry +} from '@jupyterlab/apputils'; import { Cell, CellModel, @@ -34,6 +38,7 @@ const TEXT_MIME_TYPES = [ * Widget cell toolbar classes */ const CELL_TOOLBAR_CLASS = 'jp-cell-toolbar'; +// @deprecated to be removed const CELL_MENU_CLASS = 'jp-cell-menu'; /** @@ -45,45 +50,59 @@ const TOOLBAR_OVERLAP_CLASS = 'jp-toolbar-overlap'; * Watch a notebook so that a cell toolbar appears on the active cell */ export class CellToolbarTracker implements IDisposable { + /** + * CellToolbarTracker constructor + * + * @param panel The notebook panel + * @param toolbar The toolbar; deprecated use {@link toolbarFactory} instead + * @param toolbarFactory The toolbar factory + */ constructor( panel: NotebookPanel, - toolbar: IObservableList + toolbar?: IObservableList, + toolbarFactory?: ( + widget: Cell + ) => IObservableList ) { this._panel = panel; this._previousActiveCell = this._panel.content.activeCell; - this._toolbar = toolbar; + this._toolbarItems = toolbar ?? null; + this._toolbarFactory = toolbarFactory ?? null; - this._onToolbarChanged(); - this._toolbar.changed.connect(this._onToolbarChanged, this); + if (this._toolbarItems === null && this._toolbarFactory === null) { + throw Error('You must provide the toolbarFactory or the toolbar items.'); + } + + // deprecated to be removed when we remove toolbar from input arguments + if (!this._toolbarFactory && this._toolbarItems) { + this._onToolbarChanged(); + this._toolbarItems.changed.connect(this._onToolbarChanged, this); + } // Only add the toolbar to the notebook's active cell (if any) once it has fully rendered and been revealed. void panel.revealed.then(() => { - // Wait one frame (at 60 fps) for the panel to render the first cell, then display the cell toolbar on it if possible. - setTimeout(() => { - this._onActiveCellChanged(panel.content); - }, 1000 / 60); - }); - - // Check whether the toolbar should be rendered upon a layout change - panel.content.renderingLayoutChanged.connect( - this._onActiveCellChanged, - this - ); - - // Handle subsequent changes of active cell. - panel.content.activeCellChanged.connect(this._onActiveCellChanged, this); - panel.content.activeCell?.model.metadataChanged.connect( - this._onMetadataChanged, - this - ); - panel.disposed.connect(() => { - panel.content.activeCellChanged.disconnect(this._onActiveCellChanged); - panel.content.activeCell?.model.metadataChanged.disconnect( - this._onMetadataChanged - ); + requestAnimationFrame(() => { + const notebook = panel.content; + this._onActiveCellChanged(notebook); + // Handle subsequent changes of active cell. + notebook.activeCellChanged.connect(this._onActiveCellChanged, this); + + // Check whether the toolbar should be rendered upon a layout change + notebook.renderingLayoutChanged.connect( + this._onActiveCellChanged, + this + ); + + notebook.disposed.connect(() => { + notebook.activeCellChanged.disconnect(this._onActiveCellChanged); + }); + }); }); } + /** + * @deprecated Will become protected in JupyterLab 5 + */ _onMetadataChanged(model: CellModel, args: IMapChange) { if (args.key === 'jupyter') { if ( @@ -104,6 +123,10 @@ export class CellToolbarTracker implements IDisposable { } } } + + /** + * @deprecated Will become protected in JupyterLab 5 + */ _onActiveCellChanged(notebook: Notebook): void { if (this._previousActiveCell && !this._previousActiveCell.isDisposed) { // Disposed cells do not have a model anymore. @@ -114,6 +137,8 @@ export class CellToolbarTracker implements IDisposable { } const activeCell = notebook.activeCell; + // Change previously active cell. + this._previousActiveCell = activeCell; if (activeCell === null || activeCell.inputHidden) { return; } @@ -121,7 +146,6 @@ export class CellToolbarTracker implements IDisposable { activeCell.model.metadataChanged.connect(this._onMetadataChanged, this); this._addToolbar(activeCell.model); - this._previousActiveCell = activeCell; } get isDisposed(): boolean { @@ -134,14 +158,8 @@ export class CellToolbarTracker implements IDisposable { } this._isDisposed = true; - this._toolbar.changed.disconnect(this._onToolbarChanged, this); - - const cells = this._panel?.context.model.cells; - if (cells) { - for (const model of cells) { - this._removeToolbar(model); - } - } + this._toolbarItems?.changed.disconnect(this._onToolbarChanged, this); + this._toolbar?.dispose(); this._panel = null; @@ -151,26 +169,39 @@ export class CellToolbarTracker implements IDisposable { private _addToolbar(model: ICellModel): void { const cell = this._getCell(model); - if (cell) { - const toolbarWidget = new Toolbar(); + if (cell && !cell.isDisposed) { + const toolbarWidget = (this._toolbar = new Toolbar()); + // Note: CELL_MENU_CLASS is deprecated. toolbarWidget.addClass(CELL_MENU_CLASS); - - const promises: Promise[] = []; - for (const { name, widget } of this._toolbar) { - toolbarWidget.addItem(name, widget); - if ( - widget instanceof ReactWidget && - (widget as ReactWidget).renderPromise !== undefined - ) { - (widget as ReactWidget).update(); - promises.push((widget as ReactWidget).renderPromise!); + toolbarWidget.addClass(CELL_TOOLBAR_CLASS); + const promises: Promise[] = [cell.ready]; + if (this._toolbarFactory) { + setToolbar(cell, this._toolbarFactory, toolbarWidget); + // FIXME toolbarWidget.update() - strangely this does not work + (toolbarWidget.layout as PanelLayout).widgets.forEach(w => { + w.update(); + }); + } else { + for (const { name, widget } of this._toolbarItems!) { + toolbarWidget.addItem(name, widget); + if ( + widget instanceof ReactWidget && + (widget as ReactWidget).renderPromise !== undefined + ) { + (widget as ReactWidget).update(); + promises.push((widget as ReactWidget).renderPromise!); + } } } // Wait for all the buttons to be rendered before attaching the toolbar. Promise.all(promises) .then(() => { - toolbarWidget.addClass(CELL_TOOLBAR_CLASS); + if (cell.isDisposed || this._panel?.content.activeCell !== cell) { + toolbarWidget.dispose(); + return; + } + (cell.layout as PanelLayout).insertWidget(0, toolbarWidget); // For rendered markdown, watch for resize events. @@ -192,27 +223,22 @@ export class CellToolbarTracker implements IDisposable { return this._panel?.content.widgets.find(widget => widget.model === model); } - private _findToolbarWidgets(cell: Cell): Widget[] { - const widgets = (cell.layout as PanelLayout).widgets; - - // Search for header using the CSS class or use the first one if not found. - return widgets.filter(widget => widget.hasClass(CELL_TOOLBAR_CLASS)) || []; - } - private _removeToolbar(model: ICellModel): void { const cell = this._getCell(model); - if (cell) { - this._findToolbarWidgets(cell).forEach(widget => { - widget.dispose(); - }); + if (cell && !cell.isDisposed) { // Attempt to remove the resize and changed event handlers. cell.displayChanged.disconnect(this._resizeEventCallback, this); } model.contentChanged.disconnect(this._changedEventCallback, this); + if (this._toolbar?.parent === cell && this._toolbar?.isDisposed === false) { + this._toolbar.dispose(); + } } /** * Call back on settings changes + * + * @deprecated To remove when toolbar can not be provided directly to the tracker */ private _onToolbarChanged(): void { // Reset toolbar when settings changes @@ -262,8 +288,10 @@ export class CellToolbarTracker implements IDisposable { const cellType = activeCell.model.type; // If the toolbar is too large for the current cell, hide it. - const cellLeft = this._cellEditorWidgetLeft(activeCell); - const cellRight = this._cellEditorWidgetRight(activeCell); + + const editorRect = activeCell.editorWidget?.node.getBoundingClientRect(); + const cellLeft = editorRect?.left ?? 0; + const cellRight = editorRect?.right ?? 0; const toolbarLeft = this._cellToolbarLeft(activeCell); if (toolbarLeft === null) { @@ -385,20 +413,11 @@ export class CellToolbarTracker implements IDisposable { return toolbarLeft === null ? false : lineRight > toolbarLeft; } - private _cellEditorWidgetLeft(activeCell: Cell): number { - return activeCell.editorWidget?.node.getBoundingClientRect().left ?? 0; - } - - private _cellEditorWidgetRight(activeCell: Cell): number { - return activeCell.editorWidget?.node.getBoundingClientRect().right ?? 0; - } - private _cellToolbarRect(activeCell: Cell): DOMRect | null { - const toolbarWidgets = this._findToolbarWidgets(activeCell); - if (toolbarWidgets.length < 1) { + if (this._toolbar?.parent !== activeCell) { return null; } - const activeCellToolbar = toolbarWidgets[0].node; + const activeCellToolbar = this._toolbar.node; return activeCellToolbar.getBoundingClientRect(); } @@ -410,7 +429,12 @@ export class CellToolbarTracker implements IDisposable { private _isDisposed = false; private _panel: NotebookPanel | null; private _previousActiveCell: Cell | null; - private _toolbar: IObservableList; + private _toolbar: Widget | null = null; + private _toolbarItems: IObservableList | null = + null; + private _toolbarFactory: + | ((widget: Cell) => IObservableList) + | null = null; } const defaultToolbarItems: ToolbarRegistry.IWidget[] = [ @@ -445,7 +469,7 @@ const defaultToolbarItems: ToolbarRegistry.IWidget[] = [ * created. */ export class CellBarExtension implements DocumentRegistry.WidgetExtension { - static FACTORY_NAME = 'Cell'; + static readonly FACTORY_NAME = 'Cell'; constructor( commands: CommandRegistry, @@ -473,7 +497,7 @@ export class CellBarExtension implements DocumentRegistry.WidgetExtension { } createNew(panel: NotebookPanel): IDisposable { - return new CellToolbarTracker(panel, this._toolbarFactory(panel)); + return new CellToolbarTracker(panel, undefined, this._toolbarFactory); } private _commands: CommandRegistry; diff --git a/packages/cell-toolbar/style/base.css b/packages/cell-toolbar/style/base.css index ec96edb81f33..66d79e3d7284 100644 --- a/packages/cell-toolbar/style/base.css +++ b/packages/cell-toolbar/style/base.css @@ -18,40 +18,34 @@ .jp-cell-toolbar { display: flex; flex-direction: row; - padding: 2px 0; + padding: 0; min-height: 25px; z-index: 6; position: absolute; - top: 5px; right: 8px; /* Override .jp-Toolbar */ background-color: transparent; border-bottom: inherit; - box-shadow: inherit; + box-shadow: none; } /* Overrides for mobile view hiding cell toolbar */ @media only screen and (width <= 760px) { - .jp-cell-menu.jp-cell-toolbar { + .jp-cell-toolbar { display: none; } } -.jp-cell-menu { - display: flex; - flex-direction: row; -} - -.jp-cell-menu button.jp-ToolbarButtonComponent { +.jp-cell-toolbar button.jp-ToolbarButtonComponent { cursor: pointer; } -.jp-cell-menu .jp-ToolbarButton button { +.jp-cell-toolbar .jp-ToolbarButton button { display: none; } -.jp-cell-menu .jp-ToolbarButton .jp-cell-all, +.jp-cell-toolbar .jp-ToolbarButton .jp-cell-all, .jp-CodeCell .jp-ToolbarButton .jp-cell-code, .jp-MarkdownCell .jp-ToolbarButton .jp-cell-markdown, .jp-RawCell .jp-ToolbarButton .jp-cell-raw { diff --git a/packages/cells/package.json b/packages/cells/package.json index 31f81f01b9e9..d9bfc206c22d 100644 --- a/packages/cells/package.json +++ b/packages/cells/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/cells", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "JupyterLab - Notebook Cells", "homepage": "https://github.com/jupyterlab/jupyterlab", "bugs": { @@ -46,40 +46,40 @@ "@codemirror/state": "^6.2.0", "@codemirror/view": "^6.9.6", "@jupyter/ydoc": "^1.1.1", - "@jupyterlab/apputils": "^4.2.0-alpha.2", - "@jupyterlab/attachments": "^4.1.0-alpha.2", - "@jupyterlab/codeeditor": "^4.1.0-alpha.2", - "@jupyterlab/codemirror": "^4.1.0-alpha.2", - "@jupyterlab/coreutils": "^6.1.0-alpha.2", - "@jupyterlab/documentsearch": "^4.1.0-alpha.2", - "@jupyterlab/filebrowser": "^4.1.0-alpha.2", - "@jupyterlab/nbformat": "^4.1.0-alpha.2", - "@jupyterlab/observables": "^5.1.0-alpha.2", - "@jupyterlab/outputarea": "^4.1.0-alpha.2", - "@jupyterlab/rendermime": "^4.1.0-alpha.2", - "@jupyterlab/services": "^7.1.0-alpha.2", - "@jupyterlab/toc": "^6.1.0-alpha.2", - "@jupyterlab/translation": "^4.1.0-alpha.2", - "@jupyterlab/ui-components": "^4.1.0-alpha.2", + "@jupyterlab/apputils": "^4.2.6", + "@jupyterlab/attachments": "^4.1.6", + "@jupyterlab/codeeditor": "^4.1.6", + "@jupyterlab/codemirror": "^4.1.6", + "@jupyterlab/coreutils": "^6.1.6", + "@jupyterlab/documentsearch": "^4.1.6", + "@jupyterlab/filebrowser": "^4.1.6", + "@jupyterlab/nbformat": "^4.1.6", + "@jupyterlab/observables": "^5.1.6", + "@jupyterlab/outputarea": "^4.1.6", + "@jupyterlab/rendermime": "^4.1.6", + "@jupyterlab/services": "^7.1.6", + "@jupyterlab/toc": "^6.1.6", + "@jupyterlab/translation": "^4.1.6", + "@jupyterlab/ui-components": "^4.1.6", "@lumino/algorithm": "^2.0.1", "@lumino/coreutils": "^2.1.2", "@lumino/domutils": "^2.0.1", - "@lumino/dragdrop": "^2.1.3", + "@lumino/dragdrop": "^2.1.4", "@lumino/messaging": "^2.0.1", "@lumino/polling": "^2.1.2", "@lumino/signaling": "^2.1.2", "@lumino/virtualdom": "^2.0.1", - "@lumino/widgets": "^2.3.1-alpha.0", + "@lumino/widgets": "^2.3.1", "react": "^18.2.0" }, "devDependencies": { - "@jupyterlab/testing": "^4.1.0-alpha.2", + "@jupyterlab/testing": "^4.1.6", "@types/jest": "^29.2.0", "@types/react": "^18.0.26", "jest": "^29.2.0", - "rimraf": "~3.0.0", + "rimraf": "~5.0.5", "typedoc": "~0.24.7", - "typescript": "~5.0.4" + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/cells/src/searchprovider.ts b/packages/cells/src/searchprovider.ts index b5fe8bc87464..ff38dcc23d7b 100644 --- a/packages/cells/src/searchprovider.ts +++ b/packages/cells/src/searchprovider.ts @@ -326,7 +326,7 @@ class MarkdownCellSearchProvider extends CellSearchProvider { const cell = this.cell as MarkdownCell; if (cell.rendered && this.matchesCount > 0) { // Unrender the cell - this._unrenderedByHighligh = true; + this._unrenderedByHighlight = true; const waitForRendered = signalToPromise(cell.renderedChanged); cell.rendered = false; await waitForRendered; @@ -347,7 +347,7 @@ class MarkdownCellSearchProvider extends CellSearchProvider { const cell = this.cell as MarkdownCell; if (cell.rendered && this.matchesCount > 0) { // Unrender the cell if there are matches within the cell - this._unrenderedByHighligh = true; + this._unrenderedByHighlight = true; const waitForRendered = signalToPromise(cell.renderedChanged); cell.rendered = false; await waitForRendered; @@ -397,10 +397,10 @@ class MarkdownCellSearchProvider extends CellSearchProvider { * @param rendered New rendered value */ protected onRenderedChanged(cell: MarkdownCell, rendered: boolean): void { - if (!this._unrenderedByHighligh) { + if (!this._unrenderedByHighlight) { this.currentIndex = null; } - this._unrenderedByHighligh = false; + this._unrenderedByHighlight = false; if (this.isActive) { if (rendered) { void this.renderedProvider.startQuery(this.query); @@ -413,7 +413,7 @@ class MarkdownCellSearchProvider extends CellSearchProvider { } protected renderedProvider: GenericSearchProvider; - private _unrenderedByHighligh = false; + private _unrenderedByHighlight = false; } /** diff --git a/packages/cells/src/widget.ts b/packages/cells/src/widget.ts index 196f74381b78..b2d9a83bf076 100644 --- a/packages/cells/src/widget.ts +++ b/packages/cells/src/widget.ts @@ -202,7 +202,9 @@ export class Cell extends Widget { // Set up translator for aria labels this.translator = options.translator ?? nullTranslator; - this._editorConfig = options.editorConfig ?? {}; + // For cells disable searching with CodeMirror search panel. + this._editorConfig = { searchWithCM: false, ...options.editorConfig }; + this._editorExtensions = options.editorExtensions ?? []; this._placeholder = true; this._inViewport = false; this.placeholder = options.placeholder ?? true; @@ -614,7 +616,7 @@ export class Cell extends Widget { * @returns Editor options */ protected getEditorOptions(): InputArea.IOptions['editorOptions'] { - return { config: this.editorConfig }; + return { config: this.editorConfig, extensions: this._editorExtensions }; } /** @@ -693,6 +695,7 @@ export class Cell extends Widget { protected _displayChanged = new Signal(this); private _editorConfig: Record = {}; + private _editorExtensions: Extension[] = []; private _input: InputArea | null; private _inputHidden = false; private _inputWrapper: Widget | null; @@ -1347,6 +1350,7 @@ export class CodeCell extends Cell { if (this.outputsScrolled) { this.model.setMetadata('scrolled', true); } else { + this.outputArea.node.style.height = ''; this.model.deleteMetadata('scrolled'); } } @@ -1775,7 +1779,9 @@ export abstract class AttachmentsCell< continue; } items[i].getAsString(text => { - this.editor!.replaceSelection?.(text); + this.editor!.replaceSelection?.( + text.replace(/\r\n/g, '\n').replace(/\r/g, '\n') + ); }); } this._attachFiles(event.clipboardData.items); @@ -2253,10 +2259,13 @@ export class MarkdownCell extends AttachmentsCell { .getSource() .match(/^#+/g) || [''])[0].length; if (numHashAtStart > 0) { - this.inputArea!.editor.setCursorPosition({ - column: numHashAtStart + 1, - line: 0 - }); + this.inputArea!.editor.setCursorPosition( + { + column: numHashAtStart + 1, + line: 0 + }, + { scroll: false } + ); } } } diff --git a/packages/cells/test/widget.spec.ts b/packages/cells/test/widget.spec.ts index 3aab72411e9e..d00cbbe79fa4 100644 --- a/packages/cells/test/widget.spec.ts +++ b/packages/cells/test/widget.spec.ts @@ -1,7 +1,7 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { createStandaloneCell, YCodeCell } from '@jupyter/ydoc'; +import { createStandaloneCell, YCodeCell, YMarkdownCell } from '@jupyter/ydoc'; import { ISessionContext, SessionContext } from '@jupyterlab/apputils'; import { createSessionContext } from '@jupyterlab/apputils/lib/testutils'; import { @@ -998,6 +998,33 @@ describe('cells/widget', () => { }); }); + describe('#getEditorOptions()', () => { + it('should normalise line endings on paste', () => { + const model = new MarkdownCellModel({ + sharedModel: createStandaloneCell({ + cell_type: 'markdown' + }) as YMarkdownCell + }); + const widget = new MarkdownCell({ + model, + rendermime, + contentFactory, + placeholder: false + }); + widget.initializeState(); + document.body.appendChild(widget.node); + // todo: replace with user-event + const dt = new DataTransfer(); + dt.setData('text/plain', '\r\nTest\r\nString\r\n.\r\n'); + const event = new ClipboardEvent('paste', { clipboardData: dt }); + widget.editor!.host.querySelector('.cm-content')!.dispatchEvent(event); + + expect(widget.model.sharedModel.getSource()).toEqual( + '\nTest\nString\n.\n' + ); + }); + }); + describe('#rendered', () => { it('should default to true', async () => { const widget = new MarkdownCell({ diff --git a/packages/celltags-extension/package.json b/packages/celltags-extension/package.json index 8e915a94bd02..976134b6b06c 100644 --- a/packages/celltags-extension/package.json +++ b/packages/celltags-extension/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/celltags-extension", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "An extension for manipulating tags in cell metadata", "keywords": [ "jupyter", @@ -40,17 +40,17 @@ "watch": "tsc -b --watch" }, "dependencies": { - "@jupyterlab/application": "^4.1.0-alpha.2", - "@jupyterlab/notebook": "^4.1.0-alpha.2", - "@jupyterlab/translation": "^4.1.0-alpha.2", - "@jupyterlab/ui-components": "^4.1.0-alpha.2", + "@jupyterlab/application": "^4.1.6", + "@jupyterlab/notebook": "^4.1.6", + "@jupyterlab/translation": "^4.1.6", + "@jupyterlab/ui-components": "^4.1.6", "@lumino/algorithm": "^2.0.1", - "@rjsf/utils": "^5.13.2", + "@rjsf/utils": "^5.13.4", "react": "^18.2.0" }, "devDependencies": { - "rimraf": "~3.0.0", - "typescript": "~5.0.4" + "rimraf": "~5.0.5", + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/codeeditor/package.json b/packages/codeeditor/package.json index f327160c0d44..a788f66555b6 100644 --- a/packages/codeeditor/package.json +++ b/packages/codeeditor/package.json @@ -1,6 +1,6 @@ { "name": "@jupyterlab/codeeditor", - "version": "4.1.0-alpha.2", + "version": "4.1.6", "description": "JupyterLab - Abstract Code Editor", "homepage": "https://github.com/jupyterlab/jupyterlab", "bugs": { @@ -44,27 +44,28 @@ "dependencies": { "@codemirror/state": "^6.2.0", "@jupyter/ydoc": "^1.1.1", - "@jupyterlab/coreutils": "^6.1.0-alpha.2", - "@jupyterlab/nbformat": "^4.1.0-alpha.2", - "@jupyterlab/observables": "^5.1.0-alpha.2", - "@jupyterlab/statusbar": "^4.1.0-alpha.2", - "@jupyterlab/translation": "^4.1.0-alpha.2", - "@jupyterlab/ui-components": "^4.1.0-alpha.2", + "@jupyterlab/apputils": "^4.2.6", + "@jupyterlab/coreutils": "^6.1.6", + "@jupyterlab/nbformat": "^4.1.6", + "@jupyterlab/observables": "^5.1.6", + "@jupyterlab/statusbar": "^4.1.6", + "@jupyterlab/translation": "^4.1.6", + "@jupyterlab/ui-components": "^4.1.6", "@lumino/coreutils": "^2.1.2", "@lumino/disposable": "^2.1.2", - "@lumino/dragdrop": "^2.1.3", + "@lumino/dragdrop": "^2.1.4", "@lumino/messaging": "^2.0.1", "@lumino/signaling": "^2.1.2", - "@lumino/widgets": "^2.3.1-alpha.0", + "@lumino/widgets": "^2.3.1", "react": "^18.2.0" }, "devDependencies": { - "@jupyterlab/testing": "^4.1.0-alpha.2", + "@jupyterlab/testing": "^4.1.6", "@types/jest": "^29.2.0", "jest": "^29.2.0", - "rimraf": "~3.0.0", + "rimraf": "~5.0.5", "typedoc": "~0.24.7", - "typescript": "~5.0.4" + "typescript": "~5.1.6" }, "publishConfig": { "access": "public" diff --git a/packages/codeeditor/src/editor.ts b/packages/codeeditor/src/editor.ts index 286da0404e66..e0e7354a01cc 100644 --- a/packages/codeeditor/src/editor.ts +++ b/packages/codeeditor/src/editor.ts @@ -257,11 +257,15 @@ export namespace CodeEditor { * Set the primary position of the cursor. * * @param position - The new primary position. + * @param options - Adjustment options allowing to disable scrolling. * * #### Notes * This will remove any secondary cursors. */ - setCursorPosition(position: IPosition): void; + setCursorPosition( + position: IPosition, + options?: { scroll?: boolean } + ): void; /** * Returns the primary selection, never `null`. diff --git a/packages/codeeditor/src/lineCol.tsx b/packages/codeeditor/src/lineCol.tsx index 4b47a3ee5848..dfeeacfd69d4 100644 --- a/packages/codeeditor/src/lineCol.tsx +++ b/packages/codeeditor/src/lineCol.tsx @@ -16,6 +16,7 @@ import { } from '@jupyterlab/ui-components'; import React from 'react'; import { CodeEditor } from './editor'; +import { DOMUtils } from '@jupyterlab/apputils'; /** * A namespace for LineFormComponent statics. @@ -60,6 +61,10 @@ namespace LineFormComponent { * Whether the form has focus. */ hasFocus: boolean; + /** + * A generated ID for the input field + */ + textInputId: string; } } @@ -79,7 +84,8 @@ class LineFormComponent extends React.Component< this._trans = this.translator.load('jupyterlab'); this.state = { value: '', - hasFocus: false + hasFocus: false, + textInputId: DOMUtils.createDomID() + '-line-number-input' }; } @@ -106,6 +112,7 @@ class LineFormComponent extends React.Component< > -