Parcourir la source

Merge branch 'master' into t/ckeditor5/1151

Aleksander Nowodzinski il y a 6 ans
Parent
commit
9e8d7cc080

+ 2 - 2
packages/ckeditor5-ui/docs/features/blocktoolbar.md

@@ -5,12 +5,12 @@ category: features
 
 The {@link module:ui/toolbar/block/blocktoolbar~BlockToolbar} plugin provides an additional [configurable](#configuration) toolbar on the left-hand side of the content area (the gutter). The toolbar is represented by a button with a pilcrow (or a paragraph mark — ¶). It is positioned next to the block element that the selection is anchored to (e.g. a paragraph), following the caret as the user edits the content and navigates the document.
 
-The block toolbar comes in handy when the main editor toolbar cannot be accessed. It complements the {@link builds/guides/overview#balloon-editor Balloon editor} when it falls short, for example when some content must be inserted (like an image) but the selection is collapsed, leaving the user unable to access the toolbar.
+The block toolbar comes in handy when the main editor toolbar cannot be accessed. It complements the {@link builds/guides/overview#balloon-editor Balloon editor} when it falls short, for example when some content must be inserted (like an image) but the selection is collapsed, leaving the user unable to access the toolbar. You can read more about it in the {@link builds/guides/overview#balloon-block-editor balloon block editor overview}.
 
 ## Example
 
 <info-box hint>
-	Move the caret around the content with the balloon editor below to see the block toolbar button following the selection. Click the button (&#182;) to use the toolbar, for example to create a header or insert an image.
+	Move the caret around the content with the balloon editor below to see the block toolbar button following the selection. Click the button (&#182;) to use the toolbar, for example, to create a header or insert an image. See the {@link examples/builds/balloon-block-editor balloon block editor example} page, too.
 </info-box>
 
 {@snippet features/blocktoolbar}

+ 2 - 1
packages/ckeditor5-ui/src/labeledinput/labeledinputview.js

@@ -210,7 +210,8 @@ export default class LabeledInputView extends View {
 					bind.if( 'errorText', 'ck-labeled-input__status_error' ),
 					bind.if( '_statusText', 'ck-hidden', value => !value )
 				],
-				id: statusUid
+				id: statusUid,
+				role: bind.if( 'errorText', 'alert' )
 			},
 			children: [
 				{

+ 5 - 3
packages/ckeditor5-ui/src/template.js

@@ -15,7 +15,6 @@ import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
 import View from './view';
 import ViewCollection from './viewcollection';
 import isNode from '@ckeditor/ckeditor5-utils/src/dom/isnode';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 import { isObject, cloneDeepWith } from 'lodash-es';
 
 const xhtmlNs = 'http://www.w3.org/1999/xhtml';
@@ -39,7 +38,7 @@ const xhtmlNs = 'http://www.w3.org/1999/xhtml';
  *			},
  *			on: {
  *				click: bind.to( 'clicked' )
- *			}
+ *			},
  *			children: [
  *				'A paragraph.'
  *			]
@@ -381,7 +380,10 @@ export default class Template {
 			 *
 			 * @error template-extend-render
 			 */
-			log.warn( 'template-extend-render: Attempting to extend a template which has already been rendered.' );
+			throw new CKEditorError(
+				'template-extend-render: Attempting to extend a template which has already been rendered.',
+				[ this, template ]
+			);
 		}
 
 		extendTemplate( template, normalize( clone( def ) ) );

+ 5 - 5
packages/ckeditor5-ui/src/toolbar/toolbarview.js

@@ -7,15 +7,17 @@
  * @module ui/toolbar/toolbarview
  */
 
+/* globals console */
+
 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 ToolbarSeparatorView from './toolbarseparatorview';
 import preventDefault from '../bindings/preventdefault.js';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 
 import '../../theme/components/toolbar/toolbar.css';
+import { attachLinkToDocumentation } from '@ckeditor/ckeditor5-utils/src/ckeditorerror';
 
 /**
  * The toolbar view class.
@@ -180,10 +182,8 @@ export default class ToolbarView extends View {
 				 * @error toolbarview-item-unavailable
 				 * @param {String} name The name of the component.
 				 */
-				log.warn(
-					'toolbarview-item-unavailable: The requested toolbar item is unavailable.',
-					{ name }
-				);
+				console.warn( attachLinkToDocumentation(
+					'toolbarview-item-unavailable: The requested toolbar item is unavailable.' ), { name } );
 			}
 		} );
 	}

