@@ -116,6 +116,13 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
116
116
rootLayout . addWidget ( hsplitPanel ) ;
117
117
118
118
this . layout = rootLayout ;
119
+
120
+ // Added Skip to Main Link
121
+ const skipLinkWidgetHandler = ( this . _skipLinkWidgetHandler =
122
+ new Private . SkipLinkWidgetHandler ( this ) ) ;
123
+
124
+ this . add ( skipLinkWidgetHandler . skipLinkWidget , 'top' , { rank : 0 } ) ;
125
+ this . _skipLinkWidgetHandler . show ( ) ;
119
126
}
120
127
121
128
/**
@@ -349,6 +356,7 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell {
349
356
private _rightHandler : SidePanelHandler ;
350
357
private _spacer_top : Widget ;
351
358
private _spacer_bottom : Widget ;
359
+ private _skipLinkWidgetHandler : Private . SkipLinkWidgetHandler ;
352
360
private _main : Panel ;
353
361
private _translator : ITranslator = nullTranslator ;
354
362
private _currentChanged = new Signal < this, void > ( this ) ;
@@ -364,3 +372,82 @@ export namespace Shell {
364
372
*/
365
373
export type Area = 'main' | 'top' | 'left' | 'right' | 'menu' ;
366
374
}
375
+
376
+ export namespace Private {
377
+ export class SkipLinkWidgetHandler {
378
+ /**
379
+ * Construct a new skipLink widget handler.
380
+ */
381
+ constructor ( shell : INotebookShell ) {
382
+ const skipLinkWidget = ( this . _skipLinkWidget = new Widget ( ) ) ;
383
+ const skipToMain = document . createElement ( 'a' ) ;
384
+ skipToMain . href = '#first-cell' ;
385
+ skipToMain . tabIndex = 1 ;
386
+ skipToMain . text = 'Skip to Main' ;
387
+ skipToMain . className = 'skip-link' ;
388
+ skipToMain . addEventListener ( 'click' , this ) ;
389
+ skipLinkWidget . addClass ( 'jp-skiplink' ) ;
390
+ skipLinkWidget . id = 'jp-skiplink' ;
391
+ skipLinkWidget . node . appendChild ( skipToMain ) ;
392
+ }
393
+
394
+ handleEvent ( event : Event ) : void {
395
+ switch ( event . type ) {
396
+ case 'click' :
397
+ this . _focusMain ( ) ;
398
+ break ;
399
+ }
400
+ }
401
+
402
+ private _focusMain ( ) {
403
+ const input = document . querySelector (
404
+ '#main-panel .jp-InputArea-editor'
405
+ ) as HTMLInputElement ;
406
+ input . tabIndex = 1 ;
407
+ input . focus ( ) ;
408
+ }
409
+
410
+ /**
411
+ * Get the input element managed by the handler.
412
+ */
413
+ get skipLinkWidget ( ) : Widget {
414
+ return this . _skipLinkWidget ;
415
+ }
416
+
417
+ /**
418
+ * Dispose of the handler and the resources it holds.
419
+ */
420
+ dispose ( ) : void {
421
+ if ( this . isDisposed ) {
422
+ return ;
423
+ }
424
+ this . _isDisposed = true ;
425
+ this . _skipLinkWidget . node . removeEventListener ( 'click' , this ) ;
426
+ this . _skipLinkWidget . dispose ( ) ;
427
+ }
428
+
429
+ /**
430
+ * Hide the skipLink widget.
431
+ */
432
+ hide ( ) : void {
433
+ this . _skipLinkWidget . hide ( ) ;
434
+ }
435
+
436
+ /**
437
+ * Show the skipLink widget.
438
+ */
439
+ show ( ) : void {
440
+ this . _skipLinkWidget . show ( ) ;
441
+ }
442
+
443
+ /**
444
+ * Test whether the handler has been disposed.
445
+ */
446
+ get isDisposed ( ) : boolean {
447
+ return this . _isDisposed ;
448
+ }
449
+
450
+ private _skipLinkWidget : Widget ;
451
+ private _isDisposed = false ;
452
+ }
453
+ }
0 commit comments