return focus to the status bar buttons

when the kb shortcut dialog or the a11y checker tray close,
return focus to the button that opened it.

closes COREFE-108

test plan:
  - in rce, click on the kb short cutton in the status bar
  - close the kb shortcut dialog
  > expect focus to return to the button
  - repeat for the a11y checker
  - tab until the show-on-focus kb shortcut button above the RCE
    appears, click it, then close the dialog
  > expect focus to return to the button

Change-Id: I27ea79930e643d9908a784fbcb89900918d3be01
Reviewed-on: https://gerrit.instructure.com/204283
Tested-by: Jenkins
Reviewed-by: Clay Diffrient <cdiffrient@instructure.com>
QA-Review: Clay Diffrient <cdiffrient@instructure.com>
Product-Review: Ed Schiebel <eschiebel@instructure.com>
This commit is contained in:
Ed Schiebel 2019-08-07 16:19:35 -04:00
parent eb8d55ea48
commit 6ccad53796
5 changed files with 25 additions and 17 deletions

View File

@ -233,7 +233,9 @@
"optionalDependencies": {
"inspect-process": "^0.5"
},
"browserslist": ["extends @instructure/browserslist-config-canvas-lms"],
"browserslist": [
"extends @instructure/browserslist-config-canvas-lms"
],
"jest-junit": {
"output": "./coverage-js/junit-reports/jest.xml"
},

View File

@ -137,6 +137,7 @@ class RCEWrapper extends React.Component {
this.indicator = false;
this._elementRef = null;
this._showOnFocusButton = null;
injectTinySkin()
@ -278,14 +279,14 @@ class RCEWrapper extends React.Component {
return editors.filter(ed => ed.id === this.props.textareaId)[0];
}
onTinyMCEInstance(command) {
if (command == "mceRemoveEditor") {
let editor = this.mceInstance();
if (editor) {
onTinyMCEInstance(command, args) {
const editor = this.mceInstance();
if (editor) {
if (command == "mceRemoveEditor") {
editor.execCommand("mceNewDocument");
} // makes sure content can't persist past removal
editor.execCommand(command, false, this.props.textareaId, args);
}
this.props.tinymce.execCommand(command, false, this.props.textareaId);
}
destroy() {
@ -552,7 +553,7 @@ class RCEWrapper extends React.Component {
}
onA11yChecker = () => {
this.onTinyMCEInstance('openAccessibilityChecker', {'data-canvas-component': true})
this.onTinyMCEInstance('openAccessibilityChecker', {skip_focus: true})
}
handleShortcutKeyShortcut = (event) => {
@ -572,8 +573,10 @@ class RCEWrapper extends React.Component {
}
KBShortcutModalClosed = () => {
if(Bridge.activeEditor() === this) {
Bridge.focusActiveEditor(false)
// when the modal is opened from the showOnFocus button, focus doesn't
// get automatically returned to the button like it should.
if (this._showOnFocusButton && document.activeElement === document.body) {
this._showOnFocusButton.focus()
}
}
@ -710,6 +713,7 @@ class RCEWrapper extends React.Component {
icon: IconKeyboardShortcutsLine,
margin: 'xx-small'
}}
ref={el => this._showOnFocusButton = el}
>
{<ScreenReaderContent>{formatMessage('View keyboard shortcuts')}</ScreenReaderContent>}
</ShowOnFocusButton>

View File

@ -111,7 +111,7 @@ export default function StatusBar(props) {
>
<ScreenReaderContent>{kbshortcut}</ScreenReaderContent>
</Button>
<Button
<Button
variant="link"
icon={IconA11yLine}
title={a11y}

View File

@ -26,7 +26,7 @@ import RCEWrapper from "../../src/rce/RCEWrapper";
const textareaId = "myUniqId";
let React, fakeTinyMCE, execCommandSpy, editorCommandSpy, sd, editor;
let React, fakeTinyMCE, editorCommandSpy, sd, editor;
// ====================
// HELPERS
@ -38,6 +38,10 @@ function requireReactDeps() {
}
function createBasicElement(opts) {
if (opts && opts.textareaId) {
// so RCEWrapper.mceInstance() works
fakeTinyMCE.editors[0].id = opts.textareaId
}
let props = Object.assign({ textareaId, tinymce: fakeTinyMCE }, opts);
return new RCEWrapper(props);
}
@ -117,13 +121,11 @@ describe("RCEWrapper", () => {
editors: [editor]
};
execCommandSpy = sinon.spy(fakeTinyMCE, "execCommand");
sinon.spy(editor, "insertContent");
});
afterEach(() => {
jsdomify.destroy();
execCommandSpy.restore();
});
// ====================
@ -163,7 +165,7 @@ describe("RCEWrapper", () => {
element = createBasicElement({ textareaId: "myOtherUniqId" });
element.focus();
assert(
execCommandSpy.withArgs("mceFocus", false, "myOtherUniqId").called
editorCommandSpy.withArgs("mceFocus", false, "myOtherUniqId", undefined).called
);
});

View File

@ -18962,9 +18962,9 @@ tinycolor2@1.4.1, tinycolor2@^1.4.1:
integrity sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g=
tinymce-a11y-checker@^2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tinymce-a11y-checker/-/tinymce-a11y-checker-2.2.0.tgz#8ac8ad0fa298b2c24ad025ca3345199ce18486f3"
integrity sha512-0GSXRNZa8zhj/f1S0DGRNRPnhJ7SDg5rMRqTlSrKOb9El6eR8JxokE/jc2OPLtlCioJMhre6KUUiV8G0tlWAAQ==
version "2.3.0"
resolved "https://registry.yarnpkg.com/tinymce-a11y-checker/-/tinymce-a11y-checker-2.3.0.tgz#9698550ae50664281df7de5c08abf2fc0cf7187c"
integrity sha512-7WlvnS0zLGf+HP3QqMdvZ9jSt91ZNBcay+XDPjKlBHPIpVnF8rQdWK6QwDDenMlOu9fg/jmOYb+A799Uox24Rg==
dependencies:
"@instructure/ui-buttons" "^5"
"@instructure/ui-core" "^5"