Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard handling for grid components in font color and list style #12202

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
dd4e5e6
poc for colors and list properties
mmotyczynska Jul 14, 2022
bdf35cb
poc for tables
mmotyczynska Jul 18, 2022
7159662
Special characters arrow navigation
mmotyczynska Jul 19, 2022
f30aafd
Change addKeyboardHandlingForGrid to pass reference to children colle…
mmotyczynska Jul 19, 2022
04bb929
Create parent view for special characters
mmotyczynska Jul 19, 2022
b0c8e4d
Finish handling of arrowup in grid navigation.
mmotyczynska Jul 28, 2022
4f019d3
Fix naviagation for insert table grid (arrowright, arrowleft).
mmotyczynska Jul 28, 2022
387c6e1
Merge remote-tracking branch 'origin/master' into ck/11851-keyboard-h…
mmotyczynska Jul 28, 2022
cf0ece8
Fix navigation with tab in special characters
mmotyczynska Jul 28, 2022
28f2acd
Merge remote-tracking branch 'origin/master' into ck/11851-keyboard-h…
mmotyczynska Jul 28, 2022
62a604c
Some code adjusting.
mmotyczynska Aug 1, 2022
1d0dbdc
Move addKeyboardHandlingForGrid to ui/bindings.
mmotyczynska Aug 2, 2022
ce0a42f
Add arrow navigation to bulleted list.
mmotyczynska Aug 2, 2022
5690290
Improve tab navigation in list styles (tab no longer moves focus betw…
mmotyczynska Aug 2, 2022
ccb2792
Fix 'start at' in list properties by moving keystroke handlers for li…
mmotyczynska Aug 2, 2022
516eb51
Move keyboard navigation handlers to the ColorGridView - this adds na…
mmotyczynska Aug 2, 2022
f500ad0
Fix navigation with tab for font color dropdowns.
mmotyczynska Aug 2, 2022
9fd48cc
Remove focusCycler form ColorGridView because now the keystrokes (arr…
mmotyczynska Aug 2, 2022
111782a
Get focused element using FocusTracker instead of document.activeElem…
mmotyczynska Aug 2, 2022
3c94673
Change the function parameter from view to keystrokes.
mmotyczynska Aug 3, 2022
a12ec03
Change grid view collection listeners from 'add/remove' to 'change'.
mmotyczynska Aug 3, 2022
36065c3
Fix inserting tables after removing view parameter from the helper.
mmotyczynska Aug 3, 2022
5497d76
Improve focusTracker for InsertTableView.
mmotyczynska Aug 3, 2022
8e5a42f
Merge remote-tracking branch 'origin/master' into ck/11851-keyboard-h…
mmotyczynska Aug 3, 2022
9f28dc2
Add keyboard navigation only when there is styles grid.
mmotyczynska Aug 4, 2022
d607ff4
Remove test for focus cycler in ColorGridView.
mmotyczynska Aug 4, 2022
e735c34
Ensure every grid has its own focusTrackers and pass it to helper fun…
mmotyczynska Aug 4, 2022
6d19dca
Add document colors grid to focus tracker in a right place. Change or…
mmotyczynska Aug 5, 2022
7f6b334
Update tests of listpropertiesview after moving grid elements to the …
mmotyczynska Aug 5, 2022
c09629f
Modify tests for list properties for tab, shift+tab and arrowright ke…
mmotyczynska Aug 8, 2022
5746bd0
Update tests for special characters after grouping navigation, grid a…
mmotyczynska Aug 8, 2022
2caba6f
Merge remote-tracking branch 'origin/master' into ck/11851-keyboard-h…
mmotyczynska Aug 8, 2022
0f04cbf
Unit test for focus() in charactergridview.
mmotyczynska Aug 8, 2022
087b28c
Remove some unnecessary comments from specialcharactersview.js.
mmotyczynska Aug 8, 2022
ecf7c09
Add test for focus() in specialcharactersview.js.
mmotyczynska Aug 8, 2022
131bd3e
Improve cc for inserttableview.js.
mmotyczynska Aug 8, 2022
e6528b4
Destroy view in afterEach in inserttableview.js tests.
mmotyczynska Aug 9, 2022
86a29a1
Add test when nothing is focused in inserttableview.js.
mmotyczynska Aug 9, 2022
027b0a1
Add unit tests for addKeyboardHandlingForGrid helper.
mmotyczynska Aug 9, 2022
b4550a9
Merge remote-tracking branch 'origin/master' into ck/11851-keyboard-h…
mmotyczynska Aug 9, 2022
4fa70e7
Docs added. The name of function changed: getFocusedElementIndex.
mmotyczynska Aug 10, 2022
a94610e
Refactor of addKeyboardHandlingForGrid helper.
mmotyczynska Aug 10, 2022
beae189
Do not convert collection to an array.
mmotyczynska Aug 10, 2022
b925457
Fix typo.
mmotyczynska Aug 10, 2022
8a5af96
Use number of columns from the configuration.
mmotyczynska Aug 10, 2022
c278ac8
Refactor tests for addKeyboardHandlingForGrid.js.
mmotyczynska Aug 10, 2022
2c74741
Move TestView class definition into describe scope.
mmotyczynska Aug 10, 2022
4cfa57a
Move stylesView.keystrokes initialization to _createStylesView.
mmotyczynska Aug 10, 2022
2568b6a
Code refactoring fro getGridItemFocuser (use collection api).
mmotyczynska Aug 10, 2022
8eeea65
Revert special characters keyboard navigation to handle it in a diffe…
mmotyczynska Aug 10, 2022
d61f7f0
Revert insert table keyboard navigation to handle it in a different b…
mmotyczynska Aug 10, 2022
9c925db
Set default number of columns in a color grid.
mmotyczynska Aug 11, 2022
861f4cd
Move stylesView keystroke initialization to _createStylesView.
mmotyczynska Aug 11, 2022
d3bde2d
Merge branch 'master' into ck/11851-keyboard-handling-for-grid-compon…
oleq Aug 12, 2022
e90ff17
Refactored the arguments of addKeyboardHandlingForGrid() into an obje…
oleq Aug 12, 2022
4bf588d
Rename addKeyboardHandlingForGrid.js to addkeyboardhandlingforgrid.js
oleq Aug 12, 2022
f13f149
Rename addKeyboardHandlingForGrid.js to addkeyboardhandlingforgrid.js
oleq Aug 12, 2022
8e67abd
Tests: Code refactoring in ListPropertyView tests.
oleq Aug 12, 2022
7f842d4
Tests: Additional tests for the ColorTableView.
oleq Aug 12, 2022
915f7a6
Fixed import paths in several files to use lower case.
oleq Aug 12, 2022
f8ef863
Tests: Additional tests for the keyboard navigation in the ColorGridV…
oleq Aug 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 36 additions & 13 deletions packages/ckeditor5-font/src/ui/colortableview.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,16 @@
*/

import { icons } from 'ckeditor5/src/core';
import { ButtonView, ColorGridView, ColorTileView, FocusCycler, LabelView, Template, View } from 'ckeditor5/src/ui';
import {
ButtonView,
ColorGridView,
ColorTileView,
FocusCycler,
LabelView,
Template,
View,
ViewCollection
} from 'ckeditor5/src/ui';
import { FocusTracker, KeystrokeHandler } from 'ckeditor5/src/utils';

import DocumentColorCollection from '../documentcolorcollection';
Expand Down Expand Up @@ -109,6 +118,15 @@ export default class ColorTableView extends View {
*/
this.documentColorsCount = documentColorsCount;

/**
* A collection of views that can be focused in the view.
*
* @readonly
* @protected
* @member {module:ui/viewcollection~ViewCollection}
*/
this._focusables = new ViewCollection();

/**
* Preserves the reference to {@link module:ui/colorgrid/colorgrid~ColorGridView} used to create
* the default (static) color set.
Expand Down Expand Up @@ -137,15 +155,15 @@ export default class ColorTableView extends View {
* @member {module:ui/focuscycler~FocusCycler}
*/
this._focusCycler = new FocusCycler( {
focusables: this.items,
focusables: this._focusables,
focusTracker: this.focusTracker,
keystrokeHandler: this.keystrokes,
actions: {
// Navigate list items backwards using the Arrow Up key.
focusPrevious: 'arrowup',
// Navigate list items backwards using the <kbd>Shift</kbd> + <kbd>Tab</kbd> keystroke.
focusPrevious: 'shift + tab',

// Navigate list items forwards using the Arrow Down key.
focusNext: 'arrowdown'
// Navigate list items forwards using the <kbd>Tab</kbd> key.
focusNext: 'tab'
}
} );

Expand All @@ -169,7 +187,7 @@ export default class ColorTableView extends View {
children: this.items
} );

this.items.add( this._removeColorButton() );
this.items.add( this._createRemoveColorButton() );
}

/**
Expand Down Expand Up @@ -226,11 +244,6 @@ export default class ColorTableView extends View {
render() {
super.render();

// Items added before rendering should be known to the #focusTracker.
for ( const item of this.items ) {
this.focusTracker.add( item.element );
}

// Start listening for the keystrokes coming from #element.
this.keystrokes.listenTo( this.element );
}
Expand All @@ -256,6 +269,8 @@ export default class ColorTableView extends View {
this.staticColorsGrid = this._createStaticColorsGrid();

this.items.add( this.staticColorsGrid );
this.focusTracker.add( this.staticColorsGrid.element );
this._focusables.add( this.staticColorsGrid );

if ( this.documentColorsCount ) {
// Create a label for document colors.
Expand All @@ -273,7 +288,10 @@ export default class ColorTableView extends View {
} );
this.items.add( label );
this.documentColorsGrid = this._createDocumentColorsGrid();

this.items.add( this.documentColorsGrid );
this.focusTracker.add( this.documentColorsGrid.element );
this._focusables.add( this.documentColorsGrid );
}
}

Expand All @@ -297,7 +315,7 @@ export default class ColorTableView extends View {
* @private
* @returns {module:ui/button/buttonview~ButtonView}
*/
_removeColorButton() {
_createRemoveColorButton() {
const buttonView = new ButtonView();

buttonView.set( {
Expand All @@ -312,6 +330,11 @@ export default class ColorTableView extends View {
this.fire( 'execute', { value: null } );
} );

buttonView.render();

this.focusTracker.add( buttonView.element );
this._focusables.add( buttonView );

return buttonView;
}

Expand Down
81 changes: 71 additions & 10 deletions packages/ckeditor5-font/tests/ui/colortableview.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,24 @@

/* globals document,Event */

import TestColorPlugin from '../_utils/testcolorplugin';
import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import ColorTableView from './../../src/ui/colortableview';
import ColorTileView from '@ckeditor/ckeditor5-ui/src/colorgrid/colortileview';

import Collection from '@ckeditor/ckeditor5-utils/src/collection';
import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection';
import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler';
import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg';
import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
import global from '@ckeditor/ckeditor5-utils/src/dom/global';

import TestColorPlugin from '../_utils/testcolorplugin';
import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
import ColorTileView from '@ckeditor/ckeditor5-ui/src/colorgrid/colortileview';
import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
import global from '@ckeditor/ckeditor5-utils/src/dom/global';

import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg';

describe( 'ColorTableView', () => {
let locale, colorTableView;
Expand Down Expand Up @@ -79,12 +83,16 @@ describe( 'ColorTableView', () => {
documentColorsLabel: 'Document colors',
documentColorsCount: 4
} );
colorTableView.appendGrids();
// Grids rendering is deferred (#6192) therefore render happens before appending grids.
colorTableView.render();
colorTableView.appendGrids();

document.body.appendChild( colorTableView.element );
} );

afterEach( () => {
colorTableView.destroy();
colorTableView.element.remove();
} );

testUtils.createSinonSandbox();
Expand Down Expand Up @@ -163,22 +171,74 @@ describe( 'ColorTableView', () => {
} );
} );

describe( 'focus tracker', () => {
it( 'should focus first child of colorTableView in DOM', () => {
describe( 'focus tracking', () => {
it( 'should focus first child of colorTableView in DOM on focus()', () => {
const spy = sinon.spy( colorTableView._focusCycler, 'focusFirst' );

colorTableView.focus();

sinon.assert.calledOnce( spy );
} );

it( 'should focuses the last child of colorTableView in DOM', () => {
it( 'should focus the last child of colorTableView in DOM on focusLast()', () => {
const spy = sinon.spy( colorTableView._focusCycler, 'focusLast' );

colorTableView.focusLast();

sinon.assert.calledOnce( spy );
} );

describe( 'navigation across table controls using Tab and Shift+Tab keys', () => {
beforeEach( () => {
// Needed for the document colors grid to show up in the view.
colorTableView.documentColors.add( {
color: '#000000',
label: 'Black',
options: {
hasBorder: false
}
} );
} );

it( 'should navigate forwards using the Tab key', () => {
const keyEvtData = {
keyCode: keyCodes.tab,
preventDefault: sinon.spy(),
stopPropagation: sinon.spy()
};

// Mock the remove color button is focused.
colorTableView.focusTracker.isFocused = true;
colorTableView.focusTracker.focusedElement = colorTableView.items.get( 0 ).element;

const spy = sinon.spy( colorTableView.staticColorsGrid, 'focus' );

colorTableView.keystrokes.press( keyEvtData );
sinon.assert.calledOnce( keyEvtData.preventDefault );
sinon.assert.calledOnce( keyEvtData.stopPropagation );
sinon.assert.calledOnce( spy );
} );

it( 'should navigate backwards using the Shift+Tab key', () => {
const keyEvtData = {
keyCode: keyCodes.tab,
shiftKey: true,
preventDefault: sinon.spy(),
stopPropagation: sinon.spy()
};

// Mock the remove color button is focused.
colorTableView.focusTracker.isFocused = true;
colorTableView.focusTracker.focusedElement = colorTableView.items.get( 0 ).element;

const spy = sinon.spy( colorTableView.documentColorsGrid, 'focus' );

colorTableView.keystrokes.press( keyEvtData );
sinon.assert.calledOnce( keyEvtData.preventDefault );
sinon.assert.calledOnce( keyEvtData.stopPropagation );
sinon.assert.calledOnce( spy );
} );
} );
} );

describe( 'remove color button', () => {
Expand Down Expand Up @@ -382,8 +442,9 @@ describe( 'ColorTableView', () => {
removeButtonLabel: 'Remove color',
documentColorsCount: 0
} );
colorTableView.appendGrids();
// Grids rendering is deferred (#6192) therefore render happens before appending grids.
colorTableView.render();
colorTableView.appendGrids();
} );

afterEach( () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import {
FocusCycler,
SwitchButtonView,
LabeledFieldView,
createLabeledInputNumber
createLabeledInputNumber,
addKeyboardHandlingForGrid
} from 'ckeditor5/src/ui';
import {
FocusTracker,
Expand Down Expand Up @@ -178,19 +179,25 @@ export default class ListPropertiesView extends View {
super.render();

if ( this.stylesView ) {
for ( const styleButtonView of this.stylesView.children ) {
// Register the view as focusable.
this.focusables.add( styleButtonView );

// Register the view in the focus tracker.
this.focusTracker.add( styleButtonView.element );
}
this.focusables.add( this.stylesView );
this.focusTracker.add( this.stylesView.element );

// Register the collapsible toggle button to the focus system.
if ( this.startIndexFieldView || this.reversedSwitchButtonView ) {
this.focusables.add( this.children.last.buttonView );
this.focusTracker.add( this.children.last.buttonView.element );
}

for ( const item of this.stylesView.children ) {
this.stylesView.focusTracker.add( item.element );
}

addKeyboardHandlingForGrid( {
keystrokeHandler: this.stylesView.keystrokes,
focusTracker: this.stylesView.focusTracker,
gridItems: this.stylesView.children,
numberOfColumns: 4
} );
}

if ( this.startIndexFieldView ) {
Expand Down Expand Up @@ -276,6 +283,17 @@ export default class ListPropertiesView extends View {

stylesView.children.delegate( 'execute' ).to( this );

stylesView.focus = function() {
this.children.first.focus();
};

stylesView.focusTracker = new FocusTracker();
stylesView.keystrokes = new KeystrokeHandler();

stylesView.render();

stylesView.keystrokes.listenTo( stylesView.element );

return stylesView;
}

Expand Down
Loading