浏览代码

Other: Remove ButtonGroupView and use ToolbarView in button dropdown.

Maciej Gołaszewski 8 年之前
父节点
当前提交
b8164f7338

+ 0 - 128
packages/ckeditor5-ui/src/buttongroup/buttongroupview.js

@@ -1,128 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module ui/buttongroup/buttongroupview
- */
-
-import View from '../view';
-import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
-import FocusCycler from '../focuscycler';
-import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
-
-import '../../theme/components/buttongroup.css';
-
-/**
- * The button group view class.
- *
- * @extends module:ui/view~View
- */
-export default class ButtonGroupView extends View {
-	/**
-	 * @inheritDoc
-	 */
-	constructor( options = {} ) {
-		super();
-
-		/**
-		 * Collection of the child button views.
-		 *
-		 * @readonly
-		 * @member {module:ui/viewcollection~ViewCollection}
-		 */
-		this.items = this.createCollection();
-
-		/**
-		 * Tracks information about DOM focus in the group.
-		 *
-		 * @readonly
-		 * @member {module:utils/focustracker~FocusTracker}
-		 */
-		this.focusTracker = new FocusTracker();
-
-		/**
-		 * Instance of the {@link module:utils/keystrokehandler~KeystrokeHandler}.
-		 *
-		 * @readonly
-		 * @member {module:utils/keystrokehandler~KeystrokeHandler}
-		 */
-		this.keystrokes = new KeystrokeHandler();
-
-		/**
-		 * Helps cycling over focusable {@link #items} in the group.
-		 *
-		 * @readonly
-		 * @protected
-		 * @member {module:ui/focuscycler~FocusCycler}
-		 */
-		this._focusCycler = new FocusCycler( {
-			focusables: this.items,
-			focusTracker: this.focusTracker,
-			keystrokeHandler: this.keystrokes,
-			actions: {
-				// Navigate list items backwards using the arrowup key.
-				focusPrevious: [ 'arrowup', 'arrowleft' ],
-
-				// Navigate toolbar items forwards using the arrowdown key.
-				focusNext: [ 'arrowdown', 'arrowright' ]
-			}
-		} );
-
-		this.set( 'isVertical', !!options.isVertical );
-
-		const bind = this.bindTemplate;
-
-		this.setTemplate( {
-			tag: 'div',
-
-			attributes: {
-				class: [
-					'ck-reset',
-					'ck-button-group',
-					bind.if( 'isVertical', 'ck-button-group__vertical' )
-				]
-			},
-
-			children: this.items
-		} );
-	}
-
-	/**
-	 * @inheritDoc
-	 */
-	render() {
-		super.render();
-
-		// Items added before rendering should be known to the #focusTracker.
-		for ( const item of this.items ) {
-			this.focusTracker.add( item.element );
-		}
-
-		this.items.on( 'add', ( evt, item ) => {
-			this.focusTracker.add( item.element );
-		} );
-
-		this.items.on( 'remove', ( evt, item ) => {
-			this.focusTracker.remove( item.element );
-		} );
-
-		// Start listening for the keystrokes coming from #element.
-		this.keystrokes.listenTo( this.element );
-	}
-
-	/**
-	 * Focuses the first focusable in {@link #items}.
-	 */
-	focus() {
-		this._focusCycler.focusFirst();
-	}
-
-	/**
-	 * Focuses the last focusable in {@link #items}.
-	 */
-	focusLast() {
-		this._focusCycler.focusLast();
-	}
-}

+ 12 - 4
packages/ckeditor5-ui/src/dropdown/button/createbuttondropdown.js

@@ -9,7 +9,7 @@
 
 
 import createDropdown from '../createdropdown';
 import createDropdown from '../createdropdown';
 
 
-import ButtonGroupView from '../../buttongroup/buttongroupview';
+import ToolbarView from '../../toolbar/toolbarview';
 import { closeDropdownOnBlur, closeDropdownOnExecute, openDropdownOnArrows } from '../utils';
 import { closeDropdownOnBlur, closeDropdownOnExecute, openDropdownOnArrows } from '../utils';
 
 
 import '../../../theme/components/dropdown/buttondropdown.css';
 import '../../../theme/components/dropdown/buttondropdown.css';