+ 4 - 0
packages/ckeditor5-ui/tests/labeledinput/labeledinputview.js

@@ -93,11 +93,13 @@ describe( 'LabeledInputView', () => {
 					view.errorText = '';
 					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.true;
 					expect( statusElement.classList.contains( 'ck-labeled-input__status_error' ) ).to.be.false;
+					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
 					expect( statusElement.innerHTML ).to.equal( '' );
 
 					view.errorText = 'foo';
 					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.false;
 					expect( statusElement.classList.contains( 'ck-labeled-input__status_error' ) ).to.be.true;
+					expect( statusElement.getAttribute( 'role' ) ).to.equal( 'alert' );
 					expect( statusElement.innerHTML ).to.equal( 'foo' );
 				} );
 
@@ -107,11 +109,13 @@ describe( 'LabeledInputView', () => {
 					view.infoText = '';
 					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.true;
 					expect( statusElement.classList.contains( 'ck-labeled-input__status_error' ) ).to.be.false;
+					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
 					expect( statusElement.innerHTML ).to.equal( '' );
 
 					view.infoText = 'foo';
 					expect( statusElement.classList.contains( 'ck-hidden' ) ).to.be.false;
 					expect( statusElement.classList.contains( 'ck-labeled-input__status_error' ) ).to.be.false;
+					expect( statusElement.hasAttribute( 'role' ) ).to.be.false;
 					expect( statusElement.innerHTML ).to.equal( 'foo' );
 				} );
 			} );

+ 33 - 38
packages/ckeditor5-ui/tests/template.js

@@ -5,7 +5,6 @@
 
 /* globals HTMLElement, Event, document */
 
-import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 import { default as Template, TemplateToBinding, TemplateIfBinding } from '../src/template';
 import View from '../src/view';
 import ViewCollection from '../src/viewcollection';
@@ -14,7 +13,6 @@ import Model from '../src/model';
 import EmitterMixin from '@ckeditor/ckeditor5-utils/src/emittermixin';
 import DomEmitterMixin from '@ckeditor/ckeditor5-utils/src/dom/emittermixin';
 import normalizeHtml from '@ckeditor/ckeditor5-utils/tests/_utils/normalizehtml';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 
 import { expectToThrowCKEditorError } from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
 
