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