Procházet zdrojové kódy

Tests: Complete refactoring of the main manual test. Used utils.createTestUIController() and UI Classes instead of static HTML for better maintainability and extendability.

Aleksander Nowodzinski před 9 roky
rodič
revize
ee7aab32dc

+ 92 - 201
packages/ckeditor5-theme-lark/tests/manual/theme.html

@@ -6,24 +6,18 @@
 			line-height: 3em;
 		}
 
-		#icons, #iconsColored {
-			overflow: hidden;
+		*[id^="icon"] .ck-icon + .ck-icon,
+		*[id^="button"] .ck-button + .ck-button,
+		*[id^="dropdown"] .ck-dropdown + .ck-dropdown,
+		*[id^="toolbar"] .ck-button + .ck-button {
+			margin-left: 0.3em;
 		}
 
-		#iconsColored {
+		.icon-color {
 			color: red;
 		}
 
-		#buttonResponsive div > div {
-			font-size: 1.3em;
-			line-height: 2.8em;
-		}
-
-		#buttonResponsive div .ck-button {
-			font-size: inherit;
-		}
-
-		@keyframes iconColorChange {
+		@keyframes icon-color-change {
 			0% {
 				color: white;
 				background: orange;
@@ -38,214 +32,111 @@
 			}
 		}
 
-		#iconColorChange {
+		#icon-color-change {
 			border: 0;
-			animation: iconColorChange 3s infinite;
+			animation: icon-color-change 3s infinite;
+		}
+
+		.button-responsive > div {
+			font-size: 1.5em;
+			line-height: 2.8em;
+		}
+
+		.button-responsive div .ck-button {
+			font-size: inherit;
 		}
 	</style>
 </head>
 
-<div id="editor"></div>
-
 <h2>Icon</h2>
-<h3>Icon: In–text</h3>
-
-<p>Icons
-	<svg class="ck-icon"><use xlink:href="#ck-icon-quote"></use></svg>
-	and
-	<svg class="ck-icon"><use xlink:href="#ck-icon-bold"></use></svg> in a plain paragraph.
-	<span style="color: red">
-		Icons
-		<svg class="ck-icon"><use xlink:href="#ck-icon-link"></use></svg>
-		follow the
-		<svg class="ck-icon"><use xlink:href="#ck-icon-source"></use></svg>
-		color of text.
-	</span>
-</p>
-
-<h3>Icon: Availability</h3>
-<p id="icons" class="ck-reset-all"></p>
-
-<h3>Icon: Availability (colored)</h3>
-<p id="iconsColored" class="ck-reset-all"></p>
+
+	<h3>Icon: In–text</h3>
+
+	<p>Icons <span id="icon-plain-1"></span> and <span id="icon-plain-2"></span> in a plain paragraph.</p>
+	<p class="icon-color">
+		Icons <span id="icon-color-1"></span> follow the <span id="icon-color-2"></span> color of text.
+	</p>
+
+	<h3>Icon: Availability</h3>
+	<p id="icon-availability" class="ck-reset-all"></p>
+
+	<h3>Icon: Availability (colored)</h3>
+	<p id="icon-availability-color" class="ck-reset-all icon-color"></p>
 
 <hr/>
 
 <h2>Button</h2>
