diff --git a/packages/application-extension/src/index.ts b/packages/application-extension/src/index.ts index 18c12a1ab..b337117ee 100644 --- a/packages/application-extension/src/index.ts +++ b/packages/application-extension/src/index.ts @@ -45,6 +45,11 @@ const NOTEBOOK_FACTORY = 'Notebook'; */ const EDITOR_FACTORY = 'Editor'; +/** + * A regular expression to match path to notebooks and documents + */ +const TREE_PATTERN = new RegExp('/(notebooks|edit)/(.*)'); + /** * The command IDs used by the application plugin. */ @@ -108,22 +113,18 @@ const opener: JupyterFrontEndPlugin = { docManager: IDocumentManager ): void => { const { commands } = app; - const treePattern = new RegExp('/(notebooks|edit)/(.*)'); const command = 'router:tree'; commands.addCommand(command, { execute: (args: any) => { const parsed = args as IRouter.ILocation; - const matches = parsed.path.match(treePattern); - if (!matches) { - return; - } - - const [, , file] = matches; - if (!file) { + const matches = parsed.path.match(TREE_PATTERN) ?? []; + const [, , path] = matches; + if (!path) { return; } + const file = decodeURIComponent(path); const ext = PathExt.extname(file); app.restored.then(() => { // TODO: get factory from file type instead? @@ -140,7 +141,7 @@ const opener: JupyterFrontEndPlugin = { } }); - router.register({ command, pattern: treePattern }); + router.register({ command, pattern: TREE_PATTERN }); } }; @@ -312,20 +313,29 @@ const title: JupyterFrontEndPlugin = { h.textContent = current.title.label; widget.node.appendChild(h); widget.node.style.marginLeft = '10px'; - if (docManager) { - widget.node.onclick = async () => { - const result = await renameDialog(docManager, current.context.path); - if (result) { - h.textContent = result.path; - if (router) { - // TODO: better handle this - router.navigate(`/classic/notebooks/${result.path}`, { - skipRouting: true - }); - } - } - }; + if (!docManager) { + return; } + widget.node.onclick = async () => { + const result = await renameDialog(docManager, current.context.path); + if (result) { + const basename = PathExt.basename(result.path); + h.textContent = basename; + if (!router) { + return; + } + const current = router.current; + const matches = current.path.match(TREE_PATTERN) ?? []; + const [, route, path] = matches; + if (!route || !path) { + return; + } + const encoded = encodeURIComponent(result.path); + router.navigate(`/classic/${route}/${encoded}`, { + skipRouting: true + }); + } + }; }); } };