Browse Source

Other: Introduce DropdownPanelFocusable interface for dropdown panel contents.

Maciej Gołaszewski 8 years ago
parent
commit
7495bfcf62

+ 27 - 0
packages/ckeditor5-ui/src/dropdown/dropdownpanelfocusable.jsdoc

@@ -0,0 +1,27 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module ui/dropdown/dropdownpanelfocusable
+ */
+
+/**
+ * The dropdown panel interface interface for focusable contents. It provides two methods for managing focus of the contents
+ * of dropdown's panel.
+ *
+ * @interface module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
+ */
+
+/**
+ * Focuses the view element or first item in view collection on opening dropdown's panel.
+ *
+ * @method #focus
+ */
+
+/**
+ * Focuses the view element or last item in view collection on opening dropdown's panel.
+ *
+ * @method #focusLast
+ */

+ 1 - 1
packages/ckeditor5-ui/src/dropdown/utils.js

@@ -13,7 +13,7 @@
  * Adds a behavior to a dropdownView that focuses dropdown panel view contents on keystrokes.
  *
  * @param {module:ui/dropdown/dropdownview~DropdownView} dropdownView
- * @param panelViewContents
+ * @param {module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable} panelViewContents
  */
 export function focusDropdownContentsOnArrows( dropdownView, panelViewContents ) {
 	// If the dropdown panel is already open, the arrow down key should

+ 1 - 0
packages/ckeditor5-ui/src/list/listview.js

@@ -18,6 +18,7 @@ import '../../theme/components/list/list.css';
  * The list view class.
  *
  * @extends module:ui/view~View
+ * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
  */
 export default class ListView extends View {
 	/**

+ 8 - 0
packages/ckeditor5-ui/src/toolbar/toolbarview.js

@@ -21,6 +21,7 @@ import '../../theme/components/toolbar/toolbar.css';
  * The toolbar view class.
  *
  * @extends module:ui/view~View
+ * @implements module:ui/dropdown/dropdownpanelfocusable~DropdownPanelFocusable
  */
 export default class ToolbarView extends View {
 	/**
@@ -121,6 +122,13 @@ export default class ToolbarView extends View {
 	}
 
 	/**
+	 * Focuses the last focusable in {@link #items}.
+	 */
+	focusLast() {
+		this._focusCycler.focusLast();
+	}
+
+	/**
 	 * A utility which expands a plain toolbar configuration into
 	 * {@link module:ui/toolbar/toolbarview~ToolbarView#items} using a given component factory.
 	 *

+ 17 - 0
packages/ckeditor5-ui/tests/dropdown/button/createbuttondropdown.js

@@ -134,6 +134,23 @@ describe( 'createButtonDropdown', () => {
 				view.keystrokes.press( keyEvtData );
 				sinon.assert.calledOnce( spy );
 			} );
+
+			it( 'so "arrowup" focuses the last #item in #buttonGroupView if dropdown is open', () => {
+				const keyEvtData = {
+					keyCode: keyCodes.arrowup,
+					preventDefault: sinon.spy(),
+					stopPropagation: sinon.spy()
+				};
+				const spy = sinon.spy( view.buttonGroupView, 'focusLast' );
+
+				view.isOpen = false;
+				view.keystrokes.press( keyEvtData );
+				sinon.assert.notCalled( spy );
+
+				view.isOpen = true;
+				view.keystrokes.press( keyEvtData );
+				sinon.assert.calledOnce( spy );
+			} );
 		} );
 
 		describe( 'icon', () => {

+ 19 - 0
packages/ckeditor5-ui/tests/toolbar/toolbarview.js

@@ -234,6 +234,25 @@ describe( 'ToolbarView', () => {
 		} );
 	} );
 
+	describe( 'focusLast()', () => {
+		it( 'focuses the last focusable item in DOM', () => {
+			// No children to focus.
+			view.focusLast();
+
+			// The second child is focusable.
+			view.items.add( nonFocusable() );
+			view.items.add( focusable() );
+			view.items.add( focusable() );
+			view.items.add( focusable() );
+			view.items.add( nonFocusable() );
+
+			const spy = sinon.spy( view.items.get( 3 ), 'focus' );
+			view.focusLast();
+
+			sinon.assert.calledOnce( spy );
+		} );
+	} );
+
 	describe( 'fillFromConfig()', () => {
 		let factory;