@@ -22,10 +20,10 @@ let el, text;
 const injectedElements = [];
 
 describe( 'Template', () => {
-	testUtils.createSinonSandbox();
-
 	// Clean-up document.body from the rendered elements.
 	afterEach( () => {
+		sinon.restore();
+
 		for ( const el of injectedElements ) {
 			el.remove();
 		}
@@ -1026,9 +1024,9 @@ describe( 'Template', () => {
 					'<div><a class="a1 a2">a</a><b class="b1 b2">b</b></div>'
 				);
 
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
-				const spy3 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
+				const spy3 = sinon.spy();
 
 				observable.on( 'ku', spy1 );
 				observable.on( 'kd', spy2 );
@@ -1593,7 +1591,7 @@ describe( 'Template', () => {
 			} );
 
 			it( 'accepts plain binding', () => {
-				const spy = testUtils.sinon.spy();
+				const spy = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1612,8 +1610,8 @@ describe( 'Template', () => {
 			} );
 
 			it( 'accepts an array of event bindings', () => {
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1640,9 +1638,9 @@ describe( 'Template', () => {
 			} );
 
 			it( 'accepts DOM selectors', () => {
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
-				const spy3 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
+				const spy3 = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1721,8 +1719,8 @@ describe( 'Template', () => {
 			} );
 
 			it( 'accepts function callbacks', () => {
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1753,7 +1751,7 @@ describe( 'Template', () => {
 			} );
 
 			it( 'supports event delegation', () => {
-				const spy = testUtils.sinon.spy();
+				const spy = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1777,7 +1775,7 @@ describe( 'Template', () => {
 			} );
 
 			it( 'works for future elements', () => {
-				const spy = testUtils.sinon.spy();
+				const spy = sinon.spy();
 
 				setElement( {
 					tag: 'p',
@@ -1811,7 +1809,7 @@ describe( 'Template', () => {
 
 			describe( 'to', () => {
 				it( 'returns an instance of TemplateToBinding', () => {
-					const spy = testUtils.sinon.spy();
+					const spy = sinon.spy();
 					const binding = bind.to( 'foo', spy );
 
 					expect( binding ).to.be.instanceof( TemplateToBinding );
@@ -2034,7 +2032,7 @@ describe( 'Template', () => {
 
 			describe( 'if', () => {
 				it( 'returns an object which describes the binding', () => {
-					const spy = testUtils.sinon.spy();
+					const spy = sinon.spy();
 					const binding = bind.if( 'foo', 'whenTrue', spy );
 
 					expect( binding ).to.be.instanceof( TemplateIfBinding );
@@ -2333,9 +2331,7 @@ describe( 'Template', () => {
 			expect( tpl.attributes.b[ 0 ] ).to.equal( 'bar' );
 		} );
 
-		it( 'logs a warning if an element has already been rendered', () => {
-			const spy = testUtils.sinon.stub( log, 'warn' );
-
+		it( 'throws an error if an element has already been rendered', () => {
 			const tpl = new Template( {
 				tag: 'p'
 			} );
@@ -2348,14 +2344,13 @@ describe( 'Template', () => {
 
 			tpl.render();
 
-			Template.extend( tpl, {
-				attributes: {
-					class: 'bar'
-				}
-			} );
-
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWithExactly( spy, sinon.match( /^template-extend-render/ ) );
+			expectToThrowCKEditorError( () => {
+				Template.extend( tpl, {
+					attributes: {
+						class: 'bar'
+					}
+				} );
+			}, /^template-extend-render/ );
 		} );
 
 		describe( 'attributes', () => {
@@ -2918,11 +2913,11 @@ describe( 'Template', () => {
 
 		describe( 'listeners', () => {
 			it( 'extends existing', () => {
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
-				const spy3 = testUtils.sinon.spy();
-				const spy4 = testUtils.sinon.spy();
-				const spy5 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
+				const spy3 = sinon.spy();
+				const spy4 = sinon.spy();
+				const spy5 = sinon.spy();
 
 				observable.on( 'A', spy1 );
 				observable.on( 'C', spy2 );
@@ -2973,9 +2968,9 @@ describe( 'Template', () => {
 			} );
 
 			it( 'creates new', () => {
-				const spy1 = testUtils.sinon.spy();
-				const spy2 = testUtils.sinon.spy();
-				const spy3 = testUtils.sinon.spy();
+				const spy1 = sinon.spy();
+				const spy2 = sinon.spy();
+				const spy3 = sinon.spy();
 
 				observable.on( 'A', spy1 );
 				observable.on( 'B', spy2 );

+ 5 - 8
packages/ckeditor5-ui/tests/toolbar/toolbarview.js

@@ -3,7 +3,7 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
-/* global document, Event */
+/* global document, Event, console */
 
 import ToolbarView from '../../src/toolbar/toolbarview';
 import ToolbarSeparatorView from '../../src/toolbar/toolbarseparatorview';
@@ -13,15 +13,11 @@ import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker';
 import FocusCycler from '../../src/focuscycler';
 import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 import ViewCollection from '../../src/viewcollection';
-import log from '@ckeditor/ckeditor5-utils/src/log';
 import View from '../../src/view';
-import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 
 describe( 'ToolbarView', () => {
 	let locale, view;
 
-	testUtils.createSinonSandbox();
-
 	beforeEach( () => {
 		locale = {};
 		view = new ToolbarView( locale );
@@ -29,6 +25,7 @@ describe( 'ToolbarView', () => {
 	} );
 
 	afterEach( () => {
+		sinon.restore();
 		view.destroy();
 	} );
 
@@ -306,7 +303,7 @@ describe( 'ToolbarView', () => {
 
 		it( 'warns if there is no such component in the factory', () => {
 			const items = view.items;
-			testUtils.sinon.stub( log, 'warn' );
+			const consoleWarnStub = sinon.stub( console, 'warn' );
 
 			view.fillFromConfig( [ 'foo', 'bar', 'baz' ], factory );
 
@@ -314,8 +311,8 @@ describe( 'ToolbarView', () => {
 			expect( items.get( 0 ).name ).to.equal( 'foo' );
 			expect( items.get( 1 ).name ).to.equal( 'bar' );
 
-			sinon.assert.calledOnce( log.warn );
-			sinon.assert.calledWithExactly( log.warn,
+			sinon.assert.calledOnce( consoleWarnStub );
+			sinon.assert.calledWithExactly( consoleWarnStub,
 				sinon.match( /^toolbarview-item-unavailable/ ),
 				{ name: 'baz' }
 			);