-<h3>Button: States</h3>
-
-<div class="ck-reset-all">
-	<button class="ck-button">State: normal (none)</button>
-	<button class="ck-button ck-disabled">State: disabled</button>
-	<button class="ck-button ck-on">State: on</button>
-</div>
-
-<h3>Button: Types</h3>
-
-<div class="ck-reset-all">
-	<button class="ck-button ck-button-action">Action button</button>
-	<button class="ck-button ck-rounded-corners">Rounded corners</button>
-	<button class="ck-button ck-button-bold">Bold text</button>
-</div>
-
-<h3>Button: Icon</h3>
-<div class="ck-reset-all" >
-	<div id="buttonIcon" class="wrappable"></div>
-
-	<br/>
-
-	<button class="ck-button">
-		<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		Icon to the left
-	</button>
-	<button class="ck-button">
-		<svg class="ck-icon ck-icon-right"><use xlink:href="#ck-icon-bold"></use></svg>
-		Icon to the right (RTL)
-	</button>
-	<button class="ck-button" style="border-radius: 100px; border: 0">
-		<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-image"></use></svg>
-		Custom style with icon
-	</button>
-
-	<br/>
-	<br/>
-
-	<button class="ck-button ck-disabled">
-		<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		Disabled with icon
-	</button>
-
-	<button class="ck-button ck-disabled ck-button-notext">
-		<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-	</button>
-	<button id="iconColorChange" class="ck-button">
-		<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		Icon follows text color
-	</button>
-</div>
-
-<h3>Button: Responsiveness</h3>
-<div id="buttonResponsive" class="ck-reset-all">
-	<div>
-		<button class="ck-button">A button</button>
-		<button class="ck-button ck-button-action">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-image"></use></svg>
-			Image
-		</button>
-		<button class="ck-button">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-			Bold
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-link"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-image"></use></svg>
-		</button>
+
+	<h3>Button: States</h3>
+	<div id="button-states" class="ck-reset-all"></div>
+
+	<h3>Button: Types</h3>
+	<div id="button-types" class="ck-reset-all"></div>
+
+	<h3>Button: Icon</h3>
+	<div class="ck-reset-all" >
+		<div id="button-icon" class="wrappable"></div>
+
+		<br/>
+
+		<div id="button-icon-custom"></div>
+
+		<br/>
+		<br/>
+
+		<div id="button-icon-states"></div>
+	</div>
+
+	<h3>Button: Responsiveness</h3>
+	<div id="button-responsive-1" class="button-responsive ck-reset-all">
+		<div id="button-responsive-2" class="button-responsive">
+			<div id="button-responsive-3" class="button-responsive"></div>
+		</div>
 	</div>
-</div>
+
+<hr/>
+
+<h2>Dropdown</h2>
+
+	<h3>ListDropdown</h3>
+	<div id="dropdown"></div>
 
 <hr/>
 
 <h2>Toolbar</h2>
 
-<h3>Toolbar: Text</h3>
-<div class="ck-reset-all">
-	<div class="ck-toolbar">
-		Just text and some <svg class="ck-icon"><use xlink:href="#ck-icon-bold"></use></svg> icon.
+	<h3>Toolbar: Text</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-text" class="ck-toolbar">
+			Just text and some icon.
+		</div>
 	</div>
-</div>
-
-<h3>Toolbar: Button</h3>
-<div class="ck-reset-all">
-	<div class="ck-toolbar">
-		<button class="ck-button">A button</button>
-		<button class="ck-button ck-disabled">Disabled button</button>
-		<button class="ck-button ck-button-active">Active button</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-link"></use></svg>
-		</button>
-		And some text.
+
+	<h3>Toolbar: Button</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-button" class="ck-toolbar">
+			Some text.
+		</div>
 	</div>
-</div>
 
-<h3>Toolbar: Rounded</h3>
-<div class="ck-reset-all">
-	<div class="ck-rounded-corners ck-toolbar">
-		<button class="ck-button">A button which corners are also rounded because of toolbar class</button>
-		<button class="ck-button ck-button-notext"><svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg></button>
+	<h3>Toolbar: Rounded</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-rounded" class="ck-rounded-corners ck-toolbar"></div>
 	</div>
-</div>
-
-<h3>Toolbar: Wrapping content</h3>
-<div class="ck-reset-all">
-	<div class="ck-toolbar" style="width: 80px">
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-italic"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-underline"></use></svg>
-		</button>
+
+	<h3>Toolbar: Wrapping content</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-wrap" class="ck-toolbar" style="width: 250px"></div>
 	</div>
-</div>
-
-<h3>Toolbar: Item separators</h3>
-<div class="ck-reset-all">
-	<div class="ck-toolbar">
-		<button class="ck-button">First</button>
-		<button class="ck-button">Second</button>
-		<span class="ck-toolbar-separator"></span>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-italic"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-underline"></use></svg>
-		</button>
-		<span class="ck-toolbar-separator"></span>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-link"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-image"></use></svg>
-		</button>
+
+	<h3>Toolbar: Item separators</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-separator" class="ck-toolbar"></div>
 	</div>
-</div>
-
-<h3>Toolbar: Multi-row</h3>
-<div class="ck-reset-all">
-	<div class="ck-toolbar">
-		<button class="ck-button">First row</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-bold"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-italic"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-underline"></use></svg>
-		</button>
-		<span class="ck-toolbar-newline"></span>
-		<button class="ck-button">Second row</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-link"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-image"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-table"></use></svg>
-		</button>
-		<button class="ck-button ck-button-notext">
-			<svg class="ck-icon ck-icon-left"><use xlink:href="#ck-icon-source"></use></svg>
-		</button>
+
+	<h3>Toolbar: Multi-row</h3>
+	<div class="ck-reset-all">
+		<div id="toolbar-multi-row" class="ck-toolbar"></div>
 	</div>