@@ -80,15 +80,23 @@ export default function createButtonDropdown( model, buttonViews, locale ) {
 
 
 	const dropdownView = createDropdown( model, locale );
 	const dropdownView = createDropdown( model, locale );
 
 
-	const buttonGroupView = dropdownView.buttonGroupView = new ButtonGroupView( { isVertical: model.isVertical } );
+	const buttonGroupView = dropdownView.buttonGroupView = new ToolbarView();
+
+	buttonGroupView.extendTemplate( {
+		attributes: {
+			class: [
+				buttonGroupView.bindTemplate.if( 'isVertical', 'ck-toolbar__vertical' )
+			]
+		}
+	} );
 
 
 	buttonGroupView.bind( 'isVertical' ).to( model, 'isVertical' );
 	buttonGroupView.bind( 'isVertical' ).to( model, 'isVertical' );
 
 
 	buttonViews.map( view => buttonGroupView.items.add( view ) );
 	buttonViews.map( view => buttonGroupView.items.add( view ) );
 
 
-	dropdownView.buttonView.extendTemplate( {
+	dropdownView.extendTemplate( {
 		attributes: {
 		attributes: {
-			class: [ 'ck-button-dropdown' ]
+			class: [ 'ck-buttondropdown' ]
 		}
 		}
 	} );
 	} );
 
 

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

@@ -9,12 +9,12 @@
 
 
 /* global document */
 /* global document */
 
 
-export function openDropdownOnArrows( dropdownView, buttonGroupView ) {
+export function openDropdownOnArrows( dropdownView, panelViewContents ) {
 	// If the dropdown panel is already open, the arrow down key should
 	// If the dropdown panel is already open, the arrow down key should
 	// focus the first element in list.
 	// focus the first element in list.
 	dropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {
 	dropdownView.keystrokes.set( 'arrowdown', ( data, cancel ) => {
 		if ( dropdownView.isOpen ) {
 		if ( dropdownView.isOpen ) {
-			buttonGroupView.focus();
+			panelViewContents.focus();
 			cancel();
 			cancel();
 		}
 		}
 	} );
 	} );
@@ -23,7 +23,7 @@ export function openDropdownOnArrows( dropdownView, buttonGroupView ) {
 	// focus the last element in the list.
 	// focus the last element in the list.
 	dropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {
 	dropdownView.keystrokes.set( 'arrowup', ( data, cancel ) => {
 		if ( dropdownView.isOpen ) {
 		if ( dropdownView.isOpen ) {
-			buttonGroupView.focusLast();
+			panelViewContents.focusLast();
 			cancel();
 			cancel();
 		}
 		}
 	} );
 	} );

+ 0 - 195
packages/ckeditor5-ui/tests/buttongroup/buttongroupview.js

@@ -1,195 +0,0 @@
-/**
- * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
-import ButtonGroupView from '../../src/buttongroup/buttongroupview';
-import ButtonView from '../../src/button/buttonview';
-import ViewCollection from '../../src/viewcollection';
-import FocusCycler from '../../src/focuscycler';
-import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
-import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler';
-import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
-
-testUtils.createSinonSandbox();
-
-describe( 'ButtonGroupView', () => {
-	let view;
-
-	beforeEach( () => {
-		view = new ButtonGroupView();
-		view.render();
-	} );
-
-	describe( 'constructor()', () => {
-		it( 'creates element from template', () => {
-			expect( view.element.classList.contains( 'ck-reset' ) ).to.be.true;
-			expect( view.element.classList.contains( 'ck-button-group' ) ).to.be.true;
-			expect( view.element.classList.contains( 'ck-button-group__vertical' ) ).to.be.false;
-		} );
-
-		it( 'creates view#items collection', () => {
-			expect( view.items ).to.be.instanceOf( ViewCollection );
-			expect( view.template.children ).to.have.length( 1 );
-			expect( view.template.children[ 0 ] ).to.equal( view.items );
-		} );
-
-		it( 'creates #focusTracker instance', () => {
-			expect( view.focusTracker ).to.be.instanceOf( FocusTracker );
-		} );
-
-		it( 'creates #keystrokeHandler instance', () => {
-			expect( view.keystrokes ).to.be.instanceOf( KeystrokeHandler );
-		} );
-
-		it( 'creates #_focusCycler instance', () => {
-			expect( view._focusCycler ).to.be.instanceOf( FocusCycler );
-		} );
-	} );
-
-	describe( 'DOM bindings', () => {
-		describe( '"class" attribute', () => {
-			it( 'is set from options', () => {
-				view = new ButtonGroupView( { isVertical: true } );
-				view.render();
-
-				expect( view.element.classList.contains( 'ck-button-group__vertical' ) ).to.be.true;
-			} );
-
-			it( 'reacts to view#isVertical', () => {
-				expect( view.element.classList.contains( 'ck-button-group__vertical' ) ).to.be.false;
-
-				view.isVertical = true;
-
-				expect( view.element.classList.contains( 'ck-button-group__vertical' ) ).to.be.true;
-			} );
-		} );
-	} );
-
-	describe( 'render()', () => {
-		it( 'registers #items in #focusTracker', () => {
-			const view = new ButtonGroupView();
-
-			const spyAdd = sinon.spy( view.focusTracker, 'add' );
-			const spyRemove = sinon.spy( view.focusTracker, 'remove' );
-
-			sinon.assert.notCalled( spyAdd );
-			view.items.add( new ButtonView() );
-			view.items.add( new ButtonView() );
-
-			view.render();
-			sinon.assert.calledTwice( spyAdd );
-
-			view.items.remove( 1 );
-			sinon.assert.calledOnce( spyRemove );
-
-			view.items.add( new ButtonView() );
-			sinon.assert.calledThrice( spyAdd );
-
-			view.destroy();
-		} );
-
-		it( 'starts listening for #keystrokes coming from #element', () => {
-			const view = new ButtonGroupView();
-			const spy = sinon.spy( view.keystrokes, 'listenTo' );
-
-			view.render();
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWithExactly( spy, view.element );
-
-			view.destroy();
-		} );
-
-		describe( 'activates keyboard navigation for the group', () => {
-			it( 'so "arrowup" focuses previous item', () => {
-				testFocusCycle( {
-					keyCode: keyCodes.arrowup,
-					currentlyFocused: 3,
-					shouldBeFocused: 2
-				} );
-			} );
-
-			it( 'so "arrowleft" focuses previous item', () => {
-				testFocusCycle( {
-					keyCode: keyCodes.arrowleft,
-					currentlyFocused: 3,
-					shouldBeFocused: 2
-				} );
-			} );
-
-			it( 'so "arrowdown" focuses next item', () => {
-				testFocusCycle( {
-					keyCode: keyCodes.arrowdown,
-					currentlyFocused: 1,
-					shouldBeFocused: 2
-				} );
-			} );
-
-			it( 'so "arrowright" focuses next item', () => {
-				testFocusCycle( {
-					keyCode: keyCodes.arrowright,
-					currentlyFocused: 1,
-					shouldBeFocused: 2
-				} );
-			} );
-
-			function testFocusCycle( parameters ) {
-				const { keyCode, currentlyFocused, shouldBeFocused } = parameters;
-
-				const keyEvtData = {
-					keyCode,
-					preventDefault: sinon.spy(),
-					stopPropagation: sinon.spy()
-				};
-
-				// No children to focus.
-				view.keystrokes.press( keyEvtData );
-				sinon.assert.calledOnce( keyEvtData.preventDefault );
-				sinon.assert.calledOnce( keyEvtData.stopPropagation );
-
-				view.items.add( new ButtonView() );
-				view.items.add( new ButtonView() );
-				view.items.add( new ButtonView() );
-				view.items.add( new ButtonView() );
-
-				// Mock the item is focused.
-				view.focusTracker.isFocused = true;
-				view.focusTracker.focusedElement = view.items.get( currentlyFocused ).element;
-
-				const spy = sinon.spy( view.items.get( shouldBeFocused ), 'focus' );
-				view.keystrokes.press( keyEvtData );
-
-				sinon.assert.calledTwice( keyEvtData.preventDefault );
-				sinon.assert.calledTwice( keyEvtData.stopPropagation );
-				sinon.assert.calledOnce( spy );
-			}
-		} );
-	} );
-
-	describe( 'focus()', () => {
-		it( 'focuses the first button in DOM', () => {
-			view.items.add( new ButtonView() );
-			view.items.add( new ButtonView() );
-
-			const spy = sinon.spy( view.items.get( 0 ), 'focus' );
-
-			view.focus();
-
-			sinon.assert.calledOnce( spy );
-		} );
-	} );
-
-	describe( 'focusLast()', () => {
-		it( 'focuses the last button in DOM', () => {
-			view.items.add( new ButtonView() );
-			view.items.add( new ButtonView() );
-
-			const spy = sinon.spy( view.items.get( 1 ), 'focus' );
-
-			view.focusLast();
-
-			sinon.assert.calledOnce( spy );
-		} );
-	} );
-} );

+ 2 - 19
packages/ckeditor5-ui/tests/dropdown/button/createbuttondropdown.js

@@ -9,7 +9,7 @@ import Model from '../../../src/model';
 import createButtonDropdown from '../../../src/dropdown/button/createbuttondropdown';
 import createButtonDropdown from '../../../src/dropdown/button/createbuttondropdown';
 
 
 import ButtonView from '../../../src/button/buttonview';
 import ButtonView from '../../../src/button/buttonview';
-import ButtonGroupView from '../../../src/buttongroup/buttongroupview';
+import ToolbarView from '../../../src/toolbar/toolbarview';
 
 
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
 
@@ -47,7 +47,7 @@ describe( 'createButtonDropdown', () => {
 
 
 				expect( panelChildren ).to.have.length( 1 );
 				expect( panelChildren ).to.have.length( 1 );
 				expect( panelChildren.get( 0 ) ).to.equal( view.buttonGroupView );
 				expect( panelChildren.get( 0 ) ).to.equal( view.buttonGroupView );
-				expect( view.buttonGroupView ).to.be.instanceof( ButtonGroupView );
+				expect( view.buttonGroupView ).to.be.instanceof( ToolbarView );
 			} );
 			} );
 
 
 			it( 'delegates view.buttonGroupView#execute to the view', done => {
 			it( 'delegates view.buttonGroupView#execute to the view', done => {
@@ -134,23 +134,6 @@ describe( 'createButtonDropdown', () => {
 				view.keystrokes.press( keyEvtData );
 				view.keystrokes.press( keyEvtData );
 				sinon.assert.calledOnce( spy );
 				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', () => {
 		describe( 'icon', () => {

+ 0 - 11
packages/ckeditor5-ui/theme/components/buttongroup.css

@@ -1,11 +0,0 @@
-// Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
-// For licensing, see LICENSE.md or http://ckeditor.com/license
-
-.ck-button-group {
-	@include ck-unselectable();
-}
-
-.ck-button-group__vertical {
-	display: flex;
-	flex-direction: column;
-}

+ 17 - 1
packages/ckeditor5-ui/theme/components/dropdown/buttondropdown.css

@@ -3,8 +3,24 @@
  * For licensing, see LICENSE.md.
  * For licensing, see LICENSE.md.
  */
  */
 
 
-.ck-dropdown .ck-button-group .ck-button {
+.ck-buttondropdown .ck-button {
 	&:focus {
 	&:focus {
 		z-index: calc(var(--ck-z-default) + 1);
 		z-index: calc(var(--ck-z-default) + 1);
 	}
 	}
 }
 }
+
+.ck-dropdown {
+	&.ck-buttondropdown .ck-toolbar {
+		display: flex;
+		flex-direction: row;
+
+		&.ck-toolbar__vertical {
+			flex-direction: column;
+		}
+
+		& .ck-button {
+			margin: 0;
+			border-radius: 0;
+		}
+	}
+}