@@ -47,6 +47,8 @@ import {
47
47
SidePanel ,
48
48
SidePanelHandler ,
49
49
SidePanelPalette ,
50
+ INotebookPathOpener ,
51
+ defaultNotebookPathOpener ,
50
52
} from '@jupyter-notebook/application' ;
51
53
52
54
import { jupyterIcon } from '@jupyter-notebook/ui-components' ;
@@ -301,15 +303,15 @@ const pages: JupyterFrontEndPlugin<void> = {
301
303
activate : (
302
304
app : JupyterFrontEnd ,
303
305
translator : ITranslator ,
304
- palette : ICommandPalette | null
306
+ palette : ICommandPalette | null ,
305
307
) : void => {
306
308
const trans = translator . load ( 'notebook' ) ;
307
309
const baseUrl = PageConfig . getBaseUrl ( ) ;
308
310
309
311
app . commands . addCommand ( CommandIDs . openLab , {
310
312
label : trans . __ ( 'Open JupyterLab' ) ,
311
313
execute : ( ) => {
312
- window . open ( ` ${ baseUrl } lab` ) ;
314
+ window . open ( URLExt . join ( baseUrl , ' lab' ) ) ;
313
315
} ,
314
316
} ) ;
315
317
const page = PageConfig . getOption ( 'notebookPage' ) ;
@@ -320,7 +322,7 @@ const pages: JupyterFrontEndPlugin<void> = {
320
322
if ( page === 'tree' ) {
321
323
app . commands . execute ( 'filebrowser:activate' ) ;
322
324
} else {
323
- window . open ( ` ${ baseUrl } tree` ) ;
325
+ window . open ( URLExt . join ( baseUrl , ' tree' ) ) ;
324
326
}
325
327
} ,
326
328
} ) ;
@@ -332,6 +334,18 @@ const pages: JupyterFrontEndPlugin<void> = {
332
334
} ,
333
335
} ;
334
336
337
+ /**
338
+ * A plugin to open paths in new browser tabs.
339
+ */
340
+ const pathOpener : JupyterFrontEndPlugin < INotebookPathOpener > = {
341
+ id : '@jupyter-notebook/application-extension:path-opener' ,
342
+ autoStart : true ,
343
+ provides : INotebookPathOpener ,
344
+ activate : ( app : JupyterFrontEnd ) : INotebookPathOpener => {
345
+ return defaultNotebookPathOpener ;
346
+ }
347
+ } ;
348
+
335
349
/**
336
350
* The default paths for a Jupyter Notebook app.
337
351
*/
@@ -361,16 +375,19 @@ const rendermime: JupyterFrontEndPlugin<IRenderMimeRegistry> = {
361
375
ISanitizer ,
362
376
IMarkdownParser ,
363
377
ITranslator ,
378
+ INotebookPathOpener ,
364
379
] ,
365
380
activate : (
366
381
app : JupyterFrontEnd ,
367
382
docManager : IDocumentManager | null ,
368
383
latexTypesetter : ILatexTypesetter | null ,
369
384
sanitizer : IRenderMime . ISanitizer | null ,
370
385
markdownParser : IMarkdownParser | null ,
371
- translator : ITranslator | null
386
+ translator : ITranslator | null ,
387
+ notebookPathOpener : INotebookPathOpener | null ,
372
388
) => {
373
389
const trans = ( translator ?? nullTranslator ) . load ( 'jupyterlab' ) ;
390
+ const opener = notebookPathOpener ?? defaultNotebookPathOpener ;
374
391
if ( docManager ) {
375
392
app . commands . addCommand ( CommandIDs . handleLink , {
376
393
label : trans . __ ( 'Handle Local Link' ) ,
@@ -382,10 +399,12 @@ const rendermime: JupyterFrontEndPlugin<IRenderMimeRegistry> = {
382
399
return docManager . services . contents
383
400
. get ( path , { content : false } )
384
401
. then ( ( model ) => {
385
- // Open in a new browser tab
386
- const url = PageConfig . getBaseUrl ( ) ;
387
- const treeUrl = URLExt . join ( url , 'tree' , model . path ) ;
388
- window . open ( treeUrl , '_blank' ) ;
402
+ const baseUrl = PageConfig . getBaseUrl ( ) ;
403
+ opener . open ( {
404
+ route : URLExt . join ( baseUrl , 'tree' ) ,
405
+ path : model . path ,
406
+ target : '_blank' ,
407
+ } )
389
408
} ) ;
390
409
} ,
391
410
} ) ;
@@ -395,18 +414,18 @@ const rendermime: JupyterFrontEndPlugin<IRenderMimeRegistry> = {
395
414
linkHandler : ! docManager
396
415
? undefined
397
416
: {
398
- handleLink : ( node : HTMLElement , path : string , id ?: string ) => {
399
- // If node has the download attribute explicitly set, use the
400
- // default browser downloading behavior.
401
- if ( node . tagName === 'A' && node . hasAttribute ( 'download' ) ) {
402
- return ;
403
- }
404
- app . commandLinker . connectNode ( node , CommandIDs . handleLink , {
405
- path,
406
- id,
407
- } ) ;
408
- } ,
417
+ handleLink : ( node : HTMLElement , path : string , id ?: string ) => {
418
+ // If node has the download attribute explicitly set, use the
419
+ // default browser downloading behavior.
420
+ if ( node . tagName === 'A' && node . hasAttribute ( 'download' ) ) {
421
+ return ;
422
+ }
423
+ app . commandLinker . connectNode ( node , CommandIDs . handleLink , {
424
+ path,
425
+ id,
426
+ } ) ;
409
427
} ,
428
+ } ,
410
429
latexTypesetter : latexTypesetter ?? undefined ,
411
430
markdownParser : markdownParser ?? undefined ,
412
431
translator : translator ?? undefined ,
@@ -1089,6 +1108,7 @@ const plugins: JupyterFrontEndPlugin<any>[] = [
1089
1108
menuSpacer ,
1090
1109
opener ,
1091
1110
pages ,
1111
+ pathOpener ,
1092
1112
paths ,
1093
1113
rendermime ,
1094
1114
shell ,
0 commit comments