From a26c60eaf6e72e96434167facc32d07684bdb7b4 Mon Sep 17 00:00:00 2001 From: Serena Irani <92682603+seirani@users.noreply.github.com> Date: Tue, 18 Apr 2023 20:18:27 -0400 Subject: [PATCH 1/7] Update base.css --- packages/notebook-extension/style/base.css | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/notebook-extension/style/base.css b/packages/notebook-extension/style/base.css index ddbdb15a1e..b20f55b869 100644 --- a/packages/notebook-extension/style/base.css +++ b/packages/notebook-extension/style/base.css @@ -280,3 +280,28 @@ body[data-notebook='notebooks'] overflow: hidden; white-space: nowrap; } + +.jp-skiplink { + position: absolute; + top: -100em; +} + +.jp-skiplink:focus-within { + position: absolute; + z-index: 10000; + top: 0; + left: 46%; + margin: 0 auto; + padding: 1em; + width: 15%; + box-shadow: var(--jp-elevation-z4); + border-radius: 4px; + background: var(--jp-layout-color0); + text-align: center; +} + +.jp-skiplink:focus-within a { + text-decoration: underline; + color: var(--jp-content-link-color); +} + From f6eb4fc8f4f177b2af82288610701eddfcec95d8 Mon Sep 17 00:00:00 2001 From: Serena Irani <92682603+seirani@users.noreply.github.com> Date: Tue, 18 Apr 2023 20:22:32 -0400 Subject: [PATCH 2/7] Update shell.ts --- packages/application/src/shell.ts | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index eb916291db..26e94f6c64 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -116,6 +116,14 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell { rootLayout.addWidget(hsplitPanel); this.layout = rootLayout; + + // Added Skip to Main Link + const skipLinkWidgetHandler = (this._skipLinkWidgetHandler = new Private.SkipLinkWidgetHandler( + this + )); + + this.add(skipLinkWidgetHandler.skipLinkWidget, 'top', { rank: 0 }); + this._skipLinkWidgetHandler.show(); } /** @@ -349,6 +357,7 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell { private _rightHandler: SidePanelHandler; private _spacer_top: Widget; private _spacer_bottom: Widget; + private _skipLinkWidgetHandler: Private.SkipLinkWidgetHandler; private _main: Panel; private _translator: ITranslator = nullTranslator; private _currentChanged = new Signal(this); @@ -364,3 +373,85 @@ export namespace Shell { */ export type Area = 'main' | 'top' | 'left' | 'right' | 'menu'; } + + +export namespace Private { + + export class SkipLinkWidgetHandler { + /** + * Construct a new skipLink widget handler. + */ + constructor(shell: INotebookShell) { + const skipLinkWidget = (this._skipLinkWidget = new Widget()); + const skipToMain = document.createElement('a'); + skipToMain.href = '#first-cell'; + skipToMain.tabIndex = 1; + skipToMain.text = 'Skip to Main'; + skipToMain.className = 'skip-link'; + skipToMain.addEventListener('click', this); + skipLinkWidget.addClass('jp-skiplink'); + skipLinkWidget.id = 'jp-skiplink'; + skipLinkWidget.node.appendChild(skipToMain); + } + + handleEvent(event: Event): void { + switch (event.type) { + case 'click': + this._focusMain(); + break; + } + } + + private _focusMain() { + const input = document.querySelector( + '#main-panel .jp-InputArea-editor' + ) as HTMLInputElement; + input.tabIndex = 1; + input.focus(); + } + + /** + * Get the input element managed by the handler. + */ + get skipLinkWidget(): Widget { + return this._skipLinkWidget; + } + + /** + * Dispose of the handler and the resources it holds. + */ + dispose(): void { + if (this.isDisposed) { + return; + } + this._isDisposed = true; + this._skipLinkWidget.node.removeEventListener('click', this); + this._skipLinkWidget.dispose(); + } + + /** + * Hide the skipLink widget. + */ + hide(): void { + this._skipLinkWidget.hide(); + } + + /** + * Show the skipLink widget. + */ + show(): void { + this._skipLinkWidget.show(); + } + + /** + * Test whether the handler has been disposed. + */ + get isDisposed(): boolean { + return this._isDisposed; + } + + private _skipLinkWidget: Widget; + private _isDisposed: boolean = false; + } +} + From fd27d16999476f5733ecacb12ab216ceebb7d746 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 19 Apr 2023 00:37:42 +0000 Subject: [PATCH 3/7] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- packages/application/src/shell.ts | 3 +-- packages/notebook-extension/style/base.css | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index 26e94f6c64..77329d6688 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -116,7 +116,7 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell { rootLayout.addWidget(hsplitPanel); this.layout = rootLayout; - + // Added Skip to Main Link const skipLinkWidgetHandler = (this._skipLinkWidgetHandler = new Private.SkipLinkWidgetHandler( this @@ -454,4 +454,3 @@ export namespace Private { private _isDisposed: boolean = false; } } - diff --git a/packages/notebook-extension/style/base.css b/packages/notebook-extension/style/base.css index b20f55b869..9921ad121f 100644 --- a/packages/notebook-extension/style/base.css +++ b/packages/notebook-extension/style/base.css @@ -304,4 +304,3 @@ body[data-notebook='notebooks'] text-decoration: underline; color: var(--jp-content-link-color); } - From 7260268bb3391b5a2a11a29a051494fd15a87511 Mon Sep 17 00:00:00 2001 From: Serena Irani <92682603+seirani@users.noreply.github.com> Date: Fri, 21 Apr 2023 11:11:10 -0400 Subject: [PATCH 4/7] prettier lint test fixes --- packages/application/src/shell.ts | 55 +++++++++++++++---------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index 77329d6688..f4d06aaf28 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -118,9 +118,8 @@ export class NotebookShell extends Widget implements JupyterFrontEnd.IShell { this.layout = rootLayout; // Added Skip to Main Link - const skipLinkWidgetHandler = (this._skipLinkWidgetHandler = new Private.SkipLinkWidgetHandler( - this - )); + const skipLinkWidgetHandler = (this._skipLinkWidgetHandler = + new Private.SkipLinkWidgetHandler(this)); this.add(skipLinkWidgetHandler.skipLinkWidget, 'top', { rank: 0 }); this._skipLinkWidgetHandler.show(); @@ -374,37 +373,35 @@ export namespace Shell { export type Area = 'main' | 'top' | 'left' | 'right' | 'menu'; } - export namespace Private { - export class SkipLinkWidgetHandler { - /** - * Construct a new skipLink widget handler. - */ - constructor(shell: INotebookShell) { - const skipLinkWidget = (this._skipLinkWidget = new Widget()); - const skipToMain = document.createElement('a'); - skipToMain.href = '#first-cell'; - skipToMain.tabIndex = 1; - skipToMain.text = 'Skip to Main'; - skipToMain.className = 'skip-link'; - skipToMain.addEventListener('click', this); - skipLinkWidget.addClass('jp-skiplink'); - skipLinkWidget.id = 'jp-skiplink'; - skipLinkWidget.node.appendChild(skipToMain); - } + /** + * Construct a new skipLink widget handler. + */ + constructor(shell: INotebookShell) { + const skipLinkWidget = (this._skipLinkWidget = new Widget()); + const skipToMain = document.createElement('a'); + skipToMain.href = '#first-cell'; + skipToMain.tabIndex = 1; + skipToMain.text = 'Skip to Main'; + skipToMain.className = 'skip-link'; + skipToMain.addEventListener('click', this); + skipLinkWidget.addClass('jp-skiplink'); + skipLinkWidget.id = 'jp-skiplink'; + skipLinkWidget.node.appendChild(skipToMain); + } - handleEvent(event: Event): void { - switch (event.type) { - case 'click': - this._focusMain(); - break; + handleEvent(event: Event): void { + switch (event.type) { + case 'click': + this._focusMain(); + break; + } } - } - private _focusMain() { - const input = document.querySelector( - '#main-panel .jp-InputArea-editor' + private _focusMain() { + const input = document.querySelector( + '#main-panel .jp-InputArea-editor' ) as HTMLInputElement; input.tabIndex = 1; input.focus(); From 0718da1ea8754d760a90fa17d40dabf908f8ce96 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Mon, 24 Apr 2023 09:11:33 +0200 Subject: [PATCH 5/7] Fix ESLint error --- packages/application/src/shell.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/application/src/shell.ts b/packages/application/src/shell.ts index f4d06aaf28..405ca1e1d8 100644 --- a/packages/application/src/shell.ts +++ b/packages/application/src/shell.ts @@ -448,6 +448,6 @@ export namespace Private { } private _skipLinkWidget: Widget; - private _isDisposed: boolean = false; + private _isDisposed = false; } } From 767e3daa4924c40dec937923b5c580dbf046419d Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Thu, 4 May 2023 10:18:54 +0200 Subject: [PATCH 6/7] Update tests --- packages/application/test/shell.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/application/test/shell.spec.ts b/packages/application/test/shell.spec.ts index 74ff75842f..4592600f4d 100644 --- a/packages/application/test/shell.spec.ts +++ b/packages/application/test/shell.spec.ts @@ -28,12 +28,17 @@ describe('Shell for notebooks', () => { expect(shell).toBeInstanceOf(NotebookShell); }); - it('should make all areas empty initially', () => { - ['main', 'top', 'left', 'right', 'menu'].forEach((area) => { + it('should make some areas empty initially', () => { + ['main', 'left', 'right', 'menu'].forEach((area) => { const widgets = Array.from(shell.widgets(area as Shell.Area)); expect(widgets.length).toEqual(0); }); }); + + it('should have the skip link widget in the top area initially', () => { + const widgets = Array.from(shell.widgets('top')); + expect(widgets.length).toEqual(1); + }); }); describe('#widgets()', () => { From 6bfdd1304181d64438c177a2b33b12d88c857430 Mon Sep 17 00:00:00 2001 From: Jeremy Tuloup Date: Thu, 4 May 2023 10:29:49 +0200 Subject: [PATCH 7/7] Update more tests --- packages/application/test/shell.spec.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/application/test/shell.spec.ts b/packages/application/test/shell.spec.ts index 4592600f4d..109d8b69cf 100644 --- a/packages/application/test/shell.spec.ts +++ b/packages/application/test/shell.spec.ts @@ -137,12 +137,17 @@ describe('Shell for tree view', () => { expect(shell).toBeInstanceOf(NotebookShell); }); - it('should make all areas empty initially', () => { - ['main', 'top', 'left', 'right', 'menu'].forEach((area) => { + it('should make some areas empty initially', () => { + ['main', 'left', 'right', 'menu'].forEach((area) => { const widgets = Array.from(shell.widgets(area as Shell.Area)); expect(widgets.length).toEqual(0); }); }); + + it('should have the skip link widget in the top area initially', () => { + const widgets = Array.from(shell.widgets('top')); + expect(widgets.length).toEqual(1); + }); }); describe('#widgets()', () => {