From 56c5c526bebb8cf428aa786246f61ed43d9471b5 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 5 Mar 2019 16:32:52 +0100 Subject: [PATCH 01/92] Add Some proof of concept for font-color. With basic manual test. Work in progress. --- src/fontcolor.js | 28 +++++ src/fontcolor/fontcolorcommand.js | 19 ++++ src/fontcolor/fontcolorediting.js | 167 ++++++++++++++++++++++++++++++ src/fontcolor/fontcolorui.js | 76 ++++++++++++++ src/fontcolor/utils.js | 29 ++++++ src/ui/insertcolorview.js | 78 ++++++++++++++ tests/manual/font-color.html | 8 ++ tests/manual/font-color.js | 24 +++++ tests/manual/font-color.md | 0 9 files changed, 429 insertions(+) create mode 100644 src/fontcolor.js create mode 100644 src/fontcolor/fontcolorcommand.js create mode 100644 src/fontcolor/fontcolorediting.js create mode 100644 src/fontcolor/fontcolorui.js create mode 100644 src/fontcolor/utils.js create mode 100644 src/ui/insertcolorview.js create mode 100644 tests/manual/font-color.html create mode 100644 tests/manual/font-color.js create mode 100644 tests/manual/font-color.md diff --git a/src/fontcolor.js b/src/fontcolor.js new file mode 100644 index 0000000..886dc54 --- /dev/null +++ b/src/fontcolor.js @@ -0,0 +1,28 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontcolor + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import FontColorEditing from './fontcolor/fontcolorediting'; +import FontColorUI from './fontcolor/fontcolorui'; + +export default class FontFamily extends Plugin { + /** + * @inheritDoc + */ + static get requires() { + return [ FontColorEditing, FontColorUI ]; + } + + /** + * @inheritDoc + */ + static get pluginName() { + return 'FontColor'; + } +} diff --git a/src/fontcolor/fontcolorcommand.js b/src/fontcolor/fontcolorcommand.js new file mode 100644 index 0000000..e100785 --- /dev/null +++ b/src/fontcolor/fontcolorcommand.js @@ -0,0 +1,19 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontcolor/fontcolorcommand + */ + +import FontCommand from '../fontcommand'; + +export default class FontColorCommand extends FontCommand { + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor, 'fontColor' ); + } +} diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js new file mode 100644 index 0000000..d77c56c --- /dev/null +++ b/src/fontcolor/fontcolorediting.js @@ -0,0 +1,167 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontfamily/fontfamilyediting + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; + +import FontColorCommand from './fontcolorcommand'; + +const FONT_COLOR = 'fontColor'; + +export default class FontColorEditing extends Plugin { + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor ); + + editor.config.define( FONT_COLOR, { + options: [ + { + label: 'Strong Cyan', + color: '1ABC9C' + }, + { + label: 'Emerald', + color: '2ECC71' + }, + { + label: 'Bright Blue', + color: '3498DB' + }, + { + label: 'Amethyst', + color: '9B59B6' + }, + { + label: 'Grayish Blue', + color: '4E5F70' + }, + { + label: 'Vivid Yellow', + color: 'F1C40F' + }, + { + label: 'Dark Cyan', + color: '16A085' + }, + { + label: 'Dark Emerald', + color: '27AE60' + }, + { + label: 'Strong Blue', + color: '2980B9' + }, + { + label: 'Dark Violet', + color: '8E44AD' + }, + { + label: 'Desaturated Blue', + color: '2C3E50' + }, + { + label: 'Orange', + color: 'F39C12' + }, + { + label: 'Carrot', + color: 'E67E22' + }, + { + label: 'Pale Red', + color: 'E74C3C' + }, + { + label: 'Bright Silver', + color: 'ECF0F1' + }, + { + label: 'Light Grayish Cyan', + color: '95A5A6' + }, + { + label: 'Light Gray', + color: 'DDD' + }, + { + label: 'White', + color: 'FFF' + }, + { + label: 'Pumpkin', + color: 'D35400' + }, + { + label: 'Strong Red', + color: 'C0392B' + }, + { + label: 'Silver', + color: 'BDC3C7' + }, + { + label: 'Grayish Cyan', + color: '7F8C8D' + }, + { + label: 'Dark Gray', + color: '999' + }, + { + label: 'Black', + color: '000' + } + ] + } ); + + editor.conversion.for( 'upcast' ).elementToAttribute( { + view: { + name: 'span', + styles: { + 'color': /#\d+/ + } + }, + model: { + key: 'fontColor', + value: _renderUpcastAttribute + } + } ); + + editor.conversion.for( 'downcast' ).attributeToElement( { + model: 'fontColor', + view: _renderDowncastElement + } ); + + editor.commands.add( FONT_COLOR, new FontColorCommand( editor ) ); + } + + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + + // Allow fontColor attribute on text nodes. + editor.model.schema.extend( '$text', { allowAttributes: FONT_COLOR } ); + } +} + +function _renderUpcastAttribute( viewElement ) { + const fontColor = viewElement.getStyle( 'color' ); + const value = fontColor.replace( '#', '' ); + + return value; +} + +function _renderDowncastElement( modelAttributeValue, viewWriter ) { + return viewWriter.createAttributeElement( 'span', { + style: 'color:#' + modelAttributeValue + } ); +} diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js new file mode 100644 index 0000000..bb1e560 --- /dev/null +++ b/src/fontcolor/fontcolorui.js @@ -0,0 +1,76 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontcolor/fontcolorui + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; + +import fontColorIcon from '../../theme/icons/font-family.svg'; +import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; +import { normalizeOptions } from './utils'; +import InsertColorView from '../ui/insertcolorview'; + +export default class FontColorUI extends Plugin { + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + const t = editor.t; + const command = editor.commands.get( 'fontColor' ); + + const options = this._getLocalizedOptions(); + + // Register UI component. + editor.ui.componentFactory.add( 'fontColor', locale => { + const dropdownView = createDropdown( locale ); + + const insertColorView = new InsertColorView( locale, options ); + dropdownView.panelView.children.add( insertColorView ); + + insertColorView.delegate( 'execute' ).to( dropdownView ); + + dropdownView.buttonView.set( { + label: t( 'Font Color' ), + icon: fontColorIcon, + tooltip: true + } ); + + dropdownView.extendTemplate( { + attributes: { + class: 'ck-font-family-dropdown' + } + } ); + + dropdownView.bind( 'isEnabled' ).to( command ); + + dropdownView.on( 'execute', ( evt, val ) => { + editor.execute( 'fontColor', val ); + } ); + + return dropdownView; + } ); + } + + /** + * Returns options as defined in `config.fontFamily.options` but processed to account for + * editor localization, i.e. to display {@link module:font/fontfamily~FontFamilyOption} + * in the correct language. + * + * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} + * when the user configuration is defined because the editor does not exist yet. + * + * @private + * @returns {Array.}. + */ + _getLocalizedOptions() { + const editor = this.editor; + const options = normalizeOptions( editor.config.get( 'fontColor.options' ) ); + + return options; + } +} diff --git a/src/fontcolor/utils.js b/src/fontcolor/utils.js new file mode 100644 index 0000000..5e513f7 --- /dev/null +++ b/src/fontcolor/utils.js @@ -0,0 +1,29 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontcolor/utils + */ + +export function normalizeOptions( configuredOptions ) { + return configuredOptions + .map( getOptionDefinition ) + .filter( option => !!option ); +} + +function getOptionDefinition( option ) { + return { + title: option.label, + model: option.color, + label: option.label, + view: { + name: 'span', + styles: { + color: `#${ option.color }` + }, + priority: 5 + } + }; +} diff --git a/src/ui/insertcolorview.js b/src/ui/insertcolorview.js new file mode 100644 index 0000000..6289a96 --- /dev/null +++ b/src/ui/insertcolorview.js @@ -0,0 +1,78 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import View from '@ckeditor/ckeditor5-ui/src/view'; +import Template from '@ckeditor/ckeditor5-ui/src/template'; + +export default class InsertColorView extends View { + constructor( locale, options ) { + super( locale ); + + const bind = this.bindTemplate; + + this.items = this.createCollection(); + + this.setTemplate( { + tag: 'div', + attributes: { + class: [ 'ck' ] + }, + + children: [ new ColorTable( options.map( item => ( { name: item.label, color: item.model } ) ), bind, this ) ] + } ); + } +} + +class ColorTable { + constructor( colorsDefinition, bind, colorViewInstance ) { + this.bind = bind; + this.colorsDefinition = colorsDefinition; + this.colorViewInstance = colorViewInstance; + this.COLUMNS = 6; + const template = new Template( { + tag: 'table', + children: this.colorRows(), + attributes: { + style: { + width: '150px' + } + } + } ); + return template; + } + + colorRows() { + const rows = []; + for ( let i = 0; i < Math.ceil( this.colorsDefinition.length / this.COLUMNS ); i++ ) { + rows.push( new Template( { + tag: 'tr', + children: this.colorElements( i ) + } ) ); + } + return rows; + } + + colorElements( index ) { + const elements = []; + for ( let i = 0; i < this.COLUMNS; i++ ) { + elements.push( new Template( { + tag: 'td', + attributes: { + style: { + backgroundColor: `#${ this.colorsDefinition[ index * this.COLUMNS + i ].color }`, + width: '25px', + height: '25px' + } + }, + on: { + click: this.bind.to( () => { + this.colorViewInstance.fire( 'execute', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); + } ) + } + } ) ); + } + return elements; + } +} diff --git a/tests/manual/font-color.html b/tests/manual/font-color.html new file mode 100644 index 0000000..a909c2a --- /dev/null +++ b/tests/manual/font-color.html @@ -0,0 +1,8 @@ +
+

Font Color feature sample.

+ +

Color: #9B59B6;

+

+ Jujubes sweet wafer. Pastry cotton candy sweet muffin dessert cookie. Chocolate cake candy canes dragée wafer donut bear claw. +

+
diff --git a/tests/manual/font-color.js b/tests/manual/font-color.js new file mode 100644 index 0000000..f76bfb9 --- /dev/null +++ b/tests/manual/font-color.js @@ -0,0 +1,24 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* globals console, window, document */ + +import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; +import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; +import FontColor from '../../src/fontcolor'; + +ClassicEditor + .create( document.querySelector( '#editor' ), { + plugins: [ ArticlePluginSet, FontColor ], + toolbar: [ + 'heading', '|', 'fontColor', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' + ] + } ) + .then( editor => { + window.editor = editor; + } ) + .catch( err => { + console.error( err.stack ); + } ); diff --git a/tests/manual/font-color.md b/tests/manual/font-color.md new file mode 100644 index 0000000..e69de29 From a8685d85915daa160efaf4a81357cf54d48fb858 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 7 Mar 2019 13:07:27 +0100 Subject: [PATCH 02/92] Further improvements to font color. Code reorganization, rename view to be more accurate, add feedback for the user when color is selected. --- src/fontcolor/fontcolorui.js | 13 +++-- src/ui/colortableview.js | 98 ++++++++++++++++++++++++++++++++++++ src/ui/insertcolorview.js | 78 ---------------------------- theme/fontcolor.css | 41 +++++++++++++++ 4 files changed, 147 insertions(+), 83 deletions(-) create mode 100644 src/ui/colortableview.js delete mode 100644 src/ui/insertcolorview.js create mode 100644 theme/fontcolor.css diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index bb1e560..1e45b65 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -12,8 +12,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { normalizeOptions } from './utils'; -import InsertColorView from '../ui/insertcolorview'; - +import ColorTableView from '../ui/colortableview'; export default class FontColorUI extends Plugin { /** * @inheritDoc @@ -29,10 +28,14 @@ export default class FontColorUI extends Plugin { editor.ui.componentFactory.add( 'fontColor', locale => { const dropdownView = createDropdown( locale ); - const insertColorView = new InsertColorView( locale, options ); - dropdownView.panelView.children.add( insertColorView ); + const colorTableView = new ColorTableView( locale, { + colors: options.map( item => ( { name: item.label, color: item.model } ) ) + } ); + + dropdownView.panelView.children.add( colorTableView ); - insertColorView.delegate( 'execute' ).to( dropdownView ); + colorTableView.bind( 'selectedColor' ).to( command, 'value' ); + colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); dropdownView.buttonView.set( { label: t( 'Font Color' ), diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js new file mode 100644 index 0000000..3e5cd2d --- /dev/null +++ b/src/ui/colortableview.js @@ -0,0 +1,98 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import View from '@ckeditor/ckeditor5-ui/src/view'; +import Template from '@ckeditor/ckeditor5-ui/src/template'; +import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; + +import '../../theme/fontcolor.css'; + +export default class ColorTableView extends View { + constructor( locale, { colors, columns = 6 } ) { + super( locale ); + + this.COLUMNS = columns; + this.colorsDefinition = colors; + + this.set( 'selectedColor' ); + + this.setTemplate( { + tag: 'div', + attributes: { + class: [ 'ck-color-table' ] + }, + children: [ + this.createColorTableTemplate(), + this.removeColorButton() + ] + } ); + } + + removeColorButton() { + const btnView = new ButtonView(); + btnView.set( { + label: 'X', + tooltip: this.t( 'Remove font color' ), + withText: true + } ); + btnView.class = 'ck-color-table__remove-color'; + btnView.on( 'execute', () => { + this.fire( 'colorPicked', { value: null } ); + } ); + return btnView; + } + + createColorTableTemplate() { + return new Template( { + tag: 'table', + children: this._colorRows(), + attributes: { + class: 'ck-color-table__table' + } + } ); + } + + _colorRows() { + const rows = []; + for ( let i = 0; i < Math.ceil( this.colorsDefinition.length / this.COLUMNS ); i++ ) { + rows.push( new Template( { + tag: 'tr', + children: this._colorElements( i ) + } ) ); + } + return rows; + } + + _colorElements( index ) { + const elements = []; + const bind = this.bindTemplate; + for ( let i = 0; i < this.COLUMNS; i++ ) { + elements.push( new Template( { + tag: 'td', + attributes: { + style: { + backgroundColor: `#${ this.colorsDefinition[ index * this.COLUMNS + i ].color }` + }, + class: [ + 'ck-color-table__cell-color', + bind.if( + 'selectedColor', + 'ck-color-table__cell-color_active', + value => { + return value === this.colorsDefinition[ index * this.COLUMNS + i ].color; + } + ) + ] + }, + on: { + click: bind.to( () => { + this.fire( 'colorPicked', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); + } ) + } + } ) ); + } + return elements; + } +} diff --git a/src/ui/insertcolorview.js b/src/ui/insertcolorview.js deleted file mode 100644 index 6289a96..0000000 --- a/src/ui/insertcolorview.js +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import View from '@ckeditor/ckeditor5-ui/src/view'; -import Template from '@ckeditor/ckeditor5-ui/src/template'; - -export default class InsertColorView extends View { - constructor( locale, options ) { - super( locale ); - - const bind = this.bindTemplate; - - this.items = this.createCollection(); - - this.setTemplate( { - tag: 'div', - attributes: { - class: [ 'ck' ] - }, - - children: [ new ColorTable( options.map( item => ( { name: item.label, color: item.model } ) ), bind, this ) ] - } ); - } -} - -class ColorTable { - constructor( colorsDefinition, bind, colorViewInstance ) { - this.bind = bind; - this.colorsDefinition = colorsDefinition; - this.colorViewInstance = colorViewInstance; - this.COLUMNS = 6; - const template = new Template( { - tag: 'table', - children: this.colorRows(), - attributes: { - style: { - width: '150px' - } - } - } ); - return template; - } - - colorRows() { - const rows = []; - for ( let i = 0; i < Math.ceil( this.colorsDefinition.length / this.COLUMNS ); i++ ) { - rows.push( new Template( { - tag: 'tr', - children: this.colorElements( i ) - } ) ); - } - return rows; - } - - colorElements( index ) { - const elements = []; - for ( let i = 0; i < this.COLUMNS; i++ ) { - elements.push( new Template( { - tag: 'td', - attributes: { - style: { - backgroundColor: `#${ this.colorsDefinition[ index * this.COLUMNS + i ].color }`, - width: '25px', - height: '25px' - } - }, - on: { - click: this.bind.to( () => { - this.colorViewInstance.fire( 'execute', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); - } ) - } - } ) ); - } - return elements; - } -} diff --git a/theme/fontcolor.css b/theme/fontcolor.css new file mode 100644 index 0000000..b44e2ef --- /dev/null +++ b/theme/fontcolor.css @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +.ck-color-table .ck-color-table__table { + margin: 0.5em 0.5em 0 0.5em; + width: 14em; + border-collapse: separate; + border-spacing: 0.2em; +} + +.ck-color-table .ck-color-table__cell-color { + width: 2em; + height: 2em; + border: 0.1em solid #000; + transition-property: border-width; + transition-duration: 0.1s; + transition-timing-function: ease; + text-align: center; + vertical-align: middle; + line-height: 0; +} + +.ck-color-table .ck-color-table__cell-color:hover { + border-width: 0.2em; +} + +.ck-color-table .ck-color-table__cell-color_active::before { + content: "✓"; + font-size: 1.2em; + color: white; + text-shadow: -1px -1px 0 #000, + 1px -1px 0 #000, + -1px 1px 0 #000, + 1px 1px 0 #000; +} + +.ck-color-table .ck-color-table__remove-color { + margin: 0.5em; +} From 0c3b13de2c22dee5782cd24aeb00c09d2720a4a6 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 7 Mar 2019 13:27:52 +0100 Subject: [PATCH 03/92] Move hash to model, to be ready to apply different color options. --- src/fontcolor/fontcolorediting.js | 52 +++++++++++++++---------------- src/fontcolor/utils.js | 2 +- src/ui/colortableview.js | 2 +- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index d77c56c..e7865b6 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -24,99 +24,99 @@ export default class FontColorEditing extends Plugin { options: [ { label: 'Strong Cyan', - color: '1ABC9C' + color: '#1ABC9C' }, { label: 'Emerald', - color: '2ECC71' + color: '#2ECC71' }, { label: 'Bright Blue', - color: '3498DB' + color: '#3498DB' }, { label: 'Amethyst', - color: '9B59B6' + color: '#9B59B6' }, { label: 'Grayish Blue', - color: '4E5F70' + color: '#4E5F70' }, { label: 'Vivid Yellow', - color: 'F1C40F' + color: '#F1C40F' }, { label: 'Dark Cyan', - color: '16A085' + color: '#16A085' }, { label: 'Dark Emerald', - color: '27AE60' + color: '#27AE60' }, { label: 'Strong Blue', - color: '2980B9' + color: '#2980B9' }, { label: 'Dark Violet', - color: '8E44AD' + color: '#8E44AD' }, { label: 'Desaturated Blue', - color: '2C3E50' + color: '#2C3E50' }, { label: 'Orange', - color: 'F39C12' + color: '#F39C12' }, { label: 'Carrot', - color: 'E67E22' + color: '#E67E22' }, { label: 'Pale Red', - color: 'E74C3C' + color: '#E74C3C' }, { label: 'Bright Silver', - color: 'ECF0F1' + color: '#ECF0F1' }, { label: 'Light Grayish Cyan', - color: '95A5A6' + color: '#95A5A6' }, { label: 'Light Gray', - color: 'DDD' + color: '#DDD' }, { label: 'White', - color: 'FFF' + color: '#FFF' }, { label: 'Pumpkin', - color: 'D35400' + color: '#D35400' }, { label: 'Strong Red', - color: 'C0392B' + color: '#C0392B' }, { label: 'Silver', - color: 'BDC3C7' + color: '#BDC3C7' }, { label: 'Grayish Cyan', - color: '7F8C8D' + color: '#7F8C8D' }, { label: 'Dark Gray', - color: '999' + color: '#999' }, { label: 'Black', - color: '000' + color: '#000' } ] } ); @@ -155,13 +155,13 @@ export default class FontColorEditing extends Plugin { function _renderUpcastAttribute( viewElement ) { const fontColor = viewElement.getStyle( 'color' ); - const value = fontColor.replace( '#', '' ); + const value = fontColor; return value; } function _renderDowncastElement( modelAttributeValue, viewWriter ) { return viewWriter.createAttributeElement( 'span', { - style: 'color:#' + modelAttributeValue + style: 'color:' + modelAttributeValue } ); } diff --git a/src/fontcolor/utils.js b/src/fontcolor/utils.js index 5e513f7..8401e7b 100644 --- a/src/fontcolor/utils.js +++ b/src/fontcolor/utils.js @@ -21,7 +21,7 @@ function getOptionDefinition( option ) { view: { name: 'span', styles: { - color: `#${ option.color }` + color: `${ option.color }` }, priority: 5 } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 3e5cd2d..26fe07f 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -73,7 +73,7 @@ export default class ColorTableView extends View { tag: 'td', attributes: { style: { - backgroundColor: `#${ this.colorsDefinition[ index * this.COLUMNS + i ].color }` + backgroundColor: `${ this.colorsDefinition[ index * this.COLUMNS + i ].color }` }, class: [ 'ck-color-table__cell-color', From b6670a44f103b4ebf3ecb4c08d69efc8efac1568 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 7 Mar 2019 13:43:36 +0100 Subject: [PATCH 04/92] Use variable instead of strings. Move upcast and downcast functions to utils. --- src/fontcolor/fontcolorcommand.js | 4 ++-- src/fontcolor/fontcolorediting.js | 25 ++++++------------------- src/fontcolor/fontcolorui.js | 10 +++++----- src/fontcolor/utils.js | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/src/fontcolor/fontcolorcommand.js b/src/fontcolor/fontcolorcommand.js index e100785..2fa37e6 100644 --- a/src/fontcolor/fontcolorcommand.js +++ b/src/fontcolor/fontcolorcommand.js @@ -8,12 +8,12 @@ */ import FontCommand from '../fontcommand'; - +import { FONT_COLOR } from './utils'; export default class FontColorCommand extends FontCommand { /** * @inheritDoc */ constructor( editor ) { - super( editor, 'fontColor' ); + super( editor, FONT_COLOR ); } } diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index e7865b6..5da44dd 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontColorCommand from './fontcolorcommand'; -const FONT_COLOR = 'fontColor'; +import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from './utils'; export default class FontColorEditing extends Plugin { /** @@ -125,18 +125,18 @@ export default class FontColorEditing extends Plugin { view: { name: 'span', styles: { - 'color': /#\d+/ + 'color': /[\s\S]+/ } }, model: { - key: 'fontColor', - value: _renderUpcastAttribute + key: FONT_COLOR, + value: renderUpcastAttribute } } ); editor.conversion.for( 'downcast' ).attributeToElement( { - model: 'fontColor', - view: _renderDowncastElement + model: FONT_COLOR, + view: renderDowncastElement } ); editor.commands.add( FONT_COLOR, new FontColorCommand( editor ) ); @@ -152,16 +152,3 @@ export default class FontColorEditing extends Plugin { editor.model.schema.extend( '$text', { allowAttributes: FONT_COLOR } ); } } - -function _renderUpcastAttribute( viewElement ) { - const fontColor = viewElement.getStyle( 'color' ); - const value = fontColor; - - return value; -} - -function _renderDowncastElement( modelAttributeValue, viewWriter ) { - return viewWriter.createAttributeElement( 'span', { - style: 'color:' + modelAttributeValue - } ); -} diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 1e45b65..1e26759 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { normalizeOptions } from './utils'; +import { normalizeOptions, FONT_COLOR } from './utils'; import ColorTableView from '../ui/colortableview'; export default class FontColorUI extends Plugin { /** @@ -20,12 +20,12 @@ export default class FontColorUI extends Plugin { init() { const editor = this.editor; const t = editor.t; - const command = editor.commands.get( 'fontColor' ); + const command = editor.commands.get( FONT_COLOR ); const options = this._getLocalizedOptions(); // Register UI component. - editor.ui.componentFactory.add( 'fontColor', locale => { + editor.ui.componentFactory.add( FONT_COLOR, locale => { const dropdownView = createDropdown( locale ); const colorTableView = new ColorTableView( locale, { @@ -52,7 +52,7 @@ export default class FontColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); dropdownView.on( 'execute', ( evt, val ) => { - editor.execute( 'fontColor', val ); + editor.execute( FONT_COLOR, val ); } ); return dropdownView; @@ -72,7 +72,7 @@ export default class FontColorUI extends Plugin { */ _getLocalizedOptions() { const editor = this.editor; - const options = normalizeOptions( editor.config.get( 'fontColor.options' ) ); + const options = normalizeOptions( editor.config.get( `${ FONT_COLOR }.options` ) ); return options; } diff --git a/src/fontcolor/utils.js b/src/fontcolor/utils.js index 8401e7b..763338b 100644 --- a/src/fontcolor/utils.js +++ b/src/fontcolor/utils.js @@ -7,12 +7,27 @@ * @module font/fontcolor/utils */ +export const FONT_COLOR = 'fontColor'; + export function normalizeOptions( configuredOptions ) { return configuredOptions .map( getOptionDefinition ) .filter( option => !!option ); } +export function renderUpcastAttribute( viewElement ) { + const fontColor = viewElement.getStyle( 'color' ); + const value = fontColor; + + return value; +} + +export function renderDowncastElement( modelAttributeValue, viewWriter ) { + return viewWriter.createAttributeElement( 'span', { + style: 'color:' + modelAttributeValue + } ); +} + function getOptionDefinition( option ) { return { title: option.label, From 7c38f8fe564fc960cd9ca3c76a4109403549de12 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 7 Mar 2019 16:59:09 +0100 Subject: [PATCH 05/92] Improve test case examples. Add biding for color name in panel. --- src/fontcolor/utils.js | 8 +++++--- src/ui/colortableview.js | 14 ++++++++++++-- tests/manual/font-color.html | 22 +++++++++++++++++----- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/fontcolor/utils.js b/src/fontcolor/utils.js index 763338b..aeb0ffa 100644 --- a/src/fontcolor/utils.js +++ b/src/fontcolor/utils.js @@ -17,9 +17,7 @@ export function normalizeOptions( configuredOptions ) { export function renderUpcastAttribute( viewElement ) { const fontColor = viewElement.getStyle( 'color' ); - const value = fontColor; - - return value; + return normalizeColorCode( fontColor ); } export function renderDowncastElement( modelAttributeValue, viewWriter ) { @@ -42,3 +40,7 @@ function getOptionDefinition( option ) { } }; } + +function normalizeColorCode( color ) { + return color.replace( /\s/g, '' ); +} diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 26fe07f..b8a3cfe 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -8,15 +8,16 @@ import Template from '@ckeditor/ckeditor5-ui/src/template'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import '../../theme/fontcolor.css'; - export default class ColorTableView extends View { constructor( locale, { colors, columns = 6 } ) { super( locale ); + const bind = this.bindTemplate; this.COLUMNS = columns; this.colorsDefinition = colors; this.set( 'selectedColor' ); + this.set( 'hoveredColor' ); this.setTemplate( { tag: 'div', @@ -25,7 +26,10 @@ export default class ColorTableView extends View { }, children: [ this.createColorTableTemplate(), - this.removeColorButton() + this.removeColorButton(), + { + text: bind.to( 'hoveredColor' ) + } ] } ); } @@ -89,6 +93,12 @@ export default class ColorTableView extends View { on: { click: bind.to( () => { this.fire( 'colorPicked', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); + } ), + mouseover: bind.to( () => { + this.set( 'hoveredColor', this.colorsDefinition[ index * this.COLUMNS + i ].name ); + } ), + mouseout: bind.to( () => { + this.set( 'hoveredColor', undefined ); } ) } } ) ); diff --git a/tests/manual/font-color.html b/tests/manual/font-color.html index a909c2a..52fb67e 100644 --- a/tests/manual/font-color.html +++ b/tests/manual/font-color.html @@ -1,8 +1,20 @@

Font Color feature sample.

- -

Color: #9B59B6;

-

- Jujubes sweet wafer. Pastry cotton candy sweet muffin dessert cookie. Chocolate cake candy canes dragée wafer donut bear claw. -

+

color:gold

+

color:lightcoral;

+

color:#9B59B6

+

color:rgb(248, 77, 77)

+

color:rgb(248,180,77)

+

color:rgba(248, 77, 77, 0.8)

+

color:rgba(248,180,77,0.8)

+

color:rgba(248, 77, 77, .8)

+

color:rgba(248,180,77,.8)

+

color:rgb(10%, 80%, 0%);

+

color:rgb(85%,70%,5%);

+

color:rgba(10%, 80%, 0%, 80%);

+

color:rgba(85%,70%,5%,80%);

+

color:hsl(0, 100%, 50%);

+

color:hsl(50,100%,50%);

+

color:hsla(100, 100%, 50%, 80%);

+

color:hsla(250,100%,50%,80%);

From 34545e7c0ddbaae891d39402dd3a578fed5d8c58 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 8 Mar 2019 13:12:40 +0100 Subject: [PATCH 06/92] Add font background color, move common logic to utils and update paths for imports. --- src/fontbackgroundcolor.js | 28 ++++ .../fontbackgroundcolorcommand.js | 19 +++ .../fontbackgroundcolorediting.js | 154 ++++++++++++++++++ .../fontbackgroundcolorui.js | 79 +++++++++ src/fontcolor.js | 2 +- src/fontcolor/fontcolorcommand.js | 2 +- src/fontcolor/fontcolorediting.js | 6 +- src/fontcolor/fontcolorui.js | 2 +- src/fontcolor/utils.js | 46 ------ src/utils.js | 41 +++++ tests/manual/font-color.js | 6 +- 11 files changed, 331 insertions(+), 54 deletions(-) create mode 100644 src/fontbackgroundcolor.js create mode 100644 src/fontbackgroundcolor/fontbackgroundcolorcommand.js create mode 100644 src/fontbackgroundcolor/fontbackgroundcolorediting.js create mode 100644 src/fontbackgroundcolor/fontbackgroundcolorui.js delete mode 100644 src/fontcolor/utils.js diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js new file mode 100644 index 0000000..f10d611 --- /dev/null +++ b/src/fontbackgroundcolor.js @@ -0,0 +1,28 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontbackgroundcolor + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import FontBackgroundColorEditing from './fontbackgroundcolor/fontbackgroundcolorediting'; +import FontBackgroundColorUI from './fontbackgroundcolor/fontbackgroundcolorui'; + +export default class FontBackgroundColor extends Plugin { + /** + * @inheritDoc + */ + static get requires() { + return [ FontBackgroundColorEditing, FontBackgroundColorUI ]; + } + + /** + * @inheritDoc + */ + static get pluginName() { + return 'FontBackgroundColor'; + } +} diff --git a/src/fontbackgroundcolor/fontbackgroundcolorcommand.js b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js new file mode 100644 index 0000000..848319a --- /dev/null +++ b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js @@ -0,0 +1,19 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontbackgroundcolor/fontbackgroundcolorcommand + */ + +import FontCommand from '../fontcommand'; +import { FONT_BACKGROUND_COLOR } from '../utils'; +export default class FontBackgroundColorCommand extends FontCommand { + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor, FONT_BACKGROUND_COLOR ); + } +} diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js new file mode 100644 index 0000000..8ad9db6 --- /dev/null +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -0,0 +1,154 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontfamily/fontfamilyediting + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; + +import FontBackgroundColorCommand from './fontbackgroundcolorcommand'; + +import { FONT_BACKGROUND_COLOR, renderDowncastElement, renderUpcastAttribute } from '../utils'; + +export default class FontBackgroundColorEditing extends Plugin { + /** + * @inheritDoc + */ + constructor( editor ) { + super( editor ); + + editor.config.define( FONT_BACKGROUND_COLOR, { + options: [ + { + label: 'Strong Cyan', + color: '#1ABC9C' + }, + { + label: 'Emerald', + color: '#2ECC71' + }, + { + label: 'Bright Blue', + color: '#3498DB' + }, + { + label: 'Amethyst', + color: '#9B59B6' + }, + { + label: 'Grayish Blue', + color: '#4E5F70' + }, + { + label: 'Vivid Yellow', + color: '#F1C40F' + }, + { + label: 'Dark Cyan', + color: '#16A085' + }, + { + label: 'Dark Emerald', + color: '#27AE60' + }, + { + label: 'Strong Blue', + color: '#2980B9' + }, + { + label: 'Dark Violet', + color: '#8E44AD' + }, + { + label: 'Desaturated Blue', + color: '#2C3E50' + }, + { + label: 'Orange', + color: '#F39C12' + }, + { + label: 'Carrot', + color: '#E67E22' + }, + { + label: 'Pale Red', + color: '#E74C3C' + }, + { + label: 'Bright Silver', + color: '#ECF0F1' + }, + { + label: 'Light Grayish Cyan', + color: '#95A5A6' + }, + { + label: 'Light Gray', + color: '#DDD' + }, + { + label: 'White', + color: '#FFF' + }, + { + label: 'Pumpkin', + color: '#D35400' + }, + { + label: 'Strong Red', + color: '#C0392B' + }, + { + label: 'Silver', + color: '#BDC3C7' + }, + { + label: 'Grayish Cyan', + color: '#7F8C8D' + }, + { + label: 'Dark Gray', + color: '#999' + }, + { + label: 'Black', + color: '#000' + } + ] + } ); + + editor.conversion.for( 'upcast' ).elementToAttribute( { + view: { + name: 'span', + styles: { + 'background-color': /[\s\S]+/ + } + }, + model: { + key: FONT_BACKGROUND_COLOR, + value: renderUpcastAttribute( 'background-color' ) + } + } ); + + editor.conversion.for( 'downcast' ).attributeToElement( { + model: FONT_BACKGROUND_COLOR, + view: renderDowncastElement( 'background-color' ) + } ); + + editor.commands.add( FONT_BACKGROUND_COLOR, new FontBackgroundColorCommand( editor ) ); + } + + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + + // Allow fontBackgroundColor attribute on text nodes. + editor.model.schema.extend( '$text', { allowAttributes: FONT_BACKGROUND_COLOR } ); + } +} diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js new file mode 100644 index 0000000..f505b2e --- /dev/null +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -0,0 +1,79 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontbackgroundcolor/fontbackgroundolorui + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; + +import fontBackgroundColorIcon from '../../theme/icons/font-family.svg'; +import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; +import { FONT_BACKGROUND_COLOR, normalizeOptions } from '../utils'; +import ColorTableView from '../ui/colortableview'; +export default class FontBackgroundColorUI extends Plugin { + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + const t = editor.t; + const command = editor.commands.get( FONT_BACKGROUND_COLOR ); + + const options = this._getLocalizedOptions(); + + // Register UI component. + editor.ui.componentFactory.add( FONT_BACKGROUND_COLOR, locale => { + const dropdownView = createDropdown( locale ); + + const colorTableView = new ColorTableView( locale, { + colors: options.map( item => ( { name: item.label, color: item.model } ) ) + } ); + + dropdownView.panelView.children.add( colorTableView ); + + colorTableView.bind( 'selectedColor' ).to( command, 'value' ); + colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); + + dropdownView.buttonView.set( { + label: t( 'Font Background Color' ), + icon: fontBackgroundColorIcon, + tooltip: true + } ); + + dropdownView.extendTemplate( { + attributes: { + class: 'ck-font-family-dropdown' + } + } ); + + dropdownView.bind( 'isEnabled' ).to( command ); + + dropdownView.on( 'execute', ( evt, val ) => { + editor.execute( FONT_BACKGROUND_COLOR, val ); + } ); + + return dropdownView; + } ); + } + + /** + * Returns options as defined in `config.fontFamily.options` but processed to account for + * editor localization, i.e. to display {@link module:font/fontfamily~FontFamilyOption} + * in the correct language. + * + * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} + * when the user configuration is defined because the editor does not exist yet. + * + * @private + * @returns {Array.}. + */ + _getLocalizedOptions() { + const editor = this.editor; + const options = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.options` ) ); + + return options; + } +} diff --git a/src/fontcolor.js b/src/fontcolor.js index 886dc54..18d3b1e 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontColorEditing from './fontcolor/fontcolorediting'; import FontColorUI from './fontcolor/fontcolorui'; -export default class FontFamily extends Plugin { +export default class FontColor extends Plugin { /** * @inheritDoc */ diff --git a/src/fontcolor/fontcolorcommand.js b/src/fontcolor/fontcolorcommand.js index 2fa37e6..b669c84 100644 --- a/src/fontcolor/fontcolorcommand.js +++ b/src/fontcolor/fontcolorcommand.js @@ -8,7 +8,7 @@ */ import FontCommand from '../fontcommand'; -import { FONT_COLOR } from './utils'; +import { FONT_COLOR } from '../utils'; export default class FontColorCommand extends FontCommand { /** * @inheritDoc diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index 5da44dd..019755a 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontColorCommand from './fontcolorcommand'; -import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from './utils'; +import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from '../utils'; export default class FontColorEditing extends Plugin { /** @@ -130,13 +130,13 @@ export default class FontColorEditing extends Plugin { }, model: { key: FONT_COLOR, - value: renderUpcastAttribute + value: renderUpcastAttribute( 'color' ) } } ); editor.conversion.for( 'downcast' ).attributeToElement( { model: FONT_COLOR, - view: renderDowncastElement + view: renderDowncastElement( 'color' ) } ); editor.commands.add( FONT_COLOR, new FontColorCommand( editor ) ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 1e26759..f9e7510 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { normalizeOptions, FONT_COLOR } from './utils'; +import { FONT_COLOR, normalizeOptions } from '../utils'; import ColorTableView from '../ui/colortableview'; export default class FontColorUI extends Plugin { /** diff --git a/src/fontcolor/utils.js b/src/fontcolor/utils.js deleted file mode 100644 index aeb0ffa..0000000 --- a/src/fontcolor/utils.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * @module font/fontcolor/utils - */ - -export const FONT_COLOR = 'fontColor'; - -export function normalizeOptions( configuredOptions ) { - return configuredOptions - .map( getOptionDefinition ) - .filter( option => !!option ); -} - -export function renderUpcastAttribute( viewElement ) { - const fontColor = viewElement.getStyle( 'color' ); - return normalizeColorCode( fontColor ); -} - -export function renderDowncastElement( modelAttributeValue, viewWriter ) { - return viewWriter.createAttributeElement( 'span', { - style: 'color:' + modelAttributeValue - } ); -} - -function getOptionDefinition( option ) { - return { - title: option.label, - model: option.color, - label: option.label, - view: { - name: 'span', - styles: { - color: `${ option.color }` - }, - priority: 5 - } - }; -} - -function normalizeColorCode( color ) { - return color.replace( /\s/g, '' ); -} diff --git a/src/utils.js b/src/utils.js index ca02a9c..f20a755 100644 --- a/src/utils.js +++ b/src/utils.js @@ -35,3 +35,44 @@ export function buildDefinition( modelAttributeKey, options ) { return definition; } + +export const FONT_COLOR = 'fontColor'; +export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; + +export function renderUpcastAttribute( styleAttr ) { + return viewElement => { + const fontColor = viewElement.getStyle( styleAttr ); + return normalizeColorCode( fontColor ); + }; +} + +export function renderDowncastElement( styleAttr ) { + return ( modelAttributeValue, viewWriter ) => viewWriter.createAttributeElement( 'span', { + style: `${ styleAttr }:${ modelAttributeValue }` + } ); +} + +function normalizeColorCode( value ) { + return value.replace( /\s/g, '' ); +} + +export function normalizeOptions( configuredOptions ) { + return configuredOptions + .map( getOptionDefinition ) + .filter( option => !!option ); +} + +function getOptionDefinition( option ) { + return { + title: option.label, + model: option.color, + label: option.label, + view: { + name: 'span', + styles: { + color: `${ option.color }` + }, + priority: 5 + } + }; +} diff --git a/tests/manual/font-color.js b/tests/manual/font-color.js index f76bfb9..0c68d5c 100644 --- a/tests/manual/font-color.js +++ b/tests/manual/font-color.js @@ -8,12 +8,14 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import FontColor from '../../src/fontcolor'; +import FontBackgroundColor from '../../src/fontbackgroundcolor'; ClassicEditor .create( document.querySelector( '#editor' ), { - plugins: [ ArticlePluginSet, FontColor ], + plugins: [ ArticlePluginSet, FontColor, FontBackgroundColor ], toolbar: [ - 'heading', '|', 'fontColor', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' + 'heading', '|', + 'fontColor', 'fontBackgroundColor', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ] } ) .then( editor => { From cef3c57cb24c7a2e35633b83c8621cbd34fcad70 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 8 Mar 2019 13:24:20 +0100 Subject: [PATCH 07/92] Extract tooltip for remove color button. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 3 ++- src/fontcolor/fontcolorui.js | 3 ++- src/ui/colortableview.js | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index f505b2e..3628821 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -29,7 +29,8 @@ export default class FontBackgroundColorUI extends Plugin { const dropdownView = createDropdown( locale ); const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ) + colors: options.map( item => ( { name: item.label, color: item.model } ) ), + removeButtonTooltip: t( 'Remove background color' ) } ); dropdownView.panelView.children.add( colorTableView ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index f9e7510..7408f0f 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -29,7 +29,8 @@ export default class FontColorUI extends Plugin { const dropdownView = createDropdown( locale ); const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ) + colors: options.map( item => ( { name: item.label, color: item.model } ) ), + removeButtonTooltip: t( 'Remove text color' ) } ); dropdownView.panelView.children.add( colorTableView ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index b8a3cfe..2a98b88 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -9,12 +9,13 @@ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import '../../theme/fontcolor.css'; export default class ColorTableView extends View { - constructor( locale, { colors, columns = 6 } ) { + constructor( locale, { colors, removeButtonTooltip, columns = 6 } ) { super( locale ); const bind = this.bindTemplate; this.COLUMNS = columns; this.colorsDefinition = colors; + this.removeButtonTooltip = removeButtonTooltip; this.set( 'selectedColor' ); this.set( 'hoveredColor' ); @@ -38,7 +39,7 @@ export default class ColorTableView extends View { const btnView = new ButtonView(); btnView.set( { label: 'X', - tooltip: this.t( 'Remove font color' ), + tooltip: this.removeButtonTooltip, withText: true } ); btnView.class = 'ck-color-table__remove-color'; From e30173cf0d0bd0281f686ecb1103ba943090bc91 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 11 Mar 2019 10:06:27 +0100 Subject: [PATCH 08/92] Extract button tooltip to observable. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 4 ++-- src/fontcolor/fontcolorui.js | 4 ++-- src/ui/colortableview.js | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 3628821..b402091 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -29,9 +29,9 @@ export default class FontBackgroundColorUI extends Plugin { const dropdownView = createDropdown( locale ); const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ), - removeButtonTooltip: t( 'Remove background color' ) + colors: options.map( item => ( { name: item.label, color: item.model } ) ) } ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); dropdownView.panelView.children.add( colorTableView ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 7408f0f..ae553e9 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -29,10 +29,10 @@ export default class FontColorUI extends Plugin { const dropdownView = createDropdown( locale ); const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ), - removeButtonTooltip: t( 'Remove text color' ) + colors: options.map( item => ( { name: item.label, color: item.model } ) ) } ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); dropdownView.panelView.children.add( colorTableView ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 2a98b88..d3708f7 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -9,16 +9,16 @@ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import '../../theme/fontcolor.css'; export default class ColorTableView extends View { - constructor( locale, { colors, removeButtonTooltip, columns = 6 } ) { + constructor( locale, { colors } ) { super( locale ); const bind = this.bindTemplate; - this.COLUMNS = columns; + this.COLUMNS = 6; this.colorsDefinition = colors; - this.removeButtonTooltip = removeButtonTooltip; this.set( 'selectedColor' ); this.set( 'hoveredColor' ); + this.set( 'removeButtonTooltip' ); this.setTemplate( { tag: 'div', @@ -39,9 +39,9 @@ export default class ColorTableView extends View { const btnView = new ButtonView(); btnView.set( { label: 'X', - tooltip: this.removeButtonTooltip, withText: true } ); + btnView.bind( 'tooltip' ).to( this, 'removeButtonTooltip' ); btnView.class = 'ck-color-table__remove-color'; btnView.on( 'execute', () => { this.fire( 'colorPicked', { value: null } ); From 6646611426d6a4d6efd7fcb47cae0a348a328cdd Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 11 Mar 2019 10:55:12 +0100 Subject: [PATCH 09/92] Add font color and font background color as requirement for font plugin. --- src/font.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/font.js b/src/font.js index ad05c8d..706afa2 100644 --- a/src/font.js +++ b/src/font.js @@ -11,6 +11,8 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontFamily from './fontfamily'; import FontSize from './fontsize'; +import FontColor from './fontcolor'; +import FontBackgroundColor from './fontbackgroundcolor'; /** * A plugin that enables a set of text styling features: @@ -28,7 +30,7 @@ export default class Font extends Plugin { * @inheritDoc */ static get requires() { - return [ FontFamily, FontSize ]; + return [ FontFamily, FontSize, FontColor, FontBackgroundColor ]; } /** From 8621892d3779655cc53ae5b5426d54930b567881 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 11 Mar 2019 10:58:57 +0100 Subject: [PATCH 10/92] Fix unit test to expect font color and font background color plugin. --- tests/font.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/font.js b/tests/font.js index 38a1bf5..6dd1b66 100644 --- a/tests/font.js +++ b/tests/font.js @@ -6,10 +6,12 @@ import Font from './../src/font'; import FontFamily from './../src/fontfamily'; import FontSize from './../src/fontsize'; +import FontColor from './../src/fontcolor'; +import FontBackgroundColor from './../src/fontbackgroundcolor'; describe( 'Font', () => { - it( 'requires FontSize', () => { - expect( Font.requires ).to.deep.equal( [ FontFamily, FontSize ] ); + it( 'requires FontFamily, FontSize, FontColor, FontBackgroundColor', () => { + expect( Font.requires ).to.deep.equal( [ FontFamily, FontSize, FontColor, FontBackgroundColor ] ); } ); it( 'defines plugin name', () => { From 468b164ec4135edcb91de76637bbb0f4733f749c Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 11 Mar 2019 14:03:17 +0100 Subject: [PATCH 11/92] Add some basic unit test for font color and font background color and its commands. --- tests/fontbackgroundcolor.js | 18 ++++++++++ .../fontbackgroundcolorcommand.js | 35 +++++++++++++++++++ tests/fontcolor.js | 18 ++++++++++ tests/fontcolor/fontcolorcommand.js | 35 +++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 tests/fontbackgroundcolor.js create mode 100644 tests/fontbackgroundcolor/fontbackgroundcolorcommand.js create mode 100644 tests/fontcolor.js create mode 100644 tests/fontcolor/fontcolorcommand.js diff --git a/tests/fontbackgroundcolor.js b/tests/fontbackgroundcolor.js new file mode 100644 index 0000000..5aa9658 --- /dev/null +++ b/tests/fontbackgroundcolor.js @@ -0,0 +1,18 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontBackgroundColor from './../src/fontbackgroundcolor'; +import FontBackgroundColorEditing from './../src/fontbackgroundcolor/fontbackgroundcolorediting'; +import FontBackgroundColorUI from '../src/fontbackgroundcolor/fontbackgroundcolorui'; + +describe( 'FontBackgroundColor', () => { + it( 'requires FontBackgroundColorEditing and FontBackgroundColorUI', () => { + expect( FontBackgroundColor.requires ).to.deep.equal( [ FontBackgroundColorEditing, FontBackgroundColorUI ] ); + } ); + + it( 'defines plugin name', () => { + expect( FontBackgroundColor.pluginName ).to.equal( 'FontBackgroundColor' ); + } ); +} ); diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js b/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js new file mode 100644 index 0000000..24d8b19 --- /dev/null +++ b/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js @@ -0,0 +1,35 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontBackgroundColorCommand from '../../src/fontbackgroundcolor/fontbackgroundcolorcommand'; +import FontCommand from '../../src/fontcommand'; + +import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; + +describe( 'FontBackgroundColorCommand', () => { + let editor, command; + + beforeEach( () => { + return ModelTestEditor.create() + .then( newEditor => { + editor = newEditor; + + command = new FontBackgroundColorCommand( editor ); + } ); + } ); + + afterEach( () => { + editor.destroy(); + } ); + + it( 'is a FontCommand', () => { + expect( FontBackgroundColorCommand.prototype ).to.be.instanceOf( FontCommand ); + expect( command ).to.be.instanceOf( FontCommand ); + } ); + + it( 'operates on fontBackgroundColor attribute', () => { + expect( command ).to.have.property( 'attributeKey', 'fontBackgroundColor' ); + } ); +} ); diff --git a/tests/fontcolor.js b/tests/fontcolor.js new file mode 100644 index 0000000..99068f7 --- /dev/null +++ b/tests/fontcolor.js @@ -0,0 +1,18 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontColor from './../src/fontcolor'; +import FontColorEditing from './../src/fontcolor/fontcolorediting'; +import FontColorUI from '../src/fontcolor/fontcolorui'; + +describe( 'FontColor', () => { + it( 'requires FontColorEditing and FontColorUI', () => { + expect( FontColor.requires ).to.deep.equal( [ FontColorEditing, FontColorUI ] ); + } ); + + it( 'defines plugin name', () => { + expect( FontColor.pluginName ).to.equal( 'FontColor' ); + } ); +} ); diff --git a/tests/fontcolor/fontcolorcommand.js b/tests/fontcolor/fontcolorcommand.js new file mode 100644 index 0000000..ae9cf29 --- /dev/null +++ b/tests/fontcolor/fontcolorcommand.js @@ -0,0 +1,35 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontColorCommand from '../../src/fontcolor/fontcolorcommand'; +import FontCommand from '../../src/fontcommand'; + +import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; + +describe( 'FontColorCommand', () => { + let editor, command; + + beforeEach( () => { + return ModelTestEditor.create() + .then( newEditor => { + editor = newEditor; + + command = new FontColorCommand( editor ); + } ); + } ); + + afterEach( () => { + editor.destroy(); + } ); + + it( 'is a FontCommand', () => { + expect( FontColorCommand.prototype ).to.be.instanceOf( FontCommand ); + expect( command ).to.be.instanceOf( FontCommand ); + } ); + + it( 'operates on fontColor attribute', () => { + expect( command ).to.have.property( 'attributeKey', 'fontColor' ); + } ); +} ); From 252c52001a011af994ddafb224e4169095d770d8 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 12 Mar 2019 12:09:29 +0100 Subject: [PATCH 12/92] Correct class names for color ropdown containers. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 2 +- src/fontcolor/fontcolorui.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index b402091..4a4dab5 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -46,7 +46,7 @@ export default class FontBackgroundColorUI extends Plugin { dropdownView.extendTemplate( { attributes: { - class: 'ck-font-family-dropdown' + class: 'ck-font-background-color-dropdown' } } ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index ae553e9..0bd6f13 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -46,7 +46,7 @@ export default class FontColorUI extends Plugin { dropdownView.extendTemplate( { attributes: { - class: 'ck-font-family-dropdown' + class: 'ck-font-color-dropdown' } } ); From 8da5975c5545cd85a01fbea5c8948745fea2b37f Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 12 Mar 2019 16:47:41 +0100 Subject: [PATCH 13/92] Make better separation of used utils. --- src/fontcolor/fontcolorui.js | 16 ++++++---------- src/utils.js | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 0bd6f13..7eb43c2 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -11,8 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_COLOR, normalizeOptions } from '../utils'; -import ColorTableView from '../ui/colortableview'; +import { FONT_COLOR, normalizeOptions, colorUI } from '../utils'; export default class FontColorUI extends Plugin { /** * @inheritDoc @@ -27,16 +26,13 @@ export default class FontColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_COLOR, locale => { const dropdownView = createDropdown( locale ); - - const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ) - } ); - - colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); - dropdownView.panelView.children.add( colorTableView ); + const colorTableView = colorUI.addColorsToDropdown( + dropdownView, + options.map( item => ( { name: item.label, color: item.model } ) ) + ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); dropdownView.buttonView.set( { label: t( 'Font Color' ), diff --git a/src/utils.js b/src/utils.js index f20a755..efd064b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -7,6 +7,8 @@ * @module font/utils */ +import ColorTableView from './ui/colortableview'; + /** * Builds a proper {@link module:engine/conversion/conversion~ConverterDefinition converter definition} out of input data. * @@ -76,3 +78,15 @@ function getOptionDefinition( option ) { } }; } + +export const colorUI = { + addColorsToDropdown( dropdownView, colors ) { + const locale = dropdownView.locale; + const colorTableView = new ColorTableView( locale, { colors } ); + + dropdownView.panelView.children.add( colorTableView ); + + colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); + return colorTableView; + } +}; From eed4b4838f4977e35b924613f7445d3a6cd6d320 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 12 Mar 2019 16:59:50 +0100 Subject: [PATCH 14/92] Add basic unit tests for font color. --- tests/fontcolor/fontcolorediting.js | 180 ++++++++++++++++++++++++++++ tests/fontcolor/fontcolorui.js | 144 ++++++++++++++++++++++ 2 files changed, 324 insertions(+) create mode 100644 tests/fontcolor/fontcolorediting.js create mode 100644 tests/fontcolor/fontcolorui.js diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js new file mode 100644 index 0000000..f4ff8d8 --- /dev/null +++ b/tests/fontcolor/fontcolorediting.js @@ -0,0 +1,180 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontColorEditing from './../../src/fontcolor/fontcolorediting'; + +import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; + +import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; +import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; + +describe( 'FontColorEditing', () => { + let editor, doc; + + beforeEach( () => VirtualTestEditor + .create( { + plugins: [ FontColorEditing, Paragraph ] + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.document; + } ) + ); + + afterEach( () => { + editor.destroy(); + } ); + + it( 'should set proper schema rules', () => { + expect( editor.model.schema.checkAttribute( [ '$block', '$text' ], 'fontColor' ) ).to.be.true; + expect( editor.model.schema.checkAttribute( [ '$clipboardHolder', '$text' ], 'fontColor' ) ).to.be.true; + + expect( editor.model.schema.checkAttribute( [ '$block' ], 'fontColor' ) ).to.be.false; + } ); + + describe( 'config', () => { + describe( 'default value', () => { + it( 'should be set', () => { + expect( editor.config.get( 'fontColor.options' ) ).to.deep.equal( [ + { + label: 'Strong Cyan', + color: '#1ABC9C' + }, + { + label: 'Emerald', + color: '#2ECC71' + }, + { + label: 'Bright Blue', + color: '#3498DB' + }, + { + label: 'Amethyst', + color: '#9B59B6' + }, + { + label: 'Grayish Blue', + color: '#4E5F70' + }, + { + label: 'Vivid Yellow', + color: '#F1C40F' + }, + { + label: 'Dark Cyan', + color: '#16A085' + }, + { + label: 'Dark Emerald', + color: '#27AE60' + }, + { + label: 'Strong Blue', + color: '#2980B9' + }, + { + label: 'Dark Violet', + color: '#8E44AD' + }, + { + label: 'Desaturated Blue', + color: '#2C3E50' + }, + { + label: 'Orange', + color: '#F39C12' + }, + { + label: 'Carrot', + color: '#E67E22' + }, + { + label: 'Pale Red', + color: '#E74C3C' + }, + { + label: 'Bright Silver', + color: '#ECF0F1' + }, + { + label: 'Light Grayish Cyan', + color: '#95A5A6' + }, + { + label: 'Light Gray', + color: '#DDD' + }, + { + label: 'White', + color: '#FFF' + }, + { + label: 'Pumpkin', + color: '#D35400' + }, + { + label: 'Strong Red', + color: '#C0392B' + }, + { + label: 'Silver', + color: '#BDC3C7' + }, + { + label: 'Grayish Cyan', + color: '#7F8C8D' + }, + { + label: 'Dark Gray', + color: '#999' + }, + { + label: 'Black', + color: '#000' + } + ] ); + } ); + } ); + } ); + + describe( 'editing pipeline conversion', () => { + beforeEach( () => VirtualTestEditor + .create( { + plugins: [ FontColorEditing, Paragraph ], + fontColor: { + options: [ + { + label: 'Color1', + color: '#000' + }, { + label: 'Color2', + color: '#123456' + }, { + label: 'Color3', + color: 'rgb( 0, 10, 20 )' + }, { + label: 'Color4', + color: 'hsl( 200,100%,50%)' + }, { + label: 'Color5 - Light Green', + color: 'lightgreen' + } + ] + } + } ) + .then( newEditor => { + editor = newEditor; + doc = editor.model; + } ) + ); + + it( 'should convert fontColor attribute to proper style value.', () => { + setModelData( doc, 'fo<$text fontColor="#000">o bar' ); + + expect( editor.getData() ).to.equal( '

foo bar

' ); + } ); + } ); +} ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js new file mode 100644 index 0000000..66e3cc0 --- /dev/null +++ b/tests/fontcolor/fontcolorui.js @@ -0,0 +1,144 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* global document */ + +import FontColorEditing from '../../src/fontcolor/fontcolorediting'; +import FontColorUI from '../../src/fontcolor/fontcolorui'; + +import fontColorIcon from '../../theme/icons/font-family.svg'; + +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; +import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; +import { add as addTranslations, _clear as clearTranslations } from '@ckeditor/ckeditor5-utils/src/translation-service'; + +describe( 'FontColorUI', () => { + let editor, command, element; + + testUtils.createSinonSandbox(); + + before( () => { + addTranslations( 'en', { + 'Font Color': 'Font Color', + 'Remove text color': 'Remove text color' + } ); + + addTranslations( 'pl', { + 'Font Color': 'Kolor czcionki', + 'Remove text color': 'Usuń kolor tekstu' + } ); + } ); + + after( () => { + clearTranslations(); + } ); + + beforeEach( () => { + element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ FontColorEditing, FontColorUI ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); + + afterEach( () => { + element.remove(); + + return editor.destroy(); + } ); + + describe( 'fontColor Dropdown', () => { + let dropdown; + + beforeEach( () => { + command = editor.commands.get( 'fontColor' ); + dropdown = editor.ui.componentFactory.create( 'fontColor' ); + } ); + + it( 'button has the base properties', () => { + const button = dropdown.buttonView; + + expect( button ).to.have.property( 'label', 'Font Color' ); + expect( button ).to.have.property( 'tooltip', true ); + expect( button ).to.have.property( 'icon', fontColorIcon ); + } ); + + it( 'should add custom CSS class to dropdown', () => { + const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + + dropdown.render(); + + expect( dropdown.element.classList.contains( 'ck-font-color-dropdown' ) ).to.be.true; + } ); + + it( 'should focus view after command execution', () => { + const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); + const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + + dropdown.commandName = 'fontColor'; + dropdown.fire( 'execute' ); + + sinon.assert.calledOnce( focusSpy ); + } ); + + describe( 'model to command binding', () => { + it( 'isEnabled', () => { + command.isEnabled = false; + + expect( dropdown.buttonView.isEnabled ).to.be.false; + + command.isEnabled = true; + expect( dropdown.buttonView.isEnabled ).to.be.true; + } ); + } ); + + describe( 'localization', () => { + beforeEach( () => { + return localizedEditor(); + } ); + + it( 'works for the #buttonView', () => { + const buttonView = dropdown.buttonView; + + expect( buttonView.label ).to.equal( 'Kolor czcionki' ); + } ); + + it( 'works for the colorTableView#items in the panel', () => { + const colorTableView = dropdown.colorTableView; + + expect( colorTableView.items.map( item => item.children.first.label ) ).to.deep.equal( [ + 'Domyślna', + 'Arial' + ] ); + } ); + + function localizedEditor() { + const editorElement = document.createElement( 'div' ); + document.body.appendChild( editorElement ); + + return ClassicTestEditor + .create( editorElement, { + plugins: [ FontColorEditing, FontColorUI ], + toolbar: [ 'fontColor' ], + language: 'pl', + } ) + .then( newEditor => { + editor = newEditor; + dropdown = editor.ui.componentFactory.create( 'fontColor' ); + command = editor.commands.get( 'fontColor' ); + + editorElement.remove(); + + return editor.destroy(); + } ); + } + } ); + } ); +} ); From d8f995eeb576ff871cbd1a999d728d9fa3f3d5f5 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 13 Mar 2019 13:06:02 +0100 Subject: [PATCH 15/92] Replace regular button with splitbutton for dropdown. Preserve lastly used color to be applied by splitbutton. --- src/fontcolor/fontcolorui.js | 11 ++++++++++- src/ui/colortableview.js | 4 ++-- src/utils.js | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 7eb43c2..d617121 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -8,6 +8,7 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; @@ -25,7 +26,8 @@ export default class FontColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_COLOR, locale => { - const dropdownView = createDropdown( locale ); + const dropdownView = createDropdown( locale, SplitButtonView ); + const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( item => ( { name: item.label, color: item.model } ) ) @@ -34,6 +36,8 @@ export default class FontColorUI extends Plugin { colorTableView.bind( 'selectedColor' ).to( command, 'value' ); colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); + dropdownView.buttonView.set( { label: t( 'Font Color' ), icon: fontColorIcon, @@ -49,9 +53,14 @@ export default class FontColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); dropdownView.on( 'execute', ( evt, val ) => { + dropdownView.set( 'lastlySelectedColor', val ); editor.execute( FONT_COLOR, val ); } ); + splitButtonView.on( 'execute', () => { + editor.execute( FONT_COLOR, dropdownView.lastlySelectedColor ); + } ); + return dropdownView; } ); } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index d3708f7..35953ce 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -44,7 +44,7 @@ export default class ColorTableView extends View { btnView.bind( 'tooltip' ).to( this, 'removeButtonTooltip' ); btnView.class = 'ck-color-table__remove-color'; btnView.on( 'execute', () => { - this.fire( 'colorPicked', { value: null } ); + this.fire( 'execute', { value: null } ); } ); return btnView; } @@ -93,7 +93,7 @@ export default class ColorTableView extends View { }, on: { click: bind.to( () => { - this.fire( 'colorPicked', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); + this.fire( 'execute', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); } ), mouseover: bind.to( () => { this.set( 'hoveredColor', this.colorsDefinition[ index * this.COLUMNS + i ].name ); diff --git a/src/utils.js b/src/utils.js index efd064b..3f3afec 100644 --- a/src/utils.js +++ b/src/utils.js @@ -86,7 +86,7 @@ export const colorUI = { dropdownView.panelView.children.add( colorTableView ); - colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); + colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); return colorTableView; } }; From 58e5e4f4cfff2e863f2862849c5e1fe33a400857 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 13 Mar 2019 13:48:58 +0100 Subject: [PATCH 16/92] Update background color to use splitbutton. --- .../fontbackgroundcolorui.js | 25 +++++++++++-------- src/fontcolor/fontcolorui.js | 2 +- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 4a4dab5..f38f504 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -8,11 +8,11 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview'; import fontBackgroundColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_BACKGROUND_COLOR, normalizeOptions } from '../utils'; -import ColorTableView from '../ui/colortableview'; +import { FONT_BACKGROUND_COLOR, normalizeOptions, colorUI } from '../utils'; export default class FontBackgroundColorUI extends Plugin { /** * @inheritDoc @@ -26,17 +26,17 @@ export default class FontBackgroundColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_BACKGROUND_COLOR, locale => { - const dropdownView = createDropdown( locale ); - - const colorTableView = new ColorTableView( locale, { - colors: options.map( item => ( { name: item.label, color: item.model } ) ) - } ); + const dropdownView = createDropdown( locale, SplitButtonView ); + const splitButtonView = dropdownView.buttonView; + const colorTableView = colorUI.addColorsToDropdown( + dropdownView, + options.map( item => ( { name: item.label, color: item.model } ) ) + ); colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); - dropdownView.panelView.children.add( colorTableView ); - colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - colorTableView.delegate( 'colorPicked' ).to( dropdownView, 'execute' ); + + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); dropdownView.buttonView.set( { label: t( 'Font Background Color' ), @@ -53,9 +53,14 @@ export default class FontBackgroundColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); dropdownView.on( 'execute', ( evt, val ) => { + dropdownView.set( 'lastlySelectedColor', val ); editor.execute( FONT_BACKGROUND_COLOR, val ); } ); + splitButtonView.on( 'execute', () => { + editor.execute( FONT_BACKGROUND_COLOR, dropdownView.lastlySelectedColor ); + } ); + return dropdownView; } ); } diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index d617121..80e8dca 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -32,9 +32,9 @@ export default class FontColorUI extends Plugin { dropdownView, options.map( item => ( { name: item.label, color: item.model } ) ) ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); From 2e0f8a9bbf44eff89f9d0b8a6382c7a2b06f5651 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 14 Mar 2019 10:20:20 +0100 Subject: [PATCH 17/92] Add reference to color table in dropdown, fix unit test. --- src/utils.js | 2 +- tests/fontcolor/fontcolorediting.js | 20 +++++++++++++++++--- tests/fontcolor/fontcolorui.js | 18 ++++++++++++------ 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/utils.js b/src/utils.js index 3f3afec..aa2b900 100644 --- a/src/utils.js +++ b/src/utils.js @@ -83,7 +83,7 @@ export const colorUI = { addColorsToDropdown( dropdownView, colors ) { const locale = dropdownView.locale; const colorTableView = new ColorTableView( locale, { colors } ); - + dropdownView.colorTableView = colorTableView; dropdownView.panelView.children.add( colorTableView ); colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index f4ff8d8..b09ed93 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -171,10 +171,24 @@ describe( 'FontColorEditing', () => { } ) ); - it( 'should convert fontColor attribute to proper style value.', () => { - setModelData( doc, 'fo<$text fontColor="#000">o bar' ); + describe( 'convert different color version', () => { + const tests = [ + '#000', + 'green', + 'rgb( 0, 10, 20 )', + 'rgba( 20, 30, 50, 0.4)', + 'hsl( 10, 20%, 30%)', + 'hsla( 300, 50%, 100%, .3)', + 'rgb( 20%, 30%, 40% )', + '#345678' + ]; + tests.forEach( test => { + it( `should convert fontColor attribute: "${ test }" to proper style value.`, () => { + setModelData( doc, `fo<$text fontColor="${ test }">o bar` ); - expect( editor.getData() ).to.equal( '

foo bar

' ); + expect( editor.getData() ).to.equal( `

foo bar

` ); + } ); + } ); } ); } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 66e3cc0..6b0e6a7 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -78,7 +78,7 @@ describe( 'FontColorUI', () => { expect( dropdown.element.classList.contains( 'ck-font-color-dropdown' ) ).to.be.true; } ); - it( 'should focus view after command execution', () => { + it( 'should focus view after command execution from dropdown', () => { const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); const dropdown = editor.ui.componentFactory.create( 'fontColor' ); @@ -88,6 +88,16 @@ describe( 'FontColorUI', () => { sinon.assert.calledOnce( focusSpy ); } ); + it( 'should focus view after command execution from splitbutton', () => { + const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); + const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + + dropdown.commandName = 'fontColor'; + dropdown.buttonView.fire( 'execute' ); + + sinon.assert.calledOnce( focusSpy ); + } ); + describe( 'model to command binding', () => { it( 'isEnabled', () => { command.isEnabled = false; @@ -112,11 +122,7 @@ describe( 'FontColorUI', () => { it( 'works for the colorTableView#items in the panel', () => { const colorTableView = dropdown.colorTableView; - - expect( colorTableView.items.map( item => item.children.first.label ) ).to.deep.equal( [ - 'Domyślna', - 'Arial' - ] ); + expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor tekstu' ); } ); function localizedEditor() { From 5da1395ae09675425ec8d772460ba03396cd1163 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 18 Mar 2019 09:51:40 +0100 Subject: [PATCH 18/92] Change color model to be 2 dimension array and fix all references to it. --- .../fontbackgroundcolorediting.js | 119 ++++-------------- .../fontbackgroundcolorui.js | 10 +- src/fontcolor/fontcolorediting.js | 119 ++++-------------- src/fontcolor/fontcolorui.js | 10 +- src/ui/colortableview.js | 78 +++++------- src/utils.js | 44 ++++--- 6 files changed, 112 insertions(+), 268 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index 8ad9db6..d281535 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -21,103 +21,28 @@ export default class FontBackgroundColorEditing extends Plugin { super( editor ); editor.config.define( FONT_BACKGROUND_COLOR, { - options: [ - { - label: 'Strong Cyan', - color: '#1ABC9C' - }, - { - label: 'Emerald', - color: '#2ECC71' - }, - { - label: 'Bright Blue', - color: '#3498DB' - }, - { - label: 'Amethyst', - color: '#9B59B6' - }, - { - label: 'Grayish Blue', - color: '#4E5F70' - }, - { - label: 'Vivid Yellow', - color: '#F1C40F' - }, - { - label: 'Dark Cyan', - color: '#16A085' - }, - { - label: 'Dark Emerald', - color: '#27AE60' - }, - { - label: 'Strong Blue', - color: '#2980B9' - }, - { - label: 'Dark Violet', - color: '#8E44AD' - }, - { - label: 'Desaturated Blue', - color: '#2C3E50' - }, - { - label: 'Orange', - color: '#F39C12' - }, - { - label: 'Carrot', - color: '#E67E22' - }, - { - label: 'Pale Red', - color: '#E74C3C' - }, - { - label: 'Bright Silver', - color: '#ECF0F1' - }, - { - label: 'Light Grayish Cyan', - color: '#95A5A6' - }, - { - label: 'Light Gray', - color: '#DDD' - }, - { - label: 'White', - color: '#FFF' - }, - { - label: 'Pumpkin', - color: '#D35400' - }, - { - label: 'Strong Red', - color: '#C0392B' - }, - { - label: 'Silver', - color: '#BDC3C7' - }, - { - label: 'Grayish Cyan', - color: '#7F8C8D' - }, - { - label: 'Dark Gray', - color: '#999' - }, - { - label: 'Black', - color: '#000' - } + colors: [ + [ + 'hsl(0, 0%, 0%)', + 'hsl(0, 0%, 30%)', + 'hsl(0, 0%, 60%)', + 'hsl(0, 0%, 90%)', + 'hsl(0, 0%, 100%)' + ], + [ + 'hsl(360, 75%, 60%)', + 'hsl(30, 75%, 60%)', + 'hsl(60, 75%, 60%)', + 'hsl(90, 75%, 60%)', + 'hsl(120, 75%, 60%)' + ], + [ + 'hsl(150, 75%, 60%)', + 'hsl(180, 75%, 60%)', + 'hsl(210, 75%, 60%)', + 'hsl(240, 75%, 60%)', + 'hsl(270, 75%, 60%)' + ] ] } ); diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index f38f504..f73bc07 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -30,13 +30,14 @@ export default class FontBackgroundColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( item => ( { name: item.label, color: item.model } ) ) + options.map( row => row.map( element => ( { name: element.label, color: element.model } ) ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); + // Preselect first element on color list. + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ][ 0 ].model } ); dropdownView.buttonView.set( { label: t( 'Font Background Color' ), @@ -78,8 +79,7 @@ export default class FontBackgroundColorUI extends Plugin { */ _getLocalizedOptions() { const editor = this.editor; - const options = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.options` ) ); - - return options; + const colors = editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ).map( colorRow => normalizeOptions( colorRow ) ); + return colors; } } diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index 019755a..b0ab834 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -21,103 +21,28 @@ export default class FontColorEditing extends Plugin { super( editor ); editor.config.define( FONT_COLOR, { - options: [ - { - label: 'Strong Cyan', - color: '#1ABC9C' - }, - { - label: 'Emerald', - color: '#2ECC71' - }, - { - label: 'Bright Blue', - color: '#3498DB' - }, - { - label: 'Amethyst', - color: '#9B59B6' - }, - { - label: 'Grayish Blue', - color: '#4E5F70' - }, - { - label: 'Vivid Yellow', - color: '#F1C40F' - }, - { - label: 'Dark Cyan', - color: '#16A085' - }, - { - label: 'Dark Emerald', - color: '#27AE60' - }, - { - label: 'Strong Blue', - color: '#2980B9' - }, - { - label: 'Dark Violet', - color: '#8E44AD' - }, - { - label: 'Desaturated Blue', - color: '#2C3E50' - }, - { - label: 'Orange', - color: '#F39C12' - }, - { - label: 'Carrot', - color: '#E67E22' - }, - { - label: 'Pale Red', - color: '#E74C3C' - }, - { - label: 'Bright Silver', - color: '#ECF0F1' - }, - { - label: 'Light Grayish Cyan', - color: '#95A5A6' - }, - { - label: 'Light Gray', - color: '#DDD' - }, - { - label: 'White', - color: '#FFF' - }, - { - label: 'Pumpkin', - color: '#D35400' - }, - { - label: 'Strong Red', - color: '#C0392B' - }, - { - label: 'Silver', - color: '#BDC3C7' - }, - { - label: 'Grayish Cyan', - color: '#7F8C8D' - }, - { - label: 'Dark Gray', - color: '#999' - }, - { - label: 'Black', - color: '#000' - } + colors: [ + [ + 'hsl(0, 0%, 0%)', + 'hsl(0, 0%, 30%)', + 'hsl(0, 0%, 60%)', + 'hsl(0, 0%, 90%)', + 'hsl(0, 0%, 100%)' + ], + [ + 'hsl(360, 75%, 60%)', + 'hsl(30, 75%, 60%)', + 'hsl(60, 75%, 60%)', + 'hsl(90, 75%, 60%)', + 'hsl(120, 75%, 60%)' + ], + [ + 'hsl(150, 75%, 60%)', + 'hsl(180, 75%, 60%)', + 'hsl(210, 75%, 60%)', + 'hsl(240, 75%, 60%)', + 'hsl(270, 75%, 60%)' + ] ] } ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 80e8dca..beeb351 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -30,13 +30,14 @@ export default class FontColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( item => ( { name: item.label, color: item.model } ) ) + options.map( row => row.map( element => ( { name: element.label, color: element.model } ) ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); + // Preselect first element on color list. + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ][ 0 ].model } ); dropdownView.buttonView.set( { label: t( 'Font Color' ), @@ -78,8 +79,7 @@ export default class FontColorUI extends Plugin { */ _getLocalizedOptions() { const editor = this.editor; - const options = normalizeOptions( editor.config.get( `${ FONT_COLOR }.options` ) ); - - return options; + const colors = editor.config.get( `${ FONT_COLOR }.colors` ).map( colorRow => normalizeOptions( colorRow ) ); + return colors; } } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 35953ce..cd8ef7e 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -11,7 +11,6 @@ import '../../theme/fontcolor.css'; export default class ColorTableView extends View { constructor( locale, { colors } ) { super( locale ); - const bind = this.bindTemplate; this.COLUMNS = 6; this.colorsDefinition = colors; @@ -27,10 +26,7 @@ export default class ColorTableView extends View { }, children: [ this.createColorTableTemplate(), - this.removeColorButton(), - { - text: bind.to( 'hoveredColor' ) - } + this.removeColorButton() ] } ); } @@ -52,58 +48,44 @@ export default class ColorTableView extends View { createColorTableTemplate() { return new Template( { tag: 'table', - children: this._colorRows(), + children: this._colorRows( this.colorsDefinition ), attributes: { class: 'ck-color-table__table' } } ); } - _colorRows() { - const rows = []; - for ( let i = 0; i < Math.ceil( this.colorsDefinition.length / this.COLUMNS ); i++ ) { - rows.push( new Template( { - tag: 'tr', - children: this._colorElements( i ) - } ) ); - } - return rows; + _colorRows( colorTable ) { + return colorTable.map( rowArr => new Template( { + tag: 'tr', + children: this._colorElements( rowArr ) + } ) ); } - _colorElements( index ) { - const elements = []; + _colorElements( rowArr ) { const bind = this.bindTemplate; - for ( let i = 0; i < this.COLUMNS; i++ ) { - elements.push( new Template( { - tag: 'td', - attributes: { - style: { - backgroundColor: `${ this.colorsDefinition[ index * this.COLUMNS + i ].color }` - }, - class: [ - 'ck-color-table__cell-color', - bind.if( - 'selectedColor', - 'ck-color-table__cell-color_active', - value => { - return value === this.colorsDefinition[ index * this.COLUMNS + i ].color; - } - ) - ] + return rowArr.map( element => new Template( { + tag: 'td', + attributes: { + style: { + backgroundColor: element.color }, - on: { - click: bind.to( () => { - this.fire( 'execute', { value: this.colorsDefinition[ index * this.COLUMNS + i ].color } ); - } ), - mouseover: bind.to( () => { - this.set( 'hoveredColor', this.colorsDefinition[ index * this.COLUMNS + i ].name ); - } ), - mouseout: bind.to( () => { - this.set( 'hoveredColor', undefined ); - } ) - } - } ) ); - } - return elements; + class: [ + 'ck-color-table__cell-color', + bind.if( + 'selectedColor', + 'ck-color-table__cell-color_active', + value => { + return value === element.color; + } + ) + ] + }, + on: { + click: bind.to( () => { + this.fire( 'execute', { value: element.color } ); + } ) + } + } ) ); } } diff --git a/src/utils.js b/src/utils.js index aa2b900..6b847bc 100644 --- a/src/utils.js +++ b/src/utils.js @@ -58,25 +58,37 @@ function normalizeColorCode( value ) { return value.replace( /\s/g, '' ); } -export function normalizeOptions( configuredOptions ) { - return configuredOptions - .map( getOptionDefinition ) +export function normalizeOptions( colorRow ) { + return colorRow + .map( getColorsDefinition ) .filter( option => !!option ); } -function getOptionDefinition( option ) { - return { - title: option.label, - model: option.color, - label: option.label, - view: { - name: 'span', - styles: { - color: `${ option.color }` - }, - priority: 5 - } - }; +function getColorsDefinition( color ) { + if ( typeof color === 'string' ) { + return { + model: color, + view: { + name: 'span', + styles: { + color + }, + priority: 5 + } + }; + } else { + return { + model: color.color, + label: color.label, + view: { + name: 'span', + styles: { + color: `${ color.color }` + }, + priority: 5 + } + }; + } } export const colorUI = { From 63c730e988eec4803fc2a9cddbf0f87b483f322e Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 18 Mar 2019 12:01:01 +0100 Subject: [PATCH 19/92] Flat color structure. to better work with grid. --- .../fontbackgroundcolorediting.js | 36 ++++++++----------- .../fontbackgroundcolorui.js | 6 ++-- src/fontcolor/fontcolorediting.js | 36 ++++++++----------- src/fontcolor/fontcolorui.js | 6 ++-- src/ui/colortableview.js | 33 +++++++---------- theme/fontcolor.css | 6 ++-- 6 files changed, 52 insertions(+), 71 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index d281535..99d72f1 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -22,27 +22,21 @@ export default class FontBackgroundColorEditing extends Plugin { editor.config.define( FONT_BACKGROUND_COLOR, { colors: [ - [ - 'hsl(0, 0%, 0%)', - 'hsl(0, 0%, 30%)', - 'hsl(0, 0%, 60%)', - 'hsl(0, 0%, 90%)', - 'hsl(0, 0%, 100%)' - ], - [ - 'hsl(360, 75%, 60%)', - 'hsl(30, 75%, 60%)', - 'hsl(60, 75%, 60%)', - 'hsl(90, 75%, 60%)', - 'hsl(120, 75%, 60%)' - ], - [ - 'hsl(150, 75%, 60%)', - 'hsl(180, 75%, 60%)', - 'hsl(210, 75%, 60%)', - 'hsl(240, 75%, 60%)', - 'hsl(270, 75%, 60%)' - ] + 'hsl(0, 0%, 0%)', + 'hsl(0, 0%, 30%)', + 'hsl(0, 0%, 60%)', + 'hsl(0, 0%, 90%)', + 'hsl(0, 0%, 100%)', + 'hsl(360, 75%, 60%)', + 'hsl(30, 75%, 60%)', + 'hsl(60, 75%, 60%)', + 'hsl(90, 75%, 60%)', + 'hsl(120, 75%, 60%)', + 'hsl(150, 75%, 60%)', + 'hsl(180, 75%, 60%)', + 'hsl(210, 75%, 60%)', + 'hsl(240, 75%, 60%)', + 'hsl(270, 75%, 60%)' ] } ); diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index f73bc07..60cb7c3 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -30,14 +30,14 @@ export default class FontBackgroundColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( row => row.map( element => ( { name: element.label, color: element.model } ) ) ) + options.map( element => ( { name: element.label, color: element.model } ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); // Preselect first element on color list. - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ][ 0 ].model } ); + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); dropdownView.buttonView.set( { label: t( 'Font Background Color' ), @@ -79,7 +79,7 @@ export default class FontBackgroundColorUI extends Plugin { */ _getLocalizedOptions() { const editor = this.editor; - const colors = editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ).map( colorRow => normalizeOptions( colorRow ) ); + const colors = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ) ); return colors; } } diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index b0ab834..884fd9a 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -22,27 +22,21 @@ export default class FontColorEditing extends Plugin { editor.config.define( FONT_COLOR, { colors: [ - [ - 'hsl(0, 0%, 0%)', - 'hsl(0, 0%, 30%)', - 'hsl(0, 0%, 60%)', - 'hsl(0, 0%, 90%)', - 'hsl(0, 0%, 100%)' - ], - [ - 'hsl(360, 75%, 60%)', - 'hsl(30, 75%, 60%)', - 'hsl(60, 75%, 60%)', - 'hsl(90, 75%, 60%)', - 'hsl(120, 75%, 60%)' - ], - [ - 'hsl(150, 75%, 60%)', - 'hsl(180, 75%, 60%)', - 'hsl(210, 75%, 60%)', - 'hsl(240, 75%, 60%)', - 'hsl(270, 75%, 60%)' - ] + 'hsl(0, 0%, 0%)', + 'hsl(0, 0%, 30%)', + 'hsl(0, 0%, 60%)', + 'hsl(0, 0%, 90%)', + 'hsl(0, 0%, 100%)', + 'hsl(360, 75%, 60%)', + 'hsl(30, 75%, 60%)', + 'hsl(60, 75%, 60%)', + 'hsl(90, 75%, 60%)', + 'hsl(120, 75%, 60%)', + 'hsl(150, 75%, 60%)', + 'hsl(180, 75%, 60%)', + 'hsl(210, 75%, 60%)', + 'hsl(240, 75%, 60%)', + 'hsl(270, 75%, 60%)' ] } ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index beeb351..8c87516 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -30,14 +30,14 @@ export default class FontColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( row => row.map( element => ( { name: element.label, color: element.model } ) ) ) + options.map( element => ( { name: element.label, color: element.model } ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); // Preselect first element on color list. - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ][ 0 ].model } ); + dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); dropdownView.buttonView.set( { label: t( 'Font Color' ), @@ -79,7 +79,7 @@ export default class FontColorUI extends Plugin { */ _getLocalizedOptions() { const editor = this.editor; - const colors = editor.config.get( `${ FONT_COLOR }.colors` ).map( colorRow => normalizeOptions( colorRow ) ); + const colors = normalizeOptions( editor.config.get( `${ FONT_COLOR }.colors` ) ); return colors; } } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index cd8ef7e..9aaa486 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -47,38 +47,31 @@ export default class ColorTableView extends View { createColorTableTemplate() { return new Template( { - tag: 'table', - children: this._colorRows( this.colorsDefinition ), + tag: 'div', + children: this._colorElements( this.colorsDefinition ), attributes: { - class: 'ck-color-table__table' + class: 'ck-color-table__main-container' } } ); } - _colorRows( colorTable ) { - return colorTable.map( rowArr => new Template( { - tag: 'tr', - children: this._colorElements( rowArr ) - } ) ); - } + // _colorRows( colorTable ) { + // return colorTable.map( rowArr => new Template( { + // tag: 'tr', + // children: this._colorElements( rowArr ) + // } ) ); + // } - _colorElements( rowArr ) { + _colorElements( colorArr ) { const bind = this.bindTemplate; - return rowArr.map( element => new Template( { - tag: 'td', + return colorArr.map( element => new Template( { + tag: 'span', attributes: { style: { backgroundColor: element.color }, class: [ - 'ck-color-table__cell-color', - bind.if( - 'selectedColor', - 'ck-color-table__cell-color_active', - value => { - return value === element.color; - } - ) + 'ck-color-table__cell-color' ] }, on: { diff --git a/theme/fontcolor.css b/theme/fontcolor.css index b44e2ef..dc37d59 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -5,14 +5,14 @@ .ck-color-table .ck-color-table__table { margin: 0.5em 0.5em 0 0.5em; - width: 14em; + width: 100%; border-collapse: separate; border-spacing: 0.2em; } .ck-color-table .ck-color-table__cell-color { - width: 2em; - height: 2em; + width: 20px; + height: 20px; border: 0.1em solid #000; transition-property: border-width; transition-duration: 0.1s; From 374b46f6bcd80b5757a6e40cdfb6e080aa19b9ae Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 18 Mar 2019 12:52:12 +0100 Subject: [PATCH 20/92] Update color table styles. --- src/ui/colortableview.js | 15 ++++++---- theme/fontcolor.css | 63 +++++++++++++++++++++++----------------- theme/icons/eraser.svg | 1 + 3 files changed, 46 insertions(+), 33 deletions(-) create mode 100644 theme/icons/eraser.svg diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 9aaa486..e1bc8ea 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -6,8 +6,10 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import Template from '@ckeditor/ckeditor5-ui/src/template'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; +import removeButtonIcon from '../../theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; + export default class ColorTableView extends View { constructor( locale, { colors } ) { super( locale ); @@ -25,8 +27,8 @@ export default class ColorTableView extends View { class: [ 'ck-color-table' ] }, children: [ - this.createColorTableTemplate(), - this.removeColorButton() + this.removeColorButton(), + this.createColorTableTemplate() ] } ); } @@ -34,10 +36,11 @@ export default class ColorTableView extends View { removeColorButton() { const btnView = new ButtonView(); btnView.set( { - label: 'X', - withText: true + withText: true, + icon: removeButtonIcon, + tooltip: true } ); - btnView.bind( 'tooltip' ).to( this, 'removeButtonTooltip' ); + btnView.bind( 'label' ).to( this, 'removeButtonTooltip' ); btnView.class = 'ck-color-table__remove-color'; btnView.on( 'execute', () => { this.fire( 'execute', { value: null } ); @@ -71,7 +74,7 @@ export default class ColorTableView extends View { backgroundColor: element.color }, class: [ - 'ck-color-table__cell-color' + 'ck-color-table__color-item' ] }, on: { diff --git a/theme/fontcolor.css b/theme/fontcolor.css index dc37d59..8fca92e 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -3,39 +3,48 @@ * For licensing, see LICENSE.md. */ -.ck-color-table .ck-color-table__table { - margin: 0.5em 0.5em 0 0.5em; - width: 100%; - border-collapse: separate; - border-spacing: 0.2em; +:root { + /* --grid-size: 20px; */ + --grid-size: 25px; + + --grid-columns-max: 5; + /* Test it and uncomment variable. */ + /* --grid-columns-max: 8; */ + /* --grid-columns-max: 3; */ } -.ck-color-table .ck-color-table__cell-color { - width: 20px; - height: 20px; - border: 0.1em solid #000; - transition-property: border-width; - transition-duration: 0.1s; - transition-timing-function: ease; - text-align: center; - vertical-align: middle; - line-height: 0; +.ck-color-table div.ck-color-table__main-container { + display: grid; + grid-template-columns: repeat( var(--grid-columns-max), 1fr); + grid-gap: 5px; + padding: 10px; } -.ck-color-table .ck-color-table__cell-color:hover { - border-width: 0.2em; +.ck-color-table__main-container span.ck-color-table__color-item { + width: var(--grid-size); + height: var(--grid-size); + border-radius: 3px; + cursor: pointer; + transition: 300ms ease all; } -.ck-color-table .ck-color-table__cell-color_active::before { - content: "✓"; - font-size: 1.2em; - color: white; - text-shadow: -1px -1px 0 #000, - 1px -1px 0 #000, - -1px 1px 0 #000, - 1px 1px 0 #000; +.ck-color-table__main-container span.ck-color-table__color-item:hover { + box-shadow: 0 0 0 2px hsl(184, 80%, 50%); } -.ck-color-table .ck-color-table__remove-color { - margin: 0.5em; +.ck-color-table button.ck-color-table__remove-color svg { + width: 24px; + margin-right: 10px; +} + +.ck-color-table button.ck-color-table__remove-color { + display: flex; + align-items: center; + text-align: left; + font-size: 16px; + border: 0; + width: 100%; + border-bottom: 1px solid hsl(0, 0%, 87%); + padding: 10px; + cursor: pointer; } diff --git a/theme/icons/eraser.svg b/theme/icons/eraser.svg new file mode 100644 index 0000000..e64a293 --- /dev/null +++ b/theme/icons/eraser.svg @@ -0,0 +1 @@ + \ No newline at end of file From c415b5f5be52b0054cc6be857a20a67177522614 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 18 Mar 2019 14:20:23 +0100 Subject: [PATCH 21/92] Clean up in code, add support for bordered colors. --- .../fontbackgroundcolorediting.js | 5 ++- .../fontbackgroundcolorui.js | 8 +++- src/fontcolor/fontcolorediting.js | 5 ++- src/fontcolor/fontcolorui.js | 8 +++- src/ui/colortableview.js | 41 +++++++++---------- src/utils.js | 2 + theme/fontcolor.css | 7 ++-- 7 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index 99d72f1..aa60e51 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -26,7 +26,10 @@ export default class FontBackgroundColorEditing extends Plugin { 'hsl(0, 0%, 30%)', 'hsl(0, 0%, 60%)', 'hsl(0, 0%, 90%)', - 'hsl(0, 0%, 100%)', + { + color: 'hsl(0, 0%, 100%)', + hasBorder: true + }, 'hsl(360, 75%, 60%)', 'hsl(30, 75%, 60%)', 'hsl(60, 75%, 60%)', diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 60cb7c3..c82342a 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -30,7 +30,13 @@ export default class FontBackgroundColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( element => ( { name: element.label, color: element.model } ) ) + options.map( element => ( { + name: element.label, + color: element.model, + options: { + hasBorder: element.hasBorder + } + } ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index 884fd9a..a5238e1 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -26,7 +26,10 @@ export default class FontColorEditing extends Plugin { 'hsl(0, 0%, 30%)', 'hsl(0, 0%, 60%)', 'hsl(0, 0%, 90%)', - 'hsl(0, 0%, 100%)', + { + color: 'hsl(0, 0%, 100%)', + hasBorder: true + }, 'hsl(360, 75%, 60%)', 'hsl(30, 75%, 60%)', 'hsl(60, 75%, 60%)', diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 8c87516..77706ef 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -30,7 +30,13 @@ export default class FontColorUI extends Plugin { const splitButtonView = dropdownView.buttonView; const colorTableView = colorUI.addColorsToDropdown( dropdownView, - options.map( element => ( { name: element.label, color: element.model } ) ) + options.map( element => ( { + name: element.label, + color: element.model, + options: { + hasBorder: element.hasBorder + } + } ) ) ); colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index e1bc8ea..07ee076 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -58,30 +58,27 @@ export default class ColorTableView extends View { } ); } - // _colorRows( colorTable ) { - // return colorTable.map( rowArr => new Template( { - // tag: 'tr', - // children: this._colorElements( rowArr ) - // } ) ); - // } - _colorElements( colorArr ) { const bind = this.bindTemplate; - return colorArr.map( element => new Template( { - tag: 'span', - attributes: { - style: { - backgroundColor: element.color - }, - class: [ - 'ck-color-table__color-item' - ] - }, - on: { - click: bind.to( () => { - this.fire( 'execute', { value: element.color } ); - } ) + return colorArr.map( element => { + const classNames = [ 'ck-color-table__color-item' ]; + if ( element.options.hasBorder ) { + classNames.push( 'ck-color-table__color-item_bordered' ); } - } ) ); + return new Template( { + tag: 'span', + attributes: { + style: { + backgroundColor: element.color + }, + class: classNames + }, + on: { + click: bind.to( () => { + this.fire( 'execute', { value: element.color } ); + } ) + } + } ); + } ); } } diff --git a/src/utils.js b/src/utils.js index 6b847bc..9199605 100644 --- a/src/utils.js +++ b/src/utils.js @@ -68,6 +68,7 @@ function getColorsDefinition( color ) { if ( typeof color === 'string' ) { return { model: color, + label: color, view: { name: 'span', styles: { @@ -80,6 +81,7 @@ function getColorsDefinition( color ) { return { model: color.color, label: color.label, + hasBorder: color.hasBorder, view: { name: 'span', styles: { diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 8fca92e..866c677 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -4,13 +4,9 @@ */ :root { - /* --grid-size: 20px; */ --grid-size: 25px; --grid-columns-max: 5; - /* Test it and uncomment variable. */ - /* --grid-columns-max: 8; */ - /* --grid-columns-max: 3; */ } .ck-color-table div.ck-color-table__main-container { @@ -27,6 +23,9 @@ cursor: pointer; transition: 300ms ease all; } +.ck-color-table__main-container span.ck-color-table__color-item.ck-color-table__color-item_bordered { + box-shadow: 0 0 1px hsl( 0,0%,60%); +} .ck-color-table__main-container span.ck-color-table__color-item:hover { box-shadow: 0 0 0 2px hsl(184, 80%, 50%); From 6ec8710d7405769fe7dd84436384380577f92e58 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 12:59:26 +0100 Subject: [PATCH 22/92] Add color tile class and apply those changes to font color plugin. --- src/ui/colortableview.js | 72 +++++++++++++++++++++++++------------- src/ui/colortile.js | 36 +++++++++++++++++++ tests/manual/font-color.js | 12 +++++-- theme/fontcolor.css | 8 ++--- 4 files changed, 97 insertions(+), 31 deletions(-) create mode 100644 src/ui/colortile.js diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 07ee076..509ae3f 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -6,20 +6,25 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import Template from '@ckeditor/ckeditor5-ui/src/template'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; +import ColorTile from './colortile'; + import removeButtonIcon from '../../theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; +import Collection from '@ckeditor/ckeditor5-utils/src/collection'; export default class ColorTableView extends View { constructor( locale, { colors } ) { super( locale ); - this.COLUMNS = 6; this.colorsDefinition = colors; this.set( 'selectedColor' ); this.set( 'hoveredColor' ); this.set( 'removeButtonTooltip' ); + this.set( 'colorColumns', 5 ); + this.set( 'recentlyUsedColors', new Collection() ); + this.initRecentCollection(); this.setTemplate( { tag: 'div', @@ -28,7 +33,8 @@ export default class ColorTableView extends View { }, children: [ this.removeColorButton(), - this.createColorTableTemplate() + this.createColorTableTemplate(), + this.recentlyUsed() ] } ); } @@ -49,36 +55,54 @@ export default class ColorTableView extends View { } createColorTableTemplate() { + const colorCollection = this.createCollection(); + this.colorsDefinition.forEach( item => { + const colorTile = new ColorTile(); + colorTile.set( { + color: item.color, + hasBorder: item.hasBorder + } ); + colorTile.delegate( 'execute' ).to( this ); + colorCollection.add( colorTile ); + } ); + return new Template( { tag: 'div', - children: this._colorElements( this.colorsDefinition ), + children: colorCollection, attributes: { - class: 'ck-color-table__main-container' + class: 'ck-color-table__grid-container' } } ); } - _colorElements( colorArr ) { - const bind = this.bindTemplate; - return colorArr.map( element => { - const classNames = [ 'ck-color-table__color-item' ]; - if ( element.options.hasBorder ) { - classNames.push( 'ck-color-table__color-item_bordered' ); + recentlyUsed() { + this.recentlyUsedViews = this.createCollection(); + + this.recentlyUsedViews.bindTo( this.recentlyUsedColors ).using( + storegColor => { + const colorTile = new ColorTile(); + colorTile.set( { + color: storegColor.color, + hasBorder: true + } ); + colorTile.delegate( 'execute' ).to( this ); + return colorTile; + } + ); + return new Template( { + tag: 'div', + children: this.recentlyUsedViews, + attributes: { + class: [ 'ck-color-table__grid-container' ] } - return new Template( { - tag: 'span', - attributes: { - style: { - backgroundColor: element.color - }, - class: classNames - }, - on: { - click: bind.to( () => { - this.fire( 'execute', { value: element.color } ); - } ) - } - } ); } ); } + + initRecentCollection() { + for ( let i = 0; i < this.colorColumns; i++ ) { + this.recentlyUsedColors.add( { + color: 'hsla( 0, 0%, 0%, 0 )' + } ); + } + } } diff --git a/src/ui/colortile.js b/src/ui/colortile.js new file mode 100644 index 0000000..0ee7e20 --- /dev/null +++ b/src/ui/colortile.js @@ -0,0 +1,36 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import View from '@ckeditor/ckeditor5-ui/src/view'; + +export default class ColorTile extends View { + constructor( locale ) { + super( locale ); + + const bind = this.bindTemplate; + + this.set( 'color' ); + this.set( 'label' ); + this.set( 'hasBorder' ); + + this.setTemplate( { + tag: 'span', + attributes: { + style: { + backgroundColor: bind.to( 'color' ) + }, + class: [ + 'ck-color-table__color-tile', + bind.if( 'hasBorder', 'ck-color-table__color-tile_bordered' ) + ] + }, + on: { + click: bind.to( () => { + this.fire( 'execute', { value: this.color } ); + } ) + } + } ); + } +} diff --git a/tests/manual/font-color.js b/tests/manual/font-color.js index 0c68d5c..d540b10 100644 --- a/tests/manual/font-color.js +++ b/tests/manual/font-color.js @@ -8,14 +8,20 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import FontColor from '../../src/fontcolor'; -import FontBackgroundColor from '../../src/fontbackgroundcolor'; +// import FontBackgroundColor from '../../src/fontbackgroundcolor'; ClassicEditor .create( document.querySelector( '#editor' ), { - plugins: [ ArticlePluginSet, FontColor, FontBackgroundColor ], + plugins: [ + ArticlePluginSet, + FontColor, + // FontBackgroundColor + ], toolbar: [ 'heading', '|', - 'fontColor', 'fontBackgroundColor', 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' + 'fontColor', + // 'fontBackgroundColor', + 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' ] } ) .then( editor => { diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 866c677..543e004 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -9,25 +9,25 @@ --grid-columns-max: 5; } -.ck-color-table div.ck-color-table__main-container { +.ck-color-table div.ck-color-table__grid-container { display: grid; grid-template-columns: repeat( var(--grid-columns-max), 1fr); grid-gap: 5px; padding: 10px; } -.ck-color-table__main-container span.ck-color-table__color-item { +.ck-color-table__grid-container span.ck-color-table__color-tile { width: var(--grid-size); height: var(--grid-size); border-radius: 3px; cursor: pointer; transition: 300ms ease all; } -.ck-color-table__main-container span.ck-color-table__color-item.ck-color-table__color-item_bordered { +.ck-color-table__grid-container span.ck-color-table__color-tile.ck-color-table__color-tile_bordered { box-shadow: 0 0 1px hsl( 0,0%,60%); } -.ck-color-table__main-container span.ck-color-table__color-item:hover { +.ck-color-table__grid-container span.ck-color-table__color-tile:hover { box-shadow: 0 0 0 2px hsl(184, 80%, 50%); } From 75671853c74d62e61a8276698f93d64f9a27c2e0 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 14:24:05 +0100 Subject: [PATCH 23/92] Add support for recently used colors wihtout repetition. --- src/fontcolor/fontcolorui.js | 3 +++ src/ui/colortableview.js | 16 +++++++++++++--- src/ui/colortile.js | 2 +- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 77706ef..bc008eb 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -61,6 +61,9 @@ export default class FontColorUI extends Plugin { dropdownView.on( 'execute', ( evt, val ) => { dropdownView.set( 'lastlySelectedColor', val ); + if ( val.value !== null ) { + colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); + } editor.execute( FONT_COLOR, val ); } ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 509ae3f..68b8005 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -26,6 +26,16 @@ export default class ColorTableView extends View { this.set( 'recentlyUsedColors', new Collection() ); this.initRecentCollection(); + this.recentlyUsedColors.on( 'add', ( evt, item ) => { + const duplicates = this.recentlyUsedColors.filter( element => element.color === item.color, this ); + if ( duplicates.length === 2 ) { + this.recentlyUsedColors.remove( duplicates[ 1 ] ); + } + if ( this.recentlyUsedColors.length > this.colorColumns ) { + this.recentlyUsedColors.remove( this.recentlyUsedColors.length - 1 ); + } + } ); + this.setTemplate( { tag: 'div', attributes: { @@ -60,7 +70,7 @@ export default class ColorTableView extends View { const colorTile = new ColorTile(); colorTile.set( { color: item.color, - hasBorder: item.hasBorder + hasBorder: item.options.hasBorder } ); colorTile.delegate( 'execute' ).to( this ); colorCollection.add( colorTile ); @@ -79,10 +89,10 @@ export default class ColorTableView extends View { this.recentlyUsedViews = this.createCollection(); this.recentlyUsedViews.bindTo( this.recentlyUsedColors ).using( - storegColor => { + colorObj => { const colorTile = new ColorTile(); colorTile.set( { - color: storegColor.color, + color: colorObj.color, hasBorder: true } ); colorTile.delegate( 'execute' ).to( this ); diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 0ee7e20..9d0323e 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -28,7 +28,7 @@ export default class ColorTile extends View { }, on: { click: bind.to( () => { - this.fire( 'execute', { value: this.color } ); + this.fire( 'execute', { value: this.color, hasBorder: this.hasBorder } ); } ) } } ); From de9ad3660b8292ca7e512e062e0689d07a051802 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 14:27:25 +0100 Subject: [PATCH 24/92] Switch split button to dropdown --- src/fontcolor/fontcolorui.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index bc008eb..72b4a90 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -8,7 +8,6 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview'; import fontColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; @@ -26,8 +25,7 @@ export default class FontColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_COLOR, locale => { - const dropdownView = createDropdown( locale, SplitButtonView ); - const splitButtonView = dropdownView.buttonView; + const dropdownView = createDropdown( locale ); const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( element => ( { @@ -42,9 +40,6 @@ export default class FontColorUI extends Plugin { colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - // Preselect first element on color list. - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); - dropdownView.buttonView.set( { label: t( 'Font Color' ), icon: fontColorIcon, @@ -60,17 +55,12 @@ export default class FontColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); dropdownView.on( 'execute', ( evt, val ) => { - dropdownView.set( 'lastlySelectedColor', val ); if ( val.value !== null ) { colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); } editor.execute( FONT_COLOR, val ); } ); - splitButtonView.on( 'execute', () => { - editor.execute( FONT_COLOR, dropdownView.lastlySelectedColor ); - } ); - return dropdownView; } ); } From ba51327cb117a1d3534441b94cbbb2d5f5641008 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 14:51:52 +0100 Subject: [PATCH 25/92] Enable background color again in manual test. --- .../fontbackgroundcolorui.js | 17 +++++------------ src/fontcolor/fontcolorui.js | 2 +- tests/manual/font-color.js | 18 +++++++++++++----- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index c82342a..dc365b5 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -8,7 +8,6 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview'; import fontBackgroundColorIcon from '../../theme/icons/font-family.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; @@ -26,8 +25,7 @@ export default class FontBackgroundColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_BACKGROUND_COLOR, locale => { - const dropdownView = createDropdown( locale, SplitButtonView ); - const splitButtonView = dropdownView.buttonView; + const dropdownView = createDropdown( locale ); const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( element => ( { @@ -38,13 +36,10 @@ export default class FontBackgroundColorUI extends Plugin { } } ) ) ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove background color' ) ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - // Preselect first element on color list. - dropdownView.set( 'lastlySelectedColor', { value: options[ 0 ].model } ); - dropdownView.buttonView.set( { label: t( 'Font Background Color' ), icon: fontBackgroundColorIcon, @@ -60,14 +55,12 @@ export default class FontBackgroundColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); dropdownView.on( 'execute', ( evt, val ) => { - dropdownView.set( 'lastlySelectedColor', val ); + if ( val.value !== null ) { + colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); + } editor.execute( FONT_BACKGROUND_COLOR, val ); } ); - splitButtonView.on( 'execute', () => { - editor.execute( FONT_BACKGROUND_COLOR, dropdownView.lastlySelectedColor ); - } ); - return dropdownView; } ); } diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 72b4a90..38927bb 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -36,7 +36,7 @@ export default class FontColorUI extends Plugin { } } ) ) ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove text color' ) ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); diff --git a/tests/manual/font-color.js b/tests/manual/font-color.js index d540b10..54e4560 100644 --- a/tests/manual/font-color.js +++ b/tests/manual/font-color.js @@ -8,20 +8,28 @@ import ClassicEditor from '@ckeditor/ckeditor5-editor-classic/src/classiceditor'; import ArticlePluginSet from '@ckeditor/ckeditor5-core/tests/_utils/articlepluginset'; import FontColor from '../../src/fontcolor'; -// import FontBackgroundColor from '../../src/fontbackgroundcolor'; +import FontBackgroundColor from '../../src/fontbackgroundcolor'; ClassicEditor .create( document.querySelector( '#editor' ), { plugins: [ ArticlePluginSet, FontColor, - // FontBackgroundColor + FontBackgroundColor ], toolbar: [ - 'heading', '|', + 'heading', + '|', 'fontColor', - // 'fontBackgroundColor', - 'bold', 'italic', 'link', 'bulletedList', 'numberedList', 'blockQuote', 'undo', 'redo' + 'fontBackgroundColor', + 'bold', + 'italic', + 'link', + 'bulletedList', + 'numberedList', + 'blockQuote', + 'undo', + 'redo' ] } ) .then( editor => { From 1c6bd61443b502f0ebb05719a571c214d42b8450 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 15:09:46 +0100 Subject: [PATCH 26/92] Disable possibility to apply filler colors. --- src/ui/colortableview.js | 7 ++++++- src/ui/colortile.js | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 68b8005..dcf7273 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -24,6 +24,7 @@ export default class ColorTableView extends View { this.set( 'removeButtonTooltip' ); this.set( 'colorColumns', 5 ); this.set( 'recentlyUsedColors', new Collection() ); + this.initRecentCollection(); this.recentlyUsedColors.on( 'add', ( evt, item ) => { @@ -95,6 +96,9 @@ export default class ColorTableView extends View { color: colorObj.color, hasBorder: true } ); + if ( colorObj.isEnabled === false ) { + colorTile.set( 'isEnabled', false ); + } colorTile.delegate( 'execute' ).to( this ); return colorTile; } @@ -111,7 +115,8 @@ export default class ColorTableView extends View { initRecentCollection() { for ( let i = 0; i < this.colorColumns; i++ ) { this.recentlyUsedColors.add( { - color: 'hsla( 0, 0%, 0%, 0 )' + color: 'hsla( 0, 0%, 0%, 0 )', + isEnabled: false } ); } } diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 9d0323e..659adc7 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -14,6 +14,7 @@ export default class ColorTile extends View { this.set( 'color' ); this.set( 'label' ); this.set( 'hasBorder' ); + this.set( 'isEnabled', true ); this.setTemplate( { tag: 'span', @@ -28,7 +29,9 @@ export default class ColorTile extends View { }, on: { click: bind.to( () => { - this.fire( 'execute', { value: this.color, hasBorder: this.hasBorder } ); + if ( this.isEnabled ) { + this.fire( 'execute', { value: this.color, hasBorder: this.hasBorder } ); + } } ) } } ); From 17339c7ebf6dfd76e5cdf4e5dc42aa7a7a2db772 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 19 Mar 2019 15:12:01 +0100 Subject: [PATCH 27/92] Add proper icons to font color. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 2 +- src/fontcolor/fontcolorui.js | 2 +- theme/icons/font-background.svg | 1 + theme/icons/font-color.svg | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) create mode 100644 theme/icons/font-background.svg create mode 100644 theme/icons/font-color.svg diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index dc365b5..01011aa 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -9,7 +9,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import fontBackgroundColorIcon from '../../theme/icons/font-family.svg'; +import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { FONT_BACKGROUND_COLOR, normalizeOptions, colorUI } from '../utils'; export default class FontBackgroundColorUI extends Plugin { diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 38927bb..1d3fe89 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -9,7 +9,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import fontColorIcon from '../../theme/icons/font-family.svg'; +import fontColorIcon from '../../theme/icons/font-color.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { FONT_COLOR, normalizeOptions, colorUI } from '../utils'; export default class FontColorUI extends Plugin { diff --git a/theme/icons/font-background.svg b/theme/icons/font-background.svg new file mode 100644 index 0000000..fa7ce96 --- /dev/null +++ b/theme/icons/font-background.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/theme/icons/font-color.svg b/theme/icons/font-color.svg new file mode 100644 index 0000000..51ddbea --- /dev/null +++ b/theme/icons/font-color.svg @@ -0,0 +1 @@ + From efeb3e9baa1f3e931d7dd4a7ff9d6376b03e33c5 Mon Sep 17 00:00:00 2001 From: Damian Konopka Date: Wed, 20 Mar 2019 11:54:29 +0100 Subject: [PATCH 28/92] Improved code style of CSS. --- theme/fontcolor.css | 53 +++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 543e004..e04d47e 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -4,46 +4,47 @@ */ :root { - --grid-size: 25px; + --ck-table-color-tile-size: 20px; + --ck-table-color-max-columns: 5; + --ck-table-color-padding: 10px; - --grid-columns-max: 5; + --ck-color-table-color-tile-border: hsl(0, 0%, 90%); + --ck-color-table-color-tile-border-active: hsl(184, 80%, 50%); } -.ck-color-table div.ck-color-table__grid-container { +.ck .ck-color-table__grid-container { display: grid; - grid-template-columns: repeat( var(--grid-columns-max), 1fr); - grid-gap: 5px; - padding: 10px; + grid-template-columns: repeat( var(--ck-table-color-max-columns), 1fr); + grid-gap: calc( var(--ck-table-color-padding) / 2 ); + padding: var(--ck-table-color-padding); } -.ck-color-table__grid-container span.ck-color-table__color-tile { - width: var(--grid-size); - height: var(--grid-size); - border-radius: 3px; +.ck .ck-color-table__color-tile { + width: var(--ck-table-color-tile-size); + height: var(--ck-table-color-tile-size); + border-radius: var(--ck-border-radius); cursor: pointer; - transition: 300ms ease all; -} -.ck-color-table__grid-container span.ck-color-table__color-tile.ck-color-table__color-tile_bordered { - box-shadow: 0 0 1px hsl( 0,0%,60%); + transition: 200ms ease box-shadow; } -.ck-color-table__grid-container span.ck-color-table__color-tile:hover { - box-shadow: 0 0 0 2px hsl(184, 80%, 50%); +.ck .ck-color-table__color-tile_bordered { + box-shadow: 0 0 0 1px var(--ck-color-table-color-tile-border); } -.ck-color-table button.ck-color-table__remove-color svg { - width: 24px; - margin-right: 10px; +.ck .ck-color-table__color-tile:hover { + box-shadow: 0 0 0 2px var(--ck-color-table-color-tile-border-active); } -.ck-color-table button.ck-color-table__remove-color { +/* If we change it to list element this CSS will be obsolete. */ +.ck .ck-button.ck-color-table__remove-color { display: flex; align-items: center; - text-align: left; - font-size: 16px; - border: 0; width: 100%; - border-bottom: 1px solid hsl(0, 0%, 87%); - padding: 10px; - cursor: pointer; + border-bottom: 1px solid var(--ck-color-base-border); + padding: calc(var(--ck-table-color-padding) / 2 ) var(--ck-table-color-padding); +} + +.ck .ck-button.ck-button_with-text.ck-color-table__remove-color svg { + width: var(--ck-table-color-tile-size); + margin-right: var(--ck-spacing-large); } From 5af98a8816a850d81bc89cbc4f2bdda2035f32fb Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 09:50:01 +0100 Subject: [PATCH 29/92] Extract color grid to separate class. Add simple focus tracking. --- src/ui/colorgrid.js | 33 ++++++++++++++ src/ui/colortableview.js | 92 ++++++++++++++++++++++------------------ 2 files changed, 84 insertions(+), 41 deletions(-) create mode 100644 src/ui/colorgrid.js diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js new file mode 100644 index 0000000..3477377 --- /dev/null +++ b/src/ui/colorgrid.js @@ -0,0 +1,33 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import View from '@ckeditor/ckeditor5-ui/src/view'; +import ColorTile from './colortile'; + +export default class ColorGrid extends View { + constructor( locale, { colorsDefinition = [] } = {} ) { + super( locale ); + + this.items = this.createCollection(); + + colorsDefinition.forEach( item => { + const colorTile = new ColorTile(); + colorTile.set( { + color: item.color, + hasBorder: item.options.hasBorder + } ); + colorTile.delegate( 'execute' ).to( this ); + this.items.add( colorTile ); + } ); + + this.setTemplate( { + tag: 'div', + children: this.items, + attributes: { + class: 'ck-color-table__grid-container' + } + } ); + } +} diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index dcf7273..e5d9795 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -4,20 +4,26 @@ */ import View from '@ckeditor/ckeditor5-ui/src/view'; -import Template from '@ckeditor/ckeditor5-ui/src/template'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import ColorTile from './colortile'; +import ColorGrid from './colorgrid'; import removeButtonIcon from '../../theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; +import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; +import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; export default class ColorTableView extends View { constructor( locale, { colors } ) { super( locale ); + this.locale = locale; + this.items = this.createCollection(); this.colorsDefinition = colors; + this.focusTracker = new FocusTracker(); + this.keystrokes = new KeystrokeHandler(); this.set( 'selectedColor' ); this.set( 'hoveredColor' ); @@ -27,27 +33,17 @@ export default class ColorTableView extends View { this.initRecentCollection(); - this.recentlyUsedColors.on( 'add', ( evt, item ) => { - const duplicates = this.recentlyUsedColors.filter( element => element.color === item.color, this ); - if ( duplicates.length === 2 ) { - this.recentlyUsedColors.remove( duplicates[ 1 ] ); - } - if ( this.recentlyUsedColors.length > this.colorColumns ) { - this.recentlyUsedColors.remove( this.recentlyUsedColors.length - 1 ); - } - } ); - this.setTemplate( { tag: 'div', attributes: { class: [ 'ck-color-table' ] }, - children: [ - this.removeColorButton(), - this.createColorTableTemplate(), - this.recentlyUsed() - ] + children: this.items } ); + + this.items.add( this.removeColorButton() ); + this.items.add( this.createColorTableTemplate() ); + this.items.add( this.recentlyUsed() ); } removeColorButton() { @@ -66,30 +62,15 @@ export default class ColorTableView extends View { } createColorTableTemplate() { - const colorCollection = this.createCollection(); - this.colorsDefinition.forEach( item => { - const colorTile = new ColorTile(); - colorTile.set( { - color: item.color, - hasBorder: item.options.hasBorder - } ); - colorTile.delegate( 'execute' ).to( this ); - colorCollection.add( colorTile ); - } ); - - return new Template( { - tag: 'div', - children: colorCollection, - attributes: { - class: 'ck-color-table__grid-container' - } - } ); + const colorGrid = new ColorGrid( this.locale, { colorsDefinition: this.colorsDefinition } ); + colorGrid.delegate( 'execute' ).to( this ); + return colorGrid; } recentlyUsed() { - this.recentlyUsedViews = this.createCollection(); + const recentViews = new ColorGrid( this.locale ); - this.recentlyUsedViews.bindTo( this.recentlyUsedColors ).using( + recentViews.items.bindTo( this.recentlyUsedColors ).using( colorObj => { const colorTile = new ColorTile(); colorTile.set( { @@ -103,13 +84,19 @@ export default class ColorTableView extends View { return colorTile; } ); - return new Template( { - tag: 'div', - children: this.recentlyUsedViews, - attributes: { - class: [ 'ck-color-table__grid-container' ] + + this.recentlyUsedColors.on( 'add', ( evt, item ) => { + const duplicates = this.recentlyUsedColors.filter( element => element.color === item.color, this ); + if ( duplicates.length === 2 ) { + this.recentlyUsedColors.remove( duplicates[ 1 ] ); + } + if ( this.recentlyUsedColors.length > this.colorColumns ) { + this.recentlyUsedColors.remove( this.recentlyUsedColors.length - 1 ); } } ); + + recentViews.delegate( 'execute' ).to( this ); + return recentViews; } initRecentCollection() { @@ -120,4 +107,27 @@ export default class ColorTableView extends View { } ); } } + + /** + * @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 ); + } } From 607f34553bee2d7ca8b057a0fec64218471fb2ab Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 12:17:41 +0100 Subject: [PATCH 30/92] Add focus manager for color grid and tiles. --- src/ui/colorgrid.js | 56 ++++++++++++++++++++++++++++++++++++++++ src/ui/colortableview.js | 28 +++++++++++++++++--- src/ui/colortile.js | 10 +++---- 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 3477377..8f7cb01 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -5,12 +5,17 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import ColorTile from './colortile'; +import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; +import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; +import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; export default class ColorGrid extends View { constructor( locale, { colorsDefinition = [] } = {} ) { super( locale ); this.items = this.createCollection(); + this.focusTracker = new FocusTracker(); + this.keystrokes = new KeystrokeHandler(); colorsDefinition.forEach( item => { const colorTile = new ColorTile(); @@ -29,5 +34,56 @@ export default class ColorGrid extends View { class: 'ck-color-table__grid-container' } } ); + + this._focusCycler = new FocusCycler( { + focusables: this.items, + focusTracker: this.focusTracker, + keystrokeHandler: this.keystrokes, + actions: { + // Navigate list items backwards using the arrowup key. + focusPrevious: 'arrowleft', + + // Navigate toolbar items forwards using the arrowdown key. + focusNext: 'arrowright', + } + } ); + } + + focus() { + if ( this.items.length ) { + this.items.first.focus(); + } + } + + focusLast() { + if ( this.items.length ) { + const lastChild = this.children.last; + + if ( typeof lastChild.focusLast === 'function' ) { + lastChild.focusLast(); + } else { + lastChild.focus(); + } + } + } + + 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 ); } } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index e5d9795..c32a63d 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -13,6 +13,7 @@ import removeButtonIcon from '../../theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; +import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; export default class ColorTableView extends View { @@ -41,9 +42,22 @@ export default class ColorTableView extends View { children: this.items } ); - this.items.add( this.removeColorButton() ); this.items.add( this.createColorTableTemplate() ); this.items.add( this.recentlyUsed() ); + this.items.add( this.removeColorButton() ); + + this._focusCycler = new FocusCycler( { + focusables: this.items, + focusTracker: this.focusTracker, + keystrokeHandler: this.keystrokes, + actions: { + // Navigate list items backwards using the arrowup key. + focusPrevious: 'arrowup', + + // Navigate toolbar items forwards using the arrowdown key. + focusNext: 'arrowdown', + } + } ); } removeColorButton() { @@ -127,7 +141,15 @@ export default class ColorTableView extends View { this.focusTracker.remove( item.element ); } ); - // // Start listening for the keystrokes coming from #element. - // this.keystrokes.listenTo( this.element ); + // Start listening for the keystrokes coming from #element. + this.keystrokes.listenTo( this.element ); + } + + focus() { + this._focusCycler.focusFirst(); + } + + focusLast() { + this._focusCycler.focusLast(); } } diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 659adc7..67ed920 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -3,21 +3,17 @@ * For licensing, see LICENSE.md. */ -import View from '@ckeditor/ckeditor5-ui/src/view'; - -export default class ColorTile extends View { +import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; +export default class ColorTile extends ButtonView { constructor( locale ) { super( locale ); const bind = this.bindTemplate; this.set( 'color' ); - this.set( 'label' ); this.set( 'hasBorder' ); - this.set( 'isEnabled', true ); - this.setTemplate( { - tag: 'span', + this.extendTemplate( { attributes: { style: { backgroundColor: bind.to( 'color' ) From d2b05d05d34551a0b06c7764107f4320954d3f57 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 12:31:36 +0100 Subject: [PATCH 31/92] Fix applying colors with tiles as buttons. --- src/ui/colorgrid.js | 4 +++- src/ui/colortableview.js | 6 ++++-- src/ui/colortile.js | 7 ------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 8f7cb01..d11e379 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -23,7 +23,9 @@ export default class ColorGrid extends View { color: item.color, hasBorder: item.options.hasBorder } ); - colorTile.delegate( 'execute' ).to( this ); + colorTile.on( 'execute', () => { + this.fire( 'execute', { value: item.color, hasBorder: item.options.hasBorder } ); + } ); this.items.add( colorTile ); } ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index c32a63d..35040fe 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -89,12 +89,14 @@ export default class ColorTableView extends View { const colorTile = new ColorTile(); colorTile.set( { color: colorObj.color, - hasBorder: true + hasBorder: colorObj.hasBorder } ); if ( colorObj.isEnabled === false ) { colorTile.set( 'isEnabled', false ); } - colorTile.delegate( 'execute' ).to( this ); + colorTile.on( 'execute', () => { + this.fire( 'execute', { value: colorObj.color, hasBorder: colorObj.hasBorder } ); + } ); return colorTile; } ); diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 67ed920..b3ab5ff 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -22,13 +22,6 @@ export default class ColorTile extends ButtonView { 'ck-color-table__color-tile', bind.if( 'hasBorder', 'ck-color-table__color-tile_bordered' ) ] - }, - on: { - click: bind.to( () => { - if ( this.isEnabled ) { - this.fire( 'execute', { value: this.color, hasBorder: this.hasBorder } ); - } - } ) } } ); } From 7015f10cd8c2cc78e3ce6c6b498897bec0407661 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 12:57:14 +0100 Subject: [PATCH 32/92] Add ocus return to editor. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 1 + src/fontcolor/fontcolorui.js | 1 + 2 files changed, 2 insertions(+) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 01011aa..cba1f32 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -59,6 +59,7 @@ export default class FontBackgroundColorUI extends Plugin { colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); } editor.execute( FONT_BACKGROUND_COLOR, val ); + editor.editing.view.focus(); } ); return dropdownView; diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 1d3fe89..0215dac 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -59,6 +59,7 @@ export default class FontColorUI extends Plugin { colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); } editor.execute( FONT_COLOR, val ); + editor.editing.view.focus(); } ); return dropdownView; From 0778ca714c5e74302d09967d5f1644b4eca35567 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 13:10:42 +0100 Subject: [PATCH 33/92] Add min-width and min-height css for color tile button. --- theme/fontcolor.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/theme/fontcolor.css b/theme/fontcolor.css index e04d47e..a250e28 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -22,6 +22,8 @@ .ck .ck-color-table__color-tile { width: var(--ck-table-color-tile-size); height: var(--ck-table-color-tile-size); + min-width: var(--ck-table-color-tile-size); + min-height: var(--ck-table-color-tile-size); border-radius: var(--ck-border-radius); cursor: pointer; transition: 200ms ease box-shadow; From ad16c83d11e44eed7470ead639593516cb95a0fd Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 14:06:39 +0100 Subject: [PATCH 34/92] Improve recent colors sryles. --- src/ui/colortableview.js | 5 +++-- theme/fontcolor.css | 7 ++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 35040fe..1af18d2 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -42,9 +42,9 @@ export default class ColorTableView extends View { children: this.items } ); + this.items.add( this.removeColorButton() ); this.items.add( this.createColorTableTemplate() ); this.items.add( this.recentlyUsed() ); - this.items.add( this.removeColorButton() ); this._focusCycler = new FocusCycler( { focusables: this.items, @@ -119,7 +119,8 @@ export default class ColorTableView extends View { for ( let i = 0; i < this.colorColumns; i++ ) { this.recentlyUsedColors.add( { color: 'hsla( 0, 0%, 0%, 0 )', - isEnabled: false + isEnabled: false, + hasBorder: true } ); } } diff --git a/theme/fontcolor.css b/theme/fontcolor.css index a250e28..81f689b 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -29,11 +29,16 @@ transition: 200ms ease box-shadow; } +.ck .ck-disabled.ck-color-table__color-tile { + cursor: unset; + transition: unset; +} + .ck .ck-color-table__color-tile_bordered { box-shadow: 0 0 0 1px var(--ck-color-table-color-tile-border); } -.ck .ck-color-table__color-tile:hover { +.ck .ck-color-table__color-tile:hover :not( .ck-disabled ) { box-shadow: 0 0 0 2px var(--ck-color-table-color-tile-border-active); } From 8e60d9c64de39cf4de668ff55bd7a48a32890cd9 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 14:21:18 +0100 Subject: [PATCH 35/92] Use eareaser icon from core. --- src/ui/colortableview.js | 2 +- theme/icons/eraser.svg | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 theme/icons/eraser.svg diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 1af18d2..244f313 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -8,7 +8,7 @@ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import ColorTile from './colortile'; import ColorGrid from './colorgrid'; -import removeButtonIcon from '../../theme/icons/eraser.svg'; +import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; diff --git a/theme/icons/eraser.svg b/theme/icons/eraser.svg deleted file mode 100644 index e64a293..0000000 --- a/theme/icons/eraser.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From e1c1fcd0a114699edbee1637d9ce759a017ceed4 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 14:25:45 +0100 Subject: [PATCH 36/92] Correct small issue in hovered css. --- theme/fontcolor.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 81f689b..2dcb1b6 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -38,7 +38,7 @@ box-shadow: 0 0 0 1px var(--ck-color-table-color-tile-border); } -.ck .ck-color-table__color-tile:hover :not( .ck-disabled ) { +.ck .ck-color-table__color-tile:hover:not( .ck-disabled ) { box-shadow: 0 0 0 2px var(--ck-color-table-color-tile-border-active); } From 29affa33f48b462b373af6f6ac6d1603333582e6 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 14:59:59 +0100 Subject: [PATCH 37/92] Add support for labels. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 4 ++-- src/fontcolor/fontcolorui.js | 4 ++-- src/ui/colorgrid.js | 4 +++- src/ui/colortableview.js | 8 +++++++- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index cba1f32..11b2fb8 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -29,7 +29,7 @@ export default class FontBackgroundColorUI extends Plugin { const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( element => ( { - name: element.label, + label: element.label, color: element.model, options: { hasBorder: element.hasBorder @@ -56,7 +56,7 @@ export default class FontBackgroundColorUI extends Plugin { dropdownView.on( 'execute', ( evt, val ) => { if ( val.value !== null ) { - colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); + colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); } editor.execute( FONT_BACKGROUND_COLOR, val ); editor.editing.view.focus(); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 0215dac..105f904 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -29,7 +29,7 @@ export default class FontColorUI extends Plugin { const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( element => ( { - name: element.label, + label: element.label, color: element.model, options: { hasBorder: element.hasBorder @@ -56,7 +56,7 @@ export default class FontColorUI extends Plugin { dropdownView.on( 'execute', ( evt, val ) => { if ( val.value !== null ) { - colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder }, 0 ); + colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); } editor.execute( FONT_COLOR, val ); editor.editing.view.focus(); diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index d11e379..28df1e0 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -21,10 +21,12 @@ export default class ColorGrid extends View { const colorTile = new ColorTile(); colorTile.set( { color: item.color, + label: item.label, + tooltip: true, hasBorder: item.options.hasBorder } ); colorTile.on( 'execute', () => { - this.fire( 'execute', { value: item.color, hasBorder: item.options.hasBorder } ); + this.fire( 'execute', { value: item.color, hasBorder: item.options.hasBorder, label: item.label } ); } ); this.items.add( colorTile ); } ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 244f313..b589809 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -91,11 +91,17 @@ export default class ColorTableView extends View { color: colorObj.color, hasBorder: colorObj.hasBorder } ); + if ( colorObj.label ) { + colorTile.set( { + label: colorObj.label, + tooltip: true + } ); + } if ( colorObj.isEnabled === false ) { colorTile.set( 'isEnabled', false ); } colorTile.on( 'execute', () => { - this.fire( 'execute', { value: colorObj.color, hasBorder: colorObj.hasBorder } ); + this.fire( 'execute', { value: colorObj.color, hasBorder: colorObj.hasBorder, label: colorObj.label } ); } ); return colorTile; } From 2fddd46da456b9ca0c3ad9c81d570754a834ef9b Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Wed, 20 Mar 2019 16:39:53 +0100 Subject: [PATCH 38/92] Fix currently failing unit tests. --- tests/fontcolor/fontcolorediting.js | 218 +++++++++++++++------------- tests/fontcolor/fontcolorui.js | 21 +-- 2 files changed, 121 insertions(+), 118 deletions(-) diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index b09ed93..b435616 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -8,7 +8,7 @@ import FontColorEditing from './../../src/fontcolor/fontcolorediting'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; -import { setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; describe( 'FontColorEditing', () => { let editor, doc; @@ -38,103 +38,25 @@ describe( 'FontColorEditing', () => { describe( 'config', () => { describe( 'default value', () => { it( 'should be set', () => { - expect( editor.config.get( 'fontColor.options' ) ).to.deep.equal( [ - { - label: 'Strong Cyan', - color: '#1ABC9C' - }, - { - label: 'Emerald', - color: '#2ECC71' - }, - { - label: 'Bright Blue', - color: '#3498DB' - }, - { - label: 'Amethyst', - color: '#9B59B6' - }, - { - label: 'Grayish Blue', - color: '#4E5F70' - }, - { - label: 'Vivid Yellow', - color: '#F1C40F' - }, - { - label: 'Dark Cyan', - color: '#16A085' - }, - { - label: 'Dark Emerald', - color: '#27AE60' - }, - { - label: 'Strong Blue', - color: '#2980B9' - }, - { - label: 'Dark Violet', - color: '#8E44AD' - }, - { - label: 'Desaturated Blue', - color: '#2C3E50' - }, - { - label: 'Orange', - color: '#F39C12' - }, - { - label: 'Carrot', - color: '#E67E22' - }, - { - label: 'Pale Red', - color: '#E74C3C' - }, - { - label: 'Bright Silver', - color: '#ECF0F1' - }, - { - label: 'Light Grayish Cyan', - color: '#95A5A6' - }, - { - label: 'Light Gray', - color: '#DDD' - }, - { - label: 'White', - color: '#FFF' - }, - { - label: 'Pumpkin', - color: '#D35400' - }, - { - label: 'Strong Red', - color: '#C0392B' - }, - { - label: 'Silver', - color: '#BDC3C7' - }, - { - label: 'Grayish Cyan', - color: '#7F8C8D' - }, - { - label: 'Dark Gray', - color: '#999' - }, - { - label: 'Black', - color: '#000' - } + expect( editor.config.get( 'fontColor.colors' ) ).to.deep.equal( [ + 'hsl(0, 0%, 0%)', + 'hsl(0, 0%, 30%)', + 'hsl(0, 0%, 60%)', + 'hsl(0, 0%, 90%)', + { + color: 'hsl(0, 0%, 100%)', + hasBorder: true + }, + 'hsl(360, 75%, 60%)', + 'hsl(30, 75%, 60%)', + 'hsl(60, 75%, 60%)', + 'hsl(90, 75%, 60%)', + 'hsl(120, 75%, 60%)', + 'hsl(150, 75%, 60%)', + 'hsl(180, 75%, 60%)', + 'hsl(210, 75%, 60%)', + 'hsl(240, 75%, 60%)', + 'hsl(270, 75%, 60%)' ] ); } ); } ); @@ -145,7 +67,7 @@ describe( 'FontColorEditing', () => { .create( { plugins: [ FontColorEditing, Paragraph ], fontColor: { - options: [ + colors: [ { label: 'Color1', color: '#000' @@ -155,10 +77,9 @@ describe( 'FontColorEditing', () => { }, { label: 'Color3', color: 'rgb( 0, 10, 20 )' - }, { - label: 'Color4', - color: 'hsl( 200,100%,50%)' - }, { + }, + 'hsl( 200,100%,50%)', + { label: 'Color5 - Light Green', color: 'lightgreen' } @@ -191,4 +112,95 @@ describe( 'FontColorEditing', () => { } ); } ); } ); + + describe( 'data pipeline conversions', () => { + beforeEach( () => { + return VirtualTestEditor + .create( { + plugins: [ FontColorEditing, Paragraph ], + fontColor: { + colors: [ + { + label: 'Color1', + color: '#000' + }, { + label: 'Color2', + color: '#123456' + }, { + label: 'Color3', + color: 'rgb( 0, 10, 20 )' + }, + 'hsl( 200,100%,50%)', + { + label: 'Color5 - Light Green', + color: 'lightgreen' + } + ] + } + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.model; + } ); + } ); + + it( 'should convert from element with defined style when with other styles', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontColor="rgb(10,20,30)">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + describe( 'should convert from different color versions', () => { + const tests = [ + '#000', + 'green', + 'rgb( 0, 10, 20 )', + 'rgba( 20, 30, 50, 0.4)', + 'hsl( 10, 20%, 30%)', + 'hsla( 300, 50%, 100%, .3)', + 'rgb( 20%, 30%, 40% )', + '#345678' + ]; + + tests.forEach( test => { + it( `should convert fontColor attribute: "${ test }" to proper style value.`, () => { + const data = `

foo

`; + editor.setData( data ); + + expect( getModelData( doc ) ) + .to.equal( `[]f<$text fontColor="${ test.replace( / /g, '' ) }">oo` ); + + expect( editor.getData() ).to.equal( `

foo

` ); + } ); + } ); + } ); + + it( 'should convert from complex definition', () => { + editor.setData( + '

foo

' + + '

foo

' + + '

bar

' + + '

baz

' + ); + + expect( getModelData( doc ) ).to.equal( + '[]f<$text fontColor="lightgreen">oo' + + 'f<$text fontColor="hsl(200,100%,50%)">oo' + + 'b<$text fontColor="rgba(1,2,3,.4)">ar' + + 'b<$text fontColor="#fff">az' + ); + + expect( editor.getData() ).to.equal( + '

foo

' + + '

foo

' + + '

bar

' + + '

baz

' + ); + } ); + } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 6b0e6a7..7e216dd 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -8,7 +8,7 @@ import FontColorEditing from '../../src/fontcolor/fontcolorediting'; import FontColorUI from '../../src/fontcolor/fontcolorui'; -import fontColorIcon from '../../theme/icons/font-family.svg'; +import fontColorIcon from '../../theme/icons/font-color.svg'; import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; @@ -22,12 +22,12 @@ describe( 'FontColorUI', () => { before( () => { addTranslations( 'en', { 'Font Color': 'Font Color', - 'Remove text color': 'Remove text color' + 'Remove color': 'Remove text color' } ); addTranslations( 'pl', { 'Font Color': 'Kolor czcionki', - 'Remove text color': 'Usuń kolor tekstu' + 'Remove color': 'Usuń kolor' } ); } ); @@ -83,17 +83,7 @@ describe( 'FontColorUI', () => { const dropdown = editor.ui.componentFactory.create( 'fontColor' ); dropdown.commandName = 'fontColor'; - dropdown.fire( 'execute' ); - - sinon.assert.calledOnce( focusSpy ); - } ); - - it( 'should focus view after command execution from splitbutton', () => { - const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); - const dropdown = editor.ui.componentFactory.create( 'fontColor' ); - - dropdown.commandName = 'fontColor'; - dropdown.buttonView.fire( 'execute' ); + dropdown.fire( 'execute', { value: null } ); sinon.assert.calledOnce( focusSpy ); } ); @@ -122,7 +112,8 @@ describe( 'FontColorUI', () => { it( 'works for the colorTableView#items in the panel', () => { const colorTableView = dropdown.colorTableView; - expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor tekstu' ); + expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor' ); + expect( colorTableView.items.first.label ).to.equal( 'Usuń kolor' ); } ); function localizedEditor() { From c67befb31a28bf774405bc89bc0191a4a1172a8a Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 09:40:11 +0100 Subject: [PATCH 39/92] Add support for objects without label. --- src/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 9199605..04c3636 100644 --- a/src/utils.js +++ b/src/utils.js @@ -80,7 +80,7 @@ function getColorsDefinition( color ) { } else { return { model: color.color, - label: color.label, + label: color.label || color.color, hasBorder: color.hasBorder, view: { name: 'span', From 23de22efe403b2e29f818cacd78113f78d05999e Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 09:58:44 +0100 Subject: [PATCH 40/92] Add pointer cursor for remove button. --- theme/fontcolor.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 2dcb1b6..3eec924 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -55,3 +55,7 @@ width: var(--ck-table-color-tile-size); margin-right: var(--ck-spacing-large); } + +.ck .ck-color-table__remove-color { + cursor: pointer; +} From 9e1d3df1d4055c4b2824b5edf04f361fc1b079b2 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 10:26:45 +0100 Subject: [PATCH 41/92] Add color names. --- .../fontbackgroundcolorediting.js | 59 ++++++++++++++----- src/fontcolor/fontcolorediting.js | 59 ++++++++++++++----- 2 files changed, 88 insertions(+), 30 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index aa60e51..5047eaf 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -22,24 +22,53 @@ export default class FontBackgroundColorEditing extends Plugin { editor.config.define( FONT_BACKGROUND_COLOR, { colors: [ - 'hsl(0, 0%, 0%)', - 'hsl(0, 0%, 30%)', - 'hsl(0, 0%, 60%)', - 'hsl(0, 0%, 90%)', { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, { color: 'hsl(0, 0%, 100%)', + label: 'White', hasBorder: true - }, - 'hsl(360, 75%, 60%)', - 'hsl(30, 75%, 60%)', - 'hsl(60, 75%, 60%)', - 'hsl(90, 75%, 60%)', - 'hsl(120, 75%, 60%)', - 'hsl(150, 75%, 60%)', - 'hsl(180, 75%, 60%)', - 'hsl(210, 75%, 60%)', - 'hsl(240, 75%, 60%)', - 'hsl(270, 75%, 60%)' + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, { + color: 'hsl(150, 75%, 60%)', + label: 'Aquamarine' + }, { + color: 'hsl(180, 75%, 60%)', + label: 'Turquoise' + }, { + color: 'hsl(210, 75%, 60%)', + label: 'Light blue' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Blue' + }, { + color: 'hsl(270, 75%, 60%)', + label: 'Purple' + } ] } ); diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index a5238e1..c1cb3cd 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -22,24 +22,53 @@ export default class FontColorEditing extends Plugin { editor.config.define( FONT_COLOR, { colors: [ - 'hsl(0, 0%, 0%)', - 'hsl(0, 0%, 30%)', - 'hsl(0, 0%, 60%)', - 'hsl(0, 0%, 90%)', { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, { color: 'hsl(0, 0%, 100%)', + label: 'White', hasBorder: true - }, - 'hsl(360, 75%, 60%)', - 'hsl(30, 75%, 60%)', - 'hsl(60, 75%, 60%)', - 'hsl(90, 75%, 60%)', - 'hsl(120, 75%, 60%)', - 'hsl(150, 75%, 60%)', - 'hsl(180, 75%, 60%)', - 'hsl(210, 75%, 60%)', - 'hsl(240, 75%, 60%)', - 'hsl(270, 75%, 60%)' + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, { + color: 'hsl(150, 75%, 60%)', + label: 'Aquamarine' + }, { + color: 'hsl(180, 75%, 60%)', + label: 'Turquoise' + }, { + color: 'hsl(210, 75%, 60%)', + label: 'Light blue' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Blue' + }, { + color: 'hsl(270, 75%, 60%)', + label: 'Purple' + } ] } ); From b04aad202080b2a8fc11c2ef2b950e93671eba32 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 10:53:07 +0100 Subject: [PATCH 42/92] Add possibility to translate labels. --- src/fontcolor/fontcolorui.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 105f904..b0e5cf9 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -29,7 +29,7 @@ export default class FontColorUI extends Plugin { const colorTableView = colorUI.addColorsToDropdown( dropdownView, options.map( element => ( { - label: element.label, + label: t( element.label ), color: element.model, options: { hasBorder: element.hasBorder @@ -66,17 +66,6 @@ export default class FontColorUI extends Plugin { } ); } - /** - * Returns options as defined in `config.fontFamily.options` but processed to account for - * editor localization, i.e. to display {@link module:font/fontfamily~FontFamilyOption} - * in the correct language. - * - * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} - * when the user configuration is defined because the editor does not exist yet. - * - * @private - * @returns {Array.}. - */ _getLocalizedOptions() { const editor = this.editor; const colors = normalizeOptions( editor.config.get( `${ FONT_COLOR }.colors` ) ); From 90f2559e528e0d3fc037e61c5b4239fa449256cb Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 11:41:36 +0100 Subject: [PATCH 43/92] Add unit test for color translations. --- tests/fontcolor/fontcolorediting.js | 59 +++++++++++++++++++++-------- tests/fontcolor/fontcolorui.js | 51 ++++++++++++++++++++++++- 2 files changed, 93 insertions(+), 17 deletions(-) diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index b435616..b4c7d64 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -39,24 +39,53 @@ describe( 'FontColorEditing', () => { describe( 'default value', () => { it( 'should be set', () => { expect( editor.config.get( 'fontColor.colors' ) ).to.deep.equal( [ - 'hsl(0, 0%, 0%)', - 'hsl(0, 0%, 30%)', - 'hsl(0, 0%, 60%)', - 'hsl(0, 0%, 90%)', { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, { color: 'hsl(0, 0%, 100%)', + label: 'White', hasBorder: true - }, - 'hsl(360, 75%, 60%)', - 'hsl(30, 75%, 60%)', - 'hsl(60, 75%, 60%)', - 'hsl(90, 75%, 60%)', - 'hsl(120, 75%, 60%)', - 'hsl(150, 75%, 60%)', - 'hsl(180, 75%, 60%)', - 'hsl(210, 75%, 60%)', - 'hsl(240, 75%, 60%)', - 'hsl(270, 75%, 60%)' + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, { + color: 'hsl(150, 75%, 60%)', + label: 'Aquamarine' + }, { + color: 'hsl(180, 75%, 60%)', + label: 'Turquoise' + }, { + color: 'hsl(210, 75%, 60%)', + label: 'Light blue' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Blue' + }, { + color: 'hsl(270, 75%, 60%)', + label: 'Purple' + } ] ); } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 7e216dd..02a4f1a 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -22,12 +22,25 @@ describe( 'FontColorUI', () => { before( () => { addTranslations( 'en', { 'Font Color': 'Font Color', - 'Remove color': 'Remove text color' + 'Remove color': 'Remove text color', + 'Black': 'Black', + 'White': 'White', + 'Red': 'Red', + 'Orange': 'Orange', + 'Blue': 'Blue', + 'Green': 'Green' } ); addTranslations( 'pl', { 'Font Color': 'Kolor czcionki', - 'Remove color': 'Usuń kolor' + 'Remove color': 'Usuń kolor', + 'Black': 'Czarny', + 'White': 'Biały', + 'Red': 'Czerwony', + 'Orange': 'Pomarańczowy', + 'Blue': 'Niebieski', + 'Green': 'Zielony', + 'Yellow': 'Żółty' } ); } ); @@ -116,6 +129,40 @@ describe( 'FontColorUI', () => { expect( colorTableView.items.first.label ).to.equal( 'Usuń kolor' ); } ); + describe( 'works for', () => { + const colors = [ + { + color: 'hsl(0, 0%, 0%)', + label: 'Czarny' + }, { + color: 'hsl(0, 0%, 100%)', + label: 'Biały' + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Czerwony' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Pomarańczowy' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Niebieski' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Zielony' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Żółty' + } + ]; + + colors.forEach( test => { + it( `tested color ${ test.color } with name ${ test.label }.`, () => { + const colorGrid = dropdown.colorTableView.items.get( 1 ); + const tile = colorGrid.items.find( colorTile => test.color === colorTile.color ); + expect( tile.label ).to.equal( test.label ); + } ); + } ); + } ); function localizedEditor() { const editorElement = document.createElement( 'div' ); document.body.appendChild( editorElement ); From 2f4807456b61930def14832f69e95a9b459518a1 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 14:59:59 +0100 Subject: [PATCH 44/92] Add part of fixes after review. --- .../fontbackgroundcolorcommand.js | 12 ++++++ .../fontbackgroundcolorediting.js | 21 +++++----- .../fontbackgroundcolorui.js | 39 ++++++++++++------- src/fontcolor/fontcolorcommand.js | 11 ++++++ src/fontcolor/fontcolorediting.js | 21 +++++----- src/fontcolor/fontcolorui.js | 34 ++++++++++++---- src/ui/colorgrid.js | 6 ++- src/ui/colortableview.js | 7 +--- src/ui/colortile.js | 1 + src/utils.js | 18 ++++----- 10 files changed, 114 insertions(+), 56 deletions(-) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorcommand.js b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js index 848319a..da85c65 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorcommand.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js @@ -9,6 +9,18 @@ import FontCommand from '../fontcommand'; import { FONT_BACKGROUND_COLOR } from '../utils'; + +/** + * The font background color command. It's used by + * {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} + * to apply the font background color. + * + * editor.execute( 'fontBackgroundColor', { value: 'rgb(250, 20, 20)' } ); + * + * **Note**: Executing the command with value equal null removes the attribute from the model. + * + * @extends module:font/fontcommand~FontCommand + */ export default class FontBackgroundColorCommand extends FontCommand { /** * @inheritDoc diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index 5047eaf..4652d7b 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -4,15 +4,23 @@ */ /** - * @module font/fontfamily/fontfamilyediting + * @module font/fontbackgroundcolor/fontbackgroundcolorediting */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; - import FontBackgroundColorCommand from './fontbackgroundcolorcommand'; - import { FONT_BACKGROUND_COLOR, renderDowncastElement, renderUpcastAttribute } from '../utils'; +/** + * The font background color editing feature. + * + * It introduces the {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand command} and + * the `fontBackgroundColor` attribute in the {@link module:engine/model/model~Model model} which renders + * in the {@link module:engine/view/view view} as an inline `` element (``), + * depending on the {@link module:font/fontbackgroundcolor~FontBackgroundColortConfig configuration}. + * + * @extends module:core/plugin~Plugin + */ export default class FontBackgroundColorEditing extends Plugin { /** * @inheritDoc @@ -91,13 +99,6 @@ export default class FontBackgroundColorEditing extends Plugin { } ); editor.commands.add( FONT_BACKGROUND_COLOR, new FontBackgroundColorCommand( editor ) ); - } - - /** - * @inheritDoc - */ - init() { - const editor = this.editor; // Allow fontBackgroundColor attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: FONT_BACKGROUND_COLOR } ); diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 11b2fb8..b898fd9 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -8,10 +8,15 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; - -import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_BACKGROUND_COLOR, normalizeOptions, colorUI } from '../utils'; +import { FONT_BACKGROUND_COLOR, normalizeOptions, addColorsToDropdown } from '../utils'; +import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; + +/** + * The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown. + * + * @extends module:core/plugin~Plugin + */ export default class FontBackgroundColorUI extends Plugin { /** * @inheritDoc @@ -26,7 +31,7 @@ export default class FontBackgroundColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_BACKGROUND_COLOR, locale => { const dropdownView = createDropdown( locale ); - const colorTableView = colorUI.addColorsToDropdown( + const colorTableView = addColorsToDropdown( dropdownView, options.map( element => ( { label: element.label, @@ -54,11 +59,15 @@ export default class FontBackgroundColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); - dropdownView.on( 'execute', ( evt, val ) => { - if ( val.value !== null ) { - colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); + dropdownView.on( 'execute', ( evt, data ) => { + if ( data.value !== null ) { + colorTableView.recentlyUsedColors.add( { + color: data.value, + hasBorder: data.hasBorder, + label: data.label + }, 0 ); } - editor.execute( FONT_BACKGROUND_COLOR, val ); + editor.execute( FONT_BACKGROUND_COLOR, data ); editor.editing.view.focus(); } ); @@ -67,19 +76,23 @@ export default class FontBackgroundColorUI extends Plugin { } /** - * Returns options as defined in `config.fontFamily.options` but processed to account for - * editor localization, i.e. to display {@link module:font/fontfamily~FontFamilyOption} + * Returns options as defined in `config.fontBackgroundColor.colors` but processed to account for + * editor localization, i.e. to display {@link module:font/fontBackgroundColor~FontBackgroundColorOption} * in the correct language. * * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} * when the user configuration is defined because the editor does not exist yet. * * @private - * @returns {Array.}. + * @returns {Array.}. */ _getLocalizedOptions() { const editor = this.editor; - const colors = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ) ); - return colors; + const t = editor.t; + const options = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ) ); + options.forEach( option => { + option.label = t( option.label ); + } ); + return options; } } diff --git a/src/fontcolor/fontcolorcommand.js b/src/fontcolor/fontcolorcommand.js index b669c84..9b50c6d 100644 --- a/src/fontcolor/fontcolorcommand.js +++ b/src/fontcolor/fontcolorcommand.js @@ -9,6 +9,17 @@ import FontCommand from '../fontcommand'; import { FONT_COLOR } from '../utils'; + +/** + * The font color command. It's used by {@link module:font/fontcolor/fontcolorediting~FontColorEditing} + * to apply the font color. + * + * editor.execute( 'fontColor', { value: 'rgb(250, 20, 20)' } ); + * + * **Note**: Executing the command with value equal null removes the attribute from the model. + * + * @extends module:font/fontcommand~FontCommand + */ export default class FontColorCommand extends FontCommand { /** * @inheritDoc diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index c1cb3cd..ebb39ec 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -4,15 +4,23 @@ */ /** - * @module font/fontfamily/fontfamilyediting + * @module font/fontcolor/fontcolorediting */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; - import FontColorCommand from './fontcolorcommand'; - import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from '../utils'; +/** + * The font color editing feature. + * + * It introduces the {@link module:font/fontcolor/fontcolorcommand~FontColorCommand command} and + * the `fontColor` attribute in the {@link module:engine/model/model~Model model} which renders + * in the {@link module:engine/view/view view} as an inline `` element (``), + * depending on the {@link module:font/fontcolor~FontColortConfig configuration}. + * + * @extends module:core/plugin~Plugin + */ export default class FontColorEditing extends Plugin { /** * @inheritDoc @@ -91,13 +99,6 @@ export default class FontColorEditing extends Plugin { } ); editor.commands.add( FONT_COLOR, new FontColorCommand( editor ) ); - } - - /** - * @inheritDoc - */ - init() { - const editor = this.editor; // Allow fontColor attribute on text nodes. editor.model.schema.extend( '$text', { allowAttributes: FONT_COLOR } ); diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index b0e5cf9..c3314bf 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -8,10 +8,15 @@ */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; - -import fontColorIcon from '../../theme/icons/font-color.svg'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_COLOR, normalizeOptions, colorUI } from '../utils'; +import { FONT_COLOR, normalizeOptions, addColorsToDropdown } from '../utils'; +import fontColorIcon from '../../theme/icons/font-color.svg'; + +/** + * The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown. + * + * @extends module:core/plugin~Plugin + */ export default class FontColorUI extends Plugin { /** * @inheritDoc @@ -26,10 +31,10 @@ export default class FontColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( FONT_COLOR, locale => { const dropdownView = createDropdown( locale ); - const colorTableView = colorUI.addColorsToDropdown( + const colorTableView = addColorsToDropdown( dropdownView, options.map( element => ( { - label: t( element.label ), + label: element.label, color: element.model, options: { hasBorder: element.hasBorder @@ -66,9 +71,24 @@ export default class FontColorUI extends Plugin { } ); } + /** + * Returns options as defined in `config.fontColor.colors` but processed to account for + * editor localization, i.e. to display {@link module:font/fontColor~FontColorOption} + * in the correct language. + * + * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} + * when the user configuration is defined because the editor does not exist yet. + * + * @private + * @returns {Array.}. + */ _getLocalizedOptions() { const editor = this.editor; - const colors = normalizeOptions( editor.config.get( `${ FONT_COLOR }.colors` ) ); - return colors; + const t = editor.t; + const options = normalizeOptions( editor.config.get( `${ FONT_COLOR }.colors` ) ); + options.forEach( option => { + option.label = t( option.label ); + } ); + return options; } } diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 28df1e0..3fbd9d7 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -26,7 +26,11 @@ export default class ColorGrid extends View { hasBorder: item.options.hasBorder } ); colorTile.on( 'execute', () => { - this.fire( 'execute', { value: item.color, hasBorder: item.options.hasBorder, label: item.label } ); + this.fire( 'execute', { + value: item.color, + hasBorder: item.options.hasBorder, + label: item.label + } ); } ); this.items.add( colorTile ); } ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index b589809..7e9e760 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -7,14 +7,12 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import ColorTile from './colortile'; import ColorGrid from './colorgrid'; - -import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; - -import '../../theme/fontcolor.css'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; +import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; +import '../../theme/fontcolor.css'; export default class ColorTableView extends View { constructor( locale, { colors } ) { @@ -27,7 +25,6 @@ export default class ColorTableView extends View { this.keystrokes = new KeystrokeHandler(); this.set( 'selectedColor' ); - this.set( 'hoveredColor' ); this.set( 'removeButtonTooltip' ); this.set( 'colorColumns', 5 ); this.set( 'recentlyUsedColors', new Collection() ); diff --git a/src/ui/colortile.js b/src/ui/colortile.js index b3ab5ff..5db0c7a 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -4,6 +4,7 @@ */ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; + export default class ColorTile extends ButtonView { constructor( locale ) { super( locale ); diff --git a/src/utils.js b/src/utils.js index 04c3636..0954edb 100644 --- a/src/utils.js +++ b/src/utils.js @@ -93,14 +93,12 @@ function getColorsDefinition( color ) { } } -export const colorUI = { - addColorsToDropdown( dropdownView, colors ) { - const locale = dropdownView.locale; - const colorTableView = new ColorTableView( locale, { colors } ); - dropdownView.colorTableView = colorTableView; - dropdownView.panelView.children.add( colorTableView ); +export function addColorsToDropdown( dropdownView, colors ) { + const locale = dropdownView.locale; + const colorTableView = new ColorTableView( locale, { colors } ); + dropdownView.colorTableView = colorTableView; + dropdownView.panelView.children.add( colorTableView ); - colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); - return colorTableView; - } -}; + colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); + return colorTableView; +} From 8c783f5c9f126537c2ecffdfc1ae4386312edd36 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 15:48:13 +0100 Subject: [PATCH 45/92] Extract color UI to same class. --- .../fontbackgroundcolorui.js | 90 ++-------------- src/fontcolor/fontcolorui.js | 84 ++------------- src/ui/colorui.js | 102 ++++++++++++++++++ 3 files changed, 121 insertions(+), 155 deletions(-) create mode 100644 src/ui/colorui.js diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index b898fd9..29a14d1 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -4,12 +4,11 @@ */ /** - * @module font/fontbackgroundcolor/fontbackgroundolorui + * @module font/fontcolor/fontcolorui */ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_BACKGROUND_COLOR, normalizeOptions, addColorsToDropdown } from '../utils'; +import ColorUI from '../ui/colorui'; +import { FONT_BACKGROUND_COLOR } from '../utils'; import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; /** @@ -17,82 +16,13 @@ import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; * * @extends module:core/plugin~Plugin */ -export default class FontBackgroundColorUI extends Plugin { - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - const command = editor.commands.get( FONT_BACKGROUND_COLOR ); - - const options = this._getLocalizedOptions(); - - // Register UI component. - editor.ui.componentFactory.add( FONT_BACKGROUND_COLOR, locale => { - const dropdownView = createDropdown( locale ); - const colorTableView = addColorsToDropdown( - dropdownView, - options.map( element => ( { - label: element.label, - color: element.model, - options: { - hasBorder: element.hasBorder - } - } ) ) - ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); - - colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - - dropdownView.buttonView.set( { - label: t( 'Font Background Color' ), - icon: fontBackgroundColorIcon, - tooltip: true - } ); - - dropdownView.extendTemplate( { - attributes: { - class: 'ck-font-background-color-dropdown' - } - } ); - - dropdownView.bind( 'isEnabled' ).to( command ); - - dropdownView.on( 'execute', ( evt, data ) => { - if ( data.value !== null ) { - colorTableView.recentlyUsedColors.add( { - color: data.value, - hasBorder: data.hasBorder, - label: data.label - }, 0 ); - } - editor.execute( FONT_BACKGROUND_COLOR, data ); - editor.editing.view.focus(); - } ); - - return dropdownView; - } ); - } - - /** - * Returns options as defined in `config.fontBackgroundColor.colors` but processed to account for - * editor localization, i.e. to display {@link module:font/fontBackgroundColor~FontBackgroundColorOption} - * in the correct language. - * - * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} - * when the user configuration is defined because the editor does not exist yet. - * - * @private - * @returns {Array.}. - */ - _getLocalizedOptions() { - const editor = this.editor; - const t = editor.t; - const options = normalizeOptions( editor.config.get( `${ FONT_BACKGROUND_COLOR }.colors` ) ); - options.forEach( option => { - option.label = t( option.label ); +export default class FontColorUI extends ColorUI { + constructor( editor ) { + super( editor, { + commandName: FONT_BACKGROUND_COLOR, + componentName: FONT_BACKGROUND_COLOR, + icon: fontBackgroundColorIcon, + dropdownLabel: 'Font Background Color' } ); - return options; } } diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index c3314bf..4d3611d 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -7,9 +7,8 @@ * @module font/fontcolor/fontcolorui */ -import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; -import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { FONT_COLOR, normalizeOptions, addColorsToDropdown } from '../utils'; +import ColorUI from '../ui/colorui'; +import { FONT_COLOR } from '../utils'; import fontColorIcon from '../../theme/icons/font-color.svg'; /** @@ -17,78 +16,13 @@ import fontColorIcon from '../../theme/icons/font-color.svg'; * * @extends module:core/plugin~Plugin */ -export default class FontColorUI extends Plugin { - /** - * @inheritDoc - */ - init() { - const editor = this.editor; - const t = editor.t; - const command = editor.commands.get( FONT_COLOR ); - - const options = this._getLocalizedOptions(); - - // Register UI component. - editor.ui.componentFactory.add( FONT_COLOR, locale => { - const dropdownView = createDropdown( locale ); - const colorTableView = addColorsToDropdown( - dropdownView, - options.map( element => ( { - label: element.label, - color: element.model, - options: { - hasBorder: element.hasBorder - } - } ) ) - ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); - - colorTableView.bind( 'selectedColor' ).to( command, 'value' ); - - dropdownView.buttonView.set( { - label: t( 'Font Color' ), - icon: fontColorIcon, - tooltip: true - } ); - - dropdownView.extendTemplate( { - attributes: { - class: 'ck-font-color-dropdown' - } - } ); - - dropdownView.bind( 'isEnabled' ).to( command ); - - dropdownView.on( 'execute', ( evt, val ) => { - if ( val.value !== null ) { - colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); - } - editor.execute( FONT_COLOR, val ); - editor.editing.view.focus(); - } ); - - return dropdownView; - } ); - } - - /** - * Returns options as defined in `config.fontColor.colors` but processed to account for - * editor localization, i.e. to display {@link module:font/fontColor~FontColorOption} - * in the correct language. - * - * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} - * when the user configuration is defined because the editor does not exist yet. - * - * @private - * @returns {Array.}. - */ - _getLocalizedOptions() { - const editor = this.editor; - const t = editor.t; - const options = normalizeOptions( editor.config.get( `${ FONT_COLOR }.colors` ) ); - options.forEach( option => { - option.label = t( option.label ); +export default class FontColorUI extends ColorUI { + constructor( editor ) { + super( editor, { + commandName: FONT_COLOR, + componentName: FONT_COLOR, + icon: fontColorIcon, + dropdownLabel: 'Font Color' } ); - return options; } } diff --git a/src/ui/colorui.js b/src/ui/colorui.js new file mode 100644 index 0000000..a680beb --- /dev/null +++ b/src/ui/colorui.js @@ -0,0 +1,102 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/** + * @module font/fontcolor/fontcolorui + */ + +import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; +import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; +import { normalizeOptions, addColorsToDropdown } from '../utils'; + +/** + * The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown. + * + * @extends module:core/plugin~Plugin + */ +export default class ColorUI extends Plugin { + constructor( editor, { commandName, icon, componentName, dropdownLabel } ) { + super( editor ); + + this.commandName = commandName; + this.icon = icon; + this.componentName = componentName; + this.dropdownLabel = dropdownLabel; + } + + /** + * @inheritDoc + */ + init() { + const editor = this.editor; + const t = editor.t; + const command = editor.commands.get( this.commandName ); + + const options = this._getLocalizedOptions(); + + // Register UI component. + editor.ui.componentFactory.add( this.componentName, locale => { + const dropdownView = createDropdown( locale ); + const colorTableView = addColorsToDropdown( + dropdownView, + options.map( element => ( { + label: element.label, + color: element.model, + options: { + hasBorder: element.hasBorder + } + } ) ) + ); + colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); + + colorTableView.bind( 'selectedColor' ).to( command, 'value' ); + + dropdownView.buttonView.set( { + label: t( this.dropdownLabel ), + icon: this.icon, + tooltip: true + } ); + + dropdownView.extendTemplate( { + attributes: { + class: 'ck-color-ui-dropdown' + } + } ); + + dropdownView.bind( 'isEnabled' ).to( command ); + + dropdownView.on( 'execute', ( evt, val ) => { + if ( val.value !== null ) { + colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); + } + editor.execute( this.commandName, val ); + editor.editing.view.focus(); + } ); + + return dropdownView; + } ); + } + + /** + * Returns options as defined in `config.fontColor.colors` but processed to account for + * editor localization, i.e. to display {@link module:font/fontColor~FontColorOption} + * in the correct language. + * + * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} + * when the user configuration is defined because the editor does not exist yet. + * + * @private + * @returns {Array.}. + */ + _getLocalizedOptions() { + const editor = this.editor; + const t = editor.t; + const options = normalizeOptions( editor.config.get( `${ this.componentName }.colors` ) ); + options.forEach( option => { + option.label = t( option.label ); + } ); + return options; + } +} From d2448e03b1433e534def893b345e8c3aedf2ef2d Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Thu, 21 Mar 2019 17:25:36 +0100 Subject: [PATCH 46/92] Add more docs to feature. --- src/ui/colorgrid.js | 102 ++++++++++++++++++++++++++++++++++++++------ src/ui/colortile.js | 21 ++++++++- src/ui/colorui.js | 40 ++++++++++++++--- 3 files changed, 144 insertions(+), 19 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 3fbd9d7..b38ba60 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -3,20 +3,75 @@ * For licensing, see LICENSE.md. */ +/** + * @module font/ui/colorgrid + */ + import View from '@ckeditor/ckeditor5-ui/src/view'; import ColorTile from './colortile'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; +/** + * It keeps nicely collection of {@link module:font/ui/colortile~ColorTile}. + */ export default class ColorGrid extends View { + /** + * Construct instance of color grid used to display {@link module:font/ui/colortile~ColorTile} in drop down. + * + * @param {module:utils/locale~Locale} [locale] The localization services instance. + * @param {Object} config Configuration + * @param {Array. { const colorTile = new ColorTile(); colorTile.set( { @@ -42,27 +97,20 @@ export default class ColorGrid extends View { class: 'ck-color-table__grid-container' } } ); - - this._focusCycler = new FocusCycler( { - focusables: this.items, - focusTracker: this.focusTracker, - keystrokeHandler: this.keystrokes, - actions: { - // Navigate list items backwards using the arrowup key. - focusPrevious: 'arrowleft', - - // Navigate toolbar items forwards using the arrowdown key. - focusNext: 'arrowright', - } - } ); } + /** + * Focuses the first focusable in {@link #items}. + */ focus() { if ( this.items.length ) { this.items.first.focus(); } } + /** + * Focuses the last focusable in {@link #items}. + */ focusLast() { if ( this.items.length ) { const lastChild = this.children.last; @@ -75,6 +123,9 @@ export default class ColorGrid extends View { } } + /** + * @inheritDoc + */ render() { super.render(); @@ -95,3 +146,28 @@ export default class ColorGrid extends View { this.keystrokes.listenTo( this.element ); } } + +/** + * Color definition used to build {@link module:font/ui/colortile~ColorTile}. + * + * { + * color: hsl(0, 0%, 75%), + * label: 'Light Grey', + * options: { + * hasBorder: true + * } + * } + * + * @typedef module:font/ui/colorgrid~colorsDefinition + * @type Object + * + * @property {String} color String representing inserted color. + * It's used as value of background-color style in {@link module:font/ui/colortile~ColorTile}. + * + * @property {String} label String used as label for {@link module:font/ui/colortile~ColorTile}. + * + * @property {Object} options Additional options passed to build {@link module:font/ui/colortile~ColorTile}. + * + * @property {Boolean} options.hasBorder Flag indicates if special CSS class should be added + * to {@link module:font/ui/colortile~ColorTile}, which draw border around it. + */ diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 5db0c7a..8dbf787 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -3,15 +3,34 @@ * For licensing, see LICENSE.md. */ +/** + * @module font/ui/colortile + */ + import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; +/** + * Class represents single color tile possible to click in dropdown. Element was designed + * for being used in {@link module:font/ui/colorgrid~ColorGrid}. + * + * @extends module:ui/button/buttonview~ButtonView + */ export default class ColorTile extends ButtonView { constructor( locale ) { super( locale ); - const bind = this.bindTemplate; + /** + * String representing color which will be shown as tile's background. + * @type {String} + */ this.set( 'color' ); + + /** + * Parameter which trigger adding special CSS class to button. + * This class is responsible for displaying border around button. + * @type {Boolean} + */ this.set( 'hasBorder' ); this.extendTemplate( { diff --git a/src/ui/colorui.js b/src/ui/colorui.js index a680beb..90486cb 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -4,7 +4,7 @@ */ /** - * @module font/fontcolor/fontcolorui + * @module font/ui/colorui */ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; @@ -12,17 +12,47 @@ import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { normalizeOptions, addColorsToDropdown } from '../utils'; /** - * The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown. + * The color UI plugin. It's template for creating the `'fontBackgroundColor'` and the `'fotnColor'` dropdown. + * Plugin separates common logic responsible for displaying dropdown with color grids. * * @extends module:core/plugin~Plugin */ export default class ColorUI extends Plugin { + /** + * Creates plugin which adds UI with {@link module:font/ui/colortableview~ColorTableView} with proper configuration. + * + * @param {module:core/editor/editor~Editor} editor + * @param {Object} config Configuration object + * @param {String} config.commandName Name of command which will be execute after click into selected color tile.config. + * @param {String} config.componentName Name of this component in {@link module:ui/componentfactory~ComponentFactory} + * @param {String} config.icon SVG icon used in toolbar for displaying this UI element. + * @param {String} config.dropdownLabel Label used for icon in toolbar for this element. + */ constructor( editor, { commandName, icon, componentName, dropdownLabel } ) { super( editor ); + /** + * Name of command which will be execute after click into selected color tile.config. + * @type {String} + */ this.commandName = commandName; - this.icon = icon; + + /** + * Name of this component in {@link module:ui/componentfactory~ComponentFactory}. + * @type {String} + */ this.componentName = componentName; + + /** + * SVG icon used in toolbar for displaying this UI element. + * @type {String} + */ + this.icon = icon; + + /** + * Label used for icon in toolbar for this element. + * @type {String} + */ this.dropdownLabel = dropdownLabel; } @@ -80,9 +110,9 @@ export default class ColorUI extends Plugin { } /** - * Returns options as defined in `config.fontColor.colors` but processed to account for + * Returns options as defined in `config` but processed to account for * editor localization, i.e. to display {@link module:font/fontColor~FontColorOption} - * in the correct language. + * or {@link module:font/fontBackgroundColor~FontBackgroundColorOption} in the correct language. * * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} * when the user configuration is defined because the editor does not exist yet. From d7682b388c210774e956e6cf6f6a6ed6c96d8d2f Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 22 Mar 2019 12:13:06 +0100 Subject: [PATCH 47/92] Other review part. Lots of docs improvements. Expose config with amount of columns drawed in color table dropdown. --- src/fontbackgroundcolor.js | 96 +++++++++++++ .../fontbackgroundcolorediting.js | 5 +- .../fontbackgroundcolorui.js | 4 +- src/fontcolor.js | 95 ++++++++++++ src/fontcolor/fontcolorediting.js | 5 +- src/ui/colorgrid.js | 6 +- src/ui/colortableview.js | 136 +++++++++++++++--- src/ui/colorui.js | 23 +-- src/utils.js | 38 ++++- 9 files changed, 368 insertions(+), 40 deletions(-) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index f10d611..a52d392 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -11,6 +11,15 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontBackgroundColorEditing from './fontbackgroundcolor/fontbackgroundcolorediting'; import FontBackgroundColorUI from './fontbackgroundcolor/fontbackgroundcolorui'; +/** + * The font background color plugin. + * + * This is a "glue" plugin which loads + * the {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} and + * {@link module:font/fontbackgroundcolor/fontbackgroundcolorui~FontBackgroundColorUI} features in the editor. + * + * @extends module:core/plugin~Plugin + */ export default class FontBackgroundColor extends Plugin { /** * @inheritDoc @@ -26,3 +35,90 @@ export default class FontBackgroundColor extends Plugin { return 'FontBackgroundColor'; } } + +/** + * The configuration of the font background color feature. + * This option is used by the {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} feature. + * + * ClassicEditor + * .create( { + * fontBackgroundColor: ... // Font family feature configuration. + * } ) + * .then( ... ) + * .catch( ... ); + * + * See {@link module:core/editor/editorconfig~EditorConfig all editor options}. + * + * @interface module:font/fontbackgroundcolor~FontBackgroundColorConfig + */ + +/** + * Available 'font background color' colors defined as an array of strings or objects. The default value is: + * + * const fontBackgroundColorConfig = { + * colors: [ + * { + * color: 'hsl(0, 0%, 0%)', + * label: 'Black' + * }, { + * color: 'hsl(0, 0%, 30%)', + * label: 'Dim grey' + * }, { + * color: 'hsl(0, 0%, 60%)', + * label: 'Grey' + * }, { + * color: 'hsl(0, 0%, 90%)', + * label: 'Light grey' + * }, { + * color: 'hsl(0, 0%, 100%)', + * label: 'White', + * hasBorder: true + * }, { + * color: 'hsl(0, 75%, 60%)', + * label: 'Red' + * }, { + * color: 'hsl(30, 75%, 60%)', + * label: 'Orange' + * }, { + * color: 'hsl(60, 75%, 60%)', + * label: 'Yellow' + * }, { + * color: 'hsl(90, 75%, 60%)', + * label: 'Light green' + * }, { + * color: 'hsl(120, 75%, 60%)', + * label: 'Green' + * }, { + * color: 'hsl(150, 75%, 60%)', + * label: 'Aquamarine' + * }, { + * color: 'hsl(180, 75%, 60%)', + * label: 'Turquoise' + * }, { + * color: 'hsl(210, 75%, 60%)', + * label: 'Light blue' + * }, { + * color: 'hsl(240, 75%, 60%)', + * label: 'Blue' + * }, { + * color: 'hsl(270, 75%, 60%)', + * label: 'Purple' + * } + * ] + * }; + * + * which configures 15 default colors. Each color is used in dropdown as available color to choose from dropdown. + * + * @member {Array.} module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors + */ + +/** + * Value represent amount of drawn columns in color panel. It also represent amount of visible recently used colors. + * The default value is: + * + * const fontBackgroundColorConfig = { + * columns: 5 + * } + * + * @member {Numebr} module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns + */ diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index 4652d7b..d030c8e 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -17,7 +17,7 @@ import { FONT_BACKGROUND_COLOR, renderDowncastElement, renderUpcastAttribute } f * It introduces the {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand command} and * the `fontBackgroundColor` attribute in the {@link module:engine/model/model~Model model} which renders * in the {@link module:engine/view/view view} as an inline `` element (``), - * depending on the {@link module:font/fontbackgroundcolor~FontBackgroundColortConfig configuration}. + * depending on the {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig configuration}. * * @extends module:core/plugin~Plugin */ @@ -77,7 +77,8 @@ export default class FontBackgroundColorEditing extends Plugin { color: 'hsl(270, 75%, 60%)', label: 'Purple' } - ] + ], + columns: 5 } ); editor.conversion.for( 'upcast' ).elementToAttribute( { diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 29a14d1..fbfadf9 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -4,7 +4,7 @@ */ /** - * @module font/fontcolor/fontcolorui + * @module font/fontbackgroundcolor/fontbackgroundcolorui */ import ColorUI from '../ui/colorui'; @@ -16,7 +16,7 @@ import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; * * @extends module:core/plugin~Plugin */ -export default class FontColorUI extends ColorUI { +export default class FontBackgroundColorUI extends ColorUI { constructor( editor ) { super( editor, { commandName: FONT_BACKGROUND_COLOR, diff --git a/src/fontcolor.js b/src/fontcolor.js index 18d3b1e..a56e728 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -11,6 +11,14 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontColorEditing from './fontcolor/fontcolorediting'; import FontColorUI from './fontcolor/fontcolorui'; +/** + * The font color plugin. + * + * This is a "glue" plugin which loads the {@link module:font/fontcolor/fontcolorediting~FontColorEditing} and + * {@link module:font/fontcolor/fontcolorui~FontColorUI} features in the editor. + * + * @extends module:core/plugin~Plugin + */ export default class FontColor extends Plugin { /** * @inheritDoc @@ -26,3 +34,90 @@ export default class FontColor extends Plugin { return 'FontColor'; } } + +/** + * The configuration of the font color feature. + * This option is used by the {@link module:font/fontcolor/fontcolorediting~FontColorEditing} feature. + * + * ClassicEditor + * .create( { + * fontColor: ... // Font family feature configuration. + * } ) + * .then( ... ) + * .catch( ... ); + * + * See {@link module:core/editor/editorconfig~EditorConfig all editor options}. + * + * @interface module:font/fontcolor~FontColorConfig + */ + +/** + * Available 'font color' colors defined as an array of strings or objects. The default value is: + * + * const fontColorConfig = { + * colors: [ + * { + * color: 'hsl(0, 0%, 0%)', + * label: 'Black' + * }, { + * color: 'hsl(0, 0%, 30%)', + * label: 'Dim grey' + * }, { + * color: 'hsl(0, 0%, 60%)', + * label: 'Grey' + * }, { + * color: 'hsl(0, 0%, 90%)', + * label: 'Light grey' + * }, { + * color: 'hsl(0, 0%, 100%)', + * label: 'White', + * hasBorder: true + * }, { + * color: 'hsl(0, 75%, 60%)', + * label: 'Red' + * }, { + * color: 'hsl(30, 75%, 60%)', + * label: 'Orange' + * }, { + * color: 'hsl(60, 75%, 60%)', + * label: 'Yellow' + * }, { + * color: 'hsl(90, 75%, 60%)', + * label: 'Light green' + * }, { + * color: 'hsl(120, 75%, 60%)', + * label: 'Green' + * }, { + * color: 'hsl(150, 75%, 60%)', + * label: 'Aquamarine' + * }, { + * color: 'hsl(180, 75%, 60%)', + * label: 'Turquoise' + * }, { + * color: 'hsl(210, 75%, 60%)', + * label: 'Light blue' + * }, { + * color: 'hsl(240, 75%, 60%)', + * label: 'Blue' + * }, { + * color: 'hsl(270, 75%, 60%)', + * label: 'Purple' + * } + * ] + * }; + * + * which configures 15 default colors. Each color is used in dropdown as available color to choose from dropdown. + * + * @member {Array.} module:font/fontcolor~FontColorConfig#colors + */ + +/** + * Value represent amount of drawn columns in color panel. It also represents amount of visible recently used colors. + * The default value is: + * + * const fontColorConfig = { + * columns: 5 + * } + * + * @member {Numebr} module:font/fontcolor~FontColorConfig#columns + */ diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index ebb39ec..d62a98f 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -17,7 +17,7 @@ import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from '../uti * It introduces the {@link module:font/fontcolor/fontcolorcommand~FontColorCommand command} and * the `fontColor` attribute in the {@link module:engine/model/model~Model model} which renders * in the {@link module:engine/view/view view} as an inline `` element (``), - * depending on the {@link module:font/fontcolor~FontColortConfig configuration}. + * depending on the {@link module:font/fontcolor~FontColorConfig configuration}. * * @extends module:core/plugin~Plugin */ @@ -77,7 +77,8 @@ export default class FontColorEditing extends Plugin { color: 'hsl(270, 75%, 60%)', label: 'Purple' } - ] + ], + columns: 5 } ); editor.conversion.for( 'upcast' ).elementToAttribute( { diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index b38ba60..0598c41 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -15,6 +15,8 @@ import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; /** * It keeps nicely collection of {@link module:font/ui/colortile~ColorTile}. + * + * @extends module:ui/view~View */ export default class ColorGrid extends View { /** @@ -22,7 +24,7 @@ export default class ColorGrid extends View { * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} config Configuration - * @param {Array.} colorsDefinition Array with definitions * required to build {@link module:font/ui/colortile~ColorTile}. */ constructor( locale, { colorsDefinition = [] } = {} ) { @@ -158,7 +160,7 @@ export default class ColorGrid extends View { * } * } * - * @typedef module:font/ui/colorgrid~colorsDefinition + * @typedef {Object} module:font/ui/colorgrid~ColorDefinition * @type Object * * @property {String} color String representing inserted color. diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 7e9e760..e4fb332 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -3,6 +3,10 @@ * For licensing, see LICENSE.md. */ +/** + * @module font/ui/colortableview + */ + import View from '@ckeditor/ckeditor5-ui/src/view'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; import ColorTile from './colortile'; @@ -14,35 +18,87 @@ import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; +/** + * Class which represents view with {@link module:font/ui/colorgrid~ColorGrid} + * and remove buttons inside {@link module:ui/dropdown/dropdownview~DropdownView}. + * + * @extends module:ui/view~View + */ export default class ColorTableView extends View { - constructor( locale, { colors } ) { + /** + * Construct view which will be inserted as child of {@link module:ui/dropdown/dropdownview~DropdownView} + * @param {module:utils/locale~Locale} [locale] The localization services instance. + * @param {Object} config Configuration object + * @param {Array.} config.colors Array with objects drawn as static set of available colors in color table. + * @param {Number} config.colorColumns Number of columns in color grid. Determines how many recent color will be displayed. + * @param {String} config.removeButtonTooltip Description of button responsible for removing color attributes. + */ + constructor( locale, { colors, colorColumns, removeButtonTooltip } ) { super( locale ); - this.locale = locale; + + /** + * Collection of the child list views. + * + * @readonly + * @member {module:ui/viewcollection~ViewCollection} + */ this.items = this.createCollection(); + /** + * Array with objects representing color to be drawn in color grid. + * @type {Arrray.} + */ this.colorsDefinition = colors; + + /** + * Tracks information about DOM focus in the list. + * + * @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(); + /** + * Keeps value of command for current selection. + * @type {String} + */ this.set( 'selectedColor' ); - this.set( 'removeButtonTooltip' ); - this.set( 'colorColumns', 5 ); - this.set( 'recentlyUsedColors', new Collection() ); - - this.initRecentCollection(); - - this.setTemplate( { - tag: 'div', - attributes: { - class: [ 'ck-color-table' ] - }, - children: this.items - } ); - - this.items.add( this.removeColorButton() ); - this.items.add( this.createColorTableTemplate() ); - this.items.add( this.recentlyUsed() ); + /** + * Description of button responsible for removing color attributes. + * @type {String} + */ + this.removeButtonTooltip = removeButtonTooltip; + + /** + * Number of columns in color grid. Determines how many recent color will be displayed. + * @type {Number} + */ + this.colorColumns = colorColumns; + + /** + * Collection kept model of colors used for Recent Colors section. + * + * @readonly + * @member {module:utils/collection~Collection} + */ + this.recentlyUsedColors = new Collection(); + + /** + * Helps cycling over focusable {@link #items} in the list. + * + * @readonly + * @protected + * @member {module:ui/focuscycler~FocusCycler} + */ this._focusCycler = new FocusCycler( { focusables: this.items, focusTracker: this.focusTracker, @@ -55,16 +111,34 @@ export default class ColorTableView extends View { focusNext: 'arrowdown', } } ); + + this.initRecentCollection(); + this.setTemplate( { + tag: 'div', + attributes: { + class: [ 'ck-color-table' ] + }, + children: this.items + } ); + + this.items.add( this.removeColorButton() ); + this.items.add( this.createStaticColorTable() ); + this.items.add( this.recentlyUsed() ); } + /** + * Adds remove color button as child for current view. + * + * @private + */ removeColorButton() { const btnView = new ButtonView(); btnView.set( { withText: true, icon: removeButtonIcon, - tooltip: true + tooltip: true, + label: this.removeButtonTooltip } ); - btnView.bind( 'label' ).to( this, 'removeButtonTooltip' ); btnView.class = 'ck-color-table__remove-color'; btnView.on( 'execute', () => { this.fire( 'execute', { value: null } ); @@ -72,12 +146,20 @@ export default class ColorTableView extends View { return btnView; } - createColorTableTemplate() { + /** + * Creates static color table grid based on editor config. + * @private + */ + createStaticColorTable() { const colorGrid = new ColorGrid( this.locale, { colorsDefinition: this.colorsDefinition } ); colorGrid.delegate( 'execute' ).to( this ); return colorGrid; } + /** + * Adds recently used color section view and bind it to {@link #recentlyUsedColors}. + * @private + */ recentlyUsed() { const recentViews = new ColorGrid( this.locale ); @@ -118,6 +200,10 @@ export default class ColorTableView extends View { return recentViews; } + /** + * Populate {@link #recentlyUsedColors} with empty non-clickable buttons, which represents space for colors. + * @private + */ initRecentCollection() { for ( let i = 0; i < this.colorColumns; i++ ) { this.recentlyUsedColors.add( { @@ -151,10 +237,16 @@ export default class ColorTableView extends View { 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(); } diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 90486cb..7532819 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -54,6 +54,12 @@ export default class ColorUI extends Plugin { * @type {String} */ this.dropdownLabel = dropdownLabel; + + /** + * Number of columns in color grid. Determines how many recent color will be displayed. + * @type {Number} + */ + this.colorColumns = editor.config.get( `${ this.componentName }.columns` ); } /** @@ -69,17 +75,18 @@ export default class ColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( this.componentName, locale => { const dropdownView = createDropdown( locale ); - const colorTableView = addColorsToDropdown( + const colorTableView = addColorsToDropdown( { dropdownView, - options.map( element => ( { + colors: options.map( element => ( { label: element.label, color: element.model, options: { hasBorder: element.hasBorder } - } ) ) - ); - colorTableView.set( 'removeButtonTooltip', t( 'Remove color' ) ); + } ) ), + colorColumns: this.colorColumns, + removeButtonTooltip: t( 'Remove color' ) + } ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); @@ -111,14 +118,14 @@ export default class ColorUI extends Plugin { /** * Returns options as defined in `config` but processed to account for - * editor localization, i.e. to display {@link module:font/fontColor~FontColorOption} - * or {@link module:font/fontBackgroundColor~FontBackgroundColorOption} in the correct language. + * editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} + * or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig} in the correct language. * * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} * when the user configuration is defined because the editor does not exist yet. * * @private - * @returns {Array.}. + * @returns {Array.|Array.}. */ _getLocalizedOptions() { const editor = this.editor; diff --git a/src/utils.js b/src/utils.js index 0954edb..dbd3741 100644 --- a/src/utils.js +++ b/src/utils.js @@ -38,9 +38,23 @@ export function buildDefinition( modelAttributeKey, options ) { return definition; } +/** + * Name of font color plugin + */ export const FONT_COLOR = 'fontColor'; + +/** + * Name of font background color plugin. + */ export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; +/** + * Function for font color and font background color plugins + * which is responsible for upcasting data to model. + * styleAttr should eqaul to `'color'` or `'background-color'`. + * + * @param {String} styleAttr + */ export function renderUpcastAttribute( styleAttr ) { return viewElement => { const fontColor = viewElement.getStyle( styleAttr ); @@ -48,6 +62,13 @@ export function renderUpcastAttribute( styleAttr ) { }; } +/** + * Function for font color and font background color plugins + * which is responsible for downcasting color attribute to span element. + * styleAttr should eqaul to `'color'` or `'background-color'`. + * + * @param {String} styleAttr + */ export function renderDowncastElement( styleAttr ) { return ( modelAttributeValue, viewWriter ) => viewWriter.createAttributeElement( 'span', { style: `${ styleAttr }:${ modelAttributeValue }` @@ -58,6 +79,12 @@ function normalizeColorCode( value ) { return value.replace( /\s/g, '' ); } +/** + * Creates model of color from configuration option. It keeps them coherent, + * regardles how user define them in config. + * + * @param {String|Object} colorRow + */ export function normalizeOptions( colorRow ) { return colorRow .map( getColorsDefinition ) @@ -93,9 +120,16 @@ function getColorsDefinition( color ) { } } -export function addColorsToDropdown( dropdownView, colors ) { +/** + * Helper which add {@link module:font/ui/colortableview~ColorTableView} to dropdown with proper initial values. + * @param {Object} config Configuration object + * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which + * will be added {@link module:font/ui/colortableview~ColorTableView}. + * @param {Array.} Array with objects representing color to be drawn in color grid. + */ +export function addColorsToDropdown( { dropdownView, colors, colorColumns, removeButtonTooltip } ) { const locale = dropdownView.locale; - const colorTableView = new ColorTableView( locale, { colors } ); + const colorTableView = new ColorTableView( locale, { colors, colorColumns, removeButtonTooltip } ); dropdownView.colorTableView = colorTableView; dropdownView.panelView.children.add( colorTableView ); From 15fbb63ffad4aff126d821ecaa7cdf239a4d7815 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 22 Mar 2019 12:36:27 +0100 Subject: [PATCH 48/92] Few small fixes. --- src/utils.js | 4 ++-- theme/fontcolor.css | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/utils.js b/src/utils.js index dbd3741..d7b658b 100644 --- a/src/utils.js +++ b/src/utils.js @@ -87,11 +87,11 @@ function normalizeColorCode( value ) { */ export function normalizeOptions( colorRow ) { return colorRow - .map( getColorsDefinition ) + .map( normalizeSingleColorDefinition ) .filter( option => !!option ); } -function getColorsDefinition( color ) { +function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { model: color, diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 3eec924..ffaa9f9 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -25,7 +25,6 @@ min-width: var(--ck-table-color-tile-size); min-height: var(--ck-table-color-tile-size); border-radius: var(--ck-border-radius); - cursor: pointer; transition: 200ms ease box-shadow; } @@ -55,7 +54,3 @@ width: var(--ck-table-color-tile-size); margin-right: var(--ck-spacing-large); } - -.ck .ck-color-table__remove-color { - cursor: pointer; -} From 71de300970fa303e416376ec4c28002d906b950f Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 22 Mar 2019 13:48:37 +0100 Subject: [PATCH 49/92] Add some base unit test. --- .../fontbackgroundcoloreditng.js | 237 ++++++++++++++++++ .../fontbackgroundcolorui.js | 13 + tests/fontcolor/fontcolorediting.js | 1 + tests/fontcolor/fontcolorui.js | 183 +------------- 4 files changed, 255 insertions(+), 179 deletions(-) create mode 100644 tests/fontbackgroundcolor/fontbackgroundcoloreditng.js create mode 100644 tests/fontbackgroundcolor/fontbackgroundcolorui.js diff --git a/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js new file mode 100644 index 0000000..150f5f3 --- /dev/null +++ b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js @@ -0,0 +1,237 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontBackgroundColorEditing from './../../src/fontbackgroundcolor/fontbackgroundcolorediting'; + +import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; + +import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; +import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; + +describe( 'FontBackgroundColorEditing', () => { + let editor, doc; + + beforeEach( () => VirtualTestEditor + .create( { + plugins: [ FontBackgroundColorEditing, Paragraph ] + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.document; + } ) + ); + + afterEach( () => { + editor.destroy(); + } ); + + it( 'should set proper schema rules', () => { + expect( editor.model.schema.checkAttribute( [ '$block', '$text' ], 'fontBackgroundColor' ) ).to.be.true; + expect( editor.model.schema.checkAttribute( [ '$clipboardHolder', '$text' ], 'fontBackgroundColor' ) ).to.be.true; + + expect( editor.model.schema.checkAttribute( [ '$block' ], 'fontBackgroundColor' ) ).to.be.false; + } ); + + describe( 'config', () => { + describe( 'default value', () => { + it( 'should be set', () => { + expect( editor.config.get( 'fontBackgroundColor.colors' ) ).to.deep.equal( [ + { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, { + color: 'hsl(0, 0%, 100%)', + label: 'White', + hasBorder: true + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, { + color: 'hsl(150, 75%, 60%)', + label: 'Aquamarine' + }, { + color: 'hsl(180, 75%, 60%)', + label: 'Turquoise' + }, { + color: 'hsl(210, 75%, 60%)', + label: 'Light blue' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Blue' + }, { + color: 'hsl(270, 75%, 60%)', + label: 'Purple' + } + ] ); + expect( editor.config.get( 'fontBackgroundColor.columns' ) ).to.equal( 5 ); + } ); + } ); + } ); + + describe( 'editing pipeline conversion', () => { + beforeEach( () => VirtualTestEditor + .create( { + plugins: [ FontBackgroundColorEditing, Paragraph ], + fontBackgroundColor: { + colors: [ + { + label: 'Color1', + color: '#000' + }, { + label: 'Color2', + color: '#123456' + }, { + label: 'Color3', + color: 'rgb( 0, 10, 20 )' + }, + 'hsl( 200,100%,50%)', + { + label: 'Color5 - Light Green', + color: 'lightgreen' + } + ] + } + } ) + .then( newEditor => { + editor = newEditor; + doc = editor.model; + } ) + ); + + describe( 'convert different color version', () => { + const tests = [ + '#000', + 'green', + 'rgb( 0, 10, 20 )', + 'rgba( 20, 30, 50, 0.4)', + 'hsl( 10, 20%, 30%)', + 'hsla( 300, 50%, 100%, .3)', + 'rgb( 20%, 30%, 40% )', + '#345678' + ]; + tests.forEach( test => { + it( `should convert fontBackgroundColor attribute: "${ test }" to proper style value.`, () => { + setModelData( doc, `fo<$text fontBackgroundColor="${ test }">o bar` ); + + expect( editor.getData() ).to.equal( `

foo bar

` ); + } ); + } ); + } ); + } ); + + describe( 'data pipeline conversions', () => { + beforeEach( () => { + return VirtualTestEditor + .create( { + plugins: [ FontBackgroundColorEditing, Paragraph ], + fontBackgroundColor: { + colors: [ + { + label: 'Color1', + color: '#000' + }, { + label: 'Color2', + color: '#123456' + }, { + label: 'Color3', + color: 'rgb( 0, 10, 20 )' + }, + 'hsl( 200,100%,50%)', + { + label: 'Color5 - Light Green', + color: 'lightgreen' + } + ] + } + } ) + .then( newEditor => { + editor = newEditor; + + doc = editor.model; + } ); + } ); + + it( 'should convert from element with defined style when with other styles', () => { + const data = '

foo

'; + + editor.setData( data ); + + expect( getModelData( doc ) ).to.equal( '[]f<$text fontBackgroundColor="rgb(10,20,30)">oo' ); + + expect( editor.getData() ).to.equal( '

foo

' ); + } ); + + describe( 'should convert from different color versions', () => { + const tests = [ + '#000', + 'green', + 'rgb( 0, 10, 20 )', + 'rgba( 20, 30, 50, 0.4)', + 'hsl( 10, 20%, 30%)', + 'hsla( 300, 50%, 100%, .3)', + 'rgb( 20%, 30%, 40% )', + '#345678' + ]; + + tests.forEach( test => { + it( `should convert fontBackgroundColor attribute: "${ test }" to proper style value.`, () => { + const data = `

foo

`; + editor.setData( data ); + + expect( getModelData( doc ) ) + .to.equal( `[]f<$text fontBackgroundColor="${ test.replace( / /g, '' ) }">oo` ); + + expect( editor.getData() ) + .to.equal( `

foo

` ); + } ); + } ); + } ); + + it( 'should convert from complex definition', () => { + editor.setData( + '

foo

' + + '

foo

' + + '

bar

' + + '

baz

' + ); + + expect( getModelData( doc ) ).to.equal( + '[]f<$text fontBackgroundColor="lightgreen">oo' + + 'f<$text fontBackgroundColor="hsl(200,100%,50%)">oo' + + 'b<$text fontBackgroundColor="rgba(1,2,3,.4)">ar' + + 'b<$text fontBackgroundColor="#fff">az' + ); + + expect( editor.getData() ).to.equal( + '

foo

' + + '

foo

' + + '

bar

' + + '

baz

' + ); + } ); + } ); +} ); diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorui.js b/tests/fontbackgroundcolor/fontbackgroundcolorui.js new file mode 100644 index 0000000..3479956 --- /dev/null +++ b/tests/fontbackgroundcolor/fontbackgroundcolorui.js @@ -0,0 +1,13 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import FontBackgroundColorUI from './../../src/fontbackgroundcolor/fontbackgroundcolorui'; +import ColorUI from './../../src/ui/colorui'; + +describe( 'FontBackgroundColorUI', () => { + it( 'is ColorUI', () => { + expect( FontBackgroundColorUI.prototype ).to.be.instanceOf( ColorUI ); + } ); +} ); diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index b4c7d64..a32263c 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -87,6 +87,7 @@ describe( 'FontColorEditing', () => { label: 'Purple' } ] ); + expect( editor.config.get( 'fontColor.columns' ) ).to.equal( 5 ); } ); } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 02a4f1a..c76bf60 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -3,186 +3,11 @@ * For licensing, see LICENSE.md. */ -/* global document */ - -import FontColorEditing from '../../src/fontcolor/fontcolorediting'; -import FontColorUI from '../../src/fontcolor/fontcolorui'; - -import fontColorIcon from '../../theme/icons/font-color.svg'; - -import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; -import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; -import { add as addTranslations, _clear as clearTranslations } from '@ckeditor/ckeditor5-utils/src/translation-service'; +import FontColorUI from './../../src/fontcolor/fontcolorui'; +import ColorUI from './../../src/ui/colorui'; describe( 'FontColorUI', () => { - let editor, command, element; - - testUtils.createSinonSandbox(); - - before( () => { - addTranslations( 'en', { - 'Font Color': 'Font Color', - 'Remove color': 'Remove text color', - 'Black': 'Black', - 'White': 'White', - 'Red': 'Red', - 'Orange': 'Orange', - 'Blue': 'Blue', - 'Green': 'Green' - } ); - - addTranslations( 'pl', { - 'Font Color': 'Kolor czcionki', - 'Remove color': 'Usuń kolor', - 'Black': 'Czarny', - 'White': 'Biały', - 'Red': 'Czerwony', - 'Orange': 'Pomarańczowy', - 'Blue': 'Niebieski', - 'Green': 'Zielony', - 'Yellow': 'Żółty' - } ); - } ); - - after( () => { - clearTranslations(); - } ); - - beforeEach( () => { - element = document.createElement( 'div' ); - document.body.appendChild( element ); - - return ClassicTestEditor - .create( element, { - plugins: [ FontColorEditing, FontColorUI ] - } ) - .then( newEditor => { - editor = newEditor; - } ); - } ); - - afterEach( () => { - element.remove(); - - return editor.destroy(); - } ); - - describe( 'fontColor Dropdown', () => { - let dropdown; - - beforeEach( () => { - command = editor.commands.get( 'fontColor' ); - dropdown = editor.ui.componentFactory.create( 'fontColor' ); - } ); - - it( 'button has the base properties', () => { - const button = dropdown.buttonView; - - expect( button ).to.have.property( 'label', 'Font Color' ); - expect( button ).to.have.property( 'tooltip', true ); - expect( button ).to.have.property( 'icon', fontColorIcon ); - } ); - - it( 'should add custom CSS class to dropdown', () => { - const dropdown = editor.ui.componentFactory.create( 'fontColor' ); - - dropdown.render(); - - expect( dropdown.element.classList.contains( 'ck-font-color-dropdown' ) ).to.be.true; - } ); - - it( 'should focus view after command execution from dropdown', () => { - const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); - const dropdown = editor.ui.componentFactory.create( 'fontColor' ); - - dropdown.commandName = 'fontColor'; - dropdown.fire( 'execute', { value: null } ); - - sinon.assert.calledOnce( focusSpy ); - } ); - - describe( 'model to command binding', () => { - it( 'isEnabled', () => { - command.isEnabled = false; - - expect( dropdown.buttonView.isEnabled ).to.be.false; - - command.isEnabled = true; - expect( dropdown.buttonView.isEnabled ).to.be.true; - } ); - } ); - - describe( 'localization', () => { - beforeEach( () => { - return localizedEditor(); - } ); - - it( 'works for the #buttonView', () => { - const buttonView = dropdown.buttonView; - - expect( buttonView.label ).to.equal( 'Kolor czcionki' ); - } ); - - it( 'works for the colorTableView#items in the panel', () => { - const colorTableView = dropdown.colorTableView; - expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor' ); - expect( colorTableView.items.first.label ).to.equal( 'Usuń kolor' ); - } ); - - describe( 'works for', () => { - const colors = [ - { - color: 'hsl(0, 0%, 0%)', - label: 'Czarny' - }, { - color: 'hsl(0, 0%, 100%)', - label: 'Biały' - }, { - color: 'hsl(0, 75%, 60%)', - label: 'Czerwony' - }, { - color: 'hsl(30, 75%, 60%)', - label: 'Pomarańczowy' - }, { - color: 'hsl(240, 75%, 60%)', - label: 'Niebieski' - }, { - color: 'hsl(120, 75%, 60%)', - label: 'Zielony' - }, { - color: 'hsl(60, 75%, 60%)', - label: 'Żółty' - } - ]; - - colors.forEach( test => { - it( `tested color ${ test.color } with name ${ test.label }.`, () => { - const colorGrid = dropdown.colorTableView.items.get( 1 ); - const tile = colorGrid.items.find( colorTile => test.color === colorTile.color ); - expect( tile.label ).to.equal( test.label ); - } ); - } ); - } ); - function localizedEditor() { - const editorElement = document.createElement( 'div' ); - document.body.appendChild( editorElement ); - - return ClassicTestEditor - .create( editorElement, { - plugins: [ FontColorEditing, FontColorUI ], - toolbar: [ 'fontColor' ], - language: 'pl', - } ) - .then( newEditor => { - editor = newEditor; - dropdown = editor.ui.componentFactory.create( 'fontColor' ); - command = editor.commands.get( 'fontColor' ); - - editorElement.remove(); - - return editor.destroy(); - } ); - } - } ); + it( 'is ColorUI', () => { + expect( FontColorUI.prototype ).to.be.instanceOf( ColorUI ); } ); } ); From 7e554d9d0f4bd8e792c232aea0d552e42edfb052 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 22 Mar 2019 17:41:18 +0100 Subject: [PATCH 50/92] Add bunch of unit tests. --- .../fontbackgroundcolorui.js | 7 + src/fontcolor/fontcolorui.js | 7 + src/utils.js | 3 +- .../fontbackgroundcolorui.js | 40 +++++- tests/fontcolor/fontcolorui.js | 38 ++++++ tests/ui/colortile.js | 30 +++++ tests/utils.js | 126 ++++++++++++++++++ 7 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 tests/ui/colortile.js create mode 100644 tests/utils.js diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index fbfadf9..d20277a 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -25,4 +25,11 @@ export default class FontBackgroundColorUI extends ColorUI { dropdownLabel: 'Font Background Color' } ); } + + /** + * @inheritDoc + */ + static get pluginName() { + return 'FontBackgroundColorUI'; + } } diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 4d3611d..5f927c4 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -25,4 +25,11 @@ export default class FontColorUI extends ColorUI { dropdownLabel: 'Font Color' } ); } + + /** + * @inheritDoc + */ + static get pluginName() { + return 'FontColorUI'; + } } diff --git a/src/utils.js b/src/utils.js index d7b658b..465e20a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -96,6 +96,7 @@ function normalizeSingleColorDefinition( color ) { return { model: color, label: color, + hasBorder: false, view: { name: 'span', styles: { @@ -108,7 +109,7 @@ function normalizeSingleColorDefinition( color ) { return { model: color.color, label: color.label || color.color, - hasBorder: color.hasBorder, + hasBorder: color.hasBorder === undefined ? false : color.hasBorder, view: { name: 'span', styles: { diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorui.js b/tests/fontbackgroundcolor/fontbackgroundcolorui.js index 3479956..162236f 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/tests/fontbackgroundcolor/fontbackgroundcolorui.js @@ -3,11 +3,49 @@ * For licensing, see LICENSE.md. */ +/* global document */ + +import FontBackgroundColorEditing from './../../src/fontbackgroundcolor/fontbackgroundcolorediting'; import FontBackgroundColorUI from './../../src/fontbackgroundcolor/fontbackgroundcolorui'; import ColorUI from './../../src/ui/colorui'; -describe( 'FontBackgroundColorUI', () => { +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; + +import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; + +describe( 'FontBckgroundColorUI', () => { + let element, editor; + + beforeEach( () => { + element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ FontBackgroundColorEditing, FontBackgroundColorUI ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); + + afterEach( () => { + element.remove(); + + return editor.destroy(); + } ); + it( 'is ColorUI', () => { expect( FontBackgroundColorUI.prototype ).to.be.instanceOf( ColorUI ); } ); + + it( 'has properly set initial values', () => { + const fontBackgroundColorUIPlugin = editor.plugins.get( 'FontBackgroundColorUI' ); + + expect( fontBackgroundColorUIPlugin.commandName ).to.equal( 'fontBackgroundColor' ); + expect( fontBackgroundColorUIPlugin.componentName ).to.equal( 'fontBackgroundColor' ); + expect( fontBackgroundColorUIPlugin.icon ).to.equal( fontBackgroundColorIcon ); + expect( fontBackgroundColorUIPlugin.dropdownLabel ).to.equal( 'Font Background Color' ); + expect( fontBackgroundColorUIPlugin.colorColumns ).to.equal( 5 ); + } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index c76bf60..88bf0b5 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -3,11 +3,49 @@ * For licensing, see LICENSE.md. */ +/* global document */ + +import FontColorEditing from './../../src/fontcolor/fontcolorediting'; import FontColorUI from './../../src/fontcolor/fontcolorui'; import ColorUI from './../../src/ui/colorui'; +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; + +import fontColorIcon from '../../theme/icons/font-color.svg'; + describe( 'FontColorUI', () => { + let element, editor; + + beforeEach( () => { + element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ FontColorEditing, FontColorUI ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); + + afterEach( () => { + element.remove(); + + return editor.destroy(); + } ); + it( 'is ColorUI', () => { expect( FontColorUI.prototype ).to.be.instanceOf( ColorUI ); } ); + + it( 'has properly set initial values', () => { + const fontColorUIPlugin = editor.plugins.get( 'FontColorUI' ); + + expect( fontColorUIPlugin.commandName ).to.equal( 'fontColor' ); + expect( fontColorUIPlugin.componentName ).to.equal( 'fontColor' ); + expect( fontColorUIPlugin.icon ).to.equal( fontColorIcon ); + expect( fontColorUIPlugin.dropdownLabel ).to.equal( 'Font Color' ); + expect( fontColorUIPlugin.colorColumns ).to.equal( 5 ); + } ); } ); diff --git a/tests/ui/colortile.js b/tests/ui/colortile.js new file mode 100644 index 0000000..3bb5d70 --- /dev/null +++ b/tests/ui/colortile.js @@ -0,0 +1,30 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import ColorTile from './../../src/ui/colortile'; +import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; + +describe( 'ColorTile', () => { + it( 'inhertence from ButtonView', () => { + const colorTile = new ColorTile(); + expect( colorTile ).to.be.instanceOf( ButtonView ); + } ); + + it( 'has proper attributes and classes', () => { + const colorTile = new ColorTile(); + colorTile.render(); + expect( colorTile.color ).to.be.undefined; + expect( colorTile.hasBorder ).to.be.undefined; + + colorTile.set( 'color', 'green' ); + expect( colorTile.color ).to.equal( 'green' ); + expect( colorTile.element.style.backgroundColor ).to.equal( 'green' ); + expect( colorTile.element.classList.contains( 'ck-color-table__color-tile' ) ).to.be.true; + expect( colorTile.element.classList.contains( 'ck-color-table__color-tile_bordered' ) ).to.be.false; + + colorTile.set( 'hasBorder', true ); + expect( colorTile.element.classList.contains( 'ck-color-table__color-tile_bordered' ) ).to.be.true; + } ); +} ); diff --git a/tests/utils.js b/tests/utils.js new file mode 100644 index 0000000..bb865d2 --- /dev/null +++ b/tests/utils.js @@ -0,0 +1,126 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { FONT_COLOR, FONT_BACKGROUND_COLOR, normalizeOptions, addColorsToDropdown } from './../src/utils'; +import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; +import ColorTableView from './../src/ui/colortableview'; + +describe( 'utils', () => { + describe( 'color and background color related', () => { + it( 'plugin names has proper values', () => { + expect( FONT_COLOR ).to.equal( 'fontColor' ); + expect( FONT_BACKGROUND_COLOR ).to.equal( 'fontBackgroundColor' ); + } ); + + it( 'normalizeOptions can produce the same output object', () => { + const normalizedArray = normalizeOptions( [ + 'black', + { + color: 'black' + }, { + color: 'black', + label: 'Black' + }, { + color: 'black', + label: 'Black', + hasBorder: true + }, { + color: 'black', + hasBorder: true + } + ] ); + + expect( normalizedArray ).to.deep.equal( [ + { + model: 'black', + label: 'black', + hasBorder: false, + view: { + name: 'span', + styles: { + color: 'black' + }, + priority: 5 + } + }, { + model: 'black', + label: 'black', + hasBorder: false, + view: { + name: 'span', + styles: { + color: 'black' + }, + priority: 5 + } + }, { + model: 'black', + label: 'Black', + hasBorder: false, + view: { + name: 'span', + styles: { + color: 'black' + }, + priority: 5 + } + }, + { + model: 'black', + label: 'Black', + hasBorder: true, + view: { + name: 'span', + styles: { + color: 'black' + }, + priority: 5 + } + }, + { + model: 'black', + label: 'black', + hasBorder: true, + view: { + name: 'span', + styles: { + color: 'black' + }, + priority: 5 + } + }, + ] ); + } ); + + it( 'adding colors table to dropdown works', () => { + const dropdown = createDropdown(); + dropdown.render(); + + addColorsToDropdown( { + dropdownView: dropdown, + colors: [ + { + label: 'Black', + color: '#000', + options: { + hasBorder: false + } + }, { + label: 'White', + color: '#FFFFFF', + options: { + hasBorder: true + } + } + ], + colorColumns: 2, + removeButtonTooltip: 'Remove Color' + } ); + + expect( dropdown.colorTableView ).to.be.instanceOf( ColorTableView ); + expect( dropdown.panelView.children.length ).to.equal( 1 ); + } ); + } ); +} ); From 53b40d9c9c4407d4680dc6f281ab82d26a22db90 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Fri, 22 Mar 2019 17:41:52 +0100 Subject: [PATCH 51/92] Add another part of test (requires improvements). --- tests/ui/colorgrid.js | 75 +++++++++++++++++ tests/ui/colorui.js | 188 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 tests/ui/colorgrid.js create mode 100644 tests/ui/colorui.js diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js new file mode 100644 index 0000000..659a91a --- /dev/null +++ b/tests/ui/colorgrid.js @@ -0,0 +1,75 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import ColorGrid from './../../src/ui/colorgrid'; +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 ColorTile from '../../src/ui/colortile'; + +describe( 'ColorGrid', () => { + const colorDefinition = [ + { + color: '#000', + label: 'Black', + options: { + hasBorder: false + } + }, { + color: 'rgb(255, 255, 255)', + label: 'White', + options: { + hasBorder: true + } + }, { + color: 'red', + label: 'Red', + options: { + hasBorder: false + } + } + ]; + + let locale, colorGrid; + beforeEach( () => { + locale = { t() {} }; + colorGrid = new ColorGrid( locale, colorDefinition ); + colorGrid.render(); + } ); + + describe( 'constructor()', () => { + it( 'creates view collection with children', () => { + expect( colorGrid.items ).to.be.instanceOf( ViewCollection ); + } ); + + it( 'creates focus tracker', () => { + expect( colorGrid.focusTracker ).to.be.instanceOf( FocusTracker ); + } ); + + it( 'creates keystroke handler', () => { + expect( colorGrid.keystrokes ).to.be.instanceOf( KeystrokeHandler ); + } ); + + it( 'creates focus cycler', () => { + expect( colorGrid._focusCycler ).to.be.instanceOf( FocusCycler ); + } ); + + describe( 'add colors from definition as child items', () => { + it( 'has proper number of elements', () => { + expect( colorGrid.items.length ).to.equal( 3 ); + } ); + colorDefinition.forEach( ( color, index ) => { + describe( 'child items has proper attributes', () => { + it( `for ${ index } child`, () => { + const colorTile = colorGrid.items.get( index ); + expect( colorTile ).to.be.instanceOf( ColorTile ); + expect( colorTile.color ).to.equal( color.color ); + } ); + } ); + } ); + } ); + } ); +} ); diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js new file mode 100644 index 0000000..7df6e34 --- /dev/null +++ b/tests/ui/colorui.js @@ -0,0 +1,188 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* global document */ + +import FontColorEditing from '../../src/fontcolor/fontcolorediting'; +import FontColorUI from '../../src/fontcolor/fontcolorui'; + +import fontColorIcon from '../../theme/icons/font-color.svg'; + +import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; +import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; +import { add as addTranslations, _clear as clearTranslations } from '@ckeditor/ckeditor5-utils/src/translation-service'; + +describe.skip( 'ColorUI', () => { + let editor, command, element; + + testUtils.createSinonSandbox(); + + before( () => { + addTranslations( 'en', { + 'Font Color': 'Font Color', + 'Remove color': 'Remove text color', + 'Black': 'Black', + 'White': 'White', + 'Red': 'Red', + 'Orange': 'Orange', + 'Blue': 'Blue', + 'Green': 'Green' + } ); + + addTranslations( 'pl', { + 'Font Color': 'Kolor czcionki', + 'Remove color': 'Usuń kolor', + 'Black': 'Czarny', + 'White': 'Biały', + 'Red': 'Czerwony', + 'Orange': 'Pomarańczowy', + 'Blue': 'Niebieski', + 'Green': 'Zielony', + 'Yellow': 'Żółty' + } ); + } ); + + after( () => { + clearTranslations(); + } ); + + beforeEach( () => { + element = document.createElement( 'div' ); + document.body.appendChild( element ); + + return ClassicTestEditor + .create( element, { + plugins: [ FontColorEditing, FontColorUI ] + } ) + .then( newEditor => { + editor = newEditor; + } ); + } ); + + afterEach( () => { + element.remove(); + + return editor.destroy(); + } ); + + describe( 'fontColor Dropdown', () => { + let dropdown; + + beforeEach( () => { + command = editor.commands.get( 'fontColor' ); + dropdown = editor.ui.componentFactory.create( 'fontColor' ); + } ); + + it( 'button has the base properties', () => { + const button = dropdown.buttonView; + + expect( button ).to.have.property( 'label', 'Font Color' ); + expect( button ).to.have.property( 'tooltip', true ); + expect( button ).to.have.property( 'icon', fontColorIcon ); + } ); + + it( 'should add custom CSS class to dropdown', () => { + const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + + dropdown.render(); + + expect( dropdown.element.classList.contains( 'ck-font-color-dropdown' ) ).to.be.true; + } ); + + it( 'should focus view after command execution from dropdown', () => { + const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); + const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + + dropdown.commandName = 'fontColor'; + dropdown.fire( 'execute', { value: null } ); + + sinon.assert.calledOnce( focusSpy ); + } ); + + describe( 'model to command binding', () => { + it( 'isEnabled', () => { + command.isEnabled = false; + + expect( dropdown.buttonView.isEnabled ).to.be.false; + + command.isEnabled = true; + expect( dropdown.buttonView.isEnabled ).to.be.true; + } ); + } ); + + describe( 'localization', () => { + beforeEach( () => { + return localizedEditor(); + } ); + + it( 'works for the #buttonView', () => { + const buttonView = dropdown.buttonView; + + expect( buttonView.label ).to.equal( 'Kolor czcionki' ); + } ); + + it( 'works for the colorTableView#items in the panel', () => { + const colorTableView = dropdown.colorTableView; + expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor' ); + expect( colorTableView.items.first.label ).to.equal( 'Usuń kolor' ); + } ); + + describe( 'works for', () => { + const colors = [ + { + color: 'hsl(0, 0%, 0%)', + label: 'Czarny' + }, { + color: 'hsl(0, 0%, 100%)', + label: 'Biały' + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Czerwony' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Pomarańczowy' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Niebieski' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Zielony' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Żółty' + } + ]; + + colors.forEach( test => { + it( `tested color ${ test.color } with name ${ test.label }.`, () => { + const colorGrid = dropdown.colorTableView.items.get( 1 ); + const tile = colorGrid.items.find( colorTile => test.color === colorTile.color ); + expect( tile.label ).to.equal( test.label ); + } ); + } ); + } ); + function localizedEditor() { + const editorElement = document.createElement( 'div' ); + document.body.appendChild( editorElement ); + + return ClassicTestEditor + .create( editorElement, { + plugins: [ FontColorEditing, FontColorUI ], + toolbar: [ 'fontColor' ], + language: 'pl', + } ) + .then( newEditor => { + editor = newEditor; + dropdown = editor.ui.componentFactory.create( 'fontColor' ); + command = editor.commands.get( 'fontColor' ); + + editorElement.remove(); + + return editor.destroy(); + } ); + } + } ); + } ); +} ); From bb9b666e7c8d1e56d7e67f9f93bcbda7815863c4 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 25 Mar 2019 10:35:08 +0100 Subject: [PATCH 52/92] Correct error with naming and simplify focus method. Add unit test for color grid. --- src/ui/colorgrid.js | 8 +--- tests/ui/colorgrid.js | 93 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 89 insertions(+), 12 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 0598c41..6917db1 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -115,13 +115,7 @@ export default class ColorGrid extends View { */ focusLast() { if ( this.items.length ) { - const lastChild = this.children.last; - - if ( typeof lastChild.focusLast === 'function' ) { - lastChild.focusLast(); - } else { - lastChild.focus(); - } + this.items.last.focus(); } } diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js index 659a91a..c0ddfac 100644 --- a/tests/ui/colorgrid.js +++ b/tests/ui/colorgrid.js @@ -3,6 +3,8 @@ * For licensing, see LICENSE.md. */ +/* globals Event */ + import ColorGrid from './../../src/ui/colorgrid'; import ViewCollection from '@ckeditor/ckeditor5-ui/src/viewcollection'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; @@ -10,8 +12,10 @@ import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import ColorTile from '../../src/ui/colortile'; +import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; + describe( 'ColorGrid', () => { - const colorDefinition = [ + const colorsDefinition = [ { color: '#000', label: 'Black', @@ -32,14 +36,16 @@ describe( 'ColorGrid', () => { } } ]; - let locale, colorGrid; + beforeEach( () => { locale = { t() {} }; - colorGrid = new ColorGrid( locale, colorDefinition ); + colorGrid = new ColorGrid( locale, { colorsDefinition } ); colorGrid.render(); } ); + testUtils.createSinonSandbox(); + describe( 'constructor()', () => { it( 'creates view collection with children', () => { expect( colorGrid.items ).to.be.instanceOf( ViewCollection ); @@ -61,9 +67,9 @@ describe( 'ColorGrid', () => { it( 'has proper number of elements', () => { expect( colorGrid.items.length ).to.equal( 3 ); } ); - colorDefinition.forEach( ( color, index ) => { + colorsDefinition.forEach( ( color, index ) => { describe( 'child items has proper attributes', () => { - it( `for ${ index } child`, () => { + it( `for (index: ${ index }, color: ${ color.color }) child`, () => { const colorTile = colorGrid.items.get( index ); expect( colorTile ).to.be.instanceOf( ColorTile ); expect( colorTile.color ).to.equal( color.color ); @@ -72,4 +78,81 @@ describe( 'ColorGrid', () => { } ); } ); } ); + + describe( 'execute()', () => { + it( 'fires event for rendered tiles', () => { + const spy = sinon.spy(); + const firstTile = colorGrid.items.first; + + colorGrid.on( 'execute', spy ); + + firstTile.isEnabled = true; + + firstTile.element.dispatchEvent( new Event( 'click' ) ); + sinon.assert.callCount( spy, 1 ); + + firstTile.isEnabled = false; + + firstTile.element.dispatchEvent( new Event( 'click' ) ); + sinon.assert.callCount( spy, 1 ); + } ); + } ); + + describe( 'focus', () => { + it( 'focuses the tile in DOM', () => { + const spy = sinon.spy( colorGrid.items.first, 'focus' ); + + colorGrid.focus(); + + sinon.assert.calledOnce( spy ); + + colorGrid.items.clear(); + colorGrid.focus(); + + expect( colorGrid.items.length ).to.equal( 0 ); + sinon.assert.calledOnce( spy ); + } ); + + it( 'focuses last the tile in DOM', () => { + const spy = sinon.spy( colorGrid.items.last, 'focus' ); + + colorGrid.focusLast(); + + sinon.assert.calledOnce( spy ); + + colorGrid.items.clear(); + colorGrid.focusLast(); + + expect( colorGrid.items.length ).to.equal( 0 ); + sinon.assert.calledOnce( spy ); + } ); + + describe( 'update elements in focus tracker', () => { + it( 'adding new element', () => { + const spy = sinon.spy( colorGrid.focusTracker, 'add' ); + + const colorTile = new ColorTile(); + colorTile.set( { + color: 'yellow', + label: 'Yellow', + tooltip: true, + options: { + hasBorder: false + } + } ); + colorGrid.items.add( colorTile ); + + expect( colorGrid.items.length ).to.equal( 4 ); + sinon.assert.calledOnce( spy ); + } ); + it( 'removes element', () => { + const spy = sinon.spy( colorGrid.focusTracker, 'remove' ); + + colorGrid.items.remove( colorGrid.items.length - 1 ); + + expect( colorGrid.items.length ).to.equal( 2 ); + sinon.assert.calledOnce( spy ); + } ); + } ); + } ); } ); From cfd3c331166b63284ca570f31de0d7e2c511e992 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 25 Mar 2019 13:35:15 +0100 Subject: [PATCH 53/92] Remove unnecessary code, add unit tests for color table view. --- src/ui/colortableview.js | 10 +- src/ui/colorui.js | 12 +- tests/ui/colortableview.js | 277 +++++++++++++++++++++++++++++++++++++ 3 files changed, 286 insertions(+), 13 deletions(-) create mode 100644 tests/ui/colortableview.js diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index e4fb332..96cf7cf 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -207,7 +207,7 @@ export default class ColorTableView extends View { initRecentCollection() { for ( let i = 0; i < this.colorColumns; i++ ) { this.recentlyUsedColors.add( { - color: 'hsla( 0, 0%, 0%, 0 )', + color: 'hsla(0, 0%, 0%, 0)', isEnabled: false, hasBorder: true } ); @@ -225,14 +225,6 @@ export default class ColorTableView extends View { 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 ); } diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 7532819..549475c 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -104,11 +104,15 @@ export default class ColorUI extends Plugin { dropdownView.bind( 'isEnabled' ).to( command ); - dropdownView.on( 'execute', ( evt, val ) => { - if ( val.value !== null ) { - colorTableView.recentlyUsedColors.add( { color: val.value, hasBorder: val.hasBorder, label: val.label }, 0 ); + dropdownView.on( 'execute', ( evt, data ) => { + if ( data.value !== null ) { + colorTableView.recentlyUsedColors.add( { + color: data.value, + hasBorder: data.hasBorder, + label: data.label }, + 0 ); } - editor.execute( this.commandName, val ); + editor.execute( this.commandName, data ); editor.editing.view.focus(); } ); diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js new file mode 100644 index 0000000..ffbbd61 --- /dev/null +++ b/tests/ui/colortableview.js @@ -0,0 +1,277 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +/* globals Event */ + +import ColorTableView from './../../src/ui/colortableview'; +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 testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; + +describe( 'ColorTableView', () => { + let locale, colorTableView; + const colorsDefinition = [ + { + color: '#000', + label: 'Black', + options: { + hasBorder: false + } + }, { + color: 'rgb(255, 255, 255)', + label: 'White', + options: { + hasBorder: true + } + }, { + color: 'red', + label: 'Red', + options: { + hasBorder: false + } + } + ]; + + beforeEach( () => { + locale = { t() {} }; + colorTableView = new ColorTableView( locale, { + colors: colorsDefinition, + colorColumns: 5, + removeButtonTooltip: 'Remove color' + } ); + colorTableView.render(); + } ); + + testUtils.createSinonSandbox(); + + describe( 'constructor()', () => { + it( 'creates items collection', () => { + expect( colorTableView.items ).to.be.instanceOf( ViewCollection ); + } ); + + it( 'creates focus tracker', () => { + expect( colorTableView.focusTracker ).to.be.instanceOf( FocusTracker ); + } ); + + it( 'creates keystroke handler', () => { + expect( colorTableView.keystrokes ).to.be.instanceOf( KeystrokeHandler ); + } ); + + it( 'creates observable for selected color', () => { + expect( colorTableView.selectedColor ).to.be.undefined; + + colorTableView.set( 'selectedColor', 'white' ); + + expect( colorTableView.selectedColor ).to.equal( 'white' ); + } ); + + it( 'keep tooltip for remove color button', () => { + expect( colorTableView.removeButtonTooltip ).to.equal( 'Remove color' ); + } ); + + it( 'keep number of drawed columns', () => { + expect( colorTableView.colorColumns ).to.equal( 5 ); + } ); + + it( 'creaets collection of recently used colors', () => { + expect( colorTableView.recentlyUsedColors ).to.be.instanceOf( Collection ); + } ); + + it( 'creates focus cycler', () => { + expect( colorTableView._focusCycler ).to.be.instanceOf( FocusCycler ); + } ); + + it( 'has proper class', () => { + expect( colorTableView.element.classList.contains( 'ck-color-table' ) ).to.be.true; + } ); + } ); + + describe( 'update elements in focus tracker', () => { + it( 'focuses the tile in DOM', () => { + const spy = sinon.spy( colorTableView._focusCycler, 'focusFirst' ); + + colorTableView.focus(); + + sinon.assert.calledOnce( spy ); + } ); + + it( 'focuses last the tile in DOM', () => { + const spy = sinon.spy( colorTableView._focusCycler, 'focusLast' ); + + colorTableView.focusLast(); + + sinon.assert.calledOnce( spy ); + } ); + } ); + + describe( 'remove color button', () => { + let removeButton; + + beforeEach( () => { + removeButton = colorTableView.items.first; + } ); + + it( 'has proper class', () => { + expect( removeButton.element.classList.contains( 'ck-color-table__remove-color' ) ).to.be.true; + } ); + + it( 'has proper setting', () => { + expect( removeButton.withText ).to.be.true; + expect( removeButton.icon ).to.equal( removeButtonIcon ); + expect( removeButton.tooltip ).to.be.true; + expect( removeButton.label ).to.equal( 'Remove color' ); + } ); + + it( 'executes event with "null" value', () => { + const spy = sinon.spy(); + colorTableView.on( 'execute', spy ); + + removeButton.element.dispatchEvent( new Event( 'click' ) ); + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, sinon.match.any, { value: null } ); + } ); + } ); + + describe( 'static colors grid', () => { + let staticColorTable; + beforeEach( () => { + staticColorTable = colorTableView.items.get( 1 ); + } ); + + it( 'has added 3 children from definition', () => { + expect( staticColorTable.items.length ).to.equal( 3 ); + } ); + + colorsDefinition.forEach( ( item, index ) => { + it( `dispatch event to parent element for color: ${ item.color }`, () => { + const spy = sinon.spy(); + colorTableView.on( 'execute', spy ); + + staticColorTable.items.get( index ).element.dispatchEvent( new Event( 'click' ) ); + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, sinon.match.any, { + value: item.color, + label: item.label, + hasBorder: item.options.hasBorder + } ); + } ); + } ); + } ); + + describe( 'recent colors grid', () => { + const colorBlack = { + color: '#000000', + label: 'Black', + hasBorder: false + }; + const colorWhite = { + color: '#FFFFFF', + label: 'Black', + hasBorder: true + }; + const colorRed = { + color: 'rgb(255,0,0)', + hasBorder: false + }; + const emptyColor = { + color: 'hsla(0, 0%, 0%, 0)', + isEnabled: false, + hasBorder: true + }; + let recentColorsGridView, recentColorModel; + + beforeEach( () => { + recentColorModel = colorTableView.recentlyUsedColors; + recentColorsGridView = colorTableView.items.last; + } ); + + describe( 'initialization', () => { + it( 'has proper length of populated items', () => { + expect( recentColorModel.length ).to.equal( 5 ); + } ); + for ( let i = 0; i < 5; i++ ) { + it( `initialized item with index: "${ i }" has proper attributes`, () => { + const modelItem = recentColorModel.get( i ); + const viewItem = recentColorsGridView.items.get( i ); + expect( modelItem.color ).to.equal( 'hsla(0, 0%, 0%, 0)' ); + expect( modelItem.isEnabled ).to.be.false; + expect( modelItem.hasBorder ).to.be.true; + expect( viewItem.isEnabled ).to.be.false; + expect( viewItem.color ).to.equal( 'hsla(0, 0%, 0%, 0)' ); + expect( viewItem.hasBorder ).to.be.true; + expect( viewItem.label ).to.be.undefined; + } ); + } + } ); + + describe( 'model manipulation', () => { + it( 'adding item will preserve length of collection', () => { + expect( recentColorModel.length ).to.equal( 5 ); + + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + + expect( recentColorModel.length ).to.equal( 5 ); + expect( recentColorModel.first.color ).to.equal( '#000000' ); + expect( recentColorModel.first.label ).to.equal( 'Black' ); + expect( recentColorModel.first.hasBorder ).to.be.false; + } ); + + it( 'adding multiple times same color should not work', () => { + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + + expect( recentColorModel.first ).to.own.include( colorBlack ); + expect( recentColorModel.get( 1 ) ).to.own.include( emptyColor ); + + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + + expect( recentColorModel.first ).to.own.include( colorBlack ); + expect( recentColorModel.get( 1 ) ).to.own.include( emptyColor ); + } ); + + it( 'adding duplicates move color to the front', () => { + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + recentColorModel.add( Object.assign( {}, colorWhite ), 0 ); + recentColorModel.add( Object.assign( {}, colorRed ), 0 ); + + expect( recentColorModel.get( 0 ) ).to.own.include( colorRed ); + expect( recentColorModel.get( 1 ) ).to.own.include( colorWhite ); + expect( recentColorModel.get( 2 ) ).to.own.include( colorBlack ); + expect( recentColorModel.get( 3 ) ).to.own.include( emptyColor ); + + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + + expect( recentColorModel.get( 0 ) ).to.own.include( colorBlack ); + expect( recentColorModel.get( 1 ) ).to.own.include( colorRed ); + expect( recentColorModel.get( 2 ) ).to.own.include( colorWhite ); + expect( recentColorModel.get( 3 ) ).to.own.include( emptyColor ); + } ); + } ); + + describe( 'events', () => { + it( 'added colors delegates eexecute to parent', () => { + const spy = sinon.spy(); + colorTableView.on( 'execute', spy ); + + recentColorModel.add( Object.assign( {}, colorBlack ), 0 ); + + recentColorsGridView.items.first.element.dispatchEvent( new Event( 'click' ) ); + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, sinon.match.any, { + value: '#000000', + label: 'Black', + hasBorder: false + } ); + } ); + } ); + } ); +} ); From b725e368c9681a14583ce44aa4fa6e29845eb2a5 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 25 Mar 2019 14:58:29 +0100 Subject: [PATCH 54/92] Correct spelling mistake, add unit tests for colorui. --- tests/ui/colortableview.js | 2 +- tests/ui/colorui.js | 175 ++++++++++++++++++++++++++----------- 2 files changed, 126 insertions(+), 51 deletions(-) diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index ffbbd61..645867a 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -257,7 +257,7 @@ describe( 'ColorTableView', () => { } ); describe( 'events', () => { - it( 'added colors delegates eexecute to parent', () => { + it( 'added colors delegates execute to parent', () => { const spy = sinon.spy(); colorTableView.on( 'execute', spy ); diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js index 7df6e34..71332ff 100644 --- a/tests/ui/colorui.js +++ b/tests/ui/colorui.js @@ -3,44 +3,75 @@ * For licensing, see LICENSE.md. */ -/* global document */ +/* global document, Event */ -import FontColorEditing from '../../src/fontcolor/fontcolorediting'; -import FontColorUI from '../../src/fontcolor/fontcolorui'; - -import fontColorIcon from '../../theme/icons/font-color.svg'; +import ColorUI from './../../src/ui/colorui'; +import FontColorCommand from './../../src/fontcolor/fontcolorcommand'; import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; import { add as addTranslations, _clear as clearTranslations } from '@ckeditor/ckeditor5-utils/src/translation-service'; -describe.skip( 'ColorUI', () => { - let editor, command, element; +describe( 'ColorUI', () => { + class TestColorPlugin extends ColorUI { + constructor( editor ) { + super( editor, { + commandName: 'testColorCommand', + componentName: 'testColor', + icon: '', + dropdownLabel: 'Test Color' + } ); + editor.commands.add( 'testColorCommand', new FontColorCommand( editor ) ); + } + + /** + * @inheritDoc + */ + static get pluginName() { + return 'TestColorPlugin'; + } + } + + const testColorConfig = { + colors: [ + 'yellow', + { + color: '#000', + }, { + color: 'rgb(255, 255, 255)', + label: 'White', + hasBorder: true + }, { + color: 'red', + label: 'RED' + }, { + color: '#00FF00', + label: 'Green', + hasBorder: false + } + ], + columns: 3 + }; testUtils.createSinonSandbox(); before( () => { addTranslations( 'en', { - 'Font Color': 'Font Color', - 'Remove color': 'Remove text color', - 'Black': 'Black', + 'Test Color': 'Test Color', + 'Remove color': 'Remove color', + 'yellow': 'yellow', 'White': 'White', - 'Red': 'Red', - 'Orange': 'Orange', - 'Blue': 'Blue', + 'RED': 'RED', 'Green': 'Green' } ); addTranslations( 'pl', { - 'Font Color': 'Kolor czcionki', + 'Test Color': 'Testowy plugin do kolorów', 'Remove color': 'Usuń kolor', - 'Black': 'Czarny', + 'yellow': 'żółty', 'White': 'Biały', - 'Red': 'Czerwony', - 'Orange': 'Pomarańczowy', - 'Blue': 'Niebieski', - 'Green': 'Zielony', - 'Yellow': 'Żółty' + 'RED': 'CZERWONY', + 'Green': 'Zielony' } ); } ); @@ -48,16 +79,20 @@ describe.skip( 'ColorUI', () => { clearTranslations(); } ); + let editor, element, testColorPlugin, command; + beforeEach( () => { element = document.createElement( 'div' ); document.body.appendChild( element ); return ClassicTestEditor .create( element, { - plugins: [ FontColorEditing, FontColorUI ] + plugins: [ TestColorPlugin ], + testColor: testColorConfig } ) .then( newEditor => { editor = newEditor; + testColorPlugin = newEditor.plugins.get( 'TestColorPlugin' ); } ); } ); @@ -67,40 +102,85 @@ describe.skip( 'ColorUI', () => { return editor.destroy(); } ); - describe( 'fontColor Dropdown', () => { + describe( 'constructor()', () => { + it( 'has assigned proper commandName', () => { + expect( testColorPlugin.commandName ).to.equal( 'testColorCommand' ); + } ); + + it( 'has assigned proper componentName', () => { + expect( testColorPlugin.componentName ).to.equal( 'testColor' ); + } ); + + it( 'has assigned proper icon', () => { + expect( testColorPlugin.icon ).to.equal( '' ); + } ); + + it( 'has assigned proper dropdownLabel', () => { + expect( testColorPlugin.dropdownLabel ).to.equal( 'Test Color' ); + } ); + + it( 'has assigned proper amount of columns', () => { + // Value taken from editor's config above. + expect( testColorPlugin.colorColumns ).to.equal( 3 ); + } ); + } ); + + describe( 'testColor Dropdown', () => { let dropdown; beforeEach( () => { - command = editor.commands.get( 'fontColor' ); - dropdown = editor.ui.componentFactory.create( 'fontColor' ); + command = editor.commands.get( 'testColorCommand' ); + dropdown = editor.ui.componentFactory.create( 'testColor' ); } ); it( 'button has the base properties', () => { const button = dropdown.buttonView; - expect( button ).to.have.property( 'label', 'Font Color' ); + expect( button ).to.have.property( 'label', 'Test Color' ); expect( button ).to.have.property( 'tooltip', true ); - expect( button ).to.have.property( 'icon', fontColorIcon ); + expect( button ).to.have.property( 'icon', '' ); } ); it( 'should add custom CSS class to dropdown', () => { - const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + const dropdown = editor.ui.componentFactory.create( 'testColor' ); dropdown.render(); - expect( dropdown.element.classList.contains( 'ck-font-color-dropdown' ) ).to.be.true; + expect( dropdown.element.classList.contains( 'ck-color-ui-dropdown' ) ).to.be.true; } ); it( 'should focus view after command execution from dropdown', () => { const focusSpy = testUtils.sinon.spy( editor.editing.view, 'focus' ); - const dropdown = editor.ui.componentFactory.create( 'fontColor' ); + const dropdown = editor.ui.componentFactory.create( 'testColor' ); - dropdown.commandName = 'fontColor'; + dropdown.commandName = 'testColorCommand'; dropdown.fire( 'execute', { value: null } ); sinon.assert.calledOnce( focusSpy ); } ); + it( 'static color grid should impact on recent colors', () => { + const firstStaticTile = dropdown.colorTableView.items.get( 1 ).items.first; + const recentColorsModel = dropdown.colorTableView.recentlyUsedColors; + const spy = sinon.spy(); + + dropdown.on( 'execute', spy ); + + firstStaticTile.element.dispatchEvent( new Event( 'click' ) ); + + sinon.assert.calledOnce( spy ); + sinon.assert.calledWith( spy, sinon.match.any, { + value: 'yellow', + label: 'yellow', + hasBorder: false + } ); + expect( recentColorsModel.get( 0 ) ).to.include( { + color: 'yellow', + label: 'yellow', + hasBorder: false + } ); + } ); + describe( 'model to command binding', () => { it( 'isEnabled', () => { command.isEnabled = false; @@ -120,7 +200,7 @@ describe.skip( 'ColorUI', () => { it( 'works for the #buttonView', () => { const buttonView = dropdown.buttonView; - expect( buttonView.label ).to.equal( 'Kolor czcionki' ); + expect( buttonView.label ).to.equal( 'Testowy plugin do kolorów' ); } ); it( 'works for the colorTableView#items in the panel', () => { @@ -132,26 +212,20 @@ describe.skip( 'ColorUI', () => { describe( 'works for', () => { const colors = [ { - color: 'hsl(0, 0%, 0%)', - label: 'Czarny' - }, { - color: 'hsl(0, 0%, 100%)', - label: 'Biały' + color: 'yellow', + label: 'żółty' }, { - color: 'hsl(0, 75%, 60%)', - label: 'Czerwony' + color: '#000', + label: '#000' }, { - color: 'hsl(30, 75%, 60%)', - label: 'Pomarańczowy' + color: 'rgb(255, 255, 255)', + label: 'Biały' }, { - color: 'hsl(240, 75%, 60%)', - label: 'Niebieski' + color: 'red', + label: 'CZERWONY' }, { - color: 'hsl(120, 75%, 60%)', + color: '#00FF00', label: 'Zielony' - }, { - color: 'hsl(60, 75%, 60%)', - label: 'Żółty' } ]; @@ -169,14 +243,15 @@ describe.skip( 'ColorUI', () => { return ClassicTestEditor .create( editorElement, { - plugins: [ FontColorEditing, FontColorUI ], - toolbar: [ 'fontColor' ], + plugins: [ TestColorPlugin ], + testColor: testColorConfig, + toolbar: [ 'testColor' ], language: 'pl', } ) .then( newEditor => { editor = newEditor; - dropdown = editor.ui.componentFactory.create( 'fontColor' ); - command = editor.commands.get( 'fontColor' ); + dropdown = editor.ui.componentFactory.create( 'testColor' ); + command = editor.commands.get( 'testColorCommand' ); editorElement.remove(); From fab201be2296ca9d41cab1f4e0c6c15ed01ad078 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 25 Mar 2019 15:24:53 +0100 Subject: [PATCH 55/92] Update manual tests. --- tests/manual/font-color.html | 28 ++++++++++------------------ tests/manual/font-color.md | 23 +++++++++++++++++++++++ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/tests/manual/font-color.html b/tests/manual/font-color.html index 52fb67e..2e12c5c 100644 --- a/tests/manual/font-color.html +++ b/tests/manual/font-color.html @@ -1,20 +1,12 @@
-

Font Color feature sample.

-

color:gold

-

color:lightcoral;

-

color:#9B59B6

-

color:rgb(248, 77, 77)

-

color:rgb(248,180,77)

-

color:rgba(248, 77, 77, 0.8)

-

color:rgba(248,180,77,0.8)

-

color:rgba(248, 77, 77, .8)

-

color:rgba(248,180,77,.8)

-

color:rgb(10%, 80%, 0%);

-

color:rgb(85%,70%,5%);

-

color:rgba(10%, 80%, 0%, 80%);

-

color:rgba(85%,70%,5%,80%);

-

color:hsl(0, 100%, 50%);

-

color:hsl(50,100%,50%);

-

color:hsla(100, 100%, 50%, 80%);

-

color:hsla(250,100%,50%,80%);

+

01. no-color; no-color

+

02. color:hsl(0, 0%, 100%);background-color:hsl(0, 0%, 0%);

+

03. color:hsl(0, 75%, 60%); no-color;

+

04. no-color; background-color:hsl(90, 75%, 60%);

+

05. color:hsl(30, 75%, 60%); background-color:hsl(0, 0%, 30%);

+

06. color:#00FFFF;background-color:rgb(255, 0, 0);

+

07. color:hsla( 0, 0%, 0%, .7); background-color:gold;

+

08. color:;background-color:hsla(270, 100%, 50%, 0.3);

+

09. color:#ddd;background-color:hsl(150, 75%, 60%);

+

10. color:hsl(270, 75%, 60%);background-color:#d82;

diff --git a/tests/manual/font-color.md b/tests/manual/font-color.md index e69de29..7f9c2f6 100644 --- a/tests/manual/font-color.md +++ b/tests/manual/font-color.md @@ -0,0 +1,23 @@ +### Loading + +The data should be loaded with different text and background colors with followed order. Colors 1-5 use predefined palette. Colors 6-8 use any css color not defined in configuration. +Color 9-10 mixes colors from predefined palette and custom one. +( First is font color, last is background color ) +1. no-color; no-color +2. White; Black +3. Red; no-color +4. no-color; Light green +5. Orange: Dim grey +6. #00FFFF; rgb(255, 0, 0) +7. hsla( 0, 0%, 0%, .7); gold +8. rgba( 0, 120, 250, 0.8); hsla(270, 100%, 50%, 0.3) +9. #ddd; Aquamarine +10. Purple; #d82 + +### Testing + +Try to: +- Change font by selecting many paragraphs. +- Change font by selecting some text. +- Change to default font by selecting many paragraphs. +- Change to default font by selecting some text. From 382a4ff7423e97de6d7b60d51922d9a84e8fe999 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Mon, 25 Mar 2019 15:30:28 +0100 Subject: [PATCH 56/92] Remove spaces from kept colors. --- src/utils.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.js b/src/utils.js index 465e20a..86245ff 100644 --- a/src/utils.js +++ b/src/utils.js @@ -94,7 +94,7 @@ export function normalizeOptions( colorRow ) { function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { - model: color, + model: color.replace( / /g, '' ), label: color, hasBorder: false, view: { @@ -107,7 +107,7 @@ function normalizeSingleColorDefinition( color ) { }; } else { return { - model: color.color, + model: color.color.replace( / /g, '' ), label: color.label || color.color, hasBorder: color.hasBorder === undefined ? false : color.hasBorder, view: { From 1e4a832cf9e1d0bd3c842e97f457e1f13309360e Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 26 Mar 2019 11:19:37 +0100 Subject: [PATCH 57/92] Fix test, add option to give amount of columns from JS. --- src/ui/colorgrid.js | 7 +++++-- src/ui/colortableview.js | 7 +++++-- tests/ui/colorui.js | 2 +- theme/fontcolor.css | 1 - 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 6917db1..baeb943 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -27,7 +27,7 @@ export default class ColorGrid extends View { * @param {Array.} colorsDefinition Array with definitions * required to build {@link module:font/ui/colortile~ColorTile}. */ - constructor( locale, { colorsDefinition = [] } = {} ) { + constructor( locale, { colorsDefinition = [], colorColumns } = {} ) { super( locale ); /** @@ -96,7 +96,10 @@ export default class ColorGrid extends View { tag: 'div', children: this.items, attributes: { - class: 'ck-color-table__grid-container' + class: 'ck-color-table__grid-container', + style: { + gridTemplateColumns: `repeat( ${ colorColumns }, 1fr)` + } } } ); } diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 96cf7cf..10fe039 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -151,7 +151,10 @@ export default class ColorTableView extends View { * @private */ createStaticColorTable() { - const colorGrid = new ColorGrid( this.locale, { colorsDefinition: this.colorsDefinition } ); + const colorGrid = new ColorGrid( this.locale, { + colorsDefinition: this.colorsDefinition, + colorColumns: this.colorColumns + } ); colorGrid.delegate( 'execute' ).to( this ); return colorGrid; } @@ -161,7 +164,7 @@ export default class ColorTableView extends View { * @private */ recentlyUsed() { - const recentViews = new ColorGrid( this.locale ); + const recentViews = new ColorGrid( this.locale, { colorColumns: this.colorColumns } ); recentViews.items.bindTo( this.recentlyUsedColors ).using( colorObj => { diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js index 71332ff..b89961f 100644 --- a/tests/ui/colorui.js +++ b/tests/ui/colorui.js @@ -218,7 +218,7 @@ describe( 'ColorUI', () => { color: '#000', label: '#000' }, { - color: 'rgb(255, 255, 255)', + color: 'rgb(255,255,255)', label: 'Biały' }, { color: 'red', diff --git a/theme/fontcolor.css b/theme/fontcolor.css index ffaa9f9..2bd33ed 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -14,7 +14,6 @@ .ck .ck-color-table__grid-container { display: grid; - grid-template-columns: repeat( var(--ck-table-color-max-columns), 1fr); grid-gap: calc( var(--ck-table-color-padding) / 2 ); padding: var(--ck-table-color-padding); } From 76ae5bddb7703ae0f0c1a180eb009216206d71a5 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 26 Mar 2019 12:31:33 +0100 Subject: [PATCH 58/92] Correct manual test description. --- tests/manual/font-color.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/manual/font-color.md b/tests/manual/font-color.md index 7f9c2f6..d854abf 100644 --- a/tests/manual/font-color.md +++ b/tests/manual/font-color.md @@ -17,7 +17,7 @@ Color 9-10 mixes colors from predefined palette and custom one. ### Testing Try to: -- Change font by selecting many paragraphs. -- Change font by selecting some text. -- Change to default font by selecting many paragraphs. -- Change to default font by selecting some text. +- Change color and background color by selecting many paragraphs. +- Change color and background color by selecting some text. +- Check if chosen colors from dropdown are added to recent color list. +- Try to re-apply color from Recent Color list - check if it moves to it beginning. From 987471824656e2f7a9d1e324b63d9ad990e5ddf6 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 12:40:18 +0100 Subject: [PATCH 59/92] =?UTF-8?q?Docs:=20Improved=20font=20(background)=20?= =?UTF-8?q?color=20feature=20docs.=20Fixed=20spelling=20and=20wording.=20F?= =?UTF-8?q?ixed=20code=E2=80=93style=20in=20various=20classes=20and=20meth?= =?UTF-8?q?ods.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/fontbackgroundcolor.js | 18 +++-- .../fontbackgroundcolorcommand.js | 6 +- .../fontbackgroundcolorediting.js | 2 +- .../fontbackgroundcolorui.js | 4 +- src/fontcolor.js | 18 +++-- src/fontcolor/fontcolorcommand.js | 6 +- src/fontcolor/fontcolorediting.js | 2 +- src/fontcolor/fontcolorui.js | 6 +- src/ui/colorgrid.js | 46 +++++------ src/ui/colortableview.js | 79 +++++++++++++------ src/ui/colortile.js | 10 +-- src/ui/colorui.js | 45 ++++++----- 12 files changed, 142 insertions(+), 100 deletions(-) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index a52d392..3810869 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -42,7 +42,7 @@ export default class FontBackgroundColor extends Plugin { * * ClassicEditor * .create( { - * fontBackgroundColor: ... // Font family feature configuration. + * fontBackgroundColor: ... // Font background color feature configuration. * } ) * .then( ... ) * .catch( ... ); @@ -53,7 +53,9 @@ export default class FontBackgroundColor extends Plugin { */ /** - * Available 'font background color' colors defined as an array of strings or objects. The default value is: + * Available font background colors defined as an array of strings or objects. + * + * The default value registers 15 colors: * * const fontBackgroundColorConfig = { * colors: [ @@ -107,18 +109,18 @@ export default class FontBackgroundColor extends Plugin { * ] * }; * - * which configures 15 default colors. Each color is used in dropdown as available color to choose from dropdown. + * *Note*: The colors are displayed in the `'fontBackgroundColor'` dropdown. * * @member {Array.} module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors */ /** - * Value represent amount of drawn columns in color panel. It also represent amount of visible recently used colors. - * The default value is: + * Represents the amount of columns in the dropdown. It also represents the number of background colors + * recently used by the user displayed in the dropdown. The default value is: * - * const fontBackgroundColorConfig = { - * columns: 5 - * } + * const fontBackgroundColorConfig = { + * columns: 5 + * } * * @member {Numebr} module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns */ diff --git a/src/fontbackgroundcolor/fontbackgroundcolorcommand.js b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js index da85c65..8a7853a 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorcommand.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorcommand.js @@ -11,13 +11,13 @@ import FontCommand from '../fontcommand'; import { FONT_BACKGROUND_COLOR } from '../utils'; /** - * The font background color command. It's used by + * The font background color command. It's used by the * {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} * to apply the font background color. * - * editor.execute( 'fontBackgroundColor', { value: 'rgb(250, 20, 20)' } ); + * editor.execute( 'fontBackgroundColor', { value: 'rgb(250, 20, 20)' } ); * - * **Note**: Executing the command with value equal null removes the attribute from the model. + * **Note**: Executing the command with the `null` value removes the attribute from the model. * * @extends module:font/fontcommand~FontCommand */ diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index d030c8e..7319117 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -16,7 +16,7 @@ import { FONT_BACKGROUND_COLOR, renderDowncastElement, renderUpcastAttribute } f * * It introduces the {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand command} and * the `fontBackgroundColor` attribute in the {@link module:engine/model/model~Model model} which renders - * in the {@link module:engine/view/view view} as an inline `` element (``), + * in the {@link module:engine/view/view view} as a `` element (``), * depending on the {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig configuration}. * * @extends module:core/plugin~Plugin diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index d20277a..524f14a 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -18,11 +18,13 @@ import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; */ export default class FontBackgroundColorUI extends ColorUI { constructor( editor ) { + const t = editor.locale.t; + super( editor, { commandName: FONT_BACKGROUND_COLOR, componentName: FONT_BACKGROUND_COLOR, icon: fontBackgroundColorIcon, - dropdownLabel: 'Font Background Color' + dropdownLabel: t( 'Font Background Color' ) } ); } diff --git a/src/fontcolor.js b/src/fontcolor.js index a56e728..2d0067d 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -41,7 +41,7 @@ export default class FontColor extends Plugin { * * ClassicEditor * .create( { - * fontColor: ... // Font family feature configuration. + * fontColor: ... // Font color feature configuration. * } ) * .then( ... ) * .catch( ... ); @@ -52,7 +52,9 @@ export default class FontColor extends Plugin { */ /** - * Available 'font color' colors defined as an array of strings or objects. The default value is: + * Available font colors defined as an array of strings or objects. + * + * The default value registers 15 colors: * * const fontColorConfig = { * colors: [ @@ -106,18 +108,18 @@ export default class FontColor extends Plugin { * ] * }; * - * which configures 15 default colors. Each color is used in dropdown as available color to choose from dropdown. + * *Note*: The colors are displayed in the `'fontColor'` dropdown. * * @member {Array.} module:font/fontcolor~FontColorConfig#colors */ /** - * Value represent amount of drawn columns in color panel. It also represents amount of visible recently used colors. - * The default value is: + * Represents the amount of columns in the dropdown. It also represents the number of font colors + * recently used by the user displayed in the dropdown. The default value is: * - * const fontColorConfig = { - * columns: 5 - * } + * const fontColorConfig = { + * columns: 5 + * } * * @member {Numebr} module:font/fontcolor~FontColorConfig#columns */ diff --git a/src/fontcolor/fontcolorcommand.js b/src/fontcolor/fontcolorcommand.js index 9b50c6d..b9a6a68 100644 --- a/src/fontcolor/fontcolorcommand.js +++ b/src/fontcolor/fontcolorcommand.js @@ -11,12 +11,12 @@ import FontCommand from '../fontcommand'; import { FONT_COLOR } from '../utils'; /** - * The font color command. It's used by {@link module:font/fontcolor/fontcolorediting~FontColorEditing} + * The font color command. It's used by the {@link module:font/fontcolor/fontcolorediting~FontColorEditing} * to apply the font color. * - * editor.execute( 'fontColor', { value: 'rgb(250, 20, 20)' } ); + * editor.execute( 'fontColor', { value: 'rgb(250, 20, 20)' } ); * - * **Note**: Executing the command with value equal null removes the attribute from the model. + * **Note**: Executing the command with the `null` value removes the attribute from the model. * * @extends module:font/fontcommand~FontCommand */ diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index d62a98f..d08d550 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -16,7 +16,7 @@ import { FONT_COLOR, renderDowncastElement, renderUpcastAttribute } from '../uti * * It introduces the {@link module:font/fontcolor/fontcolorcommand~FontColorCommand command} and * the `fontColor` attribute in the {@link module:engine/model/model~Model model} which renders - * in the {@link module:engine/view/view view} as an inline `` element (``), + * in the {@link module:engine/view/view view} as a `` element (``), * depending on the {@link module:font/fontcolor~FontColorConfig configuration}. * * @extends module:core/plugin~Plugin diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 5f927c4..597a7a3 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -12,17 +12,19 @@ import { FONT_COLOR } from '../utils'; import fontColorIcon from '../../theme/icons/font-color.svg'; /** - * The font background color UI plugin. It introduces the `'fontBackgroundColor'` dropdown. + * The font background color UI plugin. It introduces the `'fontColor'` dropdown. * * @extends module:core/plugin~Plugin */ export default class FontColorUI extends ColorUI { constructor( editor ) { + const t = editor.locale.t; + super( editor, { commandName: FONT_COLOR, componentName: FONT_COLOR, icon: fontColorIcon, - dropdownLabel: 'Font Color' + dropdownLabel: t( 'Font Color' ) } ); } diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index baeb943..1103361 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -14,13 +14,13 @@ import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; /** - * It keeps nicely collection of {@link module:font/ui/colortile~ColorTile}. + * A grid of {@link module:font/ui/colortile~ColorTile}. * * @extends module:ui/view~View */ export default class ColorGrid extends View { /** - * Construct instance of color grid used to display {@link module:font/ui/colortile~ColorTile} in drop down. + * Creates an instance of a color grid containing {@link module:font/ui/colortile~ColorTile}. * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} config Configuration @@ -31,7 +31,7 @@ export default class ColorGrid extends View { super( locale ); /** - * Collection of the child list views. + * Collection of the child tile views. * * @readonly * @member {module:ui/viewcollection~ViewCollection} @@ -39,7 +39,7 @@ export default class ColorGrid extends View { this.items = this.createCollection(); /** - * Tracks information about DOM focus in the list. + * Tracks information about DOM focus in the grid. * * @readonly * @member {module:utils/focustracker~FocusTracker} @@ -55,7 +55,7 @@ export default class ColorGrid extends View { this.keystrokes = new KeystrokeHandler(); /** - * Helps cycling over focusable {@link #items} in the list. + * Helps cycling over focusable {@link #items} in the grid. * * @readonly * @protected @@ -66,22 +66,24 @@ export default class ColorGrid extends View { focusTracker: this.focusTracker, keystrokeHandler: this.keystrokes, actions: { - // Navigate list items backwards using the arrowup key. + // Navigate grid items backwards using the arrowup key. focusPrevious: 'arrowleft', - // Navigate toolbar items forwards using the arrowdown key. + // Navigate grid items forwards using the arrowdown key. focusNext: 'arrowright', } } ); colorsDefinition.forEach( item => { const colorTile = new ColorTile(); + colorTile.set( { color: item.color, label: item.label, tooltip: true, hasBorder: item.options.hasBorder } ); + colorTile.on( 'execute', () => { this.fire( 'execute', { value: item.color, @@ -89,6 +91,7 @@ export default class ColorGrid extends View { label: item.label } ); } ); + this.items.add( colorTile ); } ); @@ -147,26 +150,23 @@ export default class ColorGrid extends View { } /** - * Color definition used to build {@link module:font/ui/colortile~ColorTile}. + * A color definition used to create a {@link module:font/ui/colortile~ColorTile}. * - * { - * color: hsl(0, 0%, 75%), - * label: 'Light Grey', - * options: { - * hasBorder: true - * } - * } + * { + * color: hsl(0, 0%, 75%), + * label: 'Light Grey', + * options: { + * hasBorder: true + * } + * } * * @typedef {Object} module:font/ui/colorgrid~ColorDefinition * @type Object * - * @property {String} color String representing inserted color. - * It's used as value of background-color style in {@link module:font/ui/colortile~ColorTile}. - * + * @property {String} color String representing a color. + * It is used as value of background-color style in {@link module:font/ui/colortile~ColorTile}. * @property {String} label String used as label for {@link module:font/ui/colortile~ColorTile}. - * - * @property {Object} options Additional options passed to build {@link module:font/ui/colortile~ColorTile}. - * - * @property {Boolean} options.hasBorder Flag indicates if special CSS class should be added - * to {@link module:font/ui/colortile~ColorTile}, which draw border around it. + * @property {Object} options Additional options passed to create a {@link module:font/ui/colortile~ColorTile}. + * @property {Boolean} options.hasBorder A flag that indicates if special a CSS class should be added + * to {@link module:font/ui/colortile~ColorTile}, which renders a border around it. */ diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 10fe039..00cff05 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -19,25 +19,27 @@ import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; /** - * Class which represents view with {@link module:font/ui/colorgrid~ColorGrid} - * and remove buttons inside {@link module:ui/dropdown/dropdownview~DropdownView}. + * Class which represents a view with {@link module:font/ui/colorgrid~ColorGrid} + * and remove color buttons. * * @extends module:ui/view~View */ export default class ColorTableView extends View { /** - * Construct view which will be inserted as child of {@link module:ui/dropdown/dropdownview~DropdownView} + * Creates a view to be inserted as child of {@link module:ui/dropdown/dropdownview~DropdownView}. + * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} config Configuration object - * @param {Array.} config.colors Array with objects drawn as static set of available colors in color table. - * @param {Number} config.colorColumns Number of columns in color grid. Determines how many recent color will be displayed. - * @param {String} config.removeButtonTooltip Description of button responsible for removing color attributes. + * @param {Array.} config.colors Array with definitions of colors to be displayed in the table. + * @param {Number} config.colorColumns Number of columns in the color grid. + * Also determines how many recent color will be displayed. + * @param {String} config.removeButtonLabel A label of a button responsible for removing the color. */ - constructor( locale, { colors, colorColumns, removeButtonTooltip } ) { + constructor( locale, { colors, colorColumns, removeButtonLabel } ) { super( locale ); /** - * Collection of the child list views. + * Collection of the children of the table. * * @readonly * @member {module:ui/viewcollection~ViewCollection} @@ -45,7 +47,8 @@ export default class ColorTableView extends View { this.items = this.createCollection(); /** - * Array with objects representing color to be drawn in color grid. + * An array with objects representing colors to be displayed in the grid. + * * @type {Arrray.} */ this.colorsDefinition = colors; @@ -67,25 +70,28 @@ export default class ColorTableView extends View { this.keystrokes = new KeystrokeHandler(); /** - * Keeps value of command for current selection. + * Keeps value of the command associated with the table for current selection. + * * @type {String} */ this.set( 'selectedColor' ); /** - * Description of button responsible for removing color attributes. + * A label of the button responsible for removing color attributes. + * * @type {String} */ - this.removeButtonTooltip = removeButtonTooltip; + this.removeButtonLabel = removeButtonLabel; /** - * Number of columns in color grid. Determines how many recent color will be displayed. + * The number of columns in color grid. Also determines the number of recent color to be displayed. + * * @type {Number} */ this.colorColumns = colorColumns; /** - * Collection kept model of colors used for Recent Colors section. + * A collection storing definitions of recently used colors. * * @readonly * @member {module:utils/collection~Collection} @@ -107,7 +113,7 @@ export default class ColorTableView extends View { // Navigate list items backwards using the arrowup key. focusPrevious: 'arrowup', - // Navigate toolbar items forwards using the arrowdown key. + // Navigate list items forwards using the arrowdown key. focusNext: 'arrowdown', } } ); @@ -127,27 +133,31 @@ export default class ColorTableView extends View { } /** - * Adds remove color button as child for current view. + * Adds the remove color button as child for current view. * * @private */ removeColorButton() { - const btnView = new ButtonView(); - btnView.set( { + const buttonView = new ButtonView(); + + buttonView.set( { withText: true, icon: removeButtonIcon, tooltip: true, - label: this.removeButtonTooltip + label: this.removeButtonLabel } ); - btnView.class = 'ck-color-table__remove-color'; - btnView.on( 'execute', () => { + + buttonView.class = 'ck-color-table__remove-color'; + buttonView.on( 'execute', () => { this.fire( 'execute', { value: null } ); } ); - return btnView; + + return buttonView; } /** - * Creates static color table grid based on editor config. + * Creates a static color table grid based on editor config. + * * @private */ createStaticColorTable() { @@ -155,12 +165,15 @@ export default class ColorTableView extends View { colorsDefinition: this.colorsDefinition, colorColumns: this.colorColumns } ); + colorGrid.delegate( 'execute' ).to( this ); + return colorGrid; } /** - * Adds recently used color section view and bind it to {@link #recentlyUsedColors}. + * Adds recently used colors section view and binds it to {@link #recentlyUsedColors}. + * * @private */ recentlyUsed() { @@ -169,42 +182,56 @@ export default class ColorTableView extends View { recentViews.items.bindTo( this.recentlyUsedColors ).using( colorObj => { const colorTile = new ColorTile(); + colorTile.set( { color: colorObj.color, hasBorder: colorObj.hasBorder } ); + if ( colorObj.label ) { colorTile.set( { label: colorObj.label, tooltip: true } ); } + if ( colorObj.isEnabled === false ) { colorTile.set( 'isEnabled', false ); } + colorTile.on( 'execute', () => { - this.fire( 'execute', { value: colorObj.color, hasBorder: colorObj.hasBorder, label: colorObj.label } ); + this.fire( 'execute', { + value: colorObj.color, + hasBorder: colorObj.hasBorder, + label: colorObj.label + } ); } ); + return colorTile; } ); this.recentlyUsedColors.on( 'add', ( evt, item ) => { const duplicates = this.recentlyUsedColors.filter( element => element.color === item.color, this ); + if ( duplicates.length === 2 ) { this.recentlyUsedColors.remove( duplicates[ 1 ] ); } + if ( this.recentlyUsedColors.length > this.colorColumns ) { this.recentlyUsedColors.remove( this.recentlyUsedColors.length - 1 ); } } ); recentViews.delegate( 'execute' ).to( this ); + return recentViews; } /** - * Populate {@link #recentlyUsedColors} with empty non-clickable buttons, which represents space for colors. + * Populates {@link #recentlyUsedColors} with empty non-clickable buttons, which represent placeholders + * for colors. + * * @private */ initRecentCollection() { diff --git a/src/ui/colortile.js b/src/ui/colortile.js index 8dbf787..cf61026 100644 --- a/src/ui/colortile.js +++ b/src/ui/colortile.js @@ -10,25 +10,25 @@ import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; /** - * Class represents single color tile possible to click in dropdown. Element was designed - * for being used in {@link module:font/ui/colorgrid~ColorGrid}. + * This class represents a single color tile in the {@link module:font/ui/colorgrid~ColorGrid}. * * @extends module:ui/button/buttonview~ButtonView */ export default class ColorTile extends ButtonView { constructor( locale ) { super( locale ); + const bind = this.bindTemplate; /** - * String representing color which will be shown as tile's background. + * String representing a color shown as tile's background. * @type {String} */ this.set( 'color' ); /** - * Parameter which trigger adding special CSS class to button. - * This class is responsible for displaying border around button. + * A flag that toggles a special CSS class responsible for displaying + * a border around the button. * @type {Boolean} */ this.set( 'hasBorder' ); diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 549475c..8af0462 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -9,54 +9,59 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { normalizeOptions, addColorsToDropdown } from '../utils'; +import { + normalizeOptions, + addColorsToDropdown +} from '../utils'; /** - * The color UI plugin. It's template for creating the `'fontBackgroundColor'` and the `'fotnColor'` dropdown. - * Plugin separates common logic responsible for displaying dropdown with color grids. + * The color UI plugin which isolates the common logic responsible for displaying dropdowns with color grids. + * It is used to create the `'fontBackgroundColor'` and the `'fontColor'` dropdowns. * * @extends module:core/plugin~Plugin */ export default class ColorUI extends Plugin { /** - * Creates plugin which adds UI with {@link module:font/ui/colortableview~ColorTableView} with proper configuration. + * Creates a plugin which brings dropdown with a pre–configured {@link module:font/ui/colortableview~ColorTableView} * * @param {module:core/editor/editor~Editor} editor * @param {Object} config Configuration object - * @param {String} config.commandName Name of command which will be execute after click into selected color tile.config. - * @param {String} config.componentName Name of this component in {@link module:ui/componentfactory~ComponentFactory} - * @param {String} config.icon SVG icon used in toolbar for displaying this UI element. - * @param {String} config.dropdownLabel Label used for icon in toolbar for this element. + * @param {String} config.commandName Name of command which will be executed when a color tile is clicked. + * @param {String} config.componentName Name of the dropdown in the {@link module:ui/componentfactory~ComponentFactory} + * and the configuration scope name in `editor.config`. + * @param {String} config.icon SVG icon used by the dropdown. + * @param {String} config.dropdownLabel Label used by the dropdown. */ constructor( editor, { commandName, icon, componentName, dropdownLabel } ) { super( editor ); /** - * Name of command which will be execute after click into selected color tile.config. + * Name of the command which will be executed when a color tile is clicked. * @type {String} */ this.commandName = commandName; /** - * Name of this component in {@link module:ui/componentfactory~ComponentFactory}. + * Name of this component in the {@link module:ui/componentfactory~ComponentFactory}. + * Also the configuration scope name in `editor.config`. * @type {String} */ this.componentName = componentName; /** - * SVG icon used in toolbar for displaying this UI element. + * SVG icon used by the dropdown. * @type {String} */ this.icon = icon; /** - * Label used for icon in toolbar for this element. + * Label used by the dropdown. * @type {String} */ this.dropdownLabel = dropdownLabel; /** - * Number of columns in color grid. Determines how many recent color will be displayed. + * Number of columns in color grid. Determines the number of recent colors to be displayed. * @type {Number} */ this.colorColumns = editor.config.get( `${ this.componentName }.columns` ); @@ -69,7 +74,6 @@ export default class ColorUI extends Plugin { const editor = this.editor; const t = editor.t; const command = editor.commands.get( this.commandName ); - const options = this._getLocalizedOptions(); // Register UI component. @@ -85,13 +89,13 @@ export default class ColorUI extends Plugin { } } ) ), colorColumns: this.colorColumns, - removeButtonTooltip: t( 'Remove color' ) + removeButtonLabel: t( 'Remove color' ) } ); colorTableView.bind( 'selectedColor' ).to( command, 'value' ); dropdownView.buttonView.set( { - label: t( this.dropdownLabel ), + label: this.dropdownLabel, icon: this.icon, tooltip: true } ); @@ -109,9 +113,10 @@ export default class ColorUI extends Plugin { colorTableView.recentlyUsedColors.add( { color: data.value, hasBorder: data.hasBorder, - label: data.label }, - 0 ); + label: data.label + }, 0 ); } + editor.execute( this.commandName, data ); editor.editing.view.focus(); } ); @@ -121,7 +126,7 @@ export default class ColorUI extends Plugin { } /** - * Returns options as defined in `config` but processed to account for + * Returns options as defined in the `editor.config` but processed to account for * editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} * or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig} in the correct language. * @@ -135,9 +140,11 @@ export default class ColorUI extends Plugin { const editor = this.editor; const t = editor.t; const options = normalizeOptions( editor.config.get( `${ this.componentName }.colors` ) ); + options.forEach( option => { option.label = t( option.label ); } ); + return options; } } From b6e6f7bd11a64998a8b99060d134ace7b1293e79 Mon Sep 17 00:00:00 2001 From: Mateusz Samsel Date: Tue, 26 Mar 2019 12:54:10 +0100 Subject: [PATCH 60/92] Add information about font color to guide. --- ...nt-color-and-background-color-options.html | 3 + ...font-color-and-background-color-options.js | 209 ++++++++++++++++++ docs/_snippets/features/font.html | 8 + docs/_snippets/features/font.js | 12 +- docs/features/font.md | 108 ++++++++- 5 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 docs/_snippets/features/custom-font-color-and-background-color-options.html create mode 100644 docs/_snippets/features/custom-font-color-and-background-color-options.js diff --git a/docs/_snippets/features/custom-font-color-and-background-color-options.html b/docs/_snippets/features/custom-font-color-and-background-color-options.html new file mode 100644 index 0000000..38f0fe6 --- /dev/null +++ b/docs/_snippets/features/custom-font-color-and-background-color-options.html @@ -0,0 +1,3 @@ +
+

This is sample text which has applied multiple different font colors and font background colors.

+
diff --git a/docs/_snippets/features/custom-font-color-and-background-color-options.js b/docs/_snippets/features/custom-font-color-and-background-color-options.js new file mode 100644 index 0000000..d4b563e --- /dev/null +++ b/docs/_snippets/features/custom-font-color-and-background-color-options.js @@ -0,0 +1,209 @@ +/** + * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. + * For licensing, see LICENSE.md. + */ + +import { CS_CONFIG } from '@ckeditor/ckeditor5-cloud-services/tests/_utils/cloud-services-config'; + +/* globals ClassicEditor, console, window, document */ +ClassicEditor + .create( document.querySelector( '#snippet-custom-font-color-and-background-color-options' ), { + cloudServices: CS_CONFIG, + toolbar: { + items: [ + 'heading', '|', 'fontColor', 'fontBackgroundColor', 'bulletedList', 'numberedList', 'undo', 'redo' + ], + viewportTopOffset: window.getViewportTopOffsetConfig() + }, + fontBackgroundColor: { + colors: [ + 'hsl(0,0%,0%)', + 'hsl(0,0%,12.5%)', + 'hsl(0,0%,25%)', + 'hsl(0,0%,37.5%)', + 'hsl(0,0%,50%)', + 'hsl(0,0%,62.50%)', + 'hsl(0,0%,75%)', + 'hsl(0,0%,87.5%)', + { + color: 'hsl(0,0%,100%)', + hasBorder: true + }, + 'hsl(0,100%,10%)', + 'hsl(0,100%,20%)', + 'hsl(0,100%,30%)', + 'hsl(0,100%,40%)', + 'hsl(0,100%,50%)', + 'hsl(0,100%,60%)', + 'hsl(0,100%,70%)', + 'hsl(0,100%,80%)', + { + color: 'hsl(0,100%,90%)', + hasBorder: true + }, + 'hsl(30,100%,10%)', + 'hsl(30,100%,20%)', + 'hsl(30,100%,30%)', + 'hsl(30,100%,40%)', + 'hsl(30,100%,50%)', + 'hsl(30,100%,60%)', + 'hsl(30,100%,70%)', + 'hsl(30,100%,80%)', + { + color: 'hsl(30,100%,90%)', + hasBorder: true + }, + 'hsl(60,100%,10%)', + 'hsl(60,100%,20%)', + 'hsl(60,100%,30%)', + 'hsl(60,100%,40%)', + 'hsl(60,100%,50%)', + 'hsl(60,100%,60%)', + 'hsl(60,100%,70%)', + 'hsl(60,100%,80%)', + { + color: 'hsl(60,100%,90%)', + hasBorder: true + }, + 'hsl(90,100%,10%)', + 'hsl(90,100%,20%)', + 'hsl(90,100%,30%)', + 'hsl(90,100%,40%)', + 'hsl(90,100%,50%)', + 'hsl(90,100%,60%)', + 'hsl(90,100%,70%)', + 'hsl(90,100%,80%)', + { + color: 'hsl(90,100%,90%)', + hasBorder: true + }, + 'hsl(120,100%,10%)', + 'hsl(120,100%,20%)', + 'hsl(120,100%,30%)', + 'hsl(120,100%,40%)', + 'hsl(120,100%,50%)', + 'hsl(120,100%,60%)', + 'hsl(120,100%,70%)', + 'hsl(120,100%,80%)', + { + color: 'hsl(120,100%,90%)', + hasBorder: true + }, + 'hsl(150,100%,10%)', + 'hsl(150,100%,20%)', + 'hsl(150,100%,30%)', + 'hsl(150,100%,40%)', + 'hsl(150,100%,50%)', + 'hsl(150,100%,60%)', + 'hsl(150,100%,70%)', + 'hsl(150,100%,80%)', + { + color: 'hsl(150,100%,90%)', + hasBorder: true + }, + 'hsl(180,100%,10%)', + 'hsl(180,100%,20%)', + 'hsl(180,100%,30%)', + 'hsl(180,100%,40%)', + 'hsl(180,100%,50%)', + 'hsl(180,100%,60%)', + 'hsl(180,100%,70%)', + 'hsl(180,100%,80%)', + { + color: 'hsl(180,100%,90%)', + hasBorder: true + }, + 'hsl(210,100%,10%)', + 'hsl(210,100%,20%)', + 'hsl(210,100%,30%)', + 'hsl(210,100%,40%)', + 'hsl(210,100%,50%)', + 'hsl(210,100%,60%)', + 'hsl(210,100%,70%)', + 'hsl(210,100%,80%)', + { + color: 'hsl(210,100%,90%)', + hasBorder: true + }, + 'hsl(240,100%,10%)', + 'hsl(240,100%,20%)', + 'hsl(240,100%,30%)', + 'hsl(240,100%,40%)', + 'hsl(240,100%,50%)', + 'hsl(240,100%,60%)', + 'hsl(240,100%,70%)', + 'hsl(240,100%,80%)', + { + color: 'hsl(240,100%,90%)', + hasBorder: true + }, + 'hsl(270,100%,10%)', + 'hsl(270,100%,20%)', + 'hsl(270,100%,30%)', + 'hsl(270,100%,40%)', + 'hsl(270,100%,50%)', + 'hsl(270,100%,60%)', + 'hsl(270,100%,70%)', + 'hsl(270,100%,80%)', + { + color: 'hsl(270,100%,90%)', + hasBorder: true + }, + 'hsl(300,100%,10%)', + 'hsl(300,100%,20%)', + 'hsl(300,100%,30%)', + 'hsl(300,100%,40%)', + 'hsl(300,100%,50%)', + 'hsl(300,100%,60%)', + 'hsl(300,100%,70%)', + 'hsl(300,100%,80%)', + { + color: 'hsl(300,100%,90%)', + hasBorder: true + }, + 'hsl(330,100%,10%)', + 'hsl(330,100%,20%)', + 'hsl(330,100%,30%)', + 'hsl(330,100%,40%)', + 'hsl(330,100%,50%)', + 'hsl(330,100%,60%)', + 'hsl(330,100%,70%)', + 'hsl(330,100%,80%)', + { + color: 'hsl(330,100%,90%)', + hasBorder: true + }, + ], + columns: 9 + }, + fontColor: { + colors: [ + 'black', + 'gray', + 'silver', + { + color: 'white', + hasBorder: true + }, + 'maroon', + 'red', + 'purple', + 'fuchsia', + 'green', + 'lime', + 'olive', + 'yellow', + 'navy', + 'blue', + 'teal', + 'aqua' + ], + columns: 4 + } + } ) + .then( editor => { + window.editor = editor; + } ) + .catch( err => { + console.error( err.stack ); + } ); diff --git a/docs/_snippets/features/font.html b/docs/_snippets/features/font.html index e600acb..e30ab74 100644 --- a/docs/_snippets/features/font.html +++ b/docs/_snippets/features/font.html @@ -15,4 +15,12 @@ This text has the "Courier New, Courier, monospace" family set.

+

+ This text has light green color and blue background. +

+ +

+ This text has white color and black background. +

+ diff --git a/docs/_snippets/features/font.js b/docs/_snippets/features/font.js index df67b6d..7940bf1 100644 --- a/docs/_snippets/features/font.js +++ b/docs/_snippets/features/font.js @@ -12,7 +12,17 @@ ClassicEditor cloudServices: CS_CONFIG, toolbar: { items: [ - 'heading', '|', 'fontSize', 'fontFamily', '|', 'bulletedList', 'numberedList', 'undo', 'redo' + 'heading', + '|', + 'fontSize', + 'fontFamily', + 'fontColor', + 'fontBackgroundColor', + '|', + 'bulletedList', + 'numberedList', + 'undo', + 'redo' ], viewportTopOffset: window.getViewportTopOffsetConfig() } diff --git a/docs/features/font.md b/docs/features/font.md index 7a7a15c..87c6395 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -8,6 +8,8 @@ category: features The {@link module:font/font~Font} plugin enables the following features in the editor: * {@link module:font/fontfamily~FontFamily} – Allows to change the font family by applying inline `` elements with a `font-family` in the `style` attribute. * {@link module:font/fontsize~FontSize} – Allows to control the font size by applying inline `` elements that either have a CSS class or a `font-size` in the `style` attribute. +* {@link module:font/fontcolor~FontColor} – Allows to control the font color by applying inline `` elements with a `color` in the `style` attribute. +* {@link module:font/fontbackgroundcolor~FontBackgroundColor} – Allows to control the font background color by applying inline `` elements with a `background-color` in the `style` attribute. ## Demo @@ -145,6 +147,77 @@ ClassicEditor {@snippet features/custom-font-size-numeric-options} +## Configuring font color and font background color + +Plugin enables `font color` and `font background color`. Which allows on using style `color` and `background-color` over text. + + Please notice that you can turn on only one of those plugins. As well as configure them separately. + + +### Dropdown + +It is possible to configure which colors are available in dropdown in the editor. Use the `fontColor.colors` or `fontBackgroundColor.colors` configuration option to do so. + +It is possible to configure how many columns is shown in color dropdown. Use the `fontColor.columns` or `fontBackgroundColor.columns` configuration option to do so. This option also reflects to number of recently used colors section, which always have 1 row with amount of columns equal to `columns` configuration option. +Default colors configuration is presented below: + +```js +fontColor = { + colors: [ + { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, { + color: 'hsl(0, 0%, 100%)', + label: 'White', + hasBorder: true + }, { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, { + color: 'hsl(150, 75%, 60%)', + label: 'Aquamarine' + }, { + color: 'hsl(180, 75%, 60%)', + label: 'Turquoise' + }, { + color: 'hsl(210, 75%, 60%)', + label: 'Light blue' + }, { + color: 'hsl(240, 75%, 60%)', + label: 'Blue' + }, { + color: 'hsl(270, 75%, 60%)', + label: 'Purple' + } + ], + columns: 5 +} +``` + +{@snippet features/custom-font-color-and-background-color-options} + ## Installation To add this feature to your editor, install the [`@ckeditor/ckeditor5-font`](https://www.npmjs.com/package/@ckeditor/ckeditor5-font) package: @@ -161,7 +234,7 @@ import Font from '@ckeditor/ckeditor5-font/src/font'; ClassicEditor .create( document.querySelector( '#editor' ), { plugins: [ Font, ... ], - toolbar: [ 'fontSize', 'fontFamily', ... ] + toolbar: [ 'fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', ... ] } ) .then( ... ) .catch( ... ); @@ -256,6 +329,39 @@ The {@link module:font/fontsize~FontSize} plugin registers the following compone editor.execute( 'fontSize' ); ``` +The {@link module:font/fontcolor~FontColor} plugin registers the following components: + +* The `'fontColor'` dropdown, +* The {@link module:font/fontcolor/fontcolorcommand~FontColorCommand `'fontColor'`} command. + + The number of options and their names correspond to the {@link module:font/fontcolor~FontColorConfig#colors `fontColor.colors`} + and {@link module:font/fontcolor~FontColorConfig#columns `fontColor.columns`} configuration options. + + You can change the font color of the current selection by executing the command with a desired value: + + ```js + editor.execute( 'fontColor', { value: rgb(30, 188, 97) } ); + ``` + + The `'fontColor'` command will accept any strings as values. + +The {@link module:font/fontbackgroundcolor~FontBackgroundColor} plugin registers the following components: + +* The `'fontColor'` dropdown, +* The {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand `'fontBackgroundColor'`} command. + + The number of options and their names correspond to the {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} + and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} configuration options. + + You can change the font background color of the current selection by executing the command with a desired value: + + ```js + editor.execute( 'fontBackgroundColor', { value: rgb(30, 188, 97) } ); + ``` + + The `'fontBackgroundColor'` command will accept any strings as values. + + ## Contribute The source code of the feature is available on GitHub in https://github.com/ckeditor/ckeditor5-font. From ca81b72ba841cc3f87c0d9ad4a0620cd274a8cf7 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 13:07:21 +0100 Subject: [PATCH 61/92] Code refactoring in font utils. --- src/utils.js | 61 ++++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/utils.js b/src/utils.js index 86245ff..441b288 100644 --- a/src/utils.js +++ b/src/utils.js @@ -9,6 +9,16 @@ import ColorTableView from './ui/colortableview'; +/** + * Name of font color plugin. + */ +export const FONT_COLOR = 'fontColor'; + +/** + * Name of font background color plugin. + */ +export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; + /** * Builds a proper {@link module:engine/conversion/conversion~ConverterDefinition converter definition} out of input data. * @@ -38,16 +48,6 @@ export function buildDefinition( modelAttributeKey, options ) { return definition; } -/** - * Name of font color plugin - */ -export const FONT_COLOR = 'fontColor'; - -/** - * Name of font background color plugin. - */ -export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; - /** * Function for font color and font background color plugins * which is responsible for upcasting data to model. @@ -56,10 +56,7 @@ export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; * @param {String} styleAttr */ export function renderUpcastAttribute( styleAttr ) { - return viewElement => { - const fontColor = viewElement.getStyle( styleAttr ); - return normalizeColorCode( fontColor ); - }; + return viewElement => normalizeColorCode( viewElement.getStyle( styleAttr ) ); } /** @@ -91,6 +88,25 @@ export function normalizeOptions( colorRow ) { .filter( option => !!option ); } +/** + * Helper which add {@link module:font/ui/colortableview~ColorTableView} to dropdown with proper initial values. + * @param {Object} config Configuration object + * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which + * will be added {@link module:font/ui/colortableview~ColorTableView}. + * @param {Array.} Array with objects representing color to be drawn in color grid. + */ +export function addColorsToDropdown( { dropdownView, colors, colorColumns, removeButtonLabel } ) { + const locale = dropdownView.locale; + const colorTableView = new ColorTableView( locale, { colors, colorColumns, removeButtonLabel } ); + + dropdownView.colorTableView = colorTableView; + dropdownView.panelView.children.add( colorTableView ); + + colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); + + return colorTableView; +} + function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { @@ -120,20 +136,3 @@ function normalizeSingleColorDefinition( color ) { }; } } - -/** - * Helper which add {@link module:font/ui/colortableview~ColorTableView} to dropdown with proper initial values. - * @param {Object} config Configuration object - * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which - * will be added {@link module:font/ui/colortableview~ColorTableView}. - * @param {Array.} Array with objects representing color to be drawn in color grid. - */ -export function addColorsToDropdown( { dropdownView, colors, colorColumns, removeButtonTooltip } ) { - const locale = dropdownView.locale; - const colorTableView = new ColorTableView( locale, { colors, colorColumns, removeButtonTooltip } ); - dropdownView.colorTableView = colorTableView; - dropdownView.panelView.children.add( colorTableView ); - - colorTableView.delegate( 'execute' ).to( dropdownView, 'execute' ); - return colorTableView; -} From 76368eb78e9781e8df78fa73afb30c329171509b Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 13:52:45 +0100 Subject: [PATCH 62/92] Tests: Code refactoring. --- tests/fontbackgroundcolor/fontbackgroundcolorcommand.js | 1 - tests/fontbackgroundcolor/fontbackgroundcoloreditng.js | 8 +++++--- tests/fontbackgroundcolor/fontbackgroundcolorui.js | 2 -- tests/fontcolor/fontcolorcommand.js | 1 - tests/fontcolor/fontcolorediting.js | 9 ++++----- tests/fontcolor/fontcolorui.js | 2 -- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js b/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js index 24d8b19..67a39e5 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js +++ b/tests/fontbackgroundcolor/fontbackgroundcolorcommand.js @@ -5,7 +5,6 @@ import FontBackgroundColorCommand from '../../src/fontbackgroundcolor/fontbackgroundcolorcommand'; import FontCommand from '../../src/fontcommand'; - import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; describe( 'FontBackgroundColorCommand', () => { diff --git a/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js index 150f5f3..8bcbf94 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js +++ b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js @@ -4,11 +4,12 @@ */ import FontBackgroundColorEditing from './../../src/fontbackgroundcolor/fontbackgroundcolorediting'; - import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; - import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; -import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import { + getData as getModelData, + setData as setModelData +} from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; describe( 'FontBackgroundColorEditing', () => { let editor, doc; @@ -133,6 +134,7 @@ describe( 'FontBackgroundColorEditing', () => { 'rgb( 20%, 30%, 40% )', '#345678' ]; + tests.forEach( test => { it( `should convert fontBackgroundColor attribute: "${ test }" to proper style value.`, () => { setModelData( doc, `fo<$text fontBackgroundColor="${ test }">o bar` ); diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorui.js b/tests/fontbackgroundcolor/fontbackgroundcolorui.js index 162236f..68f34d4 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/tests/fontbackgroundcolor/fontbackgroundcolorui.js @@ -8,9 +8,7 @@ import FontBackgroundColorEditing from './../../src/fontbackgroundcolor/fontbackgroundcolorediting'; import FontBackgroundColorUI from './../../src/fontbackgroundcolor/fontbackgroundcolorui'; import ColorUI from './../../src/ui/colorui'; - import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; - import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; describe( 'FontBckgroundColorUI', () => { diff --git a/tests/fontcolor/fontcolorcommand.js b/tests/fontcolor/fontcolorcommand.js index ae9cf29..f538198 100644 --- a/tests/fontcolor/fontcolorcommand.js +++ b/tests/fontcolor/fontcolorcommand.js @@ -5,7 +5,6 @@ import FontColorCommand from '../../src/fontcolor/fontcolorcommand'; import FontCommand from '../../src/fontcommand'; - import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; describe( 'FontColorCommand', () => { diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index a32263c..c3f900c 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -4,11 +4,12 @@ */ import FontColorEditing from './../../src/fontcolor/fontcolorediting'; - import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; - import VirtualTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/virtualtesteditor'; -import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; +import { + getData as getModelData, + setData as setModelData +} from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; describe( 'FontColorEditing', () => { let editor, doc; @@ -31,7 +32,6 @@ describe( 'FontColorEditing', () => { it( 'should set proper schema rules', () => { expect( editor.model.schema.checkAttribute( [ '$block', '$text' ], 'fontColor' ) ).to.be.true; expect( editor.model.schema.checkAttribute( [ '$clipboardHolder', '$text' ], 'fontColor' ) ).to.be.true; - expect( editor.model.schema.checkAttribute( [ '$block' ], 'fontColor' ) ).to.be.false; } ); @@ -181,7 +181,6 @@ describe( 'FontColorEditing', () => { editor.setData( data ); expect( getModelData( doc ) ).to.equal( '[]f<$text fontColor="rgb(10,20,30)">oo' ); - expect( editor.getData() ).to.equal( '

foo

' ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 88bf0b5..0bbdaf8 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -8,9 +8,7 @@ import FontColorEditing from './../../src/fontcolor/fontcolorediting'; import FontColorUI from './../../src/fontcolor/fontcolorui'; import ColorUI from './../../src/ui/colorui'; - import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; - import fontColorIcon from '../../theme/icons/font-color.svg'; describe( 'FontColorUI', () => { From 372ece40bb4ca08924b246dc8fc674f469acc634 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 13:56:41 +0100 Subject: [PATCH 63/92] Tests: Code refactoring. --- tests/ui/colorgrid.js | 5 +++-- tests/ui/colortableview.js | 5 +++++ tests/ui/colortile.js | 6 +++--- tests/ui/colorui.js | 31 +++++++++++++++++++------------ 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js index c0ddfac..93a569d 100644 --- a/tests/ui/colorgrid.js +++ b/tests/ui/colorgrid.js @@ -11,10 +11,11 @@ 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 ColorTile from '../../src/ui/colortile'; - import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'ColorGrid', () => { + let locale, colorGrid; + const colorsDefinition = [ { color: '#000', @@ -36,7 +37,6 @@ describe( 'ColorGrid', () => { } } ]; - let locale, colorGrid; beforeEach( () => { locale = { t() {} }; @@ -145,6 +145,7 @@ describe( 'ColorGrid', () => { expect( colorGrid.items.length ).to.equal( 4 ); sinon.assert.calledOnce( spy ); } ); + it( 'removes element', () => { const spy = sinon.spy( colorGrid.focusTracker, 'remove' ); diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index 645867a..2f0ebed 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -17,6 +17,7 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'ColorTableView', () => { let locale, colorTableView; + const colorsDefinition = [ { color: '#000', @@ -142,6 +143,7 @@ describe( 'ColorTableView', () => { describe( 'static colors grid', () => { let staticColorTable; + beforeEach( () => { staticColorTable = colorTableView.items.get( 1 ); } ); @@ -187,6 +189,7 @@ describe( 'ColorTableView', () => { isEnabled: false, hasBorder: true }; + let recentColorsGridView, recentColorModel; beforeEach( () => { @@ -198,10 +201,12 @@ describe( 'ColorTableView', () => { it( 'has proper length of populated items', () => { expect( recentColorModel.length ).to.equal( 5 ); } ); + for ( let i = 0; i < 5; i++ ) { it( `initialized item with index: "${ i }" has proper attributes`, () => { const modelItem = recentColorModel.get( i ); const viewItem = recentColorsGridView.items.get( i ); + expect( modelItem.color ).to.equal( 'hsla(0, 0%, 0%, 0)' ); expect( modelItem.isEnabled ).to.be.false; expect( modelItem.hasBorder ).to.be.true; diff --git a/tests/ui/colortile.js b/tests/ui/colortile.js index 3bb5d70..9dbe5b9 100644 --- a/tests/ui/colortile.js +++ b/tests/ui/colortile.js @@ -7,14 +7,14 @@ import ColorTile from './../../src/ui/colortile'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; describe( 'ColorTile', () => { - it( 'inhertence from ButtonView', () => { - const colorTile = new ColorTile(); - expect( colorTile ).to.be.instanceOf( ButtonView ); + it( 'inherits from ButtonView', () => { + expect( new ColorTile() ).to.be.instanceOf( ButtonView ); } ); it( 'has proper attributes and classes', () => { const colorTile = new ColorTile(); colorTile.render(); + expect( colorTile.color ).to.be.undefined; expect( colorTile.hasBorder ).to.be.undefined; diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js index b89961f..09bd03a 100644 --- a/tests/ui/colorui.js +++ b/tests/ui/colorui.js @@ -21,12 +21,10 @@ describe( 'ColorUI', () => { icon: '', dropdownLabel: 'Test Color' } ); + editor.commands.add( 'testColorCommand', new FontColorCommand( editor ) ); } - /** - * @inheritDoc - */ static get pluginName() { return 'TestColorPlugin'; } @@ -37,14 +35,17 @@ describe( 'ColorUI', () => { 'yellow', { color: '#000', - }, { + }, + { color: 'rgb(255, 255, 255)', label: 'White', hasBorder: true - }, { + }, + { color: 'red', label: 'RED' - }, { + }, + { color: '#00FF00', label: 'Green', hasBorder: false @@ -194,7 +195,7 @@ describe( 'ColorUI', () => { describe( 'localization', () => { beforeEach( () => { - return localizedEditor(); + return createLocalizedEditor(); } ); it( 'works for the #buttonView', () => { @@ -214,16 +215,20 @@ describe( 'ColorUI', () => { { color: 'yellow', label: 'żółty' - }, { + }, + { color: '#000', label: '#000' - }, { + }, + { color: 'rgb(255,255,255)', label: 'Biały' - }, { + }, + { color: 'red', label: 'CZERWONY' - }, { + }, + { color: '#00FF00', label: 'Zielony' } @@ -233,11 +238,13 @@ describe( 'ColorUI', () => { it( `tested color ${ test.color } with name ${ test.label }.`, () => { const colorGrid = dropdown.colorTableView.items.get( 1 ); const tile = colorGrid.items.find( colorTile => test.color === colorTile.color ); + expect( tile.label ).to.equal( test.label ); } ); } ); } ); - function localizedEditor() { + + function createLocalizedEditor() { const editorElement = document.createElement( 'div' ); document.body.appendChild( editorElement ); From 3b7af4476182c4f6493f0cea456283415f23ce67 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 14:05:32 +0100 Subject: [PATCH 64/92] Code refactoring: Used spacings from _spacing.css in the color grid. --- theme/fontcolor.css | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/theme/fontcolor.css b/theme/fontcolor.css index 2bd33ed..cc96a63 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -6,16 +6,14 @@ :root { --ck-table-color-tile-size: 20px; --ck-table-color-max-columns: 5; - --ck-table-color-padding: 10px; - --ck-color-table-color-tile-border: hsl(0, 0%, 90%); --ck-color-table-color-tile-border-active: hsl(184, 80%, 50%); } .ck .ck-color-table__grid-container { display: grid; - grid-gap: calc( var(--ck-table-color-padding) / 2 ); - padding: var(--ck-table-color-padding); + grid-gap: calc( var(--ck-spacing-standard) / 2 ); + padding: var(--ck-spacing-standard); } .ck .ck-color-table__color-tile { @@ -46,10 +44,9 @@ align-items: center; width: 100%; border-bottom: 1px solid var(--ck-color-base-border); - padding: calc(var(--ck-table-color-padding) / 2 ) var(--ck-table-color-padding); + padding: calc(var(--ck-spacing-standard) / 2 ) var(--ck-spacing-standard); } .ck .ck-button.ck-button_with-text.ck-color-table__remove-color svg { - width: var(--ck-table-color-tile-size); - margin-right: var(--ck-spacing-large); + margin-right: var(--ck-spacing-standard); } From a2d169e6cac33f828581ec740aaa000223a58ca7 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 15:06:34 +0100 Subject: [PATCH 65/92] Fixed broken color localization. Code refactoring. --- src/fontbackgroundcolor.js | 42 +++++++++----- .../fontbackgroundcolorediting.js | 42 +++++++++----- src/fontcolor.js | 42 +++++++++----- src/fontcolor/fontcolorediting.js | 42 +++++++++----- src/ui/colorgrid.js | 45 ++++++++------- src/ui/colorui.js | 37 +++--------- src/utils.js | 43 ++++++++++++++ .../fontbackgroundcoloreditng.js | 54 ++++++++++++------ tests/fontcolor/fontcolorediting.js | 54 ++++++++++++------ tests/ui/colorgrid.js | 6 +- tests/ui/colortableview.js | 12 ++-- tests/ui/colorui.js | 57 +++++++++---------- tests/utils.js | 18 ++++-- 13 files changed, 306 insertions(+), 188 deletions(-) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index 3810869..8bf1b37 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -62,47 +62,61 @@ export default class FontBackgroundColor extends Plugin { * { * color: 'hsl(0, 0%, 0%)', * label: 'Black' - * }, { + * }, + * { * color: 'hsl(0, 0%, 30%)', * label: 'Dim grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 60%)', * label: 'Grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 90%)', * label: 'Light grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 100%)', * label: 'White', * hasBorder: true - * }, { + * }, + * { * color: 'hsl(0, 75%, 60%)', * label: 'Red' - * }, { + * }, + * { * color: 'hsl(30, 75%, 60%)', * label: 'Orange' - * }, { + * }, + * { * color: 'hsl(60, 75%, 60%)', * label: 'Yellow' - * }, { + * }, + * { * color: 'hsl(90, 75%, 60%)', * label: 'Light green' - * }, { + * }, + * { * color: 'hsl(120, 75%, 60%)', * label: 'Green' - * }, { + * }, + * { * color: 'hsl(150, 75%, 60%)', * label: 'Aquamarine' - * }, { + * }, + * { * color: 'hsl(180, 75%, 60%)', * label: 'Turquoise' - * }, { + * }, + * { * color: 'hsl(210, 75%, 60%)', * label: 'Light blue' - * }, { + * }, + * { * color: 'hsl(240, 75%, 60%)', * label: 'Blue' - * }, { + * }, + * { * color: 'hsl(270, 75%, 60%)', * label: 'Purple' * } diff --git a/src/fontbackgroundcolor/fontbackgroundcolorediting.js b/src/fontbackgroundcolor/fontbackgroundcolorediting.js index 7319117..ba338f9 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorediting.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorediting.js @@ -33,47 +33,61 @@ export default class FontBackgroundColorEditing extends Plugin { { color: 'hsl(0, 0%, 0%)', label: 'Black' - }, { + }, + { color: 'hsl(0, 0%, 30%)', label: 'Dim grey' - }, { + }, + { color: 'hsl(0, 0%, 60%)', label: 'Grey' - }, { + }, + { color: 'hsl(0, 0%, 90%)', label: 'Light grey' - }, { + }, + { color: 'hsl(0, 0%, 100%)', label: 'White', hasBorder: true - }, { + }, + { color: 'hsl(0, 75%, 60%)', label: 'Red' - }, { + }, + { color: 'hsl(30, 75%, 60%)', label: 'Orange' - }, { + }, + { color: 'hsl(60, 75%, 60%)', label: 'Yellow' - }, { + }, + { color: 'hsl(90, 75%, 60%)', label: 'Light green' - }, { + }, + { color: 'hsl(120, 75%, 60%)', label: 'Green' - }, { + }, + { color: 'hsl(150, 75%, 60%)', label: 'Aquamarine' - }, { + }, + { color: 'hsl(180, 75%, 60%)', label: 'Turquoise' - }, { + }, + { color: 'hsl(210, 75%, 60%)', label: 'Light blue' - }, { + }, + { color: 'hsl(240, 75%, 60%)', label: 'Blue' - }, { + }, + { color: 'hsl(270, 75%, 60%)', label: 'Purple' } diff --git a/src/fontcolor.js b/src/fontcolor.js index 2d0067d..86c59e6 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -61,47 +61,61 @@ export default class FontColor extends Plugin { * { * color: 'hsl(0, 0%, 0%)', * label: 'Black' - * }, { + * }, + * { * color: 'hsl(0, 0%, 30%)', * label: 'Dim grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 60%)', * label: 'Grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 90%)', * label: 'Light grey' - * }, { + * }, + * { * color: 'hsl(0, 0%, 100%)', * label: 'White', * hasBorder: true - * }, { + * }, + * { * color: 'hsl(0, 75%, 60%)', * label: 'Red' - * }, { + * }, + * { * color: 'hsl(30, 75%, 60%)', * label: 'Orange' - * }, { + * }, + * { * color: 'hsl(60, 75%, 60%)', * label: 'Yellow' - * }, { + * }, + * { * color: 'hsl(90, 75%, 60%)', * label: 'Light green' - * }, { + * }, + * { * color: 'hsl(120, 75%, 60%)', * label: 'Green' - * }, { + * }, + * { * color: 'hsl(150, 75%, 60%)', * label: 'Aquamarine' - * }, { + * }, + * { * color: 'hsl(180, 75%, 60%)', * label: 'Turquoise' - * }, { + * }, + * { * color: 'hsl(210, 75%, 60%)', * label: 'Light blue' - * }, { + * }, + * { * color: 'hsl(240, 75%, 60%)', * label: 'Blue' - * }, { + * }, + * { * color: 'hsl(270, 75%, 60%)', * label: 'Purple' * } diff --git a/src/fontcolor/fontcolorediting.js b/src/fontcolor/fontcolorediting.js index d08d550..ea5eb18 100644 --- a/src/fontcolor/fontcolorediting.js +++ b/src/fontcolor/fontcolorediting.js @@ -33,47 +33,61 @@ export default class FontColorEditing extends Plugin { { color: 'hsl(0, 0%, 0%)', label: 'Black' - }, { + }, + { color: 'hsl(0, 0%, 30%)', label: 'Dim grey' - }, { + }, + { color: 'hsl(0, 0%, 60%)', label: 'Grey' - }, { + }, + { color: 'hsl(0, 0%, 90%)', label: 'Light grey' - }, { + }, + { color: 'hsl(0, 0%, 100%)', label: 'White', hasBorder: true - }, { + }, + { color: 'hsl(0, 75%, 60%)', label: 'Red' - }, { + }, + { color: 'hsl(30, 75%, 60%)', label: 'Orange' - }, { + }, + { color: 'hsl(60, 75%, 60%)', label: 'Yellow' - }, { + }, + { color: 'hsl(90, 75%, 60%)', label: 'Light green' - }, { + }, + { color: 'hsl(120, 75%, 60%)', label: 'Green' - }, { + }, + { color: 'hsl(150, 75%, 60%)', label: 'Aquamarine' - }, { + }, + { color: 'hsl(180, 75%, 60%)', label: 'Turquoise' - }, { + }, + { color: 'hsl(210, 75%, 60%)', label: 'Light blue' - }, { + }, + { color: 'hsl(240, 75%, 60%)', label: 'Blue' - }, { + }, + { color: 'hsl(270, 75%, 60%)', label: 'Purple' } diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 1103361..8c1e353 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -23,11 +23,12 @@ export default class ColorGrid extends View { * Creates an instance of a color grid containing {@link module:font/ui/colortile~ColorTile}. * * @param {module:utils/locale~Locale} [locale] The localization services instance. - * @param {Object} config Configuration - * @param {Array.} colorsDefinition Array with definitions - * required to build {@link module:font/ui/colortile~ColorTile}. + * @param {Object} options Component configuration + * @param {Array.} [options.colorsDefinition] Array with definitions + * required to create the {@link module:font/ui/colortile~ColorTile tiles}. + * @param {Number} options.colorColumns A number of columns to display the tiles. */ - constructor( locale, { colorsDefinition = [], colorColumns } = {} ) { + constructor( locale, options ) { super( locale ); /** @@ -74,26 +75,28 @@ export default class ColorGrid extends View { } } ); - colorsDefinition.forEach( item => { - const colorTile = new ColorTile(); + if ( options.colorsDefinition ) { + options.colorsDefinition.forEach( item => { + const colorTile = new ColorTile(); - colorTile.set( { - color: item.color, - label: item.label, - tooltip: true, - hasBorder: item.options.hasBorder - } ); + colorTile.set( { + color: item.color, + label: item.label, + tooltip: true, + hasBorder: item.options.hasBorder + } ); - colorTile.on( 'execute', () => { - this.fire( 'execute', { - value: item.color, - hasBorder: item.options.hasBorder, - label: item.label + colorTile.on( 'execute', () => { + this.fire( 'execute', { + value: item.color, + hasBorder: item.options.hasBorder, + label: item.label + } ); } ); - } ); - this.items.add( colorTile ); - } ); + this.items.add( colorTile ); + } ); + } this.setTemplate( { tag: 'div', @@ -101,7 +104,7 @@ export default class ColorGrid extends View { attributes: { class: 'ck-color-table__grid-container', style: { - gridTemplateColumns: `repeat( ${ colorColumns }, 1fr)` + gridTemplateColumns: `repeat( ${ options.colorColumns }, 1fr)` } } } ); diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 8af0462..2f96ef5 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -10,8 +10,8 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { - normalizeOptions, - addColorsToDropdown + addColorsToDropdown, + getLocalizedColorOptions } from '../utils'; /** @@ -74,18 +74,18 @@ export default class ColorUI extends Plugin { const editor = this.editor; const t = editor.t; const command = editor.commands.get( this.commandName ); - const options = this._getLocalizedOptions(); + const options = getLocalizedColorOptions( editor, this.componentName ); // Register UI component. editor.ui.componentFactory.add( this.componentName, locale => { const dropdownView = createDropdown( locale ); const colorTableView = addColorsToDropdown( { dropdownView, - colors: options.map( element => ( { - label: element.label, - color: element.model, + colors: options.map( option => ( { + label: option.label, + color: option.model, options: { - hasBorder: element.hasBorder + hasBorder: option.hasBorder } } ) ), colorColumns: this.colorColumns, @@ -124,27 +124,4 @@ export default class ColorUI extends Plugin { return dropdownView; } ); } - - /** - * Returns options as defined in the `editor.config` but processed to account for - * editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} - * or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig} in the correct language. - * - * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} - * when the user configuration is defined because the editor does not exist yet. - * - * @private - * @returns {Array.|Array.}. - */ - _getLocalizedOptions() { - const editor = this.editor; - const t = editor.t; - const options = normalizeOptions( editor.config.get( `${ this.componentName }.colors` ) ); - - options.forEach( option => { - option.label = t( option.label ); - } ); - - return options; - } } diff --git a/src/utils.js b/src/utils.js index 441b288..7bb4c6e 100644 --- a/src/utils.js +++ b/src/utils.js @@ -107,6 +107,49 @@ export function addColorsToDropdown( { dropdownView, colors, colorColumns, remov return colorTableView; } +/** + * Returns configuration options as defined in the `editor.config[ featureName ]` but processed to account for + * editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} + * or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig} in the correct language. + * + * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} + * when the user configuration is defined because the editor does not exist yet. + * + * @param {module:core/editor/editor~Editor} editor An editor instance. + * @param {String} featureName Determines which config (`editor.config[ featureName ]`) colors to localize. + * @returns {Array.|Array.}. + */ +export function getLocalizedColorOptions( editor, featureName ) { + const t = editor.t; + const localizedColorNames = { + Black: t( 'Black' ), + 'Dim grey': t( 'Dim grey' ), + Grey: t( 'Grey' ), + 'Light grey': t( 'Light grey' ), + White: t( 'White' ), + Red: t( 'Red' ), + Orange: t( 'Orange' ), + Yellow: t( 'Yellow' ), + 'Light green': t( 'Light green' ), + Green: t( 'Green' ), + Aquamarine: t( 'Aquamarine' ), + Turquoise: t( 'Turquoise' ), + 'Light blue': t( 'Light blue' ), + Blue: t( 'Blue' ), + Purple: t( 'Purple' ) + }; + + return normalizeOptions( editor.config.get( featureName ).colors ).map( colorOption => { + const label = localizedColorNames[ colorOption.label ]; + + if ( label && label != colorOption.label ) { + colorOption.label = label; + } + + return colorOption; + } ); +} + function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { diff --git a/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js index 8bcbf94..783ef84 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js +++ b/tests/fontbackgroundcolor/fontbackgroundcoloreditng.js @@ -43,47 +43,61 @@ describe( 'FontBackgroundColorEditing', () => { { color: 'hsl(0, 0%, 0%)', label: 'Black' - }, { + }, + { color: 'hsl(0, 0%, 30%)', label: 'Dim grey' - }, { + }, + { color: 'hsl(0, 0%, 60%)', label: 'Grey' - }, { + }, + { color: 'hsl(0, 0%, 90%)', label: 'Light grey' - }, { + }, + { color: 'hsl(0, 0%, 100%)', label: 'White', hasBorder: true - }, { + }, + { color: 'hsl(0, 75%, 60%)', label: 'Red' - }, { + }, + { color: 'hsl(30, 75%, 60%)', label: 'Orange' - }, { + }, + { color: 'hsl(60, 75%, 60%)', label: 'Yellow' - }, { + }, + { color: 'hsl(90, 75%, 60%)', label: 'Light green' - }, { + }, + { color: 'hsl(120, 75%, 60%)', label: 'Green' - }, { + }, + { color: 'hsl(150, 75%, 60%)', label: 'Aquamarine' - }, { + }, + { color: 'hsl(180, 75%, 60%)', label: 'Turquoise' - }, { + }, + { color: 'hsl(210, 75%, 60%)', label: 'Light blue' - }, { + }, + { color: 'hsl(240, 75%, 60%)', label: 'Blue' - }, { + }, + { color: 'hsl(270, 75%, 60%)', label: 'Purple' } @@ -102,10 +116,12 @@ describe( 'FontBackgroundColorEditing', () => { { label: 'Color1', color: '#000' - }, { + }, + { label: 'Color2', color: '#123456' - }, { + }, + { label: 'Color3', color: 'rgb( 0, 10, 20 )' }, @@ -155,10 +171,12 @@ describe( 'FontBackgroundColorEditing', () => { { label: 'Color1', color: '#000' - }, { + }, + { label: 'Color2', color: '#123456' - }, { + }, + { label: 'Color3', color: 'rgb( 0, 10, 20 )' }, diff --git a/tests/fontcolor/fontcolorediting.js b/tests/fontcolor/fontcolorediting.js index c3f900c..ec54518 100644 --- a/tests/fontcolor/fontcolorediting.js +++ b/tests/fontcolor/fontcolorediting.js @@ -42,47 +42,61 @@ describe( 'FontColorEditing', () => { { color: 'hsl(0, 0%, 0%)', label: 'Black' - }, { + }, + { color: 'hsl(0, 0%, 30%)', label: 'Dim grey' - }, { + }, + { color: 'hsl(0, 0%, 60%)', label: 'Grey' - }, { + }, + { color: 'hsl(0, 0%, 90%)', label: 'Light grey' - }, { + }, + { color: 'hsl(0, 0%, 100%)', label: 'White', hasBorder: true - }, { + }, + { color: 'hsl(0, 75%, 60%)', label: 'Red' - }, { + }, + { color: 'hsl(30, 75%, 60%)', label: 'Orange' - }, { + }, + { color: 'hsl(60, 75%, 60%)', label: 'Yellow' - }, { + }, + { color: 'hsl(90, 75%, 60%)', label: 'Light green' - }, { + }, + { color: 'hsl(120, 75%, 60%)', label: 'Green' - }, { + }, + { color: 'hsl(150, 75%, 60%)', label: 'Aquamarine' - }, { + }, + { color: 'hsl(180, 75%, 60%)', label: 'Turquoise' - }, { + }, + { color: 'hsl(210, 75%, 60%)', label: 'Light blue' - }, { + }, + { color: 'hsl(240, 75%, 60%)', label: 'Blue' - }, { + }, + { color: 'hsl(270, 75%, 60%)', label: 'Purple' } @@ -101,10 +115,12 @@ describe( 'FontColorEditing', () => { { label: 'Color1', color: '#000' - }, { + }, + { label: 'Color2', color: '#123456' - }, { + }, + { label: 'Color3', color: 'rgb( 0, 10, 20 )' }, @@ -153,10 +169,12 @@ describe( 'FontColorEditing', () => { { label: 'Color1', color: '#000' - }, { + }, + { label: 'Color2', color: '#123456' - }, { + }, + { label: 'Color3', color: 'rgb( 0, 10, 20 )' }, diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js index 93a569d..c5660b4 100644 --- a/tests/ui/colorgrid.js +++ b/tests/ui/colorgrid.js @@ -23,13 +23,15 @@ describe( 'ColorGrid', () => { options: { hasBorder: false } - }, { + }, + { color: 'rgb(255, 255, 255)', label: 'White', options: { hasBorder: true } - }, { + }, + { color: 'red', label: 'Red', options: { diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index 2f0ebed..36ccae0 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -12,7 +12,6 @@ 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 testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'ColorTableView', () => { @@ -25,7 +24,8 @@ describe( 'ColorTableView', () => { options: { hasBorder: false } - }, { + }, + { color: 'rgb(255, 255, 255)', label: 'White', options: { @@ -45,7 +45,7 @@ describe( 'ColorTableView', () => { colorTableView = new ColorTableView( locale, { colors: colorsDefinition, colorColumns: 5, - removeButtonTooltip: 'Remove color' + removeButtonLabel: 'Remove color' } ); colorTableView.render(); } ); @@ -73,11 +73,11 @@ describe( 'ColorTableView', () => { expect( colorTableView.selectedColor ).to.equal( 'white' ); } ); - it( 'keep tooltip for remove color button', () => { - expect( colorTableView.removeButtonTooltip ).to.equal( 'Remove color' ); + it( 'sets tooltip for the remove color button', () => { + expect( colorTableView.removeButtonLabel ).to.equal( 'Remove color' ); } ); - it( 'keep number of drawed columns', () => { + it( 'sets number of drawed columns', () => { expect( colorTableView.colorColumns ).to.equal( 5 ); } ); diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js index 09bd03a..1de6ad4 100644 --- a/tests/ui/colorui.js +++ b/tests/ui/colorui.js @@ -19,7 +19,7 @@ describe( 'ColorUI', () => { commandName: 'testColorCommand', componentName: 'testColor', icon: '', - dropdownLabel: 'Test Color' + dropdownLabel: editor.locale.t( 'Test Color' ) } ); editor.commands.add( 'testColorCommand', new FontColorCommand( editor ) ); @@ -43,7 +43,7 @@ describe( 'ColorUI', () => { }, { color: 'red', - label: 'RED' + label: 'Red' }, { color: '#00FF00', @@ -57,21 +57,12 @@ describe( 'ColorUI', () => { testUtils.createSinonSandbox(); before( () => { - addTranslations( 'en', { - 'Test Color': 'Test Color', - 'Remove color': 'Remove color', - 'yellow': 'yellow', - 'White': 'White', - 'RED': 'RED', - 'Green': 'Green' - } ); - addTranslations( 'pl', { - 'Test Color': 'Testowy plugin do kolorów', + 'Test Color': 'Testowy plugin', 'Remove color': 'Usuń kolor', - 'yellow': 'żółty', + 'Yellow': 'Żółty', 'White': 'Biały', - 'RED': 'CZERWONY', + 'Red': 'Czerwony', 'Green': 'Zielony' } ); } ); @@ -117,7 +108,7 @@ describe( 'ColorUI', () => { } ); it( 'has assigned proper dropdownLabel', () => { - expect( testColorPlugin.dropdownLabel ).to.equal( 'Test Color' ); + expect( testColorPlugin.dropdownLabel ).to.equal( 'Testowy plugin' ); } ); it( 'has assigned proper amount of columns', () => { @@ -137,7 +128,7 @@ describe( 'ColorUI', () => { it( 'button has the base properties', () => { const button = dropdown.buttonView; - expect( button ).to.have.property( 'label', 'Test Color' ); + expect( button ).to.have.property( 'label', 'Testowy plugin' ); expect( button ).to.have.property( 'tooltip', true ); expect( button ).to.have.property( 'icon', '' ); } ); @@ -194,19 +185,28 @@ describe( 'ColorUI', () => { } ); describe( 'localization', () => { + let editor, editorElement; + beforeEach( () => { - return createLocalizedEditor(); + editorElement = document.createElement( 'div' ); + document.body.appendChild( editorElement ); + + return createLocalizedEditor( editorElement ) + .then( localizedEditor => { + editor = localizedEditor; + } ); } ); - it( 'works for the #buttonView', () => { - const buttonView = dropdown.buttonView; + afterEach( () => { + editorElement.remove(); - expect( buttonView.label ).to.equal( 'Testowy plugin do kolorów' ); + return editor.destroy(); } ); it( 'works for the colorTableView#items in the panel', () => { const colorTableView = dropdown.colorTableView; - expect( colorTableView.removeButtonTooltip ).to.equal( 'Usuń kolor' ); + + expect( colorTableView.removeButtonLabel ).to.equal( 'Usuń kolor' ); expect( colorTableView.items.first.label ).to.equal( 'Usuń kolor' ); } ); @@ -214,7 +214,7 @@ describe( 'ColorUI', () => { const colors = [ { color: 'yellow', - label: 'żółty' + label: 'yellow' }, { color: '#000', @@ -226,7 +226,7 @@ describe( 'ColorUI', () => { }, { color: 'red', - label: 'CZERWONY' + label: 'Czerwony' }, { color: '#00FF00', @@ -235,7 +235,7 @@ describe( 'ColorUI', () => { ]; colors.forEach( test => { - it( `tested color ${ test.color } with name ${ test.label }.`, () => { + it( `tested color "${ test.color }" translated to "${ test.label }".`, () => { const colorGrid = dropdown.colorTableView.items.get( 1 ); const tile = colorGrid.items.find( colorTile => test.color === colorTile.color ); @@ -244,10 +244,7 @@ describe( 'ColorUI', () => { } ); } ); - function createLocalizedEditor() { - const editorElement = document.createElement( 'div' ); - document.body.appendChild( editorElement ); - + function createLocalizedEditor( editorElement ) { return ClassicTestEditor .create( editorElement, { plugins: [ TestColorPlugin ], @@ -260,9 +257,7 @@ describe( 'ColorUI', () => { dropdown = editor.ui.componentFactory.create( 'testColor' ); command = editor.commands.get( 'testColorCommand' ); - editorElement.remove(); - - return editor.destroy(); + return editor; } ); } } ); diff --git a/tests/utils.js b/tests/utils.js index bb865d2..2f4c186 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -19,14 +19,17 @@ describe( 'utils', () => { 'black', { color: 'black' - }, { + }, + { color: 'black', label: 'Black' - }, { + }, + { color: 'black', label: 'Black', hasBorder: true - }, { + }, + { color: 'black', hasBorder: true } @@ -44,7 +47,8 @@ describe( 'utils', () => { }, priority: 5 } - }, { + }, + { model: 'black', label: 'black', hasBorder: false, @@ -55,7 +59,8 @@ describe( 'utils', () => { }, priority: 5 } - }, { + }, + { model: 'black', label: 'Black', hasBorder: false, @@ -107,7 +112,8 @@ describe( 'utils', () => { options: { hasBorder: false } - }, { + }, + { label: 'White', color: '#FFFFFF', options: { From 5de2862f625578a3658f45c772ed76088fa1d7e8 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 15:15:40 +0100 Subject: [PATCH 66/92] Code refactoring and documentation. --- src/ui/colorgrid.js | 12 ++++---- src/ui/colortableview.js | 30 +++++++++++-------- src/ui/colorui.js | 8 ++--- src/utils.js | 9 ++++-- .../fontbackgroundcolorui.js | 2 +- tests/fontcolor/fontcolorui.js | 2 +- tests/ui/colorgrid.js | 6 ++-- tests/ui/colortableview.js | 10 +++---- tests/ui/colorui.js | 2 +- tests/utils.js | 6 ++-- 10 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js index 8c1e353..6a0df53 100644 --- a/src/ui/colorgrid.js +++ b/src/ui/colorgrid.js @@ -14,7 +14,7 @@ import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; /** - * A grid of {@link module:font/ui/colortile~ColorTile}. + * A grid of {@link module:font/ui/colortile~ColorTile color tiles}. * * @extends module:ui/view~View */ @@ -24,9 +24,9 @@ export default class ColorGrid extends View { * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} options Component configuration - * @param {Array.} [options.colorsDefinition] Array with definitions + * @param {Array.} [options.colorDefinitions] Array with definitions * required to create the {@link module:font/ui/colortile~ColorTile tiles}. - * @param {Number} options.colorColumns A number of columns to display the tiles. + * @param {Number} options.columns A number of columns to display the tiles. */ constructor( locale, options ) { super( locale ); @@ -75,8 +75,8 @@ export default class ColorGrid extends View { } } ); - if ( options.colorsDefinition ) { - options.colorsDefinition.forEach( item => { + if ( options.colorDefinitions ) { + options.colorDefinitions.forEach( item => { const colorTile = new ColorTile(); colorTile.set( { @@ -104,7 +104,7 @@ export default class ColorGrid extends View { attributes: { class: 'ck-color-table__grid-container', style: { - gridTemplateColumns: `repeat( ${ options.colorColumns }, 1fr)` + gridTemplateColumns: `repeat( ${ options.columns }, 1fr)` } } } ); diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 00cff05..b9cbab5 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -19,8 +19,11 @@ import removeButtonIcon from '@ckeditor/ckeditor5-core/theme/icons/eraser.svg'; import '../../theme/fontcolor.css'; /** - * Class which represents a view with {@link module:font/ui/colorgrid~ColorGrid} - * and remove color buttons. + * Class which represents a view with the following sub–components: + * + * * a remove color button, + * * a {@link module:font/ui/colorgrid~ColorGrid}, + * * a grid of recently used colors. * * @extends module:ui/view~View */ @@ -30,12 +33,13 @@ export default class ColorTableView extends View { * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} config Configuration object - * @param {Array.} config.colors Array with definitions of colors to be displayed in the table. - * @param {Number} config.colorColumns Number of columns in the color grid. + * @param {Array.} config.colors Array with definitions of colors to + * be displayed in the table. + * @param {Number} config.columns Number of columns in the color grid. * Also determines how many recent color will be displayed. * @param {String} config.removeButtonLabel A label of a button responsible for removing the color. */ - constructor( locale, { colors, colorColumns, removeButtonLabel } ) { + constructor( locale, { colors, columns, removeButtonLabel } ) { super( locale ); /** @@ -49,9 +53,9 @@ export default class ColorTableView extends View { /** * An array with objects representing colors to be displayed in the grid. * - * @type {Arrray.} + * @type {Arrray.} */ - this.colorsDefinition = colors; + this.colorDefinitions = colors; /** * Tracks information about DOM focus in the list. @@ -88,7 +92,7 @@ export default class ColorTableView extends View { * * @type {Number} */ - this.colorColumns = colorColumns; + this.columns = columns; /** * A collection storing definitions of recently used colors. @@ -162,8 +166,8 @@ export default class ColorTableView extends View { */ createStaticColorTable() { const colorGrid = new ColorGrid( this.locale, { - colorsDefinition: this.colorsDefinition, - colorColumns: this.colorColumns + colorDefinitions: this.colorDefinitions, + columns: this.columns } ); colorGrid.delegate( 'execute' ).to( this ); @@ -177,7 +181,7 @@ export default class ColorTableView extends View { * @private */ recentlyUsed() { - const recentViews = new ColorGrid( this.locale, { colorColumns: this.colorColumns } ); + const recentViews = new ColorGrid( this.locale, { columns: this.columns } ); recentViews.items.bindTo( this.recentlyUsedColors ).using( colorObj => { @@ -218,7 +222,7 @@ export default class ColorTableView extends View { this.recentlyUsedColors.remove( duplicates[ 1 ] ); } - if ( this.recentlyUsedColors.length > this.colorColumns ) { + if ( this.recentlyUsedColors.length > this.columns ) { this.recentlyUsedColors.remove( this.recentlyUsedColors.length - 1 ); } } ); @@ -235,7 +239,7 @@ export default class ColorTableView extends View { * @private */ initRecentCollection() { - for ( let i = 0; i < this.colorColumns; i++ ) { + for ( let i = 0; i < this.columns; i++ ) { this.recentlyUsedColors.add( { color: 'hsla(0, 0%, 0%, 0)', isEnabled: false, diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 2f96ef5..886b00d 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -10,7 +10,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { - addColorsToDropdown, + addColorTableToDropdown, getLocalizedColorOptions } from '../utils'; @@ -64,7 +64,7 @@ export default class ColorUI extends Plugin { * Number of columns in color grid. Determines the number of recent colors to be displayed. * @type {Number} */ - this.colorColumns = editor.config.get( `${ this.componentName }.columns` ); + this.columns = editor.config.get( `${ this.componentName }.columns` ); } /** @@ -79,7 +79,7 @@ export default class ColorUI extends Plugin { // Register UI component. editor.ui.componentFactory.add( this.componentName, locale => { const dropdownView = createDropdown( locale ); - const colorTableView = addColorsToDropdown( { + const colorTableView = addColorTableToDropdown( { dropdownView, colors: options.map( option => ( { label: option.label, @@ -88,7 +88,7 @@ export default class ColorUI extends Plugin { hasBorder: option.hasBorder } } ) ), - colorColumns: this.colorColumns, + columns: this.columns, removeButtonLabel: t( 'Remove color' ) } ); diff --git a/src/utils.js b/src/utils.js index 7bb4c6e..03342cd 100644 --- a/src/utils.js +++ b/src/utils.js @@ -90,14 +90,17 @@ export function normalizeOptions( colorRow ) { /** * Helper which add {@link module:font/ui/colortableview~ColorTableView} to dropdown with proper initial values. + * * @param {Object} config Configuration object * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which * will be added {@link module:font/ui/colortableview~ColorTableView}. - * @param {Array.} Array with objects representing color to be drawn in color grid. + * @param {Array.} Array with definitions representing colors to be displayed + * in the color table. + * @returns {module:font/ui/colortableview~ColorTableView} The new color table view. */ -export function addColorsToDropdown( { dropdownView, colors, colorColumns, removeButtonLabel } ) { +export function addColorTableToDropdown( { dropdownView, colors, columns, removeButtonLabel } ) { const locale = dropdownView.locale; - const colorTableView = new ColorTableView( locale, { colors, colorColumns, removeButtonLabel } ); + const colorTableView = new ColorTableView( locale, { colors, columns, removeButtonLabel } ); dropdownView.colorTableView = colorTableView; dropdownView.panelView.children.add( colorTableView ); diff --git a/tests/fontbackgroundcolor/fontbackgroundcolorui.js b/tests/fontbackgroundcolor/fontbackgroundcolorui.js index 68f34d4..012ff80 100644 --- a/tests/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/tests/fontbackgroundcolor/fontbackgroundcolorui.js @@ -44,6 +44,6 @@ describe( 'FontBckgroundColorUI', () => { expect( fontBackgroundColorUIPlugin.componentName ).to.equal( 'fontBackgroundColor' ); expect( fontBackgroundColorUIPlugin.icon ).to.equal( fontBackgroundColorIcon ); expect( fontBackgroundColorUIPlugin.dropdownLabel ).to.equal( 'Font Background Color' ); - expect( fontBackgroundColorUIPlugin.colorColumns ).to.equal( 5 ); + expect( fontBackgroundColorUIPlugin.columns ).to.equal( 5 ); } ); } ); diff --git a/tests/fontcolor/fontcolorui.js b/tests/fontcolor/fontcolorui.js index 0bbdaf8..c3f1bdd 100644 --- a/tests/fontcolor/fontcolorui.js +++ b/tests/fontcolor/fontcolorui.js @@ -44,6 +44,6 @@ describe( 'FontColorUI', () => { expect( fontColorUIPlugin.componentName ).to.equal( 'fontColor' ); expect( fontColorUIPlugin.icon ).to.equal( fontColorIcon ); expect( fontColorUIPlugin.dropdownLabel ).to.equal( 'Font Color' ); - expect( fontColorUIPlugin.colorColumns ).to.equal( 5 ); + expect( fontColorUIPlugin.columns ).to.equal( 5 ); } ); } ); diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js index c5660b4..bd410d9 100644 --- a/tests/ui/colorgrid.js +++ b/tests/ui/colorgrid.js @@ -16,7 +16,7 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'ColorGrid', () => { let locale, colorGrid; - const colorsDefinition = [ + const colorDefinitions = [ { color: '#000', label: 'Black', @@ -42,7 +42,7 @@ describe( 'ColorGrid', () => { beforeEach( () => { locale = { t() {} }; - colorGrid = new ColorGrid( locale, { colorsDefinition } ); + colorGrid = new ColorGrid( locale, { colorDefinitions } ); colorGrid.render(); } ); @@ -69,7 +69,7 @@ describe( 'ColorGrid', () => { it( 'has proper number of elements', () => { expect( colorGrid.items.length ).to.equal( 3 ); } ); - colorsDefinition.forEach( ( color, index ) => { + colorDefinitions.forEach( ( color, index ) => { describe( 'child items has proper attributes', () => { it( `for (index: ${ index }, color: ${ color.color }) child`, () => { const colorTile = colorGrid.items.get( index ); diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index 36ccae0..a84972c 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -17,7 +17,7 @@ import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; describe( 'ColorTableView', () => { let locale, colorTableView; - const colorsDefinition = [ + const colorDefinitions = [ { color: '#000', label: 'Black', @@ -43,8 +43,8 @@ describe( 'ColorTableView', () => { beforeEach( () => { locale = { t() {} }; colorTableView = new ColorTableView( locale, { - colors: colorsDefinition, - colorColumns: 5, + colors: colorDefinitions, + columns: 5, removeButtonLabel: 'Remove color' } ); colorTableView.render(); @@ -78,7 +78,7 @@ describe( 'ColorTableView', () => { } ); it( 'sets number of drawed columns', () => { - expect( colorTableView.colorColumns ).to.equal( 5 ); + expect( colorTableView.columns ).to.equal( 5 ); } ); it( 'creaets collection of recently used colors', () => { @@ -152,7 +152,7 @@ describe( 'ColorTableView', () => { expect( staticColorTable.items.length ).to.equal( 3 ); } ); - colorsDefinition.forEach( ( item, index ) => { + colorDefinitions.forEach( ( item, index ) => { it( `dispatch event to parent element for color: ${ item.color }`, () => { const spy = sinon.spy(); colorTableView.on( 'execute', spy ); diff --git a/tests/ui/colorui.js b/tests/ui/colorui.js index 1de6ad4..bb845ea 100644 --- a/tests/ui/colorui.js +++ b/tests/ui/colorui.js @@ -113,7 +113,7 @@ describe( 'ColorUI', () => { it( 'has assigned proper amount of columns', () => { // Value taken from editor's config above. - expect( testColorPlugin.colorColumns ).to.equal( 3 ); + expect( testColorPlugin.columns ).to.equal( 3 ); } ); } ); diff --git a/tests/utils.js b/tests/utils.js index 2f4c186..a47a195 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -3,7 +3,7 @@ * For licensing, see LICENSE.md. */ -import { FONT_COLOR, FONT_BACKGROUND_COLOR, normalizeOptions, addColorsToDropdown } from './../src/utils'; +import { FONT_COLOR, FONT_BACKGROUND_COLOR, normalizeOptions, addColorTableToDropdown } from './../src/utils'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import ColorTableView from './../src/ui/colortableview'; @@ -103,7 +103,7 @@ describe( 'utils', () => { const dropdown = createDropdown(); dropdown.render(); - addColorsToDropdown( { + addColorTableToDropdown( { dropdownView: dropdown, colors: [ { @@ -121,7 +121,7 @@ describe( 'utils', () => { } } ], - colorColumns: 2, + columns: 2, removeButtonTooltip: 'Remove Color' } ); From c8191d08928be8aa5c6b93f94f11247d5e952053 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Tue, 26 Mar 2019 16:03:25 +0100 Subject: [PATCH 67/92] Moved ColorGrid and ColorTile to ckeditor5-ui. Refactroing of styles; some moved to ckeditor5-theme-lark. --- src/ui/colorgrid.js | 175 --------------------------------------- src/ui/colortableview.js | 10 +-- src/ui/colortile.js | 48 ----------- src/utils.js | 2 +- tests/ui/colorgrid.js | 161 ----------------------------------- tests/ui/colortile.js | 30 ------- theme/fontcolor.css | 42 ---------- 7 files changed, 6 insertions(+), 462 deletions(-) delete mode 100644 src/ui/colorgrid.js delete mode 100644 src/ui/colortile.js delete mode 100644 tests/ui/colorgrid.js delete mode 100644 tests/ui/colortile.js diff --git a/src/ui/colorgrid.js b/src/ui/colorgrid.js deleted file mode 100644 index 6a0df53..0000000 --- a/src/ui/colorgrid.js +++ /dev/null @@ -1,175 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * @module font/ui/colorgrid - */ - -import View from '@ckeditor/ckeditor5-ui/src/view'; -import ColorTile from './colortile'; -import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; -import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; -import KeystrokeHandler from '@ckeditor/ckeditor5-utils/src/keystrokehandler'; - -/** - * A grid of {@link module:font/ui/colortile~ColorTile color tiles}. - * - * @extends module:ui/view~View - */ -export default class ColorGrid extends View { - /** - * Creates an instance of a color grid containing {@link module:font/ui/colortile~ColorTile}. - * - * @param {module:utils/locale~Locale} [locale] The localization services instance. - * @param {Object} options Component configuration - * @param {Array.} [options.colorDefinitions] Array with definitions - * required to create the {@link module:font/ui/colortile~ColorTile tiles}. - * @param {Number} options.columns A number of columns to display the tiles. - */ - constructor( locale, options ) { - super( locale ); - - /** - * Collection of the child tile views. - * - * @readonly - * @member {module:ui/viewcollection~ViewCollection} - */ - this.items = this.createCollection(); - - /** - * Tracks information about DOM focus in the grid. - * - * @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 grid. - * - * @readonly - * @protected - * @member {module:ui/focuscycler~FocusCycler} - */ - this._focusCycler = new FocusCycler( { - focusables: this.items, - focusTracker: this.focusTracker, - keystrokeHandler: this.keystrokes, - actions: { - // Navigate grid items backwards using the arrowup key. - focusPrevious: 'arrowleft', - - // Navigate grid items forwards using the arrowdown key. - focusNext: 'arrowright', - } - } ); - - if ( options.colorDefinitions ) { - options.colorDefinitions.forEach( item => { - const colorTile = new ColorTile(); - - colorTile.set( { - color: item.color, - label: item.label, - tooltip: true, - hasBorder: item.options.hasBorder - } ); - - colorTile.on( 'execute', () => { - this.fire( 'execute', { - value: item.color, - hasBorder: item.options.hasBorder, - label: item.label - } ); - } ); - - this.items.add( colorTile ); - } ); - } - - this.setTemplate( { - tag: 'div', - children: this.items, - attributes: { - class: 'ck-color-table__grid-container', - style: { - gridTemplateColumns: `repeat( ${ options.columns }, 1fr)` - } - } - } ); - } - - /** - * Focuses the first focusable in {@link #items}. - */ - focus() { - if ( this.items.length ) { - this.items.first.focus(); - } - } - - /** - * Focuses the last focusable in {@link #items}. - */ - focusLast() { - if ( this.items.length ) { - this.items.last.focus(); - } - } - - /** - * @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 ); - } -} - -/** - * A color definition used to create a {@link module:font/ui/colortile~ColorTile}. - * - * { - * color: hsl(0, 0%, 75%), - * label: 'Light Grey', - * options: { - * hasBorder: true - * } - * } - * - * @typedef {Object} module:font/ui/colorgrid~ColorDefinition - * @type Object - * - * @property {String} color String representing a color. - * It is used as value of background-color style in {@link module:font/ui/colortile~ColorTile}. - * @property {String} label String used as label for {@link module:font/ui/colortile~ColorTile}. - * @property {Object} options Additional options passed to create a {@link module:font/ui/colortile~ColorTile}. - * @property {Boolean} options.hasBorder A flag that indicates if special a CSS class should be added - * to {@link module:font/ui/colortile~ColorTile}, which renders a border around it. - */ diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index b9cbab5..4a64f8c 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -9,8 +9,8 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; -import ColorTile from './colortile'; -import ColorGrid from './colorgrid'; +import ColorTile from '@ckeditor/ckeditor5-ui/src/colorgrid/colortile'; +import ColorGrid from '@ckeditor/ckeditor5-ui/src/colorgrid/colorgrid'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; @@ -22,7 +22,7 @@ import '../../theme/fontcolor.css'; * Class which represents a view with the following sub–components: * * * a remove color button, - * * a {@link module:font/ui/colorgrid~ColorGrid}, + * * a {@link module:ui/colorgrid/colorgrid~ColorGrid}, * * a grid of recently used colors. * * @extends module:ui/view~View @@ -33,7 +33,7 @@ export default class ColorTableView extends View { * * @param {module:utils/locale~Locale} [locale] The localization services instance. * @param {Object} config Configuration object - * @param {Array.} config.colors Array with definitions of colors to + * @param {Array.} config.colors Array with definitions of colors to * be displayed in the table. * @param {Number} config.columns Number of columns in the color grid. * Also determines how many recent color will be displayed. @@ -53,7 +53,7 @@ export default class ColorTableView extends View { /** * An array with objects representing colors to be displayed in the grid. * - * @type {Arrray.} + * @type {Arrray.} */ this.colorDefinitions = colors; diff --git a/src/ui/colortile.js b/src/ui/colortile.js deleted file mode 100644 index cf61026..0000000 --- a/src/ui/colortile.js +++ /dev/null @@ -1,48 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/** - * @module font/ui/colortile - */ - -import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; - -/** - * This class represents a single color tile in the {@link module:font/ui/colorgrid~ColorGrid}. - * - * @extends module:ui/button/buttonview~ButtonView - */ -export default class ColorTile extends ButtonView { - constructor( locale ) { - super( locale ); - - const bind = this.bindTemplate; - - /** - * String representing a color shown as tile's background. - * @type {String} - */ - this.set( 'color' ); - - /** - * A flag that toggles a special CSS class responsible for displaying - * a border around the button. - * @type {Boolean} - */ - this.set( 'hasBorder' ); - - this.extendTemplate( { - attributes: { - style: { - backgroundColor: bind.to( 'color' ) - }, - class: [ - 'ck-color-table__color-tile', - bind.if( 'hasBorder', 'ck-color-table__color-tile_bordered' ) - ] - } - } ); - } -} diff --git a/src/utils.js b/src/utils.js index 03342cd..240794c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -94,7 +94,7 @@ export function normalizeOptions( colorRow ) { * @param {Object} config Configuration object * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which * will be added {@link module:font/ui/colortableview~ColorTableView}. - * @param {Array.} Array with definitions representing colors to be displayed + * @param {Array.} Array with definitions representing colors to be displayed * in the color table. * @returns {module:font/ui/colortableview~ColorTableView} The new color table view. */ diff --git a/tests/ui/colorgrid.js b/tests/ui/colorgrid.js deleted file mode 100644 index bd410d9..0000000 --- a/tests/ui/colorgrid.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -/* globals Event */ - -import ColorGrid from './../../src/ui/colorgrid'; -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 ColorTile from '../../src/ui/colortile'; -import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils'; - -describe( 'ColorGrid', () => { - let locale, colorGrid; - - const colorDefinitions = [ - { - color: '#000', - label: 'Black', - options: { - hasBorder: false - } - }, - { - color: 'rgb(255, 255, 255)', - label: 'White', - options: { - hasBorder: true - } - }, - { - color: 'red', - label: 'Red', - options: { - hasBorder: false - } - } - ]; - - beforeEach( () => { - locale = { t() {} }; - colorGrid = new ColorGrid( locale, { colorDefinitions } ); - colorGrid.render(); - } ); - - testUtils.createSinonSandbox(); - - describe( 'constructor()', () => { - it( 'creates view collection with children', () => { - expect( colorGrid.items ).to.be.instanceOf( ViewCollection ); - } ); - - it( 'creates focus tracker', () => { - expect( colorGrid.focusTracker ).to.be.instanceOf( FocusTracker ); - } ); - - it( 'creates keystroke handler', () => { - expect( colorGrid.keystrokes ).to.be.instanceOf( KeystrokeHandler ); - } ); - - it( 'creates focus cycler', () => { - expect( colorGrid._focusCycler ).to.be.instanceOf( FocusCycler ); - } ); - - describe( 'add colors from definition as child items', () => { - it( 'has proper number of elements', () => { - expect( colorGrid.items.length ).to.equal( 3 ); - } ); - colorDefinitions.forEach( ( color, index ) => { - describe( 'child items has proper attributes', () => { - it( `for (index: ${ index }, color: ${ color.color }) child`, () => { - const colorTile = colorGrid.items.get( index ); - expect( colorTile ).to.be.instanceOf( ColorTile ); - expect( colorTile.color ).to.equal( color.color ); - } ); - } ); - } ); - } ); - } ); - - describe( 'execute()', () => { - it( 'fires event for rendered tiles', () => { - const spy = sinon.spy(); - const firstTile = colorGrid.items.first; - - colorGrid.on( 'execute', spy ); - - firstTile.isEnabled = true; - - firstTile.element.dispatchEvent( new Event( 'click' ) ); - sinon.assert.callCount( spy, 1 ); - - firstTile.isEnabled = false; - - firstTile.element.dispatchEvent( new Event( 'click' ) ); - sinon.assert.callCount( spy, 1 ); - } ); - } ); - - describe( 'focus', () => { - it( 'focuses the tile in DOM', () => { - const spy = sinon.spy( colorGrid.items.first, 'focus' ); - - colorGrid.focus(); - - sinon.assert.calledOnce( spy ); - - colorGrid.items.clear(); - colorGrid.focus(); - - expect( colorGrid.items.length ).to.equal( 0 ); - sinon.assert.calledOnce( spy ); - } ); - - it( 'focuses last the tile in DOM', () => { - const spy = sinon.spy( colorGrid.items.last, 'focus' ); - - colorGrid.focusLast(); - - sinon.assert.calledOnce( spy ); - - colorGrid.items.clear(); - colorGrid.focusLast(); - - expect( colorGrid.items.length ).to.equal( 0 ); - sinon.assert.calledOnce( spy ); - } ); - - describe( 'update elements in focus tracker', () => { - it( 'adding new element', () => { - const spy = sinon.spy( colorGrid.focusTracker, 'add' ); - - const colorTile = new ColorTile(); - colorTile.set( { - color: 'yellow', - label: 'Yellow', - tooltip: true, - options: { - hasBorder: false - } - } ); - colorGrid.items.add( colorTile ); - - expect( colorGrid.items.length ).to.equal( 4 ); - sinon.assert.calledOnce( spy ); - } ); - - it( 'removes element', () => { - const spy = sinon.spy( colorGrid.focusTracker, 'remove' ); - - colorGrid.items.remove( colorGrid.items.length - 1 ); - - expect( colorGrid.items.length ).to.equal( 2 ); - sinon.assert.calledOnce( spy ); - } ); - } ); - } ); -} ); diff --git a/tests/ui/colortile.js b/tests/ui/colortile.js deleted file mode 100644 index 9dbe5b9..0000000 --- a/tests/ui/colortile.js +++ /dev/null @@ -1,30 +0,0 @@ -/** - * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md. - */ - -import ColorTile from './../../src/ui/colortile'; -import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; - -describe( 'ColorTile', () => { - it( 'inherits from ButtonView', () => { - expect( new ColorTile() ).to.be.instanceOf( ButtonView ); - } ); - - it( 'has proper attributes and classes', () => { - const colorTile = new ColorTile(); - colorTile.render(); - - expect( colorTile.color ).to.be.undefined; - expect( colorTile.hasBorder ).to.be.undefined; - - colorTile.set( 'color', 'green' ); - expect( colorTile.color ).to.equal( 'green' ); - expect( colorTile.element.style.backgroundColor ).to.equal( 'green' ); - expect( colorTile.element.classList.contains( 'ck-color-table__color-tile' ) ).to.be.true; - expect( colorTile.element.classList.contains( 'ck-color-table__color-tile_bordered' ) ).to.be.false; - - colorTile.set( 'hasBorder', true ); - expect( colorTile.element.classList.contains( 'ck-color-table__color-tile_bordered' ) ).to.be.true; - } ); -} ); diff --git a/theme/fontcolor.css b/theme/fontcolor.css index cc96a63..991dee3 100644 --- a/theme/fontcolor.css +++ b/theme/fontcolor.css @@ -3,50 +3,8 @@ * For licensing, see LICENSE.md. */ -:root { - --ck-table-color-tile-size: 20px; - --ck-table-color-max-columns: 5; - --ck-color-table-color-tile-border: hsl(0, 0%, 90%); - --ck-color-table-color-tile-border-active: hsl(184, 80%, 50%); -} - -.ck .ck-color-table__grid-container { - display: grid; - grid-gap: calc( var(--ck-spacing-standard) / 2 ); - padding: var(--ck-spacing-standard); -} - -.ck .ck-color-table__color-tile { - width: var(--ck-table-color-tile-size); - height: var(--ck-table-color-tile-size); - min-width: var(--ck-table-color-tile-size); - min-height: var(--ck-table-color-tile-size); - border-radius: var(--ck-border-radius); - transition: 200ms ease box-shadow; -} - -.ck .ck-disabled.ck-color-table__color-tile { - cursor: unset; - transition: unset; -} - -.ck .ck-color-table__color-tile_bordered { - box-shadow: 0 0 0 1px var(--ck-color-table-color-tile-border); -} - -.ck .ck-color-table__color-tile:hover:not( .ck-disabled ) { - box-shadow: 0 0 0 2px var(--ck-color-table-color-tile-border-active); -} - -/* If we change it to list element this CSS will be obsolete. */ .ck .ck-button.ck-color-table__remove-color { display: flex; align-items: center; width: 100%; - border-bottom: 1px solid var(--ck-color-base-border); - padding: calc(var(--ck-spacing-standard) / 2 ) var(--ck-spacing-standard); -} - -.ck .ck-button.ck-button_with-text.ck-color-table__remove-color svg { - margin-right: var(--ck-spacing-standard); } From e7e1c0b099abb95196dd011f3bfb63a73453f321 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 10:33:30 +0100 Subject: [PATCH 68/92] Added .ck class to .ck-color-table. --- src/ui/colortableview.js | 5 ++++- tests/ui/colortableview.js | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 4a64f8c..f71ac28 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -126,7 +126,10 @@ export default class ColorTableView extends View { this.setTemplate( { tag: 'div', attributes: { - class: [ 'ck-color-table' ] + class: [ + 'ck', + 'ck-color-table' + ] }, children: this.items } ); diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index a84972c..e7ace91 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -31,7 +31,8 @@ describe( 'ColorTableView', () => { options: { hasBorder: true } - }, { + }, + { color: 'red', label: 'Red', options: { @@ -90,6 +91,7 @@ describe( 'ColorTableView', () => { } ); it( 'has proper class', () => { + expect( colorTableView.element.classList.contains( 'ck' ) ).to.be.true; expect( colorTableView.element.classList.contains( 'ck-color-table' ) ).to.be.true; } ); } ); From 46dfa2909337084f9513d3472dde848edd258b3d Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 10:36:04 +0100 Subject: [PATCH 69/92] Renamed ColorGrid, ColorTile -> ColorGridView, ColorTileView. --- src/ui/colortableview.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index f71ac28..6a44e21 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -9,8 +9,8 @@ import View from '@ckeditor/ckeditor5-ui/src/view'; import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview'; -import ColorTile from '@ckeditor/ckeditor5-ui/src/colorgrid/colortile'; -import ColorGrid from '@ckeditor/ckeditor5-ui/src/colorgrid/colorgrid'; +import ColorTileView from '@ckeditor/ckeditor5-ui/src/colorgrid/colortileview'; +import ColorGridView from '@ckeditor/ckeditor5-ui/src/colorgrid/colorgridview'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import FocusTracker from '@ckeditor/ckeditor5-utils/src/focustracker'; import FocusCycler from '@ckeditor/ckeditor5-ui/src/focuscycler'; @@ -22,7 +22,7 @@ import '../../theme/fontcolor.css'; * Class which represents a view with the following sub–components: * * * a remove color button, - * * a {@link module:ui/colorgrid/colorgrid~ColorGrid}, + * * a {@link module:ui/colorgrid/colorgrid~ColorGridView}, * * a grid of recently used colors. * * @extends module:ui/view~View @@ -168,7 +168,7 @@ export default class ColorTableView extends View { * @private */ createStaticColorTable() { - const colorGrid = new ColorGrid( this.locale, { + const colorGrid = new ColorGridView( this.locale, { colorDefinitions: this.colorDefinitions, columns: this.columns } ); @@ -184,11 +184,11 @@ export default class ColorTableView extends View { * @private */ recentlyUsed() { - const recentViews = new ColorGrid( this.locale, { columns: this.columns } ); + const recentViews = new ColorGridView( this.locale, { columns: this.columns } ); recentViews.items.bindTo( this.recentlyUsedColors ).using( colorObj => { - const colorTile = new ColorTile(); + const colorTile = new ColorTileView(); colorTile.set( { color: colorObj.color, From b0ea7d2becc72f32c74882433a76975271c0394a Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 10:46:11 +0100 Subject: [PATCH 70/92] Updated contexts.json file. --- lang/contexts.json | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lang/contexts.json b/lang/contexts.json index 52edcfc..d2b22c0 100644 --- a/lang/contexts.json +++ b/lang/contexts.json @@ -5,5 +5,21 @@ "Big": "Dropdown option label for the 'big' font size preset.", "Huge": "Dropdown option label for the 'huge' font size preset.", "Font Family": "Tooltip for the font family dropdown.", - "Default": "Dropdown option label for the default font family." + "Default": "Dropdown option label for the default font family.", + "Remove color": "Label or a button that removes the color from the text (font color and background).", + "Black": "Label of a button that applies a black text color (font color and background)", + "Dim grey": "Label of a button that applies a dim grey text color (font color and background)", + "Grey": "Label of a button that applies a grey text color (font color and background)", + "Light grey": "Label of a button that applies a light grey text color (font color and background)", + "White": "Label of a button that applies a white text color (font color and background)", + "Red": "Label of a button that applies a red text color (font color and background)", + "Orange": "Label of a button that applies a orange text color (font color and background)", + "Yellow": "Label of a button that applies a yellow text color (font color and background)", + "Light green": "Label of a button that applies a light green text color (font color and background)", + "Green": "Label of a button that applies a green text color (font color and background)", + "Aquamarine": "Label of a button that applies a aquamarine text color (font color and background)", + "Turquoise": "Label of a button that applies a turquoise text color (font color and background)", + "Light blue": "Label of a button that applies a light blue text color (font color and background)", + "Blue": "Label of a button that applies a blue text color (font color and background)", + "Purple": "Label of a button that applies a purple text color (font color and background)" } From 1ac04fc39017ea8383a743125bf8deb301688336 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 10:53:15 +0100 Subject: [PATCH 71/92] Code refactoring: color config localization. --- src/ui/colorui.js | 6 ++++-- src/utils.js | 11 +++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 886b00d..dfcf102 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -11,6 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { addColorTableToDropdown, + normalizeOptions, getLocalizedColorOptions } from '../utils'; @@ -74,14 +75,15 @@ export default class ColorUI extends Plugin { const editor = this.editor; const t = editor.t; const command = editor.commands.get( this.commandName ); - const options = getLocalizedColorOptions( editor, this.componentName ); + const colorsConfig = normalizeOptions( editor.config.get( this.componentName ).colors ); + const localizedColors = getLocalizedColorOptions( editor, colorsConfig ); // Register UI component. editor.ui.componentFactory.add( this.componentName, locale => { const dropdownView = createDropdown( locale ); const colorTableView = addColorTableToDropdown( { dropdownView, - colors: options.map( option => ( { + colors: localizedColors.map( option => ( { label: option.label, color: option.model, options: { diff --git a/src/utils.js b/src/utils.js index 240794c..5055ee4 100644 --- a/src/utils.js +++ b/src/utils.js @@ -111,18 +111,17 @@ export function addColorTableToDropdown( { dropdownView, colors, columns, remove } /** - * Returns configuration options as defined in the `editor.config[ featureName ]` but processed to account for - * editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} + * Returns color configuration options as defined in the `editor.config.(fontColor|fontBackgroundColor).colors` + * but processed to account for editor localization, i.e. to display {@link module:font/fontcolor~FontColorConfig} * or {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig} in the correct language. * * Note: The reason behind this method is that there is no way to use {@link module:utils/locale~Locale#t} * when the user configuration is defined because the editor does not exist yet. * * @param {module:core/editor/editor~Editor} editor An editor instance. - * @param {String} featureName Determines which config (`editor.config[ featureName ]`) colors to localize. - * @returns {Array.|Array.}. + * @returns {Array.}. */ -export function getLocalizedColorOptions( editor, featureName ) { +export function getLocalizedColorOptions( editor, options ) { const t = editor.t; const localizedColorNames = { Black: t( 'Black' ), @@ -142,7 +141,7 @@ export function getLocalizedColorOptions( editor, featureName ) { Purple: t( 'Purple' ) }; - return normalizeOptions( editor.config.get( featureName ).colors ).map( colorOption => { + return options.map( colorOption => { const label = localizedColorNames[ colorOption.label ]; if ( label && label != colorOption.label ) { From 8f37314757bb97408611901a6f1ad90b6f492dbd Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 11:13:12 +0100 Subject: [PATCH 72/92] Docs: Improvement in docs. Extended contexts.json. --- lang/contexts.json | 2 ++ src/fontcolor/fontcolorui.js | 2 +- src/ui/colorui.js | 4 +++- src/utils.js | 9 +++++---- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/lang/contexts.json b/lang/contexts.json index d2b22c0..37b312a 100644 --- a/lang/contexts.json +++ b/lang/contexts.json @@ -6,6 +6,8 @@ "Huge": "Dropdown option label for the 'huge' font size preset.", "Font Family": "Tooltip for the font family dropdown.", "Default": "Dropdown option label for the default font family.", + "Font color": "Label of a button that allows selecting a font color.", + "Font Background Color": "Label of a button that allows selecting a font background color.", "Remove color": "Label or a button that removes the color from the text (font color and background).", "Black": "Label of a button that applies a black text color (font color and background)", "Dim grey": "Label of a button that applies a dim grey text color (font color and background)", diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index 597a7a3..b1a5113 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -12,7 +12,7 @@ import { FONT_COLOR } from '../utils'; import fontColorIcon from '../../theme/icons/font-color.svg'; /** - * The font background color UI plugin. It introduces the `'fontColor'` dropdown. + * The font color UI plugin. It introduces the `'fontColor'` dropdown. * * @extends module:core/plugin~Plugin */ diff --git a/src/ui/colorui.js b/src/ui/colorui.js index dfcf102..5605701 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -17,7 +17,9 @@ import { /** * The color UI plugin which isolates the common logic responsible for displaying dropdowns with color grids. - * It is used to create the `'fontBackgroundColor'` and the `'fontColor'` dropdowns. + * + * It is used to create the `'fontBackgroundColor'` and the `'fontColor'` dropdowns, each hosting + * a {@link module:font/ui/colortableview~ColorTableView}. * * @extends module:core/plugin~Plugin */ diff --git a/src/utils.js b/src/utils.js index 5055ee4..ab42bc2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -89,13 +89,14 @@ export function normalizeOptions( colorRow ) { } /** - * Helper which add {@link module:font/ui/colortableview~ColorTableView} to dropdown with proper initial values. + * Helper which add {@link module:font/ui/colortableview~ColorTableView} to a dropdown with proper initial values. * * @param {Object} config Configuration object * @param {module:ui/dropdown/dropdownview~DropdownView} config.dropdownView Dropdown view to which - * will be added {@link module:font/ui/colortableview~ColorTableView}. - * @param {Array.} Array with definitions representing colors to be displayed - * in the color table. + * a {@link module:font/ui/colortableview~ColorTableView} will be added. + * @param {Array.} config.colors An array with definitions + * representing colors to be displayed in the color table. + * @param {String} config.removeButtonLabel A label of a button responsible for removing the color. * @returns {module:font/ui/colortableview~ColorTableView} The new color table view. */ export function addColorTableToDropdown( { dropdownView, colors, columns, removeButtonLabel } ) { From fa83b3daf1517f431728d6688db43451f4622e50 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 11:28:25 +0100 Subject: [PATCH 73/92] Docs: Improved color utils docs. Minor code refactoring. --- src/ui/colorui.js | 4 ++-- src/utils.js | 34 +++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/ui/colorui.js b/src/ui/colorui.js index 5605701..acd2be7 100644 --- a/src/ui/colorui.js +++ b/src/ui/colorui.js @@ -11,7 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { addColorTableToDropdown, - normalizeOptions, + normalizeColorOptions, getLocalizedColorOptions } from '../utils'; @@ -77,7 +77,7 @@ export default class ColorUI extends Plugin { const editor = this.editor; const t = editor.t; const command = editor.commands.get( this.commandName ); - const colorsConfig = normalizeOptions( editor.config.get( this.componentName ).colors ); + const colorsConfig = normalizeColorOptions( editor.config.get( this.componentName ).colors ); const localizedColors = getLocalizedColorOptions( editor, colorsConfig ); // Register UI component. diff --git a/src/utils.js b/src/utils.js index ab42bc2..46906c9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -49,9 +49,11 @@ export function buildDefinition( modelAttributeKey, options ) { } /** - * Function for font color and font background color plugins - * which is responsible for upcasting data to model. - * styleAttr should eqaul to `'color'` or `'background-color'`. + * A {@link module:font/fontcolor~FontColor font color} and + * {@link module:font/fontbackgroundcolor~FontBackgroundColor font background color} helper + * responsible for upcasting data to model. + * + * **Note**: `styleAttr` should be either `'color'` or `'background-color'`. * * @param {String} styleAttr */ @@ -60,9 +62,11 @@ export function renderUpcastAttribute( styleAttr ) { } /** - * Function for font color and font background color plugins - * which is responsible for downcasting color attribute to span element. - * styleAttr should eqaul to `'color'` or `'background-color'`. + * A {@link module:font/fontcolor~FontColor font color} and + * {@link module:font/fontbackgroundcolor~FontBackgroundColor font background color} helper + * responsible for downcasting a color attribute to a span element. + * + * **Note**: `styleAttr` should be either `'color'` or `'background-color'`. * * @param {String} styleAttr */ @@ -72,18 +76,14 @@ export function renderDowncastElement( styleAttr ) { } ); } -function normalizeColorCode( value ) { - return value.replace( /\s/g, '' ); -} - /** - * Creates model of color from configuration option. It keeps them coherent, - * regardles how user define them in config. + * Creates a unified color definition object from color configuration options. + * The object contains both the information necessary to render the UI and initialize a conversion. * - * @param {String|Object} colorRow + * @param {module:font/fontcolor~FontColorConfig#colors|module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors} options */ -export function normalizeOptions( colorRow ) { - return colorRow +export function normalizeColorOptions( options ) { + return options .map( normalizeSingleColorDefinition ) .filter( option => !!option ); } @@ -153,6 +153,10 @@ export function getLocalizedColorOptions( editor, options ) { } ); } +function normalizeColorCode( value ) { + return value.replace( /\s/g, '' ); +} + function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { From d82c21558de5b54f666e08df25974e36251808d1 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 12:07:32 +0100 Subject: [PATCH 74/92] Tests: Fixed broken test after renamed normalizeOptions() to normalizeColorOptions(). --- tests/utils.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/utils.js b/tests/utils.js index a47a195..73b701a 100644 --- a/tests/utils.js +++ b/tests/utils.js @@ -3,7 +3,12 @@ * For licensing, see LICENSE.md. */ -import { FONT_COLOR, FONT_BACKGROUND_COLOR, normalizeOptions, addColorTableToDropdown } from './../src/utils'; +import { + FONT_COLOR, + FONT_BACKGROUND_COLOR, + normalizeColorOptions, + addColorTableToDropdown +} from './../src/utils'; import { createDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import ColorTableView from './../src/ui/colortableview'; @@ -14,8 +19,8 @@ describe( 'utils', () => { expect( FONT_BACKGROUND_COLOR ).to.equal( 'fontBackgroundColor' ); } ); - it( 'normalizeOptions can produce the same output object', () => { - const normalizedArray = normalizeOptions( [ + it( 'normalizeColorOptions can produce the same output object', () => { + const normalizedArray = normalizeColorOptions( [ 'black', { color: 'black' From dd003326e869d48528fdf6eefae3c6eee5338db2 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 14:26:47 +0100 Subject: [PATCH 75/92] Code refac: What the hell, used importable plugin name constants for the font size and family too. --- src/fontfamily/fontfamilycommand.js | 3 ++- src/fontfamily/fontfamilyediting.js | 4 +--- src/fontfamily/fontfamilyui.js | 9 +++++---- src/fontsize/fontsizecommand.js | 3 ++- src/fontsize/fontsizeediting.js | 4 +--- src/fontsize/fontsizeui.js | 11 ++++++----- src/utils.js | 14 ++++++++++++-- 7 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/fontfamily/fontfamilycommand.js b/src/fontfamily/fontfamilycommand.js index d2d2ba1..c178da4 100644 --- a/src/fontfamily/fontfamilycommand.js +++ b/src/fontfamily/fontfamilycommand.js @@ -8,6 +8,7 @@ */ import FontCommand from '../fontcommand'; +import { FONT_FAMILY } from '../utils'; /** * The font family command. It is used by {@link module:font/fontfamily/fontfamilyediting~FontFamilyEditing} @@ -24,6 +25,6 @@ export default class FontFamilyCommand extends FontCommand { * @inheritDoc */ constructor( editor ) { - super( editor, 'fontFamily' ); + super( editor, FONT_FAMILY ); } } diff --git a/src/fontfamily/fontfamilyediting.js b/src/fontfamily/fontfamilyediting.js index d2dcd93..e002e20 100644 --- a/src/fontfamily/fontfamilyediting.js +++ b/src/fontfamily/fontfamilyediting.js @@ -11,9 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontFamilyCommand from './fontfamilycommand'; import { normalizeOptions } from './utils'; -import { buildDefinition } from '../utils'; - -const FONT_FAMILY = 'fontFamily'; +import { buildDefinition, FONT_FAMILY } from '../utils'; /** * The font family editing feature. diff --git a/src/fontfamily/fontfamilyui.js b/src/fontfamily/fontfamilyui.js index 8856ce7..430dc14 100644 --- a/src/fontfamily/fontfamilyui.js +++ b/src/fontfamily/fontfamilyui.js @@ -13,6 +13,7 @@ import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import { createDropdown, addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; import { normalizeOptions } from './utils'; +import { FONT_FAMILY } from '../utils'; import fontFamilyIcon from '../../theme/icons/font-family.svg'; /** @@ -30,10 +31,10 @@ export default class FontFamilyUI extends Plugin { const options = this._getLocalizedOptions(); - const command = editor.commands.get( 'fontFamily' ); + const command = editor.commands.get( FONT_FAMILY ); // Register UI component. - editor.ui.componentFactory.add( 'fontFamily', locale => { + editor.ui.componentFactory.add( FONT_FAMILY, locale => { const dropdownView = createDropdown( locale ); addListToDropdown( dropdownView, _prepareListOptions( options, command ) ); @@ -76,7 +77,7 @@ export default class FontFamilyUI extends Plugin { const editor = this.editor; const t = editor.t; - const options = normalizeOptions( editor.config.get( 'fontFamily.options' ) ); + const options = normalizeOptions( editor.config.get( FONT_FAMILY ).options ); return options.map( option => { // The only title to localize is "Default" others are font names. @@ -101,7 +102,7 @@ function _prepareListOptions( options, command ) { const def = { type: 'button', model: new Model( { - commandName: 'fontFamily', + commandName: FONT_FAMILY, commandParam: option.model, label: option.title, withText: true diff --git a/src/fontsize/fontsizecommand.js b/src/fontsize/fontsizecommand.js index 5ad2158..78dcc3d 100644 --- a/src/fontsize/fontsizecommand.js +++ b/src/fontsize/fontsizecommand.js @@ -8,6 +8,7 @@ */ import FontCommand from '../fontcommand'; +import { FONT_SIZE } from '../utils'; /** * The font size command. It is used by {@link module:font/fontsize/fontsizeediting~FontSizeEditing} @@ -24,6 +25,6 @@ export default class FontSizeCommand extends FontCommand { * @inheritDoc */ constructor( editor ) { - super( editor, 'fontSize' ); + super( editor, FONT_SIZE ); } } diff --git a/src/fontsize/fontsizeediting.js b/src/fontsize/fontsizeediting.js index db45b44..ef9502f 100644 --- a/src/fontsize/fontsizeediting.js +++ b/src/fontsize/fontsizeediting.js @@ -11,9 +11,7 @@ import Plugin from '@ckeditor/ckeditor5-core/src/plugin'; import FontSizeCommand from './fontsizecommand'; import { normalizeOptions } from './utils'; -import { buildDefinition } from '../utils'; - -const FONT_SIZE = 'fontSize'; +import { buildDefinition, FONT_SIZE } from '../utils'; /** * The font size editing feature. diff --git a/src/fontsize/fontsizeui.js b/src/fontsize/fontsizeui.js index 4633b45..62c957b 100644 --- a/src/fontsize/fontsizeui.js +++ b/src/fontsize/fontsizeui.js @@ -12,7 +12,8 @@ import Model from '@ckeditor/ckeditor5-ui/src/model'; import Collection from '@ckeditor/ckeditor5-utils/src/collection'; import { createDropdown, addListToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils'; -import { normalizeOptions } from '../fontsize/utils'; +import { normalizeOptions } from './utils'; +import { FONT_SIZE } from '../utils'; import fontSizeIcon from '../../theme/icons/font-size.svg'; import '../../theme/fontsize.css'; @@ -32,10 +33,10 @@ export default class FontSizeUI extends Plugin { const options = this._getLocalizedOptions(); - const command = editor.commands.get( 'fontSize' ); + const command = editor.commands.get( FONT_SIZE ); // Register UI component. - editor.ui.componentFactory.add( 'fontSize', locale => { + editor.ui.componentFactory.add( FONT_SIZE, locale => { const dropdownView = createDropdown( locale ); addListToDropdown( dropdownView, _prepareListOptions( options, command ) ); @@ -89,7 +90,7 @@ export default class FontSizeUI extends Plugin { Huge: t( 'Huge' ) }; - const options = normalizeOptions( editor.config.get( 'fontSize.options' ) ); + const options = normalizeOptions( editor.config.get( FONT_SIZE ).options ); return options.map( option => { const title = localizedTitles[ option.title ]; @@ -115,7 +116,7 @@ function _prepareListOptions( options, command ) { const def = { type: 'button', model: new Model( { - commandName: 'fontSize', + commandName: FONT_SIZE, commandParam: option.model, label: option.title, class: 'ck-fontsize-option', diff --git a/src/utils.js b/src/utils.js index 46906c9..fb9b00d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -10,12 +10,22 @@ import ColorTableView from './ui/colortableview'; /** - * Name of font color plugin. + * Name of the font size plugin. + */ +export const FONT_SIZE = 'fontSize'; + +/** + * Name of the font family plugin. + */ +export const FONT_FAMILY = 'fontFamily'; + +/** + * Name of the font color plugin. */ export const FONT_COLOR = 'fontColor'; /** - * Name of font background color plugin. + * Name of font font background color plugin. */ export const FONT_BACKGROUND_COLOR = 'fontBackgroundColor'; From 7771773f0507c026f7d2a4f4e22c81cabeb147dc Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 14:29:11 +0100 Subject: [PATCH 76/92] Docs: Added info about font color features to README.md. --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9afec53..de6ae6e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,12 @@ CKEditor 5 font feature [![Dependency Status](https://david-dm.org/ckeditor/ckeditor5-font/status.svg)](https://david-dm.org/ckeditor/ckeditor5-font) [![devDependency Status](https://david-dm.org/ckeditor/ckeditor5-font/dev-status.svg)](https://david-dm.org/ckeditor/ckeditor5-font?type=dev) -This package implements font size and font family support for CKEditor 5. +This package implements support for the following CKEditor 5 features: + +* font size, +* font family, +* font color, +* font background color. ## Demo From d8d2fd8bb9aa395058b4b44c89a98328b660c9f1 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 15:13:26 +0100 Subject: [PATCH 77/92] Docs: Improved the font feature guide. Changed wording and code snippets. --- ...nt-color-and-background-color-options.html | 2 +- docs/features/font.md | 185 +++++++++++------- 2 files changed, 115 insertions(+), 72 deletions(-) diff --git a/docs/_snippets/features/custom-font-color-and-background-color-options.html b/docs/_snippets/features/custom-font-color-and-background-color-options.html index 38f0fe6..8d85890 100644 --- a/docs/_snippets/features/custom-font-color-and-background-color-options.html +++ b/docs/_snippets/features/custom-font-color-and-background-color-options.html @@ -1,3 +1,3 @@
-

This is sample text which has applied multiple different font colors and font background colors.

+

Text in this sample has multiple font colors and font background colors.

diff --git a/docs/features/font.md b/docs/features/font.md index 87c6395..dc56855 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -147,76 +147,114 @@ ClassicEditor {@snippet features/custom-font-size-numeric-options} -## Configuring font color and font background color +## Configuring font color and font background color features + +Both font color and font background color features are configurable and share the same configuration format. -Plugin enables `font color` and `font background color`. Which allows on using style `color` and `background-color` over text. - Please notice that you can turn on only one of those plugins. As well as configure them separately. + Please note that {@link module:font/fontcolor~FontColor font color} and {@link module:font/fontbackgroundcolor~FontBackgroundColor font background color} are separate plugins. They must be enabled and configured individually. -### Dropdown +Check out the editor below with both features customized using the editor configuration: + +{@snippet features/custom-font-color-and-background-color-options} -It is possible to configure which colors are available in dropdown in the editor. Use the `fontColor.colors` or `fontBackgroundColor.colors` configuration option to do so. +### Specifying the available colors -It is possible to configure how many columns is shown in color dropdown. Use the `fontColor.columns` or `fontBackgroundColor.columns` configuration option to do so. This option also reflects to number of recently used colors section, which always have 1 row with amount of columns equal to `columns` configuration option. -Default colors configuration is presented below: +It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontColor~FontColor#colors `fontColor.colors`} and {@link module:font/fontBackgroundColor~FontBackgroundColor#colors `fontBackgroundColor.colors`} configuration options to do so. ```js -fontColor = { - colors: [ - { - color: 'hsl(0, 0%, 0%)', - label: 'Black' - }, { - color: 'hsl(0, 0%, 30%)', - label: 'Dim grey' - }, { - color: 'hsl(0, 0%, 60%)', - label: 'Grey' - }, { - color: 'hsl(0, 0%, 90%)', - label: 'Light grey' - }, { - color: 'hsl(0, 0%, 100%)', - label: 'White', - hasBorder: true - }, { - color: 'hsl(0, 75%, 60%)', - label: 'Red' - }, { - color: 'hsl(30, 75%, 60%)', - label: 'Orange' - }, { - color: 'hsl(60, 75%, 60%)', - label: 'Yellow' - }, { - color: 'hsl(90, 75%, 60%)', - label: 'Light green' - }, { - color: 'hsl(120, 75%, 60%)', - label: 'Green' - }, { - color: 'hsl(150, 75%, 60%)', - label: 'Aquamarine' - }, { - color: 'hsl(180, 75%, 60%)', - label: 'Turquoise' - }, { - color: 'hsl(210, 75%, 60%)', - label: 'Light blue' - }, { - color: 'hsl(240, 75%, 60%)', - label: 'Blue' - }, { - color: 'hsl(270, 75%, 60%)', - label: 'Purple' - } - ], - columns: 5 -} +ClassicEditor + .create( document.querySelector( '#editor' ), { + fontColor: { + colors: [ + { + color: 'hsl(0, 0%, 0%)', + label: 'Black' + }, + { + color: 'hsl(0, 0%, 30%)', + label: 'Dim grey' + }, + { + color: 'hsl(0, 0%, 60%)', + label: 'Grey' + }, + { + color: 'hsl(0, 0%, 90%)', + label: 'Light grey' + }, + { + color: 'hsl(0, 0%, 100%)', + label: 'White', + hasBorder: true + }, + + // ... + ] + }, + fontBackgroundColor: { + colors: [ + { + color: 'hsl(0, 75%, 60%)', + label: 'Red' + }, + { + color: 'hsl(30, 75%, 60%)', + label: 'Orange' + }, + { + color: 'hsl(60, 75%, 60%)', + label: 'Yellow' + }, + { + color: 'hsl(90, 75%, 60%)', + label: 'Light green' + }, + { + color: 'hsl(120, 75%, 60%)', + label: 'Green' + }, + + // ... + ] + }, + toolbar: [ + 'heading', 'bulletedList', 'numberedList', 'fontColor', 'fontBackgroundColor', 'undo', 'redo' + ] + } ) + .then( ... ) + .catch( ... ); ``` -{@snippet features/custom-font-color-and-background-color-options} +### Changing the geometry of the color grid + +It is also possible to configure in how many columns the colors in the grid are displayed. Use {@link module:font/fontColor~FontColor#columns `fontColor.columns`} and {@link module:font/fontBackgroundColor~FontBackgroundColor#columns `fontBackgroundColor.columns`} to do so. + + + The configuration of the columns also affects the number of recently used colors displayed under the color grid. The less columns, the fewer recently used colors will be displayed. + + +```js +ClassicEditor + .create( document.querySelector( '#editor' ), { + fontColor: { + columns: 3, + + // ... + }, + fontBackgroundColor: { + columns: 6, + + // ... + }, + toolbar: [ + 'heading', 'bulletedList', 'numberedList', 'fontColor', 'fontBackgroundColor', 'undo', 'redo' + ] + } ) + .then( ... ) + .catch( ... ); +``` ## Installation @@ -334,33 +372,38 @@ The {@link module:font/fontcolor~FontColor} plugin registers the following compo * The `'fontColor'` dropdown, * The {@link module:font/fontcolor/fontcolorcommand~FontColorCommand `'fontColor'`} command. - The number of options and their names correspond to the {@link module:font/fontcolor~FontColorConfig#colors `fontColor.colors`} - and {@link module:font/fontcolor~FontColorConfig#columns `fontColor.columns`} configuration options. - You can change the font color of the current selection by executing the command with a desired value: ```js - editor.execute( 'fontColor', { value: rgb(30, 188, 97) } ); + editor.execute( 'fontColor', { value: 'rgb(30, 188, 97)' } ); ``` - The `'fontColor'` command will accept any strings as values. + Passing an empty value will remove the font color from the selection: + + ```js + editor.execute( 'fontColor' ); + ``` The {@link module:font/fontbackgroundcolor~FontBackgroundColor} plugin registers the following components: -* The `'fontColor'` dropdown, +* The `'fontBackgroundColor'` dropdown, * The {@link module:font/fontbackgroundcolor/fontbackgroundcolorcommand~FontBackgroundColorCommand `'fontBackgroundColor'`} command. - The number of options and their names correspond to the {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} - and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} configuration options. - You can change the font background color of the current selection by executing the command with a desired value: ```js - editor.execute( 'fontBackgroundColor', { value: rgb(30, 188, 97) } ); + editor.execute( 'fontBackgroundColor', { value: 'rgb(30, 188, 97)' } ); ``` - The `'fontBackgroundColor'` command will accept any strings as values. + Passing an empty value will remove the font background color from the selection: + ```js + editor.execute( 'fontBackgroundColor' ); + ``` + + + We recommend using the official {@link framework/guides/development-tools#ckeditor-5-inspector CKEditor 5 inspector} for development and debugging. It will give you tons of useful information about the state of the editor such as internal data structures, selection, commands, and many more. + ## Contribute From 73f2a9f7d2f1b6502b023f473babe47a37a849d7 Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 15:23:49 +0100 Subject: [PATCH 78/92] Tests: Fixed wording and grammar in the manual font color test. --- tests/manual/font-color.md | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/manual/font-color.md b/tests/manual/font-color.md index d854abf..8205283 100644 --- a/tests/manual/font-color.md +++ b/tests/manual/font-color.md @@ -1,8 +1,13 @@ ### Loading -The data should be loaded with different text and background colors with followed order. Colors 1-5 use predefined palette. Colors 6-8 use any css color not defined in configuration. -Color 9-10 mixes colors from predefined palette and custom one. -( First is font color, last is background color ) +The data should be loaded with different text and background colors in the following order: + +* Colors 1-5 use the predefined palette, +* Colors 6-8 use custom CSS colors, not defined in the configuration, +* Color 9-10 use a mix from the predefined palette and custom ones. + +The format is the editor content is `N. [font color]; [background color]`. + 1. no-color; no-color 2. White; Black 3. Red; no-color @@ -16,8 +21,7 @@ Color 9-10 mixes colors from predefined palette and custom one. ### Testing -Try to: -- Change color and background color by selecting many paragraphs. -- Change color and background color by selecting some text. -- Check if chosen colors from dropdown are added to recent color list. -- Try to re-apply color from Recent Color list - check if it moves to it beginning. +- Change the font color and font background color on selected text. +- Change the font color and font background color across many paragraphs. +- Check whether the colors are added to recent colors list. +- Try to re-apply a color from recent colors list: the color should move to the beginning of the list. From 4c9fd6b44895376061509b593d5c4191e737d89c Mon Sep 17 00:00:00 2001 From: Aleksander Nowodzinski Date: Wed, 27 Mar 2019 17:08:52 +0100 Subject: [PATCH 79/92] Bound ColorGridView#selectedColor to ColorTableView#selectedColor. --- src/ui/colortableview.js | 1 + tests/ui/colortableview.js | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/ui/colortableview.js b/src/ui/colortableview.js index 6a44e21..ec9d8ae 100644 --- a/src/ui/colortableview.js +++ b/src/ui/colortableview.js @@ -174,6 +174,7 @@ export default class ColorTableView extends View { } ); colorGrid.delegate( 'execute' ).to( this ); + colorGrid.bind( 'selectedColor' ).to( this ); return colorGrid; } diff --git a/tests/ui/colortableview.js b/tests/ui/colortableview.js index e7ace91..6bdc8a1 100644 --- a/tests/ui/colortableview.js +++ b/tests/ui/colortableview.js @@ -154,6 +154,14 @@ describe( 'ColorTableView', () => { expect( staticColorTable.items.length ).to.equal( 3 ); } ); + it( 'binds #selectedColor to the table', () => { + colorTableView.selectedColor = 'foo'; + expect( staticColorTable.selectedColor ).to.equal( 'foo' ); + + colorTableView.selectedColor = 'bar'; + expect( staticColorTable.selectedColor ).to.equal( 'bar' ); + } ); + colorDefinitions.forEach( ( item, index ) => { it( `dispatch event to parent element for color: ${ item.color }`, () => { const spy = sinon.spy(); From bb21e4c2ded974a9da478bf7d4c1eb3802b3b9a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:16:03 +0100 Subject: [PATCH 80/92] Add links to font color plugins into the docs of the Font feature. --- src/font.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/font.js b/src/font.js index 706afa2..da331c3 100644 --- a/src/font.js +++ b/src/font.js @@ -19,6 +19,8 @@ import FontBackgroundColor from './fontbackgroundcolor'; * * * {@link module:font/fontsize~FontSize}, * * {@link module:font/fontfamily~FontFamily}. + * * {@link module:font/fontcolor~FontColor}, + * * {@link module:font/fontbackgroundcolor~FontBackgroundColor}. * * For a detailed overview, check the {@glink features/font Font feature} documentation * and the {@glink api/font package page}. From e7078f9e54272aff1c89d2fd3dae9d5bf85242b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:18:03 +0100 Subject: [PATCH 81/92] Add links to feature guide in new font plugins docs. --- src/fontbackgroundcolor.js | 3 +++ src/fontcolor.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index 8bf1b37..50761b0 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -14,6 +14,9 @@ import FontBackgroundColorUI from './fontbackgroundcolor/fontbackgroundcolorui'; /** * The font background color plugin. * + * For a detailed overview, check the {@glink features/font font feature} documentation + * and the {@glink api/font package page}. + * * This is a "glue" plugin which loads * the {@link module:font/fontbackgroundcolor/fontbackgroundcolorediting~FontBackgroundColorEditing} and * {@link module:font/fontbackgroundcolor/fontbackgroundcolorui~FontBackgroundColorUI} features in the editor. diff --git a/src/fontcolor.js b/src/fontcolor.js index 86c59e6..eebb523 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -14,6 +14,9 @@ import FontColorUI from './fontcolor/fontcolorui'; /** * The font color plugin. * + * For a detailed overview, check the {@glink features/font font feature} documentation + * and the {@glink api/font package page}. + * * This is a "glue" plugin which loads the {@link module:font/fontcolor/fontcolorediting~FontColorEditing} and * {@link module:font/fontcolor/fontcolorui~FontColorUI} features in the editor. * From 5467682af5aeebf92a16c07272f41d4e2a5b0601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:19:14 +0100 Subject: [PATCH 82/92] Typo fix. --- src/fontbackgroundcolor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index 50761b0..6d72602 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -139,5 +139,5 @@ export default class FontBackgroundColor extends Plugin { * columns: 5 * } * - * @member {Numebr} module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns + * @member {Number} module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns */ From 755a6034890a272bab404e0794382ff8e12b0d9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:20:58 +0100 Subject: [PATCH 83/92] Fix links to #columns in feature guide. --- docs/features/font.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/font.md b/docs/features/font.md index dc56855..5255a4f 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -161,7 +161,7 @@ Check out the editor below with both features customized using the editor config ### Specifying the available colors -It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontColor~FontColor#colors `fontColor.colors`} and {@link module:font/fontBackgroundColor~FontBackgroundColor#colors `fontBackgroundColor.colors`} configuration options to do so. +It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontColor~FontColorConfig#colors `fontColor.colors`} and {@link module:font/fontBackgroundColor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} configuration options to do so. ```js ClassicEditor @@ -229,7 +229,7 @@ ClassicEditor ### Changing the geometry of the color grid -It is also possible to configure in how many columns the colors in the grid are displayed. Use {@link module:font/fontColor~FontColor#columns `fontColor.columns`} and {@link module:font/fontBackgroundColor~FontBackgroundColor#columns `fontBackgroundColor.columns`} to do so. +It is also possible to configure in how many columns the colors in the grid are displayed. Use {@link module:font/fontColor~FontColorConfig#columns `fontColor.columns`} and {@link module:font/fontBackgroundColor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} to do so. The configuration of the columns also affects the number of recently used colors displayed under the color grid. The less columns, the fewer recently used colors will be displayed. From 8cba7545579f371777257ac3b16d73ea08b5fe55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:24:27 +0100 Subject: [PATCH 84/92] Add missing jsdoc annotations. --- src/utils.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/utils.js b/src/utils.js index fb9b00d..b646dfc 100644 --- a/src/utils.js +++ b/src/utils.js @@ -91,6 +91,7 @@ export function renderDowncastElement( styleAttr ) { * The object contains both the information necessary to render the UI and initialize a conversion. * * @param {module:font/fontcolor~FontColorConfig#colors|module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors} options + * @returns {Array.} */ export function normalizeColorOptions( options ) { return options @@ -130,6 +131,7 @@ export function addColorTableToDropdown( { dropdownView, colors, columns, remove * when the user configuration is defined because the editor does not exist yet. * * @param {module:core/editor/editor~Editor} editor An editor instance. + * @param {module:font/fontcolor~FontColorConfig#colors|module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors} options * @returns {Array.}. */ export function getLocalizedColorOptions( editor, options ) { From c5305735c5c5bb3daee6c5f3aba0a10e3a419913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:24:45 +0100 Subject: [PATCH 85/92] Typo fix. --- src/fontcolor.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fontcolor.js b/src/fontcolor.js index eebb523..94fd0dc 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -138,5 +138,5 @@ export default class FontColor extends Plugin { * columns: 5 * } * - * @member {Numebr} module:font/fontcolor~FontColorConfig#columns + * @member {Number} module:font/fontcolor~FontColorConfig#columns */ From d772c7ef5944cdd4fb082655eea5cb32a2d3bae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:29:00 +0100 Subject: [PATCH 86/92] Fix incorrect links to API in feature guide. --- docs/features/font.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/features/font.md b/docs/features/font.md index 5255a4f..2276d75 100644 --- a/docs/features/font.md +++ b/docs/features/font.md @@ -161,7 +161,7 @@ Check out the editor below with both features customized using the editor config ### Specifying the available colors -It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontColor~FontColorConfig#colors `fontColor.colors`} and {@link module:font/fontBackgroundColor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} configuration options to do so. +It is possible to configure which colors are available in the color dropdown. Use the {@link module:font/fontcolor~FontColorConfig#colors `fontColor.colors`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors `fontBackgroundColor.colors`} configuration options to do so. ```js ClassicEditor @@ -229,7 +229,7 @@ ClassicEditor ### Changing the geometry of the color grid -It is also possible to configure in how many columns the colors in the grid are displayed. Use {@link module:font/fontColor~FontColorConfig#columns `fontColor.columns`} and {@link module:font/fontBackgroundColor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} to do so. +It is also possible to configure in how many columns the colors in the grid are displayed. Use {@link module:font/fontcolor~FontColorConfig#columns `fontColor.columns`} and {@link module:font/fontbackgroundcolor~FontBackgroundColorConfig#columns `fontBackgroundColor.columns`} to do so. The configuration of the columns also affects the number of recently used colors displayed under the color grid. The less columns, the fewer recently used colors will be displayed. From 920e286731fad1f30b0c1bf84c151a5b9e6433b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:34:24 +0100 Subject: [PATCH 87/92] Add missing jsdoc doclets to constructors. --- src/fontbackgroundcolor/fontbackgroundcolorui.js | 3 +++ src/fontcolor/fontcolorui.js | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/fontbackgroundcolor/fontbackgroundcolorui.js b/src/fontbackgroundcolor/fontbackgroundcolorui.js index 524f14a..32b08a4 100644 --- a/src/fontbackgroundcolor/fontbackgroundcolorui.js +++ b/src/fontbackgroundcolor/fontbackgroundcolorui.js @@ -17,6 +17,9 @@ import fontBackgroundColorIcon from '../../theme/icons/font-background.svg'; * @extends module:core/plugin~Plugin */ export default class FontBackgroundColorUI extends ColorUI { + /** + * @inheritDoc + */ constructor( editor ) { const t = editor.locale.t; diff --git a/src/fontcolor/fontcolorui.js b/src/fontcolor/fontcolorui.js index b1a5113..f69c6e3 100644 --- a/src/fontcolor/fontcolorui.js +++ b/src/fontcolor/fontcolorui.js @@ -17,6 +17,9 @@ import fontColorIcon from '../../theme/icons/font-color.svg'; * @extends module:core/plugin~Plugin */ export default class FontColorUI extends ColorUI { + /** + * @inheritDoc + */ constructor( editor ) { const t = editor.locale.t; From 414fb19715160a087fedd90ec6cea10a178a5280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 10:47:44 +0100 Subject: [PATCH 88/92] Add links to sub-features in api page. --- docs/api/font.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/api/font.md b/docs/api/font.md index 5b34d16..cc54163 100644 --- a/docs/api/font.md +++ b/docs/api/font.md @@ -14,8 +14,11 @@ Check out the {@link features/font#demo demo in the Font feature} guide. ## Documentation -See the {@link features/font Font feature} guide -and {@link module:font/fontfamily~FontFamily} and {@link module:font/fontsize~FontSize} plugins documentation. +See the {@link features/font Font feature} guide and plugins documentation: +- {@link module:font/fontfamily~FontFamily}. +- {@link module:font/fontsize~FontSize}. +- {@link module:font/fontcolor~FontColor}. +- {@link module:font/fontbackgroundcolor~FontBackgroundColor}. ## Installation From ebcbe8c565b81473a138fd09ca78f37faa19cef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 11:02:34 +0100 Subject: [PATCH 89/92] Add private methods docs. --- src/utils.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/utils.js b/src/utils.js index b646dfc..2bcb57a 100644 --- a/src/utils.js +++ b/src/utils.js @@ -66,6 +66,7 @@ export function buildDefinition( modelAttributeKey, options ) { * **Note**: `styleAttr` should be either `'color'` or `'background-color'`. * * @param {String} styleAttr + * @return {String} */ export function renderUpcastAttribute( styleAttr ) { return viewElement => normalizeColorCode( viewElement.getStyle( styleAttr ) ); @@ -165,10 +166,18 @@ export function getLocalizedColorOptions( editor, options ) { } ); } +// Fixes color value string +// +// @param {String} value +// @returns {String} function normalizeColorCode( value ) { return value.replace( /\s/g, '' ); } +// Creates normalized color definition from user defined configuration. +// +// @param {String|Object} +// @returns {module:ui/colorgrid/colorgrid~ColorDefinition} function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { return { From 32cfbf1ec0c1937b0b07ea51c9927c6f39554996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Go=C5=82aszewski?= Date: Fri, 29 Mar 2019 11:32:29 +0100 Subject: [PATCH 90/92] Update color definition related docs. --- src/utils.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/utils.js b/src/utils.js index 2bcb57a..ef4de54 100644 --- a/src/utils.js +++ b/src/utils.js @@ -91,8 +91,8 @@ export function renderDowncastElement( styleAttr ) { * Creates a unified color definition object from color configuration options. * The object contains both the information necessary to render the UI and initialize a conversion. * - * @param {module:font/fontcolor~FontColorConfig#colors|module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors} options - * @returns {Array.} + * @param {module:ui/colorgrid/colorgrid~ColorDefinition} options + * @returns {Array.} */ export function normalizeColorOptions( options ) { return options @@ -132,7 +132,7 @@ export function addColorTableToDropdown( { dropdownView, colors, columns, remove * when the user configuration is defined because the editor does not exist yet. * * @param {module:core/editor/editor~Editor} editor An editor instance. - * @param {module:font/fontcolor~FontColorConfig#colors|module:font/fontbackgroundcolor~FontBackgroundColorConfig#colors} options + * @param {Array.} options * @returns {Array.}. */ export function getLocalizedColorOptions( editor, options ) { @@ -176,7 +176,7 @@ function normalizeColorCode( value ) { // Creates normalized color definition from user defined configuration. // -// @param {String|Object} +// @param {String|module:ui/colorgrid/colorgrid~ColorDefinition} // @returns {module:ui/colorgrid/colorgrid~ColorDefinition} function normalizeSingleColorDefinition( color ) { if ( typeof color === 'string' ) { From 50328e19dede89b5f4e67e52332decbafdfd5409 Mon Sep 17 00:00:00 2001 From: Marek Lewandowski Date: Fri, 29 Mar 2019 13:40:11 +0100 Subject: [PATCH 91/92] Tests: Simplified manual test description. --- tests/manual/font-color.md | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/tests/manual/font-color.md b/tests/manual/font-color.md index 8205283..cbe94ec 100644 --- a/tests/manual/font-color.md +++ b/tests/manual/font-color.md @@ -6,18 +6,7 @@ The data should be loaded with different text and background colors in the follo * Colors 6-8 use custom CSS colors, not defined in the configuration, * Color 9-10 use a mix from the predefined palette and custom ones. -The format is the editor content is `N. [font color]; [background color]`. - -1. no-color; no-color -2. White; Black -3. Red; no-color -4. no-color; Light green -5. Orange: Dim grey -6. #00FFFF; rgb(255, 0, 0) -7. hsla( 0, 0%, 0%, .7); gold -8. rgba( 0, 120, 250, 0.8); hsla(270, 100%, 50%, 0.3) -9. #ddd; Aquamarine -10. Purple; #d82 +The format in the editor content is: `N. [font color]; [background color]`. ### Testing From 2ab56e78bc4510434fc8fff411400fcf493532fc Mon Sep 17 00:00:00 2001 From: Marek Lewandowski Date: Fri, 29 Mar 2019 14:35:31 +0100 Subject: [PATCH 92/92] Docs: Minor rewording to improve docs maintainability. --- src/fontbackgroundcolor.js | 2 +- src/fontcolor.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fontbackgroundcolor.js b/src/fontbackgroundcolor.js index 6d72602..daffdb1 100644 --- a/src/fontbackgroundcolor.js +++ b/src/fontbackgroundcolor.js @@ -58,7 +58,7 @@ export default class FontBackgroundColor extends Plugin { /** * Available font background colors defined as an array of strings or objects. * - * The default value registers 15 colors: + * The default value registers the following colors: * * const fontBackgroundColorConfig = { * colors: [ diff --git a/src/fontcolor.js b/src/fontcolor.js index 94fd0dc..e7845a3 100644 --- a/src/fontcolor.js +++ b/src/fontcolor.js @@ -57,7 +57,7 @@ export default class FontColor extends Plugin { /** * Available font colors defined as an array of strings or objects. * - * The default value registers 15 colors: + * The default value registers the following colors: * * const fontColorConfig = { * colors: [