-</div>
+
+<div id="body"></div>

+ 359 - 29
packages/ckeditor5-theme-lark/tests/manual/theme.js

@@ -5,51 +5,381 @@
 
 'use strict';
 
+import testUtils from '/tests/ckeditor5/_utils/utils.js';
+
+import Collection from '/ckeditor5/utils/collection.js';
 import IconManagerView from '/ckeditor5/ui/iconmanagerview.js';
 import Model from '/ckeditor5/ui/model.js';
+import Controller from '/ckeditor5/ui/controller.js';
+import View from '/ckeditor5/ui/view.js';
+
+import iconManagerModel from '/theme/iconmanagermodel.js';
 import IconView from '/ckeditor5/ui/icon/iconview.js';
+
+import Button from '/ckeditor5/ui/button/button.js';
 import ButtonView from '/ckeditor5/ui/button/buttonview.js';
-import iconManagerModel from '/theme/iconmanagermodel.js';
 
-function setupIconManager() {
-	const iconManagerView = new IconManagerView( iconManagerModel );
-	document.body.appendChild( iconManagerView.element );
-	iconManagerView.init();
+import ListDropdown from '/ckeditor5/ui/dropdown/list/listdropdown.js';
+import ListDropdownView from '/ckeditor5/ui/dropdown/list/listdropdownview.js';
+
+testUtils.createTestUIController( {
+	'icon-plain-1':					'#icon-plain-1',
+	'icon-plain-2':					'#icon-plain-2',
+	'icon-color-1':					'#icon-color-1',
+	'icon-color-2':					'#icon-color-2',
+	'icon-availability':			'#icon-availability',
+	'icon-availability-color':		'#icon-availability-color',
+
+	'button-states':				'#button-states',
+	'button-types':					'#button-types',
+	'button-icon':					'#button-icon',
+	'button-custom':				'#button-custom',
+	'button-icon-custom':			'#button-icon-custom',
+	'button-icon-states':			'#button-icon-states',
+	'button-responsive-1':			'#button-responsive-1',
+	'button-responsive-2':			'#button-responsive-2',
+	'button-responsive-3':			'#button-responsive-3',
+
+	dropdown:						'#dropdown',
+
+	'toolbar-text':					'#toolbar-text',
+	'toolbar-button':				'#toolbar-button',
+	'toolbar-rounded':				'#toolbar-rounded',
+	'toolbar-wrap':					'#toolbar-wrap',
+	'toolbar-separator':			'#toolbar-separator',
+	'toolbar-multi-row':			'#toolbar-multi-row',
+
+	body:							'div#body'
+} ).then( ui => {
+	setupIconManager( ui );
+	renderIcon( ui );
+	renderButton( ui );
+	renderDropdown( ui );
+	renderToolbar( ui );
+} );
+
+function renderIcon( ui ) {
+	// --- In-text ------------------------------------------------------------
+
+	ui.add( 'icon-plain-1', getIcon( 'bold' ) );
+	ui.add( 'icon-plain-2', getIcon( 'quote' ) );
+
+	ui.add( 'icon-color-1', getIcon( 'bold' ) );
+	ui.add( 'icon-color-2', getIcon( 'quote' ) );
+
+	// --- Availability ------------------------------------------------------------
+
+	iconManagerModel.icons.forEach( i => {
+		ui.add( 'icon-availability', getIcon( i ) );
+		ui.add( 'icon-availability-color', getIcon( i ) );
+	} );
 }
 
-function renderIcons() {
-	const containers = [
-		document.getElementById( 'icons' ),
-		document.getElementById( 'iconsColored' )
-	];
-	const buttonIcons = document.getElementById( 'buttonIcon' );
+function renderButton( ui ) {
+	// --- States ------------------------------------------------------------
+
+	ui.add( 'button-states', getButton( {
+		label: 'State: normal (none)',
+	} ) );
+
+	ui.add( 'button-states', getButton( {
+		label: 'State: disabled',
+		isEnabled: false
+	} ) );
+
+	ui.add( 'button-states', getButton( {
+		label: 'State: on',
+		isOn: true
+	} ) );
+
+	// --- Types ------------------------------------------------------------
+
+	const actionButton = getButton( { label: 'Action button' } );
+	const roundedButton = getButton( { label: 'Rounded corners' } );
+	const boldButton = getButton( { label: 'Bold text' } );
+
+	// TODO: It requires model interface.
+	actionButton.view.element.classList.add( 'ck-button-action' );
+
+	// TODO: It requires model interface.
+	roundedButton.view.element.classList.add( 'ck-rounded-corners' );
+
+	// TODO: It requires model interface.
+	boldButton.view.element.classList.add( 'ck-button-bold' );
+
+	ui.add( 'button-types', actionButton );
+	ui.add( 'button-types', roundedButton );
+	ui.add( 'button-types', boldButton );
+
+	// --- Icon ------------------------------------------------------------
 
 	iconManagerModel.icons.forEach( i => {
-		const view = new IconView( new Model( { icon: i } ) );
-		const button = new ButtonView( new Model( { label: i, icon: i, isEnabled: true } ) );
-		button.init();
+		ui.add( 'button-icon', getButton( {
+			label: i,
+			icon: i,
+			iconAlign: 'left'
+		} ) );
+	} );
+
+	ui.add( 'button-icon-custom', getButton( {
+		label: 'Icon to the left',
+		icon: 'bold',
+		iconAlign: 'left'
+	} ) );
+
+	ui.add( 'button-icon-custom', getButton( {
+		label: 'Icon to the right (RTL)',
+		icon: 'bold',
+		iconAlign: 'right'
+	} ) );
+
+	const styledButton = getButton( {
+		label: 'Button with icon and custom styles',
+		icon: 'italic',
+		iconAlign: 'left'
+	} );
+
+	// TODO: It probably requires model interface.
+	styledButton.view.element.setAttribute( 'style', 'border-radius: 100px; border: 0' );
+
+	ui.add( 'button-icon-custom', styledButton );
+
+	ui.add( 'button-icon-states', getButton( {
+		label: 'Disabled',
+		icon: 'bold',
+		iconAlign: 'left',
+		isEnabled: false
+	} ) );
+
+	const notextButton = getButton( {
+		label: '',
+		icon: 'bold',
+		iconAlign: 'left'
+	} );
 
-		containers.forEach( c => {
-			c.appendChild( view.element.cloneNode( 1 ) );
-			c.appendChild( document.createTextNode( ' ' ) );
+	// TODO: It requires model interface.
+	notextButton.view.element.classList.add( 'ck-button-notext' );
+
+	ui.add( 'button-icon-states', notextButton );
+
+	const colChangeButton = getButton( {
+		label: 'Icon follows text color',
+		icon: 'bold',
+		iconAlign: 'left'
+	} );
+
+	// TODO: It requires model interface.
+	colChangeButton.view.element.id = 'icon-color-change';
+
+	ui.add( 'button-icon-states', colChangeButton );
+
+	// --- Responsive ------------------------------------------------------------
+
+	for ( let i = 1; i < 4; i++ ) {
+		ui.add( `button-responsive-${ i }`, getButton( {
+			label: 'A button',
+			isEnabled: true
+		} ) );
+
+		ui.add( `button-responsive-${ i }`, getButton( {
+			label: 'Bold',
+			icon: 'bold',
+			iconAlign: 'left',
+			isEnabled: true
+		} ) );
+
+		const notextButton = getButton( {
+			label: '',
+			icon: 'link',
+			iconAlign: 'left'
 		} );
 
-		buttonIcons.appendChild( button.element );
-		buttonIcons.appendChild( document.createTextNode( ' ' ) );
+		// TODO: It requires model interface.
+		notextButton.view.element.classList.add( 'ck-button-notext' );
+		notextButton.view.element.classList.add( 'ck-button-action' );
+
+		ui.add( `button-responsive-${ i }`, notextButton );
+	}
+}
+
+function renderDropdown( ui ) {
+	// --- ListDropdown ------------------------------------------------------------
+
+	const collection = new Collection( { idProperty: 'label' } );
+
+	[ 'Arial', 'Tahoma', 'Georgia' ].forEach( font => {
+		collection.add( new Model( {
+			label: font,
+			style: `font-family: ${ font }`
+		} ) );
+	} );
+
+	const itemListModel = new Model( {
+		items: collection
+	} );
+
+	const enabledModel = new Model( {
+		label: 'Normal state',
+		isEnabled: true,
+		isOn: false,
+		content: itemListModel
 	} );
+
+	const disabledModel = new Model( {
+		label: 'Disabled',
+		isEnabled: false,
+		isOn: false,
+		content: itemListModel
+	} );
+
+	ui.add( 'dropdown', new ListDropdown( enabledModel, new ListDropdownView( enabledModel ) ) );
+	ui.add( 'dropdown', new ListDropdown( disabledModel, new ListDropdownView( disabledModel ) ) );
 }
 
-function renderResponsiveButtons() {
-	const responsive = document.getElementById( 'buttonResponsive' );
-	let current = responsive.firstElementChild;
+function renderToolbar( ui ) {
+	// --- Text ------------------------------------------------------------
+
+	ui.add( 'toolbar-text', getIcon( 'bold' ) );
+
+	// --- Button ------------------------------------------------------------
+
+	ui.add( 'toolbar-button', getButton( {
+		label: 'Some button'
+	} ) );
+
+	ui.add( 'toolbar-button', getButton( {
+		label: 'Button with icon',
+		icon: 'bold',
+		iconAlign: 'left'
+	} ) );
+
+	// --- Rounded ------------------------------------------------------------
+
+	ui.add( 'toolbar-rounded', getButton( {
+		label: 'A button which corners are also rounded because of toolbar class'
+	} ) );
+
+	ui.add( 'toolbar-rounded', getButton( {
+		label: 'Button with icon',
+		icon: 'bold',
+		iconAlign: 'left'
+	} ) );
+
+	// --- Wrap ------------------------------------------------------------
+
+	ui.add( 'toolbar-wrap', getButton( {
+		label: 'Some button'
+	} ) );
+
+	ui.add( 'toolbar-wrap', getButton( {
+		label: 'Some button'
+	} ) );
+
+	ui.add( 'toolbar-wrap', getButton( {
+		label: 'Some button'
+	} ) );
+
+	// --- Separator ------------------------------------------------------------
+
+	ui.add( 'toolbar-separator', getButton( {
+		label: 'Some button'
+	} ) );
+
+	ui.add( 'toolbar-separator', getButton( {
+		label: 'Another button'
+	} ) );
+
+	ui.add( 'toolbar-separator', getToolbarSeparator() );
 
-	for ( let i = 3; i--; ) {
-		const clone = current.cloneNode( 1 );
-		current.appendChild( clone );
-		current = clone;
+	ui.add( 'toolbar-separator', getButton( {
+		label: 'Link',
+		icon: 'link',
+		iconAlign: 'left'
+	} ) );
+
+	ui.add( 'toolbar-separator', getToolbarSeparator() );
+
+	ui.add( 'toolbar-separator', getButton( {
+		label: 'Unlink RTL',
+		icon: 'unlink',
+		iconAlign: 'right'
+	} ) );
+
+	// --- Multi row ------------------------------------------------------------
+
+	ui.add( 'toolbar-multi-row', getButton( {
+		label: 'Some button'
+	} ) );
+
+	ui.add( 'toolbar-multi-row', getButton( {
+		label: 'Another button'
+	} ) );
+
+	ui.add( 'toolbar-multi-row', getToolbarNewline() );
+
+	ui.add( 'toolbar-multi-row', getButton( {
+		label: 'Link',
+		icon: 'link',
+		iconAlign: 'left'
+	} ) );
+
+	ui.add( 'toolbar-multi-row', getButton( {
+		label: 'Unlink RTL',
+		icon: 'unlink',
+		iconAlign: 'right'
+	} ) );
+
+	ui.add( 'toolbar-multi-row', getButton( {
+		label: 'Link',
+		icon: 'link',
+		iconAlign: 'left'
+	} ) );
+}
+
+function setupIconManager( ui ) {
+	ui.add( 'body', new Controller( null, new IconManagerView( iconManagerModel ) ) );
+}
+
+function getIcon( name ) {
+	return new Controller( null, new IconView( new Model( { icon: name } ) ) );
+}
+
+function getButton( { label = 'A button', isEnabled = true, isOn = false, icon, iconAlign } = {} ) {
+	const model = new Model( { label, isEnabled, isOn, icon, iconAlign } );
+
+	return new Button( model, new ButtonView( model ) );
+}
+
+const ToolbarSeparatorView = class extends View {
+	constructor() {
+		super();
+
+		this.template = {
+			tag: 'span',
+			attributes: {
+				class: 'ck-toolbar-separator'
+			}
+		};
 	}
+};
+
+function getToolbarSeparator() {
+	return new Controller( null, new ToolbarSeparatorView( null ) );
 }
 
-setupIconManager();
-renderIcons();
-renderResponsiveButtons();
+const ToolbarNewlineView = class extends View {
+	constructor() {
+		super();
+
+		this.template = {
+			tag: 'span',
+			attributes: {
+				class: 'ck-toolbar-newline'
+			}
+		};
+	}
+};
+
+function getToolbarNewline() {
+	return new Controller( null, new ToolbarNewlineView( null ) );
+}